Forráskód Böngészése

Merge branch 'master' of http://59.110.6.97:3000/root/BoundLink-UI

liqh 3 hónapja
szülő
commit
732c0a2e62
26 módosított fájl, 805 hozzáadás és 653 törlés
  1. 8 1
      src/api/flow/settingApi.js
  2. 65 36
      src/views/flow/setting/mainSetting.vue
  3. 1 1
      src/views/flow/stDesignMain/index.vue
  4. 4 0
      src/views/flow/stFlowDesign/components/ConfigPanel/selectParticipant.vue
  5. 71 30
      src/views/flow/stFormDesign/packages/PopUpMapping/index.vue
  6. 20 8
      src/views/flow/stFormDesign/packages/PopUpQuery/index.vue
  7. 14 4
      src/views/flow/stFormDesign/packages/PopUpQueryChild/index.vue
  8. 5 0
      src/views/flow/stFormDesign/packages/PopUpQueryGlobal/index.vue
  9. 2 24
      src/views/flow/stFormDesign/packages/StBatch/batch.vue
  10. 20 22
      src/views/flow/stFormDesign/packages/StBatch/module/StTableCard.vue
  11. 0 1
      src/views/flow/stFormDesign/packages/StChangeOption/index.vue
  12. 0 5
      src/views/flow/stFormDesign/packages/StFormDesign/module/formComponentPanel.vue
  13. 0 5
      src/views/flow/stFormDesign/packages/StFormDesign/module/formComponentPanelMobile.vue
  14. 67 39
      src/views/flow/stFormDesign/packages/StFormDesign/module/formItemProperties.vue
  15. 1 1
      src/views/flow/stFormDesign/packages/StFormDesign/module/formNode.vue
  16. 9 8
      src/views/flow/stFormDesign/packages/StFormDesign/module/jsModal.vue
  17. 49 34
      src/views/flow/stFormDesign/packages/StFormDesign/module/layoutItem.vue
  18. 0 6
      src/views/flow/stFormDesign/packages/StFormDesign/module/operatingArea.vue
  19. 51 31
      src/views/flow/stFormDesign/packages/StFormItem/index.vue
  20. 339 337
      src/views/flow/stFormDesign/packages/UploadFile/uploadFile.vue
  21. 5 4
      src/views/flow/stFormWork/components/headerInfo/mobileIndex.vue
  22. 22 12
      src/views/flow/stFormWork/formWork.vue
  23. 0 1
      src/views/flow/stFormWork/style/formWork.less
  24. 13 3
      src/views/flow/stSetting/flowNameSetting.vue
  25. 3 3
      src/views/flow/stSetting/flowNumberPrefix.vue
  26. 36 37
      src/views/flow/stSetting/index.vue

+ 8 - 1
src/api/flow/settingApi.js

@@ -22,6 +22,7 @@ const settingApi = {
 
 
     getQueryData: '/setting/engine/getQueryData',
+    getQueryMainSingleForMapping: '/setting/engine/getQueryMainSingleForMapping',
     getQueryPopupData: '/setting/engine/getQueryPopupData',
     getPopUpData: '/form/engine/popup/data',
     getSingleFlowSetting: '/setting/engine/getSingleFlowSetting',
@@ -337,7 +338,13 @@ export function getQueryData(parameter) {
         params: parameter
     })
 }
