Просмотр исходного кода

feat: 新增子表排序配置和子表弹窗可以带默认参数

johnsen 7 месяцев назад
Родитель
Сommit
6b7bad918e

+ 27 - 0
src/business/platform/data/templaterender/templates/list.vue

@@ -545,6 +545,18 @@ export default {
     pkKey() {
       return this.key || 'id_'
     },
+    isRoleFilter() {
+      const highRoles = this.$store.getters.userInfo.highRoles || [] // 高权限角色
+      const userRole = this.$store.getters.userInfo.role || [] // 用户权限角色
+      let isHighRole = false
+      userRole.forEach((el) => {
+        const roleAlias = el.alias
+        if (highRoles.includes(roleAlias)) {
+          isHighRole = true
+        }
+      })
+      return this.$store.getters.isSuper || isHighRole
+    },
     formFieldMap() {
       if (this.$utils.isEmpty(this.fields)) {
         return {}
@@ -1512,6 +1524,21 @@ export default {
         rowHandle: rowHandle,
         searchForm: searchForms.length > 0 ? { forms: searchForms } : null
       }
+      if (
+        this.isRoleFilter &&
+        rowHandle &&
+        rowHandle.actions &&
+        rowHandle.actions.some((t) => t.key === 'consult')
+      ) {
+        console.log(
+          'rowHandle.actions.====>',
+          this.isRoleFilter,
+          rowHandle.actions,
+          rowHandle.actions.some((t) => t.key === 'consult')
+        )
+        const consult = rowHandle.actions.find((t) => t.key === 'consult')
+        console.log('加快照按钮==>', consult.reportPath)
+      }
       // 判断地点是否第一层级
       const position = this.$store.getters.userInfo.positions
       let showBoolean = false

+ 1 - 0
src/business/platform/form/constants/fieldTypes.js

@@ -579,6 +579,7 @@ const fieldTypes = {
         columns: [],
         summary: false,
         page: 'Y',
+        sortable: 'Y',
         pageSize: 20,
         index: true,
         sum_text: '',

+ 4 - 0
src/business/platform/form/formbuilder/constants/helpTip.js

@@ -177,6 +177,10 @@ export default {
     title: '关于选项数据值来源',
     content: `此属性用于设置选项数据值来源是自定义固定的选项值/标签【静态数据】,还是通过【数据模版】的【值来源】类型。`
   },
+  sortable: {
+    title: '关于拖拽排序',
+    content: `此属性用于开启或关闭表格拖拽排序功能。`
+  },
   valueSource: {
     title: '关于值来源',
     content: '【值来源】的数据来源是“数据模版管理”中,模版类型为“值来源”信息。'

+ 10 - 0
src/business/platform/form/formbuilder/right-aside/editors/editor-base.vue

@@ -250,6 +250,16 @@
         /></template>
         <el-switch v-model="isDisplay" />
       </el-form-item>
+      <el-form-item v-if="types.includes('sortable')" label="是否拖拽排序">
+        <template slot="label"
+          >是否拖拽排序<help-tip prop="sortable"
+        /></template>
+        <el-switch
+          v-model="fieldOptions.sortable"
+          active-value="Y"
+          inactive-value="N"
+        />
+      </el-form-item>
     </div>
     <!--公式编辑-->
     <formula-edit

+ 1 - 1
src/business/platform/form/formbuilder/right-aside/field-types/ibps-field-table.vue

@@ -6,7 +6,7 @@
         :field-item="fieldItem"
         :bo-data="boData"
         :fields="fields"
-        types="label,name,desc,display"
+        types="label,name,desc,display,sortable"
       />
       <!-- 表单字段和按钮 -->
       <editor-field-table

+ 49 - 25
src/business/platform/form/formrender/dynamic-form/dynamic-form-table.vue

@@ -306,7 +306,6 @@
 </template>
 <script>
 import emitter from '@/plugins/element-ui/src/mixins/emitter'
-import { valueEquals } from '@/plugins/element-ui/src/utils/util'
 import { nestedFieldTypes } from '@/business/platform/form/constants/fieldTypes'
 import FormOptions from '../../constants/formOptions'
 import ActionUtils from '@/utils/action'
@@ -324,6 +323,7 @@ import FormrenderDialog from '@/business/platform/form/formrender/dialog'
 import ImportTable from './components/import-table'
 import IbpsExport from '@/plugins/export'
 import IbpsImport from '@/plugins/import'
+import sortableJs from '@/mixins/sortable'
 
 const JForm = window.JForm
 // 获取子表展示数据
@@ -340,7 +340,7 @@ export default {
     CustomDialog,
     ImportTable
   },
-  mixins: [emitter],
+  mixins: [emitter, sortableJs],
   props: {
     value: [Array, Object, String], // 值
     formData: [Array, Object], // 表单数据
@@ -406,22 +406,19 @@ export default {
       actionPosition: 'toolbar',
       handleCout: '',
       dynamicShow: true,
-
       customDialogVisible: false,
       customDialogKey: '',
       customDialogDynamicParams: {},
       customDialogCustom: {},
-
       formEditVisible: false,
       formDialogVisible: false,
+      subDefaultFormData: {},
       dialogFormDef: {},
       dialogFormData: {},
       dialogFormIndex: -1,
-
       importTableDialogVisible: false,
       dialogTemplate: null,
       dialogTemplateAtts: {},
-
       oldList: [], // 子表旧数据
       importList: [],
       importValue: null,
@@ -525,6 +522,9 @@ export default {
         ? true
         : this.tableRights === FormOptions.t.PERMISSIONS.READ
     },
+    canSortable() {
+      return !this.tableReadonly && this.fieldOptions.sortable === 'Y'
+    },
     tableHidden() {
       return this.tableRights === FormOptions.t.PERMISSIONS.HIDE
     },
@@ -565,6 +565,7 @@ export default {
           this.dataModel = []
           return
         }
+        // this.dataModel = []
         this.dataModel = val
         // if (!valueEquals(val, oldVal)) {
         //     this.dispatch('ElFormItem', 'el.form.change', val)
@@ -644,8 +645,17 @@ export default {
   },
   mounted() {
     this.handleRefreshTable()
+    this.canSortable && this.initSortable()
   },
   methods: {
+    sortableEnd(evt) {
+      const { oldIndex, newIndex } = evt
+      // 处理数据交换
+      const tem = JSON.parse(JSON.stringify(this.copDataModel))
+      const currRow = tem.splice(oldIndex, 1)[0]
+      tem.splice(newIndex, 0, currRow)
+      this.$emit('update:value', tem)
+    },
     handleRefreshTable() {
       this.$nextTick(() => {
         if (this.$refs.elTable) {
@@ -665,24 +675,33 @@ export default {
       this.$emit('change-data', key, val)
     },
     handlePagination(val) {
-      this.totalCount = val.length
-      // 限制最小页数为1
-      const pageCount = Math.ceil(this.totalCount / this.pageSize) || 1
-      // 逻辑:删除后当前页大于总页数,替换为总页数,否则留在当前页
-      if (this.editFromType === 'add') {
-        // 新增按钮逻辑:前往最后一页
-        this.currentPage = pageCount
-      } else if (this.editFromType === 'import') {
-        // 导入定位到第一页
-        this.currentPage = 1
-      } else {
-        // 其余逻辑(编辑、删除、整表赋值):操作后当前页大于总页数,替换为总页数,否则留在当前页
-        this.currentPage =
-          this.currentPage > pageCount ? pageCount : this.currentPage
-      }
-      this.copDataModel = this.getShowData(val, this.currentPage, this.pageSize)
-      this.editFromType = ''
-      this.$emit('update:value', val)
+      this.copDataModel = []
+      this.$nextTick(() => {
+        this.totalCount = val.length
+        // 限制最小页数为1
+        const pageCount = Math.ceil(this.totalCount / this.pageSize) || 1
+        // 逻辑:删除后当前页大于总页数,替换为总页数,否则留在当前页
+        if (this.editFromType === 'add') {
+          // 新增按钮逻辑:前往最后一页
+          this.currentPage = pageCount
+        } else if (this.editFromType === 'import') {
+          // 导入定位到第一页
+          this.currentPage = 1
+        } else {
+          // 其余逻辑(编辑、删除、整表赋值):操作后当前页大于总页数,替换为总页数,否则留在当前页
+          this.currentPage =
+            this.currentPage > pageCount ? pageCount : this.currentPage
+        }
+
+        this.copDataModel = this.getShowData(
+          val,
+          this.currentPage,
+          this.pageSize
+        )
+        this.editFromType = ''
+      })
+
+      // this.$emit('update:value', val)
     },
     // 处理切换分页
     handleCurrentChange(val) {
@@ -1253,7 +1272,10 @@ export default {
     },
     // =====================对话框模式数据处理   金源信通改=====================
     handleDialogMode(index) {
-      const data = this.$utils.isNotEmpty(index) ? this.dataModel[index] : {}
+      const data = this.$utils.isNotEmpty(index)
+        ? this.dataModel[index]
+        : // : this.subDefaultFormData
+          this.subDefaultFormData
       this.dialogFormData = {
         responses: JSON.parse(JSON.stringify(data)),
         // 表单字段权限
@@ -1444,6 +1466,8 @@ export default {
     },
     // 后置脚本
     afterScript(action, position, params, callback) {
+      // 刷新拖拽表格排序实例
+      this.canSortable && this.refreshSortable()
       if (!this.hasScript()) {
         if (callback) {
           const flag = true

+ 23 - 1
src/components/ibps-crud/mixin/data.js

@@ -1,5 +1,6 @@
 import { cloneDeep, debounce, snakeCase, get, set } from 'lodash'
 import { on, off } from 'element-ui/lib/utils/dom'
+import Sortable from 'sortablejs'
 
 export default {
   props: {
@@ -43,7 +44,8 @@ export default {
       /**
        * @description 选中的选项
        */
-      selectionRadio: ''
+      selectionRadio: '',
+      sortable: null
     }
   },
   computed: {
@@ -77,6 +79,7 @@ export default {
     this.handleDataChange()
     this.handleTableHeight()
     on(document.body, 'resize', this.handleResize)
+    // this.initSortable()
   },
   beforeDestroy() {
     off(document.body, 'resize', this.handleResize)
@@ -99,6 +102,25 @@ export default {
         this.ibpsData = cloneDeep(this.data)
       }
     },
+    // 初始化拖拽排序
+    initSortable() {
+      // 获取表格的tbody元素
+      const el = this.$refs.elTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0];
+      this.sortable = new Sortable(el, {
+        // 拖拽时的类名
+        ghostClass: 'sortable-ghost',
+        // 拖拽动画时间
+        animation: 150,
+        // 结束拖拽时的回调
+        onEnd: (evt) => {
+          const { oldIndex, newIndex } = evt;
+          // 处理数据交换
+          const currRow = this.ibpsData.splice(oldIndex, 1)[0];
+          this.ibpsData.splice(newIndex, 0, currRow);
+          console.log('排序已变更', this.ibpsData);
+        }
+      });
+    },
     /**
      * @description 排序状态
      */

+ 43 - 0
src/mixins/sortable.js

@@ -0,0 +1,43 @@
+import Sortable from 'sortablejs'
+/**
+ * 组件必须提供一个sortableEnd方法用于拖拽数据更新
+ */
+export default {
+  data() {
+    return {
+      sortable: null
+    }
+  },
+  methods: {
+    // 初始化拖拽排序
+    initSortable() {
+      // 获取表格的tbody元素
+      const el = this.$refs.elTable.$el.querySelectorAll(
+        '.el-table__body-wrapper > table > tbody'
+      )[0]
+      this.sortable = new Sortable(el, {
+        // 拖拽时的类名
+        ghostClass: 'sortable-ghost',
+        // 拖拽动画时间
+        animation: 150,
+        // 结束拖拽时的回调
+        onEnd: this.sortableEnd
+      })
+    },
+    // 重新实例化sortable
+    refreshSortable() {
+      this.$nextTick(() => {
+        if (this.sortable) {
+          this.sortable.destroy()
+        }
+        this.initSortable()
+      })
+    }
+  },
+  // 销毁实例
+  beforeDestroy() {
+    if (this.sortable) {
+      this.sortable.destroy()
+    }
+  }
+}

+ 77 - 5
src/views/platform/risk/riskDetail.vue

@@ -111,7 +111,14 @@
           />
         </div>
         <div class="table">
-          <el-table :data="tableList" border>
+          <el-alert
+            style="margin-bottom: 12px"
+            title=""
+            type="success"
+            :closable="false"
+            description="提示:可以拖动表格数据进行排序"
+          />
+          <el-table ref="eltable1" :data="tableList" border>
             <el-table-column
               prop=""
               label="序号"
@@ -373,7 +380,10 @@ import { getSetting } from '@/utils/query'
 import dayjs from 'dayjs'
 import ibpsUserSelector from '@/business/platform/org/selector'
 import { getImage } from '@/api/platform/file/attachment'
+import sortableJs from '@/mixins/sortable'
+import Sortable from 'sortablejs'
 export default {
+  mixins: [sortableJs],
   components: {
     ibpsUserSelector,
     IbpsCustomDialog: () =>
@@ -400,6 +410,7 @@ export default {
           userType: 'position'
         }
       ],
+      tkey: 1,
       form: {
         xuan_ze_feng_xian: ''
       },
@@ -463,9 +474,15 @@ export default {
       return getImage('risk_fxjz') // 风险矩阵参照图
     },
     descriptionContent() {
-      const msg1 = `1.当前风险系数计算公式为模板一:'${this.culWays[this.muban]}'。2.风险等级由严重程度和发生频度组成的坐标值映射成为矩阵坐标。`
-      const msg2 = `1.当前风险系数计算公式为模板二:'${this.culWays[this.muban]}'。2.风险系数 RPN = Severity(严重度) × Occurrence(发生度)× Likelihood of Detection(检测度)。`
-      const msg3 = `1.当前风险系数计算公式为模板三:'${this.culWays[this.muban]}'。2.风险系数 RPN = Severity(严重程度) × Possibility(发生的可能性)。`
+      const msg1 = `1.当前风险系数计算公式为模板一:'${
+        this.culWays[this.muban]
+      }'。2.风险等级由严重程度和发生频度组成的坐标值映射成为矩阵坐标。`
+      const msg2 = `1.当前风险系数计算公式为模板二:'${
+        this.culWays[this.muban]
+      }'。2.风险系数 RPN = Severity(严重度) × Occurrence(发生度)× Likelihood of Detection(检测度)。`
+      const msg3 = `1.当前风险系数计算公式为模板三:'${
+        this.culWays[this.muban]
+      }'。2.风险系数 RPN = Severity(严重程度) × Possibility(发生的可能性)。`
       switch (this.muban) {
         case '1':
           return msg1
@@ -500,11 +517,13 @@ export default {
   watch: {
     params: {
       handler(val) {
+        console.log('params')
         this.getTableData()
       }
     },
     rowParams: {
       handler(val) {
+        console.log('rowParams')
         this.getTableData()
       }
     },
@@ -573,6 +592,50 @@ export default {
     }
   },
   methods: {
+    // 初始化拖拽排序
+    initSortable() {
+      // 获取表格的tbody元素
+      console.log(this.$refs)
+      const el = this.$refs.eltable1.$el.querySelectorAll(
+        '.el-table__body-wrapper > table > tbody'
+      )[0]
+      this.sortable = new Sortable(el, {
+        // 拖拽时的类名
+        ghostClass: 'sortable-ghost',
+        // 拖拽动画时间
+        animation: 150,
+        // 结束拖拽时的回调
+        onEnd: this.sortableEnd
+      })
+    },
+    sortableEnd(evt) {
+      const { oldIndex, newIndex } = evt
+      // 复制原数组
+      const newData = [...this.tableList]
+      // 操作副本
+      const movedItem = newData.splice(oldIndex, 1)[0]
+      newData.splice(newIndex, 0, movedItem)
+      // 重新赋值(引用变化,触发更新)
+      this.tableList = []
+      this.$nextTick(() => {
+        // 确保数据已更新到DOM
+        this.tableList = newData // 可结合表格自身的强制更新
+      })
+      // this.$forceUpdate()
+      // const { oldIndex, newIndex } = evt
+      // const temData = JSON.parse(JSON.stringify(this.tableList))
+      // // 处理数据交换
+      // const currRow = temData.splice(oldIndex, 1)[0]
+      // temData.splice(newIndex, 0, currRow)
+      // console.log(
+      //   'temData==>',
+      //   temData.map((t) => t.yao_su_tiao_kuan_)
+      // )
+      // this.tableList = temData
+      // this.$nextTick(() => {
+      //   this.$refs.eltable1.doLayout()
+      // })
+    },
     async getTableData() {
       this.loading = true
       // console.log(this.params)
@@ -682,7 +745,9 @@ export default {
             (this.muban === '2' && jianCeData.length === 0)
           ) {
             throw new Error(
-              `检测到风险类型为${this.leixing}且计算方式为'${this.culWays[this.muban] || this.muban}'的配置数据不完整,建议配置完成后再使用!`
+              `检测到风险类型为${this.leixing}且计算方式为'${
+                this.culWays[this.muban] || this.muban
+              }'的配置数据不完整,建议配置完成后再使用!`
             )
           }
           let degreeWord = ''
@@ -767,6 +832,7 @@ export default {
         this.rowParams = row
       }
       this.dialogVisible = true
+      !this.readonly && this.refreshSortable()
     },
     // 计算风险指数
     culRate(row) {
@@ -1160,6 +1226,12 @@ export default {
     height: 300px;
     overflow: auto;
     margin-top: 20px;
+    ::v-deep .el-table__row {
+      cursor: move;
+    }
+  }
+  .tip {
+    padding-bottom: 12px;
   }
 }
 </style>

+ 12 - 1
src/views/platform/risk/riskPeopleTable.vue

@@ -69,12 +69,14 @@
 <script>
 import ibpsUserSelector from '@/business/platform/org/selector'
 import RiskDetail from './riskDetail.vue'
+import sortableJs from '@/mixins/sortable'
 
 export default {
   components: {
     ibpsUserSelector,
     RiskDetail
   },
+  mixins: [sortableJs],
   props: {
     params: {
       type: Object,
@@ -95,7 +97,8 @@ export default {
       tableList: [],
       detail: [],
       isZuZhang: false,
-      userId: userId
+      userId: userId,
+      sortable: null
     }
   },
   watch: {
@@ -108,8 +111,16 @@ export default {
   },
   mounted() {
     this.getPeopleList()
+    // this.initSortable()
   },
   methods: {
+    sortableEnd(evt) {
+      const { oldIndex, newIndex } = evt
+      // 处理数据交换
+      const currRow = this.tableList.splice(oldIndex, 1)[0]
+      this.tableList.splice(newIndex, 0, currRow)
+      console.log('排序已变更', this.tableList)
+    },
     // 获取人员部门
     getPersonPosition(id) {
       const userList = this.$store.getters.userList