Bläddra i källkod

Merge remote-tracking branch 'origin/1.2.2' into 1.2.2

# Conflicts:
#	src/utils/request.js
#	src/views/basic/dynamicModel/list/index.vue
yangfan 3 månader sedan
förälder
incheckning
013d0ece96

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 500 - 264
package-lock.json


+ 4 - 0
package.json

@@ -48,6 +48,7 @@
     "fuse.js": "3.4.4",
     "highcharts": "7.1.3",
     "highcharts-vue": "^1.3.5",
+    "husky": "^9.1.6",
     "js-base64": "^2.6.4",
     "js-beautify": "^1.14.9",
     "js-md5": "^0.7.3",
@@ -63,6 +64,8 @@
     "nprogress": "0.2.0",
     "path-to-regexp": "2.4.0",
     "qrcodejs2": "0.0.2",
+    "qs": "^6.13.0",
+    "quill": "^2.0.2",
     "reconnecting-websocket": "^4.4.0",
     "screenfull": "4.2.0",
     "script-loader": "0.7.2",
@@ -70,6 +73,7 @@
     "sortablejs": "1.8.4",
     "swiper": "^5.4.5",
     "throttle-debounce": "^2.1.0",
+    "uuid": "^11.0.2",
     "vcrontab": "^0.3.5",
     "vue": "^2.7.0",
     "vue-awesome-swiper": "^3.1.3",

+ 1 - 1
src/components/Generator/generator/comConfig.js

