Alsmile 2 年 前
コミット
6575a5e8d5

+ 1 - 1
package.json

@@ -19,7 +19,7 @@
     "localforage": "^1.10.0",
     "monaco-editor": "^0.38.0",
     "qrcode": "^1.5.3",
-    "tdesign-vue-next": "^1.3.4",
+    "tdesign-vue-next": "^1.3.5",
     "vue": "^3.3.2",
     "vue-router": "^4.2.0"
   },

ファイルの差分が大きいため隠しています
+ 207 - 179
pnpm-lock.yaml


+ 26 - 23
src/services/common.ts

@@ -4,6 +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 dayjs from 'dayjs';
 import { noLoginTip, localStorageName } from '@/services/utils';
 import { upload, dataURLtoBlob } from '@/services/file';
 import { delImage, addCollection, updateCollection } from '@/services/api';
@@ -180,6 +181,30 @@ export const save = async (
   localforage.removeItem(localStorageName);
   return true;
 };
+
+export const autoSave = () => {
+  // 没有更新,不用保存
+  if (!dot.value) {
+    return;
+  }
+
+  const data: any = meta2d.data();
+  if (
+    user &&
+    user.id &&
+    user.isVip &&
+    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));
+  }
+};
+
 const pen = ref(false);
 export const drawPen = () => {
   meta2d.inactive();
@@ -243,26 +268,6 @@ export const unsave = '当前文件未保存,是否继续?(开通vip可享
 //
 export const newFile = async () => {
   notificFn(newfile, true);
-  // if (!(user && user.id)) {
-  //   if (await showNotification(unLogin)) {
-  //     newfile(false);
-  //   }
-  // } else {
-  //   if (dot.value) {
-  //     if (!user.vipExpired) {
-  //       if (await save(SaveType.Save)) {
-  //         //TODO 保存报错了需要save吗
-  //         newfile(false);
-  //       }
-  //     } else {
-  //       if (await showNotification(unsave)) {
-  //         newfile(false);
-  //       }
-  //     }
-  //   } else {
-  //     newfile(false);
-  //   }
-  // }
 };
 
 export const notificFn = async (fn: Function, params: any) => {
@@ -272,10 +277,8 @@ export const notificFn = async (fn: Function, params: any) => {
     }
   } else {
     if (dot.value) {
-      if (!user.vipExpired) {
+      if (user.isVip) {
         if (await save(SaveType.Save)) {
-          //TODO 保存报错了需要save吗
-          // newfile(false);
           fn(params);
         }
       } else {

+ 48 - 686
src/services/defaults.ts

@@ -217,42 +217,26 @@ export interface FormItemType extends FormItem {
   hidden?: boolean; //是否隐藏
 }
 
-export const shapeLib = [
-  //   {
-  //     id: normalShapeLocalName,
-  //     name: "常用图形",
-  //     show: true,
-  //     count: 0, // 默认值,后续与它无关
-  //     list: [],
-  //   },
+export const shapes = [
   {
     name: '基本形状',
     show: true,
     list: [
       {
-        name: 'square',
+        name: '正方形',
         icon: 'l-rect',
         id: 1,
         data: {
-          text: '正方形',
           width: 100,
           height: 100,
           name: 'square',
-          form: [
-            {
-              key: 'text',
-              type: 'text',
-              name: '文字',
-            },
-          ] as FormItemType[],
         },
       },
       {
-        name: 'rectangle',
+        name: '矩形',
         icon: 'l-rectangle',
         id: 2,
         data: {
-          text: '圆角矩形',
           width: 200,
           height: 50,
           borderRadius: 0.1,
@@ -260,179 +244,141 @@ export const shapeLib = [
         },
       },
       {
-        name: 'circle',
+        name: '',
         icon: 'l-circle',
         id: 3,
         data: {
-          text: '圆',
           width: 100,
           height: 100,
           name: 'circle',
         },
       },
       {
-        name: 'triangle',
+        name: '三角形',
         icon: 'l-triangle',
         id: 4,
         data: {
-          text: '三角形',
           width: 100,
           height: 100,
           name: 'triangle',
         },
       },
       {
-        name: 'diamond',
+        name: '菱形',
         icon: 'l-diamond',
         id: 5,
         data: {
-          text: '菱形',
           width: 100,
           height: 100,
           name: 'diamond',
         },
       },
       {
-        name: 'pentagon',
+        name: '五边形',
         icon: 'l-pentagon',
         id: 6,
         data: {
-          text: '五边形',
           width: 100,
           height: 100,
           name: 'pentagon',
         },
       },
       {
-        name: 'hexagon',
+        name: '六边形',
         icon: 'l-hexagon',
         id: 7,
         data: {
-          text: '六边形',
           width: 100,
           height: 100,
           name: 'hexagon',
         },
       },
       {
-        name: 'pentagram',
+        name: '五角星',
         icon: 'l-pentagram',
         id: 8,
         data: {
-          text: '五角星',
           width: 100,
           height: 100,
           name: 'pentagram',
         },
       },
       {
-        name: 'leftArrow',
+        name: '左箭头',
         icon: 'l-arrow-left',
         id: 9,
         data: {
-          text: '左箭头',
           width: 120,
           height: 60,
           name: 'leftArrow',
         },
       },
       {
-        name: 'rightArrow',
+        name: '右箭头',
         icon: 'l-arrow-right',
         id: 10,
         data: {
-          text: '右箭头',
           width: 120,
           height: 60,
           name: 'rightArrow',
         },
       },
       {
-        name: 'twowayArrow',
+        name: '双向箭头',
         icon: 'l-twoway-arrow',
         id: 11,
         data: {
-          text: '双向箭头',
           width: 150,
           height: 60,
           name: 'twowayArrow',
         },
       },
       {
-        name: 'line',
-        icon: 'l-line',
-        id: 12,
-        data: {
-          anchors: [
-            {
-              x: 0,
-              y: 0.5,
-              id: '0',
-            },
-            {
-              x: 1,
-              y: 0.5,
-              id: '1',
-            },
-          ],
-          width: 200,
-          height: 5,
-          name: 'rectangle',
-          lineWidth: 0,
-          background: '#222222',
-        },
-      },
-      {
-        name: 'cloud',
+        name: '云',
         icon: 'l-cloud',
         id: 13,
         data: {
-          text: '云',
           width: 100,
           height: 100,
           name: 'cloud',
         },
       },
       {
-        name: 'message',
+        name: '消息框',
         icon: 'l-msg',
         id: 14,
         data: {
           textTop: -0.1,
-          text: '消息框',
           width: 100,
           height: 100,
           name: 'message',
         },
       },
       {
-        name: 'file',
+        name: '文件',
         icon: 'l-file',
         id: 15,
         data: {
-          text: '文档',
           width: 80,
           height: 100,
           name: 'file',
         },
       },
       {
-        name: 'text',
+        name: '文字',
         icon: 'l-text',
         id: 16,
         data: {
-          text: `text`,
           width: 160,
           height: 30,
           name: 'text',
         },
       },
       {
-        name: 'image',
+        name: '图片',
         icon: 'l-image',
         id: 17,
         data: {
-          text: '',
           width: 100,
           height: 100,
           name: 'image',
@@ -440,7 +386,7 @@ export const shapeLib = [
         },
       },
       {
-        name: 'cube',
+        name: '立方体',
         icon: 'l-cube',
         id: 18,
         data: {
@@ -448,35 +394,34 @@ export const shapeLib = [
           height: 100,
           name: 'cube',
           z: 0.25,
-          form: [
+          props: [
             {
               key: 'z',
-              name: 'z',
+              label: 'Z',
               type: 'number',
               min: 0,
-              step: 0.1,
               placeholder: '<= 1 即宽度的比例',
             },
             {
               key: 'backgroundFront',
-              name: '前背景色',
+              label: '前背景色',
               type: 'color',
             },
             {
               key: 'backgroundUp',
-              name: '顶背景色',
+              label: '顶背景色',
               type: 'color',
             },
             {
               key: 'backgroundRight',
-              name: '右背景色',
+              label: '右背景色',
               type: 'color',
             },
-          ] as FormItemType[],
+          ],
         },
       },
       {
-        name: 'people',
+        name: '',
         icon: 'l-people',
         id: 19,
         data: {
@@ -486,7 +431,7 @@ export const shapeLib = [
         },
       },
       {
-        name: 'video',
+        name: '视频',
         icon: 'l-pc',
         id: 20,
         data: {
@@ -498,39 +443,8 @@ export const shapeLib = [
             'https://video.699pic.com/videos/17/69/11/a_aa3jeKZ0D63g1556176911_10s.mp4',
         },
       },
-      // {
-      //   name: 'video',
-      //   icon: 'l-pc',
-      //   id: 20,
-      //   data: {
-      //     width: 200,
-      //     height: 200,
-      //     externElement: true,
-      //     name: 'video',
-      //     videoType: 'flv',
-      //     video: 'http://1011.hlsplay.aodianyun.com/demo/game.flv'
-      //   }
-      // },
-      // {
-      //   name: 'video',
-      //   icon: 'l-pc',
-      //   id: 20,
-      //   data: {
-      //     width: 200,
-      //     height: 200,
-      //     externElement: true,
-      //     name: 'video',
-      //     videoType: 'flv',
-      //     video:
-      //       // 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8'
-      //       'https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/hls/xgplayer-demo.m3u8'
-      //       // 'https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4'
-      //       // '/vod/mp4:BigBuckBunny_115k.mov'
-      //       // '/livetv/gxtv'
-      //   }
-      // },
-      {
-        name: 'iframe',
+      {
+        name: '网页',
         icon: 'l-02',
         id: 21,
         data: {
@@ -541,18 +455,6 @@ export const shapeLib = [
           iframe: 'http://le5le.com',
         },
       },
-      {
-        name: 'icon',
-        icon: 'l-tubiao',
-        id: 22,
-        data: {
-          width: 100,
-          height: 100,
-          name: 'image',
-          icon: '\ue620',
-          iconFamily: 'ticon',
-        },
-      },
     ],
   },
   {
@@ -560,7 +462,7 @@ export const shapeLib = [
     show: true,
     list: [
       {
-        name: 'mindNode',
+        name: '主题',
         icon: 'l-zhuti',
         data: {
           text: '主题',
@@ -571,7 +473,7 @@ export const shapeLib = [
         },
       },
       {
-        name: 'mindLine',
+        name: '子主题',
         icon: 'l-zizhuti',
         data: {
           text: '子主题',
@@ -1062,7 +964,7 @@ export const shapeLib = [
   },
 ];
 
-export const chartLib = [
+export const charts = [
   {
     name: 'Echarts图表',
     show: true,
@@ -1345,564 +1247,9 @@ export const chartLib = [
         },
       },
     ],
-  } /*
-  {
-    name: "Highcharts图表",
-    show: true,
-    list: [
-      {
-        name: "折线图",
-        icon: "l-line-chart",
-        data: {
-          name: "highcharts",
-          width: 400,
-          height: 200,
-          disableAnchor: true,
-          externElement: true,
-          form: [
-            {
-              key: "highcharts",
-              name: "highcharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          highcharts: {
-            option: {
-              chart: {
-                backgroundColor: "#ffffff00",
-              },
-              credits: {
-                enabled: false,
-              },
-              xAxis: {
-                categories: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
-              },
-              yAxis: {
-                type: "value",
-              },
-              series: [
-                {
-                  data: [820, 932, 901, 934, 1290, 1330, 1320],
-                  type: "line",
-                },
-              ],
-            },
-          },
-        },
-      },
-      {
-        name: "柱状图",
-        icon: "l-bar-chart",
-        data: {
-          name: "highcharts",
-          width: 400,
-          height: 300,
-          disableAnchor: true,
-          externElement: true,
-          form: [
-            {
-              key: "highcharts",
-              name: "highcharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          highcharts: {
-            option: {
-              chart: {
-                backgroundColor: "#ffffff00",
-                type: "column",
-              },
-              title: {
-                text: "月平均降雨量",
-              },
-              subtitle: {
-                text: "数据来源: WorldClimate.com",
-              },
-              xAxis: {
-                categories: [
-                  "一月",
-                  "二月",
-                  "三月",
-                  "四月",
-                  "五月",
-                  "六月",
-                  "七月",
-                  "八月",
-                  "九月",
-                  "十月",
-                  "十一月",
-                  "十二月",
-                ],
-                crosshair: true,
-              },
-              yAxis: {
-                min: 0,
-                title: {
-                  text: "降雨量 (mm)",
-                },
-              },
-              tooltip: {
-                // head + 每个 point + footer 拼接成完整的 table
-                headerFormat:
-                  '<span style="font-size:10px">{point.key}</span><table>',
-                pointFormat:
-                  '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
-                  '<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
-                footerFormat: "</table>",
-                shared: true,
-                useHTML: true,
-              },
-              plotOptions: {
-                column: {
-                  borderWidth: 0,
-                },
-              },
-              series: [
-                {
-                  name: "东京",
-                  data: [
-                    49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4,
-                    194.1, 95.6, 54.4,
-                  ],
-                },
-                {
-                  name: "纽约",
-                  data: [
-                    83.6, 78.8, 98.5, 93.4, 106.0, 84.5, 105.0, 104.3, 91.2,
-                    83.5, 106.6, 92.3,
-                  ],
-                },
-                {
-                  name: "伦敦",
-                  data: [
-                    48.9, 38.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 65.2,
-                    59.3, 51.2,
-                  ],
-                },
-                {
-                  name: "柏林",
-                  data: [
-                    42.4, 33.2, 34.5, 39.7, 52.6, 75.5, 57.4, 60.4, 47.6, 39.1,
-                    46.8, 51.1,
-                  ],
-                },
-              ],
-            },
-          },
-        },
-      },
-      {
-        name: "饼图",
-        icon: "l-pie-chart",
-        data: {
-          name: "highcharts",
-          width: 300,
-          height: 300,
-          disableAnchor: true,
-          externElement: true,
-          form: [
-            {
-              key: "highcharts",
-              name: "highcharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          highcharts: {
-            option: {
-              chart: {
-                backgroundColor: "#ffffff00",
-                plotBackgroundColor: null,
-                plotBorderWidth: null,
-                plotShadow: false,
-                type: "pie",
-              },
-              title: {
-                text: "2018年1月浏览器市场份额",
-              },
-              tooltip: {
-                pointFormat: "{series.name}: <b>{point.percentage:.1f}%</b>",
-              },
-              plotOptions: {
-                pie: {
-                  allowPointSelect: true,
-                  cursor: "pointer",
-                  dataLabels: {
-                    enabled: true,
-                    format: "<b>{point.name}</b>: {point.percentage:.1f} %",
-                    style: {
-                      color: "black",
-                    },
-                  },
-                },
-              },
-              series: [
-                {
-                  name: "Brands",
-                  colorByPoint: true,
-                  data: [
-                    {
-                      name: "Chrome",
-                      y: 61.41,
-                      sliced: true,
-                      selected: true,
-                    },
-                    {
-                      name: "Internet Explorer",
-                      y: 11.84,
-                    },
-                    {
-                      name: "Firefox",
-                      y: 10.85,
-                    },
-                    {
-                      name: "Edge",
-                      y: 4.67,
-                    },
-                    {
-                      name: "Safari",
-                      y: 4.18,
-                    },
-                    {
-                      name: "Sogou Explorer",
-                      y: 1.64,
-                    },
-                    {
-                      name: "Opera",
-                      y: 1.6,
-                    },
-                    {
-                      name: "QQ",
-                      y: 1.2,
-                    },
-                    {
-                      name: "Other",
-                      y: 2.61,
-                    },
-                  ],
-                },
-              ],
-            },
-          },
-        },
-      },
-      {
-        name: "仪表盘",
-        icon: "l-dashboard-chart",
-        data: {
-          name: "highcharts",
-          width: 300,
-          height: 300,
-          disableAnchor: true,
-          form: [
-            {
-              key: "highcharts",
-              name: "highcharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          externElement: true,
-          highcharts: {
-            option: {
-              chart: {
-                type: "gauge",
-                plotBackgroundColor: null,
-                plotBackgroundImage: null,
-                plotBorderWidth: 0,
-                plotShadow: false,
-                backgroundColor: "#ffffff00",
-              },
-              title: {
-                text: "速度仪",
-              },
-              pane: {
-                startAngle: -150,
-                endAngle: 150,
-                background: [
-                  {
-                    backgroundColor: {
-                      linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
-                      stops: [
-                        [0, "#FFF"],
-                        [1, "#333"],
-                      ],
-                    },
-                    borderWidth: 0,
-                    outerRadius: "109%",
-                  },
-                  {
-                    backgroundColor: {
-                      linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
-                      stops: [
-                        [0, "#333"],
-                        [1, "#FFF"],
-                      ],
-                    },
-                    borderWidth: 1,
-                    outerRadius: "107%",
-                  },
-                  {
-                    // default background
-                  },
-                  {
-                    backgroundColor: "#DDD",
-                    borderWidth: 0,
-                    outerRadius: "105%",
-                    innerRadius: "103%",
-                  },
-                ],
-              },
-              // the value axis
-              yAxis: {
-                min: 0,
-                max: 200,
-                minorTickInterval: "auto",
-                minorTickWidth: 1,
-                minorTickLength: 10,
-                minorTickPosition: "inside",
-                minorTickColor: "#666",
-                tickPixelInterval: 30,
-                tickWidth: 2,
-                tickPosition: "inside",
-                tickLength: 10,
-                tickColor: "#666",
-                labels: {
-                  step: 2,
-                  rotation: "auto",
-                },
-                title: {
-                  text: "km/h",
-                },
-                plotBands: [
-                  {
-                    from: 0,
-                    to: 120,
-                    color: "#55BF3B", // green
-                  },
-                  {
-                    from: 120,
-                    to: 160,
-                    color: "#DDDF0D", // yellow
-                  },
-                  {
-                    from: 160,
-                    to: 200,
-                    color: "#DF5353", // red
-                  },
-                ],
-              },
-              series: [
-                {
-                  name: "Speed",
-                  data: [80],
-                  tooltip: {
-                    valueSuffix: " km/h",
-                  },
-                },
-              ],
-            },
-          },
-        },
-      },
-    ],
   },
   {
-    name: "LightningChart图表",
-    show: true,
-    list: [
-      {
-        name: "折线图",
-        icon: "l-line-chart",
-        data: {
-          name: "lightningCharts",
-          width: 400,
-          height: 200,
-          disableAnchor: true,
-          externElement: true,
-          form: [
-            {
-              key: "lightningCharts",
-              name: "lightningCharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          lightningCharts: {
-            option: {
-              type: "line",
-              //主题参考 https://www.arction.com/lightningchart-js-api-documentation/v3.4.0/interfaces/themes.html
-              theme: "darkGreen",
-              data: [
-                {
-                  name: "Sports Car",
-                  data: [
-                    { x: 0, y: 0 },
-                    { x: 50, y: 10 },
-                    { x: 80, y: 20 },
-                    { x: 100, y: 30 },
-                    { x: 150, y: 40 },
-                    { x: 180, y: 50 },
-                    { x: 230, y: 60 },
-                    { x: 290, y: 70 },
-                  ],
-                },
-                {
-                  name: "Family Car",
-                  data: [
-                    { x: 0, y: 0 },
-                    { x: 100, y: 10 },
-                    { x: 230, y: 20 },
-                    { x: 390, y: 30 },
-                    { x: 470, y: 40 },
-                    { x: 540, y: 50 },
-                    { x: 600, y: 60 },
-                    { x: 800, y: 70 },
-                  ],
-                },
-                {
-                  name: "Pick-up Car",
-                  data: [
-                    { x: 0, y: 0 },
-                    { x: 80, y: 10 },
-                    { x: 100, y: 20 },
-                    { x: 150, y: 30 },
-                    { x: 230, y: 40 },
-                    { x: 380, y: 50 },
-                    { x: 450, y: 60 },
-                    { x: 580, y: 70 },
-                  ],
-                },
-              ],
-              title: "title",
-            },
-          },
-        },
-      },
-      {
-        name: "柱状图",
-        icon: "l-bar-chart",
-        data: {
-          name: "lightningCharts",
-          width: 400,
-          height: 200,
-          disableAnchor: true,
-          externElement: true,
-          form: [
-            {
-              key: "lightningCharts",
-              name: "lightningCharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          lightningCharts: {
-            option: {
-              type: "bar",
-              theme: "darkGreen",
-              groups: ["Finland", "Germany", "UK"],
-              categories: ["Engineers", "Sales", "Marketing"],
-              data: [
-                [48, 27, 24],
-                [19, 40, 14],
-                [33, 33, 62],
-              ],
-              title: "My first chart",
-              yTitle: "纵坐标",
-            },
-          },
-        },
-      },
-      {
-        name: "饼图",
-        icon: "l-pie-chart",
-        data: {
-          name: "lightningCharts",
-          width: 600,
-          height: 300,
-          disableAnchor: true,
-          externElement: true,
-          form: [
-            {
-              key: "lightningCharts",
-              name: "lightningCharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          lightningCharts: {
-            option: {
-              type: "pie",
-              innerRadius: 50,
-              data: [
-                {
-                  name: "Planning",
-                  value: 40,
-                },
-                {
-                  name: "Development",
-                  value: 120,
-                },
-                {
-                  name: "Testing",
-                  value: 60,
-                },
-                {
-                  name: "Review",
-                  value: 24,
-                },
-                {
-                  name: "Bug Fixing",
-                  value: 90,
-                },
-              ],
-            },
-          },
-        },
-      },
-      {
-        name: "仪表盘",
-        icon: "l-dashboard-chart",
-        data: {
-          name: "lightningCharts",
-          width: 300,
-          height: 300,
-          disableAnchor: true,
-          externElement: true,
-          form: [
-            {
-              key: "lightningCharts",
-              name: "lightningCharts",
-              type: "code",
-              language: "json",
-              isNotString: true,
-            },
-          ] as FormItemType[],
-          lightningCharts: {
-            option: {
-              type: "gauge",
-              data: 80,
-              title: "进度条",
-              startAngle: 90,
-              endAngle: -270,
-              background: "#0000ff",
-            },
-          },
-        },
-      },
-    ],
-  },*/,
-  {
-    name: 'le5le charts',
+    name: '乐吾乐Charts',
     show: true,
     list: [
       {
@@ -2069,7 +1416,7 @@ export const chartLib = [
   },
 ];
 
-export const formLib = [
+export const formComponents = [
   {
     name: '表单',
     show: true,
@@ -2802,3 +2149,18 @@ export const formLib = [
     ],
   },
 ];
+
+export const cases: any[] = [
+  { name: '智慧物联' },
+  { name: '电力能源' },
+  { name: '智慧水务' },
+  { name: '智慧工厂' },
+  { name: '智慧校园' },
+  { name: '智慧园区' },
+  { name: '智慧交通' },
+  { name: '智慧城市' },
+  { name: '智慧农业' },
+  { name: '电信机房' },
+  { name: '航天航空' },
+  { name: '智能家居' },
+];

+ 1 - 2
src/services/icons.ts

@@ -2,9 +2,8 @@ import axios from '@/http';
 import { parseSvg } from '@meta2d/svg';
 import { cdn } from './api';
 import { getFolders } from './png';
-const market = import.meta.env.VITE_BASEURL;
 
-const normalFolder = market ? '/2d/svg/' : '/svg/';
+const normalFolder = import.meta.env.VITE_BASEURL ? '/2d/svg/' : '/svg/';
 /**
  * 请求 svg 的目录
  * @returns

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

@@ -1,6 +1,6 @@
 <template>
   <div class="elements">
-    <div class="title" style="margin: 8px 0 0 12px">图结构</div>
+    <div class="title" style="margin: 8px 0 0 12px">图结构</div>
     <t-tree
       class="flex-grow"
       ref="tree"
@@ -9,7 +9,7 @@
       activable
       :expand-parent="true"
       @active="onActive"
-      style="padding: 0 4px 8px 0"
+      style="padding: 0 4px 8px 8px"
     >
       <template #label="{ node }: any">
         <div class="flex middle" :class="{ gray: node.data.visible === false }">

+ 135 - 98
src/views/components/Graphics.vue

@@ -6,40 +6,52 @@
       </div>
       <t-input placeholder="搜索" />
     </div>
-    <div class="groups">
-      <div class="sub-groups">
+    <div class="groups-panel">
+      <div class="groups">
         <div
           v-for="group in groups"
-          :class="group.name === activeGroup ? 'active' : ''"
+          :class="group.name === activedGroup ? 'active' : ''"
           @click="groupChange(group.name)"
         >
           <t-icon :name="group.icon" />
           {{ group.name }}
         </div>
       </div>
-      <div class="list" :class="showType === 1 ? 'two-list' : ''">
-        <t-collapse v-model:value="panelValue">
+      <div class="list" :class="groupType ? 'two-list' : ''">
+        <t-collapse v-model:value="activedPanel">
           <t-collapse-panel
             :value="item.name"
             :header="item.name"
-            v-for="item in showList"
+            v-for="item in subGroups"
             :key="item.name"
           >
             <div
               class="show-item"
-              v-for="iItem in item.list"
-              :draggable="true"
-              @dragstart="dragStart($event, iItem)"
-              @drag="drag($event, iItem)"
+              v-for="subItem in item.list"
+              :draggable="!groupType || groupType >= 10"
+              @dragstart="dragStart($event, subItem)"
+              @drag="drag($event, subItem)"
               @dragend="dragEnd()"
-              @click.stop="dragStart($event, iItem)"
+              @click.stop="dragStart($event, subItem)"
+              @dblclick.stop="open(subItem)"
             >
-              <t-image v-if="iItem.image" :src="iItem.image" fit="cover" />
-              <div class="svg-box" v-else-if="iItem.svg" v-html="iItem.svg" />
+              <t-image v-if="subItem.image" :src="subItem.image" fit="cover" />
+              <div
+                class="svg-box"
+                v-else-if="subItem.svg"
+                v-html="subItem.svg"
+              />
               <svg v-else class="l-icon" aria-hidden="true">
-                <use :xlink:href="'#' + iItem.icon"></use>
+                <use :xlink:href="'#' + subItem.icon"></use>
               </svg>
-              <p :title="iItem.name">{{ iItem.name }}</p>
+              <p :title="subItem.name">{{ subItem.name }}</p>
+            </div>
+            <div
+              v-if="!item.list || !item.list.length"
+              class="gray center"
+              style="white-space: nowrap; margin-left: 32px"
+            >
+              暂无数据,待更新
             </div>
           </t-collapse-panel>
         </t-collapse>
@@ -50,15 +62,19 @@
 
 <script lang="ts" setup>
 import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
-import { shapeLib, chartLib, formLib } from '@/services/defaults';
+import axios from 'axios';
+
+import { cases, shapes, charts, formComponents } from '@/services/defaults';
 import { getPngFolders, getPngs } from '@/services/png';
 import { getIconFolders, getIcons } from '@/services/icons';
 import { getComponents, getComponentsList } from '@/services/api';
 import { convertPen } from '@/services/upgrade';
 import { deepClone } from '@meta2d/core';
 import { isGif } from '@/services/utils';
+import { autoSave } from '@/services/common';
+
+const activedGroup = ref('图形');
 
-const activeGroup = ref('图形');
 const groups = reactive([
   {
     icon: 'desktop',
@@ -101,10 +117,87 @@ const groups = reactive([
     key: '',
   },
 ]);
+const subGroups = ref<any[]>([]);
+const groupType = ref(0);
+const activedPanel = ref([]);
 
-const getSceneLib = () => {};
+const templates = reactive<any>({});
+const materials = reactive([]);
+const icons = reactive([]);
+
+const groupChange = async (name: string) => {
+  activedPanel.value = [];
+  activedGroup.value = name;
+  groupType.value = 0;
+  switch (name) {
+    case '场景':
+      groupType.value = 1;
+      subGroups.value = cases;
+      if (!templates[name + cases[0].name]) {
+        templates[name + cases[0].name] = await getCaseProjects(
+          name,
+          cases[0].name
+        );
+      }
+      subGroups.value[0].list = templates[name + cases[0].name];
+      break;
+    case '模板':
+      groupType.value = 2;
+      subGroups.value = cases;
+      if (!templates[name + cases[0].name]) {
+        templates[name + cases[0].name] = await getCaseProjects(
+          name,
+          cases[0].name
+        );
+      }
+      subGroups.value[0].list = templates[name + cases[0].name];
+      break;
+    case '图表':
+      subGroups.value = charts;
+      break;
+    case '控件':
+      subGroups.value = formComponents;
+      break;
+    case '素材':
+      if (!materials.length) {
+        materials.push(...(await getPngFolders()));
+      }
+      subGroups.value = materials;
+      break;
+    case '图标':
+      if (!icons.length) {
+        icons.push(...(await getIconFolders()));
+      }
+      subGroups.value = icons;
+      break;
+    case '图形':
+      subGroups.value = shapes;
+      break;
+    case '我的':
+      subGroups.value = await getPrivateCommponents();
+      groupType.value = 10;
+      break;
+  }
+  activedPanel.value = [subGroups.value[0].name];
+};
+
+const getCaseProjects = async (name: string, group: string) => {
+  const ret: any = await axios.post(
+    '/api/data/le5leV/list?current=1&pageSize=1000',
+    {
+      query: { tags: name, case: group },
+      shared: 'true',
+      projection: { _id: 1, name: 1, image: 1 },
+    }
+  );
+
+  if (!ret) {
+    return [];
+  }
+  return ret.list;
+};
 
-const getCommponentsLib = async () => {
+const getPrivateCommponents = async () => {
   const data = {
     projection: {
       image: 1,
@@ -141,65 +234,8 @@ const getCommponentsLib = async () => {
   return list;
 };
 
-const getMaterialLib = async () => {
-  const pngs = await getPngFolders();
-  return pngs;
-};
-let materialLib: any[] = [];
-
-const getIconsLib = async () => {
-  const icons = await getIconFolders();
-  return icons;
-};
-
-let iconsLib: any[] = [];
-
-const groupChange = async (name: string) => {
-  panelValue.value = [];
-  activeGroup.value = name;
-  showType.value = 0;
-  switch (name) {
-    case '场景':
-      showList.value = [];
-      break;
-    case '模板':
-      showList.value = [];
-      break;
-    case '图表':
-      showList.value = chartLib;
-      break;
-    case '控件':
-      showList.value = formLib;
-      break;
-    case '素材':
-      if (materialLib.length === 0) {
-        materialLib = await getMaterialLib();
-      }
-      showList.value = materialLib;
-      break;
-    case '图标':
-      if (iconsLib.length === 0) {
-        iconsLib = await getIconsLib();
-      }
-      showList.value = iconsLib;
-      break;
-    case '图形':
-      showList.value = shapeLib;
-      panelValue.value = ['基本形状'];
-      break;
-    case '我的':
-      showList.value = await getCommponentsLib();
-      showType.value = 1;
-      break;
-  }
-};
-
-const showList = ref<any[]>([]);
-const showType = ref(0);
-const panelValue = ref([]);
-
 watch(
-  () => panelValue.value,
+  () => activedPanel.value,
   async (newV: any[], oldV: any[]) => {
     const newOpen: any = [];
     for (let v of newV) {
@@ -208,28 +244,32 @@ watch(
     if (newOpen.length === 0) {
       return;
     }
-    if (activeGroup.value === '素材') {
-      const data: any = materialLib.find((item) => item.name === newOpen[0]); //  materialLib[newOpen[0]];
+    if (activedGroup.value === '素材') {
+      const data: any = materials.find((item) => item.name === newOpen[0]);
       if (!data.list || data.list.length === 0) {
         data.list = await getPngs(
           globalThis.folderJson ? data.pinyin : data.name
         );
-        showList.value = deepClone(materialLib);
+        subGroups.value = deepClone(materials);
       }
-    } else if (activeGroup.value === '图标') {
-      const data: any = iconsLib.find((item) => item.name === newOpen[0]); // iconsLib[newOpen[0]];
+    } else if (activedGroup.value === '图标') {
+      const data: any = icons.find((item) => item.name === newOpen[0]);
       if (!data.list || data.list.length === 0) {
         data.list = await getIcons(
           globalThis.folderJson ? data.pinyin : data.name
         );
-        showList.value = deepClone(iconsLib);
+        subGroups.value = deepClone(icons);
       }
     }
   }
 );
 
 const dragStart = async (event: DragEvent | MouseEvent, item: any) => {
-  if (!item || (event instanceof DragEvent && !event.dataTransfer)) {
+  if (
+    (groupType.value > 0 && groupType.value < 10) ||
+    !item ||
+    (event instanceof DragEvent && !event.dataTransfer)
+  ) {
     return;
   }
   let data = null;
@@ -291,22 +331,20 @@ const dragend = (event: any) => {
   event.target.style.opacity = 1;
 };
 
-//获取所有图形库
-const getGraphics = async () => {
-  // if (!materialLib.length) {
-  //   materialLib = await getPngFolders();
-  // }
+const open = (item: any) => {
+  console.log(item);
+  autoSave();
 };
 
 onMounted(() => {
-  groupChange('图形');
-  document.removeEventListener('dragstart', dragstart);
-  document.removeEventListener('dragend', dragend);
+  groupChange('场景');
+  document.addEventListener('dragstart', dragstart, false);
+  document.addEventListener('dragend', dragend, false);
 });
 
 onUnmounted(() => {
-  document.addEventListener('dragstart', dragstart, false);
-  document.addEventListener('dragend', dragend, false);
+  document.removeEventListener('dragstart', dragstart);
+  document.removeEventListener('dragend', dragend);
 });
 </script>
 <style lang="postcss" scoped>
@@ -319,7 +357,7 @@ onUnmounted(() => {
     height: 40px;
   }
 
-  .groups {
+  .groups-panel {
     display: grid;
     grid-template-columns: 50px 1fr;
     border-top: 1px solid var(--color-background-input);
@@ -327,7 +365,7 @@ onUnmounted(() => {
     overflow-y: auto;
     font-size: 12px;
 
-    .sub-groups {
+    .groups {
       & > div {
         display: flex;
         flex-direction: column;
@@ -397,7 +435,7 @@ onUnmounted(() => {
         p {
           text-align: center;
           font-size: 12px;
-          height: 14px;
+          height: 12px;
           line-height: 1;
           overflow: hidden;
           text-overflow: ellipsis;
@@ -446,7 +484,6 @@ onUnmounted(() => {
       :deep(.t-collapse-panel__content) {
         padding: 8px;
         grid-template-columns: 116px 116px;
-        grid-template-rows: 136px;
       }
       .show-item {
         p {

+ 4 - 5
src/views/components/Header.vue

@@ -458,8 +458,7 @@ const openZip = async (file: File, isNew: boolean = false) => {
     return;
   }
 
-  if (user.vipExpired) {
-    // vipVisible.value = true;
+  if (!user.isVip) {
     gotoAccount();
     return;
   }
@@ -618,7 +617,7 @@ const downloadZip = async () => {
     return;
   }
 
-  if (user.vipExpired) {
+  if (!user.isVip) {
     gotoAccount();
     return;
   }
@@ -653,7 +652,7 @@ const downloadHtml = async () => {
     return;
   }
 
-  if (user.vipExpired) {
+  if (!user.isVip) {
     gotoAccount();
     return;
   }
@@ -707,7 +706,7 @@ async function downloadAsFrame(type: Frame) {
     return;
   }
 
-  if (user.vipExpired) {
+  if (!user.isVip) {
     gotoAccount();
     return;
   }

+ 21 - 24
src/views/components/View.vue

@@ -230,7 +230,25 @@
         <a><t-icon name="qrcode" /></a>
         <template #content>
           <div style="padding: 12px 12px 6px 12px">
-            <img :src="qrcode.url" />
+            <img
+              v-if="route.query.id && route.query.component !== 'true'"
+              :src="qrcode.url"
+            />
+            <div
+              v-else-if="!route.query.id"
+              class="gray center mb-4"
+              style="font-size: 10px; margin-bottom: 6px"
+            >
+              当前项目为本地编辑模式<br />
+              请保存为大屏项目后访问
+            </div>
+            <div
+              v-else
+              class="gray center mb-4"
+              style="font-size: 10px; margin-bottom: 6px"
+            >
+              仅支持手机访问大屏项目
+            </div>
           </div>
         </template>
       </t-popup>
@@ -591,6 +609,7 @@ import { useUser } from '@/services/user';
 import { cdn, getLe5leV, updateCollection } from '@/services/api';
 import {
   save,
+  autoSave,
   newFile,
   SaveType,
   onScaleView,
@@ -666,29 +685,7 @@ onMounted(() => {
   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);
+  timer = setInterval(autoSave, 60000);
 });
 
 const watcher = watch(

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません