Browse Source

Merge remote-tracking branch 'zkqyOrigin/master'

# Conflicts:
#	zkqy-ui/src/api/bpmprocess/process.js
lucky 3 weeks ago
parent
commit
2cfaac8229
29 changed files with 3429 additions and 1271 deletions
  1. 91 34
      zkqy-admin/src/main/resources/sql/initialize_sys_tenant_menu_i18n.json
  2. 1 1
      zkqy-system/src/main/resources/mapper/system/SysMenuMapper.xml
  3. 185 37
      zkqy-ui/node_modules/k-form-design/packages/components/KChangeOption/index.vue
  4. 54 115
      zkqy-ui/node_modules/k-form-design/packages/components/KFormBuild/buildBlocks.vue
  5. 38 35
      zkqy-ui/node_modules/k-form-design/packages/components/KFormBuild/index.vue
  6. 11 4
      zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/index.vue
  7. 1 0
      zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/module/formComponentPanel.vue
  8. 218 377
      zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/module/formItemProperties.vue
  9. 38 4
      zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/module/layoutItem.vue
  10. 3 2
      zkqy-ui/node_modules/k-form-design/packages/components/KFormPreview/index.vue
  11. 9 0
      zkqy-ui/src/api/bpmprocess/process.js
  12. 24 5
      zkqy-ui/src/api/formCreateMange/mobilePageDesignData.js
  13. 73 0
      zkqy-ui/src/api/system/table.js
  14. 11 0
      zkqy-ui/src/lang/en.js
  15. 13 2
      zkqy-ui/src/lang/zh.js
  16. 2 2
      zkqy-ui/src/views/asEditor/components/realTimeView/index.vue
  17. 1 1
      zkqy-ui/src/views/asEditor/components/uploadImg/index.vue
  18. 0 1
      zkqy-ui/src/views/asEditor/layout/home/pageDesign.vue
  19. 52 0
      zkqy-ui/src/views/excelSheet/components/DynamicButtonGroup.vue
  20. 230 0
      zkqy-ui/src/views/excelSheet/components/DynamicForm.vue
  21. 212 0
      zkqy-ui/src/views/excelSheet/index.vue
  22. 1617 0
      zkqy-ui/src/views/excelSheetEdit/index.vue
  23. 2 5
      zkqy-ui/src/views/formCreate/layout/home/formCreateMange.vue
  24. 388 131
      zkqy-ui/src/views/formCreate/utils/index.js
  25. 66 61
      zkqy-ui/src/views/tableMange/index.vue
  26. 0 6
      zkqy-ui/src/views/treeTable/index.vue
  27. 86 3
      zkqy-ui/src/views/treeTableMange/index.vue
  28. 0 442
      zkqy-ui/ss.html
  29. 3 3
      zkqy-ui/vue.config.js

+ 91 - 34
zkqy-admin/src/main/resources/sql/initialize_sys_tenant_menu_i18n.json

@@ -1375,17 +1375,17 @@
     "updateBy": null,
     "updateTime": null,
     "remark": null,
-    "menuId": 4216,
-    "menuName": "生产管理",
+    "menuId": 11445,
+    "menuName": "电子表格",
     "parentName": null,
     "parentId": 0,
-    "orderNum": 2,
-    "path": "processMange",
-    "component": null,
+    "orderNum": 4,
+    "path": "excelSheet",
+    "component": "excelSheet/excel",
     "query": null,
     "isFrame": "1",
     "isCache": "0",
-    "menuType": "M",
+    "menuType": "C",
     "visible": "0",
     "status": "0",
     "perms": "",
@@ -1425,6 +1425,34 @@
     "tenantId": null,
     "menuNameEn": "Pending Approval"
   },
+  {
+    "createBy": null,
+    "createTime": "2023-10-11 01:28:10",
+    "updateBy": null,
+    "updateTime": null,
+    "remark": null,
+    "menuId": 4216,
+    "menuName": "生产管理",
+    "parentName": null,
+    "parentId": 0,
+    "orderNum": 2,
+    "path": "processMange",
+    "component": null,
+    "query": null,
+    "isFrame": "1",
+    "isCache": "0",
+    "menuType": "M",
+    "visible": "0",
+    "status": "0",
+    "perms": "",
+    "icon": "bpmn-icon-end-event-error",
+    "children": [
+
+    ],
+    "tenantName": null,
+    "tenantId": null,
+    "menuNameEn": "Production Management"
+  },
   {
     "createBy": null,
     "createTime": "2023-10-11 01:28:10",
@@ -1817,34 +1845,6 @@
     "tenantId": null,
     "menuNameEn": "Mobile Engine"
   },
-  {
-    "createBy": null,
-    "createTime": "2023-10-11 01:28:10",
-    "updateBy": null,
-    "updateTime": null,
-    "remark": null,
-    "menuId": 11444,
-    "menuName": "导航条配置",
-    "parentName": null,
-    "parentId": 9574,
-    "orderNum": 1,
-    "path": "navigationBar",
-    "component": "formCreate/layout/home/navigationBar",
-    "query": null,
-    "isFrame": "1",
-    "isCache": "0",
-    "menuType": "C",
-    "visible": "0",
-    "status": "0",
-    "perms": "",
-    "icon": "bpmn-icon-intermediate-event-catch-cancel",
-    "children": [
-
-    ],
-    "tenantName": null,
-    "tenantId": null,
-    "menuNameEn": "Navigation Bar Config"
-  },
   {
     "createBy": null,
     "createTime": "2023-10-11 01:28:10",
@@ -1957,6 +1957,62 @@
     "tenantId": null,
     "menuNameEn": "Tree Table"
   },
+  {
+    "createBy": null,
+    "createTime": "2025-03-08 15:22:00",
+    "updateBy": null,
+    "updateTime": null,
+    "remark": null,
+    "menuId": 15004,
+    "menuName": "电子表格",
+    "parentName": null,
+    "parentId": 1103,
+    "orderNum": 5,
+    "path": "excelSheet",
+    "component": "excelSheet/index",
+    "query": null,
+    "isFrame": "1",
+    "isCache": "0",
+    "menuType": "C",
+    "visible": "0",
+    "status": "0",
+    "perms": "",
+    "icon": "form",
+    "children": [
+
+    ],
+    "tenantName": null,
+    "tenantId": null,
+    "menuNameEn": "excel"
+  },
+  {
+    "createBy": null,
+    "createTime": "2025-03-08 15:22:00",
+    "updateBy": null,
+    "updateTime": null,
+    "remark": null,
+    "menuId": 15005,
+    "menuName": "电子表格编辑",
+    "parentName": null,
+    "parentId": 1103,
+    "orderNum": 5,
+    "path": "excelSheetEdit",
+    "component": "excelSheetEdit/index",
+    "query": null,
+    "isFrame": "1",
+    "isCache": "0",
+    "menuType": "C",
+    "visible": "1",
+    "status": "0",
+    "perms": "",
+    "icon": "form",
+    "children": [
+
+    ],
+    "tenantName": null,
+    "tenantId": null,
+    "menuNameEn": "excel edit"
+  },
   {
     "createBy": null,
     "createTime": "2025-03-08 15:22:01",
@@ -1985,4 +2041,5 @@
     "tenantId": null,
     "menuNameEn": "Tree Table Edit"
   }
+
 ]

+ 1 - 1
zkqy-system/src/main/resources/mapper/system/SysMenuMapper.xml

@@ -46,7 +46,7 @@
                ifnull(perms, '') as perms,
                icon,
                create_time
-        from sys_menu_default
+        from sys_menu
     </sql>
 
     <select id="selectMenuList" parameterType="com.zkqy.common.core.domain.entity.SysMenu" resultMap="SysMenuResult">

+ 185 - 37
zkqy-ui/node_modules/k-form-design/packages/components/KChangeOption/index.vue

@@ -2,24 +2,22 @@
   <div class="option-change-container">
     <a-row v-if="type === 'option' || type === 'tab'" :gutter="8">
       <div class="option-change-box" v-for="(val, index) in value" :key="index">
-        <a-col :span="9"><Input v-model="val.label" placeholder="名称"/></a-col>
+        <a-col :span="9"><Input v-model="val.label" placeholder="名称" /></a-col>
         <a-col :span="9">
           <!-- <Input v-model="val.value" placeholder="值"/> -->
           <el-select v-model="val.value" placeholder="请选择" filterable>
-            <el-option
-              v-for="item in tableList"
-              :key="item.tableName"
-              :label="item.tableComment"
+            <el-option v-for="item in tableList" :key="item.tableName" :label="item.tableComment"
               :value="item.tableName">
               <span class="discribe" style="float: left">{{ item.tableComment }}</span>
-      <span style="float: right; color: #8492a6; font-size: 13px">{{ item.tableName }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.tableName }}</span>
             </el-option>
           </el-select>
-          </a-col>
-        <a-col :span="6"
-          ><div @click="handleDelete(index)" class="option-delete-box">
-            <a-icon type="delete" /></div
-        ></a-col>
+        </a-col>
+        <a-col :span="6">
+          <div @click="handleDelete(index)" class="option-delete-box">
+            <a-icon type="delete" />
+          </div>
+        </a-col>
       </div>
       <a-col :span="24"><a @click="handleAdd">添加</a></a-col>
     </a-row>
@@ -27,33 +25,61 @@
     <a-row v-if="type === 'rules'" :gutter="8">
       <span v-for="(val, index) in value" :key="index">
         <div class="option-change-box" v-if="index !== 0">
-          <a-col :span="18"
-            ><Input v-model="val.message" placeholder="提示信息"
-          /></a-col>
-          <a-col :span="18"
-            ><Input v-model="val.pattern" placeholder="正则表达式pattern"
-          /></a-col>
-          <a-col :span="6"
-            ><div @click="handleDelete(index)" class="option-delete-box">
-              <a-icon type="delete" /></div
-          ></a-col>
+          <a-col :span="18"><Input v-model="val.message" placeholder="提示信息" /></a-col>
+          <a-col :span="18"><Input v-model="val.pattern" placeholder="正则表达式pattern" /></a-col>
+          <a-col :span="6">
+            <div @click="handleDelete(index)" class="option-delete-box">
+              <a-icon type="delete" />
+            </div>
+          </a-col>
         </div>
       </span>
       <a-col :span="24"><a @click="handleAddRules">增加校验</a></a-col>
     </a-row>
     <a-row v-else-if="type === 'colspan'" :gutter="8">
       <div class="option-change-box" v-for="(val, index) in value" :key="index">
-        <a-col :span="18"
-          ><InputNumber
-            style="width:100%"
-            :max="24"
-            v-model="val.span"
-            placeholder="名称"
-        /></a-col>
-        <a-col :span="6"
-          ><div @click="handleDelete(index)" class="option-delete-box">
-            <a-icon type="delete" /></div
-        ></a-col>
+        <a-col :span="18">
+          <InputNumber style="width:100%" :max="24" v-model="val.span" placeholder="名称" />
+        </a-col>
+        <a-col :span="6">
+          <div @click="handleDelete(index)" class="option-delete-box">
+            <a-icon type="delete" />
+          </div>
+        </a-col>
+      </div>
+      <a-col :span="24"><a @click="handleAddCol">添加</a></a-col>
+    </a-row>
+    <a-row v-else-if="type === 'column'" :gutter="8">
+      <div class="option-change-box" v-for="(val, index) in value" :key="index">
+        <a-col :span="9"><Input style="width:100%" :max="12" v-model="val.label" placeholder="描述" :disabled ="val.type  ===  'result'"/></a-col>
+        <a-col :span="9">
+          <el-select v-model="val.prop" filterable size="mini" @focus="editTableColumnsJSBG"
+            @change="changeTableColumnsJSBG" :disabled ="val.type  ===  'result'">
+            <el-option v-for="item in formListListName" :key="item.value" :label="item.label" :value="item.value">
+              <span style="float: left">{{ item.label }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.fieldDescription }}</span>
+            </el-option>
+          </el-select>
+        </a-col>
+        <a-col :span="18"><Input style="width:100%" :max="8" v-model="val.type" placeholder="类型"
+            @change="changeTableColumnsJSBG" :disabled ="val.type  ===  'result'"/></a-col>
+        <a-col :span="24" v-if="val.type == 'select'">
+          <div class="option-change-box" v-for="(selectItem, selectKey) in val.list" :key="selectKey">
+            <a-col :span="9"><Input v-model="selectItem.label" placeholder="名称" /></a-col>
+            <a-col :span="9"><Input v-model="selectItem.value" placeholder="值" /></a-col>
+            <a-col :span="6">
+              <div @click="handleSelectDelete(index, selectKey)" class="option-delete-box">
+                <a-icon type="delete" />
+              </div>
+            </a-col>
+          </div>
+          <a-col :span="24"><a @click="handleSelectAdd(index)">添加选项</a></a-col>
+        </a-col>
+        <a-col :span="4">
+          <div @click="handleDelete(index)" class="option-delete-box">
+            <a-icon type="delete" />
+          </div>
+        </a-col>
       </div>
       <a-col :span="24"><a @click="handleAddCol">添加</a></a-col>
     </a-row>
@@ -67,6 +93,8 @@ import { mounted } from 'vue2-ace-editor'
  * description 修改多选、下拉、单选等控件options的组件,添加移除校验规制的组件
  */
 import { getUncommonTable } from '@/utils/other';
+import { containsSelectFollowedByNumbers } from '@/components/customControl/utils/tool.js'
+
 import { pluginManager } from "../../utils/index";
 const Input = pluginManager.getComponent("input").component;
 const InputNumber = pluginManager.getComponent("number").component;
@@ -87,18 +115,28 @@ export default {
       type: String,
       default: "option"
     },
-    tableList:{
+    tableList: {
       type: Array,
-      default:()=>[],
-    }
+      default: () => [],
+    },
+    formListListName: {
+      type: Array,
+      default: () => [],
+    },
+    selectItem: {
+      type: Object,
+    },
   },
   data() {
     return {
       // tableOptions: [],
+      // debouncedChangeTableColumnsJSBG: null,
     }
   },
   mounted() {
+    // console.log('[selectItem]',this.selectItem)
     // this.getTableList();
+    // this.debouncedChangeTableColumnsJSBG = this.debounce(this.changeTableColumnsJSBG, 500);
   },
   methods: {
     // 获取表格list
@@ -107,7 +145,7 @@ export default {
         ... this.$store.state.user.dataSource
       }
       let res = await getUncommonTable()
-      this.tableOptions=res||[]
+      this.tableOptions = res || []
     },
     handleAdd() {
       // 添加
@@ -132,6 +170,28 @@ export default {
       ];
       this.$emit("input", addData);
     },
+    handleSelectDelete(key, selectKey) {
+      console.log("delete", key, selectKey);
+      console.log("this.value[key].list", this.value[key].list);
+      this.value[key].list = this.value[key].list.filter(
+        (val, index) => index !== selectKey
+      );
+      this.$emit("input", this.value);
+    },
+    handleSelectAdd(index) {
+      // 添加
+      const addData = [...this.value];
+
+      addData[index].list = [
+        ...addData[index].list,
+        {
+          value: `${addData[index].list.length + 1}`,
+          label: "选项" + (addData[index].list.length + 1)
+        }
+      ];
+      console.log("addData/", addData);
+      this.$emit("input", addData);
+    },
     handleAddRules() {
       const addData = [
         ...this.value,
@@ -148,7 +208,95 @@ export default {
         "input",
         this.value.filter((val, index) => index !== deleteIndex)
       );
-    }
+    },
+    // 当点击计算表格的prop下拉框时
+    editTableColumnsJSBG() {
+      if (this.formListListName.length == 0) {
+        this.$message.warning('请先选择表名')
+        return
+      }
+    },
+    //   someMethodThatCallsChangeTableColumnsJSBG(value) {
+    //   this.debouncedChangeTableColumnsJSBG(value);
+    // },
+    changeTableColumnsJSBG(value) {
+      if (this.selectItem.tableName && this.selectItem.type === "calculation_table") {
+        const updatedColumns = this.selectItem.options.tableColumns.map(item => {
+          if (item.type.trim() === 'select0') {
+            console.log('[type是select0时调接口传表名和id名字]', item, item.prop, this.selectItem.tableName);
+            return this.fetchThreeLevelSelectData(this.selectItem.tableName, item.prop).then(data => {
+              return {
+                ...item,
+                prop: item.prop,
+                list: data.data
+              };
+            });
+          } else {
+            // console.log("[value-------------------]", value.target.value)
+
+          }
+
+          return Promise.resolve(item);
+        });
+
+        Promise.all(updatedColumns).then(newColumns => {
+          this.selectItem.options.tableColumns = newColumns;
+        }).catch(error => {
+          console.error('Error updating table columns:', error);
+        });
+
+
+      } else {
+        console.log('[changeTableColumnsJSBG] No matching conditions.');
+      }
+    },
+    // 模拟调用接口获取三级select数据
+    async fetchThreeLevelSelectData(tableName, prop) {
+      // 这里是模拟的数据结构,实际应用中应替换为API调用
+      const mockData = {
+        data: [
+          {
+            prop: 'id', value: 'level1Value1', label: '浙江省', children: [
+              {
+                value: 'level2Value1', label: '杭州市', children: [
+                  {
+                    value: 'level3Value1', label: '余杭区', children: [
+                      { value: 'level4Value1', label: 'xx1街道' },
+                      { value: 'level4Value2', label: 'xx2街道' }
+                    ]
+                  },
+                  { value: 'level3Value2', label: '萧山区', children: [
+                      { value: 'level4Value1', label: '临浦镇' },
+                      { value: 'level4Value2', label: '浦阳镇' }
+                    ] }
+                ]
+              },
+              {
+                value: 'level2Value2', label: '宁波市', children: [
+                  { value: 'level3Value3', label: '海曙区' }
+                ]
+              }
+            ]
+          },
+          {
+            prop: 'id', value: 'level1Value2', label: '四川省', children: [
+              {
+                value: 'level2Value3', label: '成都市', children: [
+                  { value: 'level3Value4', label: '高新区' }
+                ]
+              }
+            ]
+          }
+        ]
+      };
+      return mockData
+    },
+    checkSelectFollowedByNumbers(str) {
+      return containsSelectFollowedByNumbers(str);
+    },
+    debounce(func, wait) {
+      return debounce(func, wait);
+    },
   }
 };
 </script>

+ 54 - 115
zkqy-ui/node_modules/k-form-design/packages/components/KFormBuild/buildBlocks.vue

@@ -1,130 +1,59 @@
 <template>
   <!-- 标签页布局 -->
-  <a-tabs
-    v-if="record.type === 'tabs'"
-    class="grid-row"
-    :default-active-key="0"
-    :tabBarGutter="record.options.tabBarGutter"
-    :type="record.options.type"
-    :size="record.options.size"
-    :tabPosition="record.options.tabPosition"
-    :animated="record.options.animated"
-    v-model="activeKey"
-  >
-    <a-tab-pane
-      v-for="(tabItem, index) in record.columns"
-      :key="index"
-      :tab="tabItem.label"
-      :forceRender="true"
-    >
-      <buildBlocks
-        ref="nestedComponents"
-        @handleReset="$emit('handleReset')"
-        @change="handleChange"
-        v-for="item in tabItem.list"
-        :disabled="disabled"
-        :dynamicData="dynamicData"
-        :key="item.key"
-        :record="item"
-        :formConfig="formConfig"
-        :config="config"
-      />
+  <a-tabs v-if="record.type === 'tabs'" class="grid-row" :default-active-key="0"
+    :tabBarGutter="record.options.tabBarGutter" :type="record.options.type" :size="record.options.size"
+    :tabPosition="record.options.tabPosition" :animated="record.options.animated" v-model="activeKey">
+    <a-tab-pane v-for="(tabItem, index) in record.columns" :key="index" :tab="tabItem.label" :forceRender="true">
+      <buildBlocks ref="nestedComponents" @handleReset="$emit('handleReset')" @change="handleChange"
+        v-for="item in tabItem.list" :disabled="disabled" :dynamicData="dynamicData" :key="item.key" :record="item"
+        :formConfig="formConfig" :config="config" />
     </a-tab-pane>
   </a-tabs>
   <!-- 栅格布局 -->
-  <a-row
-    v-else-if="record.type === 'grid'"
-    class="grid-row"
-    :gutter="record.options.gutter"
-  >
-    <a-col
-      class="grid-col"
-      v-for="(colItem, idnex) in record.columns"
-      :key="idnex"
-      :span="colItem.span || 0"
-    >
-      <buildBlocks
-        ref="nestedComponents"
-        @handleReset="$emit('handleReset')"
-        @change="handleChange"
-        v-for="item in colItem.list"
-        :disabled="disabled"
-        :dynamicData="dynamicData"
-        :key="item.key"
-        :record="item"
-        :formConfig="formConfig"
-        :config="config"
-      />
+  <a-row v-else-if="record.type === 'grid'" class="grid-row" :gutter="record.options.gutter">
+    <a-col class="grid-col" v-for="(colItem, idnex) in record.columns" :key="idnex" :span="colItem.span || 0">
+      <buildBlocks ref="nestedComponents" @handleReset="$emit('handleReset')" @change="handleChange"
+        v-for="item in colItem.list" :disabled="disabled" :dynamicData="dynamicData" :key="item.key" :record="item"
+        :formConfig="formConfig" :config="config" />
     </a-col>
   </a-row>
   <!-- 卡片布局 -->
-  <a-card
-    v-else-if="record.type === 'card'"
-    class="grid-row"
-    :title="record.label"
-  >
-    <buildBlocks
-      ref="nestedComponents"
-      @handleReset="$emit('handleReset')"
-      @change="handleChange"
-      v-for="item in record.list"
-      :disabled="disabled"
-      :dynamicData="dynamicData"
-      :key="item.key"
-      :record="item"
-      :formConfig="formConfig"
-      :config="config"
-    />
+  <a-card v-else-if="record.type === 'card'" class="grid-row" :title="record.label">
+    <buildBlocks ref="nestedComponents" @handleReset="$emit('handleReset')" @change="handleChange"
+      v-for="item in record.list" :disabled="disabled" :dynamicData="dynamicData" :key="item.key" :record="item"
+      :formConfig="formConfig" :config="config" />
   </a-card>
   <!-- 表格布局 -->
-  <table
-    v-else-if="record.type === 'table'"
-    class="kk-table-9136076486841527"
-    :class="{
-      bright: record.options.bright,
-      small: record.options.small,
-      bordered: record.options.bordered
-    }"
-    :style="'width:' + record.options.width + ';' + record.options.customStyle"
-  >
+
+  <table v-else-if="record.type === 'table'" class="kk-table-9136076486841527" :class="{
+    bright: record.options.bright,
+    small: record.options.small,
+    bordered: record.options.bordered
+  }" :style="'width:' + record.options.width + ';' + record.options.customStyle">
     <tr v-for="(trItem, trIndex) in record.trs" :key="trIndex">
-      <td
-        class="table-td"
-        v-for="(tdItem, tdIndex) in trItem.tds.filter(
-          item => item.colspan && item.rowspan
-        )"
-        :key="tdIndex"
-        :colspan="tdItem.colspan"
-        :rowspan="tdItem.rowspan"
-      >
-        <buildBlocks
-          ref="nestedComponents"
-          @handleReset="$emit('handleReset')"
-          @change="handleChange"
-          v-for="item in tdItem.list"
-          :disabled="disabled"
-          :dynamicData="dynamicData"
-          :key="item.key"
-          :record="item"
-          :formConfig="formConfig"
-          :config="config"
-        />
+      <td class="table-td" v-for="(tdItem, tdIndex) in trItem.tds.filter(
+    item => item.colspan && item.rowspan
+  )" :key="tdIndex" :colspan="tdItem.colspan" :rowspan="tdItem.rowspan">
+        <buildBlocks ref="nestedComponents" @handleReset="$emit('handleReset')" @change="handleChange"
+          v-for="item in tdItem.list" :disabled="disabled" :dynamicData="dynamicData" :key="item.key" :record="item"
+          :formConfig="formConfig" :config="config" />
       </td>
     </tr>
   </table>
 
-  <KFormItem
-    v-else-if="!record.options.hidden"
-    ref="nestedComponents"
-    @handleReset="$emit('handleReset')"
-    @change="handleChange"
-    :disabled="disabled"
-    :dynamicData="dynamicData"
-    :key="record.key"
-    :record="record"
-    :formConfig="formConfig"
-    :config="config"
-  />
+  <div v-else-if="record.type === 'calculation_table'">
+  
+    <Tabulation :tableColumns="record.options.tableColumns" :disabled="record.options.disabled" 
+      :showAddButton="record.options.showAddButton" :showSummary="record.options.showSummary" @change="handleChange"
+      :formula="record.options.formula" :tableColor="record.options.tableColor"
+      :tableTextColor="record.options.tableTextColor" :tableValue="tableValue" />
+    <buildBlocks ref="nestedComponents" @handleReset="$emit('handleReset')" @change="handleChange"
+      v-for="item in record.list" :disabled="disabled" :dynamicData="dynamicData" :key="item.key" :record="item"
+      :formConfig="formConfig" :config="config" />
+  </div>
+  <KFormItem v-else-if="!record.options.hidden" ref="nestedComponents" @handleReset="$emit('handleReset')"
+    @change="handleChange" :disabled="disabled" :dynamicData="dynamicData" :key="record.key" :record="record"
+    :formConfig="formConfig" :config="config" />
 </template>
 <script>
 /*
@@ -132,6 +61,8 @@
  * date 2019-11-20
  */
 import KFormItem from "../KFormItem/index";