@@ -28,7 +28,7 @@ const dyOptionsList = ['radio', 'checkbox', 'select', 'cascader', 'treeSelect']
 const noVModelList = ['divider', 'JNPFText', 'groupTitle', 'relationFormAttr', 'relationFlowAttr', 'PlaceholderCom','new-divider']
 // 不可以添加到子表组件
 const noTableAllowList = [
-  'serialNumber',
+  // 'serialNumber',
   'textarea',
   'JNPFText',
   'JNPFAmount',

+ 37 - 7
src/components/Generator/index/Home.vue

@@ -14,7 +14,7 @@
               filter=".disabled"
               :sort="false"
               :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
-              @end="onEnd"
+              @end="onEnd"  :move="onHandleAdd"
             >
               <div v-for="(element, index) in item.list" :key="index" class="components-item" :class="{ disabled: element.__config__.dragDisabled }" @click="addComponent(element)">
                 <div class="components-body">
@@ -138,6 +138,7 @@ import { noTableAllowList, noVModelList, webPeculiarList } from '@/components/Ge
 import { deepClone } from '@/components/Generator/utils'
 import DraggableItem from './DraggableItem'
 import { getIdGlobal, saveDrawingList, saveIdGlobal } from '@/components/Generator/utils/db'
+import {loopRelationList, loopSerialNumberList} from "@/utils";
 
 const emptyActiveData = { style: {}, autosize: {} }
 let oldActiveId
@@ -501,12 +502,22 @@ export default {
       if (isRowContainer) return true
       if (conf.cmpType === 'custom') return false
       if (conf.__config__.rowType === 'table') {
+        if (!targetConf) return false;
         if (noTableAllowList.includes(targetConf.__config__.jnpfKey)) {
           // if (this.showTip) {
           //   this.$message.warning(`子表内暂不支持使用该组件`)
           //   this.showTip = false
           // }
           return false
+        }else {
+          let serialRow = conf.__config__.children
+            .map((z) => z.__config__.jnpfKey)
+            .flat()
+            .find((i) => i === targetConf.__config__.jnpfKey && targetConf.__config__.jnpfKey === 'serialNumber')
+          if (serialRow){
+            this.$message.warning('子表中仅可添加一个流水号控件')
+            return false
+          }
         }
         if (targetConf.__config__.layout === 'rowFormItem') return false
         if (this.$store.getters.hasTable) {
@@ -527,6 +538,16 @@ export default {
       this.activeData = element
       this.activeId = element.__config__.formId
     },
+    onHandleAdd(to){
+      if (to.to.className === 'drawing-board' || to.to.className === 'drag-wrapper') {
+        let fieldsFil = loopSerialNumberList(this.drawingList)
+        const z = fieldsFil.find(i=> i.__config__.jnpfKey && i.__config__.jnpfKey === 'serialNumber')
+        if (z){
+          this.$message.warning('表单中仅可添加一个流水号控件')
+          return false;
+        }
+      }
+    },
     onEnd(obj) {
       if (!tempActiveData) return
       this.showTip = true
@@ -615,11 +636,14 @@ export default {
     },
     cloneComponent(origin) {
       if (origin.__config__.jnpfKey === 'serialNumber') {
-        let serialRow = this.drawingList
-          .map((z) => z.__config__.jnpfKey)
-          .flat()
-          .find((i) => i === origin.__config__.jnpfKey && origin.__config__.jnpfKey === 'serialNumber')
-        if (serialRow) return this.$message.warning('表单中仅可添加一个流水号控件')
+        let isTable = this.drawingList.find((i) => i.__config__.jnpfKey && i.__config__.jnpfKey === 'table')
+        if (!isTable) {
+          let serialRow = this.drawingList
+            .map((z) => z.__config__.jnpfKey)
+            .flat()
+            .find((i) => i === origin.__config__.jnpfKey && origin.__config__.jnpfKey === 'serialNumber')
+          if (serialRow) return this.$message.warning('表单中仅可添加一个流水号控件')
+        }
       }
       const clone = deepClone(origin)
       const config = clone.__config__
@@ -660,7 +684,6 @@ export default {
       if (Array.isArray(config.children)) {
         config.children = config.children.map((childItem) => this.createIdAndKey(childItem))
       }
-      console.log(item)
       return item
     },
     AssembleFormData() {
@@ -695,6 +718,13 @@ export default {
         .catch(() => {})
     },
     drawingItemCopy(item, parent) {
+      if (item.__config__.jnpfKey === 'serialNumber') {
+        let serialRow = parent
+          .map((z) => z.__config__.jnpfKey)
+          .flat()
+          .find((i) => i === item.__config__.jnpfKey && item.__config__.jnpfKey === 'serialNumber')
+        if (serialRow) return this.$message.warning('表单中仅可添加一个流水号控件')
+      }
       let clone = deepClone(item)
       clone = this.createIdAndKey(clone)
       parent.push(clone)

+ 6 - 2
src/components/Generator/index/RightComponents/serialNumber.vue

@@ -23,7 +23,7 @@
         <div v-for="(item, index) in activeData.serialgz" :key="index" class="serial-item">
           <div class="serial-item-gz">
             <div class="serial-label">{{ serialLabel(item.type) }}</div>
-            <el-input v-if="item.type === 'fixedChars'" v-model="item.chars" placeholder="请输入内容" />
+            <el-input v-if="item.type === 'fixedChars'" v-model="item.chars" :key="item.id" placeholder="请输入内容" />
             <el-input v-if="item.type === 'createTime'" @click.native="setTimeFun(item)" readonly :value="getSerialData(item.format)" />
             <el-input v-if="item.type === 'incNumber'" @click.native="setIncNumberFun(item)" readonly :value="getSerialincNumber(item)" placeholder="请输入内容" />
             <el-input v-if="item.type === 'widget'" readonly :value="item.widgetName" placeholder="请输入内容" />
@@ -124,6 +124,7 @@ import comMixin from './mixin'
 import draggable from 'vuedraggable'
 import moment from 'moment'
 import {getResetSerialnumber} from "@/api/onlineDev/visualDev";
+import {deepClone} from "@/utils";
 let presetList = [
   { label: '2024', value: 'yyyy' },
   { label: '202401', value: 'yyyyMM' },
@@ -219,7 +220,10 @@ export default {
     },
     handleCommand(command) {
       if (command === 'widget') return
-      let item = this.serialRules.find((o) => o.type === command)
+      let item = deepClone(this.serialRules.find((o) => o.type === command))
+      if (item.type === 'fixedChars') {
+        item.id = +new Date()
+      }
       this.activeData.serialgz.push(item)
     },
     widgethandleCommand(command) {

+ 21 - 8
src/components/Generator/index/RightPanel.vue

@@ -37,18 +37,31 @@
                   <el-select v-model="activeData.__vModel__" placeholder="请选择控件字段(v-model)" clearable @change="fieldChange" filterable>
                     <!--                    <el-option-group v-for="group in formItemList" :key="group.id"-->
                     <!--                                     :label="group.tableName">-->
+                    <template v-if="activeData.__config__.isSubTable">
+                      <el-option
+                                 v-for="item in getSubTalebFiled(activeData.__config__.relationTable)"
+                                 :key="item.id"
+                                 :value="item.id"
+                                 :disabled="getChildrenDisabledSelect(activeData.__config__.relationTable, item.id)"
+                                 :label="item.columnTitle ? item.columnTitle + ' ' + item.columnName : item.columnComment + ' ' + item.columnName"
+                      >
+                      </el-option>
+                    </template>
+                    <template v-else>
+                      <el-option
+                        v-for="item in formItemList"
+                        :key="item.id"
+                        :value="item.id"
+                        :disabled="getDisabledStrSelect(item.id, item)"
+                        :label="item.columnTitle ? item.columnTitle + ' ' + item.columnName : item.columnComment + ' ' + item.columnName"
+                      >
+                      </el-option>
+                    </template>
 
-                    <el-option
-                      v-for="item in formItemList"
-                      :key="item.id"
-                      :value="item.id"
-                      :disabled="getDisabledStrSelect(item.id, item)"
-                      :label="item.columnTitle ? item.columnTitle + ' ' + item.columnName : item.columnComment + ' ' + item.columnName"
-                    >
-                    </el-option>
                     <!--                    </el-option-group>-->
                   </el-select>
                 </el-form-item>
+
               </template>
               <template v-else>
                 <template v-if="!activeData.__config__.isSubTable">

+ 1 - 1
src/components/Generator/parser/Parser.vue

@@ -515,7 +515,7 @@ function getConfigDefVal(h, item) {
   } else {
     return formConfCopy.fields
       .map((i, k) => {
-        if (i.__vModelName__ === item && (i.__config__.defaultValue || i.__config__.defaultValue === 0)) return i.__config__.defaultValue
+        if (i.__vModelName__ === item) return i.__config__.defaultValue || 0
       })
       .filter((l) => l !== undefined)
   }

+ 71 - 67
src/main.js

@@ -1,106 +1,110 @@
-import Vue from 'vue'
-import 'xe-utils'
-import VXETable from 'vxe-table'
+import Vue from "vue";
+import "xe-utils";
+import VXETable from "vxe-table";
 VXETable.config({
-  'column-config': {
+  "column-config": {
     resizable: true
   }
-})
-import 'vxe-table/lib/style.css'
-Vue.use(VXETable)
-import VXETablePluginElement from 'vxe-table-plugin-element'
-import 'vxe-table-plugin-element/dist/style.css'
-VXETable.use(VXETablePluginElement)
-const jnpf = require('./utils/jnpf').default
+});
+import "vxe-table/lib/style.css";
+Vue.use(VXETable);
+import VXETablePluginElement from "vxe-table-plugin-element";
+import "vxe-table-plugin-element/dist/style.css";
+VXETable.use(VXETablePluginElement);
+const jnpf = require("./utils/jnpf").default;
 
-import 'normalize.css/normalize.css' // a modern alternative to CSS resets
+import "normalize.css/normalize.css"; // a modern alternative to CSS resets
 
-import Element from 'element-ui'
-import 'element-ui/lib/theme-chalk/index.css'
-import './styles/element-variables.scss'
-import './assets/scss/common.scss'
+import Element from "element-ui";
+import "element-ui/lib/theme-chalk/index.css";
+import "./styles/element-variables.scss";
+import "./assets/scss/common.scss";
 
-import '@/styles/index.scss' // global css
-import './assets/scss/theme.scss' // 主题
+import "@/styles/index.scss"; // global css
+import "./assets/scss/theme.scss"; // 主题
 
-import VueAwesomeSwiper from 'vue-awesome-swiper'
-import 'swiper/css/swiper.css'
-Vue.use(VueAwesomeSwiper)
+import VueAwesomeSwiper from "vue-awesome-swiper";
+import "swiper/css/swiper.css";
+Vue.use(VueAwesomeSwiper);
 
-import App from './App'
-import store from './store'
-import router from './router'
+import App from "./App";
+import store from "./store";
+import router from "./router";
 
-import i18n from './lang' // internationalization
-import './permission' // permission control
+import i18n from "./lang"; // internationalization
+import "./permission"; // permission control
 // import './utils/error-log' // error log
-import { message } from './utils/message'
+import { message } from "./utils/message";
 
-import * as filters from './filters' // global filters
+import * as filters from "./filters"; // global filters
 
 // 自定义按钮权限指令
-import permission from '@/directive/permission'
-Vue.use(permission)
+import permission from "@/directive/permission";
+Vue.use(permission);
 
 Vue.use(Element, {
-  size: jnpf.storageGet('size') || 'small', // set element-ui default size
+  size: jnpf.storageGet("size") || "small", // set element-ui default size
   i18n: (key, value) => i18n.t(key, value)
-})
+});
 // 批量引入组件
-import components from './components'
-Vue.use(components)
+import components from "./components";
+Vue.use(components);
 
 // 添加实例属性
 Object.assign(Vue.prototype, {
-  define: require('./utils/define'), // 常量
+  define: require("./utils/define"), // 常量
   jnpf, // 公共方法
-  formValidate: require('./utils/formValidate').default, // 表单验证
+  formValidate: require("./utils/formValidate").default, // 表单验证
   $message: message
-})
+});
 
 // 全局注册过滤器
 Object.keys(filters).forEach((key) => {
-  Vue.filter(key, filters[key])
-})
+  Vue.filter(key, filters[key]);
+});
 
-Vue.config.productionTip = false
+Vue.config.productionTip = false;
 
 // 按需引入需要的语言包皮肤等资源
-require('brace/ext/emmet') // 如果是lang=html时需引入
-require('brace/ext/language_tools') // language extension
+require("brace/ext/emmet"); // 如果是lang=html时需引入
+require("brace/ext/language_tools"); // language extension
 
-require('brace/mode/sql')
-require('brace/snippets/sql')
-require('brace/mode/java')
-require('brace/snippets/java')
-require('brace/mode/javascript')
-require('brace/snippets/javascript')
-require('brace/theme/monokai')
-require('brace/theme/solarized_dark')
-require('brace/theme/chrome')
+require("brace/mode/sql");
+require("brace/snippets/sql");
+require("brace/mode/java");
+require("brace/snippets/java");
+require("brace/mode/javascript");
+require("brace/snippets/javascript");
+require("brace/theme/monokai");
+require("brace/theme/solarized_dark");
+require("brace/theme/chrome");
 // 注册组件后即可使用
-import Editor from 'bin-ace-editor'
-Vue.component(Editor.name, Editor)
-import { throttle } from 'lodash';
+import Editor from "bin-ace-editor";
+Vue.component(Editor.name, Editor);
+import { throttle } from "lodash";
 // 避免高频率调用 使用节流throttle
-Vue.prototype.apiVariableSetItem = throttle(function (key, value) {
-  if (key === 'API_VARIABLE_CHANGE') {
-    let newStorageEvent = document.createEvent('StorageEvent')
+Vue.prototype.apiVariableSetItem = throttle(function(key, value) {
+  if (key === "API_VARIABLE_CHANGE") {
+    let newStorageEvent = document.createEvent("StorageEvent");
     const storage = {
-      setItem: function (k, val) {
-        sessionStorage.setItem(k, val)
-        newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null)
-        window.dispatchEvent(newStorageEvent)
+      setItem: function(k, val) {
+        sessionStorage.setItem(k, val);
+        newStorageEvent.initStorageEvent("setItem", false, false, k, null, val, null, null);
+        window.dispatchEvent(newStorageEvent);
       }
-    }
-    return storage.setItem(key, value)
+    };
+    return storage.setItem(key, value);
   }
-},340)
+}, 340);
+window.logjson = function(val) {
+  if (typeof val === "object") console.log(JSON.parse(JSON.stringify(val)));
+  else console.log(val);
+};
 const vm = new Vue({
-  el: '#app',
+  el: "#app",
   router,
   store,
   i18n,
   render: (h) => h(App)
-})
-export default vm
+});
+export default vm;

+ 22 - 5
src/mixins/generator/form.js

@@ -369,12 +369,29 @@ export default {
           formMethod(param)
             .then((res) => {
               //查询当前表单是否存在流水号控件
-             let allFormItem =  loopRelationList(this.formData.fields)
+              let allFormItem =  loopRelationList(this.formData.fields)
+              // 查询子表是否存在流水号控件
+              let foreignFields = this.formData.fields.filter((o) => o.__config__ && o.__config__.jnpfKey === 'table')
+              const foreignList = foreignFields.reduce((list, field) => {
+                const foreignSerialRow = field.__config__ && field.__config__.children.find(o => o.__config__.jnpfKey === 'serialNumber');
+                if (foreignSerialRow) {
+                  const incNumberRow = foreignSerialRow.serialgz.find(o => o.type === 'incNumber');
+                  if (incNumberRow) {
+                    list.push({ cubeId: field.dbLinkId, resetCycle: incNumberRow.resetCycle, startValue: incNumberRow.startValue });
+                  }
+                }
+                return list;
+              }, []);
               let serialRow = allFormItem.find((o) => o.__config__.jnpfKey === 'serialNumber')
-              if (serialRow) {
-                let incNumberRow = serialRow.serialgz.find((o) => o.type === 'incNumber')
-                let obj = { modelId: this.dataForm.id, resetCycle: incNumberRow.resetCycle, startValue: incNumberRow.startValue }
-                this.CreateSerial(obj, res.data.msg)
+              if (serialRow || foreignList.length) {
+                if (serialRow){
+                  let incNumberRow = serialRow.serialgz.find((o) => o.type === 'incNumber')
+                  let obj = { modelId: this.dataForm.id, resetCycle: incNumberRow.resetCycle, startValue: incNumberRow.startValue,foreignList }
+                  this.CreateSerial(obj, res.data.msg)
+                }else {
+                  let obj = { foreignList }
+                  this.CreateSerial(obj, res.data.msg)
+                }
               } else {
                 const locat = XEUtils.locat()
                 locat.hashQuery.id = this.dataForm.id

+ 24 - 1
src/utils/index.js

@@ -387,7 +387,30 @@ export function numberChinese(ele) {
     .replace(/亿零{0,3}万/, '亿')
     .replace(/^元/, '零元')
 }
-
+export function loopSerialNumberList(fields) {
+  const list = []
+  const loop = (data, parent) => {
+    if (!data) return
+    if (data.__config__ && data.__config__.jnpfKey === 'tab' && data.__config__.children && Array.isArray(data.__config__.children)) {
+      loop(data.__config__.children, data.__config__.jnpfKey)
+    }
+    if (Array.isArray(data) && data.length) {
+      for (let i = 0; i < data.length; i++) {
+        loop(data[i], parent)
+      }
+    }
+    if (Object.prototype.toString.call(data) === '[object Object]' && parent === 'tab' && data.__config__.children && data.__config__.children.length) {
+      loop(data.__config__.children, parent)
+    }
+    if (data.__config__ && data.__config__.jnpfKey) {
+      if (data.__config__.layout === 'colFormItem') {
+        list.push(data)
+      }
+    }
+  }
+  loop(fields)
+  return list
+}
 export function loopRelationList(fields) {
   const list = []
   const loop = (data, parent) => {

+ 1 - 1
src/utils/jnpf.js

@@ -216,7 +216,7 @@ const jnpf = {
     function cacheItem(key, val) {
       key = STORAGEPREFIX + key
       let valType = typeof val
-      if (val !== null) {
+      if (val !== null&&val !== undefined) {
         var valConstructor = val.constructor
       }
       if (valType === 'string' || valType === 'number' || valType === 'boolean') {

+ 8 - 2
src/views/basic/dynamicModel/list/Form.vue

@@ -444,7 +444,7 @@ export default {
               if (val) item.__config__.defaultValue = val
               // 特殊情况 时间戳unix时间可能为秒 为10位数字 且存储字段类型不是DATE类型 可能是bigint或者lang
               if (item.__config__ && item.__config__.jnpfKey === 'date' && item.__config__.viewDataType !== 'DATETIME') {
-                if(val && g.getLen(String(val)) === 10) {
+                if(val && g.getLen(String(val)) === 10 && Number.isFinite(val)) {
                   try {
                     item.__config__.defaultValue = val * 1000
                   }catch (e) {}
@@ -570,6 +570,12 @@ export default {
       let allFields = loopRelationTabelList(this.formData.fields)
       const result = []
       for (const key in foreignObj) {
+        let foreignTable = this.formData.fields.find(i=> i.__vModel__ == key && i.__config__ &&  i.__config__.jnpfKey === 'table')
+        let serialincData = {}
+        if (foreignTable) {
+          // 子表获取流水号信息
+          serialincData = this.getSerialincNumberData(foreignTable.__config__.children,foreignObj[key])
+        }
         foreignObj[key].forEach((item) => {
           allFields.forEach((i,z)=>{
             if (i.__config__.jnpfKey === 'uploadImg' && item[i.__vModel__] && item[i.__vModel__].length){
@@ -579,7 +585,7 @@ export default {
               item[i.__vModel__] = item[i.__vModel__].map(q => (q > 0 ? q : q.id)).filter(Boolean).join(';');
             }
           })
-          result.push({ dbLink: key, id: '', oldData: null, data: JSON.stringify(item) })
+          result.push({ dbLink: key, id: '', oldData: null, data: JSON.stringify(item),...serialincData })
         })
       }
       return result

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1669 - 1552
src/views/basic/dynamicModel/list/index.vue


+ 1 - 1
src/views/extend/projectGantt/Task.vue

@@ -67,7 +67,7 @@
 
 <script>
 import dayjs from 'dayjs' // 导入日期js
-const uuidv4 = require('uuid/v4') // 导入uuid生成插件
+const uuidv4 = require('uuid/dist/cjs/v4') // 导入uuid生成插件
 import isBetween from 'dayjs/plugin/isBetween'
 dayjs.extend(isBetween)
 import { TaskList, Delete } from '@/api/extend/projectGantt'

+ 231 - 155
src/views/form/webDesign/CustomButton.vue

@@ -12,23 +12,28 @@
           <vxe-column field="label" title="按钮名称"></vxe-column>
           <vxe-column field="type" title="按钮类型"></vxe-column>
           <vxe-column field="buttonStatus" title="按钮状态">
-            <template #default> 启用 </template>
+            <template #default> 启用</template>
           </vxe-column>
           <vxe-column title="操作" align="left" width="250">
             <template #default="{ row }">
-              <el-button size="small" type="success" plain @click="selectEvent(row)"> {{ row.eventNum > 0 ? `(${row.eventNum})` : '' }}设置事件 </el-button>
+              <el-button size="small" type="success" plain @click="selectEvent(row)">
+                {{ row.eventNum > 0 ? `(${row.eventNum})` : "" }}设置事件
+              </el-button>
             </template>
           </vxe-column>
         </vxe-table>
-        <vxe-table align="center" border :show-header="false" :data="customTableData.filter((o) => o.buttonLocation === 1)" empty-text="请点击新增自定义按钮">
+        <vxe-table align="center" border :show-header="false"
+                   :data="customTableData.filter((o) => o.buttonLocation === 1)" empty-text="请点击新增自定义按钮">
           <vxe-column field="label" title="按钮名称"></vxe-column>
           <vxe-column field="type" title="按钮类型"></vxe-column>
           <vxe-column field="buttonStatus" title="按钮状态">
-            <template #default> 启用 </template>
+            <template #default> 启用</template>
           </vxe-column>
           <vxe-column title="操作" align="left" width="250">
             <template #default="{ row }">
-              <el-button size="mini" type="success" plain @click="selectEvent(row)">{{ row.eventNum > 0 ? `(${row.eventNum})` : '' }}设置事件</el-button>
+              <el-button size="mini" type="success" plain @click="selectEvent(row)">
+                {{ row.eventNum > 0 ? `(${row.eventNum})` : "" }}设置事件
+              </el-button>
               <el-button size="mini" type="primary" plain @click="editEvent(row)">编辑</el-button>
               <el-button size="mini" type="danger" plain @click="removeEvent(row)">删除</el-button>
             </template>
@@ -41,15 +46,19 @@
           <vxe-column field="label" title="按钮名称"></vxe-column>
           <vxe-column field="type" title="按钮类型"></vxe-column>
           <vxe-column field="buttonStatus" title="按钮状态">
-            <template #default> 启用 </template>
+            <template #default> 启用</template>
           </vxe-column>
           <vxe-column title="操作" align="left" width="250">
             <template #default="{ row }">
-              <el-button size="small" type="success" plain @click="selectEvent(row)"> {{ row.eventNum > 0 ? `(${row.eventNum})` : '' }}设置事件 </el-button>
+              <el-button size="small" type="success" plain @click="selectEvent(row)">
+                {{ row.eventNum > 0 ? `(${row.eventNum})` : "" }}设置事件
+              </el-button>
+              <el-button size="mini" type="primary" plain @click="onSystemEdit(row)">设置显隐条件</el-button>
             </template>
           </vxe-column>
         </vxe-table>
-        <vxe-table align="center" border :show-header="false" :data="customTableData.filter((o) => o.buttonLocation === 2)" empty-text="请点击新增自定义按钮">
+        <vxe-table align="center" border :show-header="false"
+                   :data="customTableData.filter((o) => o.buttonLocation === 2)" empty-text="请点击新增自定义按钮">
           <vxe-column field="label" title="按钮名称"></vxe-column>
           <vxe-column field="type" title="按钮类型"></vxe-column>
           <vxe-column field="buttonStatus" title="按钮状态">
@@ -68,7 +77,9 @@
           </vxe-column>
           <vxe-column title="操作" align="left" width="250">
             <template #default="{ row }">
-              <el-button size="mini" type="success" v-if="row.execType === 2" plain @click="selectEvent(row)">{{ row.eventNum > 0 ? `(${row.eventNum})` : '' }}设置事件</el-button>
+              <el-button size="mini" type="success" v-if="row.execType === 2" plain @click="selectEvent(row)">
+                {{ row.eventNum > 0 ? `(${row.eventNum})` : "" }}设置事件
+              </el-button>
               <el-button size="mini" type="primary" plain @click="editEvent(row)">编辑</el-button>
               <el-button size="mini" type="danger" plain @click="removeEvent(row)">删除</el-button>
             </template>
@@ -94,7 +105,10 @@
           例句:SELECT id from {表名} where {约束条件} and id IN([ids])
         </el-form-item>
         <el-form-item label="按钮样式">
-          <div class="flex gap-10">颜色{{ showFrom.color }}<el-color-picker v-model="showFrom.buttonInfo.color" show-alpha :predefine="predefineColors"></el-color-picker></div>
+          <div class="flex gap-10">颜色{{ showFrom.color }}
+            <el-color-picker v-model="showFrom.buttonInfo.color" show-alpha
+                             :predefine="predefineColors"></el-color-picker>
+          </div>
         </el-form-item>
         <el-form-item label="触发事件">
           <el-radio-group v-model="showFrom.execType">
@@ -107,7 +121,8 @@
             <el-radio-group v-model="showFrom.isWindow">
               <el-radio :label="0" :value="0">
                 弹窗提示
-                <el-tooltip style="cursor: pointer" effect="dark" :content="'选择弹窗提示时,如未填写弹窗提示语则无法触发弹窗'" placement="top">
+                <el-tooltip style="cursor: pointer" effect="dark"
+                            :content="'选择弹窗提示时,如未填写弹窗提示语则无法触发弹窗'" placement="top">
                   <i class="el-icon-question" />
                 </el-tooltip>
               </el-radio>
@@ -119,22 +134,22 @@
           </el-form-item>
           <el-form-item label="弹窗字段" v-if="showFrom.isWindow === 1">
             <el-table :data="windowViewColumns.value" height="250">
-              <el-table-column label="字段" >
+              <el-table-column label="字段">
                 <template slot-scope="scope">
-                  <span>{{scope.row.label}}</span>
+                  <span>{{ scope.row.label }}</span>
                 </template>
               </el-table-column>
-              <el-table-column label="可见" >
+              <el-table-column label="可见">
                 <template slot-scope="scope">
                   <el-checkbox v-model="scope.row.isShow"></el-checkbox>
                 </template>
               </el-table-column>
-              <el-table-column label="读写" >
+              <el-table-column label="读写">
                 <template slot-scope="scope">
                   <el-checkbox v-model="scope.row.isChange"></el-checkbox>
                 </template>
               </el-table-column>
-              <el-table-column label="必填" >
+              <el-table-column label="必填">
                 <template slot-scope="scope">
                   <el-checkbox v-model="scope.row.isRequired"></el-checkbox>
                 </template>
@@ -144,12 +159,17 @@
         </template>
 
         <el-form-item label="选择事件" v-if="showFrom.execType === 2">
-          <custom-event ref="customevent" :is-compont="true" :dbSourceId="dataForm.dbSourceId" :model-id="columnData.modelId" :cube-id="dataForm.dbLinkId" @select="selectEventList" />
+          <custom-event ref="customevent" :is-compont="true" :dbSourceId="dataForm.dbSourceId"
+                        :model-id="columnData.modelId" :cube-id="dataForm.dbLinkId" :allTabelData="allTabelData"
+                        @select="selectEventList" />
         </el-form-item>
         <el-form-item label="链接地址" v-if="showFrom.execType === 1">
           <el-input v-model="showFrom.redirectUrl" placeholder="请输入链接地址"></el-input>
-          可用变量<template v-for="item in cubeList">
-            {{ item.label }}:<el-button type="text">{{ item.value }} </el-button></template
+          可用变量
+          <template v-for="item in cubeList">
+            {{ item.label }}:
+            <el-button type="text">{{ item.value }}</el-button>
+          </template
           >
         </el-form-item>
       </el-form>
@@ -158,8 +178,34 @@
         <el-button type="primary" @click="saveEvent">保存</el-button>
       </template>
     </vxe-modal>
+    <vxe-modal v-model="showSystemEdit" title="编辑系统按钮" width="60%" height="500px" :position="{ top: 60 }"
+               show-footer>
+      <el-form label-width="120px" size="small">
+        <el-form-item label="按钮名称">
+          <el-input disabled v-model="showFrom.buttonName" placeholder="请输入按钮名称"></el-input>
+        </el-form-item>
+        <el-form-item label="展示位置">
+          <el-radio-group disabled v-model="showFrom.buttonLocation">
+            <el-radio :label="1" :value="1">表头位置</el-radio>
+            <el-radio :label="2" :value="2">行数据操作位置</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="展示条件">
+          <amis-sdk :amis-json="amisJson" v-model="showFrom.buttonCondition" />
+          <!--          <el-input type="textarea" :rows="2" placeholder="请输入内容" v-model="showFrom.buttonCondition"> </el-input>-->
+          注:条件sql返回列必须存在主键列,并且where条件必须有主键列约束<br />
+          例句:SELECT id from {表名} where {约束条件} and id IN([ids])
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="showSystemEdit = false">取消</el-button>
+        <el-button type="primary" @click="onSystemEditConfirm">保存</el-button>
+      </template>
+    </vxe-modal>
     <vxe-modal v-model="isEvent" title="选择事件" width="60%" :position="{ top: 60 }" show-footer>
-      <custom-event ref="customevent" :is-compont="true" :dbSourceId="dataForm.dbSourceId" :model-id="columnData.modelId" :cube-id="dataForm.dbLinkId" @select="selectEventList" />
+      <custom-event ref="customevent" :is-compont="true" :dbSourceId="dataForm.dbSourceId"
+                    :model-id="columnData.modelId" :cube-id="dataForm.dbLinkId" :allTabelData="allTabelData"
+                    @select="selectEventList" />
       <template #footer>
         <el-button type="primary" @click="saveEvent">保存</el-button>
       </template>
@@ -167,32 +213,41 @@
   </div>
 </template>
 <script setup>
-import { onMounted, ref, watch, computed } from 'vue'
-import { addCustomButton, deleteCustomButton, getCustomButton } from '@/api/onlineDev/visualDev'
-import { Loading, Message } from 'element-ui'
-import { predefineColors } from '@/utils/useUtil'
-import CustomEvent from '@/views/form/webDesign/CustomEvent.vue'
-import AmisSdk from '@/components/AmisSdk.vue'
-import {getDrawingList} from "@/components/Generator/utils/db";
-import {loopRelationList} from "@/utils";
+import { computed, ref } from "vue";
+import { addCustomButton, deleteCustomButton, getCustomButton } from "@/api/onlineDev/visualDev";
+import { Loading, Message } from "element-ui";
+import { predefineColors } from "@/utils/useUtil";
+import CustomEvent from "@/views/form/webDesign/CustomEvent.vue";
+import AmisSdk from "@/components/AmisSdk.vue";
+import { getDrawingList } from "@/components/Generator/utils/db";
+import { loopRelationList } from "@/utils";
 
 const props = defineProps({
   columnData: Object,
   dataForm: Object,
   systemBtn: [],
   actionBtn: [],
+  allTabelData: [],
   activeName: String
-})
-const modelId = props?.columnData?.modelId || 0
+});
+const modelId = props?.columnData?.modelId || 0;
 
 const amisJson = ref({
-  type: 'editor',
-  language: 'sql'
-})
+  type: "editor",
+  language: "sql"
+});
 
-const customTableData = ref([])
+const customTableData = ref([]);
 
-const drawList = loopRelationList(getDrawingList()).map(i =>{ return {label:i.__config__.label,id:i.__vModel__,isShow:false,isChange:false,isRequired:i.__config__.required}})
+const drawList = loopRelationList(getDrawingList()).map(i => {
+  return {
+    label: i.__config__.label,
+    id: i.__vModel__,
+    isShow: false,
+    isChange: false,
+    isRequired: i.__config__.required
+  };
+});
 // watch([() => props.activeName], () => {
 //   init()
 // })
@@ -201,196 +256,217 @@ const cubeList = computed(() => {
   return props.columnData.cubeList.map((item) => {
     return {
       label: item.columnTitle,
-      value: '{{ ' + item.columnName + ' }}'
-    }
-  })
-})
+      value: "{{ " + item.columnName + " }}"
+    };
+  });
+});
 
-const systemBtn = ref([])
-const actionBtn = ref([])
+const systemBtn = ref([]);
+const actionBtn = ref([]);
 const init = async () => {
-  const loading = Loading.service({ text: '加载中' })
-  const { data } = await getCustomButton(modelId)
-  loading.close()
-  const { records } = data.data
+  const loading = Loading.service({ text: "加载中" });
+  const { data } = await getCustomButton(modelId);
+  loading.close();
+  const { records } = data.data;
   customTableData.value = records
     .filter((v) => v.buttonType === 1)
     .map((item) => {
-      item.buttonInfo = item.buttonInfo ? JSON.parse(item.buttonInfo || {}) : {}
-      item.label = item.buttonName
-      item.type = item.buttonType === 1 ? '自定义按钮' : '系统按钮'
-      return item
-    })
+      item.buttonInfo = item.buttonInfo ? JSON.parse(item.buttonInfo || {}) : {};
+      item.label = item.buttonName;
+      item.type = item.buttonType === 1 ? "自定义按钮" : "系统按钮";
+      return item;
+    });
 
-  const systemBtns = records.filter((v) => v.buttonType === 2)
+  const systemBtns = records.filter((v) => v.buttonType === 2);
   systemBtn.value = props.systemBtn.map((item) => {
-    const find = systemBtns.find((v) => v.buttonName === item.label)
-    item.buttonName = item.label
+    const find = systemBtns.find((v) => v.buttonName === item.label);
+    item.buttonName = item.label;
     item.buttonInfo = {
-      color: '#409EFF'
-    }
-    item.buttonLocation = 1
-    item.buttonType = 2
-    item.buttonStatus = 0
-    item.type = '系统按钮'
-    item.formId = modelId
-    item.eventList = find?.eventList || []
-    item.id = find ? find.id : 0
-    item.execType = 2
-    item.eventNum = find?.eventNum || 0
-    return item
-  })
+      color: "#409EFF"
+    };
+    item.buttonLocation = 1;
+    item.buttonType = 2;
+    item.buttonStatus = 0;
+    item.type = "系统按钮";
+    item.formId = modelId;
+    item.eventList = find?.eventList || [];
+    item.id = find ? find.id : 0;
+    item.execType = 2;
+    item.eventNum = find?.eventNum || 0;
+    return item;
+  });
   actionBtn.value = props.actionBtn.map((item) => {
-    const find = systemBtns.find((v) => v.buttonName === item.label)
-    item.buttonName = item.label
+    const find = systemBtns.find((v) => v.buttonName === item.label);
+    item.buttonName = item.label;
     item.buttonInfo = {
-      color: '#409EFF'
-    }
-    item.buttonLocation = 2
-    item.buttonType = 2
-    item.buttonStatus = 0
-    item.type = '系统按钮'
-    item.formId = modelId
-    item.eventList = find?.eventList || []
-    item.eventNum = find?.eventNum || 0
-    item.id = find ? find.id : 0
-    item.execType = 2
-    return item
-  })
-}
-init()
-const customevent = ref()
-const isShow = ref(false)
+      color: "#409EFF"
+    };
+    item.buttonLocation = 2;
+    item.buttonType = 2;
+    item.buttonStatus = 0;
+    item.type = "系统按钮";
+    item.formId = modelId;
+    item.eventList = find?.eventList || [];
+    item.eventNum = find?.eventNum || 0;
+    item.id = find ? find.id : 0;
+    item.execType = 2;
+    item.buttonCondition = find?.buttonCondition || null;
+    return item;
+  });
+};
+init();
+const customevent = ref();
+const isShow = ref(false);
 
 const defaultForm = {
-  buttonCondition: '',
+  buttonCondition: "",
   buttonLocation: 2,
   buttonInfo: {
     // 事件类型 1-按钮 2-链接
     buttonType: 1,
     // 颜色
-    color: '#409EFF'
+    color: "#409EFF"
   },
-  buttonName: '',
+  buttonName: "",
   execType: 2,
   isWindow: 0,
-  windowTips: '',
+  windowTips: "",
   buttonStatus: 0,
   buttonType: 1,
   eventList: [],
   formId: modelId,
   id: 0,
-  redirectUrl: 'http://'
-}
-const windowViewColumns = drawList || []
-const showFrom = ref({ ...defaultForm })
+  redirectUrl: "http://"
+};
+const windowViewColumns = drawList || [];
+const showFrom = ref({ ...defaultForm });
 
 // 新增按钮
 const addEvent = () => {
-  showFrom.value = { ...defaultForm }
-  isShow.value = true
-  windowViewColumns.value = drawList || []
-}
+  showFrom.value = { ...defaultForm };
+  isShow.value = true;
+  windowViewColumns.value = drawList || [];
+};
 
 const editEvent = (row) => {
-  showFrom.value = row
-  isShow.value = true
-  windowViewColumns.value = row.windowViewColumns
+  showFrom.value = row;
+  isShow.value = true;
+  windowViewColumns.value = row.windowViewColumns;
   const list = row.eventList.map((item) => {
-    const data = {
+    return {
       id: item.eventId
-    }
-    return data
-  })
+    };
+  });
   setTimeout(() => {
-    customevent.value.multipass(list)
-  }, 100)
+    customevent.value.multipass(list);
+  }, 100);
   if (showFrom.value.isWindow === 1 && !windowViewColumns.value) {
-    windowViewColumns.value = drawList || []
-  }else {
-   if (row.windowViewColumns){
-     try {
-       windowViewColumns.value = JSON.parse(row.windowViewColumns)
-     }catch (e) {
-       windowViewColumns.value = row.windowViewColumns
-     }
-   }
+    windowViewColumns.value = drawList || [];
+  } else {
+    if (row.windowViewColumns) {
+      try {
+        windowViewColumns.value = JSON.parse(row.windowViewColumns);
+      } catch (e) {
+        windowViewColumns.value = row.windowViewColumns;
+      }
+    }
   }
