From dc3af0cbb4a6d105bdff497b510cc0a87b3e8d0a Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期五, 28 二月 2025 17:53:44 +0800
Subject: [PATCH] Merge branch 'dev' of http://114.132.189.42:9002/r/lims-ruoyi-before into dev

---
 src/views/CNAS/personnel/personnelInfo/index.vue                                      |  329 +
 src/InspectionWorker.worker.js                                                        |    4 
 src/views/CNAS/personnel/personnelInfo/components/communicateAdd.vue                  |  136 
 src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue                      |  729 ++++
 src/api/cnas/personal/personPersonnelCapacity.js                                      |   51 
 src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue              |  344 +
 src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue                               |  178 
 src/views/business/inspectionTask/index.vue                                           |    3 
 src/assets/styles/ruoyi.scss                                                          |    2 
 src/views/tool/file-preview.vue                                                       |  238 +
 src/api/cnas/process/method/standardMethodsChange.js                                  |  102 
 src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue                    |  576 +++
 src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue   |  118 
 src/api/cnas/personal/personPostAuthorizationRecord.js                                |   35 
 src/api/cnas/personal/personalList.js                                                 |  179 +
 src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue                     |  802 ++++
 src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableList.vue       |  240 +
 src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue                           |  153 
 src/views/CNAS/externalService/serviceAndSupplyPro/component/AddProject.vue           |   97 
 src/views/business/rawMaterialInspection/index.vue                                    |    6 
 src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue                      |  186 +
 src/views/business/productOrder/components/add.vue                                    |    2 
 src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue                 | 1115 ++++++
 src/views/business/inspectionTask/inspection.vue                                      |    2 
 src/api/cnas/process/method/standardNoveltyRetrieval.js                               |   75 
 src/components/Pagination/index.vue                                                   |    3 
 src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableProject.vue    |  164 
 src/api/cnas/personal/personRewardPunishmentRecord.js                                 |   35 
 src/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro.js               |  220 +
 src/views/CNAS/personnel/personnelInfo/components/mandateAdd.vue                      |  200 +
 src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue    |  138 
 src/api/cnas/personal/personTrainingRecord.js                                         |   27 
 src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue      |  172 
 src/main.js                                                                           |    4 
 src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue       |  456 ++
 src/api/cnas/personal/personJobResponsibilities.js                                    |   35 
 src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue                  |  395 ++
 src/views/CNAS/externalService/serviceAndSupplyPro/component/contents.vue             |  312 +
 src/utils/index.js                                                                    |    2 
 src/views/CNAS/externalService/serviceAndSupplyPro/component/Store.vue                |  468 ++
 src/views/CNAS/personnel/personalOverview/index.vue                                   |    0 
 src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue                        |  317 +
 src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue                       |  303 +
 src/api/cnas/personal/personalOverview.js                                             |    0 
 src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue                     |  175 
 src/api/cnas/personal/personPersonCommunicationAbilityPage.js                         |   35 
 src/views/CNAS/externalService/serviceAndSupplyPro/index.vue                          |   53 
 src/views/CNAS/externalService/serviceAndSupplyPro/component/Edit.vue                 |  252 +
 src/api/cnas/personal/personalTraining.js                                             |  141 
 src/api/system/user.js                                                                |    8 
 src/views/CNAS/personnel/personnelInfo/components/Edit.vue                            |  452 ++
 src/views/business/materialOrder/index.vue                                            |   24 
 src/views/standard/model/index.vue                                                    |    2 
 src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue |  123 
 src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableOverview.vue   |    1 
 package.json                                                                          |    1 
 src/views/CNAS/process/method/standardMethodsChange/index.vue                         |  201 +
 src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue      |  148 
 src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue       |  131 
 59 files changed, 10,656 insertions(+), 44 deletions(-)

diff --git a/package.json b/package.json
index b7774ff..750ba15 100644
--- a/package.json
+++ b/package.json
@@ -56,6 +56,7 @@
     "jsencrypt": "3.0.0-rc.1",
     "jspdf": "^3.0.0",
     "mammoth": "^1.9.0",
+    "moment": "^2.30.1",
     "nprogress": "0.2.0",
     "pako": "^2.1.0",
     "print-js": "^1.6.0",
diff --git a/src/InspectionWorker.worker.js b/src/InspectionWorker.worker.js
index c8e0764..9f6d11c 100644
--- a/src/InspectionWorker.worker.js
+++ b/src/InspectionWorker.worker.js
@@ -1815,7 +1815,7 @@
     // Create version of divisor with leading zero.
     bz.unshift(0);
 
-    // Add zeros to make remainder as long as divisor.
+    // CommunicateAdd zeros to make remainder as long as divisor.
     for (; rl++ < bl; ) r.push(0);
 
     do {
@@ -1853,7 +1853,7 @@
         }
       }
 
-      // Add the digit n to the result array.
+      // CommunicateAdd the digit n to the result array.
       qc[qi++] = cmp ? n : ++n;
 
       // Update the remainder.
diff --git a/src/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro.js b/src/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro.js
index 890fb4e..2a0d5ca 100644
--- a/src/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro.js
+++ b/src/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro.js
@@ -8,3 +8,223 @@
     params: query
   })
 }
+
+export function deleteProcurementSuppliesList(query) {
+  return request({
+    url: '/procurementSuppliesList/deleteProcurementSuppliesList',
+    method: 'delete',
+    params: query
+  })
+}
+
+export function exportProcurementSuppliesList(query) {
+  return request({
+    url: "/procurementSuppliesList/exportProcurementSuppliesList",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+export function addProcurementSuppliesList(query) {
+  return request({
+    url: '/procurementSuppliesList/addProcurementSuppliesList',
+    method: 'post',
+    data: query,
+  })
+}
+
+export function selectEnumByCategory(query) {
+  return request({
+    url: '/enum/selectEnumByCategory',
+    method: 'post',
+    data: query,
+  })
+}
+
+export function updateProcurementSuppliesList(query) {
+  return request({
+    url: '/procurementSuppliesList/updateProcurementSuppliesList',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 鏈嶅姟鍜屼緵搴斿搧閲囪喘
+export function selectSupplierManagementAll(query) {
+  return request({
+    url: '/supplierManagement/selectSupplierManagementAll',
+    method: 'get',
+    params: query
+  })
+}
+
+export function addProcurementSuppliesExpends(query) {
+  return request({
+    url: '/procurementSuppliesExpends/addProcurementSuppliesExpends',
+    method: 'post',
+    data: query,
+  })
+}
+
+export function deleteProcurementSuppliesExpends(query) {
+  return request({
+    url: '/procurementSuppliesExpends/deleteProcurementSuppliesExpends',
+    method: 'delete',
+    params: query
+  })
+}
+
+export function procurementSuppliesExpendlist(query) {
+  return request({
+    url: '/procurementSuppliesExpends/procurementSuppliesExpendlist/',
+    method: 'get',
+    params: query
+  })
+}
+
+export function exportProcurementSuppliesStoreExcel(query) {
+  return request({
+    url: '/procurementSuppliesStore/exportExcel',
+    method: "get",
+    responseType: "blob",
+    params: query,
+  })
+}
+
+// 鏂板鑺傜偣
+export function addSuppliersDirectoryContents(query) {
+  return request({
+    url: '/suppliersDirectoryContents/addSuppliersDirectoryContents',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 缂栬緫鑺傜偣
+export function updateSuppliersDirectoryContents(query) {
+  return request({
+    url: '/suppliersDirectoryContents/updateSuppliersDirectoryContents',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 鍒犻櫎鑺傜偣
+export function deleteSuppliersDirectoryContentsById(query) {
+  return request({
+    url: '/suppliersDirectoryContents/deleteSuppliersDirectoryContentsById',
+    method: 'delete',
+    params: query
+  })
+}
+
+// 閲囪喘鐗╄祫鐩綍鍒犻櫎
+export function deleteProcurementSuppliesContentById(query) {
+  return request({
+    url: '/procurementSuppliesContents/deleteProcurementSuppliesContentById',
+    method: 'delete',
+    params: query
+  })
+}
+
+// 鏌ヨ鎵�鏈夎妭鐐�
+export function getSuppliersDirectoryContentsNodeNames(query) {
+  return request({
+    url: '/suppliersDirectoryContents/getSuppliersDirectoryContentsNodeNames',
+    method: 'get',
+    params: query
+  })
+}
+
+// 閲囪喘鐗╄祫鐩綍鑾峰彇鑺傜偣鍚嶇О
+export function getProcurementSuppliesContentsNodeNames(query) {
+  return request({
+    url: '/procurementSuppliesContents/getNodeNames',
+    method: 'get',
+    params: query
+  })
+}
+
+//鑾峰彇鐢ㄦ埛鍒楄〃
+export function selectUserCondition(query) {
+  return request({
+    url: "/system/newUser/selectUserCondition",
+    method: "get",
+    params: query,
+  });
+}
+
+// 閲囪喘鐗╄祫鐩綍璇︽儏
+export function selectProcurementSuppliesContentById(query) {
+  return request({
+    url: "/procurementSuppliesContents/selectProcurementSuppliesContentById",
+    method: "get",
+    params: query,
+  });
+}
+
+// 閲囪喘鐗╄祫鐩綍鍒楄〃
+export function directoryListing(query) {
+  return request({
+    url: "/procurementSuppliesContents/directoryListing",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鑰楁潗鍏ュ簱淇敼
+export function updateStore(query) {
+  return request({
+    url: '/procurementSuppliesStore/updateStore',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 鑰楁潗鍏ュ簱鏂板
+export function addStore(query) {
+  return request({
+    url: '/procurementSuppliesStore/addStore',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 鏍规嵁id鏌ヨ鑰楁潗鍏ュ簱
+export function selectStoreById(query) {
+  return request({
+    url: "/procurementSuppliesStore/selectStoreById",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鑰楁潗鍏ュ簱鍒楄〃
+export function storeList(query) {
+  return request({
+    url: "/procurementSuppliesStore/storeList",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鑰楁潗鍏ュ簱鍒犻櫎
+export function deleteStore(query) {
+  return request({
+    url: '/procurementSuppliesStore/deleteStore',
+    method: 'delete',
+    params: query
+  })
+}
+
+// 閲囪喘鐗╄祫鐩綍鏂板
+export function addProcurementSuppliesContents(query) {
+  return request({
+    url: '/procurementSuppliesContents/addProcurementSuppliesContents',
+    method: 'post',
+    data: query,
+  })
+}
+
+
diff --git a/src/api/cnas/personal/personJobResponsibilities.js b/src/api/cnas/personal/personJobResponsibilities.js
new file mode 100644
index 0000000..0c2673b
--- /dev/null
+++ b/src/api/cnas/personal/personJobResponsibilities.js
@@ -0,0 +1,35 @@
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ宀椾綅鑱岃矗
+export function personJobResponsibilitiesSelect(query) {
+  return request({
+    url: "/personJobResponsibilities/personJobResponsibilitiesSelect",
+    method: "get",
+    params: query
+  });
+}
+// 鏂板宀椾綅鑱岃矗
+export function personJobResponsibilitiesSave(query) {
+  return request({
+    url: "/personJobResponsibilities/personJobResponsibilitiesSave",
+    method: "post",
+    data: query
+  });
+}
+// 瀵煎嚭宀椾綅鑱岃矗
+export function exportPersonJobResponsibilities(query) {
+  return request({
+    url: "/personJobResponsibilities/exportPersonJobResponsibilities",
+    method: "post",
+    params: query,
+    responseType: "blob"
+  });
+}
+// 鍒犻櫎宀椾綅鑱岃矗
+export function personJobResponsibilitiesDelete(query) {
+  return request({
+    url: "/personJobResponsibilities/personJobResponsibilitiesDelete",
+    method: "delete ",
+    params: query
+  });
+}
diff --git a/src/api/cnas/personal/personPersonCommunicationAbilityPage.js b/src/api/cnas/personal/personPersonCommunicationAbilityPage.js
new file mode 100644
index 0000000..c1d553c
--- /dev/null
+++ b/src/api/cnas/personal/personPersonCommunicationAbilityPage.js
@@ -0,0 +1,35 @@
+import request from "@/utils/request";
+
+// 鏌ヨ浜哄憳娌熼�氳褰�
+export function personPersonCommunicationAbilityPage(query) {
+  return request({
+    url: "/personCommunicationAbility/personPersonCommunicationAbilityPage",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎浜哄憳娌熼�氳褰�
+export function deletePersonCommunicationAbility(query) {
+  return request({
+    url: "/personCommunicationAbility/deletePersonCommunicationAbility",
+    method: "delete",
+    params: query
+  });
+}
+// 瀵煎嚭浜哄憳娌熼�氳褰�
+export function exportPersonCommunicationAbility(query) {
+  return request({
+    url: "/personCommunicationAbility/exportPersonCommunicationAbility",
+    method: "get",
+    params: query,
+    responseType: "blob"
+  });
+}
+// 鏂板-缂栬緫浜哄憳娌熼�氳褰�
+export function addOrUpdatePersonCommunicationAbility(query) {
+  return request({
+    url: "/personCommunicationAbility/addOrUpdatePersonCommunicationAbility",
+    method: "post",
+    data: query
+  });
+}
diff --git a/src/api/cnas/personal/personPersonnelCapacity.js b/src/api/cnas/personal/personPersonnelCapacity.js
new file mode 100644
index 0000000..f5b4503
--- /dev/null
+++ b/src/api/cnas/personal/personPersonnelCapacity.js
@@ -0,0 +1,51 @@
+import request from "@/utils/request";
+
+// 鏌ヨ浜哄憳鑳藉姏
+export function personPersonnelCapacityPage(query) {
+  return request({
+    url: "/personPersonnelCapacity/personPersonnelCapacityPage",
+    method: "get",
+    params: query
+  });
+}
+// 鏂板缂栬緫浜哄憳鑳藉姏
+export function addOrUpdatePersonPersonnelCapacity(query) {
+  return request({
+    url: "/personPersonnelCapacity/addOrUpdatePersonPersonnelCapacity",
+    method: "post",
+    data: query
+  });
+}
+// 鏂板缂栬緫浜哄憳鑳藉姏
+export function submitConfirmPersonnelCapability(query) {
+  return request({
+    url: "/personPersonnelCapacity/submitConfirmPersonnelCapability",
+    method: "post",
+    data: query
+  });
+}
+// 纭浜哄憳鑳藉姏
+export function confirmPersonnelCapability(query) {
+  return request({
+    url: "/personPersonnelCapacity/confirmPersonnelCapability",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎浜哄憳鑳藉姏
+export function deletePersonPersonnelCapacity(query) {
+  return request({
+    url: "/personPersonnelCapacity/deletePersonPersonnelCapacity",
+    method: "delete",
+    params: query
+  });
+}
+// 瀵煎嚭浜哄憳鑳藉姏
+export function exportPersonnelCapacity(query) {
+  return request({
+    url: "/personPersonnelCapacity/exportPersonnelCapacity",
+    method: "get",
+    params: query,
+    responseType: "blob"
+  });
+}
diff --git a/src/api/cnas/personal/personPostAuthorizationRecord.js b/src/api/cnas/personal/personPostAuthorizationRecord.js
new file mode 100644
index 0000000..b3be2eb
--- /dev/null
+++ b/src/api/cnas/personal/personPostAuthorizationRecord.js
@@ -0,0 +1,35 @@
+import request from "@/utils/request";
+
+// 浠昏亴鎺堟潈璁板綍鏌ヨ琛ㄦ牸
+export function PersonPostAuthorizationRecordPage(query) {
+  return request({
+    url: "/personPostAuthorizationRecord/PersonPostAuthorizationRecordPage",
+    method: "get",
+    params: query
+  });
+}
+// 浠昏亴鎺堟潈璁板綍鍒犻櫎
+export function deletePersonPostAuthorizationRecord(query) {
+  return request({
+    url: "/personPostAuthorizationRecord/deletePersonPostAuthorizationRecord",
+    method: "delete",
+    params: query
+  });
+}
+// 浠昏亴鎺堟潈瀵煎嚭
+export function exportPersonPostAuthorizationRecord(query) {
+  return request({
+    url: "/personPostAuthorizationRecord/exportPersonPostAuthorizationRecord",
+    method: "get",
+    params: query,
+    responseType: "blob"
+  });
+}
+// 浠昏亴鎺堟潈瀵煎嚭
+export function addOrUpdatePersonPostAuthorizationRecord(query) {
+  return request({
+    url: "/personPostAuthorizationRecord/addOrUpdatePersonPostAuthorizationRecord",
+    method: "post",
+    data: query,
+  });
+}
diff --git a/src/api/cnas/personal/personRewardPunishmentRecord.js b/src/api/cnas/personal/personRewardPunishmentRecord.js
new file mode 100644
index 0000000..c160073
--- /dev/null
+++ b/src/api/cnas/personal/personRewardPunishmentRecord.js
@@ -0,0 +1,35 @@
+import request from "@/utils/request";
+
+// 浜哄憳 - 濂栨儵璁板綍 鍒嗛〉鏌ヨ
+export function rewardPunishmentPage(query) {
+  return request({
+    url: "/personRewardPunishmentRecord/rewardPunishmentPage",
+    method: "get",
+    params: query
+  });
+}
+// 浜哄憳 - 濂栨儵璁板綍 瀵煎嚭
+export function rewardPunishmentExport(query) {
+  return request({
+    url: "/personRewardPunishmentRecord/rewardPunishmentExport",
+    method: "get",
+    params: query,
+    responseType: 'blob'
+  });
+}
+// 浜哄憳 - 濂栨儵璁板綍 鏂板/鏇存柊
+export function addOrUpdateRewardPunishment(query) {
+  return request({
+    url: "/personRewardPunishmentRecord/addOrUpdateRewardPunishment",
+    method: "post",
+    data: query,
+  });
+}
+// 浜哄憳 - 濂栨儵璁板綍 鏂板/鏇存柊
+export function deleteRewardPunishment(query) {
+  return request({
+    url: "/personRewardPunishmentRecord/deleteRewardPunishment",
+    method: "delete",
+    params: query,
+  });
+}
diff --git a/src/api/cnas/personal/personTrainingRecord.js b/src/api/cnas/personal/personTrainingRecord.js
new file mode 100644
index 0000000..6b75b4d
--- /dev/null
+++ b/src/api/cnas/personal/personTrainingRecord.js
@@ -0,0 +1,27 @@
+import request from "@/utils/request";
+
+// 瀵煎嚭鍩硅璁板綍
+export function exportTrainingRecord(query) {
+  return request({
+    url: "/personTrainingRecord/exportTrainingRecord",
+    method: "get",
+    params: query,
+    responseType: 'blob'
+  });
+}
+// 鏌ヨ浜哄憳 鍩硅璁板綍
+export function trainingSelectTrainingRecord(query) {
+  return request({
+    url: "/personTrainingRecord/trainingSelectTrainingRecord",
+    method: "get",
+    params: query,
+  });
+}
+// 鏌ヨ浜哄憳鏄庣粏 鍩硅璁板綍
+export function queryPersonnelDetails(query) {
+  return request({
+    url: "/personTrainingRecord/queryPersonnelDetails",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/api/cnas/personal/personalList.js b/src/api/cnas/personal/personalList.js
new file mode 100644
index 0000000..567c481
--- /dev/null
+++ b/src/api/cnas/personal/personalList.js
@@ -0,0 +1,179 @@
+import request from "@/utils/request";
+
+// 鍒犻櫎浜哄憳鏄庣粏鎵�鍦ㄧ粍缁囨灦鏋�
+export function delUserDepardLimsId(query) {
+  return request({
+    url: "/system/newUser/delUserDepardLimsId",
+    method: "delete",
+    params: query,
+  });
+}
+// 淇敼浜哄憳鏄庣粏鎵�鍦ㄧ粍缁囨灦鏋�
+export function upUserDepardLimsId(query) {
+  return request({
+    url: "/system/newUser/upUserDepardLimsId",
+    method: "post",
+    data: query,
+  });
+}
+// 瀵煎嚭
+export function exportPersonBasicInfo(query) {
+  return request({
+    url: "/personBasicInfo/exportPersonBasicInfo",
+    method: "get",
+    data: query,
+    responseType: "blob"
+  });
+}
+// 瀵煎嚭
+export function exportPersonBasicInfoById(query) {
+  return request({
+    url: "/personBasicInfo/exportPersonBasicInfoById",
+    method: "get",
+    data: query,
+    responseType: "blob"
+  });
+}
+// 鑾峰彇浜哄憳鍒楄〃
+export function basicInformationOfPersonnelSelectPage(query) {
+  return request({
+    url: "/personBasicInfo/basicInformationOfPersonnelSelectPage",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎閮ㄩ棬
+export function delDepartmentLims(query) {
+  return request({
+    url: "/department/delDepartmentLims",
+    method: "delete",
+    params: query
+  });
+}
+// 娣诲姞閮ㄩ棬
+export function addDepartmentLims(query) {
+  return request({
+    url: "/department/addDepartmentLims",
+    method: "post",
+    data: query
+  });
+}
+// 鏌ヨCNAS浜哄憳渚ц竟鏍�
+export function selectCNSAPersonTree() {
+  return request({
+    url: "/personBasicInfo/selectCNSAPersonTree",
+    method: "get"
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅闄勪欢鍒楄〃
+export function getBasicInfoFileList(query) {
+  return request({
+    url: "/personBasicInfo/getBasicInfoFileList",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎闄勪欢
+export function delBasicInfoFileList(query) {
+  return request({
+    url: "/personBasicInfo/delBasicInfoFileList",
+    method: "delete",
+    params: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻鏂板
+export function addBasicInfoWork(query) {
+  return request({
+    url: "/personBasicInfo/addBasicInfoWork",
+    method: "post",
+    data: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻淇敼
+export function updateBasicInfoWorkList(query) {
+  return request({
+    url: "/personBasicInfo/updateBasicInfoWorkList",
+    method: "post",
+    data: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻鍒犻櫎
+export function delBasicInfoWorkList(query) {
+  return request({
+    url: "/personBasicInfo/delBasicInfoWorkList",
+    method: "delete",
+    params: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻鏌ヨ
+export function getBasicInfoWorkList(query) {
+  return request({
+    url: "/personBasicInfo/getBasicInfoWorkList",
+    method: "get",
+    params: query
+  });
+}
+// 鑾峰彇闄勪欢
+export function getAnnex(query) {
+  return request({
+    url: "/personBasicInfo/getAnnex",
+    method: "get",
+    params: query
+  });
+}
+// 鏇存柊闄勪欢
+export function updateAnnex(query) {
+  return request({
+    url: "/personBasicInfo/updateAnnex",
+    method: "post",
+    data: query
+  });
+}
+// 鏇存柊闄勪欢
+export function getAnnexByUserId(query) {
+  return request({
+    url: "/personBasicInfo/getAnnexByUserId",
+    method: "get",
+    params: query
+  });
+}
+// 娣诲姞闄勪欢
+export function addAnnex(query) {
+  return request({
+    url: "/personBasicInfo/addAnnex",
+    method: "post",
+    data: query
+  });
+}
+// 鍒犻櫎闄勪欢
+export function deleteAnnex(query) {
+  return request({
+    url: "/personBasicInfo/deleteAnnex",
+    method: "delete",
+    params: query
+  });
+}
+// 浜哄憳鍩烘湰淇℃伅鏌ヨ
+export function getCNASPersonnelInfo(query) {
+  return request({
+    url: "/personBasicInfo/getCNASPersonnelInfo",
+    method: "get",
+    params: query
+  });
+}
+// 浜哄憳鍩烘湰淇℃伅淇濆瓨
+export function saveCNASPersonnelInfo(query) {
+  return request({
+    url: "/personBasicInfo/saveCNASPersonnelInfo",
+    method: "post",
+    data: query
+  });
+}
+// 鍒犻櫎鏂囦欢
+export function deleteCNASFile(query) {
+  return request({
+    url: "/personBasicInfo/deleteCNASFile",
+    method: "delete",
+    params: query
+  });
+}
diff --git a/src/api/cnas/personnel/personnelOverview.js b/src/api/cnas/personal/personalOverview.js
similarity index 100%
rename from src/api/cnas/personnel/personnelOverview.js
rename to src/api/cnas/personal/personalOverview.js
diff --git a/src/api/cnas/personal/personalTraining.js b/src/api/cnas/personal/personalTraining.js
new file mode 100644
index 0000000..cdca93c
--- /dev/null
+++ b/src/api/cnas/personal/personalTraining.js
@@ -0,0 +1,141 @@
+import request from "@/utils/request";
+
+// 鏌ヨ浜哄憳鍩硅
+export function personTraining(query) {
+  return request({
+    url: "/personTraining/personTrainingSelect",
+    method: "get",
+    params: query
+  });
+}
+// 鏌ヨ鍩硅璁″垝骞村害璁″垝鏄庣粏琛�
+export function queryTheAnnualPlanDetailsTable(query) {
+  return request({
+    url: "/personTraining/queryTheAnnualPlanDetailsTable",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎浜哄憳鍩硅淇℃伅
+export function personTrainingDelete(query) {
+  return request({
+    url: "/personTraining/personTrainingDelete",
+    method: "delete",
+    params: query
+  });
+}
+// 瀹℃牳 骞村害浜哄憳鍩硅
+export function reviewAnnualPersonnelTraining(query) {
+  return request({
+    url: "/personTraining/reviewAnnualPersonnelTraining",
+    method: "post",
+    data: query
+  });
+}
+// 鎵瑰噯 骞村害浜哄憳鍩硅
+export function approveAnnualPersonnelTraining(query) {
+  return request({
+    url: "/personTraining/approveAnnualPersonnelTraining",
+    method: "post",
+    data: query
+  });
+}
+// 瀵煎嚭浜哄憳鍩硅
+export function exportPersonTraining(query) {
+  return request({
+    url: "/personTraining/exportPersonTraining",
+    method: "get",
+    params: query,
+    responseType: "blob"
+  });
+}
+// 瀵煎嚭浜哄憳鍩硅涓庤�冩牳璁板綍
+export function exportPersonTrainingRecord(query) {
+  return request({
+    url: "/personTraining/exportPersonTrainingRecord",
+    method: "get",
+    params: query,
+    responseType: "blob"
+  });
+}
+// 鎵归噺鍒犻櫎 骞村害璁″垝鏄庣粏琛�
+export function deleteAnnualPlanDetailTable(query) {
+  return request({
+    url: "/personTraining/deleteAnnualPlanDetailTable",
+    method: "delete",
+    params: query
+  });
+}
+// 鎵归噺鍒犻櫎 骞村害璁″垝鏄庣粏琛�
+export function addOrUpdatePersonTrainingDetailed(query) {
+  return request({
+    url: "/personTraining/addOrUpdatePersonTrainingDetailed",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳璁板綍 鏌ヨ
+export function trainingAndAssessmentRecordsPage(query) {
+  return request({
+    url: "/personTraining/trainingAndAssessmentRecordsPage",
+    method: "get",
+    params: query
+  });
+}
+// 鍩硅涓庤�冩牳 澶辩劍鏇存柊
+export function outOfFocusPreservation(query) {
+  return request({
+    url: "/personTraining/outOfFocusPreservation",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳 鏂板浜哄憳
+export function newPersonnelAddedToTrainingRecords(query) {
+  return request({
+    url: "/personTraining/newPersonnelAddedToTrainingRecords",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳 鍒犻櫎浜哄憳
+export function deleteTrainingAndAssessmentRecords(query) {
+  return request({
+    url: "/personTraining/deleteTrainingAndAssessmentRecords",
+    method: "delete",
+    params: query
+  });
+}
+// 鍩硅涓庤�冩牳璁板綍 鎻愪氦
+export function trainingAndAssessmentRecordsAdded(query) {
+  return request({
+    url: "/personTraining/trainingAndAssessmentRecordsAdded",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳璁板綍 鎻愪氦璇勪环
+export function trainingAndAssessmentRecordsEvaluate(query) {
+  return request({
+    url: "/personTraining/trainingAndAssessmentRecordsEvaluate",
+    method: "post",
+    data: query
+  });
+}
+
+// 浜哄憳鍩硅璇︽儏闄勪欢鍒楄〃
+export function getTrainingDetailedFileList(query) {
+  return request({
+    url: "/personTraining/getTrainingDetailedFileList",
+    method: "get",
+    params: query
+  });
+}
+// 浜哄憳鍩硅璇︽儏闄勪欢鍒犻櫎
+export function delTrainingDetailedFileList(query) {
+  return request({
+    url: "/personTraining/delTrainingDetailedFileList",
+    method: "delete",
+    params: query
+  });
+}
diff --git a/src/api/cnas/process/method/standardMethodsChange.js b/src/api/cnas/process/method/standardMethodsChange.js
new file mode 100644
index 0000000..e4579aa
--- /dev/null
+++ b/src/api/cnas/process/method/standardMethodsChange.js
@@ -0,0 +1,102 @@
+// 瀹為獙瀹ょ殑妫�娴嬭兘鍔涙。妗堢浉鍏虫帴鍙�
+import request from "@/utils/request";
+
+//鏍囧噯鏂规硶鏇存柊楠岃瘉鍒楄〃
+export function pagesMethodVerify(query) {
+  return request({
+    url: "/processMethodVerify/pagesMethodVerify",
+    method: "get",
+    params: query,
+  });
+}
+
+//鑾峰彇鐢ㄦ埛鍒楄〃
+export function selectUserCondition(query) {
+  return request({
+    url: "/system/newUser/selectUserCondition",
+    method: "get",
+    params: query,
+  });
+}
+
+//鏌ヨ鏍囧噯鏂规硶楠岃瘉璇︽儏
+export function getMethodVerifyOne(query) {
+  return request({
+    url: "/processMethodVerify/getMethodVerifyOne",
+    method: "get",
+    params: query,
+  });
+}
+
+// 閫氳繃璁惧鍒嗙被鑾峰彇璁惧鍒楄〃
+export function deviceScopeSearch(query) {
+  return request({
+    url: '/deviceScope/search',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏂板鏍囧噯鏂规硶楠岃瘉
+export function addMethodVerify(data) {
+  return request({
+    url: "/processMethodVerify/addMethodVerify",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼鏍囧噯鏂规硶楠岃瘉
+export function updateMethodVerify(data) {
+  return request({
+    url: "/processMethodVerify/updateMethodVerify",
+    method: "post",
+    data: data,
+  });
+}
+
+// 瀵煎嚭鏍囧噯鏂规硶鏇存柊楠岃瘉
+export function exportMethodVerify(query) {
+  return request({
+    url: '/processMethodVerify/exportMethodVerify',
+    method: "get",
+    responseType: "blob",
+    params: query,
+  })
+}
+
+// 楠岃瘉纭
+export function methodVerifyAffirm(query) {
+  return request({
+    url: '/processMethodVerify/methodVerifyAffirm',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鍒犻櫎鏍囧噯鏂规硶鏇存柊楠岃瘉
+export function delMethodVerify(query) {
+  return request({
+    url: '/processMethodVerify/delMethodVerify',
+    method: 'delete',
+    params: query
+  })
+}
+
+// 鍘熷璁板綍鍒楄〃
+export function getVerifyMethodFileList(query) {
+  return request({
+    url: '/processMethodVerify/getVerifyMethodFileList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鍒犻櫎楠岃瘉鍘熷璁板綍鍒楄〃
+export function delVerifyMethodFileList(query) {
+  return request({
+    url: '/processMethodVerify/delVerifyMethodFileList',
+    method: 'delete',
+    params: query
+  })
+}
diff --git a/src/api/cnas/process/method/standardNoveltyRetrieval.js b/src/api/cnas/process/method/standardNoveltyRetrieval.js
new file mode 100644
index 0000000..a0062e8
--- /dev/null
+++ b/src/api/cnas/process/method/standardNoveltyRetrieval.js
@@ -0,0 +1,75 @@
+// 瀹為獙瀹ょ殑妫�娴嬭兘鍔涙。妗堢浉鍏虫帴鍙�
+import request from "@/utils/request";
+
+// 鏍囧噯鏌ユ柊鍒楄〃
+export function pageMethodSearchNew(query) {
+  return request({
+    url: "/processMethodSearchNew/pageMethodSearchNew",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏌ヨ瀛樻。
+export function pageSearchNewArchived(query) {
+  return request({
+    url: "/processMethodSearchNew/pageSearchNewArchived",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板鏍囧噯鏌ユ柊瀹℃壒娴佺▼
+export function addSearchNewArchived(data) {
+  return request({
+    url: "/processMethodSearchNew/addSearchNewArchived",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鏂板鏍囧噯鏌ユ柊
+export function addMethodSearchNew(data) {
+  return request({
+    url: "/processMethodSearchNew/addMethodSearchNew",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼鏍囧噯鏌ユ柊
+export function updateMethodSearchNew(data) {
+  return request({
+    url: "/processMethodSearchNew/updateMethodSearchNew",
+    method: "post",
+    data: data,
+  });
+}
+
+// 瀛樻。鎵瑰噯
+export function ratifySearchNewArchivedr(data) {
+  return request({
+    url: "/processMethodSearchNew/ratifySearchNewArchivedr",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鏌ヨ瀛樻。澶囦唤鍒楄〃
+export function pageSearchNewBackups(query) {
+  return request({
+    url: "/processMethodSearchNew/pageSearchNewBackups",
+    method: "get",
+    params: query,
+  });
+}
+
+// 瀵煎嚭鏍囧噯鏌ユ柊
+export function exportMethodSearchNew(query) {
+  return request({
+    url: "/processMethodSearchNew/exportMethodSearchNew",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
diff --git a/src/api/system/user.js b/src/api/system/user.js
index 14b4c2b..8ecfc5a 100644
--- a/src/api/system/user.js
+++ b/src/api/system/user.js
@@ -187,3 +187,11 @@
     method: 'get'
   })
 }
+// 鑾峰彇鐢ㄦ埛鍒楄〃
+export function selectUserCondition(query) {
+  return request({
+    url: "/system/newUser/selectUserCondition",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss
index 7e44513..8dfe1d0 100644
--- a/src/assets/styles/ruoyi.scss
+++ b/src/assets/styles/ruoyi.scss
@@ -121,7 +121,7 @@
   height: 32px;
   margin-bottom: 10px;
   margin-top: 15px;
-  padding: 10px 20px !important;
+  padding: 0 20px !important;
 }
 
 /* tree border */
diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue
index 56f5a6b..9be5ddb 100644
--- a/src/components/Pagination/index.vue
+++ b/src/components/Pagination/index.vue
@@ -106,7 +106,8 @@
 <style scoped>
 .pagination-container {
   background: #fff;
-  padding: 32px 16px;
+  padding: 28px 16px;
+  margin-top: 10px;
 }
 .pagination-container.hidden {
   display: none;
diff --git a/src/main.js b/src/main.js
index 24129ca..0736a8c 100644
--- a/src/main.js
+++ b/src/main.js
@@ -49,6 +49,8 @@
 import DictData from "@/components/DictData";
 import { checkPermi } from "@/utils/permission"; // 鏉冮檺鍒ゆ柇鍑芥暟
 import { getToken } from "@/utils/auth";
+// 鏃堕棿杞崲
+import Moment from "moment";
 
 // 鍏ㄥ眬鏂规硶鎸傝浇
 Vue.prototype.getDicts = getDicts;
@@ -80,6 +82,8 @@
     });
   },
 });
+Vue.use(Moment);
+Vue.prototype.$moment = Moment;
 
 // 鍏ㄥ眬缁勪欢鎸傝浇
 Vue.component("DictTag", DictTag);
diff --git a/src/utils/index.js b/src/utils/index.js
index 6a246f9..553fb3c 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -307,7 +307,7 @@
 }
 
 /**
- * Add class to element
+ * CommunicateAdd class to element
  * @param {HTMLElement} elm
  * @param {string} cls
  */
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/component/AddProject.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/component/AddProject.vue
new file mode 100644
index 0000000..326d5f4
--- /dev/null
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/component/AddProject.vue
@@ -0,0 +1,97 @@
+<template>
+  <el-dialog
+    :title="dialogTitle"
+    width="60%"
+    :visible.sync="dialogVisible"
+  >
+    <el-form :model="model" label-width="100px">
+      <el-col :span="12">
+        <el-form-item label="椤圭洰鍚嶇О">
+          <el-select
+            v-model="model.name"
+            placeholder="璇烽�夋嫨椤圭洰鍚嶇О"
+            style="width: 100%"
+            :disabled="row ? true:false"
+            @change="handleSelect"
+          >
+            <el-option
+              v-for="(v, i) in consumableOptions"
+              :label="v.consumablesName"
+              :value="v"
+              :key="i"
+            />
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="娑堣�楁暟閲�">
+          <el-input-number v-model="model.amount" :min="0" :step="1" placeholder="璇疯緭鍏ユ秷鑰楁暟閲�"></el-input-number>
+        </el-form-item>
+      </el-col>
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+            <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+            <el-button type="primary" @click="sumbit">纭� 瀹�</el-button>
+        </span>
+  </el-dialog>
+</template>
+
+<script>
+
+import {
+  addProcurementSuppliesExpends,
+  procurementSuppliesList
+} from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro";
+
+export default {
+  data() {
+    return {
+      dialogTitle: "",
+      dialogVisible: false,
+      model: {
+        listId: undefined,
+        name: ""
+      },
+      consumableOptions: [],
+      row: undefined
+    }
+  },
+  created() {
+    this.fetchConsumableOptions()
+  },
+  methods: {
+    fetchConsumableOptions() {
+      procurementSuppliesList().then(res => {
+        if (res.code === 200) {
+          this.consumableOptions = res.data.records
+        }
+      })
+    },
+    openDialog(row) {
+      if(row) {
+        console.log(row, 'true')
+        this.dialogTitle = `${row.consumablesName}娣诲姞娑堣�楅」`
+        this.row = row
+        this.model.listId = row.id
+        this.model.name = row.consumablesName
+      } else {
+        this.dialogTitle = '娣诲姞娑堣�楅」'
+      }
+      this.dialogVisible = true
+    },
+    handleSelect(item) {
+      console.log(item)
+      this.model.listId = item.id
+      this.model.name = item.consumablesName
+    },
+    sumbit() {
+      addProcurementSuppliesExpends(this.model).then(res => {
+        if (res.code === 200) {
+          this.dialogVisible = false
+          this.$emit('submit')
+        }
+      })
+    }
+    }
+  }
+</script>
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableList.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableList.vue
new file mode 100644
index 0000000..189ccd3
--- /dev/null
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableList.vue
@@ -0,0 +1,240 @@
+<template>
+  <div>
+    <TableCard :showTitle="false">
+      <template slot="form">
+        <div class="action-box">
+          <div></div>
+          <div class="flex">
+            <el-button icon="el-icon-plus" size="small" type="primary" @click="showDialog(undefined)">
+              鏂板缓
+            </el-button>
+            <el-button icon="el-icon-upload2" size="small" @click="exportExcel">
+              瀵煎嚭Excel
+            </el-button>
+          </div>
+        </div>
+      </template>
+      <template v-slot:table>
+        <limsTable
+          :column="columns"
+          :currentChange="rowClick"
+          :height="'25vh'"
+          :highlightCurrentRow="true"
+          :isSelection="false"
+          :rowStyle="tableRowStyle"
+          :table-data="tableData"
+          rowKey="id"
+          style="margin-top: 18px; padding: 0 15px;"
+        >
+          <template v-slot:consumablesTypeSlot="{row}">
+            {{ findType(row.consumablesType) }}
+          </template>
+          <template v-slot:operation="scope">
+            <el-button size="small" type="text" @click="showDialog(scope.row)">缂栬緫</el-button>
+            <el-button size="small" style="color: #f56c6c" type="text" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </limsTable>
+        <div class="pagination">
+          <div></div>
+          <el-pagination
+            :page-size="pagination.pageSize"
+            :page-sizes="[10, 20, 30, 40]"
+            :total="pagination.total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrent"
+            @size-change="handleSize"
+          >
+          </el-pagination>
+        </div>
+      </template>
+    </TableCard>
+    <el-divider></el-divider>
+    <div>
+      <ConsumableProject ref="consumableProject"></ConsumableProject>
+    </div>
+    <Edit ref="editRef" :contentsId="contentsId" @submit="fetchData"/>
+  </div>
+</template>
+
+<script>
+import TableCard from './index.vue';
+import Edit from "./Edit.vue"
+import limsTable from '@/components/Table/lims-table.vue'
+import {
+  deleteProcurementSuppliesList,
+  procurementSuppliesList,
+  exportProcurementSuppliesList
+} from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro";
+import ConsumableProject from "./ConsumableProject.vue"
+
+export default {
+  dicts: ["consumables_type"],
+  components: {
+    TableCard, limsTable,Edit, ConsumableProject
+  },
+  props: {
+    contentsId: {
+      type: Number,
+      required: true,
+    }
+  },
+  watch: {
+    contentsId(newVal, oldVal) {
+      if (newVal !== 0) {
+        this.fetchData()
+      }
+    }
+  },
+  data() {
+    return {
+      columns: [
+        {
+          label: "璐у彿",
+          prop: "itemNumber"
+        },
+        {
+          label: "绫诲埆",
+          prop: "consumablesType",
+          dataType: "slot",
+          slot: "consumablesTypeSlot"
+        },
+        {
+          label: "鍚嶇О",
+          prop: "consumablesName"
+        },
+        {
+          label: "瑙勬牸",
+          prop: "specifications"
+        },
+        {
+          label: "鍙傝�冧緵搴斿晢",
+          prop: "supplierName"
+        },
+        {
+          label: "搴撳瓨涓嬮檺",
+          prop: "lowerLimit"
+        },
+        {
+          label: "褰撳墠搴撳瓨",
+          prop: "currentAmount"
+        },
+        {
+          label: "璁¢噺鍗曚綅",
+          prop: "unit"
+        },
+        {
+          label: "澶囨敞",
+          prop: "remark"
+        },
+        {
+          label: "璐熻矗浜�",
+          prop: "personInChargeName"
+        },
+        {
+          label: "鏈�杩戞洿鏂颁汉",
+          prop: "updateUserName"
+        },
+        {
+          label: "鏈�杩戞洿鏂版棩鏈�",
+          prop: "updateTime"
+        },
+        {
+          fixed: 'right',
+          label: "鎿嶄綔",
+          width: 120,
+          dataType: "slot",
+          slot: "operation"
+        }
+      ],
+      tableData: [],
+      pagination: {
+        current: 1,
+        pageSize: 20,
+        total: 0
+      },
+      options: [],
+    }
+  },
+  mounted() {
+    this.fetchData()
+    this.options = this.dict.type.consumables_type;
+  },
+  methods: {
+    async fetchData() {
+      procurementSuppliesList({ contentId: this.contentsId}).then(res => {
+        if (res.code === 200) {
+          this.tableData = res.data.records
+          if (this.tableData.length > 0) {
+            this.rowClick(this.tableData[0])
+          }
+        }
+      })
+    },
+    findType(val) {
+      this.$nextTick()
+      let res
+      const e = this.options.find(item => item.value == val)
+      if(e) {
+        res = e.label
+      } else {
+        res = '-'
+      }
+      return res
+    },
+    showDialog(row) {
+      this.$refs.editRef.openDialog(row);
+    },
+    async exportExcel() {
+      exportProcurementSuppliesList({parentId:this.contentsId}).then(res => {
+        const blob = new Blob([res], {type: 'application/octet-stream'});
+        this.$download.saveAs(blob, '鑰楁潗鍒楄〃.xlsx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    handleCurrent() {
+    },
+    handleSize() {
+    },
+    handleDelete(row) {
+      deleteProcurementSuppliesList({ id:row.id }).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.fetchData()
+        }
+      })
+    },
+    rowClick(row) {
+      this.$refs.consumableProject.fetchListId(row)
+    },
+    tableRowStyle({row}) {
+      if(row.currentAmount <= row.lowerLimit) {
+        return { background: '#ffcaca' }
+      } else {
+        return {}
+      }
+    }
+  }
+}
+</script>
+
+
+<style scoped>
+.flex {
+  display: flex;
+}
+
+.action-box {
+  width: 100%;
+  padding-top: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.pagination {
+  padding-top: 15px;
+  padding-right: 10px;
+  display: flex;
+  justify-content: space-between
+}
+</style>
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableOverview.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableOverview.vue
index 6c465f3..6ac65b9 100644
--- a/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableOverview.vue
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableOverview.vue
@@ -29,7 +29,6 @@
 import TableCard from './index.vue';
 import { procurementSuppliesList } from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro"
 import limsTable from '@/components/Table/lims-table.vue'
-import axios from "axios";
 
 export default {
     components: { CardPanel, TableCard, limsTable },
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableProject.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableProject.vue
new file mode 100644
index 0000000..1f2ed15
--- /dev/null
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableProject.vue
@@ -0,0 +1,164 @@
+<template>
+  <div>
+    <TableCard :showTitle="false">
+      <template slot="form">
+        <div class="action-box">
+          <div></div>
+          <div class="flex">
+            <el-button icon="el-icon-plus" size="small" type="primary" @click="showDialog">
+              娣诲姞椤圭洰
+            </el-button>
+            <el-button icon="el-icon-upload2" size="small" @click="exportExcel">
+              瀵煎嚭
+            </el-button>
+          </div>
+        </div>
+      </template>
+      <template v-slot:table>
+        <limsTable
+          :column="columns"
+          :height="'25vh'"
+          :isSelection="true"
+          :table-data="tableData"
+          style="margin-top: 18px; padding: 0 15px;"
+        >
+          <template v-slot:operation="scope">
+            <el-button size="small" type="text" @click="deleteData(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </limsTable>
+        <div class="pagination">
+          <div></div>
+          <el-pagination
+            :page-size="pagination.pageSize"
+            :page-sizes="[10, 20, 30, 40]"
+            :total="pagination.total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrent"
+            @size-change="handleSize"
+          >
+          </el-pagination>
+        </div>
+      </template>
+    </TableCard>
+    <AddProject ref="AddProjectRef" @submit="fetchData"/>
+  </div>
+</template>
+
+<script>
+import TableCard from './index.vue';
+import limsTable from '@/components/Table/lims-table.vue'
+import Edit from "./Edit.vue"
+import AddProject from './AddProject.vue';
+import {
+  deleteProcurementSuppliesExpends,
+  procurementSuppliesExpendlist
+} from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro";
+
+export default {
+  components: {
+    TableCard, limsTable, Edit, AddProject
+  },
+  data() {
+    return {
+      columns: [
+        // {
+        //   label: "缂栧彿"
+        // },
+        {
+          label: "椤圭洰鍚嶇О",
+          prop: "listName"
+        },
+        {
+          label: "娑堣�楁暟閲�",
+          prop: "amount"
+        },
+        {
+          label: "褰曞叆浜�",
+          prop: "enterUserName"
+        },
+        {
+          label: "鏈�杩戞洿鏂颁汉",
+          prop: "updateUserName"
+        },
+        {
+          label: "鏈�杩戞洿鏂版棩鏈�",
+          prop: "updateTime"
+        },
+        {
+          label: "鎿嶄綔",
+          dataType: "slot",
+          slot: "operation"
+        }
+      ],
+      tableData: [],
+      pagination: {
+        current: 1,
+        pageSize: 20,
+        total: 0
+      },
+      listId: 0,
+      row: undefined
+    }
+  },
+  mounted() {
+    this.fetchData()
+  },
+  methods: {
+    fetchListId(row) {
+      if(row) {
+        this.listId = row.id
+        this.row = row
+      }
+      this.fetchData()
+    },
+    async fetchData() {
+      if (this.listId === 0) return
+      procurementSuppliesExpendlist({
+        procurementSuppliesListId:this.listId
+      }).then(res => {
+        if (res.code === 200) {
+          this.tableData = res.data
+        }
+      })
+    },
+    showDialog() {
+      this.$refs.AddProjectRef.openDialog(this.row);
+    },
+    deleteData(row) {
+      deleteProcurementSuppliesExpends({ expendId:row.expendId}).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.fetchData()
+        }
+      })
+    },
+    handleCurrent() {
+    },
+    handleSize() {
+    },
+    exportExcel() {
+    }
+  }
+}
+</script>
+
+<style scoped>
+.flex {
+  display: flex;
+}
+
+.action-box {
+  width: 100%;
+  padding-top: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.pagination {
+  padding-top: 15px;
+  padding-right: 10px;
+  display: flex;
+  justify-content: space-between
+}
+</style>
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/component/Edit.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/component/Edit.vue
new file mode 100644
index 0000000..5e7f431
--- /dev/null
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/component/Edit.vue
@@ -0,0 +1,252 @@
+<template>
+  <el-dialog
+    :visible.sync="dialogVisible"
+    title="娣诲姞鑰楁潗椤圭洰淇℃伅"
+    width="70%"
+  >
+    <el-form ref="modelForm" :model="model" :rules="rules" label-width="100px">
+      <el-col :span="12">
+        <el-form-item label="鑰楁潗绫诲瀷" prop="consumablesType">
+          <el-select v-model="model.consumablesType" placeholder="璇烽�夋嫨鑰楁潗绫诲瀷" size="small" style="width: 100%">
+            <el-option v-for="(v, i) in dict.type.consumables_type" :key="i" :label="v.label" :value="v.value"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="璐у彿">
+          <el-input v-model="model.itemNumber" placeholder="璇疯緭鍏ヨ揣鍙�" size="small"></el-input>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鑰楁潗鍚嶇О">
+          <el-input v-model="model.consumablesName" placeholder="璇疯緭鍏ヨ�楁潗鍚嶇О" size="small"></el-input>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="瑙勬牸">
+          <el-input v-model="model.specifications" placeholder="璇疯緭鍏ヨ鏍�" size="small"></el-input>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="璁¢噺鍗曚綅">
+          <el-input v-model="model.unit" placeholder="璇疯緭鍏ヨ閲忓崟浣�" size="small"></el-input>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍙傝�冧环鏍�">
+          <el-input-number v-model="model.referencePrice" :min="0" :precision="2" :step="0.01" placeholder="璇疯緭鍏ュ弬鑰冧环鏍�"
+                           size="small"></el-input-number>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="瀛樻斁浣嶇疆">
+          <el-select v-model="model.contentId" placeholder="璇烽�夋嫨瀛樻斁浣嶇疆" size="small" style="width: 100%">
+            <el-option v-for="(v, i) in procurementSuppliesContentOptions" :key="i" :label="v.nodeName"
+                       :value="v.id"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="璐熻矗浜�">
+          <el-select v-model="model.personInCharge" placeholder="璇烽�夋嫨璐熻矗浜�" size="small" style="width: 100%">
+            <el-option v-for="(v, i) in userOptions" :key="i" :label="v.name" :value="v.id"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="搴撳瓨涓婇檺">
+          <el-input-number v-model="model.upperLimit" :min="0" :step="1" placeholder="璇疯緭鍏ュ簱瀛樹笂闄�" size="small"></el-input-number>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="搴撳瓨涓嬮檺">
+          <el-input-number v-model="model.lowerLimit" :min="0" :step="1" placeholder="璇疯緭鍏ュ簱瀛樹笅闄�" size="small"></el-input-number>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="渚涘簲鍟�">
+          <el-select v-model="model.supplier" placeholder="璇烽�夋嫨渚涘簲鍟�" size="small" style="width: 100%">
+            <el-option v-for="(v, i) in supplierOptions" :key="i" :label="v.supplierName"
+                       :value="v.supplierManagementId"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="鑰楁潗鍥炬爣">
+          <div class="rows">
+            <el-input v-model="model.consumablesIcon" placeholder="璇疯緭鍏ヨ�楁潗鍥炬爣" size="small" style="width: 90%;"/>
+            <el-upload
+              ref="upload"
+              :action="action"
+              :headers="uploadHeader"
+              :on-success="onSuccessIcon"
+              :show-file-list="false"
+              style="float: left; margin: 0 12px 0 20px;"
+            >
+              <el-button slot="trigger" class="uploadFile" size="small" type="primary">娴忚</el-button>
+            </el-upload>
+          </div>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="鑰楁潗闄勪欢">
+          <div class="rows">
+            <el-input v-model="model.attachment" placeholder="璇疯緭鍏ヨ�楁潗闄勪欢" size="small" style="width: 90%;"/>
+            <el-upload
+              ref="upload"
+              :action="action"
+              :on-success="onSuccessFile"
+              :show-file-list="false"
+              :headers="uploadHeader"
+              style="float: left; margin: 0 12px 0 20px;"
+            >
+              <el-button slot="trigger" class="uploadFile" size="small" type="primary">娴忚</el-button>
+            </el-upload>
+          </div>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="澶囨敞">
+          <el-input
+            v-model="model.remark"
+            :rows="2"
+            placeholder="璇疯緭鍏ュ娉�"
+            size="small"
+            type="textarea"
+          >
+          </el-input>
+        </el-form-item>
+      </el-col>
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+            <el-button @click="resetForm">鍙� 娑�</el-button>
+            <el-button type="primary" @click="submit">淇� 瀛�</el-button>
+        </span>
+  </el-dialog>
+</template>
+
+<script>
+import {
+  addProcurementSuppliesList,
+  updateProcurementSuppliesList,
+  selectSupplierManagementAll,
+  getProcurementSuppliesContentsNodeNames,
+  selectUserCondition
+} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      model: {
+        consumablesType: undefined,
+        consumablesIcon: undefined,
+        attachment: undefined,
+      },
+      procurementSuppliesContentOptions: [],
+      userOptions: [],
+      supplierOptions: [],
+      rules: {
+        consumablesType: [{ required: true, message: '璇烽�夋嫨鑰楁潗绫诲瀷', trigger: 'blur' }],
+      },
+    }
+  },
+  dicts: ["consumables_type"],
+  props: {
+    contentsId: {
+      type: Number,
+      required: true,
+    }
+  },
+  computed: {
+    action() {
+      return this.javaApi + '/personBasicInfo/saveCNASFile'
+    }
+  },
+  mounted() {
+    this.findProcurementSuppliesContentOptions()
+    this.findUserOptions()
+    this.findSupplierOptions()
+  },
+  methods: {
+    // 閲嶇疆琛ㄥ崟
+    resetForm() {
+      this.$refs.modelForm.resetFields();
+      this.dialogVisible = false
+    },
+    openDialog(row) {
+      if (row) {
+        console.log("row", row)
+        this.model = row
+      } else {
+        this.model = {}
+      }
+      this.dialogVisible = true
+    },
+    findProcurementSuppliesContentOptions() {
+      getProcurementSuppliesContentsNodeNames().then(res => {
+        if (res.code === 200) {
+          this.procurementSuppliesContentOptions = res.data
+        }
+      })
+    },
+    findUserOptions() {
+      selectUserCondition().then(res => {
+        if (res.code === 200) {
+          this.userOptions = res.data
+        }
+      })
+    },
+    findSupplierOptions() {
+      selectSupplierManagementAll().then(res => {
+        if (res.code === 200) {
+          this.supplierOptions = res.data
+        }
+      })
+    },
+    async onSuccessIcon(response) {
+      this.$set(this.model, "consumablesIcon", response.data)
+    },
+    async onSuccessFile(response) {
+      this.$set(this.model, "attachment", response.data)
+    },
+    submit() {
+      this.$refs.modelForm.validate((valid) => {
+        if (valid) {
+          if (this.model.id) {
+            updateProcurementSuppliesList(this.model).then(res => {
+              if (res.code === 200) {
+                this.dialogVisible = false
+              }
+            })
+          } else {
+            addProcurementSuppliesList(this.model).then(res => {
+              if (res.code === 200) {
+                this.dialogVisible = false
+                this.$emit('submit')
+              }
+            })
+          }
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+>>> .el-dialog__body {
+  max-height: 42em;
+  overflow-y: auto;
+}
+.rows {
+  width: 100%;
+  display: flex;
+  justify-content: space-between;
+}
+>>>.el-form-item__content {
+  line-height: 39px;
+}
+</style>
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/component/Store.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/component/Store.vue
new file mode 100644
index 0000000..1951036
--- /dev/null
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/component/Store.vue
@@ -0,0 +1,468 @@
+<template>
+  <div>
+    <div style="
+        display: flex;
+        justify-content: flex-end;
+        margin-right: 20px;
+        margin-bottom: 20px;
+      ">
+      <el-button icon="el-icon-plus" size="small" type="primary" @click="addOrUpdateStore('add')">娣诲姞
+      </el-button>
+      <el-button icon="el-icon-download" size="small" @click="importExcel">
+        瀵煎嚭excel
+      </el-button>
+    </div>
+    <div class="table">
+      <limsTable
+        :column="tableColumn"
+        :height="'calc(100vh - 20em)'"
+        :table-data="storageTableData"
+        :table-loading="tableLoading"
+        style="padding: 0 10px;margin-bottom: 16px"
+        :page="page"
+        @pagination="pagination">
+      </limsTable>
+    </div>
+
+    <!-- 缂栬緫-鏂板寮规 -->
+    <el-dialog :before-close="handleClose" :close-on-click-modal="false"
+               :close-on-press-escape="false" :title="title"
+               :visible.sync="dialogVisible" width="70%">
+      <!-- 鍏ュ簱鍗� -->
+      <div>
+        <div style="display: flex; align-items: center">
+          <span style="margin-left: 10px">鍏ュ簱鍗�</span>
+        </div>
+        <el-form ref="formModel" :model="form" label-width="auto">
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱鍗曞彿">
+              <el-input v-model="form.oddNumbers" placeholder="璇疯緭鍏ュ叆搴撳崟鍙�" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱搴撳瓨">
+              <el-input v-model="form.inventory" placeholder="璇疯緭鍏ュ叆搴撳簱瀛�" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱鎬婚噾棰�">
+              <el-input v-model="form.totalAmount" placeholder="璇疯緭鍏ュ叆搴撴�婚噾棰�" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱鏃ユ湡">
+              <el-date-picker v-model="form.storageTime" format="yyyy-MM-dd"
+                              placeholder="閫夋嫨鏃ユ湡"
+                              size="small"
+                              style="width: 100%" type="date" value-format="yyyy-MM-dd"></el-date-picker>
+            </el-form-item>
+          </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍏ュ簱浜�">
+                <el-select v-model="form.storageUser" size="small" style="width: 100%">
+                  <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱璇存槑">
+              <el-input v-model="form.remark" :rows="2" placeholder="璇疯緭鍏ュ唴瀹�" type="textarea">
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-form>
+      </div>
+      <!-- 鍏ュ簱鏄庣粏 -->
+      <div>
+        <div>鍏ュ簱鏄庣粏</div>
+        <div class="input-form">
+          <div>
+            <div>
+              <span>鑰楁潗鍚嶇О:</span>
+              <el-select v-model="formTwo.id" filterable placeholder="璇烽�夋嫨鑰楁潗鍚嶇О" size="small" style="width: 70%">
+                <el-option v-for="(v, i) in consumableOptions" :key="i" :label="v.consumablesName"
+                  :value="v.id"></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div>
+            <div>
+              <span>鍗曚环:</span>
+              <el-input v-model="formTwo.unitPrice" placeholder="璇疯緭鍏ュ崟浠�" size="small" style="width: 70%">
+              </el-input>
+            </div>
+          </div>
+          <div>
+            <div>
+              <span>鍏ュ簱鏁伴噺:</span>
+              <el-input v-model="formTwo.storeNumber" placeholder="璇疯緭鍏ュ叆搴撴暟閲�" size="small" style="width: 70%">
+              </el-input>
+            </div>
+          </div>
+          <div>
+            <div>
+              <span>鎬讳环:</span>
+              <el-input v-model="formTwo.totalPrice" placeholder="璇疯緭鍏ユ�讳环" size="small" style="width: 70%">
+              </el-input>
+            </div>
+          </div>
+          <el-button size="mini" type="primary"
+            @click="addTableData">娣诲姞
+          </el-button>
+        </div>
+        <el-table :data="consumables" style="margin-top: 10px">
+          <el-table-column label="缂栧彿" type="index" width="120px"></el-table-column>
+          <el-table-column label="璐у彿" prop="itemNumber"></el-table-column>
+          <el-table-column label="绫诲埆" prop="type"></el-table-column>
+          <el-table-column label="鍚嶇О" prop="consumablesName"></el-table-column>
+          <el-table-column label="瑙勬牸" prop="specifications"></el-table-column>
+          <el-table-column label="鍙傝�冧緵搴斿晢" prop="supplier"></el-table-column>
+          <el-table-column label="璁¢噺鍗曚綅" prop="unit"></el-table-column>
+          <el-table-column label="鍗曚环" prop="unitPrice"></el-table-column>
+          <el-table-column label="鍏ュ簱鏁伴噺" prop="storeNumber"></el-table-column>
+          <el-table-column label="鎬讳环" prop="totalPrice"></el-table-column>
+          <el-table-column label="鎿嶄綔" width="80px">
+            <template slot-scope="scope">
+              <el-button size="mini" style="color: #f56c6c" type="text" @click="deleteTableData(scope.$index)">鍒犻櫎
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">鍙� 娑�</el-button>
+        <el-button type="primary" :loading="saveLoading" @click="save">淇� 瀛�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addStore,
+  deleteStore,
+  exportProcurementSuppliesStoreExcel,
+  procurementSuppliesList,
+  selectStoreById,
+  selectUserCondition,
+  storeList,
+  updateStore
+} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
+import limsTable from '@/components/Table/lims-table.vue'
+
+export default {
+  computed: {
+    title() {
+      return this.dialogType == "add" ? "鏂板缓鍏ュ簱" : "缂栬緫鍏ュ簱";
+    },
+  },
+  dicts: ["consumables_type"],
+  props: {
+    contentsId: {
+      type: Number,
+      default: 0
+    }
+  },
+  watch: {
+
+  },
+  data() {
+    return {
+      mutiList: [],
+      consumables: [],
+      users: [],
+      form: {
+        oddNumbers: null,
+        inventory: null,
+        totalAmount: null,
+        storageTime: null,
+        storageUser: null,
+        remark: null,
+      },
+      formTwo: {
+        consumablesName: null,
+        unitPrice: null,
+        storeNumber: null,
+        totalPrice: null,
+      },
+      dialogVisible: false,
+      dialogType: "",
+      upIndex: 0,
+      tableColumn: [
+        {
+          label: '鍏ュ簱鍗曞彿',
+          prop: 'oddNumbers',
+          minWidth: '100'
+        },
+        {
+          label: '鑰楁潗鍚嶇О',
+          prop: 'consumablesName',
+          minWidth: '100'
+        },
+        {
+          label: '鍏ュ簱鏁伴噺',
+          prop: 'storeNumber',
+          minWidth: '100'
+        },
+        {
+          label: '鍏ュ簱鎬讳环',
+          prop: 'totalPrice',
+          minWidth: '100'
+        },
+        {
+          label: '鍏ュ簱浜�',
+          prop: 'storageUserName',
+          minWidth: '100'
+        }, {
+          label: '鍏ュ簱鏃ユ湡',
+          prop: 'storageTime',
+          minWidth: '100'
+        }, {
+          label: '璇存槑',
+          prop: 'remark',
+          minWidth: '100'
+        }, {
+          label: '鐧昏浜�',
+          prop: 'registrantName',
+          minWidth: '160'
+        },{
+          label: '鐧昏鏃ユ湡',
+          prop: 'registrantTime',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          fixed: 'right',
+          minWidth: '120',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.addOrUpdateStore('edit', row);
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deleteStore(row)
+              },
+            }
+          ]
+        }
+      ],
+      tableLoading: false,
+      page: {
+        total: 0,
+        size: 10,
+        current: 1
+      },
+      consumableOptions: [],
+      options: [],
+      storageTableData: [],
+      searchForm: {
+        orderBy: {
+          field: "id",
+          order: "desc",
+        },
+      },
+      saveLoading: false,
+    };
+  },
+  components: {
+    limsTable,
+  },
+  mounted() {
+    this.searchList();
+    this.getUserList();
+    this.fetchListOptions()
+    this.options = this.dict.type.consumables_type
+  },
+  methods: {
+    // 淇濆瓨
+    save() {
+      let data = {
+        store: this.form,
+        consumables: this.consumables,
+      };
+      this.saveLoading = true;
+      if (this.dialogType === "update") {
+        updateStore(data).then((res) => {
+          this.saveLoading = false
+          if (res.code == 200) {
+            this.$message.success("淇敼鎴愬姛");
+            this.handleClose();
+            // this.$refs.selectList()
+            this.searchList()
+          }
+        }).catch((err) => {
+          this.saveLoading = false
+        })
+      } else {
+        addStore(data).then((res) => {
+          this.saveLoading = false
+          if (res.code == 200) {
+            this.$message.success("鏂板鎴愬姛");
+            this.handleClose();
+            // this.$refs.selectList()
+            this.searchList()
+          }
+        }).catch((err) => {
+          this.saveLoading = false
+        })
+      }
+    },
+    findType(val) {
+      console.log(val)
+      return this.options.find(item => item.value === val).label
+    },
+    // 娣诲姞琛ㄦ牸鏁版嵁
+    addTableData() {
+      this.$nextTick()
+      console.log('this.consumableOptions',this.consumableOptions)
+      this.consumableOptions.forEach(item => {
+        if (item.id === this.formTwo.id) {
+          this.consumables.push({
+            itemNumber: null,
+            type: this.findType(item.consumablesType),
+            consumablesName: item.consumablesName,
+            specifications: item.specifications,
+            supplier: item.supplierName,
+            unit: item.unit,
+            unitPrice: this.formTwo.unitPrice,
+            storeNumber: this.formTwo.storeNumber,
+            totalPrice: this.formTwo.totalPrice,
+          });
+        }
+      })
+    },
+    deleteTableData(index) {
+      this.consumables.splice(index, 1);
+    },
+    // 鎵撳紑寮规
+    addOrUpdateStore(type,row) {
+      if (type === 'edit') {
+        this.dialogType = "update";
+        selectStoreById({id:row.id}).then(res => {
+          if (res.code === 201) return
+          this.consumables = res.data.consumables
+          this.form = {...res.data.store}
+        }).catch(err => {
+          console.log('err---', err);
+        })
+      } else {
+        this.dialogType = "add";
+      }
+      this.dialogVisible = true;
+    },
+    // 鏌ヨ鍒楄〃
+    searchList () {
+      this.tableLoading = true
+      storeList({...this.page,...this.searchForm}).then(res => {
+        this.tableLoading = false
+        if (res.code === 200){
+          this.storageTableData = res.data.records
+          this.page.total = res.data.total
+        }
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 瀵煎嚭excel
+    async importExcel() {
+      exportProcurementSuppliesStoreExcel({parentId:this.contentsId}).then(res => {
+        const blob = new Blob([res], {type: 'application/octet-stream'});
+        this.$download.saveAs(blob, '鑰楁潗鍏ュ簱.xlsx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    handleClose() {
+      this.form = {
+        oddNumbers: null,
+        inventory: null,
+        totalAmount: null,
+        storageTime: null,
+        storageUser: null,
+        remark: null,
+      };
+      this.formTwo = {
+        consumablesName: null,
+        unitPrice: null,
+        storeNumber: null,
+        totalPrice: null,
+      };
+      this.consumables = [];
+      this.dialogVisible = false;
+    },
+    viewIssued(row) {
+      console.log(row);
+    },
+    // 鑾峰彇鎵�鏈夌敤鎴�
+    getUserList() {
+      selectUserCondition().then((res) => {
+          this.users = res.data;
+        });
+    },
+    async fetchListOptions() {
+      procurementSuppliesList({contentsId: this.contentsId}).then(res => {
+        if (res.code === 200) {
+          this.consumableOptions = res.data.records
+        }
+      })
+
+    },
+    // 鍒犻櫎
+    deleteStore (row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        console.log('row>>>>>>>>>>>>>>s',row)
+        deleteStore({
+          id:row.id,
+          consumablesId:row.consumablesId
+        }).then(res => {
+          this.tableLoading = false
+          if (res.code === 200){
+            this.$message.success('鍒犻櫎鎴愬姛')
+            this.searchList()
+          }
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+
+    pagination(page) {
+      this.page.size = page.limit
+      this.searchList();
+    },
+  },
+};
+</script>
+
+<style scoped>
+.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+.el-dialog__body {
+  max-height: 42em;
+  overflow-y: auto;
+}
+.input-form {
+  display: flex;
+  margin: 10px 0;
+}
+</style>
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/component/contents.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/component/contents.vue
new file mode 100644
index 0000000..2d17786
--- /dev/null
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/component/contents.vue
@@ -0,0 +1,312 @@
+<template>
+  <div class="parent-class">
+    <div style="display: flex; justify-content: flex-end; margin-right: 20px">
+      <el-button
+        type="primary"
+        @click="addContents"
+        size="small"
+        icon="el-icon-plus"
+        >娣诲姞瀛愯妭鐐�</el-button
+      >
+      <el-button
+        type="danger"
+        @click="deletetContents"
+        size="small"
+        icon="el-icon-delete"
+        >鍒犻櫎瀛愯妭鐐�</el-button
+      >
+      <el-button
+        type="warning"
+        @click="updateContents"
+        size="small"
+        icon="el-icon-edit"
+        >鏇存柊瀛愯妭鐐�</el-button
+      >
+    </div>
+    <el-form label-width="100px">
+      <el-form-item label="鑺傜偣鍚嶇О">
+        <el-input
+          v-model="form.nodeName"
+          style="width: 200px"
+          size="small"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="浠e彿">
+        <el-input
+          v-model="form.code"
+          style="width: 200px"
+          size="small"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="鏇存柊浜�">
+        <el-select v-model="form.updateUser">
+          <el-option
+            v-for="item in users"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鏇存柊鏃堕棿">
+        <el-input
+          v-model="form.updateTime"
+          style="width: 200px"
+          size="small"
+        ></el-input>
+      </el-form-item>
+    </el-form>
+
+    <!-- 鏂板寮规 -->
+    <el-dialog title="娣诲姞鑺傜偣" :visible.sync="dialogVisible" width="40%">
+      <el-form
+        label-width="100px"
+        :model="addForm"
+        ref="addForm"
+        :rules="rules"
+      >
+        <el-form-item label="鐖惰妭鐐瑰悕绉�">
+          <!-- <el-select v-model="addForm.parentId">
+              <el-option v-for="(item,index) in nodeNames" :key="index" :label="item.nodeName" :value="item.id"></el-option>
+            </el-select> -->
+          <el-cascader
+            v-model="addForm.parentId"
+            :options="treeData"
+            :props="{ checkStrictly: true, value: 'id', label: 'nodeName' }"
+            clearable
+          ></el-cascader>
+        </el-form-item>
+        <el-form-item label="鑺傜偣鍚嶇О" prop="nodeName">
+          <el-input
+            v-model="addForm.nodeName"
+            style="width: 200px"
+            size="small"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="浠e彿">
+          <el-input
+            v-model="addForm.code"
+            style="width: 200px"
+            size="small"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+<script>
+
+import {
+  addSuppliersDirectoryContents,
+  updateSuppliersDirectoryContents,
+  deleteSuppliersDirectoryContentsById,
+  getSuppliersDirectoryContentsNodeNames,
+  selectUserCondition,
+  selectProcurementSuppliesContentById,
+  getProcurementSuppliesContentsNodeNames,
+  addProcurementSuppliesContents, deleteProcurementSuppliesContentById
+} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
+export default {
+  props: {
+    id: {
+      type: Number,
+      default: 0,
+    },
+    treeData: {
+      type: Array,
+      default: () => [],
+    },
+    from: {
+      type: String,
+      default: "鑰楁潗鏍�"
+    }
+  },
+  data() {
+    return {
+      nodeNames: [],
+      users: [],
+      dialogVisible: false,
+      form: {
+        nodeName: "",
+        code: "",
+        updateUser: "",
+        updateTime: "",
+      },
+      addForm: {
+        nodeName: "",
+        code: "",
+        updateUser: "",
+        updateTime: "",
+        parentId: null,
+      },
+      rules: {
+        nodeName: [
+          { required: true, message: "璇疯緭鍏ヨ妭鐐瑰悕绉�", trigger: "blur" },
+        ],
+      },
+    };
+  },
+  mounted() {
+    if (this.id !== 0) {
+      this.getContentsDetail();
+    }
+    this.getNodeNames();
+    this.getUserList();
+  },
+  watch: {
+    id(newVal, oldVal) {
+      if (newVal !== 0) {
+        console.log(newVal, oldVal);
+        this.getContentsDetail();
+      }
+    },
+  },
+  methods: {
+    // 鑾峰彇鐩綍璇︽儏
+    getContentsDetail() {
+      selectProcurementSuppliesContentById({id:this.id})
+        .then((res) => {
+          if (res.data == null) {
+            this.form = {
+              nodeName: "",
+              code: "",
+              updateUser: "",
+              updateTime: "",
+            };
+            return;
+          }
+          this.form = res.data;
+        });
+    },
+    // 鏂板缓
+    addContents() {
+      this.dialogVisible = true;
+      this.resetForm();
+    },
+    resetForm() {
+      this.addForm = {
+        nodeName: "",
+        code: "",
+        updateUser: "",
+        updateTime: "",
+        parentId: null,
+      };
+    },
+    async submitForm() {
+      let flag = true;
+      this.$refs.addForm.validate((valid) => {
+        if (!valid) {
+          flag = false;
+          return false;
+        }
+      });
+      if (this.addForm.parentId) {
+        this.addForm.parentId =
+          this.addForm.parentId[this.addForm.parentId.length - 1];
+      }
+      if (!flag) {
+        return;
+      }
+      try {
+        let res = null
+        console.log('this.from',this.from)
+        if(this.from == '鑰楁潗鏍�' ){
+          console.log('111')
+          res = await addProcurementSuppliesContents(this.addForm)
+        }else {
+          console.log('222')
+          res = await addSuppliersDirectoryContents(this.addForm)
+        }
+        if (res.code === 200) {
+          this.$message.success("娣诲姞鎴愬姛");
+          this.dialogVisible = false;
+          this.$emit("contentsUpdate", res.data);
+          this.getContentsDetail();
+        }
+      }catch (error){
+        this.$message.error("娣诲姞澶辫触");
+      }
+    },
+    // 鏇存柊
+    updateContents() {
+      Object.keys(this.form).forEach((key) => {
+        if (key == "children") {
+          delete this.form[key];
+        }
+      });
+      updateSuppliersDirectoryContents(this.form).then((res) => {
+          if (res.code === 200) {
+            this.$message.success("鏇存柊鎴愬姛");
+            this.$emit("contentsUpdate", this.id);
+            this.dialogVisible = false;
+            this.getContentsDetail();
+          }
+        });
+    },
+    // 鍒犻櫎
+    deletetContents() {
+      if (
+        this.form.id == null ||
+        this.form.id == "" ||
+        this.form.id == undefined
+      ) {
+        this.$message.error("璇烽�夋嫨瑕佸垹闄ょ殑鑺傜偣");
+        return;
+      }
+      this.$confirm("姝ゆ搷浣滃皢鍒犻櫎璇ヨ妭鐐�, 鏄惁缁х画?", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      }).then(() => {
+        if(this.from == '鑰楁潗鏍�'){
+          deleteProcurementSuppliesContentById({id:this.form.id}).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("鍒犻櫎鎴愬姛");
+              this.$emit("contentsUpdate", this.form.parentId, true);
+              this.getContentsDetail();
+            }
+          });
+        }else {
+          deleteSuppliersDirectoryContentsById({id:this.form.id}).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("鍒犻櫎鎴愬姛");
+              this.$emit("contentsUpdate", this.form.parentId, true);
+              this.getContentsDetail();
+            }
+          });
+        }
+      });
+    },
+    // 鑾峰彇鎵�鏈夌洰褰曡妭鐐�
+    getNodeNames() {
+      if(this.from == '鑰楁潗鏍�'){
+        getProcurementSuppliesContentsNodeNames().then(res => {
+          this.nodeNames = res.data;
+        })
+      }else {
+        getSuppliersDirectoryContentsNodeNames().then(res => {
+          this.nodeNames = res.data;
+        })
+      }
+    },
+    // 鑾峰彇鎵�鏈夌敤鎴�
+    getUserList() {
+      selectUserCondition().then((res) => {
+        this.users = res.data;
+      })
+    },
+  },
+  created() {},
+};
+</script>
+
+  <style scoped>
+.parent-class {
+  margin-top: 20px;
+}
+</style>
diff --git a/src/views/CNAS/externalService/serviceAndSupplyPro/index.vue b/src/views/CNAS/externalService/serviceAndSupplyPro/index.vue
index 836d07a..9efac6d 100644
--- a/src/views/CNAS/externalService/serviceAndSupplyPro/index.vue
+++ b/src/views/CNAS/externalService/serviceAndSupplyPro/index.vue
@@ -27,30 +27,33 @@
         <el-tab-pane label="鑰楁潗鎬昏" name="first" :lazy="true">
           <ConsumableOverview v-if="activeName == 'first'" :contentsId="contentsId"></ConsumableOverview>
         </el-tab-pane>
-<!--        <el-tab-pane label="鑰楁潗鍒楄〃" name="second" :lazy="true">-->
-<!--          <ConsumableList v-if="activeName == 'second'" :contentsId="contentsId"></ConsumableList>-->
-<!--        </el-tab-pane>-->
-<!--        <el-tab-pane label="鑰楁潗鍏ュ簱" name="third" :lazy="true">-->
-<!--          <Store v-if="activeName == 'third'" :contentsId="contentsId"></Store>-->
-<!--        </el-tab-pane>-->
-<!--        <el-tab-pane label="鐩綍缁存姢" name="fourth" :lazy="true">-->
-<!--          <Contents-->
-<!--            v-if="activeName == 'fourth'"-->
-<!--            :id="contentsId"-->
-<!--            @contentsUpdate="contentsUpdate"-->
-<!--            :treeData="treeData"-->
-<!--            from="鑰楁潗鏍�"-->
-<!--          ></Contents>-->
-<!--        </el-tab-pane>-->
+        <el-tab-pane label="鑰楁潗鍒楄〃" name="second" :lazy="true">
+          <ConsumableList v-if="activeName == 'second'" :contentsId="contentsId"></ConsumableList>
+        </el-tab-pane>
+        <el-tab-pane label="鑰楁潗鍏ュ簱" name="third" :lazy="true">
+          <Store v-if="activeName == 'third'" :contentsId="contentsId"></Store>
+        </el-tab-pane>
+        <el-tab-pane label="鐩綍缁存姢" name="fourth" :lazy="true">
+          <Contents
+            v-if="activeName == 'fourth'"
+            :id="contentsId"
+            @contentsUpdate="contentsUpdate"
+            :treeData="treeData"
+            from="鑰楁潗鏍�"
+          ></Contents>
+        </el-tab-pane>
       </el-tabs>
     </div>
   </div>
 </template>
 <script>
-// import Contents from "@/components/do/a6.service-and-supply-purchase/contents.vue";
-// import Store from "@/components/do/a6.service-and-supply-purchase/store.vue";
-import ConsumableOverview from "../serviceAndSupplyPro/component/ConsumableOverview.vue";
-// import ConsumableList from "@/components/do/a6.service-and-supply-purchase/ConsumableList.vue"
+import Contents from "./component/contents.vue";
+import Store from "./component/Store.vue";
+import ConsumableOverview from "./component/ConsumableOverview.vue";
+import ConsumableList from "./component/ConsumableList.vue"
+import {
+  directoryListing
+} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
 
 export default {
   data() {
@@ -70,10 +73,10 @@
     };
   },
   components: {
-    // Contents,
-    // Store,
-    ConsumableOverview
-    // ConsumableList
+    Contents,
+    Store,
+    ConsumableOverview,
+    ConsumableList
   },
   watch: {
     contentsId(newVal, oldVal) {
@@ -129,9 +132,7 @@
     },
     // 鏌ヨ鎵�鏈夌洰褰�
     getTreeData() {
-      this.$axios
-        .get(this.$api.procurementSuppliesContents.directoryListing)
-        .then((res) => {
+      directoryListing().then((res) => {
           this.treeData = res.data;
         });
     },
diff --git a/src/views/CNAS/personnel/personnelOverview/index.vue b/src/views/CNAS/personnel/personalOverview/index.vue
similarity index 100%
rename from src/views/CNAS/personnel/personnelOverview/index.vue
rename to src/views/CNAS/personnel/personalOverview/index.vue
diff --git a/src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue b/src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue
new file mode 100644
index 0000000..564fee1
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue
@@ -0,0 +1,175 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="addTrainingPlanDia" title="鏂板鍩硅璁″垝" width="50%" @close="closeAdd">
+      <div class="body">
+        <el-form ref="trainingPlanForm" :model="trainingPlan" label-position="right" label-width="90px" :rules="trainingPlanRules">
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鏃ユ湡:" prop="trainingDate">
+                <el-date-picker v-model="trainingPlan.trainingDate" format="yyyy-MM"
+                                placeholder="閫夋嫨鏃ユ湡" size="small" value-format="yyyy-MM"
+                                type="month" style="width: 100%"></el-date-picker>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="璇炬椂:" prop="classHour">
+                <el-input type="number" v-model="trainingPlan.classHour" label="鎻忚堪鏂囧瓧" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鐩爣:" prop="trainingObjectives">
+                <el-input v-model="trainingPlan.trainingObjectives" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍙傚姞瀵硅薄:" prop="participants">
+                <el-input v-model="trainingPlan.participants" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鍐呭:" prop="trainingContent">
+                <el-input v-model="trainingPlan.trainingContent" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅璁插笀:" prop="trainingLecturerId">
+                <el-select v-model="trainingPlan.trainingLecturerId"
+                           clearable filterable
+                           placeholder="璇烽�夋嫨" size="small" style="width: 100%;">
+                  <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鏂瑰紡:" prop="trainingMode">
+                <el-input v-model="trainingPlan.trainingMode" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="涓惧姙閮ㄩ棬:" prop="holdingDepartment">
+                <el-input v-model="trainingPlan.holdingDepartment" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="澶囨敞:" prop="remarks">
+                <el-input v-model="trainingPlan.remarks" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+				<el-button @click="closeAdd">鍙� 娑�</el-button>
+        <el-button type="primary" :loading="submitAddLoading" @click="submitAdd">纭� 瀹�</el-button>
+			</span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {addOrUpdatePersonTrainingDetailed} from "@/api/cnas/personal/personalTraining";
+import {selectUserCondition} from "@/api/system/user";
+
+export default {
+  props: {
+    currentChangeRow: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+  },
+  name: 'Add',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      addTrainingPlanDia: false,
+      submitAddLoading: false,
+      trainingPlan: {
+        planId: '',
+        id: '',
+        trainingDate: '',
+        classHour: '',
+        trainingObjectives: '',
+        participants: '',
+        trainingContent: '',
+        trainingLecturerId: '',
+        trainingMode: '',
+        holdingDepartment: '',
+        remarks: '',
+      },
+      trainingPlanRules: {
+        trainingDate: [{ required: true, message: '璇烽�夋嫨鍩硅鏃ユ湡', trigger: 'change' }],
+        trainingContent: [{ required: true, message: '璇疯緭鍏ュ煿璁唴瀹�', trigger: 'blur' }],
+        trainingLecturerId: [{ required: true, message: '璇烽�夋嫨鍩硅璁插笀', trigger: 'blur' }],
+      },
+      responsibleOptions: [],
+      operationType: ''
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    showDialog(id, type, row) {
+      this.addTrainingPlanDia = true;
+      this.operationType = type
+      if (this.operationType === 'edit') {
+        this.trainingPlan = this.HaveJson(row)
+      } else {
+        this.trainingPlan = {
+          id: '',
+          trainingDate: '',
+          classHour: '',
+          trainingObjectives: '',
+          participants: '',
+          trainingContent: '',
+          trainingLecturerId: '',
+          trainingMode: '',
+          holdingDepartment: '',
+          remarks: '',
+        }
+      }
+      this.trainingPlan.planId = id
+      this.getUserList()
+    },
+    // 鎻愪氦鏂板
+    submitAdd() {
+      this.$refs.trainingPlanForm.validate((valid) => {
+        if (valid) {
+          this.submitAddLoading = true
+          this.trainingPlan.planId = this.currentChangeRow.id
+          const personTrainingDetailed = this.trainingPlan
+          addOrUpdatePersonTrainingDetailed(personTrainingDetailed).then(res => {
+            this.submitAddLoading = false
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.closeAdd();
+            }
+          }).catch(() => {
+            this.submitAddLoading = false
+          })
+        }
+      })
+    },
+    // 鍏抽棴寮规
+    closeAdd() {
+      this.$refs['trainingPlanForm'].resetFields();
+      this.$emit('search')
+      this.addTrainingPlanDia = false;
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      selectUserCondition().then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      })
+    },
+  },
+};
+</script>
+
+<style scoped>
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/components/Edit.vue b/src/views/CNAS/personnel/personnelInfo/components/Edit.vue
new file mode 100644
index 0000000..3992697
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/Edit.vue
@@ -0,0 +1,452 @@
+<template>
+  <div>
+    <div class="page-header">
+      <h4><span class="line"></span><span>鍩硅涓庤�冩牳璁板綍</span></h4>
+      <div class="btns">
+        <el-button size="small" type="primary" @click="submitForm(3)" v-if="this.currentRow.state !== 1">鎾ら攢</el-button>
+        <el-button size="small" type="primary" @click="submitForm(0)" v-if="this.currentRow.state !== 1">鎻愪氦</el-button>
+        <el-button size="small" @click="$emit('goBack')">杩斿洖</el-button>
+      </div>
+    </div>
+    <div class="form_title">
+      <el-row>
+        <el-col :span="7">
+          <span class="form_label">鍩硅鍐呭锛�</span>
+          <span> {{ trainingForm.trainingContent }} </span>
+        </el-col>
+        <el-col :span="5">
+          <span class="form_label">鐘舵�侊細</span>
+          <el-tag v-if="trainingForm.state === 1" type="success">宸插畬鎴�</el-tag>
+          <el-tag v-if="trainingForm.state === 2" type="warning">寰呰瘎浠�</el-tag>
+          <el-tag v-if="trainingForm.state === 3" type="primary">鏈紑濮�</el-tag>
+        </el-col>
+        <el-col :span="4">
+          <span class="form_label">鍩硅璁插笀锛�</span>
+          <span> {{ trainingForm.trainingLecturerName }} </span>
+        </el-col>
+      </el-row>
+      <el-row style="margin: 15px 0">
+        <el-form>
+          <el-row>
+          <el-col :span="5">
+            <el-form-item label="鍩硅鏃ユ湡:">
+              <el-date-picker v-model="trainingForm.openingTime" format="yyyy-MM-dd" :disabled="currentRow.state !== 3"
+                              placeholder="閫夋嫨鏃ユ湡" size="small" value-format="yyyy-MM-dd"
+                              type="date" style="width: 60%"></el-date-picker>
+            </el-form-item>
+          </el-col>
+            <el-col :span="7">
+              <el-form-item label="鍩硅鍦扮偣">
+                <el-input v-model="trainingForm.placeTraining" :disabled="currentRow.state !== 3" :rows="2" placeholder="璇疯緭鍏�"
+                          size="small" style="width: 60%" type="text"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="璇勪环浜�">
+                <el-select v-model="trainingForm.assessmentUserId" :disabled="currentRow.state !== 3" placeholder="璇烽�夋嫨" size="small" style="width: 50%">
+                  <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鑰冩牳鏂瑰紡">
+                <el-input v-model="trainingForm.assessmentMethod" :disabled="currentRow.state !== 3" :rows="2" placeholder="璇疯緭鍏�"
+                          size="small" style="width: 79%" type="textarea"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="璇勪环鏃堕棿">
+                <el-date-picker v-model="trainingForm.assessmentDate" :disabled="currentRow.state !== 2 || isDisabled"
+                                type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" size="small"
+                                placeholder="閫夋嫨鏃ユ湡">
+                </el-date-picker>
+              </el-form-item>
+            </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏈鍩硅缁煎悎璇勪环">
+              <el-input v-model="trainingForm.comprehensiveAssessment" :disabled="currentRow.state !== 2 || isDisabled" :rows="2" placeholder="璇疯緭鍏�"
+                        size="small" style="width: 68%" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          </el-row>
+        </el-form>
+      </el-row>
+    </div>
+    <el-divider>浜哄憳璇︽儏</el-divider>
+    <div>
+      <div class="items_center">
+        <span>濮撳悕</span>
+        <el-input v-model="userName" class="search" placeholder="璇疯緭鍏�"
+                  size="small"></el-input>
+        <el-button size="small" type="primary" @click="getInfo">鏌ヨ</el-button>
+      </div>
+      <div class="items_btn">
+        <el-button :disabled="currentRow.state === 1" size="small" type="primary" @click="addPerson">鏂板浜哄憳</el-button>
+        <el-button :disabled="currentRow.state === 1" size="small" @click="batchDelete">鎵归噺鍒犻櫎</el-button>
+      </div>
+      <el-table :data="trainingTableData" height="calc(100vh - 30em)" stripe style="width: 100%"
+                @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column label="搴忓彿" type="index" width="60"></el-table-column>
+        <el-table-column label="濮撳悕" prop="userName"></el-table-column>
+        <el-table-column label="宸ュ彿" prop="account"></el-table-column>
+        <el-table-column label="瑙掕壊" prop="roleName"></el-table-column>
+        <el-table-column label="鐢佃瘽鍙风爜" prop="phone"></el-table-column>
+        <el-table-column label="鑰冩牳缁撴灉" prop="examinationResults">
+          <template v-slot="scope">
+            <el-input v-model="scope.row.examinationResults" :disabled="currentRow.state === 1" clearable size="small" style="width: 100%" @blur="updatePersonResult(scope.row)"></el-input>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <el-dialog :visible.sync="selectUserDia" title="閫夋嫨鐢ㄦ埛" width="70%">
+      <div class="search" style="margin-bottom: 9px;">
+        <div class="search_thing">
+          <div class="search_label">鐢ㄦ埛鍚嶏細</div>
+          <div class="search_input">
+            <el-input
+              v-model="addUserTableInfo.name"
+              clearable
+              placeholder="璇疯緭鍏�"
+              size="small"
+              @keyup.enter.native="selectUserList"
+            ></el-input>
+          </div>
+        </div>
+      </div>
+      <div v-if="selectUserDia" class="body" style="height: 60vh;">
+        <lims-table :tableData="tableData1" :column="column1"
+                    :isSelection="true" :handleSelectionChange="selectMethod"
+                    @pagination="pagination1" :height="'calc(100vh - 290px)'"
+                    :page="page1" :tableLoading="tableLoading1"></lims-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="selectUserDia = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="selectUser">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+import limsTable from "@/components/Table/lims-table.vue";
+import {selectUserCondition} from "@/api/business/inspectionTask";
+import {mapGetters} from "vuex";
+import {
+  newPersonnelAddedToTrainingRecords,
+  outOfFocusPreservation, trainingAndAssessmentRecordsAdded, trainingAndAssessmentRecordsEvaluate,
+  trainingAndAssessmentRecordsPage
+} from "@/api/cnas/personal/personalTraining";
+
+export default {
+  name: 'Edit',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {limsTable},
+  props: {
+    currentRow: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+  },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      isSelectedList: [], // 绂佺敤鐨勫閫�
+      userName: undefined,
+      trainingForm: {
+        code: '111111',
+        date: '2024-10-10',
+      },
+      trainingColumn: [
+        {
+          label: '濮撳悕',
+          prop: 'userName'
+        },
+        {
+          label: '宸ュ彿',
+          prop: 'account'
+        },
+        {
+          label: '瑙掕壊',
+          prop: 'roleName'
+        },
+        {
+          label: '鐢佃瘽鍙风爜',
+          prop: 'phone'
+        },
+        {
+          label: '鑰冩牳缁撴灉',
+          prop: 'result'
+        }
+      ],
+      trainingTableData: [],
+      trainingLoading: false,
+      isDisabled: false,
+      selectUserDia: false, // 娣诲姞浜哄憳寮规
+      tableData1: [],
+      tableLoading1: false,
+      column1: [
+        {label: '濮撳悕', prop: 'name'},
+        {label: '璐﹀彿', prop: 'account'},
+        {label: '瑙掕壊', prop: 'roleName'},
+        {
+          dataType: 'tag',
+          label: '鐘舵��',
+          prop: 'status',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鍚敤'
+            } else {
+              return ''
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'success'
+            } else {
+              return 'danger'
+            }
+          }
+        },
+        {label: '鐢佃瘽鍙风爜', prop: 'phone'},
+      ],
+      page1: {
+        total:0,
+        size:10,
+        current:1
+      },
+      addUserTableInfo: {
+        name: null,
+      },
+      multipleSelection: [],
+      userList: [],
+    };
+  },
+  computed: {
+    ...mapGetters(["userId"]),
+  },
+  mounted() {
+    this.trainingForm = this.currentRow
+    this.getInfo()
+    this.getUserList()
+    this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鑾峰彇褰撳墠鏁版嵁
+    async getInfo() {
+      this.trainingLoading = true
+      await trainingAndAssessmentRecordsPage({
+        trainingDetailedId: this.currentRow.id,
+        userName: this.userName
+      }).then(res => {
+        if (res.code === 200) {
+          this.trainingTableData = res.data
+        }
+        this.trainingLoading = false
+      })
+    },
+    updatePersonResult(row) {
+      outOfFocusPreservation(row).then(res => {
+        this.$message.success("鎿嶄綔鎴愬姛锛�")
+      })
+    },
+    addPerson() {
+      this.isSelectedList = this.trainingTableData.map(item => item.userId)
+      this.selectUserDia = true;
+    },
+    selectUserList () {
+      this.tableLoading1 = true
+      selectUserCondition({...this.addUserTableInfo}).then(res => {
+        this.tableData1 = res.data.records
+        this.page1.total = res.data.total
+      }).catch(err => {
+        this.tableLoading1 = false
+      })
+    },
+    pagination1 (page) {
+      this.page1.size = page.limit
+      this.selectUserList()
+    },
+    // 琛ㄦ牸閫夋嫨鏂规硶
+    selectMethod(val) {
+      this.multipleSelection = val
+    },
+    selectUser() {
+      let selects = this.multipleSelection;
+      if (selects.length == 0) {
+        this.$message.error('鏈�夋嫨鏁版嵁');
+        return;
+      }
+      let list = []
+      selects.forEach(a => {
+        const obj = {
+          courseId: this.currentRow.id,
+          examinationResults: "",
+          userId: a.id
+        }
+        list.push(obj)
+      });
+      newPersonnelAddedToTrainingRecords(list).then(res => {
+        this.isSelectedList = []
+        this.selectUserDia = false;
+        this.getInfo()
+      })
+    },
+    // 鎵归噺鍒犻櫎
+    handleSelectionChange(list) {
+      this.multipleSelection = list
+    },
+    batchDelete() {
+      if (this.multipleSelection.length > 0) {
+        let ids = this.multipleSelection.map(item => item.trainingRecordId)
+        this.$confirm('鏄惁纭鍒犻櫎鎵�閫夋嫨鐨勬暟鎹�?', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          let formData = new FormData()
+          formData.append('ids', ids)
+          deleteTrainingAndAssessmentRecords(formData).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鍒犻櫎鎴愬姛');
+              this.getInfo()
+            }
+          });
+        }).catch(() => {
+          this.$message.warning('鍙栨秷鍒犻櫎');
+        });
+      } else {
+        this.$message.warning('璇烽�夋嫨闇�瑕佸垹闄ょ殑鏁版嵁')
+      }
+    },
+    handleSizeChange(val) {
+      this.search.size = val;
+      this.getInfo();
+    },
+    handleCurrentChange(val) {
+      this.search.current = val;
+      this.getInfo();
+    },
+    /**
+     * @desc 鎻愪氦琛ㄥ崟
+     */
+    async submitForm(status) {
+      let state = this.currentRow.state
+      if (this.trainingForm.assessmentUserId) {
+        state = 2
+      }
+      if (this.trainingForm.comprehensiveAssessment) {
+        state = 1
+      }
+      if (status === 3) {
+        state = 3
+      }
+      let data = {
+        assessmentMethod: this.trainingForm.assessmentMethod,
+        openingTime: this.trainingForm.openingTime,
+        placeTraining: this.trainingForm.placeTraining,
+        comprehensiveAssessment: this.trainingForm.comprehensiveAssessment,
+        trainingDetailedId: this.trainingForm.id,
+        assessmentUserId: this.trainingForm.assessmentUserId,
+        assessmentDate: this.trainingForm.assessmentDate,
+        state: state
+      }
+      let code = {}
+      if (state === 2) {
+        code = await trainingAndAssessmentRecordsAdded(data)
+      } else {
+        code = await trainingAndAssessmentRecordsEvaluate(data)
+      }
+      this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
+      if(code.code === 200) {
+        this.currentRow.state = state
+        this.$message.success("鎿嶄綔鎴愬姛")
+      }
+    },
+    getUserList(){
+      selectUserCondition({ type: 0 }).then((res) => {
+        this.userList = res.data;
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+.page-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 20px;
+  margin-bottom: 10px;
+}
+
+h4 {
+  display: flex;
+  align-items: center;
+}
+
+h4 .line {
+  display: inline-block;
+  width: 3px;
+  height: 16px;
+  background: #3A7BFA;
+  margin-right: 4px;
+}
+
+.form_title {
+  font-size: 14px;
+  padding: 0 20px;
+  margin-bottom: 10px;
+}
+
+.el-divider {
+  margin: 0 1em 1em 0;
+}
+
+.form__input_label {
+  width: 90px;
+  margin-right: 6px;
+  color: #606266;
+}
+
+.form__input_label2 {
+  width: 210px;
+  margin-right: 6px;
+  color: #606266;
+}
+.search_thing {
+  display: flex;
+  align-items: center
+}
+.search_label {
+  width: 120px;
+}
+.pagination {
+  display: flex;
+  justify-content: space-between
+}
+
+.items_center {
+  float: left;
+  width: 50%;
+  text-align: left;
+}
+.items_btn {
+  text-align: right;
+  width: 50%;
+  float: right;
+  margin-bottom: 1em;
+}
+
+.search {
+  width: 180px;
+  padding: 0 16px;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue b/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue
new file mode 100644
index 0000000..e9938c7
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue
@@ -0,0 +1,186 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="filesDialogVisible" title="闄勪欢涓婁紶" width="80%" @closed="closeFilesLook">
+      <div style="display: flex;justify-content: space-between;">
+        <el-upload ref='upload'
+                   :action="fileAction"
+                   :auto-upload="true"
+                   :before-upload="fileBeforeUpload" :data="{trainingDetailedId: info.id}"
+                   :headers="uploadHeader" :on-error="onError"
+                   :on-success="handleSuccessUp"
+                   :show-file-list="false"
+                   accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
+          <el-button size="small" style="height: 38px" type="primary">闄勪欢涓婁紶</el-button>
+        </el-upload>
+      </div>
+      <div>
+        <lims-table :tableData="tableData" :column="columnData"
+                    :height="'calc(100vh - 47em)'"
+                    :highlightCurrentRow="true"
+                    :tableLoading="tableLoading"></lims-table>
+      </div>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="lookDialogVisible"
+      fullscreen
+      title="鏌ョ湅闄勪欢" width="800px">
+      <filePreview v-if="lookDialogVisible" :currentFile="{}"
+                   :fileUrl="javaApi+'/word/'+currentInfo.fileUrl" style="height: 90vh;overflow-y: auto;top: 0"/>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import file from '@/utils/file';
+import filePreview from '@/components/Preview/filePreview.vue';
+import limsTable from "@/components/Table/lims-table.vue";
+import {delTrainingDetailedFileList, getTrainingDetailedFileList} from "@/api/cnas/personal/personalTraining";
+import {delCustomById} from "@/api/system/customer";
+
+export default {
+  name: 'ViewRecord',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {limsTable, filePreview },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      filesDialogVisible: false,
+      tableLoading: false,
+      filesLookInfo: {},
+      columnData: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '棰勮',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleLook(row)
+              }
+            },
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.upload(row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delete(row)
+              }
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      info: {},
+      currentInfo:{},
+      lookDialogVisible: false,
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.filesDialogVisible = true
+      this.info = row
+      this.searchTableList()
+    },
+    // 鏌ヨ闄勪欢鍒楄〃
+    searchTableList () {
+      this.tableLoading = true
+      getTrainingDetailedFileList({trainingDetailedId: this.info.id}).then(res => {
+        this.tableLoading = false
+        this.tableData = res.data
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    closeFilesLook () {
+      this.filesDialogVisible = false
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        file.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+    // 鍒犻櫎
+    delete (row) {
+      this.$confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      }).then(() => {
+        this.tableLoading = true
+        delTrainingDetailedFileList({detailedFileId: row.detailedFileId}).then(res => {
+          this.tableLoading = false
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchTableList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {})
+    },
+    // 涓婁紶楠岃瘉
+    fileBeforeUpload(file) {
+      let flag = true
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        flag = false
+      }
+      if (!flag) {
+        return Promise.reject(flag); //姝g‘鐨勭粓姝�
+      }
+    },
+    onError(err, file, fileList,type) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+    },
+    handleSuccessUp(response, ) {
+      this.upLoading = false;
+      if (response.code == 200) {
+        this.$message.success('涓婁紶鎴愬姛');
+        this.searchTableList()
+      }
+    },
+    // 鏌ョ湅鏂囦欢
+    handleLook(row){
+      this.currentInfo = row
+      this.lookDialogVisible = true
+    },
+  },
+  computed: {
+    fileAction() {
+      return this.javaApi + '/personTraining/uploadTrainingDetailedFile'
+
+    }
+  },
+};
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/components/communicateAdd.vue b/src/views/CNAS/personnel/personnelInfo/components/communicateAdd.vue
new file mode 100644
index 0000000..8ac6ea6
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/communicateAdd.vue
@@ -0,0 +1,136 @@
+<template><div class="add">
+  <el-dialog
+    :title="isEdit ?'缂栬緫闄勪欢璧勬枡':'鏂板闄勪欢璧勬枡'"
+    :visible.sync="dialogVisible"
+    width="40%"
+  >
+    <el-form
+      :model="form"
+      ref="form"
+      :rules="rules"
+      label-width="80px"
+      size="small"
+    >
+      <el-form-item label="娌熼�氫汉" prop="userId">
+        <el-select
+          v-model="form.userId"
+          placeholder="璇烽�夋嫨"
+          style="width: 100%" multiple
+        >
+          <el-option
+            v-for="(item, index) in userList"
+            :key="index"
+            :label="item.name"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="娌熼�氭椂闂�" prop="communicationTime">
+        <el-date-picker
+          v-model="form.communicationTime"
+          type="datetime"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          placeholder="璇烽�夋嫨鏃ユ湡鏃堕棿"
+          style="width: 100%"
+        >
+        </el-date-picker>
+      </el-form-item >
+      <el-form-item label="娌熼�氬湴鐐�" prop="communicationPlace">
+        <el-input v-model="form.communicationPlace" placeholder="璇峰~鍐欐矡閫氬湴鐐�"></el-input>
+      </el-form-item >
+      <el-form-item label="娌熼�氬唴瀹�" prop="communicationContent">
+        <el-input v-model="form.communicationContent" placeholder="璇峰~鍐欐矡閫氬唴瀹�"></el-input>
+      </el-form-item >
+    </el-form>
+    <div slot="footer" class="foot">
+      <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+      <el-button type="primary" :loading="loading" @click="submitForm">纭� 瀹�</el-button>
+    </div>
+  </el-dialog>
+</div>
+</template>
+<script>
+import {selectUserCondition} from "@/api/business/inspectionTask";
+import {addOrUpdatePersonCommunicationAbility} from "@/api/cnas/personal/personPersonCommunicationAbilityPage";
+
+export default {
+  data() {
+    return {
+      isEdit: false,
+      dialogVisible: false,
+      form: {
+        id: '',
+        userId: [],
+        communicationTime: undefined,
+        communicationPlace: undefined,
+        communicationContent: undefined
+      },
+      rules: {
+        userId: [{ required: true, message: '璇烽�夋嫨娌熼�氫汉', trigger: 'change' }],
+        communicationTime: [{ required: true, message: '璇烽�夋嫨娌熼�氭椂闂�', trigger: 'change' }],
+        communicationPlace: [{ required: true, message: '璇峰~鍐欐矡閫氬湴鐐�', trigger: 'blur' }],
+        communicationContent: [{ required: true, message: '璇峰~鍐欐矡閫氬唴瀹�', trigger: 'blur' }],
+      },
+      loading: false,
+      userList: []
+    }
+  },
+  methods: {
+    /**
+     * @desc 鏄剧ず妯℃�佹
+     * @param {*} row
+     * @param {*} type
+     */
+    openDialog(row, type) {
+      this.getUserList()
+      this.dialogVisible = true
+      if(type) {
+        this.isEdit = true
+        this.form.id = row.id
+        this.form.userId = row.userId.split(',').map(m=>Number(m))
+        this.form.communicationTime = row.communicationTime
+        this.form.communicationPlace = row.communicationPlace
+        this.form.communicationContent = row.communicationContent
+      } else {
+        this.form.id = ''
+        this.resetForm('form')
+      }
+    },
+    /**
+     * @desc 鑾峰彇鐢ㄦ埛淇℃伅
+     */
+    async getUserList() {
+      selectUserCondition().then((res) => {
+        this.userList = res.data;
+      })
+    },
+    /**
+     * @desc 鎻愪氦琛ㄥ崟
+     */
+    async submitForm() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          this.loading = true
+          const params = {
+            id: this.form.id,
+            userId: this.form.userId.join(','),
+            communicationTime: this.form.communicationTime,
+            communicationPlace: this.form.communicationPlace,
+            communicationContent: this.form.communicationContent,
+          }
+          addOrUpdatePersonCommunicationAbility(params).then((res) => {
+            this.loading = false
+            this.resetForm('form')
+            this.$emit('submit')
+            this.dialogVisible = false
+          }).catch((err) => {
+            this.loading = false
+          })
+        }
+      })
+    }
+  }
+}
+</script>
+<style scoped>
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/components/mandateAdd.vue b/src/views/CNAS/personnel/personnelInfo/components/mandateAdd.vue
new file mode 100644
index 0000000..9e77475
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/mandateAdd.vue
@@ -0,0 +1,200 @@
+<template>
+  <div class="add">
+    <el-dialog
+      :title="isEdit ?'缂栬緫闄勪欢璧勬枡':'鏂板闄勪欢璧勬枡'"
+      :visible.sync="dialogVisible"
+      width="50%"
+    >
+      <el-form
+        ref="ruleForm"
+        :rules="rules"
+        :model="form"
+        label-width="130px"
+        size="medium"
+      >
+        <el-form-item label="璇佷功缂栧彿" prop="certificateNumber">
+          <el-input v-model="form.certificateNumber" placeholder="璇疯緭鍏�" style="width: 100%">
+          </el-input>
+        </el-form-item >
+        <el-form-item label="琚换鑱屼汉鍛�" prop="userId">
+          <el-select v-model="form.userId" placeholder="璇烽�夋嫨">
+            <el-option
+              v-for="(item, index) in userList"
+              :key="index"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item >
+        <el-form-item label="浠昏亴宀椾綅" prop="post">
+          <el-input v-model="form.post" placeholder="璇疯緭鍏�"></el-input>
+        </el-form-item >
+        <el-form-item label="鐞嗚鑰冭瘯鎴愮哗" prop="num1">
+          <el-input v-model="form.num1" placeholder="璇疯緭鍏�"></el-input>
+        </el-form-item >
+        <el-form-item label="鎿嶄綔鎶�鑳借�冭瘯鎴愮哗" prop="num2">
+          <el-input v-model="form.num2" placeholder="璇疯緭鍏�"></el-input>
+        </el-form-item >
+        <el-form-item label="鎿嶄綔绫诲瀷" prop="operationType">
+          <el-input v-model="form.operationType" placeholder="璇烽�夋嫨"></el-input>
+        </el-form-item >
+        <el-row>
+          <el-col :span="20">
+            <el-form-item label="涓婂矖璇佷功">
+              <el-input v-model="form.systemFileName" size="small" disabled>
+                <el-button slot="append" icon="el-icon-delete-solid"
+                           @click="deleteFile(form.systemFileName)"></el-button>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="4">
+            <el-upload ref="upload" style="float: left; margin: 0 12px 0 20px;" :action="action"
+                       :headers="uploadHeader"
+                       :show-file-list="false"
+                       :on-success="onSuccess">
+              <el-button class="uploadFile" slot="trigger" size="small" type="primary">涓婁紶</el-button>
+            </el-upload>
+          </el-col>
+        </el-row>
+        <el-form-item label="澶囨敞">
+          <el-input v-model="form.remarks" placeholder="璇烽�夋嫨"></el-input>
+        </el-form-item >
+      </el-form>
+      <div slot="footer" class="foot">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" :loading="loading" @click="submitForm">纭� 瀹�</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import {deleteCNASFile} from "@/api/cnas/personal/personalList";
+import {selectUserCondition} from "@/api/business/inspectionTask";
+import {addOrUpdatePersonPostAuthorizationRecord} from "@/api/cnas/personal/personPostAuthorizationRecord";
+
+export default {
+  data() {
+    return {
+      isEdit: false,
+      dialogVisible: false,
+      form: {
+        id: undefined,
+        certificateNumber: undefined,
+        userId: undefined,
+        post: undefined,
+        operationType: undefined,
+        fileList: [],
+        fileName: undefined,
+        systemFileName: undefined,
+        remarks: undefined,
+        num2:undefined,
+        num1:undefined
+      },
+      rules: {
+        certificateNumber: [{ required: true, message: '璇疯緭鍏ヨ瘉涔︾紪鍙�', trigger: 'blur' }],
+        userId: [{ required: true, message: '璇烽�夋嫨琚换鑱屼汉鍛�', trigger: 'change' }],
+        post: [{ required: true, message: '浠昏亴宀椾綅', trigger: 'blur' }],
+        operationType: [{ required: true, message: '鎿嶄綔绫诲瀷', trigger: 'blur' }],
+      },
+      loading: false,
+      userList: []
+    }
+  },
+  computed: {
+    action() {
+      return this.javaApi + '/personBasicInfo/saveCNASFile'
+    }
+  },
+  methods: {
+    onSuccess(response, file, fileList) {
+      this.$set(this.form, "systemFileName", response.data)
+    },
+    deleteFile(fileName) {
+      deleteCNASFile({fileName: fileName}).then(res => {
+        this.$message.success('鍒犻櫎鎴愬姛锛�')
+        this.$set(this.form, "systemFileName", null)
+      })
+    },
+    async openDialog(row, type) {
+      await this.getUserList()
+      this.dialogVisible = true
+      if(type) {
+        this.isEdit = true
+        this.form.id = row.id
+        this.form.certificateNumber = row.certificateNumber
+        this.form.userId = Number(row.userId)
+        this.form.post = row.post
+        this.form.operationType = row.operationType
+        this.form.systemFileName = row.systemFileName
+        this.form.remarks = row.remarks
+        this.form.num1 = row.num1
+        this.form.num2 = row.num2
+      } else {
+        this.resetForm('ruleForm')
+      }
+    },
+    closeDialog() {
+      this.resetForm('ruleForm')
+      this.dialogVisible = false
+    },
+    /**
+     * @desc 鑾峰彇鐢ㄦ埛淇℃伅
+     */
+    async getUserList() {
+      selectUserCondition().then((res) => {
+        this.userList = res.data;
+      })
+    },
+    /**
+     * @desc 鎻愪氦琛ㄥ崟
+     */
+    submitForm() {
+      this.$refs.ruleForm.validate((valid) => {
+        if(valid) {
+          const params = {
+            id: this.form.id,
+            certificateNumber: this.form.certificateNumber,
+            userId: this.form.userId,
+            post: this.form.post,
+            operationType: this.form.operationType,
+            systemFileName: this.form.systemFileName,
+            remarks: this.form.remarks,
+            num1: this.form.num1,
+            num2: this.form.num2
+          }
+          this.loading = true
+          addOrUpdatePersonPostAuthorizationRecord(params).then(res => {
+            this.loading = false
+            this.closeDialog()
+            this.$emit('refresh')
+          }).catch(err => {
+            this.loading = false
+          })
+        }
+      })
+    },
+    /**
+     * @desc 涓婁紶鏂囦欢
+     */
+    beforeUpload(file) {
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        return false;
+      } else {
+        this.form.fileList = [file]
+        this.form.fileName = file.name
+        return true;
+      }
+    },
+  }
+}
+</script>
+<style scoped>
+.foot {
+    width: 100%;
+}
+.add >>> .el-dialog__footer {
+    padding-right: 20px;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/index.vue b/src/views/CNAS/personnel/personnelInfo/index.vue
new file mode 100644
index 0000000..9867a41
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/index.vue
@@ -0,0 +1,329 @@
+<template>
+  <div class="main">
+    <div class="main_left">
+      <el-row>
+        <el-col :span="20">
+          <el-input
+            v-model="search"
+            class="div_left_input"
+            clearable
+            placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
+            size="small"
+            suffix-icon="el-icon-search"
+            @blur="searchFilter"
+            @clear="searchFilter"
+            @keyup.enter.native="searchFilter"
+          ></el-input>
+        </el-col>
+        <el-col :span="4" style="text-align: center;line-height: 30px; margin-top: 14px">
+          <el-button circle icon="el-icon-plus" size="mini" type="primary" @click="handleAdd"></el-button>
+        </el-col>
+      </el-row>
+      <el-tree
+        ref="tree"
+        :data="list"
+        :default-expanded-keys="[22]"
+        :expand-on-click-node="false"
+        :filter-node-method="filterNode"
+        :props="{ children: 'children', label: 'name' }"
+        highlight-current
+        node-key="id"
+        style="height:calc(100% - 70px);overflow-y: scroll;scrollbar-width: none;"
+        @node-click="handleNodeClick"
+        @node-expand="nodeOpen"
+        @node-collapse="nodeClose"
+      >
+        <div slot-scope="{ node, data }" class="custom-tree-node">
+          <el-row style="width: 100%;">
+            <el-col :span="22" style="text-align: left;">
+              <span><i
+                :class="`node_i ${data.children != undefined&&data.children.length>0 ? 'el-icon-folder-opened' : 'el-icon-tickets'}`"></i>
+                {{ data.name }}</span>
+            </el-col>
+            <el-col v-if="node.level>1 && data.id !== null" :span="2" style="text-align: right;">
+              <el-button size="mini" type="text" @click.stop="remove(node, data)">
+                <i class="el-icon-delete"></i>
+              </el-button>
+            </el-col>
+          </el-row>
+        </div>
+      </el-tree>
+    </div>
+    <div class="main_right">
+      <el-tabs v-model="activeName" :lazy="true" type="border-card">
+        <el-tab-pane label="浜哄憳鍩烘湰淇℃伅" name="浜哄憳鍩烘湰淇℃伅">
+          <PersonnelList v-if="activeName === '浜哄憳鍩烘湰淇℃伅' && isShowAll" ref="personnelList" :currentCompaniesList="currentCompaniesList"
+                         :departId="departId" @refreshTree="refreshTree"
+                         @updatePerson="updatePerson"></PersonnelList>
+          <personnelInformation v-if="activeName === '浜哄憳鍩烘湰淇℃伅' && !isShowAll" :clickNodeVal="clickNodeVal"></personnelInformation>
+        </el-tab-pane>
+        <el-tab-pane label="鍩硅璁″垝" name="鍩硅璁″垝">
+          <PersonnelTraining v-if="activeName === '鍩硅璁″垝'" ref="personnelTraining"
+                             :departId="departId" :isDepartment="isDepartment"></PersonnelTraining>
+        </el-tab-pane>
+        <el-tab-pane label="宀椾綅鑱岃矗" name="宀椾綅鑱岃矗">
+          <job-responsibilities v-if="activeName === '宀椾綅鑱岃矗'" ref="jobResponsibilities"
+                                :departId="departId"
+                                :isDepartment="isDepartment"></job-responsibilities>
+        </el-tab-pane>
+        <el-tab-pane label="濂栨儵璁板綍" name="濂栨儵璁板綍">
+          <rewardPunishmentRecord v-if="activeName === '濂栨儵璁板綍'"
+                                  :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord>
+        </el-tab-pane>
+        <el-tab-pane label="鍩硅璁板綍" name="鍩硅璁板綍">
+          <training-record v-if="activeName === '鍩硅璁板綍'" ref="trainingRecord"
+                           :departId="departId"
+                           :isDepartment="isDepartment"></training-record>
+        </el-tab-pane>
+        <el-tab-pane label="浠昏亴鎺堟潈璁板綍" name="浠昏亴鎺堟潈璁板綍">
+          <Mandate v-if="activeName === '浠昏亴鎺堟潈璁板綍'" ref="manDateRef" :departId="departId" :isDepartment="isDepartment"></Mandate>
+        </el-tab-pane>
+        <el-tab-pane label="浜哄憳鑳藉姏" name="浜哄憳鑳藉姏">
+          <personnel-capacity v-if="activeName === '浜哄憳鑳藉姏'" ref="personnelCapacity"
+                              :departId="departId"
+                              :isDepartment="isDepartment"></personnel-capacity>
+        </el-tab-pane>
+        <el-tab-pane label="娌熼�氳褰�" name="娌熼�氳褰�">
+          <Communicate v-if="activeName === '娌熼�氳褰�'" ref="communicateRef" :departId="departId" :isDepartment="isDepartment"></Communicate>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+    <el-dialog :visible.sync="addDia" title="鏋舵瀯鏂板" width="400px">
+      <div class="body">
+        <el-row style="line-height: 50px;">
+          <el-col :span="6" style="text-align: right;">
+            <span class="required-span">* </span>鏋舵瀯鍚嶇О锛�
+          </el-col>
+          <el-col :offset="1" :span="16">
+            <el-input v-model="addOb.name" clearable placeholder="璇疯緭鍏ユ灦鏋勫悕绉�" size="small" @keyup.enter.native="addStandardTree"></el-input>
+          </el-col>
+        </el-row>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="addDia = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="addStandardTree">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import PersonnelList from './tabs/personnel-list.vue'
+import personnelInformation from './tabs/personnel-information.vue'
+import PersonnelTraining from './tabs/personnelTraining';
+import JobResponsibilities from './tabs/job-responsibilities.vue';
+import rewardPunishmentRecord from "./tabs/reward-punishment-record.vue";
+import TrainingRecord from './tabs/training-record.vue';
+import Mandate from './tabs/mandate.vue';
+import PersonnelCapacity from './tabs/personnel-capacity.vue';
+import Communicate from './tabs/communicate.vue'
+import {addDepartmentLims, delDepartmentLims, selectCNSAPersonTree} from "@/api/cnas/personal/personalList";
+export default {
+  components: {
+    PersonnelList, personnelInformation, PersonnelTraining, JobResponsibilities, rewardPunishmentRecord, TrainingRecord, Mandate, PersonnelCapacity, Communicate
+  },
+  data() {
+    return {
+      isShowAll: true, //  鏄惁灞曠ず鏍囩鏍�
+      activeName: '浜哄憳鍩烘湰淇℃伅',
+      departId: 1,
+      list: [],
+      addDia: false,
+      addOb: {
+        name: '',
+        fatherId: ''
+      },
+      search: '',
+      clickNodeVal: {},
+      addUserForm: {
+        name: ''
+      },
+      currentCompaniesList: [],
+      entity: {
+        name: '',
+        departLimsId: '',
+        orderBy: {
+          field: 'id',
+          order: 'asc'
+        }
+      },
+      overallRecord: '浜哄憳鍒楄〃',
+      isDepartment: false,
+    };
+  },
+  mounted() {
+    this.geList();
+  },
+  methods: {
+    remove(node, data) {
+      this.$confirm("鏄惁鍒犻櫎璇ュ眰绾�", "鎻愮ず", {
+        type: "error"
+      }).then(() => {
+        delDepartmentLims({
+          id: data.id
+        }).then(res => {
+          this.$message.success('宸插垹闄�')
+          this.geList();
+        })
+      }).catch(e => {})
+    },
+    addStandardTree() {
+      if (this.addOb.name == null || this.addOb.factory == '') {
+        this.$message.error('鏋勬灦鍚嶇О鏄繀濉」')
+        return
+      }
+      addDepartmentLims(this.addOb).then(res => {
+        this.$message.success('娣诲姞鎴愬姛')
+        this.addDia = false
+        this.geList();
+        this.addOb.name = ''
+        this.addOb.fatherId = ''
+      })
+    },
+    handleAdd() {
+      if (this.addOb.fatherId) {
+        this.addDia = true;
+      } else {
+        this.$message.error('璇烽�夋嫨涓�涓灦鏋勫眰绾�')
+      }
+    },
+    // 浜哄憳鍒楄〃缂栬緫
+    updatePerson(row) {
+      const node = this.findNodeById(this.list, row.name);
+      if (node) {
+        this.handleNodeClick(node);
+      } else {
+        this.$message.warning('鏈壘鍒拌浜哄憳');
+      }
+    },
+    // 鏂板缓浜哄憳鍚庡埛鏂版爲
+    refreshTree () {
+      this.geList()
+    },
+    findNodeById(treeData, name) {
+      for (let i = 0; i < treeData.length; i++) {
+        if (treeData[i].name === name) {
+          return treeData[i]; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
+        }
+        if (treeData[i].children && treeData[i].children.length > 0) {
+          const foundNode = this.findNodeById(treeData[i].children, name);
+          if (foundNode) {
+            return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
+          }
+        }
+      }
+      return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+    },
+    searchFilter() {
+      this.$refs.tree.filter(this.search);
+    },
+    // 鑾峰彇鏍�
+    geList() {
+      selectCNSAPersonTree().then(res => {
+        this.list = res.data;
+        if(this.list.length > 0) {
+          this.isDepartment = true;
+        }
+      });
+    },
+    filterNode(value, data) {
+      if (!value) return true;
+      return data.name.indexOf(value) !== -1;
+    },
+    nodeClose(data, node, el) {
+      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder');
+    },
+    nodeOpen(data, node, el) {
+      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder-opened');
+    },
+    handleNodeClick(val, node, el) {
+      //鏍戠殑鍊�
+      this.clickNodeVal = val;
+      // 瀛樺偍鐖剁骇鑺傜偣绾ф暟
+      if (node) {
+        this.getNodeParent(node);
+        this.clickNodeVal.level = node.level;
+        this.clickNodeVal.parent = node.parent.data;
+      }
+      this.entity.departLimsId = val.id;
+      this.addOb.fatherId = val.id;
+      // 鏄惁鏄剧ず璁惧璇︽儏
+      this.isShowAll = val.id !== null;
+      if (val.id) {	// 濡傛灉鏄疄楠屽
+        this.departId = val.id;
+        this.isDepartment = true;
+      }
+      if (val.userId) { // 鏄汉鍛�
+        this.departId = val.userId;
+        this.isDepartment = false
+      }
+    },
+    getNodeParent(val) {
+      if (val.parent != null) {
+        this.currentCompaniesList[val.level - 1] = val.data.id;
+        this.selectTree += ' - ' + val.label;
+        this.getNodeParent(val.parent);
+      }
+    }
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-table__body-wrapper::-webkit-scrollbar {
+  height: 14px;
+  /* 璁剧疆婊氬姩鏉″搴� */
+}
+.node_i {
+  color: orange;
+  font-size: 18px;
+}
+.custom-tree-node {
+  width: 80%;
+  line-height: 32px;
+}
+.custom-tree-node .el-icon-delete {
+  color: #3A7BFA;
+  opacity: 0;
+  font-size: 15px;
+}
+
+.custom-tree-node:hover .el-icon-delete {
+  opacity: 1;
+}
+
+.main {
+  display: flex;
+  padding: 15px 0;
+}
+
+.main_left {
+  background: #ffffff;
+  text-align: center;
+  height: calc(100vh - 8em);
+  width: 270px;
+  border-radius: 15px;
+}
+
+.main_right {
+  width: calc(100% - 288px);
+  border-radius: 15px;
+}
+
+.div_left_input {
+  margin: 15px 0;
+  width: 90%;
+}
+
+>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item {
+  border: 0 none;
+}
+
+>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
+  color: black;
+}
+
+>>> .el-tabs--border-card > .el-tabs__header {
+  border-bottom: none;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue b/src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue
new file mode 100644
index 0000000..186ee8e
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue
@@ -0,0 +1,153 @@
+<template>
+  <div class="flex_column">
+    <div v-if="isDepartment" style="display: flex;justify-content: space-between;margin-bottom: 10px">
+      <el-button size="small" type="primary" @click="getTableData">鍒锋柊</el-button>
+      <el-button size="small" type="primary" icon="el-icon-plus" @click="openDialog">鏂板</el-button>
+    </div>
+    <lims-table :tableData="tableData" :column="columnData"
+                @pagination="page" :height="'calc(100vh - 18em)'"
+                :page="pagination" :tableLoading="loading"></lims-table>
+    <Add ref="communicateModal" @submit="getTableData"></Add>
+  </div>
+</template>
+<script>
+import CommunicateAdd from "../components/communicateAdd.vue"
+import limsTable from "@/components/Table/lims-table.vue";
+import {
+  deletePersonCommunicationAbility, exportPersonCommunicationAbility,
+  personPersonCommunicationAbilityPage
+} from "@/api/cnas/personal/personPersonCommunicationAbilityPage";
+
+export default {
+  components: {
+    limsTable,
+    Add: CommunicateAdd
+  },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      columnData: [
+        {
+          label: '娌熼�氫汉',
+          prop: 'userName'
+        }, {
+          label: '娌熼�氭椂闂�',
+          prop: 'communicationTime'
+        }, {
+          label: '娌熼�氬湴鐐�',
+          prop: 'communicationPlace'
+        }, {
+          label: '娌熼�氬唴瀹�',
+          prop: 'communicationContent'
+        }, {
+          label: '鎿嶄綔',
+          dataType: 'action',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openDialog(row, true)
+              }
+            }, {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            }, {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPerson(row.id)
+              }
+            }
+          ]
+        },
+      ],
+      tableData: [],
+      pagination: {
+        current: 1,
+        size: 20,
+        total: 0
+      },
+      loading: false
+    }
+  },
+  mounted() {
+    this.getTableData()
+  },
+  methods: {
+    openDialog(row, type=false) {
+      this.$refs.communicateModal.openDialog(row, type)
+    },
+    getTableData() {
+      this.loading = true
+      const params = this.isDepartment ? {
+        departLimsId: this.departId,
+        current: this.pagination.current,
+        size: this.pagination.size
+      } : {
+        userId: this.departId,
+        current: this.pagination.current,
+        size: this.pagination.size
+      }
+      personPersonCommunicationAbilityPage(params).then(res => {
+        this.loading = false
+        this.tableData = res.data.records
+        this.pagination.total = res.data.total
+      }).catch(err => {
+        this.loading = false
+      })
+    },
+    page (page) {
+      this.pagination.size = page.limit
+      this.getTableData()
+    },
+    /**
+     * @desc 鍒犻櫎娌熼�氳褰�
+     */
+    delPerson(id) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(async () => {
+        deletePersonCommunicationAbility({id: id}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛!');
+          this.getTableData()
+        })
+      })
+    },
+    async handleDown(row){
+      exportPersonCommunicationAbility({id:row.id}).then(res => {
+        const blob = new Blob([res],{ type: 'application/octet-stream' });
+        this.$download.saveAs(blob, row.userName+'-娌熼�氳褰�'+'.docx');
+      })
+    }
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (newId) {
+          this.getTableData();
+        }
+      }
+    }
+  }
+}
+</script>
+<style scoped>
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue b/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue
new file mode 100644
index 0000000..1ae74e8
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue
@@ -0,0 +1,395 @@
+<!-- 宀椾綅鑱岃矗 -->
+<template>
+  <div class="view">
+    <div style="display: flex;justify-content: space-between;">
+      <el-form ref="page" size="small" :inline="true">
+        <el-form-item label="鍛樺伐">
+          <el-input v-model="userName" clearable placeholder="璇疯緭鍏ュ憳宸�" size="small" style="width: 20vh;"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="small" type="primary" @click="refreshTable">鏌ヨ</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button size="small" type="primary" @click="addPost">鏂板</el-button>
+        <!--        <el-button size="small" type="primary">瀵煎嚭excel</el-button>-->
+      </div>
+    </div>
+    <div class="table">
+      <el-table :data="tableData" v-loading="tableLoading" height="66.5vh" style="width: 100%">
+        <el-table-column label="搴忓彿" type="index" width="60"></el-table-column>
+        <el-table-column label="鍛樺伐缂栧彿" min-width="120" prop="account"></el-table-column>
+        <el-table-column label="宀椾綅鍚嶇О" min-width="180" prop="postName"></el-table-column>
+        <el-table-column label="鎵�灞為儴闂�" min-width="180" prop="departLimsName"></el-table-column>
+        <el-table-column label="宸ヤ綔鐩爣" min-width="180" prop="jobObjective"></el-table-column>
+        <el-table-column label="宀椾綅鑱岃矗" min-width="180" prop="jobResponsibilities"></el-table-column>
+        <el-table-column label="浠昏亴浜�" min-width="180" prop="incumbentName"></el-table-column>
+        <el-table-column label="浠昏亴浜哄鏍告棩鏈�" min-width="180" prop="incumbentDate"></el-table-column>
+        <el-table-column label="涓荤" min-width="180" prop="supervisorName"></el-table-column>
+        <el-table-column label="涓荤瀹℃牳鏃ユ湡" min-width="180" prop="supervisorDate"></el-table-column>
+        <el-table-column fixed="right" label="鎿嶄綔" width="140" align="center">
+          <template v-slot="scope">
+            <el-button v-if="!isDepartment || scope.row.currentState === '鍏抽棴'" size="small" type="text"
+                       @click="handleViewClick(scope.row, 'view')">鏌ョ湅
+            </el-button>
+            <el-button v-if="isDepartment && scope.row.currentState !== '鍏抽棴'" size="small" type="text"
+                       @click="handleViewClick(scope.row, 'edit')">缂栬緫
+            </el-button>
+            <el-button size="small" type="text" @click="downLoadPost(scope.row)">瀵煎嚭</el-button>
+            <el-button v-if="isDepartment" size="small" style="color: #f56c6c" type="text" @click="deletePost(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]"
+                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
+                     background
+                     style="margin-top: 10px"
+                     @size-change="handleSizeChange"
+                     @current-change="handleCurrentChange">
+      </el-pagination>
+    </div>
+    <!-- 鏂板宀椾綅鑱岃矗 -->
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="dialogVisible"
+               title="鏂板宀椾綅鑱岃矗"
+               width="50%" @close="resetForm">
+      <el-steps :active="currentStep" align-center finish-status="success">
+        <el-step v-for="(v, i) in steps" :key="i" :title="v" style="cursor:pointer"
+                 @click.native="choiceStep(i)"></el-step>
+      </el-steps>
+      <el-form ref="form" :model="form" :rules="rules" label-width="130px">
+        <div>
+          <el-card style="margin-top: 1em; height: 40vh; overflow-y: scroll;">
+            <!-- 鏂板璁惧浜嬭褰曞崱鐗� -->
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="宀椾綅鍚嶇О锛�" prop="postName">
+                  <el-input v-model="form.postName" :disabled="currentStep !== 0 || operationType === 'view'"
+                            size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="宸ヤ綔鐩爣锛�" prop="jobObjective">
+                  <el-input v-model="form.jobObjective" :disabled="currentStep !== 0 || operationType === 'view'"
+                            size="small"
+                            type="textarea"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="宀椾綅鑱岃矗锛�" prop="jobResponsibilities">
+                  <el-input v-model="form.jobResponsibilities" :disabled="currentStep !== 0 || operationType === 'view'"
+                            size="small"
+                            type="textarea"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col v-if="currentStep === 0 || operationType === 'view'" :span="12">
+                <el-form-item
+                  :rules="[{ required: currentStep === 0, message: '璇烽�夋嫨浠昏亴浜�', trigger: 'change' }]"
+                  label="浠昏亴浜猴細"
+                  prop="incumbentId">
+                  <el-select v-model="form.incumbentId" :disabled="operationType === 'view'" clearable
+                             filterable
+                             placeholder="璇烽�夋嫨浠昏亴浜�" size="small" style="width: 100%;">
+                    <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col v-if="currentStep === 1 || operationType === 'view'" :span="12">
+                <el-form-item
+                  :rules="[{ required: currentStep === 1, message: '璇烽�夋嫨涓荤', trigger: 'blur' }]"
+                  label="涓荤锛�"
+                  prop="supervisorId">
+                  <el-select v-model="form.supervisorId" :disabled="currentStep !== 1 || operationType === 'view'"
+                             clearable filterable
+                             placeholder="璇烽�夋嫨涓荤" size="small" style="width: 100%;">
+                    <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-card>
+          <el-row style="margin-top: 1em;">
+            <el-col :span="4">
+              鎿嶄綔浜猴細{{ form.submitPerson }}
+            </el-col>
+            <el-col :span="6">
+              鏃ユ湡锛歿{ form.submitDate }}
+            </el-col>
+          </el-row>
+        </div>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="currentStep !== 0 && currentStep !== 3" @click="submitForm('3reject')">椹冲洖</el-button>
+        <el-button v-if="currentStep === 0" @click="submitForm('2save')">淇濆瓨</el-button>
+        <el-button v-if="currentStep !== 3" type="primary"
+                   @click="submitForm('1submit')">{{ currentStep === 0 ? '鎻愪氦' : '閫氳繃' }}</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { dateFormat } from '@/utils/date'
+import {
+  exportPersonJobResponsibilities, personJobResponsibilitiesDelete,
+  personJobResponsibilitiesSave,
+  personJobResponsibilitiesSelect
+} from "@/api/cnas/personal/personJobResponsibilities";
+import {selectUserCondition} from "@/api/cnas/resourceDemand/facilitiesEnvironment/facilitiesAndEnvironment";
+import {mapGetters} from "vuex";
+
+export default {
+  data() {
+    return {
+      userName: '',
+      tableData: [],
+      tableLoading: false,
+      responsibleOptions: [],
+      search: {
+        size: 20,
+        current: 1,
+        total: 0
+      },
+      dialogVisible: false,
+      currentStep: 0, // 姝ラ鏉℃樉绀虹鍑犳
+      currentStepClick: 0, // 鐐瑰嚮姝ラ鏉″彉鍖�
+      operationType: '',
+      steps: ['鎻愪氦', '浠昏亴浜虹‘璁�', '涓荤纭'],
+      form: {
+        postName: '', // 宀椾綅鍚嶇О
+        jobObjective: '', // 宸ヤ綔鐩爣
+        jobResponsibilities: '', // 宀椾綅鑱岃矗
+        incumbentId: '', // 浠昏亴浜�
+        supervisorId: '' // 涓荤
+      },
+      rules: {
+        postName: [{ required: true, message: '璇疯緭鍏ュ矖浣嶅悕绉�', trigger: 'blur' }],
+        jobObjective: [{ required: true, message: '璇疯緭鍏ュ伐浣滅洰鏍�', trigger: 'blur' }],
+        jobResponsibilities: [{ required: true, message: '璇疯緭鍏ュ矖浣嶈亴璐�', trigger: 'blur' }],
+        incumbentId: [{ required: true, message: '璇烽�夋嫨浠昏亴浜�', trigger: 'change' }],
+        supervisorId: [{ required: true, message: '璇烽�夋嫨涓荤', trigger: 'change' }]
+      }
+      // departId: 0
+    };
+  },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted() {
+    this.getPostList(this.departId);
+  },
+  methods: {
+    addPost() {
+      this.dialogVisible = true;
+      this.form = {
+        postName: '', // 宀椾綅鍚嶇О
+        jobObjective: '', // 宸ヤ綔鐩爣
+        jobResponsibilities: '', // 宀椾綅鑱岃矗
+        incumbentId: '', // 浠昏亴浜�
+        supervisorId: '', // 鎿嶄綔浜�
+        submitPerson: '', // 涓荤
+        submitDate: '', // 鏃ユ湡
+        currentStep: 0 // 鏃ユ湡
+      };
+      this.currentStep = 0;
+      this.getUserList();
+    },
+    // 鏌ヨ鍒楄〃淇℃伅
+    getPostList(userId) {
+      this.search.userId = userId;
+      const params = this.isDepartment ? {
+        userName: this.userName,
+        departmentId: this.search.userId,
+        size: this.search.size,
+        current: this.search.current,
+      }: {
+        userName: this.userName,
+        userId: this.search.userId,
+        size: this.search.size,
+        current: this.search.current,
+      }
+      this.tableLoading = true
+      personJobResponsibilitiesSelect(params).then(res => {
+        this.tableLoading = false
+        this.tableData = res.data.records;
+        this.search.total = res.data.total;
+      }).catch(err => {
+        this.tableLoading = false
+      })
+    },
+    //鎻愪氦琛ㄥ崟
+    async submitForm(saveState) {
+      this.$refs.form.validate((valid) => {
+        if (valid === true || saveState !== '1submit') {
+          // 缁欏綋鍓嶇幆鑺傝缃垱寤轰汉涓庢椂闂�
+          let user = this.nickName;
+          const dateTime = dateFormat(new Date());
+          // 鑾峰彇褰撳墠鐜妭鎿嶄綔浜轰笌鏃ユ湡
+          switch (this.currentStep) {
+            case 0:
+              this.form.submittingOperator = user.name;
+              this.form.submittingDate = dateTime;
+              break;
+            case 1:
+              this.form.incumbentOperator = user.name;
+              this.form.incumbentDate = dateTime;
+              break;
+            case 2:
+              this.form.supervisorOperator = user.name;
+              this.form.supervisorDate = dateTime;
+              break;
+            default:
+              break;
+          }
+          // 鑾峰彇褰撳墠鐜妭璐熻矗浜�
+          switch (saveState === '3reject' ? this.currentStep - 1 : this.currentStep) {
+            case 1:
+              this.form.currentResponsible = this.form.submittingOperator;
+              break;
+            case 2:
+              this.form.currentResponsible = this.form.incumbentOperator;
+              break;
+            default:
+              break;
+          }
+          let currentStepAction;
+          // 璁剧疆璇ユ搷浣滃垽鏂槸鍚︿负鎻愪氦锛屼繚瀛橈紝椹冲洖锛岄�氳繃
+          switch (saveState) {
+            // 鎻愪氦锛岄�氳繃
+            case '1submit':
+              currentStepAction = this.currentStep + 1;
+              break;
+            // 淇濆瓨
+            case '2save':
+              currentStepAction = this.currentStep;
+              break;
+            // 椹冲洖
+            case '3reject':
+              currentStepAction = this.currentStep - 1;
+              break;
+            default:
+              break;
+          }
+          // 鑾峰彇褰撳墠鐘舵��
+          this.form.currentState = currentStepAction === 3 ? '鍏抽棴' : this.steps[currentStepAction];
+          personJobResponsibilitiesSave(this.form).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.getPostList(this.departId);
+              this.dialogVisible = false;
+            }
+          });
+        } else {
+          let step = this.steps[this.currentStep];
+          this.$message.warning(step + '  娴佺▼涓湁蹇呭~椤规湭濉紒');
+        }
+      });
+    },
+    // 缂栬緫
+    handleViewClick(row, type) {
+      this.operationType = type;
+      this.getUserList();
+      row.incumbentId = Number(row.incumbentId);
+      this.form = { ...row };
+      switch (row.currentState) {
+        case '鎻愪氦':
+          this.currentStep = 0;
+          break;
+        case '浠昏亴浜虹‘璁�':
+          this.currentStep = 1;
+          this.form.submitPerson = row.submittingOperator;
+          this.form.submitDate = row.submittingDate;
+          break;
+        case '涓荤纭':
+          this.currentStep = 2;
+          this.form.submitPerson = row.incumbentOperator;
+          this.form.submitDate = row.incumbentDate;
+          break;
+        case '鍏抽棴':
+          this.currentStep = 3;
+          this.form.submitPerson = row.supervisorOperator;
+          this.form.submitDate = row.supervisorDate;
+          break;
+        default:
+          break;
+      }
+      this.form.currentState = this.currentStep;
+      this.currentStepClick = this.currentStep === 3 ? 0 : this.currentStep
+      console.log('this.form---', this.form);
+      this.dialogVisible = true;
+    },
+    // 涓嬭浇宀椾綅鑱岃矗
+    downLoadPost(row) {
+      exportPersonJobResponsibilities({id:row.id}).then(res => {
+        const blob = new Blob([res],{ type: 'application/octet-stream' });
+        this.$download.saveAs(blob, row.incumbentName+'-宀椾綅鑱岃矗'+'.docx');
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 鍒犻櫎宀椾綅鑱岃矗
+    deletePost(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎姝ゆ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        personJobResponsibilitiesDelete({id: row.id}).then(res => {
+          if (res.code == 200) {
+            this.$message.success('鍒犻櫎鎴愬姛');
+            this.getPostList(this.departId);
+          }
+        });
+      }).catch(() => {
+        this.$message.error('鍒犻櫎澶辫触');
+      });
+    },
+    resetForm() {
+      this.$refs.form.resetFields();
+    },
+    refreshTable() {
+      this.getPostList(this.departId);
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      selectUserCondition().then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      })
+    },
+    choiceStep(index) {
+      this.currentStepClick = index;
+    },
+    handleSizeChange(val) {
+      this.search.size = val;
+      this.getPostList(this.departId);
+    },
+    handleCurrentChange(val) {
+      this.search.current = val;
+      this.getPostList(this.departId);
+    }
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        this.getPostList(newId);
+      }
+    }
+  },
+  computed: {
+    ...mapGetters(['nickName'])
+  },
+};
+</script>
+<style scoped>
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue b/src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue
new file mode 100644
index 0000000..691970d
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue
@@ -0,0 +1,178 @@
+<template>
+  <div class="flex_column">
+    <div>
+      <div v-if="isDepartment" style="display: flex;justify-content: space-between;margin-bottom: 10px">
+        <el-button size="small" type="primary" @click="getTableData">鍒锋柊</el-button>
+        <el-button size="small" type="primary" icon="el-icon-plus" @click="openDialog">鏂板</el-button>
+      </div>
+      <lims-table :tableData="tableData" :column="columnData"
+                  @pagination="page" :height="'calc(100vh - 18em)'"
+                  :page="pagination" :tableLoading="loading"></lims-table>
+    </div>
+    <Add ref="mandateModal" @refresh="getTableData"></Add>
+  </div>
+</template>
+<script>
+import Add from "../components/mandateAdd.vue"
+import limsTable from "@/components/Table/lims-table.vue";
+import {
+  deletePersonPostAuthorizationRecord, exportPersonPostAuthorizationRecord,
+  PersonPostAuthorizationRecordPage
+} from "@/api/cnas/personal/personPostAuthorizationRecord";
+import {delCustomById} from "@/api/system/customer";
+
+export default {
+  components: {
+    limsTable,
+    Add
+  },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      columnData: [
+        {
+          label: '搴忓彿',
+          prop: 'id'
+        }, {
+          label: '璇佷功缂栧彿',
+          prop: 'certificateNumber'
+        }, {
+          label: '琚换鑱屼汉鍛�',
+          prop: 'userName'
+        }, {
+          label: '浠昏亴宀椾綅',
+          prop: 'post'
+        }, {
+          label: '鐞嗚鑰冭瘯鎴愮哗',
+          prop: 'num1',
+          width: 120
+        },{
+          label: '鎿嶄綔鎶�鑳借�冭瘯鎴愮哗',
+          prop: 'num2',
+          width: 150
+        },{
+          label: '鎿嶄綔鏃堕棿',
+          prop: 'updateTime'
+        }, {
+          label: '澶囨敞',
+          prop: 'remarks',
+          width: 300
+        }, {
+          label: '鎿嶄綔',
+          dataType: 'action',
+          width: 160,
+          fixed: 'right',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openDialog(row, true)
+              }
+            }, {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            }, {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deleteNotify(row.id)
+              }
+            }
+          ]
+        },
+      ],
+      tableData: [],
+      pagination: {
+        current: 1,
+        size: 20,
+        total: 0
+      },
+      loading: false
+    }
+  },
+  mounted() {
+    this.getTableData()
+  },
+  methods: {
+    openDialog(row, type=false) {
+      this.$refs.mandateModal.openDialog(row, type)
+    },
+    /**
+     * @desc 鏌ヨ琛ㄦ牸鏁版嵁
+     */
+    async getTableData() {
+      const params = this.isDepartment ? {
+        departLimsId: this.departId,
+        current: this.pagination.current,
+        size: this.pagination.pageSize
+      } : {
+        userId: this.departId,
+        current: this.pagination.current,
+        size: this.pagination.pageSize
+      }
+      this.loading = true
+      PersonPostAuthorizationRecordPage(params).then(res => {
+        this.loading = false
+        this.tableData = res.data.records
+        this.pagination.total = res.data.total
+      }).catch(err => {
+        this.loading = false
+      })
+    },
+    page (page) {
+      this.pagination.size = page.limit
+      this.getTableData()
+    },
+    /**
+     * @desc 鍒犻櫎浠昏亴璁板綍
+     */
+    deleteNotify(id) {
+      this.$confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      }).then(() => {
+        deletePersonPostAuthorizationRecord({id: id}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.getTableData()
+        }).catch(e => {
+          this.$message.error('鍒犻櫎澶辫触')
+        })
+      }).catch(() => {})
+    },
+    handleDown(row){
+      exportPersonPostAuthorizationRecord({id:row.id}).then(res => {
+        const blob = new Blob([res],{ type: 'application/octet-stream' });
+        this.$download.saveAs(blob, '浠昏亴鎺堟潈-'+row.certificateNumber+'-'+row.post + '.docx')
+      })
+    }
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (newId) {
+          this.getTableData();
+        }
+      }
+    }
+  }
+}
+</script>
+<style scoped>
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue
new file mode 100644
index 0000000..ac989ea
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue
@@ -0,0 +1,576 @@
+<!-- 浜哄憳鑳藉姏 -->
+<template>
+  <div>
+    <div style="display: flex;justify-content: space-between;">
+      <el-form ref="page" size="small" :inline="true">
+        <el-form-item label="濮撳悕">
+          <el-input v-model="userName" placeholder="璇疯緭鍏ュ鍚�" size="small" clearable></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="small" type="primary" @click="refreshTable">鏌� 璇�</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button v-if="!isDepartment" size="small" type="primary" @click="addAppointPost('add')">鏂板</el-button>
+      </div>
+    </div>
+    <lims-table :tableData="tableData" :column="yearColumnData"
+                @pagination="pagination" :height="'calc(100vh - 20em)'"
+                :page="search" :tableLoading="yearLoading">
+      <div slot="jobResponsibilities" slot-scope="scope">
+        <div v-html="changeLine(scope.row.responsibilities)"></div>
+      </div>
+      <div slot="placeWorkSlot" slot-scope="scope">
+        <div v-html="changeLine(scope.row.placeWork)"></div>
+      </div>
+    </lims-table>
+    <!--鏂板鑳藉姏璁ゅ畾寮规-->
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :title="title"
+               :visible.sync="dialogVisible"
+               width="80%" @close="resetForm">
+      <el-form v-if="dialogVisible" ref="infoForm" :model="form" :rules="rules">
+        <el-col :span="12">
+          <el-form-item label="浜哄憳锛�" label-width="110px" prop="userId">
+            <el-select v-model="form.userId" disabled clearable
+                       filterable size="small" style="width: 100%;">
+              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <div style="display: flex;justify-content: space-evenly;font-weight: 600">
+            <span>鏌ユ牳缁撴灉</span>
+            <span>绗﹀悎涓庡惁</span>
+            <span>澶囨敞</span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="瀛﹀巻锛�" label-width="110px" prop="academicDegree">
+            <el-input v-model="form.academicDegree" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="academicConformNot" style="text-align: center">
+            <el-radio-group v-model="form.academicConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="academicRemarks">
+            <el-input v-model="form.academicRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鐩稿叧骞撮檺锛�" label-width="110px" prop="relatedYears">
+            <el-input v-model="form.relatedYears" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="relatedYearsConformNot" style="text-align: center">
+            <el-radio-group v-model="form.relatedYearsConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="relatedYearsRemarks	">
+            <el-input v-model="form.relatedYearsRemarks	" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鐩稿叧鍩硅锛�" label-width="110px" prop="relatedTraining">
+            <el-input v-model="form.relatedTraining" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="relatedTrainingConformNot" style="text-align: center">
+            <el-radio-group v-model="form.relatedTrainingConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="relatedTrainingRemarks">
+            <el-input v-model="form.relatedTrainingRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
+                      size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鐩稿叧缁忛獙锛�" label-width="110px" prop="relevantExperience">
+            <el-input v-model="form.relevantExperience" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="relevantExperienceConformNot" style="text-align: center">
+            <el-radio-group v-model="form.relevantExperienceConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="relevantExperienceRemarks">
+            <el-input v-model="form.relevantExperienceRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
+                      size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="涓婂矖璇侊細" label-width="110px" prop="workLicense">
+            <el-input v-model="form.workLicense" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"
+                      style="width: 100%">
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="workLicenseConformNot" style="text-align: center">
+            <el-radio-group v-model="form.workLicenseConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="workLicenseRemarks">
+            <el-input v-model="form.workLicenseRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="宀椾綅鑱岃矗锛�" label-width="110px" prop="jobResponsibilitiesTem" style="height: 450px">
+            <el-checkbox-group v-model="form.jobResponsibilitiesTem" :disabled="operationType === 'view' || operationType === 'confirm'"
+                               @change="selectResponsibilities">
+              <el-checkbox v-for="city in dict.type.responsibilities_list" :key="city.value" :label="city.label"
+                           :value="city.value"></el-checkbox>
+            </el-checkbox-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="jobResponsibilitiesConformNot"
+                        style="text-align: center;height: 420px">
+            <el-radio-group v-model="form.jobResponsibilitiesConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="jobResponsibilitiesRemarks" style="height: 420px">
+            <el-input v-model="form.jobResponsibilitiesRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
+                      size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <span style="padding-left: 110px;font-size: 14px">澶囨敞锛氬矖浣嶈亴璐h揪鍒�5椤瑰強5椤逛互涓婁负绗﹀悎</span>
+        </el-col>
+        <el-col :span="16">
+          <el-form-item label="缁煎悎璇勪环锛�" label-width="110px" prop="comprehensiveAssessment">
+            <el-radio-group v-model="form.comprehensiveAssessment" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
+              <el-radio label="Qualified this position">鍙儨浠昏宀椾綅</el-radio>
+              <el-radio label="You can work while training">鍙竟鍩硅杈逛笂宀�</el-radio>
+              <el-radio label="Iconpetent for the position">涓嶈儨浠昏宀椾綅</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item prop="confirmOperatingPersonnelId" label="纭浜猴細">
+            <el-select v-model="form.confirmOperatingPersonnelId" clearable :disabled="operationType === 'view' || operationType === 'confirm'"
+                       filterable size="small" style="width: 50%;">
+              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="operationType !== 'view'" @click="resetForm">鍙栨秷</el-button>
+        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm">淇濆瓨</el-button>
+        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm1">鎻愪氦骞堕�氱煡</el-button>
+        <el-button v-if="operationType === 'confirm'" type="primary" @click="verifyGet">纭</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+import limsTable from "@/components/Table/lims-table.vue";
+import {
+  addOrUpdatePersonPersonnelCapacity,
+  confirmPersonnelCapability,
+  deletePersonPersonnelCapacity,
+  exportPersonnelCapacity,
+  personPersonnelCapacityPage,
+  submitConfirmPersonnelCapability
+} from "@/api/cnas/personal/personPersonnelCapacity";
+import {selectUserCondition} from "@/api/cnas/resourceDemand/facilitiesEnvironment/facilitiesAndEnvironment";
+import {mapGetters} from "vuex";
+
+export default {
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  components: {
+    limsTable
+  },
+  computed: {
+    ...mapGetters(["userId"]),
+  },
+  dicts: ['responsibilities_list'],
+  data() {
+    return {
+      userName: '',
+      tableData: [],
+      search: {
+        size: 20,
+        current: 1,
+        total: 0
+      },
+      title: '鏂板鑳藉姏璁ゅ畾',
+      operationType: '',
+      yearColumnData: [
+        {
+          label: '宀椾綅',
+          prop: 'postName',
+          minWidth: '100'
+        }, {
+          label: '濮撳悕',
+          prop: 'userName',
+          minWidth: '100'
+        }, {
+          label: '瀛﹀巻',
+          prop: 'academicDegree',
+          minWidth: '100'
+        }, {
+          label: '涓撲笟',
+          prop: 'major',
+          minWidth: '100'
+        }, {
+          label: '鑱岀О',
+          prop: 'professionalTitle',
+          minWidth: '100'
+        }, {
+          dataType: 'slot',
+          label: '宀椾綅鑱岃矗',
+          prop: 'jobResponsibilities',
+          minWidth: '200px',
+          slot: 'jobResponsibilities'
+        }, {
+          dataType: 'tag',
+          label: '缁煎悎璇勪环',
+          minWidth: '140px',
+          prop: 'comprehensiveAssessment',
+          formatData: (params) => {
+            if (params == 'Qualified this position') {
+              return '鍙儨浠昏宀椾綅';
+            } else if (params == 'You can work while training') {
+              return '鍙竟鍩硅杈逛笂宀�';
+            } else {
+              return '涓嶈儨浠昏宀椾綅';
+            }
+          },
+          formatType: (params) => {
+            if (params == 'Qualified this position') {
+              return 'success';
+            } else if (params == 'You can work while training') {
+              return 'warning';
+            } else {
+              return 'danger';
+            }
+          }
+        }, {
+          label: '纭浜�',
+          prop: 'confirmOperatingPersonnelName',
+          minWidth: '100'
+        }, {
+          label: '纭鏃ユ湡',
+          prop: 'confirmDate',
+          minWidth: '160'
+        }, {
+          dataType: 'action',
+          minWidth: '220',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleViewClick('edit', row);
+              },
+              disabled: (row) => {
+                if (row.confirmDate) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鏌ョ湅',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleViewClick('view', row);
+              }
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.downLoadPost(row);
+              }
+            },
+            {
+              name: '纭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleViewClick('confirm', row);
+              },
+              disabled: (row) => {
+                if (row.confirmDate || this.userId != row.confirmOperatingPersonnelId) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deletePost(row.id);
+              },
+              disabled: (row) => {
+                if (row.confirmDate) {
+                  return true
+                } else {
+                  return false
+                }
+              }
+            }
+          ]
+        }],
+      yearLoading: false,
+      dialogVisible: false,
+      verifyGetId: '',
+      form: {
+        jobResponsibilitiesTem: []
+      },
+      responsibleOptions: [],
+      rules: {
+        confirmOperatingPersonnelId: [{ required: true, message: '璇烽�夋嫨纭浜�', trigger: 'change' }],
+        userId: [{ required: true, message: '璇烽�夋嫨浜哄憳', trigger: 'change' }],
+        academicDegree: [{ required: true, message: '璇疯緭鍏ュ鍘嗘煡鏍哥粨鏋�', trigger: 'blur' }],
+        academicConformNot: [{ required: true, message: '璇烽�夋嫨瀛﹀巻绗﹀悎涓庡惁', trigger: 'change' }],
+        relatedYears: [{ required: true, message: '璇疯緭鍏ョ浉鍏冲勾闄愭煡鏍哥粨鏋�', trigger: 'blur' }],
+        relatedYearsConformNot: [{ required: true, message: '璇烽�夋嫨鐩稿叧骞撮檺绗﹀悎涓庡惁', trigger: 'change' }],
+        relatedTraining: [{ required: true, message: '璇疯緭鍏ョ浉鍩硅闄愭煡鏍哥粨鏋�', trigger: 'blur' }],
+        relatedTrainingConformNot: [{ required: true, message: '璇烽�夋嫨鐩稿叧鍩硅绗﹀悎涓庡惁', trigger: 'change' }],
+        relevantExperience: [{ required: true, message: '璇疯緭鍏ョ浉鍏崇粡楠屾煡鏍哥粨鏋�', trigger: 'blur' }],
+        relevantExperienceConformNot: [{ required: true, message: '璇烽�夋嫨鐩稿叧缁忛獙绗﹀悎涓庡惁', trigger: 'change' }],
+        workLicense: [{ required: true, message: '璇疯緭鍏ヤ笂宀楄瘉鏌ユ牳缁撴灉', trigger: 'blur' }],
+        workLicenseConformNot: [{ required: true, message: '璇烽�夋嫨涓婂矖璇佺鍚堜笌鍚�', trigger: 'change' }],
+        jobResponsibilitiesTem: [{ required: true, message: '璇烽�夋嫨宀椾綅鑱岃矗鏌ユ牳缁撴灉', trigger: 'change' }],
+        jobResponsibilitiesConformNot: [{ required: true, message: '璇烽�夋嫨宀椾綅鑱岃矗绗﹀悎涓庡惁', trigger: 'change' }],
+        comprehensiveAssessment: [{ required: true, message: '璇烽�夋嫨缁煎悎璇勪环', trigger: 'change' }]
+      },
+      responsibilities: []
+    };
+  },
+  mounted() {
+    this.getList(this.departId);
+  },
+  methods: {
+    // 涓嬭浇
+    downLoadPost(row) {
+      exportPersonnelCapacity({id: row.id}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, '浜哄憳鑳藉姏瀵煎嚭.docx')
+      })
+    },
+    // 鏌ヨ
+    refreshTable() {
+      this.getList(this.departId);
+    },
+    // 鑾峰彇浜哄憳鑳藉姏鍒楄〃淇℃伅
+    getList(userId) {
+      this.search.userId = userId;
+      const params = this.isDepartment ?
+        {
+          departmentId: this.search.userId,
+          size: this.search.size,
+          current: this.search.current,
+          userName: this.userName,
+        }: {
+          userId: this.search.userId,
+          size: this.search.size,
+          current: this.search.current,
+          userName: this.userName,
+        }
+      this.yearLoading = true
+      personPersonnelCapacityPage(params).then(res => {
+        this.yearLoading = false
+        this.tableData = res.data.records;
+        this.search.total = res.data.total;
+      }).catch(err => {
+        console.log(err);
+        this.yearLoading = false
+      })
+    },
+    pagination (page) {
+      this.search.size = page.limit
+      this.refreshTable()
+    },
+    selectResponsibilities(arr) {
+      let arrTem = [];
+      arr.map(val => {
+        const index = this.dict.type.responsibilities_list.findIndex(item => item.label === val);
+        if (index > -1) {
+          arrTem.push(this.dict.type.responsibilities_list[index].value);
+        }
+      });
+      this.form.jobResponsibilities = arrTem.join(',');
+    },
+    changeLine (val) {
+      if(val) {
+        return val.replace(/,/g, '<br>')
+      } else {
+        return
+      }
+    },
+    // 鏂板
+    addAppointPost(type) {
+      this.operationType = type;
+      this.title = '鏂板鑳藉姏璁ゅ畾'
+      this.dialogVisible = true;
+      this.form = {
+        jobResponsibilitiesTem: []
+      }
+      this.form.userId = this.departId
+      this.getUserList();
+
+    },
+    // 缂栬緫/鏌ョ湅
+    handleViewClick(type, row) {
+      this.operationType = type;
+      this.verifyGetId = row.id
+      this.title = this.operationType === 'edit' ? '淇敼鑳藉姏璁ゅ畾' : '鏌ョ湅鑳藉姏璁ゅ畾'
+      this.dialogVisible = true;
+      this.form = {...row}
+      if(this.form.responsibilities) {
+        this.$set(this.form, 'jobResponsibilitiesTem', this.form.responsibilities.split(","))
+      } else {
+        this.$set(this.form, 'jobResponsibilitiesTem', [])
+      }
+      this.getUserList();
+    },
+    // 淇濆瓨
+    submitForm() {
+      this.$refs.infoForm.validate((valid) => {
+        if (valid) {
+          addOrUpdatePersonPersonnelCapacity(this.form).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.getList(this.departId);
+              this.dialogVisible = false;
+            }
+          });
+        }
+      });
+    },
+    // 鎻愪氦骞堕�氱煡
+    submitForm1() {
+      this.$refs.infoForm.validate((valid) => {
+        if (valid) {
+          submitConfirmPersonnelCapability(this.form).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.getList(this.departId);
+              this.dialogVisible = false;
+            }
+          });
+        }
+      });
+    },
+    verifyGet () {
+      confirmPersonnelCapability({id: this.verifyGetId}).then(res => {
+        if (res.code == 200) {
+          this.$message.success('纭鎴愬姛');
+          this.resetForm()
+          this.getList(this.departId);
+        }
+      });
+    },
+    // 鍒犻櫎宀椾綅鑱岃矗
+    deletePost(id) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎姝ゆ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        deletePersonPersonnelCapacity({id: id}).then(res => {
+          if (res.code == 200) {
+            this.$message.success('鍒犻櫎鎴愬姛');
+            this.getList(this.departId);
+          }
+        });
+      }).catch(() => {
+        this.$message.error('鍒犻櫎澶辫触');
+      });
+    },
+    resetForm() {
+      this.$refs.infoForm.resetFields();
+      this.dialogVisible = false;
+    },
+    getUserList(){
+      selectUserCondition().then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      })
+    },
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    departId: {
+      handler(newId, oldId) {
+        this.getList(newId);
+      }
+    },
+  }
+};
+</script>
+<style scoped>
+>>> .el-dialog__body {
+  max-height: 74vh;
+  overflow-y: auto;
+}
+
+.radio-group >>> .el-form-item__error {
+  padding-left: 38px;
+}
+>>>.el-checkbox__label {
+  width: 212px;
+  white-space: pre-wrap;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue
new file mode 100644
index 0000000..2b71f75
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue
@@ -0,0 +1,1115 @@
+<template>
+  <div>
+    <div style="text-align: right;margin-bottom: 10px">
+<!--       <el-button size="small" @click="$emit('goBackList')">杩斿洖</el-button>-->
+      <el-button size="small" type="primary" @click="downPerson">涓嬭浇妗f</el-button>
+      <el-button size="small" type="primary" @click="dialogVisible = true">浜哄憳鍒嗙被</el-button>
+      <el-button :loading="saveLoading" size="small" type="primary" @click="save">淇濆瓨</el-button>
+    </div>
+    <div>
+      <div style="display: flex;flex-direction: row;">
+        <div style="width: 12em">
+          <el-image :src="javaApi + '/img/' + form.pictureUrl" fit="fill"
+                    style="width:100%;height: 300px;border: 1px solid #000;border-radius: 10px;margin-left: 6px;margin-top: 10px;">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
+            </div>
+          </el-image>
+          <el-image :src="javaApi + '/img/' + form.signatureUrl" fit="fill"
+                    style="width:80%;height: 50px;border: 1px solid #000;border-radius: 10px;margin-left: 22px;margin-top: 20px;">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
+            </div>
+          </el-image>
+        </div>
+        <div style="height: calc(100vh - 14em);overflow-y: auto">
+          <el-form ref="form" :model="form" label-width="110px">
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="濮撳悕">
+                  <el-input disabled v-model="form.name" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="宸ュ彿">
+                  <el-input disabled v-model="form.account" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="褰撳墠鐘舵��">
+                  <el-radio-group v-model="form.currentState">
+                    <el-radio label="1formal" size="mini">姝e紡</el-radio>
+                    <el-radio label="2intern" size="mini">瀹炰範</el-radio>
+                    <el-radio label="3leaveOffice" size="mini">绂昏亴</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鎬у埆">
+                  <el-radio-group v-model="form.sex">
+                    <el-radio label="1" size="mini">鐢�</el-radio>
+                    <el-radio label="0" size="mini">濂�</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍏徃鍚嶇О">
+                  <el-input v-model="form.corporateName" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鎵�灞為儴闂�">
+                  <el-cascader v-model="form.departLimsId" :options="department" :props="{ label: 'name', value: 'id',checkStrictly: true }"  filterable style="width: 100%;"></el-cascader>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="宀椾綅鍚嶇О">
+                  <el-input v-model="form.postName" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍏ラ泦鍥㈡椂闂�">
+                  <el-date-picker v-model="form.groupTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍔冲姩鍏崇郴">
+                  <el-radio-group v-model="form.laborRelations">
+                    <el-radio :label=0 size="mini">鍚堝悓宸�</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鍏徃閭">
+                  <el-input v-model="form.email" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="宸ヤ綔鏃堕棿">
+                  <el-date-picker v-model="form.workingTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍚堝悓鍒版湡鏃堕棿">
+                  <el-date-picker v-model="form.contractLifeTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鑱岀О">
+                  <el-input v-model="form.professionalTitle" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="16" style="text-align: left;">
+                <el-form-item label="浜哄憳鍒嗙被">
+                  <span style="color: #000;">{{ form.personnelClassification }}</span>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鍑虹敓鏃ユ湡">
+                  <el-date-picker v-model="form.dateBirth" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  @change="getAge"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="绫嶈疮">
+                  <el-input v-model="form.nativePlace" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="姘戞棌">
+                  <el-input v-model="form.nation" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="韬唤璇佸彿">
+                  <el-input v-model="form.identityCard" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="骞撮緞">
+                  <el-input-number v-model="form.age" :max="130" :min="1"
+                                   controls-position="right" size="small" style="width: 99%;"></el-input-number>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="濠氬Щ鐘跺喌">
+                  <el-radio-group v-model="form.maritalStatus">
+                    <el-radio :label=0 size="mini">宸插</el-radio>
+                    <el-radio :label=1 size="mini">鏈</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="璇佷欢鏈夋晥鏈�">
+                  <el-date-picker v-model="form.validityPeriod" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="璇佷欢鍦板潃">
+                  <el-input v-model="form.idAddress" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="璇佷欢璇︾粏鍦板潃">
+                  <el-input v-model="form.idDetailAddress" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鏀挎不闈㈣矊">
+                  <el-input v-model="form.politicalStatus" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍏ュ厷/鍥㈡椂闂�">
+                  <el-date-picker v-model="form.dumplingTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鎵嬫満鍙�">
+                  <el-input v-model="form.telephone" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鏈�楂樺鍘�">
+                  <el-input v-model="form.officialAcademicRedentials" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鏈�楂樺浣�">
+                  <el-input v-model="form.highestDegree" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟闄㈡牎1">
+                  <el-input v-model="form.graduatedInstitutions1" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="涓撲笟1">
+                  <el-input v-model="form.major1" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟鏃堕棿1">
+                  <el-date-picker v-model="form.graduationTime1" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟闄㈡牎2">
+                  <el-input v-model="form.graduatedInstitutions2" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="涓撲笟2">
+                  <el-input v-model="form.major2" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟鏃堕棿2">
+                  <el-date-picker v-model="form.graduationTime2" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鐧昏鏃堕棿">
+                  <el-date-picker v-model="form.lastUpdateTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="澶囨敞">
+                  <el-input type="textarea" v-model="form.remarks" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="18">
+                <el-form-item label="涓汉鐓х墖">
+                  <el-input v-model="form.pictureUrl" disabled size="small">
+                    <el-button v-if="form.pictureUrl" slot="append" icon="el-icon-delete-solid"
+                               @click="deleteFile(form.pictureUrl, 'pictureUrl')"></el-button>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-upload ref="upload" :action="action"
+                           :headers="uploadHeader"
+                           :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'pictureUrl')"
+                           :show-file-list="false"
+                           style="float: left; margin: 0 10px 0 10px;">
+                  <el-button slot="trigger" class="uploadFile" size="mini" type="primary">涓婁紶</el-button>
+                </el-upload>
+                <el-button v-if="form.pictureUrl" class="uploadFile" size="mini"
+                           type="primary" @click="downloadFile(form.pictureUrl)">涓嬭浇</el-button>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="18">
+                <el-form-item label="鐢靛瓙绛惧悕">
+                  <el-input v-model="form.signatureUrl" disabled size="small">
+                    <el-button v-if="form.signatureUrl" slot="append" icon="el-icon-delete-solid"
+                               @click="deleteFile(form.signatureUrl, 'signatureUrl')"></el-button>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-upload ref="upload" :action="action"
+                           :headers="uploadHeader"
+                           :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'signatureUrl')"
+                           :show-file-list="false"
+                           style="float: left; margin: 0 10px 0 10px;">
+                  <el-button slot="trigger" class="uploadFile" size="small" type="primary">涓婁紶</el-button>
+                </el-upload>
+                <el-button v-if="form.signatureUrl" class="uploadFile" size="small"
+                           type="primary" @click="downloadFile(form.signatureUrl)">涓嬭浇</el-button>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="20">
+                <el-form-item label="璇佷功璧勬枡" >
+                </el-form-item>
+              </el-col>
+              <el-col :span="4">
+                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd(0)">鏂板</el-button>
+              </el-col>
+            </el-row>
+            <lims-table :tableData="annexList" :column="columnData2" style="width: 96%;margin-left: 34px"
+                        height="200" :tableLoading="tableLoading2"></lims-table>
+            <el-row style="margin-top: 10px">
+              <el-col :span="20">
+                <el-form-item label="闄勪欢璧勬枡" >
+                </el-form-item>
+              </el-col>
+              <el-col :span="4">
+                <el-upload ref='upload'
+                           :action="fileAction"
+                           :auto-upload="true" :data="{userId: clickNodeVal.userId}"
+                           :before-upload="fileBeforeUpload"
+                           :headers="uploadHeader" :on-error="onError"
+                           :on-success="handleSuccessUp"
+                           :show-file-list="false"
+                           accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
+                  <el-button size="small" type="primary">闄勪欢涓婁紶</el-button>
+                </el-upload>
+              </el-col>
+            </el-row>
+            <lims-table :tableData="tableData" :column="columnData" style="width: 96%;float: right;"
+                        height="200" :tableLoading="tableLoading"></lims-table>
+            <el-row style="margin-top: 10px">
+              <el-col :span="20">
+                <el-form-item label="宸ヤ綔缁忓巻" >
+                </el-form-item>
+              </el-col>
+              <el-col :span="4">
+                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd1('add')">鏂板</el-button>
+              </el-col>
+            </el-row>
+            <el-table :data="tableData1" border height="200" style="width: 96%;float: right;" v-loading="tableLoading1">
+              <el-table-column label="搴忓彿" type="index" width="55px" align="center">
+              </el-table-column>
+              <el-table-column label="宸ヤ綔缁忓巻" prop="workExperience">
+              </el-table-column>
+              <el-table-column align="center" label="鎿嶄綔">
+                <template slot-scope="scope">
+                  <el-button type="text" size="mini" @click="annexAdd1('edit',scope.row)">缂栬緫</el-button>
+                  <el-button type="text" size="mini" @click="deleteAnnex1(scope.row)" style="color: #f56c6c">鍒犻櫎</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form>
+        </div>
+      </div>
+    </div>
+    <!-- 浜哄憳鍒嗙被寮规 -->
+    <el-dialog :visible.sync="dialogVisible" title="鎻愮ず" width="40%" @open="getComparisonList">
+      <div style="height: 30vh;">
+        <el-row>
+          <el-col :span="4">
+            浜哄憳鍒嗙被锛�
+          </el-col>
+          <el-col :span="20" style="text-align: left;">
+            <el-checkbox-group v-model="checkList">
+              <el-checkbox v-for="v in dict.type.personnl_type" :key="v.value"
+                           :label="v.value"></el-checkbox>
+            </el-checkbox-group>
+          </el-col>
+        </el-row>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="clickPersonnelClassificationSure">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 鏂板闄勪欢璧勬枡 -->
+    <el-dialog :before-close="handleClose" :title="title" :visible.sync="dialogVisible1" width="40%" @open="getComparisonList">
+      <el-form ref="annex" :model="annex" :rules="rules" label-width="100px">
+        <el-row>
+          <el-col :span="16">
+            <el-form-item label="璇佷欢鍙�" prop="idNumber">
+              <el-input v-model="annex.idNumber" clearable size="small" style="width: 100%;"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鍙戣瘉鍗曚綅" prop="issueUnit">
+              <el-input v-model="annex.issueUnit" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="绾у埆">
+              <el-input v-model="annex.level" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鏈夋晥鏈�" prop="periodValidity">
+              <el-input v-model="annex.periodValidity" clearable size="small"></el-input>
+<!--              <el-date-picker v-model="annex.periodValidity" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"-->
+<!--                              style="width: 99%;" type="date" value-format="yyyy-MM-dd">-->
+<!--              </el-date-picker>-->
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="澶嶅嵃浠�">
+              <el-input v-model="annex.copy" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鍘熶欢">
+              <el-input v-model="annex.original" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鏂囦欢">
+              <el-upload
+                :action="action"
+                :before-upload="beforeAvatarUpload"
+                :headers="uploadHeader"
+                :on-success="(response,file,fileList) => onSuccess(response, file, fileList, 'fileName')"
+                :show-file-list="false">
+                <span v-if="annex.fileName">{{annex.fileName}}</span>
+<!--                <img v-if="imageUrl" :src="imageUrl" class="avatar">-->
+                <i v-else class="el-icon-upload avatar-uploader-icon"></i>
+              </el-upload>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="cancellation">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+    <!-- 鏂板宸ヤ綔缁忓巻 -->
+    <el-dialog @close="handleClose2" title="娣诲姞宸ヤ綔缁忓巻" :visible.sync="dialogVisible2" width="40%">
+      <el-form ref="annex2" :model="annex2" label-width="100px">
+        <el-row>
+          <el-col :span="16">
+            <el-form-item label="宸ヤ綔缁忓巻" prop="idNumber">
+              <el-input type="textarea" v-model="annex2.workExperience" clearable size="small" style="width: 100%;"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose2">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitForm2">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import fileDownload from '@/utils/file'
+import {
+  addAnnex,
+  addBasicInfoWork,
+  delBasicInfoFileList,
+  delBasicInfoWorkList,
+  deleteAnnex, deleteCNASFile,
+  exportPersonBasicInfoById,
+  getAnnex,
+  getAnnexByUserId,
+  getBasicInfoFileList,
+  getBasicInfoWorkList,
+  getCNASPersonnelInfo,
+  saveCNASPersonnelInfo,
+  updateAnnex,
+  updateBasicInfoWorkList
+} from "@/api/cnas/personal/personalList";
+import limsTable from "@/components/Table/lims-table.vue";
+
+export default {
+  props: {
+    clickNodeVal: {
+      type: Object,
+      default: () => { return {} }
+    },
+  },
+  dicts: ['personnl_type'],
+  data() {
+    return {
+      operationType: '',
+      basicInfoWorkId: '',
+      dialogVisible2: false,
+      annex2: {
+        workExperience: ''
+      },
+      tableLoading: false,
+      tableData: [],
+      columnData: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.upload(row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delete(row)
+              }
+            }
+          ]
+        }
+      ],
+      columnData2: [
+        {
+          label: '璇佷欢鍙�',
+          prop: 'idNumber',
+          minWidth: '150px'
+        },{
+          label: '鍙戣瘉鍗曚綅',
+          prop: 'issueUnit',
+          minWidth: '150px'
+        },{
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '200px'
+        },{
+          label: '绾у埆',
+          prop: 'level',
+          minWidth: '150px'
+        },{
+          label: '鏈夋晥鏈�',
+          prop: 'periodValidity',
+          minWidth: '150px'
+        },{
+          label: '娣诲姞鏃堕棿',
+          prop: 'createTime',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '130',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.downloadFile(row.fileName)
+              }
+            },
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.annexAdd(1,row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deleteAnnex(row)
+              }
+            }
+          ]
+        }
+      ],
+      tableLoading1: false,
+      tableLoading2: false,
+      tableData1: [],
+      addOrupdate: null,
+      title: '',
+      annexList: [],
+      imageUrl: '',
+      annex: {
+        userId: '',
+        idNumber: '',
+        issueUnit: '',
+        level: '',
+        periodValidity: '',
+        copy: '',
+        original: '',
+        fileName: ''
+      },
+      rules: {
+        idNumber: [
+          { required: true, message: '璇疯緭鍏ヨ瘉浠跺彿', trigger: 'blur' }
+        ],
+        issueUnit: [
+          { required: true, message: '璇疯緭鍏ュ彂璇佸崟浣�', trigger: 'blur' }
+        ],
+        periodValidity: [
+          { required: false, message: '璇烽�夋嫨鏈夋晥鏈�', trigger: 'blur' }
+        ]
+      },
+      dialogVisible1: false,
+      form: {
+        userId: '',
+        name: '',
+        account: '',
+        currentState: '',
+        sex: '',
+        corporateName: '',
+        department: '',
+        departLimsId: [],
+        postName: '',
+        groupTime: '',
+        laborRelations: '',
+        workingTime: '',
+        contractLifeTime: '',
+        personnelClassification: '',
+        dateBirth: '',
+        nativePlace: '',
+        nation: '',
+        identityCard: '',
+        age: '',
+        validityPeriod: '',
+        maritalStatus: '',
+        idAddress: '',
+        idDetailAddress: '',
+        politicalStatus: '',
+        dumplingTime: '',
+        telephone: '',
+        email: '',
+        officialAcademicRedentials: '',
+        highestDegree: '',
+        graduatedInstitutions1: '',
+        major1: '',
+        graduationTime1: '',
+        graduatedInstitutions2: '',
+        major2: '',
+        graduationTime2: '',
+        lastUpdateTime: '',
+        pictureUrl: '',
+        signatureUrl: '',
+        professionalTitle: '',
+        remarks: '',
+      },
+      department: [],
+      saveLoading: false,
+      dialogVisible: false,
+      checkList: [],
+      successFileList: [], // 闃叉鍚庣鍑虹幇鑴忔暟鎹�
+      isSave: false,
+    }
+  },
+  components: {limsTable, fileDownload},
+  created() {
+    this.init()
+    this.searchTableList()
+    this.searchTableList2()
+  },
+  computed: {
+    action() {
+      return this.javaApi + '/personBasicInfo/saveCNASFile'
+    },
+    fileAction() {
+      return this.javaApi + '/personBasicInfo/uploadBasicInfoFile'
+    },
+  },
+  methods: {
+    // 涓嬭浇妗f
+    downPerson(){
+      exportPersonBasicInfoById({id: this.clickNodeVal.userId}).then(res => {
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, '浜哄憳妗f.docx');
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 涓婁紶楠岃瘉
+    fileBeforeUpload(file) {
+      let flag = true
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        flag = false
+      }
+      if (!flag) {
+        return Promise.reject(flag); //姝g‘鐨勭粓姝�
+      }
+    },
+    onError(err, file, fileList,type) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+    },
+    handleSuccessUp(response, ) {
+      this.upLoading = false;
+      if (response.code == 200) {
+        this.$message.success('涓婁紶鎴愬姛');
+        this.searchTableList()
+      } else {
+        this.$message.error(response.message);
+      }
+    },
+    // 鏌ヨ闄勪欢鍒楄〃
+    searchTableList () {
+      this.tableLoading = true
+      getBasicInfoFileList({userId: this.clickNodeVal.userId}).then(res => {
+        this.tableLoading = false
+        this.tableData = res.data
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        fileDownload.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+    // 鍒犻櫎
+    delete (row) {
+      this.$confirm('姝ゆ搷浣滃皢鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delBasicInfoFileList({basicInfoFileId: row.basicInfoFileId}).then(res => {
+          this.tableLoading = false
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchTableList();
+        }).catch(err => {
+          this.tableLoading = false
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      })
+    },
+    // 鎵撳紑宸ヤ綔缁忓巻鎺㈠喌
+    annexAdd1 (type, row) {
+      this.operationType = type
+      if (type === 'edit') {
+        this.basicInfoWorkId = row.basicInfoWorkId
+        this.annex2.workExperience = row.workExperience
+      } else {
+        this.basicInfoWorkId = ''
+        this.annex2.workExperience = ''
+      }
+      this.dialogVisible2 = true
+    },
+    // 鎻愪氦宸ヤ綔缁忓巻
+    submitForm2 () {
+      const params = {
+        workExperience: this.annex2.workExperience,
+        userId: this.clickNodeVal.userId,
+        basicInfoWorkId: this.basicInfoWorkId
+      }
+      this.tableLoading1 = true
+      if (this.operationType === 'add') {
+        addBasicInfoWork(params).then(res => {
+          this.tableLoading1 = false
+          if (res.code == 200) {
+            this.dialogVisible2 = false
+            this.$message.success('鏂板鎴愬姛')
+            this.searchTableList2();
+          }
+        }).catch(err => {
+          this.tableLoading1 = false
+        })
+      } else {
+        updateBasicInfoWorkList(params).then(res => {
+          this.tableLoading1 = false
+          this.dialogVisible2 = false
+          this.$message.success('淇敼鎴愬姛')
+          this.searchTableList2();
+        }).catch(err => {
+          this.tableLoading1 = false
+        })
+      }
+    },
+    // 鍏抽棴宸ヤ綔缁忓巻寮规
+    handleClose2 () {
+      this.dialogVisible2 = false
+      this.annex2.workExperience = ''
+    },
+    // 鍒犻櫎宸ヤ綔缁忓巻
+    deleteAnnex1 (row) {
+      this.$confirm('姝ゆ搷浣滃皢鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading1 = true
+        delBasicInfoWorkList({basicInfoWorkId: row.basicInfoWorkId}).then(res => {
+          this.tableLoading1 = false
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchTableList2();
+        }).catch(err => {
+          this.tableLoading1 = false
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 鏌ヨ宸ヤ綔缁忓巻鍒楄〃
+    searchTableList2 () {
+      this.tableLoading1 = true
+      getBasicInfoWorkList({userId: this.clickNodeVal.userId}).then(res => {
+        this.tableLoading1 = false
+        this.tableData1 = res.data
+      }).catch(err => {
+        this.tableLoading1 = false
+        console.log('err---', err);
+      })
+    },
+    annexAdd(type,row) {
+      if(type === 1) {
+        this.title = '缂栬緫闄勪欢璧勬枡'
+        this.addOrupdate = 1
+        getAnnex({id: row.id}).then(res => {
+          this.annex = res.data
+          this.imageUrl = this.javaApi + '/img/' + res.data.fileName
+        })
+      }else {
+        this.title = '鏂板闄勪欢璧勬枡'
+        this.addOrupdate = 2
+      }
+      this.dialogVisible1 = true
+    },
+    submitForm() {
+      this.$refs['annex'].validate((valid) => {
+        if (valid) {
+          this.addAnnex()
+        } else {
+          return false
+        }
+      })
+    },
+    addAnnex() {
+      if(this.annex.fileName == "" || this.annex.fileName == null || this.annex.fileName == undefined) {
+        this.$message.error("璇蜂笂浼犳枃浠�")
+        return
+      }
+      this.annex.userId = this.clickNodeVal.userId
+      if(this.addOrupdate === 1) {
+        updateAnnex(this.annex).then(res => {
+          if(res.code == 200) {
+            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
+              this.imageUrl = ''
+              this.resetForm('annex')
+              this.annexList = res.data
+              this.dialogVisible1 = false
+              this.$message.success('鏇存柊鎴愬姛锛�')
+            })
+          }
+        })
+      }else {
+        this.annex.id = null
+        addAnnex(this.annex).then(res => {
+          if(res.code == 200) {
+            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
+              this.imageUrl = ''
+              this.resetForm('annex')
+              this.annexList = res.data
+              this.dialogVisible1 = false
+              this.$message.success('淇濆瓨鎴愬姛')
+            })
+          }
+        })
+      }
+    },
+    deleteAnnex(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        deleteAnnex({id: row.id}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛锛�')
+          this.annexList = this.annexList.filter(item => item.id != row.id)
+        })
+      })
+    },
+    beforeAvatarUpload(file) {
+      let flag = true
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        flag = false
+      }
+      if (!flag) {
+        return Promise.reject(flag); //姝g‘鐨勭粓姝�
+      }
+    },
+    downloadFile(fileName) {
+      let state = /\.(jpg|jpeg|png|gif)$/i.test(fileName)
+      if (state) {
+        let url = this.javaApi + '/img/' + fileName;
+        fileDownload.downloadIamge(url, fileName)
+      } else {
+        const url = this.javaApi + '/word/' + fileName
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = fileName;
+        link.click();
+        this.$message.success('涓嬭浇鎴愬姛')
+      }
+    },
+    async onSuccess(response, file, fileList, entityVal) {
+      if(entityVal == 'fileName') {
+        this.annex.fileName = response.data
+      }
+      // 鍦ㄤ繚瀛樿祴鍊兼柊鏂囦欢
+      this.successFileList.push(response.data)
+      this.$set(this.form, entityVal, response.data)
+    },
+    // 鍒濆鍖栬皟鐢�
+    init() {
+      if (!this.clickNodeVal.userId) {
+        let user = JSON.parse(localStorage.getItem('user'))
+        this.getUserBasisInfo(user.userId)
+        this.clickNodeVal.userId = user.userId
+      } else {
+        this.getUserBasisInfo(this.clickNodeVal.userId)
+      }
+    },
+    getUserBasisInfo(userId) {
+      getCNASPersonnelInfo({userId: userId}).then(res => {
+        this.form = res.data.PersonBasicInfoDto
+        this.department = res.data.department
+        this.annexList = res.data.annexList
+        this.form.departLimsId = res.data.PersonBasicInfoDto.departLimsId.split(',').filter(a => a != "").map(Number)
+      })
+    },
+    async save() {
+      this.saveLoading = true
+      this.form.userId = this.clickNodeVal.userId
+      if(Array.isArray(this.form.departLimsId)) {
+        if(this.form.departLimsId.length > 0) {
+          this.form.departLimsId = this.form.departLimsId.join(',').trim() + ','
+        }else {
+          this.form.departLimsId = ''
+        }
+      }
+      saveCNASPersonnelInfo(this.form).then(res => {
+        this.saveLoading = false
+        this.isSave = true
+        this.getUserBasisInfo(this.clickNodeVal.userId)
+        this.$message.success('淇濆瓨鎴愬姛锛�')
+      })
+    },
+    // 鍙栦汉鍛樺垎绫荤殑瀛楀吀
+    getComparisonList() {
+      if (this.checkList.length > 0) {
+        this.form.personnelClassification = this.checkList.split('锛�')
+      }
+    },
+    clickPersonnelClassificationSure() {
+      this.dialogVisible = false
+      this.form.personnelClassification = this.checkList.filter(m=>m).join('锛�')
+    },
+    async deleteFile(fileName, entityVal) {
+      await deleteCNASFile({fileName: fileName}).then(res => {
+        this.$message.success('鍒犻櫎鎴愬姛锛�')
+        this.$set(this.form, entityVal, null)
+        let index = this.successFileList.indexOf(fileName)
+        if (index != -1) {
+          this.successFileList.splice(index, 1)
+        }
+      })
+    },
+    cancellation() {
+      this.dialogVisible1 = false
+      this.imageUrl = ''
+      this.resetForm('annex')
+    },
+    handleClose(done) {
+      this.imageUrl = ''
+      this.annex = {
+        userId: '',
+        idNumber: '',
+        issueUnit: '',
+        level: '',
+        periodValidity: '',
+        copy: '',
+        original: '',
+        fileName: ''
+      }
+      done();
+    },
+    resetForm(formName) {
+      this.$refs[formName].resetFields();
+    },
+    getAge (val) {
+      this.form.age = this.calculateAge(val)
+    },
+    calculateAge(birthDateString) {
+      // 瑙f瀽鍑虹敓鏃ユ湡瀛楃涓蹭负鏃ユ湡瀵硅薄
+      const birthDate = new Date(birthDateString);
+
+      // 鑾峰彇褰撳墠鏃ユ湡
+      const currentDate = new Date();
+
+      // 璁$畻骞翠唤宸�
+      let age = currentDate.getFullYear() - birthDate.getFullYear();
+
+      // 妫�鏌ユ槸鍚﹀凡缁忚繃浜嗕粖骞寸殑鐢熸棩
+      const currentMonth = currentDate.getMonth();
+      const currentDay = currentDate.getDate();
+      const birthMonth = birthDate.getMonth();
+      const birthDay = birthDate.getDate();
+
+      if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
+        // 濡傛灉杩樻病鍒颁粖骞寸殑鐢熸棩锛屽勾榫勫噺1
+        age--;
+      }
+
+      return age;
+    }
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    clickNodeVal: {
+      handler(newVal, oldVal) {
+        if (newVal.userId) {
+          this.getUserBasisInfo(newVal.userId)
+          this.searchTableList()
+          this.searchTableList2()
+        }
+      },
+    }
+  }
+}
+</script>
+
+<style scoped>
+>>>.el-table__body-wrapper::-webkit-scrollbar {
+  height: 12px;
+  /* 璁剧疆婊氬姩鏉″搴� */
+}
+>>>.el-form-item {
+    margin-bottom: 3px;
+}
+
+.el-input {
+    border-radius: 15px;
+}
+
+.el-icon-picture-outline {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+}
+
+.uploadFile {
+    margin-top: 2px;
+    float: left;
+}
+  .avatar-uploader-icon {
+    font-size: 28px;
+    color: #0f8bf1;
+    width: 178px;
+    height: 50px;
+    text-align: center;
+    border: 1px solid #d9d9d9;
+  }
+  .avatar {
+    width: 178px;
+    height: 178px;
+    display: block;
+  }
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue
new file mode 100644
index 0000000..92e0233
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue
@@ -0,0 +1,317 @@
+<template>
+  <div>
+    <div style="display: flex;justify-content: space-between;">
+      <el-form :model="entity" ref="entity" size="small" :inline="true">
+        <el-form-item label="浜哄憳鍚嶇О">
+          <el-input v-model="entity.name" clearable></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="small" style="margin-left: 10px" @click="refresh()">閲� 缃�</el-button>
+          <el-button size="small" type="primary" @click="refreshTable()">鏌� 璇�</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button
+          :loading="outLoading"
+          size="small"
+          type="primary"
+          @click="handleDown">瀵煎嚭</el-button>
+        <el-button size="small" type="primary" @click="openSelectUserDia">鏂板缓</el-button>
+      </div>
+    </div>
+    <div class="search-table">
+      <el-table v-loading="tableLoading" :data="tableData" border height="calc(100vh - 21em)" style="width: 100%;">
+        <el-table-column align="center" label="搴忓彿" type="index" width="60"></el-table-column>
+        <el-table-column label="鍛樺伐缂栧彿" prop="account" width="150"></el-table-column>
+        <el-table-column label="濮撳悕" prop="name" width="120"></el-table-column>
+        <el-table-column label="绫嶈疮" prop="nativePlace" width="120"></el-table-column>
+        <el-table-column label="璇佷欢鍦板潃" prop="idAddress" show-overflow-tooltip width="100"></el-table-column>
+        <el-table-column label="鎵嬫満鍙�" prop="telephone" show-overflow-tooltip width="100"></el-table-column>
+        <el-table-column label="姣曚笟闄㈡牎" prop="graduatedInstitutions1" width="100"></el-table-column>
+        <el-table-column label="鎵�瀛︿笓涓�" prop="major1" width="100"></el-table-column>
+        <el-table-column label="姣曚笟鏃堕棿" prop="graduationTime1" width="100"></el-table-column>
+        <el-table-column label="鏈�楂樺鍘�" prop="officialAcademicRedentials" width="100"></el-table-column>
+        <el-table-column label="鏈�楂樺浣�" prop="highestDegree" width="100"></el-table-column>
+        <el-table-column label="鑱岀О" prop="professionalTitle" width="100"></el-table-column>
+        <el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
+          <template slot-scope="scope">
+            <el-button size="small" type="text" @click="$emit('updatePerson', scope.row)">缂栬緫</el-button>
+            <el-button size="small" type="text" @click="deletePerson(scope.row)" style="color: #f56c6c">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        :current-page="1"
+        :current-page.sync="page.current"
+        :page-size="page.size"
+        :page-sizes="[10, 20, 30, 50, 100]"
+        :total="page.total"
+        background
+        layout="->,total, sizes, prev, pager, next, jumper"
+        style="margin-top: 10px"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      >
+      </el-pagination>
+    </div>
+    <el-dialog :visible.sync="selectUserDia" title="閫夋嫨鐢ㄦ埛" width="70%">
+      <div class="search" style="margin-bottom: 9px;">
+        <div class="search_thing">
+          <div class="search_label">鐢ㄦ埛鍚嶏細</div>
+          <div class="search_input">
+            <el-input
+              v-model="addUserTableInfo.name"
+              clearable
+              placeholder="璇疯緭鍏�"
+              size="small"
+              @change="selectUserList"
+            ></el-input>
+          </div>
+          <el-button size="small" style="margin-left: 10px" type="primary" @click="selectUserList">鏌ヨ</el-button>
+        </div>
+      </div>
+      <div v-if="selectUserDia" class="body" style="height: 60vh;">
+        <lims-table :tableData="tableData1" :column="column1"
+                    :isSelection="true" :handleSelectionChange="selectMethod"
+                    :height="'calc(100vh - 290px)'"
+                    :tableLoading="tableLoading1"></lims-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="selectUserDia = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="selectUser">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {selectUserCondition} from "@/api/business/inspectionTask";
+import limsTable from "@/components/Table/lims-table.vue";
+import {
+  basicInformationOfPersonnelSelectPage,
+  delUserDepardLimsId,
+  exportPersonBasicInfo,
+  upUserDepardLimsId
+} from "@/api/cnas/personal/personalList";
+import store from "@/store";
+import {Message} from "element-ui";
+
+export default {
+  name: 'PersonnelList',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {limsTable},
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    },
+    currentCompaniesList: {
+      type: Array,
+      default: []
+    }
+  },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      page: {
+        size: 20,
+        current: 1,
+      },
+      outLoading: false,
+      tableLoading: false,
+      tableData: [], // 浜哄憳鎬诲垪琛ㄦ暟鎹�
+      tableData1: [],
+      tableLoading1: false,
+      column1: [
+        {label: '濮撳悕', prop: 'name'},
+        {label: '璐﹀彿', prop: 'account'},
+        {label: '瑙掕壊', prop: 'roleName'},
+        {
+          dataType: 'tag',
+          label: '鐘舵��',
+          prop: 'status',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鍚敤'
+            } else {
+              return ''
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'success'
+            } else {
+              return 'danger'
+            }
+          }
+        },
+        {label: '鐢佃瘽鍙风爜', prop: 'phone'},
+      ],
+      page1: {
+        total:0,
+        size:10,
+        current:1
+      },
+      selectUserDia: false, // 娣诲姞浜哄憳寮规
+      entity: {
+        name: '',
+        orderBy: {
+          field: 'id',
+          order: 'asc'
+        }
+      },
+      addUserTableInfo: {
+        name: null,
+        isCustom: 0,
+      },
+      multipleSelection: []
+    };
+  },
+  mounted() {
+    this.refreshTable();
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    /**
+     * @desc 鑾峰彇璁惧id
+     */
+    // 閲嶇疆
+    refresh() {
+      this.page = {
+        size: 20,
+        current: 1,
+      };
+      this.entity.name = ''
+      this.refreshTable();
+    },
+    // 鏌ヨ浜哄憳鍒楄〃鏁版嵁
+    refreshTable() {
+      this.tableLoading = true;
+      this.entity.departLimsId = this.departId;
+      const params = {
+        size: this.page.size,
+        current: this.page.current,
+        departmentId: this.entity.departLimsId,
+        name: this.entity.name,
+      }
+      basicInformationOfPersonnelSelectPage(params).then(res => {
+        this.tableLoading = false;
+        this.page.total = res.data.total;
+        this.tableData = res.data.records;
+      }).catch(err => {
+        this.tableLoading = false;
+      })
+    },
+    // 鍒犻櫎浜哄憳
+    deletePerson(row) {
+      this.$confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', '璀﹀憡', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        delUserDepardLimsId({id: row.userId}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛');
+          this.refreshTable();
+          this.$emit('refreshTree')
+        }).catch(e => {
+          this.$message.error('鍒犻櫎澶辫触');
+        });
+      }).catch(() => {
+      });
+    },
+    handleSizeChange(val) {
+      this.page.size = val;
+      this.refreshTable();
+    },
+    handleCurrentChange(val) {
+      this.page.current = val;
+      this.refreshTable();
+    },
+    // 鎵撳紑鏂板浜哄憳寮规
+    openSelectUserDia () {
+      this.selectUserDia = true;
+      this.selectUserList()
+    },
+    // 鏌ヨ鏂板寮规鐨勪汉鍛樺垪琛�
+    selectUserList () {
+      this.tableLoading1 = true
+      selectUserCondition().then(res => {
+        this.tableLoading1 = false
+        this.tableData1 = res.data
+      }).catch(err => {
+        this.tableLoading1 = false
+      })
+    },
+    // 琛ㄦ牸閫夋嫨鏂规硶
+    selectMethod(val) {
+      this.multipleSelection = val
+    },
+    // 鎻愪氦闇�瑕佹坊鍔犵殑浜哄憳
+    selectUser() {
+      if (!this.currentCompaniesList.length > 0) {
+        this.$message.warning("璇烽�夋嫨閮ㄩ棬锛�")
+        return;
+      }
+      let selects = this.HaveJson(this.multipleSelection)
+      if (selects.length === 0) {
+        this.$message.error('鏈�夋嫨鏁版嵁');
+        return;
+      }
+      let ids = [];
+      selects.forEach(a => {
+        ids.push(a.id);
+      });
+      let str = '';
+      this.currentCompaniesList.forEach(a => {
+        if (a) {
+          str += a + ',';
+        }
+      });
+      upUserDepardLimsId({
+        ids: JSON.stringify(ids),
+        id: str
+      }).then(res => {
+        this.selectUserDia = false;
+        this.$message.success('娣诲姞鎴愬姛');
+        this.refreshTable();
+        this.$emit('refreshTree')
+      });
+    },
+    // 瀵煎嚭浜哄憳淇℃伅
+    handleDown() {
+      this.outLoading = true;
+      let entity = this.HaveJson(this.entity)
+      delete entity.orderBy;
+      exportPersonBasicInfo({...entity}).then(res => {
+        this.outLoading = false;
+        const blob = new Blob([res], {type: 'application/octet-stream'});
+        this.$download.saveAs(blob, '浜哄憳淇℃伅.xlsx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (newId) {
+          this.page.current = 1
+          this.refreshTable();
+        }
+      }
+    }
+  }
+};
+</script>
+
+<style scoped>
+.search_thing {
+  display: flex;
+  align-items: center;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue
new file mode 100644
index 0000000..46c637d
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue
@@ -0,0 +1,802 @@
+<!-- 浜哄憳鍩硅 -->
+<template>
+  <div class="flex_column">
+    <div v-if="!editPlanShow && isDepartment">
+      <div class="title">
+        <span style="font-weight: bold">骞村害璁″垝</span>
+      </div>
+      <div style="display: flex;justify-content: space-between;">
+        <el-form :model="page" ref="page" size="small" :inline="true">
+          <el-form-item label="缂栧埗浜�">
+            <el-input v-model="page.compilerName" clearable></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" @click="getYearPlanList(departId)">鏌� 璇�</el-button>
+          </el-form-item>
+        </el-form>
+        <div>
+          <el-button size="small" type="primary" @click="uploadDia = true, getUserList()">瀵煎叆</el-button>
+        </div>
+      </div>
+      <lims-table :tableData="yearPlanTableData" :column="yearPlanColumn"
+                  :currentChange="currentChange"
+                  @pagination="pagination" height="40vh"
+                  :page="page" :tableLoading="yearLoading"></lims-table>
+    </div>
+    <div v-if="!editPlanShow" class="table">
+      <div>
+        <div class="title">
+          <span style="font-weight: bold">骞村害璁″垝鏄庣粏</span>
+        </div>
+        <div style="display: flex;justify-content: space-between;">
+          <el-form :model="inDetailForm" ref="inDetailForm" size="small" :inline="true">
+            <el-form-item label="鍩硅璁插笀">
+              <el-input v-model="inDetailForm.trainingLecturerName" class="search" clearable placeholder="璇疯緭鍏�" size="small"></el-input>
+            </el-form-item>
+            <el-form-item label="鍩硅鏃ユ湡">
+              <el-date-picker v-model="inDetailForm.trainingDate" clearable
+                              format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                              type="date" value-format="yyyy-MM-dd"></el-date-picker>
+            </el-form-item>
+            <el-form-item>
+              <el-button size="small" type="primary" @click="searchTable">鏌� 璇�</el-button>
+            </el-form-item>
+          </el-form>
+          <div>
+            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" @click="batchDelete">鎵归噺鍒犻櫎</el-button>
+            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" type="primary" @click="addTrainingPlan('add')">鏂板</el-button>
+          </div>
+        </div>
+        <lims-table :tableData="inDetailPlanTableData" :column="inDetailPlanColumn"
+                    :height="isDepartment ? '40vh' : '62vh' "
+                    :isSelection="true" :handleSelectionChange="handleSelectionChange"
+                    @pagination="pagination1"
+                    :page="inDetailPagination" :tableLoading="yearDetailLoading"></lims-table>
+      </div>
+    </div>
+    <Add ref="addPlan" :currentChangeRow="currentChangeRow" @search="getInDetailPlan(currentRowId, departId)"></Add>
+    <Edit
+      v-if="editPlanShow"
+      ref="editPlan"
+      :currentRow="currentRow"
+      @del="getInDetailPlan(currentRowId, departId)"
+      @goBack="goBack"
+    ></Edit>
+    <el-dialog :visible.sync="reviewDialog" title="瀹℃牳" width="30%" @close="auditRemarks = ''">
+      <span>
+        瀹℃牳澶囨敞锛�
+        <el-input v-model="auditRemarks" type="textarea"></el-input>
+      </span>
+      <span style="margin-top: 10px;display: inline-block">
+        鎵瑰噯浜猴細
+        <el-select v-model="approverId" clearable
+                   filterable size="small" style="width: 70%;">
+          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+          </el-option>
+        </el-select>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="reviewLoading" @click="handleReview(2)">涓嶉�氳繃</el-button>
+        <el-button :loading="reviewLoading" type="primary" @click="handleReview(1)">閫� 杩�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="approvalDialog" title="鎵瑰噯" width="30%" @close="approvalRemarks = ''">
+      <span>
+        鎵瑰噯澶囨敞锛�
+        <el-input v-model="approvalRemarks" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="approvalLoading" @click="handleApproval(2)">涓嶆壒鍑�</el-button>
+        <el-button :loading="reviewLoading" type="primary" @click="handleApproval(1)">鎵� 鍑�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="uploadDia" title="鏁版嵁瀵煎叆" width="500px">
+      <div style="display: flex;align-items: center;">
+        <div style="width: 70px">骞翠唤锛�</div>
+        <el-date-picker
+          v-model="planYear"
+          type="year"
+          value-format="yyyy"
+          clearable
+          size="small"
+          format="yyyy"
+          placeholder="閫夋嫨骞�">
+        </el-date-picker>
+      </div>
+      <div style="display: flex;align-items: center;margin: 10px 0">
+        <div style="width: 70px">瀹℃牳浜猴細</div>
+        <el-select v-model="reviewerId" clearable
+                   filterable size="small" style="width: 50%;">
+          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+          </el-option>
+        </el-select>
+      </div>
+      <div style="margin: 0 auto;">
+        <el-upload ref="upload" :action="javaApi + '/personTraining/personTrainingImport' + '?planYear=' + planYear + '&reviewerId=' + reviewerId"
+                   :auto-upload="false" :before-upload="beforeUpload" :file-list="fileList" :headers="uploadHeader"
+                   :limit="1" :on-error="onError" :on-success="onSuccess" accept=".xlsx" drag
+                   name="file">
+          <i class="el-icon-upload"></i>
+          <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        </el-upload>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="uploadDia = false">鍙� 娑�</el-button>
+        <el-button :loading="uploading" type="primary" @click="submitUpload()">涓� 浼�</el-button>
+      </span>
+    </el-dialog >
+    <view-record v-if="ViewRecord" ref="ViewRecord"></view-record>
+  </div>
+</template>
+
+<script>
+import Add from '../components/AddInDetail.vue';
+import Edit from '../components/Edit.vue';
+import ViewRecord from "../components/ViewRecord.vue";
+import limsTable from "@/components/Table/lims-table.vue";
+import {mapGetters} from "vuex";
+import {
+  approveAnnualPersonnelTraining, deleteAnnualPlanDetailTable, exportPersonTraining, exportPersonTrainingRecord,
+  personTraining,
+  personTrainingDelete,
+  queryTheAnnualPlanDetailsTable, reviewAnnualPersonnelTraining
+} from "@/api/cnas/personal/personalTraining";
+import {selectUserCondition} from "@/api/system/user";
+
+export default {
+  name: 'PersonnelTraining',
+  components: {limsTable, ViewRecord, Add, Edit },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    ...mapGetters(["userId"]),
+  },
+  data() {
+    return {
+      planYear: '',
+      reviewerId: '',
+      responsibleOptions: [],
+      search: {},
+      superviseForm: {},
+      inDetailForm: {
+        trainingLecturerName: '',
+        trainingDate: '',
+      },
+      yearLoading: false,
+      yearDetailLoading: false,
+      yearPlanTableData: [], // 骞村害璁″垝琛ㄦ暟鎹�
+      yearPlanColumn: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          width: '160px',
+          prop: 'fileName'
+        }, {
+          label: '鍒涘缓鏃堕棿',
+          width: '160px',
+          prop: 'createTime'
+        },{
+          label: '缂栧埗浜�',
+          prop: 'compilerName'
+        }, {
+          label: '缂栧埗鏃ユ湡',
+          width: '160px',
+          prop: 'compilationDate'
+        }, {
+          label: '瀹℃牳浜�',
+          prop: 'reviewerName',
+          minWidth: '100px',
+        }, {
+          dataType: 'tag',
+          label: '瀹℃牳鐘舵��',
+          prop: 'reviewerStatus',
+          width: '100px',
+          formatData: (params) => {
+            if (params == 1) {
+              return '閫氳繃';
+            } else if (params == 2) {
+              return '涓嶉�氳繃';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 1) {
+              return 'success';
+            } else if (params == 2) {
+              return 'danger';
+            } else {
+              return null
+            }
+          }
+        }, {
+          label: '瀹℃牳澶囨敞',
+          prop: 'auditRemarks',
+          minWidth: '100px',
+        }, {
+          label: '瀹℃牳鏃ユ湡',
+          width: '160px',
+          prop: 'auditDate'
+        }, {
+          label: '鎵瑰噯浜�',
+          prop: 'approverName',
+          minWidth: '100px',
+        }, {
+          label: '鎵瑰噯澶囨敞',
+          prop: 'approvalRemarks',
+          minWidth: '100px',
+        }, {
+          dataType: 'tag',
+          label: '鎵瑰噯鐘舵��',
+          minWidth: '100px',
+          prop: 'approvalStatus',
+          formatData: (params) => {
+            if (params == 1) {
+              return '鎵瑰噯';
+            } else if (params == 2) {
+              return '涓嶆壒鍑�';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 1) {
+              return 'success';
+            } else if (params == 2)  {
+              return 'danger';
+            } else {
+              return null
+            }
+          }
+        }, {
+          label: '鎵瑰噯鏃ユ湡',
+          width: '160px',
+          prop: 'approvalDate'
+        }, {
+          dataType: 'action',
+          width: '180px',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              disabled: (row) => {
+                if(row.approvalStatus === 1 && row.reviewerStatus === 1) {
+                  return false;
+                } else {
+                  return true;
+                }
+              },
+              clickFun: (row) => {
+                this.downLoadPost(row);
+              }
+            },
+            {
+              name: '瀹℃牳',
+              type: 'text',
+              disabled: (row) => {
+                if(row.reviewerStatus === 1 || this.userId != row.reviewerId) {
+                  return true;
+                } else {
+                  return false;
+                }
+              },
+              clickFun: (row) => {
+                this.handleCheck(row.id);
+              }
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              disabled: (row) => {
+                if(row.approvalStatus === 1 || this.userId != row.approverId || row.reviewerStatus != 1) {
+                  return true;
+                } else {
+                  return false;
+                }
+              },
+              clickFun: (row) => {
+                this.handleApprove(row.id);
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deleteFun(row.id);
+              },
+              disabled: (row) => {
+                if(row.reviewerStatus === 1) {
+                  return true;
+                } else {
+                  return false;
+                }
+              },
+            }
+          ]
+        }],
+      inDetailPlanTableData: [], // 骞村害璁″垝鏄庣粏琛ㄨ〃鏁版嵁
+      inDetailPlanColumn: [
+       {
+          label: '鍩硅鐩爣',
+          prop: 'trainingObjectives',
+          width: '100px',
+        }, {
+          label: '鍩硅鍐呭',
+          prop: 'trainingContent',
+          width: '100px',
+        }, {
+          label: '鍩硅鏂瑰紡',
+          prop: 'trainingMode',
+          width: '100px',
+        }, {
+          dataType: 'tag',
+          label: '璇剧▼鐘舵��',
+          width: '100px',
+          prop: 'state',
+          formatData: (params) => {
+            if (params == 1) {
+              return '宸插畬鎴�';
+            } else if (params == 2) {
+              return '寰呰瘎浠�';
+            } else if (params == 3) {
+              return '鏈紑濮�';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 1) {
+              return 'success';
+            } else if (params == 2) {
+              return 'warning';
+            } else if (params == 3) {
+              return 'primary';
+            } else if (params == 4) {
+              return 'info';
+            } else {
+              return null
+            }
+          }
+        }, {
+          label: '鍙傚姞瀵硅薄',
+          prop: 'participants',
+          width: '100px',
+        }, {
+          label: '涓惧姙閮ㄩ棬',
+          prop: 'holdingDepartment',
+          width: '100px',
+        }, {
+          label: '鍩硅璁插笀',
+          prop: 'trainingLecturerName',
+          width: '100px',
+        }, {
+          label: '鍩硅鏃ユ湡',
+          prop: 'trainingDate',
+          width: '100px',
+        }, {
+          label: '寮�濮嬫椂闂�',
+          prop: 'openingTime',
+          width: '100px',
+        }, {
+          label: '璇炬椂',
+          prop: 'classHour',
+          width: '100px',
+        }, {
+          label: '澶囨敞',
+          prop: 'remarks',
+          width: '100px',
+        }, {
+          dataType: 'action',
+          width: '200',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.addTrainingPlan('edit', row);
+              },
+            },
+            {
+              name: '缁撴灉鏄庣粏',
+              type: 'text',
+              clickFun: (row) => {
+                this.editInDetail(row);
+              },
+              showHide: () => {
+                if (this.isDepartment) {
+                  return true;
+                } else {
+                  return false;
+                }
+              }
+            },
+            {
+              name: '闄勪欢',
+              type: 'text',
+              clickFun: (row) => {
+                this.viewRecord(row);
+              },
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.downLoadInDetail(row);
+              }
+            },
+
+          ]
+        }],
+      page: {
+        total:0,
+        size:10,
+        current:1,
+        compilerName: ""
+      },
+      inDetailPagination: {
+        total:0,
+        size:10,
+        current:1,
+      },
+      editPlanShow: false,
+      currentRow: {},
+      currentRowId: null, // 褰撳墠閫変腑鏁版嵁鐨刬d
+      auditRemarks: '', // 瀹℃牳澶囨敞
+      reviewDialog: false, // 瀹℃牳寮规
+      reviewLoading: false, // 瀹℃牳鎻愪氦鎸夐挳
+      approvalRemarks: '', // 瀹℃牳澶囨敞
+      approvalDialog: false, // 瀹℃牳寮规
+      approvalLoading: false, // 瀹℃牳鎻愪氦鎸夐挳
+      multipleSelection: [], // 骞村害鏄庣粏琛ㄩ�変腑鐨勬暟鎹�
+      uploadDia: false,
+      uploading: false,
+      isOperation: false,
+      ViewRecord: false,
+      fileList: [],
+      currentChangeRow: {},
+      approverId: ''
+    };
+  },
+  mounted() {
+    if (this.isDepartment) {
+      this.getYearPlanList(this.departId)
+    } else {
+      this.getInDetailPlan('', this.departId)
+    }
+  },
+  methods: {
+    searchTable () {
+      this.getInDetailPlan(this.currentRowId)
+    },
+    // 鏌ヨ-骞村害璁″垝琛�
+    getYearPlanList(userId) {
+      this.yearLoading = true
+      const params = this.isDepartment ?
+      {
+        departmentId: userId,
+        size: this.page.size,
+        current: this.page.current,
+        compilerName: this.page.compilerName,
+      }: {
+          userId: userId,
+          size: this.page.size,
+          current: this.page.current,
+          compilerName: this.page.compilerName,
+        }
+      personTraining(params).then(res => {
+        this.yearLoading = false
+        this.yearPlanTableData = res.data.records;
+        this.pagination.total = res.data.total;
+        if (this.yearPlanTableData.length > 0) {
+          this.currentRowId = this.yearPlanTableData[0].id
+          this.currentChange(this.yearPlanTableData[0])
+        }
+      }).catch(err => {
+        this.yearLoading = false
+      })
+    },
+    pagination (page) {
+      this.page.size = page.limit
+      this.getYearPlanList()
+    },
+    currentChange (row) {
+      const now = new Date();
+      const currentYear = now.getFullYear();
+      if (row) {
+        this.currentChangeRow = row
+        this.currentRowId = row.id
+        if (row.createTime.slice(0,4) == currentYear) {
+          this.isOperation = true;
+        } else {
+          this.isOperation = false;
+        }
+        this.getInDetailPlan(row.id)
+      }
+    },
+    getInDetailPlan (id) {
+      if (this.inDetailForm.trainingDate === null) {
+        this.inDetailForm.trainingDate = ''
+      }
+      const userId = this.isDepartment ? '' : this.departId
+      const params =
+        {
+          userId: userId,
+          size: this.inDetailPagination.pageSize,
+          current: this.inDetailPagination.current,
+          id: id,
+          trainingLecturerName: this.inDetailForm.trainingLecturerName,
+          trainingDate: this.inDetailForm.trainingDate,
+        }
+      this.yearDetailLoading = true
+      queryTheAnnualPlanDetailsTable(params).then(res => {
+        this.yearDetailLoading = false
+        this.inDetailPlanTableData = res.data.records;
+        this.inDetailPagination.total = res.data.total;
+      }).catch(err => {
+        this.yearDetailLoading = false
+      })
+    },
+    pagination1 (page) {
+      this.inDetailPagination.size = page.limit
+      this.getInDetailPlan(this.currentRowId)
+    },
+    // 鏂板骞村害璁″垝鏄庣粏琛�
+    addTrainingPlan(type, row) {
+      if (!this.currentRowId) {
+        this.$message.warning('璇烽�夋嫨涓�鏉¤鍒掕繘琛屾柊澧�')
+        return
+      }
+      this.$refs.addPlan.showDialog(this.currentRowId, type, row);
+    },
+    // 骞村害璁″垝琛�-鍒犻櫎
+    deleteFun(id) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        personTrainingDelete({id: id}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛锛�');
+          this.getYearPlanList(this.departId);
+        });
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 骞村害璁″垝琛�-瀹℃牳
+    handleCheck(id) {
+      this.currentRowId = id
+      this.reviewDialog = true
+      this.getUserList()
+    },
+    // 鎻愪氦瀹℃牳
+    handleReview (status) {
+      const personTrainingUpdateDto = {
+        id: this.currentRowId,
+        auditRemarks: this.auditRemarks,
+        reviewerStatus: status,
+        approverId: this.approverId
+      }
+      this.reviewLoading = true
+      reviewAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.reviewDialog = false
+          this.getYearPlanList(this.departId);
+        }
+        this.reviewLoading = false
+      }).catch(() => {
+        this.reviewLoading = false
+      })
+    },
+    // 骞村害璁″垝琛�-鎵瑰噯
+    handleApprove(id) {
+      this.currentRowId = id
+      this.approvalDialog = true
+    },
+    // 鎻愪氦鎵瑰噯
+    handleApproval (status) {
+      const personTrainingUpdateDto = {
+        id: this.currentRowId,
+        approvalRemarks: this.approvalRemarks,
+        approvalStatus: status
+      }
+      this.approvalLoading = true
+      approveAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.getYearPlanList(this.departId);
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    // 骞村害璁″垝琛�-涓嬭浇
+    downLoadPost(row) {
+      exportPersonTraining({id: row.id}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, row.fileName + '.docx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 骞村害璁″垝-瀵煎叆
+    submitUpload() {
+      if (this.$refs.upload.uploadFiles.length == 0) {
+        this.$message.error('鏈�夋嫨鏂囦欢')
+        return
+      }
+      this.uploading = true
+      this.$refs.upload.submit();
+      this.uploading = false
+    },
+    onSuccess(response, file, fileList) {
+      this.$refs.upload.clearFiles()
+      this.uploadDia = false
+      this.uploading = false
+      if (response.code != 200) {
+        this.$message.error(response.msg)
+        return
+      }
+      this.$message.success('涓婁紶鎴愬姛')
+      this.standardList = []
+      this.productList = []
+      this.getYearPlanList(this.departId)
+    },
+    onError(err, file, fileList) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+      this.uploading = false
+    },
+    beforeUpload(file, fileList) {
+      if (file.type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
+        this.$message.error('涓婁紶鏂囦欢鏍煎紡涓嶆纭�');
+        this.$refs.upload.clearFiles()
+        return false;
+      }
+    },
+    // 骞村害璁″垝鏄庣粏琛�-缂栬緫
+    editInDetail(row) {
+      this.editPlanShow = true;
+      this.currentRow = row
+    },
+    //
+    goBack() {
+      this.editPlanShow = false;
+      this.getInDetailPlan(this.currentRowId)
+    },
+    viewRecord (row) {
+      this.ViewRecord = true
+      this.$nextTick(() => {
+        this.$refs.ViewRecord.openDia(row)
+      })
+    },
+    // 骞村害璁″垝鏄庣粏琛�-涓嬭浇
+    downLoadInDetail(row) {
+      exportPersonTrainingRecord({id: row.id}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, '浜哄憳鍩硅涓庤�冩牳璁板綍.docx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 骞村害璁″垝鏄庣粏琛�-澶氶��
+    handleSelectionChange(list) {
+      this.multipleSelection = list
+    },
+    // 骞村害鏄庣粏琛�-鍒犻櫎
+    batchDelete () {
+      if (this.multipleSelection.length > 0) {
+        let ids = []
+        this.multipleSelection.forEach(item => {
+          ids.push(item.id)
+        })
+        this.$confirm('鏄惁纭鍒犻櫎鎵�閫夋嫨鐨勬暟鎹�?', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          deleteAnnualPlanDetailTable({ids: ids.join(',')}).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鍒犻櫎鎴愬姛');
+              this.getInDetailPlan(this.currentRowId);
+            }
+          });
+        }).catch(() => {
+          this.$message.warning('鍙栨秷鍒犻櫎');
+        });
+      } else {
+        this.$message.warning('璇烽�夋嫨闇�瑕佸垹闄ょ殑鏁版嵁')
+      }
+    },
+    handleSizeChange(val) {
+      this.inDetailPagination.size = val;
+      this.getInDetailPlan(this.currentChangeRow.id)
+    },
+    handleCurrentChange(val) {
+      this.inDetailPagination.current = val;
+      this.getInDetailPlan(this.currentChangeRow.id)
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      selectUserCondition().then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      });
+    }
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    departId: {
+      handler(newId, oldId) {
+        if (this.isDepartment) {
+          this.getYearPlanList(newId);
+        } else {
+          this.getInDetailPlan('')
+        }
+      }
+    },
+    currentRowId: {
+      handler(newId, oldId) {
+        if (newId) {
+          console.log('newId', newId);
+          this.inDetailPagination.current = 1
+          this.getInDetailPlan(this.currentChangeRow.id)
+        }
+      }
+    }
+  }
+}
+</script>
+<style scoped>
+.flex_column {
+  display: flex;
+  height: 80vh;
+  flex-direction: column;
+  overflow: auto;
+  justify-content: space-between;
+}
+.search {
+  width: 150px;
+  margin: 0 16px;
+}
+.title {
+  position: relative;
+  font-size: 16px;
+  color: #333;
+  font-weight: 400;
+  padding-left: 10px;
+  margin-bottom: 10px;
+}
+
+.title::before {
+  position: absolute;
+  left: 0;
+  top: 4px;
+  content: '';
+  width: 4px;
+  height: 16px;
+  background-color: #3A7BFA;
+  border-radius: 2px;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue b/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue
new file mode 100644
index 0000000..40b2f82
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue
@@ -0,0 +1,344 @@
+<!-- 濂栨儵璁板綍 -->
+<template>
+  <div>
+    <div class="view">
+      <div style="display: flex;justify-content: space-between;">
+        <el-form :model="search" ref="page" size="small" :inline="true">
+          <el-form-item label="濮撳悕">
+            <el-input v-model="search.userName" clearable placeholder="璇疯緭鍏ュ叧閿瓧" size="small" style="width: 20vh;"></el-input>
+          </el-form-item>
+          <el-form-item label="濂栨儵鏃ユ湡">
+            <el-date-picker
+              v-model="search.searchTimeList"
+              :picker-options="pickerOptions"
+              align="right"
+              clearable
+              end-placeholder="缁撴潫鏃ユ湡"
+              format="yyyy-MM-dd"
+              range-separator="鑷�"
+              size="small"
+              start-placeholder="寮�濮嬫棩鏈�"
+              style="width: 100%"
+              type="daterange"
+              unlink-panels
+              value-format="yyyy-MM-dd 00:00:00">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button>
+          </el-form-item>
+        </el-form>
+        <div>
+          <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">瀵煎嚭</el-button>
+          <el-button size="small" type="primary" @click="addRow">鏂板</el-button>
+        </div>
+      </div>
+    </div>
+    <div class="table">
+      <el-table :data="tableData" v-loading="tableLoading" height="66.5vh" style="width: 100%">
+        <el-table-column label="搴忓彿" type="index" width="120">
+          <template v-slot="scope">
+            <span>{{ (search.current - 1) * search.size + scope.$index + 1 }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍛樺伐缂栧彿" min-width="180" prop="account">
+        </el-table-column>
+        <el-table-column label="濮撳悕" min-width="180" prop="userName">
+        </el-table-column>
+        <el-table-column label="濂栨儵绾у埆" min-width="180" prop="rewardPunishLevel">
+        </el-table-column>
+        <el-table-column label="濂栨儵鏃堕棿" min-width="180" prop="rewardPunishTime">
+        </el-table-column>
+        <el-table-column label="濂栨儵鍚嶇О" min-width="180" prop="rewardPunishName">
+        </el-table-column>
+        <el-table-column label="濂栨儵鍏蜂綋鍐呭" min-width="120" prop="rewardPunishContent">
+        </el-table-column>
+        <el-table-column label="濂栨儵鍗曚綅" min-width="180" prop="rewardPunishWorkUnit">
+        </el-table-column>
+        <el-table-column label="鍒涘缓浜�" min-width="180" prop="createUserName">
+        </el-table-column>
+        <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+          <template v-slot="scope">
+            <el-button size="small" type="text" @click="editForm(scope.row)">缂栬緫</el-button>
+            <el-button size="small" type="text" style="color: #f56c6c" @click="deleteRow(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination :current-page="1" :page-size="search.size"
+                     :page-sizes="[10, 20, 30, 50, 100]"
+                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
+                     background
+                     style="margin-top: 10px"
+                     @size-change="handleSizeChange"
+                     @current-change="handleCurrentChange">
+      </el-pagination>
+    </div>
+    <el-dialog
+      :visible.sync="dialogVisible"
+      title="濂栨儵璁板綍"
+      width="50%"
+      @open="getUserList">
+      <div style="height: 40vh">
+        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+          <el-col :span="12">
+            <el-form-item label="鍛樺伐缂栧彿">
+              <el-input v-model="form.account" disabled size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍛樺伐濮撳悕" prop="userId">
+              <el-select v-model="form.userId" placeholder="璇烽�夋嫨" size="small" style="width: 100%" value-key="id"
+                         @change="selectUserChange" :disabled="!isDepartment">
+                <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵绾у埆" prop="rewardPunishLevel">
+              <el-input v-model="form.rewardPunishLevel" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵鍚嶇О" prop="rewardPunishName">
+              <el-input v-model="form.rewardPunishName" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵鏃堕棿" prop="rewardPunishTime">
+              <el-date-picker
+                v-model="form.rewardPunishTime"
+                format="yyyy-MM-dd HH:mm:ss"
+                placeholder="閫夋嫨鏃ユ湡"
+                size="small"
+                style="width: 100%"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵鍗曚綅" prop="rewardPunishWorkUnit">
+              <el-input v-model="form.rewardPunishWorkUnit" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="濂栨儵鍐呭">
+              <el-input v-model="form.rewardPunishContent" :rows="2" size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="saveOrUpdate">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addOrUpdateRewardPunishment, deleteRewardPunishment,
+  rewardPunishmentExport,
+  rewardPunishmentPage
+} from "@/api/cnas/personal/personRewardPunishmentRecord";
+import {selectUserCondition} from "@/api/system/user";
+import {delCustomById} from "@/api/system/customer";
+
+export default {
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      tableData: [],
+      tableLoading: false,
+      search: {
+        size: 20,
+        current: 1,
+        total: 0,
+        userName: '',
+        searchTimeList: []
+      },
+      form: {},
+      dialogVisible: false,
+      outLoading: false,
+      pickerOptions: {
+        shortcuts: [{
+          text: '鏈�杩戜竴鍛�',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '鏈�杩戜竴涓湀',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '鏈�杩戜笁涓湀',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      rules: {
+        userId: [{
+          required: true, message: '璇烽�夋嫨鍛樺伐', trigger: 'change'
+        }],
+        rewardPunishLevel: [{
+          required: true, message: '璇疯緭鍏ュ鎯╃骇鍒�', trigger: 'blur'
+        }],
+        rewardPunishName: [{
+          required: true, message: '璇疯緭鍏ュ鎯╁悕绉�', trigger: 'blur'
+        }],
+        rewardPunishTime: [{
+          required: true, message: '璇疯緭鍏ュ鎯╂椂闂�', trigger: 'blur'
+        }],
+        rewardPunishWorkUnit: [{
+          required: true, message: '璇疯緭鍏ュ鎯╁崟浣�', trigger: 'blur'
+        }]
+      },
+      responsibleOptions: []
+    };
+  },
+  mounted() {
+    this.getPersonnelTraining(this.departId);
+  },
+  methods: {
+    handleSizeChange(val) {
+      this.search.size = val
+      this.getPersonnelTraining(this.departId);
+    },
+    handleCurrentChange(val) {
+      this.search.current = val
+      this.getPersonnelTraining(this.departId);
+    },
+    async getPersonnelTraining() {
+      const params = {
+        userId: this.isDepartment ? '' : this.departId,
+          departmentId: this.isDepartment ? this.departId : '',
+          current: this.search.curent,
+          size: this.search.size,
+          userName: this.search.userName,
+          startTime: this.search.searchTimeList && this.search.searchTimeList[0],
+          endTime: this.search.searchTimeList && this.search.searchTimeList[1],
+      }
+      this.tableLoading = true
+      rewardPunishmentPage(params).then(res => {
+        this.tableLoading = false
+        this.tableData = res.data.records
+        this.search.total = res.data.total
+      }).catch(err => {
+        this.tableLoading = false
+      })
+    },
+    addRow () {
+      this.dialogVisible = true
+      if (!this.isDepartment) {
+        this.form.userId = this.departId
+        this.selectUserChange(this.form.userId)
+      }
+    },
+    handleDown(){
+      this.outLoading = true
+      rewardPunishmentExport({
+        userId: this.isDepartment ? '' : this.departId,
+        departmentId: this.isDepartment ? this.departId : '',
+        userName: this.search.userName,
+        startTime: this.search.searchTimeList && this.search.searchTimeList[0],
+        endTime: this.search.searchTimeList && this.search.searchTimeList[1]
+      }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], {
+          type: 'application/force-download'
+        })
+        this.$download.saveAs(blob, '濂栨儵璁板綍.xlsx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      selectUserCondition().then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      });
+    },
+    selectUserChange(val) {
+      const index = this.responsibleOptions.findIndex(item => item.id === val)
+      if (index > -1) {
+        this.form.userName = this.responsibleOptions[index].name
+        this.form.account = this.responsibleOptions[index].account
+      }
+    },
+    // 鎵撳紑琛ㄥ崟寮规
+    editForm(row) {
+      this.dialogVisible = true
+      this.form = {...row};
+    },
+    // 鎻愪氦琛ㄥ崟鏁版嵁
+    saveOrUpdate() {
+      this.$refs.form.validate(async (valid) => {
+        if (valid) {
+          addOrUpdateRewardPunishment(this.form).then(res => {
+            this.dialogVisible = false
+            this.$message.success("鎿嶄綔鎴愬姛")
+            this.getPersonnelTraining(this.departId);
+          })
+        }
+      })
+    },
+    deleteRow(row) {
+      this.$confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      }).then(() => {
+        deleteRewardPunishment({id: row.id}).then(res => {
+          if (res.code === 500) {
+            return
+          }
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.getPersonnelTraining(this.departId);
+        }).catch(e => {
+          this.$message.error('鍒犻櫎澶辫触')
+        })
+      }).catch(() => {})
+
+    }
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    departId: {
+      handler(newId, oldId) {
+        this.getPersonnelTraining(newId);
+      }
+    },
+    dialogVisible(newVal) {
+      if (newVal === false) {
+        this.form = {}
+        this.$refs['form'].resetFields()
+      }
+    }
+  }
+};
+</script>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue b/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue
new file mode 100644
index 0000000..a2642b7
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue
@@ -0,0 +1,303 @@
+<!-- 鍩硅璁板綍 -->
+<template>
+  <div>
+    <div class="flex_table">
+      <div v-if="isDepartment" style="width: 49%">
+        <div class="title">
+          <span style="font-weight: bold">骞村害璁″垝</span>
+        </div>
+        <div style="display: flex;justify-content: space-between;">
+          <el-form :model="trainingPagination" ref="trainingPagination" size="small" :inline="true">
+            <el-form-item label="濮撳悕">
+              <el-input v-model="trainingPagination.userName" class="search" clearable placeholder="璇疯緭鍏�" size="small"></el-input>
+            </el-form-item>
+            <el-form-item>
+              <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button>
+            </el-form-item>
+          </el-form>
+        </div>
+        <lims-table :tableData="trainingTableData" :column="trainingColumn"
+                    ref="trainingTableData"
+                    :currentChange="currentChange" :highlightCurrentRow="true"
+                    @pagination="pagination" :height="'calc(100vh - 22em)'"
+                    :page="trainingPagination" :tableLoading="trainingLoading"></lims-table>
+      </div>
+      <div :style="`width: ${isDepartment ? '49%' : '100%'};`">
+        <div class="title">
+          <span style="font-weight: bold">骞村害璁″垝鏄庣粏</span>
+        </div>
+        <div style="display: flex;justify-content: space-between;">
+          <el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
+            <el-form-item label="骞翠唤">
+              <el-date-picker
+                v-model="searchForm.trainingDate"
+                clearable
+                format="yyyy"
+                placeholder="閫夋嫨骞�"
+                size="small"
+                type="year"
+                value-format="yyyy">
+              </el-date-picker>
+            </el-form-item>
+            <el-form-item>
+              <el-button size="small" type="primary" @click="queryPersonnelDetailsPage(currentChangeRow.userId)">鏌ヨ</el-button>
+            </el-form-item>
+          </el-form>
+          <div>
+            <el-button size="small" type="primary" @click="openDownloadDia(currentChangeRow)">瀵煎嚭</el-button>
+          </div>
+        </div>
+        <lims-table :tableData="trainingPersonTableData" :column="trainingPersonColumn"
+                    :height="'calc(100vh - 22em)'" @pagination="pagination1"
+                    :page="trainingPersonPagination" :tableLoading="trainingPersonLoading"></lims-table>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+
+import limsTable from "@/components/Table/lims-table.vue";
+import {
+  exportTrainingRecord,
+  queryPersonnelDetails,
+  trainingSelectTrainingRecord
+} from "@/api/cnas/personal/personTrainingRecord";
+
+export default {
+  components: {limsTable},
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      outLoading: false,
+      trainingForm: {},
+      trainingColumn: [
+        {
+          label: '鍛樺伐缂栧彿',
+          prop: 'account',
+          width: '100'
+        }, {
+          label: '濮撳悕',
+          prop: 'name'
+        }, {
+          label: '鎵�鍦ㄩ儴闂�',
+          prop: 'departLimsName',
+          width: '150'
+        }, {
+          label: '鑱岀О',
+          prop: 'professionalTitle'
+        }, {
+          label: '鏈�楂樺鍘�',
+          prop: 'officialAcademicRedentials',
+          width: '100'
+        }, {
+          label: '鍏ュ崟浣嶆椂闂�',
+          prop: 'unitTime',
+          width: '150'
+        },
+        // {
+        //   fixed: 'right',
+        //   dataType: 'action',
+        //   width: 80,
+        //   label: '鎿嶄綔',
+        //   operation: [
+        //     {
+        //       name: '瀵煎嚭',
+        //       type: 'text',
+        //       clickFun: (row) => {
+        //         this.openDownloadDia(row)
+        //       }
+        //     }
+        //   ]
+        // }
+      ],
+      trainingTableData: [],
+      trainingLoading: false,
+      trainingPagination: {
+        size: 20,
+        total: 0,
+        current: 1,
+        userName: null
+      },
+      searchForm: {
+        trainingDate: ''
+      },
+      trainingPersonColumn: [
+        {
+          label: '鍩硅鏃ユ湡',
+          prop: 'trainingDate'
+        }, {
+          label: '鍩硅鍐呭',
+          prop: 'trainingContent'
+        }, {
+          label: '鍩硅璇炬椂',
+          prop: 'educationBackground'
+        }, {
+          label: '璇炬椂',
+          prop: 'classHour'
+        }, {
+          label: '鍩硅缁撴灉',
+          prop: 'examinationResults',
+        }, {
+          label: '澶囨敞',
+          prop: 'remarks'
+        }
+      ],
+      trainingPersonTableData: [],
+      trainingPersonLoading: false,
+      trainingPersonPagination: {
+        size: 20,
+        current: 1,
+        total: 0
+      },
+      currentChangeRow: '',
+    };
+  },
+  mounted() {
+    this.getPersonnelTraining(this.departId);
+  },
+  methods: {
+    // exportExcel() {
+    //   this.outLoading = true;
+    //   const name = this.isDepartment ? 'departmentId' : 'userId';
+    //   this.$axios.get(this.$api.personal.personTrackRecordExport + `&${name}=` + this.departId, { responseType: 'blob' }).then(res => {
+    //     this.outLoading = false;
+    //     this.$message.success('瀵煎嚭鎴愬姛');
+    //     const blob = new Blob([res], { type: 'application/octet-stream' });
+    //     const url = URL.createObjectURL(blob);
+    //     const link = document.createElement('a');
+    //     link.href = url;
+    //     link.download = '鍩硅璁板綍.xlsx';
+    //     link.click();
+    //   }).catch(err => {
+    //     this.outLoading = false;
+    //   })
+    // },
+    // 鏌ヨ
+    refreshTable() {
+      this.getPersonnelTraining(this.departId);
+    },
+    // 鍩硅璁板綍瀵煎嚭
+    openDownloadDia (row) {
+      let date = this.searchForm.trainingDate
+      if (!date) {
+        date = this.$moment().format('YYYY')
+      }
+      exportTrainingRecord({userId: row.userId, trainingDate: date}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, '鍩硅璁板綍瀵煎嚭.docx');
+      })
+    },
+    // 鑾峰彇瀹為獙瀹�-鍩硅璁″垝鍒楄〃淇℃伅
+    getPersonnelTraining(departId) {
+      const params = {
+        departmentId: departId,
+        size: this.trainingPagination.size,
+        current: this.trainingPagination.current,
+        userName: this.trainingPagination.userName,
+      }
+      this.trainingLoading = true
+      trainingSelectTrainingRecord(params).then(res => {
+        this.trainingLoading = false
+        this.trainingTableData = res.data.records;
+        this.trainingPagination.total = res.data.total;
+        if (this.trainingTableData.length > 0) {
+          this.$refs.trainingTableData.setCurrentRow(this.trainingTableData[0])
+        }
+      }).catch(err => {
+        this.trainingLoading = false
+      })
+    },
+    // 鑾峰彇涓汉-鍩硅璁″垝鍒楄〃淇℃伅
+    currentChange(row) {
+      this.currentChangeRow = row
+      if (row === null) {
+        row = this.trainingTableData[0]
+      }
+      this.queryPersonnelDetailsPage(row.userId)
+    },
+    queryPersonnelDetailsPage(userId) {
+      if (this.searchForm.trainingDate === null) {
+        this.searchForm.trainingDate = ''
+      }
+      const params = {
+        userId: userId,
+        size: this.trainingPersonPagination.size,
+        current: this.trainingPersonPagination.current,
+        trainingDate: this.searchForm.trainingDate,
+      }
+      this.trainingPersonLoading = true
+      queryPersonnelDetails(params).then(res => {
+        this.trainingPersonLoading = false
+        this.trainingPersonTableData = res.data.records;
+        this.trainingPersonPagination.total = res.data.total;
+      }).catch(err => {
+        this.trainingPersonLoading = false
+      })
+    },
+    // 鍒嗛〉
+    pagination(page) {
+      this.trainingPagination.size = page.limit;
+      this.getPersonnelTraining(this.departId);
+    },
+    // 鍒嗛〉
+    pagination1(page) {
+      this.trainingPersonPagination.size = page.limit;
+      this.queryPersonnelDetailsPage(this.currentChangeRow.userId);
+    },
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (this.isDepartment) {
+          this.getPersonnelTraining(newId);
+        } else {
+          this.queryPersonnelDetailsPage(newId)
+        }
+      }
+    }
+  }
+};
+</script>
+<style scoped>
+.flex_table {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+}
+
+.search {
+  width: 150px;
+}
+.title {
+  position: relative;
+  font-size: 16px;
+  color: #333;
+  font-weight: 400;
+  padding-left: 10px;
+  margin-bottom: 10px;
+}
+
+.title::before {
+  position: absolute;
+  left: 0;
+  top: 4px;
+  content: '';
+  width: 4px;
+  height: 16px;
+  background-color: #3A7BFA;
+  border-radius: 2px;
+}
+</style>
diff --git a/src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue b/src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue
new file mode 100644
index 0000000..797a81c
--- /dev/null
+++ b/src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue
@@ -0,0 +1,138 @@
+<template>
+  <div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="viewDeviceDialog" title="鏌ョ湅璁惧" width="80%" @close="closeDia">
+      <div style="text-align: right;margin-bottom: 10px">
+        <el-button size="small" type="primary" @click="addRow">娣诲姞</el-button>
+        <el-button size="small" type="danger" @click="clearTable">娓呯┖</el-button>
+      </div>
+      <div>
+        <el-table :data="machineAttachmentList" border height="500" style="width: 100%">
+          <el-table-column header-align="center" label="鍚嶇О" prop="machineName" width="200">
+            <template slot="header" slot-scope="scope">
+              <p>鍚嶇О</p>
+            </template>
+            <template slot-scope="scope">
+              <el-select v-model="scope.row.machineName"
+                         class="table_input"
+                         clearable
+                         filterable
+                         placeholder="璁惧鍚嶇О"
+                         size="small" @change="(val)=>changeMachineName(val, scope.$index)">
+                <el-option v-for="item in equipOptions" :key="item.value"  :label="item.label" :value="item.value">
+                  {{item.label + item.value}}
+                </el-option>
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column header-align="center" label="鍨嬪彿瑙勬牸" prop="machineSpecification" width="180">
+            <template slot="header" slot-scope="scope">
+              <p>鍨嬪彿瑙勬牸</p>
+            </template>
+            <template slot-scope="{row}">
+              <el-input v-model="row.machineSpecification" size="small"/>
+            </template>
+          </el-table-column>
+          <el-table-column header-align="center" label="娴嬮噺鑼冨洿" prop="machineMeasuringRange">
+            <template slot="header" slot-scope="scope">
+              <p>娴嬮噺鑼冨洿</p>
+            </template>
+            <template slot-scope="{row}">
+              <el-input v-model="row.machineMeasuringRange" size="small" type="textarea"/>
+            </template>
+          </el-table-column>
+          <el-table-column header-align="center" label="鈶犳墿灞曚笉纭畾搴︹憽鏈�澶у厑宸憿鍑嗙‘搴︾瓑绾�" prop="other">
+            <template slot="header" slot-scope="scope">
+              <p>鈶犳墿灞曚笉纭畾搴︹憽鏈�澶у厑宸憿鍑嗙‘搴︾瓑绾�</p>
+            </template>
+            <template slot-scope="{row}">
+              <el-input v-model="row.other" size="small" type="textarea"/>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeDia">鍙� 娑�</el-button>
+        <el-button type="primary" @click="handleDeviceInfo">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { deviceScopeSearch } from '@/api/cnas/process/method/standardMethodsChange'
+
+export default {
+  name: 'ViewDeviceDialog',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      viewDeviceDialog: false,
+      machineAttachmentList: [],
+      equipOptions: [],
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(info) {
+      this.viewDeviceDialog = true
+      this.machineAttachmentList = info.machineAttachmentList
+      this.getEquipOptions()
+    },
+    // 澧炲姞琛ㄦ牸琛屾暟鎹�
+    addRow () {
+      this.machineAttachmentList.push({
+        machineName: '',
+        machineSpecification: '',
+        machineMeasuringRange: '',
+        other: '',
+      })
+    },
+    // 娓呯┖琛ㄦ牸鏁版嵁
+    clearTable () {
+      this.machineAttachmentList = []
+    },
+    // 閫夋嫨璁惧鐨勫洖璋�
+    changeMachineName (val, index) {
+      const index1 = this.equipOptions.findIndex(item => item.value === val);
+      if (index1 !== -1) {
+        this.machineAttachmentList[index].deviceId = this.equipOptions[index1].id;
+        this.machineAttachmentList[index].machineName = this.equipOptions[index1].deviceName;
+      }
+      this.machineAttachmentList[index].machineSpecification = val
+    },
+    // 鎻愪氦璁惧淇℃伅
+    handleDeviceInfo () {
+      if (this.machineAttachmentList.length === 0) {
+        this.$message.warning('璇锋坊鍔犱俊鎭�')
+        return
+      }
+      this.viewDeviceDialog = false
+      this.$emit('handleDeviceInfo', this.machineAttachmentList)
+    },
+    closeDia () {
+      this.viewDeviceDialog = false
+      this.$emit('closDeviceDia')
+    },
+    // 鑾峰彇鎵�鏈夎澶�
+    getEquipOptions() {
+      this.equipOptions = []
+      deviceScopeSearch({status:'0'}).then(res => {
+        if (res.code === 200 && res.data) {
+          this.equipOptions = res.data.map(m => {
+            m.value = m.managementNumber
+            m.label = m.deviceName
+            return m
+          })
+        }
+      }).catch(error => {
+        console.error(error)
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+</style>
diff --git a/src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue b/src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue
new file mode 100644
index 0000000..e8cd69d
--- /dev/null
+++ b/src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue
@@ -0,0 +1,172 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="filesDialogVisible" title="闄勪欢涓婁紶" width="80%" @closed="closeFilesLook">
+      <div style="display: flex;justify-content: space-between;">
+        <el-upload ref='upload'
+                   :action="fileAction"
+                   :auto-upload="true"
+                   :before-upload="fileBeforeUpload" :data="{methodVerifyId: info.methodVerifyId}"
+                   :headers="uploadHeader"
+                   :on-error="onError"
+                   :on-success="handleSuccessUp"
+                   :show-file-list="false"
+                   accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
+          <el-button size="small" style="height: 38px" type="primary">闄勪欢涓婁紶</el-button>
+        </el-upload>
+      </div>
+      <div>
+        <lims-table
+          ref="yearTable"
+          :column="columnData"
+          :height="'calc(100vh - 47em)'"
+          :highlightCurrentRow="true"
+          :table-data="tableData"
+          :table-loading="tableLoading"
+          style="margin-top: 0.5em;">
+        </lims-table>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import limsTable from '@/components/Table/lims-table.vue'
+import file from "@/utils/file";
+import { delVerifyMethodFileList, getVerifyMethodFileList } from '@/api/cnas/process/method/standardMethodsChange'
+
+export default {
+  name: 'ViewTestRecord',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      filesDialogVisible: false,
+      tableLoading: false,
+      filesLookInfo: {},
+      columnData: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.upload(row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delete(row)
+              }
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      info: {}
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.filesDialogVisible = true
+      this.info = row
+      if (this.info === undefined) {
+        this.info = {
+          methodVerifyId: ''
+        }
+      }
+      this.searchTableList()
+    },
+    // 鏌ヨ闄勪欢鍒楄〃
+    searchTableList () {
+      this.tableLoading = true
+      getVerifyMethodFileList({methodVerifyId:this.info.methodVerifyId}).then(res => {
+        this.tableLoading = false
+        if (res.code === 200){
+          this.tableData = res.data
+        }
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    closeFilesLook () {
+      this.filesDialogVisible = false
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        file.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+    // 鍒犻櫎
+    delete (row) {
+      this.tableLoading = true
+      delVerifyMethodFileList({methodFileId:row.methodFileId}).then(res => {
+        this.tableLoading = false
+        if (res.code === 200){
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchTableList()
+        }
+
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    // 涓婁紶楠岃瘉
+    fileBeforeUpload(file) {
+      let flag = true
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        flag = false
+      }
+      if (!flag) {
+        return Promise.reject(flag); //姝g‘鐨勭粓姝�
+      }
+    },
+    onError(err, file, fileList,type) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+    },
+    handleSuccessUp(response, ) {
+      this.upLoading = false;
+      if (response.code == 200) {
+        this.$message.success('涓婁紶鎴愬姛');
+        this.searchTableList()
+      }
+    },
+  },
+  computed: {
+    fileAction() {
+      return this.javaApi + '/processMethodVerify/uploadVerifyMethodFile'
+
+    }
+  },
+};
+</script>
+
+<style scoped>
+</style>
diff --git a/src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue b/src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue
new file mode 100644
index 0000000..0f43503
--- /dev/null
+++ b/src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue
@@ -0,0 +1,123 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="filesDialogVisible" title="鏌ョ湅鏍″噯璇佷功" width="80%" @closed="closeFilesLook">
+      <div>
+        <limsTable
+          ref="yearTable"
+          :column="columnData"
+          :height="'calc(100vh - 47em)'"
+          :highlightCurrentRow="true"
+          :table-data="tableData"
+          :table-loading="tableLoading"
+          style="margin-top: 0.5em;">
+        </limsTable>
+      </div>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="lookDialogVisible"
+      fullscreen
+      title="鏌ョ湅闄勪欢" top="5vh" width="800px">
+      <filePreview v-if="lookDialogVisible" :currentFile="{}"
+                   :fileUrl="javaApi+'/img/'+currentInfo.fileUrl" style="max-height: 90vh;overflow-y: auto;"/>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import filePreview from '@/views/tool/file-preview.vue';
+import limsTable from '@/components/Table/lims-table.vue'
+import file from '@/utils/file';
+
+export default {
+  name: 'calibrationsFileDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { limsTable, filePreview },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      filesDialogVisible: false,
+      tableLoading: false,
+      filesLookInfo: {},
+      columnData: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '150px'
+        },
+        {
+          label: '璁惧鍚嶇О',
+          prop: 'deviceName',
+          minWidth: '150px'
+        },
+        {
+          label: '璁惧缂栧彿',
+          prop: 'managementNumber',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '棰勮',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleLook(row)
+              }
+            },
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.upload(row)
+              }
+            },
+          ]
+        }
+      ],
+      tableData: [],
+      info: {},
+      currentInfo:{},
+      lookDialogVisible: false,
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.filesDialogVisible = true
+      this.info = row
+      this.tableData = this.info.calibrationsFileList
+    },
+    closeFilesLook () {
+      this.filesDialogVisible = false
+    },
+    // 鏌ョ湅鏂囦欢
+    handleLook(row){
+      this.currentInfo = row
+      this.lookDialogVisible = true
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        file.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+  }
+};
+</script>
+
+<style scoped>
+</style>
diff --git a/src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue b/src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue
new file mode 100644
index 0000000..a63023a
--- /dev/null
+++ b/src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue
@@ -0,0 +1,456 @@
+<template>
+  <div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false"
+               :title="operationType === 'edit' ? '缂栬緫' : '鏂板'"
+               :visible.sync="formDia"
+               width="90%" @close="closeDia">
+      <div v-if="operationType === 'edit'" style="text-align: right">
+        <el-button :disabled="form.confirmDate !== '' && form.confirmDate !== null && form.confirmDate !== undefined" size="medium" type="primary" @click="validation">楠岃瘉纭</el-button>
+      </div>
+      <table border="1" cellspacing="10" class="tables">
+        <tr>
+          <td>
+            <p>鏍囧噯鏂规硶</p>
+          </td>
+          <td>
+            <p>楠岃瘉鍘熷洜</p>
+          </td>
+          <td>
+            <p>涓昏鎶�鏈彉鍖�</p>
+          </td>
+          <td>
+            <p>娑夊強鏂归潰</p>
+          </td>
+          <td>
+            <p>鏍囧噯瑕佹眰</p>
+          </td>
+          <td>
+            <p>鍑嗗鎯呭喌</p>
+          </td>
+          <td>
+            <p>鏄惁婊¤冻</p>
+          </td>
+          <td>
+            <p>澶囨敞</p>
+          </td>
+        </tr>
+        <tr>
+          <td rowspan="9">
+            <el-input v-model="form.methodName" :rows="6"
+                      placeholder="璇疯緭鍏ュ唴瀹�"
+                      size="small"
+                      type="textarea">
+            </el-input>
+          </td>
+          <td rowspan="9">
+            <el-input v-model="form.verifyReason" :rows="6"
+                      placeholder="璇疯緭鍏ュ唴瀹�"
+                      size="small"
+                      type="textarea">
+            </el-input>
+          </td>
+          <td rowspan="9">
+            <el-input v-model="form.technologyChange" :rows="6"
+                      placeholder="璇疯緭鍏ュ唴瀹�"
+                      size="small"
+                      type="textarea">
+            </el-input>
+          </td>
+        </tr>
+        <tr>
+          <td>浜猴細</td>
+          <td>
+            <el-input v-model="form.personRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.personReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.personIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-link type="primary" @click="viewWorkPermit">鏌ョ湅涓婂矖璇�</el-link>
+          </td>
+        </tr>
+        <tr>
+          <td>鏈猴細</td>
+          <td>
+            <el-input v-model="form.machineRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.machineReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.machineIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-link type="primary" @click="viewDevice">鏌ョ湅璁惧</el-link>
+          </td>
+        </tr>
+        <tr>
+          <td>鏂欙細</td>
+          <td>
+            <el-input v-model="form.materialRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.materialReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.materialIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-input v-model="form.materialRemark" size="small"></el-input>
+          </td>
+        </tr>
+        <tr>
+          <td>娉曪細</td>
+          <td>
+            <el-input v-model="form.methodRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.methodReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.methodIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-link type="primary" @click="viewTestRecord">鏌ョ湅妫�娴嬭褰�</el-link>
+          </td>
+        </tr>
+        <tr>
+          <td>鐜細</td>
+          <td>
+            <el-input v-model="form.environmentRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.environmentReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.environmentIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-input v-model="form.traceabilityRemark" size="small"></el-input>
+          </td>
+        </tr>
+        <tr>
+          <td>娴嬮噺婧簮鎬э細</td>
+          <td>
+            <el-input v-model="form.traceabilityRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.traceabilityReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.traceabilityIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-link type="primary" @click="viewCalibrationsFileDia">鏌ョ湅鏍″噯璇佷功</el-link>
+          </td>
+        </tr>
+        <tr>
+          <td>鏍峰搧绠$悊闇�姹傦細</td>
+          <td>
+            <el-input v-model="form.managementRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.managementReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.managementIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-input v-model="form.managementRemark" size="small"></el-input>
+          </td>
+        </tr>
+        <tr>
+          <td>鍏朵粬锛�</td>
+          <td>
+            <el-input v-model="form.otherRequirements" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-input v-model="form.otherReadiness" size="small" type="textarea"></el-input>
+          </td>
+          <td>
+            <el-radio-group v-model="form.otherIsSatisfied" v-removeAriaHidden>
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </td>
+          <td>
+            <el-input v-model="form.otherRemark" size="small"></el-input>
+          </td>
+        </tr>
+        <tr>
+          <td colspan="3">
+            <p>鏄惁寮曠敤姝ゆ爣鍑嗗紑灞曟娴�:</p>
+          </td>
+          <td colspan="3">鍙互寮曠敤姝ゆ爣鍑嗗紑灞曟娴�</td>
+          <td>
+            <p>纭鏃堕棿:</p>
+          </td>
+          <td>{{form.confirmDate}}</td>
+        </tr>
+        <tr>
+          <td colspan="3">
+            <p>鍙傚姞纭浜虹鍚�:</p>
+          </td>
+          <td colspan="5">
+            <el-select v-model="form.confirmUser" multiple placeholder="璇烽�夋嫨" size="small" style="width: 100%" :multiple-limit="5">
+              <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+            </el-select>
+          </td>
+        </tr>
+      </table>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeDia">鍙� 娑�</el-button>
+        <el-button :loading="editLoad" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+    <ViewDeviceDialog v-if="viewDeviceDialog" ref="viewDeviceDialog" @closDeviceDia="closDeviceDia" @handleDeviceInfo="handleDeviceInfo"></ViewDeviceDialog>
+    <ViewTestRecord v-if="viewTestRecordDialog" ref="viewTestRecordDialog"></ViewTestRecord>
+    <ViewWorkPermitDia v-if="viewWorkPermitDia" ref="viewWorkPermitDia"></ViewWorkPermitDia>
+    <calibrations-file-dia v-if="calibrationsFileDia" ref="calibrationsFileDia"></calibrations-file-dia>
+  </div>
+</template>
+
+<script>
+import { dateFormat } from '@/utils/date'
+import ViewTestRecord from '../component/ViewTestRecord.vue';
+import ViewDeviceDialog from '../component/ViewDeviceDialog.vue';
+import ViewWorkPermitDia from '../component/viewWorkPermitDia.vue';
+import CalibrationsFileDia from '../component/calibrationsFileDia.vue';
+import {
+  addMethodVerify, deviceScopeSearch,
+  getMethodVerifyOne,
+  selectUserCondition,
+  updateMethodVerify
+} from '@/api/cnas/process/method/standardMethodsChange'
+
+export default {
+  name: 'formDIaChange',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { CalibrationsFileDia, ViewWorkPermitDia, ViewDeviceDialog, ViewTestRecord },
+  props: {
+    operationType: {
+      type: String,
+      default: () => ''
+    }
+  },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      form: {
+        methodName: '',
+        verifyReason: '',
+        technologyChange: '',
+        personRequirements: '',
+        personReadiness: '',
+        personIsSatisfied: '',
+        personRemark: '',
+        machineRequirements: '',
+        machineReadiness: '',
+        machineIsSatisfied: '',
+        materialRequirements: '',
+        materialReadiness: '',
+        materialIsSatisfied: '',
+        materialRemark: '',
+        methodRequirements: '',
+        methodReadiness: '',
+        methodIsSatisfied: '',
+        environmentRequirements: '',
+        environmentReadiness: '',
+        environmentIsSatisfied: '',
+        traceabilityRequirements: '',
+        traceabilityReadiness: '',
+        traceabilityIsSatisfied: '',
+        traceabilityRemark: '',
+        managementRequirements: '',
+        managementReadiness: '',
+        managementIsSatisfied: '',
+        managementRemark: '',
+        otherRequirements: '',
+        otherReadiness: '',
+        otherIsSatisfied: '',
+        otherRemark: '',
+        machineAttachmentList: []
+      },
+      editLoad: false,
+      info: {
+        methodVerifyId: ''
+      },
+      userList: [],
+      viewDeviceDialog: false,
+      viewTestRecordDialog: false,
+      viewWorkPermitDia: false,
+      calibrationsFileDia: false,
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.formDia = true
+      this.info = row
+      this.getUserList()
+      if (this.operationType === 'edit') {
+        this.searchInfo(row)
+      }
+    },
+    // 鏌ヨ璇︽儏淇℃伅
+    searchInfo (row) {
+      getMethodVerifyOne({methodVerifyId:row.methodVerifyId}).then(res => {
+        if (res.code === 200) {
+          this.form = {...res.data}
+          if (this.form.confirmUser) {
+            this.form.confirmUser = this.form.confirmUser.split(',').map(Number)
+          }
+        }
+      }).catch(err => {
+        console.log('err---', err);
+      })
+    },
+    // 鎻愪氦
+    handleEdit() {
+      this.editLoad = true
+      const processMethodSearchNews = this.HaveJson(this.form)
+      processMethodSearchNews.confirmUser = processMethodSearchNews.confirmUser && processMethodSearchNews.confirmUser.join(',')
+      processMethodSearchNews.operationType = 0
+      if (this.operationType === 'edit') {
+        this.editInfo(processMethodSearchNews)
+      } else {
+        this.addInfo(processMethodSearchNews)
+      }
+    },
+    // 鏌ョ湅涓婂矖璇�
+    viewWorkPermit () {
+      this.viewWorkPermitDia = true
+      this.$nextTick(() => {
+        this.$refs.viewWorkPermitDia.openDia(this.form)
+      })
+    },
+    // 鏌ョ湅鏍″噯璇佷功
+    viewCalibrationsFileDia () {
+      this.calibrationsFileDia = true
+      this.$nextTick(() => {
+        this.$refs.calibrationsFileDia.openDia(this.form)
+      })
+    },
+    // 鏌ョ湅璁惧
+    viewDevice () {
+      this.viewDeviceDialog = true
+      this.$nextTick(() => {
+        this.$refs.viewDeviceDialog.openDia(this.form)
+      })
+    },
+    // 鍏抽棴璁惧寮规
+    closDeviceDia () {
+      this.viewDeviceDialog = false
+    },
+    // 鎻愪氦璁惧淇℃伅
+    handleDeviceInfo (machineAttachmentList) {
+      this.viewDeviceDialog = false
+      this.form.machineAttachmentList = machineAttachmentList
+    },
+    // 鏌ョ湅妫�娴嬭褰�
+    viewTestRecord () {
+      this.viewTestRecordDialog = true
+      this.$nextTick(() => {
+        this.$refs.viewTestRecordDialog.openDia(this.info)
+      })
+    },
+    // 鎻愪氦缂栬緫
+    editInfo (processMethodSearchNews) {
+      updateMethodVerify(processMethodSearchNews).then(res => {
+        this.editLoad = false
+        if (res.code === 200){
+          this.$message.success('鎿嶄綔鎴愬姛')
+          this.closeDia()
+        }
+      }).catch(err => {
+        console.log('err---', err);
+        this.editLoad = false
+      })
+    },
+    // 鎻愪氦鏂板
+    addInfo (processMethodSearchNews) {
+      addMethodVerify(processMethodSearchNews).then(res => {
+        this.editLoad = false
+        if (res.code === 200) {
+          this.$message.success('鎿嶄綔鎴愬姛')
+          this.closeDia()
+        }
+      }).catch(err => {
+        console.log('err---', err);
+        this.editLoad = false
+      })
+    },
+    // 楠岃瘉纭
+    validation () {
+      deviceScopeSearch({methodVerifyId:this.info.methodVerifyId}).then(res => {
+        if (res.code === 200){
+          this.form.confirmDate = dateFormat(new Date())
+        }
+      }).catch(err => {
+        console.log('err---', err);
+      })
+    },
+    // 鍏抽棴寮规
+    closeDia() {
+      this.formDia = false
+      this.$emit('closeDia');
+    },
+    getUserList(){
+      selectUserCondition().then(res => {
+        if (res.code === 200) {
+          this.userList = res.data
+        }
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin-top: 2vh !important;
+}
+>>>.el-dialog__body {
+  max-height: 720px;
+  overflow-y: auto;
+}
+.tables {
+  table-layout: fixed;
+  width: 100%;
+  margin-top: 10px;
+}
+.tables td {
+  height: 34px;
+  width: 100px;
+  text-align: center;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+  padding: 4px;
+}
+</style>
diff --git a/src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue b/src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue
new file mode 100644
index 0000000..0d8f468
--- /dev/null
+++ b/src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue
@@ -0,0 +1,118 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="filesDialogVisible" title="鏌ョ湅涓婂矖璇�" width="80%" @closed="closeFilesLook">
+      <div>
+        <limsTable
+          ref="yearTable"
+          :column="columnData"
+          :height="'calc(100vh - 400px)'"
+          :highlightCurrentRow="true"
+          :table-data="tableData"
+          :table-loading="tableLoading"
+          style="margin-top: 0.5em;">
+        </limsTable>
+      </div>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="lookDialogVisible"
+      fullscreen
+      title="鏌ョ湅闄勪欢" top="5vh" width="800px">
+      <filePreview v-if="lookDialogVisible" :currentFile="{}"
+                   :fileUrl="javaApi+'/img/'+currentInfo.fileUrl" style="max-height: 90vh;overflow-y: auto;"/>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import file from '@/utils/file';
+import filePreview from '@/views/tool/file-preview.vue';
+import limsTable from '@/components/Table/lims-table.vue'
+
+export default {
+  name: 'viewWorkPermitDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { filePreview, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      filesDialogVisible: false,
+      tableLoading: false,
+      filesLookInfo: {},
+      columnData: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '150px'
+        },
+        {
+          label: '鎸佹湁浜�',
+          prop: 'userName',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '棰勮',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleLook(row)
+              }
+            },
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.upload(row)
+              }
+            },
+          ]
+        }
+      ],
+      tableData: [],
+      info: {},
+      currentInfo:{},
+      lookDialogVisible: false,
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.filesDialogVisible = true
+      this.info = row
+      this.tableData = this.info.workFileList
+    },
+    closeFilesLook () {
+      this.filesDialogVisible = false
+    },
+    // 鏌ョ湅鏂囦欢
+    handleLook(row){
+      this.currentInfo = row
+      this.lookDialogVisible = true
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        file.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+  },
+};
+</script>
+
+<style scoped>
+</style>
diff --git a/src/views/CNAS/process/method/standardMethodsChange/index.vue b/src/views/CNAS/process/method/standardMethodsChange/index.vue
new file mode 100644
index 0000000..9a4ac26
--- /dev/null
+++ b/src/views/CNAS/process/method/standardMethodsChange/index.vue
@@ -0,0 +1,201 @@
+<template>
+  <div class="capacity-scope">
+    <div class="search">
+      <div>
+        <el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
+          <el-form-item label="鏍囧噯鏂规硶" prop="methodName">
+            <el-input size="small" placeholder="璇疯緭鍏�" clearable v-model="searchForm.methodName"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="el-icon-search" size="mini" @click="searchList">鏌� 璇�</el-button>
+            <el-button icon="el-icon-refresh" size="mini" @click="resetSearchForm">閲� 缃�</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div>
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </div>
+    </div>
+    <div class="table">
+      <div>
+        <TableCard :showForm="false" :showTitle="false">
+          <template v-slot:table>
+            <lims-table :tableData="tableData" :column="tableColumn" :height="'calc(100vh - 250px)'" @pagination="pagination"
+                        :page="page" :tableLoading="tableLoading"></lims-table>
+          </template>
+        </TableCard>
+      </div>
+    </div>
+    <formDIaChange v-if="formDIa" ref="formDIa" :operationType="operationType" @closeDia="closeDia"></formDIaChange>
+  </div>
+</template>
+
+<script>
+import TableCard from '@/views/CNAS/externalService/serviceAndSupplyPro/component/index.vue';
+import formDIaChange from './component/formDIaChange.vue';
+import limsTable from '@/components/Table/lims-table.vue'
+import {
+  delMethodVerify,
+  exportMethodVerify,
+  pagesMethodVerify
+} from '@/api/cnas/process/method/standardMethodsChange'
+
+export default {
+  name: 'a7-changes-standard-methods',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { limsTable, formDIaChange, TableCard },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        methodName: '',
+        operationType: 0,
+      },
+      options: [
+        { label: '涓婂崐骞�', value: '1' },
+        { label: '涓嬪崐骞�', value: '2' },
+      ],
+      tableColumn: [
+        {
+          label: '鏍囧噯鏂规硶',
+          prop: 'methodName',
+          minWidth: '100'
+        },
+        {
+          label: '楠岃瘉鍘熷洜',
+          prop: 'verifyReason',
+          minWidth: '100'
+        },
+        {
+          label: '涓昏鎶�鏈彉鍖�',
+          prop: 'technologyChange',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          minWidth: '60',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.downLoadPost(row);
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deleteRow(row);
+              },
+            }
+
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 10,
+        current: 1,
+        total: 0,
+      },
+      formDIa: false,
+      operationType: '',
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = {
+        methodName: this.searchForm.methodName,
+        operationType: this.searchForm.operationType,
+      }
+      this.tableLoading = true
+      pagesMethodVerify({... this.page,...entity}).then(res => {
+        this.tableLoading = false
+        if (res.code === 200){
+          this.tableData = res.data.records
+          this.page.total = res.data.total
+        }
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鍒犻櫎
+    deleteRow (row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delMethodVerify({methodVerifyId:row.methodVerifyId}).then(res => {
+          this.tableLoading = false
+          if (res.code === 200){
+            this.$message.success('鍒犻櫎鎴愬姛')
+            this.searchList()
+          }
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      })
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.methodName = '';
+      this.searchList()
+    },
+    openFormDia (type, row) {
+      this.formDIa = true
+      this.operationType = type
+      this.$nextTick(() => {
+        this.$refs.formDIa.openDia(row)
+      })
+    },
+    // 鍏抽棴寮规
+    closeDia () {
+      this.formDIa = false
+      this.searchList()
+    },
+    // 瀵煎嚭
+    downLoadPost(row) {
+      this.outLoading = true
+      exportMethodVerify({methodVerifyId:row.methodVerifyId}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, '鏍囧噯锛堟柟娉曪級纭璁板綍.docx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 鍒嗛〉鍒囨崲
+    pagination(page) {
+      this.page.size = page.limit
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search {
+  height: 46px;
+  display: flex;
+  justify-content: space-between;
+}
+</style>
diff --git a/src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue
new file mode 100644
index 0000000..38b4025
--- /dev/null
+++ b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue
@@ -0,0 +1,148 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="formDia" title="缂栬緫" width="80%" @close="closeDia">
+      <el-form ref="form" :model="form" :rules="formRules" label-width="auto">
+        <el-col :span="8">
+          <el-form-item label="鏍囧噯鍚嶇О锛�" prop="methodName">
+            <el-input v-model="form.methodName" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鏍囧噯鍙凤細" prop="standardNo">
+            <el-input v-model="form.standardNo" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鏂囦欢缂栧彿锛�" prop="fileNo">
+            <el-input v-model="form.fileNo" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鏄惁鏄柊鏍囧噯锛�" prop="isNewStandard">
+            <el-radio-group v-model="form.isNewStandard">
+              <el-radio :label="0">鍚�</el-radio>
+              <el-radio :label="1">鏄�</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鏌ユ柊璁板綍鏉ユ簮锛�" prop="searchNewSource">
+            <el-radio-group v-model="form.searchNewSource">
+              <el-radio :label="0">鏍囧噯缃�</el-radio>
+              <el-radio :label="1">濮旀墭鎯呮姤</el-radio>
+              <el-radio :label="2">鏍囧噯鏁�</el-radio>
+              <el-radio :label="3">鍏朵粬</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="澶囨敞锛�" prop="remark">
+            <el-select v-model="form.remark"
+                       clearable size="small">
+              <el-option :value="0" label="浣滃簾"></el-option>
+              <el-option :value="1" label="鏇挎崲"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col v-if="form.isNewStandard == 1" :span="8">
+          <el-form-item label="鏂版爣鍑嗗悕绉帮細" prop="newMethodName">
+            <el-input v-model="form.newMethodName" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col v-if="form.isNewStandard == 1" :span="8">
+          <el-form-item label="鏂版爣鍑嗗彿锛�" prop="newStandardNo">
+            <el-input v-model="form.newStandardNo" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeDia">鍙� 娑�</el-button>
+        <el-button :loading="editLoad" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  updateMethodSearchNew
+} from '@/api/cnas/process/method/standardNoveltyRetrieval'
+
+export default {
+  name: 'FormDialog',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      form: {
+        methodName: '',
+        standardNo: '',
+        isNewStandard: '',
+        newMethodName: '',
+        newStandardNo: '',
+        searchNewSource: '',
+        remark: '',
+        fileNo: '',
+      },
+      formRules: {
+        methodName: [{required: true, message: '璇峰~鍐欐爣鍑嗗悕绉�',trigger: 'blur'}],
+        standardNo: [{required: true, message: '璇峰~鍐欐爣鍑嗗彿',trigger: 'blur'}],
+        isNewStandard: [{required: true, message: '璇烽�夋嫨鏄惁鏄柊鏍囧噯',trigger: 'change'}],
+        newMethodName: [{required: false, message: '璇峰~鍐欐柊鏍囧噯鍚嶇О',trigger: 'blur'}],
+        newStandardNo: [{required: false, message: '璇峰~鍐欐柊鏍囧噯鍙�',trigger: 'blur'}],
+        searchNewSource: [{required: true, message: '璇烽�夋嫨鏌ユ柊璁板綍鏉ユ簮',trigger: 'change'}],
+        fileNo: [{required: true, message: '璇峰~鍐欐枃浠跺彿',trigger: 'blur'}],
+      },
+      editLoad: false,
+      info: {},
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.formDia = true
+      this.form = {...row}
+    },
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.editLoad = true
+          const processMethodSearchNews = this.HaveJson(this.form)
+          delete processMethodSearchNews.createTime
+          updateMethodSearchNew(processMethodSearchNews).then(res => {
+            this.editLoad = false
+            if (res.code === 200){
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeDia()
+            }
+          }).catch(err => {
+            console.log('err---', err);
+            this.editLoad = false
+          })
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    closeDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeEditDia');
+    },
+  }
+};
+</script>
+
+<style scoped>
+.form-info {
+  display: inline-block;
+  max-height: 600px;
+  overflow-y: auto;
+}
+>>>.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+</style>
diff --git a/src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue
new file mode 100644
index 0000000..6ce226e
--- /dev/null
+++ b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue
@@ -0,0 +1,131 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="formDia" title="鏂板" width="80%" @close="closeDia">
+      <el-form ref="form" :model="form" :rules="formRules" label-width="auto">
+        <el-button size="small" type="primary" @click="addBtn">娣诲姞涓�鏉�</el-button>
+        <div class="form-info">
+          <div v-for="(items,index) in form.taskRel" :key="index">
+            <el-col :span="12">
+              <el-form-item :prop="`taskRel.${index}.newMethodName`" :rules="{required: true, message: '璇峰~鍐欐爣鍑嗗悕绉�',trigger: 'blur',}" label="鏂版爣鍑嗗悕绉帮細">
+                <el-input v-model="items.newMethodName" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item :prop="`taskRel.${index}.newStandardNo`" :rules="{required: true,message: '璇峰~鍐欐爣鍑嗗彿',trigger: 'blur',}" label="鏂版爣鍑嗗彿锛�">
+                <el-input v-model="items.newStandardNo" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item :prop="`taskRel.${index}.searchNewSource`" :rules="{required: true,message: '璇烽�夋嫨鏌ユ柊璁板綍鏉ユ簮',trigger: 'change',}" label="鏌ユ柊璁板綍鏉ユ簮锛�">
+                <el-radio-group v-model="items.searchNewSource">
+                  <el-radio :label="0">鏍囧噯缃�</el-radio>
+                  <el-radio :label="1">濮旀墭鎯呮姤</el-radio>
+                  <el-radio :label="2">鏍囧噯鏁�</el-radio>
+                  <el-radio :label="3">鍏朵粬</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item :prop="`taskRel.${index}.remark`" :rules="{required: false,message: '璇烽�夋嫨澶囨敞',trigger: 'change',}" label="澶囨敞锛�">
+                <el-select v-model="items.remark" :prop="`taskRel.${index}.remark`"
+                           :rules="{required: false,message: '璇烽�夋嫨澶囨敞',trigger: 'change',}"
+                           clearable size="small">
+                  <el-option :value="0" label="浣滃簾"></el-option>
+                  <el-option :value="1" label="鏇挎崲"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="4">
+              <el-button v-if="index !== 0" circle icon="el-icon-delete" size="small" type="danger" @click="deleteHeaderRow(index)"></el-button>
+            </el-col>
+            <el-col :span="24">
+              <el-divider></el-divider>
+            </el-col>
+          </div>
+        </div>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeDia">鍙� 娑�</el-button>
+        <el-button :loading="editLoad" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { addMethodSearchNew } from '@/api/cnas/process/method/standardNoveltyRetrieval'
+
+export default {
+  name: 'FormDialog',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      form: {
+        taskRel: [
+          {
+            newMethodName: '',
+            newStandardNo: '',
+            searchNewSource: '',
+            remark: '',
+          }
+        ]
+      },
+      formRules: {},
+      editLoad: false,
+      info: {},
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia (row) {
+      this.formDia = true
+    },
+    // 娣诲姞涓�鏉�
+    addBtn() {
+      this.form.taskRel.push({ newMethodName: '', newStandardNo:'', searchNewSource: '', remark: ''});
+    },
+    // 鍒犻櫎涓�鏉�
+    deleteHeaderRow (index) {
+      this.form.taskRel.splice(index, 1);
+    },
+    handleEdit () {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.editLoad = true
+          addMethodSearchNew(this.form.taskRel).then(res => {
+            this.editLoad = false
+            if (res.code === 201) return
+            this.$message.success('鎿嶄綔鎴愬姛')
+            this.closeDia()
+          }).catch(err => {
+            console.log('err---', err);
+            this.editLoad = false
+          })
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    closeDia () {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeDia');
+    },
+  }
+};
+</script>
+
+<style scoped>
+.form-info {
+  display: inline-block;
+  max-height: 42em;
+  overflow-y: auto;
+}
+>>>.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+</style>
diff --git a/src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue b/src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue
new file mode 100644
index 0000000..5822548
--- /dev/null
+++ b/src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue
@@ -0,0 +1,729 @@
+<template>
+  <div class="capacity-scope">
+    <div class="search">
+      <div>
+        <el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
+          <el-form-item label="鏍囧噯鍙�" prop="standardNo">
+            <el-input size="small" placeholder="璇疯緭鍏�" clearable v-model="searchForm.standardNo"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="el-icon-search" size="mini" @click="searchList">鏌� 璇�</el-button>
+            <el-button icon="el-icon-refresh" size="mini" @click="resetSearchForm">閲� 缃�</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div>
+        <el-button size="medium" type="primary" @click="openApprovalDialog1">寤� 妗�</el-button>
+        <el-upload ref='upload' :action="action"
+                             :before-upload="beforeUpload" :headers="headers" :on-error="onError"
+                             :on-success="handleSuccessUp" :show-file-list="false" accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'
+                             style="display: inline-block; margin-left: 10px;">
+                    <el-button :loading="upLoading" size="medium" type="primary">瀵煎叆</el-button>
+        </el-upload>
+        <el-button size="medium" style="margin-left: 10px;" type="primary" @click="openFormDia">鏂� 澧�</el-button>
+      </div>
+    </div>
+    <div>
+      <div class="table">
+        <div class="table-tab">
+          <el-radio-group v-model="tabIndex" @input="searchList">
+            <el-radio-button label="0">浠婂勾鏍囧噯璁板綍</el-radio-button>
+            <el-radio-button label="1">鍘嗗彶妗f</el-radio-button>
+          </el-radio-group>
+        </div>
+        <div v-if="tabIndex === '0'">
+          <TableCard :showForm="false" :showTitle="false">
+            <template v-slot:table>
+              <lims-table
+                :column="tableColumn"
+                :height="'calc(100vh - 26em)'"
+                :table-data="tableData"
+                :table-loading="tableLoading"
+                :page="page"
+                @pagination="pagination">
+              </lims-table>
+            </template>
+          </TableCard>
+        </div>
+        <div v-if="tabIndex === '1'">
+          <TableCard :showForm="false" :showTitle="false">
+            <template v-slot:table>
+              <lims-table
+                :column="oldTableColumn"
+                :height="'calc(100vh - 20em)'"
+                :table-data="oldTableData"
+                :table-loading="oldTableLoading"
+                :page="oldPage"
+                @pagination="oldPagination">
+              </lims-table>
+            </template>
+          </TableCard>
+        </div>
+      </div>
+      <!--      鍘嗗彶妗f鎵瑰噯寮规-->
+      <el-dialog :visible.sync="approvalDialog" title="鎵瑰噯" width="30%" @close="approvalDialog = false">
+        <span>
+          鎵瑰噯澶囨敞锛�
+          <el-input v-model="qualityRemark" type="textarea"></el-input>
+        </span>
+        <span slot="footer" class="dialog-footer">
+          <el-button :loading="approvalLoading" @click="handleApproval(0)">涓嶆壒鍑�</el-button>
+          <el-button :loading="approvalLoading" type="primary" @click="handleApproval(1)">鎵� 鍑�</el-button>
+        </span>
+      </el-dialog>
+      <el-dialog :visible.sync="approvalDialog1" title="寤烘。" width="30%" @close="approvalDialog1 = false">
+        <span>
+          妗f鍚嶇О锛�
+          <el-input v-model="archivedName" type="textarea"></el-input>
+        </span>
+        <span slot="footer" class="dialog-footer">
+          <el-button :loading="approvalLoading" @click="approvalDialog1 = false, archivedName = ''">鍙� 娑�</el-button>
+          <el-button :loading="approvalLoading" type="primary" @click="handleApproval1()">纭� 瀹�</el-button>
+        </span>
+      </el-dialog>
+      <FormDialog v-if="formDialog" ref="formDialog" @closeDia="closeDia"></FormDialog>
+      <EditFormDia v-if="editFormDialog" ref="editFormDialog" @closeEditDia="closeEditDia"></EditFormDia>
+      <el-dialog :visible.sync="viewRocordDia" title="璇︽儏" width="80%" @close="approvalDialog = false">
+        <TableCard :showForm="false" :showTitle="false">
+          <template v-slot:table>
+            <limsTable
+              :column="tableColumn1"
+              :height="'calc(100vh - 26em)'"
+              :table-data="tableData1"
+              :table-loading="tableLoading1"
+              style="padding: 0 15px;margin-bottom: 16px"
+              :page="page1"
+              @pagination="pagination1">
+            </limsTable>
+          </template>
+        </TableCard>
+      </el-dialog>
+    </div>
+  </div>
+</template>
+
+<script>
+import limsTable from '@/components/Table/lims-table.vue'
+import TableCard from '@/views/CNAS/externalService/serviceAndSupplyPro/component/index.vue';
+import FormDialog from './component/FormDialog.vue';
+import EditFormDia from './component/EditFormDia.vue';
+import {
+  addSearchNewArchived, exportMethodSearchNew,
+  pageMethodSearchNew, pageSearchNewArchived, pageSearchNewBackups, ratifySearchNewArchivedr
+} from '@/api/cnas/process/method/standardNoveltyRetrieval'
+
+export default {
+  name: 'a7-standard-novelty-retrieval',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {
+    FormDialog,
+    TableCard,
+    limsTable,
+    EditFormDia
+  },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        year: '',
+        standardNo: '',
+      },
+      options: [
+        {label: '涓婂崐骞�', value: '1'},
+        {label: '涓嬪崐骞�', value: '2'},
+      ],
+      tableColumn: [
+        {
+          label: '鏍囧噯鍚嶇О',
+          prop: 'methodName',
+          minWidth: '100'
+        },
+        {
+          label: '鏍囧噯鍙�',
+          prop: 'standardNo',
+          minWidth: '100'
+        },
+        {
+          label: '鏂囦欢缂栧彿',
+          prop: 'fileNo',
+          minWidth: '100'
+        },
+        {
+          dataType: 'tag',
+          label: '鏄惁鏄柊鏍囧噯',
+          prop: 'isNewStandard',
+          minWidth: '100',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鍚�';
+            } else if (params == 1) {
+              return '鏄�';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'danger';
+            } else if (params == 1) {
+              return 'success';
+            } else {
+              return null
+            }
+          }
+        },
+        {
+          label: '鏂版爣鍑嗗悕绉�',
+          prop: 'newMethodName',
+          minWidth: '100'
+        },
+        {
+          label: '鏂版爣鍑嗗彿',
+          prop: 'newStandardNo',
+          minWidth: '100'
+        },
+        {
+          dataType: 'tag',
+          label: '鏌ヨ璁板綍鏉ユ簮',
+          prop: 'searchNewSource',
+          minWidth: '100',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鏍囧噯缃�';
+            } else if (params == 1) {
+              return '濮旀墭鎯呮姤';
+            } else if (params == 2) {
+              return '鏍囧噯鏁�';
+            } else if (params == 3) {
+              return '鍏朵粬';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'success';
+            } else if (params == 1) {
+              return 'danger';
+            } else if (params == 2) {
+              return 'warning';
+            } else if (params == 3) {
+              return 'info';
+            } else {
+              return null
+            }
+          }
+        },
+        {
+          dataType: 'tag',
+          label: '澶囨敞',
+          prop: 'remark',
+          minWidth: '100',
+          formatData: (params) => {
+            if (params == 0) {
+              return '浣滃簾';
+            } else if (params == 1) {
+              return '鏇挎崲';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'danger';
+            } else if (params == 1) {
+              return 'success';
+            } else {
+              return null
+            }
+          }
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openEditFormDia(row);
+              },
+            },
+          ]
+        }
+      ],
+      tableColumn1: [
+        {
+          label: '鏍囧噯鍚嶇О',
+          prop: 'methodName',
+          minWidth: '100'
+        },
+        {
+          label: '鏍囧噯鍙�',
+          prop: 'standardNo',
+          minWidth: '100'
+        },
+        {
+          label: '鏂囦欢缂栧彿',
+          prop: 'fileNo',
+          minWidth: '100'
+        },
+        {
+          dataType: 'tag',
+          label: '鏄惁鏄柊鏍囧噯',
+          prop: 'isNewStandard',
+          minWidth: '100',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鍚�';
+            } else if (params == 1) {
+              return '鏄�';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'danger';
+            } else if (params == 1) {
+              return 'success';
+            } else {
+              return null
+            }
+          }
+        },
+        {
+          label: '鏂版爣鍑嗗悕绉�',
+          prop: 'newMethodName',
+          minWidth: '100'
+        },
+        {
+          label: '鏂版爣鍑嗗彿',
+          prop: 'newStandardNo',
+          minWidth: '100'
+        },
+        {
+          dataType: 'tag',
+          label: '鏌ヨ璁板綍鏉ユ簮',
+          prop: 'searchNewSource',
+          minWidth: '100',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鏍囧噯缃�';
+            } else if (params == 1) {
+              return '濮旀墭鎯呮姤';
+            } else if (params == 2) {
+              return '鏍囧噯鏁�';
+            } else if (params == 3) {
+              return '鍏朵粬';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'success';
+            } else if (params == 1) {
+              return 'danger';
+            } else if (params == 2) {
+              return 'warning';
+            } else if (params == 3) {
+              return 'info';
+            } else {
+              return null
+            }
+          }
+        },
+        {
+          dataType: 'tag',
+          label: '澶囨敞',
+          prop: 'remark',
+          minWidth: '100',
+          formatData: (params) => {
+            if (params == 0) {
+              return '浣滃簾';
+            } else if (params == 1) {
+              return '鏇挎崲';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'danger';
+            } else if (params == 1) {
+              return 'success';
+            } else {
+              return null
+            }
+          }
+        }
+      ],
+      tableData: [],
+      tableData1: [],
+      tableLoading: false,
+      tableLoading1: false,
+      page: {
+        size: 10,
+        current: 1,
+        total: 0
+      },
+      page1: {
+        size: 10,
+        current: 1,
+        total: 0
+      },
+      oldPage: {
+        size: 10,
+        current: 1,
+        total: 0,
+      },
+      oldTableColumn: [
+        {
+          label: '瀛樻。鍚嶇О',
+          prop: 'archivedName',
+          minWidth: '100'
+        },
+        {
+          label: '缂栧埗浜�',
+          prop: 'writeName',
+          minWidth: '100'
+        },
+        {
+          label: '缂栧埗鏃堕棿',
+          prop: 'writeTime',
+          minWidth: '100'
+        },
+        {
+          label: '鎵瑰噯浜�',
+          prop: 'ratifyName',
+          minWidth: '100'
+        },
+        {
+          label: '鎵瑰噯淇℃伅',
+          prop: 'ratifyRemark',
+          minWidth: '100'
+        },
+        {
+          dataType: 'tag',
+          label: '鎵瑰噯鐘舵��',
+          prop: 'ratifyStatus',
+          minWidth: '100',
+          formatData: (params) => {
+            if (params == 0) {
+              return '涓嶉�氳繃';
+            } else if (params == 1) {
+              return '閫氳繃';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'danger';
+            } else if (params == 1) {
+              return 'success';
+            } else {
+              return null
+            }
+          }
+        },
+        {
+          label: '鎵瑰噯鏃堕棿',
+          prop: 'ratifyTime',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              clickFun: (row) => {
+                this.openApprovalDialog(row);
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鏌ョ湅',
+              type: 'text',
+              clickFun: (row) => {
+                this.openViewDia(row);
+              },
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleOut(row);
+              },
+            }
+          ]
+        }
+      ],
+      oldTableData: [],
+      oldTableLoading: false,
+      tabIndex: '0',
+      formDialog: false,
+      editFormDialog: false,
+      upLoading:false,
+      outLoading:false,
+      ratifyInfo: {
+        writeUserId: '',
+        ratifyUserId: '',
+        writeDate: '',
+        ratifyDate: '',
+      },
+      userList: [],
+      approvalDialog: false,
+      approvalDialog1: false,
+      viewRocordDia: false,
+      approvalLoading: false,
+      qualityRemark: '',
+      archivedName: '',
+      archivedId: '',
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList () {
+      let params = {}
+      if (this.tabIndex === '0') {
+        params = {
+          entity: {
+            standardNo: this.searchForm.standardNo,
+          },
+          page: this.page
+        }
+      } else {
+        params = {
+          entity: {},
+          page: this.oldPage
+        }
+      }
+      if (this.tabIndex === '0') {
+        this.tableLoading = true
+        pageMethodSearchNew({...params.oldPage,...params.entity}).then(res => {
+          this.tableLoading = false
+          if (res.code === 200){
+            this.tableData = res.data.records
+            this.page.total = res.data.total
+          }
+        }).catch(err => {
+          console.log('err---', err);
+          this.tableLoading = false
+        })
+      } else {
+        this.oldTableLoading = true
+        pageSearchNewArchived({
+          ...params.page,...params.entity
+        }).then(res => {
+          this.oldTableLoading = false
+          if (res.code === 200){
+            console.log('res>>>>>>>>>>>>',res)
+            this.oldTableData = res.data.records
+            this.oldPage.total = res.data.total
+          }
+
+        }).catch(err => {
+          console.log('err---', err);
+          this.oldTableLoading = false
+        })
+      }
+    },
+    // 鎵撳紑鍘嗗彶妗f璇︽儏寮规
+    openViewDia (row) {
+      this.archivedId = row.archivedId
+      this.viewRocordDia = true
+      this.pageSearchNewBackups()
+    },
+    pageSearchNewBackups () {
+      const entity = {
+        archivedId: this.archivedId,
+      }
+      this.tableLoading1 = true
+      pageSearchNewBackups({...this.page1,...entity}).then(res => {
+        this.tableLoading1 = false
+        if (res.code === 200){
+          this.tableData1 = res.data.records
+          this.page1.total = res.data.total
+        }
+
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading1 = false
+      })
+    },
+    // 鎵撳紑鎵瑰噯寮规
+    openApprovalDialog (row) {
+      this.approvalDialog = true
+      this.archivedId = row.archivedId
+    },
+    // 鎵撳紑鎵瑰噯寮规
+    openApprovalDialog1 (row) {
+      this.approvalDialog1 = true
+      this.archivedId = row.archivedId
+    },
+    // 鎻愪氦鎵瑰噯
+    handleApproval (status) {
+      this.approvalLoading = true
+      let internalReport = {
+        archivedId: this.archivedId,
+        ratifyStatus: status,
+        ratifyRemark: this.ratifyRemark
+      }
+      ratifySearchNewArchivedr(internalReport).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.searchList()
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    // 鎻愪氦鎵瑰噯
+    handleApproval1 (status) {
+      this.approvalLoading = true
+      let internalReport = {
+        archivedName: this.archivedName,
+      }
+      addSearchNewArchived(internalReport).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog1 = false
+          this.searchList()
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm () {
+      this.searchForm.standardNo = '';
+      this.searchList()
+    },
+    // 鎿嶄綔鏂板妗�
+    openFormDia (row) {
+      this.formDialog = true
+      this.$nextTick(() => {
+        this.$refs.formDialog.openDia(row)
+      })
+    },
+    // 鍏抽棴鏂板寮规
+    closeDia () {
+      this.formDialog = false
+      this.searchList()
+    },
+    // 鎵撳紑淇敼寮规
+    openEditFormDia (row) {
+      this.editFormDialog = true
+      this.$nextTick(() => {
+        this.$refs.editFormDialog.openDia(row)
+      })
+    },
+    //
+    closeEditDia () {
+      this.editFormDialog = false
+      this.searchList()
+    },
+    // 瀵煎嚭
+    handleOut (row) {
+      this.outLoading = true
+      exportMethodSearchNew({archivedId:row.archivedId}).then(res => {
+        const blob = new Blob([res],{ type: 'application/octet-stream' });
+        this.$download.saveAs(blob, '鏍囧噯鏌ユ柊瀵煎嚭.xlsx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 瀵煎叆
+    beforeUpload(file) {
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        return false;
+      } else {
+        this.upLoading = true;
+        return true;
+      }
+    },
+    onError(err, file, fileList) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+    },
+    handleSuccessUp(response) {
+      this.upLoading = false;
+      if (response.code == 200) {
+        this.$message.success('涓婁紶鎴愬姛');
+        this.searchList()
+      }
+    },
+    // 鍒嗛〉
+    pagination(page){
+      this.page.size = page.limit
+      this.searchList();
+    },
+    pagination1(page){
+      this.page1.size = page.limit
+      this.pageSearchNewBackups();
+    },
+    oldPagination(page){
+      this.oldPage.size = page.limit
+      this.searchList();
+    },
+    //
+    getUserList(){
+      this.$axios.post(this.$api.user.selectUserList, {
+        page: {current: -1, size: -1,},
+        entity: {name: null}
+      }, {
+        headers: {
+          'Content-Type': 'application/json'
+        }
+      }).then(res => {
+        if (res.code === 201) {
+          return
+        }
+        this.userList = res.data.body.records
+      })
+    },
+  },
+  // 鐢ㄤ簬涓婁紶鏂囦欢鐨勪俊鎭�
+  computed: {
+    headers() {
+      return {
+        'token': sessionStorage.getItem('token')
+      }
+    },
+    action() {
+      return this.javaApi + '/processMethodSearchNew/importMethodSearchNew'
+    }
+  },
+};
+</script>
+
+<style scoped>
+.search {
+  height: 46px;
+  display: flex;
+  justify-content: space-between;
+}
+.table-tab {
+  margin-bottom: 10px;
+}
+</style>
diff --git a/src/views/business/inspectionTask/index.vue b/src/views/business/inspectionTask/index.vue
index e10d812..521864b 100644
--- a/src/views/business/inspectionTask/index.vue
+++ b/src/views/business/inspectionTask/index.vue
@@ -572,10 +572,11 @@
     this.getDicts("inspection_task_state").then((response) => {
       this.inspectionTaskState = this.dictToValue(response.data);
     });
+    this.refreshTable();
+
   },
   mounted() {
     this.queryParams.userId = this.userId;
-    this.refreshTable();
   },
   methods: {
     getList() {
diff --git a/src/views/business/inspectionTask/inspection.vue b/src/views/business/inspectionTask/inspection.vue
index 697a551..8b844ee 100644
--- a/src/views/business/inspectionTask/inspection.vue
+++ b/src/views/business/inspectionTask/inspection.vue
@@ -2899,7 +2899,7 @@
       }
     },
     goback() {
-      this.$tab.closeOpenPage({ path: "/business/inspectionTask" });
+      this.$router.go(-1)
     }
   },
 };
diff --git a/src/views/business/materialOrder/index.vue b/src/views/business/materialOrder/index.vue
index c8e8854..3c09dec 100644
--- a/src/views/business/materialOrder/index.vue
+++ b/src/views/business/materialOrder/index.vue
@@ -72,30 +72,38 @@
         </div>
         <!--寰呬笅鍗�-->
         <div class="table">
-          <lims-table :tableData="tableData" :column="column" v-if="tabIndex === 0" @pagination="pagination"
-            :height="'calc(100vh - 290px)'" key="tableData" :page="page" :tableLoading="tableLoading"></lims-table>
+          <lims-table :tableData="tableData" :column="column"
+                      v-if="tabIndex === 0" @pagination="pagination"
+                      :rowClassName="changeRowClass"
+                      :height="'calc(100vh - 290px)'" key="tableData"
+                      :page="page" :tableLoading="tableLoading"></lims-table>
         </div>
         <!--妫�楠屼腑-->
         <div class="table">
-          <lims-table :tableData="tableData1" :column="column1" v-if="tabIndex === 1" :isSelection="true"
-            :handleSelectionChange="selectMethod" @pagination="pagination1" :height="'calc(100vh - 290px)'"
-            key="tableData1" :page="page1" :tableLoading="tableLoading1"></lims-table>
+          <lims-table :tableData="tableData1" :column="column1"
+                      v-if="tabIndex === 1" :isSelection="true"
+                      :rowClassName="changeRowClass"
+                      :handleSelectionChange="selectMethod" @pagination="pagination1" :height="'calc(100vh - 290px)'"
+                      key="tableData1" :page="page1" :tableLoading="tableLoading1"></lims-table>
         </div>
         <!--宸叉楠�-->
         <div class="table">
           <lims-table :tableData="tableData2" :column="column2" v-if="tabIndex === 2" :isSelection="true"
