Browse Source

perfect_view_new&save

ananzhusen 2 years ago
parent
commit
b7b6347aa4
4 changed files with 418 additions and 390 deletions
  1. 18 0
      src/services/common.ts
  2. 3 0
      src/services/utils.ts
  3. 393 389
      src/views/components/Header.vue
  4. 4 1
      src/views/components/View.vue

+ 18 - 0
src/services/common.ts

@@ -0,0 +1,18 @@
+import { ref } from "vue";
+
+const dot = ref(false);
+
+export const useDot = () => {
+  const getDot = async () => {
+    return dot;
+  };
+  const setDot = async (value: boolean) => {
+    dot.value = value;
+  };
+
+  return {
+    dot,
+    getDot,
+    setDot,
+  };
+};

+ 3 - 0
src/services/utils.ts

@@ -4,6 +4,9 @@ import { ref } from "vue";
 
 const market = import.meta.env.VITE_MARKET;
 
+export const noLoginTip = "请先登录,否则无法保存!";
+export const localMeta2dDataName = "meta2dData";
+
 export interface Meta2dBackData extends Meta2dData {
   id?: string;
   name?: string;

+ 393 - 389
src/views/components/Header.vue

@@ -287,6 +287,8 @@ import {
 import JSZip from "jszip";
 import axios from "axios";
 import { switchTheme } from "@/services/theme";
+import { noLoginTip ,localMeta2dDataName} from "@/services/utils";
+import { useDot } from "@/services/common";
 
 const router = useRouter();
 const route = useRoute();
@@ -297,17 +299,16 @@ const baseUrl = import.meta.env.BASE_URL || "/";
 
 const { user, message, getUser, getMessage, signout } = useUser();
 
-const isNew = ref(false);
 const data = reactive({
   name: "空白文件",
 });
 
-const inputMeta2dName = (value) => {
-  meta2d.store.data.name = data.name;
+const inputMeta2dName = () => {
+  (meta2d.store.data as Meta2dBackData).name = data.name;
 };
 
 const initMeta2dName = () => {
-  data.name = meta2d.store.data.name;
+  data.name = (meta2d.store.data as Meta2dBackData).name||'';
 };
 
 nextTick(() => {
@@ -333,87 +334,6 @@ function login() {
   //     }
 }
 
-const title = "系统可能不会保存您所做的更改,是否继续?";
-const newFile = async () => {
-  if (isNew.value) {
-    if (await showNotification(title)) {
-      newfile(false);
-    }
-  } else {
-    newfile(false);
-  }
-};
-
-const pen = ref(false);
-const drawPen = () => {
-  meta2d.inactive();
-  try {
-    if (!meta2d.canvas.drawingLineName) {
-      // 开了钢笔,需要关掉铅笔
-      meta2d.canvas.pencil && drawingPencil();
-      meta2d.drawLine(meta2d.store.options.drawingLineName);
-    } else {
-      meta2d.finishDrawLine();
-      meta2d.drawLine();
-    }
-    //钢笔
-    pen.value = !!meta2d.canvas.drawingLineName;
-  } catch (e: any) {
-    MessagePlugin.warning(e.message);
-  }
-};
-
-const pencil = ref(false);
-const drawingPencil = () => {
-  try {
-    if (!meta2d.canvas.pencil) {
-      // 开了铅笔需要关掉钢笔
-      meta2d.canvas.drawingLineName && drawPen();
-      meta2d.drawingPencil();
-    } else {
-      meta2d.stopPencil();
-    }
-    pencil.value = meta2d.canvas.pencil || false;
-  } catch (e: any) {
-    MessagePlugin.warning(e.message);
-  }
-};
-
-const magnifier = ref(false);
-const showMagnifier = () => {
-  if (!meta2d.canvas.magnifierCanvas.magnifier) {
-    meta2d.showMagnifier();
-  } else {
-    meta2d.hideMagnifier();
-  }
-  magnifier.value = meta2d.canvas.magnifierCanvas.magnifier;
-};
-
-const map = ref(false);
-const showMap = () => {
-  if (!meta2d.map?.isShow) {
-    meta2d.showMap();
-  } else {
-    meta2d.hideMap();
-  }
-  map.value = meta2d.map?.isShow;
-};
-
-async function newfile(noRouter: boolean = false) {
-  meta2d.canvas.drawingLineName && drawPen();
-  meta2d.canvas.pencil && drawingPencil();
-  meta2d.canvas.magnifierCanvas.magnifier && showMagnifier();
-  meta2d.map?.isShow && showMap();
-  isNew.value = false;
-  // await localforage.removeItem(localMeta2dDataName);
-  // 打开文件操作不跳转
-  !noRouter &&
-    router.replace({
-      path: "/",
-      query: { r: Date.now() + "" },
-    });
-}
-
 function load(newT: boolean = false) {
   const input = document.createElement("input");
   input.type = "file";
@@ -603,7 +523,7 @@ const openZip = async (file: File, isNew: boolean = false) => {
 };
 
 async function loadFile(newT: boolean = false) {
-  if (isNew.value) {
+  if (dot.value) {
     if (await showNotification(title)) {
       load(newT);
     }
@@ -616,323 +536,116 @@ async function openFile() {
   loadFile(true);
 }
 
-enum SaveType {
-  Save,
-  SaveAs,
-}
-
-//本地保存图纸数据 key
-const localMeta2dDataName = "meta2dData";
-const save = async (type: SaveType = SaveType.Save, component?: boolean) => {
-  meta2d.stopAnimate();
+const downloadJson = () => {
   const data: Meta2dBackData = meta2d.data();
+  if (data._id) delete data._id;
+  checkData(data);
+  import("file-saver").then(({ saveAs }) => {
+    saveAs(
+      new Blob(
+        [JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")],
+        {
+          type: "text/plain;charset=utf-8",
+        }
+      ),
+      `${data.name || "le5le.meta2d"}.json`
+    );
+  });
+};
+
+const downloadZip = async () => {
   if (!(user && user.username)) {
     MessagePlugin.warning(noLoginTip);
-    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))
-  ) {
+  if (!user.vipExpired) {
+    gotoAccount();
     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(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;
-    }
+  MessagePlugin.info("正在下载打包中,可能需要几分钟,请耐心等待...");
+  const [{ default: JSZip }, { saveAs }] = await Promise.all([
+    import("jszip"),
+    import("file-saver"),
+  ]);
 
-    // 缩略图
-    data.image = file.url;
-    (meta2d.store.data as Meta2dBackData).image = data.image;
-  }
+  const zip: any = new JSZip();
+  const data: Meta2dBackData = meta2d.data();
+  let _fileName =
+    (data.name && data.name.replace(/\//g, "_").replace(/:/g, "_")) ||
+    "le5le.meta2d";
+  const _zip = zip.folder(`${_fileName}`);
+  if (data._id) delete data._id;
+  checkData(data);
+  _zip.file(
+    `${_fileName}.json`,
+    JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")
+  );
+  await zipImages(_zip, meta2d.store.data.pens);
 
-  if (component) {
-    data.component = true;
-    // pens 存储原数据用于二次编辑 ; componentDatas 组合后的数据,用于复用
-    data.componentDatas = meta2d.toComponent(
-      undefined,
-      (meta2d.store.data as Meta2dBackData).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()}`;
-    (meta2d.store.data as Meta2dBackData).name = data.name;
+  const blob = await zip.generateAsync({ type: "blob" });
+  saveAs(blob, `${_fileName}.zip`);
+};
+
+const downloadHtml = async () => {
+  if (!(user && user.username)) {
+    MessagePlugin.warning(noLoginTip);
+    return;
   }
-  !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 (!user.vipExpired) {
+    gotoAccount();
+    return;
   }
-  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;
-    (meta2d.store.data as Meta2dBackData)._id = data._id;
-    router.replace({
-      path: "/",
-      query: {
-        id: data._id,
-        r: Date.now() + "",
-        component: data.component + "",
-      },
-    });
-  }
-
-  MessagePlugin.success("保存成功!");
-  // 保存成功,重新请求文件夹
-  meta2d.emit("t-save-success", true);
-  // 已保存,不再是新的,无需提示保存
-  // isNew.value = false;
-  localforage.removeItem(localMeta2dDataName);
-};
-
-const downloadJson = () => {
-  const data: Meta2dBackData = meta2d.data();
-  if (data._id) delete data._id;
-  checkData(data);
-  import("file-saver").then(({ saveAs }) => {
-    saveAs(
-      new Blob(
-        [JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")],
-        {
-          type: "text/plain;charset=utf-8",
-        }
-      ),
-      `${data.name || "le5le.meta2d"}.json`
-    );
-  });
-};
-
-const noLoginTip = "请先登录,否则无法保存!";
-const downloadZip = async () => {
-  if (!(user && user.username)) {
-    MessagePlugin.warning(noLoginTip);
-    return;
-  }
-
-  if (!user.vipExpired) {
-    gotoAccount();
-    return;
-  }
-
-  MessagePlugin.info("正在下载打包中,可能需要几分钟,请耐心等待...");
-  const [{ default: JSZip }, { saveAs }] = await Promise.all([
-    import("jszip"),
-    import("file-saver"),
-  ]);
-
-  const zip: any = new JSZip();
-  const data: Meta2dBackData = meta2d.data();
-  let _fileName =
-    (data.name && data.name.replace(/\//g, "_").replace(/:/g, "_")) ||
-    "le5le.meta2d";
-  const _zip = zip.folder(`${_fileName}`);
-  if (data._id) delete data._id;
-  checkData(data);
-  _zip.file(
-    `${_fileName}.json`,
-    JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")
-  );
-  await zipImages(_zip, meta2d.store.data.pens);
-
-  const blob = await zip.generateAsync({ type: "blob" });
-  saveAs(blob, `${_fileName}.zip`);
-};
-
-const downloadHtml = async () => {
-  if (!(user && user.username)) {
-    MessagePlugin.warning(noLoginTip);
-    return;
-  }
-
-  if (!user.vipExpired) {
-    gotoAccount();
-    return;
-  }
-
-  MessagePlugin.info("正在下载打包中,可能需要几分钟,请耐心等待...");
-
-  const data: Meta2dBackData = meta2d.data();
-  if (data._id) delete data._id;
-  checkData(data);
-  const [{ default: JSZip }, { saveAs }] = await Promise.all([
-    import("jszip"),
-    import("file-saver"),
-  ]);
-  const zip = new JSZip();
-  let _fileName =
-    (data.name && data.name.replace(/\//g, "_").replace(/:/g, "_")) ||
-    "le5le.meta2d";
-
-  //处理cdn图片地址
-  const _zip: any = zip.folder(`${_fileName}`);
-  _zip.file(
-    "data.json",
-    JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")
-  );
-  await Promise.all([zipImages(_zip, meta2d.store.data.pens), zipFiles(_zip)]);
-  const blob = await zip.generateAsync({ type: "blob" });
-  saveAs(blob, `${_fileName}.zip`);
-};
-
-enum Frame {
-  vue2,
-  vue3,
-  react,
-}
-
-const downloadVue3 = async () => {
-  downloadAsFrame(Frame.vue3);
-};
-
-const downloadVue2 = async () => {
-  downloadAsFrame(Frame.vue2);
-};
-
-const downloadReact = async () => {
-  downloadAsFrame(Frame.react);
-};
-
-async function downloadAsFrame(type: Frame) {
-  if (!(user && user.username)) {
-    MessagePlugin.warning(noLoginTip);
-    return;
+
+  MessagePlugin.info("正在下载打包中,可能需要几分钟,请耐心等待...");
+
+  const data: Meta2dBackData = meta2d.data();
+  if (data._id) delete data._id;
+  checkData(data);
+  const [{ default: JSZip }, { saveAs }] = await Promise.all([
+    import("jszip"),
+    import("file-saver"),
+  ]);
+  const zip = new JSZip();
+  let _fileName =
+    (data.name && data.name.replace(/\//g, "_").replace(/:/g, "_")) ||
+    "le5le.meta2d";
+
+  //处理cdn图片地址
+  const _zip: any = zip.folder(`${_fileName}`);
+  _zip.file(
+    "data.json",
+    JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")
+  );
+  await Promise.all([zipImages(_zip, meta2d.store.data.pens), zipFiles(_zip)]);
+  const blob = await zip.generateAsync({ type: "blob" });
+  saveAs(blob, `${_fileName}.zip`);
+};
+
+enum Frame {
+  vue2,
+  vue3,
+  react,
+}
+
+const downloadVue3 = async () => {
+  downloadAsFrame(Frame.vue3);
+};
+
+const downloadVue2 = async () => {
+  downloadAsFrame(Frame.vue2);
+};
+
+const downloadReact = async () => {
+  downloadAsFrame(Frame.react);
+};
+
+async function downloadAsFrame(type: Frame) {
+  if (!(user && user.username)) {
+    MessagePlugin.warning(noLoginTip);
+    return;
   }
 
   if (!user.vipExpired) {
@@ -1309,6 +1022,297 @@ const helpList = [
   },
 ];
 </script>
+<script lang="ts">
+// import { noLoginTip } from "@/services/utils";
+
+const { user } = useUser();
+const route = useRoute();
+const router = useRouter();
+const { dot ,setDot} = useDot();
+
+enum SaveType {
+  Save,
+  SaveAs,
+}
+export const save = async (type: SaveType = SaveType.Save, component?: boolean) => {
+  meta2d.stopAnimate();
+  const data: Meta2dBackData = meta2d.data();
+  if (!(user && user.username)) {
+    MessagePlugin.warning(noLoginTip);
+    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(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;
+    (meta2d.store.data as Meta2dBackData).image = data.image;
+  }
+
+  if (component) {
+    data.component = true;
+    // pens 存储原数据用于二次编辑 ; componentDatas 组合后的数据,用于复用
+    data.componentDatas = meta2d.toComponent(
+      undefined,
+      (meta2d.store.data as Meta2dBackData).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()}`;
+    (meta2d.store.data as Meta2dBackData).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;
+    (meta2d.store.data as Meta2dBackData)._id = data._id;
+    router.replace({
+      path: "/",
+      query: {
+        id: data._id,
+        r: Date.now() + "",
+        component: data.component + "",
+      },
+    });
+  }
+
+  MessagePlugin.success("保存成功!");
+  // 保存成功,重新请求文件夹
+  meta2d.emit("t-save-success", true);
+  // 已保存,不再是新的,无需提示保存
+  setDot(false);
+  localforage.removeItem(localMeta2dDataName);
+};
+const pen = ref(false);
+const drawPen = () => {
+  meta2d.inactive();
+  try {
+    if (!meta2d.canvas.drawingLineName) {
+      // 开了钢笔,需要关掉铅笔
+      meta2d.canvas.pencil && drawingPencil();
+      meta2d.drawLine(meta2d.store.options.drawingLineName);
+    } else {
+      meta2d.finishDrawLine();
+      meta2d.drawLine();
+    }
+    //钢笔
+    pen.value = !!meta2d.canvas.drawingLineName;
+  } catch (e: any) {
+    MessagePlugin.warning(e.message);
+  }
+};
+
+const pencil = ref(false);
+const drawingPencil = () => {
+  try {
+    if (!meta2d.canvas.pencil) {
+      // 开了铅笔需要关掉钢笔
+      meta2d.canvas.drawingLineName && drawPen();
+      meta2d.drawingPencil();
+    } else {
+      meta2d.stopPencil();
+    }
+    pencil.value = meta2d.canvas.pencil || false;
+  } catch (e: any) {
+    MessagePlugin.warning(e.message);
+  }
+};
+
+const magnifier = ref(false);
+const showMagnifier = () => {
+  if (!meta2d.canvas.magnifierCanvas.magnifier) {
+    meta2d.showMagnifier();
+  } else {
+    meta2d.hideMagnifier();
+  }
+  magnifier.value = meta2d.canvas.magnifierCanvas.magnifier;
+};
+
+const map = ref(false);
+const showMap = () => {
+  if (!meta2d.map?.isShow) {
+    meta2d.showMap();
+  } else {
+    meta2d.hideMap();
+  }
+  map.value = meta2d.map?.isShow;
+};
+
+const title = "系统可能不会保存您所做的更改,是否继续?";
+export const newFile = async () => {
+  if (dot.value) {
+    if (await showNotification(title)) {
+      newfile(false);
+    }
+  } else {
+    newfile(false);
+  }
+};
+
+async function newfile(noRouter: boolean = false) {
+  meta2d.canvas.drawingLineName && drawPen();
+  meta2d.canvas.pencil && drawingPencil();
+  meta2d.canvas.magnifierCanvas.magnifier && showMagnifier();
+  meta2d.map?.isShow && showMap();
+  setDot(false);
+  // await localforage.removeItem(localMeta2dDataName);
+  // 打开文件操作不跳转
+  !noRouter &&
+    router.replace({
+      path: "/",
+      query: { r: Date.now() + "" },
+    });
+}
+</script>
 <style lang="postcss" scoped>
 .app-header {
   display: flex;

+ 4 - 1
src/views/components/View.vue

@@ -5,7 +5,7 @@
         <a><t-icon name="add" @click="newFile" /></a>
       </t-tooltip>
       <t-tooltip content="保存" placement="bottom">
-        <a> <t-icon name="save" @click="save(SaveType.Save)" /></a>
+        <a> <t-badge dot :showZero="false" :count="dot?1:0"> <t-icon name="save" @click="save(SaveType.Save)" /></t-badge></a>
       </t-tooltip>
       <t-tooltip content="保存为模板" placement="bottom">
         <a><t-icon name="layers" @click="save(SaveType.Save,true)" /></a>
@@ -106,10 +106,13 @@ import { registerBasicDiagram } from "@/services/register";
 import { useRouter, useRoute } from "vue-router";
 import { useUser } from "@/services/user";
 import { getLe5le2d } from "@/services/api";
+import { useDot } from "@/services/common";
+import { save , newFile} from "./Header.vue";
 
 const router = useRouter();
 const route = useRoute();
 const { user, message, getUser, getMessage, signout } = useUser();
+const { dot,setDot,getDot} = useDot();
 
 const meta2dOptions: Options = {
   cdn: "https://assets.le5lecdn.com",