-}
+};
 
 // 保存按钮
 const saveEvent = () => {
   if (!showFrom.value.buttonName) {
-    Message.error('请输入按钮名称')
-    return
+    Message.error("请输入按钮名称");
+    return;
   }
   if (showFrom.value.execType === 2 && showFrom.value.buttonType === 1 && !showFrom.value.eventList.length) {
-    Message.error('请选择事件')
-    return
+    Message.error("请选择事件");
+    return;
   }
-  if (showFrom.value.execType === 1 && showFrom.value.redirectUrl === 'http://') {
-    Message.error('请输入链接地址')
-    return
+  if (showFrom.value.execType === 1 && showFrom.value.redirectUrl === "http://") {
+    Message.error("请输入链接地址");
+    return;
   }
-  showFrom.value.buttonInfo = JSON.stringify(showFrom.value.buttonInfo)
+  showFrom.value.buttonInfo = JSON.stringify(showFrom.value.buttonInfo);
   try {
-    showFrom.value.windowViewColumns = JSON.stringify(windowViewColumns.value)
-  }catch (e) {}
+    showFrom.value.windowViewColumns = JSON.stringify(windowViewColumns.value);
+  } catch (e) {
+  }
   addCustomButton(modelId, showFrom.value).then((res) => {
     if (res.data.code === 200) {
-      Message.success('操作成功')
-      isShow.value = false
-      isEvent.value = false
-      init()
+      Message.success("操作成功");
+      isShow.value = false;
+      isEvent.value = false;
+      init();
     } else {
-      Message.error('新增失败' + res.data.msg)
+      Message.error("新增失败" + res.data.msg);
     }
-  })
-}
+  });
+};
 
 const removeEvent = (row) => {
-  customTableData.value = customTableData.value.filter((item) => item !== row)
+  customTableData.value = customTableData.value.filter((item) => item !== row);
   deleteCustomButton(modelId, row.id).then((res) => {
     if (res.data.code === 200) {
-      Message.success('删除成功')
+      Message.success("删除成功");
     }
-  })
-}
+  });
+};
 
 // 禁用按钮
 const disableEvent = (row) => {
-  row.buttonInfo = JSON.stringify(row.buttonInfo)
+  row.buttonInfo = JSON.stringify(row.buttonInfo);
   addCustomButton(modelId, row).then((res) => {
     if (res.data.code === 200) {
-      Message.success('操作成功')
+      Message.success("操作成功");
     }
-  })
-}
+  });
+};
 
