Преглед на файлове

Merge branch 'main' of https://github.com/le5le-com/visualization-design

ananzhusen преди 2 години
родител
ревизия
0641221276

+ 6 - 6
index.html

@@ -23,7 +23,7 @@
         overflow: hidden;
       }
     </style>
-    <script src="//at.alicdn.com/t/c/font_4042197_tr04p9fflg.js"></script>
+    <script src="//at.alicdn.com/t/c/font_4042197_yrikqthz1j.js"></script>
   </head>
   <body>
     <div id="app"></div>
@@ -33,10 +33,10 @@
         return this.replace(new RegExp(s1, 'gm'), s2);
       };
     </script>
-        <script defer src="/js/html2canvas.min.js"></script>
-        <script defer src="/js/flv.min.js"></script>
-        <script defer src="/js/marked.min.js"></script>
-        <script defer src="/js/echarts.min.js"></script>
-        <script defer src="/js/mycharts.js"></script>
+    <script defer src="/js/html2canvas.min.js"></script>
+    <script defer src="/js/flv.min.js"></script>
+    <script defer src="/js/marked.min.js"></script>
+    <script defer src="/js/echarts.min.js"></script>
+    <script defer src="/js/mycharts.js"></script>
   </body>
 </html>

+ 1 - 0
src/services/common.ts

