zenglf
2023-10-18 73250e481e966dd8e3372c518530203ac047da14
操作证申请表 操作证管理功能提交 操作证计分规则
已添加9个文件
已修改6个文件
1866 ■■■■■ 文件已修改
src/api/manage.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/JVxeCells/JVxePopupCell.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/jeecg/JVxeTable/components/JVxeTable.js 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mixins/JVxeTableMixin.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mixins/JVxeTableModelMixin.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/encryption/signMd5Utils.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/DeductionItemList.vue 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/OperationCertificateApplyList.vue 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/OperationCertificateList.vue 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/modules/deductionItem/DeductionItemForm.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/modules/deductionItem/DeductionItemModal.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/modules/operationCertificate/OperationCertificateForm.vue 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/modules/operationCertificate/OperationCertificateModal.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/modules/operationCertificateApply/OperationCertificateApplyForm.vue 280 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/modules/operationCertificateApply/OperationCertificateApplyModal.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/manage.js
@@ -16,7 +16,9 @@
export function postAction(url,parameter) {
  let sign = signMd5Utils.getSign(url, parameter);
  //将签名和时间戳,添加在请求接口 Header
  let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()};
  // update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
  let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
  // update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
  return axios({
    url: url,
@@ -30,7 +32,9 @@
export function httpAction(url,parameter,method) {
  let sign = signMd5Utils.getSign(url, parameter);
  //将签名和时间戳,添加在请求接口 Header
  let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()};
  // update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
  let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
  // update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
  return axios({
    url: url,
@@ -53,7 +57,9 @@
export function getAction(url,parameter) {
  let sign = signMd5Utils.getSign(url, parameter);
  //将签名和时间戳,添加在请求接口 Header
  let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()};
  // update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
  let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
  // update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
  return axios({
    url: url,
src/components/JVxeCells/JVxePopupCell.vue
@@ -51,6 +51,10 @@
    enhanced: {
      aopEvents: {
        editActived(event) {
          // ã€issues/3854】附表控件类型为popup必填时未选择值提交表单会报错
          if (event.$event && event.$event.type === 'valid-error') {
            return;
          }
          dispatchEvent.call(this, event, 'ant-input')
        },
      },
src/components/jeecg/JVxeTable/components/JVxeTable.js
@@ -23,7 +23,7 @@
    }
  },
  mixins: [VxeWebSocketMixins],
  components: {JVxeToolbar, JVxeSubPopover, JVxeDetailsModal, JVxePagination},
  components: { JVxeToolbar, JVxeSubPopover, JVxeDetailsModal, JVxePagination },
  props: {
    rowKey: PropTypes.string.def('id'),
    // åˆ—信息
@@ -48,7 +48,7 @@
      // prefix å‰ç¼€ï¼›suffix åŽç¼€ï¼›
      slots: ['prefix', 'suffix'],
      // add æ–°å¢žæŒ‰é’®ï¼›remove åˆ é™¤æŒ‰é’®ï¼›clearSelection æ¸…空选择按钮;collapse å±•开收起
      btns: ['add', 'remove', 'clearSelection'],
      btns: ['add', 'remove', 'clearSelection']
    })),
    // æ˜¯å¦æ˜¾ç¤ºè¡Œå·
    rowNumber: PropTypes.bool.def(false),
@@ -66,7 +66,7 @@
    // æœ€å¤§é«˜åº¦
    maxHeight: {
      type: Number,
      default: () => null,
      default: () => null
    },
    // è¦ç¦ç”¨çš„行 TODO æœªå®žçް
    disabledRows: PropTypes.object.def(() => ({})),
@@ -99,7 +99,7 @@
    // æ³¨ï¼šè¯¥å‚数不能动态修改;如果行、列字段多的情况下,会根据机器性能造成不同程度的卡顿。
    alwaysEdit: PropTypes.bool.def(false),
    // è”动配置,数组,详情配置见文档
    linkageConfig: PropTypes.array.def(() => []),
    linkageConfig: PropTypes.array.def(() => [])
  },
  data() {
    return {
@@ -111,7 +111,7 @@
      // å†…ç½® EditRules
      innerEditRules: [],
      // è®°å½•滚动条位置
      scroll: {top: 0, left: 0},
      scroll: { top: 0, left: 0 },
      // å½“前是否正在滚动
      scrolling: false,
      // vxe é»˜è®¤é…ç½®
@@ -125,7 +125,7 @@
        'show-header-overflow': true,
        'show-footer-overflow': true,
        // å¯ç¼–辑配置
        'edit-config': {trigger: 'click', mode: 'cell', showStatus: true},
        'edit-config': { trigger: 'click', mode: 'cell', showStatus: true },
        'expand-config': {
          iconClose: 'ant-table-row-expand-icon ant-table-row-collapsed',
          iconOpen: 'ant-table-row-expand-icon ant-table-row-expanded'
@@ -137,8 +137,8 @@
        // 'scroll-x': {
        //   gt: 15
        // },
        'radio-config': {highlight: true},
        'checkbox-config': {highlight: true},
        'radio-config': { highlight: true },
        'checkbox-config': { highlight: true }
      },
      // ç»‘定左侧选择框
      selectedRows: [],
@@ -148,15 +148,15 @@
      statistics: {
        has: false,
        sum: [],
        average: [],
        average: []
      },
      // å…è®¸æ‰§è¡Œåˆ·æ–°ç‰¹æ•ˆçš„行ID
      reloadEffectRowKeysMap: {},
      //配置了但是没有授权的按钮和列 é›†åˆ
      excludeCode:[],
      excludeCode: [],
      // è”动下拉选项(用于隔离不同的下拉选项)
      // å†…部联动配置,map
      innerLinkageConfig: null,
      innerLinkageConfig: null
    }
  },
  computed: {
@@ -171,7 +171,7 @@
          scrolling: this.scrolling,
          reloadEffect: this.reloadEffect,
          reloadEffectRowKeysMap: this.reloadEffectRowKeysMap,
          listeners: this.cellListeners,
          listeners: this.cellListeners
        }
        if (column.$type === JVXETypes.rowDragSort) {
          renderOptions.dragSortKey = this.dragSortKey
@@ -191,7 +191,7 @@
              config: this.innerLinkageConfig.get(column.key),
              getLinkageOptionsSibling: this.getLinkageOptionsSibling,
              getLinkageOptionsAsync: this.getLinkageOptionsAsync,
              linkageSelectChange: this.linkageSelectChange,
              linkageSelectChange: this.linkageSelectChange
            }
          }
        }
@@ -204,21 +204,21 @@
        // update--begin--autor:lvdandan-----date:20201019------for:LOWCOD-882 ã€æ–°è¡Œç¼–辑】列表上带按钮的遮挡问题
        if (column.$type === JVXETypes.file || column.$type === JVXETypes.image) {
          if (column.width && column.width.endsWith('px')) {
            column.width = Number.parseInt(column.width.substr(0,column.width.length-2))+Number.parseInt(1)+'px';
            column.width = Number.parseInt(column.width.substr(0, column.width.length - 2)) + Number.parseInt(1) + 'px'
          }
        }
        // update--begin--autor:lvdandan-----date:20201019------for:LOWCOD-882 ã€æ–°è¡Œç¼–辑】列表上带按钮的遮挡问题
        // update--begin--autor:lvdandan-----date:20201211------for:JT-118 ã€online】 æ—¥æœŸã€æ—¶é—´æŽ§ä»¶é•¿åº¦è¾ƒå°
        if (column.$type === JVXETypes.datetime || column.$type === JVXETypes.userSelect || column.$type === JVXETypes.departSelect) {
          let width = column.width && column.width.endsWith('px')?Number.parseInt(column.width.substr(0,column.width.length-2)):0;
          if(width <= 190){
          let width = column.width && column.width.endsWith('px') ? Number.parseInt(column.width.substr(0, column.width.length - 2)) : 0
          if (width <= 190) {
            column.width = '190px'
          }
        }
        if (column.$type === JVXETypes.date) {
          let width = column.width && column.width.endsWith('px')?Number.parseInt(column.width.substr(0,column.width.length-2)):0;
          if(width <= 135){
          let width = column.width && column.width.endsWith('px') ? Number.parseInt(column.width.substr(0, column.width.length - 2)) : 0
          if (width <= 135) {
            column.width = '135px'
          }
        }
@@ -235,7 +235,7 @@
      let expandConfig = Object.assign({}, this.defaultVxeProps['expand-config'], this.expandConfig)
      return Object.assign({}, this.defaultVxeProps, {
        showFooter: this.statistics.has,
        showFooter: this.statistics.has
      }, this.$attrs, {
        loading: this.loading,
        columns: this.vxeColumns,
@@ -245,7 +245,7 @@
        maxHeight: this.maxHeight,
        border: this.bordered,
        expandConfig: expandConfig,
        footerMethod: this.handleFooterMethod,
        footerMethod: this.handleFooterMethod
        // footerSpanMethod: this.handleFooterSpanMethod,
      })
    },
@@ -259,7 +259,7 @@
        'edit-actived': this.handleEditActived,
        'radio-change': this.handleVxeRadioChange,
        'checkbox-all': this.handleVxeCheckboxAll,
        'checkbox-change': this.handleVxeCheckboxChange,
        'checkbox-change': this.handleVxeCheckboxChange
      }
      // ç”¨æˆ·ä¼ é€’的事件,进行合并操作
      Object.keys(this.$listeners).forEach(key => {
@@ -285,9 +285,9 @@
        /** å½“前行向下移一位 */
        rowMoveDown: rowIndex => this.rowResort(rowIndex, rowIndex + 1),
        /** åœ¨å½“前行下面插入一行 */
        rowInsertDown: rowIndex => this.insertRows({}, rowIndex + 1),
        rowInsertDown: rowIndex => this.insertRows({}, rowIndex + 1)
      }
    },
    }
  },
  watch: {
    dataSource: {
@@ -334,7 +334,7 @@
        //     }
        //   }
        // })
      },
      }
    },
    columns: {
      immediate: true,
@@ -343,7 +343,7 @@
        this.loadExcludeCode()
        let innerColumns = []
        let innerEditRules = {}
        let {rowNumber, rowSelection, rowExpand, dragSort} = this
        let { rowNumber, rowSelection, rowExpand, dragSort } = this
        let expandColumn, seqColumn, checkboxColumn, radioColumn, dragSortColumn
        if (Array.isArray(columns)) {
          this.statistics.has = false
@@ -352,11 +352,11 @@
          // å¤„理成vxe可识别的columns
          columns.forEach(column => {
            if(this.excludeCode.indexOf(column.key)>=0){
            if (this.excludeCode.indexOf(column.key) >= 0) {
              return false
            }
            let col = {...column}
            let {type} = col
            let col = { ...column }
            let { type } = col
            const enhanced = getEnhancedMixins(type)
            if (type === JVXETypes.rowNumber) {
              seqColumn = col
@@ -373,7 +373,7 @@
              // é˜²æ­¢å’ŒvxeTable自带的type起冲突
              col.$type = col.type
              delete col.type
              let renderName = 'cellRender', renderOptions = {name: JVXETypes._prefix + type}
              let renderName = 'cellRender', renderOptions = { name: JVXETypes._prefix + type }
              if (type) {
                // hidden æ˜¯ç‰¹æ®Šçš„组件
                if (type === JVXETypes.hidden) {
@@ -441,9 +441,9 @@
        }
        // åˆ¤æ–­æ˜¯å¦å¼€å¯äº†åºå·
        if (rowNumber) {
          let col = {type: 'seq', title: '#', width: 60, fixed: 'left', align: 'center'}
          let col = { type: 'seq', title: '#', width: 60, fixed: 'left', align: 'center' }
          if (seqColumn) {
            col = Object.assign(col, seqColumn, {type: 'seq'})
            col = Object.assign(col, seqColumn, { type: 'seq' })
          }
          innerColumns.unshift(col)
        }
@@ -453,14 +453,14 @@
          if (this.statistics.has && !rowExpand && !dragSort) {
            width = 60
          }
          let col = {type: this.rowSelectionType, width, fixed: 'left', align: 'center'}
          let col = { type: this.rowSelectionType, width, fixed: 'left', align: 'center' }
          // radio
          if (this.rowSelectionType === 'radio' && radioColumn) {
            col = Object.assign(col, radioColumn, {type: 'radio'})
            col = Object.assign(col, radioColumn, { type: 'radio' })
          }
          // checkbox
          if (this.rowSelectionType === 'checkbox' && checkboxColumn) {
            col = Object.assign(col, checkboxColumn, {type: 'checkbox'})
            col = Object.assign(col, checkboxColumn, { type: 'checkbox' })
          }
          innerColumns.unshift(col)
        }
@@ -470,9 +470,16 @@
          if (this.statistics.has && !dragSort) {
            width = 60
          }
          let col = {type: 'expand', title: '', width, fixed: 'left', align: 'center', slots: {content: 'expandContent'}}
          let col = {
            type: 'expand',
            title: '',
            width,
            fixed: 'left',
            align: 'center',
            slots: { content: 'expandContent' }
          }
          if (expandColumn) {
            col = Object.assign(col, expandColumn, {type: 'expand'})
            col = Object.assign(col, expandColumn, { type: 'expand' })
          }
          innerColumns.unshift(col)
        }
@@ -482,9 +489,16 @@
          if (this.statistics.has) {
            width = 60
          }
          let col = {type: JVXETypes.rowDragSort, title: '', width, fixed: 'left', align: 'center', cellRender: {name: JVXETypes._prefix + JVXETypes.rowDragSort}}
          let col = {
            type: JVXETypes.rowDragSort,
            title: '',
            width,
            fixed: 'left',
            align: 'center',
            cellRender: { name: JVXETypes._prefix + JVXETypes.rowDragSort }
          }
          if (dragSortColumn) {
            col = Object.assign(col, dragSortColumn, {type: JVXETypes.rowDragSort})
            col = Object.assign(col, dragSortColumn, { type: JVXETypes.rowDragSort })
          }
          innerColumns.unshift(col)
        }
@@ -525,7 +539,7 @@
          this.innerLinkageConfig = null
        }
      }
    },
    }
  },
  created() {
  },
