From 73250e481e966dd8e3372c518530203ac047da14 Mon Sep 17 00:00:00 2001
From: zenglf <18502938215@163.com>
Date: 星期三, 18 十月 2023 09:29:26 +0800
Subject: [PATCH] 操作证申请表 操作证管理功能提交 操作证计分规则

---
 src/views/eam/OperationCertificateList.vue                                         |  260 ++++++++
 src/views/eam/modules/operationCertificate/OperationCertificateModal.vue           |   64 ++
 src/views/eam/modules/deductionItem/DeductionItemModal.vue                         |   60 +
 src/mixins/JVxeTableModelMixin.js                                                  |   17 
 src/views/eam/OperationCertificateApplyList.vue                                    |  234 +++++++
 src/views/eam/modules/deductionItem/DeductionItemForm.vue                          |  114 +++
 src/views/eam/modules/operationCertificate/OperationCertificateForm.vue            |  240 +++++++
 src/api/manage.js                                                                  |   12 
 src/views/eam/modules/operationCertificateApply/OperationCertificateApplyModal.vue |   64 ++
 src/views/eam/DeductionItemList.vue                                                |  210 ++++++
 src/views/eam/modules/operationCertificateApply/OperationCertificateApplyForm.vue  |  280 ++++++++
 src/components/JVxeCells/JVxePopupCell.vue                                         |    4 
 src/components/jeecg/JVxeTable/components/JVxeTable.js                             |  250 ++++---
 src/utils/encryption/signMd5Utils.js                                               |   44 
 src/mixins/JVxeTableMixin.js                                                       |   13 
 15 files changed, 1,724 insertions(+), 142 deletions(-)

diff --git a/src/api/manage.js b/src/api/manage.js
index 9472df5..2d86db1 100644
--- a/src/api/manage.js
+++ b/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,
diff --git a/src/components/JVxeCells/JVxePopupCell.vue b/src/components/JVxeCells/JVxePopupCell.vue
index 885933d..52c6be8 100644
--- a/src/components/JVxeCells/JVxePopupCell.vue
+++ b/src/components/JVxeCells/JVxePopupCell.vue
@@ -51,6 +51,10 @@
     enhanced: {
       aopEvents: {
         editActived(event) {
+          // 銆恑ssues/3854銆戦檮琛ㄦ帶浠剁被鍨嬩负popup蹇呭~鏃舵湭閫夋嫨鍊兼彁浜よ〃鍗曚細鎶ラ敊
+          if (event.$event && event.$event.type === 'valid-error') {
+            return;
+          }
           dispatchEvent.call(this, event, 'ant-input')
         },
       },
diff --git a/src/components/jeecg/JVxeTable/components/JVxeTable.js b/src/components/jeecg/JVxeTable/components/JVxeTable.js
index dd2e1fb..7d60fbb 100644
--- a/src/components/jeecg/JVxeTable/components/JVxeTable.js
+++ b/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 鍓嶇紑锛泂uffix 鍚庣紑锛�
       slots: ['prefix', 'suffix'],
       // add 鏂板鎸夐挳锛況emove 鍒犻櫎鎸夐挳锛沜learSelection 娓呯┖閫夋嫨鎸夐挳锛沜ollapse 灞曞紑鏀惰捣
-      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 },
       // 褰撳墠鏄惁姝e湪婊氬姩
       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: [],
       // 鑱斿姩涓嬫媺閫夐」锛堢敤浜庨殧绂讳笉鍚岀殑涓嬫媺閫夐」锛�
       // 鍐呴儴鑱斿姩閰嶇疆锛宮ap
-      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 銆恛nline銆� 鏃ユ湡銆佹椂闂存帶浠堕暱搴﹁緝灏�
         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 @@
 
           // 澶勭悊鎴恦xe鍙瘑鍒殑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 @@
               // 闃叉鍜寁xeTable鑷甫鐨則ype璧峰啿绐�
               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 @@
       // 銆恑ssues/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
       // 浠呮煡璇㈡寚瀹歩d鐨勮
       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锛氭病鏈夋壘鍒癷d涓�"${id}"鐨勮`)
-          return {row: null}
+          return { row: null }
         }
         isNew = true
       }
-      return {row, isNew}
+      return { row, isNew }
     },
     /** 閫氳繃涓存椂ID鑾峰彇鏂板鐨勮 */
     getNewRowById(id) {
@@ -885,9 +899,9 @@
      * @param isOnlJs 鏄惁鏄痮nlineJS澧炲己瑙﹀彂鐨�
      * @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 銆愭柊琛岀紪杈戙�慾s澧炲己闄勮〃鍐呯疆鏂规硶璋冪敤闂 #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) {
diff --git a/src/mixins/JVxeTableMixin.js b/src/mixins/JVxeTableMixin.js
index 98e086d..2a01351 100644
--- a/src/mixins/JVxeTableMixin.js
+++ b/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({})
diff --git a/src/mixins/JVxeTableModelMixin.js b/src/mixins/JVxeTableModelMixin.js
index 5f2ee79..f23847d 100644
--- a/src/mixins/JVxeTableModelMixin.js
+++ b/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)
     },
diff --git a/src/utils/encryption/signMd5Utils.js b/src/utils/encryption/signMd5Utils.js
index 9dee410..3c2279a 100644
--- a/src/utils/encryption/signMd5Utils.js
+++ b/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);
diff --git a/src/views/eam/DeductionItemList.vue b/src/views/eam/DeductionItemList.vue
new file mode 100644
index 0000000..47f05d5
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/views/eam/OperationCertificateApplyList.vue b/src/views/eam/OperationCertificateApplyList.vue
new file mode 100644
index 0000000..6c86750
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/views/eam/OperationCertificateList.vue b/src/views/eam/OperationCertificateList.vue
new file mode 100644
index 0000000..a6e5030
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/views/eam/modules/deductionItem/DeductionItemForm.vue b/src/views/eam/modules/deductionItem/DeductionItemForm.vue
new file mode 100644
index 0000000..4215080
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/views/eam/modules/deductionItem/DeductionItemModal.vue b/src/views/eam/modules/deductionItem/DeductionItemModal.vue
new file mode 100644
index 0000000..5ffd146
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/views/eam/modules/operationCertificate/OperationCertificateForm.vue b/src/views/eam/modules/operationCertificate/OperationCertificateForm.vue
new file mode 100644
index 0000000..8d47cef
--- /dev/null
+++ b/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: '鎵e垎椤�',
+              key: 'deductionItem',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '璇疯緭鍏�${title}',
+              defaultValue:'',
+            },
+            {
+              title: '鎵e垎鍛ㄦ湡',
+              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)
+      },
+      /** 璋冪敤瀹宔dit()鏂规硶涔嬪悗浼氳嚜鍔ㄨ皟鐢ㄦ鏂规硶 */
+      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)
+                }
+              })
+            })
+        },
+      /** 鏁寸悊鎴恌ormData */
+      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>
\ No newline at end of file
diff --git a/src/views/eam/modules/operationCertificate/OperationCertificateModal.vue b/src/views/eam/modules/operationCertificate/OperationCertificateModal.vue
new file mode 100644
index 0000000..e881924
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/views/eam/modules/operationCertificateApply/OperationCertificateApplyForm.vue b/src/views/eam/modules/operationCertificateApply/OperationCertificateApplyForm.vue
new file mode 100644
index 0000000..16a4a2b
--- /dev/null
+++ b/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)
+    },
+    /** 璋冪敤瀹宔dit()鏂规硶涔嬪悗浼氳嚜鍔ㄨ皟鐢ㄦ鏂规硶 */
+    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)
+          }
+        })
+      })
+    },
+    /** 鏁寸悊鎴恌ormData */
+    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>
\ No newline at end of file
diff --git a/src/views/eam/modules/operationCertificateApply/OperationCertificateApplyModal.vue b/src/views/eam/modules/operationCertificateApply/OperationCertificateApplyModal.vue
new file mode 100644
index 0000000..047354b
--- /dev/null
+++ b/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>
\ No newline at end of file

--
Gitblit v1.9.3