+                      :rowClassName="changeRowClass"
             :handleSelectionChange="selectMethod" @pagination="pagination2" :height="'calc(100vh - 290px)'"
             key="tableData2" :page="page2" :tableLoading="tableLoading2"></lims-table>
         </div>
         <!--鍏ㄩ儴-->
         <div class="table">
           <lims-table :tableData="tableData3" :column="column3" v-if="tabIndex === 3" :isSelection="true"
+                      :rowClassName="changeRowClass"
             :handleSelectionChange="selectMethod" @pagination="pagination3" :height="'calc(100vh - 290px)'"
             key="tableData3" :page="page3" :tableLoading="tableLoading3"></lims-table>
         </div>
         <!--瀛e害妫�楠�-->
         <div class="table">
           <lims-table :tableData="tableData4" :column="column4" v-if="tabIndex === 4" :isSelection="true"
+                      :rowClassName="changeRowClass"
             :handleSelectionChange="selectMethod" @pagination="pagination4" :height="'calc(100vh - 290px)'"
             key="tableData4" :page="page4" :tableLoading="tableLoading4"></lims-table>
         </div>
@@ -1108,6 +1116,12 @@
     selectMethod(val) {
       this.multipleSelection = val
     },
+    changeRowClass({row, rowIndex}) {
+      if (row.isFirst == 1) {
+        return 'highlight-danger-row-border'
+      }
+      return ''
+    },
   },
 }
 </script>
