From 2e8eebd8e5a549cdf16fda43c5cf6b1568aadcaa Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期二, 04 三月 2025 11:45:01 +0800
Subject: [PATCH] 搬迁体系管理70%

---
 vue.config.js                                                                                       |    2 
 src/assets/stamps/储能.png                                                                            |    0 
 src/views/CNAS/systemManagement/managementReview/components/meetingRecordsDia.vue                   |  158 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveActionDIa.vue          |  409 ++
 src/api/cnas/systemManagement/correctiveAction.js                                                   |   59 
 src/api/cnas/systemManagement/measuresDealRisks.js                                                  |  112 
 src/assets/stamps/通信.png                                                                            |    0 
 src/store/getters.js                                                                                |   38 
 src/views/CNAS/systemManagement/internalAuditManagement/index.vue                                   |   57 
 src/api/cnas/systemManagement/managementReview.js                                                   |  159 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspection.vue              |  253 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveAction.vue             |  181 +
 src/components/Table/lims-table.vue                                                                 |  475 +-
 src/store/modules/user.js                                                                           |  146 
 src/views/CNAS/systemManagement/correctiveAction/components/ViewTestRecord.vue                      |  169 +
 src/views/CNAS/systemManagement/customerManagement/components/formDialog.vue                        |  256 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSignDia.vue          |  183 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlanDia.vue                  |  342 ++
 src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlan.vue                     |  313 ++
 src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSign.vue             |  201 +
 src/views/CNAS/systemManagement/correctiveAction/components/correctiveInfo.vue                      |  258 +
 src/views/CNAS/systemManagement/managementReview/components/managementFormDIa.vue                   |  246 +
 src/main.js                                                                                         |    2 
 src/assets/stamps/质量负责人.png                                                                         |    0 
 src/assets/stamps/主任.png                                                                            |    0 
 src/utils/index.js                                                                                  |  301 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspectionDia.vue           |  231 +
 src/assets/stamps/电力.png                                                                            |    0 
 src/views/CNAS/systemManagement/managementReview/components/reviewReport.vue                        |  266 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/ViewTestRecord.vue               |  176 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/auditReportDia.vue               |  333 ++
 src/views/CNAS/systemManagement/measuresDealRisks/index.vue                                         |   39 
 src/views/CNAS/systemManagement/managementReview/components/managementReviewPlan.vue                |  306 ++
 src/views/CNAS/systemManagement/internalAuditManagement/components/implementationPlan.vue           |  291 +
 src/views/CNAS/systemManagement/customerManagement/customerSatisfaction.vue                         |    0 
 src/api/cnas/systemManagement/internalAuditManagement.js                                            |  386 ++
 src/assets/stamps/射频.png                                                                            |    0 
 src/views/CNAS/systemManagement/managementReview/components/reviewReportDia.vue                     |  259 +
 src/views/CNAS/systemManagement/internalAuditManagement/components/implementPlanDia.vue             |  307 ++
 src/assets/stamps/装备.png                                                                            |    0 
 src/views/CNAS/systemManagement/internalAuditManagement/components/auditReport.vue                  |  311 ++
 src/api/cnas/systemManagement/customerSatisfaction.js                                               |   56 
 src/api/system/user.js                                                                              |  169 
 src/views/CNAS/systemManagement/measuresDealRisks/components/hazardIdentificationRiskAssessment.vue |  331 ++
 src/views/CNAS/systemManagement/managementReview/components/meetingRecords.vue                      |  196 +
 src/views/CNAS/systemManagement/managementReview/index.vue                                          |   48 
 src/views/CNAS/systemManagement/measuresDealRisks/components/listRiskAnalysisControlPlans.vue       |  298 ++
 package.json                                                                                        |    7 
 src/assets/stamps/技术负责人.png                                                                         |    0 
 src/assets/stamps/综合室.png                                                                           |    0 
 src/components/Preview/filePreview.vue                                                              |  230 +
 src/views/CNAS/systemManagement/correctiveAction/index.vue                                          |  202 +
 52 files changed, 8,268 insertions(+), 494 deletions(-)

