Alsmile 2 years ago
parent
commit
a6f7fa3796

+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "jszip": "^3.10.0",
     "localforage": "^1.10.0",
     "monaco-editor": "^0.38.0",
+    "qrcode": "^1.5.3",
     "tdesign-vue-next": "^1.3.4",
     "vue": "^3.3.2",
     "vue-router": "^4.2.0"

File diff suppressed because it is too large
+ 213 - 175
pnpm-lock.yaml


+ 11 - 14
src/services/api.ts

@@ -1,17 +1,17 @@
 //所有的接口请求
-import axios from "axios";
-export const cdn = "";
+import axios from 'axios';
+export const cdn = '';
 // import.meta.env.VITE_ROUTER_BASE
 // ? ""
 // : "https://assets.le5lecdn.com";
 
 export const upCdn = import.meta.env.VITE_ROUTER_BASE
-  ? ""
-  : "https://drive.le5lecdn.com";
+  ? ''
+  : 'https://drive.le5lecdn.com';
 
 export async function delImage(image: string) {
   if (image.startsWith(upCdn)) {
-    await axios.delete("/file" + image.replace(upCdn, ""));
+    await axios.delete('/file' + image.replace(upCdn, ''));
   } else {
     await axios.delete(`${image}`);
   }
@@ -19,7 +19,7 @@ export async function delImage(image: string) {
 }
 
 export async function getFolders(query: any) {
-  const folder: any = await axios.post("/api/data/folders/get", {
+  const folder: any = await axios.post('/api/data/folders/get', {
     query,
   });
   if (folder.error) {
@@ -30,7 +30,7 @@ export async function getFolders(query: any) {
 }
 
 export async function updateFolders(data: any) {
-  const folder: any = await axios.post("/api/data/folders/update", data);
+  const folder: any = await axios.post('/api/data/folders/update', data);
   if (folder.error) {
     return;
   } else {
@@ -39,18 +39,15 @@ export async function updateFolders(data: any) {
 }
 
 export async function addCollection(collection: string, data: any) {
-  return await axios.post(`/api/data/${collection}/add`, data); // 新增
+  return await axios.post(`/api/data/${collection}/add`, data);
 }
 
 export async function updateCollection(collection: string, data: any) {
-  return await axios.post(`/api/data/${collection}/update`, data); // 新增
+  return await axios.post(`/api/data/${collection}/update`, data);
 }
 
-// export async function addCollection(collection: string, data: any) {
-//   return await axios.post(`/data/${collection}/add`, data); // 新增
-// }
 export async function getLe5le2d(id: string) {
-  return await axios.post("/api/data/le5le2d/get", {
+  return await axios.post('/api/data/le5le2d/get', {
     id,
   });
 }
@@ -62,5 +59,5 @@ export async function getComponents(id: string) {
 }
 
 export async function getComponentsList(data: any, config: any) {
-  return await axios.post("/api/data/le5le2d-components/list", data, config);
+  return await axios.post('/api/data/le5le2d-components/list', data, config);
 }

+ 9 - 22
src/services/common.ts

@@ -4,7 +4,7 @@ import { useUser } from '@/services/user';
 import { showNotification, Meta2dBackData, checkData } from '@/services/utils';
 import { MessagePlugin } from 'tdesign-vue-next';
 import localforage from 'localforage';
-import { noLoginTip, localMeta2dDataName } from '@/services/utils';
+import { noLoginTip, localStorageName } from '@/services/utils';
 import { upload, dataURLtoBlob } from '@/services/file';
 import { delImage, addCollection, updateCollection } from '@/services/api';
 import { baseVer } from '@/services/upgrade';
@@ -47,7 +47,7 @@ export const save = async (
   const data: Meta2dBackData = meta2d.data();
   if (!(user && user.id)) {
     MessagePlugin.warning(noLoginTip);
-    localforage.setItem(localMeta2dDataName, JSON.stringify(data));
+    localforage.setItem(localStorageName, JSON.stringify(data));
     return;
   }
   checkData(data);
@@ -157,7 +157,7 @@ export const save = async (
     for (const k of delAttrs) {
       delete (data as any)[k];
     }
-    ret = addCollection(collection, data); // 新增
+    ret = await addCollection(collection, data);
     /*
     if (!data.component) {
       list.push({
@@ -171,9 +171,9 @@ export const save = async (
     if (data._id && data.teams && data.owner?.id !== user.id) {
       // 团队图纸 不允许修改文件夹信息
       delete data.folder;
-      ret = updateCollection(collection, data);
+      ret = await updateCollection(collection, data);
     } else if (data._id) {
-      ret = updateCollection(collection, data);
+      ret = await updateCollection(collection, data);
       /*
       if (!data.component) {
         list.forEach((i: any) => {
@@ -193,7 +193,7 @@ export const save = async (
         });
       }*/
     } else {
-      ret = addCollection(collection, data); // 新增
+      ret = await addCollection(collection, data); // 新增
       /*
       if (!data.component) {
         list.push({
@@ -207,21 +207,9 @@ export const save = async (
   }
 
   if (ret.error) {
-    return null;
+    return;
   }
 
-  /*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));
@@ -249,7 +237,7 @@ export const save = async (
   // 已保存,不再是新的,无需提示保存
   // setDot(false);
   dot.value = false;
-  localforage.removeItem(localMeta2dDataName);
+  localforage.removeItem(localStorageName);
   return true;
 };
 const pen = ref(false);
@@ -382,9 +370,8 @@ export const newfile = async (noRouter: boolean = false) => {
   meta2d.canvas.pencil && drawingPencil();
   meta2d.canvas.magnifierCanvas.magnifier && showMagnifier();
   meta2d.map?.isShow && showMap();
-  // setDot(false);
   dot.value = false;
-  await localforage.removeItem(localMeta2dDataName);
+  await localforage.removeItem(localStorageName);
   // 打开文件操作不跳转
   // const router = useRouter();
   !noRouter &&

+ 2 - 4
src/services/utils.ts

@@ -1,12 +1,10 @@
-import { FormItem, Pen, Meta2d, Meta2dData } from '@meta2d/core';
+import { Pen, Meta2dData } from '@meta2d/core';
 import { MessagePlugin, NotifyPlugin, Button } from 'tdesign-vue-next';
 import { h, ref } from 'vue';
-import { cdn } from './api';
-
 const market = import.meta.env.VITE_MARKET;
 
 export const noLoginTip = '请先登录,否则无法保存!';
-export const localMeta2dDataName = 'meta2dData';
+export const localStorageName = 'le5le2d';
 
 export interface Meta2dBackData extends Meta2dData {
   id?: string;

+ 4 - 0
src/styles/app.css

@@ -340,6 +340,10 @@ a.hover:hover {
   padding-bottom: 12px;
 }
 
+.p-12 {
+  padding: 12px;
+}
+
 .pb-16 {
   padding-bottom: 16px;
 }

+ 8 - 7
src/views/Preview.vue

@@ -7,7 +7,7 @@
 <script setup lang="ts">
 import { ref, onMounted, watch, onUnmounted } from 'vue';
 import localforage from 'localforage';
-import { localMeta2dDataName } from '@/services/utils';
+import { localStorageName } from '@/services/utils';
 import { defaultFormat } from '@/services/defaults';
 import { useRouter, useRoute } from 'vue-router';
 import { Meta2d, Options, Pen } from '@meta2d/core';
@@ -19,13 +19,12 @@ const meta2dDom = ref('');
 
 const meta2dOptions: Options = {
   cdn,
-  //   rule: true,
   background: '#1e2430',
   x: 10,
   y: 10,
   width: 1920,
   height: 1080,
-  //   defaultFormat: { ...defaultFormat },
+  defaultFormat: { ...defaultFormat },
 };
 
 onMounted(() => {
@@ -47,10 +46,12 @@ const open = async () => {
     const ret: any = getLe5le2d(route.query.id + '');
     ret && meta2d.open(ret);
   } else {
-    const data: any = JSON.parse(
-      await localforage.getItem(localMeta2dDataName)
-    );
-    data && meta2d.open(data);
+    let data: any = await localforage.getItem(localStorageName);
+    if (data) {
+      data = JSON.parse(data);
+      data.locked = 1;
+      meta2d.open(data);
+    }
   }
 };
 

+ 6 - 6
src/views/components/FileProps.vue

@@ -113,17 +113,17 @@
                   <div class="form-item">
                     <label>水平对齐</label>
                     <t-radio-group class="ml-8" default-value="2">
-                      <t-radio value="1">左对齐</t-radio>
-                      <t-radio value="2">居中</t-radio>
-                      <t-radio value="3">右对齐</t-radio>
+                      <t-radio value="1" style="width: 200px">左对齐</t-radio>
+                      <t-radio value="2" style="width: 200px">居中</t-radio>
+                      <t-radio value="3" style="width: 200px">右对齐</t-radio>
                     </t-radio-group>
                   </div>
                   <div class="form-item">
                     <label>垂直对齐</label>
                     <t-radio-group class="ml-8" default-value="2">
-                      <t-radio value="1">顶部对齐</t-radio>
-                      <t-radio value="2">居中</t-radio>
-                      <t-radio value="3">底部对齐</t-radio>
+                      <t-radio value="1" style="width: 200px">顶部对齐</t-radio>
+                      <t-radio value="2" style="width: 200px">居中</t-radio>
+                      <t-radio value="3" style="width: 200px">底部对齐</t-radio>
                     </t-radio-group>
                   </div>
                 </template>

+ 11 - 21
src/views/components/Header.vue

@@ -220,7 +220,7 @@
         </t-dropdown-item>
       </t-dropdown-menu>
     </t-dropdown>
-    <input v-model="data.name" @input="inputMeta2dName" />
+    <input v-model="data.name" @input="onInputName" />
 
     <div style="width: 290px; flex-shrink: 0"></div>
     <t-dropdown
@@ -268,35 +268,25 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, ref, onMounted, onUnmounted, nextTick } from 'vue';
+import { reactive, ref, onUnmounted, nextTick } from 'vue';
 import { useRouter, useRoute } from 'vue-router';
 import { useUser } from '@/services/user';
-import { NotifyPlugin, MessagePlugin } from 'tdesign-vue-next';
+import { MessagePlugin } from 'tdesign-vue-next';
 import {
-  showNotification,
   Meta2dBackData,
   dealwithFormatbeforeOpen,
   gotoAccount,
   checkData,
 } from '@/services/utils';
-import { readFile, upload, dataURLtoBlob } from '@/services/file';
+import { readFile } from '@/services/file';
 import { compareVersion, baseVer, upgrade } from '@/services/upgrade';
 import { parseSvg } from '@meta2d/svg';
-import { Pen, Rect, getGlobalColor, isShowChild } from '@meta2d/core';
-import localforage from 'localforage';
-import {
-  delImage,
-  getFolders,
-  addCollection,
-  updateCollection,
-  updateFolders,
-  cdn,
-  upCdn,
-} from '@/services/api';
+import { Pen, getGlobalColor, isShowChild } from '@meta2d/core';
+import { cdn, upCdn } from '@/services/api';
 import JSZip from 'jszip';
 import axios from 'axios';
 import { switchTheme } from '@/services/theme';
-import { noLoginTip, localMeta2dDataName } from '@/services/utils';
+import { noLoginTip } from '@/services/utils';
 import { useDot, notificFn } from '@/services/common';
 import {
   save,
@@ -316,17 +306,17 @@ import {
 const router = useRouter();
 const route = useRoute();
 
-const market = import.meta.env.VITE_MARKET;
 const baseUrl = import.meta.env.BASE_URL || '/';
 
-const { user, message, getUser, getMessage, signout } = useUser();
-const { dot } = useDot();
+const { user, signout } = useUser();
+const { setDot } = useDot();
 const data = reactive({
   name: '空白文件',
 });
 
-const inputMeta2dName = () => {
+const onInputName = () => {
   (meta2d.store.data as Meta2dBackData).name = data.name;
+  setDot(true);
 };
 
 const initMeta2dName = () => {

+ 2 - 2
src/views/components/Network.vue

@@ -128,12 +128,12 @@ import { debounce } from '@/services/debouce';
 
 const { modelValue, mode } = defineProps<{
   modelValue: any;
-  mode: any;
+  mode?: any;
 }>();
 
 const emit = defineEmits(['update:modelValue', 'change']);
 
-const popupVisible = ref<bool>(false);
+const popupVisible = ref<boolean>(false);
 const networkList = ref<any[]>([]);
 
 onBeforeMount(() => {});

+ 101 - 76
src/views/components/View.vue

@@ -103,7 +103,6 @@
           </svg>
         </a>
       </t-tooltip>
-      <!-- <t-tooltip content="连线" placement="top"> -->
       <t-dropdown
         :minColumnWidth="200"
         :maxHeight="560"
@@ -123,7 +122,6 @@
           <t-dropdown-item v-for="item in lineTypes">
             <div class="flex middle" @click="changeLineType(item.value)">
               {{ item.name }} <span class="flex-grow"></span>
-              <!-- <t-icon v-show="item.value === currentLineType" name="check" /> -->
               <svg class="l-icon" aria-hidden="true">
                 <use :xlink:href="item.icon"></use>
               </svg>
@@ -223,13 +221,20 @@
       <t-tooltip content="运行(查看)" placement="bottom">
         <a @click="preview"><t-icon name="caret-right" /></a>
       </t-tooltip>
-
-      <t-tooltip content="手机查看" placement="bottom">
-        <a><t-icon name="qrcode" /></a>
-      </t-tooltip>
       <t-tooltip content="分享" placement="bottom">
-        <a><t-icon name="share" /></a>
+        <a @click="share">
+          <t-icon name="share" :class="{ primary: shared }" />
+        </a>
       </t-tooltip>
+      <t-popup placement="bottom" trigger="click" v-model="qrcode.visible">
+        <a @mouseenter="qrcode.visible = true"><t-icon name="qrcode" /></a>
+        <template #content>
+          <div style="padding: 12px 12px 6px 12px">
+            <img :src="qrcode.url" />
+          </div>
+        </template>
+      </t-popup>
+
       <t-tooltip content="发布" placement="bottom">
         <a><t-icon name="cloud" /></a>
       </t-tooltip>
@@ -424,18 +429,16 @@ import {
   Options,
   Pen,
   deepClone,
-  LockState,
   PenType,
   HoverType,
 } from '@meta2d/core';
 import localforage from 'localforage';
 import dayjs from 'dayjs';
-import axios from 'axios';
-import { MessagePlugin } from 'tdesign-vue-next';
+import QRCode from 'qrcode';
 
 import { registerBasicDiagram } from '@/services/register';
 import { useUser } from '@/services/user';
-import { cdn, getLe5le2d } from '@/services/api';
+import { cdn, getLe5le2d, updateCollection } from '@/services/api';
 import {
   save,
   newFile,
@@ -444,23 +447,20 @@ import {
   onScaleWindow,
   useDot,
 } from '@/services/common';
-import { useSelection, SelectionMode } from '@/services/selections';
+import { useSelection } from '@/services/selections';
 import { defaultFormat } from '@/services/defaults';
-import {
-  checkData,
-  localMeta2dDataName,
-  Meta2dBackData,
-} from '@/services/utils';
+import { checkData, localStorageName, Meta2dBackData } from '@/services/utils';
 import { debounce } from '@/services/debouce';
 import { importExcel } from '@/services/excel';
 
 import ContextMenu from './ContextMenu.vue';
 import Network from './Network.vue';
+import { MessagePlugin } from 'tdesign-vue-next';
 
 const router = useRouter();
 const route = useRoute();
-const { user, message, getUser, getMessage, signout } = useUser();
-const { dot, setDot, getDot } = useDot();
+const { user } = useUser();
+const { dot, setDot } = useDot();
 const { select } = useSelection();
 
 const meta2dOptions: Options = {
@@ -475,6 +475,15 @@ const meta2dOptions: Options = {
   disableAnchor: true,
   defaultFormat: { ...defaultFormat },
 };
+
+let timer: any = 0;
+
+const shared = ref<boolean>(false);
+const qrcode = reactive({
+  visible: false,
+  url: '',
+});
+
 onMounted(() => {
   meta2d = new Meta2d('meta2d', meta2dOptions);
   registerBasicDiagram();
@@ -489,18 +498,42 @@ onMounted(() => {
   meta2d.on('add', lineAdd);
   meta2d.on('opened', openedListener);
 
-  meta2d.on('undo', autoSave);
-  meta2d.on('redo', autoSave);
-  meta2d.on('add', autoSave);
-  meta2d.on('delete', autoSave);
-  meta2d.on('rotatePens', autoSave);
-  meta2d.on('translatePens', autoSave);
+  meta2d.on('undo', patchFlag);
+  meta2d.on('redo', patchFlag);
+  meta2d.on('add', patchFlag);
+  meta2d.on('delete', patchFlag);
+  meta2d.on('rotatePens', patchFlag);
+  meta2d.on('translatePens', patchFlag);
 
   // 所有编辑栏所做修改
-  meta2d.on('components-update-value', autoSave);
+  meta2d.on('components-update-value', patchFlag);
   // @ts-ignore
   meta2d.on('contextmenu', contextmenu);
   meta2d.on('click', canvasClick);
+
+  timer = setInterval(() => {
+    // 没有更新,不用保存
+    if (!dot.value) {
+      return;
+    }
+
+    const data: any = meta2d.data();
+
+    if (
+      user &&
+      user.id &&
+      !user.vipExpired &&
+      data._id &&
+      !data.component &&
+      data.owner &&
+      data.owner.id === user.id
+    ) {
+      save(SaveType.Save);
+    } else {
+      data.updateAt = dayjs().format();
+      localforage.setItem(localStorageName, JSON.stringify(data));
+    }
+  }, 60000);
 });
 
 const watcher = watch(
@@ -512,10 +545,21 @@ const watcher = watch(
 
 const open = async () => {
   if (route.query.id) {
-    const ret: any = getLe5le2d(route.query.id + '');
-    ret && meta2d.open(ret);
+    const ret: any = await getLe5le2d(route.query.id + '');
+    if (ret) {
+      meta2d.open(ret);
+      shared.value = ret.shared;
+
+      const qr: any = await QRCode.toDataURL(
+        `https://view2d.le5le.com/?id=${route.query.id + ''}`
+      );
+      qrcode.url = qr;
+    }
   } else {
-    meta2d.open();
+    const data: string = await localforage.getItem(localStorageName);
+    if (data) {
+      meta2d.open(JSON.parse(data));
+    }
   }
   meta2d.store.data.x = meta2d.store.options.x || 0;
   meta2d.store.data.y = meta2d.store.options.y || 0;
@@ -534,7 +578,12 @@ const openedListener = () => {
   toArrow.value = canvasToArrow || '';
 };
 
+const patchFlag = () => {
+  setDot(true);
+};
+
 onUnmounted(() => {
+  clearInterval(timer);
   watcher();
   if (meta2d) {
     // @ts-ignore
@@ -547,13 +596,13 @@ onUnmounted(() => {
     meta2d.off('add', lineAdd);
     meta2d.on('opened', openedListener);
 
-    meta2d.off('undo', autoSave);
-    meta2d.off('redo', autoSave);
-    meta2d.off('add', autoSave);
-    meta2d.off('delete', autoSave);
-    meta2d.off('rotatePens', autoSave);
-    meta2d.off('translatePens', autoSave);
-    meta2d.off('components-update-value', autoSave);
+    meta2d.off('undo', patchFlag);
+    meta2d.off('redo', patchFlag);
+    meta2d.off('add', patchFlag);
+    meta2d.off('delete', patchFlag);
+    meta2d.off('rotatePens', patchFlag);
+    meta2d.off('translatePens', patchFlag);
+    meta2d.off('components-update-value', patchFlag);
     // @ts-ignore
     meta2d.off('contextmenu', contextmenu);
     meta2d.off('click', canvasClick);
@@ -562,45 +611,6 @@ onUnmounted(() => {
   }
 });
 
-let localSaveTimer: any = 0;
-let saveTimer: any = 0;
-const autoSave = () => {
-  setDot(true);
-  localSaveTimer && clearTimeout(localSaveTimer);
-  localSaveTimer = setTimeout(() => {
-    const data: Meta2dBackData = meta2d.data();
-    let _localMeta2dDataName = data._id
-      ? localMeta2dDataName + '-' + data._id
-      : localMeta2dDataName;
-    (data as any).localSaveAt = dayjs().format();
-    localforage.setItem(_localMeta2dDataName, JSON.stringify(data));
-    localSaveTimer = undefined;
-  }, 3000);
-  autoSaveServer();
-};
-//运行 在新标签页查看
-function autoSaveServer() {
-  //会员享受自动保存
-  if (saveTimer) {
-    return;
-  }
-  saveTimer = setTimeout(() => {
-    const data: Meta2dBackData = meta2d.data();
-    if (
-      user &&
-      user.id &&
-      user.vipExpired &&
-      data._id &&
-      !data.component &&
-      data.owner &&
-      data.owner?.id === user.id
-    ) {
-      save(SaveType.Save);
-    }
-    saveTimer = null;
-  }, 60000);
-}
-
 const inactive = () => {
   select();
 };
@@ -834,7 +844,7 @@ const preview = async () => {
     await save(SaveType.Save);
   }
   if (!data._id) {
-    await localforage.setItem(localMeta2dDataName, JSON.stringify(data));
+    await localforage.setItem(localStorageName, JSON.stringify(data));
   }
   router.push({
     path: '/preview',
@@ -1017,6 +1027,21 @@ const importDataset = async () => {
   console.log('data', data);
   dataDialog.dataset = data;
 };
+
+const share = async () => {
+  if (!route.query.id) {
+    MessagePlugin.error('请先保存!');
+    return;
+  }
+
+  const ret: any = await updateCollection('le5le2d', {
+    _id: route.query.id,
+    shared: !shared.value,
+  });
+  if (ret) {
+    shared.value = ret.shared;
+  }
+};
 </script>
 <style lang="postcss" scoped>
 .meta2d {

Some files were not shown because too many files changed in this diff