-const isEvent = ref(false)
+const isEvent = ref(false);
 const selectEvent = (row) => {
-  showFrom.value = row
-  isEvent.value = true
+  showFrom.value = row;
+  isEvent.value = true;
   const list = row.eventList.map((item) => {
-    const data = {
+    return {
       id: item.eventId
-    }
-    return data
-  })
+    };
+  });
   setTimeout(() => {
-    customevent.value.multipass(list)
-  }, 100)
-}
+    customevent.value.multipass(list);
+  }, 100);
+};
 const selectEventModel = (row) => {
-  isEvent.value = true
-}
+  isEvent.value = true;
+};
 const selectEventList = (row) => {
   showFrom.value.eventList = row.map((item, index) => {
     return {
       eventId: item.id,
       eventSort: index
+    };
+  });
+};
+
+// 系统按钮添加显示条件
+const showSystemEdit = ref(false);
+const onSystemEdit = (row) => {
+  logjson(row);
+  showFrom.value = row;
+  showSystemEdit.value = true;
+};
+const onSystemEditConfirm = () => {
+  showFrom.value.buttonInfo = JSON.stringify(showFrom.value.buttonInfo);
+  addCustomButton(modelId, showFrom.value).then((res) => {
+    if (res.data.code === 200) {
+      Message.success("操作成功");
+      showSystemEdit.value = false;
+      init();
+    } else {
+      Message.error("新增失败" + res.data.msg);
     }
-  })
-}
+  });
+};
+
 </script>
 <style scoped lang="scss"></style>

