Bladeren bron

feat:方案/模版

ananzhusen 1 jaar geleden
bovenliggende
commit
50cb0108a5

+ 6 - 6
public/view/vue3/Meta2d.vue

@@ -9,7 +9,7 @@ import { onMounted, onUnmounted } from 'vue';
 let meta2d: any = null;
 
 onMounted(async () => {
-  meta2d = new (window as any).Meta2d('meta2d',{
+  meta2d = new (window as any).Meta2d('meta2d', {
     background: '#1e2430',
     x: 10,
     y: 10,
@@ -24,11 +24,11 @@ onMounted(async () => {
     data.locked = 1;
     meta2d.open(data);
     let fit =
-        meta2d.store.data.scaleMode === '3'
-            ? 'height'
-            : meta2d.store.data.scaleMode === '2'
-                ? 'width'
-                : true;
+      meta2d.store.data.scaleMode === '3'
+        ? 'height'
+        : meta2d.store.data.scaleMode === '2'
+        ? 'width'
+        : true;
     meta2d.fitSizeView(fit, 10);
   });
 });

+ 4 - 3
src/services/api.ts

@@ -6,10 +6,11 @@ const isProd =
 
 export const cdn = isProd ? 'https://assets.le5lecdn.com' : '';
 export const upCdn = isProd ? 'https://drive.le5lecdn.com' : '';
-
+const imageDrive = 'https://drive.le5lecdn.com';
+//https://v.le5le.com/file/2023/0828/1/1/thumb.07c0a78f.png
 export async function delImage(image: string) {
-  if (image.startsWith(upCdn)) {
-    await axios.delete('/file' + image.replace(upCdn, ''));
+  if (image.startsWith(upCdn) || image.startsWith(imageDrive)) {
+    await axios.delete('/file' + image.replace(upCdn || imageDrive, ''));
   } else {
     await axios.delete(`${image}`);
   }

+ 94 - 26
src/services/common.ts

@@ -96,11 +96,26 @@ export enum SaveType {
   Save,
   SaveAs,
 }
+
+let saveTimer: any = 0;
+let saveFlag: boolean = true;
+
 export const save = async (
   type: SaveType = SaveType.Save,
   vType?: string,
   notice?: boolean
 ) => {
+  if (saveTimer) {
+    clearTimeout(saveTimer);
+  }
+  if (!saveFlag) {
+    return;
+  }
+  saveFlag = false;
+  saveTimer = setTimeout(() => {
+    saveFlag = true;
+  }, 1000);
+
   meta2d.stopAnimate();
   const data: Meta2dBackData = meta2d.data();
   if (!(user && user.id)) {
@@ -108,16 +123,12 @@ export const save = async (
     localforage.setItem(localStorageName, JSON.stringify(data));
     return;
   }
-  let componentActive = false;
   if (
-    vType === 'component' &&
+    vType === 'le5leV-components' &&
     meta2d.store.active &&
     meta2d.store.active.length === 1 &&
     meta2d.store.active[0].name === 'combine'
   ) {
-    componentActive = true;
-  }
-  if (componentActive) {
     let comData: any = {
       center: data.center,
       folder: '',
@@ -160,21 +171,39 @@ export const save = async (
     MessagePlugin.success('成功保存为组件!');
     return;
   }
-  checkData(data);
-  if (!data._id && router.currentRoute.value.query.id) {
-    data._id = router.currentRoute.value.query.id as string;
-  }
 
+  checkData(data);
+  // if (!data._id && router.currentRoute.value.query.id) {
+  //   data._id = router.currentRoute.value.query.id as string;
+  // }
   if (
     (globalThis as any).beforeSaveMeta2d &&
     !(await (globalThis as any).beforeSaveMeta2d(data))
   ) {
     return;
   }
+  if (vType === 'le5leV-template') {
+    if (data.tags && !data.tags.includes('模板')) {
+      delete data._id;
+      delete data.id;
+      delete data.folder;
+    }
+    data.tags = ['模板'];
+  } else if (!vType) {
+    if (data.tags && !data.tags.includes('方案')) {
+      delete data._id;
+      delete data.id;
+      delete data.folder;
+    }
+    data.tags = ['方案'];
+  }
   if (type === SaveType.SaveAs) {
     //另存为去掉teams信息
     delete data.teams;
+    delete data.folder;
+    delete data.id;
   }
+
   //如果不是自己创建的团队图纸,就不去修改缩略图(没有权限去删除缩略图)
   if (!(data.teams && data.owner?.id !== user.id)) {
     let blob: Blob;
@@ -202,7 +231,7 @@ export const save = async (
     (meta2d.store.data as Meta2dBackData).image = data.image;
   }
 
-  if (data.component || vType === 'component') {
+  if (data.component || vType === 'le5leV-components') {
     data.component = true;
     // pens 存储原数据用于二次编辑 ; componentDatas 组合后的数据,用于复用
     data.componentDatas = meta2d.toComponent(
@@ -221,9 +250,35 @@ export const save = async (
     (meta2d.store.data as Meta2dBackData).name = data.name;
   }
   !data.version && (data.version = baseVer);
+  // TODO
   if (!data.folder) {
-    data.folder = folder.name;
+    data.folder = ''; // folder.name;
   }
+
+  let _list: any = undefined;
+  let _folderId: any = undefined;
+  if (data.folder) {
+    if (!folder._id) {
+      let type = vType;
+      if (!type) {
+        type = 'le5leV';
+      }
+      let folderRet: any = await axios.post('/api/data/folders/get', {
+        query: {
+          type,
+          name: data.folder,
+        },
+      });
+      if (!folderRet.error) {
+        _list = folderRet.list;
+        _folderId = folderRet._id;
+      }
+    } else {
+      _list = folder.list;
+      _folderId = folder._id;
+    }
+  }
+
   let _temType = '';
   if (type === SaveType.SaveAs) {
     // 另存为一定走 新增 ,由于后端 未控制 userId 等属性,清空一下
@@ -232,12 +287,14 @@ export const save = async (
     }
     ret = await addCollection(collection, data);
   } else {
-    if (data._id && data.teams && data.owner?.id !== user.id) {
-      // 团队图纸 不允许修改文件夹信息
-      delete data.folder;
-      ret = await updateCollection(collection, data);
-    } else if (data._id) {
+    // if (data._id && data.teams && data.owner?.id !== user.id) {
+    //   // 团队图纸 不允许修改文件夹信息
+    //   delete data.folder;
+    //   ret = await updateCollection(collection, data);
+    // } else
+    if (data._id) {
       ret = await updateCollection(collection, data);
+      _temType = 'update';
     } else {
       ret = await addCollection(collection, data); // 新增
       _temType = 'add';
@@ -247,19 +304,26 @@ export const save = async (
   if (ret.error) {
     return;
   }
-  if (_temType === 'add') {
-    //文件夹
-    if (folder._id) {
-      folder.list.push({
+  if (_folderId) {
+    if (_temType === 'add') {
+      //文件夹
+      _list.push({
         image: data.image,
         name: data.name,
         _id: ret._id,
       });
-      await axios.post('/api/data/folders/update', {
-        _id: folder._id,
-        list: folder.list,
+    } else if (_temType === 'update') {
+      _list.forEach((i: any) => {
+        if (i._id === data._id) {
+          i.image = data.image;
+          i.name = data.name;
+        }
       });
     }
+    await axios.post('/api/data/folders/update', {
+      _id: _folderId,
+      list: _list,
+    });
   }
   //  保存图纸之后的钩子函数
   globalThis.afterSaveMeta2d && (await globalThis.afterSaveMeta2d(ret));
@@ -360,7 +424,11 @@ export function autoSave(force = false) {
     data.owner &&
     data.owner.id === user.id
   ) {
-    save(SaveType.Save);
+    let _vType = '';
+    if (data.tags.includes('模板')) {
+      _vType = 'le5leV-template';
+    }
+    save(SaveType.Save, _vType);
   } else {
     data.updateAt = dayjs().format();
     localforage.setItem(localStorageName, JSON.stringify(data));
@@ -581,14 +649,14 @@ let folder = reactive<any>({
 
 export const useFolder = () => {
   const getFolder = async () => {
-    return dot;
+    return folder;
   };
   const setFolder = async (value: any) => {
     folder = deepClone(value);
   };
 
   return {
-    dot,
+    folder,
     getFolder,
     setFolder,
   };

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

@@ -257,12 +257,12 @@ import CodeEditor from '@/views/components/common/CodeEditor.vue';
 import { autoSave, inTreePanel, useAssets } from '@/services/common';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { loadCss } from '@meta2d/core';
-import { defaultPureColor} from "@/services/defaults";
+import { defaultPureColor } from '@/services/defaults';
 
 const headers = {
   Authorization: 'Bearer ' + (localStorage.token || getCookie('token') || ''),
 };
-const updataData = { directory: '/大屏/未分类' };
+const updataData = { directory: '/大屏/默认' };
 
 const { assets } = useAssets();
 

+ 64 - 32
src/views/components/Graphics.vue

@@ -96,7 +96,7 @@
                       directory:
                         activedGroup === '图片'
                           ? `/大屏/${item.name}`
-                          : '/大屏/未分类',
+                          : '/大屏/默认',
                     }"
                     :auto-upload="true"
                     :upload-all-files-in-one-request="false"
@@ -292,7 +292,7 @@ import { useUser } from '@/services/user';
 import { iframeCustom } from '@/services/defaults';
 
 const { user } = useUser();
-const { setFolder } = useFolder();
+const { setFolder, getFolder } = useFolder();
 const router = useRouter();
 
 const activedGroup = ref('');
@@ -393,7 +393,7 @@ const loading = ref(false);
 const headers = {
   Authorization: 'Bearer ' + (localStorage.token || getCookie('token') || ''),
 };
-const updataData = { directory: '/大屏/未分类' };
+const updataData = { directory: '/大屏/默认' };
 let lastName = '方案';
 let userLastName = '方案';
 const assetsChange = (value) => {
@@ -575,7 +575,7 @@ const getImageList = async () => {
       return {
         name: secondDir[2],
         _id: item._id,
-        canEdited: secondDir[2] !== '未分类',
+        canEdited: secondDir[2] !== '默认',
         list: list,
       };
     })
@@ -661,7 +661,7 @@ const getCaseProjects = async (name: string, current = 1, pageSize = 1000) => {
 const getPrivateGroups = async () => {
   const list = [
     {
-      name: '我的组件',
+      name: '默认',
       list: [],
     },
   ];
@@ -707,7 +707,7 @@ const getPrivateGroups = async () => {
 const getUserComponents = async () => {
   const list = [
     {
-      name: '我的组件',
+      name: '默认',
       list: [],
     },
   ];
@@ -747,7 +747,7 @@ const getUserComponents = async () => {
 const getUserProjects = async (type: string) => {
   const list = [
     {
-      name: '未分类',
+      name: '默认',
       list: [],
     },
   ];
@@ -788,17 +788,17 @@ const getPrivateProjects = async (type: string) => {
     if (!item.list.length) {
       item.loading = true;
       //TODO 方案/模板分类
-      if (item.name === '未分类') {
+      if (item.name === '默认') {
         const data = {
           query: {
             folder: '',
-            isTemplate: type === 'le5leV-template' ? true : undefined,
+            tags: type === 'le5leV-template' ? '模板' : '方案',
           },
           projection: {
             image: 1,
             _id: 1,
             name: 1,
-            isTemplate: 1,
+            tags: 1,
           },
         };
         const config = {
@@ -813,10 +813,10 @@ const getPrivateProjects = async (type: string) => {
           //   item.draggable = false;
           // })
           item.list = res.list;
-          if (type === 'le5leV') {
-            //过滤模板
-            item.list = res.list.filter((item) => !item.isTemplate);
-          }
+          // if (type === 'le5leV') {
+          //   //过滤模板
+          //   // item.list = res.list.filter((item) => !item.isTemplate);
+          // }
         }
       }
       item.loading = false;
@@ -867,7 +867,7 @@ const dragStart = async (event: DragEvent | MouseEvent, item: any) => {
       iframe: 'https://view3d.le5le.com/?id=' + (item._id || item.id),
     };
   } else if (item.component) {
-    // 我的组件
+    // 默认
     if (!item.componentDatas && !item.componentData) {
       isAsync = true;
       const ret: any = await axios.post(`/api/data/le5leV-components/get`, {
@@ -973,7 +973,7 @@ const getPrivateGraphics = async () => {
   for (const item of subGroups.value) {
     if (!item.list.length) {
       item.loading = true;
-      if (item.name === '我的组件') {
+      if (item.name === '默认') {
         const data = {
           query: { folder: '' },
           projection: {
@@ -1122,14 +1122,27 @@ const onEditHeader = (item: any) => {
 
 const onAdd = (item: any) => {
   blank();
+  if (activedGroup.value === '方案') {
+    item.vType = 'le5leV';
+  } else if (activedGroup.value === '模板') {
+    item.vType = 'le5leV-template';
+  }
   setFolder(item);
   router.push({
     path: '/',
     query: {
       r: Date.now() + '',
       folder: item.name,
+      tags: activedGroup.value,
     },
   });
+  // meta2d.open({
+  //   name: '新建项目',
+  //   pens: [],
+  //   enableMock: true,
+  //   tags: activedGroup.value,
+  //   folder: item.name,
+  // } as any);
 };
 
 const onKeyHeader = (text: string, event: any) => {
@@ -1138,7 +1151,7 @@ const onKeyHeader = (text: string, event: any) => {
   }
 };
 
-// 我的组件右键菜单
+// 默认右键菜单
 const contextmenu = reactive<any>({
   visible: false,
   style: {},
@@ -1154,11 +1167,7 @@ const onContextMenu = async (e: MouseEvent, group: any, item: any) => {
   e.preventDefault();
   e.stopPropagation();
 
-  if (
-    activedGroup.value !== '组件' &&
-    activedGroup.value !== '图片' &&
-    activedGroup.value !== '3D'
-  ) {
+  if (activeAssets.value === 'system') {
     return;
   }
 
@@ -1220,6 +1229,19 @@ const onMenu = async (val: string) => {
           url = window.url3D;
         }
         window.open(url + id, '_blank');
+      } else {
+        if (contextmenu.group._id && contextmenu.group.name !== '默认') {
+          setFolder(contextmenu.group);
+        }
+        autoSave();
+        //文件夹
+        router.push({
+          path: '/',
+          query: {
+            id,
+            r: Date.now() + '',
+          },
+        });
       }
 
       break;
@@ -1247,18 +1269,20 @@ const onMenu = async (val: string) => {
           arr.splice(index, 1);
         }
       });
-
+      let collection = contextmenu.component.component
+        ? 'le5leV-components'
+        : 'le5leV';
       // 更新后端组件信息
-      let ret = await updateCollection('le5leV-components', {
+      let ret = await updateCollection(collection, {
         _id: id,
-        folder: val === '我的组件' ? '' : val,
+        folder: val === '默认' ? '' : val,
       });
       if (!ret) {
         return;
       }
 
       // 更新后端源文件夹列表
-      if (contextmenu.group.name !== '我的组件') {
+      if (contextmenu.group.name !== '默认') {
         await axios.post('/api/data/folders/update', {
           _id: contextmenu.group._id || contextmenu.group.id,
           list: contextmenu.group.list,
@@ -1266,7 +1290,7 @@ const onMenu = async (val: string) => {
       }
 
       // 更新后端目标文件夹列表
-      if (group.name !== '我的组件') {
+      if (group.name !== '默认') {
         await axios.post('/api/data/folders/update', {
           _id: group._id || group.id,
           list: group.list,
@@ -1283,18 +1307,26 @@ const hideContextmenu = () => {
 
 const delComponent = async () => {
   // const id = contextmenu.component._id || contextmenu.component.id;
-  if (activedGroup.value === '组件') {
+  if (['组件', '方案', '模板'].includes(activedGroup.value)) {
+    let collection = delDialog.contextmenuObj.component.component
+      ? 'le5leV-components'
+      : 'le5leV';
     const id =
       delDialog.contextmenuObj.component._id ||
       delDialog.contextmenuObj.component.id;
     try {
-      await axios.post(`/api/data/le5leV-components/delete`, {
+      await axios.post(`/api/data/${collection}/delete`, {
         id,
       });
     } catch (e) {
       console.error(e);
       return;
     }
+    //删除缩略图
+    if (delDialog.contextmenuObj.component.image) {
+      await delImage(delDialog.contextmenuObj.component.image);
+    }
+
     // 前端:从源文件夹移出组件
     delDialog.contextmenuObj.group.list.forEach(
       (item: any, index: number, arr: any[]) => {
@@ -1305,7 +1337,7 @@ const delComponent = async () => {
     );
 
     // 更新后端源文件夹列表
-    if (delDialog.contextmenuObj.group.name !== '我的组件') {
+    if (delDialog.contextmenuObj.group.name !== '默认') {
       await axios.post('/api/data/folders/update', {
         _id:
           delDialog.contextmenuObj.group._id ||
@@ -1465,7 +1497,7 @@ const fileSuccessed = async (content: any) => {
     const c: any = {
       name: filename(content.file.name),
       image: content.response.url,
-      folder: uploadGroup.name === '我的组件' ? '' : uploadGroup.name,
+      folder: uploadGroup.name === '默认' ? '' : uploadGroup.name,
     };
     let rst = await processFileObj(
       { raw: content.file.raw, name: content.file.name },
@@ -1473,7 +1505,7 @@ const fileSuccessed = async (content: any) => {
     );
     const ret: any = await addCollection('le5leV-components', rst);
     c._id = ret._id || ret.id;
-    if (ret && uploadGroup.name !== '我的组件') {
+    if (ret && uploadGroup.name !== '默认') {
       if (!uploadGroup.list) {
         uploadGroup.list = [];
       }

+ 1 - 1
src/views/components/Header.vue

@@ -498,7 +498,7 @@ const openZip = async (file: File) => {
       //   // await zip.file(key).async('blob'),
       //   true,
       //   filename + ext,
-      //   "/2D/未分类"
+      //   "/2D/默认"
       // );
       let _key = key;
       // if (_png) {

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

@@ -1118,13 +1118,13 @@ import { autoSave, fonts, inTreePanel } from '@/services/common';
 import { updatePen } from './pen';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { useUser } from '@/services/user';
-import {defaultGradientColor, defaultPureColor} from "@/services/defaults";
+import { defaultGradientColor, defaultPureColor } from '@/services/defaults';
 
 const { user } = useUser();
 const headers = {
   Authorization: 'Bearer ' + (localStorage.token || getCookie('token') || ''),
 };
-const updataData = { directory: '/大屏/未分类' };
+const updataData = { directory: '/大屏/默认' };
 
 const uploadRef = ref();
 

+ 15 - 7
src/views/components/View.vue

@@ -4,7 +4,7 @@
       <t-tooltip content="新建" placement="bottom">
         <a><t-icon name="add" @click="newFile" /></a>
       </t-tooltip>
-      <t-tooltip content="保存为大屏" placement="bottom">
+      <t-tooltip content="保存为方案" placement="bottom">
         <a>
           <t-badge
             :class="{ gray: route.query.c }"
@@ -19,7 +19,7 @@
           </t-badge>
         </a>
       </t-tooltip>
-      <!-- <t-tooltip content="保存为模板" placement="bottom">
+      <t-tooltip content="保存为模板" placement="bottom">
         <a>
           <t-badge
             :class="{ gray: route.query.c }"
@@ -28,19 +28,21 @@
             :count="dot ? 1 : 0"
           >
             <t-icon
-              name="save"
-              @click="!route.query.c && save(SaveType.Save, 'template', true)"
+              name="view-module"
+              @click="
+                !route.query.c && save(SaveType.Save, 'le5leV-template', true)
+              "
             />
           </t-badge>
         </a>
-      </t-tooltip> -->
+      </t-tooltip>
       <t-tooltip content="保存为我的组件" placement="bottom">
         <a :class="{ gray: route.query.id && !route.query.c }">
           <t-icon
             name="layers"
             @click="
               (!route.query.id || route.query.c) &&
-                save(SaveType.Save, 'component', true)
+                save(SaveType.Save, 'le5leV-components', true)
             "
           />
         </a>
@@ -874,7 +876,13 @@ const open = async (flag: boolean = false) => {
       meta2d.open(JSON.parse(data));
     }
   } else if (!sessionStorage.getItem('opening')) {
-    meta2d.open({ name: '新建项目', pens: [], enableMock: true } as any);
+    meta2d.open({
+      name: '新建项目',
+      pens: [],
+      enableMock: true,
+      folder: route.query.folder,
+      tags: [route.query.tags],
+    } as any);
   }
   sessionStorage.removeItem('opening');
   !meta2d.store.data.x && (meta2d.store.data.x = meta2d.store.options.x || 0);