Wind-Breaker1 пре 1 година
родитељ
комит
10164123ba

+ 1 - 1
src/App.vue

@@ -15,7 +15,7 @@ onBeforeMount(() => {
   setTimeout(() => {
     registerTheme();
     changeTheme('le-dark');
-  }, 1000);
+  }, 0);
 });
 </script>
 <style lang="postcss" scoped></style>

BIN
src/assets/fonts/TG-TYPE-Bold.otf


BIN
src/assets/fonts/TG-TYPE-Regular.otf


+ 21 - 0
src/assets/fonts/fonts.css

@@ -0,0 +1,21 @@
+/* 字体文件 */
+@font-face {
+  font-family: '斗鱼追光体';
+  src: url('./斗鱼追光体.ttf');
+}
+
+@font-face {
+  font-family: '庞门正道标题体';
+  src: url('./庞门正道标题体.ttf');
+}
+
+/* 数字字体 */
+@font-face {
+  font-family: 'ALIBABA Regular';
+  src: url('./TG-TYPE-Regular.otf');
+}
+
+@font-face {
+  font-family: 'ALIBABA Bold';
+  src: url('./TG-TYPE-Bold.otf');
+}

BIN
src/assets/fonts/庞门正道标题体.ttf


BIN
src/assets/fonts/斗鱼追光体.ttf


+ 56 - 0
src/services/common.ts

@@ -107,6 +107,58 @@ export const save = async (
     localforage.setItem(localStorageName, JSON.stringify(data));
     return;
   }
+  let componentActive = false;
+  if (
+    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: '',
+      origin: data.origin,
+      scale: data.scale,
+      x: data.x,
+      y: data.y,
+    };
+    let blob: Blob;
+    try {
+      blob = dataURLtoBlob(meta2d.activeToPng(0) + '');
+      console.log('blob', blob);
+    } catch (e) {
+      MessagePlugin.error(
+        '无法下载,宽度不合法,可能没有选中画笔/选中画笔大小超出浏览器最大限制'
+      );
+      return;
+    }
+
+    const file = await upload(blob, true);
+    if (!file) {
+      return;
+    }
+
+    // 缩略图
+    comData.image = file.url;
+    comData.component = true;
+    const allPens = meta2d.canvas.getAllByPens(meta2d.store.active);
+    comData.componentDatas = meta2d.toComponent(
+      allPens,
+      (meta2d.store.data as Meta2dBackData).showChild,
+      false
+    );
+    comData.name =
+      (meta2d.store.active[0] as any).description ||
+      `meta2d.${new Date().toLocaleString()}`;
+    let ret: any = await addCollection('le5leV-components', comData); // 新增
+    if (ret.error) {
+      return;
+    }
+    MessagePlugin.success('成功保存为组件!');
+    return;
+  }
   checkData(data);
   if (!data._id && router.currentRoute.value.query.id) {
     data._id = router.currentRoute.value.query.id as string;
@@ -441,6 +493,10 @@ export const fonts = [
   '微软雅黑',
   '黑体',
   '楷体',
+  '斗鱼追光体',
+  '庞门正道标题体',
+  'ALIBABA Regular',
+  'ALIBABA Bold',
   '-apple-system',
   'BlinkMacSystemFont',
   'PingFang SC',

+ 48 - 7
src/services/defaults.ts

@@ -216,6 +216,46 @@ export interface FormItemType extends FormItem {
   hidden?: boolean; //是否隐藏
 }
 
+export const iframeCustom = [
+  {
+    key: 'iframe',
+    label: '网页地址',
+    type: 'string',
+  },
+  {
+    key: 'operationalRect.x',
+    label: '可操作x',
+    type: 'number',
+    min: 0,
+    max: 1,
+    placeholder: '范围0-1',
+  },
+  {
+    key: 'operationalRect.y',
+    label: '可操作y',
+    type: 'number',
+    min: 0,
+    max: 1,
+    placeholder: '范围0-1',
+  },
+  {
+    key: 'operationalRect.width',
+    label: '可操作宽度',
+    type: 'number',
+    min: 0,
+    max: 1,
+    placeholder: '范围0-1',
+  },
+  {
+    key: 'operationalRect.height',
+    label: '可操作高度',
+    type: 'number',
+    min: 0,
+    max: 1,
+    placeholder: '范围0-1',
+  },
+];
+
 export const shapes = [
   {
     name: '基本形状',
@@ -1739,13 +1779,7 @@ export const formComponents = [
           externElement: true,
           iframe: 'https://le5le.com',
           props: {
-            custom: [
-              {
-                key: 'iframe',
-                label: '网页地址',
-                type: 'string',
-              },
-            ],
+            custom: iframeCustom,
           },
         },
       },
@@ -2926,6 +2960,13 @@ export const formComponents = [
           background: '#FF5D3C33',
           activeBackground: '#FF5D3C',
           textColor: '#FFFFFFB3',
+          sub: 5,
+          barrel: {
+            x: 0.3,
+            y: 0.2,
+            width: 0.2,
+            height: 7 / 9,
+          },
         },
       },
     ],

+ 66 - 65
src/services/echarts.ts

@@ -37,10 +37,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -127,10 +127,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -263,10 +263,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -319,10 +319,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -410,10 +410,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -548,10 +548,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -605,10 +605,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -702,10 +702,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -794,10 +794,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -940,10 +940,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -1117,10 +1117,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               xAxis: {
@@ -1252,10 +1252,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               xAxis: {
@@ -1395,10 +1395,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               fontSize: 10,
@@ -1623,10 +1623,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               yAxis: {
@@ -1762,10 +1762,10 @@ export const charts = [
           echarts: {
             option: {
               grid: {
-                bottom: 16,
-                left: 16,
-                right: 16,
-                top: 24,
+                bottom: 8,
+                left: 8,
+                right: 8,
+                top: 12,
                 containLabel: true,
               },
               yAxis: {
@@ -5294,7 +5294,8 @@ export const charts = [
             { value: 234, name: '大屏' },
             { value: 135, name: '物联网平台' },
             { value: 1548, name: '图形库' },
-          ],realTimes: [
+          ],
+          realTimes: [
             {
               key: 'data.0.value',
               label: '2D',
@@ -5329,10 +5330,10 @@ export const charts = [
               type: 'float',
               enableMock: true,
               mock: '10-100',
-            }
-          ]
-        }
-      }
+            },
+          ],
+        },
+      },
     ],
   },
 ];

