|
@@ -2,13 +2,13 @@
|
|
|
<div class="meta2d">
|
|
|
<div class="tools">
|
|
|
<t-tooltip content="新建" placement="bottom">
|
|
|
- <a><t-icon name="add" /></a>
|
|
|
+ <a><t-icon name="add" @click="newFile" /></a>
|
|
|
</t-tooltip>
|
|
|
<t-tooltip content="保存" placement="bottom">
|
|
|
- <a> <t-icon name="save" /></a>
|
|
|
+ <a> <t-icon name="save" @click="save" /></a>
|
|
|
</t-tooltip>
|
|
|
<t-tooltip content="保存为模板" placement="bottom">
|
|
|
- <a><t-icon name="layers" /></a>
|
|
|
+ <a><t-icon name="layers" @click="saveAsComponents" /></a>
|
|
|
</t-tooltip>
|
|
|
<t-tooltip content="格式化" placement="bottom">
|
|
|
<a>
|
|
@@ -100,16 +100,39 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { Meta2d, Options } from '@meta2d/core';
|
|
|
-import { onMounted, onUnmounted } from 'vue';
|
|
|
-import { registerBasicDiagram } from '@/services/register';
|
|
|
+import { Meta2d, Options } from "@meta2d/core";
|
|
|
+import { onMounted, onUnmounted } from "vue";
|
|
|
+import { registerBasicDiagram } from "@/services/register";
|
|
|
+import { Meta2dBackData, checkData } from "@/services/utils";
|
|
|
+import { useRouter, useRoute } from "vue-router";
|
|
|
+import { useUser } from "@/services/user";
|
|
|
+import { MessagePlugin } from "tdesign-vue-next";
|
|
|
+import localforage from "localforage";
|
|
|
+import { dataURLtoBlob, upload } from "@/services/file";
|
|
|
+import {
|
|
|
+ delImage,
|
|
|
+ getFolders,
|
|
|
+ addCollection,
|
|
|
+ updateCollection,
|
|
|
+ updateFolders,
|
|
|
+} from "@/services/api";
|
|
|
+import { baseVer } from "@/services/upgrade";
|
|
|
+
|
|
|
+const router = useRouter();
|
|
|
+const route = useRoute();
|
|
|
+const { user, message, getUser, getMessage, signout } = useUser();
|
|
|
|
|
|
const meta2dOptions: Options = {
|
|
|
- cdn: 'https://assets.le5lecdn.com',
|
|
|
+ cdn: "https://assets.le5lecdn.com",
|
|
|
rule: true,
|
|
|
+ background: '#1e2430',
|
|
|
+ x: 32,
|
|
|
+ y: 32,
|
|
|
+ width: 1920,
|
|
|
+ height: 1080,
|
|
|
};
|
|
|
onMounted(() => {
|
|
|
- new Meta2d('meta2d', meta2dOptions);
|
|
|
+ new Meta2d("meta2d", meta2dOptions);
|
|
|
registerBasicDiagram();
|
|
|
});
|
|
|
|
|
@@ -118,6 +141,217 @@ onUnmounted(() => {
|
|
|
(<any>globalThis).meta2d.destroy();
|
|
|
}
|
|
|
});
|
|
|
+
|
|
|
+enum SaveType {
|
|
|
+ Save,
|
|
|
+ SaveAs,
|
|
|
+}
|
|
|
+
|
|
|
+//本地保存图纸数据 key
|
|
|
+const localMeta2dDataName = "meta2dData";
|
|
|
+
|
|
|
+const save = async (type: SaveType = SaveType.Save) => {
|
|
|
+ (<any>globalThis).meta2d.stopAnimate();
|
|
|
+ const data: Meta2dBackData = (<any>globalThis).meta2d.data();
|
|
|
+ if (!(user && user.username)) {
|
|
|
+ MessagePlugin.warning("请先登录,否则无法保存!");
|
|
|
+ localforage.setItem(localMeta2dDataName, JSON.stringify(data));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ checkData(data);
|
|
|
+ if (!data._id && route.query.id) {
|
|
|
+ data._id = route.query.id as string;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ (globalThis as any).beforeSaveMeta2d &&
|
|
|
+ !(await (globalThis as any).beforeSaveMeta2d(data))
|
|
|
+ ) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === SaveType.SaveAs) {
|
|
|
+ //另存为去掉teams信息
|
|
|
+ delete data.teams;
|
|
|
+ }
|
|
|
+ //如果不是自己创建的团队图纸,就不去修改缩略图(没有权限去删除缩略图)
|
|
|
+ if (!((data as any).teams && data.owner?.id !== user.id)) {
|
|
|
+ let blob: Blob;
|
|
|
+ try {
|
|
|
+ blob = dataURLtoBlob((<any>globalThis).meta2d.toPng(10));
|
|
|
+ } catch (e) {
|
|
|
+ MessagePlugin.error(
|
|
|
+ "无法下载,宽度不合法,画布可能没有画笔/画布大小超出浏览器最大限制"
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (data._id && type === SaveType.Save) {
|
|
|
+ if (data.image && !(await delImage(data.image))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const file = await upload(blob, true);
|
|
|
+ if (!file) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 缩略图
|
|
|
+ data.image = file.url;
|
|
|
+ (<any>globalThis).meta2d.store.data.image = data.image;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data.component) {
|
|
|
+ // pens 存储原数据用于二次编辑 ; componentDatas 组合后的数据,用于复用
|
|
|
+ data.componentDatas = (<any>globalThis).meta2d.toComponent(
|
|
|
+ undefined,
|
|
|
+ (<any>globalThis).meta2d.store.data.showChild,
|
|
|
+ false //自定义组合节点生成默认锚点
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ data.component = false; // 必要值
|
|
|
+ }
|
|
|
+ let collection = data.component ? "le5le2d-components" : "le5le2d";
|
|
|
+ let ret: any;
|
|
|
+ if (!data.name) {
|
|
|
+ // 文件名称
|
|
|
+ data.name = `meta2d.${new Date().toLocaleString()}`;
|
|
|
+ (<any>globalThis).meta2d.store.data.name = data.name;
|
|
|
+ }
|
|
|
+ !data.version && (data.version = baseVer);
|
|
|
+
|
|
|
+ let list = undefined;
|
|
|
+ let folder: any = undefined;
|
|
|
+ let folderId = undefined;
|
|
|
+ if (
|
|
|
+ !data.component &&
|
|
|
+ data.folder &&
|
|
|
+ !(data.teams && data.owner?.id !== user.id)
|
|
|
+ ) {
|
|
|
+ //自己的图纸才允许去请求
|
|
|
+ folder = getFolders({
|
|
|
+ type: collection,
|
|
|
+ name: data.folder,
|
|
|
+ });
|
|
|
+ if (folder) {
|
|
|
+ list = folder.list; //团队图纸文件夹
|
|
|
+ folderId = folder._id;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!list) {
|
|
|
+ list = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type === SaveType.SaveAs) {
|
|
|
+ // 另存为一定走 新增 ,由于后端 未控制 userId 等属性,清空一下
|
|
|
+ const delAttrs = [
|
|
|
+ "userId",
|
|
|
+ "id",
|
|
|
+ "shared",
|
|
|
+ "star",
|
|
|
+ "view",
|
|
|
+ "username",
|
|
|
+ "editorName",
|
|
|
+ "editorId",
|
|
|
+ "createdAt",
|
|
|
+ "updatedAt",
|
|
|
+ "recommend",
|
|
|
+ ];
|
|
|
+ for (const k of delAttrs) {
|
|
|
+ delete (data as any)[k];
|
|
|
+ }
|
|
|
+ ret = addCollection(collection, data); // 新增
|
|
|
+ if (!data.component) {
|
|
|
+ list.push({
|
|
|
+ id: ret._id,
|
|
|
+ image: data.image,
|
|
|
+ name: data.name,
|
|
|
+ component: data.component,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (data._id && data.teams && data.owner?.id !== user.id) {
|
|
|
+ // 团队图纸 不允许修改文件夹信息
|
|
|
+ delete data.folder;
|
|
|
+ ret = updateCollection(collection, data);
|
|
|
+ } else if (data._id) {
|
|
|
+ ret = updateCollection(collection, data);
|
|
|
+ if (!data.component) {
|
|
|
+ list.forEach((i: any) => {
|
|
|
+ if (i.id === data._id) {
|
|
|
+ i.image = data.image;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //TODO 处理老接口图纸情况
|
|
|
+ let one = list.find((item: any) => item.id === data._id);
|
|
|
+ if (!data.component && !one) {
|
|
|
+ list.push({
|
|
|
+ id: ret._id,
|
|
|
+ image: data.image,
|
|
|
+ name: data.name,
|
|
|
+ component: data.component,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ret = addCollection(collection, data); // 新增
|
|
|
+ if (!data.component) {
|
|
|
+ list.push({
|
|
|
+ id: ret._id,
|
|
|
+ image: data.image,
|
|
|
+ name: data.name,
|
|
|
+ component: data.component,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ret.error) {
|
|
|
+ return null;
|
|
|
+ } else {
|
|
|
+ if (!data.component && folderId) {
|
|
|
+ const updateRet: any = updateFolders({
|
|
|
+ _id: folderId,
|
|
|
+ list,
|
|
|
+ });
|
|
|
+ if (updateRet.error) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // showModelSaveAsPop.value = false;
|
|
|
+ }
|
|
|
+ // 保存图纸之后的钩子函数
|
|
|
+ (window as any).afterSaveMeta2d &&
|
|
|
+ (await (window as any).afterSaveMeta2d(ret));
|
|
|
+ if (
|
|
|
+ !data._id ||
|
|
|
+ data.owner?.id !== user.id ||
|
|
|
+ route.query.version ||
|
|
|
+ type === SaveType.SaveAs // 另存为肯定走新增,也会产生新的 id
|
|
|
+ ) {
|
|
|
+ data._id = ret._id;
|
|
|
+ (<any>globalThis).meta2d.store.data._id = data._id;
|
|
|
+ router.replace({
|
|
|
+ path: "/",
|
|
|
+ query: {
|
|
|
+ id: data._id,
|
|
|
+ r: Date.now() + "",
|
|
|
+ component: data.component + "",
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ MessagePlugin.success("保存成功!");
|
|
|
+ // 保存成功,重新请求文件夹
|
|
|
+ (<any>globalThis).meta2d.emit("t-save-success", true);
|
|
|
+ // 已保存,不再是新的,无需提示保存
|
|
|
+ // isNew.value = false;
|
|
|
+ localforage.removeItem(localMeta2dDataName);
|
|
|
+};
|
|
|
+
|
|
|
+const saveAsComponents = () => {
|
|
|
+ // (<any>globalThis).meta2d.store.data.component = true;
|
|
|
+ save();
|
|
|
+}
|
|
|
</script>
|
|
|
<style lang="postcss" scoped>
|
|
|
.meta2d {
|