+import Tabulation from "@/components/customControl/Tabulation"
+
 export default {
   name: "buildBlocks",
   props: {
@@ -158,10 +89,17 @@ export default {
     validatorError: {
       type: [Object, null],
       default: () => ({})
-    }
+    },
+
+    tableValue: {
+      type: Array,
+      default: () => []
+    },
+    // tableValue
   },
   components: {
-    KFormItem
+    KFormItem,
+    Tabulation
   },
   data() {
     return {
@@ -189,6 +127,7 @@ export default {
       }
     },
     handleChange(value, key) {
+      console.log(111111,value)
       this.$emit("change", value, key);
     }
   },
@@ -199,7 +138,7 @@ export default {
      */
     validatorError: {
       deep: true,
-      handler: function(n) {
+      handler: function (n) {
         const errorItems = Object.keys(n);
         if (errorItems.length) {
           if (!this.record.columns) return false;

+ 38 - 35
zkqy-ui/node_modules/k-form-design/packages/components/KFormBuild/index.vue

@@ -1,31 +1,12 @@
 <template>
   <a-config-provider :locale="locale">
-    <a-form
-      v-bind="$attrs"
-      selfUpdate
-      v-if="
-        typeof value.list !== 'undefined' && typeof value.config !== 'undefined'
-      "
-      class="k-form-build-9136076486841527"
-      :layout="value.config.layout"
-      :hideRequiredMark="value.config.hideRequiredMark"
-      :form="form"
-      @submit="handleSubmit"
-      :style="value.config.customStyle"
-    >
-      <buildBlocks
-        ref="buildBlocks"
-        @handleReset="reset"
-        v-for="(record, index) in value.list"
-        :record="record"
-        :dynamicData="getDynamicData"
-        :config="config"
-        :disabled="disabled"
-        :formConfig="value.config"
-        :validatorError="validatorError"
-        :key="index"
-        @change="handleChange"
-      />
+    <a-form :model="value" selfUpdate v-if="typeof value.list !== 'undefined' && typeof value.config !== 'undefined'
+    " class="k-form-build-9136076486841527" :layout="value.config.layout"
+      :hideRequiredMark="value.config.hideRequiredMark" :form="form" @submit="handleSubmit"
+      :style="value.config.customStyle">
+      <buildBlocks ref="buildBlocks" @handleReset="reset" v-for="(record, index) in value.list" :record="record"
+        :dynamicData="getDynamicData" :config="config" :tableValue="record.tableData" :disabled="disabled"
+        :formConfig="value.config" :validatorError="validatorError" :key="index" @change="handleChange" />
     </a-form>
   </a-config-provider>
 </template>
@@ -44,7 +25,7 @@ export default {
   data() {
     return {
       locale: zhCN,
-      form: this.$form.createForm(this),
+      form: this.$form.createForm(this, { name: 'horizontal_login' }),
       validatorError: {},
       defaultDynamicData: {}
     };
@@ -110,11 +91,26 @@ export default {
       this.form.resetFields();
     },
     getData() {
-      console.log('this.form',this.form);
       // 提交函数,提供父级组件调用
+
       return new Promise((resolve, reject) => {
         try {
+          console.log('[--this.form--]', this.form)
+          // tableName
+          let myTbaleData = {}
           this.form.validateFields((err, values) => {
+            this.value.list.forEach((item, index) => {
+              if (item.key.includes('calculation_table')) {
+                console.log(item.tableData, '333333')
+                values[item.key] = item.tableData
+                
+              }
+            })
+            // console.log('1111',values);
+
+            // values=Object.a
+            // console.log('[--Inside validateFields callback--]', err, values);
+            // console.log('[--Form Fields--]', this.form.getFieldsValue()); // 打印表单字段的值
             if (err) {
               reject(err);
               /**
@@ -144,9 +140,9 @@ export default {
                   values[key] = `k-form-design#${type}#${String(values[key])}`;
                 }
               }
-
               resolve(values);
             } else {
+
               resolve(values);
             }
           });
@@ -155,7 +151,7 @@ export default {
         }
       });
     },
-    getselectData(){},
+    getselectData() { },
     setData(json) {
       return new Promise((resolve, reject) => {
         lazyLoadTick.nextTick(() => {
@@ -191,7 +187,6 @@ export default {
     // 批量设置某个option的值
     setOptions(fields, optionName, value) {
       fields = new Set(fields);
-
       // 递归遍历控件树
       const traverse = array => {
         array.forEach(element => {
@@ -236,15 +231,23 @@ export default {
     },
     handleChange(value, key) {
       // 触发change事件
+      console.log('handleChange', value);
+
       this.$emit("change", value, key);
     }
   },
   mounted() {
-    this.setData(this.defaultValue);
+    // this.setData(this.defaultValue);
+    // console.log('[--Form defaultValue--]', this.defaultValue);
+    this.$nextTick(() => {
+      setTimeout(() => {
+        console.log('[--Form Value--]', this.value);
+        console.log('[--Form Value--]', this.$attrs);
+        this.setData(this.value);
+
+      }, 2000);
 
-    // this.$nextTick(() => {
-    //   this.setData(this.defaultValue);
-    // });
+    });
   },
   created() {
     lazyLoadTick.reset();

+ 11 - 4
zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/index.vue

@@ -165,7 +165,7 @@ export default {
   props: {
     title: {
       type: String,
-      default: "表单设计器 --by kcz"
+      default: "表单设计器"
     },
     showHead: {
       type: Boolean,
@@ -220,7 +220,7 @@ export default {
         "table",
         "alert",
         "text",
-        "html"
+        "html",
       ],
       schemaGroup: [],
       data: {
@@ -349,6 +349,7 @@ export default {
     },
     handlePreview() {
       // 打开预览模态框
+      console.log('[打开预览模态框]',this.data,this.previewOptions.width)
       this.$refs.previewModal.jsonData = this.data;
       this.$refs.previewModal.previewWidth = this.previewOptions.width;
       this.$refs.previewModal.visible = true;
@@ -476,6 +477,7 @@ export default {
       window.localStorage.setItem("collapseDefaultActiveKey", val);
     },
     handleStart(type) {
+      // console.log('[handleStart]',type)
       this.startType = type;
     },
 
@@ -529,14 +531,19 @@ export default {
     }
   },
   created() {
-    let blackList=['评分','警告提示','HTML','富文本','按钮']
+    let blackList=['评分','警告提示','HTML','富文本','按钮','级联选择器']
     this.loadState = true;
     nodeSchema.addComputed(this.schemaGroup);
     this.schemaGroup = tempData;
-    console.log('this.schemaGroup',this.schemaGroup);
+    console.log('this.schemaGroup123',this.schemaGroup);
     this.schemaGroup[0].list = this.schemaGroup[0].list.filter(item => {
       return !blackList.some(v=>v==item.label)
     })
+    this.schemaGroup[0].list.forEach(item => {
+      if (item.label == '树形选择器') {
+        item.label='级联选择器'
+      }
+    })
   }
 };
 </script>

+ 1 - 0
zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/module/formComponentPanel.vue

@@ -498,6 +498,7 @@ export default {
     // 添加监听取消右键菜单
     document.addEventListener("click", this.handleRemoveRightMenu, true);
     document.addEventListener("contextmenu", this.handleRemoveRightMenu, true);
+    console.log('[this.data]',this.data)
   },
   destroyed() {
     // 移除监听

+ 218 - 377
zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/module/formItemProperties.vue

@@ -1,11 +1,7 @@
 <template>
   <div class="properties-centent kk-checkbox">
     <div class="properties-body">
-      <a-empty
-        class="hint-box"
-        v-show="selectItem.key === ''"
-        description="未选择控件"
-      />
+      <a-empty class="hint-box" v-show="selectItem.key === ''" description="未选择控件" />
 
       <a-form v-show="selectItem.key !== ''">
         <a-form-item v-if="isDefined(selectItem.label)" label="标签">
@@ -13,11 +9,8 @@
         </a-form-item>
 
         <!-- +++ -->
-        <a-form-item
-          v-if="!hideModel && isDefined(selectItem.model)"
-          label="表名"
-        >
-        <!-- <Select
+        <a-form-item v-if="!hideModel && isDefined(selectItem.model)" label="表名">
+          <!-- <Select
             v-model="formList.tableName"
             :fieldNames="{
               'label': tableComment, 'value': tableName
@@ -26,36 +19,23 @@
             mode="tags"
           /> -->
           <el-select v-model="selectItem.tableName" placeholder="请选择" filterable @change="getListName(selectItem)">
-            <el-option
-              v-for="item in formList.formName"
-              :key="item.tableName"
-              :label="item.tableComment"
+            <el-option v-for="item in formList.formName" :key="item.tableName" :label="item.tableComment"
               :value="item.tableName">
               <span class="discribe" style="float: left">{{ item.tableComment }}</span>
-      <span style="float: right; color: #8492a6; font-size: 13px">{{ item.tableName }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.tableName }}</span>
             </el-option>
           </el-select>
         </a-form-item>
-        <a-form-item
-          v-if="!hideModel && isDefined(selectItem.model) && isNeedColumn(selectItem)"
-          label="列名"
-        >
+        <a-form-item v-if="!hideModel && isDefined(selectItem.model) && isNeedColumn(selectItem)" label="列名">
           <el-select v-model="selectItem.model" @change="changeModel" filterable placeholder="请选择">
-            <el-option
-              v-for="item in formList.listName"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value">
+            <el-option v-for="item in formList.listName" :key="item.value" :label="item.label" :value="item.value">
               <span style="float: left">{{ item.label }}</span>
-      <span style="float: right; color: #8492a6; font-size: 13px">{{ item.fieldDescription }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.fieldDescription }}</span>
             </el-option>
           </el-select>
         </a-form-item>
-        <a-form-item
-          v-if="!hideModel && isDefined(selectItem.columns)"
-          label="编辑列"
-        >
-        <el-button type="primary" icon="el-icon-edit" @click="editTableColumns(selectItem)">编辑</el-button>
+        <a-form-item v-if="!hideModel && isDefined(selectItem.columns)" label="编辑列">
+          <el-button type="primary" icon="el-icon-edit" @click="editTableColumns(selectItem)">编辑</el-button>
           <!-- <el-select v-model="selectItem.model" @change="changeModel" filterable placeholder="请选择">
             <el-option
               v-for="item in formList.listName"
@@ -67,42 +47,24 @@
             </el-option>
           </el-select> -->
         </a-form-item>
-       
+
         <!-- input type start -->
         <a-form-item v-if="selectItem.type === 'input'" label="输入框type">
           <Input v-model="options.type" placeholder="请输入" />
         </a-form-item>
         <!-- input type end -->
-        <a-form-item
-          v-if="
-            typeof options.rangePlaceholder !== 'undefined' && options.range
-          "
-          label="占位内容"
-        >
+        <a-form-item v-if="typeof options.rangePlaceholder !== 'undefined' && options.range
+        " label="占位内容">
           <Input placeholder="请输入" v-model="options.rangePlaceholder[0]" />
           <Input placeholder="请输入" v-model="options.rangePlaceholder[1]" />
         </a-form-item>
 
-        <a-form-item
-          v-else-if="isDefined(options.placeholder)"
-          label="占位内容"
-        >
+        <a-form-item v-else-if="isDefined(options.placeholder)" label="占位内容">
           <Input placeholder="请输入" v-model="options.placeholder" />
         </a-form-item>
-        <a-form-item
-          v-if="selectItem.type === 'textarea'"
-          label="自适应内容高度"
-        >
-          <InputNumber
-            style="width: 100%"
-            v-model="options.minRows"
-            placeholder="最小高度"
-          />
-          <InputNumber
-            style="width: 100%"
-            v-model="options.maxRows"
-            placeholder="最大高度"
-          />
+        <a-form-item v-if="selectItem.type === 'textarea'" label="自适应内容高度">
+          <InputNumber style="width: 100%" v-model="options.minRows" placeholder="最小高度" />
+          <InputNumber style="width: 100%" v-model="options.maxRows" placeholder="最大高度" />
         </a-form-item>
         <a-form-item v-if="isDefined(options.width)" label="宽度">
           <Input placeholder="请输入" v-model="options.width" />
@@ -123,28 +85,15 @@
         <a-form-item v-if="isDefined(options.maxLength)" label="最大长度">
           <InputNumber v-model="options.maxLength" placeholder="请输入" />
         </a-form-item>
-        <a-form-item
-          v-if="
-            isDefined(options.minLimit) || ['batch'].includes(selectItem.type)
-          "
-          label="最小行数"
-        >
-          <InputNumber
-            v-model="options.minLimit"
-            :min="0"
-            placeholder="请输入"
-          />
+        <a-form-item v-if="isDefined(options.minLimit) || ['batch'].includes(selectItem.type)
+        " label="最小行数">
+          <InputNumber v-model="options.minLimit" :min="0" placeholder="请输入" />
         </a-form-item>
         <a-form-item v-if="isDefined(options.tabBarGutter)" label="标签间距">
           <InputNumber v-model="options.tabBarGutter" placeholder="请输入" />
         </a-form-item>
         <a-form-item v-if="isDefined(options.precision)" label="数值精度">
-          <InputNumber
-            :min="0"
-            :max="50"
-            v-model="options.precision"
-            placeholder="请输入"
-          />
+          <InputNumber :min="0" :max="50" v-model="options.precision" placeholder="请输入" />
         </a-form-item>
         <a-form-item v-if="isDefined(options.dictCode)" label="dictCode">
           <Input v-model="options.dictCode" />
@@ -157,34 +106,25 @@
             <RadioButton :value="true">动态数据</RadioButton>
           </Radio>
           <!-- <div class="dynamic-wrap"> -->
-            <Input
-            v-show="options.dynamic"
-            v-model="options.dynamicKey"
-            placeholder="动态数据变量名"
-          />
-          <OptionsEdit class="ml5 mt10" :dynamicKey="options.dynamicKey" v-show="options.dynamic&&options
-          .dynamicKey" @setDynamicKey="setDynamicKey" :options="options" :selectItem="selectItem"></OptionsEdit>
+          <Input v-show="options.dynamic" v-model="options.dynamicKey" placeholder="动态数据变量名" />
+          <OptionsEdit class="ml5 mt10" :dynamicKey="options.dynamicKey" v-show="options.dynamic && options
+        .dynamicKey" @setDynamicKey="setDynamicKey" :options="options" :selectItem="selectItem"></OptionsEdit>
           <!-- </div> -->
-          
-          
+
+
 
           <KChangeOption v-show="!options.dynamic" v-model="options.options" />
         </a-form-item>
         <!-- 选项配置及动态数据配置 end -->
 
         <!-- tabs配置 start -->
-        <a-form-item
-          v-if="['tabs', 'selectInputList'].includes(selectItem.type)"
-          :label="selectItem.type === 'tabs' ? '页签配置' : '列选项配置'"
-        >
+        <a-form-item v-if="['tabs', 'selectInputList'].includes(selectItem.type)"
+          :label="selectItem.type === 'tabs' ? '页签配置' : '列选项配置'">
           <KChangeOption v-model="selectItem.columns" :tableList="formList.formName" type="tab" />
         </a-form-item>
         <!-- tabs配置 end -->
         <a-form-item v-if="selectItem.type === 'grid'" label="栅格间距">
-          <InputNumber
-            v-model="selectItem.options.gutter"
-            placeholder="请输入"
-          />
+          <InputNumber v-model="selectItem.options.gutter" placeholder="请输入" />
         </a-form-item>
         <a-form-item v-if="selectItem.type === 'grid'" label="列配置项">
           <KChangeOption v-model="selectItem.columns" type="colspan" />
@@ -193,32 +133,17 @@
         <a-form-item v-if="selectItem.type === 'switch'" label="默认值">
           <ASwitch v-model="options.defaultValue" />
         </a-form-item>
-        <a-form-item
-          v-if="['number', 'slider'].indexOf(selectItem.type) >= 0"
-          label="默认值"
-        >
-          <InputNumber
-            :step="options.step"
-            :min="options.min || -Infinity"
-            :max="options.max || Infinity"
-            v-model="options.defaultValue"
-          />
+        <a-form-item v-if="['number', 'slider'].indexOf(selectItem.type) >= 0" label="默认值">
+          <InputNumber :step="options.step" :min="options.min || -Infinity" :max="options.max || Infinity"
+            v-model="options.defaultValue" />
         </a-form-item>
         <a-form-item v-if="selectItem.type === 'rate'" label="默认值">
-          <Rate
-            v-model="options.defaultValue"
-            :allowHalf="options.allowHalf"
-            :count="options.max"
-          />
+          <Rate v-model="options.defaultValue" :allowHalf="options.allowHalf" :count="options.max" />
         </a-form-item>
-        
+
         <a-form-item v-if="selectItem.type === 'select'" label="默认值">
-          <Select
-            :options="formList.listName"
-            v-model="options.defaultValue"
-            :allowClear="options.clearable"
-            :mode="options.multiple ? 'multiple' : ''"
-          />
+          <Select :options="formList.listName" v-model="options.defaultValue" :allowClear="options.clearable"
+            :mode="options.multiple ? 'multiple' : ''" />
           <!-- <el-option
               v-for="item in formList.listName"
               :key="item.fieldName"
@@ -236,56 +161,34 @@
         </a-form-item>
         <!-- 默认值 start -->
         <a-form-item v-if="selectItem.type === 'date'" label="默认值">
-          <Input
-            v-if="!options.range"
-            v-model="options.defaultValue"
-            :placeholder="!isDefined(options.format) ? '' : options.format"
-          />
-          <Input
-            v-if="options.range"
-            v-model="options.rangeDefaultValue[0]"
-            :placeholder="!isDefined(options.format) ? '' : options.format"
-          />
-          <Input
-            v-if="options.range"
-            v-model="options.rangeDefaultValue[1]"
-            :placeholder="!isDefined(options.format) ? '' : options.format"
-          />
+          <Input v-if="!options.range" v-model="options.defaultValue"
+            :placeholder="!isDefined(options.format) ? '' : options.format" />
+          <Input v-if="options.range" v-model="options.rangeDefaultValue[0]"
+            :placeholder="!isDefined(options.format) ? '' : options.format" />
+          <Input v-if="options.range" v-model="options.rangeDefaultValue[1]"
+            :placeholder="!isDefined(options.format) ? '' : options.format" />
         </a-form-item>
         <!-- 日期选择器默认值 start -->
-        <a-form-item
-          v-if="
-            ![
-              'number',
-              'radio',
-              'checkbox',
-              'date',
-              'rate',
-              'select',
-              'switch',
-              'slider',
-              'html'
-            ].includes(selectItem.type) && isDefined(options.defaultValue)
-          "
-          label="默认值"
-        >
-          <Input
-            v-model="options.defaultValue"
-            :placeholder="isDefined(options.format) ? '请输入' : options.format"
-          />
+        <a-form-item v-if="![
+        'number',
+        'radio',
+        'checkbox',
+        'date',
+        'rate',
+        'select',
+        'switch',
+        'slider',
+        'html'
+      ].includes(selectItem.type) && isDefined(options.defaultValue)
+        " label="默认值">
+          <Input v-model="options.defaultValue" :placeholder="isDefined(options.format) ? '请输入' : options.format" />
         </a-form-item>
         <!-- 修改html -->
         <a-form-item v-if="selectItem.type === 'html'" label="默认值">
-          <Textarea
-            v-model="options.defaultValue"
-            :autoSize="{ minRows: 4, maxRows: 8 }"
-          />
+          <Textarea v-model="options.defaultValue" :autoSize="{ minRows: 4, maxRows: 8 }" />
         </a-form-item>
         <a-form-item v-if="isDefined(options.format)" label="时间格式">
-          <Input
-            v-model="options.format"
-            placeholder="时间格式如:YYYY-MM-DD HH:mm:ss"
-          />
+          <Input v-model="options.format" placeholder="时间格式如:YYYY-MM-DD HH:mm:ss" />
         </a-form-item>
 
         <a-form-item v-if="isDefined(options.orientation)" label="标签位置">
@@ -337,11 +240,7 @@
             <RadioButton value="ajax">ajax</RadioButton>
             <RadioButton value="dynamic">动态函数</RadioButton>
           </Radio>
-          <Input
-            v-show="options.downloadWay === 'dynamic'"
-            v-model="options.dynamicFun"
-            placeholder="动态函数名"
-          />
+          <Input v-show="options.downloadWay === 'dynamic'" v-model="options.dynamicFun" placeholder="动态函数名" />
         </a-form-item>
         <!-- 下载方式 end -->
         <a-form-item v-if="selectItem.type === 'button'" label="按钮操作">
@@ -350,11 +249,7 @@
             <RadioButton value="reset">重置</RadioButton>
             <RadioButton value="dynamic">动态函数</RadioButton>
           </Radio>
-          <Input
-            v-show="options.handle === 'dynamic'"
-            v-model="options.dynamicFun"
-            placeholder="动态函数名"
-          />
+          <Input v-show="options.handle === 'dynamic'" v-model="options.dynamicFun" placeholder="动态函数名" />
         </a-form-item>
         <a-form-item v-if="selectItem.type === 'alert'" label="辅助描述">
           <Input v-model="options.description" />
@@ -400,14 +295,8 @@
           <Input v-model="options.fileName" placeholder="请输入" />
         </a-form-item>
         <!-- 上传额外参数 -->
-        <a-form-item
-          v-if="isDefined(options.data)"
-          label="额外参数(JSON格式)"
-        >
-          <Textarea
-            v-model="options.data"
-            placeholder="严格JSON格式"
-          ></Textarea>
+        <a-form-item v-if="isDefined(options.data)" label="额外参数(JSON格式)">
+          <Textarea v-model="options.data" placeholder="严格JSON格式"></Textarea>
         </a-form-item>
         <!-- 文字对齐方式 -->
         <a-form-item v-if="selectItem.type === 'text'" label="文字对齐方式">
@@ -420,135 +309,73 @@
         <!-- 文字字体 -->
         <a-form-item v-if="selectItem.type === 'text'" label="字体属性设置">
           <ColorPicker v-model="options.color" />
-          <Select
-            :options="familyOptions"
-            v-model="options.fontFamily"
-            style="width:36%;margin-left:2%;vertical-align:bottom;"
-          />
-          <Select
-            :options="sizeOptions"
-            v-model="options.fontSize"
-            style="width:35%;margin-left:2%;vertical-align:bottom;"
-          />
+          <Select :options="familyOptions" v-model="options.fontFamily"
+            style="width:36%;margin-left:2%;vertical-align:bottom;" />
+          <Select :options="sizeOptions" v-model="options.fontSize"
+            style="width:35%;margin-left:2%;vertical-align:bottom;" />
         </a-form-item>
         <a-form-item v-if="selectItem.type === 'text'" label="操作属性">
           <kCheckbox v-model="options.showRequiredMark" label="显示必选标记" />
         </a-form-item>
 
-        <a-form-item
-          v-if="
-            typeof options.hidden !== 'undefined' ||
-              typeof options.disabled !== 'undefined' ||
-              typeof options.readonly !== 'undefined' ||
-              typeof options.clearable !== 'undefined' ||
-              typeof options.multiple !== 'undefined' ||
-              typeof options.range !== 'undefined' ||
-              typeof options.showTime !== 'undefined' ||
-              typeof options.allowHalf !== 'undefined' ||
-              typeof options.showInput !== 'undefined' ||
-              typeof options.animated !== 'undefined'
-          "
-          label="操作属性"
-        >
-          <kCheckbox
-            v-if="isDefined(options.hidden)"
-            v-model="options.hidden"
-            label="隐藏"
-          />
-          <kCheckbox
-            v-if="isDefined(options.disabled)"
-            v-model="options.disabled"
-            label="禁用"
-          />
-          <kCheckbox
-            v-if="isDefined(options.readonly)"
-            v-model="options.readonly"
-            label="只读"
-          />
-          <kCheckbox
-            v-if="isDefined(options.clearable)"
-            v-model="options.clearable"
-            label="可清除"
-          />
-          <kCheckbox
-            v-if="isDefined(options.multiple)"
-            v-model="options.multiple"
-            label="多选"
-          />
-          <kCheckbox
-            v-if="isDefined(options.range)"
-            v-model="options.range"
-            label="范围选择"
-          />
-          <kCheckbox
-            v-if="isDefined(options.showTime)"
-            v-model="options.showTime"
-            label="时间选择器"
-          />
-          <kCheckbox
-            v-if="isDefined(options.allowHalf)"
-            v-model="options.allowHalf"
-            label="允许半选"
-          />
-          <kCheckbox
-            v-if="isDefined(options.showInput)"
-            v-model="options.showInput"
-            label="显示输入框"
-          />
-          <kCheckbox
-            v-if="isDefined(options.showLabel)"
-            v-model="options.showLabel"
-            label="显示Label"
-          />
-          <kCheckbox
-            v-if="isDefined(options.chinesization)"
-            v-model="options.chinesization"
-            label="汉化"
-          />
-          <kCheckbox
-            v-if="isDefined(options.hideSequence)"
-            v-model="options.hideSequence"
-            label="隐藏序号"
-          />
-          <kCheckbox
-            v-if="isDefined(options.drag)"
-            v-model="options.drag"
-            label="允许拖拽"
-          />
-          <kCheckbox
-            v-if="isDefined(options.showSearch)"
-            v-model="options.showSearch"
-            label="可搜索"
-          />
-          <kCheckbox
-            v-if="isDefined(options.treeCheckable)"
-            v-model="options.treeCheckable"
-            label="可勾选"
-          />
-          <kCheckbox
-            v-if="isDefined(options.animated)"
-            v-model="options.animated"
-            label="动画切换"
-          />
-          <kCheckbox
-            title="勾选后移除FormItem嵌套且表单无法获取该组件数据"
-            v-model="options.noFormItem"
-            label="移除FormItem"
-          />
-        </a-form-item>
-
-        <a-form-item
-          v-if="isDefined(selectItem.rules) && selectItem.rules.length > 0"
-          label="校验"
-        >
+        <a-form-item v-if="typeof options.hidden !== 'undefined' ||
+        typeof options.disabled !== 'undefined' ||
+        typeof options.readonly !== 'undefined' ||
+        typeof options.clearable !== 'undefined' ||
+        typeof options.multiple !== 'undefined' ||
+        typeof options.range !== 'undefined' ||
+        typeof options.showTime !== 'undefined' ||
+        typeof options.allowHalf !== 'undefined' ||
+        typeof options.showInput !== 'undefined' ||
+        typeof options.animated !== 'undefined'
+        " label="操作属性">
+          <kCheckbox v-if="isDefined(options.hidden)" v-model="options.hidden" label="隐藏" />
+          <kCheckbox v-if="isDefined(options.disabled)" v-model="options.disabled" label="禁用" />
+          <kCheckbox v-if="isDefined(options.readonly)" v-model="options.readonly" label="只读" />
+          <kCheckbox v-if="isDefined(options.clearable)" v-model="options.clearable" label="可清除" />
+          <kCheckbox v-if="isDefined(options.multiple)" v-model="options.multiple" label="多选" />
+          <kCheckbox v-if="isDefined(options.range)" v-model="options.range" label="范围选择" />
+          <kCheckbox v-if="isDefined(options.showTime)" v-model="options.showTime" label="时间选择器" />
+          <kCheckbox v-if="isDefined(options.allowHalf)" v-model="options.allowHalf" label="允许半选" />
+          <kCheckbox v-if="isDefined(options.showInput)" v-model="options.showInput" label="显示输入框" />
+          <kCheckbox v-if="isDefined(options.showLabel)" v-model="options.showLabel" label="显示Label" />
+          <kCheckbox v-if="isDefined(options.chinesization)" v-model="options.chinesization" label="汉化" />
+          <kCheckbox v-if="isDefined(options.hideSequence)" v-model="options.hideSequence" label="隐藏序号" />
+          <kCheckbox v-if="isDefined(options.drag)" v-model="options.drag" label="允许拖拽" />
+          <kCheckbox v-if="isDefined(options.showSearch)" v-model="options.showSearch" label="可搜索" />
+          <kCheckbox v-if="isDefined(options.treeCheckable)" v-model="options.treeCheckable" label="可勾选" />
+          <kCheckbox v-if="isDefined(options.animated)" v-model="options.animated" label="动画切换" />
+          <kCheckbox title="勾选后移除FormItem嵌套且表单无法获取该组件数据" v-model="options.noFormItem" label="移除FormItem" />
+          <kCheckbox title="isDefined(options.showSummary)" v-model="options.showSummary" label="显示计算" />
+
+        </a-form-item>
+
+        <a-form-item v-if="isDefined(selectItem.rules) && selectItem.rules.length > 0" label="校验">
           <kCheckbox v-model="selectItem.rules[0].required" label="必填" />
-          <Input
-            v-model="selectItem.rules[0].message"
-            placeholder="必填校验提示信息"
-          />
+          <Input v-model="selectItem.rules[0].message" placeholder="必填校验提示信息" />
           <KChangeOption v-model="selectItem.rules" type="rules" />
         </a-form-item>
 
+        <!-- 新增控件属性设置 start-->
+        <a-form-item v-if="isDefined(options.tableColumns) && options.tableColumns.length > 0" label="列属性">
+          <KChangeOption v-model="options.tableColumns" type="column" :formListListName="this.formList.listName"
+            :selectItem="selectItem" />
+        </a-form-item>
+        <a-form-item v-if="isDefined(options.tableColumns) && options.eventAttribute && options.tableColumns.length > 0"
+          label="事件属性">
+          <eventAttribute v-model="options.eventAttributeList" :tableColumns="options.tableColumns" type="column"
+            @addTableColumns="addTableColumns" @delectTableColumns="delectTableColumns" />
+        </a-form-item>
+        <a-form-item v-if="isDefined(options.formula)" label="计算公式">
+          <KFormula v-model="options.formula" />
+        </a-form-item>
+        <a-form-item v-if="isDefined(options.tableColor)" label="表格背景颜色">
+          <KColor v-model="options.tableColor" />
+        </a-form-item>
+        <a-form-item v-if="isDefined(options.tableTextColor)" label="表格字体颜色">
+          <KColor v-model="options.tableTextColor" />
+        </a-form-item>
+        <!-- 新增控件属性设置 end -->
         <!-- 表格选项 -->
         <a-form-item v-if="selectItem.type === 'table'" label="表格样式CSS">
           <Input v-model="selectItem.options.customStyle" />
@@ -579,50 +406,42 @@
       </a-form>
     </div>
     <!-- 表格展示数据弹窗 -->
-    <el-dialog
-      :visible.sync="tableShowData.isShow"
-      :modal-append-to-body="false"
-      :append-to-body="true"
-      title="表格展示数据"
-      width="500px"
-    >
-    <div class="ben-list mb5" >
-      <el-button type="primary" size="small" icon="el-icon-plus" @click="addOneColumn">添加一列</el-button>
-      <el-button size="small" icon="el-icon-close" @click="tableShowData.isShow=false">关闭</el-button>
-    </div>
-    
-    <div class="table-wrap">
-    <el-table v-if="selectItem" :data="selectItem.columns||[]" border stripe>
-    <el-table-column type="index" width="50" />
-    <el-table-column prop="prop" label="字段">
-      <template slot-scope="scope">
-        <el-select v-model="scope.row.prop" filterable size="mini">
-      <el-option
-              v-for="item in formList.listName"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value">
-              <span style="float: left">{{ item.label }}</span>
-      <span style="float: right; color: #8492a6; font-size: 13px">{{ item.fieldDescription }}</span>
-            </el-option>
-      </el-select>
-      </template>
-      
-    </el-table-column>
-    <el-table-column prop="label" label="描述">
-      <template slot-scope="scope">
-        <el-input v-model="scope.row.label"  size="mini" clearable ></el-input>
-        
-      </template>
-    </el-table-column>
-    <el-table-column label="操作">
-      <template slot-scope="scope">
-        <el-button type="text" size="mini" icon="el-icon-delete" @click="handleDelete(scope.$index)">删除</el-button>
-      </template>
-    </el-table-column>
-    
-    </el-table>
-    </div>
+    <el-dialog :visible.sync="tableShowData.isShow" :modal-append-to-body="false" :append-to-body="true" title="表格展示数据"
+      width="500px">
+      <div class="ben-list mb5">
+        <el-button type="primary" size="small" icon="el-icon-plus" @click="addOneColumn">添加一列</el-button>
+        <el-button size="small" icon="el-icon-close" @click="tableShowData.isShow = false">关闭</el-button>
+      </div>
+
+      <div class="table-wrap">
+        <el-table v-if="selectItem" :data="selectItem.columns || []" border stripe>
+          <el-table-column type="index" width="50" />
+          <el-table-column prop="prop" label="字段">
+            <template slot-scope="scope">
+              <el-select v-model="scope.row.prop" filterable size="mini">
+                <el-option v-for="item in formList.listName" :key="item.value" :label="item.label" :value="item.value">
+                  <span style="float: left">{{ item.label }}</span>
+                  <span style="float: right; color: #8492a6; font-size: 13px">{{ item.fieldDescription }}</span>
+                </el-option>
+              </el-select>
+            </template>
+
+          </el-table-column>
+          <el-table-column prop="label" label="描述">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.label" size="mini" clearable></el-input>
+
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template slot-scope="scope">
+              <el-button type="text" size="mini" icon="el-icon-delete"
+                @click="handleDelete(scope.$index)">删除</el-button>
+            </template>
+          </el-table-column>
+
+        </el-table>
+      </div>
     </el-dialog>
   </div>
 </template>
@@ -635,7 +454,11 @@ import { message } from 'ant-design-vue'
  * description 表单控件属性设置组件,因为配置数据是引用关系,所以可以直接修改
  */
 import KChangeOption from "../../KChangeOption/index.vue";
+import KFormula from "../../KFormula/index.vue";
+import KColor from "../../KColor/index.vue";
 import kCheckbox from "../../KCheckbox/index.vue";
+import EventAttribute from "../../EventAttribute/index.vue";
+
 import { pluginManager } from "../../../utils/index";
 import { getListName, getFormName } from "@/api/dragform/form";
 import { getUncommonTable } from '@/utils/other';
@@ -657,6 +480,7 @@ export default {
   components: {
     KChangeOption,
     kCheckbox,
+    EventAttribute,
     ColorPicker,
     Input,
     InputNumber,
@@ -668,7 +492,9 @@ export default {
     RadioButton,
     Textarea,
     Select,
-    OptionsEdit
+    OptionsEdit,
+    KFormula,
+    KColor
   },
   data() {
     return {
@@ -746,20 +572,20 @@ export default {
           label: "小五"
         }
       ],
-      formList:{
-        formName:[],
-        listName:[],
-        tableName:""
+      formList: {
+        formName: [],
+        listName: [],
+        tableName: ""
       },
       tableShowData: {
         isShow: false,
-        columns:[]
+        columns: []
       }
     };
   },
   computed: {
     options() {
-      if(!this.selectItem.tableName){
+      if (!this.selectItem.tableName) {
         this.formList.listName = [];
       }
       return this.selectItem.options || {};
@@ -775,41 +601,53 @@ export default {
       type: Boolean,
       default: false
     },
-    
+
   },
   methods: {
+    delectTableColumns(item) {
+      console.log('item00000000',item)
+      this.options.tableColumns = this.options.tableColumns.filter(column => column.prop !== item);
+
+      console.log('------0000', this.options.tableColumns); // 输出更新后的 tableColumns 数组
+    },
+    addTableColumns(item) {
+      console.log('add---',item)
+
+      this.options.tableColumns = item
+
+    },
     // 删除一列
-    handleDelete(index){
-      this.selectItem.columns.splice(index,1)
+    handleDelete(index) {
+      this.selectItem.columns.splice(index, 1)
     },
     // 添加一列
-    addOneColumn(){
+    addOneColumn() {
       this.selectItem.columns.push({
-        label:'',
-        prop:'',
+        label: '',
+        prop: '',
       })
     },
     // 编辑tableShow的列
     editTableColumns() {
-      if(!this.selectItem.tableName){
+      if (!this.selectItem.tableName) {
         this.$message.warning('请先选择表名')
         return
       }
       console.log(this.selectItem)
       this.tableShowData.isShow = true;
-      
+
     },
     seeSelectItem() {
-      console.log('selectItem',this.selectItem);
+      console.log('selectItem', this.selectItem);
     },
     // 列名变化回调
     changeModel() {
-      console.log('列',this.selectItem);
+      console.log('列', this.selectItem);
     },
     setDynamicKey(sqlData) {
-      console.log('sqlData',sqlData);
+      console.log('sqlData', sqlData);
       this.options.dynamicKey = sqlData.dynamicName;
-      this.options.sqlData=JSON.parse(JSON.stringify(sqlData))
+      this.options.sqlData = JSON.parse(JSON.stringify(sqlData))
       // console.log(this.options.dynamicKey,key,111);
     },
     /**
@@ -822,8 +660,7 @@ export default {
     },
     // 判断是否需要列名
     isNeedColumn(value) {
-      console.log(value.type);
-      let notNeedColumnList = ['batch', 'selectInputList','tableShow'];
+      let notNeedColumnList = ['batch', 'selectInputList', 'tableShow', 'calculation_table'];
       if (notNeedColumnList.includes(value.type)) {
         return false;
       } else {
@@ -835,7 +672,7 @@ export default {
         ... this.$store.state.user.dataSource
       }
       let res = await getUncommonTable()
-      this.formList.formName=res
+      this.formList.formName = res
       // console.log(res);
       // getFormName(par).then(res=>{
       //   this.formList.formName = res.data
@@ -843,55 +680,59 @@ export default {
     },
     getListName(item = {}) {
       let notNeedColumnList = ['batch', 'selectInputList'];
-      let flag=notNeedColumnList.includes(item.type)
+      let flag = notNeedColumnList.includes(item.type)
       if (flag) {
-      item.model='batch.'+item.tableName
-      } else if(item.type){
-        item.model='tableShow.'+item.tableName
-      }else {
-      item.model=''
-    }
+        item.model = 'batch.' + item.tableName
+
+      } else if (item.type) {
+        // item.model = item.type == 'calculation_table' ? 'calculation_table.' + item.tableName :  'tableShow.' + item.tableName
+        item.model = 'tableShow.' + item.tableName
+      } else {
+        item.model = ''
+      }
       let par2 = {
         ... this.$store.state.user.dataSource,
-        'tableName':this.selectItem.tableName
+        'tableName': this.selectItem.tableName
       }
-      
-      getListName(par2).then(res=>{
+      getListName(par2).then(res => {
         this.formList.listName = res.map(item => {
           return {
             label: item.fieldName,
             value: item.fieldName,
-            fieldDescription:item.fieldDescription
+            fieldDescription: item.fieldDescription
           }
         });
       })
+      // console.log('[this.formList.listName]',t?is.formList.listName)
     }
   },
   mounted() {
     this.getFormList();
-    console.log('this.selectItem',this.selectItem);
+    console.log('this.selectItem', this.selectItem);
     if (this.selectItem.tableName) {
       this.getListName()
     }
   },
-  
+
 };
 </script>
 
 <style lang="scss" scoped>
-.dynamic-wrap{
+.dynamic-wrap {
   display: flex !important;
   align-items: center;
 
 }
-.discribe{
+
+.discribe {
   display: block;
   max-width: 200px;
-  white-space:nowrap;
-  overflow:hidden;
-  text-overflow:ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
-.table-wrap{
+
+.table-wrap {
   max-height: 500px;
   overflow-y: scroll
 }

+ 38 - 4
zkqy-ui/node_modules/k-form-design/packages/components/KFormDesign/module/layoutItem.vue

@@ -22,6 +22,7 @@
         @click.stop="handleSelectItem(record)"
       >
         <a-form-item
+          :colon="false"
           :label="!record.options.showLabel ? '' : record.label"
           :label-col="
             config.layout === 'horizontal' && record.options.showLabel
@@ -483,7 +484,6 @@
         :class="{ active: record.key === selectItem.key }"
         @click.stop="handleSelectItem(record)"
         style="overflow: scroll;"
-
       >
         <table
           class="table-layout kk-table-9136076486841527"
@@ -491,8 +491,7 @@
             bright: record.options.bright,
             small: record.options.small,
             bordered: record.options.bordered
-          }"
-          
+          }"     
         >
           <tr>
             <td>
@@ -528,6 +527,36 @@
       </div>
     </template>
     <!-- 表格展示  end -->
+     <!--计算表格展示  start -->
+     <template v-else-if="record.type === 'calculation_table'">
+      <div
+        class="table-box"
+        :class="{ active: record.key === selectItem.key }"
+        @click.stop="handleSelectItem(record)"
+        style="overflow: scroll;"
+      >
+     <Tabulation :tableColumns="record.options.tableColumns" :disabled="record.options.disabled"
+      :showAddButton="false" :showSummary="false" 
+      :formula="record.options.formula" :tableColor="record.options.tableColor" :tableTextColor="record.options.tableTextColor"
+
+      /> 
+     <div
+          class="copy"
+          :class="record.key === selectItem.key ? 'active' : 'unactivated'"
+          @click.stop="$emit('handleCopy')"
+        >
+          <a-icon type="copy" />
+        </div>
+        <div
+          class="delete"
+          :class="record.key === selectItem.key ? 'active' : 'unactivated'"
+          @click.stop="$emit('handleDelete')"
+        >
+          <a-icon type="delete" />
+        </div>
+     </div>
+    </template>
+    <!-- 计算表格展示  end -->
     <template v-else>
       <formNode
         :key="record.key"
@@ -549,6 +578,9 @@
  * date 2019-11-20
  * description 使用递归组件调用自己,生成布局结构及表单
  */
+
+ // 计算表格组件
+import Tabulation from "@/components/customControl/Tabulation"
 import draggable from "vuedraggable";
 import formNode from "./formNode";
 import { pluginManager } from "../../../utils/index";
@@ -591,13 +623,15 @@ export default {
     formNode,
     draggable,
     CheckboxItem,
-    RadioItem
+    RadioItem,
+    Tabulation
   },
   methods: {
     handleShowRightMenu(e, record, trIndex, tdIndex) {
       this.$emit("handleShowRightMenu", e, record, trIndex, tdIndex);
     },
     handleSelectItem(record) {
+      console.log('[handleSelectItem---------------]',record)
       this.$emit("handleSelectItem", record);
     },
     handleColAdd(e, list) {

+ 3 - 2
zkqy-ui/node_modules/k-form-design/packages/components/KFormPreview/index.vue

@@ -26,7 +26,7 @@
 <script>
 /*
  * author kcz
- * date 2019-11-20
+ * date 2019-11-20 
  */
 import jsonModel from "../KFormDesign/module/jsonModal";
 import { dialogStyle, bodyStyle } from "../../config/modal.js";
@@ -65,9 +65,10 @@ export default {
      */
     async handleGetData() {
       // 获取表单数据
+      
       this.$refs.KFormBuild.getData()
         .then(res => {
-          console.log(res, "获取数据成功");
+          console.log(res, "获取数据成功1");
           // 获取自定义  表格  勾选数据
           let selectData= this.$refs.KFormBuild.getselectData()
           this.$refs.jsonModel.jsonData = res;

+ 9 - 0
zkqy-ui/src/api/bpmprocess/process.js

@@ -194,3 +194,12 @@ export function listBusinessFlowScript(query) {
     params: query
   })
 }
+
+// 查询所有的业务脚本页面
+export function listBusinessFlowVuePage(query) {
+  return request({
+    url: '/system/SysBusinessFlowVuePage/list',
+    method: 'get',
+    params: query
+  })
+}

+ 24 - 5
zkqy-ui/src/api/formCreateMange/mobilePageDesignData.js

@@ -1,4 +1,5 @@
 import request from '@/utils/request'
+import path from "path";
 
 // 查询新新页面设计列表 name
 export function listMobilePageDesignData(query) {
@@ -19,8 +20,8 @@ export function getMobilePageDesignData(id) {
   })
 }
 
-// 新增新新页面设计 
-export function addMobilePageDesignData(data) { 
+// 新增新新页面设计
+export function addMobilePageDesignData(data) {
   return request({
     url: '/system/mobilePageDesignData',
     method: 'post',
@@ -47,7 +48,7 @@ export function delMobilePageDesignData(id) {
     baseURL: process.env.VUE_APP_BASE_API3
   })
 }
-// 获取所有表: http://192.168.10.103:8088/dataSource/getAllTable
+// 获取所有表: http://192.168.10.114:8088/dataSource/getAllTable
 export function getAllTable(data) {
   return request({
     url: '/dataSource/getAllTable',
@@ -66,7 +67,7 @@ export function tableLimitInfo(params) {
   })
 }
 
-// 获取表里的所有字段:http://192.168.10.103:8088/dataSource/getInfoTable
+// 获取表里的所有字段:http://192.168.10.114:8088/dataSource/getInfoTable
 export function getListName(data) {
   return request({
     url: '/dataSource/getInfoTable',
@@ -102,4 +103,22 @@ export function getListName(data) {
 //     parentIdField: "parent_id"
 //   }
 // }
-// this.getTreeApi({}, dataSource)
+// this.getTreeApi({}, dataSource)
+
+// 获取表里的所有字段:http://192.168.10.103:8088/dataSource/getInfoTable
+export function upload(data) {
+  return request({
+    url: '/system/mobilePageDesignData/upload',
+    method: 'post',
+    data: data,
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+export function download(path) {
+  return request({
+    url: '/system/mobilePageDesignData/download?path='+path,
+    method: 'get',
+    baseURL: process.env.VUE_APP_BASE_API3,
+    responseType: 'blob' // 关键!告诉axios接收二进制数据
+  })
+}

+ 73 - 0
zkqy-ui/src/api/system/table.js

@@ -20,3 +20,76 @@ export function editTable(data) {
     baseURL: process.env.VUE_APP_BASE_API3
   })
 }
+
+// 根据tableKey获取tId
+export function getTIdByTableKey(query) {
+  return request({
+    url: `/excel/excelSheet/getTIdByTableKey?tableKey=${query}`,
+    method: 'get', 
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 根据tablekey获取表格数据
+export function getTableInfoByTableKey(query) {
+  return request({
+    url: `/excel/excelSheet/getTableInfoByTableKey?tableKey=${query}`,
+    method: 'get', 
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 根据tablekey删除表格数据
+export function removeByTableKey(data) {
+  return request({
+    url: '/system/table/removeByTableKey',
+    method: 'delete',
+    data: data,
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 新增excel
+export function addExcel(data) {
+  return request({
+    url: '/excel/excelSheet',
+    method: 'post',
+    data: data,
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+// 更新excel
+export function updateExcel(data) {
+  return request({
+    url: '/excel/excelSheet',
+    method: 'put',
+    data: data,
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+// 查询excel列表 name
+export function listExcel(query) {
+  return request({
+    url: '/excel/excelSheet/list',
+    method: 'get',
+    params: query,
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+// 查询excel单个 name
+export function getExcelItem(query) {
+  return request({
+    url: `/excel/excelSheet/${query}`,
+    method: 'get',
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}
+
+// 删除excel
+export function delExcel(ids) {
+  return request({
+    url: '/excel/excelSheet/' + ids,
+    method: 'delete',
+    baseURL: process.env.VUE_APP_BASE_API3
+  })
+}

+ 11 - 0
zkqy-ui/src/lang/en.js

@@ -675,6 +675,9 @@ export default {
     modify: 'Modify',
     delete: 'Delete',
     add: 'Add',
+    upload:'Upload',
+    download: 'Download',
+    htmlUrl:'Html Url',
     pleaseSelectDelete: 'Please select records to delete first',
     confirmDelete: 'Are you sure to delete number',
     pleaseEnterPageName: 'Please enter page name'
@@ -2722,5 +2725,13 @@ export default {
         networkError: 'Network error, failed to get form list'
       }
     },
+  },
+  excelSheet: {
+    excelSheetKey: 'Excel Table Key',
+    excelSheetName: 'Excel Name',
+    excelSheetDesc: 'Excel Table Alias',
+    confirmDelete: 'Are you sure to delete the data item with ID',
+    deleteMenuTip: 'Delete menu failed',
+    deleteSuccess: 'Delete success',
   }
 };

+ 13 - 2
zkqy-ui/src/lang/zh.js

@@ -680,6 +680,9 @@ export default {
     modify: '修改',
     delete: '删除',
     add: '新增',
+    upload:'上传',
+    download:'下载',
+    htmlUrl:'页面访问路径',
     pleaseSelectDelete: '请先选择要删除的记录',
     confirmDelete: '是否确认删除编号为',
     pleaseEnterPageName: '请输入页面名称'
@@ -687,7 +690,7 @@ export default {
   treeTable: {
     treeTableKey: '树形表主键',
     treeTableName: '树形表名',
-    treeTableDesc: '树形表格别名',
+    treeTableDesc: '表格别名',
     treeTableDgl: '树形递归列',
     treeTableCondition: '树形条件',
     boundTableId: '绑定表id',
@@ -700,7 +703,7 @@ export default {
     confirmDelete: '是否确认删除编号为',
     deleteMenuTip: '删除后菜单中相关数据也将删除',
     enterTreeTableName: '请输入树形表名',
-    enterTreeTableDesc: '请输入树形表格别名',
+    enterTreeTableDesc: '请输入表格别名',
     treeMenuConfig: '树形菜单配置',
     tableFieldConfig: '表格字段配置',
     addTreeTableConfig: '新增树形表格配置',
@@ -2733,5 +2736,13 @@ export default {
         networkError: '网络异常,获取表单列表失败'
       }
     },
+  },
+  excelSheet: {
+    excelSheetKey: 'Excel表主键',
+    excelSheetName: 'Excel名称',
+    excelSheetDesc: '表格别名',
+    confirmDelete: '是否确认删除编号为',
+    deleteMenuTip: '删除菜单失败',
+    deleteSuccess: '删除成功',
   }
 };

+ 2 - 2
zkqy-ui/src/views/asEditor/components/realTimeView/index.vue

@@ -7,7 +7,7 @@
         ref="iframe"
         class="screen"
         :scrolling="false"
-        :src="`http://192.168.10.103:8088/system/mobilePageData/ + ${this.val.id}`"
+        :src="`http://192.168.10.114:8088/system/mobilePageData/ + ${this.val.id}`"
         @load="load"
       ></iframe>
       <van-loading v-if="loading" size="24px" vertical>加载中</van-loading>
@@ -39,7 +39,7 @@ export default {
     load() {
       this.loading = false
       console.log(this.val.id,11111111);
-      this.$refs["iframe"].contentWindow.postMessage(this.val, `http://192.168.10.103:8088/system/mobilePageData/+ ${this.val.id}`);
+      this.$refs["iframe"].contentWindow.postMessage(this.val, `http://192.168.10.114:8088/system/mobilePageData/+ ${this.val.id}`);
     },
   },
 }

+ 1 - 1
zkqy-ui/src/views/asEditor/components/uploadImg/index.vue

@@ -148,7 +148,7 @@ export default {
       const formData = new FormData();
       formData.append('file', file);
 
-      axios.post('http://192.168.10.103:8066/common/upload', formData, {
+      axios.post('http://192.168.10.114:8066/common/upload', formData, {
         headers: {
           Authorization: "Bearer " + getToken(),
         },

+ 0 - 1
zkqy-ui/src/views/asEditor/layout/home/pageDesign.vue

@@ -322,7 +322,6 @@ export default {
           selectDataKey: [{ label: "", value: "" }],
         },
       },
-      clickTimer: null,
       isSingleClick: false, // 是否是单击
       clickTimer: null, // 存储定时器引用
       isEdit: false, //是否编辑

+ 52 - 0
zkqy-ui/src/views/excelSheet/components/DynamicButtonGroup.vue

@@ -0,0 +1,52 @@
+<template>
+  <el-row :gutter="10" class="mb8">
+    <el-col
+      v-for="(button, index) in buttons"
+      :key="index"
+      :span="button.span || 1.5"
+    >
+      <el-button
+        :type="button.type"
+        :plain="button.plain"
+        :icon="button.icon"
+        :size="button.size"
+        :disabled="button.disabled"
+        @click="button.click"
+      >
+        {{ button.label }}
+      </el-button>
+    </el-col>
+  </el-row>
+</template>
+
+<script>
+/**
+ * buttons: 每个按钮必须包含 label(按钮文本)和 click(点击事件)属性
+ * label:按钮显示的文本
+ * type:按钮类型(如 primary、danger 等)
+ * plain:是否为朴素按钮(true/false)
+ * icon:按钮图标(如 el-icon-plus、el-icon-delete 等)
+ * size:按钮大小(如 mini、small 等)
+ * disabled:是否禁用按钮(true/false)
+ * click:按钮点击事件的处理函数
+ * span:按钮所占的列宽(默认为 1.5)
+ */
+export default {
+  name: 'DynamicButtonGroup',
+  props: {
+    buttons: {
+      type: Array,
+      required: true,
+      validator: (value) => {
+        return value.every((button) => button.label && button.click);
+      },
+    },
+  },
+};
+</script>
+
+<style scoped>
+.mb8 {
+  margin-bottom: 8px;
+}
+</style>

+ 230 - 0
zkqy-ui/src/views/excelSheet/components/DynamicForm.vue

@@ -0,0 +1,230 @@
+<template>
+
+  <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
+    :label-width="labelWidth">
+    <!-- 动态渲染表单项 -->
+    <div v-for="(item, index) in formItems" :key="index" class="el-form-div">
+      <el-form-item :label="(item.component === 'el-radio-group' ? (item.options.length > 0 ? item.label : '') : item.label)" :prop="item.prop" :label-width="item.labelWidth || labelWidth"
+        :rules="item.rules" :class="item.prop">
+        <!-- 动态渲染输入组件 -->
+        <component v-if="!item.type && item.type != 'tree'" :is="item.component || 'el-input'"
+          v-model="queryParams[item.prop]" v-bind="item.attrs || {}" v-on="item.listeners || {}">
+          <template v-if="item.component === 'el-select'">
+            <el-option v-for="option in item.options" :key="option.value" :label="option.label" :value="option.value">
+              <span style="float: left" v-if="item.selectSlot" class="discribe">{{ option.label }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px" v-if="item.selectSlot">{{ option.value
+                }}</span>
+            </el-option>
+          </template>
+          <template v-if="item.component === 'el-radio-group' && item.options && item.options.length > 0">
+            <el-radio-group v-model="queryParams[item.prop]" >
+              <el-radio v-for="option in item.options" :key="option.value" :label="option.value">
+                {{ option.label }}
+              </el-radio>
+            </el-radio-group>
+          </template>
+        </component>
+        <div v-if="item.type && item.type == 'tree'" class="treeselect">
+          <treeselect :append-to-body="true" v-model="queryParams[item.prop]" :options="item.menus"
+            :placeholder="item.placeholder" :normalizer="normalizer" :show-count="true"
+            :openDirection="item.openDirection" />
+        </div>
+      </el-form-item>
+
+      <!-- 插入父组件提供的插槽内容 -->
+      <el-form-item>
+        <slot :name="`${item.prop}Slot`"></slot>
+      </el-form-item>
+    </div>
+
+    <!-- 动态渲染按钮 -->
+    <el-form-item v-if="Showbuttons" class="el-form-btn">
+      <el-button v-for="(button, idx) in buttonsWithDefaults" :key="idx" :type="button.type || 'default'"
+        :icon="button.icon || ''" :size="button.size || 'mini'" @click="handleButtonClick(button)">
+        {{ button.label }}
+      </el-button>
+    </el-form-item>
+
+  </el-form>
+</template>
+
+<script>
+/**
+ * showSearch: 控制搜索表单是否显示。
+ * formItems: 表单项配置数组,每个元素代表一个表单项。
+ *            必需字段:label(表单项标签文本),prop(绑定的模型数据键名)
+ *            校验规则:每个元素必须包含 label 和 prop 属性
+ * labelWidth: 表单项标签的宽度。
+ * formButtons: 按钮配置, 不传值时默认搜索和重置,传值时传出表单数据,父组件定义逻辑。
+ */
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import Treeselect from "@riophae/vue-treeselect";
+export default {
+  name: 'DynamicForm',
+  components: {
+    Treeselect,
+  },
+  props: {
+    showSearch: {
+      type: Boolean,
+      default: true,
+    },
+    Showbuttons: {
+      type: Boolean,
+      default: true,
+    },
+    formItems: {
+      type: Array,
+      required: true,
+      validator: (value) => {
+        return value.every((item) => item.label && item.prop);
+      },
+    },
+    labelWidth: {
+      type: String,
+      default: '85px',
+    },
+    formButtons: {
+      type: Array,
+      default: () => [],
+      validator: (value) => value.every((button) => button.label && button.event),
+    },
+  },
+  data() {
+    return {
+      // 表单数据
+      queryParams: {},
+    };
+  },
+  watch: {
+  queryParams: {
+    handler(newVal) {
+      // 当 queryParams 变化时,通知父组件
+      this.$emit('query-params-change', newVal);
+    },
+    deep: true, // 深度监听,确保嵌套属性的变化也能触发
+  },
+},
+  created() {
+    this.initQueryParams();
+  },
+  computed: {
+    // 如果没有传入按钮,则提供默认的搜索和重置按钮
+    buttonsWithDefaults() {
+      if (this.formButtons.length === 0) {
+        return [
+          { label: this.$t('normal.search'), event: 'search', eventName: 'query', icon: 'el-icon-search', type: 'primary', size: 'mini' },
+          { label: this.$t('normal.reset'), event: 'reset', eventName: 'reset', icon: 'el-icon-refresh', size: 'mini' },
+        ];
+      }
+      return this.formButtons;
+    },
+  },
+  methods: {
+    /**
+     * 初始化 queryParams 对象,根据 formItems 的配置动态设置表单的初始值。
+     * item.defaultValue || '':如果表单项配置了 defaultValue,则使用该值;否则使用空字符串 '' 作为默认值。
+     */
+    initQueryParams() {
+      this.formItems.forEach((item) => {
+        // console.log('defaultValue', item)
+
+        this.$set(this.queryParams, item.prop, item.radioDefaultValue ? true : item.treeDefaultValue?null:"");
+        // console.log('this.queryParams', this.queryParams)
+      });
+    },
+    // 查询
+    handleQuery() {
+      // console.log('[点击查询]')
+      this.$emit('query', this.queryParams);
+    },
+    // 重置
+    resetQuery() {
+      this.initQueryParams();
+      this.$emit('reset');
+    },
+    // 处理按钮点击事件
+    handleButtonClick(button) {
+      if (button.event === 'search') {
+        this.handleQuery();
+      } else if (button.event === 'reset') {
+        this.resetQuery();
+      } else {
+        // 触发自定义事件,传递表单数据、事件类型以及可能的额外参数
+        const payload = { event: button.event, data: this.queryParams };
+        if (button.extraData) {
+          payload.extraData = button.extraData;
+        }
+        this.$emit(button.eventName || 'button-click', payload);
+      }
+    },
+    /** 转换菜单数据结构 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.menuId,
+        label: node.menuName,
+        children: node.children,
+      };
+    },
+  },
+};
+</script>
+
+<style scoped>
+.el-form {
+  display: flex;
+  flex-wrap: wrap;
+  /* 允许换行 */
+}
+
+.el-form-div {
+  min-width: 200px;
+  /* 设置最小宽度,防止过窄 */
+}
+
+.discribe {
+  display: block;
+  max-width: 200px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+
+</style>
+<style lang="scss">
+::v-deep .el-select-dropdown {  
+/* transform-origin: center top !important; */
+z-index: 9999 !important;
+
+}
+::v-deep .vue-treeselect--has-value .vue-treeselect__input {
+  vertical-align: middle !important;
+}
+
+::v-deep .vue-treeselect--has-value .vue-treeselect__input {
+  vertical-align: middle !important;
+}
+
+.treeselect {
+  .vue-treeselect {
+    width: 205px !important;
+  }
+}
+
+.treeselect {
+  .vue-treeselect .vue-treeselect__control {
+    height: 32px;
+    line-height: 32px;
+    border-radius: 4px;
+    font-size: 13px;
+  }
+}
+
+.vue-treeselect {
+  z-index: 100 !important;
+}
+</style>

+ 212 - 0
zkqy-ui/src/views/excelSheet/index.vue

@@ -0,0 +1,212 @@
+<template>
+    <div class="app-container">
+        <!-- 上层输入框 -->
+        <DynamicForm :formItems="formItems" @query="queryExcel" @reset="resetForm" />
+        <!-- 上层按钮 -->
+        <DynamicButtonGroup :buttons="buttons" />
+        <!-- 中间渲染 -->
+        <el-table v-loading="loading" :data="excelList" ref="excelRef" @selection-change="handleSelectionChange">
+            <el-table-column type="selection" width="55" align="center" />
+            <el-table-column label="主键" align="center" prop="id" />
+            <el-table-column label="excel名称" align="center" prop="name" />
+            <el-table-column label="创建时间" align="center" prop="updateTime" show-overflow-tooltip />
+            <el-table-column :label="$t('formCreate.operation')" align="center" class-name="small-padding fixed-width">
+                <template slot-scope="scope">
+                    <el-dropdown>
+                        <el-button type="warning" plain size="small">
+                            {{ $t('formCreate.process') }}<i class="el-icon-arrow-down el-icon--right"></i>
+                        </el-button>
+                        <el-dropdown-menu slot="dropdown">
+                            <el-dropdown-item>
+                                <el-button size="mini" type="text" icon="el-icon-edit"
+                                    @click="handleUpdate(scope.row)">{{ $t('formCreate.modify') }}
+                                </el-button>
+                            </el-dropdown-item>
+                            <el-dropdown-item>
+                                <el-button size="mini" type="text" icon="el-icon-delete"
+                                    @click="handleDelete(scope.row)">{{ $t('formCreate.delete') }}
+                                </el-button>
+                            </el-dropdown-item>
+                        </el-dropdown-menu>
+                    </el-dropdown>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
+            :limit.sync="queryParams.pageSize" @pagination="getList" />
+    </div>
+</template>
+
+<script>
+import DynamicForm from './components/DynamicForm.vue';
+import DynamicButtonGroup from './components/DynamicButtonGroup.vue';
+import { listExcel,delExcel } from "@/api/system/table.js";
+export default {
+    name: "ExcelSheet",
+    props: [],
+    components: {
+        DynamicForm,
+        DynamicButtonGroup,
+    },
+    data() {
+        return {
+            //输入框配置
+            formItems: [{
+                // Excel名称
+                label: this.$t('excelSheet.excelSheetName'),
+                prop: 'name',
+                attrs: {
+                    placeholder: this.$t('excelSheet.excelSheetName'),
+                    clearable: true,
+                },
+            },
+            ],
+            // 查询参数
+            queryParams: {
+                name: '',
+                pageNum: 1,
+                pageSize: 10,
+            },
+            // 非单个禁用
+            single: true,
+            // 非多个禁用
+            multiple: true,
+            //标记,2增加3修改4查看
+            mode: 4,
+            loading: false,
+            excelList: [],
+            total: 0,
+        };
+    },
+    computed: {
+        buttons() {
+            return [
+                {
+                    label: this.$t('insert'),
+                    type: 'primary',
+                    plain: true,
+                    icon: 'el-icon-plus',
+                    size: 'mini',
+                    click: this.handleAdd,
+                },
+                {
+                    label: this.$t('update'),
+                    type: 'success',
+                    plain: true,
+                    icon: 'el-icon-edit',
+                    size: 'mini',
+                    disabled: this.single,
+                    click: this.handleUpdate,
+                },
+                {
+                    label: this.$t('delete'),
+                    type: 'danger',
+                    plain: true,
+                    icon: 'el-icon-delete',
+                    size: 'mini',
+                    disabled: this.multiple,
+                    click: this.handleDelete,
+                }
+            ];
+        }
+    },
+    methods: {
+        /* 输入框查询 */
+        queryExcel(queryParams) {
+            this.queryParams = queryParams
+            console.log('[输入框查询]', this.queryParams)
+            this.getList()
+        },
+        /* 输入框重置 */
+        resetForm() {
+            console.log('输入框已重置');
+        },
+        getList() {
+            console.log('获取列表')
+            this.loading = true;
+            listExcel(this.queryParams).then(
+                (response) => {
+                    this.excelList = response.rows;
+                    this.total = response.total;
+                    this.loading = false;
+                }
+            );
+        },
+        /* ---------按钮事件start---------*/
+        // 新增
+        handleAdd() {
+            console.log('新增按钮被点击');
+            this.mode = 2
+            this.$router.push({
+                path: "/system/fromModel/index/excelSheetEdit",
+                query: {
+                    mode: this.mode // mode
+                }
+            });
+        },
+        // 修改 
+        handleUpdate(rowData) {
+            let row;
+            if (rowData instanceof PointerEvent || rowData instanceof Event) {
+                row = this.selection[0]
+            } else {
+                row = rowData
+            }
+            if (row) {
+                console.log('row', row);
+                this.mode = 3
+                this.$router.push({
+                    path: "/system/fromModel/index/excelSheetEdit",
+                    query: {
+                        mode: this.mode, // mode
+                        editorId: row.id,
+                    }
+                });
+            }
+
+        },
+        // 删除
+        handleDelete(rowData) {
+            let rows;
+            if (rowData instanceof PointerEvent || rowData instanceof Event) {
+                rows = this.selection;
+            } else {
+                rows = [rowData];
+            }
+            if (!rows.length) return;
+
+            const ids = rows.map(row => row.id).join(', ');
+            this.$modal
+                .confirm(
+                    this.$t('excelSheet.confirmDelete') +
+                    ids +
+                    '"的数据项?'
+                )
+                .then(async () => {
+                    // 并发删除所有选中的id
+                    await Promise.all(rows.map(row => delExcel(row.id)));
+                })
+                .then(() => {
+                    this.getList();
+                    this.$modal.msgSuccess(this.$t('excelSheet.deleteSuccess'));
+                })
+                .catch((e) => {
+                    console.log(e);
+                });
+        },
+        /* ---------按钮事件end---------*/
+        // 选择多条
+        handleSelectionChange(selection) {
+            this.selection = selection;
+            this.single = selection.length !== 1;
+            this.multiple = !selection.length;
+        },
+    },
+    created() {
+        this.getList();
+    },
+};
+
+</script>
+<style scoped></style>

+ 1617 - 0
zkqy-ui/src/views/excelSheetEdit/index.vue

@@ -0,0 +1,1617 @@
+<template>
+    <div class="app-container">
+        <!-- 按钮 -->
+        <div style="height: auto;width: 100%; padding-bottom: 20px;">
+            <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openPopUp">获取表格数据</el-button>
+            <el-button type="primary" plain size="mini" @click="saveData">保存</el-button>
+            <!-- <el-button type="info" plain icon="el-icon-view" size="mini" @click="showRangeDataObjectsInfo" style="margin-left: 10px;">查看选区数据</el-button> -->
+        </div>
+        <!-- Luckysheet容器 -->
+        <div id="luckysheet" style="margin:0px;padding:0px;width:100%;height:100%;left: 0px;top: 0px;"></div>
+        <!-- 弹窗 -->
+        <el-dialog title="表格编辑" ref="popUpForm" :visible.sync="popUpVisible" @close="popUpVisibleCancel" width="50%"
+            :show-close="false">
+            <el-alert v-if="errorMessage && errorMessage != ''" :title="errorMessage" type="error" show-icon />
+            <div style="display: flex;gap: 20px;">
+                <div class="popUpTitle">
+                    <div class="popUpTitleDiv">数据表</div>
+                    <el-select v-model="popUpTableName" :placeholder="$t('tableMange.selectTable')" filterable
+                        @change="getList" class="mb10">
+                        <el-option v-for="item in popUpTableList" :key="item.tableName" :label="item.tableComment"
+                            :value="item.tableName">
+                            <span class="discribe" style="float: left">{{
+                                item.tableComment
+                            }}</span>
+                            <span style="float: right; color: #8492a6; font-size: 13px">{{
+                                item.tableName
+                            }}</span>
+                        </el-option>
+                    </el-select>
+                </div>
+                <div class="popUpTitle">
+                    <div class="popUpTitleDiv" style="margin-bottom: 10px;">别名</div>
+                    <el-input v-model="dtName" placeholder="请输入别名" style="margin-bottom: 10px;width: 221px;" clearable>
+                    </el-input>
+                </div>
+            </div>
+            <el-table :data="popUpTableFieldList" border ref="dragTable" row-key="id" max-height="500px">
+                <el-table-column type="index" :label="$t('tableMange.serialNumber')" width="50" class-name="allowDrag">
+                </el-table-column>
+                <el-table-column align="center" prop="fieldName" :label="$t('tableMange.dataField')">
+                </el-table-column>
+                <el-table-column align="center" prop="fieldDescription" :label="$t('tableMange.fieldDescription')">
+                    <template slot-scope="scope">
+                        <input :class="{
+                            isNullDesc:
+                                scope.row.fieldDescription == '' &&
+                                    scope.row.isShow &&
+                                    isInputInvalid
+                                    ? true
+                                    : false,
+                            ipt: true,
+                        }" v-model="scope.row.fieldDescription" />
+                    </template>
+                </el-table-column>
+                <el-table-column align="center" prop="relationTable" :label="$t('tableMange.relatedTable')">
+                    <template slot-scope="scope">
+                        <el-select v-model="scope.row.relationTable" :disabled="!scope.row.relationTableList ||
+                            !scope.row.relationTableList.length
+                            " :placeholder="$t('tableMange.selectTable')" clearable filterable
+                            @change="ralationTableChange(scope.row)">
+                            <el-option v-for="item in scope.row.relationTableList" :key="item.tableName"
+                                :label="item.tableComment" :value="item.tableName">
+                                <span style="float: left">{{ item.tableComment }}</span>
+                                <span style="float: right; color: #8492a6; font-size: 13px">{{ item.tableName }}</span>
+                            </el-option>
+                        </el-select>
+                    </template>
+                </el-table-column>
+                <el-table-column align="center" prop="relationFieldName" :label="$t('tableMange.relatedField')">
+                    <template slot-scope="scope">
+                        <el-select v-model="scope.row.relationFieldName" @change="relationFieldChange(scope.row)"
+                            :disabled="!scope.row.disableRelaFieldName" :placeholder="$t('tableMange.relatedField')"
+                            filterable>
+                            <el-option v-for="item in scope.row.relaFieldNameList" :key="item.fieldName"
+                                :label="item.fieldDescription" :value="item.fieldName">
+                            </el-option>
+                        </el-select>
+                    </template>
+                </el-table-column>
+                <el-table-column align="center" prop="relationType" :label="$t('tableMange.relatedType')">
+                    <template slot-scope="scope">
+                        <el-select v-model="scope.row.relationType" :placeholder="$t('tableMange.relatedType')"
+                            :disabled="!scope.row.disableRelaType" @change="relationTypeChangeHandler(scope.row)"
+                            filterable>
+                            <el-option v-for="item in relaTypeList" :key="item.value" :label="item.label"
+                                :value="item.value">
+                            </el-option>
+                        </el-select>
+                    </template>
+                </el-table-column>
+                <el-table-column align="center" prop="isShow" :label="$t('tableMange.isShow')">
+                    <template slot-scope="scope">
+                        <el-switch v-model="scope.row.isShow"></el-switch>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="popUpVisibleCancel">取 消</el-button>
+                <el-button type="primary" @click="popUpCreateHandle">确 定</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { mapState } from "vuex";
+import { v4 as uuidv4 } from "uuid";
+// 导入API方法
+import { getDicts } from "@/api/system/dict/data";
+import { addDragTable } from "@/api/tablelist/commonTable.js";
+import {
+    getFormName,
+    getListName
+} from "@/api/dragform/form.js";
+import { getTIdByTableKey, getTableInfo, getTableInfoByTableKey, removeByTableKey, addExcel, getExcelItem, updateExcel } from "@/api/system/table.js";
+export default {
+    name: "ExcelSheetEdit",
+    dicts: ["sys_time_format", "table_statistic_type"],
+    props: [],
+
+    data() {
+        return {
+            id: '',
+            excelJson: '',
+            name:'',
+            luckysheetOptions: {
+                container: 'luckysheet',
+                lang: 'zh',
+                forceCalculation: false,
+                plugins: ['chart'],
+                myFolderUrl: '/system/fromModel/index/excelSheet',
+                hook: {
+                    cellUpdated: (r, c, oldValue, newValue, isRefresh) => {
+                        console.log('单元格更新:', r, c, oldValue, newValue);
+                    },
+                    updated: (operate) => {
+                        console.log('操作更新:', operate);
+                    },
+                    cellEditBefore: (range) => {
+                        console.log('编辑前:', range);
+                    },
+                    cellEditAfter: (range) => {
+                        console.log('编辑后:', range);
+                    }
+                }
+            },
+            luckysheetInitialized: false,
+            originalWindowOpen: null,
+            pendingData: null,
+            // 弹窗
+            popUpVisible: false,
+            // 弹窗表格名称
+            popUpTableName: '',
+            // 弹窗表格列表
+            popUpTableList: [],
+            // 弹窗表格字段option[]
+            popUpTableFieldList: [],
+
+            relationTableList: [], //关联表格列表
+            // 关联方式option[]
+            relaTypeList: [
+                {
+                    label: "等值连接",
+                    value: "INNER JOIN",
+                },
+                {
+                    label: "左连接",
+                    value: "LEFT JOIN",
+                },
+                {
+                    label: "右连接",
+                    value: "RIGHT JOIN",
+                },
+            ],
+            isInputInvalid: false,
+            errorMessage: '',
+            dtName: '',
+            uuid: "",
+            tableKey: "",
+            // 修改表格的idList
+            tIdList: [],
+            tId: "",
+            // 当前选区
+            rangeAxis: [],
+            // 选区数据缓存
+            rangeDataCache: {},
+            // 存储所有选区的数据对象
+            rangeDataObjects: [],
+        };
+    },
+
+    mounted() {
+        // 清空之前的数据
+        this.clearPreviousData();
+        // 动态引入Luckysheet资源
+        this.loadLuckysheet();
+        // 获取所有表
+        this.getAllTable();
+        // 获取路由参数
+        const { mode, editorId } = this.$route.query;
+        // console.log('路由参数:', { mode, editorId });
+        if (mode == 3 && editorId) {
+            // 编辑且id存在
+            this.getExistingData(editorId);
+        } else {
+            // 新增模式 - 获取模板数据
+            this.getTemplateData();
+        }
+
+
+    },
+
+    // 添加keep-alive支持
+    activated() {
+        // 组件被激活时,清空之前的数据并重新初始化
+        console.log('组件被激活,清空数据并重新初始化');
+        this.clearPreviousData();
+        this.loadLuckysheet();
+    },
+
+    deactivated() {
+        // 组件被缓存时,保存状态
+        console.log('组件被缓存,保存当前状态');
+    },
+    computed: {
+        ...mapState({
+            databaseName: (state) => state.user.dataSource.databaseName,
+            databaseType: (state) => state.user.dataSource.databaseType,
+            username: (state) => state.user.dataSource.username,
+        }),
+    },
+    watch: {
+        popUpTableName: function (val) {
+            if (val) {
+                this.relationTableList = this.popUpTableList
+                    .filter((item) => item.tableName != val)
+                    .map((item) => {
+                        return {
+                            tableName: item.tableName,
+                            tableComment: item.tableComment,
+                        };
+                    });
+            } else {
+                this.relationTableList = [];
+            }
+        },
+    },
+    methods: {
+        async openPopUp() {
+            this.popUpVisible = true;
+            this.rangeAxis = luckysheet.getRangeAxis();
+            
+            // 添加详细的调试信息
+            console.log('=== openPopUp 调试信息 ===');
+            console.log('this.rangeDataObjects:', this.rangeDataObjects);
+            console.log('this.rangeDataObjects.length:', this.rangeDataObjects.length);
+            console.log('this.rangeDataObjects类型:', typeof this.rangeDataObjects);
+            console.log('this.rangeDataObjects是否为数组:', Array.isArray(this.rangeDataObjects));
+            
+            if (this.rangeDataObjects && this.rangeDataObjects.length > 0) {
+                console.log('第一个对象:', this.rangeDataObjects[0]);
+                console.log('第一个对象的rangeAxis:', this.rangeDataObjects[0]?.rangeAxis);
+            }
+            
+            // 获取所有sheet,获取当前激活sheet的数字索引
+            let sheets = luckysheet.getAllSheets();
+            let currentSheet = sheets.find(sheet => sheet.status == 1);
+            let activeSheetIndex = sheets.findIndex(sheet => sheet.index === currentSheet.index);
+            console.log('当前激活的sheet索引:', activeSheetIndex);
+            
+            // 检查当前选区是否已存在于rangeDataObjects中,且属于当前工作表
+            let existingRangeData = null;
+            let existingRangeIndex = -1;
+            
+            // 遍历当前选区,检查是否已存在且属于当前工作表
+            for (let i = 0; i < this.rangeAxis.length; i++) {
+                const currentRange = this.rangeAxis[i];
+                console.log('=== 开始检查选区 ===');
+                console.log('当前选区:', currentRange, '类型:', typeof currentRange);
+                console.log('当前工作表索引:', activeSheetIndex, '类型:', typeof activeSheetIndex);
+                console.log('rangeDataObjects总数:', this.rangeDataObjects.length);
+                
+                const existingIndex = this.rangeDataObjects.findIndex((item, index) => {
+                    console.log(`\n--- 检查第${index}个对象 ---`);
+                    console.log('item:', item);
+                    console.log('item.rangeAxis:', item.rangeAxis);
+                    console.log('item.rangeAxis[0]:', item.rangeAxis[0], '类型:', typeof item.rangeAxis[0]);
+                    console.log('item.activeSheetIndex:', item.activeSheetIndex, '类型:', typeof item.activeSheetIndex);
+                    
+                    // 严格比较,确保类型一致
+                    const rangeMatch = item.rangeAxis[0] === currentRange;
+                    const sheetMatch = String(item.activeSheetIndex) === String(activeSheetIndex);
+                    
+                    console.log('选区比较:', item.rangeAxis[0], '===', currentRange, '结果:', rangeMatch);
+                    console.log('工作表比较:', String(item.activeSheetIndex), '===', String(activeSheetIndex), '结果:', sheetMatch);
+                    console.log('最终结果:', rangeMatch && sheetMatch);
+                    
+                    return rangeMatch && sheetMatch;
+                });
+                
+                console.log('existingIndex结果:', existingIndex);
+                console.log('=== 选区检查结束 ===\n');
+                
+                if (existingIndex !== -1) {
+                    console.log(` this.rangeDataObjects: `,this.rangeDataObjects);
+
+                    existingRangeData = this.rangeDataObjects[existingIndex];
+                    existingRangeIndex = existingIndex;
+                    console.log(`找到已存在的选区数据(当前工作表): ${currentRange}`, existingRangeData);
+                    break; // 找到第一个匹配的选区就停止
+                }
+            }
+            
+            if (existingRangeData) {
+                // 如果找到已存在的选区数据,进行回显
+                console.log('使用已存在的选区数据进行回显:', existingRangeData);
+                
+                // 通过tableKey获取配置信息
+                if (existingRangeData.tableKey) {
+                    try {
+                        // 1. 通过 tableKey 获取 tId
+                        let tIdRes = await getTIdByTableKey(existingRangeData.tableKey);
+                        if (tIdRes.code == 200 && tIdRes.data) {
+                            let tId = tIdRes.data;
+                            // 2. 通过 tId 获取表格配置信息
+                            let res = await getTableInfo(tId);
+                            if (res.code == 200 && res.data) {
+                                let echoData = JSON.parse(res.data.echoData);
+                                this.popUpTableFieldList = echoData.tableFieldData;
+                                this.popUpTableName = echoData.tableName;
+                                this.dtName = res.data.dtName || '';
+                                console.log('echoData', echoData);
+                            } else {
+                                this.popUpTableFieldList = [];
+                                console.log('获取表格配置信息失败');
+                            }
+                        } else {
+                            this.popUpTableFieldList = [];
+                            console.log('通过tableKey获取tId失败');
+                        }
+                    } catch (error) {
+                        console.error('通过tableKey获取配置信息时出错:', error);
+                        this.popUpTableFieldList = [];
+                    }
+                } else {
+                    console.log('没有tableKey,无法获取配置信息');
+                    this.popUpTableFieldList = [];
+                }
+            } else {
+                // 如果没有找到已存在的选区数据,使用原有的缓存逻辑
+                const cacheKey = this.tableKey + JSON.stringify(this.rangeAxis);
+                if (this.rangeDataCache[cacheKey]) {
+                    // 有缓存,回显
+                    this.popUpTableFieldList = JSON.parse(JSON.stringify(this.rangeDataCache[cacheKey]));
+                    console.log('使用缓存数据回显');
+                } else {
+                    // 没有缓存,清空
+                    this.popUpTableFieldList = [];
+                    console.log('没有缓存数据,清空表格字段列表');
+                }
+            }
+            
+            console.log('打开弹窗,当前选区:', this.rangeAxis);
+            console.log('当前工作表索引:', activeSheetIndex);
+            console.log('当前表格字段列表:', this.popUpTableFieldList);
+        },
+        // 取消弹窗
+        popUpVisibleCancel() {
+            this.popUpVisible = false;
+            // 弹窗表格名称
+            this.popUpTableName = '';
+            // 弹窗表格字段option[] - 清空当前选择的表格字段
+            this.popUpTableFieldList = [];
+            // 关联表格列表 - 清空当前关联表数据
+            this.relationTableList = [];
+            // 重置输入验证状态
+            this.isInputInvalid = false;
+            // 重置别名
+            this.dtName = '';
+            // 重置错误提示
+            this.errorMessage = '';
+
+        },
+        // 确认弹窗
+        async popUpCreateHandle() {
+            this.isInputInvalid = true;
+            let columns = [];
+            let allColumns = [];
+            let validRes = this.validateTableData(this.popUpTableFieldList);
+            if (!validRes.val) {
+                this.errorMessage = validRes.msg;
+                return;
+            }
+            this.getCol(
+                this.popUpTableFieldList,
+                columns,
+                allColumns
+            );
+            
+            this.uuid = uuidv4();
+            this.tableKey = uuidv4();
+            let echoData = {
+            tableName: this.popUpTableName,
+            tableFieldData: this.popUpTableFieldList,
+            formData: '',
+            filterData: '',
+          };
+            let data = {
+                dtName: this.dtName,
+                dtTableName: this.popUpTableName,
+                dtType: "8",
+                sqlKey: this.tableKey,
+                tableKey: this.uuid,
+                tId: "",
+                dtColumnName: columns, //列字段标题名称(存储显示字段信息
+                tableSql: this.getSQLStr(),
+                echoData: JSON.stringify(echoData),
+            };
+            console.log(' this.rangeDataObjects',  this.rangeDataObjects);
+            if (this.tId) {
+                // res = await editTable(data);
+                // let res = await getTableInfo(this.tId);
+                // console.log('res---------', res);
+            } else {
+                let dataJ = [];
+                let tId = "";
+                let activeSheetIndex = '';
+                let res = await addDragTable(data);
+                if (res.code == 200) {
+
+                    // 获取到的表格数据
+                    let excelData = await getTableInfoByTableKey(this.uuid);
+                    if (excelData.code == 200 && excelData.data) {
+                        dataJ = excelData.data;
+                    } else {
+                        dataJ = [];
+                    }
+                    // 获取tId
+                    let tIdRes = await getTIdByTableKey(this.uuid);
+                    if (tIdRes.code == 200 && tIdRes.data) {
+                        tId = tIdRes.data;
+                    } else {
+                        tId = "";
+                    }
+                    // 获取所有sheet, 遍历sheets获取status为1的sheet名称
+                    let sheets = luckysheet.getAllSheets();
+                    let currentSheet = sheets.find(sheet => sheet.status == 1);
+                    let activeSheetIndex = sheets.findIndex(sheet => sheet.index === currentSheet.index);
+                    console.log('当前激活的sheet索引:', activeSheetIndex);
+
+                    let dataXQSJ = {
+                        tableKey: this.uuid,//tableKey
+                        rangeAxis: this.rangeAxis,//当前所有选区
+                        dataJ: dataJ,//当前选区数据
+                        tId: tId,//tId
+                        activeSheetIndex: activeSheetIndex,//当前激活的sheet名称
+                    }
+                    // 将dataXQSJ的dataJ写入到当前激活的sheet的rangeAxis所有选区中
+                    this.fillDataWithSetCellValue(dataXQSJ);
+
+                    // 遍历每个选区,存储或替换数据对象
+                    this.rangeAxis.forEach(async (range, index) => {
+                        console.log('range', range);
+
+                        // 创建当前选区的数据对象
+                        let rangeDataObj = {
+                            tableKey: this.uuid,
+                            rangeAxis: [range], // 单个选区
+                            activeSheetIndex: activeSheetIndex,
+                             tId: tId,
+                        };
+
+                        // 检查是否有重叠的选区(只判断同一个 sheet)
+                        const overlappingIndex = this.rangeDataObjects.findIndex(item => {
+                            if (item.activeSheetIndex !== activeSheetIndex) return false;
+                            const existingRange = item.rangeAxis[0];
+                            return this.isRangeOverlapping(range, existingRange);
+                        });
+
+                        if (overlappingIndex !== -1) {
+                            // 如果存在重叠选区,删除重叠选区之前的所有数据
+                            console.log(`检测到重叠选区: ${range} 与 ${this.rangeDataObjects[overlappingIndex].rangeAxis[0]},调用接口删除重叠选区之前的所有数据`);
+
+                            try {
+                                // 获取需要删除的选区数据(重叠选区之前的所有选区)
+                                const rangesToDelete = this.rangeDataObjects.slice(0, overlappingIndex + 1);
+                                console.log('需要删除的重叠选区:', rangesToDelete);
+                                let tableKey = this.rangeDataObjects[overlappingIndex].tableKey;
+                                console.log('需要删除的重叠选区tableKey:', tableKey);
+
+                                tableKey = {
+                                    tableKey: tableKey
+                                }
+                                // 调用删除接口
+                                let res = await removeByTableKey(tableKey);
+                                if (res.code == 200) {
+                                    console.log('删除成功');
+                                    // 删除成功后,更新本地数组
+                                    this.rangeDataObjects.splice(overlappingIndex, 1);
+                                    // 添加新的选区数据
+                                    this.rangeDataObjects.push(rangeDataObj);
+                                    console.log(`接口删除成功,已清空重叠选区及其之前的所有数据,添加新选区: ${range}`);
+                                } else {
+                                    console.log('删除失败');
+                                }
+
+                                // 模拟API调用
+                                console.log('调用删除接口,删除重叠选区:', rangesToDelete.map(item => item.rangeAxis[0]));
+
+                            } catch (error) {
+                                console.error('删除重叠选区数据失败:', error);
+                                this.$message.error('删除重叠选区数据失败');
+                            }
+                        } else {
+                            // 如果不存在重复或重叠,添加新数据
+                            this.rangeDataObjects.push(rangeDataObj);
+                            console.log(`添加新选区数据:`, range);
+                        }
+                    });
+
+                    console.log('当前所有选区数据对象:', this.rangeDataObjects);
+                }
+            }
+            // 清空错误提示和关闭弹窗
+            this.errorMessage = '';
+            this.popUpVisible = false;
+        },
+        // 递归获取列表信息
+        getCol(
+            tableFieldList,
+            columns,
+            allColumns = []
+        ) {
+            if (!tableFieldList.length) return;
+            for (let i = 0; i < tableFieldList.length; i++) {
+                let temp = tableFieldList[i];
+                let tempFieldName = "",
+                    exportFieldName = "";
+                if (temp.isChildren) {
+                    tempFieldName = temp.tableName + "_" + temp.fieldName;
+                    exportFieldName = temp.tableName + "@" + temp.fieldName;
+                } else {
+                    // tempFieldName = temp.fieldName;
+                    tempFieldName = temp.tableName + "_" + temp.fieldName;
+                    exportFieldName = temp.tableName + "_" + temp.fieldName;
+                }
+                // 保存所有字段
+                let obj = {
+                    tableName: temp.tableName,
+                    fieldName: temp.fieldName,
+                    fieldDescription: temp.fieldDescription,
+                };
+                allColumns.push(obj);
+
+                if (temp.isShow) {
+                    let tempObj = {};
+                    tempObj[tempFieldName] = temp?.fieldDescription;
+                    columns.push(tempObj);
+                }
+
+            }
+        },
+        // 校验字段合法性(非递归版)
+        validateTableData(popUpTableFieldList) {
+            if (!popUpTableFieldList.length) {
+                return {
+                    val: false,
+                    msg: "字段个数不能为空",
+                };
+            }
+            if (!this.dtName) {
+                return {
+                    val: false,
+                    msg: "别名不能为空",
+                };
+            }
+            for (let i = 0; i < popUpTableFieldList.length; i++) {
+                let temp = popUpTableFieldList[i];
+                if (!temp.fieldDescription?.trim() && temp.isShow) {
+                    return {
+                        val: false,
+                        msg: "显示的字段,字段描述不能为空",
+                    };
+                }
+                if (
+                    temp.relationTable &&
+                    (!temp.relationFieldName || !temp.relationType)
+                ) {
+                    return {
+                        val: false,
+                        msg: "关联条件不足,请完善关联条件",
+                    };
+                }
+            }
+            if (popUpTableFieldList.filter((item) => item.isShow).length == 0) {
+                return {
+                    val: false,
+                    msg: "显示的字段数不能为空",
+                };
+            }
+            return {
+                val: true,
+                msg: "",
+            };
+        },
+        // 获取表格字段option[]
+        async getAllTable() {
+            let data = {
+                databaseName: this.databaseName,
+                databaseType: this.databaseType,
+            };
+            let res = await getFormName(data);
+            console.log('getForm-Nameres', res);
+            const baseTable = await this.getDicts("base_table");
+            console.log('getDicts-baseTable', baseTable);
+            // 弹窗表格字段option[]
+            // 过滤掉在 baseTable.data 里出现过的表名,toLowerCase忽略大小写
+            this.popUpTableList = res.data.filter((item) => {
+                return !baseTable.data.some(
+                    (value) =>
+                        value.dictValue.toLowerCase() == item.tableName.toLowerCase()
+                );
+            });
+        },
+        // 获取关联表
+        getList() {
+            if (!this.popUpTableName) return;
+            let data = {
+                databaseName: this.databaseName,
+                databaseType: this.databaseType,
+                tableName: this.popUpTableName,
+            };
+            let popUpTableComment = this.getTableCommont(this.popUpTableName, this.popUpTableList);
+            // 获取当前表单结构信息
+            getListName(data).then((res) => {
+                console.log('res', res);
+                this.popUpTableFieldList = res.map((item, index) => {
+                    return {
+                        id: this.popUpTableName + "_" + item.fieldName,
+                        fieldName: item.fieldName,
+                        fieldDescription: item.fieldDescription,
+                        relationTable: "",
+                        relationFieldName: "",
+                        relaFieldNameList: [],
+                        disableRelaFieldName: false,
+                        relationType: "",
+                        relationShowField: [],
+                        relationShowFiledList: [],
+                        disableRelaType: false,
+                        isShow: true,
+                        isSearch: false,
+                        isExport: false,
+                        relationTableList: this.relationTableList,
+                        tableName: this.popUpTableName,
+                        tableComment: popUpTableComment,
+                        relationFieldList: [],
+                    };
+                });
+            });
+        },
+        // 获取当前表描述
+        getTableCommont(popUpTableName, popUpTableList) {
+            return popUpTableList.find((item) => item.tableName == popUpTableName).tableComment;
+        },
+        // 关联表变化回调
+        async ralationTableChange(row) {
+            this.popUpTableFieldList = this.popUpTableFieldList.filter((item) => {
+                return !row.relationFieldList.some((val) => {
+                    return val.id == item.id;
+                });
+            });
+            row.relationFieldName = "";
+            row.relationType = "";
+            row.disableRelaFieldName = false;
+            row.disableRelaType = false;
+            row.relationFieldList = [];
+            if (!row.relationTable) {
+                return;
+            }
+            // 获取关联表的字段
+            let data = {
+                databaseName: this.databaseName,
+                databaseType: this.databaseType,
+                tableName: row.relationTable,
+            };
+            let tableComment = this.getTableCommont(
+                row.relationTable,
+                this.popUpTableList
+            );
+            let res = await getListName(data);
+            // 关联字段下拉列表数据
+            row.relaFieldNameList = res.map((item) => {
+                return {
+                    fieldName: item.fieldName,
+                    fieldDescription: item.fieldDescription,
+                };
+            });
+            let relationTableList = row.relationTableList.filter(
+                (item) => row.relationTable != item.tableName
+            );
+            row.relationFieldList = row.relaFieldNameList.map((item, index) => {
+                return {
+                    id: row.relationTable + "_" + item.fieldName,
+                    fieldName: item.fieldName,
+                    fieldDescription: item.fieldDescription,
+                    relationTable: "",
+                    relationFieldName: "",
+                    relaFieldNameList: [],
+                    disableRelaFieldName: false,
+                    relationType: "",
+                    relationShowField: [],
+                    relationShowFiledList: [],
+                    disableRelaType: false,
+                    isShow: true,
+                    isSearch: false,
+                    isExport: false,
+                    relationTableList,
+                    tableName: row.relationTable,
+                    tableComment,
+                    relationFieldList: [],
+                    isChildren: true,
+                };
+            });
+            row.disableRelaFieldName = true;
+        },
+        // 关联字段回调
+        relationFieldChange(row) {
+            console.log('关联字段回调', row);
+            if (!row.relationFieldName) {
+                row.relationType = "";
+                row.disableRelaType = false;
+                row.relaFieldNameList = [];
+                return;
+            }
+            row.disableRelaType = true;
+        },
+        // 关联类型变化回调
+        relationTypeChangeHandler(row) {
+            let tempRelationFieldList = row.relationFieldList.filter((item) => {
+                return !this.popUpTableFieldList.find((val) => val.id === item.id);
+            });
+            //       // 确保关联字段的id是唯一的,添加时间戳或随机数
+            //       tempRelationFieldList = tempRelationFieldList.map((item, index) => {
+            //   return {
+            //     ...item,
+            //     id: item.id + '_' + Date.now() + '_' + index
+            //   };
+            // });
+            this.popUpTableFieldList = [...this.popUpTableFieldList, ...tempRelationFieldList];
+        },
+        // 清空之前的数据
+        clearPreviousData() {
+            console.log('清空之前的数据...');
+
+            // 不清空选区数据对象数组,因为这是从服务器加载的重要数据
+            // this.rangeDataObjects = [];
+            console.log('保留rangeDataObjects数据:', this.rangeDataObjects);
+
+            // 清空Luckysheet容器
+            const container = document.getElementById('luckysheet');
+            if (container) {
+                container.innerHTML = '';
+            }
+            // 销毁之前的Luckysheet实例
+            if (window.luckysheet) {
+                try {
+                    window.luckysheet.destroy();
+                    console.log('之前的Luckysheet实例已销毁');
+                } catch (error) {
+                    console.log('销毁之前的实例时出错:', error);
+                }
+            }
+
+            // 重置初始化状态
+            this.luckysheetInitialized = false;
+
+            // 清空可能存在的全局变量
+            if (window.luckysheetfile) {
+                delete window.luckysheetfile;
+            }
+
+            // 清空其他可能的全局变量
+            this.clearGlobalVariables();
+
+            // 移除可能存在的CSS和JS
+            this.removePreviousResources();
+        },
+
+        // 清空全局变量
+        clearGlobalVariables() {
+            const globalVars = [
+                'luckysheetfile',
+                'luckysheet_select_save',
+                'luckysheet_alternateformat_save',
+                'luckysheet_conditionformat_save',
+                'luckysheet_alternateformat_save_modelCustom'
+            ];
+
+            globalVars.forEach(varName => {
+                if (window[varName]) {
+                    delete window[varName];
+                    console.log(`已清空全局变量: ${varName}`);
+                }
+            });
+        },
+
+        // 移除之前的资源
+        removePreviousResources() {
+            // 移除可能重复的CSS
+            const existingCSS = document.querySelectorAll('link[href*="luckysheet"]');
+            existingCSS.forEach(link => {
+                if (link.href.includes('luckysheet')) {
+                    link.remove();
+                }
+            });
+
+            // 移除可能重复的JS
+            const existingJS = document.querySelectorAll('script[src*="luckysheet"]');
+            existingJS.forEach(script => {
+                if (script.src.includes('luckysheet')) {
+                    script.remove();
+                }
+            });
+        },
+
+        // 动态加载Luckysheet资源
+        async loadLuckysheet() {
+            try {
+                console.log('开始加载Luckysheet资源...');
+
+                // 动态加载CSS
+                await this.loadCSS('/static/luckysheet/plugins/css/pluginsCss.css');
+                await this.loadCSS('/static/luckysheet/plugins/plugins.css');
+                await this.loadCSS('/static/luckysheet/css/luckysheet.css');
+                await this.loadCSS('/static/luckysheet/assets/iconfont/iconfont.css');
+
+                // 动态加载JS
+                await this.loadJS('/static/luckysheet/plugins/js/plugin.js');
+                await this.loadJS('/static/luckysheet/luckysheet.umd.js');
+
+                console.log('Luckysheet资源加载完成,开始初始化...');
+
+                // 初始化Luckysheet
+                this.initLuckysheet();
+            } catch (error) {
+                console.error('加载Luckysheet失败:', error);
+                this.$message.error('Luckysheet加载失败,请检查资源路径');
+            }
+        },
+
+        // 动态加载CSS
+        loadCSS(href) {
+            return new Promise((resolve, reject) => {
+                // 检查是否已经加载过
+                if (document.querySelector(`link[href="${href}"]`)) {
+                    resolve();
+                    return;
+                }
+
+                const link = document.createElement('link');
+                link.rel = 'stylesheet';
+                link.href = href;
+                link.onload = () => {
+                    console.log(`CSS加载成功: ${href}`);
+                    resolve();
+                };
+                link.onerror = () => {
+                    console.error(`CSS加载失败: ${href}`);
+                    reject(new Error(`Failed to load CSS: ${href}`));
+                };
+                document.head.appendChild(link);
+            });
+        },
+
+        // 动态加载JS
+        loadJS(src) {
+            return new Promise((resolve, reject) => {
+                // 检查是否已经加载过
+                if (document.querySelector(`script[src="${src}"]`)) {
+                    resolve();
+                    return;
+                }
+
+                const script = document.createElement('script');
+                script.src = src;
+                script.onload = () => {
+                    console.log(`JS加载成功: ${src}`);
+                    resolve();
+                };
+                script.onerror = () => {
+                    console.error(`JS加载失败: ${src}`);
+                    reject(new Error(`Failed to load JS: ${src}`));
+                };
+                document.head.appendChild(script);
+            });
+        },
+
+        // 初始化Luckysheet
+        initLuckysheet() {
+            // 确保Luckysheet已加载
+            if (typeof window.luckysheet !== 'undefined') {
+                console.log('Luckysheet对象已存在,标记为已初始化...');
+                try {
+                    // 不要在这里创建实例,只标记为已初始化
+                    this.luckysheetInitialized = true;
+
+                    // 拦截myFolderUrl的点击事件
+                    this.interceptMyFolderUrlClick();
+
+                    // 检查是否有待处理的数据需要渲染
+                    if (this.pendingData) {
+                        console.log('渲染待处理的数据');
+                        this.renderData(this.pendingData);
+                        this.pendingData = null;
+                    } else {
+                        // 如果没有待处理数据,使用默认数据初始化
+                        console.log('使用默认数据初始化Luckysheet');
+                        this.renderData(this.getDefaultSheetData());
+                    }
+                } catch (error) {
+                    console.error('Luckysheet初始化失败:', error);
+                    this.$message.error('Luckysheet初始化失败');
+                }
+            } else {
+                // 如果还没加载完成,延迟重试
+                console.log('Luckysheet对象未找到,延迟重试...');
+                setTimeout(() => this.initLuckysheet(), 200);
+            }
+        },
+
+        // 拦截myFolderUrl的点击事件
+        interceptMyFolderUrlClick() {
+            // 方法1: 移除原有的点击事件
+            $(document).off('click', '.luckysheet-info-detail-title');
+
+            // 方法2: 阻止默认行为并自定义跳转
+            $(document).on('click', '.luckysheet-info-detail-title', (e) => {
+                e.preventDefault();
+                e.stopPropagation();
+                console.log('myFolderUrl点击被拦截,执行自定义跳转');
+
+                // 使用Vue Router进行跳转,避免页面刷新
+                this.$router.push('/system/fromModel/index/excelSheet').then(() => {
+                    // 跳转成功后清空数据
+                    this.clearPreviousData();
+                });
+
+                return false;
+            });
+
+            // 方法3: 重写window.open方法
+            this.originalWindowOpen = window.open;
+            const that = this; // 保存this引用
+            window.open = function (url, target, features) {
+                if (url && (url.includes('myFolderUrl') || url.includes('/system/fromModel/index/excelSheet'))) {
+                    console.log('myFolderUrl跳转被拦截:', url);
+                    console.log('准备执行路由跳转...');
+
+                    // 使用Vue Router进行跳转
+                    try {
+                        // 使用相对路径,避免路径问题
+                        that.$router.push('/system/fromModel/index/excelSheet').then(() => {
+                            console.log('路由跳转成功');
+                            // 跳转成功后清空数据
+                            that.clearPreviousData();
+                        }).catch(err => {
+                            console.error('路由跳转失败:', err);
+                            // 如果路由跳转失败,使用备用方法
+                            console.log('使用备用跳转方法');
+                            window.location.href = '/system/fromModel/index/excelSheet';
+                        });
+                    } catch (error) {
+                        console.error('路由跳转异常:', error);
+                        // 如果出现异常,使用备用方法
+                        window.location.href = '/system/fromModel/index/excelSheet';
+                    }
+
+                    return null;
+                }
+                return that.originalWindowOpen.call(this, url, target, features);
+            };
+        },
+
+        // 设置初始数据
+        setInitialData() {
+            // 这里可以设置一些初始的表格数据
+            // 例如:设置单元格值、格式等
+            console.log('设置初始数据...');
+        },
+
+        // 获取表格数据
+        getSheetData() {
+            if (window.luckysheet) {
+                const data = window.luckysheet.getAllSheets();
+                console.log('当前表格数据:', data);
+                return data;
+            }
+            return null;
+        },
+
+        // 保存数据
+        async saveData() {
+            let data = this.getSheetData();
+            let name = luckysheet.getWorkbookName();
+            if (data) {
+                console.log('保存数据:', data);
+                try {
+                    // 获取所有 sheet
+                    let allSheets = luckysheet.getAllSheets();
+
+                    // 处理 rangeDataObjects,统一 activeSheetIndex 为数字下标
+                    this.rangeDataObjects.forEach(obj => {
+                        let idx = allSheets.findIndex(sheet => String(sheet.index) === String(obj.activeSheetIndex));
+                        if (idx !== -1) {
+                            obj.activeSheetIndex = idx;
+                        }
+                    });
+
+                    // 获取路由参数
+                    console.log('转换后的数据:', data[0]?.celldata);
+                    // 准备保存的数据
+                    const saveData = {
+                        ...(this.id && { id: +this.id }),
+                        name: name || '默认表格',
+                        excelJson: JSON.stringify(data.map(sheet => ({
+                            name: sheet.name,
+                            celldata: sheet.celldata,
+                        }))),
+                        excelTableConfig: this.rangeDataObjects.length > 0 ? JSON.stringify(this.rangeDataObjects.map(item => ({
+                            tableKey: item.tableKey,
+                            rangeAxis: item.rangeAxis,
+                            activeSheetIndex: item.activeSheetIndex
+                        }))) : '', // 保存简化的选区配置数据
+                        
+                        // 可以添加其他需要保存的字段
+                    };
+                    console.log('调用保存API--------------:', saveData);
+                    if(this.id && this.id !== ""){
+                        // 有ID,调用更新方法 (PUT)
+                        updateExcel(saveData).then(res => {
+                            console.log('更新成功:', res);
+                            if (res.code == 200) {
+                                this.$message.success('数据保存成功');
+                                // 关闭当前tab并跳转
+                                this.$store.dispatch('tagsView/delView', this.$route).then(() => {
+                                    this.$router.push('/system/fromModel/index/excelSheet');
+                                });
+                            } else {
+                                this.$message.error('数据保存失败');
+                            }
+                        }).catch(err => {
+                            console.error('更新失败:', err);
+                            this.$message.error('数据保存失败');
+                        });
+                    } else {
+                        // 没有ID,调用新增方法 (POST)
+                        addExcel(saveData).then(res => {
+                            console.log('新增成功:', res);
+                            if (res.code == 200) {
+                                this.$message.success('数据保存成功');
+                                // 关闭当前tab并跳转
+                                this.$store.dispatch('tagsView/delView', this.$route).then(() => {
+                                    this.$router.push('/system/fromModel/index/excelSheet');
+                                });
+                            } else {
+                                this.$message.error('数据保存失败');
+                            }
+                        }).catch(err => {
+                            console.error('新增失败:', err);
+                            this.$message.error('数据保存失败');
+                        });
+                    }
+
+
+                } catch (error) {
+                    console.error('保存数据失败:', error);
+                    this.$message.error('保存数据失败');
+                }
+            } else {
+                this.$message.warning('没有数据需要保存');
+            }
+        },
+
+        // 获取模板数据
+        async getTemplateData() {
+            try {
+                // 使用默认的空数据
+                let templateData = this.getDefaultSheetData();
+                console.log('templateData-------------', templateData);
+
+                this.renderData(templateData);
+            } catch (error) {
+                console.error('获取模板数据失败:', error);
+                this.$message.error('获取模板数据失败');
+            }
+        },
+
+        // 获取现有数据
+        async getExistingData(editorId) {
+            try {
+                // 当前id赋值
+                this.id = editorId;
+                // 使用 async/await 等待异步操作完成
+                const response = await getExcelItem(editorId);
+                // console.log('API响应:', response);
+                if (response.code == 200 && response.data) {
+                    // excel内容数据
+                    this.excelJson = JSON.parse(response.data?.excelJson);
+                    // 解析选区配置数据
+                    try {
+                        console.log('=== 解析excelTableConfig ===');
+                        console.log('response.data?.excelTableConfig:', JSON.parse(response.data?.excelTableConfig));
+                        console.log('excelTableConfig类型:', typeof response.data?.excelTableConfig);
+                        console.log('excelTableConfig是否为空:', !response.data?.excelTableConfig);
+                        console.log('excelTableConfig是否为空字符串:', response.data?.excelTableConfig === '');
+                        console.log('excelTableConfig.trim():', response.data?.excelTableConfig?.trim());
+                        if (response.data?.excelTableConfig && response.data.excelTableConfig.trim() !== '') {
+                            this.rangeDataObjects = JSON.parse(response.data.excelTableConfig);
+                            console.log('成功解析选区配置数据------------:', this.rangeDataObjects);
+                            // -----
+                        } else {
+                            this.rangeDataObjects = [];
+                            console.log('没有选区配置数据,初始化为空数组');
+                        }
+                    } catch (parseError) {
+                        console.error('解析选区配置数据失败:', parseError);
+                        console.error('解析失败的数据:', response.data?.excelTableConfig);
+                        this.rangeDataObjects = [];
+                        console.log('解析失败,初始化为空数组');
+                    }
+                    
+                    this.name = response.data?.name;
+                    console.log('excelJson------------', this.excelJson);
+                    console.log('rangeDataObjects------------', this.rangeDataObjects);
+                    // excelTableConfig: this.rangeDataObjects.length > 0 ? JSON.stringify(this.rangeDataObjects) : '', // 保存当前的选区数据
+
+                } else {
+                    this.excelJson = '';
+                    this.rangeDataObjects = [];
+                    console.log('没有找到数据或数据为空');
+                }
+                
+                // 解析excelJson
+                let existingData;
+                
+                if (this.excelJson) {
+                    try {
+                        let parsedData;
+                        if (typeof this.excelJson === 'string') {
+                            parsedData = JSON.parse(this.excelJson);
+                        } else {
+                            parsedData = this.excelJson;
+                        }
+                        let sheets = parsedData.map(sheet => ({
+                            ...sheet,
+                            // 这里可以补全 Luckysheet 需要的字段
+                        }));
+                        existingData = { sheets };
+                    } catch (parseError) {
+                        console.error('解析excelJson失败:', parseError);
+                        this.$message.error('解析Excel数据失败');
+                        // 如果解析失败,使用默认空数据
+                        existingData = this.getDefaultSheetData();
+                    }
+                } else {
+                    console.log('没有excelJson数据,使用默认数据');
+                    existingData = this.getDefaultSheetData();
+                }
+
+                this.renderData(existingData);
+
+                // 确保 activeSheetIndex 一致
+                let sheets = luckysheet.getAllSheets();
+                this.rangeDataObjects.forEach(obj => {
+                    let idx = sheets.findIndex(sheet => String(sheet.index) === String(obj.activeSheetIndex));
+                    if (idx !== -1) {
+                        obj.activeSheetIndex = idx;
+                    }
+                });
+            } catch (error) {
+                console.error('获取表格数据失败:', error);
+                this.$message.error('获取表格数据失败');
+                // 出错时使用默认数据
+                this.renderData(this.getDefaultSheetData());
+            }
+        },
+
+        // 渲染数据到Luckysheet
+        renderData(data) {
+            console.log('渲染数据到Luckysheet:', data);
+
+            // 等待Luckysheet初始化完成后再渲染数据
+            if (this.luckysheetInitialized && window.luckysheet) {
+                try {
+                    // 先销毁当前实例(如果存在)
+                    if (window.luckysheetfile) {
+                        console.log('销毁之前的Luckysheet实例...');
+                        window.luckysheet.destroy();
+                        // 等待一小段时间确保销毁完成
+                        setTimeout(() => {
+                            this.createLuckysheetInstance(data);
+                        }, 100);
+                    } else {
+                        this.createLuckysheetInstance(data);
+                    }
+                } catch (error) {
+                    console.error('渲染数据失败:', error);
+                    this.$message.error('渲染数据失败');
+                }
+            } else {
+                // 如果Luckysheet还没初始化,保存数据等待初始化完成
+                this.pendingData = data;
+                console.log('Luckysheet未初始化,数据已保存等待渲染');
+            }
+        },
+
+        // 创建Luckysheet实例
+        createLuckysheetInstance(data) {
+            try {
+                console.log('开始创建Luckysheet实例...');
+                
+                // 创建新实例并加载数据
+                const options = {
+                    ...this.luckysheetOptions,
+                    data: JSON.parse(JSON.stringify(data.sheets))
+                };
+                console.log('options--------', options);
+                
+                // 确保数据格式正确
+                if (!options.data || !Array.isArray(options.data)) {
+                    console.warn('数据格式不正确,使用默认数据');
+                    options.data = this.getDefaultSheetData().sheets;
+                }
+                
+                console.log('options.data=================:', options.data);
+                console.log('luckysheetOptions=====================ss:', this.luckysheetOptions);
+                
+                window.luckysheet.create({
+                    ...this.luckysheetOptions,
+                    data: options.data
+                });
+                console.log('Luckysheet实例创建成功');
+                
+                if(this.name){
+                    luckysheet.setWorkbookName(this.name);
+                }
+            } catch (error) {
+                console.error('创建Luckysheet实例失败:', error);
+                this.$message.error('创建Luckysheet实例失败');
+            }
+        },
+
+        // 递归拼接SQL字段和JOIN
+        getSQLString(tableFieldList, fieldArr, tableArr, sqlType = "mysql") {
+            let prefix = "{DBNAME}.";
+            let asOrSpace = sqlType === "oracle" ? " " : " AS ";
+            for (let i = 0; i < tableFieldList.length; i++) {
+                let temp = tableFieldList[i];
+                // 拼接字段
+                let tempArr = prefix + temp.tableName + "." + temp.fieldName;
+                tempArr += asOrSpace + temp.tableName + "_" + temp.fieldName;
+                fieldArr.push(tempArr);
+
+                // 拼接关联
+                if (temp.relationTable && temp.relationFieldName && temp.relationType) {
+                    let isNeedUsername = sqlType === "oracle" ? (this.username ? this.username + "." : "") : "";
+                    tableArr.push(
+                        temp.relationType +
+                        " " +
+                        isNeedUsername +
+                        prefix +
+                        temp.relationTable +
+                        asOrSpace +
+                        temp.relationTable +
+                        " ON " +
+                        prefix +
+                        temp.relationTable +
+                        "." +
+                        temp.relationFieldName +
+                        " = " +
+                        prefix +
+                        temp.tableName +
+                        "." +
+                        temp.fieldName
+                    );
+                }
+            }
+        },
+
+        // 生成最终SQL
+        getSQLStr() {
+            let prefix = "{DBNAME}.";
+            let sqlType = this.databaseType || "mysql";
+            let asOrSpace = sqlType === "oracle" ? " " : " AS ";
+            let sql = "SELECT ";
+            let fieldNameArr = [], relaTypeArr = [];
+            this.getSQLString(this.popUpTableFieldList, fieldNameArr, relaTypeArr, sqlType);
+            // console.log('fieldNameArr', fieldNameArr);
+            sql += fieldNameArr.join(",") +
+                " FROM " +
+                prefix +
+                this.popUpTableName +
+                asOrSpace +
+                this.popUpTableName;
+            if (relaTypeArr.length) {
+                sql += " " + relaTypeArr.join(" ");
+            }
+            return sql;
+        },
+
+
+        // 每个选区都填充同一份二维数据
+        fillDataWithSetCellValue(dataXQSJ) {
+            if (window.luckysheet) {
+                try {
+                    const rangeAxis = dataXQSJ.rangeAxis;
+                    const dataJ = dataXQSJ.dataJ; // 这里是一份二维数组
+                    const flowdata = luckysheet.flowdata();
+
+                    rangeAxis.forEach((rangeStr) => {
+                        const coordinates = this.parseRangeString(rangeStr);
+                        if (coordinates) {
+                            this.fillRangeWithData(coordinates, dataJ, flowdata);
+                        }
+                    });
+
+                    luckysheet.jfrefreshgrid();
+                    console.log('所有选区填充完成');
+
+                    // 保存本次数据到缓存
+                    const cacheKey = dataXQSJ.tableKey + JSON.stringify(dataXQSJ.rangeAxis);
+                    this.rangeDataCache[cacheKey] = JSON.parse(JSON.stringify(this.popUpTableFieldList));
+                } catch (error) {
+                    console.error('填充数据失败:', error);
+                }
+            } else {
+                console.error('Luckysheet未初始化,无法填充数据');
+            }
+        },
+
+        // 填充数据到指定选区,支持二维数组
+        fillRangeWithData(coordinates, dataBlock, flowdata) {
+            try {
+                const { startRow, endRow, startCol, endCol } = coordinates;
+                let rowCount = endRow - startRow + 1;
+                let colCount = endCol - startCol + 1;
+                for (let r = 0; r < rowCount; r++) {
+                    for (let c = 0; c < colCount; c++) {
+                        const cellValue = (dataBlock[r] && dataBlock[r][c]) ? dataBlock[r][c] : '';
+                        luckysheet.setcellvalue(startRow + r, startCol + c, flowdata, cellValue);
+                    }
+                }
+            } catch (error) {
+                console.error('填充选区数据失败:', error);
+            }
+        },
+
+        // 解析选区坐标字符串
+        parseRangeString(rangeStr) {
+            try {
+                // 处理单个单元格的情况,如 "A1", "C4"
+                if (/^[A-Z]+\d+$/.test(rangeStr)) {
+                    const match = rangeStr.match(/^([A-Z]+)(\d+)$/);
+                    if (match) {
+                        const col = this.columnToNumber(match[1]);
+                        const row = parseInt(match[2]) - 1; // 转换为0基索引
+                        return {
+                            startRow: row,
+                            endRow: row,
+                            startCol: col,
+                            endCol: col
+                        };
+                    }
+                }
+
+                // 处理矩形区域的情况,如 "A1:B3", "D9:E12"
+                if (/^[A-Z]+\d+:[A-Z]+\d+$/.test(rangeStr)) {
+                    const parts = rangeStr.split(':');
+                    const startMatch = parts[0].match(/^([A-Z]+)(\d+)$/);
+                    const endMatch = parts[1].match(/^([A-Z]+)(\d+)$/);
+
+                    if (startMatch && endMatch) {
+                        const startCol = this.columnToNumber(startMatch[1]);
+                        const startRow = parseInt(startMatch[2]) - 1;
+                        const endCol = this.columnToNumber(endMatch[1]);
+                        const endRow = parseInt(endMatch[2]) - 1;
+
+                        return {
+                            startRow: Math.min(startRow, endRow),
+                            endRow: Math.max(startRow, endRow),
+                            startCol: Math.min(startCol, endCol),
+                            endCol: Math.max(startCol, endCol)
+                        };
+                    }
+                }
+
+                console.warn('无法解析选区字符串:', rangeStr);
+                return null;
+            } catch (error) {
+                console.error('解析选区字符串失败:', error);
+                return null;
+            }
+        },
+
+        // 将列字母转换为数字
+        columnToNumber(column) {
+            let result = 0;
+            for (let i = 0; i < column.length; i++) {
+                result = result * 26 + (column.charCodeAt(i) - 64);
+            }
+            return result - 1; // 转换为0基索引
+        },
+
+        // 获取所有选区数据对象
+        getAllRangeDataObjects() {
+            return this.rangeDataObjects;
+        },
+
+        // 根据range获取数据对象
+        getRangeDataObjectByRange(range) {
+            return this.rangeDataObjects.find(item => item.rangeAxis[0] === range) || null;
+        },
+
+        // 根据索引获取数据对象
+        getRangeDataObjectByIndex(index) {
+            return this.rangeDataObjects[index] || null;
+        },
+
+        // 删除指定range的数据对象
+        removeRangeDataObject(range) {
+            const index = this.rangeDataObjects.findIndex(item => item.rangeAxis[0] === range);
+            if (index !== -1) {
+                this.rangeDataObjects.splice(index, 1);
+                console.log(`已删除选区数据: ${range}`);
+                return true;
+            }
+            return false;
+        },
+
+        // 清空所有选区数据对象
+        clearRangeDataObjects() {
+            this.rangeDataObjects = [];
+            console.log('已清空所有选区数据对象');
+        },
+
+        // 获取选区数据对象的数量
+        getRangeDataObjectsCount() {
+            return this.rangeDataObjects.length;
+        },
+
+        // 检查是否存在指定的range
+        hasRangeDataObject(range) {
+            return this.rangeDataObjects.some(item => item.rangeAxis[0] === range);
+        },
+
+        // 示例:展示选区数据对象的使用
+        showRangeDataObjectsInfo() {
+            console.log('=== 选区数据对象信息 ===');
+            console.log('总数量:', this.getRangeDataObjectsCount());
+
+            this.rangeDataObjects.forEach((dataObj, index) => {
+                console.log(`选区${index + 1}:`);
+                console.log('  - Range:', dataObj.rangeAxis[0]);
+                console.log('  - TableKey:', dataObj.tableKey);
+                 console.log('  - TId:', dataObj.tId);
+                console.log('  - activeSheetIndex:', dataObj.activeSheetIndex);
+            });
+        },
+
+        // 检查选区是否重叠
+        isRangeOverlapping(range1, range2) {
+            try {
+                const coords1 = this.parseRangeString(range1);
+                const coords2 = this.parseRangeString(range2);
+
+                if (!coords1 || !coords2) {
+                    return false;
+                }
+
+                // 检查是否有重叠
+                const rowOverlap = coords1.startRow <= coords2.endRow && coords1.endRow >= coords2.startRow;
+                const colOverlap = coords1.startCol <= coords2.endCol && coords1.endCol >= coords2.startCol;
+
+                return rowOverlap && colOverlap;
+            } catch (error) {
+                console.error('检查选区重叠失败:', error);
+                return false;
+            }
+        },
+
+        // 获取默认的sheet数据
+        getDefaultSheetData() {
+            return {
+                sheets: [{
+                    name: "Sheet1",
+                    color: "",
+                    index: 0,
+                    status: 1,
+                    order: 0,
+                    hide: 0,
+                    row: 36,
+                    column: 18,
+                    defaultRowHeight: 19,
+                    defaultColWidth: 73,
+                    celldata: [],
+                    config: {
+                        merge: {},
+                        rowlen: {},
+                        columnlen: {},
+                        rowhidden: {},
+                        colhidden: {},
+                        borderInfo: {},
+                        authority: {},
+                    },
+                    scrollLeft: 0,
+                    scrollTop: 0,
+                    luckysheet_select_save: [],
+                    calcChain: [],
+                    isPivotTable: false,
+                    pivotTable: {},
+                    filter_select: {},
+                    filter: null,
+                    luckysheet_alternateformat_save: [],
+                    luckysheet_alternateformat_save_modelCustom: [],
+                    luckysheet_conditionformat_save: {},
+                    frozen: {},
+                    chart: [],
+                    zoomRatio: 1,
+                    image: [],
+                    showGridLines: 1,
+                    dataVerification: {},
+                }]
+            };
+        },
+    },
+
+    beforeDestroy() {
+        // 组件销毁时清理资源
+        if (window.luckysheet) {
+            try {
+                window.luckysheet.destroy();
+                console.log('Luckysheet实例已销毁');
+            } catch (error) {
+                console.error('销毁Luckysheet实例失败:', error);
+            }
+        }
+
+        // 恢复原始的window.open方法
+        if (this.originalWindowOpen) {
+            window.open = this.originalWindowOpen;
+        }
+
+        // 移除事件监听器
+        $(document).off('click', '.luckysheet-info-detail-title');
+
+        this.luckysheetInitialized = false;
+    }
+};
+</script>
+
+<style scoped>
+.app-container {
+    position: relative;
+    height: 100vh;
+    width: 100%;
+    display: flex;
+    overflow: hidden;
+    flex-direction: column;
+}
+
+#luckysheet {
+    z-index: 1;
+}
+
+::v-deep .luckysheet-wa-editor {
+    overflow-x: auto;
+    overflow-y: hidden;
+}
+
+::v-deep #luckysheet-icon-morebtn {
+    right: 0;
+    position: relative;
+}
+
+.ipt {
+    height: 36px;
+    line-height: 36px;
+    font-size: 14px;
+    width: 100%;
+    outline: none;
+    text-align: center;
+    background-color: #fff;
+    border: 1px solid #dcdfe6;
+    color: #606266;
+    display: inline-block;
+    border-radius: 4px;
+}
+
+.isNullDesc {
+    border-color: #ff4949 !important;
+}
+
+.ipt:focus {
+    border-color: #1890ff;
+}
+
+.popUpTitle {
+    display: flex;
+    align-items: center;
+}
+
+.popUpTitleDiv {
+    width: 50px;
+    margin-bottom: 6px;
+    font-weight: bold;
+}
+</style>

+ 2 - 5
zkqy-ui/src/views/formCreate/layout/home/formCreateMange.vue

@@ -640,8 +640,6 @@ export default {
       const selectedColumns = this.mainDisplayColumns.map(c => c.selectedColumn).filter(Boolean);
       return this.mainTableColumns
     },
-
-
   },
   methods: {
     toggleImportDropdown() {
@@ -979,9 +977,8 @@ export default {
             `${customCode}\nnew Vue({`
           );
         } else if (zkqyCardItem){
-          let url = process.env.VUE_APP_BASE_API3
+          let url = 'https://yyq.mec-cloud.cn/api/'
           let htmlDataMbZkqyData;
-          console.log('this.v',this.optionCardDataPz)
 
           let columns = this.optionCardDataPz
           // 找到type为elCard的对象并添加columns属性
@@ -1004,7 +1001,7 @@ export default {
           });
           console.log('pageJson',pageJson)
           // this.$refs.designer.setRule(pageJson)
-          let { htmlDataMb } = this.$refs.designer.getSaveDate(true,JSON.stringify(columns),dataSource,url)
+          let { htmlDataMb } = this.$refs.designer.getSaveDate(true,JSON.stringify(columns),'fjqydb',url)
           htmlDataMbZkqyData = htmlDataMb
           htmlData = htmlDataMbZkqyData
         }else {

+ 388 - 131
zkqy-ui/src/views/formCreate/utils/index.js

@@ -412,6 +412,8 @@ export function htmlTemplate(json, options, zkqyData,dataSource,url) {
         <meta charset="UTF-8">
         <!-- 添加移动端视口设置 -->
         <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+        <meta name="apple-mobile-web-app-capable" content="yes">
+        <meta name="apple-mobile-web-app-status-bar-style" content="default">
         <!-- Import style -->
         <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/>
         <!-- Import Vue 2.7 -->
@@ -420,6 +422,9 @@ export function htmlTemplate(json, options, zkqyData,dataSource,url) {
         <script src="https://unpkg.com/element-ui/lib/index.js"></script>
         <!-- Import formCreate -->
         <script src="https://unpkg.com/@form-create/element-ui@super"><\/script>
+        <!-- 添加微信 JSSDK -->
+        <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
+        <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
         <style>
             html, body {
                 margin: 0;
@@ -454,7 +459,7 @@ export function htmlTemplate(json, options, zkqyData,dataSource,url) {
                 -webkit-background-clip: text;
                 background-clip: text;
                 -webkit-text-fill-color: transparent;
-                color: transparent; /* 必须加上 */
+                color: transparent; 
                 filter: drop-shadow(1px 2px 1px rgba(18, 77, 123, 0.45));
                 display: inline-block;
                 font-size: 44px;
@@ -469,8 +474,11 @@ export function htmlTemplate(json, options, zkqyData,dataSource,url) {
         </style>
     </head>
     <body>
-        <div id="app">
-            <form-create :rule="rule" :option="options" v-model:value="formData" v-model="api" @submit="onSubmit"></form-create>
+        <div>
+            <div id="app">
+                <form-create :rule="rule" :option="options" v-model:value="formData" v-model="api" @submit="onSubmit"></form-create>
+            </div>
+            // <iframe id="my-iframe" width="100%" height="100%" style="display: none; border: none; position: fixed; top: 0; left: 0; z-index: 9999; background: #fff;"></iframe>
         </div>
         <script>
             Vue.use(ELEMENT);
@@ -490,7 +498,6 @@ export function htmlTemplate(json, options, zkqyData,dataSource,url) {
                 methods: {
                     onSubmit(formData){
                         console.log('submit', formData);
-                        
                     },
                     async zkqyDataApi(data,type,id){
                         let zkqyData = this.zkqyData;
@@ -594,51 +601,34 @@ export function htmlTemplate(json, options, zkqyData,dataSource,url) {
                         return results;
                     }, 
                     clickImage(obj,id){
-                        console.log('clickImage方法参数obj::', obj);
-                        console.log('clickImage方法参数id:', id);
-                        if (id) {
-                            fetch('${url}' + 'api/mobilePageDesignData/queryMobileClickAddData/' + id, {
-                                method: 'GET',
-                                headers: {
-                                    'Accept': 'application/json',
-                                    'dbname': '${dataSource}',
-                                    'Content-Type': 'application/json'
-                                }
-                            }).then(response => {
-                                if (!response.ok) {
-                                    throw new Error('HTTP error! status: ' + response.status);
-                                }
-                                return response.json();
-                            }).then(data => {
-                                console.log('htmlData', data?.data?.htmlData);
-                                const decodedHtml = decodeURIComponent(data?.data?.htmlData);
-                                const iframe = document.createElement('iframe');
-                                iframe.srcdoc = decodedHtml;
-                                iframe.style.width = '100%';
-                                iframe.style.height = '100vh';
-                                iframe.style.border = 'none';
-                                document.body.innerHTML = '';
-                                document.body.appendChild(iframe);
-                                iframe.onload = function() {
-                                    try {
-                                        const iframeWindow = iframe.contentWindow;
-                                        setTimeout(() => {
-                                            const vueInstance = iframeWindow.document.querySelector("#app").__vue__;
-                                            if (vueInstance) {
-                                                if (typeof vueInstance?.searchCardList === 'function') {
-                                                    vueInstance.searchCardList();
-                                                }
-                                            }
-                                        }, 1000);
-                                    } catch (error) {
-                                        console.error("调用 iframe 方法时出错:", error);
-                                    }
-                                };
-                            }).catch(error => {
-                                console.error('调用接口出错:', error);
-                            });
+                     if (id) {
+                        if (typeof wx !== 'undefined' && wx.miniProgram) {
+                            try {
+                                 // 先发送消息
+                                    wx.miniProgram.postMessage({
+                                        data: {
+                                            type: 'navigation',
+                                            id: id
+                                        }
+                                    });
+                                    // 跳转时传递 id 参数
+                                    wx.miniProgram.redirectTo({
+                                        url: "/pages/detail/webView" + id + "?id=" + id,
+                                        success: function () {
+                                            console.log('页面跳转成功');
+                                        },
+                                        fail: function (err) {
+                                            console.error('页面跳转失败:', err);
+                                        }
+                                    });
+                            } catch (error) {
+                                console.error('微信小程序跳转失败:', error);
+                            }
+                        }else {
+                            console.error('wx.miniProgram 未定义,可能未正确加载微信 JSSDK');
+                            alert('请在微信小程序中打开');
                         }
-                    },
+                    }
                 },
                 mounted() {
                     if (sessionStorage.getItem('upload_row')) {
@@ -740,13 +730,8 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
             searchInputTemplate = `
                 <div style="display: flex;
                             align-items: center;
-                            position: absolute;
-                            top: 8%;
                             justify-content: flex-end;
-                            z-index: 500;
-                            width: 90%;
-                            left: 50%;
-                            transform: translate(-50%, -50%);">
+                            width: 90%;">
                     <el-input placeholder="请输入内容" v-model="selectValue" 
                      suffix-icon="el-icon-search"
                     @change="searchCardList"
@@ -756,14 +741,9 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
         } else if (cardComponent?.cardSelectType == 'monthRange') {
             searchInputTemplate = `
             <div style="display: flex;
-                            align-items: center;
-                            position: absolute;
-                            top: 200px;
-                            z-index: 500;
-                            width: 90%;
-                            left: 50%;
-                            transform: translate(-50%, -50%);"
-                            class="zkqy-monthRange">
+                        align-items: center;
+                        justify-content: flex-end; 
+                        width: 90%;" class="zkqy-monthRange">
                   <el-date-picker
                     v-model="selectValue"
                     type="month"
@@ -775,14 +755,10 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
             </div>`
         } else if (cardComponent?.cardSelectType == 'select') {
             searchInputTemplate = `
-                <div style="display: flex;
+                    <div style="display: flex;
                             align-items: center;
-                            position: absolute;
-                            top: 8%;
-                            z-index: 500;
-                            width: 90%;
-                            left: 50%;
-                            transform: translate(-50%, -50%);">
+                            justify-content: flex-end; 
+                            width: 90%;">
                     <el-select v-model="selectValue" placeholder="请选择" suffix-icon="el-icon-search" class="zkqy-searchInputTemplate" style="width: 100%" @change="searchCardList"  clearable>
                         <el-option
                             v-for="item in selectOptions"
@@ -794,14 +770,10 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                 </div>`;
         } else if (cardComponent?.cardSelectType == 'dateRange') {
             searchInputTemplate = `
-                <div style="display: flex;
+               <div style="display: flex;
                             align-items: center;
-                            position: absolute;
-                            top: 200px;
-                            z-index: 500;
-                            width: 90%;
-                            left: 50%;
-                            transform: translate(-50%, -50%);">
+                            justify-content: flex-end; 
+                            width: 90%;">
                     <el-date-picker
                         v-model="selectValue"
                         type="daterange"
@@ -843,17 +815,19 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
         <script src="https://unpkg.com/element-ui/lib/index.js"></script>
         <!-- Import formCreate -->
         <script src="https://unpkg.com/@form-create/element-ui@super"><\/script>
-
+        <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
+        <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
           <style>
             html,body{
                 margin: 0;
                 padding: 0;
                 background-color: rgba(249, 249, 251, 1);
+                overflow: hidden;
             }
              form{
-                height:80%;
-                    overflow: auto;
-                    }
+                height: 93vh;
+                overflow: scroll;
+            }
             .zkqy-searchInputTemplate input,
             .zkqy-searchInputTemplate textarea{
                 border-radius: 20px;
@@ -1016,7 +990,7 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                 font-family: "Microsoft YaHei", "微软雅黑", sans-serif;
             }
             .zkqy-inputStyle-bgxqSCDD label {
-            padding:0;
+                padding:0;
                 font-size: 16px;
                 color: #000000;
             }  
@@ -1055,9 +1029,9 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
     <body>
         <div id="app">
          <el-button type="primary" icon="el-icon-arrow-left" 
-         onclick="window.parent.location.reload()"
+          @click="handleBack"
          :style="{
-            position: 'absolute',
+            position: 'fixed',
             zIndex: '200',
             background: 'none',
             border: 'none',
@@ -1067,26 +1041,28 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
             color: isDateOrMonthRange ? '#ffffff' : '#000000'
           }">
         </el-button>
-            ${searchInputTemplate}
+          <div style="position: fixed;
+            z-index: 10;
+            width: 100%;
+            height: 86px;
+            background-color: rgba(249, 249, 251, 1);
+            display: flex;
+            justify-content: center;
+            align-items: flex-end;">
+                ${searchInputTemplate}
+            </div>
             <form-create :rule="rule" :option="options" v-model:value="formData" v-model="api" @submit="onSubmit"></form-create>
-            <!-- 分页 -->
-            <div class="block" style="position: absolute;
-                                        width: 100%;
-                                        bottom: 0px;
-                                        left: 0;
-                                        right: 0;
-                                        background: #ffffff;
-                                        display: flex;
-                                        justify-content: center;">
-                <el-pagination v-if="cardList && cardList.total > 0"
-                  @size-change="handleSizeChange"
-                  @current-change="handleCurrentChange"
-                  :current-page.sync="cardList.pageNum"
-                  :page-size="cardList.pageSize"
-                  layout="prev, pager, next"
-                  :total="cardList.total">
-                </el-pagination>
-            </div>     
+           <!-- 分页和加载状态 -->
+            <div class="block" style="width: 100%;
+            background: #F9F9FB;
+            display: flex;
+            justify-content: center;
+            flex-direction: column;
+            align-items: center;">
+                <div v-if="isLoading" style="color: #909399; font-size: 14px;">
+                    <i class="el-icon-loading"></i> 正在加载...
+                </div>
+            </div>
         </div>
         <script>
             Vue.use(ELEMENT);
@@ -1108,7 +1084,7 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                         cardList: {
                             pageId: '',
                             total: 0,
-                            pageSize: 2,
+                            pageSize: 10,
                             pageNum: 1
                         },
                         originalRule: null,
@@ -1124,18 +1100,83 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                             { value: '2', label: '未完成' },
                         ],
                         zkqyData:${zkqyData},
-                        isDateOrMonthRange: false
+                        isDateOrMonthRange: false,
+                        isWeixinIOS: false,
+                        isIOS: function () {
+                        var ua = navigator.userAgent.toLowerCase();
+                        if (ua.match(/iphone/i) == "iphone" || ua.match(/ipad/i) == "ipad" || ua.match(/ipod/i) == "ipod" || ua.match(/ios/i) == "ios") {
+                            return true;
+                        }
+                        return false;
+                    },
+                    isWeixinBrowser: function () {
+                        var ua = navigator.userAgent.toLowerCase();
+                        if (ua.match(/micromessenger/i) == "micromessenger") {
+                            return true;
+                        }
+                        return false;
+                    },
+                    isLoading: false,
                     };
                 },
                 mounted(){
+                    // 获取URL参数
+                    const urlParams = new URLSearchParams(window.location.search);
+                    const id = urlParams.get('id');
+                    const targetValue = urlParams.get('targetValue');
+                    const targetValueTZArray = urlParams.get('targetValueTZArray');
+                    // 添加滚动监听
+                    this.bindScrollListener();
+                    // 解码 targetValueTZArray
+                    let decodedTargetValueTZArray = null;
+                    // 处理数组url类型
+                    if (targetValueTZArray && targetValueTZArray !== 'undefined' && targetValueTZArray !== 'null') {
+                        try {
+                            // 先进行 URL 解码
+                            const decodedString = decodeURIComponent(targetValueTZArray);
+                            // 然后解析 JSON 字符串
+                            decodedTargetValueTZArray = JSON.parse(decodedString);
+                            console.log('解码后的 targetValueTZArray:', decodedTargetValueTZArray);
+                        } catch (error) {
+                            console.error('解码 targetValueTZArray 失败:', error);
+                        }
+                    }
                     // 保存原始规则
                     this.originalRule = JSON.parse(JSON.stringify(this.rule));
-                    const cardComponent = Array.isArray(this.rule) ? 
+                    const cardComponent = Array.isArray(this.rule) ?
                     this.rule.find(item => item.type === 'elCard') : null;
-                    
+                     // 如果是微信iOS环境
+                    if (this.isWeixinBrowser() && this.isIOS()) {
+                        // 将参数存储到localStorage
+                        if (targetValue && targetValue !== 'undefined' && targetValue !== 'null') {
+                            localStorage.setItem("targetValueJHGL", targetValue);
+                        }
+                        if (decodedTargetValueTZArray && decodedTargetValueTZArray !== 'undefined' && decodedTargetValueTZArray !== 'null') {
+                            localStorage.setItem("targetValueTZArrayJHGL", JSON.stringify(decodedTargetValueTZArray));
+                        }
+
+                        if (decodedTargetValueTZArray) {
+                            this.$nextTick(() => {
+                                this.searchCardList(targetValue, decodedTargetValueTZArray);
+                            });
+                        } else {
+                            this.$nextTick(() => {
+                                this.searchCardList();
+                            });
+                        }
+                    } else {
+                        console.log('是否循环', this.cardCycle)
+                        console.log('自选的一个接口', this.cardCallableInterface)
+                        // 有接收值
+                        let cardColumnTZJS = this.cardColumnTZJS
+                        if (!cardColumnTZJS && !this.isDateOrMonthRange) {
+                            this.getCardCycleNew({ pageId, pageNum, pageSize })
+                        }
+                        this.searchCardList()
+                    }
                     // 设置isDateOrMonthRange的值
                     this.isDateOrMonthRange = cardComponent?.cardSelectType === 'dateRange' || cardComponent?.cardSelectType === 'monthRange';
-                    
+
                     // 如果是日期范围类型,设置默认值为当前月的月初到月末 
                     if (cardComponent?.cardSelectType === 'dateRange') {
                         const now = new Date();
@@ -1145,35 +1186,114 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                             firstDay.toISOString().split('T')[0],
                             lastDay.toISOString().split('T')[0]
                         ];
-                     
                     }
                     if (cardComponent?.cardSelectType === 'monthRange') {
                         const now = new Date();
                         // 格式化为 YYYY-MM 格式
-                        const currentMonth = now.getFullYear()+'-'+String(now.getMonth() + 1).padStart(2, '0');
+                        const currentMonth = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0');
                         this.selectValue = currentMonth;
                     }
-                    
+
                     // 获取pageId
                     const x = cardComponent?.props?.pageId;
                     // 设置到cardList中
                     this.cardList.pageId = x;
                     // 获取分页参数
-                    let { pageId, pageNum, pageSize} = this.cardList;
-                    if(this.oldFlag){
-                        // 调用接口
-                        this.getTableLimitInfo({pageId, pageNum, pageSize});
-                   }else{
-                        console.log('是否循环',this.cardCycle)
-                        console.log('自选的一个接口',this.cardCallableInterface)
-                        // 有接收值
-                        let cardColumnTZJS = this.cardColumnTZJS
-                        if(!cardColumnTZJS){
-                            this.getCardCycleNew({pageId, pageNum, pageSize})
-                        }
-                   }
+                    let { pageId, pageNum, pageSize } = this.cardList;
+
+                    // 向父窗口发送 vueReady 消息
+                    window.parent.postMessage({ type: 'vueReady' }, '*');
+                    // 监听物理返回键
+                    window.history.pushState(null, null, document.URL);
+                    window.addEventListener('popstate', this.handleBack);
+                },
+                 beforeDestroy() {
+                    // 组件销毁时移除监听
+                    window.removeEventListener('popstate', this.handleBack);
+                },
+                watch: {
+                    // 监听rule的变化,当rule更新时重新绑定滚动监听器
+                    rule: {
+                        handler() {
+                            this.$nextTick(() => {
+                                this.bindScrollListener();
+                            });
+                        },
+                        deep: true
+                    }
                 },
                 methods: {
+                    bindScrollListener() {
+                        const form = document.querySelector('.el-form');
+                        if (form) {
+                            // 移除可能存在的旧监听器
+                            form.removeEventListener('scroll', this.handleScroll);
+                            // 添加新的监听器
+                            form.addEventListener('scroll', this.handleScroll);
+                        }
+                    },
+                    handleScroll(e) {
+                        const form = e.target;
+                        // 添加节流,避免频繁触发
+                        if (this.scrollTimer) {
+                            clearTimeout(this.scrollTimer);
+                        }
+                        this.scrollTimer = setTimeout(() => {
+                            // 计算滚动位置
+                            const scrollPosition = form.scrollHeight - form.scrollTop - form.clientHeight;
+                            console.log('滚动位置:', scrollPosition);
+
+                            // 当滚动到距离底部50px时触发加载
+                            if (scrollPosition <= 50) {
+                                console.log('滚动到底部', scrollPosition)
+                                console.log('this.cardList.pageNum * this.cardList.pageSize', this.cardList.pageNum * this.cardList.pageSize)
+                                if (this.cardList.total > this.cardList.pageNum * this.cardList.pageSize) {
+                                    console.log('滚动到底部,加载更多')
+                                    this.loadMore();
+                                }
+                            }
+                        }, 200); // 200ms的节流时间
+                    },
+                    loadMore() {
+                        console.log('loadMore')
+                        console.log('this.isLoading', this.isLoading)
+
+                        if (this.isLoading) return;
+                        this.isLoading = true;
+                        console.log('loadMore2')
+
+                        this.cardList.pageSize = this.cardList.pageSize + 10;
+                        this.searchCardList()
+                    },
+                    handleBack() {
+                     // 检查 wx 对象是否存在
+                        if (typeof wx !== 'undefined' && wx.miniProgram) {
+                            try {
+                                const urlParams = new URLSearchParams(window.location.search);
+                                const id = urlParams.get('id');
+                                // 先发送消息
+                                wx.miniProgram.postMessage({
+                                    data: {
+                                        type: 'navigation',
+                                        id: id
+                                    }
+                                });
+                                // 跳转时传递 id 参数
+                                wx.miniProgram.redirectTo({
+                                    // url: '/pages/detail/webView194?id=${id}',
+                                    url: '/pages/detail/webView',
+                                    success: function () {
+                                        console.log('页面跳转成功');
+                                    },
+                                    fail: function (err) {
+                                        console.error('页面跳转失败:', err);
+                                    }
+                                });
+                            } catch (error) {
+                                console.error('操作失败:', error);
+                            }
+                        }
+                    },
                     handleSizeChange(val) {
                         console.log("每页"+ val +"条");
                     },
@@ -1184,6 +1304,36 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                     },
                    async getCardCycleNew(params = {}) {
                             const endpoint = this.cardCallableInterface;
+                             // 确保参数正确传递
+                            const requestParams = {
+                                ...params,
+                                pageId: this.cardList.pageId,
+                                pageNum: this.cardList.pageNum,
+                                pageSize: this.cardList.pageSize
+                            };
+                            // 如果有选择值,添加到参数中
+                            if (this.selectValue) {
+                                if (Array.isArray(this.selectValue)) {
+                                    requestParams.beginTime = this.selectValue[0];
+                                    requestParams.endTime = this.selectValue[1];
+                                } else {
+                                    requestParams[this.selectRc] = this.selectValue;
+                                }
+                            }
+                            
+                            // 如果有保存的跳转值,添加到参数中
+                            if (this.savedTZJSValue && this.cardColumnTZJS) {
+                                if (Array.isArray(this.cardColumnTZJS)) {
+                                    this.cardColumnTZJS.forEach((field, index) => {
+                                        if (this.savedTZJSValue[index] !== undefined) {
+                                            requestParams[field] = this.savedTZJSValue[index];
+                                        }
+                                    });
+                                } else {
+                                    requestParams[this.cardColumnTZJS] = this.savedTZJSValue;
+                                }
+                            }
+                        
                             await this.fetchGet(endpoint, params, (data) => {
                                 if (data.code === 200) {
                                     console.log('Data', data);
@@ -1198,14 +1348,13 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                                         console.log('data.columns',data.data)
                                         console.log('data.columns',data.data.columns)
                                         console.log('data.result',data.data.result)
-
                                         // 检查result是否为空
                                         if (!data.data.result || data.data.result.length === 0) {
                                             console.log('result为空,使用模板卡片');
                                             this.cardList = {
                                                 pageId: this.cardList.pageId,
                                                 total: 0,
-                                                pageSize: 2,
+                                                pageSize: 10,
                                                 pageNum: 1
                                             }
                                             // 创建一个新的模板卡片,但不填入任何值
@@ -1243,7 +1392,7 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                                                     {
                                                         type: 'img',
                                                         attrs: {
-                                                            src: 'https://tc.z.wiki/autoupload/20250603/1l3o/1109X736/%E6%97%A0%E6%95%B0%E6%8D%AE.png',
+                                                            src: 'https://yyq.mec-cloud.cn/images/none.png',
                                                             alt: 'logo',
                                                             style: 'width: 184px; height: 122px;'
                                                         }
@@ -1310,6 +1459,7 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                                                             console.log('child',child);
                                                             // 要跳转的页面id 
                                                             let cardButtonTZYM = child?.cardButtonTZYM;
+                                                            let pageId = this.cardList.pageId;
                                                             let itemAssociatedField = child?.itemAssociatedField;
                                                             let itemAssociatedFieldTZ = child?.itemAssociatedFieldTZ;
                                                             let clickString = 
@@ -1329,6 +1479,7 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                                                             'console.log("当前点击的卡片索引:", '+(index+1)+');' +
                                                             'console.log("当前点击的targetChild:", targetChild);' +
                                                             'console.log("当前点击的targetChildTZ:", targetChildTZ);' +
+                                                            'let cardButtonTZYM ="'+ cardButtonTZYM +'";' +
                                                             'let targetValue = targetChild ? targetChild.value : null;' +
                                                             'let targetValueTZ = targetChildTZ ? targetChildTZ.value : null;' +
                                                             'let targetValueTZArray = ["'+itemAssociatedFieldTZ+'", targetValueTZ];' +
@@ -1338,6 +1489,36 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                                                             'console.log("关联字段:", "'+itemAssociatedField+'");' +
                                                             'console.log("跳转列:", "'+itemAssociatedFieldTZ+'");' +
                                                             'console.log("跳转列数组:", targetValueTZArray);' +
+                                                            'function isWeixinBrowser() {' +
+                                                            '    var ua = navigator.userAgent.toLowerCase();' +
+                                                            '    return ua.match(/MicroMessenger/i) == "micromessenger";' +
+                                                            '}' +
+                                                            'function isIOS() {' +
+                                                            '    var ua = navigator.userAgent.toLowerCase();' +
+                                                            '    return /iphone|ipad|ipod/.test(ua);' +
+                                                            '}' +
+                                                            'const isWeixinIOS = isWeixinBrowser() && isIOS();' +
+                                                            'if (isWeixinIOS) {' +
+                                                            '    try {' +
+                                                                '        wx.miniProgram.postMessage({' +
+                                                                '            data: {' +
+                                                                '                type: "navigation",' +
+                                                                '                id: '+cardButtonTZYM+',' +
+                                                                '            }' +
+                                                                '        });' +
+                                                                '        wx.miniProgram.redirectTo({' +
+                                                                '            url: "/pages/detail/webView"+cardButtonTZYM+"?id=" + cardButtonTZYM + "&targetValue=" + encodeURIComponent(targetValue) + "&targetValueTZArray=" + encodeURIComponent(JSON.stringify(targetValueTZArray)),' +
+                                                                '            success: function() {' +
+                                                                '                console.log("页面跳转成功");' +
+                                                                '            },' +
+                                                                '            fail: function(err) {' +
+                                                                '                console.error("页面跳转失败:", err);' +
+                                                                '            }' +
+                                                                '        });' +
+                                                                '    } catch (error) {' +
+                                                                '        console.error("操作失败:", error);' +
+                                                                '    }' +
+                                                            '} else {' +
                                                             'fetch("'+this.baseUrl+'api/mobilePageDesignData/queryMobileClickAddData/'+cardButtonTZYM+'", {' +
                                                             '    method: "GET",' +
                                                             '    headers: {' +
@@ -1410,8 +1591,6 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                             });
                     },
                      searchCardList(value,id){
-                     console.log('value',value)
-                     console.log('id',id)
                          if(value) {
                              // 如果是日期范围数组,需要特殊处理
                              if (Array.isArray(value)) {
@@ -1504,7 +1683,8 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                                     // 如果不是数组,保持原有逻辑
                                 console.log('this.selectValue------------------',this.selectValue)
                                 console.log('params[this.selectRc]------------------',params[this.selectRc])
-                                    params[this.selectRc] = this.selectValue;
+                                 this.selectValue = this.selectValue == 'undefined' ? '' : this.selectValue;    
+                                params[this.selectRc] = this.selectValue;
                                 }
                             }
                             
@@ -1517,11 +1697,84 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                             await this.fetchGet(endpoint, params, (data) => {
                                 if (data.code === 200) {
                                     console.log('Data', data);
+                                    // 更新分页总数
+                                    if(data?.data?.total > 0){
+                                        this.cardList.total = data.data.total;
+                                    }
                                     // 获取第一个 elCard 类型的组件作为模板
                                     const templateCard = Array.isArray(this.rule) ? 
                                         this.rule.find(item => item.type === 'elCard') : null;
                                     
                                     if (templateCard) {
+                                        // 检查数据是否为空
+                                        if (!data.rows || data.rows.length === 0) {
+                                            console.log('数据为空,使用模板卡片');
+                                            this.cardList = {
+                                                pageId: this.cardList.pageId,
+                                                total: 0,
+                                                pageSize: 2,
+                                                pageNum: 1
+                                            }
+                                            // 创建一个新的模板卡片,但不填入任何值
+                                            const emptyTemplateCard = JSON.parse(JSON.stringify(templateCard));
+                                            // 设置空卡片的样式为隐藏
+                                            emptyTemplateCard.style = {
+                                                ...emptyTemplateCard.style,
+                                                display: 'none'
+                                            };
+                                            // 递归清除所有子组件的值
+                                            const clearChildrenValues = (children) => {
+                                                children.forEach(child => {
+                                                    if (child.type === 'fcRow' || child.type === 'col') {
+                                                        clearChildrenValues(child.children);
+                                                    } else {
+                                                        child.value = '';
+                                                    }
+                                                });
+                                            };
+                                            clearChildrenValues(emptyTemplateCard.children);
+                                            const nonCardComponents = this.rule.filter(item => item.type !== 'elCard' && item.type !== 'div');
+                                            // 添加无数据提示的 div
+                                            const noDataDiv = {
+                                                type: 'div',
+                                                style: {
+                                                    width: '100%',
+                                                    height: '500px',
+                                                    display: 'flex',
+                                                    justifyContent: 'flex-start',
+                                                    alignItems: 'center',
+                                                    flexDirection: 'column',
+                                                    paddingTop: '3rem'
+                                                },
+                                                children: [
+                                                    {
+                                                        type: 'img',
+                                                        attrs: {
+                                                            src: 'https://tc.z.wiki/autoupload/20250603/1l3o/1109X736/%E6%97%A0%E6%95%B0%E6%8D%AE.png',
+                                                            alt: 'logo',
+                                                            style: 'width: 184px; height: 122px;'
+                                                        }
+                                                    },
+                                                    {
+                                                        type: 'span',
+                                                        style: {
+                                                            fontSize: '11px',
+                                                            color: '#C8C8C8'
+                                                        },
+                                                        children: ['暂 无 数 据']
+                                                    }
+                                                ]
+                                            };
+                                            // 将空状态 div 和隐藏的原始卡片都添加到 rule 中
+                                            this.rule = [...nonCardComponents, noDataDiv, emptyTemplateCard];
+                                            // 强制更新视图
+                                            this.$nextTick(() => {
+                                                const ruleJson = formCreate.toJson([...this.rule]);
+                                                this.rule = formCreate.parseJson(ruleJson);
+                                            });
+                                            return;
+                                        }
+
                                         const newRule = data.rows.map((row, index) => {
                                             const newCard = JSON.parse(JSON.stringify(templateCard));
                                             
@@ -1587,10 +1840,14 @@ export function htmlTemplateCard(json, options,zkqyData,dataSource,url) {
                                             return newCard;
                                         });
                                         
-                                        // this.rule = newRule.length > 0 ? newRule : [templateCard];
-                                         // 保留非elCard类型的组件(如elImage)
+                                        // 保留非elCard类型的组件(如elImage)
                                         const nonCardComponents = this.rule.filter(item => item.type !== 'elCard');
                                         this.rule = newRule.length > 0 ? [...nonCardComponents, ...newRule] : [...nonCardComponents, templateCard];
+                                        // 强制更新视图
+                                        this.$nextTick(() => {
+                                            const ruleJson = formCreate.toJson([...this.rule]);
+                                            this.rule = formCreate.parseJson(ruleJson);
+                                        });
                                         console.log('更新后的 rule:', this.rule);
                                     } else {
                                         this.rule = this.originalRule || [];

+ 66 - 61
zkqy-ui/src/views/tableMange/index.vue

@@ -13,15 +13,16 @@
             @getList="getList"
             ref="mychild"
           /> -->
-          <el-select v-model="tableName" :placeholder="$t('tableMange.selectTable')" filterable @change="getList" class="mb10">
+          <el-select v-model="tableName" :placeholder="$t('tableMange.selectTable')" filterable @change="getList"
+            class="mb10">
             <el-option v-for="item in tableList" :key="item.tableName" :label="item.tableComment"
               :value="item.tableName">
               <span class="discribe" style="float: left">{{
-      item.tableComment
-    }}</span>
+                item.tableComment
+                }}</span>
               <span style="float: right; color: #8492a6; font-size: 13px">{{
-        item.tableName
-      }}</span>
+                item.tableName
+                }}</span>
             </el-option>
           </el-select>
           <!-- <el-form
@@ -45,14 +46,14 @@
               <template slot-scope="scope">
                 <!-- <el-form-item size="normal" prop="fieldDescription"> -->
                 <input :class="{
-      isNullDesc:
-        scope.row.fieldDescription == '' &&
-          scope.row.isShow &&
-          isInputInvalid
-          ? true
-          : false,
-      ipt: true,
-    }" v-model="scope.row.fieldDescription" />
+                  isNullDesc:
+                    scope.row.fieldDescription == '' &&
+                      scope.row.isShow &&
+                      isInputInvalid
+                      ? true
+                      : false,
+                  ipt: true,
+                }" v-model="scope.row.fieldDescription" />
                 <!-- <el-input v-model="scope.row.fieldDescription" /> -->
                 <!-- </el-form-item> -->
               </template>
@@ -60,8 +61,8 @@
             <el-table-column align="center" prop="relationTable" :label="$t('tableMange.relatedTable')">
               <template slot-scope="scope">
                 <el-select v-model="scope.row.relationTable" :disabled="!scope.row.relationTableList ||
-      !scope.row.relationTableList.length
-      " :placeholder="$t('tableMange.selectTable')" clearable filterable @change="ralationTableChange(scope.row)">
+                  !scope.row.relationTableList.length
+                  " :placeholder="$t('tableMange.selectTable')" clearable filterable @change="ralationTableChange(scope.row)">
                   <el-option v-for="item in scope.row.relationTableList" :key="item.tableName"
                     :label="item.tableComment" :value="item.tableName">
                     <span style="float: left">{{ item.tableComment }}</span>
@@ -82,8 +83,8 @@
             </el-table-column>
             <el-table-column align="center" prop="relationType" :label="$t('tableMange.relatedType')">
               <template slot-scope="scope">
-                <el-select v-model="scope.row.relationType" :placeholder="$t('tableMange.relatedType')" :disabled="!scope.row.disableRelaType"
-                  @change="relationTypeChangeHandler(scope.row)" filterable>
+                <el-select v-model="scope.row.relationType" :placeholder="$t('tableMange.relatedType')"
+                  :disabled="!scope.row.disableRelaType" @change="relationTypeChangeHandler(scope.row)" filterable>
                   <el-option v-for="item in relaTypeList" :key="item.value" :label="item.label" :value="item.value">
                   </el-option>
                 </el-select>
@@ -182,8 +183,8 @@
                 <el-form-item>
                   <el-button size="mini" @click="previewHandle">{{ $t('tableMange.preview') }}</el-button>
                   <el-button size="mini" type="primary" @click="createHandle">{{
-      tId ? $t('tableMange.confirmModify') : $t('tableMange.confirmCreate')
-    }}
+                    tId ? $t('tableMange.confirmModify') : $t('tableMange.confirmCreate')
+                    }}
                   </el-button>
                 </el-form-item>
               </el-form>
@@ -205,7 +206,8 @@
               <el-table-column prop="statisticType" :label="$t('tableMange.statisticType')">
               </el-table-column>
 
-              <el-table-column :label="$t('tableMange.operation')" align="center" class-name="small-padding fixed-width">
+              <el-table-column :label="$t('tableMange.operation')" align="center"
+                class-name="small-padding fixed-width">
                 <template slot-scope="scope">
                   <el-dropdown>
                     <el-button type="warning" plain size="small">
@@ -213,11 +215,13 @@
                     </el-button>
                     <el-dropdown-menu slot="dropdown">
                       <el-dropdown-item>
-                        <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdateStat(scope.row)">{{ $t('tableMange.modify') }}
+                        <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdateStat(scope.row)">{{
+                          $t('tableMange.modify') }}
                         </el-button>
                       </el-dropdown-item>
                       <el-dropdown-item>
-                        <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDeleteStat(scope.row)">{{ $t('tableMange.delete') }}
+                        <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDeleteStat(scope.row)">{{
+                          $t('tableMange.delete') }}
                         </el-button>
                       </el-dropdown-item>
                     </el-dropdown-menu>
@@ -249,10 +253,10 @@
           <el-tooltip class="item" effect="dark" :content="item.statisticTitle" placement="top-start">
             <div class="title">
               {{
-      item.statisticTitle
-        ? item.statisticTitle
-        : item.statisticDescription
-    }}
+                item.statisticTitle
+                  ? item.statisticTitle
+                  : item.statisticDescription
+              }}
             </div>
           </el-tooltip>
           <div class="type">
@@ -280,11 +284,13 @@
           </el-button>
         </el-col>
         <el-col :span="1.5">
-          <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="false" @click="() => { }">{{ $t('tableMange.edit') }}
+          <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="false" @click="() => { }">{{
+            $t('tableMange.edit') }}
           </el-button>
         </el-col>
         <el-col :span="1.5">
-          <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="false" @click="() => { }">{{ $t('tableMange.delete') }}
+          <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="false" @click="() => { }">{{
+            $t('tableMange.delete') }}
           </el-button>
         </el-col>
         <el-col :span="1.5">
@@ -292,7 +298,9 @@
           </el-button>
         </el-col>
         <el-col :span="1.5">
-          <el-button type="warning" plain icon="el-icon-download" size="mini" @click="() => { }">{{ $t('tableMange.export') }}
+          <el-button type="warning" plain icon="el-icon-download" size="mini" @click="() => { }">{{
+            $t('tableMange.export')
+            }}
           </el-button>
         </el-col>
       </el-row>
@@ -308,11 +316,13 @@
               </el-button>
               <el-dropdown-menu slot="dropdown">
                 <el-dropdown-item>
-                  <el-button size="mini" type="text" icon="el-icon-edit" @click="() => { }">{{ $t('tableMange.modify') }}
+                  <el-button size="mini" type="text" icon="el-icon-edit" @click="() => { }">{{ $t('tableMange.modify')
+                    }}
                   </el-button>
                 </el-dropdown-item>
                 <el-dropdown-item>
-                  <el-button size="mini" type="text" icon="el-icon-delete" @click="() => { }">{{ $t('tableMange.delete') }}
+                  <el-button size="mini" type="text" icon="el-icon-delete" @click="() => { }">{{ $t('tableMange.delete')
+                    }}
                   </el-button>
                 </el-dropdown-item>
               </el-dropdown-menu>
@@ -326,8 +336,8 @@
         <span>
           <el-button @click="isShowPreview = false">{{ $t('tableMange.close') }}</el-button>
           <el-button type="primary" @click="createHandle">{{
-      tId ? $t('tableMange.confirmModify') : $t('tableMange.confirmCreate')
-    }}</el-button>
+            tId ? $t('tableMange.confirmModify') : $t('tableMange.confirmCreate')
+            }}</el-button>
         </span>
       </template>
     </el-dialog>
@@ -346,8 +356,8 @@
               <span class="discribe" style="float: left; margin-right: 5px">{{ isShowTableName }}
               </span>
               <span style="float: right; color: #8492a6; font-size: 13px">{{
-      item.fieldName
-    }}</span>
+                item.fieldName
+                }}</span>
             </el-option>
           </el-select>
         </el-form-item>
@@ -360,7 +370,8 @@
       </el-form>
       <span slot="footer" class="dialog-footer">
         <el-button @click="closeAddDialog">{{ $t('tableMange.cancel') }}</el-button>
-        <el-button v-if="staictitle == $t('tableMange.modify')" type="primary" @click="upadtaData">{{ $t('tableMange.confirm') }}</el-button>
+        <el-button v-if="staictitle == $t('tableMange.modify')" type="primary" @click="upadtaData">{{
+          $t('tableMange.confirm') }}</el-button>
 
         <el-button v-else type="primary" @click="addData">{{ $t('tableMange.confirm') }}</el-button>
       </span>
@@ -795,6 +806,7 @@ export default {
       row.relationFieldList = row.relaFieldNameList.map((item, index) => {
         return {
           id: row.relationTable + "_" + item.fieldName,
+          // id: row.relationTable + "_" + item.fieldName + "_" + Date.now() + "_" + index,
           fieldName: item.fieldName,
           fieldDescription: item.fieldDescription,
           relationTable: "",
@@ -823,6 +835,13 @@ export default {
       let tempRelationFieldList = row.relationFieldList.filter((item) => {
         return !this.tableFieldList.find((val) => val.id === item.id);
       });
+      //       // 确保关联字段的id是唯一的,添加时间戳或随机数
+      //       tempRelationFieldList = tempRelationFieldList.map((item, index) => {
+      //   return {
+      //     ...item,
+      //     id: item.id + '_' + Date.now() + '_' + index
+      //   };
+      // });
       this.tableFieldList = [...this.tableFieldList, ...tempRelationFieldList];
     },
     // 关联字段回调
@@ -904,7 +923,6 @@ export default {
     async getMenuList() {
       let res = await getMenuList();
       if (res.code == 200) {
-        this.menuList = res.data;
         this.menus = this.handleTree(res.data, "menuId");
       }
     },
@@ -936,7 +954,7 @@ export default {
       if (!tableFieldList.length) {
         return {
           val: false,
-          meg: "字段个数不能为空",
+          msg: "字段个数不能为空",
         };
       }
       for (let i = 0; i < tableFieldList.length; i++) {
@@ -1179,12 +1197,6 @@ export default {
 
         if (temp.isShow) {
           let tempObj = {};
-          // if (temp.isChildren) {
-          //   tempObj[temp.tableName + "_" + temp.fieldName] =
-          //     temp.fieldDescription;
-          // } else {
-          //   tempObj[temp.fieldName] = temp.fieldDescription;
-          // }
           tempObj[tempFieldName] = temp.fieldDescription;
           columns.push(tempObj);
         }
@@ -1195,15 +1207,6 @@ export default {
         if (temp.isExport) {
           tableExportField[exportFieldName] = temp.fieldDescription;
         }
-        // 递归
-        // if (temp.relationFieldList) {
-        //   this.getCol(
-        //     temp.relationFieldList,
-        //     columns,
-        //     searchFieldList,
-        //     tableExportField
-        //   );
-        // }
       }
     },
     // 更新路由
@@ -1531,7 +1534,7 @@ export default {
             if (res.code == 200) {
               // 新增默认按钮数据
               btnTemplate.tableKey = data.tableKey;
-              btnTemplate.menuID = result.data;
+              btnTemplate.menuID = result?.data;
               let btnRes = await insertByDefaultBtn(btnTemplate);
               if (btnRes.code == 200) {
                 // 发送权限请求
@@ -1601,12 +1604,13 @@ export default {
     async initTableData(tId) {
       let res = await getTableInfo(tId);
       if (res.code == 200) {
-        this.dragTableStatisticList = res.data.dragTableStatisticList;
-        this.dragTableStyleList = res.data.dragTableStyleList;
-        let echoData = JSON.parse(res.data.echoData);
-        this.tableName = echoData.tableName;
-        this.tableFieldList = echoData.tableFieldData;
-        this.filterDataEcho = echoData.filterData;
+        console.log('res.data----------------------------',res.data);
+        this.dragTableStatisticList = res?.data?.dragTableStatisticList;
+        this.dragTableStyleList = res?.data?.dragTableStyleList;
+        let echoData = JSON.parse(res?.data?.echoData);
+        this.tableName = echoData?.tableName;
+        this.tableFieldList = echoData?.tableFieldData;
+        this.filterDataEcho = echoData?.filterData;
         let {
           isShowList,
           timeFormate,
@@ -1645,9 +1649,10 @@ export default {
         }
         // this.formData.routePath
         this.editData = res.data;
+        this.menuId = res.data.menuId;
         let val = await getParticMenu(res.data.tableKey);
         if (val.code == 200) {
-          this.menuId = val.data?.menuId;
+          // this.menuId = val.data?.menuId;
         }
       } else {
         this.$message.error("数据回显失败");

+ 0 - 6
zkqy-ui/src/views/treeTable/index.vue

@@ -46,12 +46,6 @@ import DynamicForm from './components/DynamicForm.vue';
 import DynamicButtonGroup from './components/DynamicButtonGroup.vue';
 import { listTreeTable, removeTreeTable } from "@/api/treeTable/tableList";
 import { delMenu } from "@/api/system/menu";
-
-// import Treeselect from "@riophae/vue-treeselect";
-
-// import { delForm, addForm, updateForm, listForm } from "@/api/treeTable/form";
-// import { getMenuList, addMenu, getRouters } from "@/api/menu.js";
-// import {addGroup, listGroup, getTable, delGroup, updataGroup } from "@/api/relateTable/index.js";
 export default {
   name: "TreeTable",
   components: {

+ 86 - 3
zkqy-ui/src/views/treeTableMange/index.vue

@@ -39,9 +39,11 @@
 import DynamicForm from '../treeTable/components/DynamicForm.vue';
 import { listTable } from "@/api/dragform/tableList";
 import { addTreeTable, getTreeTable, updateTreeTable } from "@/api/treeTable/tableList";
+import { insertByDefaultBtn } from "@/api/tablelist/commonTable";
 import { getParticMenu, updateMenu } from "@/api/system/menu.js";
 import { v4 as uuidv4 } from "uuid";
 import { getMenuList, addMenu, tbnHasPerms } from "@/api/menu.js";
+import { getDicts } from "@/api/system/dict/data";
 import {
   getFormName,
   getListName
@@ -343,6 +345,8 @@ export default {
 
       /*  关于判断路由的声明 end */
       parentId: null,
+      btnTemplate: [], //按钮模板
+      // menuList: [], //路由数组--- this.treeFormItems[2].menus 
     };
   },
   computed: {
@@ -352,6 +356,7 @@ export default {
       databaseType: (state) => state.user.dataSource.databaseType,
       username: (state) => state.user.dataSource.username,
       tenantId: (state) => state.user.tenant.tenantId,
+      tenantCode: (state) => state.user.tenant.tenantCode,
     }),
     // 标题
     treeTableMangeTitle() {
@@ -368,6 +373,57 @@ export default {
     },
   },
   methods: {
+     // 获取按钮模板数据
+     async getBtnTemplate() {
+        try {
+          let res = await getDicts("drag_table_btn_template");
+          if (res.code == 200) {
+            this.btnTemplate = res.data.map((item) => JSON.parse(item.remark));
+          } else {
+            this.$message.error("获取按钮模板数据失败");
+          }
+        } catch (error) {
+          this.$message.error("获取按钮模板数据失败");
+        }
+      },
+      // 格式化按钮模板数据
+      formateBtnTemplate() {
+        let res = {
+          hasPermiName: "",
+          dragTableBtnTop: {},
+          dragTableBtnRight: {},
+        };
+        
+        // 获取菜单名称 - 从动态表单中获取
+        let moduleName = this.treeFormItems[2].menus.find(
+          (item) => item.menuId == this.$refs.dynamicForm.queryParams.menuId
+        )?.menuName;
+        
+        // 构建权限名称
+        res.hasPermiName =
+          this.tenantCode + ":" + moduleName + ":" + this.$refs.dynamicForm.queryParams.menuName;
+        
+        // 构建主键 - 从表格列表数据中获取
+        let primaryKey = this.tableList[0]?.dtTableName + "." + this.tableList[0]?.primaryKey;
+        
+        // 处理按钮模板
+        this.btnTemplate.forEach((item) => {
+          item.children.forEach((i) => {
+            if (i.btnType == "UPDATE" || i.btnType == "DELETE") {
+              let btnParams = { commonFieldData: [], conditionData: [] };
+              btnParams.conditionData.push({
+                fieldName: primaryKey,
+                fieldValue: "",
+              });
+              i.btnParams = JSON.stringify(btnParams);
+            }
+          });
+        });
+
+        res.dragTableBtnTop = this.btnTemplate[0];
+        res.dragTableBtnRight = this.btnTemplate[1];
+        return res;
+      },
     //点击树形菜单配置的取消
     cancelTree(payload) {
       this.$refs.dynamicForm.resetQuery();
@@ -409,13 +465,40 @@ export default {
                   if (this.mode == 2) {
                     let res = await addTreeTable(data);
                     if (res.code == 200) {
+                      // 新增默认按钮数据
+                      let btnTemplate = this.formateBtnTemplate();
+                      // 获取表格的tableKey
+                      let tableId = this.$refs.treeTableFormItems.queryParams['tableId'];
+                      let tableKey;
+                      if (tableId) {
+                        let tableInfo = await getTableInfo(tableId);
+                        if (tableInfo.code === 200) {
+                          tableKey = tableInfo.data.tableKey;
+                        }
+                      }
+                      btnTemplate.tableKey = tableKey; // 使用表格的tableKey
+                      btnTemplate.menuID = judgmentMenuResult.data;
+                      let btnRes = await insertByDefaultBtn(btnTemplate);
+                      if (btnRes.code == 200) {
+                        // 发送权限请求
+                        let payload = btnRes.data.map((item) => {
+                          return {
+                            ...item,
+                            tenantId: this.tenantId,
+                          };
+                        });
+                        let btnPowerRes = await tbnHasPerms(payload);
+                      } else {
+                        console.error(btnRes);
+                      }
+                      
                       this.$message.success("新增成功");
                       this.$tab.closePage();
                       this.$router.push({
                         path: "/system/fromModel/index/treeTable",
                       });
                     } else {
-                      this.$message.warning("新增成功");
+                      this.$message.warning("新增失败");
                     }
                   } else {
                     console.log('this.tableList[0].primaryKey',this.tableList[0].primaryKey)
@@ -572,8 +655,8 @@ export default {
       let res = await getMenuList();
       if (res.code == 200) {
         this.treeFormItems[2].menus = this.handleTree(res.data, "menuId");
+        console.log('this.treeFormItems[2].menus',this.treeFormItems[2].menus)
         this.menus = this.handleTree(res.data, "menuId");
-
       }
     },
     // 获取所有要关联的表格
@@ -830,7 +913,6 @@ export default {
     this.getList();
   },
   async mounted() {
-
     await this.getMenuList();
     await this.getAllTable();
     this.mode = this.$route.query.mode
@@ -841,6 +923,7 @@ export default {
 
       await this.initTableData(this.editorId);
     }
+    this.getBtnTemplate();
 
   },
 };

+ 0 - 442
zkqy-ui/ss.html

@@ -1,442 +0,0 @@
-<html lang="zh">
-    <head>
-        <meta charset="UTF-8">
-        <!-- Import style -->
-        <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/>
-        <!-- Import Vue 2.7 -->
-        <script src="https://unpkg.com/vue@2"></script>
-        <!-- Import element-ui -->
-        <script src="https://unpkg.com/element-ui/lib/index.js"></script>
-        <!-- Import formCreate -->
-        <script src="https://unpkg.com/@form-create/element-ui@super"></script>
-    </head>
-    <body>
-        <div id="app">
-            <form-create :rule="rule" :option="options" v-model:value="formData" v-model="api" @submit="onSubmit"></form-create>
-        </div>
-        <script>
-            
-// ====== 自定义代码开始 ======
-var zkqyTable = {
-    name: 'zkqyTable',
-    props: ['pageId'], // 声明接收的 props
-    template: `
-    <div class="zkqy-table">
-        <div class="table-container">
-            <div class="zkqy-table-btn" style="margin-bottom: 10px;">
-                <el-button type="primary" plain @click="add">新增</el-button>
-                <el-button type="primary" plain @click="edit">修改</el-button>
-            </div>
-            <el-table :data="tableData" style="width: 100%" :fit="true" border>
-                <el-table-column v-if="columns && columns.length > 0" :width="40">
-                    <template slot-scope="scope">
-                        <el-radio class="radio" 
-                                 :label="scope.row" 
-                                 v-model="radio" 
-                                 @change.native="getCurrentRow(scope.row)">
-                            &nbsp;
-                        </el-radio>
-                    </template>
-                </el-table-column>
-                <el-table-column 
-                    v-for="column in columns" 
-                    :key="column.prop" 
-                    :prop="column.prop" 
-                    :label="column.label" 
-                    :width="column.width"  
-                    flex="1">
-                </el-table-column>
-                <el-table-column label="操作" width="120" align="center" v-if="columns && columns.length > 0">
-                    <template slot-scope="scope">
-                        <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">
-                            删除
-                        </el-button>
-                    </template>
-                </el-table-column>
-            </el-table>
-            <el-pagination
-                @size-change="handleSizeChange"
-                @current-change="handleCurrentChange"
-                :current-page="currentPage4"
-                :page-sizes="[2, 5, 10, 15]"
-                :page-size="100"
-                layout="total, sizes, prev, pager, next, jumper"
-                :total="tableList[0].total">
-            </el-pagination>
-        </div>
-    </div>
-    `,
-    data() {
-        return {
-            zkqyTablePageJson:[{"type":"zkqyTable","field":"Fcgdma2cofgiazc","title":"表格","$required":false,"props":{"addZkqyTableRow":144,"updateZkqyTableRow":145,"pageId":146},"columns":[{"tableName":"stu","tableType":"primary","columnName":"主键","showValue":"id","searchValue":"stu@id"},{"tableName":"stu","tableType":"primary","columnName":"名称","showValue":"name","searchValue":"stu@name"},{"tableName":"stu","tableType":"primary","columnName":"老师id","showValue":"teacher_id","searchValue":"stu@teacher_id"},{"tableName":"stu","tableType":"primary","columnName":"习惯集合","showValue":"habbit_collection","searchValue":"stu@habbit_collection"},{"tableName":"stu","tableType":"primary","columnName":"树id","showValue":"tree_id","searchValue":"stu@tree_id"},{"tableName":"stu","tableType":"primary","columnName":"性别","showValue":"sex","searchValue":"stu@sex"},{"tableName":"stu","tableType":"primary","columnName":"树id2","showValue":"tree_id_two","searchValue":"stu@tree_id_two"},{"tableName":"stu","tableType":"primary","columnName":"穿梭框id集合","showValue":"el_transfer_id","searchValue":"stu@el_transfer_id"},{"tableName":"cls","tableType":"sub","primaryKey":"cls_id","subKey":"id","columnName":"课程名","showValue":"name","searchValue":"cls@name"}],"_fc_id":"id_Fwqsma2cofgib0c","name":"ref_Fk8ema2cofgib1c","display":true,"hidden":false,"_fc_drag_tag":"zkqyTable"}],
-            tableData: [],
-            columns: [{"prop":"stu@id","label":"主键"},{"prop":"stu@name","label":"名称"},{"prop":"stu@teacher_id","label":"老师id"},{"prop":"stu@habbit_collection","label":"习惯集合"},{"prop":"stu@tree_id","label":"树id"},{"prop":"stu@sex","label":"性别"},{"prop":"stu@tree_id_two","label":"树id2"},{"prop":"stu@el_transfer_id","label":"穿梭框id集合"},{"prop":"cls@name","label":"课程名"}],
-            radio: '',
-            policyData: {},
-            currentPage4: 1,
-            tableList: [{
-                pageId: '',
-                total: 0,
-                pageSize: 2,
-                pageNum: 1
-            }],
-            baseUrl: 'http://192.168.10.103:8088/',
-            headers: {
-                Accept: 'application/json',
-                dbname:'tt18',
-                'Content-Type': 'application/json'
-            },
-        };
-    },
-    methods: {
-        // 方法实现...
-        add() {
-            let p = this.zkqyTablePageJson[0]?.props?.addZkqyTableRow
-            if(p){
-                this.queryMobileClickAddData(p)
-            }
-        },
-        edit() {
-            if (!this.radio) {
-                this.$message.warning("请先选择一行数据");
-                return;
-            }
-            let formId = this.zkqyTablePageJson[0]?.props?.updateZkqyTableRow
-            let searchId;
-            let zj = this.zkqyTablePageJson[0].columns.find(item=>item.tableType=="primary")
-            if(zj.tableName){
-                let v = zj.tableName+'@id'
-                  searchId = this.radio[v]
-            }
-            if(!formId){
-                this.$message.warning("请配置跳转页面");
-                return
-            }else if(!searchId) {
-                this.$message.warning("id不存在");
-            }else {
-                let params = {
-                    formId,
-                    searchId 
-                }
-                this.queryMobileClickUpdateData(params)
-            }
-        },
-        getCurrentRow(val) {
-            this.policyData = val;
-            console.log('this.policyData', this.policyData)
-        },
-        handleSizeChange(val) {
-            this.tableList[0].pageSize = val;
-            this.getTableLimitInfo({ 
-                pageNum: this.tableList[0].pageNum, 
-                pageSize: this.tableList[0].pageSize,
-                pageId: this.pageId 
-            });
-        },
-        handleCurrentChange(val) {
-            this.tableList[0].pageNum = val;
-            this.getTableLimitInfo({ 
-                pageNum: this.tableList[0].pageNum, 
-                pageSize: this.tableList[0].pageSize,
-                pageId: this.pageId 
-            });
-        },
-        handleDelete(index, row) {
-            // console.log(row)
-            // let zj = this.zkqyTablePageJson[0].columns.find(item=>item.tableType=="primary")
-            // if(zj.tableName){
-            //     let v = zj.tableName+'@id'
-            //       searchId = this.radio[v]
-            // }
-            let id = this.zkqyTablePageJson[0]?.columns[0]?.tableName +'@id'
-            this.$msgbox.confirm('确认删除id为' + row[id] + '这行数据?', '提示', {
-                confirmButtonText: '确定',
-                cancelButtonText: '取消',
-                type: 'warning'
-            }).then(() => {
-                this.tableData.splice(index, 1);
-                this.deleteTableData(row[id], this.pageId );
-            }).catch(() => {
-                this.$message.info("已取消删除");
-            });
-        },
-        async deleteTableData(lineId, pageId) {
-             const endpoint = 'api/mobilePageDesignData/normal/deleteData';
-             try {
-               const url = this.baseUrl + endpoint;
-                 const requestBody = {
-                     lineId: lineId,
-                     pageId: pageId
-                 };
-                 const response = await fetch(url, {
-                     method: 'POST',
-                     headers: this.headers,
-                     body: JSON.stringify(requestBody) // 将参数转为JSON字符串
-                 });
-                 if (!response.ok) {
-                       throw new Error('HTTP error! status: ' + response.status);
-                   }
-                 const result = await response.json();
-                 console.log('删除结果:', result);
-                 if (result.code == 200) {
-                     this.$message.success('删除成功');
-                     let {pageId,pageNum,pageSize} =this.tableList[0]
-                     // 删除成功后刷新表格数据
-                     this.getTableLimitInfo({pageId,pageNum,pageSize})
-                     return true;
-                 } else {
-                     this.$message.error(result.message || '删除失败');
-                     return false;
-                 }
-             } catch (error) {
-                 console.error('删除数据出错:', error);
-                 this.$message.error('删除请求失败: ' + error.message);
-                 throw error;
-             }
-         },
-         async getTableLimitInfo(params = {}) {
-            const endpoint = 'api/mobilePageDesignData/muti/tableLimitInfo';
-            await this.fetchGet(endpoint, params, (data) => {
-                if (data.code === 200) {
-                    this.tableData = data.rows;
-                    this.tableList[0].total = data.total
-                } else {
-                    console.warn('接口返回非 200 状态:', data);
-                }
-            });
-        },
-        async queryMobileClickAddData(params = {}) {
-            let formId = params;
-            params ={}
-            
-            let pageId = this.pageId
-            console.log('pageId',pageId)
-            const endpoint = 'api/mobilePageDesignData/queryMobileClickAddData/'+ formId;
-            await this.fetchGet(endpoint , params,(data) => {
-                if (data.code === 200) {
-                    const decodedHtml = decodeURIComponent(data.data.htmlData);
-            
-                    // 创建全屏 iframe
-                    const iframe = document.createElement('iframe');
-                    iframe.srcdoc = decodedHtml;
-                    iframe.style.width = '100%';
-                    iframe.style.height = '100vh';
-                    iframe.style.border = 'none';
-                    
-                    // 清空页面并插入 iframe
-                    document.body.innerHTML = '';
-                    document.body.appendChild(iframe);
-                    // 将 pageId 存储到 localStorage
-                    localStorage.setItem('sharedPageId', pageId);   
-                }
-            });
-        },
-        async queryMobileClickUpdateData(params = {}) {
-            let formId = params.formId;
-            let searchId = params.searchId;
-            params = {}
-            // 移除指定的 localStorage 键
-            // localStorage.removeItem('sharedPageId');
-
-            const endpoint = 'api/mobilePageDesignData/queryMobileClickUpdateData/'+this.pageId +'/'+formId +'/'+searchId;
-            await this.fetchGet(endpoint , params,(data) => {
-                if (data.code === 200) {
-                        const decodedHtml = decodeURIComponent(data.data.htmlData);
-                        const iframe = document.createElement('iframe');
-                        iframe.srcdoc = decodedHtml;
-                        iframe.style.width = '100%';
-                        iframe.style.height = '100vh';
-                        iframe.style.border = 'none';
-                        document.body.innerHTML = '';
-                        document.body.appendChild(iframe);
-                        // 将 pageId 存储到 localStorage
-                        localStorage.setItem('sharedPageId', this.pageId);   
-                    }
-            });
-        },
-        async fetchGet(endpoint, params = {}, successCallback) {
-            try {
-                // 构建查询字符串
-                const queryString = Object.keys(params)
-                    .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
-                    .join('&');
-                // 拼接完整的 URL
-                const url = this.baseUrl + endpoint + (queryString ? '?' + queryString : '');
-        
-                // 发起 GET 请求
-                const response = await fetch(url, {
-                    method: 'GET',
-                    headers: this.headers
-                });
-        
-                // 检查响应状态
-                if (!response.ok) {
-                    throw new Error('HTTP error! status: ' + response.status);
-                }
-        
-                // 解析返回的数据
-                const data = await response.json();
-        
-                // 调用成功回调函数
-                if (successCallback && typeof successCallback === 'function') {
-                    successCallback(data);
-                }
-            } catch (error) {
-                console.error('调用接口出错:', error);
-                throw error; // 抛出错误以便上层捕获
-                }
-            }
-         },
-    mounted() {
-        console.log('父组件传递的 options:', this.pageId);
-        this.tableList[0].pageId = this.pageId
-        let { pageId, pageNum, pageSize } = this.tableList[0];
-        this.getTableLimitInfo({ pageId, pageNum, pageSize });
-    }
-};
-
-// 注册组件
-Vue.use(ELEMENT);
-Vue.use(formCreate);
-formCreate.component('zkqyTable', zkqyTable);
-
-new Vue({
-                el: '#app',
-                data() {
-                    return {
-                        rule: formCreate.parseJson('[{"type":"zkqyTable","field":"Fcgdma2cofgiazc","title":"表格","$required":false,"props":{"addZkqyTableRow":144,"updateZkqyTableRow":145,"pageId":146},"columns":[{"tableName":"stu","tableType":"primary","columnName":"主键","showValue":"id","searchValue":"stu@id"},{"tableName":"stu","tableType":"primary","columnName":"名称","showValue":"name","searchValue":"stu@name"},{"tableName":"stu","tableType":"primary","columnName":"老师id","showValue":"teacher_id","searchValue":"stu@teacher_id"},{"tableName":"stu","tableType":"primary","columnName":"习惯集合","showValue":"habbit_collection","searchValue":"stu@habbit_collection"},{"tableName":"stu","tableType":"primary","columnName":"树id","showValue":"tree_id","searchValue":"stu@tree_id"},{"tableName":"stu","tableType":"primary","columnName":"性别","showValue":"sex","searchValue":"stu@sex"},{"tableName":"stu","tableType":"primary","columnName":"树id2","showValue":"tree_id_two","searchValue":"stu@tree_id_two"},{"tableName":"stu","tableType":"primary","columnName":"穿梭框id集合","showValue":"el_transfer_id","searchValue":"stu@el_transfer_id"},{"tableName":"cls","tableType":"sub","primaryKey":"cls_id","subKey":"id","columnName":"课程名","showValue":"name","searchValue":"cls@name"}],"_fc_id":"id_Fwqsma2cofgib0c","name":"ref_Fk8ema2cofgib1c","display":true,"hidden":false,"_fc_drag_tag":"zkqyTable"}]'),
-                        options: formCreate.parseJson('{"form":{"inline":false,"hideRequiredAsterisk":false,"showMessage":true,"inlineMessage":false,"labelPosition":"right","labelWidth":"125px","validateOnRuleChange":false,"size":"small","formName":"表格1"},"resetBtn":{"show":false,"innerText":"重置"},"submitBtn":{"show":true,"innerText":"提交"}}'),
-                        formData: {},
-                        api: null,
-                        zkqyData:[],
-                        zkqyUpload:[],
-                    };
-                },
-                methods: {
-                    onSubmit(formData){
-                        console.log('submit', formData);
-                        
-                    },
-                    async zkqyDataApi(data,type,id){
-                        let zkqyData = this.zkqyData;
-                        if (!zkqyData || zkqyData.length === 0) return;
-                        const headers = {
-                            'Accept': 'application/json',
-                            'dbname': 'undefined',
-                            'Content-Type': 'application/json'
-                        };
-                        try {
-                            let response;
-                            if (type === 'cascader' || type === 'tree') {
-                                // 调用树形接口 POST
-                                const apiUrl = 'undefinedapi/mobilePageDesignData/tree';
-                                console.log('调用树形接口:', apiUrl);
-                                response = await fetch(apiUrl, {
-                                    method: 'POST',
-                                    headers,
-                                    body: JSON.stringify(data)
-                                });
-                            } else {
-                                // 调用下拉框接口 GET
-                                let x = new URLSearchParams(data).toString()
-                                const apiUrl = 'undefinedapi/mobilePageDesignData/dropdown?'+x;
-                                console.log('调用下拉框接口:', apiUrl);
-                                response = await fetch(apiUrl, {
-                                    method: 'GET',
-                                    headers
-                                });
-                            }
-                
-                            if (!response.ok) {
-                                throw new Error('HTTP error! status:response.status');
-                            }
-                            const result = await response.json();
-                            const targetRule = this.rule.find(item => item._fc_id === id);
-                              if (type === 'tree') {
-                                 this.$set(targetRule?.props, 'data', result.data);
-                              }
-                              else if(type === 'cascader'){
-                                this.$set(targetRule.props, 'options', result.data);
-
-                              }else if(type === 'elTransfer'){
-                                this.$set(targetRule.props, 'data', result.data);
-                              }else {
-                                this.$set(targetRule, 'options', result.data);
-                              }
-                              this.rule =formCreate.parseJson(formCreate.toJson([...this.rule])); // 触发重新渲染
-                          
-                              return result;
-                            
-                        } catch (error) {
-                            console.error('type接口请求失败:', error);
-                            throw error;
-                        }
-                    },
-                    transformTreeToSingleObject(node) {
-                        if (!node) return node;
-                        
-                        // 创建新对象,避免修改原对象
-                        const newNode = {...node};
-                        
-                        // 处理 childrenTree
-                        if (Array.isArray(newNode.childrenTree) ){
-                          if (newNode.childrenTree.length > 0) {
-                            // 取第一个元素作为对象
-                            newNode.childrenTree = this.transformTreeToSingleObject(newNode.childrenTree[0]);
-                          } else {
-                            // 空数组转为 null 或 undefined
-                            newNode.childrenTree = null;
-                          }
-                        } else if (newNode.childrenTree) {
-                          // 如果不是数组但存在 childrenTree,递归处理
-                          newNode.childrenTree = this.transformTreeToSingleObject(newNode.childrenTree);
-                        }
-                        
-                        return newNode;
-                      },
-                },
-                mounted() {
-                    this.rule.forEach(ruleItem => {
-                        if(ruleItem.type=="upload"){
-                          console.log('ruleItem',ruleItem)
-                          console.log('this.rule ',this.rule )
-                          if(ruleItem?.value.length>0){
-                            const processedUrl = 'undefined'.endsWith('/') ?'undefined'.slice(0, -1) : 'undefined'; // 如果 url 最后一个字符是斜杠,则去掉它
-                            console.log('processedUrl',processedUrl)
-                            ruleItem.value = ruleItem.value.map(
-                                item => processedUrl+item
-                              );
-                          }
-                          console.log(' ruleItem.value ', ruleItem.value  )
-
-                        //   this.rule =formCreate.parseJson(formCreate.toJson([...this.rule])); // 触发重新渲染
-                          ruleItem.props.onSuccess="[[FORM-CREATE-PREFIX-function onSuccess(res, file){const key='upload_row';const existingData=sessionStorage.getItem(key);let fileList=existingData?JSON.parse(existingData):[];if(!Array.isArray(fileList)){fileList=[];}const newItem={fileName: file.response.fileName, url: file.url};fileList.push(newItem);sessionStorage.setItem(key,JSON.stringify(fileList));}-FORM-CREATE-SUFFIX]]"
-                        }
-                      })
-                    let zkqyData = this.zkqyData
-                    if(zkqyData && zkqyData.length>0){
-                        console.log('[this.rule]',this.rule)
-                        this.rule.forEach(ruleItem => {
-                        const matchedData = zkqyData.find(dataItem => dataItem._fc_id === ruleItem._fc_id);
-                        if (matchedData) {
-                            if (matchedData?.type !== 'cascader' && matchedData?.type !== 'tree') {
-                                resultObj = {
-                                    tableName: matchedData?.parentNode?.tableName,
-                                    valueName: matchedData?.parentNode?.primaryIdField,
-                                    labelName: matchedData?.parentNode?.showValue,
-                                    type: matchedData?.type
-                                };
-                                this.zkqyDataApi(resultObj,matchedData?.type,matchedData._fc_id)
-                            } 
-                            else {
-                                resultObj = this.transformTreeToSingleObject(matchedData.parentNode);
-                                resultObj.componentType = matchedData?.type
-                                this.zkqyDataApi(resultObj,matchedData?.type,matchedData._fc_id)
-                            }
-                    }
-                })
-            }},
-            })
-        </script>
-    </body>
-</html>

+ 3 - 3
zkqy-ui/vue.config.js

@@ -43,7 +43,7 @@ module.exports = {
         // target: `http://192.168.110.52:8080`,
         // target: `http://192.168.110.76:8080`,
         // target: `http://175.27.169.173:8080`,
-        target: `http://192.168.10.103:8080`,
+        target: `http://192.168.10.114:8080`,
 
         changeOrigin: true,
         pathRewrite: {
@@ -52,7 +52,7 @@ module.exports = {
       },
       '/DB': {
         // target: `http://192.168.110.59:8099`,
-        target: `http://192.168.10.103:8099`,
+        target: `http://192.168.10.114:8099`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + '/DB']: ''
@@ -61,7 +61,7 @@ module.exports = {
       '/FORM': {
         // target: `http://192.168.110.59:8088`,
         // target: `http://175.27.169.173:8088`,
-        target: `http://192.168.10.103:8088`,
+        target: `http://192.168.10.114:8088`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + '/FORM']: ''