+ 1 - 0
src/styles/index.css

@@ -1,4 +1,5 @@
 @import 'tdesign-vue-next/es/style/index.css';
+@import '../assets/fonts/fonts.css';
 
 @import './var.css';
 @import './tdesign.css';

+ 82 - 43
src/views/components/Actions.vue

@@ -153,7 +153,7 @@
                         />
                       </t-dropdown-item>
                       <t-dropdown-item
-                        v-for="prop in a.props"
+                        v-for="prop in cprops"
                         :key="prop.value"
                         :value="prop.value"
                       >
@@ -253,7 +253,7 @@
                         />
                       </t-dropdown-item>
                       <t-dropdown-item
-                        v-for="prop in a.props"
+                        v-for="prop in cprops"
                         :key="prop.value"
                         :value="prop.value"
                       >
@@ -460,45 +460,84 @@ const onChangeAction = (action: any) => {
   }
 };
 
+let cprops = [
+  {
+    value: 'x',
+    label: 'X',
+  },
+  {
+    value: 'y',
+    label: 'Y',
+  },
+  {
+    value: 'width',
+    label: '宽',
+  },
+  {
+    value: 'height',
+    label: '高',
+  },
+  {
+    value: 'visible',
+    label: '显示',
+  },
+  {
+    value: 'text',
+    label: '文字',
+  },
+  {
+    value: 'progress',
+    label: '进度',
+  },
+  {
+    value: 'showChild',
+    label: '状态',
+  },
+  {
+    value: 'rotate',
+    label: '旋转',
+  },
+];
+
 const getProps = (c: any) => {
-  c.props = [
-    {
-      value: 'x',
-      label: 'X',
-    },
-    {
-      value: 'y',
-      label: 'Y',
-    },
-    {
-      value: 'width',
-      label: '宽',
-    },
-    {
-      value: 'height',
-      label: '高',
-    },
-    {
-      value: 'visible',
-      label: '显示',
-    },
-    {
-      value: 'text',
-      label: '文字',
-    },
-    {
-      value: 'progress',
-      label: '进度',
-    },
-    {
-      value: 'showChild',
-      label: '状态',
-    },
-    {
-      value: 'rotate',
-      label: '旋转',
-    },
-  ];
+  // c.props = [
+  //   {
+  //     value: 'x',
+  //     label: 'X',
+  //   },
+  //   {
+  //     value: 'y',
+  //     label: 'Y',
+  //   },
+  //   {
+  //     value: 'width',
+  //     label: '宽',
+  //   },
+  //   {
+  //     value: 'height',
+  //     label: '高',
+  //   },
+  //   {
+  //     value: 'visible',
+  //     label: '显示',
+  //   },
+  //   {
+  //     value: 'text',
+  //     label: '文字',
+  //   },
+  //   {
+  //     value: 'progress',
+  //     label: '进度',
+  //   },
+  //   {
+  //     value: 'showChild',
+  //     label: '状态',
+  //   },
+  //   {
+  //     value: 'rotate',
+  //     label: '旋转',
+  //   },
+  // ];
 
   let target: any;
   if (c.params) {
@@ -508,9 +547,9 @@ const getProps = (c: any) => {
   }
   if (target?.realTimes) {
     for (const item of target.realTimes) {
-      const found = c.props.findIndex((elem: any) => elem.value === item.key);
+      const found = cprops.findIndex((elem: any) => elem.value === item.key);
       if (found < 0) {
-        c.props.push({
+        cprops.push({
           value: item.key,
           label: item.label,
         });
@@ -520,7 +559,7 @@ const getProps = (c: any) => {
 };
 
 const getPropDesc = (a: any, key: any) => {
-  const found = a.props.find((elem: any) => elem.value === key);
+  const found = cprops.find((elem: any) => elem.value === key);
   if (found) {
     return found.label;
   }

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

@@ -1,7 +1,7 @@
 <template>
   <div class="dataset-component">
     <div class="form-item mt-8">
-      <label>数据名称</label>
+      <label>数据模型名称</label>
       <t-input v-model="modelValue.name" placeholder="名称" />
     </div>
 

+ 3 - 1
src/views/components/ElementTree.vue

@@ -265,7 +265,9 @@ const onActive = (value: string[]) => {
       }
     }
   }
-  meta2d.active(pens, false);
+  meta2d.active(pens, true);
+  meta2d.gotoView(pens[0]);
+  meta2d.resize();
   meta2d.render();
 };
 

+ 10 - 0
src/views/components/FileProps.vue

@@ -71,6 +71,7 @@
               :headers="headers"
               :data="updataData"
               :auto-upload="true"
+              :before-upload="beforeUpload"
               :upload-all-files-in-one-request="false"
               @success="fileSuccessed"
               @remove="fileRemoved"
@@ -336,6 +337,14 @@ const selectedSreen = (item: any) => {
   openData();
 };
 
+const beforeUpload = (file: any) => {
+  if (!(user && user.id)) {
+    MessagePlugin.warning('请先登录!');
+    return false;
+  }
+  return true;
+};
+
 const fileSuccessed = async (content: any) => {
   // meta2d.store.patchFlagsBackground = true;
   meta2d.setBackgroundImage(content.response.url);
@@ -407,6 +416,7 @@ const showDataTransformation = () => {
 
 const onOkDataTransformation = () => {
   meta2d.store.data.socketCbJs = dataTransformationDialog.data;
+  meta2d.listenSocket();
   dataTransformationDialog.show = false;
 };
 

+ 26 - 0
src/views/components/Graphics.vue

@@ -74,6 +74,7 @@
                     :data="updataData"
                     :auto-upload="true"
                     :upload-all-files-in-one-request="false"
+                    :before-upload="beforeUpload"
                     @selectChange="onSelectFiles(item)"
                     @success="fileSuccessed"
                     theme="custom"
@@ -248,7 +249,10 @@ import { getCookie } from '@/services/cookie';
 
 import WechatPay from './WechatPay.vue';
 import { filename } from '@/services/file';
+import { useUser } from '@/services/user';
+import { iframeCustom } from '@/services/defaults';
 
+const { user } = useUser();
 const router = useRouter();
 
 const activedGroup = ref('');
@@ -511,6 +515,15 @@ const dragStart = async (event: DragEvent | MouseEvent, item: any) => {
       y: 0,
       tags: ['meta3d'],
       zIndex: 1,
+      operationalRect: {
+        x: 0.1,
+        y: 0.2,
+        height: 0.9,
+        width: 0.6,
+      },
+      props: {
+        custom: iframeCustom,
+      },
       width: meta2d.store.data.width || meta2d.store.options.width,
       height: meta2d.store.data.height || meta2d.store.options.height,
       externElement: true,
@@ -992,6 +1005,14 @@ const onSelectFiles = (item: any) => {
   uploadGroup = item;
 };
 
+const beforeUpload = (file: any) => {
+  if (!(user && user.id)) {
+    MessagePlugin.warning('请先登录!');
+    return false;
+  }
+  return true;
+};
+
 const fileSuccessed = async (content: any) => {
   const c: any = {
     name: filename(content.file.name),
@@ -1011,6 +1032,11 @@ const fileSuccessed = async (content: any) => {
       _id: uploadGroup._id || uploadGroup.id,
       list: uploadGroup.list,
     });
+  } else {
+    if (!uploadGroup.list) {
+      uploadGroup.list = [];
+    }
+    uploadGroup.list.push(c);
   }
 };
 

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

@@ -70,7 +70,17 @@
     </div>
     <div class="form-item mt-8">
       <label>URL地址</label>
-      <t-input v-model="modelValue.url" />
+      <t-input
+        :format="urlFormat"
+        :placeholder="
+          modelValue.protocol !== 'http'
+            ? isSafeProtocol()
+              ? '必须是wss协议'
+              : '必须是ws协议'
+            : '请输入'
+        "
+        v-model="modelValue.url"
+      />
     </div>
     <template v-if="modelValue.protocol === 'websocket'">
       <div class="form-item mt-8">
@@ -100,7 +110,11 @@
           style="height: 50px"
         />
       </div>
-      <div v-if="modelValue.method === 'POST'" class="form-item mt-8">
+      <div class="form-item mt-8 desc">
+        <label></label>
+        支持设置动态参数,例如:{"Authorization": "Bearer ${token}"}
+      </div>
+      <div v-if="!mode && modelValue.method === 'POST'" class="form-item mt-8">
         <label>请求体</label>
         <!-- <t-textarea
           v-model="modelValue.body"
@@ -114,6 +128,13 @@
           style="height: 50px"
         />
       </div>
+      <div
+        v-if="!mode && modelValue.method === 'POST'"
+        class="form-item mt-8 desc"
+      >
+        <label></label>
+        支持设置动态参数,例如:{"value": "${value}"}
+      </div>
     </template>
     <template v-else>
       <div class="form-item mt-8">
@@ -264,6 +285,26 @@ const onDelNetWork = async (item: any, i: number) => {
     networkList.value.splice(i, 1);
   }
 };
+
+const isSafeProtocol = () => {
+  return document.location.protocol === 'https:' ? true : false;
+};
+
+const urlFormat = (val) => {
+  if (modelValue.protocol === 'mqtt') {
+    let reg = /^ws\:.*/;
+    if (isSafeProtocol()) {
+      reg = /^wss\:.*/;
+    }
+    if (reg.test(val)) {
+      return val;
+    } else {
+      return '';
+    }
+  } else {
+    return val;
+  }
+};
 </script>
 <style lang="postcss" scoped>
 .network-component {

+ 9 - 1
src/views/components/PenAnimates.vue

@@ -173,6 +173,7 @@
                 class="ml-8 mt-8"
                 size="small"
                 v-model="item.autoPlay"
+                @change="changeAnimateAutoPlay($event,item)"
               />
             </div>
             <div
@@ -223,7 +224,14 @@ import AnimateFrames from './AnimateFrames.vue';
 const props = defineProps<{
   pen: any;
 }>();
-
+function changeAnimateAutoPlay(value,item) {
+  props.pen.animations.forEach(i=>{
+    if(i.name !== item.name){
+      i.autoPlay = false
+    }
+  })
+  item.autoPlay = true
+}
 const penTree: any = ref([]);
 
 const openedCollapses = ref([0]);

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

@@ -825,6 +825,7 @@ const onSelectBindsChange = (value: string[], options: any) => {
     dataBindDialog.selectedIds = value;
     dataBindDialog.data.bind = toRaw(options.selectedRowData[0]);
     dataBindDialog.data.mock = dataBindDialog.data.bind.mock;
+    dataBindDialog.data.type = dataBindDialog.data.bind.type;
     doBindInit();
   } else if (options.type === 'uncheck') {
     dataBindDialog.selectedIds = [];

+ 16 - 2
src/views/components/PenEvents.vue

@@ -9,8 +9,19 @@
       >
         <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 />
+            <div @click.stop class="head flex">
+              <t-select
+                v-model="item.name"
+                style="width: 40%"
+                :options="options"
+                autoWidth
+              />
+              <t-input
+                v-if="item.name === 'message'"
+                style="width: 40%"
+                v-model="item.message"
+                placeholder="消息名"
+              />
             </div>
           </template>
           <template #headerRightContent>
@@ -124,6 +135,9 @@ onBeforeMount(() => {
 });
 
 const addEvent = (e: any) => {
+  if (!props.pen.events) {
+    props.pen.events = [];
+  }
   props.pen.events.push({ name: e.value });
 };
 

+ 22 - 0
src/views/components/PenProps.vue

@@ -742,6 +742,13 @@
                   >
                     隐藏文字
                   </t-checkbox>
+                  <t-checkbox
+                    v-model="data.pen.textAutoAdjust"
+                    @change="changeValue('textAutoAdjust')"
+                    style="width: 90px"
+                  >
+                    自动调整
+                  </t-checkbox>
                 </div>
               </t-space>
             </t-collapse-panel>
@@ -760,6 +767,7 @@
                     accept="image/*"
                     :headers="headers"
                     :data="updataData"
+                    :before-upload="beforeUpload"
                     draggable
                     @success="fileSuccessed"
                     @remove="fileRemoved"
@@ -1068,7 +1076,9 @@ import { useSelection } from '@/services/selections';
 import { autoSave, fonts, inTreePanel } from '@/services/common';
 import { updatePen } from './pen';
 import { MessagePlugin } from 'tdesign-vue-next';
+import { useUser } from '@/services/user';
 
+const { user } = useUser();
 const headers = {
   Authorization: 'Bearer ' + (localStorage.token || getCookie('token') || ''),
 };
@@ -1218,6 +1228,18 @@ const onFontFamily = (fontFamily: string) => {
   changeValue('fontFamily');
 };
 
+const beforeUpload = (file: any) => {
+  // if (file.size > 5 * 1024 * 1024) {
+  //   MessagePlugin.warning('上传的图片不能大于5M');
+  //   return false;
+  // }
+  if (!(user && user.id)) {
+    MessagePlugin.warning('请先登录!');
+    return false;
+  }
+  return true;
+};
+
 const fileSuccessed = async (content: any) => {
   // meta2d.store.patchFlagsBackground = true;
   // meta2d.setBackgroundImage(content.response.url);

+ 41 - 16
src/views/components/View.vue

@@ -286,17 +286,27 @@
       @close="dataDialog.show = false"
     >
       <t-tabs v-model="dataDialog.tab" class="body">
-        <t-tab-panel :value="1" label="实时数据" :destroy-on-hide="false">
+        <t-tab-panel :value="1" label="数据通信" :destroy-on-hide="false">
           <template #panel>
             <div v-if="!dataDialog.editNetwork">
               <div class="mt-16 flex between middle">
                 <div>
                   <t-checkbox
+                    style="display: inline"
                     v-model="dataDialog.enableMock"
                     @change="onChangeMock"
                   >
                     开启模拟数据
                   </t-checkbox>
+                  <label class="ml-8"> 时间间隔 </label>
+                  <t-input-number
+                    style="width: 100px"
+                    v-model="dataDialog.networkInterval"
+                    theme="normal"
+                    :min="30"
+                    placeholder="毫秒"
+                    suffix="ms"
+                  />
                 </div>
                 <div>
                   <t-select-input
@@ -373,7 +383,7 @@
                   {{ row.protocol || 'MQTT' }}
                 </template>
                 <template #actions="{ row, rowIndex }">
-                  <a @click="editNetwork(row)"> 编辑 </a>
+                  <a @click="editNetwork(row, rowIndex)"> 编辑 </a>
                   <a class="ml-12" @click="deleteNetwork(rowIndex)"> 删除 </a>
                 </template>
                 <template #empty>
@@ -406,17 +416,17 @@
           </template>
         </t-tab-panel>
         <t-tab-panel :value="2" :destroy-on-hide="false">
-          <template #label> 数据 </template>
+          <template #label> 数据模型 </template>
           <template #panel>
             <template v-if="!dataDialog.editDataset">
               <div class="form-item mt-16">
-                <label style="width: 100px"> 当前数据 </label>
+                <label style="width: 100px"> 当前数据模型 </label>
                 <div class="flex w-full">
                   <t-select
                     class="flex-grow"
                     v-model="dataDialog.datasetId"
                     filterable
-                    placeholder="选择数据"
+                    placeholder="选择数据模型"
                     :on-search="onInputDatasets"
                     :popup-props="{ overlayClassName: 'select-options' }"
                     @change="onSelDataset()"
@@ -451,7 +461,7 @@
                     style="height: 30px"
                     @click="addDataset"
                   >
-                    添加数据
+                    添加数据模型
                   </t-button>
                 </div>
               </div>
@@ -473,8 +483,10 @@
               <div class="mt-8">
                 <a
                   @click="
-                    dataDialog.dataset = dataDialog.datasetBak;
-                    dataDialog.datasetId = dataDialog.dataset.id;
+                    dataDialog.datasetBak &&
+                      (dataDialog.dataset = dataDialog.datasetBak);
+                    dataDialog.dataset &&
+                      (dataDialog.datasetId = dataDialog.dataset.id);
                     dataDialog.editDataset = 0;
                   "
                   class="flex middle"
@@ -506,18 +518,21 @@
           <template v-if="dataDialog.editDataset === 1">
             <div class="flex-grow"></div>
             <t-checkbox v-model="dataDialog.save" class="mr-12">
-              同时保存为我的数据
+              同时保存为我的数据模型
             </t-checkbox>
             <t-button @click="onOkDataset()">保存</t-button>
           </template>
           <template v-else-if="dataDialog.editDataset === 2">
             <div class="flex-grow"></div>
-            <t-button @click="onOkDataset(true)"> 另外为新数据 </t-button>
+            <t-button @click="onOkDataset(true)"> 另外为新数据模型 </t-button>
             <t-button @click="onOkDataset()">保存</t-button>
           </template>
           <template v-else>
-            <a v-if="dataDialog.dataset.id" @click="editDataset">
-              编辑当前数据集
+            <a
+              v-if="dataDialog.dataset && dataDialog.dataset.id"
+              @click="editDataset"
+            >
+              编辑当前数据模型
             </a>
             <div class="flex-grow"></div>
 
@@ -1187,6 +1202,7 @@ const onShowDataDialog = async () => {
   dataDialog.datasetId = dataDialog.dataset.id;
   // @ts-ignore
   dataDialog.enableMock = meta2d.store.data.enableMock;
+  dataDialog.networkInterval = meta2d.store.data.networkInterval;
   dataDialog.networkList = [];
   dataDialog.datasetList = [];
   dataDialog.editNetwork = false;
@@ -1199,6 +1215,9 @@ const onShowDataDialog = async () => {
 
 const onFinishDataDialog = () => {
   dataDialog.show = false;
+  if (dataDialog.networkInterval) {
+    meta2d.store.data.networkInterval = dataDialog.networkInterval;
+  }
   meta2d.connectNetwork();
 };
 
@@ -1266,7 +1285,7 @@ const onInputDatasets = (name: string) => {
   debounce(getDatasets, 300, name);
 };
 
-// 请求我的数据
+// 请求我的数据模型
 const getDatasets = async (name?: string) => {
   const body: any = {
     query: {
@@ -1315,10 +1334,11 @@ const addNetwork = () => {
   dataDialog.editNetwork = 1;
 };
 
-const editNetwork = (data: any) => {
+const editNetwork = (data: any, index: number) => {
   dataDialog.networkBak = data;
   dataDialog.network = JSON.parse(JSON.stringify(data));
   dataDialog.editNetwork = 2;
+  dataDialog.editNetworkIndex = index;
 };
 
 const deleteNetwork = (index: number) => {
@@ -1353,13 +1373,18 @@ const onOkNetwork = async () => {
         return;
       }
     }
+    //替换
+    let index = dataDialog.editNetworkIndex;
+    if (index !== undefined) {
+      dataDialog.networks.splice(index, 1, dataDialog.network);
+      dataDialog.networkList.splice(index, 1, dataDialog.network);
+    }
   }
-
+  dataDialog.editNetwork = false;
   meta2d.store.data.networks = dataDialog.networks;
   meta2d.connectNetwork();
   setDot(true);
 
-  dataDialog.editNetwork = false;
   delete dataDialog.networkBak;
 };