@@ -559,7 +573,7 @@
    },
    handleVxeScroll(event) {
      let {$refs, scroll} = this
      let { $refs, scroll } = this
      // è®°å½•滚动条的位置
      scroll.top = event.scrollTop
@@ -609,8 +623,8 @@
    // ç‚¹å‡»å•元格时触发的事件
    handleCellClick(event) {
      let {row, column, $event, $table} = event
      let {$refs} = this
      let { row, column, $event, $table } = event
      let { $refs } = this
      // ç‚¹å‡»äº†å¯ç¼–辑的
      if (column.editRender) {
@@ -651,20 +665,20 @@
    },
    // å•元格编辑状态下被关闭时会触发该事件
    handleEditClosed({column}) {
    handleEditClosed({ column }) {
      // æ‰§è¡Œå¢žå¼º
      getEnhancedMixins(column.own.$type, 'aopEvents').editClosed.apply(this, arguments)
    },
    // å•元格被激活编辑时会触发该事件
    handleEditActived({column}) {
    handleEditActived({ column }) {
      // æ‰§è¡Œå¢žå¼º
      getEnhancedMixins(column.own.$type, 'aopEvents').editActived.apply(this, arguments)
    },
    /** è¡¨å°¾æ•°æ®å¤„理方法,用于显示统计信息 */
    handleFooterMethod({columns, data}) {
      const {statistics} = this
    handleFooterMethod({ columns, data }) {
      const { statistics } = this
      let footers = []
      if (statistics.has) {
        if (statistics.sum.length > 0) {
@@ -687,7 +701,7 @@
      return footers
    },
    getFooterStatisticsMap({columns, title, checks, method}) {
    getFooterStatisticsMap({ columns, title, checks, method }) {
      return columns.map((column, columnIndex) => {
        if (columnIndex === 0) {
          return title
@@ -702,7 +716,7 @@
    /** è¡¨å°¾å•元格合并方法 */
    handleFooterSpanMethod(event) {
      if (event.columnIndex === 0) {
        return {colspan: 2}
        return { colspan: 2 }
      }
    },
@@ -716,10 +730,10 @@
      this.scrollTo(null, (top == null || top === '') ? this.scroll.top : top)
    },
    clearAllData() {
      let {xTable} = this.$refs.vxe.$refs
        // issues/2784
        // å…ˆæ¸…空所有数据
        xTable.loadData([])
      let { xTable } = this.$refs.vxe.$refs
      // issues/2784
      // å…ˆæ¸…空所有数据
      xTable.loadData([])
    },
    /**
     * åŠ è½½æ–°æ•°æ®ï¼Œå’Œ loadData ä¸åŒçš„æ˜¯ï¼Œç”¨è¯¥æ–¹æ³•加载的数据都是相当于点新增按钮新增的数据。
@@ -728,7 +742,7 @@
     */
    async loadNewData(dataSource) {
      if (Array.isArray(dataSource)) {
        let {xTable} = this.$refs.vxe.$refs
        let { xTable } = this.$refs.vxe.$refs
        // issues/2784
        // å…ˆæ¸…空所有数据
        xTable.loadData([])
@@ -771,8 +785,8 @@
      // æ˜¯å¦æ›´æ–°äº†æ•°æ®
      let updated = false
      values.forEach((item, idx) => {
        let {rowKey, values: record} = item
        let {row} = this.getIfRowById(rowKey)
        let { rowKey, values: record } = item
        let { row } = this.getIfRowById(rowKey)
        if (!row) {
          return
        }
@@ -791,7 +805,7 @@
                oldValue: oldValue,
                col: column.own,
                column: column,
                isSetValues: true,
                isSetValues: true
              })
            }
          } else {
@@ -802,10 +816,10 @@
      // ã€issues/3828】数据更新后,重新计算统计列
      if (updated && this.statistics.has) {
        this.$nextTick(async () => {
          let {xTable} = this.$refs.vxe.$refs;
          await xTable.updateCache(true);
          await xTable.updateData();
        });
          let { xTable } = this.$refs.vxe.$refs
          await xTable.updateCache(true)
          await xTable.updateData()
        })
      }
    },
@@ -818,18 +832,18 @@
    },
    /** èŽ·å–è¡¨æ ¼è¡¨å•é‡Œçš„å€¼ */
    getValues(callback, rowIds) {
      let tableData = this.getTableData({rowIds: rowIds})
      let tableData = this.getTableData({ rowIds: rowIds })
      callback('', tableData)
    },
    /** èŽ·å–è¡¨æ ¼æ•°æ® */
    getTableData(options = {}) {
      let {rowIds} = options
      let { rowIds } = options
      let tableData
      // ä»…查询指定id的行
      if (Array.isArray(rowIds) && rowIds.length > 0) {
        tableData = []
        rowIds.forEach(rowId => {
          let {row} = this.getIfRowById(rowId)
          let { row } = this.getIfRowById(rowId)
          if (row) {
            tableData.push(row)
          }
@@ -858,11 +872,11 @@
        row = this.getNewRowById(id)
        if (!row) {
          console.warn(`JVxeTable.getIfRowById:没有找到id为"${id}"的行`)
          return {row: null}
          return { row: null }
        }
        isNew = true
      }
      return {row, isNew}
      return { row, isNew }
    },
    /** é€šè¿‡ä¸´æ—¶ID获取新增的行 */
    getNewRowById(id) {
@@ -885,9 +899,9 @@
     * @param isOnlJs æ˜¯å¦æ˜¯onlineJS增强触发的
     * @return
     */
  /*   async addRows(rows = {}, isOnlJs) {
    async addRows(rows = {}, isOnlJs) {
      return this._addOrInsert(rows, -1, 'added', isOnlJs)
    }, */
    },
    /**
     * æ·»åŠ ä¸€è¡Œæˆ–å¤šè¡Œ
@@ -910,8 +924,8 @@
     * @param options.setActive æ˜¯å¦æ¿€æ´»æœ€åŽä¸€è¡Œçš„编辑模式
     */
    async pushRows(rows = {}, options = {}) {
      let {xTable} = this.$refs.vxe.$refs
      let {setActive, index} = options
      let { xTable } = this.$refs.vxe.$refs
      let { setActive, index } = options
      setActive = setActive == null ? false : !!setActive
      index = index == null ? -1 : index
      index = index === -1 ? index : xTable.tableFullData[index]
@@ -927,7 +941,7 @@
    /** æ¸…空选择行 */
    clearSelection() {
      let event = {$table: this.$refs.vxe, target: this}
      let event = { $table: this.$refs.vxe, target: this }
      if (this.rowSelectionType === JVXETypes.rowRadio) {
        this.$refs.vxe.clearRadioRow()
        this.handleVxeRadioChange(event)
@@ -953,7 +967,7 @@
        rowIds = [rowId]
      }
      let rows = rowIds.map((id) => {
        let {row} = this.getIfRowById(id)
        let { row } = this.getIfRowById(id)
        if (!row) {
          return
        }
@@ -1061,7 +1075,7 @@
          values[config.keys[i]] = ''
        }
        // æ¸…空后几列的数据
        this.setValues([{rowKey: row.id, values}])
        this.setValues([{ rowKey: row.id, values }])
      }
    },
@@ -1084,12 +1098,12 @@
      })
    },
    //options自定义赋值 åˆ·æ–°
    virtualRefresh(){
    virtualRefresh() {
      this.scrolling = true
      this.closeScrolling()
    },
    // è®¾ç½® this.scrolling é˜²æŠ–模式
    closeScrolling: simpleDebounce(function () {
    closeScrolling: simpleDebounce(function() {
      this.scrolling = false
    }, 100),
@@ -1105,7 +1119,7 @@
      for (let row of rows) {
        let item = cloneObject(row)
        if (insertRecords.includes(row)) {
          handler ? handler({item, row, insertRecords}) : null
          handler ? handler({ item, row, insertRecords }) : null
          if (remove) {
            continue
@@ -1134,9 +1148,19 @@
    _remove(rows) {
      const xTable = this.$refs.vxe.$refs.xTable
      const {afterFullData, tableFullData, tableSourceData, editStore, treeConfig, checkboxOpts, selection, isInsertByRow, scrollYLoad} = xTable
      const {actived, removeList, insertList} = editStore
      const {checkField: property} = checkboxOpts
      const {
        afterFullData,
        tableFullData,
        tableSourceData,
        editStore,
        treeConfig,
        checkboxOpts,
        selection,
        isInsertByRow,
        scrollYLoad
      } = xTable
      const { actived, removeList, insertList } = editStore
      const { checkField: property } = checkboxOpts
      let rest = []
      const nowData = afterFullData
      if (treeConfig) {
@@ -1187,7 +1211,7 @@
      }
      return xTable.$nextTick().then(() => {
        xTable.recalculate()
        return {row: rest.length ? rest[rest.length - 1] : null, rows: rest}
        return { row: rest.length ? rest[rest.length - 1] : null, rows: rest }
      })
    },
@@ -1220,7 +1244,7 @@
    },
    async _addOrInsert(rows = {}, index, triggerName, isOnlJs) {
      let {xTable} = this.$refs.vxe.$refs
      let { xTable } = this.$refs.vxe.$refs
      let records
      if (Array.isArray(rows)) {
        records = rows
@@ -1229,7 +1253,7 @@
      }
      // éåŽ†æ·»åŠ é»˜è®¤å€¼
      records.forEach(record => this._createRow(record))
      let result = await this.pushRows(records, {index: index, setActive: true})
      let result = await this.pushRows(records, { index: index, setActive: true })
      // éåŽ†æ’å…¥çš„è¡Œ
      // update--begin--autor:lvdandan-----date:20201117------for:LOWCOD-987 ã€æ–°è¡Œç¼–辑】js增强附表内置方法调用问题 #1819
      // online js增强时以传过来值为准,不再赋默认值
@@ -1239,7 +1263,7 @@
          this.trigger(triggerName, {
            row: row,
            $table: xTable,
            target: this,
            target: this
          })
        }
      }
@@ -1248,14 +1272,14 @@
    },
    // åˆ›å»ºæ–°è¡Œï¼Œè‡ªåŠ¨æ·»åŠ é»˜è®¤å€¼
    _createRow(record = {}) {
      let {xTable} = this.$refs.vxe.$refs
      let { xTable } = this.$refs.vxe.$refs
      // æ·»åŠ é»˜è®¤å€¼
      xTable.tableFullColumn.forEach(column => {
        let col = column.own
        if (col.key && (record[col.key] == null || record[col.key] === '')) {
          // è®¾ç½®é»˜è®¤å€¼
          let createValue = getEnhancedMixins(col.$type || col.type, 'createValue')
          record[col.key] = createValue({row: record, column, $table: xTable})
          record[col.key] = createValue({ row: record, column, $table: xTable })
        }
        // update-begin--author:sunjianlei---date:20210819------for: å¤„理联动列,联动列只能作用于 select ç»„ä»¶
        if (col.$type === JVXETypes.select && this.innerLinkageConfig != null) {
@@ -1280,7 +1304,7 @@
        props: this.vxeProps,
        on: this.vxeEvents,
        // ä½œç”¨åŸŸæ’槽的格式为
        scopedSlots: this.$scopedSlots,
        scopedSlots: this.$scopedSlots
      })
    },
    // æ¸²æŸ“工具栏
@@ -1293,7 +1317,7 @@
            size: this.size,
            disabled: this.disabled,
            disabledRows: this.disabledRows,
            selectedRowIds: this.selectedRowIds,
            selectedRowIds: this.selectedRowIds
          },
          on: {
            // æ–°å¢žäº‹ä»¶
@@ -1301,7 +1325,7 @@
            // ä¿å­˜äº‹ä»¶
            save: () => this.trigger('save', {
              $table: this.$refs.vxe,
              target: this,
              target: this
            }),
            // åˆ é™¤äº‹ä»¶
            remove: () => {
@@ -1309,7 +1333,7 @@
              let deleteRows = this.filterNewRows(this.selectedRows)
              // è§¦å‘删除事件
              if (deleteRows.length > 0) {
                let removeEvent = {deleteRows, $table, target: this}
                let removeEvent = { deleteRows, $table, target: this }
                if (this.asyncRemove) {
                  // ç¡®è®¤åˆ é™¤ï¼Œåªæœ‰è°ƒç”¨è¿™ä¸ªæ–¹æ³•才会真删除
                  removeEvent.confirmRemove = () => this.removeSelection()
@@ -1326,8 +1350,8 @@
          },
          scopedSlots: {
            toolbarPrefix: this.$scopedSlots.toolbarPrefix,
            toolbarSuffix: this.$scopedSlots.toolbarSuffix,
          },
            toolbarSuffix: this.$scopedSlots.toolbarSuffix
          }
        })
      }
      return null
@@ -1345,7 +1369,7 @@
        return h('j-vxe-sub-popover', {
          ref: 'subPopover',
          scopedSlots: {
            subForm: this.$scopedSlots.subForm,
            subForm: this.$scopedSlots.subForm
          }
        })
      }
@@ -1374,17 +1398,17 @@
          },
          on: {
            change: (e) => this.trigger('pageChange', e)
          },
          }
        })
      }
      return null
    },
    loadExcludeCode(){
      if(!this.authPre || this.authPre.length==0){
    loadExcludeCode() {
      if (!this.authPre || this.authPre.length == 0) {
        this.excludeCode = []
      }else{
      } else {
        let pre = this.authPre
        if(!pre.endsWith(':')){
        if (!pre.endsWith(':')) {
          pre += ':'
        }
        this.excludeCode = getNoAuthCols(pre)
@@ -1401,7 +1425,7 @@
      this.renderToolbar(h),
      this.renderToolbarAfterSlot(),
      this.renderVxeGrid(h),
      this.renderPagination(h),
      this.renderPagination(h)
    ])
  },
  beforeDestroy() {
@@ -1411,23 +1435,27 @@
// å…¼å®¹ online çš„规则
const fooPatterns = [
  {title: '非空', value: '*', pattern: /^.+$/},
  {title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,16}$/},
  {title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/},
  {title: '6到18位字母', value: 's6-18', pattern: /^[a-z|A-Z]{6,18}$/},
  {title: '网址', value: 'url', pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/},
  {title: '电子邮件', value: 'e', pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/},
  {title: '手机号码', value: 'm', pattern: /^1[3456789]\d{9}$/},
  {title: '邮政编码', value: 'p', pattern: /^[0-9]{6}$/},
  {title: '字母', value: 's', pattern: /^[A-Z|a-z]+$/},
  {title: '数字', value: 'n', pattern: /^-?\d+(\.?\d+|\d?)$/},
  {title: '整数', value: 'z', pattern: /^-?\d+$/},
  {title: '金额', value: 'money', pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,5}))$/},
  { title: '非空', value: '*', pattern: /^.+$/ },
  { title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,16}$/ },
  { title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/ },
  { title: '6到18位字母', value: 's6-18', pattern: /^[a-z|A-Z]{6,18}$/ },
  {
    title: '网址',
    value: 'url',
    pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/
  },
  { title: '电子邮件', value: 'e', pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/ },
  { title: '手机号码', value: 'm', pattern: /^1[3456789]\d{9}$/ },
  { title: '邮政编码', value: 'p', pattern: /^[0-9]{6}$/ },
  { title: '字母', value: 's', pattern: /^[A-Z|a-z]+$/ },
  { title: '数字', value: 'n', pattern: /^-?\d+(\.?\d+|\d?)$/ },
  { title: '整数', value: 'z', pattern: /^-?\d+$/ },
  { title: '金额', value: 'money', pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,5}))$/ }
]
/** æ—§ç‰ˆhandler转为新版Validator */
function handlerConvertToValidator(event) {
  const {column, rule} = event
  const { column, rule } = event
  return new Promise((resolve, reject) => {
    rule.handler(event, (flag, msg) => {
      let message = rule.message
@@ -1447,7 +1475,7 @@
/** å”¯ä¸€æ ¡éªŒå™¨ */
function uniqueValidator(event) {
  const {cellValue, column, rule} = event
  const { cellValue, column, rule } = event
  let tableData = this.getTableData()
  let findCount = 0
  for (let rowData of tableData) {
src/mixins/JVxeTableMixin.js
@@ -53,11 +53,14 @@
        console.warn('由于你没有在 data ä¸­å®šä¹‰ addDefaultRowNum æˆ– addDefaultRowNum ä¸æ˜¯æ•°å­—,所以默认添加一条空数据,如果不想默认添加空数据,请将定义 addDefaultRowNum ä¸º 0')
      }
      //update-begin-author:taoyan date:20210315 for: ä¸€å¯¹å¤šjvex é»˜è®¤å‡ è¡Œä¸å¥½ä½¿äº† LOWCOD-1349
      this.eachAllTable((item) => {
        setTimeout(()=>{
        /*   item.addRows() */
        }, 30)
      })
      if (rowNum > 0) {
        let newRows = new Array(rowNum).fill({})
        this.eachAllTable((item) => {
          setTimeout(()=>{
            item.addRows(newRows)
          }, 30)
        })
      }
       //update-end-author:taoyan date:20210315 for: ä¸€å¯¹å¤šjvex é»˜è®¤å‡ è¡Œä¸å¥½ä½¿äº† LOWCOD-1349
      if (typeof this.addAfter === 'function') this.addAfter(this.model)
      this.edit({})
src/mixins/JVxeTableModelMixin.js
@@ -52,13 +52,16 @@
        rowNum = 1
        console.warn('由于你没有在 data ä¸­å®šä¹‰ addDefaultRowNum æˆ– addDefaultRowNum ä¸æ˜¯æ•°å­—,所以默认添加一条空数据,如果不想默认添加空数据,请将定义 addDefaultRowNum ä¸º 0')
      }
      this.eachAllTable((item) => {
        //update-begin-author:taoyan date:20210315 for: ä¸€å¯¹å¤šjvex é»˜è®¤å‡ è¡Œä¸å¥½ä½¿äº† LOWCOD-1349
        setTimeout(()=>{
         /*  item.addRows() */
        }, 30)
        //update-end-author:taoyan date:20210315 for: ä¸€å¯¹å¤šjvex é»˜è®¤å‡ è¡Œä¸å¥½ä½¿äº† LOWCOD-1349
      })
      if (rowNum > 0) {
        let newRows = new Array(rowNum).fill({})
        this.eachAllTable((item) => {
          //update-begin-author:taoyan date:20210315 for: ä¸€å¯¹å¤šjvex é»˜è®¤å‡ è¡Œä¸å¥½ä½¿äº† LOWCOD-1349
          setTimeout(()=>{
            item.addRows(newRows)
          }, 30)
          //update-end-author:taoyan date:20210315 for: ä¸€å¯¹å¤šjvex é»˜è®¤å‡ è¡Œä¸å¥½ä½¿äº† LOWCOD-1349
        })
      }
      if (typeof this.addAfter === 'function') this.addAfter(this.model)
      this.edit(this.model)
    },
src/utils/encryption/signMd5Utils.js
@@ -104,23 +104,35 @@
    return paramStr;
  };
  static getDateTimeToString() {
    const date_ = new Date()
    const year = date_.getFullYear()
    let month = date_.getMonth() + 1
    let day = date_.getDate()
    if (month < 10) month = '0' + month
    if (day < 10) day = '0' + day
    let hours = date_.getHours()
    let mins = date_.getMinutes()
    let secs = date_.getSeconds()
    const msecs = date_.getMilliseconds()
    if (hours < 10) hours = '0' + hours
    if (mins < 10) mins = '0' + mins
    if (secs < 10) secs = '0' + secs
    if (msecs < 10) secs = '0' + msecs
    return year + '' + month + '' + day + '' + hours + '' + mins + '' + secs
  /**
   * æŽ¥å£ç­¾åç”¨ ç”Ÿæˆheader中的时间戳
   * @returns {number}
   */
  static getTimestamp(){
    return new Date().getTime()
  }
  // /**
  //  * èŽ·å–å®¢æˆ·ç«¯æ—¶é—´ï¼ˆç­¾åå‚æ•° X_TIMESTAMP)
  //  * @returns {string}
  //  */
  // static getDateTimeToString() {
  //   const date_ = new Date()
  //   const year = date_.getFullYear()
  //   let month = date_.getMonth() + 1
  //   let day = date_.getDate()
  //   if (month < 10) month = '0' + month
  //   if (day < 10) day = '0' + day
  //   let hours = date_.getHours()
  //   let mins = date_.getMinutes()
  //   let secs = date_.getSeconds()
  //   const msecs = date_.getMilliseconds()
  //   if (hours < 10) hours = '0' + hours
  //   if (mins < 10) mins = '0' + mins
  //   if (secs < 10) secs = '0' + secs
  //   if (msecs < 10) secs = '0' + msecs
  //   return year + '' + month + '' + day + '' + hours + '' + mins + '' + secs
  // }
    // true:数值型的,false:非数值型
  static myIsNaN(value) {
    return typeof value === 'number' && !isNaN(value);
src/views/eam/DeductionItemList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,210 @@
<template>
  <a-card :bordered="false">
    <!-- æŸ¥è¯¢åŒºåŸŸ -->
    <div class="table-page-search-wrapper">
      <a-form layout="inline" @keyup.enter.native="searchQuery">
        <a-row :gutter="24">
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="编号">
              <a-input placeholder="请输入编号" v-model="queryParam.num"></a-input>
            </a-form-item>
          </a-col>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="内容">
              <a-input placeholder="请输入内容" v-model="queryParam.content"></a-input>
            </a-form-item>
          </a-col>
          <template v-if="toggleSearchStatus">
            <a-col :xl="6" :lg="7" :md="8" :sm="24">
              <a-form-item label="分数">
                <a-input placeholder="请输入分数" v-model="queryParam.deductionScore"></a-input>
              </a-form-item>
            </a-col>
          </template>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
              <a @click="handleToggleSearch" style="margin-left: 8px">
                {{ toggleSearchStatus ? '收起' : '展开' }}
                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
              </a>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>
    <!-- æŸ¥è¯¢åŒºåŸŸ-END -->
    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
    <div class="table-operator">
      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
      <a-button type="primary" icon="download" @click="handleExportXls('操作计分规则')">导出</a-button>
      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
        <a-button type="primary" icon="import">导入</a-button>
      </a-upload>
      <!-- é«˜çº§æŸ¥è¯¢åŒºåŸŸ -->
<!--      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
      <a-dropdown v-if="selectedRowKeys.length > 0">
        <a-menu slot="overlay">
          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
        </a-menu>
        <a-button style="margin-left: 8px"> æ‰¹é‡æ“ä½œ <a-icon type="down" /></a-button>
      </a-dropdown>
    </div>
    <!-- table区域-begin -->
    <div>
      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
        <i class="anticon anticon-info-circle ant-alert-icon"></i> å·²é€‰æ‹© <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
      </div>
      <a-table
        ref="table"
        size="middle"
        :scroll="{x:true}"
        bordered
        rowKey="id"
        :columns="columns"
        :dataSource="dataSource"
        :pagination="ipagination"
        :loading="loading"
        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
        class="j-table-force-nowrap"
        @change="handleTableChange">
        <template slot="htmlSlot" slot-scope="text">
          <div v-html="text"></div>
        </template>
        <template slot="imgSlot" slot-scope="text,record">
          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
        </template>
        <template slot="fileSlot" slot-scope="text">
          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
          <a-button
            v-else
            :ghost="true"
            type="primary"
            icon="download"
            size="small"
            @click="downloadFile(text)">
            ä¸‹è½½
          </a-button>
        </template>
        <span slot="action" slot-scope="text, record">
          <a @click="handleEdit(record)">编辑</a>
          <a-divider type="vertical" />
          <a-dropdown>
            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
            <a-menu slot="overlay">
              <a-menu-item>
                <a @click="handleDetail(record)">详情</a>
              </a-menu-item>
              <a-menu-item>
                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
                  <a>删除</a>
                </a-popconfirm>
              </a-menu-item>
            </a-menu>
          </a-dropdown>
        </span>
      </a-table>
    </div>
    <deduction-item-modal ref="modalForm" @ok="modalFormOk"></deduction-item-modal>
  </a-card>
</template>
<script>
  import '@/assets/less/TableExpand.less'
  import { mixinDevice } from '@/utils/mixin'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import DeductionItemModal from './modules/deductionItem/DeductionItemModal'
  export default {
    name: 'DeductionItemList',
    mixins:[JeecgListMixin, mixinDevice],
    components: {
      DeductionItemModal
    },
    data () {
      return {
        description: '操作计分规则管理页面',
        // è¡¨å¤´
        columns: [
          {
            title: '#',
            dataIndex: '',
            key:'rowIndex',
            width:60,
            align:"center",
            customRender:function (t,r,index) {
              return parseInt(index)+1;
            }
          },
          {
            title:'编号',
            align:"center",
            dataIndex: 'num'
          },
          {
            title:'内容',
            align:"center",
            dataIndex: 'content'
          },
          {
            title:'分数',
            align:"center",
            dataIndex: 'deductionScore'
          },
          {
            title: '操作',
            dataIndex: 'action',
            align:"center",
            fixed:"right",
            width:147,
            scopedSlots: { customRender: 'action' }
          }
        ],
        url: {
          list: "/eam/deductionItem/list",
          delete: "/eam/deductionItem/delete",
          deleteBatch: "/eam/deductionItem/deleteBatch",
          exportXlsUrl: "/eam/deductionItem/exportXls",
          importExcelUrl: "eam/deductionItem/importExcel",
        },
        dictOptions:{},
        superFieldList:[],
      }
    },
    created() {
    this.getSuperFieldList();
    },
    computed: {
      importExcelUrl: function(){
        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
      },
    },
    methods: {
      initDictConfig(){
      },
      getSuperFieldList(){
        let fieldList=[];
        fieldList.push({type:'string',value:'num',text:'编号',dictCode:''})
        fieldList.push({type:'string',value:'content',text:'内容',dictCode:''})
        fieldList.push({type:'int',value:'deductionScore',text:'分数',dictCode:''})
        this.superFieldList = fieldList
      }
    }
  }
</script>
<style scoped>
  @import '~@assets/less/common.less';
</style>
src/views/eam/OperationCertificateApplyList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,234 @@
<template>
  <a-card :bordered="false">
    <!-- æŸ¥è¯¢åŒºåŸŸ -->
    <div class="table-page-search-wrapper">
      <a-form layout="inline" @keyup.enter.native="searchQuery">
        <a-row :gutter="24">
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="申请单编号">
              <a-input placeholder="请输入申请单编号" v-model="queryParam.num"></a-input>
            </a-form-item>
          </a-col>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="类型">
              <j-dict-select-tag placeholder="请选择类型" v-model="queryParam.type" dictCode="apply_type"/>
            </a-form-item>
          </a-col>
          <template v-if="toggleSearchStatus">
            <a-col :xl="6" :lg="7" :md="8" :sm="24">
              <a-form-item label="审核状态">
                <j-dict-select-tag placeholder="请选择审核状态" v-model="queryParam.auditStatus" dictCode="certificate_apply_status"/>
              </a-form-item>
            </a-col>
          </template>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
              <a @click="handleToggleSearch" style="margin-left: 8px">
                {{ toggleSearchStatus ? '收起' : '展开' }}
                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
              </a>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>
    <!-- æŸ¥è¯¢åŒºåŸŸ-END -->
    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
    <div class="table-operator">
      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
      <a-button type="primary" icon="download" @click="handleExportXls('操作证申请表')">导出</a-button>
      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
        <a-button type="primary" icon="import">导入</a-button>
      </a-upload>
      <!-- é«˜çº§æŸ¥è¯¢åŒºåŸŸ -->
<!--      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
      <a-dropdown v-if="selectedRowKeys.length > 0">
        <a-menu slot="overlay">
          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
        </a-menu>
        <a-button style="margin-left: 8px"> æ‰¹é‡æ“ä½œ <a-icon type="down" /></a-button>
      </a-dropdown>
    </div>
    <!-- table区域-begin -->
    <div>
      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
        <i class="anticon anticon-info-circle ant-alert-icon"></i> å·²é€‰æ‹© <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
      </div>
      <a-table
        ref="table"
        size="middle"
        bordered
        rowKey="id"
        class="j-table-force-nowrap"
        :scroll="{x:true}"
        :columns="columns"
        :dataSource="dataSource"
        :pagination="ipagination"
        :loading="loading"
        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
        @change="handleTableChange">
        <template slot="htmlSlot" slot-scope="text">
          <div v-html="text"></div>
        </template>
        <template slot="imgSlot" slot-scope="text,record">
          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
        </template>
        <template slot="fileSlot" slot-scope="text">
          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
          <a-button
            v-else
            :ghost="true"
            type="primary"
            icon="download"
            size="small"
            @click="downloadFile(text)">
            ä¸‹è½½
          </a-button>
        </template>
        <span slot="action" slot-scope="text, record">
          <a @click="handleEdit(record)">编辑</a>
          <a-divider type="vertical" />
          <a-dropdown>
            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
            <a-menu slot="overlay">
              <a-menu-item>
                <a @click="handleDetail(record)">详情</a>
              </a-menu-item>
              <a-menu-item>
                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
                  <a>删除</a>
                </a-popconfirm>
              </a-menu-item>
            </a-menu>
          </a-dropdown>
        </span>
      </a-table>
    </div>
    <operation-certificate-apply-modal ref="modalForm" @ok="modalFormOk"/>
  </a-card>
</template>
<script>
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import OperationCertificateApplyModal from './modules/operationCertificateApply/OperationCertificateApplyModal'
  import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
  import '@/assets/less/TableExpand.less'
  export default {
    name: "OperationCertificateApplyList",
    mixins:[JeecgListMixin],
    components: {
      OperationCertificateApplyModal
    },
    data () {
      return {
        description: '操作证申请表管理页面',
        // è¡¨å¤´
        columns: [
          {
            title: '#',
            dataIndex: '',
            key:'rowIndex',
            width:60,
            align:"center",
            customRender:function (t,r,index) {
              return parseInt(index)+1;
            }
          },
          {
            title:'申请单编号',
            align:"center",
            dataIndex: 'num'
          },
          {
            title:'类型',
            align:"center",
            dataIndex: 'type_dictText'
          },
          {
            title:'所在单位',
            align:"center",
            dataIndex: 'departId_dictText'
          },
          {
            title:'申请单位联系电话',
            align:"center",
            dataIndex: 'contactNumber'
          },
          {
            title:'申请人',
            align:"center",
            dataIndex: 'applicant_dictText'
          },
          {
            title:'审核状态',
            align:"center",
            dataIndex: 'auditStatus_dictText'
          },
          {
            title:'备注',
            align:"center",
            dataIndex: 'remark'
          },
          {
            title: '操作',
            dataIndex: 'action',
            align:"center",
            fixed:"right",
            width:147,
            scopedSlots: { customRender: 'action' },
          }
        ],
        url: {
          list: "/eam/operationCertificateApply/list",
          delete: "/eam/operationCertificateApply/delete",
          deleteBatch: "/eam/operationCertificateApply/deleteBatch",
          exportXlsUrl: "/eam/operationCertificateApply/exportXls",
          importExcelUrl: "eam/operationCertificateApply/importExcel",
        },
        dictOptions:{},
        superFieldList:[],
      }
    },
    created() {
      this.getSuperFieldList();
    },
    computed: {
      importExcelUrl: function(){
        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
      }
    },
    methods: {
      initDictConfig(){
      },
      getSuperFieldList(){
        let fieldList=[];
        fieldList.push({type:'string',value:'num',text:'申请单编号',dictCode:''})
        fieldList.push({type:'string',value:'type',text:'类型',dictCode:'apply_type'})
        fieldList.push({type:'sel_depart',value:'departId',text:'所在单位'})
        fieldList.push({type:'string',value:'contactNumber',text:'申请单位联系电话',dictCode:''})
        fieldList.push({type:'string',value:'applicant',text:'申请人',dictCode:"sys_user,realname,id"})
        fieldList.push({type:'string',value:'auditStatus',text:'审核状态',dictCode:'certificate_apply_status'})
        fieldList.push({type:'string',value:'remark',text:'备注',dictCode:''})
        this.superFieldList = fieldList
      }
    }
  }
</script>
<style scoped>
  @import '~@assets/less/common.less';
</style>
src/views/eam/OperationCertificateList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,260 @@
<template>
  <a-card :bordered="false">
    <!-- æŸ¥è¯¢åŒºåŸŸ -->
    <div class="table-page-search-wrapper">
      <a-form layout="inline" @keyup.enter.native="searchQuery">
        <a-row :gutter="24">
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="操作证编号">
              <a-input placeholder="请输入操作证编号" v-model="queryParam.num"></a-input>
            </a-form-item>
          </a-col>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="用户ID">
              <j-select-user-by-dep placeholder="请选择用户ID" v-model="queryParam.userId"/>
            </a-form-item>
          </a-col>
          <template v-if="toggleSearchStatus">
            <a-col :xl="6" :lg="7" :md="8" :sm="24">
              <a-form-item label="发证日期">
                <j-date placeholder="请选择发证日期" v-model="queryParam.issueDate"></j-date>
              </a-form-item>
            </a-col>
            <a-col :xl="6" :lg="7" :md="8" :sm="24">
              <a-form-item label="设备统一编码">
                <j-multi-select-tag placeholder="请选择设备统一编码" dictCode="mom_eam_equipment,num,id" v-model="queryParam.equipmentIds"/>
              </a-form-item>
            </a-col>
          </template>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
              <a @click="handleToggleSearch" style="margin-left: 8px">
                {{ toggleSearchStatus ? '收起' : '展开' }}
                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
              </a>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>
    <!-- æŸ¥è¯¢åŒºåŸŸ-END -->
    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
    <div class="table-operator">
      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
      <a-button type="primary" icon="download" @click="handleExportXls('操作证书管理')">导出</a-button>
      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
        <a-button type="primary" icon="import">导入</a-button>
      </a-upload>
      <!-- é«˜çº§æŸ¥è¯¢åŒºåŸŸ -->
<!--      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
<!--      <a-dropdown v-if="selectedRowKeys.length > 0">-->
<!--        <a-menu slot="overlay">-->
<!--          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>-->
<!--        </a-menu>-->
<!--        <a-button style="margin-left: 8px"> æ‰¹é‡æ“ä½œ <a-icon type="down" /></a-button>-->
<!--      </a-dropdown>-->
    </div>
    <!-- table区域-begin -->
    <div>
      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
        <i class="anticon anticon-info-circle ant-alert-icon"></i> å·²é€‰æ‹© <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
      </div>
      <a-table
        ref="table"
        size="middle"
        bordered
        rowKey="id"
        class="j-table-force-nowrap"
        :scroll="{x:true}"
        :columns="columns"
        :dataSource="dataSource"
        :pagination="ipagination"
        :loading="loading"
        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
        @change="handleTableChange">
        <template slot="htmlSlot" slot-scope="text">
          <div v-html="text"></div>
        </template>
        <template slot="imgSlot" slot-scope="text,record">
          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
        </template>
        <template slot="fileSlot" slot-scope="text">
          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
          <a-button
            v-else
            :ghost="true"
            type="primary"
            icon="download"
            size="small"
            @click="downloadFile(text)">
            ä¸‹è½½
          </a-button>
        </template>
        <span slot="action" slot-scope="text, record">
          <a @click="handleEdit(record)">编辑</a>
          <a-divider type="vertical" />
          <a-dropdown>
            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
            <a-menu slot="overlay">
              <a-menu-item>
                <a @click="handleDetail(record)">详情</a>
              </a-menu-item>
              <a-menu-item>
                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
                  <a>删除</a>
                </a-popconfirm>
              </a-menu-item>
            </a-menu>
          </a-dropdown>
        </span>
      </a-table>
    </div>
    <operation-certificate-modal ref="modalForm" @ok="modalFormOk"/>
  </a-card>
</template>
<script>
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import OperationCertificateModal from './modules/operationCertificate/OperationCertificateModal'
  import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
  import '@/assets/less/TableExpand.less'
  export default {
    name: "OperationCertificateList",
    mixins:[JeecgListMixin],
    components: {
      OperationCertificateModal
    },
    data () {
      return {
        description: '操作证书管理管理页面',
        // è¡¨å¤´
        columns: [
          {
            title: '#',
            dataIndex: '',
            key:'rowIndex',
            width:60,
            align:"center",
            customRender:function (t,r,index) {
              return parseInt(index)+1;
            }
          },
          {
            title:'操作证编号',
            align:"center",
            dataIndex: 'num'
          },
          {
            title:'用户ID',
            align:"center",
            dataIndex: 'userId_dictText'
          },
          {
            title:'发证日期',
            align:"center",
            dataIndex: 'issueDate',
            customRender:function (text) {
              return !text?"":(text.length>10?text.substr(0,10):text)
            }
          },
          {
            title:'开始时间',
            align:"center",
            dataIndex: 'startTime',
            customRender:function (text) {
              return !text?"":(text.length>10?text.substr(0,10):text)
            }
          },
          {
            title:'结束时间',
            align:"center",
            dataIndex: 'endTime',
            customRender:function (text) {
              return !text?"":(text.length>10?text.substr(0,10):text)
            }
          },
          {
            title:'当前周期分数',
            align:"center",
            dataIndex: 'currentCycleScore'
          },
          {
            title:'设备统一编码',
            align:"center",
            dataIndex: 'equipmentIds_dictText'
          },
          {
            title:'备注',
            align:"center",
            dataIndex: 'remark'
          },
          {
            title:'状态',
            align:"center",
            dataIndex: 'status_dictText'
          },
          {
            title: '操作',
            dataIndex: 'action',
            align:"center",
            fixed:"right",
            width:147,
            scopedSlots: { customRender: 'action' },
          }
        ],
        url: {
          list: "/eam/operationCertificate/list",
          delete: "/eam/operationCertificate/delete",
          deleteBatch: "/eam/operationCertificate/deleteBatch",
          exportXlsUrl: "/eam/operationCertificate/exportXls",
          importExcelUrl: "eam/operationCertificate/importExcel",
        },
        dictOptions:{},
        superFieldList:[],
      }
    },
    created() {
      this.getSuperFieldList();
    },
    computed: {
      importExcelUrl: function(){
        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
      }
    },
    methods: {
      initDictConfig(){
      },
      getSuperFieldList(){
        let fieldList=[];
        fieldList.push({type:'string',value:'num',text:'操作证编号',dictCode:''})
        fieldList.push({type:'sel_user',value:'userId',text:'用户ID'})
        fieldList.push({type:'date',value:'issueDate',text:'发证日期'})
        fieldList.push({type:'date',value:'startTime',text:'开始时间'})
        fieldList.push({type:'date',value:'endTime',text:'结束时间'})
        fieldList.push({type:'int',value:'currentCycleScore',text:'当前周期分数',dictCode:''})
        fieldList.push({type:'list_multi',value:'equipmentIds',text:'设备统一编码',dictTable:"mom_eam_equipment", dictText:'num', dictCode:'id'})
        fieldList.push({type:'string',value:'remark',text:'备注',dictCode:''})
        fieldList.push({type:'string',value:'status',text:'状态',dictCode:'certificate_status'})
        this.superFieldList = fieldList
      }
    }
  }
</script>
<style scoped>
  @import '~@assets/less/common.less';
</style>
src/views/eam/modules/deductionItem/DeductionItemForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
<template>
  <a-spin :spinning="confirmLoading">
    <j-form-container :disabled="formDisabled">
      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
        <a-row>
          <a-col :span="24">
            <a-form-model-item label="编号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="num">
              <a-input v-model="model.num" placeholder="请输入编号"  ></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item label="内容" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="content">
              <a-input v-model="model.content" placeholder="请输入内容"  ></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item label="分数" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="deductionScore">
              <a-input-number v-model="model.deductionScore" placeholder="请输入分数" style="width: 100%" />
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
  </a-spin>
</template>
<script>
  import { httpAction, getAction } from '@/api/manage'
  import { validateDuplicateValue } from '@/utils/util'
  export default {
    name: 'DeductionItemForm',
    components: {
    },
    props: {
      //表单禁用
      disabled: {
        type: Boolean,
        default: false,
        required: false
      }
    },
    data () {
      return {
        model:{
         },
        labelCol: {
          xs: { span: 24 },
          sm: { span: 5 },
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 16 },
        },
        confirmLoading: false,
        validatorRules: {
        },
        url: {
          add: "/eam/deductionItem/add",
          edit: "/eam/deductionItem/edit",
          queryById: "/eam/deductionItem/queryById"
        }
      }
    },
    computed: {
      formDisabled(){
        return this.disabled
      },
    },
    created () {
       //备份model原始值
      this.modelDefault = JSON.parse(JSON.stringify(this.model));
    },
    methods: {
      add () {
        this.edit(this.modelDefault);
      },
      edit (record) {
        this.model = Object.assign({}, record);
        this.visible = true;
      },
      submitForm () {
        const that = this;
        // è§¦å‘表单验证
        this.$refs.form.validate(valid => {
          if (valid) {
            that.confirmLoading = true;
            let httpurl = '';
            let method = '';
            if(!this.model.id){
              httpurl+=this.url.add;
              method = 'post';
            }else{
              httpurl+=this.url.edit;
               method = 'put';
            }
            httpAction(httpurl,this.model,method).then((res)=>{
              if(res.success){
                that.$message.success(res.message);
                that.$emit('ok');
              }else{
                that.$message.warning(res.message);
              }
            }).finally(() => {
              that.confirmLoading = false;
            })
          }
        })
      },
    }
  }
</script>
src/views/eam/modules/deductionItem/DeductionItemModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
<template>
  <j-modal
    :title="title"
    :width="width"
    :visible="visible"
    switchFullscreen
    @ok="handleOk"
    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
    @cancel="handleCancel"
    cancelText="关闭">
    <deduction-item-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></deduction-item-form>
  </j-modal>
</template>
<script>
  import DeductionItemForm from './DeductionItemForm'
  export default {
    name: 'DeductionItemModal',
    components: {
      DeductionItemForm
    },
    data () {
      return {
        title:'',
        width:800,
        visible: false,
        disableSubmit: false
      }
    },
    methods: {
      add () {
        this.visible=true
        this.$nextTick(()=>{
          this.$refs.realForm.add();
        })
      },
      edit (record) {
        this.visible=true
        this.$nextTick(()=>{
          this.$refs.realForm.edit(record);
        })
      },
      close () {
        this.$emit('close');
        this.visible = false;
      },
      handleOk () {
        this.$refs.realForm.submitForm();
      },
      submitCallback(){
        this.$emit('ok');
        this.visible = false;
      },
      handleCancel () {
        this.close()
      }
    }
  }
</script>
src/views/eam/modules/operationCertificate/OperationCertificateForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,240 @@
<template>
  <a-spin :spinning="confirmLoading">
    <j-form-container :disabled="formDisabled">
      <!-- ä¸»è¡¨å•区域 -->
      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
        <a-row>
          <a-col :span="12" >
            <a-form-model-item label="操作证编号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="num">
              <a-input v-model="model.num" placeholder="请输入操作证编号" ></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span="12" >
            <a-form-model-item label="用户ID" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="userId">
              <j-select-user-by-dep v-model="model.userId" :multi="true" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12" >
            <a-form-model-item label="发证日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="issueDate">
              <j-date placeholder="请选择发证日期" v-model="model.issueDate" style="width: 100%" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12" >
            <a-form-model-item label="开始时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="startTime">
              <j-date placeholder="请选择开始时间" v-model="model.startTime" style="width: 100%" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12" >
            <a-form-model-item label="结束时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="endTime">
              <j-date placeholder="请选择结束时间" v-model="model.endTime" style="width: 100%" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12" >
            <a-form-model-item label="当前周期分数" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="currentCycleScore">
              <a-input-number v-model="model.currentCycleScore" placeholder="请输入当前周期分数" style="width: 100%" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12" >
            <a-form-model-item label="设备统一编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentIds">
              <j-multi-select-tag type="list_multi" v-model="model.equipmentIds" dictCode="mom_eam_equipment,num,id" placeholder="请选择设备统一编码" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12" >
            <a-form-model-item label="状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="status">
              <j-dict-select-tag type="list" v-model="model.status" dictCode="certificate_status" placeholder="请选择状态" disabled/>
            </a-form-model-item>
          </a-col>
          <a-col :span="24" >
            <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
              <a-textarea v-model="model.remark" placeholder="请输入备注" ></a-textarea>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
      <!-- å­è¡¨å•区域 -->
    <a-tabs v-model="activeKey" @change="handleChangeTabs">
      <a-tab-pane tab="操作证管理明细" :key="refKeys[0]" :forceRender="true">
        <j-vxe-table
          keep-source
          :ref="refKeys[0]"
          :loading="operationCertificateDetailTable.loading"
          :columns="operationCertificateDetailTable.columns"
          :dataSource="operationCertificateDetailTable.dataSource"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="true"
          :toolbar="true"
          />
      </a-tab-pane>
    </a-tabs>
  </a-spin>
</template>
<script>
  import { getAction } from '@/api/manage'
  import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
  import { JVXETypes } from '@/components/jeecg/JVxeTable'
  import { getRefPromise,VALIDATE_FAILED} from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
  import { validateDuplicateValue } from '@/utils/util'
  import JFormContainer from '@/components/jeecg/JFormContainer'
  export default {
    name: 'OperationCertificateForm',
    mixins: [JVxeTableModelMixin],
    components: {
      JFormContainer,
    },
    data() {
      return {
        labelCol: {
          xs: { span: 24 },
          sm: { span: 5 },
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 16 },
        },
        model:{
         },
        // æ–°å¢žæ—¶å­è¡¨é»˜è®¤æ·»åŠ å‡ è¡Œç©ºæ•°æ®
        addDefaultRowNum: 1,
        validatorRules: {
           num: [
              { required: true, message: '请输入操作证编号!'},
           ],
           currentCycleScore: [
              { required: true, message: '请输入当前周期分数!'},
              { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
           ],
        },
        refKeys: ['operationCertificateDetail', ],
        tableKeys:['operationCertificateDetail', ],
        activeKey: 'operationCertificateDetail',
        // æ“ä½œè¯ç®¡ç†æ˜Žç»†
        operationCertificateDetailTable: {
          loading: false,
          dataSource: [],
          columns: [
            {
              title: '证书ID',
              key: 'operationCertificateId',
               type: JVXETypes.input,
              width:"200px",
              placeholder: '请输入${title}',
              defaultValue:'',
            },
            {
              title: '类型',
              key: 'type',
               type: JVXETypes.input,
              width:"200px",
              placeholder: '请输入${title}',
              defaultValue:'',
            },
            {
              title: '设备id',
              key: 'equipmentId',
               type: JVXETypes.input,
              width:"200px",
              placeholder: '请输入${title}',
              defaultValue:'',
            },
            {
              title: '扣分项',
              key: 'deductionItem',
               type: JVXETypes.input,
              width:"200px",
              placeholder: '请输入${title}',
              defaultValue:'',
            },
            {
              title: '扣分周期',
              key: 'period',
               type: JVXETypes.input,
              width:"200px",
              placeholder: '请输入${title}',
              defaultValue:'',
            },
          ]
        },
        url: {
          add: "/eam/operationCertificate/add",
          edit: "/eam/operationCertificate/edit",
          queryById: "/eam/operationCertificate/queryById",
          operationCertificateDetail: {
            list: '/eam/operationCertificate/queryOperationCertificateDetailByMainId'
          },
        }
      }
    },
    props: {
      //表单禁用
      disabled: {
        type: Boolean,
        default: false,
        required: false
      }
    },
    computed: {
      formDisabled(){
        return this.disabled
      },
    },
    created () {
    },
    methods: {
      addBefore(){
        this.operationCertificateDetailTable.dataSource=[]
      },
      getAllTable() {
        let values = this.tableKeys.map(key => getRefPromise(this, key))
        return Promise.all(values)
      },
      /** è°ƒç”¨å®Œedit()方法之后会自动调用此方法 */
      editAfter() {
        this.$nextTick(() => {
        })
        // åŠ è½½å­è¡¨æ•°æ®
        if (this.model.id) {
          let params = { id: this.model.id }
          this.requestSubTableData(this.url.operationCertificateDetail.list, params, this.operationCertificateDetailTable)
        }
      },
      //校验所有一对一子表表单
        validateSubForm(allValues){
            return new Promise((resolve,reject)=>{
              Promise.all([
              ]).then(() => {
                resolve(allValues)
              }).catch(e => {
                if (e.error === VALIDATE_FAILED) {
                  // å¦‚果有未通过表单验证的子表,就自动跳转到它所在的tab
                  this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
                } else {
                  console.error(e)
                }
              })
            })
        },
      /** æ•´ç†æˆformData */
      classifyIntoFormData(allValues) {
        let main = Object.assign(this.model, allValues.formValue)
        return {
          ...main, // å±•å¼€
          operationCertificateDetailList: allValues.tablesValue[0].tableData,
        }
      },
      validateError(msg){
        this.$message.error(msg)
      },
    }
  }
</script>
<style scoped>
</style>
src/views/eam/modules/operationCertificate/OperationCertificateModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
<template>
  <j-modal
    :title="title"
    :width="1200"
    :visible="visible"
    :maskClosable="false"
    switchFullscreen
    @ok="handleOk"
    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
    @cancel="handleCancel">
    <operation-certificate-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"/>
  </j-modal>
</template>
<script>
  import OperationCertificateForm from './OperationCertificateForm'
  export default {
    name: 'OperationCertificateModal',
    components: {
      OperationCertificateForm
    },
    data() {
      return {
        title:'',
        width:800,
        visible: false,
        disableSubmit: false
      }
    },
    methods:{
      add () {
        this.visible=true
        this.$nextTick(()=>{
          this.$refs.realForm.add();
        })
      },
      edit (record) {
        this.visible=true
        this.$nextTick(()=>{
          this.$refs.realForm.edit(record);
        })
      },
      close () {
        this.$emit('close');
        this.visible = false;
      },
      handleOk () {
        this.$refs.realForm.handleOk();
      },
      submitCallback(){
        this.$emit('ok');
        this.visible = false;
      },
      handleCancel () {
        this.close()
      }
    }
  }
</script>
<style scoped>
</style>
src/views/eam/modules/operationCertificateApply/OperationCertificateApplyForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,280 @@
<template>
  <a-spin :spinning='confirmLoading'>
    <j-form-container :disabled='formDisabled'>
      <!-- ä¸»è¡¨å•区域 -->
      <a-form-model ref='form' :model='model' :rules='validatorRules' slot='detail'>
        <a-row>
          <a-col :span='12'>
            <a-form-model-item label='申请单编号' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='num'>
              <a-input v-model='model.num' placeholder='请输入申请单编号'></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span='12'>
            <a-form-model-item label='类型' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='type'>
              <j-dict-select-tag type='radio' v-model='model.type' dictCode='apply_type' placeholder='请选择类型' />
            </a-form-model-item>
          </a-col>
          <a-col :span='12'>
            <a-form-model-item label='所在单位' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='departId'>
              <j-select-depart v-model='model.departId' :multi='true' />
            </a-form-model-item>
          </a-col>
          <a-col :span='12'>
            <a-form-model-item label='联系电话' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='contactNumber'>
              <a-input v-model='model.contactNumber' placeholder='请输入联系电话'></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span='12'>
            <a-form-model-item label='申请人' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='applicant'>
              <j-dict-select-tag type='list' v-model='model.applicant' dictCode='sys_user,realname,id'
                                 placeholder='请选择申请人' disabled />
            </a-form-model-item>
          </a-col>
          <a-col :span='12'>
            <a-form-model-item label='审核状态' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='auditStatus'>
              <j-dict-select-tag type='list' v-model='model.auditStatus' dictCode='certificate_apply_status'
                                 placeholder='请选择审核状态' disabled />
            </a-form-model-item>
          </a-col>
          <a-col :span='24'>
            <a-form-model-item label='备注' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='remark'>
              <a-input v-model='model.remark' placeholder='请输入备注'></a-input>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
    <!-- å­è¡¨å•区域 -->
    <a-tabs v-model='activeKey' @change='handleChangeTabs'>
      <a-tab-pane tab='操作证申请明细表' :key='refKeys[0]' :forceRender='true'>
        <j-vxe-table
          keep-source
          :ref='refKeys[0]'
          :loading='operationCertificateApplyDetailTable.loading'
          :columns='operationCertificateApplyDetailTable.columns'
          :dataSource='operationCertificateApplyDetailTable.dataSource'
          :maxHeight='300'
          :disabled='formDisabled'
          :rowNumber='true'
          :rowSelection='true'
          :toolbar='true'
        />
      </a-tab-pane>
    </a-tabs>
  </a-spin>
</template>
<script>
import { getAction } from '@/api/manage'
import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
import { getRefPromise, VALIDATE_FAILED } from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
import { validateDuplicateValue } from '@/utils/util'
import JFormContainer from '@/components/jeecg/JFormContainer'
import store from '@/store'
export default {
  name: 'OperationCertificateApplyForm',
  mixins: [JVxeTableModelMixin],
  components: {
    JFormContainer
  },
  data() {
    return {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      },
      model: {
        auditStatus: 'created',
        type: 'normal',
        applicant: store.getters.userInfo.id,
      },
      // æ–°å¢žæ—¶å­è¡¨é»˜è®¤æ·»åŠ å‡ è¡Œç©ºæ•°æ®
      addDefaultRowNum: 1,
      validatorRules: {
        num: [
          { required: true, message: '请输入申请单编号!' }
        ],
        auditStatus: [
          { required: true, message: '请输入审核状态!' }
        ]
      },
      refKeys: ['operationCertificateApplyDetail'],
      tableKeys: ['operationCertificateApplyDetail'],
      activeKey: 'operationCertificateApplyDetail',
      // æ“ä½œè¯ç”³è¯·æ˜Žç»†è¡¨
      operationCertificateApplyDetailTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            title: '用户',
            key: 'userId',
            type: JVXETypes.userSelect,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{ required: true, message: '${title}不能为空' }]
          },
          // {
          //   title: '设备统一编码',
          //   key: 'equipmentIds',
          //   type: JVXETypes.input,
          //   dictCode: 'mom_eam_equipment,num,id ',
          //   width: '200px',
          //   placeholder: '请输入${title}',
          //   defaultValue: '',
          //   validateRules: [{ required: true, message: '${title}不能为空' }]
          // },
          {
            title: '设备统一编码',
            key: 'equipmentIds',
            type: JVXETypes.selectSearch,
            dictCode: 'mom_eam_equipment,num,id ',
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{ required: true, message: '${title}不能为空' }]
          },
          {
            title: '上岗证号',
            key: 'appointmentCardNum',
            type: JVXETypes.input,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{ required: true, message: '${title}不能为空' }]
          },
          {
            title: '补办原因',
            key: 'replaceReason',
            type: JVXETypes.input,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: ''
          },
          {
            title: '备注',
            key: 'remark',
            type: JVXETypes.textarea,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: ''
          },
          {
            title: '理论成绩',
            key: 'theoreticalResults',
            type: JVXETypes.input,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: ''
          },
          {
            title: '实操成绩',
            key: 'actualPerformance',
            type: JVXETypes.input,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: ''
          },
          {
            title: '考试结论',
            key: 'examinationConclusion',
            type: JVXETypes.checkbox,
            customValue: ['Y', 'N'],
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: ''
          },
          {
            title: '状态',
            key: 'status',
            type: JVXETypes.input,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: ''
          }
        ]
      },
      url: {
        add: '/eam/operationCertificateApply/add',
        edit: '/eam/operationCertificateApply/edit',
        queryById: '/eam/operationCertificateApply/queryById',
        operationCertificateApplyDetail: {
          list: '/eam/operationCertificateApply/queryOperationCertificateApplyDetailByMainId'
        }
      }
    }
  },
  props: {
    //表单禁用
    disabled: {
      type: Boolean,
      default: false,
      required: false
    }
  },
  computed: {
    formDisabled() {
      return this.disabled
    }
  },
  created() {
  },
  methods: {
    addBefore() {
      this.operationCertificateApplyDetailTable.dataSource = []
    },
    getAllTable() {
      let values = this.tableKeys.map(key => getRefPromise(this, key))
      return Promise.all(values)
    },
    /** è°ƒç”¨å®Œedit()方法之后会自动调用此方法 */
    editAfter() {
      this.$nextTick(() => {
      })
      // åŠ è½½å­è¡¨æ•°æ®
      if (this.model.id) {
        let params = { id: this.model.id }
        this.requestSubTableData(this.url.operationCertificateApplyDetail.list, params, this.operationCertificateApplyDetailTable)
      }
    },
    //校验所有一对一子表表单
    validateSubForm(allValues) {
      return new Promise((resolve, reject) => {
        Promise.all([]).then(() => {
          resolve(allValues)
        }).catch(e => {
          if (e.error === VALIDATE_FAILED) {
            // å¦‚果有未通过表单验证的子表,就自动跳转到它所在的tab
            this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
          } else {
            console.error(e)
          }
        })
      })
    },
    /** æ•´ç†æˆformData */
    classifyIntoFormData(allValues) {
      let main = Object.assign(this.model, allValues.formValue)
      return {
        ...main, // å±•å¼€
        operationCertificateApplyDetailList: allValues.tablesValue[0].tableData
      }
    },
    validateError(msg) {
      this.$message.error(msg)
    }
  }
}
</script>
<style scoped>
</style>
src/views/eam/modules/operationCertificateApply/OperationCertificateApplyModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
<template>
  <j-modal
    :title="title"
    :width="1400"
    :visible="visible"
    :maskClosable="false"
    switchFullscreen
    @ok="handleOk"
    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
    @cancel="handleCancel">
    <operation-certificate-apply-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"/>
  </j-modal>
</template>
<script>
  import OperationCertificateApplyForm from './OperationCertificateApplyForm'
  export default {
    name: 'OperationCertificateApplyModal',
    components: {
      OperationCertificateApplyForm
    },
    data() {
      return {
        title:'',
        width:800,
        visible: false,
        disableSubmit: false
      }
    },
    methods:{
      add () {
        this.visible=true
        this.$nextTick(()=>{
          this.$refs.realForm.add();
        })
      },
      edit (record) {
        this.visible=true
        this.$nextTick(()=>{
          this.$refs.realForm.edit(record);
        })
      },
      close () {
        this.$emit('close');
        this.visible = false;
      },
      handleOk () {
        this.$refs.realForm.handleOk();
      },
      submitCallback(){
        this.$emit('ok');
        this.visible = false;
      },
      handleCancel () {
        this.close()
      }
    }
  }
</script>
<style scoped>
</style>