+ 1 - 1
src/views/form/webDesign/Form.vue

@@ -177,7 +177,7 @@
               ></datasetFilter>
             </el-tab-pane>
             <el-tab-pane label="自定义按钮" name="customBtn">
-              <custom-button v-if="activeName === 'customBtn'" :columnData="columnData" :dataForm="dataForm" :systemBtn="systemBtns" :actionBtn="actionBtns" :activeName="activeName"></custom-button>
+              <custom-button v-if="activeName === 'customBtn'" :columnData="columnData" :dataForm="dataForm" :systemBtn="systemBtns" :actionBtn="actionBtns" :activeName="activeName" :allTabelData="allTabelList"></custom-button>
             </el-tab-pane>
             <el-tab-pane label="自定义事件" name="customClick">
               <CustomEvent v-if="activeName === 'customClick'" :modelId="columnData.modelId" :dbSourceId="dataForm.dbSourceId" :cubeId="dataForm.dbLinkId" :activeName="activeName" :allTabelData="allTabelList"/>

+ 6 - 5
src/views/form/webDesign/customFormEvent.vue

@@ -8,11 +8,12 @@
     width="700px">
     <p slot="title">
       {{ id ? '编辑自定义赋值模式事件' : '新增自定义赋值模式事件' }}
+      <span style="color:#ff0000;font-size:12px;">注:表单赋值当前仅支持更新数据</span>
     </p>
     <div >
       <div style="margin-bottom:5px;">
         事件名称:<el-input style="width:300px" v-model="eventName" placeholder="请输入事件名称"></el-input>