-
+export function getQueryMainSingleForMapping(parameter) {
+    return request({
+        url: settingApi.getQueryMainSingleForMapping,
+        method: 'get',
+        params: parameter
+    })
+}
 export function getQueryPopupData(parameter) {
     return request({
         url: settingApi.getQueryPopupData,

+ 65 - 36
src/views/flow/setting/mainSetting.vue

@@ -1,68 +1,97 @@
 <template>
   <div>
     <a-drawer
-        title='流程设置'
-        width='100%'
-        placement='right'
-        :open='visible'
-        @close='onClose'
-        :closable='true'
+        title="流程设置"
+        width="100%"
+        placement="right"
+        :open="visible"
+        @close="onClose"
+        :closable="true"
     >
       <div class="custom-drawer">
-        <a-collapse accordion>
-          <a-collapse-panel key='1' header='任务代理:'>
+        <a-collapse
+            v-model:activeKey="activeKey"
+            :bordered="false"
+            style="background: rgb(255, 255, 255)"
+        >
+          <template #expandIcon="{ isActive }">
+            <caret-right-outlined :rotate="isActive ? 90 : 0" />
+          </template>
+          <a-collapse-panel key="1" header="任务代理:" :style="customStyle">
             <FlowAgent></FlowAgent>
           </a-collapse-panel>
-          <a-collapse-panel key='2' header='数据字典:'>
+          <a-collapse-panel key="2" header="数据字典:" :style="customStyle">
             <DictIndex></DictIndex>
           </a-collapse-panel>
-          <a-collapse-panel key='3' header='业务服务:'>
-            <event-service></event-service>
+          <a-collapse-panel key="3" header="业务服务:" :style="customStyle">
+            <EventService></EventService>
           </a-collapse-panel>
-          <a-collapse-panel key='4' header='查询服务:'>
+          <a-collapse-panel key="4" header="查询服务:" :style="customStyle">
             <QueryService></QueryService>
           </a-collapse-panel>
-          <a-collapse-panel key='5' header='流程管理员:'>
+          <a-collapse-panel key="5" header="流程管理员:" :style="customStyle">
             <FlowAdministrator></FlowAdministrator>
           </a-collapse-panel>
-          <a-collapse-panel key='6' header='流程操作:'>
+          <a-collapse-panel key="6" header="流程操作:" :style="customStyle">
             <FlowOperation></FlowOperation>
           </a-collapse-panel>
         </a-collapse>
       </div>
-
     </a-drawer>
   </div>
 </template>
+
 <script>
-import FlowOperation from '/@/views/flow/setting/flowOperation.vue'
-import FlowAdministrator from '/@/views/flow/setting/flowAdministrator.vue'
-import FlowAgent from '/@/views/flow/setting/flowAgent.vue'
-import QueryService from '/@/views/flow/setting/queryService.vue'
-import EventService from '/@/views/flow/setting/eventService.vue'
-import DictIndex from '/@/views/support/dict/index.vue'
+import { ref } from "vue";
+import FlowOperation from "/@/views/flow/setting/flowOperation.vue";
+import FlowAdministrator from "/@/views/flow/setting/flowAdministrator.vue";
+import FlowAgent from "/@/views/flow/setting/flowAgent.vue";
+import QueryService from "/@/views/flow/setting/queryService.vue";
+import EventService from "/@/views/flow/setting/eventService.vue";
+import DictIndex from "/@/views/support/dict/index.vue";
 
 export default {
-  components: {QueryService, EventService, DictIndex, FlowAdministrator, FlowAgent,FlowOperation},
-  data() {
-    return {
-      visible: false
+  components: {
+    FlowOperation,
+    FlowAdministrator,
+    FlowAgent,
+    QueryService,
+    EventService,
+    DictIndex,
+  },
+  setup() {
+    const visible = ref(false);
+    const activeKey = ref(["0"]);
+    const customStyle = "background: #f8f9fa;border-radius: 4px;margin-bottom: 14px;border: 0;overflow: hidden";
+
+    const show = () => {
+      visible.value = true;
+    };
 
-    }
+    const onClose = () => {
+      visible.value = false;
+    };
+
+    return {
+      visible,
+      activeKey,
+      customStyle,
+      show,
+      onClose,
+    };
   },
-  methods: {
-    show() {
-      this.visible = true
-    },
-    onClose() {
-      this.visible = false
-    }
-  }
-}
+};
 </script>
+
 <style scoped>
 .custom-drawer {
-  height: 100%;
+  height: calc(100% - 32px);
   overflow-y: auto;
+  border: 1px solid #ccc; /* 添加灰色边框 */
+  border-radius: 8px; /* 添加圆角边框 */
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
+  background-color: #fff; /* 设置背景颜色 */
+  padding: 16px; /* 添加内边距 */
+  margin: 16px;
 }
 </style>

+ 1 - 1
src/views/flow/stDesignMain/index.vue

@@ -5,7 +5,7 @@
         <span class="pg-h-txt">{{ title }}<span style="padding: 20px;font-size: 14px;color: #0D366F">{{ flowCode}}</span></span>
         <a-button-group size="large" style="flex: 1; display: flex; justify-content: center">
           <a-button
-              :type="currentComName === item.componentName && 'primary'"
+              :type="currentComName === item.componentName? 'primary':''"
               size="large"
               @click="switchTag(item, index)"
               v-for="(item, index) in headerList"

+ 4 - 0
src/views/flow/stFlowDesign/components/ConfigPanel/selectParticipant.vue

@@ -108,6 +108,10 @@ export default {
         {
           title: '条件判断IF(?,?,?)',
           key: 'IF({project_id}==1,[code1]|[code2],[code3]|[code4])'
+        },
+        {
+          title: '后台获取人员$GetByMethod(方法全路径)',
+          key: '$GetByMethod(com.cloud.sa.demo.FindParticipants.getUserCodes)'
         }
       ],
       modal1Visible: false,

+ 71 - 30
src/views/flow/stFormDesign/packages/PopUpMapping/index.vue

@@ -1,10 +1,36 @@
 <template>
   <div class="page">
-    <a-select v-model:value='queryServiceData' style='width: 100%' placeholder='选择查询服务' @change='handleChange'>
-      <a-select-option v-for='d in data' :key='d.id'>
-        {{ d.queryName }}
-      </a-select-option>
-    </a-select>
+    <a-row>
+      <a-col :span="22">
+        <a-select v-model:value='queryServiceData' style='width: 100%'
+                  optionFilterProp="label"
+                  show-search
+                  placeholder='选择查询服务'
+                  @change='handleChange'>
+          <a-select-option v-for='d in data'
+                           :key='d.id'
+                           :value="d.id"
+                           :label="d.queryName"
+          >
+            {{ d.queryName }}
+          </a-select-option>
+        </a-select>
+      </a-col>
+      <a-col :span="2">
+        <a-tooltip placement="topLeft">
+          <template #title>
+            <span>查询服务内容改变后,刷新当前查询服务</span>
+          </template>
+          <a-button type="text" @click="reloadQueryService">
+            <template #icon>
+              <SyncOutlined/>
+            </template>
+          </a-button>
+        </a-tooltip>
+
+      </a-col>
+    </a-row>
+
     <a-card size='small' title='字段映射:' :bordered='true'>
       <div v-for='(m,index) in queryMapFieldData'>
         <div v-show='m.mapping===true'>
@@ -33,10 +59,10 @@
         <div class="query-map" v-if="queryMapKeyValData.length > 0">
           <div class="query-map-item" v-for="(qItm, qIdx) in queryMapKeyValData" :key="qIdx">
             <div class="query-map-item-header">
-              <div class="query-no">查询映射{{  qIdx + 1  }}</div>
+              <div class="query-no">查询映射{{ qIdx + 1 }}</div>
               <a-button danger size="small" type="dashed" @click="deleteChangeQueryMapKeyVal(qIdx)">
                 <template #icon>
-                  <DeleteOutlined />
+                  <DeleteOutlined/>
                 </template>
               </a-button>
             </div>
@@ -50,22 +76,22 @@
               <template #title>
                 <span>Key格式</span>
               </template>
-              <span><QuestionOutlined />查询Key</span>
+              <span><QuestionCircleOutlined/>查询Key</span>
             </a-popover>
             <a-input placeholder="请输入查询Key" v-model:value="qItm.queryKey"></a-input>
 
             <span>查询Value</span>
             <a-tree-select
-              v-model:value='qItm.queryValue'
-              style='width: 100%'
-              show-search
-              :tree-data='queryMapKeyValOpts'
-              tree-node-filter-prop="name"
-              :filter-option='filterOption'
-              :allowClear='true'
-              :fieldNames='{children:"children",label:"name",key:"code",value:"code"}'
-              placeholder='请输入查询Value'
-              tree-default-expand-all
+                v-model:value='qItm.queryValue'
+                style='width: 100%'
+                show-search
+                :tree-data='queryMapKeyValOpts'
+                tree-node-filter-prop="name"
+                :filter-option='filterOption'
+                :allowClear='true'
+                :fieldNames='{children:"children",label:"name",key:"code",value:"code"}'
+                placeholder='请输入查询Value'
+                tree-default-expand-all
             >
             </a-tree-select>
           </div>
@@ -73,7 +99,7 @@
 
         <a-button type="dashed" @click="handleAddQueryMap">
           <template #icon>
-            <PlusOutlined />
+            <PlusOutlined/>
           </template>
           新增
         </a-button>
@@ -83,11 +109,11 @@
 
 </template>
 <script>
-import {getQueryMainListForMapping} from '/@/api/flow/settingApi'
-import { PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue'
+import {getQueryMainListForMapping, getQueryMainSingleForMapping} from '/@/api/flow/settingApi'
+import {PlusOutlined, DeleteOutlined} from '@ant-design/icons-vue'
 
 export default {
-  components: { PlusOutlined, DeleteOutlined },
+  components: {PlusOutlined, DeleteOutlined},
   props: {
     formDataList: {
       type: Array
@@ -105,7 +131,7 @@ export default {
     },
     queryService: {
       type: Number,
-      default: 0
+      default: null
     },
     queryMapKeyValData: {
       type: Array,
@@ -123,7 +149,7 @@ export default {
     getQueryMainListForMapping().then((res) => {
       this.data = res.data
       this.queryServiceData = this.queryService
-      if ( this.data.find(item => item.id == this.queryServiceData)){
+      if (this.data.find(item => item.id == this.queryServiceData)) {
         const newData = this.data.find(item => item.id == this.queryServiceData).queryColumnList
         for (let i in newData) {
           const exists = this.queryMapField.some(item => item.field == newData[i]["field"]);
@@ -133,12 +159,24 @@ export default {
             this.queryMapFieldData.push(newData[i])
           }
         }
-        this.$emit('changeMap',  this.queryServiceData, this.queryMapFieldData, this.queryMapKeyValData)
+        this.$emit('changeMap', this.queryServiceData, this.queryMapFieldData, this.queryMapKeyValData)
       }
     })
 
   },
   methods: {
+    reloadQueryService() {
+      const curQueryMapFieldData = JSON.parse(JSON.stringify(this.queryMapFieldData))
+      getQueryMainSingleForMapping({queryId: this.queryService}).then((res) => {
+        this.queryMapFieldData = res.data.queryColumnList
+        for (const item of this.queryMapFieldData) {
+          const resultFind = curQueryMapFieldData.find(f => f.field == item.field)
+          if (resultFind && resultFind.mapField) {
+            item.mapField = resultFind.mapField
+          }
+        }
+      })
+    },
     filterOption(input, option) {
       return (
           option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -148,7 +186,8 @@ export default {
       this.queryMapFieldData = this.data.find(item => item.id == value).queryColumnList
       this.$emit('changeMap', value, this.queryMapFieldData)
     },
-    handleChangeField(value) {},
+    handleChangeField(value) {
+    },
     handleAddQueryMap() {
       this.queryMapKeyValData.push({
         queryKey: undefined,
@@ -171,7 +210,7 @@ export default {
         code: '[CurrentLoginUser]',
         name: '当前登录人'
       },]
-      return [...customFields,...this.formFields.map(v => ({
+      return [...customFields, ...this.formFields.map(v => ({
         ...v,
         code: `{${v.code}}`
       }))]
@@ -190,6 +229,7 @@ export default {
     display: flex;
     flex-direction: column;
     gap: 10px;
+
     .query-map {
       display: flex;
       flex-direction: column;
@@ -197,6 +237,7 @@ export default {
       padding: 10px;
       border-radius: 10px;
       border: 1px dotted #ccc;
+
       .query-map-item {
         display: flex;
         flex-direction: column;
@@ -208,9 +249,9 @@ export default {
           align-items: center;
 
           .query-no {
-           font-size: 12px;
-           color: #000;
-           font-weight: bold;
+            font-size: 12px;
+            color: #000;
+            font-weight: bold;
           }
         }
       }

+ 20 - 8
src/views/flow/stFormDesign/packages/PopUpQuery/index.vue

@@ -1,19 +1,19 @@
 <template>
   <div>
     <a-form-item :class="{ 'red-label': record?.options?.requiredFirst ||record?.rules?.find(f=>f.required)}"
-        :label-col="
+                 :label-col="
         formConfig.layout === 'horizontal'
           ? formConfig.labelLayout === 'flex'
             ? { style: `width:${formConfig.labelWidth}px` }
             : formConfig.labelCol
           : {}
       "
-        :wrapper-col="
+                 :wrapper-col="
         formConfig.layout === 'horizontal' ? (formConfig.labelLayout === 'flex' ? { style: 'width:auto;flex:1' } : formConfig.wrapperCol) : {}
       "
-        :style="formConfig.layout === 'horizontal' && formConfig.labelLayout === 'flex' ? { display: 'flex' } : {}"
-        :name="record.model"
-        :rules="record.rules"
+                 :style="formConfig.layout === 'horizontal' && formConfig.labelLayout === 'flex' ? { display: 'flex' } : {}"
+                 :name="record.model"
+                 :rules="record.rules"
     >
       <template #label>
         <a-tooltip>
@@ -59,7 +59,11 @@
         <a-row>
           <a-col :span="24">
             <a-table :columns="columns" :data-source="tableData" :customRow="handleRow"
-                     :pagination="{ defaultPageSize: 50 }"
+                     :pagination="{
+                        defaultPageSize: 10,
+                        showSizeChanger: true,
+                        pageSizeOptions: ['10', '20', '50', '100']
+                      }"
                      :scroll="{ x: 1300, y: 500 }" size="small" @resizeColumn="handleResizeColumn">
               <template #bodyCell="{ text, record, index, column }">
                 <template v-if="column.key === 'isChecked'">
@@ -245,8 +249,16 @@ export default {
         this.record.queryMapKeyValData.forEach((item, index) => {
           const keyVal = {}
           keyVal.key = item.queryKey
-          if (item.queryValue.indexOf("{") >= 0) {
-            keyVal.value = this.formData[item.queryValue.substring(1, item.queryValue.length - 1)];
+          if (item.queryValue.indexOf("[") < 0) {
+            if (item.queryValue.indexOf("{") >= 0) {
+              //主表的queryValue,也就是字段都是用{}包裹的,所以会触发在这里,子表的没有被包裹
+              keyVal.value = this.formData[item.queryValue.substring(1, item.queryValue.length - 1)];
+            } else {
+              keyVal.value = this.formData[item.queryValue];
+            }
+            if (!keyVal.value) {
+              keyVal.value = ''
+            }
           } else {
             keyVal.value = item.queryValue
           }

+ 14 - 4
src/views/flow/stFormDesign/packages/PopUpQueryChild/index.vue

@@ -32,6 +32,11 @@
         <a-row>
           <a-col :span='24'>
             <a-table :columns="columns" :data-source="tableData" :customRow="handleRow"
+                     :pagination="{
+                        defaultPageSize: 10,
+                        showSizeChanger: true,
+                        pageSizeOptions: ['10', '20', '50', '100']
+                      }"
                      :scroll="{ x: 1300, y: 1000 }" size="small" @resizeColumn="handleResizeColumn">
               <template #bodyCell="{ text, record, index, column }">
                 <template v-if="column.key === 'isChecked'">
@@ -203,10 +208,15 @@ export default {
         this.record.queryMapKeyValData.forEach((item, index) => {
           const keyVal = {}
           keyVal.key = item.queryKey
-          if (item.queryValue.indexOf("{") >= 0) {
-            keyVal.value = this.formData[item.queryValue.substring(1, item.queryValue.length - 1)];
-            if (keyVal.value == undefined) {
-              keyVal.value = this.rowData[item.queryValue.substring(1, item.queryValue.length - 1)]
+          if (item.queryValue.indexOf("[") < 0) {
+            if (item.queryValue.indexOf("{") >= 0) {
+              keyVal.value = this.rowData[item.queryValue.substring(1, item.queryValue.length - 1)];
+            } else {
+              //子表的queryValue,子表的没有被{}包裹,所以会在这里触发,这是在组件PopUpMapping中的queryMapKeyValOpts没有写好的,已经没有写好了,所以就这么地吧,也没啥影响
+              keyVal.value = this.rowData[item.queryValue];
+            }
+            if (!keyVal.value) {
+              keyVal.value = ''
             }
           } else {
             keyVal.value = item.queryValue

+ 5 - 0
src/views/flow/stFormDesign/packages/PopUpQueryGlobal/index.vue

@@ -23,6 +23,11 @@
           <a-col :span='24'>
             <a-table :row-selection='{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }' :columns='columns'
                      :data-source='tableData'
+                     :pagination="{
+                        defaultPageSize: 10,
+                        showSizeChanger: true,
+                        pageSizeOptions: ['10', '20', '50', '100']
+                      }"
             >
             </a-table>
           </a-col>

+ 2 - 24
src/views/flow/stFormDesign/packages/StBatch/batch.vue

@@ -16,7 +16,7 @@
       >
         <template #headerCell="{ column }">
           <div>
-            <a-tooltip  placement="topLeft">
+            <a-tooltip placement="topLeft">
               <div>
                        <span
                            v-if="
@@ -46,32 +46,11 @@
           <div v-if="scope.column.dataIndex === 'sequence_index_number'">
             {{ getSerialNumber(scope.index) }}
           </div>
-          <div v-else-if="record.disableCell&&record.disableCell.find((item) =>item.y== scope.column.dataIndex&&item.x==getSerialNumber(scope.index))
-">
-            <StFormModelItem
-                :record="record.list.find((item) => item.model == scope.column.dataIndex)"
-                :config="config"
-                :parentDisabled="true"
-                :index="record.list.findIndex((item) => item.model == scope.column.dataIndex)"
-                :domains="dynamicValidateForm.domains"
-                :dynamicData="dynamicData"
-                :formData="formData"
-                :formConfig="formConfig"
-                :childTableFieldRecord="record.list"
-                :rowIndex="scope.index"
-                v-model:value="scope.record[record.list.find((item) => item.model == scope.column.dataIndex).model]"
-                @input="handleInput"
-                :tableScope="scope"
-                :columns="columns"
-                :pagination="pagination"
-                :currentTableData="currentTableData"
-            />
-          </div>
           <div v-else-if="record.list.find((item) => item.model == scope.column.dataIndex)">
             <StFormModelItem
                 :record="record.list.find((item) => item.model == scope.column.dataIndex)"
                 :config="config"
-                :parentDisabled="disabled"
+                :parentDisabled="record.disableCell && record.disableCell.find((item) => item.y == scope.column.dataIndex && item.x == getSerialNumber(scope.index)) ? true : disabled"
                 :index="record.list.findIndex((item) => item.model == scope.column.dataIndex)"
                 :domains="dynamicValidateForm.domains"
                 :dynamicData="dynamicData"
@@ -87,7 +66,6 @@
                 :currentTableData="currentTableData"
             />
           </div>
-
           <div v-if="scope.column.dataIndex === 'dynamic-opr-button'">
             <a-button v-if="!disabled" type="dashed" @click="removeDomain(scope.record)" danger>
               <template #icon>

+ 20 - 22
src/views/flow/stFormDesign/packages/StBatch/module/StTableCard.vue

@@ -4,7 +4,6 @@
       <div class="mobile-table" v-if="list.length === 0 && firstData.length === 0">
         <a-empty></a-empty>
       </div>
-
       <div class="mobile-table" v-for="(item, rowIdx) in list.length === 0 ? firstData : list" :key="rowIdx">
         <a-descriptions :column="3">
           <template #title>
@@ -18,6 +17,7 @@
             </a-button>
           </template>
           <a-descriptions-item
+              :span="getSpan(col)"
               v-for="(col, colIdx) in columns.filter((v) => !['sequence_index_number', 'dynamic-opr-button'].includes(v.dataIndex))"
               :key="colIdx"
           >
@@ -38,29 +38,9 @@
             </template>
             <div class="mobile-tanle-form-item">
               <StFormModelItem
-                  v-if="record.disableCell && record.disableCell.find((item) => item.y == col.dataIndex && item.x == rowIdx + 1)"
-                  :record="record.list.find((item) => item.model == col.dataIndex)"
-                  :config="config"
-                  :parentDisabled="true"
-                  :index="record.list.findIndex((item) => item.model == col.dataIndex)"
-                  :domains="dynamicValidateForm.domains"
-                  :dynamicData="dynamicData"
-                  :formData="formData"
-                  :formConfig="formConfig"
-                  :childTableFieldRecord="record.list"
-                  :rowIndex="rowIdx"
-                  v-model:value="item[record.list.find((item) => item.model == col.dataIndex).model]"
-                  @input="handleInput"
-                  :columns="columns"
-                  :pagination="pagination"
-                  :currentTableData="currentTableData"
-                  :colIndex="colIdx"
-              />
-              <StFormModelItem
-                  v-else
                   :record="record.list.find((item) => item.model == col.dataIndex)"
                   :config="config"
-                  :parentDisabled="disabled"
+                  :parentDisabled="record.disableCell && record.disableCell.find((item) => item.y == col.dataIndex && item.x == rowIdx + 1) ? true : disabled"
                   :index="record.list.findIndex((item) => item.model == col.dataIndex)"
                   :domains="dynamicValidateForm.domains"
                   :dynamicData="dynamicData"
@@ -128,7 +108,25 @@ const handleLoadMore = () => {
   refreshTableCard();
   pageNum.value++;
 };
+const getSpan = (col) => {
+  if (!col.width || col.width == '300px') {
+    return 1
+  } else if (col.width == '600px') {
+    return 2
+  } else if (col.width == '900px') {
+    return 3
+  } else {
+    return 1
+  }
 
+}
+watch(
+    () => props.dynamicValidateForm.domains,
+    (newDomains, oldDomains) => {
+      refreshTableCard();
+    },
+    { deep: true }
+);
 const refreshTableCard = () => {
   const startIndex = (pageNum.value - 1) * pageSize.value;
   const endIndex = startIndex + pageSize.value;

+ 0 - 1
src/views/flow/stFormDesign/packages/StChangeOption/index.vue

@@ -161,7 +161,6 @@ export default {
             eventKey
           },
         ];
-        console.log(addData,'add')
         this.$emit('update:value', addData);
       }
     },

+ 0 - 5
src/views/flow/stFormDesign/packages/StFormDesign/module/formComponentPanel.vue

@@ -55,23 +55,18 @@
     <div v-show="showRightMenu" :style="{ top: menuTop + 'px', left: menuLeft + 'px' }" class="right-menu">
       <ul>
         <li @click="handleDownMerge">
-          <a-icon type="caret-down"/>
           向下合并
         </li>
         <li @click="handleRightMerge">
-          <a-icon type="caret-right"/>
           向右合并
         </li>
         <li @click="handleRightSplit">
-          <a-icon type="border-inner"/>
           拆分单元格
         </li>
         <li @click="handleAddCol">
-          <a-icon type="border-horizontal"/>
           增加一列
         </li>
         <li @click="handleAddRow">
-          <a-icon type="border-verticle"/>
           增加一行
         </li>
       </ul>

+ 0 - 5
src/views/flow/stFormDesign/packages/StFormDesign/module/formComponentPanelMobile.vue

@@ -58,23 +58,18 @@
         <div v-show="showRightMenu" :style="{ top: menuTop + 'px', left: menuLeft + 'px' }" class="right-menu">
           <ul>
             <li @click="handleDownMerge">
-              <a-icon type="caret-down"/>
               向下合并
             </li>
             <li @click="handleRightMerge">
-              <a-icon type="caret-right"/>
               向右合并
             </li>
             <li @click="handleRightSplit">
-              <a-icon type="border-inner"/>
               拆分单元格
             </li>
             <li @click="handleAddCol">
-              <a-icon type="border-horizontal"/>
               增加一列
             </li>
             <li @click="handleAddRow">
-              <a-icon type="border-verticle"/>
               增加一行
             </li>
           </ul>

+ 67 - 39
src/views/flow/stFormDesign/packages/StFormDesign/module/formItemProperties.vue

@@ -80,12 +80,23 @@
               placeholder='最大高度'
           />
         </a-form-item>
-        <a-form-item v-if="typeof options.width !== 'undefined'&&!isInBatchTable" label='宽度'>
-          <a-input placeholder='请输入' v-model:value='options.width'/>
-        </a-form-item>
-
-        <a-form-item v-if="isInBatchTable" label='宽度(示例:300px)'>
-          <a-input placeholder='请输入' v-model:value='options.childWidth'/>
+<!--        <a-form-item v-if="typeof options.width !== 'undefined'&&!isInBatchTable" label='宽度'>-->
+<!--          <a-input placeholder='请输入' v-model:value='options.width'/>-->
+<!--        </a-form-item>-->
+        <a-form-item v-if="isInBatchTable&&selectItem.type != 'text'">
+          <template #label>
+            <span style="display: inline-flex; align-items: center;">
+              <a-tooltip placement="topLeft">
+                <template #title>
+                  <div>※子表列表样式示例:300px</div>
+                  <div>※子表卡片样式:通过设置300px的整数倍来设置宽度(300px为默认值,即每行三列,600px占两列,900px占一整行)</div>
+                </template>
+                <QuestionCircleOutlined style="margin-right: 4px;"/>
+              </a-tooltip>
+              宽度
+            </span>
+          </template>
+          <a-input placeholder="请输入" v-model:value="options.childWidth"/>
         </a-form-item>
 
         <a-form-item v-if="typeof options.height !== 'undefined'" label='高度'>
@@ -340,13 +351,26 @@
             "
           />
         </a-form-item>
-        <!-- 修改html -->
-        <a-form-item v-if="selectItem.type === 'html'" label='默认值'>
+        <a-form-item v-if="selectItem.type === 'html'">
+          <template #label>
+            <span style="display: inline-flex; align-items: center;">
+              <a-tooltip placement="topLeft">
+                <template #title>
+                  <div>自定义组件示例:</div>
+                  <div >&lt;div id=&quot;custom_0&quot;&gt;&lt;/div&gt;</div>
+                  <div >共有:custom_0到custom_9</div>
+                </template>
+                <QuestionCircleOutlined style="margin-right: 4px;"/>
+              </a-tooltip>
+              自定义组件/html值
+            </span>
+          </template>
           <a-textarea
-              v-model:value='options.defaultValue'
-              :autoSize='{ minRows: 4, maxRows: 8 }'
+              v-model:value="options.defaultValue"
+              :autoSize="{ minRows: 4, maxRows: 8 }"
           />
         </a-form-item>
+
         <a-form-item
             v-if="typeof options.format !== 'undefined'"
             label='时间格式'
@@ -487,36 +511,36 @@
               placeholder='严格JSON格式'
           ></a-textarea>
         </a-form-item>
-        <!-- 文字对齐方式 -->
-        <a-form-item v-if="selectItem.type === 'text'" label='文字对齐方式'>
-          <a-radio-group buttonStyle='solid' v-model:value='options.textAlign'>
-            <a-radio-button value='left'>左</a-radio-button>
-            <a-radio-button value='center'>居中</a-radio-button>
-            <a-radio-button value='right'>右</a-radio-button>
-          </a-radio-group>
-        </a-form-item>
-        <!-- 文字字体 -->
-        <a-form-item v-if="selectItem.type === 'text'" label='字体属性设置'>
-          <!-- <colorPicker v-model:value='options.color' /> -->
-          <a-select
-              :options='familyOptions'
-              v-model:value='options.fontFamily'
-              style='width:36%;margin-left:2%;vertical-align:bottom;'
-          />
-          <a-select
-              :options='sizeOptions'
-              v-model:value='options.fontSize'
-              style='width:35%;margin-left:2%;vertical-align:bottom;'
-          />
-          <a-checkbox v-model:checked="options.fontBold">加粗</a-checkbox>
-        </a-form-item>
-        <a-form-item v-if="selectItem.type === 'text'" label='操作属性'>
-          <stCheckbox v-model:value='options.showRequiredMark' label='显示必选标记'/>
-        </a-form-item>
+<!--        &lt;!&ndash; 文字对齐方式 &ndash;&gt;-->
+<!--        <a-form-item v-if="selectItem.type === 'text'" label='文字对齐方式'>-->
+<!--          <a-radio-group buttonStyle='solid' v-model:value='options.textAlign'>-->
+<!--            <a-radio-button value='left'>左</a-radio-button>-->
+<!--            <a-radio-button value='center'>居中</a-radio-button>-->
+<!--            <a-radio-button value='right'>右</a-radio-button>-->
+<!--          </a-radio-group>-->
+<!--        </a-form-item>-->
+<!--        &lt;!&ndash; 文字字体 &ndash;&gt;-->
+<!--        <a-form-item v-if="selectItem.type === 'text'" label='字体属性设置'>-->
+<!--          &lt;!&ndash; <colorPicker v-model:value='options.color' /> &ndash;&gt;-->
+<!--          <a-select-->
+<!--              :options='familyOptions'-->
+<!--              v-model:value='options.fontFamily'-->
+<!--              style='width:36%;margin-left:2%;vertical-align:bottom;'-->
+<!--          />-->
+<!--          <a-select-->
+<!--              :options='sizeOptions'-->
+<!--              v-model:value='options.fontSize'-->
+<!--              style='width:35%;margin-left:2%;vertical-align:bottom;'-->
+<!--          />-->
+<!--          <a-checkbox v-model:checked="options.fontBold">加粗</a-checkbox>-->
+<!--        </a-form-item>-->
+<!--        <a-form-item v-if="selectItem.type === 'text'" label='操作属性'>-->
+<!--          <stCheckbox v-model:value='options.showRequiredMark' label='显示必选标记'/>-->
+<!--        </a-form-item>-->
 
         <a-form-item
-            v-if="
-            (typeof options.hidden !== 'undefined' ||
+            v-if="  selectItem.type!='text'&&
+            ((typeof options.hidden !== 'undefined' ||
               typeof options.disabled !== 'undefined' ||
               typeof options.readonly !== 'undefined' ||
               typeof options.clearable !== 'undefined' ||
@@ -525,7 +549,7 @@
               typeof options.showTime !== 'undefined' ||
               typeof options.allowHalf !== 'undefined' ||
               typeof options.showInput !== 'undefined' ||
-              typeof options.animated !== 'undefined') || ['divider', 'alert', 'table', 'button', 'grid', 'card', 'tabs', 'text'].includes(selectItem.type)
+              typeof options.animated !== 'undefined') || ['divider', 'alert', 'table', 'button', 'grid', 'card', 'tabs', 'text'].includes(selectItem.type))
           "
             label='操作属性'
         >
@@ -535,6 +559,7 @@
               label='子表卡片展示'
           />
           <stCheckbox
+
               v-model:value='options.hidden'
               label='隐藏'
           />
@@ -688,6 +713,9 @@ import JsModal from './jsModal.vue'
 import cloneDeep from 'lodash.clonedeep';
 
 function hasBatchParent(code, jsonData) {
+  if (code&&code.indexOf('html_')>=0){
+    return false
+  }
   // 遍历jsonData中的每个元素
   for (const item of jsonData) {
     // 检查当前元素是否为batch类型

+ 1 - 1
src/views/flow/stFormDesign/packages/StFormDesign/module/formNode.vue

@@ -8,7 +8,7 @@
       :class="{ active: record.key === selectItem.key }"
   >
     <div class="form-item-box">
-      <StFormItem :formConfig="config" :formData='{}' :record="record" :childTableFieldRecord='childTableFieldRecord'/>
+      <StFormItem :formConfig="config" :formData='{}' :record="record" :childTableFieldRecord='childTableFieldRecord' :isDesign="true"/>
     </div>
     <div
         v-if="!hideModel"

+ 9 - 8
src/views/flow/stFormDesign/packages/StFormDesign/module/jsModal.vue

@@ -343,12 +343,13 @@ export default {
             } else if (type == '2') {
               this.editorJsCode = `
 //固定写法
-((bizObj) => {
-  const  {rule, value, resolve, reject} = bizObj;
-  console.log("bizObj", bizObj);
-  resolve();
-  // reject("错误信息")
-})(bizObj)
+const { rule, value } = bizObj;
+rule.message = '错误信息'
+if (value == '1') {
+    return true//通过校验
+} else {
+    return false//没有通过校验
+}
 
 `
             }
@@ -763,8 +764,8 @@ const commonMethods = [
   {
     "type": "复杂逻辑",
     "field": "子表单元格不可编辑",
-    "fieldCode": "        const childModel = this.getFieldByModel('test_flow2_child')\n" +
-        "        childModel.disableCell=[{\"x\":1,\"y\":\"sub_table_name\"}]//隐藏第一行,列名是sub_table_name",
+    "fieldCode": "  const childModel = this.getFieldByModel('子表code')\n" +
+        "  childModel.disableCell=[{\"x\":1,\"y\":\"子表字段code\"}]//设置第一行列名是sub_table_name的单元格不可编辑",
     "children": null
   },
   {

+ 49 - 34
src/views/flow/stFormDesign/packages/StFormDesign/module/layoutItem.vue

@@ -40,23 +40,27 @@
               @change="dragChange"
           >
             <template #item="{ element, index }">
-              <transition-group tag="div" name="list">
-                <formNode
-                    :key="element.key"
-                    class="drag-move batch-drag-move"
-                    :selectItem.sync="selectItem"
-                    :record="element"
-                    :hideModel="hideModel"
-                    :config="config"
-                    :childTableFieldRecord="record"
-                    @handleSelectItem="handleSelectItem"
-                    @handleColAdd="handleColAdd"
-                    @handleCopy="$emit('handleCopy')"
-                    @handleChange="$emit('handleChange')"
-                    @handleShowRightMenu="handleShowRightMenu"
-                    @handleDelete="$emit('handleDelete')"
-                />
-              </transition-group>
+
+              <formNode
+                  :key="element.key"
+                  :style="{ width: element.options.childWidth || '300px' }"
+                  :class="{
+                    'drag-move': true,
+                    'span-2': element.options.childWidth === '600px',
+                    'span-3': element.options.childWidth === '900px'
+                  }"
+                  :selectItem.sync="selectItem"
+                  :record="element"
+                  :hideModel="hideModel"
+                  :config="config"
+                  :childTableFieldRecord="record"
+                  @handleSelectItem="handleSelectItem"
+                  @handleColAdd="handleColAdd"
+                  @handleCopy="$emit('handleCopy')"
+                  @handleChange="$emit('handleChange')"
+                  @handleShowRightMenu="handleShowRightMenu"
+                  @handleDelete="$emit('handleDelete')"
+              />
             </template>
           </draggable>
         </a-form-item>
@@ -118,7 +122,7 @@
                 @start="$emit('dragStart', $event, column.list)"
                 @add="$emit('handleColAdd', $event, column.list)"
             >
-              <transition-group tag="div" name="list" class="list-main">
+              <div class="list-main">
                 <formNode
                     v-for="item in column.list"
                     :key="item.key"
@@ -134,18 +138,18 @@
                     @handleShowRightMenu="handleShowRightMenu"
                     @handleDelete="$emit('handleDelete')"
                 />
-              </transition-group>
+              </div>
             </draggable>
           </div>
         </a-form-item>
         <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>
@@ -179,7 +183,7 @@
                   @change="dragChange"
               >
                 <template #item="{ element, index }">
-                  <transition-group tag="div" name="list" class="list-main">
+                  <div class="list-main">
                     <layoutItem
                         :key="element.key"
                         class="drag-move"
@@ -196,7 +200,7 @@
                         @handleShowRightMenu="handleShowRightMenu"
                         @handleDelete="$emit('handleDelete')"
                     />
-                  </transition-group>
+                  </div>
                 </template>
               </draggable>
             </div>
@@ -237,7 +241,7 @@
                 @change="dragChange"
             >
               <template #item="{ element, index }">
-                <transition-group tag="div" name="list" class="list-main">
+                <div class="list-main">
                   <layoutItem
                       :key="element.key"
                       class="drag-move"
@@ -254,7 +258,7 @@
                       @handleShowRightMenu="handleShowRightMenu"
                       @handleDelete="$emit('handleDelete')"
                   />
-                </transition-group>
+                </div>
               </template>
             </draggable>
           </a-col>
@@ -293,7 +297,7 @@
                 @change="dragChange"
             >
               <template #item="{ element, index }">
-                <transition-group tag="div" name="list" class="list-main">
+                <div class="list-main">
                   <layoutItem
                       :key="element.key"
                       class="drag-move"
@@ -311,7 +315,7 @@
                       @handleShowRightMenu="handleShowRightMenu"
                       @handleDelete="$emit('handleDelete')"
                   />
-                </transition-group>
+                </div>
               </template>
             </draggable>
           </div>
@@ -367,7 +371,7 @@
                   @change="dragChange"
               >
                 <template #item="{ element, index }">
-                  <transition-group tag="div" name="list" class="list-main">
+                  <div class="list-main">
                     <layoutItem
                         :key="element.key"
                         class="drag-move"
@@ -384,7 +388,7 @@
                         @handleShowRightMenu="handleShowRightMenu"
                         @handleDelete="$emit('handleDelete')"
                     />
-                  </transition-group>
+                  </div>
                 </template>
               </draggable>
             </td>
@@ -516,11 +520,22 @@ export default {
 }
 
 .batch-draggable-box {
-  display: flex;
-  flex-wrap: nowrap;
+  display: grid;
+  grid-template-columns: repeat(3, 1fr); /* 每行3列 */
+  gap: 5px; /* 设置子元素之间的间距 */
+}
+
+.batch-draggable-box > * {
+  grid-column: span 1; /* 默认占用1列 */
+}
+
+/* 如果某个子元素需要占用2列 */
+.batch-draggable-box > .span-2 {
+  grid-column: span 2; /* 占用2列 */
+}
 
-  .batch-drag-move {
-    width: 350px;
-  }
+/* 如果某个子元素需要占用3列 */
+.batch-draggable-box > .span-3 {
+  grid-column: span 3; /* 占用3列 */
 }
 </style>

+ 0 - 6
src/views/flow/stFormDesign/packages/StFormDesign/module/operatingArea.vue

@@ -8,7 +8,6 @@
     <div class="left-btn-box">
       <a-tooltip title="保存">
         <a v-if="toolbars.includes('save')" @click="$emit('handleSave')">
-          <!-- <a-icon type="save" /> -->
           <span v-if="showToolbarsText">保存</span>
         </a>
       </a-tooltip>
@@ -24,7 +23,6 @@
             v-if="toolbars.includes('importJson')"
             @click="$emit('handleOpenImportJsonModal')"
         >
-          <!-- <a-icon type="upload" /> -->
           <span v-if="showToolbarsText">导入</span>
         </a>
       </a-tooltip>
@@ -44,14 +42,12 @@
             v-if="toolbars.includes('exportCode')"
             @click="$emit('handleOpenCodeModal')"
         >
-          <!-- <a-icon type="code" /> -->
           <span v-if="showToolbarsText">生成代码</span>
         </a>
       </a-tooltip>
 
       <a-tooltip title="清空">
         <a @click="$emit('handleReset')">
-          <!-- <a-icon type="delete" /> -->
           <span v-if="showToolbarsText">清空</span>
         </a>
       </a-tooltip>
@@ -62,7 +58,6 @@
             :class="{ disabled: !(recordList.length > 0) }"
             @click="$emit('handleUndo')"
         >
-          <!-- <a-icon type="undo" /> -->
           <span v-if="showToolbarsText">撤销</span>
         </a>
       </a-tooltip>
@@ -72,7 +67,6 @@
             :class="{ disabled: !(redoList.length > 0) }"
             @click="$emit('handleRedo')"
         >
-          <!-- <a-icon type="redo" /> -->
           <span v-if="showToolbarsText">重做</span>
         </a>
       </a-tooltip>

+ 51 - 31
src/views/flow/stFormDesign/packages/StFormItem/index.vue

@@ -102,12 +102,14 @@
           " :formatter="value => record.options.thousandth == true && value != '' ?
             `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : value" :allowClear="record.options.clearable"
                  tree-node-filter-prop="label" :dynamicData="dynamicData" :treeData="computedOptions"
-                 :options="computedOptions" :mode="record.options.multiple ? 'multiple' : ''" @change="handleChange($event, record.model, record)"
+                 :options="computedOptions" :mode="record.options.multiple ? 'multiple' : ''"
+                 @change="handleChange($event, record.model, record)"
                  :is="componentItem" v-model:value="formData[record.model]"
                  :placeholder="(disabled || record.options.disabled) ? '' : record.options.placeholder"></component>
     </a-form-item>
     <!-- 可隐藏label -->
-    <a-form-item :class="{ 'red-label': record?.options?.requiredFirst ||record?.rules?.find(f=>f.required)}" v-else-if="['batch', 'selectInputList'].includes(record.type)"
+    <a-form-item :class="{ 'red-label': record?.options?.requiredFirst ||record?.rules?.find(f=>f.required)}"
+                 v-else-if="['batch', 'selectInputList'].includes(record.type)"
                  :label="!record.options.showLabel ? '' : record.label" :label-col="formConfig.layout === 'horizontal' && record.options.showLabel
         ? formConfig.labelLayout === 'flex'
           ? { style: `width:${formConfig.labelWidth}px` }
@@ -144,24 +146,18 @@
                :showIcon="record.options.showIcon" :closable="record.options.closable" :banner="record.options.banner"/>
     </a-form-item>
 
-    <!-- 文本
-    <a-form-item v-else-if="record.type === 'text'">
-      <div :style="{ textAlign: record.options.textAlign }">
-        <div v-for="(text, i) in record.label.split('<br>')">
-          <label :class="{ 'ant-form-item-required': record.options.showRequiredMark }" :style="{
-            fontFamily: record.options.fontFamily,
-            fontSize: record.options.fontSize,
-            color: record.options.color,
-            fontWeight: record.options.fontBold == true ? '800' : '100',
-          }" v-text="text"></label>
-        </div>
 
+    <a-form-item v-else-if="record.type === 'text'&&isDesign==true">
+      <div :style="{ textAlign: record.options.textAlign, fontSize: '22px',fontWeight:100,fontFamily:'SimHei' }">
+        {{ record.label }}
       </div>
-    </a-form-item> -->
+    </a-form-item>
     <!-- html -->
-    <div :id="record.key" v-else-if="record.type === 'html'" v-html="record.options.defaultValue"></div>
+    <div :id="record.key" v-else-if="record.type === 'html'"
+         v-html="getHtml(record.options.defaultValue)"></div>
     <!-- 弹出框 -->
-    <PopUpQuery v-else-if="record.type === 'popUpSelect'" :options="computedOptions" :dynamicData="dynamicData" :disabled="disabled || record.options.disabled" :readonly="record.options.readonly"
+    <PopUpQuery v-else-if="record.type === 'popUpSelect'" :options="computedOptions" :dynamicData="dynamicData"
+                :disabled="disabled || record.options.disabled" :readonly="record.options.readonly"
                 :placeholder="(disabled || record.options.disabled) ? '' : record.options.placeholder"
                 @change="handleChange"
                 :formConfig="formConfig" :record="record" :formData="formData"
@@ -197,7 +193,8 @@ import {getDynamicData} from "/@/api/flow/formApi.js";
 
 import {getRulesFunc} from "../../packages/core/contant";
 import {useFlowStore} from '/@/store/modules/flow';
-import { PROVINCE_CITY_DISTRICT } from '/@/views/flow/stFormDesign/province-city-district.js';
+import {PROVINCE_CITY_DISTRICT} from '/@/views/flow/stFormDesign/province-city-district.js';
+
 export default {
   name: "StFormItem",
   props: {
@@ -233,6 +230,11 @@ export default {
     instanceID: {
       type: String,
       default: false,
+    },
+    //表单设计界面
+    isDesign: {
+      type: Boolean,
+      default: false
     }
   },
   components: {
@@ -254,9 +256,9 @@ export default {
   },
   computed: {
     computedOptions() {
-      if (this.record.options.area==true){
+      if (this.record.options.area == true) {
         return PROVINCE_CITY_DISTRICT
-      }      else if (!this.record.options.dynamic) {
+      } else if (!this.record.options.dynamic) {
         return this.record.options.options || [];
       } else if (this.record.options.dynamicOptions) {
         return this.record.options.dynamicOptions;
@@ -292,11 +294,14 @@ export default {
               if (rule.keyCode == 'custom') {
                 if (stScriptCodeList != null) {
                   const ruleCode = stScriptCodeList.find(v => v.objectid == rule.eventKey);
-                  rule.validator = (rule, value) => {
-                    return new Promise((resolve, reject) => {
-                      new Function('bizObj', ruleCode.scriptValue).call({}, {rule, value, resolve, reject})
-                    })
-                  }
+                  const fn = new Function('bizObj', ruleCode.scriptValue);
+                  rule.validator = async (rule, value, callback) => {
+                    const result = fn({rule, value});
+                    if (!result) {
+                      return Promise.reject(callback(new Error('')));
+                    }
+                    return Promise.resolve(callback());
+                  };
                 }
               } else {
                 const {validator} = getRulesFunc(rule.keyCode);
@@ -305,19 +310,22 @@ export default {
             }
           });
         }
-        if (this.$refs.StBatch){
+        if (this.$refs.StBatch) {
           this.$refs.StBatch.record.list.forEach((item, index) => {
-            item.rules.forEach((rule,i)=>{
+            item.rules.forEach((rule, i) => {
               if (rule.flag == "Internal") {
                 if (rule.keyCode) {
                   if (rule.keyCode == 'custom') {
                     if (stScriptCodeList != null) {
                       const ruleCode = stScriptCodeList.find(v => v.objectid == rule.eventKey);
-                      rule.validator = (rule, value) => {
-                        return new Promise((resolve, reject) => {
-                          new Function('bizObj', ruleCode.scriptValue).call({}, {rule, value, resolve, reject})
-                        })
-                      }
+                      const fn = new Function('bizObj', ruleCode.scriptValue);
+                      rule.validator = async (rule, value, callback) => {
+                        const result = fn({rule, value});
+                        if (!result) {
+                          return Promise.reject(callback(new Error('')));
+                        }
+                        return Promise.resolve(callback());
+                      };
                     }
                   } else {
                     const {validator} = getRulesFunc(rule.keyCode);
@@ -393,6 +401,17 @@ export default {
       // 传递change事件
       this.$emit("change", value, key, record, tableInfo);
     },
+    getHtml(value) {
+      if (this.isDesign == true && value.indexOf('custom_') >= 0) {
+        for (let i = 0; i < 100; i++) {
+          if (value.indexOf('custom_' + i) >= 0) {
+            return '<div style="font-size: 16px;font-weight: 800;color: #1677ff;border: 1px dashed #cccccc;display: flex;justify-content: center; border-radius: 5px;">自定义组件_' + i + '</div>'
+          }
+        }
+      } else {
+        return value
+      }
+    },
   },
 };
 </script>
@@ -413,6 +432,7 @@ export default {
 .anticon.anticon-question-circle-o {
   margin-left: 5px;
 }
+
 ::v-deep(.red-label .ant-form-item-label > label) {
   color: red;
 }

+ 339 - 337
src/views/flow/stFormDesign/packages/UploadFile/uploadFile.vue

@@ -1,32 +1,36 @@
 <template>
   <div :style="{ width: record.options.width }">
     <a-upload-dragger
-      :class="{ 'hide-upload-drag': !(fileList.length < record.options.limit) }"
-      :disabled="record.options.disabled || parentDisabled"
-      :name="config.uploadFileName || record.options.fileName"
-      :data="config.uploadFileData || optionsData"
-      :headers="headers"
-      :action="getAction"
-      :multiple="record.options.multiple"
-      :fileList="fileList"
-      @preview="handlePreview"
-      @change="handleChange"
-      :beforeUpload="beforeUpload"
+        :class="{ 'hide-upload-drag': !(fileList.length < record.options.limit) }"
+        :disabled="record.options.disabled || parentDisabled"
+        :name="config.uploadFileName || record.options.fileName"
+        :data="config.uploadFileData || optionsData"
+        :headers="headers"
+        :action="getAction"
+        :multiple="record.options.multiple"
+        :fileList="fileList"
+        @preview="handlePreview"
+        @change="handleChange"
+        :beforeUpload="beforeUpload"
     >
       <p v-if="!record.options.disabled" class="ant-upload-text">单击或拖动文件到此区域</p>
       <template #itemRender="{ file, actions }">
         <div style="display: flex; justify-content: space-between; align-items: center">
           <a :style="file.status === 'error' ? 'color: red' : ''" @click="handlePreview(file)">{{ file.name }}</a>
           <a-space style="margin-right: 10px">
-            <span style="color: #1677ff" v-show="file.originFileObj == '[object File]'"> 上传进度:{{ file.percent.toFixed(2) }}% </span>
-            <a style="font-size: 16px; margin-right: 10px" href="javascript:;" @click="handlePreview(file)">
-              <EyeOutlined />
+            <span style="color:#1677ff" v-show="file.originFileObj=='[object File]'">
+            上传进度:{{ file.percent.toFixed(2) }}%
+            </span>
+            <a style="font-size:16px;margin-right: 10px" href="javascript:;" @click="handlePreview(file)">
+              <EyeOutlined/>
             </a>
-            <a style="font-size: 16px; margin-right: 10px" v-if="!this.$route.query.isMobile" @click="handleDownload(file)">
-              <DownloadOutlined />
+            <a style="font-size:16px;margin-right: 10px" v-if="!this.$route.query.isMobile"
+               @click="handleDownload(file)">
+              <DownloadOutlined/>
             </a>
-            <a style="font-size: 16px; color: red" href="javascript:;" v-if="!record.options.disabled" @click="handleRemove(file)">
-              <DeleteOutlined />
+            <a style="font-size:16px;color: red" href="javascript:;" v-if="!record.options.disabled"
+               @click="handleRemove(file)">
+              <DeleteOutlined/>
             </a>
           </a-space>
         </div>
@@ -34,19 +38,19 @@
     </a-upload-dragger>
     <!-- 预览弹框 -->
     <vue-draggable-resizable
-      v-show="previewVisible"
-      :x="x1"
-      :y="y1"
-      :w="width"
-      :h="height"
-      class="popup-resize"
-      :resizable="true"
-      :draggable="draggableResize"
-      @resizing="handleResizing"
-      @dragging="onDragging"
-      :active="previewActive"
-      :min-width="300"
-      :min-height="100"
+        v-show="previewVisible"
+        :x="x1"
+        :y="y1"
+        :w="width"
+        :h="height"
+        class="popup-resize"
+        :resizable="true"
+        :draggable="draggableResize"
+        @resizing="handleResizing"
+        @dragging="onDragging"
+        :active="previewActive"
+        :min-width="300"
+        :min-height="100"
     >
       <div class="draggable-title">
         <span class="preview-left">附件预览</span>
@@ -61,33 +65,30 @@
       </div>
       <div class="control-buttons">
         <a-button v-show="!maxed" class="control-button" @click="maximize">
-          <ExpandOutlined />
-          <!-- 最大化图标 -->
+          <ExpandOutlined/> <!-- 最大化图标 -->
         </a-button>
         <a-button v-show="maxed" class="control-button" @click="restore">
-          <ShrinkOutlined />
-          <!-- 返回图标 -->
+          <ShrinkOutlined/> <!-- 返回图标 -->
         </a-button>
         <a-button class="control-button" @click="closeDrag">
-          <CloseOutlined />
-          <!-- 关闭图标 -->
+          <CloseOutlined/> <!-- 关闭图标 -->
         </a-button>
       </div>
     </vue-draggable-resizable>
 
     <a-drawer
-      title="附件预览"
-      placement="bottom"
-      :visible="previewVisibleMobile"
-      @close="previewVisibleMobile = false"
-      height="90%"
-      width="100vw"
-      :closable="true"
-      :bodyStyle="{
+        title="附件预览"
+        placement="bottom"
+        :visible="previewVisibleMobile"
+        @close="previewVisibleMobile = false"
+        height="90%"
+        width="100vw"
+        :closable="true"
+        :bodyStyle="{
         padding: '0',
         scrollbarWidth: 'none' /* Firefox */,
       }"
-      :drawerStyle="{
+        :drawerStyle="{
         scrollbarWidth: 'none' /* Firefox */,
       }"
     >
@@ -96,326 +97,327 @@
   </div>
 </template>
 <script>
-  import { fileApi } from '/@/api/support/file-api';
-  import { localRead } from '/@/utils/local-util';
-  import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
-  import { useUserStore } from '/@/store/modules/system/user.js';
-  import dayjs from 'dayjs';
-  import { Base64 } from 'js-base64';
-  import { message, Modal } from 'ant-design-vue';
-  import VueDraggableResizable from 'vue-draggable-resizable';
-  import 'vue-draggable-resizable/style.css';
+import {fileApi} from '/@/api/support/file-api';
+import {localRead} from '/@/utils/local-util';
+import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
+import {useUserStore} from '/@/store/modules/system/user.js';
+import dayjs from 'dayjs';
+import {Base64} from 'js-base64';
+import {message, Modal} from 'ant-design-vue';
+import VueDraggableResizable from 'vue-draggable-resizable'
+import "vue-draggable-resizable/style.css";
 
-  const fileUrl = import.meta.env.VITE_APP_API_FILE_VIEW_URL;
-  export default {
-    name: 'StUploadFile',
-    props: ['record', 'value', 'config', 'parentDisabled', 'dynamicData'],
-    components: {
-      VueDraggableResizable,
+const fileUrl = import.meta.env.VITE_APP_API_FILE_VIEW_URL;
+export default {
+  name: 'StUploadFile',
+  props: ['record', 'value', 'config', 'parentDisabled', 'dynamicData'],
+  components: {
+    VueDraggableResizable
+  },
+  data() {
+    return {
+      fileList: [],
+      getAction: import.meta.env.VITE_APP_API_URL + '/support/file/upload?folder=1',
+      headers: {'x-access-token': localRead(LocalStorageKeyConst.USER_TOKEN)},
+      previewVisible: false, // 控制弹框显示
+      previewVisibleMobile: false,
+      previewUrl: '', // 预览的 URL
+      x1: 100,
+      y1: 10,
+      x2: 100,
+      y2: 10,
+      width: 0,
+      height: 0,
+      lastWidth: 0,
+      lastHeight: 0,
+      maxed: false,
+      scaleFactor: 1.1,
+      iframeShow: true,
+      previewActive: false,
+      fileName: '',
+      draggableResize: true,
+    };
+  },
+  mounted() {
+    this.width = window.innerWidth - 200
+    this.height = window.innerHeight - 90
+    document.addEventListener('mouseup', this.handleGlobalMouseUp);
+  },
+  beforeDestroy() {
+    // 在组件销毁时移除全局 mouseup 事件
+    document.removeEventListener('mouseup', this.handleGlobalMouseUp);
+  },
+  watch: {
+    value: {
+      // value 需要深度监听及默认先执行handler函数
+      handler(val) {
+        if (val) {
+          this.setFileList();
+        }
+      },
+      immediate: true,
+      deep: true,
     },
-    data() {
-      return {
-        fileList: [],
-        getAction: import.meta.env.VITE_APP_API_URL + '/support/file/upload?folder=1',
-        headers: { 'x-access-token': localRead(LocalStorageKeyConst.USER_TOKEN) },
-        previewVisible: false, // 控制弹框显示
-        previewVisibleMobile: false,
-        previewUrl: '', // 预览的 URL
-        x1: 100,
-        y1: 10,
-        x2: 100,
-        y2: 10,
-        width: 0,
-        height: 0,
-        lastWidth: 0,
-        lastHeight: 0,
-        maxed: false,
-        scaleFactor: 1.1,
-        iframeShow: true,
-        previewActive: false,
-        fileName: '',
-        draggableResize: true,
-      };
+  },
+  computed: {
+    optionsData() {
+      try {
+        return this.record.options.data && JSON.parse(this.record.options.data);
+      } catch (err) {
+        console.error(err);
+        return {};
+      }
     },
-    mounted() {
-      this.width = window.innerWidth - 200;
-      this.height = window.innerHeight - 90;
-      document.addEventListener('mouseup', this.handleGlobalMouseUp);
+  },
+  methods: {
+    setFileList() {
+      // 当传入value改变时,fileList也要改变
+      // 如果传入的值为字符串,则转成json
+      if (typeof this.value === 'string') {
+        if (this.value.indexOf('fakepath') < 0) {
+          this.fileList = JSON.parse(this.value);
+          // 将转好的json覆盖组件默认值的字符串
+          this.handleSelectChange();
+        }
+      } else {
+        this.fileList = this.value;
+      }
     },
-    beforeDestroy() {
-      // 在组件销毁时移除全局 mouseup 事件
-      document.removeEventListener('mouseup', this.handleGlobalMouseUp);
+    // 调整大小过程中持续触发
+    handleResizing(x, y, width, height) {
+      this.x1 = x
+      this.y1 = y
+      this.width = width
+      this.height = height
+      this.iframeShow = false
+      this.maxed = false
     },
-    watch: {
-      value: {
-        // value 需要深度监听及默认先执行handler函数
-        handler(val) {
-          if (val) {
-            this.setFileList();
-          }
-        },
-        immediate: true,
-        deep: true,
-      },
+    onDragging(x, y) {
+      this.x1 = x
+      this.y1 = y
+      this.maxed = false
     },
-    computed: {
-      optionsData() {
-        try {
-          return this.record.options.data && JSON.parse(this.record.options.data);
-        } catch (err) {
-          console.error(err);
-          return {};
-        }
-      },
+    handleGlobalMouseUp() {
+      this.iframeShow = true
     },
-    methods: {
-      setFileList() {
-        // 当传入value改变时,fileList也要改变
-        // 如果传入的值为字符串,则转成json
-        if (typeof this.value === 'string') {
-          if (this.value.indexOf('fakepath') < 0) {
-            this.fileList = JSON.parse(this.value);
-            // 将转好的json覆盖组件默认值的字符串
-            this.handleSelectChange();
-          }
-        } else {
-          this.fileList = this.value;
-        }
-      },
-      // 调整大小过程中持续触发
-      handleResizing(x, y, width, height) {
-        this.x1 = x;
-        this.y1 = y;
-        this.width = width;
-        this.height = height;
-        this.iframeShow = false;
-        this.maxed = false;
-      },
-      onDragging(x, y) {
-        this.x1 = x;
-        this.y1 = y;
-        this.maxed = false;
-      },
-      handleGlobalMouseUp() {
-        this.iframeShow = true;
-      },
-      handleSelectChange() {
-        setTimeout(() => {
-          this.$emit('update:value', this.fileList); //主表,直接更新value
-          this.$emit('change', this.fileList); //如果是子表,则通过change更新
-          this.$emit('input', this.fileList);
-        }, 10);
-      },
-      handleDownload(file) {
-        fileApi.downLoadFile(file.response.data.fileKey);
-      },
-      handlePreview(file) {
-        // 预览
-        const url = file.response.data.fileUrl || file.url || file.thumbUrl;
-        const userStore = useUserStore();
-        const waterMark = [
-          userStore.actualName + '-' + (userStore.phone == undefined ? '0000' : userStore.phone?.slice(-4)),
-          dayjs().format('YYYY-MM-DD HH:mm:ss'),
-        ];
-        const viewFile = fileUrl + '/onlinePreview?url=' + encodeURIComponent(Base64.encode(url)) + '&watermarkTxt=' + waterMark;
-        if (this.$route.query.isMobile === 'true') {
-          // window.open(viewFile);
-          this.previewVisible = false; // 显示弹框
+    handleSelectChange() {
+      setTimeout(() => {
+        this.$emit('update:value', this.fileList); //主表,直接更新value
+        this.$emit('change', this.fileList); //如果是子表,则通过change更新
+        this.$emit('input', this.fileList);
+      }, 10);
+    },
+    handleDownload(file) {
+      fileApi.downLoadFile(file.response.data.fileKey);
+    },
+    handlePreview(file) {
+      // 预览
+      const url = file.response.data.fileUrl || file.url || file.thumbUrl;
+      const userStore = useUserStore();
+      const waterMark = [
+        userStore.actualName + '-' + (userStore.phone == undefined ? '0000' : userStore.phone?.slice(-4)),
+        dayjs().format('YYYY-MM-DD HH:mm:ss'),
+      ];
+      const viewFile = fileUrl + '/onlinePreview?url=' + encodeURIComponent(Base64.encode(url)) + '&watermarkTxt=' + waterMark;
+      if (this.$route.query.isMobile === 'true') {
+        // window.open(viewFile);
+        this.previewVisible = false; // 显示弹框
 
-          this.previewUrl = viewFile;
-          this.previewVisibleMobile = true;
+        this.previewUrl = viewFile;
+        this.previewVisibleMobile = true;
+      } else {
+        this.previewUrl = viewFile;
+        this.fileName = file.name
+        this.previewVisible = true; // 显示弹框
+        this.previewActive = true;
+      }
+    },
+    handleRemove(file) {
+      this.fileList = this.fileList.filter((item) => item.uid !== file.uid);
+      this.handleSelectChange();
+    },
+    beforeUpload(e, files) {
+      // if (files.length + this.fileList.length > this.record.options.limit) {
+      //   this.$message.warning(`最大上传数量为${this.record.options.limit}`)
+      //   files.splice(this.record.options.limit - this.fileList.length)
+      // }
+    },
+    handleChange(info) {
+      this.fileList = info.fileList;
+      if (info.file.status === 'done') {
+        const res = info.file.response;
+        if (res.code === 0) {
+          this.handleSelectChange();
         } else {
-          this.previewUrl = viewFile;
-          this.fileName = file.name;
-          this.previewVisible = true; // 显示弹框
-          this.previewActive = true;
-        }
-      },
-      handleRemove(file) {
-        this.fileList = this.fileList.filter((item) => item.uid !== file.uid);
-        this.handleSelectChange();
-      },
-      beforeUpload(e, files) {
-        // if (files.length + this.fileList.length > this.record.options.limit) {
-        //   this.$message.warning(`最大上传数量为${this.record.options.limit}`)
-        //   files.splice(this.record.options.limit - this.fileList.length)
-        // }
-      },
-      handleChange(info) {
-        this.fileList = info.fileList;
-        if (info.file.status === 'done') {
-          const res = info.file.response;
-          if (res.code === 0) {
-            this.handleSelectChange();
-          } else {
-            this.fileList.pop();
-            this.$message.error(`文件上传失败`);
-          }
-        } else if (info.file.status === 'error') {
+          this.fileList.pop();
           this.$message.error(`文件上传失败`);
         }
-      },
-      closeDrag() {
-        this.previewVisible = false;
-      },
-      maximize() {
-        this.maxed = true;
-        this.lastWidth = this.width;
-        this.lastHeight = this.height;
-        this.x2 = this.x1;
-        this.y2 = this.y1;
-        this.width = window.innerWidth;
-        this.height = window.innerHeight;
-        this.x1 = 0;
-        this.y1 = 0;
-        this.draggableResize = false;
-      },
-      restore() {
-        this.width = this.lastWidth;
-        this.height = this.lastHeight;
-        this.x1 = this.x2;
-        this.y1 = this.y2;
-        this.maxed = false;
-        this.draggableResize = true;
-      },
+      } else if (info.file.status === 'error') {
+        this.$message.error(`文件上传失败`);
+      }
     },
-  };
+    closeDrag() {
+      this.previewVisible = false
+    },
+    maximize() {
+      this.maxed = true
+      this.lastWidth = this.width
+      this.lastHeight = this.height
+      this.x2 = this.x1
+      this.y2 = this.y1
+      this.width = window.innerWidth
+      this.height = window.innerHeight
+      this.x1 = 0
+      this.y1 = 0
+      this.draggableResize=false
+    },
+    restore() {
+      this.width = this.lastWidth
+      this.height = this.lastHeight
+      this.x1 = this.x2
+      this.y1 = this.y2
+      this.maxed = false
+      this.draggableResize=true
+    }
+  },
+};
 </script>
 <style scoped lang="scss">
-  .fullscreen-modal {
-    width: 100vw !important;
-    height: 100vh !important;
-    max-width: 100vw !important;
-    margin: 0 !important;
-    padding: 0 !important;
-  }
+.fullscreen-modal {
+  width: 100vw !important;
+  height: 100vh !important;
+  max-width: 100vw !important;
+  margin: 0 !important;
+  padding: 0 !important;
+}
 
-  .fullscreen-modal .ant-modal-content {
-    height: 100vh !important;
-    display: flex;
-    flex-direction: column;
-  }
+.fullscreen-modal .ant-modal-content {
+  height: 100vh !important;
+  display: flex;
+  flex-direction: column;
+}
 
-  .fullscreen-modal .ant-modal-body {
-    flex: 1;
-  }
+.fullscreen-modal .ant-modal-body {
+  flex: 1;
+}
 
-  :deep(.ant-upload-wrapper) .ant-upload-drag .ant-upload {
-    padding: 0px 0px 0px 0;
-    background-color: #dde5f6;
-  }
+:deep(.ant-upload-wrapper) .ant-upload-drag .ant-upload {
+  padding: 0px 0px 0px 0;
+  background-color: #dde5f6;
+}
 
-  :deep(.vdr) {
-    z-index: 10000 !important;
-    position: fixed;
-    left: 0;
-    top: 0;
-  }
+:deep(.vdr) {
+  z-index: 10000 !important;
+  position: fixed;
+  left: 0;
+  top: 0;
+}
 
-  .drag_btn {
-    background: #fff;
-    display: flex;
-    justify-content: center;
+.drag_btn {
+  background: #fff;
+  display: flex;
+  justify-content: center;
 
-    button {
-      font-size: 20px;
-      width: 70px;
-    }
+  button {
+    font-size: 20px;
+    width: 70px;
   }
+}
 
-  .control-buttons {
-    background-color: #ffffff;
-    display: flex;
-    align-items: center;
-    justify-content: flex-end;
-    position: absolute;
-    right: 8px;
-    top: 2px;
-    z-index: 100;
-  }
+.control-buttons {
+  background-color: #ffffff;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  position: absolute;
+  right: 8px;
+  top: 2px;
+  z-index: 100;
+}
 
-  .control-button {
-    font-size: 16px;
-    margin-left: 8px; /* 按钮之间的间距 */
-    background: none;
-    border: none;
-    cursor: pointer;
-  }
+.control-button {
+  font-size: 16px;
+  margin-left: 8px; /* 按钮之间的间距 */
+  background: none;
+  border: none;
+  cursor: pointer;
+}
 
-  .draggable-title {
-    display: flex;
-    justify-content: space-between; /* 子元素之间的间距均匀分布 */
-    align-items: center; /* 垂直居中 */
-    padding: 8px;
-    cursor: move;
-    background-color: #ffffff;
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    z-index: 10;
-  }
+.draggable-title {
+  display: flex;
+  justify-content: space-between; /* 子元素之间的间距均匀分布 */
+  align-items: center; /* 垂直居中 */
+  padding: 8px;
+  cursor: move;
+  background-color: #ffffff;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 10;
+}
 
-  .preview-left {
-    margin-left: 20px;
-    color: rgba(0, 0, 0, 0.88);
-    font-weight: 600;
-    font-size: 16px;
-    line-height: 1.5;
-  }
+.preview-left {
+  margin-left: 20px;
+  color: rgba(0, 0, 0, 0.88);
+  font-weight: 600;
+  font-size: 16px;
+  line-height: 1.5;
+}
 
-  .preview-title {
-    margin: 0 auto;
-    color: rgba(0, 0, 0, 0.88);
-    font-weight: 600;
-    font-size: 16px;
-    line-height: 1.5;
-  }
+.preview-title {
+  margin: 0 auto;
+  color: rgba(0, 0, 0, 0.88);
+  font-weight: 600;
+  font-size: 16px;
+  line-height: 1.5;
+}
 
-  .draggable-content {
-    width: 100%;
-    height: 100%;
-    padding: 36px 22px 22px 22px;
-    cursor: move;
-  }
+.draggable-content {
+  width: 100%;
+  height: 100%;
+  padding: 36px 22px 22px 22px;
+  cursor: move;
+}
 
-  .popup-resize {
-    background-color: #ffffff;
-    border: 1px dashed #ffffff; /* 虚线边框,蓝色 */
-    border-radius: 8px; /* 圆角边框 */
-    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 添加阴影 */
-  }
+.popup-resize {
+  background-color: #ffffff;
+  border: 1px dashed #ffffff; /* 虚线边框,蓝色 */
+  border-radius: 8px; /* 圆角边框 */
+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 添加阴影 */
+}
 
-  .overlay {
-    position: absolute;
-    top: 60px;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    pointer-events: none; /* 防止鼠标事件干扰 iframe */
-  }
+.overlay {
+  position: absolute;
+  top: 60px;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  pointer-events: none; /* 防止鼠标事件干扰 iframe */
+}
 
-  .horizontal {
-    height: 1px;
-    width: 100%;
-    border-color: #7cb305;
-    font-size: 18px;
-    font-weight: 600;
-    border-width: 2px;
-    color: #0d366f;
-  }
+.horizontal {
+  height: 1px;
+  width: 100%;
+  border-color: #7cb305;
+  font-size: 18px;
+  font-weight: 600;
+  borderWidth: 2px;
+  color: #0D366F;
+}
+
+.vertical {
+  display: inline-flex !important;
+  align-items: center !important;
+  font-size: 18px;
+  font-weight: 600;
+  borderWidth: 2px;
+  color: #0D366F;
+  height: 100%;
+  border-color: #7cb305;
+  top: -92px;
+  z-index: 12;
+  margin-left: 70px;
+}
 
-  .vertical {
-    display: inline-flex !important;
-    align-items: center !important;
-    font-size: 18px;
-    font-weight: 600;
-    border-width: 2px;
-    color: #0d366f;
-    height: 100%;
-    border-color: #7cb305;
-    top: -92px;
-    z-index: 12;
-    margin-left: 70px;
-  }
 </style>

+ 5 - 4
src/views/flow/stFormWork/components/headerInfo/mobileIndex.vue

@@ -73,6 +73,7 @@ const imgStates = ref([{
   border-bottom-left-radius: 8px;
   border-bottom-right-radius: 8px;
   padding-left: 58px;
+  margin-top:-10px;
 
 
   .dx-label {
@@ -93,10 +94,10 @@ const imgStates = ref([{
 
   .mvc-state {
     position: absolute;
-    margin-left: 280px;
-    margin-top: 90px;
-    width: 80px;
-    height: 80px;
+    margin-left: 290px;
+    margin-top: 100px;
+    width: 70px;
+    height: 70px;
     z-index: 999;
 
     img {

+ 22 - 12
src/views/flow/stFormWork/formWork.vue

@@ -130,16 +130,16 @@
         </div>
       </div>
       <div class="form-skeleton" v-show="!loadBeforeOver">
-        <a-skeleton />
-        <br />
-        <a-skeleton />
-        <br />
-        <a-skeleton />
-        <br />
-        <a-skeleton />
-        <br />
-        <a-skeleton />
-        <br />
+        <a-skeleton/>
+        <br/>
+        <a-skeleton/>
+        <br/>
+        <a-skeleton/>
+        <br/>
+        <a-skeleton/>
+        <br/>
+        <a-skeleton/>
+        <br/>
       </div>
     </a-spin>
     <print-preview ref="preView"/>
@@ -744,7 +744,17 @@ const setValue = (field, value) => {
   const {formData} = stbRef.value;
 
   if (typeof field == 'string') {
-    formData[field] = value;
+    const fieldMapValue = fieldMap.value[field]
+    if (fieldMapValue && value && fieldMapValue.type == "MULTI" && typeof value == 'string') {
+      formData[field] = JSON.parse(value);
+    } else if (fieldMapValue && value && (fieldMapValue.type == "INTEGER" || fieldMapValue.type == "DECIMAL") && typeof value != 'string') {
+      formData[field] = value.toString();
+    } else if (fieldMapValue && value && fieldMapValue.type == "DATETIME" && typeof value != 'string') {
+      formData[field] = value.toString();
+    } else {
+      formData[field] = value;
+    }
+
   } else if (typeof field == 'object') {
     formData[field.model] = value;
   }
@@ -1073,7 +1083,7 @@ const handleSave = () => {
           saveService();
         },
         (err) => {
-          console.log(err);
+          console.error(err);
         }
     );
   } catch (e) {

+ 0 - 1
src/views/flow/stFormWork/style/formWork.less

@@ -202,7 +202,6 @@
 :deep(.ant-select-disabled .ant-select-selection),
 :deep(.ant-btn[disabled]),
 :deep(.ant-input-disabled) {
-  border-radius: 0px;
   background-color: #fafafa !important;
   color: black;
 }

+ 13 - 3
src/views/flow/stSetting/flowNameSetting.vue

@@ -6,9 +6,19 @@
           <a-alert
               message="示例:【{leaveOfAbsence}-请假审批流程-[SySSequence]-[SySOriginator]】→结果→【张三-请假审批流程-20250101000001-王五】  "
               type="warning"/>
-          <a-alert message="字段:{字段编号}" type="success"/>
-          <a-alert message="流程编号:[SySSequence]" type="success"/>
-          <a-alert message="发起人:[SySOriginator]" type="success"/>
+          <a-row>
+            <a-col :span="4">
+              <a-alert message="字段:{字段编号}" type="success"/>
+            </a-col>
+            <a-col :span="4">
+              <a-alert message="流程编号:[SySSequence]" type="success"/>
+            </a-col>
+            <a-col :span="4">
+              <a-alert message="发起人:[SySOriginator]" type="success"/>
+            </a-col>
+          </a-row>
+
+
         </a-space>
       </a-row>
       <a-row class='curRow'>

+ 3 - 3
src/views/flow/stSetting/flowNumberPrefix.vue

@@ -1,9 +1,9 @@
 <template>
   <div class='container'>
-    <a-card class='curCard' title='流程单号前缀(例:BXD202001010001)' style='width: 100%'>
+    <a-card class='curCard' title='流程单号前缀(例:BXD202501000001)' style='width: 100%'>
       <a-row class='curRow' >
-        <a-col class='left-text' :span='1'>单号前缀:</a-col>
-        <a-col :span='12'>
+        <a-col class='left-text' :span='2'>单号前缀:</a-col>
+        <a-col :span='11'>
           <a-input v-model:value='flowNamePrefix'></a-input>
         </a-col>
         <a-col class='left-text' :span='1'></a-col>

+ 36 - 37
src/views/flow/stSetting/index.vue

@@ -1,64 +1,63 @@
 <template>
   <div class="container">
-    <a-collapse v-model:activeKey='activeKey' @change='changeCollapse'>
-      <a-collapse-panel key='0' header='流程名称设置:'>
+    <a-collapse
+        v-model:activeKey="activeKey"
+        :bordered="false"
+        style="background: rgb(255, 255, 255)"
+    >
+      <template #expandIcon="{ isActive }">
+        <caret-right-outlined :rotate="isActive ? 90 : 0" />
+      </template>
+      <a-collapse-panel key='0' header='流程名称设置:' :style="customStyle">
         <FlowNameSetting :flowCode='flowCode'></FlowNameSetting>
       </a-collapse-panel>
-      <a-collapse-panel key='1' header='单号前缀:'>
+      <a-collapse-panel key='1' header='单号前缀:' :style="customStyle">
         <FlowNumberPrefix :flowCode='flowCode'></FlowNumberPrefix>
       </a-collapse-panel>
-      <a-collapse-panel key='2' header='流程描述'>
-        <FlowDescribe :flowCode='flowCode'></FlowDescribe>
-      </a-collapse-panel>
-      <a-collapse-panel key='3' header='事件方法设置'>
+      <a-collapse-panel key='3' header='事件方法设置' :style="customStyle">
         <FlowEventService :flowCode='flowCode'></FlowEventService>
       </a-collapse-panel>
-      <a-collapse-panel key='4' header='发起表单权限'>
+      <a-collapse-panel key='4' header='发起表单权限' :style="customStyle">
         <FlowInitiateForm :flowCode='flowCode'></FlowInitiateForm>
       </a-collapse-panel>
-      <a-collapse-panel key='5' header='查看表单权限'>
+      <a-collapse-panel key='5' header='查看表单权限' :style="customStyle">
         <FlowManageForm :flowCode='flowCode'></FlowManageForm>
       </a-collapse-panel>
+      <a-collapse-panel key='2' header='流程描述' :style="customStyle">
+        <FlowDescribe :flowCode='flowCode'></FlowDescribe>
+      </a-collapse-panel>
     </a-collapse>
   </div>
 </template>
-<script>
+
+<script setup>
+import { ref } from 'vue';
 import FlowNameSetting from '/@/views/flow/stSetting/flowNameSetting.vue'
 import FlowEventService from '/@/views/flow/stSetting/flowEventService.vue'
 import FlowNumberPrefix from '/@/views/flow/stSetting/flowNumberPrefix.vue'
 import FlowDescribe from '/@/views/flow/stSetting/flowDescribe.vue'
 import FlowInitiateForm from '/@/views/flow/stSetting/flowInitiateForm.vue'
 import FlowManageForm from '/@/views/flow/stSetting/flowManageForm.vue'
-
-export default {
-  data() {
-    return {
-      text: ``,
-      activeKey: ['0']
-    }
-  },
-  props: {
-    flowCode: ''
-  },
-  components: {
-    FlowEventService,
-    FlowNumberPrefix,
-    FlowDescribe,
-    FlowInitiateForm,
-    FlowManageForm,
-    FlowNameSetting
-  },
-  methods: {
-    changeCollapse(key) {
-      console.log(key, 'key')
-    }
+const customStyle = "background: #f8f9fa;border-radius: 4px;margin-bottom: 14px;border: 0;overflow: hidden";
+const props = defineProps({
+  flowCode: {
+    type: String,
+    default: ''
   }
-}
+})
+const activeKey = ref(['-1'])
+
 </script>
+
 <style scoped>
 .container {
-  height: 100%; /* 根据需要调整高度 */
-  overflow-y: auto; /* 增加竖向滚动条 */
+  height: calc(100% - 32px);
+  overflow-y: auto;
+  border: 1px solid #ccc; /* 添加灰色边框 */
+  border-radius: 8px; /* 添加圆角边框 */
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
+  background-color: #fff; /* 设置背景颜色 */
+  padding: 16px; /* 添加内边距 */
+  margin: 16px;
 }
-
 </style>