diff --git a/src/views/business/productOrder/components/add.vue b/src/views/business/productOrder/components/add.vue
index 543f32d..93e2d2c 100644
--- a/src/views/business/productOrder/components/add.vue
+++ b/src/views/business/productOrder/components/add.vue
@@ -933,7 +933,7 @@
         this.getCompanyList()
       },
       getCompanyList () {
-        selectCustomPageList().then(res => {
+        selectCustomPageList({...this.page1}).then(res => {
           this.tableLoading1 = false
           if (res.code === 200) {
             this.tableData1 = res.data.records
diff --git a/src/views/business/rawMaterialInspection/index.vue b/src/views/business/rawMaterialInspection/index.vue
index a993bac..7573f89 100644
--- a/src/views/business/rawMaterialInspection/index.vue
+++ b/src/views/business/rawMaterialInspection/index.vue
@@ -549,7 +549,7 @@
     // 寰呮姤妫�銆佸緟涓嬪崟鏌ヨ
     getWarehouseSubmitApi () {
       this.tableLoading = true
-      const params = {...this.componentData, isInspect: this.tabIndex, state: this.tabIndex === 0 ? null : 0}
+      const params = {...this.componentData, isInspect: this.tabIndex, state: this.tabIndex === 0 ? null : 0, ...this.page}
       getWarehouseSubmit(params).then(res => {
         this.tableLoading = false
         if (res.code === 200) {
@@ -563,7 +563,7 @@
     // 宸插畬鎴愰儴鏌ヨ
     getIfsByFinishList () {
       this.tableLoading1 = true
-      getIfsByFinish({...this.componentData}).then(res => {
+      getIfsByFinish({...this.componentData, ...this.page1}).then(res => {
         this.tableLoading1 = false
         if (res.code === 200) {
           this.tableData1 = res.data.records
@@ -576,7 +576,7 @@
     // 鍏ㄩ儴鏌ヨ
     getIfsByAllList () {
       this.tableLoading1 = true
-      getIfsByAll({...this.componentData}).then(res => {
+      getIfsByAll({...this.componentData, ...this.page1}).then(res => {
         this.tableLoading1 = false
         if (res.code === 200) {
           this.tableData1 = res.data.records
diff --git a/src/views/standard/model/index.vue b/src/views/standard/model/index.vue
index f6eccfd..ab46ae4 100644
--- a/src/views/standard/model/index.vue
+++ b/src/views/standard/model/index.vue
@@ -112,7 +112,7 @@
               type: "text",
               clickFun: (row) => {
                 this.title = "缂栬緫";
-                this.copyForm = row;
+                this.copyForm = this.HaveJson(row);
                 this.isShowCopyTem = true;
               },
               showHide: (row) => {
diff --git a/src/views/tool/file-preview.vue b/src/views/tool/file-preview.vue
new file mode 100644
index 0000000..591aac2
--- /dev/null
+++ b/src/views/tool/file-preview.vue
@@ -0,0 +1,238 @@
+<template>
+  <div>
+    <div v-if="isImage">
+      <img :src="imgUrl" alt="Image Preview" />
+    </div>
+    <div v-if="isPdf">
+      <object :data="fileUrl" type="application/pdf" width="100%" height="750px">
+        <p>鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 PDF 棰勮銆�<a :href="fileUrl">涓嬭浇 PDF 鏂囦欢</a></p>
+      </object>
+    </div>
+    <div v-if="isDoc">
+      <p v-if="!isDocShow">鏂囨。鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl" v-if="!isDocShow">涓嬭浇鏂囦欢</a>
+      <vue-office-docx v-else
+                       :src="fileUrl"
+                       style="height: 100vh;"
+                       @rendered="renderedHandler"
+                       @error="errorHandler"
+      />
+    </div>
+    <div v-if="isXls">
+      <p v-if="!isDocShow">鏂囨。鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl" v-if="!isDocShow">涓嬭浇鏂囦欢</a>
+      <vue-office-excel v-else
+                        :src="fileUrl"
+                        :options="options"
+                        style="height: 100vh;"
+                        @rendered="renderedHandler"
+                        @error="errorHandler"
+      />
+    </div>
+    <div v-if="isZipOrRar">
+      <p>鍘嬬缉鏂囦欢鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl">涓嬭浇鏂囦欢</a>
+    </div>
+    <div v-if="isCsv">
+      <p v-if="csvList.length==0">CSV 鏂囦欢鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
+      <a :href="fileUrl" v-if="csvList.length==0">涓嬭浇鏂囦欢</a>
+      <el-tabs type="border-card" v-if="csvList.length>0" tab-position="bottom">
+        <el-tab-pane :label="item.sheetName" v-for="(item,index) in csvList" :key="index">
+          <el-table :data="item.tableData" height="75vh">
+            <el-table-column :label="m.label" :prop="m.prop" v-for="(m,i) in item.column" :key="i" min-width="120px" show-overflow-tooltip>
+              <template slot-scope="scope" slot="header">
+                <div>
+                  <el-tooltip  :content="m.label" placement="top">
+                    <div class="oneLine">
+                      <span>{{m.label}}</span>
+                    </div>
+                  </el-tooltip>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+    <div v-if="!isSupported">
+      <p>涓嶆敮鎸佺殑鏂囦欢鏍煎紡</p>
+    </div>
+  </div>
+</template>
+
+<script>
+import VueOfficeDocx from '@vue-office/docx'
+//寮曞叆鐩稿叧鏍峰紡
+import '@vue-office/docx/lib/index.css'
+import VueOfficeExcel from '@vue-office/excel'
+//寮曞叆鐩稿叧鏍峰紡
+import '@vue-office/excel/lib/index.css'
+export default {
+  components: {
+    VueOfficeDocx,
+    VueOfficeExcel,
+  },
+  props: {
+    fileUrl: {
+      type: String,
+      required: true
+    },
+    currentFile: {
+      type: Object,
+      required: true
+    },
+  },
+  data(){
+    return {
+      isDocShow:true,
+      options:{
+        xls: false,       //棰勮xlsx鏂囦欢璁句负false锛涢瑙坸ls鏂囦欢璁句负true
+        minColLength: 0,  // excel鏈�灏戞覆鏌撳灏戝垪锛屽鏋滄兂瀹炵幇xlsx鏂囦欢鍐呭鏈夊嚑鍒楋紝灏辨覆鏌撳嚑鍒楋紝鍙互灏嗘鍊艰缃负0.
+        minRowLength: 0,  // excel鏈�灏戞覆鏌撳灏戣锛屽鏋滄兂瀹炵幇鏍规嵁xlsx瀹為檯鍑芥暟娓叉煋锛屽彲浠ュ皢姝ゅ�艰缃负0.
+        widthOffset: 10,  //濡傛灉娓叉煋鍑烘潵鐨勭粨鏋滄劅瑙夊崟鍏冩牸瀹藉害涓嶅锛屽彲浠ュ湪榛樿娓叉煋鐨勫垪琛ㄥ搴︿笂鍐嶅姞 Npx瀹�
+        heightOffset: 10, //鍦ㄩ粯璁ゆ覆鏌撶殑鍒楄〃楂樺害涓婂啀鍔� Npx楂�
+        beforeTransformData: (workbookData) => {return workbookData}, //搴曞眰閫氳繃exceljs鑾峰彇excel鏂囦欢鍐呭锛岄�氳繃璇ラ挬瀛愬嚱鏁帮紝鍙互瀵硅幏鍙栫殑excel鏂囦欢鍐呭杩涜淇敼锛屾瘮濡傛煇涓崟鍏冩牸鐨勬暟鎹樉绀轰笉姝g‘锛屽彲浠ュ湪姝よ嚜琛屼慨鏀规瘡涓崟鍏冩牸鐨剉alue鍊笺��
+        transformData: (workbookData) => {return workbookData}, //灏嗚幏鍙栧埌鐨別xcel鏁版嵁杩涜澶勭悊涔嬪悗涓旀覆鏌撳埌椤甸潰涔嬪墠锛屽彲閫氳繃transformData瀵瑰嵆灏嗘覆鏌撶殑鏁版嵁鍙婃牱寮忚繘琛屼慨鏀癸紝姝ゆ椂姣忎釜鍗曞厓鏍肩殑text鍊煎氨鏄嵆灏嗘覆鏌撳埌椤甸潰涓婄殑鍐呭
+      },
+      csvList:[],//csv鏂囦欢鏁版嵁
+      imgUrl:''
+    }
+  },
+  computed: {
+    isImage() {
+      let state = /\.(jpg|jpeg|png|gif)$/i.test(this.fileUrl)
+      this.imgUrl = this.fileUrl
+      if(state){
+        this.imgUrl = this.fileUrl.replaceAll('word', 'img')
+      }
+      return state;
+    },
+    isPdf() {
+      return /\.pdf$/i.test(this.fileUrl);
+    },
+    isDoc() {
+      return /\.(doc|docx)$/i.test(this.fileUrl);
+    },
+    isXls(){
+      let state = /\.(xls|xlsx)$/i.test(this.fileUrl)
+      if(state){
+        if(/\.(xlsx)$/i.test(this.fileUrl)){
+          this.options.xls = false
+        }else{
+          this.options.xls = true
+        }
+      }
+      return state;
+    },
+    isZipOrRar() {
+      return /\.(zip|rar)$/i.test(this.fileUrl);
+    },
+    isCsv() {
+      let state = /\.csv$/i.test(this.fileUrl)
+      if(state){
+        this.loadCSVData();
+        // this.main()
+      }
+      return state;
+    },
+    isSupported() {
+      return this.isImage || this.isPdf || this.isDoc || this.isZipOrRar || this.isCsv||this.isXls;
+    }
+  },
+  methods:{
+    renderedHandler() {
+      console.log("娓叉煋瀹屾垚")
+      this.isDocShow = true
+      this.resetStyle()
+    },
+    errorHandler() {
+      console.log("娓叉煋澶辫触")
+      this.isDocShow = false
+    },
+    async loadCSVData() {
+      this.$axios.post(this.$api.insOrderPlan.preview, {
+        id: this.currentFile.id,
+      }).then( res => {
+        let arr = res.data
+        arr = arr.map(m=>{
+          let obj = {
+            sheetName:m.sheetName,
+            tableData:[],
+            column:[]
+          }
+          obj.tableData = this.formatCSVToTable(m.content.replaceAll('null',' '))
+          // .replaceAll('MIN','=MIN').replaceAll('MAX','=MAX').replaceAll('AVERAGE','=AVERAGE')
+          for (let item in obj.tableData[0]) {
+            obj.column.push({
+              label: item,
+              prop: item,
+            })
+          }
+          return obj
+        })
+        this.csvList = arr
+      }).catch( err => {
+        console.log(err)
+      })
+    },
+    formatCSVToTable(str){
+      const result = [];
+      const jsonObj = str.split("\n");
+      let arrHeader = [];
+      for (const i in jsonObj) {
+        if (typeof jsonObj[i] === 'string' && jsonObj[i].length > 0) {
+          const row = `${jsonObj[i]}`;
+          if (row.trim().length > 0) {
+            const kv = jsonObj[i].split(',');
+            if (i == 0) {
+              // 鑾峰彇column琛ㄥご
+              arrHeader = kv;
+            } else {
+              const obj = {};
+              for (let index = 0; index < arrHeader.length; index++) {
+                // 缁勮琛ㄦ牸鏁版嵁
+                const name = String(arrHeader[index]);
+                if (!arrHeader[index]) continue
+                if (!obj[name]) {
+                  try {
+                    if (kv[index]) {
+                      obj[name] = String(kv[index]);
+                    } else {
+                      obj[name] = '';
+                    }
+                  } catch (err) {
+                    obj[name] = '';
+                  }
+                }
+              }
+              result.push(obj);
+            }
+          }
+        }
+      }
+      return result
+    },
+    resetStyle(){
+      const elements = document.querySelectorAll('[style*="pt"]');
+      for (const element of elements) {
+        const style = element.getAttribute('style');
+        if (!!style) {
+          element.setAttribute('style', style.replace(/pt/g, 'px'));
+        }
+      }
+    },
+  }
+}
+</script>
+
+<style scoped>
+img {
+  max-width: 100%;
+}
+
+.oneLine {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+</style>

--
Gitblit v1.9.3