diff --git a/package.json b/package.json
index f77ab56..0d89465 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,9 @@
   },
   "dependencies": {
     "@riophae/vue-treeselect": "0.4.0",
+    "@vue-office/docx": "^1.6.3",
+    "@vue-office/excel": "^1.7.14",
+    "@vue/composition-api": "^1.7.2",
     "axios": "0.28.1",
     "clipboard": "2.0.8",
     "core-js": "3.37.1",
@@ -59,10 +62,12 @@
     "vue": "2.6.12",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
+    "vue-demi": "^0.14.10",
     "vue-meta": "2.4.0",
     "vue-router": "3.4.9",
     "vuedraggable": "2.24.3",
-    "vuex": "3.6.0"
+    "vuex": "3.6.0",
+    "worker-loader": "^3.0.8"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "4.4.6",
diff --git a/src/api/cnas/systemManagement/correctiveAction.js b/src/api/cnas/systemManagement/correctiveAction.js
new file mode 100644
index 0000000..ebd9f5c
--- /dev/null
+++ b/src/api/cnas/systemManagement/correctiveAction.js
@@ -0,0 +1,59 @@
+// 绾犳鎺柦鐩稿叧鎺ュ彛
+import request from "@/utils/request";
+
+//鏌ヨ鐩戠潱绾犳鎺柦鍒楄〃
+export function pageSuperviseDetailCorrect(query) {
+  return request({
+    url: "/qualitySupervise/pageSuperviseDetailCorrect",
+    method: "get",
+    params: query,
+  });
+}
+
+//瀵煎嚭鐩戠潱绾犳鎺柦
+export function exportSuperviseDetaillCorrect(query) {
+  return request({
+    url: "/qualitySupervise/exportSuperviseDetaillCorrect",
+    method: "get",
+    headers: {
+      responseType: "blob",
+    },
+    params: query,
+  });
+}
+
+//鏌ヨ鐩戠潱绾犳鎺柦闄勪欢
+export function getSuperviseDetailCorrectFileList(query) {
+  return request({
+    url: "/qualitySupervise/getSuperviseDetailCorrectFileList",
+    method: "get",
+    params: query,
+  });
+}
+
+//鍒犻櫎鐩戠潱绾犳鎺柦闄勪欢
+export function delSuperviseDetailCorrectFile(query) {
+  return request({
+    url: "/qualitySupervise/delSuperviseDetailCorrectFile",
+    method: "delete",
+    params: query,
+  });
+}
+
+//鏌ヨ鐩戠潱绾犳澶勭悊
+export function getSuperviseDetailCorrect(query) {
+  return request({
+    url: "/qualitySupervise/getSuperviseDetailCorrect",
+    method: "get",
+    params: query,
+  });
+}
+
+//鏌ヨ浠婂勾浜哄憳鍩硅淇℃伅
+export function getThisYearTrainingDetailed(query) {
+  return request({
+    url: "/personTraining/getThisYearTrainingDetailed",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/api/cnas/systemManagement/customerSatisfaction.js b/src/api/cnas/systemManagement/customerSatisfaction.js
new file mode 100644
index 0000000..5368a4c
--- /dev/null
+++ b/src/api/cnas/systemManagement/customerSatisfaction.js
@@ -0,0 +1,56 @@
+// 瀹㈡埛婊℃剰搴︾浉鍏虫帴鍙�
+import request from "@/utils/request";
+
+//瀹㈡埛婊℃剰搴﹁皟鏌ュ垪琛�
+export function pageClientSatisfaction(query) {
+  return request({
+    url: "/clientSatisfaction/pageClientSatisfaction",
+    method: "get",
+    params: query,
+  });
+}
+
+//鏌ヨ瀹㈡埛鍒嗘瀽闄勪欢
+export function pageAnalyseFile(query) {
+  return request({
+    url: "/clientSatisfaction/pageAnalyseFile",
+    method: "get",
+    params: query,
+  });
+}
+
+//鍒犻櫎鏂板瀹㈡埛婊℃剰搴﹁皟鏌�
+export function delClientSatisfaction(query) {
+  return request({
+    url: "/clientSatisfaction/delClientSatisfaction",
+    method: "delete",
+    params: query,
+  });
+}
+
+//鍒犻櫎瀹㈡埛鍒嗘瀽闄勪欢
+export function delAnalyseFile(query) {
+  return request({
+    url: "/clientSatisfaction/delAnalyseFile",
+    method: "delete",
+    params: query,
+  });
+}
+
+// 鏂板瀹㈡埛婊℃剰搴﹁皟鏌�
+export function addClientSatisfaction(data) {
+  return request({
+    url: "/clientSatisfaction/addClientSatisfaction",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼鏂板瀹㈡埛婊℃剰搴﹁皟鏌�
+export function updateClientSatisfaction(data) {
+  return request({
+    url: "/clientSatisfaction/updateClientSatisfaction",
+    method: "post",
+    data: data,
+  });
+}
diff --git a/src/api/cnas/systemManagement/internalAuditManagement.js b/src/api/cnas/systemManagement/internalAuditManagement.js
new file mode 100644
index 0000000..4e22f4f
--- /dev/null
+++ b/src/api/cnas/systemManagement/internalAuditManagement.js
@@ -0,0 +1,386 @@
+// 鍐呭绠$悊鐩稿叧鎺ュ彛
+import request from "@/utils/request";
+
+//骞村害璁″垝-鍒嗛〉
+export function pageInternalPlan(query) {
+  return request({
+    url: "/internalPlan/pageInternalPlan",
+    method: "get",
+    params: query,
+  });
+}
+
+//骞村害璁″垝-鍒犻櫎
+export function delInternalPlan(query) {
+  return request({
+    url: "/internalPlan/delInternalPlan",
+    method: "delete",
+    params: query,
+  });
+}
+
+//骞村害璁″垝-瀵煎嚭
+export function exportInternalPlan(query) {
+  return request({
+    url: "/internalPlan/exportInternalPlan",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+//骞村害璁″垝璇︽儏
+export function getInternalPlanOne(query) {
+  return request({
+    url: "/internalPlan/getInternalPlanOne",
+    method: "get",
+    params: query,
+  });
+}
+
+// 骞村害璁″垝-鏂板
+export function addInternalPlan(data) {
+  return request({
+    url: "/internalPlan/addInternalPlan",
+    method: "post",
+    data: data,
+  });
+}
+
+// 骞村害璁″垝-淇敼
+export function updateInternalPlan(data) {
+  return request({
+    url: "/internalPlan/updateInternalPlan",
+    method: "post",
+    data: data,
+  });
+}
+
+// 骞村害璁″垝-瀹℃牳
+export function examineInternalPlan(data) {
+  return request({
+    url: "/internalPlan/examineInternalPlan",
+    method: "post",
+    data: data,
+  });
+}
+
+// 骞村害璁″垝-鎵瑰噯
+export function ratifyInternalPlan(data) {
+  return request({
+    url: "/internalPlan/ratifyInternalPlan",
+    method: "post",
+    data: data,
+  });
+}
+
+//鍐呭瀹炴柦璁″垝鍒嗛〉鏌ヨ
+export function pageInternalImplement(query) {
+  return request({
+    url: "/internalImplement/pageInternalImplement",
+    method: "get",
+    params: query,
+  });
+}
+
+//鍐呭瀹炴柦璁″垝鍒犻櫎
+export function delInternalImplement(query) {
+  return request({
+    url: "/internalImplement/delInternalImplement",
+    method: "delete",
+    params: query,
+  });
+}
+
+//瀵煎嚭鍐呭瀹炴柦璁″垝
+export function exportInternalImplement(query) {
+  return request({
+    url: "/internalImplement/exportInternalImplement",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+//鍐呭瀹炴柦璁″垝璇︽儏
+export function getInternalImplementOne(query) {
+  return request({
+    url: "/internalImplement/getInternalImplementOne",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鍐呭瀹炴柦璁″垝鏂板
+export function addInternalImplement(data) {
+  return request({
+    url: "/internalImplement/addInternalImplement",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍐呭瀹炴柦璁″垝淇敼
+export function updateInternalImplement(data) {
+  return request({
+    url: "/internalImplement/updateInternalImplement",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍐呭瀹炴柦璁″垝淇敼
+export function ratifyInternalImplement(data) {
+  return request({
+    url: "/internalImplement/ratifyInternalImplement",
+    method: "post",
+    data: data,
+  });
+}
+
+//浼氳绛惧埌鏌ヨ
+export function pageInternalMeeting(query) {
+  return request({
+    url: "/internalMeeting/pageInternalMeeting",
+    method: "get",
+    params: query,
+  });
+}
+
+// 浼氳绛惧埌鍒犻櫎
+export function delInternalMeeting(query) {
+  return request({
+    url: "/internalMeeting/delInternalMeeting",
+    method: "delete",
+    params: query,
+  });
+}
+
+//瀵煎嚭鍐呭浼氳
+export function exportInternalMeeting(query) {
+  return request({
+    url: "/internalMeeting/exportInternalMeeting",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+//浼氳绛惧埌鏌ヨ璇︽儏
+export function getInternalMeetingOne(query) {
+  return request({
+    url: "/internalMeeting/getInternalMeetingOne",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板浼氳绛惧埌
+export function addInternalMeeting(data) {
+  return request({
+    url: "/internalMeeting/addInternalMeeting",
+    method: "post",
+    data: data,
+  });
+}
+
+// 浼氳绛惧埌淇敼
+export function updateInternalMeeting(data) {
+  return request({
+    url: "/internalMeeting/updateInternalMeeting",
+    method: "post",
+    data: data,
+  });
+}
+
+//鍐呭妫�鏌ュ垎椤垫煡璇�
+export function pageInternalCheck(query) {
+  return request({
+    url: "/internalCheck/pageInternalCheck",
+    method: "get",
+    params: query,
+  });
+}
+
+//鍐呭妫�鏌ュ垹闄�
+export function delInternalCheck(query) {
+  return request({
+    url: "/internalCheck/delInternalCheck",
+    method: "delete",
+    params: query,
+  });
+}
+
+//瀵煎嚭鍐呭妫�鏌�
+export function exportInternalCheck(query) {
+  return request({
+    url: "/internalCheck/exportInternalCheck",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+//鍐呭妫�鏌ヨ鎯�
+export function getInternalCheckOne(query) {
+  return request({
+    url: "/internalCheck/getInternalCheckOne",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鍐呭妫�鏌ユ柊澧�
+export function addInternalCheck(data) {
+  return request({
+    url: "/internalCheck/addInternalCheck",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍐呭妫�鏌ヤ慨鏀�
+export function updateInternalCheck(data) {
+  return request({
+    url: "/internalCheck/updateInternalCheck",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍐呭妫�鏌ユ壒鍑�
+export function ratifyInternalCheck(data) {
+  return request({
+    url: "/internalCheck/ratifyInternalCheck",
+    method: "post",
+    data: data,
+  });
+}
+
+//鏌ヨ鍐呭绠$悊绾犳鎺柦鍒楄〃
+export function pageInternalCorrect(query) {
+  return request({
+    url: "/internalCorrect/pageInternalCorrect",
+    method: "get",
+    params: query,
+  });
+}
+
+//瀵煎嚭鍐呭绠$悊绾犳鎺柦闄勪欢
+export function exportInternalCorrect(query) {
+  return request({
+    url: "/internalCorrect/exportInternalCorrect",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+//鏌ヨ鍐呭绠$悊绾犳澶勭悊璇︽儏
+export function getInternalCorrect(query) {
+  return request({
+    url: "/internalCorrect/getInternalCorrect",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鎻愪氦鍐呭绠$悊绾犳鎺柦鍒楄〃
+export function addInternalCorrect(data) {
+  return request({
+    url: "/internalCorrect/addInternalCorrect",
+    method: "post",
+    data: data,
+  });
+}
+
+//鍐呭鎶ュ憡鍒犻櫎
+export function delInternalReport(query) {
+  return request({
+    url: "/internalReport/delInternalReport",
+    method: "delete",
+    params: query,
+  });
+}
+
+//鍐呭鎶ュ憡鍒嗛〉鏌ヨ
+export function pageInternalReport(query) {
+  return request({
+    url: "/internalReport/pageInternalReport",
+    method: "get",
+    params: query,
+  });
+}
+
+//瀵煎嚭鍐呭鎶ュ憡
+export function exportInternalReport(query) {
+  return request({
+    url: "/internalReport/exportInternalReport",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+//鍐呭鎶ュ憡璇︽儏
+export function getInternalReportOne(query) {
+  return request({
+    url: "/internalReport/getInternalReportOne",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鍐呭鎶ュ憡鏂板
+export function addInternalReport(data) {
+  return request({
+    url: "/internalReport/addInternalReport",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍐呭鎶ュ憡淇敼
+export function updateInternalReport(data) {
+  return request({
+    url: "/internalReport/updateInternalReport",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍐呭鎶ュ憡瀹℃牳
+export function examineInternalReport(data) {
+  return request({
+    url: "/internalReport/examineInternalReport",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍐呭鎶ュ憡璐熻矗浜哄~鍐�
+export function qualityInternalReport(data) {
+  return request({
+    url: "/internalReport/qualityInternalReport",
+    method: "post",
+    data: data,
+  });
+}
+
+//鏌ヨ鍐呭绠$悊绾犳鎺柦闄勪欢
+export function getInternalCorrectFileList(query) {
+  return request({
+    url: "/internalCorrect/getInternalCorrectFileList",
+    method: "get",
+    params: query,
+  });
+}
+
+//鍒犻櫎鍐呭绠$悊绾犳鎺柦闄勪欢
+export function delInternalCorrectFile(query) {
+  return request({
+    url: "/internalCorrect/delInternalCorrectFile",
+    method: "delete",
+    params: query,
+  });
+}
diff --git a/src/api/cnas/systemManagement/managementReview.js b/src/api/cnas/systemManagement/managementReview.js
new file mode 100644
index 0000000..5d410d3
--- /dev/null
+++ b/src/api/cnas/systemManagement/managementReview.js
@@ -0,0 +1,159 @@
+// 绠$悊璇勫鐩稿叧鎺ュ彛
+import request from "@/utils/request";
+
+// 绠$悊璁″垝-涓婁紶闄勪欢
+export function addReviewProgramFile(data) {
+  return request({
+    url: "/manageReviewProgramFile/addReviewProgramFile",
+    method: "post",
+    headers: { "Content-Type": "application/x-www-form-urlencoded" },
+    data: data,
+  });
+}
+
+//绠$悊璁″垝-闄勪欢鍒楄〃
+export function selectReviewProgramFile(query) {
+  return request({
+    url: "/manageReviewProgramFile/selectReviewProgramFile",
+    method: "get",
+    params: query,
+  });
+}
+
+//绠$悊璁″垝-鏌ヨ绠$悊璇勫璁″垝
+export function getPageReviewProgram(query) {
+  return request({
+    url: "/manageReviewProgram/getPageReviewProgram",
+    method: "get",
+    params: query,
+  });
+}
+
+//绠$悊璁″垝-鍒犻櫎绠$悊璇勫璁″垝
+export function deleteReviewProgram(query) {
+  return request({
+    url: "/manageReviewProgram/deleteReviewProgram",
+    method: "delete",
+    params: query,
+  });
+}
+
+//绠$悊璁″垝
+export function exportReviewProgram(query) {
+  return request({
+    url: "/manageReviewProgram/exportReviewProgram",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+// 绠$悊璁″垝-缂栬緫绠$悊璇勫璁″垝
+export function modifyReviewProgram(data) {
+  return request({
+    url: "/manageReviewProgram/modifyReviewProgram",
+    method: "post",
+    data: data,
+  });
+}
+
+//浼氳璁板綍-鏌ヨ绠$悊璇勫浼氳璁板綍
+export function getPageMeeting(query) {
+  return request({
+    url: "/manageMeeting/getPageMeeting",
+    method: "get",
+    params: query,
+  });
+}
+
+//浼氳璁板綍-鍒犻櫎绠$悊璇勫浼氳璁板綍
+export function deleteMeeting(query) {
+  return request({
+    url: "/manageMeeting/deleteMeeting",
+    method: "delete",
+    params: query,
+  });
+}
+
+//浼氳璁板綍-涓嬭浇绠$悊璇勫浼氳璁板綍
+export function exportMeeting(query) {
+  return request({
+    url: "/manageMeeting/exportMeeting",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+// 绠$悊璁″垝-鏂板绠$悊璇勫浼氳璁板綍
+export function addMeeting(data) {
+  return request({
+    url: "/manageMeeting/addMeeting",
+    method: "post",
+    data: data,
+  });
+}
+
+// 绠$悊璁″垝-淇敼绠$悊璇勫浼氳璁板綍
+export function modifyMeeting(data) {
+  return request({
+    url: "/manageMeeting/modifyMeeting",
+    method: "post",
+    data: data,
+  });
+}
+
+//璇勫浼氳鎶ュ憡-鏌ヨ绠$悊璇勫浼氳鎶ュ憡
+export function getPageReviewReport(query) {
+  return request({
+    url: "/manageReviewReport/getPageReviewReport",
+    method: "get",
+    params: query,
+  });
+}
+
+//璇勫浼氳鎶ュ憡-鍒犻櫎绠$悊璇勫浼氳鎶ュ憡
+export function deleteReviewReport(query) {
+  return request({
+    url: "/manageReviewReport/deleteReviewReport",
+    method: "delete",
+    params: query,
+  });
+}
+
+//璇勫浼氳鎶ュ憡-涓嬭浇
+export function exportReviewReport(query) {
+  return request({
+    url: "/manageReviewReport/exportReviewReport",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+// 璇勫浼氳鎶ュ憡-缂栬緫绠$悊璇勫浼氳鎶ュ憡
+export function modifyReviewReport(data) {
+  return request({
+    url: "/manageReviewReport/modifyReviewReport",
+    method: "post",
+    data: data,
+  });
+}
+
+// 璇勫浼氳鎶ュ憡-鏂板绠$悊璇勫浼氳鎶ュ憡
+export function addReviewReport(data) {
+  return request({
+    url: "/manageReviewReport/addReviewReport",
+    method: "post",
+    data: data,
+  });
+}
+
+// 璇勫浼氳鎶ュ憡-鏂板绠$悊璇勫璁″垝
+export function addReviewProgram(data) {
+  return request({
+    url: "/manageReviewProgram/addReviewProgram",
+    method: "post",
+    data: data,
+  });
+}
diff --git a/src/api/cnas/systemManagement/measuresDealRisks.js b/src/api/cnas/systemManagement/measuresDealRisks.js
new file mode 100644
index 0000000..268b1a0
--- /dev/null
+++ b/src/api/cnas/systemManagement/measuresDealRisks.js
@@ -0,0 +1,112 @@
+// 搴斿椋庨櫓鐨勬帾鏂界浉鍏虫帴鍙�
+import request from "@/utils/request";
+
+//鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙� 鍒嗛〉
+export function getPageResults(query) {
+  return request({
+    url: "/manageRiskAssessmentResults/getPageResults",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙� 瀹℃壒
+export function dangerousRiskApproval(data) {
+  return request({
+    url: "/manageRiskAssessmentResults/dangerousRiskApproval",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙� 鎵瑰噯
+export function hazardIdentificationAndRiskApproval(data) {
+  return request({
+    url: "/manageRiskAssessmentResults/hazardIdentificationAndRiskApproval",
+    method: "post",
+    data: data,
+  });
+}
+
+//鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙� 鍒犻櫎
+export function removeRiskFactors(query) {
+  return request({
+    url: "/manageRiskAssessmentResults/removeRiskFactors",
+    method: "delete",
+    params: query,
+  });
+}
+
+// 鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙� 鏂板
+export function addNewRiskFactors(data) {
+  return request({
+    url: "/manageRiskAssessmentResults/addNewRiskFactors",
+    method: "post",
+    data: data,
+  });
+}
+
+//鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙� 瀵煎嚭
+export function exportHazardFactorIdentification(query) {
+  return request({
+    url: "/manageRiskAssessmentResults/exportHazardFactorIdentification",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
+
+//閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗� 鍒嗛〉
+export function getPageList(query) {
+  return request({
+    url: "/manageControlPlanList/getPageList",
+    method: "get",
+    params: query,
+  });
+}
+
+// 閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗� 瀹℃牳
+export function riskAnalysisApprovalOfControlPlanChecklist(data) {
+  return request({
+    url: "/manageControlPlanList/riskAnalysisApprovalOfControlPlanChecklist",
+    method: "post",
+    data: data,
+  });
+}
+
+// 閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗� 鎵瑰噯
+export function approvalOfControlPlanChecklist(data) {
+  return request({
+    url: "/manageControlPlanList/approvalOfControlPlanChecklist",
+    method: "post",
+    data: data,
+  });
+}
+
+//閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗� 鍒犻櫎
+export function deleteSignificantRiskFactorAnalysis(query) {
+  return request({
+    url: "/manageControlPlanList/deleteSignificantRiskFactorAnalysis",
+    method: "delete",
+    params: query,
+  });
+}
+
+// 閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗� 鏂板
+export function analysisOfMajorRiskFactorsAdded(data) {
+  return request({
+    url: "/manageControlPlanList/analysisOfMajorRiskFactorsAdded",
+    method: "post",
+    data: data,
+  });
+}
+
+//閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗� 瀵煎嚭
+export function exportSignificantRiskFactors(query) {
+  return request({
+    url: "/manageControlPlanList/exportSignificantRiskFactors",
+    method: "get",
+    responseType: "blob",
+    params: query,
+  });
+}
diff --git a/src/api/system/user.js b/src/api/system/user.js
index 13fb049..bd2c924 100644
--- a/src/api/system/user.js
+++ b/src/api/system/user.js
@@ -1,182 +1,191 @@
-import request from '@/utils/request'
+import request from "@/utils/request";
 import { parseStrEmpty } from "@/utils/ruoyi";
 
 // 鏌ヨ鐢ㄦ埛鍒楄〃
 export function listUser(query) {
   return request({
-    url: '/system/user/list',
-    method: 'get',
-    params: query
-  })
+    url: "/system/user/list",
+    method: "get",
+    params: query,
+  });
 }
 
 // 鏌ヨ鐢ㄦ埛璇︾粏
 export function getUser(userId) {
   return request({
-    url: '/system/user/' + parseStrEmpty(userId),
-    method: 'get'
-  })
+    url: "/system/user/" + parseStrEmpty(userId),
+    method: "get",
+  });
 }
 
 // 鏂板鐢ㄦ埛
 export function addUser(data) {
   return request({
-    url: '/system/user',
-    method: 'post',
-    data: data
-  })
+    url: "/system/user",
+    method: "post",
+    data: data,
+  });
 }
 
 // 淇敼鐢ㄦ埛
 export function updateUser(data) {
   return request({
-    url: '/system/user',
-    method: 'put',
-    data: data
-  })
+    url: "/system/user",
+    method: "put",
+    data: data,
+  });
 }
 
 // 鍒犻櫎鐢ㄦ埛
 export function delUser(userId) {
   return request({
-    url: '/system/user/' + userId,
-    method: 'delete'
-  })
+    url: "/system/user/" + userId,
+    method: "delete",
+  });
 }
 
 // 鐢ㄦ埛瀵嗙爜閲嶇疆
 export function resetUserPwd(userId, password) {
   const data = {
     userId,
-    password
-  }
+    password,
+  };
   return request({
-    url: '/system/user/resetPwd',
-    method: 'put',
-    data: data
-  })
+    url: "/system/user/resetPwd",
+    method: "put",
+    data: data,
+  });
 }
 
 // 鐢ㄦ埛鐘舵�佷慨鏀�
 export function changeUserStatus(userId, status) {
   const data = {
     userId,
-    status
-  }
+    status,
+  };
   return request({
-    url: '/system/user/changeStatus',
-    method: 'put',
-    data: data
-  })
+    url: "/system/user/changeStatus",
+    method: "put",
+    data: data,
+  });
 }
 
 // 鏌ヨ鐢ㄦ埛涓汉淇℃伅
 export function getUserProfile() {
   return request({
-    url: '/system/user/profile',
-    method: 'get'
-  })
+    url: "/system/user/profile",
+    method: "get",
+  });
 }
 
 // 淇敼鐢ㄦ埛涓汉淇℃伅
 export function updateUserProfile(data) {
   return request({
-    url: '/system/user/profile',
-    method: 'put',
-    data: data
-  })
+    url: "/system/user/profile",
+    method: "put",
+    data: data,
+  });
 }
 
 // 鐢ㄦ埛瀵嗙爜閲嶇疆
 export function updateUserPwd(oldPassword, newPassword) {
   const data = {
     oldPassword,
-    newPassword
-  }
+    newPassword,
+  };
   return request({
-    url: '/system/user/profile/updatePwd',
-    method: 'put',
-    data: data
-  })
+    url: "/system/user/profile/updatePwd",
+    method: "put",
+    data: data,
+  });
 }
 
 // 鐢ㄦ埛澶村儚涓婁紶
 export function uploadAvatar(data) {
   return request({
-    url: '/system/user/profile/avatar',
-    method: 'post',
-    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
-    data: data
-  })
+    url: "/system/user/profile/avatar",
+    method: "post",
+    headers: { "Content-Type": "application/x-www-form-urlencoded" },
+    data: data,
+  });
 }
 
 // 鏌ヨ鎺堟潈瑙掕壊
 export function getAuthRole(userId) {
   return request({
-    url: '/system/user/authRole/' + userId,
-    method: 'get'
-  })
+    url: "/system/user/authRole/" + userId,
+    method: "get",
+  });
 }
 
 // 淇濆瓨鎺堟潈瑙掕壊
 export function updateAuthRole(data) {
   return request({
-    url: '/system/user/authRole',
-    method: 'put',
-    params: data
-  })
+    url: "/system/user/authRole",
+    method: "put",
+    params: data,
+  });
 }
 
 // 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋�
 export function deptTreeSelect() {
   return request({
-    url: '/system/user/deptTree',
-    method: 'get'
-  })
+    url: "/system/user/deptTree",
+    method: "get",
+  });
 }
 
 // 鑾峰彇浜轰簨绯荤粺缁勭粐
 export function selectCompaniesList() {
   return request({
-    url: '/companies/selectCompaniesList',
-    method: 'get'
-  })
+    url: "/companies/selectCompaniesList",
+    method: "get",
+  });
 }
 // 鑾峰彇浜轰簨绯荤粺缁勭粐涓嬬殑浜哄憳
 export function selectSimpleList(data) {
   return request({
-    url: '/companies/selectSimpleList',
-    method: 'post',
-    params: data
-  })
+    url: "/companies/selectSimpleList",
+    method: "post",
+    params: data,
+  });
 }
 // 鑾峰彇浜轰簨绯荤粺缁勭粐涓嬬殑浜哄憳
 export function addPersonUser(data) {
   return request({
-    url: '/companies/addPersonUser',
-    method: 'post',
-    params: data
-  })
+    url: "/companies/addPersonUser",
+    method: "post",
+    params: data,
+  });
 }
 // 鑾峰彇瑙掕壊
 export function selectRoleList() {
   return request({
-    url: '/role/selectRoleList',
-    method: 'get',
-  })
+    url: "/role/selectRoleList",
+    method: "get",
+  });
 }
 // 鑾峰彇鍗曚綅
 export function selectCustomEnum() {
   return request({
-    url: '/user/selectCustomEnum',
-    method: 'get',
-  })
+    url: "/user/selectCustomEnum",
+    method: "get",
+  });
 }
 // 鎻愪氦娣诲姞鏋舵瀯淇℃伅
 export function addDepartment(params) {
   return request({
-    url: '/department/addDepartment',
-    method: 'post',
-    params: params
-  })
+    url: "/department/addDepartment",
+    method: "post",
+    params: params,
+  });
+}
+
+// 鑾峰彇鐢ㄦ埛鍒楄〃
+export function selectUserCondition(query) {
+  return request({
+    url: "/system/newUser/selectUserCondition",
+    method: "get",
+    params: query,
+  });
 }
diff --git "a/src/assets/stamps/\344\270\273\344\273\273.png" "b/src/assets/stamps/\344\270\273\344\273\273.png"
new file mode 100644
index 0000000..f3312ee
--- /dev/null
+++ "b/src/assets/stamps/\344\270\273\344\273\273.png"
Binary files differ
diff --git "a/src/assets/stamps/\345\202\250\350\203\275.png" "b/src/assets/stamps/\345\202\250\350\203\275.png"
new file mode 100644
index 0000000..6260cad
--- /dev/null
+++ "b/src/assets/stamps/\345\202\250\350\203\275.png"
Binary files differ
diff --git "a/src/assets/stamps/\345\260\204\351\242\221.png" "b/src/assets/stamps/\345\260\204\351\242\221.png"
new file mode 100644
index 0000000..b243bd8
--- /dev/null
+++ "b/src/assets/stamps/\345\260\204\351\242\221.png"
Binary files differ
diff --git "a/src/assets/stamps/\346\212\200\346\234\257\350\264\237\350\264\243\344\272\272.png" "b/src/assets/stamps/\346\212\200\346\234\257\350\264\237\350\264\243\344\272\272.png"
new file mode 100644
index 0000000..630ede1
--- /dev/null
+++ "b/src/assets/stamps/\346\212\200\346\234\257\350\264\237\350\264\243\344\272\272.png"
Binary files differ
diff --git "a/src/assets/stamps/\347\224\265\345\212\233.png" "b/src/assets/stamps/\347\224\265\345\212\233.png"
new file mode 100644
index 0000000..cb873aa
--- /dev/null
+++ "b/src/assets/stamps/\347\224\265\345\212\233.png"
Binary files differ
diff --git "a/src/assets/stamps/\347\273\274\345\220\210\345\256\244.png" "b/src/assets/stamps/\347\273\274\345\220\210\345\256\244.png"
new file mode 100644
index 0000000..97fce30
--- /dev/null
+++ "b/src/assets/stamps/\347\273\274\345\220\210\345\256\244.png"
Binary files differ
diff --git "a/src/assets/stamps/\350\243\205\345\244\207.png" "b/src/assets/stamps/\350\243\205\345\244\207.png"
new file mode 100644
index 0000000..894f70d
--- /dev/null
+++ "b/src/assets/stamps/\350\243\205\345\244\207.png"
Binary files differ
diff --git "a/src/assets/stamps/\350\264\250\351\207\217\350\264\237\350\264\243\344\272\272.png" "b/src/assets/stamps/\350\264\250\351\207\217\350\264\237\350\264\243\344\272\272.png"
new file mode 100644
index 0000000..dde64e9
--- /dev/null
+++ "b/src/assets/stamps/\350\264\250\351\207\217\350\264\237\350\264\243\344\272\272.png"
Binary files differ
diff --git "a/src/assets/stamps/\351\200\232\344\277\241.png" "b/src/assets/stamps/\351\200\232\344\277\241.png"
new file mode 100644
index 0000000..232e283
--- /dev/null
+++ "b/src/assets/stamps/\351\200\232\344\277\241.png"
Binary files differ
diff --git a/src/components/Preview/filePreview.vue b/src/components/Preview/filePreview.vue
new file mode 100644
index 0000000..1105afc
--- /dev/null
+++ b/src/components/Preview/filePreview.vue
@@ -0,0 +1,230 @@
+<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" style="color: #3a7bfa;">涓嬭浇 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')
+      }
+      console.log(11111, this.imgUrl)
+      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>
diff --git a/src/components/Table/lims-table.vue b/src/components/Table/lims-table.vue
index d453b9e..26cc8df 100644
--- a/src/components/Table/lims-table.vue
+++ b/src/components/Table/lims-table.vue
@@ -1,183 +1,107 @@
 <template>
   <div>
     <!-- 琛ㄦ牸 -->
-    <el-table
-      ref="multipleTable"
-      v-loading="tableLoading"
-      :border="border"
-      :data="tableData"
-      :header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }"
-      :height="height"
-      :highlight-current-row="highlightCurrentRow"
-      :row-class-name="rowClassName"
-      :row-style="rowStyle"
-      :row-key="rowKey"
-      stripe
-      style="width: 100%"
-      tooltip-effect="dark"
-      @row-click="rowClick"
-      @current-change="currentChange"
-      @selection-change="handleSelectionChange"
-    >
-      <template v-if="isSelection">
-        <el-table-column type="selection" width="55" />
-      </template>
-      <template>
-        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-      </template>
+    <el-table ref="multipleTable" v-loading="tableLoading" :border="border" :data="tableData"
+      :header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }" :height="height"
+      :highlight-current-row="highlightCurrentRow" :row-class-name="rowClassName" :row-style="rowStyle"
+      :row-key="rowKey" :span-method="spanMethod" stripe style="width: 100%" tooltip-effect="dark" @row-click="rowClick"
+      @current-change="currentChange" @selection-change="handleSelectionChange" class="lims-table">
+      <el-table-column align="center" type="selection" width="55" v-if="isSelection" />
+      <el-table-column align="center" label="搴忓彿" type="index" width="60" :index="indexMethod" />
 
-      <template v-for="(item, index) in column">
-        <el-table-column
-          :column-key="item.columnKey"
-          :filter-method="item.filterHandler"
-          :filter-multiple="item.filterMultiple"
-          :filtered-value="item.filteredValue"
-          :filters="item.filters"
-          :fixed="item.fixed"
-          :label="item.label"
-          :min-width="item.minWidth"
-          :prop="item.prop"
-          :show-overflow-tooltip="item.showOverflowTooltip"
-          :sortable="item.sortable ? true : false"
-          :type="item.type"
-          :width="item.width"
-          align="center"
-        >
-          <!-- <div class="123" v-if="item.type == ''"> -->
-          <template
-            v-if="item.hasOwnProperty('colunmTemplate')"
-            :slot="item.colunmTemplate"
-            slot-scope="scope"
-          >
-            <slot
-              v-if="item.theadSlot"
-              :index="index"
-              :name="item.theadSlot"
-              :row="scope.row"
-            />
-          </template>
+      <el-table-column v-for="(item, index) in column" :key="index" :column-key="item.columnKey"
+        :filter-method="item.filterHandler" :filter-multiple="item.filterMultiple" :filtered-value="item.filteredValue"
+        :filters="item.filters" :fixed="item.fixed" :label="item.label" :min-width="item.minWidth" :prop="item.prop"
+        :show-overflow-tooltip="item.dataType === 'action' || item.dataType === 'slot' ? false : true"
+        :sortable="item.sortable ? true : false" :type="item.type"
+        :width="item.dataType === 'action' ? getWidth(item.operation) : item.width" align="center">
+        <!-- <div class="123" v-if="item.type == ''"> -->
+        <template v-if="item.hasOwnProperty('colunmTemplate')" :slot="item.colunmTemplate" slot-scope="scope">
+          <slot v-if="item.theadSlot" :index="index" :name="item.theadSlot" :row="scope.row" />
+        </template>
 
-          <template slot-scope="scope">
-            <!-- 鎻掓Ы -->
-            <div v-if="item.dataType == 'slot'">
-              <slot
-                v-if="item.slot"
-                :index="scope.$index"
-                :name="item.slot"
-                :row="scope.row"
-              />
-            </div>
-            <!-- 杩涘害鏉� -->
-            <div v-else-if="item.dataType == 'progress'">
-              <el-progress :percentage="Number(scope.row[item.prop])" />
-            </div>
+        <template slot-scope="scope">
+          <!-- 鎻掓Ы -->
+          <div v-if="item.dataType == 'slot'">
+            <slot v-if="item.slot" :index="scope.$index" :name="item.slot" :row="scope.row" />
+          </div>
+          <!-- 杩涘害鏉� -->
+          <div v-else-if="item.dataType == 'progress'">
+            <el-progress :percentage="Number(scope.row[item.prop])" />
+          </div>
+          <!-- 鍥剧墖 -->
+          <div v-else-if="item.dataType == 'image'">
+            <img :src="javaApi + '/img/' + scope.row[item.prop]" alt=""
+              style="width: 40px; height: 40px; margin-top: 10px" />
+          </div>
 
-            <!-- tag -->
-            <div v-else-if="item.dataType == 'tag'">
-              <el-tag
-                v-if="
-                  typeof dataTypeFn(scope.row[item.prop], item.formatData) ==
-                  'string'
-                "
-                :title="scope.row[item.prop] | formatters(item.formatData)"
-                :type="formatType(scope.row[item.prop], item.formatType)"
-                >{{
-                  scope.row[item.prop] | formatters(item.formatData)
-                }}</el-tag
-              >
-              <el-tag
-                v-for="(tag, index) in dataTypeFn(
-                  scope.row[item.prop],
-                  item.formatData
-                )"
-                v-else-if="
-                  typeof dataTypeFn(scope.row[item.prop], item.formatData) ==
-                  'object'
-                "
-                :key="index"
-                :title="scope.row[item.prop] | formatters(item.formatData)"
-                :type="formatType(tag, item.formatType)"
-                >{{
-                  item.tagGroup
+          <!-- tag -->
+          <div v-else-if="item.dataType == 'tag'">
+            <el-tag v-if="
+              typeof dataTypeFn(scope.row[item.prop], item.formatData) ==
+              'string'
+            " :title="scope.row[item.prop] | formatters(item.formatData)"
+              :type="formatType(scope.row[item.prop], item.formatType)">{{ scope.row[item.prop] |
+                formatters(item.formatData) }}</el-tag>
+            <el-tag v-for="(tag, index) in dataTypeFn(
+              scope.row[item.prop],
+              item.formatData
+            )" v-else-if="
+              typeof dataTypeFn(scope.row[item.prop], item.formatData) ==
+              'object'
+            " :key="index" :title="scope.row[item.prop] | formatters(item.formatData)"
+              :type="formatType(tag, item.formatType)">{{
+                item.tagGroup
+                  ? tag[item.tagGroup.label]
                     ? tag[item.tagGroup.label]
-                      ? tag[item.tagGroup.label]
-                      : tag
                     : tag
-                }}</el-tag
-              >
-              <el-tag
-                v-else
-                :title="scope.row[item.prop] | formatters(item.formatData)"
-                :type="formatType(scope.row[item.prop], item.formatType)"
-                >{{
-                  scope.row[item.prop] | formatters(item.formatData)
-                }}</el-tag
-              >
-            </div>
+                  : tag
+              }}</el-tag>
+            <el-tag v-else :title="scope.row[item.prop] | formatters(item.formatData)"
+              :type="formatType(scope.row[item.prop], item.formatType)">{{ scope.row[item.prop] |
+                formatters(item.formatData) }}</el-tag>
+          </div>
 
-            <!-- 鎸夐挳 -->
-            <div v-else-if="item.dataType == 'action'">
-              <template v-for="(o, key) in item.operation">
-                <el-button
-                  v-if="o.type != 'upload'"
-                  v-show="o.showHide ? o.showHide(scope.row) : true"
-                  :disabled="o.disabled ? o.disabled(scope.row) : false"
-                  :icon="o.icon | iconFn(scope.row)"
-                  :plain="o.plain"
-                  :size="o.size"
-                  :style="{ color: o.color }"
-                  :type="o.type | typeFn(scope.row)"
-                  @click="o.clickFun(scope.row)"
-                >
-                  {{ o.name }}
-                </el-button>
-                <el-upload
-                  action="#"
-                  :on-change="
-                    (file, fileList) => o.clickFun(scope.row, file, fileList)
-                  "
-                  :multiple="o.multiple ? o.multiple : false"
-                  :limit="o.limit ? o.limit : 1"
-                  :disabled="o.disabled ? o.disabled(scope.row) : false"
-                  :accept="
-                    o.accept
-                      ? o.accept
-                      : '.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'
-                  "
-                  v-if="o.type == 'upload'"
-                  style="display: inline-block; width: 50px"
-                  v-show="o.showHide ? o.showHide(scope.row) : true"
-                  :auto-upload="false"
-                  :on-exceed="onExceed"
-                  :show-file-list="false"
-                >
-                  <el-button
-                    :size="o.size ? o.size : 'small'"
-                    type="text"
-                    :disabled="o.disabled ? o.disabled(scope.row) : false"
-                    >{{ o.name }}</el-button
-                  >
-                </el-upload>
-              </template>
-            </div>
-            <!-- 榛樿绾睍绀烘暟鎹� -->
-            <div v-else>
-              <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
-              <span v-else>{{
-                scope.row[item.prop] | formatters(item.formatData)
-              }}</span>
-            </div>
-          </template>
-        </el-table-column>
-      </template>
+          <!-- 鎸夐挳 -->
+          <div v-else-if="item.dataType == 'action'">
+            <template v-for="(o, key) in item.operation">
+              <el-button v-show="o.type != 'upload'" size="mini" v-if="o.showHide ? o.showHide(scope.row) : true"
+                :disabled="o.disabled ? o.disabled(scope.row) : false" :icon="iconFn(o)" :plain="o.plain"
+                :style="{ color: o.name === '鍒犻櫎' ? '#f56c6c' : o.color }" :type="o.type | typeFn(scope.row)"
+                @click="o.clickFun(scope.row)" :key="key">
+                {{ o.name }}
+              </el-button>
+              <el-upload
+                :action="o.url ? (javaApi + o.url + '?id=' + (o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id)) : '#'"
+                size="mini" ref="upload" :multiple="o.multiple ? o.multiple : false" :limit="1"
+                :disabled="o.disabled ? o.disabled(scope.row) : false" :accept="o.accept
+                  ? o.accept
+                  : '.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'
+                  " v-if="o.type == 'upload'" style="display: inline-block; width: 50px"
+                v-show="o.showHide ? o.showHide(scope.row) : true" :headers="uploadHeader" :on-error="onError"
+                :on-exceed="onExceed" :on-success="handleSuccessUp" :show-file-list="false" :key="key">
+                <el-button :size="o.size ? o.size : 'small'" type="text"
+                  :disabled="o.disabled ? o.disabled(scope.row) : false">{{ o.name }}</el-button>
+              </el-upload>
+            </template>
+          </div>
+          <!-- 鍙偣鍑荤殑鏂囧瓧 -->
+          <div v-else-if="item.dataType == 'link'" class="cell link" style="width: 100%"
+            @click="goLink(scope.row, item.linkMethod)">
+            <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
+          </div>
+          <!-- 榛樿绾睍绀烘暟鎹� -->
+          <div v-else class="cell" style="width: 100%">
+            <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
+            <span v-else>{{
+              scope.row[item.prop] | formatters(item.formatData)
+            }}</span>
+          </div>
+        </template>
+      </el-table-column>
     </el-table>
-    <pagination
-      v-show="page.total > 0"
-      :total="page.total"
-      :page.sync="page.current"
-      :limit.sync="page.size"
-      @pagination="pagination"
-    />
+    <pagination v-show="page.total > 0" :total="page.total" :layout="page.layout" :page.sync="page.current"
+      :limit.sync="page.size" @pagination="pagination" />
   </div>
 </template>
 
@@ -234,11 +158,6 @@
 export default {
   name: "ZTTable",
   filters: {
-    iconFn(val, row) {
-      if (typeof val === "function") {
-        return val(row);
-      } else return val;
-    },
     typeFn(val, row) {
       // console.log(val, row, '11111111');
       if (typeof val === "function") {
@@ -272,24 +191,24 @@
     handleSelectionChange: {
       type: Function,
       default: () => {
-        return () => {};
+        return () => { };
       },
     },
     rowClick: {
       type: Function,
       default: () => {
-        return () => {};
+        return () => { };
       },
     },
     currentChange: {
       type: Function,
       default: () => {
-        return () => {};
+        return () => { };
       },
     },
     border: {
       type: Boolean,
-      default: false,
+      default: true,
     },
     highlightCurrentRow: {
       type: Boolean,
@@ -309,11 +228,11 @@
     },
     rowClassName: {
       type: Function,
-      default: () => {},
+      default: () => { },
     },
     rowStyle: {
       type: Object || Function,
-      default: () => {},
+      default: () => { },
     },
     tableData: {
       type: Array,
@@ -332,12 +251,45 @@
           total: 0,
           current: 0,
           size: 10,
+          layout: "total, sizes, prev, pager, next, jumper",
         };
       },
     },
   },
-
+  data() {
+    return {
+      spanList: [],
+    };
+  },
+  mounted() {
+    this.calculateSpanInfo();
+  },
   methods: {
+    getWidth(row) {
+      let count = 0;
+      row.forEach((a) => {
+        if (a.showHide !== undefined && a.showHide()) {
+          count += a.name.length;
+        } else if (!a.showHide) {
+          count += a.name.length;
+        }
+      });
+      return count * 15 + 70 + "px";
+    },
+    iconFn(row) {
+      if (row.name === "缂栬緫" || row.name === "淇敼") {
+        return "el-icon-edit";
+      } else if (row.name === "鍒犻櫎") {
+        return "el-icon-delete";
+      } else if (row.name === "鏌ョ湅") {
+        return "el-icon-view";
+      } else {
+        return row.icon;
+      }
+      // if (typeof (val) === 'function') {
+      //   return val(row);
+      // } else return val;
+    },
     formatType(val, format) {
       if (typeof format === "function") {
         return format(val);
@@ -351,18 +303,171 @@
     setCurrent(row) {
       this.$refs.multipleTable.setCurrentRow();
     },
+    handleSuccessUp(response, label) {
+      if (typeof label === "string") {
+        if (response.code == 200) {
+          this.upData[label] = response.data.url;
+        }
+      } else {
+        if (response.code == 200) {
+          this.$message.success("涓婁紶鎴愬姛");
+        }
+      }
+    },
+    onError(err, file, fileList) {
+      this.$message.error("涓婁紶澶辫触");
+      this.$refs.upload.clearFiles();
+      this.uploading = false;
+    },
     onExceed() {
       this.$message.warning("瓒呭嚭鏂囦欢涓暟");
     },
-    pagination(page, limit) {
-      this.$emit("pagination", { pageNum: page, pageSize: limit });
+    pagination({ page, limit }) {
+      this.$emit("pagination", { page: page, limit: limit });
+    },
+    indexMethod(index) {
+      // return index * 2;
+      return (this.page.current - 1) * this.page.size + index + 1;
+    },
+    // 鐐瑰嚮鍗曞厓鏍糽ink浜嬩欢
+    goLink(row, linkMethod) {
+      if (!linkMethod) {
+        return this.$message.warning("璇烽厤缃甽ingk浜嬩欢");
+      }
+      this.$parent[linkMethod](row);
+    },
+    // 鍚堝苟鍗曞厓鏍�
+    calculateSpanInfo() {
+      // 鍒濆鍖栨瘡鍒楃殑鍚堝苟淇℃伅
+      this.spanList = [];
+      this.column.forEach((m, i) => {
+        if (m.mergeCol) {
+          this.spanList.push({
+            arr: [],
+            position: 0,
+            name: m.prop,
+            index: i + 1,
+          });
+        }
+      });
+      this.spanList.forEach((item, i) => {
+        this.rowspan(
+          this.spanList[i].arr,
+          this.spanList[i].position,
+          item.name
+        );
+      });
+    },
+    rowspan(spanArr, position, spanName) {
+      this.tableData.forEach((item, index) => {
+        if (index === 0) {
+          spanArr.push(1);
+          position = 0;
+        } else {
+          if (
+            this.tableData[index][spanName] ===
+            this.tableData[index - 1][spanName]
+          ) {
+            spanArr[position] += 1;
+            spanArr.push(0);
+          } else {
+            spanArr.push(1);
+            position = index;
+          }
+        }
+      });
+    },
+    // 鍚堝苟鍗曞厓鏍�
+    spanMethod({ row, column, rowIndex, columnIndex }) {
+      // 涓�鑸殑鍚堝苟琛�
+      if (this.column.find((m) => m.mergeCol)) {
+        let i = null;
+        let obj = this.spanList.find((item, index) => {
+          i = index;
+          return item.index == columnIndex;
+        });
+        if (obj) {
+          const _row = this.spanList[i].arr[rowIndex];
+          const _col = _row > 0 ? 1 : 0;
+          return {
+            rowspan: _row,
+            colspan: _col,
+          };
+        }
+      }
+      // // 鐗规畩鐨勫悎骞惰
+      // if (
+      //   this.data.spanConfig != undefined &&
+      //   this.data.spanConfig.special &&
+      //   this.data.spanConfig.special.main &&
+      //   this.data.spanConfig.special.rows &&
+      //   this.data.spanConfig.special.rows.length > 0
+      // ) {
+      //   let i = null;
+      //   let obj = this.data.spanConfig.special.rows.find((item, index) => {
+      //     i = index;
+      //     return item.index == columnIndex;
+      //   });
+      //   if (obj) {
+      //     const _row = this.specialSpanList[i].arr[rowIndex];
+      //     const _col = _row > 0 ? 1 : 0;
+      //     return {
+      //       rowspan: _row,
+      //       colspan: _col,
+      //     };
+      //   }
+      // }
     },
   },
 };
 </script>
 
 <style scoped>
-.el-table >>> .el-table__empty-text {
+.el-table>>>.el-table__empty-text {
   text-align: center;
 }
+
+>>>.cell {
+  padding: 0 !important;
+}
+
+.cell {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding-right: 4px !important;
+  padding-left: 10px !important;
+}
+
+.link {
+  color: rgb(64, 158, 255);
+  cursor: pointer;
+}
+
+>>>.el-table__body-wrapper::-webkit-scrollbar {
+  height: 14px;
+  /* 璁剧疆婊氬姩鏉″搴� */
+}
+</style>
+<style>
+.lims-table .highlight-warning-row-border td:first-child {
+  border-left: 4px solid #ffcd29;
+}
+
+.lims-table .highlight-warning-row-border td:last-child {
+  border-right: 4px solid #ffcd29;
+}
+
+/* .lims-table .highlight-danger-row-border td {
+		border-top: 2px solid red;
+		border-bottom: 2px solid red;
+	} */
+
+.lims-table .highlight-danger-row-border td:first-child {
+  border-left: 4px solid #f56c6c;
+}
+
+.lims-table .highlight-danger-row-border td:last-child {
+  border-right: 4px solid #f56c6c;
+}
 </style>
diff --git a/src/main.js b/src/main.js
index 7f0fd18..870a586 100644
--- a/src/main.js
+++ b/src/main.js
@@ -26,6 +26,7 @@
   selectDictLabels,
   handleTree,
 } from "@/utils/ruoyi";
+import { dictToValue } from "@/utils/index";
 // 鍒嗛〉缁勪欢
 import Pagination from "@/components/Pagination";
 // 鑷畾涔夎〃鏍煎伐鍏风粍浠�
@@ -59,6 +60,7 @@
 Vue.prototype.selectDictLabels = selectDictLabels;
 Vue.prototype.download = download;
 Vue.prototype.handleTree = handleTree;
+Vue.prototype.dictToValue = dictToValue;
 Vue.prototype.HaveJson = (val) => {
   return JSON.parse(JSON.stringify(val));
 };
diff --git a/src/store/getters.js b/src/store/getters.js
index 8adb1b6..0d93723 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -1,19 +1,21 @@
 const getters = {
-  sidebar: state => state.app.sidebar,
-  size: state => state.app.size,
-  device: state => state.app.device,
-  dict: state => state.dict.dict,
-  visitedViews: state => state.tagsView.visitedViews,
-  cachedViews: state => state.tagsView.cachedViews,
-  token: state => state.user.token,
-  avatar: state => state.user.avatar,
-  name: state => state.user.name,
-  introduction: state => state.user.introduction,
-  roles: state => state.user.roles,
-  permissions: state => state.user.permissions,
-  permission_routes: state => state.permission.routes,
-  topbarRouters:state => state.permission.topbarRouters,
-  defaultRoutes:state => state.permission.defaultRoutes,
-  sidebarRouters:state => state.permission.sidebarRouters,
-}
-export default getters
+  sidebar: (state) => state.app.sidebar,
+  size: (state) => state.app.size,
+  device: (state) => state.app.device,
+  dict: (state) => state.dict.dict,
+  visitedViews: (state) => state.tagsView.visitedViews,
+  cachedViews: (state) => state.tagsView.cachedViews,
+  token: (state) => state.user.token,
+  avatar: (state) => state.user.avatar,
+  name: (state) => state.user.name,
+  nickName: (state) => state.user.nickName,
+  userId: (state) => state.user.id,
+  introduction: (state) => state.user.introduction,
+  roles: (state) => state.user.roles,
+  permissions: (state) => state.user.permissions,
+  permission_routes: (state) => state.permission.routes,
+  topbarRouters: (state) => state.permission.topbarRouters,
+  defaultRoutes: (state) => state.permission.defaultRoutes,
+  sidebarRouters: (state) => state.permission.sidebarRouters,
+};
+export default getters;
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 63e6ba2..54d35ca 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -1,106 +1,120 @@
-import { login, logout, getInfo } from '@/api/login'
-import { getToken, setToken, removeToken } from '@/utils/auth'
-import { isHttp, isEmpty } from "@/utils/validate"
-import defAva from '@/assets/images/profile.jpg'
+import { login, logout, getInfo } from "@/api/login";
+import { getToken, setToken, removeToken } from "@/utils/auth";
+import { isHttp, isEmpty } from "@/utils/validate";
+import defAva from "@/assets/images/profile.jpg";
 
 const user = {
   state: {
     token: getToken(),
-    id: '',
-    name: '',
-    avatar: '',
+    id: "",
+    name: "",
+    avatar: "",
+    nickName: "",
     roles: [],
-    permissions: []
+    permissions: [],
   },
 
   mutations: {
     SET_TOKEN: (state, token) => {
-      state.token = token
+      state.token = token;
     },
     SET_ID: (state, id) => {
-      state.id = id
+      state.id = id;
     },
     SET_NAME: (state, name) => {
-      state.name = name
+      state.name = name;
     },
     SET_AVATAR: (state, avatar) => {
-      state.avatar = avatar
+      state.avatar = avatar;
+    },
+    SET_NICKNAME: (state, nickName) => {
+      state.nickName = nickName;
     },
     SET_ROLES: (state, roles) => {
-      state.roles = roles
+      state.roles = roles;
     },
     SET_PERMISSIONS: (state, permissions) => {
-      state.permissions = permissions
-    }
+      state.permissions = permissions;
+    },
   },
 
   actions: {
     // 鐧诲綍
     Login({ commit }, userInfo) {
-      const username = userInfo.username.trim()
-      const password = userInfo.password
-      const code = userInfo.code
-      const uuid = userInfo.uuid
+      const username = userInfo.username.trim();
+      const password = userInfo.password;
+      const code = userInfo.code;
+      const uuid = userInfo.uuid;
       return new Promise((resolve, reject) => {
-        login(username, password, code, uuid).then(res => {
-          setToken(res.token)
-          commit('SET_TOKEN', res.token)
-          resolve()
-        }).catch(error => {
-          reject(error)
-        })
-      })
+        login(username, password, code, uuid)
+          .then((res) => {
+            setToken(res.token);
+            commit("SET_TOKEN", res.token);
+            resolve();
+          })
+          .catch((error) => {
+            reject(error);
+          });
+      });
     },
 
     // 鑾峰彇鐢ㄦ埛淇℃伅
     GetInfo({ commit, state }) {
       return new Promise((resolve, reject) => {
-        getInfo().then(res => {
-          const user = res.user
-          let avatar = user.avatar || ""
-          if (!isHttp(avatar)) {
-            avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
-          }
-          if (res.roles && res.roles.length > 0) { // 楠岃瘉杩斿洖鐨剅oles鏄惁鏄竴涓潪绌烘暟缁�
-            commit('SET_ROLES', res.roles)
-            commit('SET_PERMISSIONS', res.permissions)
-          } else {
-            commit('SET_ROLES', ['ROLE_DEFAULT'])
-          }
-          commit('SET_ID', user.userId)
-          commit('SET_NAME', user.userName)
-          commit('SET_AVATAR', avatar)
-          resolve(res)
-        }).catch(error => {
-          reject(error)
-        })
-      })
+        getInfo()
+          .then((res) => {
+            const user = res.user;
+            let avatar = user.avatar || "";
+            if (!isHttp(avatar)) {
+              avatar = isEmpty(avatar)
+                ? defAva
+                : process.env.VUE_APP_BASE_API + avatar;
+            }
+            if (res.roles && res.roles.length > 0) {
+              // 楠岃瘉杩斿洖鐨剅oles鏄惁鏄竴涓潪绌烘暟缁�
+              commit("SET_ROLES", res.roles);
+              commit("SET_PERMISSIONS", res.permissions);
+            } else {
+              commit("SET_ROLES", ["ROLE_DEFAULT"]);
+            }
+            commit("SET_ID", user.userId);
+            commit("SET_NAME", user.userName);
+            commit("SET_AVATAR", avatar);
+            commit("SET_NICKNAME", user.nickName);
+            resolve(res);
+          })
+          .catch((error) => {
+            reject(error);
+          });
+      });
     },
 
     // 閫�鍑虹郴缁�
     LogOut({ commit, state }) {
       return new Promise((resolve, reject) => {
-        logout(state.token).then(() => {
-          commit('SET_TOKEN', '')
-          commit('SET_ROLES', [])
-          commit('SET_PERMISSIONS', [])
-          removeToken()
-          resolve()
-        }).catch(error => {
-          reject(error)
-        })
-      })
+        logout(state.token)
+          .then(() => {
+            commit("SET_TOKEN", "");
+            commit("SET_ROLES", []);
+            commit("SET_PERMISSIONS", []);
+            removeToken();
+            resolve();
+          })
+          .catch((error) => {
+            reject(error);
+          });
+      });
     },
 
     // 鍓嶇 鐧诲嚭
     FedLogOut({ commit }) {
-      return new Promise(resolve => {
-        commit('SET_TOKEN', '')
-        removeToken()
-        resolve()
-      })
-    }
-  }
-}
+      return new Promise((resolve) => {
+        commit("SET_TOKEN", "");
+        removeToken();
+        resolve();
+      });
+    },
+  },
+};
 
-export default user
+export default user;
diff --git a/src/utils/index.js b/src/utils/index.js
index df5db12..6a246f9 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -1,18 +1,25 @@
-import { parseTime } from './ruoyi'
+import { parseTime } from "./ruoyi";
 
 /**
  * 琛ㄦ牸鏃堕棿鏍煎紡鍖�
  */
 export function formatDate(cellValue) {
   if (cellValue == null || cellValue == "") return "";
-  var date = new Date(cellValue)
-  var year = date.getFullYear()
-  var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
-  var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
-  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
-  var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
-  var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
-  return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+  var date = new Date(cellValue);
+  var year = date.getFullYear();
+  var month =
+    date.getMonth() + 1 < 10
+      ? "0" + (date.getMonth() + 1)
+      : date.getMonth() + 1;
+  var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
+  var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
+  var minutes =
+    date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
+  var seconds =
+    date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
+  return (
+    year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds
+  );
 }
 
 /**
@@ -21,40 +28,40 @@
  * @returns {string}
  */
 export function formatTime(time, option) {
-  if (('' + time).length === 10) {
-    time = parseInt(time) * 1000
+  if (("" + time).length === 10) {
+    time = parseInt(time) * 1000;
   } else {
-    time = +time
+    time = +time;
   }
-  const d = new Date(time)
-  const now = Date.now()
+  const d = new Date(time);
+  const now = Date.now();
 
-  const diff = (now - d) / 1000
+  const diff = (now - d) / 1000;
 
   if (diff < 30) {
-    return '鍒氬垰'
+    return "鍒氬垰";
   } else if (diff < 3600) {
     // less 1 hour
-    return Math.ceil(diff / 60) + '鍒嗛挓鍓�'
+    return Math.ceil(diff / 60) + "鍒嗛挓鍓�";
   } else if (diff < 3600 * 24) {
-    return Math.ceil(diff / 3600) + '灏忔椂鍓�'
+    return Math.ceil(diff / 3600) + "灏忔椂鍓�";
   } else if (diff < 3600 * 24 * 2) {
-    return '1澶╁墠'
+    return "1澶╁墠";
   }
   if (option) {
-    return parseTime(time, option)
+    return parseTime(time, option);
   } else {
     return (
       d.getMonth() +
       1 +
-      '鏈�' +
+      "鏈�" +
       d.getDate() +
-      '鏃�' +
+      "鏃�" +
       d.getHours() +
-      '鏃�' +
+      "鏃�" +
       d.getMinutes() +
-      '鍒�'
-    )
+      "鍒�"
+    );
   }
 }
 
@@ -63,18 +70,18 @@
  * @returns {Object}
  */
 export function getQueryObject(url) {
-  url = url == null ? window.location.href : url
-  const search = url.substring(url.lastIndexOf('?') + 1)
-  const obj = {}
-  const reg = /([^?&=]+)=([^?&=]*)/g
+  url = url == null ? window.location.href : url;
+  const search = url.substring(url.lastIndexOf("?") + 1);
+  const obj = {};
+  const reg = /([^?&=]+)=([^?&=]*)/g;
   search.replace(reg, (rs, $1, $2) => {
-    const name = decodeURIComponent($1)
-    let val = decodeURIComponent($2)
-    val = String(val)
-    obj[name] = val
-    return rs
-  })
-  return obj
+    const name = decodeURIComponent($1);
+    let val = decodeURIComponent($2);
+    val = String(val);
+    obj[name] = val;
+    return rs;
+  });
+  return obj;
 }
 
 /**
@@ -83,14 +90,14 @@
  */
 export function byteLength(str) {
   // returns the byte length of an utf8 string
-  let s = str.length
+  let s = str.length;
   for (var i = str.length - 1; i >= 0; i--) {
-    const code = str.charCodeAt(i)
-    if (code > 0x7f && code <= 0x7ff) s++
-    else if (code > 0x7ff && code <= 0xffff) s += 2
-    if (code >= 0xDC00 && code <= 0xDFFF) i--
+    const code = str.charCodeAt(i);
+    if (code > 0x7f && code <= 0x7ff) s++;
+    else if (code > 0x7ff && code <= 0xffff) s += 2;
+    if (code >= 0xdc00 && code <= 0xdfff) i--;
   }
-  return s
+  return s;
 }
 
 /**
@@ -98,13 +105,13 @@
  * @returns {Array}
  */
 export function cleanArray(actual) {
-  const newArray = []
+  const newArray = [];
   for (let i = 0; i < actual.length; i++) {
     if (actual[i]) {
-      newArray.push(actual[i])
+      newArray.push(actual[i]);
     }
   }
-  return newArray
+  return newArray;
 }
 
 /**
@@ -112,13 +119,13 @@
  * @returns {Array}
  */
 export function param(json) {
-  if (!json) return ''
+  if (!json) return "";
   return cleanArray(
-    Object.keys(json).map(key => {
-      if (json[key] === undefined) return ''
-      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
+    Object.keys(json).map((key) => {
+      if (json[key] === undefined) return "";
+      return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
     })
-  ).join('&')
+  ).join("&");
 }
 
 /**
@@ -126,21 +133,21 @@
  * @returns {Object}
  */
 export function param2Obj(url) {
-  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+  const search = decodeURIComponent(url.split("?")[1]).replace(/\+/g, " ");
   if (!search) {
-    return {}
+    return {};
   }
-  const obj = {}
-  const searchArr = search.split('&')
-  searchArr.forEach(v => {
-    const index = v.indexOf('=')
+  const obj = {};
+  const searchArr = search.split("&");
+  searchArr.forEach((v) => {
+    const index = v.indexOf("=");
     if (index !== -1) {
-      const name = v.substring(0, index)
-      const val = v.substring(index + 1, v.length)
-      obj[name] = val
+      const name = v.substring(0, index);
+      const val = v.substring(index + 1, v.length);
+      obj[name] = val;
     }
-  })
-  return obj
+  });
+  return obj;
 }
 
 /**
@@ -148,9 +155,9 @@
  * @returns {string}
  */
 export function html2Text(val) {
-  const div = document.createElement('div')
-  div.innerHTML = val
-  return div.textContent || div.innerText
+  const div = document.createElement("div");
+  div.innerHTML = val;
+  return div.textContent || div.innerText;
 }
 
 /**
@@ -160,21 +167,21 @@
  * @returns {Object}
  */
 export function objectMerge(target, source) {
-  if (typeof target !== 'object') {
-    target = {}
+  if (typeof target !== "object") {
+    target = {};
   }
   if (Array.isArray(source)) {
-    return source.slice()
+    return source.slice();
   }
-  Object.keys(source).forEach(property => {
-    const sourceProperty = source[property]
-    if (typeof sourceProperty === 'object') {
-      target[property] = objectMerge(target[property], sourceProperty)
+  Object.keys(source).forEach((property) => {
+    const sourceProperty = source[property];
+    if (typeof sourceProperty === "object") {
+      target[property] = objectMerge(target[property], sourceProperty);
     } else {
-      target[property] = sourceProperty
+      target[property] = sourceProperty;
     }
-  })
-  return target
+  });
+  return target;
 }
 
 /**
@@ -183,18 +190,18 @@
  */
 export function toggleClass(element, className) {
   if (!element || !className) {
-    return
+    return;
   }
-  let classString = element.className
-  const nameIndex = classString.indexOf(className)
+  let classString = element.className;
+  const nameIndex = classString.indexOf(className);
   if (nameIndex === -1) {
-    classString += '' + className
+    classString += "" + className;
   } else {
     classString =
       classString.substr(0, nameIndex) +
-      classString.substr(nameIndex + className.length)
+      classString.substr(nameIndex + className.length);
   }
-  element.className = classString
+  element.className = classString;
 }
 
 /**
@@ -202,10 +209,10 @@
  * @returns {Date}
  */
 export function getTime(type) {
-  if (type === 'start') {
-    return new Date().getTime() - 3600 * 1000 * 24 * 90
+  if (type === "start") {
+    return new Date().getTime() - 3600 * 1000 * 24 * 90;
   } else {
-    return new Date(new Date().toDateString())
+    return new Date(new Date().toDateString());
   }
 }
 
@@ -216,38 +223,38 @@
  * @return {*}
  */
 export function debounce(func, wait, immediate) {
-  let timeout, args, context, timestamp, result
+  let timeout, args, context, timestamp, result;
 
-  const later = function() {
+  const later = function () {
     // 鎹笂涓�娆¤Е鍙戞椂闂撮棿闅�
-    const last = +new Date() - timestamp
+    const last = +new Date() - timestamp;
 
     // 涓婃琚寘瑁呭嚱鏁拌璋冪敤鏃堕棿闂撮殧 last 灏忎簬璁惧畾鏃堕棿闂撮殧 wait
     if (last < wait && last > 0) {
-      timeout = setTimeout(later, wait - last)
+      timeout = setTimeout(later, wait - last);
     } else {
-      timeout = null
+      timeout = null;
       // 濡傛灉璁惧畾涓篿mmediate===true锛屽洜涓哄紑濮嬭竟鐣屽凡缁忚皟鐢ㄨ繃浜嗘澶勬棤闇�璋冪敤
       if (!immediate) {
-        result = func.apply(context, args)
-        if (!timeout) context = args = null
+        result = func.apply(context, args);
+        if (!timeout) context = args = null;
       }
     }
-  }
+  };
 
-  return function(...args) {
-    context = this
-    timestamp = +new Date()
-    const callNow = immediate && !timeout
+  return function (...args) {
+    context = this;
+    timestamp = +new Date();
+    const callNow = immediate && !timeout;
     // 濡傛灉寤舵椂涓嶅瓨鍦紝閲嶆柊璁惧畾寤舵椂
-    if (!timeout) timeout = setTimeout(later, wait)
+    if (!timeout) timeout = setTimeout(later, wait);
     if (callNow) {
-      result = func.apply(context, args)
-      context = args = null
+      result = func.apply(context, args);
+      context = args = null;
     }
 
-    return result
-  }
+    return result;
+  };
 }
 
 /**
@@ -258,18 +265,18 @@
  * @returns {Object}
  */
 export function deepClone(source) {
-  if (!source && typeof source !== 'object') {
-    throw new Error('error arguments', 'deepClone')
+  if (!source && typeof source !== "object") {
+    throw new Error("error arguments", "deepClone");
   }
-  const targetObj = source.constructor === Array ? [] : {}
-  Object.keys(source).forEach(keys => {
-    if (source[keys] && typeof source[keys] === 'object') {
-      targetObj[keys] = deepClone(source[keys])
+  const targetObj = source.constructor === Array ? [] : {};
+  Object.keys(source).forEach((keys) => {
+    if (source[keys] && typeof source[keys] === "object") {
+      targetObj[keys] = deepClone(source[keys]);
     } else {
-      targetObj[keys] = source[keys]
+      targetObj[keys] = source[keys];
     }
-  })
-  return targetObj
+  });
+  return targetObj;
 }
 
 /**
@@ -277,16 +284,16 @@
  * @returns {Array}
  */
 export function uniqueArr(arr) {
-  return Array.from(new Set(arr))
+  return Array.from(new Set(arr));
 }
 
 /**
  * @returns {string}
  */
 export function createUniqueString() {
-  const timestamp = +new Date() + ''
-  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
-  return (+(randomNum + timestamp)).toString(32)
+  const timestamp = +new Date() + "";
+  const randomNum = parseInt((1 + Math.random()) * 65536) + "";
+  return (+(randomNum + timestamp)).toString(32);
 }
 
 /**
@@ -296,7 +303,7 @@
  * @returns {boolean}
  */
 export function hasClass(ele, cls) {
-  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
+  return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
 }
 
 /**
@@ -305,7 +312,7 @@
  * @param {string} cls
  */
 export function addClass(ele, cls) {
-  if (!hasClass(ele, cls)) ele.className += ' ' + cls
+  if (!hasClass(ele, cls)) ele.className += " " + cls;
 }
 
 /**
@@ -315,76 +322,84 @@
  */
 export function removeClass(ele, cls) {
   if (hasClass(ele, cls)) {
-    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
-    ele.className = ele.className.replace(reg, ' ')
+    const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
+    ele.className = ele.className.replace(reg, " ");
   }
 }
 
 export function makeMap(str, expectsLowerCase) {
-  const map = Object.create(null)
-  const list = str.split(',')
+  const map = Object.create(null);
+  const list = str.split(",");
   for (let i = 0; i < list.length; i++) {
-    map[list[i]] = true
+    map[list[i]] = true;
   }
-  return expectsLowerCase
-    ? val => map[val.toLowerCase()]
-    : val => map[val]
+  return expectsLowerCase ? (val) => map[val.toLowerCase()] : (val) => map[val];
 }
 
-export const exportDefault = 'export default '
+export const exportDefault = "export default ";
 
 export const beautifierConf = {
   html: {
-    indent_size: '2',
-    indent_char: ' ',
-    max_preserve_newlines: '-1',
+    indent_size: "2",
+    indent_char: " ",
+    max_preserve_newlines: "-1",
     preserve_newlines: false,
     keep_array_indentation: false,
     break_chained_methods: false,
-    indent_scripts: 'separate',
-    brace_style: 'end-expand',
+    indent_scripts: "separate",
+    brace_style: "end-expand",
     space_before_conditional: true,
     unescape_strings: false,
     jslint_happy: false,
     end_with_newline: true,
-    wrap_line_length: '110',
+    wrap_line_length: "110",
     indent_inner_html: true,
     comma_first: false,
     e4x: true,
-    indent_empty_lines: true
+    indent_empty_lines: true,
   },
   js: {
-    indent_size: '2',
-    indent_char: ' ',
-    max_preserve_newlines: '-1',
+    indent_size: "2",
+    indent_char: " ",
+    max_preserve_newlines: "-1",
     preserve_newlines: false,
     keep_array_indentation: false,
     break_chained_methods: false,
-    indent_scripts: 'normal',
-    brace_style: 'end-expand',
+    indent_scripts: "normal",
+    brace_style: "end-expand",
     space_before_conditional: true,
     unescape_strings: false,
     jslint_happy: true,
     end_with_newline: true,
-    wrap_line_length: '110',
+    wrap_line_length: "110",
     indent_inner_html: true,
     comma_first: false,
     e4x: true,
-    indent_empty_lines: true
-  }
-}
+    indent_empty_lines: true,
+  },
+};
 
 // 棣栧瓧姣嶅ぇ灏�
 export function titleCase(str) {
-  return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
+  return str.replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
 }
 
 // 涓嬪垝杞┘宄�
 export function camelCase(str) {
-  return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
+  return str.replace(/_[a-z]/g, (str1) => str1.substr(-1).toUpperCase());
 }
 
 export function isNumberStr(str) {
-  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
+  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str);
 }
 
+// 淇瀛楀吀缁撴瀯
+export function dictToValue(arr) {
+  return arr.map((m) => {
+    return {
+      value: m.dictValue,
+      label: m.dictLabel,
+      type: m.listClass,
+    };
+  });
+}
diff --git a/src/views/CNAS/systemManagement/correctiveAction/components/ViewTestRecord.vue b/src/views/CNAS/systemManagement/correctiveAction/components/ViewTestRecord.vue
new file mode 100644
index 0000000..3c6a5bd
--- /dev/null
+++ b/src/views/CNAS/systemManagement/correctiveAction/components/ViewTestRecord.vue
@@ -0,0 +1,169 @@
+<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="{ superviseDetailsCorrectId: info.superviseDetailsCorrectId }" :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>
+        <limsTable ref="yearTable" :column="columnData" :height="'calc(100vh - 30em)'" :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 + '/word/' + currentInfo.fileUrl"
+        style="height: 90vh;overflow-y: auto;" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import filePreview from '@/components/Preview/filePreview.vue'
+import {
+  getSuperviseDetailCorrectFileList,
+  delSuperviseDetailCorrectFile,
+} from '@/api/cnas/systemManagement/correctiveAction.js'
+export default {
+  name: 'ViewTestRecord',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { filePreview, 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.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
+      getSuperviseDetailCorrectFileList({ superviseDetailsCorrectId: this.info.superviseDetailsCorrectId }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    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
+        this.$download.saveAs(url, row.fileName);
+      } else {
+        url = this.javaApi + '/word/' + row.fileUrl
+        this.$download.saveAs(url, row.fileName);
+      }
+    },
+    // 鍒犻櫎
+    delete(row) {
+      this.tableLoading = true
+      delSuperviseDetailCorrectFile({ superviseDetailsCorrectFileId: row.superviseDetailsCorrectFileId }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        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 + '/qualitySupervise/uploadSuperviseDetailCorrectFile'
+
+    }
+  },
+};
+</script>
+
+<style scoped></style>
diff --git a/src/views/CNAS/systemManagement/correctiveAction/components/correctiveInfo.vue b/src/views/CNAS/systemManagement/correctiveAction/components/correctiveInfo.vue
new file mode 100644
index 0000000..16d0d92
--- /dev/null
+++ b/src/views/CNAS/systemManagement/correctiveAction/components/correctiveInfo.vue
@@ -0,0 +1,258 @@
+<template>
+  <div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="formDia" title="绾犳鎺柦澶勭悊鍗�"
+      width="60%" @close="closeProcessingDia">
+      <div style="height: 660px; overflow-y: auto">
+        <table border="1" cellspacing="10" class="tables">
+          <tr>
+            <td class="td-title">
+              <p>鍩硅璁″垝锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <el-select v-model="form.personTrainingDetailedId" clearable filterable style="width: 100%" disabled
+                placeholder="璇烽�夋嫨" size="small">
+                <el-option v-for="item in yearTrainingDetailed" :key="item.id" :label="item.trainingObjectives"
+                  :value="item.id">
+                </el-option>
+              </el-select>
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>涓嶅悎鏍兼垨鍋忕浜嬪疄鐨勬弿杩帮細</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <span class="td-info1"> {{ form.raiseResult }}</span>
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>鎻愬嚭浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.raiseUserName }}
+            </td>
+            <td class="td-title">
+              <p>鎻愬嚭閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.raiseDepartment }}
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.raiseTime }}
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>鍘熷洜鍒嗘瀽锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <span class="td-info1"> {{ form.causeResult }}</span>
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>鍘熷洜鍒嗘瀽浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.causeUserName }}
+            </td>
+            <td class="td-title">
+              <p>璐d换閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.causeDepartment }}
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>鍘熷洜鍒嗘瀽鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.causeTime }}
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>绾犳鎺柦锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <span class="td-info1"> {{ form.correctResult }}</span>
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>鎻愬嚭瑕佹眰閮ㄩ棬纭锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <span class="td-info1"> {{ form.raiseDepartmentAffirm }}</span>
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>绾犳浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.correctUserName }}
+            </td>
+            <td class="td-title">
+              <p>璐d换閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.correctDepartment }}
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>绾犳鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.correctTime }}
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>瀹炴柦楠岃瘉缁撴灉锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <span class="td-info1"> {{ form.validationResult }}</span>
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>楠岃瘉浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.validationUserName }}
+            </td>
+            <td class="td-title">
+              <p>璐d换閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.validationDepartment }}
+            </td>
+          </tr>
+          <tr>
+            <td class="td-title">
+              <p>楠岃瘉鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.validationTime }}
+            </td>
+          </tr>
+        </table>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getSuperviseDetailCorrect,
+  getThisYearTrainingDetailed,
+} from '@/api/cnas/systemManagement/correctiveAction.js'
+export default {
+  name: 'correctiveInfo',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      yearTrainingDetailed: [],
+      form: {
+        superviseDetailsId: '',
+        raiseResult: '',
+        vdeRaiseResult: '',
+        causeUserId: '',
+        raiseUserName: '',
+        raiseDepartment: '',
+        raiseTime: '',
+        causeResult: '',
+        causeUserName: '',
+        causeDepartment: '',
+        causeTime: '',
+        correctUserId: '',
+        correctResult: '',
+        raiseDepartmentAffirm: '',
+        correctUserName: '',
+        correctDepartment: '',
+        correctTime: '',
+        validationUserId: '',
+        validationResult: '',
+        validationUserName: '',
+        validationDepartment: '',
+        validationTime: '',
+      },
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.formDia = true
+      this.searchInfo(row)
+      this.form.superviseDetailsId = row.superviseDetailsId
+      this.getYearTrainingDetailed() // 鑾峰彇鍩硅璁″垝
+    },
+    // 鏌ヨ鐩戞帶璁″垝璇︽儏瀹炴柦淇℃伅
+    searchInfo(row) {
+      this.form.qualityMonitorDetailsId = row.qualityMonitorDetailsId
+      getSuperviseDetailCorrect({ superviseDetailsId: row.superviseDetailsId }).then(res => {
+        if (res.code === 201) return
+        this.form = res.data
+      }).catch(err => {
+        console.log('err---', err);
+      })
+    },
+    getYearTrainingDetailed() {
+      getThisYearTrainingDetailed().then(res => {
+        this.yearTrainingDetailed = res.data
+      })
+    },
+    // 鍏抽棴寮规
+    closeProcessingDia() {
+      this.formDia = false
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 5vh auto 50px !important;
+}
+
+.tables {
+  table-layout: fixed;
+  width: 100%;
+  margin-top: 10px;
+}
+
+.td-title {
+  height: 40px;
+  width: 170px;
+  text-align: center;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+  padding: 6px;
+}
+
+.td-info {
+  padding: 6px;
+}
+
+.td-info1 {
+  display: inline-block;
+  width: 100%;
+  text-align: left;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/correctiveAction/index.vue b/src/views/CNAS/systemManagement/correctiveAction/index.vue
new file mode 100644
index 0000000..9360848
--- /dev/null
+++ b/src/views/CNAS/systemManagement/correctiveAction/index.vue
@@ -0,0 +1,202 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 150px">涓嶅悎鏍兼弿杩帮細</span>
+        <el-input v-model="searchForm.raiseResult" clearable size="small"></el-input>
+      </span>
+      <span class="search-group">
+        <el-button size="small" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="small" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <div>
+        <TableCard :showForm="false" :showTitle="false">
+          <template v-slot:table>
+            <limsTable :column="tableColumn" :height="'calc(100vh - 17em)'" :table-data="tableData"
+              :table-loading="tableLoading" style="padding: 0 15px;margin-bottom: 16px" @pagination="pagination"
+              :page="page">
+            </limsTable>
+          </template>
+        </TableCard>
+      </div>
+    </div>
+    <corrective-info v-if="correctiveInfo" ref="correctiveInfo"></corrective-info>
+    <ViewTestRecord v-if="viewTestRecordDialog" ref="viewTestRecordDialog"></ViewTestRecord>
+  </div>
+</template>
+
+<script>
+import TableCard from '@/components/TableCard/index.vue';
+import limsTable from "@/components/Table/lims-table.vue";
+import CorrectiveInfo from './components/correctiveInfo.vue';
+// import QualityInfo from '../do/a7-nonconforming-item/qualityInfo.vue';
+import ViewTestRecord from './components/ViewTestRecord.vue';
+import {
+  pageSuperviseDetailCorrect,
+  exportSuperviseDetaillCorrect,
+} from '@/api/cnas/systemManagement/correctiveAction.js'
+
+export default {
+  name: 'a8-corrective-action',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {
+    // QualityInfo, 
+    CorrectiveInfo,
+    limsTable,
+    TableCard,
+    ViewTestRecord
+  },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        raiseResult: '',
+      },
+      tableColumn: [
+        {
+          label: '涓嶅悎鏍兼垨鍋忕浜嬪疄鐨勬弿杩�',
+          prop: 'raiseResult',
+          minWidth: '100'
+        },
+        {
+          label: '鍘熷洜鍒嗘瀽',
+          prop: 'causeResult',
+          minWidth: '100'
+        },
+        {
+          label: '绾犳鎺柦',
+          prop: 'correctResult',
+          minWidth: '100'
+        },
+        {
+          label: '瀹炴柦楠岃瘉缁撴灉',
+          prop: 'validationResult',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          minWidth: '60',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '鏌ョ湅',
+              type: 'text',
+              clickFun: (row) => {
+                this.viewInfo(row);
+              },
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+            {
+              name: '鏌ョ湅闄勪欢',
+              type: 'text',
+              clickFun: (row) => {
+                this.viewFiles(row);
+              },
+            },
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      correctiveInfo: false,
+      viewTestRecordDialog: false,
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = {
+        raiseResult: this.searchForm.raiseResult,
+      }
+      const page = this.page
+      this.tableLoading = true
+      pageSuperviseDetailCorrect({ ...entity, ...page }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 瀵煎嚭
+    handleDown(row) {
+      exportSuperviseDetaillCorrect({ superviseDetailsCorrectId: row.superviseDetailsCorrectId }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鐩戠潱绾犳鎺柦' + '.docx');
+      })
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.raiseResult = '';
+      this.searchList()
+    },
+    // 鏌ョ湅璇︽儏
+    viewInfo(row) {
+      this.correctiveInfo = true
+      this.$nextTick(() => {
+        this.$refs.correctiveInfo.openDia(row)
+      })
+    },
+    // 鏌ョ湅闄勪欢
+    viewFiles(row) {
+      this.viewTestRecordDialog = true
+      this.$nextTick(() => {
+        this.$refs.viewTestRecordDialog.openDia(row)
+      })
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.view-title {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  height: 60px;
+  padding-left: 20px;
+}
+
+.search-background {
+  width: 100%;
+  height: 80px;
+  line-height: 80px;
+  background-color: #ffffff;
+  display: flex;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+
+.table {
+  background-color: #ffffff;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/customerManagement/components/formDialog.vue b/src/views/CNAS/systemManagement/customerManagement/components/formDialog.vue
new file mode 100644
index 0000000..13e5d6d
--- /dev/null
+++ b/src/views/CNAS/systemManagement/customerManagement/components/formDialog.vue
@@ -0,0 +1,256 @@
+<template>
+  <div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="formDia" title="瀹㈡埛婊℃剰搴﹁皟鏌ヨ〃"
+      width="70%" @close="closeFormDia">
+      <table border="1" cellspacing="10" class="tables">
+        <tr>
+          <td class="td-title">
+            <p>鍗曚綅鍚嶇О锛�</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-input v-model="form.unitName" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+          <td class="td-title">
+            <p>鏃ユ湡锛�</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-date-picker v-model="form.fillDate" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small" type="date"
+              value-format="yyyy-MM-dd">
+            </el-date-picker>
+          </td>
+        </tr>
+        <tr>
+          <td class="td-title">
+            <p>濮撳悕锛�</p>
+          </td>
+          <td class="td-info">
+            <el-input v-model="form.userName" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+          <td class="td-title">
+            <p>閮ㄩ棬锛�</p>
+          </td>
+          <td class="td-info">
+            <el-input v-model="form.department" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+          <td class="td-title">
+            <p>鑱旂郴鐢佃瘽锛�</p>
+          </td>
+          <td class="td-info">
+            <el-input v-model="form.contactNumber" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+        </tr>
+        <tr>
+          <td class="td-title">
+            <p>鏈嶅姟鎬佸害锛�</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-radio-group v-model="form.serviceAttitude" v-removeAriaHidden>
+              <el-radio :label="0">婊℃剰</el-radio>
+              <el-radio :label="1">涓�鑸�</el-radio>
+              <el-radio :label="2">涓嶆弧鎰�</el-radio>
+            </el-radio-group>
+          </td>
+          <td class="td-title">
+            <p>寤鸿锛�</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-input v-model="form.serviceAttitudeSuggestion" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+        </tr>
+        <tr>
+          <td class="td-title">
+            <p>鎶�鏈兘鍔涳細</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-radio-group v-model="form.technicalCompetence" v-removeAriaHidden>
+              <el-radio :label="0">婊℃剰</el-radio>
+              <el-radio :label="1">涓�鑸�</el-radio>
+              <el-radio :label="2">涓嶆弧鎰�</el-radio>
+            </el-radio-group>
+          </td>
+          <td class="td-title">
+            <p>寤鸿锛�</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-input v-model="form.technicalCompetenceSuggestion" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+        </tr>
+        <tr>
+          <td class="td-title">
+            <p>妫�娴嬪伐浣滐細</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-radio-group v-model="form.inspectionWork" v-removeAriaHidden>
+              <el-radio :label="0">婊℃剰</el-radio>
+              <el-radio :label="1">涓�鑸�</el-radio>
+              <el-radio :label="2">涓嶆弧鎰�</el-radio>
+            </el-radio-group>
+          </td>
+          <td class="td-title">
+            <p>寤鸿锛�</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-input v-model="form.inspectionWorkSuggestion" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+        </tr>
+        <tr>
+          <td class="td-title">
+            <p>鏀惰垂鍚堢悊鎬э細</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-radio-group v-model="form.reasonableFees" v-removeAriaHidden>
+              <el-radio :label="0">婊℃剰</el-radio>
+              <el-radio :label="1">涓�鑸�</el-radio>
+              <el-radio :label="2">涓嶆弧鎰�</el-radio>
+            </el-radio-group>
+          </td>
+          <td class="td-title">
+            <p>寤鸿锛�</p>
+          </td>
+          <td class="td-info" colspan="2">
+            <el-input v-model="form.reasonableFeesSuggestion" placeholder="璇疯緭鍏ュ唴瀹�" size="small">
+            </el-input>
+          </td>
+        </tr>
+        <tr>
+          <td class="td-title">
+            <p>鎮ㄥ鎴戜滑鐨勫笇鏈涳細</p>
+          </td>
+          <td class="td-info" colspan="5">
+            <el-input v-model="form.remark" :rows="4" placeholder="璇疯緭鍏ュ唴瀹�" size="small" type="textarea">
+            </el-input>
+          </td>
+        </tr>
+      </table>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeFormDia">鍙� 娑�</el-button>
+        <el-button :loading="editLoad" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addClientSatisfaction,
+  updateClientSatisfaction
+} from '@/api/cnas/systemManagement/customerSatisfaction.js'
+export default {
+  name: 'formDialog',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      form: {
+        unitName: '',
+        fillDate: '',
+        userName: '',
+        department: '',
+        contactNumber: '',
+        serviceAttitude: '',
+        technicalCompetence: '',
+        technicalCompetenceSuggestion: '',
+        inspectionWork: '',
+        inspectionWorkSuggestion: '',
+        reasonableFees: '',
+        reasonableFeesSuggestion: '',
+        remark: '',
+        clientSatisfactionId: '',
+      },
+      operationType: '',
+      editLoad: false,
+
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(type, row) {
+      this.formDia = true;
+      this.operationType = type
+      if (this.operationType === 'edit') {
+        this.form = { ...row }
+      }
+    },
+    handleEdit() {
+      if (!this.form.unitName) {
+        this.$message.warning('璇峰~鍐欏崟浣嶅悕绉�')
+        return
+      }
+      if (!this.form.department) {
+        this.$message.warning('璇峰~鍐欓儴闂�')
+        return
+      }
+      this.editLoad = true
+      if (this.operationType === 'add') {
+        addClientSatisfaction(this.form).then(res => {
+          this.editLoad = false
+          if (res.code === 201) return
+          this.$message.success('鎻愪氦鎴愬姛')
+          this.closeFormDia()
+        }).catch(err => {
+          console.log('err---', err);
+          this.editLoad = false
+        })
+      } else {
+        updateClientSatisfaction(this.form).then(res => {
+          this.editLoad = false
+          if (res.code === 201) return
+          this.$message.success('鎻愪氦鎴愬姛')
+          this.closeFormDia()
+        }).catch(err => {
+          console.log('err---', err);
+          this.editLoad = false
+        })
+      }
+    },
+    closeFormDia() {
+      this.formDia = false;
+      this.$emit('closeFormDia')
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 10vh auto 50px !important;
+}
+
+.tables {
+  table-layout: fixed;
+  width: 100%;
+  margin-top: 10px;
+}
+
+.td-title {
+  height: 40px;
+  width: 170px;
+  text-align: center;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+  padding: 6px;
+}
+
+.td-info {
+  padding: 6px;
+}
+
+.td-info1 {
+  display: inline-block;
+  width: 100%;
+  text-align: left;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/customerManagement/customerSatisfaction.vue b/src/views/CNAS/systemManagement/customerManagement/customerSatisfaction.vue
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/views/CNAS/systemManagement/customerManagement/customerSatisfaction.vue
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/ViewTestRecord.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/ViewTestRecord.vue
new file mode 100644
index 0000000..fac2da1
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/ViewTestRecord.vue
@@ -0,0 +1,176 @@
+<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="{ correctId: info.correctId }" :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>
+        <limsTable ref="yearTable" :column="columnData" :height="'calc(100vh - 30em)'" :highlightCurrentRow="true"
+          :table-data="tableData" :table-loading="tableLoading" style="margin-top: 0.5em;" :page="page">
+        </limsTable>
+      </div>
+    </el-dialog>
+    <el-dialog :visible.sync="lookDialogVisible" fullscreen title="鏌ョ湅闄勪欢" top="5vh" width="800px">
+      <filePreview v-if="lookDialogVisible" :currentFile="{}" :fileUrl="javaApi + '/word/' + currentInfo.fileUrl"
+        style="height: 90vh;overflow-y: auto;" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import filePreview from '@/components/Preview/filePreview.vue'
+import {
+  getInternalCorrectFileList,
+  delInternalCorrectFile,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+export default {
+  name: 'ViewTestRecord',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { filePreview, 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.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,
+      page: {
+        total: 0,
+        size: -1,
+        current: -1,
+      },
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.filesDialogVisible = true
+      this.info = row
+      this.searchTableList()
+    },
+    // 鏌ヨ闄勪欢鍒楄〃
+    searchTableList() {
+      this.tableLoading = true
+      getInternalCorrectFileList({ correctId: this.info.correctId }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    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
+        this.$download.saveAs(url, row.fileName)
+      } else {
+        url = this.javaApi + '/word/' + row.fileUrl
+        this.$download.saveAs(url, row.fileName)
+      }
+    },
+    // 鍒犻櫎
+    delete(row) {
+      this.tableLoading = true
+      delInternalCorrectFile({ correctFileId: row.correctFileId }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        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()
+      } else {
+        this.$message.error(response.message);
+      }
+    },
+  },
+  computed: {
+    fileAction() {
+      return this.javaApi + '/internalCorrect/uploadInternalCorrectFile'
+
+    }
+  },
+};
+</script>
+
+<style scoped></style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspection.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspection.vue
new file mode 100644
index 0000000..8b851ca
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspection.vue
@@ -0,0 +1,253 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">鍙楀閮ㄩ棬锛�</span>
+        <el-input v-model="searchForm.department" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" :page="page" @pagination="pagination">
+      </limsTable>
+    </div>
+    <audit-inspection-dia v-if="auditInspectionDia" ref="auditInspectionDia"
+      @closeImplementDia="closeImplementDia"></audit-inspection-dia>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import AuditInspectionDia from './auditInspectionDia.vue';
+import {
+  pageInternalCheck,
+  delInternalCheck,
+  exportInternalCheck
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+
+export default {
+  name: 'auditInspection',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { AuditInspectionDia, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        department: '',
+      },
+      tableColumn: [
+        {
+          label: '鍙楀閮ㄩ棬',
+          prop: 'department',
+        },
+        {
+          label: '閮ㄩ棬璐熻矗浜�',
+          prop: 'departmentHead',
+        },
+        {
+          label: '瀹℃牳鍛�',
+          prop: 'auditor',
+        },
+        {
+          label: '瀹℃牳鏃ユ湡',
+          prop: 'reviewDate',
+        }, {
+          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: 'ratifyRemark',
+          minWidth: '140'
+        },
+        {
+          dataType: 'action',
+          minWidth: '220',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return false
+                } else {
+                  return true
+                }
+              },
+            },
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('ratify', row);
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      auditInspectionDia: false
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = this.searchForm
+      const page = this.page
+      this.tableLoading = true
+      pageInternalCheck({ ...entity, ...page }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鏂板锛岀紪杈戯紝鎵瑰噯寮规
+    openFormDia(type, row) {
+      this.auditInspectionDia = true
+      this.$nextTick(() => {
+        this.$refs.auditInspectionDia.openDia(type, row)
+      })
+    },
+    closeImplementDia() {
+      this.auditInspectionDia = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.department = '';
+      this.searchList()
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delInternalCheck({ checkId: row.checkId }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 瀵煎嚭
+    handleDown(row) {
+      exportInternalCheck({ checkId: row.checkId }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鍐呭妫�鏌�' + '.docx');
+      })
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspectionDia.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspectionDia.vue
new file mode 100644
index 0000000..a1f1e58
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditInspectionDia.vue
@@ -0,0 +1,231 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="鍐呴儴瀹℃牳瀹炴柦璁″垝" width="80%" @close="closeImplementDia">
+      <el-form ref="form" :model="form" :rules="rules" label-width="auto">
+        <el-col :span="12">
+          <el-form-item label="鍙楀閮ㄩ棬" prop="department">
+            <el-input v-model="form.department" :disabled="operationType === 'ratify'" clearable
+              size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="閮ㄩ棬璐熻矗浜�" prop="departmentHead">
+            <el-input v-model="form.departmentHead" :disabled="operationType === 'ratify'" clearable
+              size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瀹℃牳鍛�" prop="auditor">
+            <el-input v-model="form.auditor" :disabled="operationType === 'ratify'" clearable size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瀹℃牳鏃ユ湡" prop="reviewDate">
+            <el-date-picker v-model="form.reviewDate" :disabled="operationType === 'ratify'" clearable
+              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-form>
+      <div v-if="operationType !== 'ratify'" 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>
+      <el-table :data="checkDetailList" border height="300" style="width: 100%">
+        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column header-align="center" label="娑夊強瑕佺礌鍜岃川閲忎綋绯绘枃浠舵潯娆�" prop="element">
+          <template slot-scope="{row}">
+            <el-input v-model="row.element" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="瀹℃牳鍐呭" prop="content">
+          <template slot-scope="{row}">
+            <el-input v-model="row.content" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="瀹℃牳鏂瑰紡" prop="method">
+          <template slot-scope="{row}">
+            <el-input v-model="row.method" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="瀹℃牳缁撴灉璁板綍" prop="resultRecords" width="180">
+          <template slot-scope="{row}">
+            <el-input v-model="row.resultRecords" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="涓嶇鍚堟�ц川" prop="nonNature" width="180">
+          <template slot-scope="{row}">
+            <el-input v-model="row.nonNature" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+      </el-table>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="operationType === 'ratify'" :loading="loading" @click="ratify(0)">涓嶆壒鍑�</el-button>
+        <el-button v-if="operationType === 'ratify'" :loading="loading" type="primary" @click="ratify(1)">鎵�
+          鍑�</el-button>
+        <el-button v-if="operationType !== 'ratify'" @click="closeImplementDia">鍙� 娑�</el-button>
+        <el-button v-if="operationType !== 'ratify'" :loading="loading" type="primary" @click="handleEdit">鎻�
+          浜�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="approvalDialog" title="鎵瑰噯" width="30%" @close="approvalDialog = false">
+      <span>
+        鎵瑰噯澶囨敞锛�
+        <el-input v-model="ratifyRemark" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="approvalLoading" @click="approvalDialog = false">鍙� 娑�</el-button>
+        <el-button :loading="approvalLoading" type="primary" @click="handleApproval(0)">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getInternalCheckOne,
+  addInternalCheck,
+  updateInternalCheck,
+  ratifyInternalCheck,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+export default {
+  name: 'auditInspectionDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        department: '',
+        departmentHead: '',
+        auditor: '',
+        reviewDate: '',
+      },
+      rules: {
+        department: [{ required: true, message: '璇峰~鍐欏彈瀹¢儴闂�', trigger: 'blur' }],
+        departmentHead: [{ required: true, message: '璇峰~鍐欓儴闂ㄨ礋璐d汉', trigger: 'blur' }],
+        auditor: [{ required: true, message: '璇峰~鍐欏鏍稿憳', trigger: 'blur' }],
+        reviewDate: [{ required: true, message: '璇峰~鍐欏鏍告棩鏈�', trigger: 'blur' }],
+      },
+      checkDetailList: [],
+      operationType: '',
+      approvalDialog: false,
+      approvalLoading: false,
+      ratifyRemark: '',
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      if (type !== 'add') {
+        this.searchInfo(row)
+      }
+    },
+    // 鏌ヨ璇︽儏
+    searchInfo(row) {
+      this.diaLoading = true
+      getInternalCheckOne({ checkId: row.checkId }).then(res => {
+        this.diaLoading = false
+        if (res.code === 201) return
+        this.form = res.data
+        this.checkDetailList = this.form.checkDetailList
+      }).catch(err => {
+        console.log(err)
+        this.diaLoading = false
+      })
+    },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          if (this.checkDetailList.length === 0) {
+            this.$message.warning('璇锋坊鍔犺〃鏍兼暟鎹�')
+            return
+          }
+          this.loading = true
+          const internalCheckDto = this.HaveJson(this.form)
+          internalCheckDto.checkDetailList = this.HaveJson(this.checkDetailList)
+          if (this.operationType === 'add') {
+            addInternalCheck(internalCheckDto).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            updateInternalCheck(internalCheckDto).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    ratify(ratifyStatus) {
+      // 涓嶆壒鍑嗛渶瑕佸~鍐欐壒鍑嗗唴瀹�
+      if (ratifyStatus === 0) {
+        this.approvalDialog = true
+      } else {
+        this.handleApproval(ratifyStatus)
+      }
+    },
+    // 鎻愪氦鎵瑰噯淇℃伅
+    handleApproval(ratifyStatus) {
+      this.approvalLoading = true
+      const internalCheckDto = this.HaveJson(this.form)
+      internalCheckDto.ratifyStatus = ratifyStatus
+      internalCheckDto.ratifyRemark = ratifyStatus === 0 ? this.ratifyRemark : ''
+      ratifyInternalCheck(internalCheckDto).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.closeImplementDia(this.departId);
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    // 澧炲姞琛ㄦ牸琛屾暟鎹�
+    addRow() {
+      this.checkDetailList.push({
+        element: '',
+        content: '',
+        method: '',
+        resultRecords: '',
+        nonNature: '',
+      })
+    },
+    // 娓呯┖琛ㄦ牸鏁版嵁
+    clearTable() {
+      this.checkDetailList = []
+    },
+    closeImplementDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeImplementDia')
+    },
+  }
+};
+</script>
+
+<style scoped></style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSign.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSign.vue
new file mode 100644
index 0000000..f18a42f
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSign.vue
@@ -0,0 +1,201 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">鏃堕棿锛�</span>
+        <el-input v-model="searchForm.meetingDate" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" :page="page" @pagination="pagination">
+      </limsTable>
+    </div>
+    <audit-meeting-sign-dia v-if="auditMeetingSignDia" ref="auditMeetingSignDia"
+      @closeYearDia="closeYearDia"></audit-meeting-sign-dia>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import AuditMeetingSignDia from './auditMeetingSignDia.vue';
+import {
+  pageInternalMeeting,
+  delInternalMeeting,
+  exportInternalMeeting,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+
+export default {
+  name: 'auditMeetingSign',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { AuditMeetingSignDia, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        meetingDate: '',
+      },
+      tableColumn: [
+        {
+          label: '鏃堕棿',
+          prop: 'meetingDate',
+          minWidth: '100'
+        },
+        {
+          label: '涓绘寔浜�',
+          prop: 'compere',
+          minWidth: '100'
+        },
+        {
+          label: '鍦扮偣',
+          prop: 'place',
+          minWidth: '100'
+        },
+        {
+          label: '浼氳涓婚',
+          prop: 'subject',
+          minWidth: '100'
+        },
+        {
+          label: '鍙備細浜哄憳',
+          prop: 'participantName',
+          minWidth: '120'
+        },
+        {
+          dataType: 'action',
+          fixed: 'right',
+          minWidth: '220',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              }
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      auditMeetingSignDia: false,
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = this.searchForm
+      const page = this.page
+      this.tableLoading = true
+      pageInternalMeeting({ ...entity, ...page }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鏂板锛岀紪杈戝脊妗�
+    openFormDia(type, row) {
+      this.auditMeetingSignDia = true
+      this.$nextTick(() => {
+        this.$refs.auditMeetingSignDia.openDia(type, row)
+      })
+    },
+    closeYearDia() {
+      this.auditMeetingSignDia = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.meetingDate = '';
+      this.searchList()
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delInternalMeeting({ meetingId: row.meetingId }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 瀵煎嚭
+    handleDown(row) {
+      exportInternalMeeting({ meetingId: row.meetingId }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鍐呭浼氳绛惧埌' + '.docx');
+      })
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSignDia.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSignDia.vue
new file mode 100644
index 0000000..0497107
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditMeetingSignDia.vue
@@ -0,0 +1,183 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="鍐呭浼氳绛惧埌琛�" width="1000px" @close="closeYearDia">
+      <el-form ref="form" :model="form" :rules="rules" label-position="top" label-width="auto">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鏃堕棿" prop="meetingDate">
+              <el-date-picker v-model="form.meetingDate" clearable 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="compere">
+              <el-input v-model="form.compere" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍦扮偣" prop="place">
+              <el-input v-model="form.place" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浼氳涓婚" prop="subject">
+              <el-input v-model="form.subject" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍙備細浜哄憳" prop="participant">
+              <el-select v-model="form.participant" clearable filterable multiple placeholder="璇烽�夋嫨" size="small"
+                style="width: 100%;">
+                <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeYearDia">鍙� 娑�</el-button>
+        <el-button :loading="loading" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  selectUserCondition,
+} from "@/api/system/user.js";
+import {
+  getInternalMeetingOne,
+  addInternalMeeting,
+  updateInternalMeeting,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+export default {
+  name: 'auditMeetingSignDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        meetingDate: '',
+        compere: '',
+        place: '',
+        subject: '',
+        participant: [],
+      },
+      rules: {
+        meetingDate: [{ required: true, message: '璇峰~鍐欎細璁椂闂�', trigger: 'blur' }],
+        compere: [{ required: true, message: '璇峰~鍐欎富鎸佷汉', trigger: 'blur' }],
+        place: [{ required: true, message: '璇峰~鍐欏湴鐐�', trigger: 'blur' }],
+        subject: [{ required: true, message: '璇峰~鍐欎細璁富棰�', trigger: 'blur' }],
+        participant: [{ required: true, message: '璇烽�夋嫨鍙傚姞浜哄憳', trigger: 'change' }],
+      },
+      operationType: '',
+      personList: []
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      this.getAuthorizedPerson()
+      if (type !== 'add') {
+        this.searchInfo(row)
+      }
+    },
+    // 鏌ヨ璇︽儏
+    searchInfo(row) {
+      this.diaLoading = true
+      getInternalMeetingOne({ meetingId: row.meetingId }).then(res => {
+        this.diaLoading = false
+        if (res.code === 201) return
+        this.form = res.data
+        this.form.participant = this.form.participant.split(',').map(Number)
+      }).catch(err => {
+        console.log(err)
+        this.diaLoading = false
+      })
+    },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.loading = true
+          const internalMeeting = this.HaveJson(this.form)
+          internalMeeting.participant = internalMeeting.participant.join(',')
+          if (this.operationType === 'add') {
+            addInternalMeeting(internalMeeting).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            updateInternalMeeting(internalMeeting).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    closeYearDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeYearDia')
+    },
+    getAuthorizedPerson() {
+      selectUserCondition().then(res => {
+        let data = []
+        res.data.forEach(a => {
+          data.push({
+            label: a.name,
+            value: a.id
+          })
+        })
+        this.personList = data
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+.table {
+  table-layout: fixed;
+  width: 100%;
+  margin-top: 10px;
+}
+
+.table 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/systemManagement/internalAuditManagement/components/auditReport.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditReport.vue
new file mode 100644
index 0000000..6909f5e
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditReport.vue
@@ -0,0 +1,311 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">瀹℃牳鐩殑锛�</span>
+        <el-input v-model="searchForm.purposes" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" :page="page" @pagination="pagination">
+      </limsTable>
+    </div>
+    <audit-report-dia v-if="auditReportDia" ref="auditReportDia"
+      @closeImplementDia="closeImplementDia"></audit-report-dia>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import AuditReportDia from './auditReportDia.vue';
+import {
+  delInternalReport,
+  pageInternalReport,
+  exportInternalReport,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+export default {
+  name: 'auditReport',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { AuditReportDia, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        purposes: '',
+      },
+      tableColumn: [
+        {
+          label: '瀹℃牳鐩殑',
+          prop: 'purposes',
+        },
+        {
+          label: '瀹℃牳渚濇嵁',
+          prop: 'basis',
+        },
+        {
+          label: '瀹℃牳鏃ユ湡',
+          prop: 'reviewDate',
+        },
+        {
+          label: '瀹℃牳鏂规硶',
+          prop: 'method',
+        },
+        {
+          label: '瀹℃牳鑼冨洿',
+          prop: 'scope',
+        },
+        {
+          label: '瀹℃牳璐d换鑰�',
+          prop: 'responsible',
+        },
+        {
+          label: '瀹℃牳缁勯暱',
+          prop: 'leader',
+        },
+        {
+          label: '瀹℃牳鍛�',
+          prop: 'auditor',
+        },
+        {
+          label: '瀹℃牳缁勫垎宸ユ儏鍐�',
+          prop: 'division',
+        },
+        {
+          dataType: 'tag',
+          label: '瀹℃牳鐘舵��',
+          prop: 'examineStatus',
+          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: 'examineRemark',
+          minWidth: '140'
+        },
+        {
+          dataType: 'tag',
+          label: '璐ㄩ噺璐熻矗浜虹姸鎬�',
+          prop: 'qualityStatus',
+          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: 'qualityRemark',
+          minWidth: '140'
+        },
+        {
+          dataType: 'action',
+          minWidth: '220',
+          fixed: 'right',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+              disabled: (row) => {
+                if (row.examineStatus === 1 || row.examineStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '瀹℃牳',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('examine', row);
+              },
+              disabled: (row) => {
+                if (row.examineStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鎰忚',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('ratify', row);
+              },
+              disabled: (row) => {
+                if (row.qualityStatus === 1 || row.examineStatus === 0 || row.examineStatus === null) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              },
+              disabled: (row) => {
+                if (row.qualityStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      auditReportDia: false
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = this.searchForm
+      const page = this.page
+      this.tableLoading = true
+      pageInternalReport({ ...entity, ...page }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鏂板锛岀紪杈戯紝鎵瑰噯寮规
+    openFormDia(type, row) {
+      this.auditReportDia = true
+      this.$nextTick(() => {
+        this.$refs.auditReportDia.openDia(type, row)
+      })
+    },
+    closeImplementDia() {
+      this.auditReportDia = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.purposes = '';
+      this.searchList()
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delInternalReport({ reportId: row.reportId }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 瀵煎嚭
+    handleDown(row) {
+      exportInternalReport({ reportId: row.reportId }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鍐呭鎶ュ憡' + '.docx');
+      })
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/auditReportDia.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditReportDia.vue
new file mode 100644
index 0000000..b2dd1fa
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/auditReportDia.vue
@@ -0,0 +1,333 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="鍐呴儴瀹℃牳鎶ュ憡" width="80%" @close="closeImplementDia">
+      <el-form ref="form" :model="form" :rules="rules" label-position="top" label-width="auto">
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="瀹℃牳鐩殑" prop="purposes">
+              <el-input v-model="form.purposes" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹℃牳渚濇嵁" prop="basis">
+              <el-input v-model="form.basis" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹℃牳鏃ユ湡" prop="reviewDate">
+              <el-date-picker v-model="form.reviewDate"
+                :disabled="operationType === 'examine' || operationType === 'ratify'" clearable 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="24">
+            <el-form-item label="瀹℃牳鏂规硶" prop="method">
+              <el-input v-model="form.method" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="瀹℃牳鑼冨洿" prop="scope">
+              <el-input v-model="form.scope" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹℃牳璐d换鑰�" prop="responsible">
+              <el-input v-model="form.responsible" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹℃牳缁勯暱" prop="leader">
+              <el-input v-model="form.leader" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="瀹℃牳鍛�" prop="auditor">
+              <el-input v-model="form.auditor" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="瀹℃牳缁勫垎宸ユ儏鍐�" prop="division">
+              <el-input v-model="form.division" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="瀹℃牳姒傚喌" prop="overview">
+              <el-input v-model="form.overview" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍐呭缁勫涓績绠$悊浣撶郴鐨勭粨璁烘�ц瘎浠�" prop="conclusion">
+              <el-input v-model="form.conclusion" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鏀硅繘鎰忚" prop="suggest">
+              <el-input v-model="form.suggest" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="棰勮鍙楀鏍搁儴闂ㄥ畬鎴愮籂姝f帾鏂芥墍闇�鏃堕棿" prop="actionDate">
+              <el-input v-model="form.actionDate" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="涓嶇鍚堟儏鍐垫暣鏀规�讳綋璺熻繘纭浜�" prop="followUser">
+              <el-input v-model="form.followUser" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="涓嶇鍚堟儏鍐垫暣鏀规�讳綋璺熻繘纭璁板綍" prop="followRecord">
+              <el-input v-model="form.followRecord"
+                :disabled="operationType === 'examine' || operationType === 'ratify'" :rows="3" clearable size="small"
+                type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鏈姤鍛婂彂鏀捐寖鍥�" prop="reportScope">
+              <el-input v-model="form.reportScope" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col v-if="operationType === 'ratify'" :span="24">
+            <el-form-item label="璐ㄩ噺璐熻矗浜烘剰瑙�" prop="qualityRemark">
+              <el-input v-model="form.qualityRemark" :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="operationType === 'examine'" :loading="loading" @click="examine(0)">涓嶉�氳繃</el-button>
+        <el-button v-if="operationType === 'examine'" :loading="loading" type="primary" @click="examine(1)">閫�
+          杩�</el-button>
+        <el-button v-if="operationType === 'ratify'" :loading="loading" @click="handleApproval(0)">涓嶆壒鍑�</el-button>
+        <el-button v-if="operationType === 'ratify'" :loading="loading" type="primary" @click="handleApproval(1)">鎵�
+          鍑�</el-button>
+        <el-button v-if="operationType !== 'ratify' && operationType !== 'examine'" @click="closeImplementDia">鍙�
+          娑�</el-button>
+        <el-button v-if="operationType !== 'ratify' && operationType !== 'examine'" :loading="loading" type="primary"
+          @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="examineDialog" title="瀹℃牳" width="30%" @close="examineDialog = false">
+      <span>
+        瀹℃牳澶囨敞锛�
+        <el-input v-model="examineRemark" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="examineLoading" @click="examineDialog = false">鍙� 娑�</el-button>
+        <el-button :loading="examineLoading" type="primary" @click="handleExamine(0)">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+    <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="approvalDialog = false">鍙� 娑�</el-button>
+        <el-button :loading="approvalLoading" type="primary" @click="handleApproval(0)">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getInternalReportOne,
+  addInternalReport,
+  updateInternalReport,
+  examineInternalReport,
+  qualityInternalReport,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+export default {
+  name: 'auditReportDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        purposes: '',
+        basis: '',
+        reviewDate: '',
+        method: '',
+        scope: '',
+        responsible: '',
+        leader: '',
+        auditor: '',
+        division: '',
+        overview: '',
+        conclusion: '',
+        suggest: '',
+        actionDate: '',
+        followUser: '',
+        followRecord: '',
+        reportScope: '',
+        qualityRemark: '',
+      },
+      rules: {
+        purposes: [{ required: true, message: '璇峰~鍐欏鏍哥洰鐨�', trigger: 'blur' }],
+        basis: [{ required: true, message: '璇峰~鍐欏鏍镐緷鎹�', trigger: 'blur' }],
+        reviewDate: [{ required: true, message: '璇峰~鍐欏鏍告棩鏈�', trigger: 'change' }],
+        method: [{ required: true, message: '璇峰~鍐欏鏍告柟娉�', trigger: 'blur' }],
+        scope: [{ required: true, message: '璇峰~鍐欏鏍歌寖鍥�', trigger: 'blur' }],
+        responsible: [{ required: true, message: '璇峰~鍐欏鏍歌矗浠昏��', trigger: 'blur' }],
+        leader: [{ required: true, message: '璇峰~鍐欏鏍哥粍闀�', trigger: 'blur' }],
+        auditor: [{ required: true, message: '璇峰~鍐欏鏍稿憳', trigger: 'blur' }],
+        division: [{ required: true, message: '璇峰~鍐欏鏍哥粍鍒嗗伐鎯呭喌', trigger: 'blur' }],
+        overview: [{ required: true, message: '璇峰~鍐欏鏍告鍐�', trigger: 'blur' }],
+        conclusion: [{ required: true, message: '璇峰~鍐�', trigger: 'blur' }],
+        suggest: [{ required: true, message: '璇峰~鍐�', trigger: 'blur' }],
+        actionDate: [{ required: true, message: '璇峰~鍐�', trigger: 'blur' }],
+        followUser: [{ required: true, message: '璇峰~鍐�', trigger: 'blur' }],
+        followRecord: [{ required: true, message: '璇峰~鍐�', trigger: 'blur' }],
+        reportScope: [{ required: true, message: '璇峰~鍐�', trigger: 'blur' }],
+        qualityRemark: [{ required: true, message: '璇峰~鍐�', trigger: 'blur' }],
+      },
+      operationType: '',
+      approvalDialog: false,
+      approvalLoading: false,
+      examineDialog: false,
+      examineLoading: false,
+      qualityRemark: '',
+      examineRemark: '',
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      if (type !== 'add') {
+        this.searchInfo(row)
+      }
+    },
+    // 鏌ヨ璇︽儏
+    searchInfo(row) {
+      this.diaLoading = true
+      getInternalReportOne({ reportId: row.reportId }).then(res => {
+        this.diaLoading = false
+        if (res.code === 201) return
+        this.form = res.data
+      }).catch(err => {
+        console.log(err)
+        this.diaLoading = false
+      })
+    },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.loading = true
+          const internalReport = this.HaveJson(this.form)
+          if (this.operationType === 'add') {
+            addInternalReport(internalReport).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            updateInternalReport(internalReport).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    // 瀹℃牳娴佺▼
+    examine(examineStatus) {
+      if (examineStatus === 0) {
+        this.examineDialog = true
+      } else {
+        this.handleExamine(examineStatus)
+      }
+    },
+    handleExamine(examineStatus) {
+      this.examineLoading = true
+      const internalReport = this.HaveJson(this.form)
+      internalReport.examineStatus = examineStatus
+      examineInternalReport(internalReport).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.closeImplementDia(this.departId);
+        }
+        this.examineLoading = false
+      }).catch(() => {
+        this.examineLoading = false
+      })
+    },
+    // 鎻愪氦瀹℃牳淇℃伅
+    handleApproval(qualityStatus) {
+      this.approvalLoading = true
+      const internalReport = this.HaveJson(this.form)
+      internalReport.qualityStatus = qualityStatus
+      qualityInternalReport(internalReport).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.closeImplementDia(this.departId);
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    closeImplementDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeImplementDia')
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+
+>>>.el-dialog__body {
+  max-height: 42em;
+  overflow-y: auto;
+}
+
+>>>.is-required {
+  margin-bottom: 6px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveAction.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveAction.vue
new file mode 100644
index 0000000..58b1b4b
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveAction.vue
@@ -0,0 +1,181 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 200px">涓嶅悎鏍兼弿杩帮細</span>
+        <el-input v-model="searchForm.raiseResult" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" :page="page" @pagination="pagination">
+      </limsTable>
+    </div>
+    <corrective-action-d-ia v-if="correctiveActionDIa" ref="correctiveActionDIa"
+      @closeRectifyDia="closeRectifyDia"></corrective-action-d-ia>
+    <view-test-record v-if="viewTestRecordDialog" ref="viewTestRecordDialog"></view-test-record>
+  </div>
+</template>
+
+<script>
+import TableCard from '@/components/TableCard/index.vue';
+import limsTable from "@/components/Table/lims-table.vue";
+import CorrectiveActionDIa from './correctiveActionDIa.vue';
+import ViewTestRecord from './ViewTestRecord.vue';
+import {
+  pageInternalCorrect,
+  exportInternalCorrect,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+
+export default {
+  name: 'correctiveAction',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { CorrectiveActionDIa, limsTable, TableCard, ViewTestRecord },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        raiseResult: '',
+      },
+      tableColumn: [
+        {
+          label: '涓嶅悎鏍兼垨鍋忕浜嬪疄鐨勬弿杩�',
+          prop: 'raiseResult',
+          minWidth: '100'
+        },
+        {
+          label: '鍘熷洜鍒嗘瀽',
+          prop: 'causeResult',
+          minWidth: '100'
+        },
+        {
+          label: '绾犳鎺柦',
+          prop: 'correctResult',
+          minWidth: '100'
+        },
+        {
+          label: '瀹炴柦楠岃瘉缁撴灉',
+          prop: 'validationResult',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          minWidth: '220',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+            {
+              name: '绾犳',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('rectify', row);
+              },
+            },
+            {
+              name: '鏌ョ湅闄勪欢',
+              type: 'text',
+              clickFun: (row) => {
+                this.viewFiles(row);
+              },
+            },
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      correctiveActionDIa: false,
+      viewTestRecordDialog: false,
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = {
+        raiseResult: this.searchForm.raiseResult,
+      }
+      const page = this.page
+      this.tableLoading = true
+      pageInternalCorrect({ ...entity, ...page }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.raiseResult = '';
+      this.searchList()
+    },
+    // 鏌ョ湅闄勪欢
+    viewFiles(row) {
+      this.viewTestRecordDialog = true
+      this.$nextTick(() => {
+        this.$refs.viewTestRecordDialog.openDia(row)
+      })
+    },
+    openFormDia(type, row) {
+      this.correctiveActionDIa = true
+      this.$nextTick(() => {
+        this.$refs.correctiveActionDIa.openDia(type, row)
+      })
+    },
+    // 瀵煎嚭
+    handleDown(row) {
+      exportInternalCorrect({ correctId: row.correctId }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鍐呭绾犳鎺柦' + '.docx');
+      })
+    },
+    closeRectifyDia() {
+      this.correctiveActionDIa = false
+      this.searchList()
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveActionDIa.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveActionDIa.vue
new file mode 100644
index 0000000..b68c4c7
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/correctiveActionDIa.vue
@@ -0,0 +1,409 @@
+<template>
+  <div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="formDia" title="绾犳鎺柦澶勭悊鍗�"
+      width="60%" @close="closeRectifyDia">
+      <el-steps :active="currentStep" align-center finish-status="success">
+        <el-step title="涓嶅悎鏍兼垨鍋忕浜嬪疄鐨勬弿杩�" @click.native="setStep(0)"></el-step>
+        <el-step title="鍘熷洜鍒嗘瀽" @click.native="setStep(1)"></el-step>
+        <el-step title="绾犳鎺柦" @click.native="setStep(2)"></el-step>
+        <el-step title="瀹炴柦楠岃瘉缁撴灉" @click.native="setStep(3)"></el-step>
+      </el-steps>
+      <div>
+        <table border="1" cellspacing="10" class="tables">
+          <tr v-if="showStep === 0">
+            <td class="td-title">
+              <p><span class="required-span">* </span>涓嶅悎鏍兼垨鍋忕浜嬪疄鐨勬弿杩帮細</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <el-input v-if="showStep === 0 && currentStep === 0" v-model="form.raiseResult" :rows="4"
+                placeholder="璇疯緭鍏ュ唴瀹�" size="small" type="textarea">
+              </el-input>
+              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.raiseResult }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 0">
+            <td v-if="currentStep === 0" class="td-title">
+              <p><span class="required-span">* </span>璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉锛�</p>
+            </td>
+            <td v-if="currentStep === 0" class="td-info" colspan="3">
+              <el-select v-model="form.causeUserId" clearable filterable placeholder="璇烽�夋嫨" size="small">
+                <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
+                </el-option>
+              </el-select>
+            </td>
+          </tr>
+          <tr v-if="showStep === 0 && currentStep !== 0">
+            <td class="td-title">
+              <p>鎻愬嚭浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.raiseUserName }}
+            </td>
+            <td class="td-title">
+              <p>鎻愬嚭閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.raiseDepartment }}
+            </td>
+          </tr>
+          <tr v-if="showStep === 0 && currentStep !== 0">
+            <td class="td-title">
+              <p>鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.raiseTime }}
+            </td>
+          </tr>
+          <tr v-if="showStep === 1">
+            <td class="td-title">
+              <p><span class="required-span">* </span>鍘熷洜鍒嗘瀽锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <el-input v-if="showStep === 1 && currentStep === 1" v-model="form.causeResult" :rows="5"
+                placeholder="璇疯緭鍏ュ唴瀹�" size="small" type="textarea">
+              </el-input>
+              <span v-if="showStep === 1 && currentStep !== 1" class="td-info1"> {{ form.causeResult }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 1 && currentStep !== 1">
+            <td class="td-title">
+              <p>鍘熷洜鍒嗘瀽浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.causeUserName }}
+            </td>
+            <td class="td-title">
+              <p>璐d换閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.causeDepartment }}
+            </td>
+          </tr>
+          <tr v-if="showStep === 1 && currentStep !== 1">
+            <td class="td-title">
+              <p>鍘熷洜鍒嗘瀽鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.causeTime }}
+            </td>
+          </tr>
+          <tr v-if="showStep === 1">
+            <td v-if="currentStep === 1" class="td-title">
+              <p><span class="required-span">* </span>璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉锛�</p>
+            </td>
+            <td v-if="currentStep === 1" class="td-info" colspan="3">
+              <el-select v-model="form.correctUserId" clearable filterable placeholder="璇烽�夋嫨" size="small">
+                <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
+                </el-option>
+              </el-select>
+            </td>
+          </tr>
+          <tr v-if="showStep === 2">
+            <td class="td-title">
+              <p><span class="required-span">* </span>绾犳鎺柦锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <el-input v-if="showStep === 2 && currentStep === 2" v-model="form.correctResult" :rows="5"
+                placeholder="璇疯緭鍏ュ唴瀹�" size="small" type="textarea">
+              </el-input>
+              <span v-if="showStep === 2 && currentStep !== 2" class="td-info1"> {{ form.correctResult }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 2">
+            <td class="td-title">
+              <p>鎻愬嚭瑕佹眰閮ㄩ棬纭锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <el-input v-if="showStep === 2 && currentStep === 2" v-model="form.raiseDepartmentAffirm" :rows="5"
+                placeholder="璇疯緭鍏ュ唴瀹�" size="small" type="textarea">
+              </el-input>
+              <span v-if="showStep === 2 && currentStep !== 2" class="td-info1"> {{ form.raiseDepartmentAffirm }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 2 && currentStep !== 2">
+            <td class="td-title">
+              <p>绾犳浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.correctUserName }}
+            </td>
+            <td class="td-title">
+              <p>璐d换閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.correctDepartment }}
+            </td>
+          </tr>
+          <tr v-if="showStep === 2 && currentStep !== 2">
+            <td class="td-title">
+              <p>绾犳鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.correctTime }}
+            </td>
+          </tr>
+          <tr v-if="showStep === 2">
+            <td v-if="currentStep === 2" class="td-title">
+              <p><span class="required-span">* </span>璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉锛�</p>
+            </td>
+            <td v-if="currentStep === 2" class="td-info" colspan="3">
+              <el-select v-model="form.validationUserId" clearable filterable placeholder="璇烽�夋嫨" size="small">
+                <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
+                </el-option>
+              </el-select>
+            </td>
+          </tr>
+          <tr v-if="showStep === 3">
+            <td class="td-title">
+              <p><span class="required-span">* </span>瀹炴柦楠岃瘉缁撴灉锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              <el-input v-if="showStep === 3 && currentStep === 3" v-model="form.validationResult" :rows="5"
+                placeholder="璇疯緭鍏ュ唴瀹�" size="small" type="textarea">
+              </el-input>
+              <span v-if="showStep === 3 && currentStep !== 3" class="td-info1"> {{ form.validationResult }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 3 && currentStep !== 3">
+            <td class="td-title">
+              <p>楠岃瘉浜猴細</p>
+            </td>
+            <td class="td-info">
+              {{ form.validationUserName }}
+            </td>
+            <td class="td-title">
+              <p>璐d换閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              {{ form.validationDepartment }}
+            </td>
+          </tr>
+          <tr v-if="showStep === 3 && currentStep !== 3">
+            <td class="td-title">
+              <p>楠岃瘉鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="3">
+              {{ form.validationTime }}
+            </td>
+          </tr>
+        </table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeRectifyDia">鍙� 娑�</el-button>
+        <el-button v-if="currentStep !== 4" :loading="editLoad" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getInternalCorrect,
+  addInternalCorrect,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+import {
+  selectUserCondition,
+} from "@/api/system/user.js";
+export default {
+  name: 'correctiveActionDIa',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      currentStep: 0,
+      showStep: 0,
+      form: {
+        superviseDetailsId: '',
+        raiseResult: '',
+        vdeRaiseResult: '',
+        causeUserId: '',
+        raiseUserName: '',
+        raiseDepartment: '',
+        raiseTime: '',
+        causeResult: '',
+        causeUserName: '',
+        causeDepartment: '',
+        causeTime: '',
+        correctUserId: '',
+        correctResult: '',
+        raiseDepartmentAffirm: '',
+        correctUserName: '',
+        correctDepartment: '',
+        correctTime: '',
+        validationUserId: '',
+        validationResult: '',
+        validationUserName: '',
+        validationDepartment: '',
+        validationTime: '',
+      },
+      editLoad: false,
+      personList: [],
+      supervisedUserList: [],
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(type, row) {
+      this.formDia = true
+      if (type !== 'add') {
+        this.searchInfo(row)
+        this.form.superviseDetailsId = row.superviseDetailsId
+      }
+      this.getAuthorizedPerson() // 鑾峰彇浜哄憳鍒楄〃
+      this.getSupervisedUserList() // 鑾峰彇褰撳墠閮ㄩ棬浜哄憳
+    },
+    // 鏌ヨ鐩戞帶璁″垝璇︽儏瀹炴柦淇℃伅
+    searchInfo(row) {
+      this.form.qualityMonitorDetailsId = row.qualityMonitorDetailsId
+      getInternalCorrect({ correctId: row.correctId }).then(res => {
+        if (res.code === 201) return
+        if (res.data.superviseDetailsCorrectId === null) {
+          this.showStep = 0
+          this.currentStep = 0
+        } else {
+          this.form = res.data
+          if (res.data.isFinish === 0) {
+            if (res.data.causeUserId) {
+              this.showStep = 1
+              this.currentStep = 1
+            }
+            if (res.data.correctUserId) {
+              this.showStep = 2
+              this.currentStep = 2
+            }
+            if (res.data.validationUserId) {
+              this.showStep = 3
+              this.currentStep = 3
+            }
+          } else {
+            this.currentStep = 4
+            this.showStep = 3
+          }
+        }
+      }).catch(err => {
+        console.log('err---', err);
+      })
+    },
+    // 鎻愪氦
+    handleEdit() {
+      if (this.currentStep === 0) {
+        if (!this.form.raiseResult) {
+          this.$message.warning('璇峰~鍐欎笉鍚堟牸鎻忚堪')
+          return
+        }
+        if (!this.form.causeUserId) {
+          this.$message.warning('璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉')
+          return
+        }
+      } else if (this.currentStep === 1) {
+        if (!this.form.causeResult) {
+          this.$message.warning('璇峰~鍐欏師鍥犲垎鏋�')
+          return
+        }
+        if (!this.form.correctUserId) {
+          this.$message.warning('璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉')
+          return
+        }
+      } else if (this.currentStep === 2) {
+        if (!this.form.correctResult) {
+          this.$message.warning('璇峰~鍐欑籂姝f帾鏂�')
+          return
+        }
+        if (!this.form.validationUserId) {
+          this.$message.warning('璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉')
+          return
+        }
+      } else if (this.currentStep === 3) {
+        if (!this.form.validationResult) {
+          this.$message.warning('璇峰~鍐欏疄鏂介獙璇佺粨鏋�')
+          return
+        }
+      }
+      this.editLoad = true
+      this.form.supervisedTime = ''
+      this.form.flowType = this.currentStep
+      addInternalCorrect(this.form).then(res => {
+        this.editLoad = false
+        if (res.code === 201) return
+        this.$message.success('鎻愪氦鎴愬姛')
+        this.closeRectifyDia()
+      }).catch(err => {
+        console.log('err---', err);
+        this.editLoad = false
+      })
+    },
+    // 鍏抽棴寮规
+    closeRectifyDia() {
+      this.formDia = false
+      this.$emit('closeRectifyDia')
+    },
+    setStep(step) {
+      this.showStep = step
+    },
+    getAuthorizedPerson() {
+      selectUserCondition().then(res => {
+        let data = []
+        res.data.forEach(a => {
+          data.push({
+            label: a.name,
+            value: a.id
+          })
+        })
+        this.personList = data
+      })
+    },
+    getSupervisedUserList() {
+      selectUserCondition({ type: 2 }).then(res => {
+        let data = []
+        res.data.forEach(a => {
+          data.push({
+            label: a.name,
+            value: a.id
+          })
+        })
+        this.supervisedUserList = data
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 10vh auto 50px !important;
+}
+
+.tables {
+  table-layout: fixed;
+  width: 100%;
+  margin-top: 10px;
+}
+
+.td-title {
+  height: 40px;
+  width: 170px;
+  text-align: center;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+  padding: 6px;
+}
+
+.td-info {
+  padding: 6px;
+}
+
+.td-info1 {
+  display: inline-block;
+  width: 100%;
+  text-align: left;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/implementPlanDia.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/implementPlanDia.vue
new file mode 100644
index 0000000..5a94ebe
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/implementPlanDia.vue
@@ -0,0 +1,307 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="鍐呴儴瀹℃牳瀹炴柦璁″垝" width="80%" @close="closeImplementDia">
+      <el-form ref="form" :model="form" :rules="rules" label-width="auto">
+        <el-col :span="24">
+          <el-form-item label="瀹℃牳鐩殑" prop="purposes">
+            <el-input v-model="form.purposes" :disabled="operationType === 'ratify'" clearable size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="瀹℃牳鎬ц川" prop="nature">
+            <el-input v-model="form.nature" :disabled="operationType === 'ratify'" clearable size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="瀹℃牳鑼冨洿" prop="scope">
+            <el-input v-model="form.scope" :disabled="operationType === 'ratify'" clearable size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="瀹℃牳渚濇嵁" prop="basis">
+            <el-input v-model="form.basis" :disabled="operationType === 'ratify'" clearable size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瀹℃牳缁勯暱" prop="teamLeader">
+            <el-input v-model="form.teamLeader" :disabled="operationType === 'ratify'" clearable
+              size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鍐呭鍛�" prop="internalAuditor">
+            <el-input v-model="form.internalAuditor" :disabled="operationType === 'ratify'" clearable
+              size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瀹℃牳鏃ユ湡" prop="reviewDate">
+            <el-date-picker v-model="form.reviewDate" :disabled="operationType === 'ratify'" clearable
+              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="瀹℃牳鏂规硶" prop="auditMethod">
+            <el-input v-model="form.auditMethod" :disabled="operationType === 'ratify'" clearable
+              size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="棣栨浼氳鏃堕棿" prop="firstMeetingTime">
+            <el-date-picker v-model="form.firstMeetingTime" :disabled="operationType === 'ratify'" clearable
+              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="鏈浼氳鏃堕棿" prop="lastMeetingTime">
+            <el-date-picker v-model="form.lastMeetingTime" :disabled="operationType === 'ratify'" clearable
+              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="瀹℃牳鎶ュ憡鎻愪氦鏃ユ湡" prop="submitTime">
+            <el-date-picker v-model="form.submitTime" :disabled="operationType === 'ratify'" clearable
+              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="瀹℃牳鎶ュ憡鍙戞斁鑼冨洿" prop="submitScope">
+            <el-input v-model="form.submitScope" :disabled="operationType === 'ratify'" clearable
+              size="small"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-form>
+      <div v-if="operationType !== 'ratify'" 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>
+      <el-table :data="implementDetailList" border height="300" style="width: 100%">
+        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column header-align="center" label="鏃堕棿" prop="implement">
+          <template slot-scope="{row}">
+            <el-input v-model="row.implement" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="鍙楀鏍搁儴闂�" prop="department">
+          <template slot-scope="{row}">
+            <el-input v-model="row.department" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="璐d换浜�" prop="responsible">
+          <template slot-scope="{row}">
+            <el-input v-model="row.responsible" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="瀹℃牳鍛�" prop="auditor" width="180">
+          <template slot-scope="{row}">
+            <el-input v-model="row.auditor" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column header-align="center" label="瀹℃牳鍐呭" prop="reviewContent" width="180">
+          <template slot-scope="{row}">
+            <el-input v-model="row.reviewContent" :disabled="operationType === 'ratify'" size="small" />
+          </template>
+        </el-table-column>
+      </el-table>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="operationType === 'ratify'" :loading="loading" @click="ratify(0)">涓嶆壒鍑�</el-button>
+        <el-button v-if="operationType === 'ratify'" :loading="loading" type="primary" @click="ratify(1)">鎵�
+          鍑�</el-button>
+        <el-button v-if="operationType !== 'ratify'" @click="closeImplementDia">鍙� 娑�</el-button>
+        <el-button v-if="operationType !== 'ratify'" :loading="loading" type="primary" @click="handleEdit">鎻�
+          浜�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="approvalDialog" title="鎵瑰噯" width="30%" @close="approvalDialog = false">
+      <span>
+        鎵瑰噯澶囨敞锛�
+        <el-input v-model="ratifyRemark" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="approvalLoading" @click="approvalDialog = false">鍙� 娑�</el-button>
+        <el-button :loading="approvalLoading" type="primary" @click="handleApproval(0)">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getInternalImplementOne,
+  addInternalImplement,
+  updateInternalImplement,
+  ratifyInternalImplement,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+export default {
+  name: 'implementPlanDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        purposes: '',
+        nature: '',
+        scope: '',
+        basis: '',
+        teamLeader: '',
+        internalAuditor: '',
+        reviewDate: '',
+        auditMethod: '',
+        firstMeetingTime: '',
+        lastMeetingTime: '',
+        submitTime: '',
+        submitScope: '',
+      },
+      rules: {
+        purposes: [{ required: true, message: '璇峰~鍐欏鏍哥洰鐨�', trigger: 'blur' }],
+        nature: [{ required: true, message: '璇峰~鍐欏鏍告�ц川', trigger: 'blur' }],
+        scope: [{ required: true, message: '璇峰~鍐欏鏍歌寖鍥�', trigger: 'blur' }],
+        basis: [{ required: true, message: '璇峰~鍐欏鏍镐緷鎹�', trigger: 'blur' }],
+        teamLeader: [{ required: true, message: '璇峰~鍐欏鏍哥粍闀�', trigger: 'blur' }],
+        internalAuditor: [{ required: true, message: '璇峰~鍐欏唴瀹″憳', trigger: 'blur' }],
+        reviewDate: [{ required: true, message: '璇峰~鍐欏鏍告椂闂�', trigger: 'blur' }],
+        auditMethod: [{ required: true, message: '璇峰~鍐欏鏍告柟娉�', trigger: 'blur' }],
+        firstMeetingTime: [{ required: true, message: '璇峰~鍐欓娆′細璁椂闂�', trigger: 'blur' }],
+        lastMeetingTime: [{ required: true, message: '璇峰~鍐欐湯娆′細璁椂闂�', trigger: 'blur' }],
+        submitTime: [{ required: true, message: '璇峰~鍐欏鏍告姤鍛婃彁浜ゆ棩鏈�', trigger: 'blur' }],
+        submitScope: [{ required: true, message: '璇峰~鍐欏鏍告姤鍛婂彂鏀捐寖鍥�', trigger: 'blur' }],
+      },
+      implementDetailList: [],
+      operationType: '',
+      approvalDialog: false,
+      approvalLoading: false,
+      ratifyRemark: '',
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      if (type !== 'add') {
+        this.searchInfo(row)
+      }
+    },
+    // 鏌ヨ璇︽儏
+    searchInfo(row) {
+      this.diaLoading = true
+      getInternalImplementOne({ implementId: row.implementId }).then(res => {
+        this.diaLoading = false
+        if (res.code === 201) return
+        this.form = res.data
+        this.implementDetailList = this.form.implementDetailList
+      }).catch(err => {
+        console.log(err)
+        this.diaLoading = false
+      })
+    },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          if (this.implementDetailList.length === 0) {
+            this.$message.warning('璇锋坊鍔犺〃鏍兼暟鎹�')
+            return
+          }
+          this.loading = true
+          const internalImplementDto = this.HaveJson(this.form)
+          internalImplementDto.implementDetailList = this.HaveJson(this.implementDetailList)
+          if (this.operationType === 'add') {
+            addInternalImplement(internalImplementDto).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            updateInternalImplement(internalImplementDto).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    ratify(ratifyStatus) {
+      // 涓嶆壒鍑嗛渶瑕佸~鍐欐壒鍑嗗唴瀹�
+      if (ratifyStatus === 0) {
+        this.approvalDialog = true
+      } else {
+        this.handleApproval(ratifyStatus)
+      }
+    },
+    // 鎻愪氦鎵瑰噯淇℃伅
+    handleApproval(ratifyStatus) {
+      this.approvalLoading = true
+      const internalImplementDto = this.HaveJson(this.form)
+      internalImplementDto.ratifyStatus = ratifyStatus
+      internalImplementDto.ratifyRemark = ratifyStatus === 0 ? this.ratifyRemark : ''
+      ratifyInternalImplement(internalImplementDto).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.closeImplementDia(this.departId);
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    // 澧炲姞琛ㄦ牸琛屾暟鎹�
+    addRow() {
+      this.implementDetailList.push({
+        implement: '',
+        department: '',
+        responsible: '',
+        auditor: '',
+        reviewContent: '',
+      })
+    },
+    // 娓呯┖琛ㄦ牸鏁版嵁
+    clearTable() {
+      this.implementDetailList = []
+    },
+    closeImplementDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeImplementDia')
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 10vh auto 50px !important;
+}
+
+>>>.el-dialog__body {
+  max-height: 38em;
+  overflow-y: auto;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/implementationPlan.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/implementationPlan.vue
new file mode 100644
index 0000000..e1810e9
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/implementationPlan.vue
@@ -0,0 +1,291 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">瀹℃牳鐩殑锛�</span>
+        <el-input v-model="searchForm.purposes" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" @pagination="pagination" :page="page">
+      </limsTable>
+    </div>
+    <implement-plan-dia v-if="implementPlanDia" ref="implementPlanDia"
+      @closeImplementDia="closeImplementDia"></implement-plan-dia>
+  </div>
+</template>
+
+<script>
+import {
+  pageInternalImplement,
+  delInternalImplement,
+  exportInternalImplement,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+import limsTable from "@/components/Table/lims-table.vue";
+import ImplementPlanDia from './implementPlanDia.vue';
+
+export default {
+  name: 'implementationPlan',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { ImplementPlanDia, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        purposes: '',
+      },
+      tableColumn: [
+        {
+          label: '瀹℃牳鐩殑',
+          prop: 'purposes',
+          minWidth: '100'
+        },
+        {
+          label: '瀹℃牳鎬ц川',
+          prop: 'nature',
+          minWidth: '100'
+        },
+        {
+          label: '瀹℃牳鑼冨洿',
+          prop: 'scope',
+          minWidth: '100'
+        },
+        {
+          label: '瀹℃牳渚濇嵁',
+          prop: 'basis',
+          minWidth: '100'
+        },
+        {
+          label: '瀹℃牳缁勯暱',
+          prop: 'teamLeader',
+          minWidth: '100'
+        },
+        {
+          label: '鍐呭鍛�',
+          prop: 'internalAuditor',
+          minWidth: '100',
+        },
+        {
+          label: '瀹℃牳鏃ユ湡',
+          prop: 'reviewDate',
+          minWidth: '100',
+        },
+        {
+          label: '瀹℃牳鏂规硶',
+          prop: 'auditMethod',
+          minWidth: '100',
+        },
+        {
+          label: '棣栨浼氳鏃堕棿',
+          prop: 'firstMeetingTime',
+          minWidth: '100',
+        },
+        {
+          label: '鏈浼氳鏃堕棿',
+          prop: 'lastMeetingTime',
+          minWidth: '100',
+        },
+        {
+          label: '瀹℃牳鎶ュ憡鎻愪氦鏃ユ湡',
+          prop: 'submitTime',
+          minWidth: '100',
+        },
+        {
+          label: '瀹℃牳鎶ュ憡鍙戞斁鑼冨洿',
+          prop: 'submitScope',
+          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: 'ratifyRemark',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          minWidth: '220',
+          fixed: 'right',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('ratify', row);
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      implementPlanDia: false,
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = this.searchForm
+      const page = this.page
+      this.tableLoading = true
+      pageInternalImplement({ ...entity, ...page }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鏂板锛岀紪杈戯紝鎵瑰噯寮规
+    openFormDia(type, row) {
+      this.implementPlanDia = true
+      this.$nextTick(() => {
+        this.$refs.implementPlanDia.openDia(type, row)
+      })
+    },
+    closeImplementDia() {
+      this.implementPlanDia = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.purposes = '';
+      this.searchList()
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delInternalImplement({ implementId: row.implementId }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 瀵煎嚭
+    handleDown(row) {
+      exportInternalImplement({ implementId: row.implementId }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鍐呭瀹炴柦璁″垝' + '.docx');
+      })
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlan.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlan.vue
new file mode 100644
index 0000000..edd31a9
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlan.vue
@@ -0,0 +1,313 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">鍐呭鐩殑锛�</span>
+        <el-input v-model="searchForm.purpose" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" @pagination="pagination" :page="page">
+      </limsTable>
+    </div>
+    <year-plan-dia v-if="yearPlanDia" ref="yearPlanDia" @closeYearDia="closeYearDia"></year-plan-dia>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import YearPlanDia from './yearPlanDia.vue';
+import {
+  pageInternalPlan,
+  delInternalPlan,
+  exportInternalPlan,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+
+export default {
+  name: 'yearPlan',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { YearPlanDia, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        purpose: '',
+      },
+      tableColumn: [
+        {
+          label: '鍐呭鐩殑',
+          prop: 'purpose',
+          minWidth: '100'
+        },
+        {
+          label: '鍐呭鑼冨洿',
+          prop: 'scope',
+          minWidth: '100'
+        },
+        {
+          label: '鍐呭渚濇嵁',
+          prop: 'basis',
+          minWidth: '100'
+        },
+        {
+          label: '缁勯暱',
+          prop: 'leader',
+          minWidth: '100'
+        },
+        {
+          label: '缁勫憳',
+          prop: 'crew',
+          minWidth: '100'
+        },
+        {
+          dataType: 'tag',
+          label: '瀹℃牳鐘舵��',
+          prop: 'examineStatus',
+          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: 'examineRemark',
+          minWidth: '100'
+        }, {
+          label: '瀹℃牳浜�',
+          prop: 'examineUserName',
+          minWidth: '100'
+        }, {
+          label: '瀹℃牳鏃ユ湡',
+          prop: 'examineTime',
+          minWidth: '160'
+        }, {
+          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: 'ratifyRemark',
+          minWidth: '100'
+        }, {
+          label: '鎵瑰噯浜�',
+          prop: 'ratifyUserName',
+          minWidth: '100'
+        }, {
+          label: '鎵瑰噯鏃ユ湡',
+          prop: 'ratifyTime',
+          minWidth: '160'
+        },
+        {
+          dataType: 'action',
+          fixed: 'right',
+          minWidth: '220',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '瀹℃牳',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('examine', row);
+              },
+              disabled: (row) => {
+                if (row.examineStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('ratify', row);
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1 || row.examineStatus === 0 || row.examineStatus === null) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              },
+              disabled: (row) => {
+                if (row.ratifyStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      yearPlanDia: false,
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      const entity = this.searchForm
+      const page = this.page
+      this.tableLoading = true
+      pageInternalPlan({ ...entity, ...page }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delInternalPlan({ planId: row.planId }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 鏂板锛岀紪杈戯紝鎵瑰噯寮规
+    openFormDia(type, row) {
+      this.yearPlanDia = true
+      this.$nextTick(() => {
+        this.$refs.yearPlanDia.openDia(type, row)
+      })
+    },
+    // 瀵煎嚭
+    handleDown(row) {
+      exportInternalPlan({ planId: row.planId }).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鍐呭骞村害璁″垝' + '.docx');
+      })
+    },
+    closeYearDia() {
+      this.yearPlanDia = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.purpose = '';
+      this.searchList()
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlanDia.vue b/src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlanDia.vue
new file mode 100644
index 0000000..0c1eba1
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/components/yearPlanDia.vue
@@ -0,0 +1,342 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="鍐呴儴瀹℃牳骞村害璁″垝" width="1000px" @close="closeYearDia">
+      <el-form ref="form" :model="form" :rules="rules" label-position="top" label-width="auto">
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鍐呭鐩殑" prop="purpose">
+              <el-input v-model="form.purpose" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍐呭鑼冨洿" prop="scope">
+              <el-input v-model="form.scope" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                :rows="3" clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍐呭渚濇嵁" prop="basis">
+              <el-input v-model="form.basis" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="缁勯暱" prop="leader">
+              <el-input v-model="form.leader" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="缁勫憳" prop="crew">
+              <el-input v-model="form.crew" :disabled="operationType === 'examine' || operationType === 'ratify'"
+                clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <table border="1" cellspacing="10" class="table">
+        <tr>
+          <td class="div-with-line">
+            <span style="float: left;">閮ㄩ棬</span>
+            <span style="float: right;">鏈堜唤</span>
+          </td>
+          <th v-for="(item, index) in dic1" :key="index">{{ item }}</th>
+        </tr>
+        <tr v-for="(item, index) in planDetailList" :key="index">
+          <td>{{ item.department }}</td>
+          <th>
+            <el-input v-model="item.january" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.february" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.march" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.april" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.may" :disabled="operationType === 'examine' || operationType === 'ratify'" clearable
+              size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.june" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.july" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.august" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.september" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.october" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.november" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+          <th>
+            <el-input v-model="item.december" :disabled="operationType === 'examine' || operationType === 'ratify'"
+              clearable size="small"></el-input>
+          </th>
+        </tr>
+      </table>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="operationType === 'examine'" :loading="loading" @click="examine(0)">涓嶉�氳繃</el-button>
+        <el-button v-if="operationType === 'examine'" :loading="loading" type="primary" @click="examine(1)">閫�
+          杩�</el-button>
+        <el-button v-if="operationType === 'ratify'" :loading="loading" @click="approval(0)">涓嶆壒鍑�</el-button>
+        <el-button v-if="operationType === 'ratify'" :loading="loading" type="primary" @click="handleApproval(1)">鎵�
+          鍑�</el-button>
+        <el-button v-if="operationType !== 'ratify' && operationType !== 'examine'" @click="closeYearDia">鍙�
+          娑�</el-button>
+        <el-button v-if="operationType !== 'ratify' && operationType !== 'examine'" :loading="loading" type="primary"
+          @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="examineDialog" title="瀹℃牳" width="30%" @close="examineDialog = false">
+      <span>
+        瀹℃牳澶囨敞锛�
+        <el-input v-model="examineRemark" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="examineLoading" @click="examineDialog = false">鍙� 娑�</el-button>
+        <el-button :loading="examineLoading" type="primary" @click="handleExamine(0)">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="approvalDialog" title="鎵瑰噯" width="30%" @close="approvalDialog = false">
+      <span>
+        鎵瑰噯澶囨敞锛�
+        <el-input v-model="ratifyRemark" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="approvalLoading" @click="approvalDialog = false">鍙� 娑�</el-button>
+        <el-button :loading="approvalLoading" type="primary" @click="handleApproval(0)">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getInternalPlanOne,
+  addInternalPlan,
+  updateInternalPlan,
+  examineInternalPlan,
+  ratifyInternalPlan,
+} from '@/api/cnas/systemManagement/internalAuditManagement.js'
+export default {
+  name: 'yearPlanDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        purpose: '',
+        scope: '',
+        basis: '',
+        leader: '',
+        crew: '',
+      },
+      rules: {
+        purpose: [{ required: true, message: '璇峰~鍐欏唴瀹$洰鐨�', trigger: 'blur' }],
+        scope: [{ required: true, message: '璇峰~鍐欏唴瀹¤寖鍥�', trigger: 'blur' }],
+        basis: [{ required: true, message: '璇峰~鍐欏唴瀹′緷鎹�', trigger: 'blur' }],
+        leader: [{ required: true, message: '璇峰~鍐欑粍闀�', trigger: 'blur' }],
+        crew: [{ required: true, message: '璇峰~鍐欑粍鍛�', trigger: 'blur' }],
+      },
+      operationType: '',
+      approvalDialog: false,
+      approvalLoading: false,
+      examineDialog: false,
+      examineLoading: false,
+      ratifyRemark: '',
+      examineRemark: '',
+      dic1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
+      planDetailList: [{ department: '瑁呭鐢电紗瀹為獙瀹�' }, { department: '閫氫俊浜у搧瀹為獙瀹�' }, { department: '鐢靛姏浜у搧瀹為獙瀹�' }, { department: '鍌ㄨ兘浜у搧瀹為獙瀹�' }, { department: '灏勯绾跨紗瀹為獙瀹�' }],
+    };
+  },
+  mounted() {
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      if (type !== 'add') {
+        this.searchInfo(row)
+      }
+    },
+    // 鏌ヨ璇︽儏
+    searchInfo(row) {
+      this.diaLoading = true
+      getInternalPlanOne({ planId: row.planId }).then(res => {
+        this.diaLoading = false
+        if (res.code === 201) return
+        this.form = res.data
+        this.planDetailList = this.form.planDetailList
+      }).catch(err => {
+        console.log(err)
+        this.diaLoading = false
+      })
+    },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.loading = true
+          const internalPlan = this.HaveJson(this.form)
+          internalPlan.planDetailList = this.HaveJson(this.planDetailList)
+          if (this.operationType === 'add') {
+            addInternalPlan(internalPlan).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            updateInternalPlan(internalPlan).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    // 瀹℃牳娴佺▼
+    examine(examineStatus) {
+      if (examineStatus === 0) {
+        this.examineDialog = true
+      } else {
+        this.handleExamine(examineStatus)
+      }
+    },
+    handleExamine(examineStatus) {
+      this.examineLoading = true
+      const internalReport = this.HaveJson(this.form)
+      internalReport.examineStatus = examineStatus
+      internalReport.examineRemark = this.examineRemark
+      examineInternalPlan(internalReport).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.closeYearDia(this.departId);
+        }
+        this.examineLoading = false
+      }).catch(() => {
+        this.examineLoading = false
+      })
+    },
+    // 鎻愪氦鎵瑰噯淇℃伅
+    approval(ratifyStatus) {
+      if (ratifyStatus === 0) {
+        this.approvalDialog = true
+      } else {
+        this.handleApproval(ratifyStatus)
+      }
+    },
+    handleApproval(ratifyStatus) {
+      this.approvalLoading = true
+      const internalReport = this.HaveJson(this.form)
+      internalReport.ratifyStatus = ratifyStatus
+      internalReport.ratifyRemark = this.ratifyRemark
+      ratifyInternalPlan(internalReport).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.closeYearDia(this.departId);
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    closeYearDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeYearDia')
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+
+>>>.el-dialog__body {
+  max-height: 42em;
+  overflow-y: auto;
+}
+
+>>>.is-required {
+  margin-bottom: 6px;
+}
+
+.table {
+  width: 100%;
+  margin-top: 20px;
+}
+
+.table th {
+  width: 70px;
+}
+
+.table td {
+  width: 70px;
+  height: 70px;
+  text-align: center;
+}
+
+.div-with-line {
+  width: 70px;
+  height: 70px;
+  position: relative;
+  /*overflow: hidden; /* 闅愯棌婧㈠嚭鍐呭 */
+}
+
+.div-with-line::after {
+  content: '';
+  position: absolute;
+  bottom: 0;
+  height: 1px;
+  background-color: #000000;
+  left: 50%;
+  transform: translateX(-50%) rotate(45deg);
+  transform-origin: center 50%;
+  top: 50%;
+  width: 100px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/internalAuditManagement/index.vue b/src/views/CNAS/systemManagement/internalAuditManagement/index.vue
new file mode 100644
index 0000000..4b61b39
--- /dev/null
+++ b/src/views/CNAS/systemManagement/internalAuditManagement/index.vue
@@ -0,0 +1,57 @@
+<template>
+  <div class="main">
+    <el-tabs v-model="activeName" class="tab-panel" type="border-card">
+      <el-tab-pane label="骞村害璁″垝" name="yearPlan">
+        <year-plan></year-plan>
+      </el-tab-pane>
+      <el-tab-pane label="鍐呴儴瀹炴柦璁″垝" name="implementationPlan">
+        <implementation-plan></implementation-plan>
+      </el-tab-pane>
+      <el-tab-pane label="鍐呭浼氳绛惧埌" name="meetingSignIn">
+        <audit-meeting-sign></audit-meeting-sign>
+      </el-tab-pane>
+      <el-tab-pane label="鍐呭妫�鏌�" name="auditInspection">
+        <audit-inspection></audit-inspection>
+      </el-tab-pane>
+      <el-tab-pane label="绾犳鎺柦" name="correctiveAction">
+        <corrective-action></corrective-action>
+      </el-tab-pane>
+      <el-tab-pane label="鍐呭鎶ュ憡" name="auditReport">
+        <audit-report></audit-report>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import YearPlan from './components/yearPlan.vue';
+import implementationPlan from './components/implementationPlan.vue';
+import AuditInspection from './components/auditInspection.vue';
+import AuditReport from './components/auditReport.vue';
+import AuditMeetingSign from './components/auditMeetingSign.vue';
+import CorrectiveAction from './components/correctiveAction.vue';
+
+export default {
+  name: 'InternalAuditManagement',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { CorrectiveAction, AuditMeetingSign, AuditReport, AuditInspection, YearPlan, implementationPlan },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      activeName: 'yearPlan',
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {}
+};
+</script>
+
+<style scoped>
+.main {
+  padding: 15px 0;
+}
+
+.tab-panel {
+  background: #fff;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/managementReview/components/managementFormDIa.vue b/src/views/CNAS/systemManagement/managementReview/components/managementFormDIa.vue
new file mode 100644
index 0000000..bb2c3f7
--- /dev/null
+++ b/src/views/CNAS/systemManagement/managementReview/components/managementFormDIa.vue
@@ -0,0 +1,246 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="绠$悊璇勫璁″垝" width="80%" @close="closeImplementDia">
+      <el-form ref="form" :model="form" :rules="rules" label-position="right" label-width="auto">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="璇勫鏃堕棿" prop="reviewTime">
+              <el-date-picker v-model="form.reviewTime" :disabled="operationType === 'ratify'" clearable
+                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="judgingLocation">
+              <el-input v-model="form.judgingLocation" :disabled="operationType === 'ratify'" clearable
+                size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇勫鐩殑" prop="judgingPurpose">
+              <el-input v-model="form.judgingPurpose" :disabled="operationType === 'ratify'" clearable
+                size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇勫鏂瑰紡" prop="judgingMethod">
+              <el-input v-model="form.judgingMethod" :disabled="operationType === 'ratify'" clearable
+                size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍙傚姞浜哄憳" prop="participants">
+              <!-- <el-input v-model="form.participants" :disabled="operationType === 'ratify'" clearable size="small"></el-input> -->
+              <el-select v-model="form.participants" size="small" style="width: 100%;" filterable
+                :disabled="operationType === 'ratify'" clearable multiple>
+                <el-option v-for="item in personList" :key="item.value" :label="item.label" :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇勫鑼冨洿" prop="judgingScope">
+              <el-input v-model="form.judgingScope" :disabled="operationType === 'ratify'" clearable
+                size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇勫渚濇嵁" prop="judgingBasis">
+              <el-input v-model="form.judgingBasis" :disabled="operationType === 'ratify'" :rows="3" clearable
+                size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇勫涓昏鍐呭" prop="mainContext">
+              <el-input v-model="form.mainContext" :disabled="operationType === 'ratify'" :rows="3" clearable
+                size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍑嗗宸ヤ綔瑕佹眰" prop="preparationRequirements">
+              <el-input v-model="form.preparationRequirements" :disabled="operationType === 'ratify'" :rows="3"
+                clearable size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeImplementDia">鍙� 娑�</el-button>
+        <el-button v-if="operationType === 'ratify'" :loading="loading" type="primary" @click="handleApproval(1)">鎵�
+          鍑�</el-button>
+        <el-button v-if="operationType !== 'ratify'" :loading="loading" type="primary" @click="handleEdit">鎻�
+          浜�</el-button>
+      </span>
+    </el-dialog>
+    <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="approvalDialog = false">鍙� 娑�</el-button>
+        <el-button :loading="approvalLoading" type="primary" @click="handleApproval(0)">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addReviewProgram,
+  modifyReviewProgram,
+} from '@/api/cnas/systemManagement/managementReview.js'
+import { dateFormat } from '@/utils/date'
+import {
+  selectUserCondition,
+} from "@/api/system/user.js";
+import { mapGetters } from "vuex";
+export default {
+  name: 'managementFormDIa',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        id: '',
+        reviewTime: '',
+        judgingLocation: '',
+        judgingPurpose: '',
+        judgingMethod: '',
+        participants: [],
+        judgingScope: '',
+        judgingBasis: '',
+        mainContext: '',
+        preparationRequirements: '',
+      },
+      rules: {
+        reviewTime: [{ required: true, message: '璇烽�夋嫨璇勫鏃堕棿', trigger: 'blur' }],
+        judgingLocation: [{ required: true, message: '璇峰~鍐欒瘎瀹″湴鐐�', trigger: 'blur' }],
+        judgingPurpose: [{ required: true, message: '璇峰~鍐欒瘎瀹$洰鐨�', trigger: 'blur' }],
+        judgingMethod: [{ required: true, message: '璇峰~鍐欒瘎瀹℃柟寮�', trigger: 'blur' }],
+        participants: [{ required: true, message: '璇峰~鍐欏弬鍔犱汉鍛�', trigger: 'change' }],
+        judgingScope: [{ required: true, message: '璇峰~鍐欒瘎瀹¤寖鍥�', trigger: 'blur' }],
+        judgingBasis: [{ required: true, message: '璇峰~鍐欒瘎瀹′緷鎹�', trigger: 'blur' }],
+        mainContext: [{ required: true, message: '璇峰~鍐欒瘎瀹′富瑕佸唴瀹�', trigger: 'blur' }],
+        preparationRequirements: [{ required: true, message: '璇峰~鍐欏噯澶囧伐浣滆姹�', trigger: 'blur' }],
+      },
+      operationType: '',
+      approvalDialog: false,
+      approvalLoading: false,
+      qualityRemark: '',
+      personList: [],
+    };
+  },
+  computed: {
+    ...mapGetters(['nickName'])
+  },
+  mounted() {
+    this.getAuthorizedPerson()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      if (type !== 'add') {
+        this.form = row
+        this.form.participants = row.participants ? row.participants.split(',').map(m => Number(m)) : []
+      }
+    },
+    // 鏌ヨ璇︽儏
+    // searchInfo (row) {
+    //   this.diaLoading = true
+    //   this.$axios(this.$api.internalReport.getInternalReportOne + '?reportId=' + row.reportId).then(res => {
+    //     this.diaLoading = false
+    //     if (res.code === 201) return
+    //     this.form = res.data
+    //   }).catch(err => {
+    //     console.log(err)
+    //     this.diaLoading = false
+    //   })
+    // },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.loading = true
+          const internalReport = this.HaveJson(this.form)
+          internalReport.participants = internalReport.participants.join(',')
+          if (this.operationType === 'add') {
+            addReviewProgram(internalReport).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            modifyReviewProgram(internalReport).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeImplementDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    // 鎻愪氦鎵瑰噯淇℃伅
+    handleApproval(qualityStatus) {
+      this.approvalLoading = true
+      const internalReport = this.HaveJson(this.form)
+      internalReport.approve = this.nickName
+      internalReport.approveDate = dateFormat(new Date())
+      internalReport.participants = internalReport.participants.join(',')
+      modifyReviewProgram(internalReport).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.closeImplementDia(this.departId);
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    closeImplementDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeImplementDia')
+    },
+    getAuthorizedPerson() {
+      selectUserCondition().then(res => {
+        let data = []
+        res.data.forEach(a => {
+          data.push({
+            label: a.name,
+            value: a.id
+          })
+        })
+        this.personList = data
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/managementReview/components/managementReviewPlan.vue b/src/views/CNAS/systemManagement/managementReview/components/managementReviewPlan.vue
new file mode 100644
index 0000000..14dc270
--- /dev/null
+++ b/src/views/CNAS/systemManagement/managementReview/components/managementReviewPlan.vue
@@ -0,0 +1,306 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">璇勫鍦扮偣锛�</span>
+        <el-input v-model="searchForm.judgingLocation" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" :page="page" @pagination="pagination">
+      </limsTable>
+    </div>
+    <management-form-d-ia v-if="managementFormDIa" ref="managementFormDIa"
+      @closeImplementDia="closeImplementDia"></management-form-d-ia>
+    <el-dialog :visible.sync="listDialogVisible" title="鏂囦欢鏌ョ湅" top="15vh" width="400px">
+      <div style="max-height:60vh;overflow-y: auto;">
+        <p v-for="(item, index) in fileList" :key="index">
+          <span>{{ item.fileName }}</span>
+          <el-button icon="el-icon-view" size="small" style="margin-left: 20px;" type="text"
+            @click="lookFile(item.url, item.fileName)">棰勮</el-button>
+          <el-button icon="el-icon-bottom" size="small" style="margin-left: 20px;" type="text"
+            @click="handleDown0(item.url, item.fileName)">涓嬭浇</el-button>
+        </p>
+      </div>
+    </el-dialog>
+    <el-dialog :visible.sync="lookDialogVisible" fullscreen title="鏌ョ湅闄勪欢" top="5vh" width="800px">
+      <filePreview v-if="lookDialogVisible" :currentFile="{}" :fileUrl="javaApi + '/word/' + currentInfo.url"
+        style="height: 90vh;overflow-y: auto;" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import ManagementFormDIa from './managementFormDIa.vue';
+import filePreview from "@/components/Preview/filePreview.vue";
+import {
+  addReviewProgramFile,
+  selectReviewProgramFile,
+  getPageReviewProgram,
+  deleteReviewProgram,
+  exportReviewProgram,
+} from '@/api/cnas/systemManagement/managementReview.js'
+
+export default {
+  name: 'managementReviewPlan',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { ManagementFormDIa, limsTable, filePreview },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        judgingLocation: '',
+      },
+      listDialogVisible: false,
+      lookDialogVisible: false,
+      fileList: [],
+      currentInfo: {},
+      tableColumn: [
+        {
+          label: '璇勫鏃堕棿',
+          prop: 'reviewTime',
+        },
+        {
+          label: '璇勫鍦扮偣',
+          prop: 'judgingLocation',
+        },
+        {
+          label: '璇勫鐩殑',
+          prop: 'judgingPurpose',
+        },
+        {
+          label: '璇勫鏂瑰紡',
+          prop: 'judgingMethod',
+        },
+        {
+          label: '璇勫鑼冨洿',
+          prop: 'judgingScope',
+        },
+        // {
+        //   dataType: 'tag',
+        //   label: '鎵瑰噯鐘舵��',
+        //   prop: 'approve',
+        //   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: '110',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+              disabled: (row) => {
+                return !!row.approve
+              },
+            },
+            {
+              name: '涓婁紶',
+              type: 'upload',
+              multiple: true,
+              limit: 20,
+              accept: '.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.pdf',
+              clickFun: async (row, file, fileList) => {
+                const formData = new FormData();
+                formData.append('file', file.raw); // 鏂囦欢瀛楁
+                formData.append('id', row.id); // 鏂囦欢鍚嶅瓧娈�
+                let res = await addReviewProgramFile(formData)
+                if (res.code == 200) {
+                  this.$message({ message: '涓婁紶鎴愬姛', type: 'success' });
+                  // this.searchList()
+                  return
+                } else {
+                  this.$message({ message: '涓婁紶澶辫触', type: 'error' });
+                  return
+                }
+              },
+              disabled: (row) => {
+                return !!row.approve
+              },
+            },
+            {
+              name: '鏌ョ湅闄勪欢',
+              type: 'text',
+              clickFun: (row) => {
+                selectReviewProgramFile({ id: row.id }).then(res => {
+                  this.listDialogVisible = true;
+                  this.fileList = res.data.fileList
+                });
+              },
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('ratify', row);
+              },
+              disabled: (row) => {
+                return !!row.approve
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              },
+              disabled: (row) => {
+                if (row.qualityStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      managementFormDIa: false,
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      this.tableLoading = true
+      getPageReviewProgram({
+        judgingLocation: this.searchForm.judgingLocation,
+        pages: this.page.current,
+        size: this.page.size
+      }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鏂板锛岀紪杈戯紝鎵瑰噯寮规
+    openFormDia(type, row) {
+      this.managementFormDIa = true
+      this.$nextTick(() => {
+        this.$refs.managementFormDIa.openDia(type, row)
+      })
+    },
+    closeImplementDia() {
+      this.managementFormDIa = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.judgingLocation = '';
+      this.searchList()
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        deleteReviewProgram({ id: row.id }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 鍒嗛〉
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+    handleDown(row) {
+      exportReviewProgram({ id: row.id }).then(res => {
+        const blob = new Blob([res], { type: 'application/octet-stream' });
+        this.$download.saveAs(blob, '璇勫璁″垝.docx');
+      })
+    },
+    lookFile(url, name) {
+      this.currentInfo.url = url
+      this.currentInfo.name = name
+      this.lookDialogVisible = true
+    },
+    handleDown0(url, name) {
+      if (!url) return this.$message.warning('鏂囦欢鏈笂浼�')
+      let url0 = this.javaApi + '/word/' + url
+      this.$download.saveAs(url0, name);
+    }
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/managementReview/components/meetingRecords.vue b/src/views/CNAS/systemManagement/managementReview/components/meetingRecords.vue
new file mode 100644
index 0000000..890ae93
--- /dev/null
+++ b/src/views/CNAS/systemManagement/managementReview/components/meetingRecords.vue
@@ -0,0 +1,196 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">浼氳鍦扮偣锛�</span>
+        <el-input v-model="searchForm.place" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" :page="page" @pagination="pagination">
+      </limsTable>
+    </div>
+    <meeting-records-dia v-if="meetingRecordsDia" ref="meetingRecordsDia"
+      @closeYearDia="closeYearDia"></meeting-records-dia>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import MeetingRecordsDia from './meetingRecordsDia.vue';
+import ManagementFormDIa from './managementFormDIa.vue';
+import {
+  getPageMeeting,
+  deleteMeeting,
+  exportMeeting,
+} from '@/api/cnas/systemManagement/managementReview.js'
+
+export default {
+  name: 'meetingRecords',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { ManagementFormDIa, MeetingRecordsDia, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        place: '',
+      },
+      tableColumn: [
+        {
+          label: '鏃堕棿',
+          prop: 'meetingTime',
+          minWidth: '100'
+        },
+        {
+          label: '涓绘寔浜�',
+          prop: 'compere',
+          minWidth: '100'
+        },
+        {
+          label: '浼氳鍦扮偣',
+          prop: 'place',
+          minWidth: '100'
+        },
+        {
+          label: '浼氳鍐呭鎽樿',
+          prop: 'content',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          minWidth: '120',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              }
+            },
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      meetingRecordsDia: false
+    };
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      this.tableLoading = true
+      getPageMeeting({ place: this.searchForm.place, pages: this.page.current, size: this.page.size }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鏂板锛岀紪杈戝脊妗�
+    openFormDia(type, row) {
+      this.meetingRecordsDia = true
+      this.$nextTick(() => {
+        this.$refs.meetingRecordsDia.openDia(type, row)
+      })
+    },
+    closeYearDia() {
+      this.meetingRecordsDia = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.place = '';
+      this.searchList()
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        deleteMeeting({ id: row.id }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+    handleDown(row) {
+      exportMeeting({ id: row.id }).then(res => {
+        if (res.code == 201) {
+          this.$message.error(res.message)
+          return
+        }
+        const blob = new Blob([res], { type: 'application/octet-stream' });
+        this.$download.saveAs(blob, '浼氳璁板綍.docx');
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/managementReview/components/meetingRecordsDia.vue b/src/views/CNAS/systemManagement/managementReview/components/meetingRecordsDia.vue
new file mode 100644
index 0000000..3acc8ed
--- /dev/null
+++ b/src/views/CNAS/systemManagement/managementReview/components/meetingRecordsDia.vue
@@ -0,0 +1,158 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="绠$悊璇勫浼氳璁板綍" width="1000px" @close="closeYearDia">
+      <el-form ref="form" :model="form" :rules="rules" label-position="top" label-width="auto">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鏃堕棿" prop="meetingTime">
+              <el-date-picker v-model="form.meetingTime" clearable 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="place">
+              <el-input v-model="form.place" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="涓绘寔浜�" prop="compere">
+              <el-input v-model="form.compere" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浼氳鍐呭鎽樿" prop="content">
+              <el-input v-model="form.content" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍙備細浜哄憳" prop="participant">
+              <el-select v-model="form.participant" clearable filterable multiple placeholder="璇烽�夋嫨" size="small"
+                style="width: 100%;">
+                <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeYearDia">鍙� 娑�</el-button>
+        <el-button :loading="loading" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addMeeting,
+  modifyMeeting,
+} from '@/api/cnas/systemManagement/managementReview.js'
+import {
+  selectUserCondition,
+} from "@/api/system/user.js";
+export default {
+  name: 'meetingRecordsDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        id: '',
+        meetingTime: '',
+        compere: '',
+        place: '',
+        content: '',
+        participant: [],
+      },
+      rules: {
+        meetingTime: [{ required: true, message: '璇峰~鍐欎細璁椂闂�', trigger: 'blur' }],
+        compere: [{ required: true, message: '璇峰~鍐欎富鎸佷汉', trigger: 'blur' }],
+        place: [{ required: true, message: '璇峰~鍐欏湴鐐�', trigger: 'blur' }],
+        content: [{ required: true, message: '璇峰~鍐欎細璁唴瀹规憳瑕�', trigger: 'blur' }],
+        participant: [{ required: true, message: '璇烽�夋嫨鍙傚姞浜哄憳', trigger: 'change' }],
+      },
+      operationType: '',
+      personList: []
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.operationType = type
+      this.getAuthorizedPerson()
+      if (type !== 'add') {
+        this.form = row
+        this.form.participant = row.participant.split(',').map(a => {
+          a = Number(a)
+          return a
+        })
+      }
+      this.formDia = true
+    },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.loading = true
+          const internalMeeting = this.HaveJson(this.form)
+          internalMeeting.participant = internalMeeting.participant.join(',')
+          if (this.operationType === 'add') {
+            addMeeting(internalMeeting).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            modifyMeeting(internalMeeting).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    closeYearDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeYearDia')
+    },
+    getAuthorizedPerson() {
+      selectUserCondition().then(res => {
+        let data = []
+        res.data.forEach(a => {
+          data.push({
+            label: a.name,
+            value: a.id
+          })
+        })
+        this.personList = data
+      })
+    },
+  }
+};
+</script>
+
+<style scoped></style>
diff --git a/src/views/CNAS/systemManagement/managementReview/components/reviewReport.vue b/src/views/CNAS/systemManagement/managementReview/components/reviewReport.vue
new file mode 100644
index 0000000..1599da1
--- /dev/null
+++ b/src/views/CNAS/systemManagement/managementReview/components/reviewReport.vue
@@ -0,0 +1,266 @@
+<template>
+  <div>
+    <div class="search-background">
+      <span class="search-group">
+        <span style="width: 160px">鍦扮偣锛�</span>
+        <el-input v-model="searchForm.place" clearable size="small"></el-input>
+        <el-button size="medium" style="margin-left: 10px" @click="resetSearchForm">閲� 缃�</el-button>
+        <el-button size="medium" type="primary" @click="searchList">鏌� 璇�</el-button>
+      </span>
+      <span class="search-group">
+        <el-button size="medium" type="primary" @click="openFormDia('add')">鏂� 澧�</el-button>
+      </span>
+    </div>
+    <div class="table">
+      <limsTable :column="tableColumn" :height="'calc(100vh - 23em)'" :table-data="tableData"
+        :table-loading="tableLoading" style="padding: 0 10px;margin-bottom: 16px" :page="page" @pagination="pagination">
+      </limsTable>
+    </div>
+    <review-report-dia v-if="reviewReportDia" ref="reviewReportDia" @closeYearDia="closeYearDia"></review-report-dia>
+  </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import ReviewReportDia from './reviewReportDia.vue';
+import {
+  getPageReviewReport,
+  deleteReviewReport,
+  exportReviewReport,
+  modifyReviewReport,
+} from '@/api/cnas/systemManagement/managementReview.js'
+import { mapGetters } from "vuex";
+export default {
+  name: 'reviewReport',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { ReviewReportDia, limsTable },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      searchForm: {
+        place: '',
+      },
+      tableColumn: [
+        {
+          label: '鐩殑',
+          prop: 'objective',
+          minWidth: '100'
+        },
+        {
+          label: '鍦扮偣',
+          prop: 'place',
+          minWidth: '100'
+        },
+        {
+          label: '涓绘寔浜�',
+          prop: 'compere',
+          minWidth: '100'
+        },
+        {
+          label: '璁板綍浜�',
+          prop: 'recordPeople',
+          minWidth: '100'
+        },
+        {
+          label: '鏃ユ湡',
+          prop: 'date',
+          minWidth: '100'
+        },
+        {
+          label: '椤垫',
+          prop: 'page',
+          minWidth: '100'
+        },
+        {
+          label: '璇勫鏂瑰紡',
+          prop: 'judgingMethod',
+          minWidth: '100'
+        },
+        {
+          label: '璇勫渚濇嵁',
+          prop: 'reviewBasis',
+          minWidth: '100'
+        },
+        {
+          dataType: 'action',
+          minWidth: '160',
+          label: '鎿嶄綔',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.openFormDia('edit', row);
+              },
+              disabled: (row) => {
+                return !!row.audit || !!row.approval
+              }
+            },
+            {
+              name: '瀹℃牳',
+              type: 'text',
+              clickFun: (row) => {
+                this.$confirm('纭畾瀹℃牳閫氳繃?', '鎻愮ず', {
+                  confirmButtonText: '纭畾',
+                  cancelButtonText: '鍙栨秷',
+                  type: 'warning'
+                }).then(() => {
+                  this.submit('audit', row)
+                }).catch(() => {
+                });
+              },
+              disabled: (row) => {
+                return !!row.audit
+              }
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              clickFun: (row) => {
+                this.$confirm('纭畾鎵瑰噯閫氳繃?', '鎻愮ず', {
+                  confirmButtonText: '纭畾',
+                  cancelButtonText: '鍙栨秷',
+                  type: 'warning'
+                }).then(() => {
+                  this.submit('approval', row)
+                }).catch(() => {
+                });
+              },
+              disabled: (row) => {
+                return !row.audit || !!row.approval
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              }
+            },
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+          ]
+        }
+      ],
+      tableData: [],
+      tableLoading: false,
+      page: {
+        size: 20,
+        current: 1,
+        total: 0,
+      },
+      reviewReportDia: false,
+    };
+  },
+  computed: {
+    ...mapGetters(['nickName'])
+  },
+  mounted() {
+    this.searchList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ鍒楄〃
+    searchList() {
+      this.tableLoading = true
+      getPageReviewReport({ place: this.searchForm.place, pages: this.page.current, size: this.page.size }).then(res => {
+        this.tableLoading = false
+        if (res.code === 201) return
+        this.tableData = res.data.records
+        this.page.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.tableLoading = false
+      })
+    },
+    // 鏂板锛岀紪杈戝脊妗�
+    openFormDia(type, row) {
+      this.reviewReportDia = true
+      this.$nextTick(() => {
+        this.$refs.reviewReportDia.openDia(type, row)
+      })
+    },
+    closeYearDia() {
+      this.reviewReportDia = false
+      this.searchList()
+    },
+    // 閲嶇疆鏌ヨ鏉′欢
+    resetSearchForm() {
+      this.searchForm.place = '';
+      this.searchList()
+    },
+    // 鍒犻櫎
+    delPlan(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        deleteReviewReport({ id: row.id }).then(res => {
+          this.tableLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchList()
+        }).catch(err => {
+          this.tableLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    pagination({ page, limit }) {
+      this.page.current = page;
+      this.page.size = limit;
+      this.searchList();
+    },
+    handleDown(row) {
+      exportReviewReport({ id: row.id }).then(res => {
+        if (res.code == 201) {
+          this.$message.error(res.message)
+          return
+        }
+        const blob = new Blob([res], { type: 'application/octet-stream' });
+        this.$download.saveAs(blob, '璇勫鎶ュ憡.docx');
+      })
+    },
+    submit(type, row) {
+      let obj = row
+      obj[type] = this.nickNamee;
+      modifyReviewReport(obj).then(res => {
+        if (res.code === 201) return
+        this.$message.success('鎿嶄綔鎴愬姛')
+        this.searchList()
+      }).catch(err => {
+        console.log('err---', err);
+      })
+    }
+  }
+};
+</script>
+
+<style scoped>
+.search-background {
+  width: 100%;
+  height: 60px;
+  line-height: 60px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.search-group {
+  display: flex;
+  align-items: center;
+  margin: 0 20px;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/managementReview/components/reviewReportDia.vue b/src/views/CNAS/systemManagement/managementReview/components/reviewReportDia.vue
new file mode 100644
index 0000000..077b316
--- /dev/null
+++ b/src/views/CNAS/systemManagement/managementReview/components/reviewReportDia.vue
@@ -0,0 +1,259 @@
+<template>
+  <div>
+    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
+      :visible.sync="formDia" title="绠$悊璇勫浼氳璁板綍" width="1000px" @close="closeYearDia">
+      <el-form ref="form" :model="form" :rules="rules" label-position="top" label-width="auto">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐩殑" prop="objective">
+              <el-input v-model="form.objective" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍦扮偣" prop="place">
+              <el-input v-model="form.place" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="涓绘寔浜�" prop="compere">
+              <el-input v-model="form.compere" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璁板綍浜�" prop="recordPeople">
+              <el-input v-model="form.recordPeople" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏃ユ湡" prop="date">
+              <el-date-picker v-model="form.date" clearable 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="page">
+              <el-input v-model="form.page" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璇勫鏂瑰紡" prop="judgingMethod">
+              <el-input v-model="form.judgingMethod" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璇勫渚濇嵁" prop="reviewBasis">
+              <el-input v-model="form.reviewBasis" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍑哄腑浜哄憳" prop="attendess">
+              <!-- <el-input v-model="form.attendess	" clearable size="small"></el-input> -->
+              <el-select v-model="form.attendess" size="small" style="width: 100%;" filterable clearable multiple>
+                <el-option v-for="item in personList" :key="item.value" :label="item.label" :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇勫杈撳叆鎯呭喌" prop="reviewInputs">
+              <el-input v-model="form.reviewInputs" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇勫杩囩▼姒傚喌" prop="reviewProcess">
+              <el-input v-model="form.reviewProcess" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="涓昏璁姒傝堪" prop="mainTopic">
+              <el-input v-model="form.mainTopic" :rows="5" clearable placeholder="璇疯緭鍏ュ唴瀹癸紝鍙緭鍏ュ嚑鍗冨瓧" size="small"
+                type="textarea">
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="浜嬮」" prop="matters">
+              <el-input v-model="form.matters" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璐熻矗浜�" prop="head">
+              <el-input v-model="form.head" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="瀹屾垚鏃ユ湡" prop="completionDate">
+              <el-date-picker v-model="form.completionDate" clearable 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="24">
+            <el-form-item label="璺熻釜纭浜�" prop="trackingConfirmed">
+              <el-input v-model="form.trackingConfirmed" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璺熻釜鎯呭喌纭璁板綍" prop="follerUp">
+              <el-input v-model="form.follerUp" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="浣撶郴璇勪环" prop="overallEvaluation">
+              <el-input v-model="form.overallEvaluation" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeYearDia">鍙� 娑�</el-button>
+        <el-button :loading="loading" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addReviewReport,
+  modifyReviewReport,
+} from '@/api/cnas/systemManagement/managementReview.js'
+import {
+  selectUserCondition,
+} from "@/api/system/user.js";
+export default {
+  name: 'reviewReportDia',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      diaLoading: false,
+      loading: false,
+      form: {
+        id: '',
+        objective: '',
+        place: '',
+        compere: '',
+        recordPeople: '',
+        date: '',
+        page: '',
+        judgingMethod: '',
+        reviewBasis: '',
+        attendess: [],
+        reviewInputs: '',
+        reviewProcess: '',
+        mainTopic: '',
+        matters: '',
+        head: '',
+        completionDate: '',
+        trackingConfirmed: '',
+        follerUp: '',
+        overallEvaluation: '',
+      },
+      rules: {
+        objective: [{ required: true, message: '璇峰~鍐欑洰鐨�', trigger: 'blur' }],
+        place: [{ required: true, message: '璇峰~鍐欏湴鐐�', trigger: 'blur' }],
+        compere: [{ required: true, message: '璇峰~鍐欎富鎸佷汉', trigger: 'blur' }],
+        recordPeople: [{ required: true, message: '璇峰~鍐欒褰曚汉', trigger: 'blur' }],
+        date: [{ required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }],
+        completionDate: [{ required: true, message: '璇烽�夋嫨瀹屾垚鏃ユ湡', trigger: 'change' }],
+        page: [{ required: true, message: '璇峰~鍐欓〉娆�', trigger: 'blur' }],
+        judgingMethod: [{ required: true, message: '璇峰~鍐欒瘎瀹℃柟寮�', trigger: 'blur' }],
+        reviewBasis: [{ required: true, message: '璇峰~鍐欒瘎瀹′緷鎹�', trigger: 'blur' }],
+        attendess: [{ required: true, message: '璇峰~鍐欏嚭甯汉鍛�', trigger: 'change' }],
+        reviewInputs: [{ required: true, message: '璇峰~鍐欒瘎瀹¤緭鍏ユ儏鍐�', trigger: 'blur' }],
+        reviewProcess: [{ required: true, message: '璇峰~鍐欒瘎瀹¤緭鍏ユ儏鍐�', trigger: 'blur' }],
+        mainTopic: [{ required: true, message: '璇峰~鍐欎富瑕佽棰樻杩�', trigger: 'blur' }],
+        matters: [{ required: true, message: '璇峰~鍐欎富瑕佽棰樻杩�', trigger: 'blur' }],
+        head: [{ required: true, message: '璇峰~鍐欒礋璐d汉', trigger: 'blur' }],
+        trackingConfirmed: [{ required: true, message: '璇峰~鍐欒窡韪‘璁や汉', trigger: 'blur' }],
+        follerUp: [{ required: true, message: '璇峰~鍐欒窡韪‘璁や汉', trigger: 'blur' }],
+        overallEvaluation: [{ required: true, message: '璇峰~鍐欎綋绯昏瘎浠�', trigger: 'blur' }],
+      },
+      operationType: '',
+      personList: []
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鎵撳紑寮规
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      this.getAuthorizedPerson()
+      if (type !== 'add') {
+        this.form = row
+        this.form.attendess = this.form.attendess ? this.form.attendess.split(',').map(m => Number(m)) : []
+      }
+    },
+    // 鎻愪氦寮规鏁版嵁
+    handleEdit() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          this.loading = true
+          const internalMeeting = this.HaveJson(this.form)
+          internalMeeting.attendess = internalMeeting.attendess ? internalMeeting.attendess.join(',') : ''
+          if (this.operationType === 'add') {
+            addReviewReport(internalMeeting).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          } else if (this.operationType === 'edit') {
+            modifyReviewReport(internalMeeting).then(res => {
+              this.loading = false
+              if (res.code === 201) return
+              this.$message.success('鎿嶄綔鎴愬姛')
+              this.closeYearDia()
+            }).catch(err => {
+              console.log('err---', err);
+              this.loading = false
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    closeYearDia() {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeYearDia')
+    },
+    getAuthorizedPerson() {
+      selectUserCondition().then(res => {
+        let data = []
+        res.data.forEach(a => {
+          data.push({
+            label: a.name,
+            value: a.id
+          })
+        })
+        this.personList = data
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog {
+  margin: 4vh auto 50px !important;
+}
+
+>>>.el-dialog__body {
+  max-height: 600px;
+  overflow-y: auto;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/managementReview/index.vue b/src/views/CNAS/systemManagement/managementReview/index.vue
new file mode 100644
index 0000000..9111484
--- /dev/null
+++ b/src/views/CNAS/systemManagement/managementReview/index.vue
@@ -0,0 +1,48 @@
+<template>
+  <div class="main">
+    <el-tabs v-model="activeName" class="tab-panel" type="border-card">
+      <el-tab-pane label="绠$悊璇勫璁″垝" name="yearPlan">
+        <management-review-plan></management-review-plan>
+      </el-tab-pane>
+      <el-tab-pane label="浼氳璁板綍" name="implementationPlan">
+        <meeting-records></meeting-records>
+      </el-tab-pane>
+      <el-tab-pane label="璇勫鎶ュ憡" name="meetingSignIn">
+        <review-report></review-report>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import ManagementReviewPlan from './components/managementReviewPlan.vue';
+import MeetingRecords from './components/meetingRecords.vue';
+import ReviewReport from './components/reviewReport.vue';
+
+export default {
+  name: 'a9-management-review',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { ReviewReport, MeetingRecords, ManagementReviewPlan },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      activeName: 'yearPlan',
+    };
+  },
+  mounted() {
+
+  },
+  // 鏂规硶闆嗗悎
+  methods: {}
+};
+</script>
+
+<style scoped>
+.main {
+  padding: 15px 0;
+}
+
+.tab-panel {
+  background: #fff;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/measuresDealRisks/components/hazardIdentificationRiskAssessment.vue b/src/views/CNAS/systemManagement/measuresDealRisks/components/hazardIdentificationRiskAssessment.vue
new file mode 100644
index 0000000..cdc0c7a
--- /dev/null
+++ b/src/views/CNAS/systemManagement/measuresDealRisks/components/hazardIdentificationRiskAssessment.vue
@@ -0,0 +1,331 @@
+<template>
+  <div style="padding: 10px">
+    <div class="header">
+      <span></span>
+      <div style="min-width: 200px">
+        <el-button type="primary" size="small" @click="addFun">鏂� 澧�</el-button>
+        <el-button type="primary" size="small" @click="approvalFun">瀹� 鎵�</el-button>
+        <el-button type="primary" size="small" @click="approveFun">鎵� 鍑�</el-button>
+        <el-upload style="display: inline-block; padding: 0 6px" :headers="uploadHeader" :action="action"
+          :on-error="onError" :show-file-list="false" :on-success="onSuccess">
+          <el-button size="small" type="primary">瀵� 鍏�</el-button>
+        </el-upload>
+        <el-button size="small" @click="openDownloadDia">瀵煎嚭</el-button>
+      </div>
+    </div>
+    <el-table :data="tableData" style="width: 100%" height="calc(100vh - 18em)" key="table1">
+      <el-table-column type="index" label="搴忓彿" width="120">
+        <template v-slot="scope">
+          <span>{{ (page.current - 1) * page.size + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="venue" label="鍦扮偣/娲诲姩" min-width="180"></el-table-column>
+      <el-table-column prop="hazard" label="鍗遍櫓鍥犵礌" width="testDate" min-width="180"></el-table-column>
+      <el-table-column prop="accidents" label="鍙兘瀵艰嚧鐨勪簨鏁�" min-width="180"></el-table-column>
+      <el-table-column prop="injury" label="瀵逛汉鍙兘閫犳垚鐨勫嵄瀹�" min-width="180"></el-table-column>
+      <el-table-column label="椋庨櫓璇勪环" align="center" min-width="180">
+        <template>
+          <el-table-column prop="riskL" label="L" min-width="80"></el-table-column>
+          <el-table-column prop="riskE" label="E" min-width="80"></el-table-column>
+          <el-table-column prop="riskC" label="C" min-width="80"></el-table-column>
+          <el-table-column prop="riskD" label="D" min-width="80"></el-table-column>
+        </template>
+      </el-table-column>
+      <el-table-column prop="level" label="椋庨櫓绛夌骇" min-width="180"></el-table-column>
+      <el-table-column prop="measures" label="鎺у埗鎺柦" min-width="180"></el-table-column>
+      <el-table-column prop="editorName" label="缂栧埗浜哄鍚�" min-width="180"></el-table-column>
+      <el-table-column prop="editorDate" label="缂栧埗鏃ユ湡" min-width="180"></el-table-column>
+      <el-table-column prop="approvalName" label="瀹℃壒浜哄鍚�" min-width="180"></el-table-column>
+      <el-table-column prop="approvalDate" label="瀹℃壒鏃ユ湡" min-width="180"></el-table-column>
+      <el-table-column prop="approvalStatus" label="瀹℃壒鐘舵��" min-width="180">
+        <template #default="{ row }">
+          {{ row.approvalStatus === 1 ? '閫氳繃' : row.approvalStatus === 2 ? '涓嶉�氳繃' : '' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="approveName" label="鎵瑰噯浜哄鍚�" min-width="180"></el-table-column>
+      <el-table-column prop="approveStatus" label="鎵瑰噯鐘舵��" min-width="180">
+        <template #default="{ row }">
+          {{ row.approveStatus === 1 ? '閫氳繃' : row.approveStatus === 2 ? '涓嶉�氳繃' : '' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="approveDate" label="鎵瑰噯鏃ユ湡" min-width="180"></el-table-column>
+      <el-table-column fixed="right" label="鎿嶄綔" width="100">
+        <template v-slot="scope">
+          <el-button type="text" size="small" @click="editClick(scope.row)">缂栬緫</el-button>
+          <el-button @click="deleteClick(scope.row)" type="text" size="small">鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination :current-page="1" :page-size="page.size" :page-sizes="[10, 20, 30, 50, 100]" :total="page.total"
+      layout="->,total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
+      @current-change="handleCurrentChange">
+    </el-pagination>
+    <el-dialog title="鎻愮ず" :visible.sync="dialogVisible" width="50%">
+      <el-form ref="form" :model="form" label-width="120px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鍦扮偣/娲诲姩">
+              <el-input v-model="form.venue" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍗遍櫓鍥犵礌">
+              <el-input v-model="form.hazard" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍙兘瀵艰嚧鐨勪簨鏁�">
+              <el-input v-model="form.accidents" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀵逛汉鍙兘閫犳垚鐨勫嵄瀹�" label-width="140px">
+              <el-input v-model="form.injury" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椋庨櫓璇勪环/L">
+              <el-input v-model="form.riskL" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椋庨櫓璇勪环/E">
+              <el-input v-model="form.riskE" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椋庨櫓璇勪环/C">
+              <el-input v-model="form.riskC" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椋庨櫓璇勪环/D">
+              <el-input v-model="form.riskD" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椋庨櫓绛夌骇">
+              <el-input v-model="form.level" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎺у埗鎺柦">
+              <el-input v-model="form.measures" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="addApi" :loading="loading">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import {
+  getPageResults,
+  dangerousRiskApproval,
+  hazardIdentificationAndRiskApproval,
+  removeRiskFactors,
+  addNewRiskFactors,
+  exportHazardFactorIdentification,
+} from '@/api/cnas/systemManagement/measuresDealRisks.js'
+import { mapGetters } from "vuex";
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      form: {},
+      page: {
+        total: 0,
+        size: 10,
+        current: 1,
+      },
+      tableData: [],
+      loading: false
+    }
+  },
+  computed: {
+    action() {
+      return this.javaApi + '/manageRiskAssessmentResults/riskAssessmentImport'
+    },
+    ...mapGetters(["userId"]),
+  },
+  methods: {
+    handleSizeChange(val) {
+      this.page.size = val;
+      this.initData();
+    },
+    handleCurrentChange(val) {
+      this.page.current = val;
+      this.initData();
+    },
+    // 鍒嗛〉琛ㄦ牸鍒濆鍖�
+    initData() {
+      this.tableData = []
+      getPageResults(this.page).then(res => {
+        if (res.code === 201) return;
+        this.tableData = res.data.records;
+        this.page.total = res.data.total;
+      });
+    },
+    // 瀹℃壒
+    approvalFun() {
+      this.$confirm('鏄惁瀹℃壒閫氳繃?', '鎻愮ず', {
+        confirmButtonText: '閫氳繃',
+        cancelButtonText: '涓嶉�氳繃',
+        type: 'warning',
+        closeOnClickModal: false, // 绂佹鐐瑰嚮閬僵灞傚叧闂�
+        distinguishCancelAndClose: true,
+        beforeClose: (action, instance, done) => {
+          if (action === 'confirm') {
+            this.approvalApi(this.userId, 1)
+            done();
+          } else if (action === 'cancel') {
+            this.approvalApi(this.userId, 2)
+            done();
+          } else if (action === 'close') {
+            // 鐐瑰嚮鈥溍椻�濇寜閽紝涓嶅厑璁稿叧闂�
+            done();
+          }
+        }
+      })
+    },
+    // 瀹℃壒鎺ュ彛
+    approvalApi(userId, status) {
+      dangerousRiskApproval({ approval: userId, status: status }).then(res => {
+        if (res.code === 201) return;
+        this.initData()
+        this.$message({
+          type: 'success',
+          message: '鎿嶄綔鎴愬姛!'
+        });
+      });
+    },
+    // 鎵瑰噯
+    approveFun() {
+      this.$confirm('鏄惁鎵瑰噯閫氳繃?', '鎻愮ず', {
+        confirmButtonText: '閫氳繃',
+        cancelButtonText: '涓嶉�氳繃',
+        type: 'warning',
+        closeOnClickModal: false, // 绂佹鐐瑰嚮閬僵灞傚叧闂�
+        distinguishCancelAndClose: true,
+        beforeClose: (action, instance, done) => {
+          if (action === 'confirm') {
+            this.approveApi(this.userId, 1)
+            done();
+          } else if (action === 'cancel') {
+            this.approveApi(this.userId, 2)
+            done();
+          } else if (action === 'close') {
+            // 鐐瑰嚮鈥溍椻�濇寜閽紝涓嶅厑璁稿叧闂�
+            done();
+          }
+        }
+      })
+    },
+    // 鎵瑰噯鎺ュ彛
+    approveApi(userId, status) {
+      hazardIdentificationAndRiskApproval({ approve: userId, status: status }).then(res => {
+        if (res.code === 201) return;
+        this.initData()
+        this.$message({
+          type: 'success',
+          message: '鎿嶄綔鎴愬姛!'
+        });
+      });
+    },
+    // 鏂囦欢涓婁紶澶辫触
+    onError() {
+      this.$message({
+        type: 'error',
+        message: '鎿嶄綔澶辫触!'
+      });
+    },
+    // 鏂囦欢涓婁紶鎴愬姛
+    onSuccess(response) {
+      if (response.code == 201) {
+        this.$message({
+          type: 'error',
+          message: response.message,
+        });
+        return
+      }
+      this.initData()
+      this.$message({
+        type: 'success',
+        message: '鎿嶄綔鎴愬姛!'
+      });
+    },
+    addFun() {
+      this.form = {}
+      this.dialogVisible = true
+    },
+    // 鍒犻櫎
+    deleteClick(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        removeRiskFactors({ id: row.id }).then(res => {
+          if (res.code === 201) return;
+          this.initData()
+          this.$message({
+            type: 'success',
+            message: '鎿嶄綔鎴愬姛!'
+          });
+        });
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    addApi() {
+      this.loading = true
+      addNewRiskFactors(this.form).then(res => {
+        if (res.code === 201) return;
+        this.dialogVisible = false
+        this.loading = false
+        this.initData()
+        this.$message({
+          type: 'success',
+          message: '鎿嶄綔鎴愬姛!'
+        });
+      }).catch(err => {
+        this.loading = false
+      });
+    },
+    // 缂栬緫
+    editClick(row) {
+      this.form = { ...row }
+      this.dialogVisible = true
+    },
+    // 瀵煎嚭
+    openDownloadDia() {
+      exportHazardFactorIdentification().then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙�' + '.docx');
+      })
+    },
+  },
+  mounted() {
+    this.initData()
+  },
+}
+</script>
+
+<style scoped>
+.header {
+  height: 3em;
+  width: 100%;
+  display: flex;
+  justify-content: space-between;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/measuresDealRisks/components/listRiskAnalysisControlPlans.vue b/src/views/CNAS/systemManagement/measuresDealRisks/components/listRiskAnalysisControlPlans.vue
new file mode 100644
index 0000000..bf9e244
--- /dev/null
+++ b/src/views/CNAS/systemManagement/measuresDealRisks/components/listRiskAnalysisControlPlans.vue
@@ -0,0 +1,298 @@
+<template>
+  <div style="padding: 10px">
+    <div class="header">
+      <div></div>
+      <div style="min-width: 200px">
+        <el-button type="primary" size="small" @click="addFun">鏂� 澧�</el-button>
+        <el-button type="primary" size="small" @click="approvalFun">瀹� 鎵�</el-button>
+        <el-button type="primary" size="small" @click="approveFun">鎵� 鍑�</el-button>
+        <el-upload style="display: inline-block; padding: 0 6px" :action="action" :headers="uploadHeader"
+          :on-error="onError" :show-file-list="false" :on-success="onSuccess">
+          <el-button size="small" type="primary">瀵� 鍏�</el-button>
+        </el-upload>
+        <el-button size="small" @click="openDownloadDia">瀵煎嚭</el-button>
+      </div>
+    </div>
+    <el-table :data="tableData" style="width: 100%" height="calc(100vh - 18em)" key="table0">
+      <el-table-column type="index" label="搴忓彿" width="120">
+        <template v-slot="scope">
+          <span>{{ (search.current - 1) * search.size + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="jobActivity" label="浣滀笟娲诲姩" min-width="180"></el-table-column>
+      <el-table-column prop="category" label="椋庨櫓鍥犵礌绫诲埆" width="testDate" min-width="180"></el-table-column>
+      <el-table-column prop="description" label="椋庨櫓鍥犵礌鎻忚堪" min-width="180"></el-table-column>
+      <el-table-column prop="result" label="鍙鑷寸殑浜嬫晠" min-width="180"></el-table-column>
+      <el-table-column prop="intolerable" label="鏄惁涓嶅彲鎵垮彈椋庨櫓" min-width="180"></el-table-column>
+      <el-table-column prop="plan" label="鎺у埗璁″垝" min-width="180"></el-table-column>
+      <el-table-column prop="editorName" label="缂栧埗浜哄鍚�" min-width="180"></el-table-column>
+      <el-table-column prop="editorDate" label="缂栧埗鏃ユ湡" min-width="180"></el-table-column>
+      <el-table-column prop="approvalName" label="瀹℃壒濮撳悕" min-width="180"></el-table-column>
+      <el-table-column prop="approvalDate" label="瀹℃壒鏃ユ湡" min-width="180"></el-table-column>
+      <el-table-column prop="approvalStatus" label="瀹℃壒鐘舵��" min-width="180">
+        <template #default="{ row }">
+          {{ row.approvalStatus === 1 ? '閫氳繃' : row.approvalStatus === 2 ? '涓嶉�氳繃' : '' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="approveName" label="鎵瑰噯濮撳悕" min-width="180"></el-table-column>
+      <el-table-column prop="approveStatus" label="鎵瑰噯鐘舵��" min-width="180">
+        <template #default="{ row }">
+          {{ row.approveStatus === 1 ? '閫氳繃' : row.approveStatus === 2 ? '涓嶉�氳繃' : '' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="approveDate" label="鎵瑰噯浜烘棩鏈�" min-width="180"></el-table-column>
+      <el-table-column fixed="right" label="鎿嶄綔" width="100">
+        <template v-slot="scope">
+          <el-button type="text" size="small" @click="editClick(scope.row)">缂栬緫</el-button>
+          <el-button @click="deleteClick(scope.row)" type="text" size="small">鍒犻櫎</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" @size-change="handleSizeChange"
+      @current-change="handleCurrentChange">
+    </el-pagination>
+    <el-dialog title="鎻愮ず" :visible.sync="dialogVisible" width="50%">
+      <el-form ref="form" :model="form" label-width="120px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="浣滀笟娲诲姩">
+              <el-input v-model="form.jobActivity" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椋庨櫓鍥犵礌绫诲埆">
+              <el-input v-model="form.category" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椋庨櫓鍥犵礌鎻忚堪">
+              <el-input v-model="form.description" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍙鑷寸殑浜嬫晠">
+              <el-input v-model="form.result" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄惁涓嶅彲鎵垮彈椋庨櫓" label-width="130px">
+              <el-input v-model="form.intolerable" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎺у埗璁″垝">
+              <el-input v-model="form.plan" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="addApi" :loading="loading">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getPageList,
+  riskAnalysisApprovalOfControlPlanChecklist,
+  approvalOfControlPlanChecklist,
+  deleteSignificantRiskFactorAnalysis,
+  analysisOfMajorRiskFactorsAdded,
+  exportSignificantRiskFactors,
+} from '@/api/cnas/systemManagement/measuresDealRisks.js'
+import { mapGetters } from "vuex";
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      form: {},
+      loading: false,
+      search: {
+        size: 20,
+        current: 1,
+        total: 0
+      },
+      tableData: [],
+    }
+  },
+  computed: {
+    action() {
+      return this.javaApi + '/manageControlPlanList/importControlPlanList'
+    },
+    ...mapGetters(["userId"]),
+  },
+  methods: {
+    handleSizeChange(val) {
+      this.search.size = val;
+      this.initData();
+    },
+    handleCurrentChange(val) {
+      this.search.current = val;
+      this.initData();
+    },
+    initData() {
+      getPageList(this.search).then(res => {
+        if (res.code === 201) return;
+        this.tableData = res.data.records;
+        this.search.total = res.data.total;
+      });
+    },
+    // 瀹℃壒
+    approvalFun() {
+      this.$confirm('鏄惁瀹℃壒閫氳繃?', '鎻愮ず', {
+        confirmButtonText: '閫氳繃',
+        cancelButtonText: '涓嶉�氳繃',
+        type: 'warning',
+        closeOnClickModal: false, // 绂佹鐐瑰嚮閬僵灞傚叧闂�
+        distinguishCancelAndClose: true,
+        beforeClose: (action, instance, done) => {
+          if (action === 'confirm') {
+            this.approvalApi(this.userId, 1)
+            done();
+          } else if (action === 'cancel') {
+            this.approvalApi(this.userId, 2)
+            done();
+          } else if (action === 'close') {
+            // 鐐瑰嚮鈥溍椻�濇寜閽紝涓嶅厑璁稿叧闂�
+            done();
+          }
+        }
+      })
+    },
+    // 瀹℃壒鎺ュ彛
+    approvalApi(userId, status) {
+      riskAnalysisApprovalOfControlPlanChecklist({ approval: userId, status }).then(res => {
+        if (res.code === 201) return;
+        this.initData()
+        this.$message({
+          type: 'success',
+          message: '鎿嶄綔鎴愬姛!'
+        });
+      });
+    },
+    // 鎵瑰噯
+    approveFun() {
+      this.$confirm('鏄惁鎵瑰噯閫氳繃?', '鎻愮ず', {
+        confirmButtonText: '閫氳繃',
+        cancelButtonText: '涓嶉�氳繃',
+        type: 'warning',
+        closeOnClickModal: false, // 绂佹鐐瑰嚮閬僵灞傚叧闂�
+        distinguishCancelAndClose: true,
+        beforeClose: (action, instance, done) => {
+          if (action === 'confirm') {
+            this.approveApi(this.userId, 1)
+            done();
+          } else if (action === 'cancel') {
+            this.approveApi(this.userId, 2)
+            done();
+          } else if (action === 'close') {
+            // 鐐瑰嚮鈥溍椻�濇寜閽紝涓嶅厑璁稿叧闂�
+            done();
+          }
+        }
+      })
+    },
+    // 鎵瑰噯鎺ュ彛
+    approveApi(userId, status) {
+      approvalOfControlPlanChecklist({ approve: userId, status }).then(res => {
+        if (res.code === 201) return;
+        this.initData()
+        this.$message({
+          type: 'success',
+          message: '鎿嶄綔鎴愬姛!'
+        });
+      });
+    },
+    onError() {
+      this.$message({
+        type: 'error',
+        message: '鎿嶄綔澶辫触!'
+      });
+    },
+    onSuccess(response) {
+      if (response.code == 201) {
+        this.$message({
+          type: 'error',
+          message: response.message,
+        });
+        return
+      }
+      this.initData()
+      this.$message({
+        type: 'success',
+        message: '鎿嶄綔鎴愬姛!'
+      });
+    },
+    addFun() {
+      this.form = {}
+      this.dialogVisible = true
+    },
+    // 鍒犻櫎
+    deleteClick(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        deleteSignificantRiskFactorAnalysis({ id: row.id }).then(res => {
+          if (res.code === 201) return;
+          this.initData()
+          this.$message({
+            type: 'success',
+            message: '鎿嶄綔鎴愬姛!'
+          });
+        });
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    addApi() {
+      this.loading = true
+      analysisOfMajorRiskFactorsAdded(this.form).then(res => {
+        if (res.code === 201) return;
+        this.dialogVisible = false
+        this.loading = false
+        this.initData()
+        this.$message({
+          type: 'success',
+          message: '鎿嶄綔鎴愬姛!'
+        });
+      }).catch(err => {
+        this.loading = false
+      });
+    },
+    // 缂栬緫
+    editClick(row) {
+      this.form = { ...row }
+      this.dialogVisible = true
+    },
+    // 瀵煎嚭
+    openDownloadDia() {
+      exportSignificantRiskFactors().then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], { type: 'application/msword' });
+        this.$download.saveAs(blob, '閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗�' + '.docx');
+      })
+    },
+  },
+  mounted() {
+    this.initData()
+  },
+}
+</script>
+
+<style scoped>
+.header {
+  height: 3em;
+  width: 100%;
+  display: flex;
+  justify-content: space-between;
+}
+</style>
diff --git a/src/views/CNAS/systemManagement/measuresDealRisks/index.vue b/src/views/CNAS/systemManagement/measuresDealRisks/index.vue
new file mode 100644
index 0000000..4088909
--- /dev/null
+++ b/src/views/CNAS/systemManagement/measuresDealRisks/index.vue
@@ -0,0 +1,39 @@
+<template>
+  <div class="main">
+    <el-tabs v-model="activeName" type="border-card" :lazy="true">
+      <el-tab-pane label="鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙�" name="鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙�">
+        <HazardIdentificationRiskAssessment v-if="activeName === '鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙�'" />
+      </el-tab-pane>
+      <el-tab-pane label="閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗�" name="閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗�">
+        <listRiskAnalysisControlPlans v-if="activeName === '閲嶅ぇ椋庨櫓鍥犵礌鍒嗘瀽鍙婃帶鍒惰鍒掓竻鍗�'" />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+
+import HazardIdentificationRiskAssessment
+  from "./components/hazardIdentificationRiskAssessment.vue";
+import listRiskAnalysisControlPlans
+  from "./components//listRiskAnalysisControlPlans.vue";
+export default {
+  components: { HazardIdentificationRiskAssessment, listRiskAnalysisControlPlans },
+  data() {
+    return {
+      activeName: '鍗遍櫓鍥犵礌杈ㄨ瘑涓庨闄╄瘎浠风粨鏋滀竴瑙�',
+    }
+  }
+}
+</script>
+
+<style scoped>
+.main {
+  width: 100%;
+}
+
+/deep/ .el-tabs--border-card>.el-tabs__content {
+  height: calc(100vh - 9em);
+  padding: 0;
+}
+</style>
diff --git a/vue.config.js b/vue.config.js
index d0aee59..1d8e525 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -36,7 +36,7 @@
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
-        target: `http://127.0.0.1:8002`,
+        target: `http://192.168.0.104:8002`,
         changeOrigin: true,
         pathRewrite: {
           ["^" + process.env.VUE_APP_BASE_API]: "",

--
Gitblit v1.9.3