-        <el-button style="float:right;" type="success" plain size="mini" @click="list.length < 3 && list.push({formName:'',dataTable:'',FormColumnList:[{columnName:'',value:''}],columnList:[]});">+添加分组</el-button>
+        <el-button style="float:right;" type="success" plain size="mini" @click="list.length < 3 && list.push({formName:'',dataTable:'',FormColumnList:[{columnName:'',value:''}],columnList:[],filterColumnList:[{columnId:'',viewDataType:'STRING',function:'like',value:''}]});">+添加分组</el-button>
       </div>
       <div style="height: 500px;overflow-y:auto">
         <el-card class="box-card" v-for="(value,key) in list" style="margin-bottom: 10px" :key="key">
@@ -22,7 +23,7 @@
               <el-option v-for="(item, index) in allTabelList.filter(o=> (o.associationType && o.associationType == 1) && (o.visualdevTableType && o.visualdevTableType == 1))" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
             </el-select>
             <span style="margin-left:10px">物理数据表:{{value.dataTable}}</span>
-            <i class="el-icon-delete" style="font-size:20px;color:#13ce66;float: right;cursor: pointer;" @click="list.splice(key,1)"></i>
+            <i class="el-icon-delete" style="font-size:20px;color:#13ce66;float: right;cursor: pointer;" @click="list.length > 1 ? list.splice(key,1) : $message.warning('至少保留一个分组') "></i>
           </div>
           <el-button type="success" plain size="mini" @click="value.FormColumnList.push({columnName:'',value:''});">+添加字段</el-button>
           <el-table v-loading="loading" size="mini" :data="value.FormColumnList"  border  style="width: 100%;margin:10px 0;">