@@ -120,6 +120,7 @@ export const save = async (
     // 另存为一定走 新增 ,由于后端 未控制 userId 等属性,清空一下
     const delAttrs = [
       'userId',
+      '_id',
       'id',
       'shared',
       'star',

Файловите разлики са ограничени, защото са твърде много
+ 789 - 165
src/services/defaults.ts


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

@@ -519,7 +519,7 @@ const getProps = (c: any) => {
   }
 };
 
-const getPropDesc = (a: any, key: string) => {
+const getPropDesc = (a: any, key: any) => {
   const found = a.props.find((elem: any) => elem.value === key);
   if (found) {
     return found.label;

+ 0 - 1
src/views/components/ChargeCloudPublish.vue

@@ -97,7 +97,6 @@ const getPayResult = async () => {
     id: data.order.id || data.order._id,
   });
   if (result && result.state) {
-    getUser(true);
     return true;
   }
 };

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

@@ -983,7 +983,7 @@ const onPaste = () => {
 };
 
 const onAll = () => {
-  // todo
+  meta2d.activeAll();
 };
 
 const onDelete = () => {

+ 14 - 14
src/views/components/PenAnimates.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="animations">
-    <template v-if="pen.animations.length">
+    <template v-if="props.pen.animations.length">
       <t-collapse
         v-model="openedCollapses"
         :borderless="true"
         :expand-on-row-click="true"
       >
-        <t-collapse-panel v-for="(item, i) in pen.animations" :value="i">
+        <t-collapse-panel v-for="(item, i) in props.pen.animations" :value="i">
           <template #header>
             <div class="flex middle" @click.stop>
               <t-input v-model="item.name" autoWidth class="mr-8" />
@@ -29,7 +29,7 @@
           <template #headerRightContent>
             <t-space size="small" @click.stop>
               <t-icon
-                v-if="!pen.type && item.animate"
+                v-if="!props.pen.type && item.animate"
                 name="edit"
                 class="hover mr-4"
                 @click="animate = item"
@@ -39,7 +39,7 @@
                 content="确认删除该动画吗"
                 placement="left"
                 @confirm="
-                  pen.animations.splice(i, 1);
+                  props.pen.animations.splice(i, 1);
                   animate = undefined;
                 "
               >
@@ -47,7 +47,7 @@
               </t-popconfirm>
             </t-space>
           </template>
-          <template v-if="pen.type">
+          <template v-if="props.pen.type">
             <div class="form-item">
               <label>动画类型</label>
               <t-select v-model="item.lineAnimateType" placeholder="水流">
@@ -220,7 +220,7 @@ import { deepClone } from '@meta2d/core';
 
 import AnimateFrames from './AnimateFrames.vue';
 
-const { pen } = defineProps<{
+const props = defineProps<{
   pen: any;
 }>();
 
@@ -357,11 +357,11 @@ const animateList = [
 const isPlaying = ref(-1);
 
 onBeforeMount(() => {
-  if (!pen.animations) {
-    pen.animations = [];
+  if (!props.pen.animations) {
+    props.pen.animations = [];
   }
 
-  const p = meta2d.findOne(pen.id);
+  const p = meta2d.findOne(props.pen.id);
   if (p?.calculative?.start) {
     // @ts-ignore
     isPlaying.value = p?.currentAnimation;
@@ -371,9 +371,9 @@ onBeforeMount(() => {
 });
 
 const addAnimate = () => {
-  openedCollapses.value.push(pen.animations.length);
-  pen.animations.push({
-    name: '动画' + (pen.animations.length + 1),
+  openedCollapses.value.push(props.pen.animations.length);
+  props.pen.animations.push({
+    name: '动画' + (props.pen.animations.length + 1),
   });
 };
 
@@ -390,12 +390,12 @@ const changeAnimate = (item: any) => {
 };
 
 const play = (i: number) => {
-  meta2d.startAnimate(pen.id, i);
+  meta2d.startAnimate(props.pen.id, i);
   isPlaying.value = i;
 };
 
 const stop = () => {
-  meta2d.stopAnimate(pen.id);
+  meta2d.stopAnimate(props.pen.id);
   isPlaying.value = -1;
 };
 </script>

+ 46 - 28
src/views/components/PenDatas.vue

@@ -1,6 +1,9 @@
 <template>
   <div class="props">
-    <div class="real-times" v-if="pen.realTimes && pen.realTimes.length">
+    <div
+      class="real-times"
+      v-if="props.pen.realTimes && props.pen.realTimes.length"
+    >
       <div class="grid head">
         <div class="title">数据名</div>
         <div class="title">值</div>
@@ -9,7 +12,7 @@
           <t-icon name="more" />
         </div>
       </div>
-      <div class="grid" v-for="(item, i) in pen.realTimes">
+      <div class="grid" v-for="(item, i) in props.pen.realTimes">
         <t-tooltip :content="item.key" placement="top">
           <label class="label">{{ item.label }}</label>
         </t-tooltip>
@@ -35,6 +38,13 @@
             size="small"
             @change="changeValue(item.key)"
           />
+          <div
+            v-else-if="item.type === 'array' || item.type === 'object'"
+            class="gray ellipsis"
+            style="height: 30px"
+          >
+            {{ JSON.stringify(pen[item.key]) }}
+          </div>
           <t-input
             v-else
             v-model="pen[item.key]"
@@ -139,13 +149,9 @@
         />
         <div class="desc mt-8">
           固定数字:直接输入数字。例如:5<br />
-          随机范围数字
-          <label class="vip-label" title="会员权限">VIP</label
-          >:最小值-最大值。例如:0-1 或 0-100
+          随机范围数字 :最小值-最大值。例如:0-1 或 0-100
           <br />
-          随机指定数字
-          <label class="vip-label" title="会员权限">VIP</label
-          >:数字1,数字2,数字3... 。 例如:1,5,10,20<br />
+          随机指定数字 :数字1,数字2,数字3... 。 例如:1,5,10,20<br />
         </div>
       </div>
       <div class="flex-grow" v-else-if="addDataDialog.data.type === 'bool'">
@@ -156,12 +162,18 @@
         </t-select>
         <div class="desc mt-8">
           固定:指定true或false<br />
-          随机
-          <label class="vip-label" title="会员权限">VIP</label
-          >:随机生成一个布尔值<br />
+          随机:随机生成一个布尔值<br />
         </div>
       </div>
-
+      <div
+        class="flex-grow"
+        v-else-if="
+          addDataDialog.data.type === 'array' ||
+          addDataDialog.data.type === 'object'
+        "
+      >
+        <CodeEditor v-model="addDataDialog.data.value" :json="true" />
+      </div>
       <div class="flex-grow" v-else>
         <t-input
           class="w-full"
@@ -170,10 +182,8 @@
         />
         <div class="desc mt-8">
           固定文字:直接输入。例如:大屏可视化<br />
-          随机文本<label class="vip-label" title="会员权限">VIP</label
-          >:[文本长度]。例如:[8] 或 [16]<br />
-          随机指定文本<label class="vip-label" title="会员权限">VIP</label
-          >:{文本1,文本2,文本3...} 。 例如:{大屏, 可视化}
+          随机文本:[文本长度]。例如:[8] 或 [16]<br />
+          随机指定文本:{文本1,文本2,文本3...} 。 例如:{大屏, 可视化}
           <br />
         </div>
       </div>
@@ -422,7 +432,7 @@ const {
   proxy: { $forceUpdate },
 }: any = getCurrentInstance();
 
-const { pen } = defineProps<{
+const props = defineProps<{
   pen: any;
 }>();
 
@@ -510,6 +520,14 @@ const typeOptions = [
     label: '布尔',
     value: 'bool',
   },
+  {
+    label: '对象',
+    value: 'object',
+  },
+  {
+    label: '数组',
+    value: 'array',
+  },
 ];
 
 const addDataDialog = reactive<any>({
@@ -581,9 +599,9 @@ let timer: any;
 
 onBeforeMount(() => {
   // realTimesOptions - 扩展的动态数据下拉列表
-  if (pen.realTimesOptions) {
+  if (props.pen.realTimesOptions) {
     options.value[options.value.length - 1].divider = true;
-    options.value.push(...pen.realTimesOptions);
+    options.value.push(...props.pen.realTimesOptions);
   }
 
   timer = setInterval($forceUpdate, 1000);
@@ -591,11 +609,11 @@ onBeforeMount(() => {
 
 const addRealTime = (e: any) => {
   if (e.keywords) {
-    if (!pen.realTimes) {
-      pen.realTimes = [];
+    if (!props.pen.realTimes) {
+      props.pen.realTimes = [];
     }
 
-    pen.realTimes.push({
+    props.pen.realTimes.push({
       label: e.content,
       key: e.value,
       type: e.type,
@@ -625,8 +643,8 @@ const onChangeLabel = () => {
 };
 
 const onConfirmData = () => {
-  if (!pen.realTimes) {
-    pen.realTimes = [];
+  if (!props.pen.realTimes) {
+    props.pen.realTimes = [];
   }
   if (!addDataDialog.data.label || !addDataDialog.data.key) {
     MessagePlugin.error('数据名或属性名不能为空!');
@@ -634,14 +652,14 @@ const onConfirmData = () => {
   }
 
   if (addDataDialog.header === '添加动态数据') {
-    const found = pen.realTimes.findIndex((item: any) => {
+    const found = props.pen.realTimes.findIndex((item: any) => {
       return item.key === addDataDialog.data.key;
     });
     if (found > -1) {
       MessagePlugin.error('已经存在相同属性数据!');
       return;
     }
-    pen.realTimes.push(addDataDialog.data);
+    props.pen.realTimes.push(addDataDialog.data);
   }
 
   addDataDialog.show = false;
@@ -655,7 +673,7 @@ const onMenuMore = (e: any, item: any, i: number) => {
       addDataDialog.show = true;
       break;
     case 'delete':
-      pen.realTimes.splice(i, 1);
+      props.pen.realTimes.splice(i, 1);
       break;
     default:
       break;
@@ -766,7 +784,7 @@ const getBindsDesc = (item: any) => {
 };
 
 const changeValue = (prop: string) => {
-  updatePen(pen, prop);
+  updatePen(props.pen, prop);
 };
 
 const onTrigger = (item: any) => {

+ 9 - 28
src/views/components/PenEvents.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="props">
-    <div v-if="pen.events && pen.events.length">
+    <div v-if="props.pen.events && props.pen.events.length">
       <t-collapse
         v-model="openedCollapses"
         :borderless="true"
         :expand-on-row-click="true"
         expand-icon-placement="left"
       >
-        <t-collapse-panel v-for="(item, i) in pen.events" :value="i">
+        <t-collapse-panel v-for="(item, i) in props.pen.events" :value="i">
           <template #header>
             <div @click.stop class="head">
               <t-select v-model="item.name" :options="options" autoWidth />
@@ -18,14 +18,14 @@
               <t-popconfirm
                 content="确认删除该交互事件吗"
                 placement="left"
-                @confirm="pen.events.splice(i, 1)"
+                @confirm="props.pen.events.splice(i, 1)"
               >
                 <t-icon name="delete" class="hover" />
               </t-popconfirm>
             </t-space>
           </template>
 
-          <Actions :data="pen.events[i]" />
+          <Actions :data="props.pen.events[i]" />
         </t-collapse-panel>
       </t-collapse>
       <t-divider />
@@ -60,30 +60,11 @@
 </template>
 
 <script lang="ts" setup>
-import {
-  getCurrentInstance,
-  onBeforeMount,
-  onUnmounted,
-  reactive,
-  ref,
-  toRaw,
-} from 'vue';
-import { useRoute, useRouter } from 'vue-router';
-import { MessagePlugin } from 'tdesign-vue-next';
-import axios from 'axios';
-import { debounce } from '@/services/debouce';
+import { onBeforeMount, onUnmounted, ref } from 'vue';
 
 import Actions from './Actions.vue';
-import { updatePen } from './pen';
 
-const route = useRoute();
-const router = useRouter();
-
-const {
-  proxy: { $forceUpdate },
-}: any = getCurrentInstance();
-
-const { pen } = defineProps<{
+const props = defineProps<{
   pen: any;
 }>();
 
@@ -133,8 +114,8 @@ const options = ref<any>([
 const openedCollapses = ref([0]);
 
 onBeforeMount(() => {
-  if (!pen.events) {
-    pen.events = [];
+  if (!props.pen.events) {
+    props.pen.events = [];
   }
 
   for (const item of options.value) {
@@ -143,7 +124,7 @@ onBeforeMount(() => {
 });
 
 const addEvent = (e: any) => {
-  pen.events.push({ name: e.value });
+  props.pen.events.push({ name: e.value });
 };
 
 onUnmounted(() => {});

+ 8 - 65
src/views/components/PenProps.vue

@@ -1016,70 +1016,14 @@ onBeforeMount(() => {
     d.groups = [];
   }
   data.groups = d.groups;
-  setPenData();
-  /*
-  data.pen = selections.pen;
-  if (!data.pen.props) {
-    data.pen.props = {};
-  }
-  if (!data.pen.globalAlpha) {
-    data.pen.globalAlpha = 1;
-  }
-  if (!data.pen.dash) {
-    data.pen.dash = 0;
-  }
-  if (!data.pen.props.text) {
-    if (data.pen.text || data.pen.name === 'text') {
-      data.pen.props.text = true;
-    }
-  }
-  if (!data.pen.props.image) {
-    if (data.pen.image || data.pen.name === 'image') {
-      data.pen.props.image = true;
-    }
-  }
-  if (data.pen.image) {
-    data.images = [
-      {
-        url: data.pen.image,
-      },
-    ];
-  }
-  if (!data.pen.tags) {
-    data.pen.tags = [];
-  }
-  if (data.pen.bkType == undefined) {
-    data.pen.bkType = 0;
-  }*/
+  initPenData();
 
-  // 示例代码
-  /*
-  data.pen.props.custom = [
-    { label: '数字', key: 'a', type: 'number', placeholder: '输入提示' },
-    { label: '文字', key: 'b' },
-    { label: '布尔', key: 'c', type: 'bool', placeholder: '输入提示' },
-    { label: '颜色', key: 'd', type: 'color', placeholder: '输入提示' },
-    {
-      label: '下拉框',
-      key: 'd',
-      type: 'select',
-      options: [
-        { label: '选项1', value: '1' },
-        { label: '选项2', value: '2' },
-      ],
-      placeholder: '输入提示',
-    },
-  ];
-  */
-  // end
-  // data.pen.shadow = !!data.pen.shadowColor;
-  getRect();
   meta2d.on('translatePens', getRect);
   meta2d.on('resizePens', getRect);
   meta2d.on('rotatePens', getRect);
 });
 
-function setPenData() {
+function initPenData() {
   data.pen = selections.pen;
   if (!data.pen.props) {
     data.pen.props = {};
@@ -1113,16 +1057,15 @@ function setPenData() {
   if (data.pen.bkType == undefined) {
     data.pen.bkType = 0;
   }
+  if (!data.pen.animations) {
+    data.pen.animations = [];
+  }
   data.pen.shadow = !!data.pen.shadowColor;
+
+  getRect();
 }
 
-const watcher = watch(
-  () => selections.pen.id,
-  async () => {
-    setPenData();
-    getRect();
-  }
-);
+const watcher = watch(() => selections.pen.id, initPenData);
 
 const getRect = () => {
   data.rect = meta2d.getPenRect(data.pen);

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

@@ -705,6 +705,10 @@ onMounted(() => {
   meta2d.on('click', canvasClick);
 
   timer = setInterval(autoSave, 60000);
+
+  window.onbeforeunload = () => {
+    autoSave();
+  };
 });
 
 const watcher = watch(

+ 22 - 4
src/views/components/common/CodeEditor.vue

@@ -58,8 +58,9 @@ import 'monaco-editor/esm/vs/basic-languages/markdown/markdown.contribution';
 
 const dom = ref<any>();
 
-const { modelValue, language, options } = defineProps<{
+const { modelValue, json, language, options } = defineProps<{
   modelValue: any;
+  json?: boolean;
   language?: string;
   options?: any;
 }>();
@@ -81,8 +82,16 @@ self.MonacoEnvironment = {
 let editor: monaco.editor.IStandaloneCodeEditor;
 
 onMounted(() => {
+  let text = '';
+  if (json) {
+    if (modelValue) {
+      text = JSON.stringify(modelValue);
+    }
+  } else {
+    text = modelValue;
+  }
   editor = monaco.editor.create(dom.value, {
-    value: modelValue,
+    value: text,
     automaticLayout: true,
     minimap: { enabled: false },
     language: language || 'javascript',
@@ -91,8 +100,17 @@ onMounted(() => {
   });
   editor.onDidChangeModelContent(() => {
     const currenValue = editor.getValue();
-    emit('update:modelValue', currenValue);
-    emit('change', currenValue);
+    if (json) {
+      let obj: any;
+      try {
+        obj = JSON.parse(currenValue);
+      } catch {}
+      emit('update:modelValue', obj);
+      emit('change', obj);
+    } else {
+      emit('update:modelValue', currenValue);
+      emit('change', currenValue);
+    }
   });
 });
 

Някои файлове не бяха показани, защото твърде много файлове са промени