@@ -34,7 +35,7 @@
             <el-table-column label="表单字段" width="180"  align="center">
               <template slot-scope="scope">
                 <el-select v-model="scope.row.columnName" filterable placeholder="请选择表单字段" clearable >
-                  <el-option v-for="(item, index) in value.columnList" :label="item.label" :value="item.field" :key="item.field"></el-option>
+                  <el-option v-for="(item, index) in value.columnList" :label="item.label" :value="item.propId" :key="item.propId"></el-option>
                 </el-select>
               </template>
             </el-table-column>
@@ -73,8 +74,8 @@
             </el-table-column>
             <el-table-column label="表单字段" width="180"  align="center">
               <template slot-scope="scope">
-                <el-select v-model="scope.row.columnId" filterable placeholder="请选择表单字段" clearable @change="scope.row.function = '';scope.row.viewDataType = value.columnList.find(o=>o.field === scope.row.columnId)?.config?.viewDataType">
-                  <el-option v-for="(item, index) in value.columnList" :label="item.label" :value="item.field" :key="item.field"></el-option>
+                <el-select v-model="scope.row.columnId" filterable placeholder="请选择表单字段" clearable @change="scope.row.function = '';scope.row.viewDataType = value.columnList.find(o=>o.propId === scope.row.columnId)?.config?.viewDataType">
+                  <el-option v-for="(item, index) in value.columnList" :label="item.label" :value="item.propId" :key="item.propId"></el-option>
                 </el-select>
               </template>
             </el-table-column>