From 97c857f75a9ef32489678e8dd5925472e9c7a9d1 Mon Sep 17 00:00:00 2001
From: licp <lichunping@guanfang.com.cn>
Date: 星期四, 26 十二月 2024 14:33:05 +0800
Subject: [PATCH] 完成7.7质量监控计划

---
 src/components/caorui/Department/components/Records/supervise/ApproveForm.vue      |   84 
 src/components/do/a7-Ensure-results-validity/ViewRecord.vue                        |  190 +
 src/components/caorui/Department/components/Records/Add.vue                        |  243 ++
 src/assets/api/api.js                                                              |  161 +
 src/components/caorui/Department/components/Records/control/index.vue              |  331 +++
 src/components/do/a7-Ensure-results-validity/detailFormDialog.vue                  |  158 +
 src/components/caorui/Department/components/Records/dispose/Step/Measure.vue       |  101 
 src/components/caorui/Department/components/Records/control/Step/ConditionForm.vue |  164 +
 src/components/caorui/Department/components/Records/dispose/index.vue              |  278 ++
 src/components/caorui/Department/components/Records/index.vue                      |  447 ++++
 src/components/caorui/Department/components/Plan/index.vue                         |  469 ++++
 src/components/caorui/Department/components/Records/dispose/Step/Reason.vue        |   97 
 src/components/caorui/Department/components/Mandate/Add.vue                        |  256 ++
 src/components/caorui/Department/components/Mandate/index.vue                      |  265 ++
 src/components/caorui/Department/components/Records/dispose/Step/Fact.vue          |   99 
 src/components/caorui/Department/components/Communicate/index.vue                  |  238 ++
 src/components/caorui/Department/components/Records/control/Step/MeasureForm.vue   |   94 
 src/components/do/a7-Ensure-results-validity/evaluateDialog.vue                    |  351 +++
 src/components/caorui/Department/components/Plan/Add.vue                           |  192 +
 src/assets/api/controller.js                                                       |   24 
 src/components/caorui/Department/components/Records/dispose/Step/Result.vue        |   98 
 src/components/caorui/Department/components/Records/control/Step/Inform.vue        |   99 
 src/components/caorui/Department/components/Plan/UploadExcel.vue                   |   58 
 src/components/caorui/Department/index.vue                                         |  150 +
 src/components/caorui/Department/components/Records/control/Step/RectifyForm.vue   |   98 
 src/components/caorui/Department/components/Communicate/Add.vue                    |  144 +
 src/components/do/a7-Ensure-results-validity/carryOutDialog.vue                    |  352 +++
 src/components/caorui/Department/components/Records/supervise/SuperviseForm.vue    |  196 +
 src/components/view/a7-Ensure-results-validity.vue                                 |  668 ++++++
 29 files changed, 6,105 insertions(+), 0 deletions(-)

diff --git a/src/assets/api/api.js b/src/assets/api/api.js
new file mode 100644
index 0000000..1061177
--- /dev/null
+++ b/src/assets/api/api.js
@@ -0,0 +1,161 @@
+/*
+ * @FileDescription: controller.js澶贡锛岃繖涓槸姝e父鏍煎紡鐨刟pi锛屽皢鏉ョ敤浜庢浛鎹ontroller
+ * @Author: 鏇圭澘
+ * @Date: 2024/09/30
+ * @LastEditors: 鏇圭澘
+ * @LastEditTime: 2024/09/30
+ */
+
+// 6.2浜哄憳
+// 骞村害璁″垝鍒楄〃
+export const yearPlanListApi = '/superVisePlan/yearPlanList'
+
+// 骞村害璁″垝鏄庣粏
+export const yearDetailPlanListApi = '/superVisePlan/yearPlanDetailList'
+
+// 鏂板鏄庣粏
+export const yearPlanDetailAdd = '/superVisePlan/yearPlanDetailAdd'
+
+// 缂栬緫鏄庣粏
+export const yearPlanDetailEdit = '/superVisePlan/yearPlanDetailEdit'
+
+// 鍒犻櫎骞磋鍒�
+export const delYearPlanApi = '/superVisePlan/yearPlanDel'
+
+// 鍒犻櫎骞磋鍒掓槑缁�
+export const delYearPlanDetailApi = '/superVisePlan/yearPlanDetailDel'
+
+// 鎵瑰噯骞村害璁″垝
+export const yearPlanDetailApprovalApi = '/superVisePlan/yearPlanDetailApproval'
+
+// 浜哄憳 鐩戠潱璁″垝瀵煎嚭
+export const exportSuperVisePlanApi = '/superVisePlan/exportSuperVisePlan'
+
+// 浜哄憳 - 濂栨儵璁板綍 鍒嗛〉鏌ヨ
+export const rewardPunishmentPageApi = '/personRewardPunishmentRecord/rewardPunishmentPage'
+
+// 浜哄憳 - 濂栨儵璁板綍 鏂板/鏇存柊
+export const addOrUpdateRewardPunishmentApi = '/personRewardPunishmentRecord/addOrUpdateRewardPunishment'
+
+// 浜哄憳 - 濂栨儵璁板綍 鍒犻櫎
+export const deleteRewardPunishmentApi = '/personRewardPunishmentRecord/deleteRewardPunishment'
+
+/**
+ * @desc 鐩戠潱璁板綍
+ */
+// 鏌ヨ
+export const personSupervisionRecordPage = '/personSupervisionRecord/personSupervisionRecordPage'
+// 鏂板-缂栬緫 鐩戠潱璁板綍
+export const addOrUpdatePersonSupervisionRecord = '/personSupervisionRecord/addOrUpdatePersonSupervisionRecord'
+// 鍒犻櫎 鐩戠潱璁板綍
+export const deletePersonSupervisionRecord = '/personSupervisionRecord/deletePersonSupervisionRecord'
+// 鏌ヨ 鎺у埗鍗�
+export const personSupervisionControlSheetPage = '/personSupervisionRecord/personSupervisionControlSheetPage'
+// 鏂板-缂栬緫 鎺у埗鍗�
+export const addOrUpdatePersonSupervisionControl = '/personSupervisionRecord/addOrUpdatePersonSupervisionControl'
+// 鏌ヨ 澶勭悊鍗�
+export const personSupervisionProcessingPage = '/personSupervisionRecord/personSupervisionProcessingPage'
+// 鏂板-缂栬緫 澶勭悊鍗�
+export const addOrUpdatePersonnelServiceProcessing = '/personSupervisionRecord/addOrUpdatePersonnelServiceProcessing'
+// 鎺у埗鍗曞鍑�
+export const exportSupervisionControlSheet = '/personSupervisionRecord/exportSupervisionControlSheet'
+// 澶勭悊鍗曞鍑�
+export const exportSupervisionProcessingSheet = '/personSupervisionRecord/exportSupervisionProcessingSheet'
+// 鐩戠潱璁板綍瀵煎嚭
+export const exportPersonSupervisionRecord = '/personSupervisionRecord/exportPersonSupervisionRecord'
+
+/**
+ * @desc 娌熼�氳褰�
+ */
+// 鏌ヨ娌熼��
+export const personPersonCommunicationAbilityPage = '/personCommunicationAbility/personPersonCommunicationAbilityPage'
+// 鏂板-缂栬緫
+export const addOrUpdatePersonCommunicationAbility = '/personCommunicationAbility/addOrUpdatePersonCommunicationAbility'
+// 鍒犻櫎
+export const deletePersonCommunicationAbility = '/personCommunicationAbility/deletePersonCommunicationAbility'
+
+/**
+ * @desc 浠昏亴鎺堟潈璁板綍
+ */
+// 鏌ヨ琛ㄦ牸
+export const getPersonPostAuthorizationRecordPage = '/personPostAuthorizationRecord/PersonPostAuthorizationRecordPage'
+// 鏂板
+export const addOrUpdatePersonPostAuthorizationRecord = '/personPostAuthorizationRecord/addOrUpdatePersonPostAuthorizationRecord'
+// 涓婁紶鏂囦欢
+export const saveCNASFile = '/personBasicInfo/saveCNASFile'
+// 浜哄憳鍒楄〃
+export const getUserListApi = '/deviceScope/selectUserList'
+// 鍒犻櫎
+export const deletePersonPostAuthorizationRecord = '/personPostAuthorizationRecord/deletePersonPostAuthorizationRecord'
+
+/**
+ * @desc 鐩戠潱璁″垝
+ */
+// 瀵煎叆骞村害璁″垝
+export const yearPlanDetailImport = '/superVisePlan/yearPlanDetailImport'
+
+/**
+ * @desc 渚涘簲鍟嗙鐞�
+ */
+// 渚涘簲鏍�
+export const suppliersDirectoryContentsSuppliersDirectoryContentsListing = '/suppliersDirectoryContents/suppliersDirectoryContentsListing'
+// 鏂板鑺傜偣
+export const suppliersDirectoryContentsAddSuppliersDirectoryContents = '/suppliersDirectoryContents/addSuppliersDirectoryContents'
+// 缂栬緫鑺傜偣
+export const suppliersDirectoryContentsUpdateSuppliersDirectoryContents = '/suppliersDirectoryContents/updateSuppliersDirectoryContents'
+// 鍒犻櫎鑺傜偣
+export const suppliersDirectoryContentsDeleteSuppliersDirectoryContentsById = '/suppliersDirectoryContents/deleteSuppliersDirectoryContentsById'
+// 鏌ヨ鎵�鏈夎妭鐐�
+export const suppliersDirectoryContentsGetSuppliersDirectoryContentsNodeNames = '/suppliersDirectoryContents/getSuppliersDirectoryContentsNodeNames'
+// 鍒嗛〉鏌ヨ鍚堟牸渚涙柟鍚�
+export const selectQualifiedSupplierManagementPage = '/supplierManagement/selectQualifiedSupplierManagementPage'
+// 鍒嗛〉鏌ヨ渚涙柟鍚嶅綍
+export const selectSupplierManagementPage = '/supplierManagement/selectSupplierManagementByParentId'
+// 鏂板渚涘簲鍟�
+export const addSupplierManagement = '/supplierManagement/addSupplierManagement'
+// 缂栬緫渚涘簲鍟�
+export const updateSupplierManagement = '/supplierManagement/updateSupplierManagement'
+// 鍒犻櫎渚涘簲鍟�
+export const delSupplierManagement = '/supplierManagement/delSupplierManagement'
+
+// 瀵煎嚭渚涘簲鍟�
+export const exportSupplierManagement = '/supplierManagement/exportSupplierManagement'
+
+export const selectSupplierManagementAll = '/supplierManagement/selectSupplierManagementAll'
+/**
+ * @desc 鏈嶅姟鍜屼緵搴斿搧閲囪喘
+ */
+export const procurementSuppliesList = '/procurementSuppliesList/procurementSuppliesList'
+export const addProcurementSuppliesList = '/procurementSuppliesList/addProcurementSuppliesList'
+export const updateProcurementSuppliesList = '/procurementSuppliesList/updateProcurementSuppliesList'
+export const deleteProcurementSuppliesList = '/procurementSuppliesList/deleteProcurementSuppliesList'
+
+/**
+ * @desc 鏍囧噯鐗╄川娓呭崟
+ */
+export const getStandardSubstanceAll = '/feStandardSubstance/getStandardSubstanceAll';
+
+/**
+ * @desc 鏍囧噯鐗╄川楠屾敹
+ */
+// 鏌ヨ
+export const getPageAcceptance = '/feStandardSubstanceAcceptance/getPageAcceptance';
+// 鏌ヨ鎯�
+export const getAcceptanceDetails = '/feStandardSubstanceAcceptance/getAcceptanceDetails'
+// 鏂板
+export const addAcceptance = '/feStandardSubstanceAcceptance/addAcceptance';
+// 缂栬緫
+export const updateAcceptance = '/feStandardSubstanceAcceptance/updateAcceptance';
+// 瀵煎嚭
+export const exportAcceptance = '/feStandardSubstanceAcceptance/exportFeStandardSubstanceAcceptance';
+/**
+ * @desc 鏈嶅姟鍜屼緵搴斿搧鑰楁潗娑堣��
+ */
+export const procurementSuppliesExpendsList = '/procurementSuppliesExpends/procurementSuppliesExpendlist'
+export const addProcurementSuppliesExpends = '/procurementSuppliesExpends/addProcurementSuppliesExpends'
+export const deleteProcurementSuppliesExpends = '/procurementSuppliesExpends/deleteProcurementSuppliesExpends'
+// 鑰楁潗鍒楄〃excel
+export const procurementSuppliesListExport = '/procurementSuppliesList/exportProcurementSuppliesList'
+// 鑰楁潗鍏ュ簱瀵煎嚭excel
+export const procurementSuppliesStoreExportExcel = 'procurementSuppliesStore/exportExcel'
+
diff --git a/src/assets/api/controller.js b/src/assets/api/controller.js
index be435b7..b6193ef 100644
--- a/src/assets/api/controller.js
+++ b/src/assets/api/controller.js
@@ -59,6 +59,7 @@
     processSample,
     processTotaldeal,
     processEvaluate,
+    qualityMonitor,
   }
 }
 
@@ -763,3 +764,26 @@
   delProcessEvaluate:'/processEvaluate/delProcessEvaluate',//鍒犻櫎  浼犲弬id
   exportProcessEvaluate:'/processEvaluate/exportProcessEvaluate',//瀵煎嚭
 }
+
+// 7.7璐ㄩ噺鐩戞帶璁″垝
+const qualityMonitor = {
+  pageQualityMonitor:'/qualityMonitor/pageQualityMonitor', // 鐩戞帶骞村害璁″垝鍒楄〃
+  pageQualityMonitorDetail:'/qualityMonitor/pageQualityMonitorDetail', // 鐩戞帶璁″垝璇︽儏鍒楄〃
+  addQualityMonitorDetail:'/qualityMonitor/addQualityMonitorDetail', // 鏂板鐩戞帶璁″垝璇︽儏
+  updateQualityMonitorDetail:'/qualityMonitor/updateQualityMonitorDetail', // 淇敼鐩戞帶璁″垝璇︽儏
+  delQualityMonitorDetail:'/qualityMonitor/delQualityMonitorDetail', // 鍒犻櫎鐩戞帶璁″垝璇︽儏
+  getQualityMonitorRatify:'/qualityMonitor/getQualityMonitorRatify', // 鏌ヨ鐩戞帶璁″垝璇︽儏瀹炴柦淇℃伅
+  addQualityMonitorRatify:'/qualityMonitor/addQualityMonitorRatify', // 鏂板鐩戞帶璁″垝璇︽儏瀹炴柦淇℃伅
+  addQualityMonitorRatifyOpinion:'/qualityMonitor/addQualityMonitorRatifyOpinion', // 鎻愪氦鐩戞帶璁″垝璇︽儏鎵瑰噯鎰忚
+  getQualityMonitorEvaluate:'/qualityMonitor/getQualityMonitorEvaluate', // 鏌ヨ鐩戞帶璇勪环
+  addQualityMonitorEvaluate:'/qualityMonitor/addQualityMonitorEvaluate', // 鏂板鐩戞帶璇勪环
+  addMonitorEvaluateOpinion:'/qualityMonitor/addMonitorEvaluateOpinion', // 鏂板鐩戞帶璇勪环鎵瑰噯
+  getEvaluateFileList:'/qualityMonitor/getEvaluateFileList', // 鏌ヨ鐩戞帶璇勪环闄勪欢鍒楄〃
+  delVerifyEvaluateFileList:'/qualityMonitor/delVerifyEvaluateFileList', // 鍒犻櫎鐩戞帶璇勪环闄勪欢鍒楄〃
+  uploadEvaluateFile:'/qualityMonitor/uploadEvaluateFile', // 鏂板鐩戞帶璇勪环闄勪欢琛�
+  examineQualityMonitor:'/qualityMonitor/examineQualityMonitor', // 鐩戞帶璁″垝瀹℃牳
+  ratifyQualityMonitor:'/qualityMonitor/ratifyQualityMonitor', // 鐩戞帶璁″垝鎵瑰噯
+  delQualitySupervise:'/qualityMonitor/delQualitySupervise', // 鐩戞帶璁″垝鎵瑰噯
+  importQualityMonitor:'/qualityMonitor/importQualityMonitor', // 瀵煎叆鐩戞帶璁″垝
+  exportQualityMonitorDetail:'/qualityMonitor/exportQualityMonitorDetail', // 瀵煎嚭鐩戞帶璁″垝
+}
diff --git a/src/components/caorui/Department/components/Communicate/Add.vue b/src/components/caorui/Department/components/Communicate/Add.vue
new file mode 100644
index 0000000..2780b86
--- /dev/null
+++ b/src/components/caorui/Department/components/Communicate/Add.vue
@@ -0,0 +1,144 @@
+<template>
+    <div class="add">
+        <el-dialog
+            :title="isEdit ?'缂栬緫闄勪欢璧勬枡':'鏂板闄勪欢璧勬枡'"
+            :visible.sync="dialogVisible"
+            width="40%"
+        >
+            <el-form
+                :model="form"
+                label-width="80px"
+                size="small"
+            >
+                    <el-form-item label="娌熼�氫汉">
+                        <el-select
+                            v-model="form.userId"
+                            placeholder="璇烽�夋嫨"
+                            style="width: 100%" multiple
+                        >
+                            <el-option
+                                v-for="(item, index) in userList"
+                                :key="index"
+                                :label="item.name"
+                                :value="item.id"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="娌熼�氭椂闂�">
+                        <el-date-picker
+                            v-model="form.communicationTime"
+                            type="datetime"
+                            value-format="yyyy-MM-dd HH:mm:ss"
+                            placeholder="璇烽�夋嫨鏃ユ湡鏃堕棿"
+                            style="width: 100%"
+                        >
+                        </el-date-picker>
+                    </el-form-item >
+                    <el-form-item label="娌熼�氬湴鐐�">
+                        <el-input v-model="form.communicationPlace" placeholder="璇烽�夋嫨"></el-input>
+                    </el-form-item >
+                    <el-form-item label="娌熼�氬唴瀹�">
+                        <el-input v-model="form.communicationContent" placeholder="璇烽�夋嫨"></el-input>
+                    </el-form-item >
+            </el-form>
+            <div slot="footer" class="foot">
+                <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+                <el-button type="primary" :loading="loading" @click="submitForm">纭� 瀹�</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import {
+    getUserListApi,
+    addOrUpdatePersonCommunicationAbility,
+} from "../../../../../assets/api/api"
+export default {
+    data() {
+        return {
+            isEdit: false,
+            dialogVisible: false,
+            form: {
+                id: undefined,
+                userId: [],
+                communicationTime: undefined,
+                communicationPlace: undefined,
+                communicationContent: undefined
+            },
+            loading: false,
+            userList: []
+        }
+    },
+    methods: {
+        /**
+         * @desc 鏄剧ず妯℃�佹
+         * @param {*} row
+         * @param {*} type
+         */
+        openDialog(row, type) {
+            this.getUserList()
+            this.dialogVisible = true
+            if(type) {
+                this.isEdit = true
+                this.form.id = row.id
+                this.form.userId = row.userId.split(',').map(m=>Number(m))
+                this.form.communicationTime = row.communicationTime
+                this.form.communicationPlace = row.communicationPlace
+                this.form.communicationContent = row.communicationContent
+            } else {
+                this.isEdit = false
+                this.form.id = undefined
+                this.form.userId = []
+                this.form.communicationTime = undefined
+                this.form.communicationPlace = undefined
+                this.form.communicationContent = undefined
+            }
+        },
+        /**
+         * @desc 鑾峰彇鐢ㄦ埛淇℃伅
+         */
+        async getUserList() {
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: getUserListApi,
+            })
+            if(code == 200) {
+                this.userList = data
+            }
+        },
+        /**
+         * @desc 鎻愪氦琛ㄥ崟
+         */
+        async submitForm() {
+            this.loading = true
+            const { code, data } = await this.$axios({
+                method: 'post',
+                url: addOrUpdatePersonCommunicationAbility,
+                data: {
+                    id: this.form.id,
+                    userId: this.form.userId.join(','),
+                    communicationTime: this.form.communicationTime,
+                    communicationPlace: this.form.communicationPlace,
+                    communicationContent: this.form.communicationContent,
+                },
+                noQs: true
+            })
+            if(code == 200) {
+                this.$emit('submit')
+                this.dialogVisible = false
+            } else {
+                this.$message.error(this.isEdit ? '缂栬緫澶辫触':'鏂板澶辫触')
+            }
+            this.loading = false
+        }
+    }
+}
+</script>
+<style scoped>
+.foot {
+    width: 100%;
+}
+.add >>> .el-dialog__footer {
+    padding-right: 20px;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Communicate/index.vue b/src/components/caorui/Department/components/Communicate/index.vue
new file mode 100644
index 0000000..758d31d
--- /dev/null
+++ b/src/components/caorui/Department/components/Communicate/index.vue
@@ -0,0 +1,238 @@
+<template>
+    <div class="flex_column">
+        <TableCard title="娌熼�氳褰�" :showForm="isDepartment">
+            <template v-slot:form >
+                <div class="w100 items_center justify_between" v-if="isDepartment">
+                    <div></div>
+                    <div>
+                        <!-- <el-button type="primary" size="small">瀵煎嚭</el-button> -->
+                        <el-button type="primary" size="small" @click="openDialog">鏂板</el-button>
+                    </div>
+                </div>
+            </template>
+            <template v-slot:table>
+                <ZTTable
+                    style="margin-top: 18px; padding: 0 15px;"
+                    :height="'calc(100vh - 21em)'"
+                    :column="columnData"
+                    :table-data="tableData"
+                    :table-loading="loading"
+                ></ZTTable>
+                <el-divider></el-divider>
+                <div class="pagination">
+                    <div></div>
+                    <el-pagination
+                        :page-sizes="[10, 20, 30, 40]"
+                        :page-size="pagination.pageSize"
+                        layout="total, sizes, prev, pager, next, jumper"
+                        :total="pagination.total"
+                        @current-change=""
+                        @size-change=""
+                    >
+                    </el-pagination>
+                </div>
+            </template>
+        </TableCard>
+        <Add ref="communicateModal" @submit="getTableData"></Add>
+    </div>
+</template>
+<script>
+import TableCard from "../../../TableCard/index.vue"
+import ZTTable from "../../../ZTTable/index.vue"
+import Add from "./Add.vue"
+import {
+    personPersonCommunicationAbilityPage,
+    deletePersonCommunicationAbility,
+    exportPersonCommunicationAbility
+} from "../../../../../assets/api/api.js"
+
+export default {
+    components: {
+        TableCard,
+        ZTTable,
+        Add
+    },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+    data() {
+        return {
+            // departId: 0,
+            columnData: [
+                {
+                    label: '搴忓彿',
+                    prop: 'id'
+                }, {
+                    label: '娌熼�氫汉',
+                    prop: 'userName'
+                }, {
+                    label: '娌熼�氭椂闂�',
+                    prop: 'communicationTime'
+                }, {
+                    label: '娌熼�氬湴鐐�',
+                    prop: 'communicationPlace'
+                }, {
+                    label: '娌熼�氬唴瀹�',
+                    prop: 'communicationContent'
+                }, {
+                    label: '鎿嶄綔',
+                    dataType: 'action',
+                    operation: [
+                        {
+                            name: '缂栬緫',
+                            type: 'text',
+                            clickFun: (row) => {
+                                this.openDialog(row, true)
+                            }
+                        }, {
+                            name: '涓嬭浇',
+                            type: 'text',
+                            clickFun: (row) => {
+                                this.handleDown(row)
+                            }
+                        }, {
+                            name: '鍒犻櫎',
+                            type: 'text',
+                            color: '#f56c6c',
+                            clickFun: (row) => {
+                                this.delPerson(row.id)
+                            }
+                        }
+                    ]
+                },
+            ],
+            tableData: [],
+            pagination: {
+                current: 1,
+                pageSize: 20,
+                total: 0
+            },
+            loading: false
+        }
+    },
+  mounted() {
+    this.getTableData()
+  },
+  methods: {
+        openDialog(row, type=false) {
+            this.$refs.communicateModal.openDialog(row, type)
+        },
+        async getTableData() {
+            this.loading = true
+          const params = this.isDepartment ? {
+            departLimsId: this.departId,
+            current: this.pagination.current,
+            size: this.pagination.pageSize
+          } : {
+            userId: this.departId,
+            current: this.pagination.current,
+            size: this.pagination.pageSize
+          }
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: personPersonCommunicationAbilityPage,
+                params: params
+            })
+            if(code == 200) {
+                this.pagination.total = data.total
+                this.tableData = data.records
+                this.loading = false
+            }
+        },
+        /**
+         * @desc 鑾峰彇璁惧id
+         */
+        getDepart(id) {
+            this.departId = id
+            this.getTableData()
+        },
+        /**
+         * @desc 鍒犻櫎娌熼�氳褰�
+         */
+        delPerson(id) {
+            this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?', '鎻愮ず', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(async () => {
+                let formData = new FormData()
+                formData.append('id', id)
+                const { code } = await this.$axios({
+                    method: 'delete',
+                    url: deletePersonCommunicationAbility,
+                    data: formData
+                })
+                if(code == 200) {
+                    this.$message({
+                        type: 'success',
+                        message: '鍒犻櫎鎴愬姛!'
+                    });
+                    this.getTableData()
+                }
+            })
+        },
+        async handleDown(row){
+          this.$axios.post(this.$api.personCommunicationAbility.exportPersonCommunicationAbility,{id:row.id},{responseType: "blob"}).then(res => {
+            if(res.code == 201){
+              this.$message.error(res.message)
+              return
+            }
+            this.$message.success('涓嬭浇鎴愬姛')
+            const blob = new Blob([res],{ type: 'application/octet-stream' });
+            const url = URL.createObjectURL(blob);
+            const link = document.createElement('a');
+            link.href = url;
+            link.download = row.userName+'-娌熼�氳褰�'+'.docx';
+            link.click();
+          })
+        }
+    },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (newId) {
+          this.getTableData();
+        }
+      }
+    }
+  }
+}
+</script>
+<style scoped>
+.flex_column {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+}
+.w100 {
+    width: 100%;
+}
+.pagination {
+    display: flex;
+    justify-content: space-between
+}
+.items_center {
+    display: flex;
+    align-items: center;
+}
+.justify_between {
+    justify-content: space-between
+}
+.date_box {
+    margin: 0 5px;
+}
+
+.search {
+    width: 150px;
+    padding: 0 16px;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Mandate/Add.vue b/src/components/caorui/Department/components/Mandate/Add.vue
new file mode 100644
index 0000000..8efef2a
--- /dev/null
+++ b/src/components/caorui/Department/components/Mandate/Add.vue
@@ -0,0 +1,256 @@
+<template>
+    <div class="add">
+        <el-dialog
+            :title="isEdit ?'缂栬緫闄勪欢璧勬枡':'鏂板闄勪欢璧勬枡'"
+            :visible.sync="dialogVisible"
+            width="50%"
+        >
+            <el-form
+                ref="ruleForm"
+                :rules="rules"
+                :model="form"
+                label-width="100px"
+                size="medium"
+            >
+                    <el-form-item label="璇佷功缂栧彿" prop="certificateNumber">
+                        <el-input v-model="form.certificateNumber" placeholder="璇疯緭鍏�" style="width: 100%">
+                        </el-input>
+                    </el-form-item >
+                    <el-form-item label="琚换鑱屼汉鍛�" prop="userId">
+                        <el-select v-model="form.userId" placeholder="璇烽�夋嫨">
+                            <el-option
+                                v-for="(item, index) in userList"
+                                :key="index"
+                                :label="item.name"
+                                :value="item.id"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item >
+                    <el-form-item label="浠昏亴宀椾綅" prop="post">
+                        <el-input v-model="form.post" placeholder="璇疯緭鍏�"></el-input>
+                    </el-form-item >
+                    <el-form-item label="鐞嗚鑰冭瘯鎴愮哗" prop="num1">
+                        <el-input v-model="form.num1" placeholder="璇疯緭鍏�"></el-input>
+                    </el-form-item >
+                    <el-form-item label="鎿嶄綔鎶�鑳借�冭瘯鎴愮哗" prop="num2">
+                        <el-input v-model="form.num2" placeholder="璇疯緭鍏�"></el-input>
+                    </el-form-item >
+                    <el-form-item label="鎿嶄綔绫诲瀷" prop="operationType">
+                        <el-input v-model="form.operationType" placeholder="璇烽�夋嫨"></el-input>
+                    </el-form-item >
+                    <el-row>
+                      <el-col :span="20">
+                        <el-form-item label="涓婂矖璇佷功">
+                          <el-input v-model="form.systemFileName" size="small" disabled>
+                            <el-button slot="append" icon="el-icon-delete-solid"
+                                       @click="deleteFile(form.systemFileName)"></el-button>
+                          </el-input>
+                        </el-form-item>
+                      </el-col>
+                      <el-col :span="4">
+                        <el-upload ref="upload" style="float: left; margin: 0 12px 0 20px;" :action="action"
+                                   :show-file-list="false"
+                                   :on-success="onSuccess">
+                          <el-button class="uploadFile" slot="trigger" size="small" type="primary">娴忚</el-button>
+                        </el-upload>
+                      </el-col>
+                    </el-row>
+<!--                    <el-form-item label="鏂囦欢">-->
+<!--                        <el-upload-->
+<!--                            ref="upload"-->
+<!--                            action="#"-->
+<!--                            :before-upload="beforeUpload"-->
+<!--                            :http-request="uploadFile"-->
+<!--                            :file-list="form.fileList"-->
+<!--                            :limit="1"-->
+<!--                            :auto-upload="false"-->
+<!--                        >-->
+<!--                            <el-button type="primary" plain>-->
+<!--                                <i class="el-icon-upload el-icon&#45;&#45;right"></i>-->
+<!--                                涓婁紶鏂囦欢-->
+<!--                            </el-button>-->
+<!--                        </el-upload>-->
+<!--                    </el-form-item>-->
+                    <el-form-item label="澶囨敞">
+                        <el-input v-model="form.remarks" placeholder="璇烽�夋嫨"></el-input>
+                    </el-form-item >
+            </el-form>
+            <div slot="footer" class="foot">
+                <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+                <el-button type="primary" :loading="loading" @click="submitForm">纭� 瀹�</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import {
+    addOrUpdatePersonPostAuthorizationRecord,
+    saveCNASFile,
+    getUserListApi
+} from "../../../../../assets/api/api"
+export default {
+    data() {
+        return {
+            isEdit: false,
+            dialogVisible: false,
+            form: {
+                id: undefined,
+                certificateNumber: undefined,
+                userId: undefined,
+                post: undefined,
+                operationType: undefined,
+                fileList: [],
+                fileName: undefined,
+                systemFileName: undefined,
+                remarks: undefined,
+                num2:undefined,
+                num1:undefined
+            },
+            rules: {
+                certificateNumber: [{ required: true, message: '璇疯緭鍏ヨ瘉涔︾紪鍙�', trigger: 'blur' }],
+                userId: [{ required: true, message: '璇烽�夋嫨琚换鑱屼汉鍛�', trigger: 'change' }],
+                post: [{ required: true, message: '浠昏亴宀椾綅', trigger: 'blur' }],
+                operationType: [{ required: true, message: '鎿嶄綔绫诲瀷', trigger: 'blur' }],
+
+            },
+            loading: false,
+            userList: []
+        }
+    },
+    mounted() {
+
+    },
+  computed: {
+    action() {
+      return this.javaApi + this.$api.personnel.saveCNASFile
+    }
+  },
+    methods: {
+      async onSuccess(response, file, fileList) {
+        this.$set(this.form, "systemFileName", response.data)
+      },
+      async deleteFile(fileName) {
+        await this.$axios.delete(this.$api.personnel.deleteCNASFile + "?fileName=" + fileName).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛锛�')
+          this.$set(this.form, "systemFileName", null)
+        })
+      },
+        async openDialog(row, type) {
+            await this.getUserList()
+            this.dialogVisible = true
+            if(type) {
+                this.isEdit = true
+                this.form.id = row.id
+                this.form.certificateNumber = row.certificateNumber
+                this.form.userId = Number(row.userId)
+                this.form.post = row.post
+                this.form.operationType = row.operationType
+                this.form.systemFileName = row.systemFileName
+                this.form.remarks = row.remarks
+                this.form.num1 = row.num1
+                this.form.num2 = row.num2
+            } else {
+                this.isEdit = false
+                this.form.id = undefined
+                this.form.certificateNumber = undefined
+                this.form.userId = undefined
+                this.form.post = undefined
+                this.form.operationType = undefined
+                this.form.fileList = []
+                this.form.fileName = undefined
+                this.form.systemFileName = undefined
+                this.form.remarks = undefined
+                this.form.num1 = undefined
+                this.form.num2 = undefined
+            }
+        },
+        closeDialog() {
+            this.dialogVisible = false
+        },
+        /**
+         * @desc 鑾峰彇鐢ㄦ埛淇℃伅
+         */
+        async getUserList() {
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: getUserListApi,
+            })
+            if(code == 200) {
+                this.userList = data
+            }
+        },
+        /**
+         * @desc 鎻愪氦琛ㄥ崟
+         */
+        submitForm() {
+            this.$refs.ruleForm.validate(async (valid) => {
+                if(valid) {
+                    await this.submitFormData()
+                }
+            })
+        },
+        /**
+         * @desc 涓婁紶鏂囦欢
+         */
+        async uploadFile() {
+            console.log('鏂囦欢', this.form.fileList[0])
+            let formData = new FormData()
+            formData.append('file', this.form.fileList[0])
+            const { code, data } = await this.$axios({
+                method: 'post',
+                url: saveCNASFile,
+                data: formData,
+                headers: {
+                    'Content-Type': 'multipart/form-data;'
+                },
+                noQs: true
+            })
+            if(code == 200) {
+                this.form.systemFileName = data
+            }
+        },
+        /**
+         * @desc 涓婁紶鏂囦欢
+         */
+        beforeUpload(file) {
+            this.form.fileList = [file]
+            this.form.fileName = file.name
+        },
+        /**
+         * @desc 鎻愪氦form琛ㄥ崟
+         */
+        async submitFormData() {
+            this.loading = true
+            const { code, data } = await this.$axios({
+                method: 'post',
+                url: addOrUpdatePersonPostAuthorizationRecord,
+                data: {
+                    id: this.form.id,
+                    certificateNumber: this.form.certificateNumber,
+                    userId: this.form.userId,
+                    post: this.form.post,
+                    operationType: this.form.operationType,
+                    systemFileName: this.form.systemFileName,
+                    remarks: this.form.remarks,
+                    num1: this.form.num1,
+                    num2: this.form.num2
+                },
+                noQs: true
+            })
+            if(code == 200) {
+                this.closeDialog()
+                this.$emit('refresh')
+            }
+            this.loading = false
+        }
+    }
+}
+</script>
+<style scoped>
+.foot {
+    width: 100%;
+}
+.add >>> .el-dialog__footer {
+    padding-right: 20px;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Mandate/index.vue b/src/components/caorui/Department/components/Mandate/index.vue
new file mode 100644
index 0000000..046aa27
--- /dev/null
+++ b/src/components/caorui/Department/components/Mandate/index.vue
@@ -0,0 +1,265 @@
+<template>
+    <div class="flex_column">
+        <TableCard title="浠昏亴鎺堟潈璁板綍" :showForm="isDepartment">
+            <template v-slot:form>
+                <div class="w100 items_center justify_between" v-if="isDepartment">
+                    <div></div>
+                    <div>
+                        <el-button type="primary" size="small" @click="openDialog">鏂板</el-button>
+                    </div>
+                </div>
+            </template>
+            <template v-slot:table>
+                <ZTTable
+                    style="margin-top: 18px; padding: 0 15px;"
+                    :height="'calc(100vh - 21em)'"
+                    :column="columnData"
+                    :table-data="tableData"
+                    :table-loading="loading"
+                ></ZTTable>
+                <el-divider></el-divider>
+                <div class="pagination">
+                    <div></div>
+                    <el-pagination
+                        :page-sizes="[10, 20, 30, 40]"
+                        :page-size="pagination.pageSize"
+                        layout="total, sizes, prev, pager, next, jumper"
+                        :total="pagination.total"
+                        @current-change="currentChange"
+                        @size-change="sizeChange"
+                    >
+                    </el-pagination>
+                </div>
+            </template>
+        </TableCard>
+        <Add ref="mandateModal" @refresh="getTableData"></Add>
+    </div>
+</template>
+<script>
+import TableCard from "../../../TableCard/index.vue"
+import ZTTable from "../../../ZTTable/index.vue"
+import Add from "./Add.vue"
+import {
+    getPersonPostAuthorizationRecordPage,
+    deletePersonPostAuthorizationRecord
+} from "../../../../../assets/api/api"
+import { nextTick } from "vue";
+
+export default {
+    components: {
+        TableCard,
+        ZTTable,
+        Add
+    },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+    data() {
+        return {
+            // departId: 0,
+            columnData: [
+                {
+                    label: '搴忓彿',
+                    prop: 'id'
+                }, {
+                    label: '璇佷功缂栧彿',
+                    prop: 'certificateNumber'
+                }, {
+                    label: '琚换鑱屼汉鍛�',
+                    prop: 'userName'
+                }, {
+                    label: '浠昏亴宀椾綅',
+                    prop: 'post'
+                }, {
+                    label: '鐞嗚鑰冭瘯鎴愮哗',
+                    prop: 'num1'
+                },{
+                    label: '鎿嶄綔鎶�鑳借�冭瘯鎴愮哗',
+                    prop: 'num2'
+                },{
+                    label: '鎿嶄綔鏃堕棿',
+                    prop: 'updateTime'
+                }, {
+                    label: '澶囨敞',
+                    prop: 'remarks',
+                    width: 300
+                }, {
+                    label: '鎿嶄綔',
+                    dataType: 'action',
+                    width: 160,
+                    operation: [
+                        {
+                            name: '缂栬緫',
+                            type: 'text',
+                            clickFun: (row) => {
+                                this.openDialog(row, true)
+                            }
+                        }, {
+                            name: '涓嬭浇',
+                            type: 'text',
+                            clickFun: (row) => {
+                                this.handleDown(row)
+                            }
+                        }, {
+                            name: '鍒犻櫎',
+                            type: 'text',
+                            color: '#f56c6c',
+                            clickFun: (row) => {
+                                this.deleteNotify(row.id)
+                            }
+                        }
+                    ]
+                },
+            ],
+            tableData: [],
+            pagination: {
+                current: 1,
+                pageSize: 20,
+                total: 0
+            },
+            loading: false
+        }
+    },
+    mounted() {
+      this.getTableData()
+        console.log(this.departId)
+    },
+    methods: {
+        openDialog(row, type=false) {
+            this.$refs.mandateModal.openDialog(row, type)
+        },
+        /**
+         * @desc 鏌ヨ琛ㄦ牸鏁版嵁
+         */
+        async getTableData() {
+            this.loading = true
+            await nextTick()
+          const params = this.isDepartment ? {
+            departLimsId: this.departId,
+            current: this.pagination.current,
+            size: this.pagination.pageSize
+          } : {
+            userId: this.departId,
+            current: this.pagination.current,
+            size: this.pagination.pageSize
+          }
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: getPersonPostAuthorizationRecordPage,
+                params: params
+            })
+            if(code == 200) {
+                this.pagination.total = data.total
+                this.tableData = data.records
+                this.loading = false
+            }
+        },
+        /**
+         * @desc 褰撳墠椤垫敼鍙�
+         */
+        currentChange(current) {
+            this.pagination.current = current
+            this.getTableData()
+        },
+        /**
+         * @desc 姣忛〉涓暟鏀瑰彉
+         */
+        sizeChange(pageSize) {
+            this.pagination.pageSize = pageSize
+            this.getTableData()
+        },
+        /**
+         * @desc 鍒犻櫎浠昏亴璁板綍
+         */
+        deleteNotify(id) {
+            this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?', '鎻愮ず', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                this.delMandate(id)
+            })
+        },
+        /**
+         * @desc api鍒犻櫎
+         */
+        async delMandate(id) {
+            const formData = new FormData()
+            formData.append('id', id)
+            const { code, data } = await this.$axios({
+                method: 'delete',
+                url: deletePersonPostAuthorizationRecord,
+                data: formData,
+                noQs: true
+            })
+            if(code == 200) {
+                this.$message({ message: '鍒犻櫎鎴愬姛', type: 'success' })
+                this.getTableData()
+            } else {
+                this.$message({ message: '鍒犻櫎澶辫触', type: 'error' })
+            }
+        },
+        /**
+         * @desc 鑾峰彇璁惧id
+         */
+        getDepart(id) {
+            this.departId = id
+            this.getTableData()
+        },
+        handleDown(row){
+          this.$axios.post(this.$api.personPostAuthorizationRecord.exportPersonPostAuthorizationRecord,{id:row.id},{responseType: "blob"}).then(res => {
+            if(res.code == 201){
+              this.$message.error(res.message)
+              return
+            }
+            this.$message.success('涓嬭浇鎴愬姛')
+            const blob = new Blob([res],{ type: 'application/octet-stream' });
+            const url = URL.createObjectURL(blob);
+            const link = document.createElement('a');
+            link.href = url;
+            link.download = '浠昏亴鎺堟潈-'+row.certificateNumber+'-'+row.post + '.docx';
+            link.click();
+          })
+        }
+    },
+//   watch: {
+//     departId: {
+//       handler(newId, oldId) {
+//         if (newId) {
+//           this.getTableData();
+//         }
+//       }
+//     }
+//   }
+}
+</script>
+<style scoped>
+.flex_column {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+}
+.w100 {
+    width: 100%;
+}
+.pagination {
+    display: flex;
+    justify-content: space-between
+}
+.items_center {
+    display: flex;
+    align-items: center;
+}
+.justify_between {
+    justify-content: space-between
+}
+</style>
diff --git a/src/components/caorui/Department/components/Plan/Add.vue b/src/components/caorui/Department/components/Plan/Add.vue
new file mode 100644
index 0000000..56cf736
--- /dev/null
+++ b/src/components/caorui/Department/components/Plan/Add.vue
@@ -0,0 +1,192 @@
+<template>
+    <div class="add">
+        <el-dialog
+            :title="isEdit ? '缂栬緫鐩戠潱璁″垝鏄庣粏':'鏂板鐩戠潱璁″垝鏄庣粏'"
+            :visible.sync="dialogVisible"
+            width="800px"
+        >
+            <el-form ref="formRef" :model="ruleForm" :rules="rules" label-width="100px">
+                <el-col :span="12">
+                    <el-form-item label="鐩戠潱鏃ユ湡" prop="superviseDate">
+                        <el-date-picker
+                            v-model="ruleForm.superviseDate"
+                            format="yyyy-MM-dd"
+                            placeholder="閫夋嫨鏃ユ湡"
+                            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="superviseDes">
+                        <el-input v-model="ruleForm.superviseDes"></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                    <el-form-item label="鐩戠潱椤圭洰" prop="superviseProject">
+                        <el-input v-model="ruleForm.superviseProject"></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                    <el-form-item label="琚洃鐫d汉" prop="supervisePerson">
+                        <el-input v-model="ruleForm.supervisePerson"></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="24">
+                    <el-form-item label="鐩戠潱鍘熷洜" prop="superviseReason">
+                        <el-input v-model="ruleForm.superviseReason"></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="24">
+                    <el-form-item label="澶囨敞" prop="remarks">
+                        <el-input v-model="ruleForm.remarks"></el-input>
+                    </el-form-item>
+                </el-col>
+            </el-form>
+            <div slot="footer" class="foot">
+                <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+                <el-button :loading="loading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import { yearPlanDetailAdd, yearPlanDetailEdit } from '../../../../../assets/api/api'
+export default {
+    props: {
+        planId: {
+            type: Number,
+            default: undefined
+        }
+    },
+    data() {
+        return {
+            loading: false,
+            isEdit: false,
+            dialogVisible: false,
+            ruleForm: {
+                id: undefined,
+                superviseDate: undefined, // 鐩戠潱鏃ユ湡
+                superviseDes: undefined, // 鐩戠潱鐩殑
+                superviseProject: undefined, // 鐩戠潱椤圭洰
+                supervisePerson: undefined, // 琚洃鐫d汉
+                superviseReason: undefined, // 鐩戠潱鍘熷洜
+                remarks: undefined, // 澶囨敞
+            },
+            rules: {
+                superviseDate: [{ required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }],
+                superviseDes: [{ required: true, message: '璇疯緭鍏ョ洃鐫g洰鐨�', trigger: 'blur' }],
+                superviseProject: [{ required: true, message: '璇疯緭鍏ョ洃鐫i」鐩�', trigger: 'blur' }],
+                supervisePerson: [{ required: true, message: '璇疯緭鍏ヨ鐩戠潱浜�', trigger: 'blur' }],
+                superviseReason: [{ required: true, message: '璇疯緭鍏ョ洃鐫e師鍥�', trigger: 'blur' }],
+            }
+        }
+    },
+    methods: {
+        formatForm(row) {
+            this.ruleForm.id = undefined
+            this.ruleForm.planId = row.planId
+            this.ruleForm.superviseDate = undefined
+            this.ruleForm.superviseDes = undefined
+            this.ruleForm.superviseProject = undefined
+            this.ruleForm.supervisePerson = undefined
+            this.ruleForm.superviseReason = undefined
+            this.ruleForm.remarks = undefined
+        },
+        renderForm(row) {
+            this.ruleForm.id = row.id
+            this.ruleForm.superviseDate = row.superviseDate
+            this.ruleForm.superviseDes = row.superviseDes
+            this.ruleForm.superviseProject = row.superviseProject
+            this.ruleForm.supervisePerson = row.supervisePerson
+            this.ruleForm.superviseReason = row.superviseReason
+            this.ruleForm.remarks = row.remarks
+        },
+        showDialog(row, type) {
+            console.log(row)
+            if(type) {
+                this.isEdit = true
+                this.renderForm(row)
+            } else {
+                this.formatForm(row)
+                this.isEdit = false
+            }
+            this.dialogVisible = true
+        },
+        closeDialog() {
+            this.dialogVisible = false
+        },
+        async addYearDetail() {
+            const { code, data } = await this.$axios({
+                method: 'post',
+                url: yearPlanDetailAdd,
+                data: this.ruleForm,
+                headers: {
+                    'Content-Type': 'application/json'
+                }
+            })
+            this.loading = false
+            if(code == 200) {
+                this.$message({
+                    type: 'success',
+                    message: '鏂板鎴愬姛'
+                })
+                this.closeDialog()
+                this.$emit('submit')
+            } else {
+                this.$message({
+                    type: 'error',
+                    message: '鏂板澶辫触'
+                })
+            }
+        },
+        async editYearDetail() {
+            const { code, data } = await this.$axios({
+                method: 'post',
+                url: yearPlanDetailEdit,
+                data: this.ruleForm,
+                headers: {
+                    'Content-Type': 'application/json'
+                }
+            })
+            this.loading = false
+            if(code == 200) {
+                this.$message({
+                    type: 'success',
+                    message: '缂栬緫鎴愬姛'
+                })
+                this.closeDialog()
+                this.$emit('submit')
+            } else {
+                this.$message({
+                    type: 'error',
+                    message: '缂栬緫澶辫触'
+                })
+            }
+        },
+        submitForm() {
+            this.$refs.formRef.validate((valid) => {
+                if (valid) {
+                    this.loading = true
+                    if(this.isEdit) {
+                        this.editYearDetail()
+                    } else {
+                        this.addYearDetail()
+                    }
+                } else {
+                    return false;
+                }
+            })
+        },
+    }
+}
+</script>
+<style scoped>
+.foot {
+    width: 100%;
+}
+.add >>> .el-dialog__footer {
+    padding-right: 20px;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Plan/UploadExcel.vue b/src/components/caorui/Department/components/Plan/UploadExcel.vue
new file mode 100644
index 0000000..99c475f
--- /dev/null
+++ b/src/components/caorui/Department/components/Plan/UploadExcel.vue
@@ -0,0 +1,58 @@
+<template>
+    <div>
+        <el-upload
+            ref="upload"
+            action="#"
+            :before-upload="beforeUpload"
+            :http-request="uploadFile"
+            :file-list="fileList"
+            :on-success="uploadFileSuccess"
+            accept=".xls, .xlsx"
+            :limit="1"
+            :auto-upload="true"
+        >
+            <el-button size="small" type="primary">瀵煎叆</el-button>
+        </el-upload>
+    </div>
+</template>
+<script>
+import { yearPlanDetailImport } from '../../../../../assets/api/api';
+export default {
+    data() {
+        return {
+            fileList: []
+        }
+    },
+    methods: {
+        /**
+         * @desc 涓婁紶鏂囦欢
+         */
+        beforeUpload(file) {
+            this.fileList = [file]
+        },
+        /**
+         * @desc 涓婁紶鑷虫湇鍔″櫒
+         */
+        async uploadFile() {
+            console.log('鏂囦欢', this.fileList[0])
+            let formData = new FormData()
+            formData.append('file', this.fileList[0])
+            const { code, data } = await this.$axios({
+                method: 'post',
+                url: yearPlanDetailImport,
+                data: formData,
+                headers: {
+                    'Content-Type': 'multipart/form-data;'
+                },
+                noQs: true
+            })
+            if(code == 200) {
+                this.$emit('upload')
+            }
+        },
+        uploadFileSuccess() {
+            this.$refs.upload.clearFiles()
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Plan/index.vue b/src/components/caorui/Department/components/Plan/index.vue
new file mode 100644
index 0000000..560a949
--- /dev/null
+++ b/src/components/caorui/Department/components/Plan/index.vue
@@ -0,0 +1,469 @@
+<template>
+    <div class="flex_column">
+        <div>
+            <TableCard title="骞村害璁″垝琛�">
+                <template v-slot:form>
+                    <div class="items_center">
+                        <span>缂栧埗浜�</span>
+                        <el-input v-model="yearForm.organizationPerson" class="search" placeholder="璇疯緭鍏�"
+                            size="small"></el-input>
+                        <el-button size="small" type="primary" @click="getYearPlanList">鏌ヨ</el-button>
+                        <el-button size="small" @click="clearYear">娓呯┖</el-button>
+                    </div>
+                    <UploadExcel @upload="getYearPlanList"></UploadExcel>
+                </template>
+                <template v-slot:table>
+                    <ZTTable
+                        ref="yearTable"
+                        :column="yearColumnData"
+                        :height="'calc(100vh - 38em)'"
+                        :highlightCurrentRow="true"
+                        :rowClick="rowClick"
+                        :table-data="yearTableData"
+                        :table-loading="yearLoading"
+                        style="margin-top: 0.5em;
+                        padding: 0 15px;"
+                    >
+                    </ZTTable>
+                    <el-divider></el-divider>
+                    <!-- 鍒嗛〉 -->
+                    <div class="pagination">
+                        <div></div>
+                        <el-pagination :page-size="yearPage.pageSize" :page-sizes="[10, 20, 30, 40]"
+                            :total="yearPage.total" layout="total, sizes, prev, pager, next, jumper"
+                            @current-change="handleYearCurrent" @size-change="handleYearSizeChange">
+                        </el-pagination>
+                    </div>
+                </template>
+            </TableCard>
+        </div>
+        <div style="width: 100%; height: 0.5em; background-color: #f5f7fb;"></div>
+        <div>
+            <TableCard title="骞村害璁″垝鏄庣粏琛�">
+                <template v-slot:form>
+                    <div class="items_center">
+                        <span>鐩戠潱鏃ユ湡</span>
+                        <el-date-picker v-model="yearDetailForm.date" class="date_box" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                            size="small" type="date" value-format="yyyy-MM-dd">
+                        </el-date-picker>
+                        <span>鐩戠潱椤圭洰</span>
+                        <el-input v-model="yearDetailForm.project" class="search" placeholder="璇疯緭鍏�" size="small"></el-input>
+                        <el-button size="small" type="primary" @click="getYearDetailPlanList">鏌ヨ</el-button>
+                        <el-button size="small" @click="clearDetail">娓呯┖</el-button>
+                    </div>
+                    <div>
+                        <el-button v-if="isOperation" size="small" type="primary" @click="showDialog('add')">鏂板</el-button>
+                    </div>
+                </template>
+                <template v-slot:table>
+                    <ZTTable :column="yearDetailColumnData" :height="'calc(100vh - 38em)'" :table-data="yearDetailTableData"
+                        :table-loading="yearDetailLoading" style="margin-top: 18px; padding: 0 15px;">
+                    </ZTTable>
+                    <el-divider></el-divider>
+                    <!-- 鍒嗛〉 -->
+                    <div class="pagination">
+                        <div></div>
+                        <el-pagination :page-size="yearDeatilPage.pageSize" :page-sizes="[10, 20, 30, 40]"
+                            :total="yearDeatilPage.total" layout="total, sizes, prev, pager, next, jumper"
+                            @current-change="handleYearDetailCurrent" @size-change="handleYearDetailSizeChange">
+                        </el-pagination>
+                    </div>
+                </template>
+            </TableCard>
+        </div>
+        <PlanAdd ref="planModal" :planId="planId"  @submit="handleForm"></PlanAdd>
+    </div>
+</template>
+<script>
+import TableCard from "../../../TableCard/index.vue"
+import PlanAdd from "./Add.vue"
+import ZTTable from '../../../ZTTable/index.vue'
+import UploadExcel from "./UploadExcel.vue"
+import { yearPlanListApi, yearDetailPlanListApi, delYearPlanApi, delYearPlanDetailApi, yearPlanDetailApprovalApi, exportSuperVisePlanApi} from "../../../../../assets/api/api"
+
+export default {
+    components: {
+        TableCard,
+        PlanAdd,
+        ZTTable,
+        UploadExcel
+    },
+    data() {
+        return {
+            planId: undefined,
+            yearForm: {
+                organizationPerson: undefined,
+            },
+            yearTableData: [],  // 骞磋〃
+            yearPage: {
+                curent: 1,
+                pageSize: 20,
+                total: 0
+            },
+            yearColumnData: [
+                {
+                    label: '鏂囦欢鍚嶇О',
+                    prop: 'fileName',
+                    minWidth: '150px'
+                }, {
+                    label: '缂栧埗浜�',
+                    prop: 'organizationPerson',
+                    minWidth: '100'
+                }, {
+                    label: '缂栧埗鏃ユ湡',
+                    prop: 'organizationDate',
+                    minWidth: '160'
+                }, {
+                    label: '鎵瑰噯浜�',
+                    prop: 'approvalName',
+                    minWidth: '100'
+                }, {
+                    label: '鎵瑰噯鏃ユ湡',
+                    prop: 'approvalDate',
+                    minWidth: '160'
+                }, {
+                    label: '瀹℃牳浜�',
+                    prop: 'examine'
+                }, {
+                    dataType: 'tag',
+                    label: '鎵瑰噯鐘舵��',
+                    prop: 'approvalStatus',
+                    minWidth: '130',
+                    formatData: (params) => {
+                        if (params == 1) {
+                            return '鎵瑰噯'
+                        } else {
+                            return '涓嶆壒鍑�'
+                        }
+                    },
+                    formatType: (params) => {
+                        if (params == 1) {
+                            return 'success'
+                        } else {
+                            return 'danger'
+                        }
+                    }
+                }, {
+                    label: '鍒涘缓鏃ユ湡',
+                    prop: 'createTime',
+                    minWidth: '160'
+                }, {
+                    label: '鍒涘缓浜�',
+                    prop: 'createName',
+                    minWidth: '100'
+                }, {
+                    dataType: 'action',
+                    minWidth: '160',
+                    label: '鎿嶄綔',
+                  fixed: 'right',
+                    operation: [
+                      {
+                        name: '瀵煎嚭',
+                        type: 'text',
+                        clickFun: (row) => {
+                          this.downLoadPost(row)
+                        }
+                      },
+                      {
+                        name: '鎵瑰噯',
+                        type: 'text',
+                        disabled: (row) => {
+                          if (row.approvalStatus == 1) {
+                            return true
+                          } else {
+                            return false
+                          }
+                        },
+                        clickFun: (row) => {
+                          this.approvalYearPlan(row)
+                        }
+                      },
+                      {
+                        name: '鍒犻櫎',
+                        type: 'text',
+                        color: '#f56c6c',
+                        clickFun: (row) => {
+                          this.delYearPlan(row.id)
+                        }
+                      }
+                    ]
+                }],
+            yearLoading: false,
+            yearDetailForm: {
+                date: undefined,
+                project: undefined
+            },
+            yearDetailTableData: [],    // 骞存槑缁嗚〃
+            yearDeatilPage: {
+                curent: 1,
+                pageSize: 20,
+                total: 0
+            },
+            yearDetailColumnData: [
+                {
+                    label: '鐩戠潱鏃ユ湡',
+                    prop: 'superviseDate'
+                }, {
+                    label: '鐩戠潱鐩殑',
+                    prop: 'superviseDes'
+                }, {
+                    label: '琚洃鐫d汉鍛�',
+                    prop: 'supervisePerson'
+                }, {
+                    label: '澶囨敞',
+                    prop: 'remarks'
+                }, {
+                    label: '鍩硅鏃ユ湡',
+                    prop: 'trainDate'
+                }, {
+                    label: '鍒涘缓',
+                    prop: 'createBy'
+                }, {
+                    dataType: 'action',
+                    width: '180',
+                    label: '鎿嶄綔',
+                    operation: [
+                        {
+                            name: '缂栬緫',
+                            type: 'text',
+                            clickFun: (row) => {
+                                this.$refs.planModal.showDialog(row, true)
+                            }
+                        },
+                        {
+                            name: '鍒犻櫎',
+                            type: 'text',
+                            color: '#f56c6c',
+                            clickFun: (row) => {
+                                this.delYearPlanDetail(row.id)
+                            }
+                        }
+                    ]
+                }
+            ],
+            yearDetailLoading: false,
+          isOperation: false,
+        }
+    },
+    mounted() {
+        this.getYearPlanList()
+        // this.getYearDetailPlanList()
+    },
+    methods: {
+        /**
+         * @desc 鏌ヨ骞村害璁″垝鍒楄〃
+         */
+        async getYearPlanList() {
+            this.yearLoading = true
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: yearPlanListApi,
+                params: {
+                    current: this.yearPage.curent,
+                    size: this.yearPage.pageSize,
+                    organizationPerson: this.yearForm.organizationPerson
+                }
+            })
+            if (code == 200) {
+                this.yearTableData = data.records
+                this.yearPage.total = data.total
+              if (this.yearTableData.length > 0) {
+                this.rowClick(this.yearTableData[0])
+              }
+            }
+            this.yearLoading = false
+        },
+        // 骞磋鍒掑垎椤�
+        handleYearCurrent(page) {
+            this.yearPage.curent = page
+            this.getYearPlanList()
+        },
+        handleYearSizeChange(size) {
+            this.yearPage.pageSize = size
+            this.getYearPlanList()
+        },
+        // 骞村害璁″垝琛ㄦ牸锛岀偣鍑昏鏁版嵁鍚庡埛鏂拌鎯�
+        rowClick(row) {
+          const now = new Date();
+          const currentYear = now.getFullYear();
+          if (row.createTime.slice(0,4) == currentYear) {
+            this.isOperation = true;
+          } else {
+            this.isOperation = false;
+          }
+            this.planId = row.id
+            this.getYearDetailPlanList()
+        },
+        // 鏂板|缂栬緫瀹屾垚鍚庡仛浠�涔�
+        handleForm() {
+            this.getYearDetailPlanList()
+        },
+        // 娓呴櫎骞�
+        clearYear() {
+            this.$refs.yearTable.setCurrent()
+            this.yearForm.organizationPerson = undefined
+            this.getYearPlanList()
+        },
+        // 娓呴櫎鏄庣粏
+        clearDetail() {
+            this.yearDetailForm.date = undefined
+            this.yearDetailForm.project = undefined
+            this.getYearDetailPlanList()
+        },
+
+        /**
+         * @desc 鏌ヨ骞村害璁″垝鏄庣粏
+         */
+        async getYearDetailPlanList() {
+            this.yearDetailLoading = true
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: yearDetailPlanListApi,
+                params: {
+                    planId: this.planId,
+                    current: this.yearDeatilPage.curent,
+                    size: this.yearDeatilPage.pageSize,
+                    date: this.yearDetailForm.date,
+                    project: this.yearDetailForm.project
+                }
+            })
+            if (code == 200) {
+                this.yearDetailTableData = data.records
+                this.yearDeatilPage.total = data.total
+            }
+            this.yearDetailLoading = false
+        },
+        showDialog(operationType,row, type = false) {
+          if (operationType === 'add') {
+            if (!this.planId) {
+              this.$message.warning('璇烽�夋嫨涓�鏉¤鍒掕繘琛屾柊澧�')
+              return
+            }
+          }
+          this.$refs.planModal.showDialog({planId:this.planId,...row}, type)
+        },
+
+
+
+        // 骞存槑缁嗚鍒掑垎椤�
+        handleYearDetailCurrent(page) {
+            this.yearDeatilPage.curent = page
+            this.getYearDetailPlanList()
+        },
+        handleYearDetailSizeChange(size) {
+            this.yearDeatilPage.pageSize = size
+            this.getYearDetailPlanList()
+        },
+        // 鍒犻櫎骞磋鍒�
+        delYearPlan(id) {
+            this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?', '鎻愮ず', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(async () => {
+                const { code } = await this.$axios({
+                    method: 'delete',
+                    url: delYearPlanApi,
+                    params: { id }
+                })
+                if (code == 200) {
+                    this.$message.success('鍒犻櫎鎴愬姛')
+                    this.getYearPlanList()
+                    this.getYearDetailPlanList()
+                } else {
+                    this.$message.error('鍒犻櫎澶辫触')
+                }
+            })
+        },
+        // 鍒犻櫎骞磋鍒掓槑缁�
+        delYearPlanDetail(id) {
+            this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?', '鎻愮ず', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(async () => {
+                const { code } = await this.$axios({
+                    method: 'delete',
+                    url: delYearPlanDetailApi,
+                    params: { id }
+                })
+                if (code == 200) {
+                    this.$message.success('鍒犻櫎鎴愬姛')
+                    this.getYearDetailPlanList()
+                } else {
+                    this.$message.error('鍒犻櫎澶辫触')
+                }
+            })
+        },
+        // 鎵瑰噯骞村害璁″垝
+        approvalYearPlan(row) {
+            this.$confirm('纭鎵瑰噯璇ュ勾搴﹁鍒�?', '鎻愮ず', {
+                confirmButtonText: '鎵瑰噯',
+                cancelButtonText: '涓嶆壒鍑�',
+                type: 'info'
+            }).then(() => {
+                this.approvalYearPlanFun(1, row.id)
+            }).catch(action => {
+              this.approvalYearPlanFun(0, row.id)
+            })
+        },
+      // 骞村害璁″垝琛�-涓嬭浇
+      downLoadPost(row) {
+        this.$axios.get(exportSuperVisePlanApi + '?id=' + row.id,{responseType: "blob"}).then(res => {
+          this.outLoading = false
+          this.$message.success('瀵煎嚭鎴愬姛')
+          const blob = new Blob([res],{ type: 'application/msword' });
+          const url = URL.createObjectURL(blob);
+          const link = document.createElement('a');
+          link.href = url;
+          link.download = row.fileName + '.docx';
+          link.click();
+        })
+      },
+      async approvalYearPlanFun(approvalStatus, rowId) {
+        const { code } = await this.$axios({
+          method: 'get',
+          url: yearPlanDetailApprovalApi,
+          params: {
+            id: rowId,
+            approvalStatus: approvalStatus
+          },
+        })
+        if (code == 200) {
+          this.$message.success('鎿嶄綔鎴愬姛锛�')
+          this.getYearPlanList()
+        } else {
+          this.$message.error('鎿嶄綔鎴愬姛锛�')
+        }
+      }
+    }
+}
+</script>
+<style scoped>
+.flex_column {
+    display: flex;
+    height: 80vh;
+    flex-direction: column;
+    overflow: auto;
+    justify-content: space-between;
+}
+
+.pagination {
+    display: flex;
+    justify-content: space-between
+}
+
+.items_center {
+    display: flex;
+    align-items: center;
+}
+
+.date_box {
+    margin: 0 5px;
+}
+
+.search {
+    width: 150px;
+    padding: 0 16px;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Records/Add.vue b/src/components/caorui/Department/components/Records/Add.vue
new file mode 100644
index 0000000..adbbb8a
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/Add.vue
@@ -0,0 +1,243 @@
+<template>
+    <div class="add">
+        <el-dialog
+            :isEdit="isEdit"
+            :title="isEdit ? '缂栬緫宸ヤ綔鐩戠潱璁板綍':'鏂板宸ヤ綔鐩戠潱璁板綍'"
+            :visible.sync="dialogVisible"
+            width="800"
+        >
+            <el-steps v-if="isEdit" :active="active" :align-center="true" finish-status="success">
+                <el-step style="cursor: pointer;" title="妫�娴�" @click.native="setStep(0)"></el-step>
+                <el-step style="cursor: pointer;" title="瀹℃壒" @click.native="setStep(1)"></el-step>
+            </el-steps>
+            <SuperviseForm
+                v-show="pageStatus == 0"
+                ref="superviseFormRef"
+                :disabled="active != 0"
+                :isEdit="isEdit"
+                :superviseForm.sync="mainForm.superviseForm"
+                :userList="userList"
+                @addData="addData"
+                @close="closeDialog"
+                @submit="submit"
+            ></SuperviseForm>
+            <ApproveForm
+                v-show="pageStatus == 1"
+                ref="approveFormRef"
+                :approveForm.sync="mainForm.approveForm"
+                :disabled="active != 1"
+                :isEdit="isEdit"
+                :userList="userList"
+                @close="toClose"
+                @submit="submit"
+            ></ApproveForm>
+            <el-result v-show="pageStatus == 2" icon="success" subTitle="澶勭悊瀹屾垚" title="瀹℃牳瀹屾垚">
+            </el-result>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import SuperviseForm from './supervise/SuperviseForm.vue'
+import ApproveForm from './supervise/ApproveForm.vue'
+import {
+    getUserListApi,
+    addOrUpdatePersonSupervisionRecord
+} from "../../../../../assets/api/api"
+import dayjs from 'dayjs'
+
+export default {
+    components: {
+        SuperviseForm,
+        ApproveForm
+    },
+    data() {
+        return {
+            active: 0,
+            pageStatus: 0,
+            isEdit: false,
+            dialogVisible: false,
+            userList: [],
+            id: undefined,
+            mainForm: {
+                superviseForm: {
+                    testerId: undefined,
+                    supervisorId: undefined,
+                    testItem: undefined,
+                    sampleNumber: undefined,
+                    detectionDate: undefined,
+                    personnel: [],
+                    instrumentEquipment: undefined,
+                    workingEnvironment: undefined,
+                    sampleCollection: undefined,
+                    samplePreparation: undefined,
+                    testMethod: undefined,
+                    testingRecords: undefined,
+                    testReport: undefined,
+                    evaluationSupervisionSituation: undefined,
+                    doNotMeetTheHandlingOpinions: undefined,
+                },
+                approveForm: {
+                    technicalDirector: undefined
+                }
+            }
+        }
+    },
+    methods: {
+        async openDialog(row, type=false) {
+            this.dialogVisible = true
+            this.isEdit = type
+            await this.getUserList()
+            if(this.isEdit) {
+                // 缂栬緫
+                this.loadForm(row)
+                this.id = row.id
+            } else {
+                // 鏂板
+                this.resetForm(row)
+                this.id = undefined
+            }
+        },
+        /**
+         * @desc 鍔犺浇琛ㄥ崟
+         */
+         loadForm(row) {
+            if(row.currentState) {
+                this.active = Number(row.currentState)
+                this.pageStatus = Number(row.currentState === '2' ? 0 : row.currentState)
+            }
+            // 绗�1姝�
+            this.mainForm.superviseForm.testerId = row.testerId
+            this.mainForm.superviseForm.supervisorId = row.supervisorId
+            this.mainForm.superviseForm.testItem = row.testItem
+            this.mainForm.superviseForm.sampleNumber = row.sampleNumber
+            this.mainForm.superviseForm.detectionDate = row.detectionDate
+            let personList = row.personnel.split(',')
+            this.mainForm.superviseForm.personnel = personList.map(item => {
+                return Number(item)
+            });
+            this.mainForm.superviseForm.instrumentEquipment = row.instrumentEquipment
+            this.mainForm.superviseForm.workingEnvironment = row.workingEnvironment
+            this.mainForm.superviseForm.sampleCollection = row.sampleCollection
+            this.mainForm.superviseForm.samplePreparation = row.samplePreparation
+            this.mainForm.superviseForm.testMethod = row.testMethod
+            this.mainForm.superviseForm.testingRecords = row.testingRecords
+            this.mainForm.superviseForm.testReport = row.testReport
+            this.mainForm.superviseForm.evaluationSupervisionSituation = row.evaluationSupervisionSituation
+            this.mainForm.superviseForm.doNotMeetTheHandlingOpinions = row.doNotMeetTheHandlingOpinions
+            // 绗�2姝�
+            this.mainForm.approveForm.technicalDirector = row.technicalDirector
+        },
+        /**
+         * @desc 閲嶇疆琛ㄥ崟
+         */
+         resetForm(row) {
+            console.log(row)
+            this.active = 0
+            this.pageStatus = 0
+            // 绗�1涓�
+            this.mainForm.superviseForm.currentState = undefined
+            this.mainForm.superviseForm.testerId = undefined
+            this.mainForm.superviseForm.supervisorId = undefined
+            this.mainForm.superviseForm.testItem = undefined
+            this.mainForm.superviseForm.sampleNumber = undefined
+            this.mainForm.superviseForm.detectionDate = undefined
+            this.mainForm.superviseForm.personnel = [row.departId]
+            this.mainForm.superviseForm.instrumentEquipment = undefined
+            this.mainForm.superviseForm.workingEnvironment = undefined
+            this.mainForm.superviseForm.sampleCollection = undefined
+            this.mainForm.superviseForm.samplePreparation = undefined
+            this.mainForm.superviseForm.testMethod = undefined
+            this.mainForm.superviseForm.testingRecords = undefined
+            this.mainForm.superviseForm.testReport = undefined
+            this.mainForm.superviseForm.evaluationSupervisionSituation = undefined
+            this.mainForm.superviseForm.doNotMeetTheHandlingOpinions = undefined
+            // 绗�2涓�
+            this.mainForm.approveForm.technicalDirector = undefined
+        },
+        closeDialog() {
+            this.dialogVisible = false
+        },
+        /**
+         * @desc 鑾峰彇鐢ㄦ埛淇℃伅
+         */
+        async getUserList() {
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: getUserListApi,
+            })
+            if(code == 200) {
+                this.userList = data
+            }
+        },
+        /**
+         * @desc 椹冲洖
+         */
+        toClose() {
+            this.submitFormApi({
+                id: this.id,
+                currentState: 0,
+            })
+        },
+        /**
+         * @desc 鏂板
+         */
+        addData(step) {
+            let data = this.setParams(step)
+            this.submitFormApi(data)
+        },
+        /**
+         * @desc 缂栬緫
+         */
+        submit(step) {
+            console.log('缂栬緫', this.isEdit)
+            let data = this.setParams(step)
+            data.id = this.id
+            this.submitFormApi(data)
+        },
+        // 璁剧疆鍙傛暟
+        setParams(step) {
+            if(step == 1) {
+                let result = this.mainForm.superviseForm
+                result.currentState = this.active + 1
+                result.personnel = result.personnel.join(",")
+                result.technicalDirectorDate = dayjs().format('YYYY-MM-DD HH:mm:ss')
+                return result
+            }
+            if(step == 2) {
+                let result = this.mainForm.approveForm
+                result.currentState = this.active + 1
+                return result
+            }
+        },
+        // 鍚戞湇鍔″櫒鍙戦�佽〃鍗�
+        async submitFormApi(data) {
+            console.log('鎺ュ彛琛ㄥ崟', data)
+            const { code } = await this.$axios({
+                method: 'post',
+                url: addOrUpdatePersonSupervisionRecord,
+                data: data,
+                noQs: true
+            })
+            if(code == 200) {
+                this.$message.success('鎿嶄綔鎴愬姛')
+                this.dialogVisible = false
+                this.$emit('submit')
+            }
+        },
+        setStep(e) {
+            this.pageStatus = e
+        }
+    }
+}
+</script>
+<style scoped>
+.foot {
+    width: 100%;
+}
+.add >>> .el-dialog__footer {
+    padding-right: 20px;
+}
+.main_right {
+    text-align: left;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Records/control/Step/ConditionForm.vue b/src/components/caorui/Department/components/Records/control/Step/ConditionForm.vue
new file mode 100644
index 0000000..53833d8
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/control/Step/ConditionForm.vue
@@ -0,0 +1,164 @@
+<template>
+    <el-form
+        label-width="160px"
+        :model="form"
+        :disabled="disabled"
+        style="position: relative;"
+        size="small"
+    >
+        <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+            <el-form-item label="閮ㄩ棬璐熻矗浜�">
+                <el-select
+                    v-model="form.departmentHeadId" 
+                    placeholder="璇烽�夋嫨"
+                    style="width: 100%"
+                >
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="琚洃鐫d汉">
+                <el-select
+                    v-model="form.supervisedPersonId" 
+                    placeholder="璇烽�夋嫨"
+                    style="width: 100%"
+                >
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="涓嶇鍚堝伐浣滃彂鐜伴�斿緞">
+                <el-checkbox-group 
+                    v-model="form.discoveryApproach"
+                >
+                    <el-checkbox
+                        v-for="(item, index) in checkbox"
+                        :key="index"
+                        :label="item.value" 
+                        name="type"
+                    >{{ item.label }}
+                    </el-checkbox>
+                </el-checkbox-group>
+            </el-form-item>
+            <el-form-item label="涓嶇鍚堝伐浣滅殑璇︾粏璁板綍">
+                <el-input
+                    v-model="form.notConformDetails"
+                    type="textarea"
+                    :rows="2"
+                    placeholder="璇疯緭鍏ュ唴瀹�"
+                ></el-input>
+            </el-form-item>
+            <el-form-item label="涓嶇鍚堢殑渚濇嵁鍙婃潯娆惧彿">
+                <el-input 
+                    v-model="form.nonConformityClause"
+                    type="textarea"
+                    :rows="2"
+                    placeholder="璇疯緭鍏ュ唴瀹�"
+                ></el-input>
+            </el-form-item>
+        </el-card>
+        <el-form-item label-width="0">
+            <div style=" display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+                <div>
+                    鎿嶄綔浜猴細{{ currentResponsible }}
+                </div>
+                <div v-if="step == 0 || step == 1">
+                    <el-button v-if="step == 1" :disabled="false" @click="cancel">椹冲洖</el-button>
+                    <el-button :disabled="false" @click="save">淇濆瓨</el-button>
+                    <el-button type="primary" @click="onSubmit" :disabled="false">鎻愪氦</el-button>
+                </div>
+            </div>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        },
+        userList: {
+            type: Array,
+            default: () => {
+                return []
+            }
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        condiForm: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.condiForm
+            },
+            set(val) {
+                this.$emit('update:condiForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+            checkbox: [
+                {
+                    label: '绠$悊璇勫',
+                    value: 0
+                }, {
+                    label: '鍐呴儴瀹℃牳',
+                    value: 1
+                }, {
+                    label: '妫�娴嬭繃绋嬫帶鍒�',
+                    value: 2
+                }, {
+                    label: '鍐呴儴璐ㄩ噺鎺у埗',
+                    value: 3
+                }, {
+                    label: '鍐呴儴鐩戠潱',
+                    value: 4
+                }, {
+                    label: '澶栭儴璇勫/妫�鏌�',
+                    value: 5
+                }, {
+                    label: '椤惧鎶曡瘔/鎰忚鍙嶉',
+                    value: 6
+                }, {
+                    label: '鍏朵粬',
+                    value: 7
+                }
+            ],
+        }
+    },
+    methods: {
+        onSubmit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/control/Step/Inform.vue b/src/components/caorui/Department/components/Records/control/Step/Inform.vue
new file mode 100644
index 0000000..a5d02f1
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/control/Step/Inform.vue
@@ -0,0 +1,99 @@
+<template>
+    <el-form 
+        :model="form" 
+        label-width="160px"
+        style="position: relative"
+        :disabled="disabled"
+        size="small"
+    >
+        <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+            <el-form-item label="閫氱煡瀹㈡埛">
+                <el-radio-group v-model="form.whetherInformCustomer">
+                    <el-radio :label="1">鏄�</el-radio>
+                    <el-radio :label="2">鍚�</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            <el-form-item label="鎭㈠宸ヤ綔">
+                <el-radio-group v-model="form.whetherResumeWork">
+                    <el-radio :label="1">鏄�</el-radio>
+                    <el-radio :label="2">鍚�</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            <el-form-item label="璐ㄩ噺璐熻矗浜�">
+                <el-select  v-model="form.qualitySupervisorId" placeholder="璇烽�夋嫨">
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+        </el-card>
+        <el-form-item label-width="0">
+            <div style=" display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+                <div>
+                    鎿嶄綔浜猴細{{ currentResponsible }}
+                </div>
+                <div v-if="step == 4" >
+                    <el-button @click="cancel">椹冲洖</el-button>
+                    <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+                </div>
+            </div>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        },
+        userList: {
+            type: Array,
+            default: []
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        inform: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.inform
+            },
+            set(val) {
+                this.$emit('update:inform', val)
+            }
+        }
+    },
+    data() {
+        return {
+           
+        }
+    },
+    methods: {
+        onSubmit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/control/Step/MeasureForm.vue b/src/components/caorui/Department/components/Records/control/Step/MeasureForm.vue
new file mode 100644
index 0000000..7218408
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/control/Step/MeasureForm.vue
@@ -0,0 +1,94 @@
+<template>
+    <el-form
+        :model="form"
+        label-width="200px"
+        style="position: relative;"
+        :disabled="disabled"
+        size="small"
+    >
+        <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+            <el-form-item label="璐d换閮ㄩ棬">
+                <el-select v-model="form.responsibleDepartmentPersonId" placeholder="璇烽�夋嫨">
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="娑堥櫎涓嶇鍚堝伐浣滄墍閲囧彇鐨勬帾鏂�">
+                <el-input 
+                    v-model="form.treatmentMeasures"
+                    type="textarea"
+                    :rows="2"
+                    placeholder="璇疯緭鍏ュ唴瀹�"
+                ></el-input>
+            </el-form-item>
+        </el-card>
+        <el-form-item v-if="step == 2" label-width="0px" :disabled="disabled">
+            <div style=" display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+                <div>
+                    鎿嶄綔浜猴細{{ currentResponsible }}
+                </div>
+                <div>
+                    <el-button @click="cancel">椹冲洖</el-button>
+                    <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+                </div>
+            </div>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        },
+        userList: {
+            type: Array,
+            default: []
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        handleForm: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.handleForm
+            },
+            set(val) {
+                this.$emit('update:handleForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+        }
+    },
+    methods: {
+        onSubmit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/control/Step/RectifyForm.vue b/src/components/caorui/Department/components/Records/control/Step/RectifyForm.vue
new file mode 100644
index 0000000..5683cc4
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/control/Step/RectifyForm.vue
@@ -0,0 +1,98 @@
+<template>
+    <el-form
+        :model="form"
+        label-width="160px"
+        style="position: relative"
+        :disabled="disabled"
+        size="small"
+    >
+        <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+            <el-form-item label="鏄惁闇�瑕侀噰鍙栫籂姝f帾鏂�">
+                <el-radio-group v-model="form.correctiveMeasure">
+                    <el-radio :label="1">鏄�</el-radio>
+                    <el-radio :label="2">鍚�</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            <el-form-item label="绾犳鎺柦澶勭悊鍗曡窡韪�">
+                <el-radio-group v-model="form.correctiveMeasureFollowTracks">
+                    <el-radio :label="1">鏄�</el-radio>
+                    <el-radio :label="2">鍚�</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            <el-form-item label="鎶�鏈礋璐d汉">
+                <el-select v-model="form.correctiveMeasurePersonId" placeholder="璇烽�夋嫨">
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+        </el-card>
+        <el-form-item label-width="0">
+            <div style=" display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+                <div>
+                    鎿嶄綔浜猴細{{ currentResponsible }}
+                </div>
+                <div v-if="step == 3">
+                    <el-button @click="cancel">椹冲洖</el-button>
+                    <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+                </div>
+            </div>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        },
+        userList: {
+            type: Array,
+            default: []
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        rectifyForm: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.rectifyForm
+            },
+            set(val) {
+                this.$emit('update:rectifyForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+        }
+    },
+    methods: {
+        onSubmit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/control/index.vue b/src/components/caorui/Department/components/Records/control/index.vue
new file mode 100644
index 0000000..3a934e4
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/control/index.vue
@@ -0,0 +1,331 @@
+<template>
+    <div>
+        <el-dialog
+            :visible.sync="dialogVisible"
+            title="涓嶇鍚堝伐浣滄帶鍒跺崟"
+        >
+            <el-steps :active="active" :align-center="true" finish-status="success">
+                <el-step
+                    v-for="(item, index) in stepList"
+                    :key="index"
+                    :title="item.label"
+                    style="cursor: pointer;"
+                    @click.native="setStep(item.value)"
+                ></el-step>
+            </el-steps>
+            <el-divider></el-divider>
+                <ConditionForm
+                    v-if="pageStatus == 0"
+                    :condiForm.sync="mainForm.condiForm"
+                    :currentResponsible="currentResponsible"
+                    :disabled="active != 0"
+                    :step="active"
+                    :userList="userList"
+                    @nextStep="submit"
+                ></ConditionForm>
+                <ConditionForm
+                    v-if="pageStatus == 1"
+                    :condiForm.sync="mainForm.condiForm"
+                    :currentResponsible="currentResponsible"
+                    :disabled="true"
+                    :step="active"
+                    :userList="userList"
+                    @cancel="cancel"
+                    @nextStep="submit"
+                ></ConditionForm>
+                <MeasureForm
+                    v-if="pageStatus == 2"
+                    :currentResponsible="currentResponsible"
+                    :disabled="active != 2"
+                    :handleForm.sync="mainForm.handleForm"
+                    :step="active"
+                    :userList="userList"
+                    @cancel="cancel"
+                    @nextStep="submit"
+                ></MeasureForm>
+                <RectifyForm
+                    v-if="pageStatus == 3"
+                    :currentResponsible="currentResponsible"
+                    :disabled="active != 3"
+                    :rectifyForm.sync="mainForm.rectifyForm"
+                    :step="active"
+                    :userList="userList"
+                    @cancel="cancel"
+                    @nextStep="submit"
+                ></RectifyForm>
+                <Inform
+                    v-if="pageStatus == 4"
+                    :disabled="active != 4"
+                    :inform.sync="mainForm.inform"
+                    :step="active"
+                    :userList="userList"
+                    @cancel="cancel"
+                    @nextStep="submit"
+                ></Inform>
+                <el-result v-if="pageStatus == 5" icon="success" subTitle="澶勭悊瀹屾垚" title="瀹℃牳瀹屾垚">
+                </el-result>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import ConditionForm from './Step/ConditionForm.vue'
+import MeasureForm from './Step/MeasureForm.vue'
+import RectifyForm from './Step/RectifyForm.vue'
+import Inform from './Step/Inform.vue'
+import {
+    personSupervisionControlSheetPage,
+    getUserListApi,
+    addOrUpdatePersonSupervisionControl
+} from "../../../../../../assets/api/api"
+
+export default {
+    components: {
+        ConditionForm, MeasureForm, RectifyForm, Inform
+    },
+    data() {
+        return {
+            active: 0,
+            pageStatus: 0,
+            dialogVisible: false,
+            currentResponsible: undefined,
+            stepList: [{
+                    label: '宸ヤ綔鎯呭喌',
+                    value: 0
+                }, {
+                    label: '琚洃鐫d汉纭',
+                    value: 1
+                }, {
+                    label: '澶勭悊鎺柦',
+                    value: 2
+                }, {
+                    label: '绾犳鎺柦',
+                    value: 3
+                }, {
+                    label: '閫氱煡瀹㈡埛',
+                    value: 4
+                }
+            ],
+            supervisionRecordId: undefined,
+            controlId: undefined,
+            mainForm: {
+                condiForm: {
+                    departmentHeadId: undefined,
+                    supervisedPersonId: undefined,
+                    discoveryApproach: [],
+                    notConformDetails: undefined,
+                    nonConformityClause: undefined,
+                },
+                handleForm: {
+                    responsibleDepartmentPersonId: undefined,
+                    treatmentMeasures: undefined
+                },
+                rectifyForm: {
+                    correctiveMeasure: undefined,
+                    correctiveMeasureFollowTracks: undefined,
+                    correctiveMeasurePersonId: undefined
+                },
+                inform: {
+                    whetherInformCustomer: undefined,
+                    whetherResumeWork: undefined,
+                    qualitySupervisorId: undefined
+                }
+            },
+            userList: [],
+            controlType: undefined
+        }
+    },
+    methods: {
+        /**
+         * @desc 鍒濆鍖栬〃鍗�
+         */
+        initForm() {
+            this.mainForm.condiForm.departmentHeadId = undefined
+            this.mainForm.condiForm.supervisedPersonId = undefined
+            this.mainForm.condiForm.discoveryApproach = []
+            this.mainForm.condiForm.notConformDetails = undefined
+            this.mainForm.condiForm.nonConformityClause = undefined
+            this.mainForm.handleForm.responsibleDepartmentPersonId = undefined
+            this.mainForm.handleForm.treatmentMeasures = undefined
+            this.mainForm.rectifyForm.correctiveMeasure = undefined
+            this.mainForm.rectifyForm.correctiveMeasureFollowTracks = undefined
+            this.mainForm.rectifyForm.correctiveMeasurePersonId = undefined
+            this.mainForm.inform.whetherInformCustomer = undefined
+            this.mainForm.inform.whetherResumeWork = undefined
+            this.mainForm.inform.qualitySupervisorId = undefined
+        },
+        /**
+         * @desc 鎵撳紑妯℃�佹
+         * @param {鐩戠潱璁板綍id} id
+         */
+        openDialog(id) {
+            this.dialogVisible = true
+            this.getUserList()
+            this.getControlData(id)
+        },
+        /**
+         * @desc 鑾峰彇鐢ㄦ埛淇℃伅
+         */
+         async getUserList() {
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: getUserListApi,
+            })
+            if(code == 200) {
+                this.userList = data
+            }
+        },
+        /**
+         * @desc 鏌ヨ鐩戠潱璁板綍鎺у埗鍗�
+         * @param {鐩戠潱璁板綍id} id
+         */
+        async getControlData(id) {
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: personSupervisionControlSheetPage,
+                params: {id}
+            })
+            if(code == 202) {
+                this.controlType = '鏂板'
+                this.supervisionRecordId = id
+                this.active = 0
+                this.pageStatus = 0
+                this.controlId = undefined
+                this.initForm()
+            }
+            if(code == 200) {
+                this.currentResponsible = data.currentResponsible
+                this.controlType = '缂栬緫'
+                this.controlId = data.id
+                this.active = Number(data.currentState)
+                this.pageStatus = Number(data.currentState === 4 ? 0 : data.currentState)
+                // 绗�1銆�2姝ユ暟鎹�
+                this.mainForm.condiForm.departmentHeadId = data.departmentHeadId
+                this.mainForm.condiForm.supervisedPersonId = data.supervisedPersonId
+                this.mainForm.condiForm.notConformDetails = data.notConformDetails
+                this.mainForm.condiForm.nonConformityClause = data.nonConformityClause
+                // 绗�3姝ユ暟鎹�
+                this.mainForm.handleForm.responsibleDepartmentPersonId = data.responsibleDepartmentPersonId
+                this.mainForm.handleForm.treatmentMeasures = data.treatmentMeasures
+                // 绗�4姝ユ暟鎹�
+                this.mainForm.rectifyForm.correctiveMeasure = data.correctiveMeasure
+                this.mainForm.rectifyForm.correctiveMeasureFollowTracks = data.correctiveMeasureFollowTracks
+                this.mainForm.rectifyForm.correctiveMeasurePersonId = data.correctiveMeasurePersonId
+                // 绗�5姝ユ暟鎹�
+                this.mainForm.whetherInformCustomer = data.whetherInformCustomer
+                this.mainForm.whetherResumeWork = data.whetherResumeWork
+                this.mainForm.qualitySupervisorId = data.qualitySupervisorId
+                this.supervisionRecordId = data.supervisionRecordId
+            }
+        },
+        submit(type) {
+            let currentState = undefined
+            if(type == 'submit') {
+                currentState = this.active + 1
+            } else if(type == 'save') {
+                currentState = undefined
+            }
+            if(this.active == 0) {
+                let { discoveryApproach, ...condiFormRest } = this.mainForm.condiForm
+                let approcahStr = discoveryApproach.join(',')
+                this.submitForm({
+                    id: this.controlId,
+                    supervisionRecordId: this.supervisionRecordId,
+                    discoveryApproach: approcahStr,
+                    currentState: currentState,
+                  discovererDate: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
+                    ...condiFormRest
+                })
+            }
+            if(this.active == 1) {
+                let { discoveryApproach, ...condiFormRest } = this.mainForm.condiForm
+                let approcahStr = discoveryApproach.join(',')
+                this.submitForm({
+                    id: this.controlId,
+                    supervisionRecordId: this.supervisionRecordId,
+                    discoveryApproach: approcahStr,
+                    currentState: currentState,
+                  supervisedPersonDate: this.$moment().format('YYYY-MM-DD'),
+                    ...condiFormRest
+                })
+            }
+            if(this.active == 2) {
+                let { handleForm } = this.mainForm
+                this.submitForm({
+                    id: this.controlId,
+                    supervisionRecordId: this.supervisionRecordId,
+                    currentState: currentState,
+                  responsibleDepartmentDate: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
+                    ...handleForm
+                })
+            }
+            if(this.active == 3) {
+                let { rectifyForm } = this.mainForm
+                this.submitForm({
+                    id: this.controlId,
+                    supervisionRecordId: this.supervisionRecordId,
+                    currentState: currentState,
+                  correctiveMeasureDate: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
+                    ...rectifyForm
+                })
+            }
+            if(this.active == 4) {
+                let { inform } = this.mainForm
+                this.submitForm({
+                    id: this.controlId,
+                    supervisionRecordId: this.supervisionRecordId,
+                    currentState: currentState,
+                  qualitySupervisorDate: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
+                    ...inform
+                })
+            }
+        },
+        /**
+         * @desc 鎻愪氦琛ㄥ崟
+         */
+        async submitForm(form) {
+            let user = JSON.parse(localStorage.getItem('user'));
+            const { code } = await this.$axios({
+                method: 'post',
+                url: addOrUpdatePersonSupervisionControl,
+                data: {
+                    currentResponsible: user.name,
+                    ...form
+                },
+                noQs: true
+            })
+            if(this.controlType == '鏂板') {
+                if(code == 200) {
+                    this.$message.success('鎻愪氦鎴愬姛')
+                }
+            } else if(this.controlType == '缂栬緫') {
+                if(code == 200) {
+                    this.$message.success('鎻愪氦鎴愬姛')
+                }
+            }
+            this.dialogVisible = false
+        },
+        /**
+         * @desc 椹冲洖
+         */
+        cancel() {
+            let currentState = this.active - 1
+            this.submitForm({
+                id: this.controlId,
+                supervisionRecordId: this.supervisionRecordId,
+                currentState: currentState,
+            })
+        },
+        setStep(e) {
+            this.pageStatus = e
+        }
+    }
+}
+</script>
+<style scoped>
+.dialog-footer {
+    width: 100%;
+}
+>>> .el-dialog__footer {
+    padding-right: 20px;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Records/dispose/Step/Fact.vue b/src/components/caorui/Department/components/Records/dispose/Step/Fact.vue
new file mode 100644
index 0000000..6145044
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/dispose/Step/Fact.vue
@@ -0,0 +1,99 @@
+<template>
+    <el-form 
+        :model="form" 
+        :disabled="disabled"
+        label-width="140px"
+        size="small"
+        style="position: relative"
+    >
+        <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+            <el-form-item label="鎻愬嚭閮ㄩ棬">
+                <el-select
+                    v-model="form.proposingDepartmentPersonId" 
+                    placeholder="璇烽�夋嫨"
+                    style="width: 100%"
+                >
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="涓嶅悎鏍兼垨鍋忕鎻忚堪">
+                <el-input type="textarea"
+                    v-model="form.descriptionNonconformity"
+                    :rows="2"
+                    placeholder="璇疯緭鍏ュ唴瀹�"
+                >
+                </el-input>
+            </el-form-item>
+        </el-card>
+        <el-form-item label-width="0">
+            <div style="display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+                <div>
+                    鎿嶄綔浜猴細{{ currentResponsible }}
+                </div>
+                <div v-if="step == 0">
+                    <el-button :disabled="false" @click="cancel">椹冲洖</el-button>
+                    <el-button @click="save">淇濆瓨</el-button>
+                    <el-button type="primary" @click="submit">鎻愪氦</el-button>
+                </div>
+            </div>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        factForm: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+        userList: {
+            type: Array,
+            default: []
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.factForm
+            },
+            set(val) {
+                this.$emit('update:factForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+        }
+    },
+    methods: {
+        submit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/dispose/Step/Measure.vue b/src/components/caorui/Department/components/Records/dispose/Step/Measure.vue
new file mode 100644
index 0000000..4177555
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/dispose/Step/Measure.vue
@@ -0,0 +1,101 @@
+<template>
+    <el-form 
+        :model="form"
+        :disabled="disabled"
+        label-width="130px" 
+        size="small"
+        style="position: relative"
+    >
+        <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+            <el-form-item label="璐d换浜�">
+                <el-select v-model="form.correctiveActionId" placeholder="璇烽�夋嫨">
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+          <el-form-item label="绾犳鎺柦">
+            <el-input type="textarea"
+                      v-model="form.correctiveMeasure"
+                      :rows="2"
+                      placeholder="璇疯緭鍏ュ唴瀹�"
+            >
+            </el-input>
+          </el-form-item>
+            <el-form-item label="鎻愬嚭瑕佹眰閮ㄩ棬纭">
+              <el-input type="textarea"
+                        v-model="form.requestDepartmentConfirmation"
+                        :rows="2"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+              >
+              </el-input>
+            </el-form-item>
+        </el-card>
+        <el-form-item label-width="0">
+            <div style="display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+                <div>
+                    鎿嶄綔浜猴細{{ currentResponsible }}
+                </div>
+                <div v-if="step == 2">
+                    <el-button :disabled="false" @click="cancel">椹冲洖</el-button>
+                    <el-button type="primary" @click="submit">鎻愪氦</el-button>
+                </div>
+            </div>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        measureForm: {
+            type: Object,
+            default: {}
+        },
+        userList: {
+            type: Array,
+            default: []
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.measureForm
+            },
+            set(val) {
+                this.$emit('update:measureForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+           
+        }
+    },
+    methods: {
+        submit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/dispose/Step/Reason.vue b/src/components/caorui/Department/components/Records/dispose/Step/Reason.vue
new file mode 100644
index 0000000..17426c5
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/dispose/Step/Reason.vue
@@ -0,0 +1,97 @@
+<template>
+    <el-form 
+        :model="form" 
+        :disabled="disabled"
+        label-width="140px"
+        size="small"
+        style="position: relative;"
+    >
+        <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+            <el-form-item label="璐d换閮ㄩ棬">
+                <el-select
+                    v-model="form.causeAnalysisPersonId" 
+                    placeholder="璇烽�夋嫨"
+                    style="width: 100%"
+                >
+                    <el-option
+                        v-for="(item, index) in userList"
+                        :key="index"
+                        :label="item.name"
+                        :value="item.id"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="鍘熷洜鍒嗘瀽">
+                <el-input type="textarea"
+                    v-model="form.causeAnalysis"
+                    :rows="2"
+                    placeholder="璇疯緭鍏ュ唴瀹�"
+                >
+                </el-input>
+            </el-form-item>
+        </el-card>
+        <el-form-item label-width="0">
+            <div style="display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+                <div>
+                    <span>鎿嶄綔浜猴細{{ currentResponsible }}</span>
+                </div>
+                <div v-if="step == 1">
+                    <el-button :disabled="false" @click="cancel">椹冲洖</el-button>
+                    <el-button type="primary" @click="submit">鎻愪氦</el-button>
+                </div>
+            </div>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        userList: {
+            type: Array,
+            default: []
+        },
+        reasonForm: {
+            type: Object,
+            default: {}
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.reasonForm
+            },
+            set(val) {
+                this.$emit('update:reasonForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+            
+        }
+    },
+    methods: {
+        submit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/dispose/Step/Result.vue b/src/components/caorui/Department/components/Records/dispose/Step/Result.vue
new file mode 100644
index 0000000..3d8d4d6
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/dispose/Step/Result.vue
@@ -0,0 +1,98 @@
+<template>
+    <el-form 
+        :model="form"
+        :disabled="disabled"
+        label-width="130px" 
+        size="small"
+        style="position: relative"
+    >
+    <el-card :body-style="{ height: '350px', overflow: 'auto'}">
+        <el-form-item label="楠岃瘉閮ㄩ棬">
+            <el-select
+                v-model="form.verificationDepartmentPersonId" 
+                placeholder="璇烽�夋嫨"
+                style="width: 100%"
+            >
+                <el-option
+                    v-for="(item, index) in userList"
+                    :key="index"
+                    :label="item.name"
+                    :value="item.id"
+                ></el-option>
+            </el-select>
+        </el-form-item>
+        <el-form-item label="瀹炴柦楠岃瘉缁撴灉">
+            <el-input type="textarea"
+                v-model="form.implementationVerificationResults"
+                :rows="2"
+                placeholder="璇疯緭鍏ュ唴瀹�"
+            >
+            </el-input>
+        </el-form-item>
+    </el-card>
+    <el-form-item label-width="0">
+        <div style="display: flex; width: 100%; justify-content: space-between; margin-top: 15px;">
+            <div>
+                鎿嶄綔浜猴細{{ currentResponsible }}
+            </div>
+            <div v-if="step == 3">
+                <el-button :disabled="false" @click="cancel">椹冲洖</el-button>
+                <el-button type="primary" @click="submit">鎻愪氦</el-button>
+            </div>
+        </div>
+    </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        currentResponsible: {
+            type: String,
+            default: ''
+        },
+        resultForm: {
+            type: Object,
+            default: {}
+        },
+        step: {
+            type: Number,
+            default: 0
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        },
+        userList: {
+            type: Array,
+            default: []
+        },
+    },
+    computed: {
+        form: {
+            get() {
+                return this.resultForm
+            },
+            set(val) {
+                this.$emit('update:resultForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+           
+        }
+    },
+    methods: {
+        submit() {
+            this.$emit('nextStep', 'submit')
+        },
+        save() {
+            this.$emit('nextStep', 'save')
+        },
+        cancel() {
+            this.$emit('cancel', 'cancel')
+        }
+    }
+}
+</script>
+<style scoped></style>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/dispose/index.vue b/src/components/caorui/Department/components/Records/dispose/index.vue
new file mode 100644
index 0000000..4ed06b9
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/dispose/index.vue
@@ -0,0 +1,278 @@
+<template>
+    <div>
+        <el-dialog
+            title="绾犻敊澶勭悊鍗�"
+            :visible.sync="dialogVisible"
+        >
+            <el-steps
+                :active="active"
+                finish-status="success"
+                :align-center="true"
+            >
+                <el-step
+                    style="cursor: pointer;"
+                    v-for="(item, index) in stepList"
+                    :key="index"
+                    :title="item.label"
+                    @click.native="setStep(item.value)"
+                ></el-step>
+            </el-steps>
+            <el-divider></el-divider>
+            <Fact
+                v-if="pageStatus == 0"
+                :factForm.sync="mainForm.factForm"
+                :userList="userList"
+                :currentResponsible="currentResponsible"
+                :disabled="active != 0"
+                :step="active"
+                @nextStep="submit"
+                @cancel="cancel"
+            ></Fact>
+            <Reason
+                v-if="pageStatus == 1"
+                :reasonForm.sync="mainForm.reasonForm"
+                :userList="userList"
+                :currentResponsible="currentResponsible"
+                :disabled="active != 1"
+                :step="active"
+                @nextStep="submit"
+                @cancel="cancel"
+            ></Reason>
+            <Measure
+                v-if="pageStatus == 2"
+                :measureForm.sync="mainForm.measureForm"
+                :userList="userList"
+                :currentResponsible="currentResponsible"
+                :disabled="active != 2"
+                :step="active"
+                @nextStep="submit"
+                @cancel="cancel"
+            ></Measure>
+            <Result
+                v-if="pageStatus == 3"
+                :resultForm.sync="mainForm.resultForm"
+                :userList="userList"
+                :currentResponsible="currentResponsible"
+                :disabled="active != 3"
+                :step="active"
+                @nextStep="submit"
+                @cancel="cancel"
+            ></Result>
+            <!-- <div slot="footer" class="dialog-footer">
+                <el-button v-if="active == 4" type="primary" @click="submit(5)">瀹屾垚</el-button>
+            </div> -->
+        </el-dialog>
+    </div>
+</template>
+<script>
+import Fact from './Step/Fact.vue'
+import Reason from './Step/Reason.vue'
+import Measure from './Step/Measure.vue'
+import Result from './Step/Result.vue'
+import dayjs from 'dayjs'
+import {
+    getUserListApi,
+    personSupervisionProcessingPage,
+    addOrUpdatePersonnelServiceProcessing
+ } from '../../../../../../assets/api/api'
+
+export default {
+    components: {
+        Fact, Reason, Measure, Result
+    },
+    data() {
+        return {
+            active: 0,
+            pageStatus: 0,
+            dialogVisible: false,
+            currentResponsible: undefined,
+            stepList: [
+                {
+                    label: '闂鎻忚堪',
+                    value: 0
+                }, {
+                    label: '鍘熷洜鍒嗘瀽',
+                    value: 1
+                }, {
+                    label: '绾犳鎺柦',
+                    value: 2
+                }, {
+                    label: '楠岃瘉缁撴灉',
+                    value: 3
+                }
+            ],
+            supervisionRecordId: undefined,
+            processId: undefined,
+            mainForm: {
+                factForm: {
+                    proposingDepartmentPersonId: undefined,
+                    descriptionNonconformity: undefined
+                },
+                reasonForm: {
+                    causeAnalysisPersonId: undefined,
+                    causeAnalysis: undefined
+                },
+                measureForm: {
+                    correctiveActionId: undefined,
+                    correctiveMeasure: undefined,
+                    requestDepartmentConfirmation: undefined
+                },
+                resultForm: {
+                    verificationDepartmentPersonId: undefined,
+                    implementationVerificationResults: undefined
+                }
+            },
+            userList: [],
+        }
+    },
+    methods: {
+        openDialog(id) {
+            this.dialogVisible = true
+            this.getUserList()
+            this.getProcessData(id)
+        },
+        /**
+         * @desc 鑾峰彇鐢ㄦ埛淇℃伅
+         */
+         async getUserList() {
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: getUserListApi,
+            })
+            if(code == 200) {
+                this.userList = data
+            }
+        },
+        /**
+         * @desc 鏌ヨ鐩戠潱璁板綍澶勭悊鍗�
+         * @param {鐩戠潱璁板綍id} id
+         */
+        async getProcessData(id) {
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: personSupervisionProcessingPage,
+                params: {id}
+            })
+            if(code == 202) {
+                this.controlType = '鏂板'
+                this.supervisionRecordId = id
+                this.active = 0
+                this.pageStatus = 0
+                this.processId = undefined
+            }
+            if(code == 200) {
+                this.currentResponsible = data.currentResponsible
+                this.controlType = '缂栬緫'
+                this.supervisionRecordId = id
+                this.processId = data.processingId
+                this.active = Number(data.currentState)
+                this.pageStatus = Number(data.currentState === 2 ? 0 : data.currentState)
+                // 绗�1姝ユ暟鎹�
+                this.mainForm.factForm.proposingDepartmentPersonId = data.proposingDepartmentPersonId
+                this.mainForm.factForm.descriptionNonconformity = data.descriptionNonconformity
+                // 绗�2姝ユ暟鎹�
+                this.mainForm.reasonForm.causeAnalysisPersonId = data.causeAnalysisPersonId
+                this.mainForm.reasonForm.causeAnalysis = data.causeAnalysis
+                // 绗�3姝ユ暟鎹�
+                this.mainForm.measureForm.correctiveActionId = data.correctiveActionId
+                this.mainForm.measureForm.correctiveMeasure = data.correctiveMeasure
+                this.mainForm.measureForm.requestDepartmentConfirmation = data.requestDepartmentConfirmation == '1' ? true:false
+                // 绗�4姝ユ暟鎹�
+                this.mainForm.resultForm.verificationDepartmentPersonId = data.verificationDepartmentPersonId
+                this.mainForm.resultForm.implementationVerificationResults = data.implementationVerificationResults
+            }
+        },
+        closeDialog() {
+            this.dialogVisible = false
+        },
+        submit(type) {
+            let currentState = undefined
+            if(type == 'submit') {
+                currentState = this.active + 1
+            } else if(type == 'save') {
+                currentState = undefined
+            }
+            if(this.active == 0) {
+                // 绗�1姝�
+                console.log('绗�1姝�', this.active, currentState)
+                let { factForm } = this.mainForm
+                this.submitForm({
+                    proposingDepartmentDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+                    currentState: currentState,
+                    ...factForm
+                })
+            } else if(this.active == 1) {
+                // 绗�2姝�
+                console.log('绗�2姝�', this.active, currentState)
+                let { reasonForm } = this.mainForm
+                this.submitForm({
+                    causeAnalysisDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+                    currentState: currentState,
+                    ...reasonForm
+                })
+            } else if(this.active == 2) {
+                // 绗�3姝�
+                console.log('绗�3姝�', this.active, currentState)
+                let { measureForm } = this.mainForm
+                let { requestDepartmentConfirmation, ...measureFormRest } = measureForm
+                this.submitForm({
+                    correctiveActionDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+                    currentState: currentState,
+                    requestDepartmentConfirmation: requestDepartmentConfirmation ? 1:2,
+                    ...measureFormRest
+                })
+            } else if(this.active == 3) {
+                // 绗�4姝�
+                console.log('绗�4姝�', this.active, currentState)
+                let { resultForm } = this.mainForm
+                this.submitForm({
+                    verificationDepartmentDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+                    currentState: currentState,
+                    ...resultForm
+                })
+            }
+        },
+        /**
+         * @desc 鎻愪氦琛ㄥ崟
+         */
+        async submitForm(form) {
+            console.log('鎻愪氦琛ㄥ崟', form)
+            const { code } = await this.$axios({
+                method: 'post',
+                url: addOrUpdatePersonnelServiceProcessing,
+                data: {
+                    processingId: this.processId,
+                    supervisionRecordId: this.supervisionRecordId,
+                    ...form
+                },
+                noQs: true
+            })
+            if(this.controlType == '鏂板') {
+                if(code == 200) {
+                    this.$message.success('鎻愪氦鎴愬姛')
+                }
+            } else if(this.controlType == '缂栬緫') {
+                if(code == 200) {
+                    this.$message.success('鎻愪氦鎴愬姛')
+                }
+            }
+            this.dialogVisible = false
+        },
+        /**
+         * @desc 椹冲洖
+         */
+         cancel() {
+            let currentState = this.active - 1
+            this.submitForm({
+                id: this.processId,
+                supervisionRecordId: this.supervisionRecordId,
+                currentState: currentState,
+            })
+        },
+        setStep(e) {
+            console.log(e)
+            this.pageStatus = e
+        }
+    }
+}
+</script>
diff --git a/src/components/caorui/Department/components/Records/index.vue b/src/components/caorui/Department/components/Records/index.vue
new file mode 100644
index 0000000..48d5365
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/index.vue
@@ -0,0 +1,447 @@
+<template>
+    <div class="flex_column">
+        <div>
+            <TableCard :showTitle="false">
+                <template v-slot:form>
+                    <div class="items_center">
+                        <!-- <span>鍏抽敭瀛�</span>
+                        <el-input size="small" class="search" v-model="superviseForm.searchVal" placeholder="璇疯緭鍏�"></el-input>
+                        <el-button type="primary" size="small">鏌ヨ</el-button> -->
+                        <el-button v-if="multipleSelection.length > 0" slot="reference" size="small" type="danger"
+                            @click="delRecords">鍒犻櫎</el-button>
+                    </div>
+                    <div>
+                        <el-button size="small" type="primary" @click="addRecord">鏂板</el-button>
+                    </div>
+                </template>
+                <template v-slot:table>
+                    <ZTTable
+                        :column="superviseColumnData"
+                        :handleSelectionChange="handleSelectionChange"
+                        :height="'calc(100vh - 19em)'"
+                        :isSelection="true"
+                        :table-data="superviseTableData"
+                        :table-loading="superviseLoading"
+                        rowKey="id"
+                        style="margin-top: 18px; padding: 0 15px;"
+                    >
+                        <div slot="action" slot-scope="scope">
+                            <el-button type="text" @click="openDownloadDia(scope.row)">
+                                <span>瀵煎嚭</span>
+                            </el-button>
+                            <el-button type="text" @click="openRecord(scope.row)">
+                                <span>鐩戠潱璁板綍</span>
+                            </el-button>
+                            <el-button type="text" @click="openControl(scope.row.id)">
+                                <span :style="renderBtn(scope.row.currentStateControl)">鎺у埗鍗�</span>
+                            </el-button>
+                            <el-button type="text" @click="openDispose(scope.row.id)">
+                                <span :style="renderBtn(scope.row.currentStateProcessing)">澶勭悊鍗�</span>
+                            </el-button>
+                        </div>
+                    </ZTTable>
+                    <!-- 鍒嗛〉 -->
+                    <div class="pagination">
+                        <div></div>
+                        <el-pagination :page-size="pagination.pageSize" :page-sizes="[10, 20, 30, 40]"
+                            :total="pagination.total" layout="total, sizes, prev, pager, next, jumper"
+                            @current-change="currentChange" @size-change="sizeChange">
+                        </el-pagination>
+                    </div>
+                </template>
+            </TableCard>
+        </div>
+        <RecordAdd ref="recordModal" @submit="getTableData"></RecordAdd>
+        <ControlModal ref="controlModal"></ControlModal>
+        <DisposeModal ref="disposeModal"></DisposeModal>
+        <el-dialog :visible.sync="downloadDialog" title="瀵煎嚭" width="600px">
+            <span>
+                <el-button :disabled="!download.currentStateControl" plain type="primary" @click="controlDown">鎺у埗鍗曞鍑�</el-button>
+                <el-button :disabled="!download.currentStateProcessing" plain type="primary" @click="processingDown">澶勭悊鍗曞鍑�</el-button>
+                <el-button plain type="primary" @click="supervisoryDown">鐩戠潱璁板綍瀵煎嚭</el-button>
+            </span>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="downloadDialog = false">鍙� 娑�</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import TableCard from "../../../TableCard/index"
+import RecordAdd from "./Add.vue"
+import ZTTable from "../../../ZTTable/index.vue"
+import ControlModal from "./control/index.vue"
+import DisposeModal from "./dispose/index.vue"
+import {
+    personSupervisionRecordPage,
+    deletePersonSupervisionRecord,
+    personSupervisionProcessingPage,
+    exportSupervisionControlSheet,
+    exportSupervisionProcessingSheet,
+    exportPersonSupervisionRecord
+} from "../../../../../assets/api/api"
+
+export default {
+  props: {
+    isDepartment: {
+      type: Boolean,
+      default: false
+    },
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+  },
+    components: {
+        TableCard,
+        RecordAdd,
+        ZTTable,
+        ControlModal,
+        DisposeModal
+    },
+    data() {
+        return {
+            loading: false,
+            pagination: {
+                current: 1,
+                pageSize: 20,
+                total: 0
+            },
+            // 鐩戠潱璁板綍
+            superviseForm: {
+                searchVal: undefined
+            },
+            superviseColumnData: [
+                {
+                    label: 'id',
+                    prop: 'id'
+                }, {
+                    label: '妫�娴嬩汉鍛�',
+                    prop: 'testerName',
+                    width: 120
+                }, {
+                    label: '鐩戠潱浜哄憳',
+                    prop: 'supervisorName',
+                    width: 120
+                }, {
+                    label: '妫�楠岄」鐩�',
+                    prop: 'testItem',
+                    width: 120
+                }, {
+                    label: '鏍峰搧缂栧彿',
+                    prop: 'sampleNumber',
+                    width: 120
+                }, {
+                    label: '妫�楠屾棩鏈�',
+                    prop: 'detectionDate',
+                    width: 160
+                }, {
+                    label: '鎺у埗鍗曠姸鎬�',
+                    prop: 'currentStateControl',
+                    formatData: (item) => {
+                        let result = undefined
+                        switch (item) {
+                            case '0':
+                                result = '宸ヤ綔鎯呭喌'
+                                break;
+                            case '1':
+                                result = '琚洃鐫d汉纭'
+                                break;
+                            case '2':
+                                result = '澶勭悊鎺柦'
+                                break;
+                            case '3':
+                                result = '绾犳鎺柦'
+                                break;
+                            case '4':
+                                result = '閫氱煡瀹㈡埛'
+                                break;
+                        }
+                        return result
+                    },
+                    width: 140,
+                }, {
+                    label: '娴佺▼鍗曠姸鎬�',
+                    prop: 'currentStateProcessing',
+                    formatData: (item) => {
+                        let result = undefined
+                        switch (item) {
+                            case '0':
+                                result = '闂鎻忚堪'
+                                break;
+                            case '1':
+                                result = '鍘熷洜鍒嗘瀽'
+                                break;
+                            case '2':
+                                result = '绾犳鎺柦'
+                                break;
+                            case '3':
+                                result = '楠岃瘉缁撴灉'
+                                break;
+                        }
+                        return result
+                    },
+                    width: 140,
+                }, {
+                    label: '浜哄憳',
+                    prop: 'personnelName',
+                    width: 150
+                }, {
+                    label: '璁惧浠櫒',
+                    prop: 'instrumentEquipment',
+                    width: 140
+                }, {
+                    label: '宸ヤ綔鐜',
+                    prop: 'workingEnvironment',
+                    width: 140
+                }, {
+                    label: '鏍峰搧閲囬泦',
+                    prop: 'sampleCollection',
+                    width: 140
+                }, {
+                    label: '鏍峰搧鐨勫噯澶�',
+                    prop: 'samplePreparation',
+                    width: 140
+                }, {
+                    label: '妫�楠屾柟娉�',
+                    prop: 'testMethod',
+                    width: 120
+                }, {
+                    label: '妫�娴嬭褰�',
+                    prop: 'testingRecords',
+                    width: 120
+                }, {
+                    label: '妫�楠屾姤鍛�',
+                    prop: 'testReport',
+                    width: 120
+                }, {
+                    label: '鐩戠潱鎯呭喌璇勪环',
+                    prop: 'evaluationSupervisionSituation',
+                    width: 140
+                }, {
+                    label: '涓嶇鍚堝鐞嗘剰瑙�',
+                    prop: 'doNotMeetTheHandlingOpinions',
+                    width: 140
+                }, {
+                    fixed: 'right',
+                    dataType: "slot",
+                    width: 280,
+                    label: '鎿嶄綔',
+                    slot: 'action',
+                }
+            ],
+            superviseTableData: [],
+            superviseLoading: false,
+            multipleSelection: [],
+            downloadDialog: false,
+          download: {
+            currentStateControl: '',
+            currentStateProcessing: '',
+          },
+            downloadId: '',
+        }
+    },
+    mounted() {
+        this.getTableData()
+    },
+    methods: {
+        /**
+         * @desc 鑾峰彇鏍戠殑浜哄憳id
+         */
+        getDepart() {
+            this.getTableData()
+        },
+        /**
+         * @desc 褰撳墠椤垫敼鍙�
+         */
+        currentChange(current) {
+            this.pagination.current = current
+            this.getTableData()
+        },
+        /**
+         * @desc 姣忛〉涓暟鏀瑰彉
+         */
+        sizeChange(pageSize) {
+            this.pagination.pageSize = pageSize
+            this.getTableData()
+        },
+        // 鑾峰彇鐩戠潱璁板綍
+        async getTableData() {
+            this.loading = true
+            const { code, data } = await this.$axios({
+                method: 'get',
+                url: personSupervisionRecordPage,
+                params: {
+                    departLimsId: this.isDepartment ? this.departId : null,
+                    userId: this.isDepartment ? null : this.departId,
+                    current: this.pagination.current,
+                    size: this.pagination.pageSize
+                }
+            })
+            if (code == 200) {
+                this.superviseTableData = data.records
+                this.pagination.total = data.total
+            }
+            this.loading = false
+        },
+        // 鏂板鐩戠潱璁板綍
+        addRecord(row, type = false) {
+            this.$refs.recordModal.openDialog({ departId: this.departId, ...row }, type)
+        },
+        openRecord(row) {
+            this.$refs.recordModal.openDialog(row, true)
+        },
+        // 鎵撳紑瀵煎嚭寮规
+        openDownloadDia(row) {
+            this.downloadDialog = true
+          this.download = row
+            this.downloadId = row.id
+        },
+        // 鎺у埗鍗曞鍑�
+        controlDown() {
+            this.$axios.get(exportSupervisionControlSheet + '?supervisionRecordId=' + this.downloadId, { responseType: "blob" }).then(res => {
+                this.outLoading = false
+                this.$message.success('瀵煎嚭鎴愬姛')
+                const blob = new Blob([res], { type: 'application/msword' });
+                const url = URL.createObjectURL(blob);
+                const link = document.createElement('a');
+                link.href = url;
+                link.download = '鎺у埗鍗曞鍑�' + '.docx';
+                link.click();
+            })
+        },
+        // 澶勭悊鍗曞鍑�
+        processingDown() {
+            this.$axios.get(exportSupervisionProcessingSheet + '?supervisionRecordId=' + this.downloadId, { responseType: "blob" }).then(res => {
+                this.outLoading = false
+                this.$message.success('瀵煎嚭鎴愬姛')
+                const blob = new Blob([res], { type: 'application/msword' });
+                const url = URL.createObjectURL(blob);
+                const link = document.createElement('a');
+                link.href = url;
+                link.download = '澶勭悊鍗曞鍑�' + '.docx';
+                link.click();
+            })
+        },
+        // 鐩戠潱璁板綍瀵煎嚭
+        supervisoryDown() {
+            this.$axios.get(exportPersonSupervisionRecord + '?id=' + this.downloadId, { responseType: "blob" }).then(res => {
+                this.outLoading = false
+                this.$message.success('瀵煎嚭鎴愬姛')
+                const blob = new Blob([res], { type: 'application/msword' });
+                const url = URL.createObjectURL(blob);
+                const link = document.createElement('a');
+                link.href = url;
+                link.download = '鐩戠潱璁板綍瀵煎嚭' + '.docx';
+                link.click();
+            })
+        },
+        // 鏄剧ず鎺у埗鍗�
+        openControl(id) {
+            this.$refs.controlModal.openDialog(id)
+        },
+        // 鏄剧ず澶勭悊鍗�
+        openDispose(id) {
+            this.$refs.disposeModal.openDialog(id)
+        },
+        // 琛ㄦ牸澶氶�夋縺娲诲悗鍋氫粈涔�
+        handleSelectionChange(val) {
+            this.multipleSelection = val
+        },
+        /**
+         * @desc 鎵归噺鍒犻櫎鐩戠潱璁板綍
+         */
+        delRecords() {
+            this.$confirm(
+                '姝ゆ搷浣滃皢鍒犻櫎閫変腑鏁版嵁, 鏄惁缁х画?',
+                '鎻愮ず',
+                {
+                    confirmButtonText: '纭畾',
+                    cancelButtonText: '鍙栨秷',
+                    type: 'warning'
+                })
+                .then(() => {
+                    console.log(this.multipleSelection)
+                    let ids = this.multipleSelection.map((item) => item.id)
+                    const code = this.delTableData(ids)
+                    this.$message({
+                        type: code == 200 ? 'success' : 'error',
+                        message: code == 200 ? '鍒犻櫎鎴愬姛锛�' : '鍒犻櫎澶辫触锛�'
+                    });
+                    this.getTableData()
+                })
+        },
+        // 鍒犻櫎api
+        async delTableData(ids) {
+            const { code } = await this.$axios({
+                method: 'delete',
+                url: deletePersonSupervisionRecord,
+                data: ids
+            })
+            return code
+        },
+        // 琛岃儗鏅壊
+        renderBtn(currentState) {
+            let status = Number(currentState)
+            let res = {}
+            switch (status) {
+                case 0:
+                    break;
+                case 1:
+                    res = {color: '#337ecc'}
+                    break;
+                case 2:
+                    res = {color: '#409EFF'}
+                    break;
+                case 3:
+                    res = {color: '#79bbff'}
+                    break;
+                case 4:
+                    res = {color: '#a0cfff'}
+                    break;
+            }
+            return res;
+        }
+    },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    departId: {
+      handler(newId, oldId) {
+        if (this.isDepartment) {
+          this.getTableData();
+        } else {
+          this.getTableData()
+        }
+      }
+    }
+  }
+}
+</script>
+<style scoped>
+.flex_column {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+}
+
+.pagination {
+    display: flex;
+    justify-content: space-between
+}
+
+.items_center {
+    display: flex;
+    align-items: center;
+}
+
+.date_box {
+    margin: 0 5px;
+}
+
+.search {
+    width: 150px;
+    padding: 0 16px;
+}
+</style>
diff --git a/src/components/caorui/Department/components/Records/supervise/ApproveForm.vue b/src/components/caorui/Department/components/Records/supervise/ApproveForm.vue
new file mode 100644
index 0000000..6563eb8
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/supervise/ApproveForm.vue
@@ -0,0 +1,84 @@
+<template>
+    <el-form
+        :model="form"
+        label-width="100px"
+        :disabled="disabled"
+        size="small"
+    >
+        <el-form-item label="鎶�鏈礋璐d汉">
+            <el-select 
+                v-model="form.technicalDirector" 
+                placeholder="璇烽�夋嫨" 
+                style="width: 100%"
+            >
+                <el-option
+                    v-for="(item, index) in userList"
+                    :key="index"
+                    :label="item.name"
+                    :value="item.id"
+                ></el-option>
+            </el-select>
+        </el-form-item>
+        <!-- <el-form-item label="瀹℃壒">
+            <el-input 
+                type="textarea"
+                :rows="2" 
+                placeholder="璇疯緭鍏�"
+            ></el-input>
+        </el-form-item> -->
+        <el-form-item v-if="!disabled" style="text-align: right;">
+            <el-button size="small" type="danger" @click="close">椹冲洖</el-button>
+            <el-button size="small" type="primary" @click="submit">鎻愪氦</el-button>
+        </el-form-item>
+    </el-form>
+</template>
+<script>
+export default {
+    props: {
+        userList: {
+            type: Array,
+            default: () => {
+                return []
+            }
+        },
+        approveForm: {
+            type: Object,
+            default: {}
+        },
+        isEdit: {
+            type: Boolean,
+            default: false
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        }
+    },
+    computed: {
+        form: {
+            get() {
+                return this.approveForm
+            },
+            set(val) {
+                this.$emit('approveForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+          
+        }
+    },
+    methods: {
+        submit() {
+            this.$emit('submit', 2)
+        },
+        /**
+         * @desc 椹冲洖
+         */
+        close() {
+            this.$emit('close', 2)
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/components/Records/supervise/SuperviseForm.vue b/src/components/caorui/Department/components/Records/supervise/SuperviseForm.vue
new file mode 100644
index 0000000..f0a57db
--- /dev/null
+++ b/src/components/caorui/Department/components/Records/supervise/SuperviseForm.vue
@@ -0,0 +1,196 @@
+<template>
+     <el-form
+        :model="ruleForm"
+        :disabled="disabled"
+        label-width="100px"
+        size="small"
+    >
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="妫�娴嬩汉鍛�">
+                    <el-select v-model="ruleForm.testerId" placeholder="璇烽�夋嫨" style="width: 100%">
+                        <el-option
+                            v-for="(item, index) in userList"
+                            :key="index"
+                            :label="item.name"
+                            :value="item.id"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-col>
+            <el-col :span="12">
+                <el-form-item label="鐩戠潱鍛�">
+                    <el-select v-model="ruleForm.supervisorId" placeholder="璇烽�夋嫨" style="width: 100%">
+                        <el-option
+                            v-for="(item, index) in userList"
+                            :key="index"
+                            :label="item.name"
+                            :value="item.id"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="妫�娴嬮」鐩�">
+                    <el-input v-model="ruleForm.testItem" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+            <el-col :span="12">
+                <el-form-item label="鏍峰搧缂栧彿">
+                    <el-input v-model="ruleForm.sampleNumber" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="妫�娴嬫棩鏈�">
+                    <el-date-picker
+                        v-model="ruleForm.detectionDate"
+                        value-format="yyyy-MM-dd HH:mm:ss"
+                        type="datetime"
+                        placeholder="閫夋嫨鏃ユ湡"
+                        style="width: 100%;"
+                    >
+                    </el-date-picker>
+                </el-form-item>
+            </el-col>
+            <el-col :span="12">
+                <el-form-item label="浜哄憳">
+                    <el-select 
+                        v-model="ruleForm.personnel" 
+                        placeholder="璇烽�夋嫨" 
+                        style="width: 100%"
+                        multiple
+                    >
+                        <el-option
+                            v-for="(item, index) in userList"
+                            :key="index"
+                            :label="item.name"
+                            :value="item.id"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="浠櫒璁惧">
+                    <el-input v-model="ruleForm.instrumentEquipment" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+            <el-col :span="12">
+                <el-form-item label="宸ヤ綔鐜">
+                    <el-input v-model="ruleForm.workingEnvironment" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="鏍峰搧閲囬泦">
+                    <el-input v-model="ruleForm.sampleCollection" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+            <el-col :span="12">
+                <el-form-item label="鏍峰搧鐨勫噯澶�">
+                    <el-input v-model="ruleForm.samplePreparation" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="妫�娴嬫柟娉�">
+                    <el-input v-model="ruleForm.testMethod" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+            <el-col :span="12">
+                <el-form-item label="妫�娴嬭褰�">
+                    <el-input v-model="ruleForm.testingRecords" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="妫�娴嬫姤鍛�">
+                    <el-input v-model="ruleForm.testReport" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+            <el-col :span="12">
+                <el-form-item label="鐩戠潱鎯呭喌璇勪环">
+                    <el-input v-model="ruleForm.evaluationSupervisionSituation" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col :span="12">
+                <el-form-item label="澶勭悊鎰忚">
+                    <el-input v-model="ruleForm.doNotMeetTheHandlingOpinions" placeholder="璇疯緭鍏�"></el-input>
+                </el-form-item>
+            </el-col>
+        </el-row>
+        <el-row>
+            <el-col v-show="isEdit && !disabled" :span="24">
+                <el-form-item style="text-align: right;">
+                    <el-button size="small" @click="close">鍙栨秷</el-button>
+                    <el-button size="small" type="primary" @click="approve">瀹℃壒</el-button>
+                </el-form-item>
+            </el-col>
+            <el-col v-show="!isEdit" :span="24">
+                <el-form-item style="text-align: right;">
+                    <el-button size="small" type="primary" @click="addData">鎻愪氦</el-button>
+                </el-form-item>
+            </el-col>
+        </el-row>
+    </el-form>
+</template>
+<script>
+
+export default {
+    props: {
+        isEdit: {
+            type: Boolean,
+            default: false
+        },
+        userList: {
+            type: Array,
+            default: () => {
+                return []
+            }
+        },
+        superviseForm: {
+            type: Object,
+            default: {}
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        }
+    },
+    computed: {
+        ruleForm: {
+            get() {
+                return this.superviseForm
+            },
+            set(val) {
+                this.$emit('superviseForm', val)
+            }
+        }
+    },
+    data() {
+        return {
+        }
+    },
+    methods: {
+        close() {
+            this.$emit('close')
+        },
+        approve() {
+            this.$emit('submit', 1)
+        },
+        addData() {
+            this.$emit('addData', 1)
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/src/components/caorui/Department/index.vue b/src/components/caorui/Department/index.vue
new file mode 100644
index 0000000..e012d17
--- /dev/null
+++ b/src/components/caorui/Department/index.vue
@@ -0,0 +1,150 @@
+<template>
+  <el-tabs v-model="activeName" :lazy="true" type="border-card">
+    <el-tab-pane label="浜哄憳鍩烘湰淇℃伅" name="浜哄憳鍩烘湰淇℃伅">
+      <PersonnelList v-if="activeName === '浜哄憳鍩烘湰淇℃伅' && isShowAll" ref="personnelList" :currentCompaniesList="currentCompaniesList"
+                     :departId="departId" @refreshTree="refreshTree"
+                     @updatePerson="updatePerson"></PersonnelList>
+      <personnelInformation v-if="activeName === '浜哄憳鍩烘湰淇℃伅' && !isShowAll" :clickNodeVal="clickNodeVal"></personnelInformation>
+    </el-tab-pane>
+    <el-tab-pane label="鍩硅璁″垝" name="鍩硅璁″垝">
+      <PersonnelTraining v-if="activeName === '鍩硅璁″垝'" ref="personnelTraining"
+                         :departId="departId" :isDepartment="isDepartment"></PersonnelTraining>
+    </el-tab-pane>
+    <el-tab-pane label="鐩戠潱璁″垝" name="鐩戠潱璁″垝">
+      <Plan v-if="activeName === '鐩戠潱璁″垝'"></Plan>
+    </el-tab-pane>
+    <el-tab-pane label="宀椾綅鑱岃矗" name="宀椾綅鑱岃矗">
+      <job-responsibilities v-if="activeName === '宀椾綅鑱岃矗'" ref="jobResponsibilities"
+                            :departId="departId"
+                            :isDepartment="isDepartment"></job-responsibilities>
+    </el-tab-pane>
+    <el-tab-pane label="宸ヤ綔灞ュ巻" name="宸ヤ綔灞ュ巻">
+      <trackRecord v-if="activeName === '宸ヤ綔灞ュ巻'" :clickNodeVal="clickNodeVal"></trackRecord>
+    </el-tab-pane>
+    <el-tab-pane label="濂栨儵璁板綍" name="濂栨儵璁板綍">
+      <rewardPunishmentRecord v-if="activeName === '濂栨儵璁板綍'"
+                              :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord>
+    </el-tab-pane>
+    <el-tab-pane label="鍩硅璁板綍" name="鍩硅璁板綍">
+      <training-record v-if="activeName === '鍩硅璁板綍'" ref="trainingRecord"
+                       :departId="departId"
+                       :isDepartment="isDepartment"></training-record>
+    </el-tab-pane>
+    <el-tab-pane label="鐩戠潱璁板綍" name="鐩戠潱璁板綍">
+      <Records v-if="activeName === '鐩戠潱璁板綍'" ref="recordsRef" :departId="departId" :isDepartment="isDepartment"></Records>
+    </el-tab-pane>
+    <el-tab-pane label="浠昏亴鎺堟潈璁板綍" name="浠昏亴鎺堟潈璁板綍">
+      <Mandate v-if="activeName === '浠昏亴鎺堟潈璁板綍'" ref="manDateRef" :departId="departId" :isDepartment="isDepartment"></Mandate>
+    </el-tab-pane>
+    <el-tab-pane label="浜哄憳鑳藉姏" name="浜哄憳鑳藉姏">
+      <personnel-capacity v-if="activeName === '浜哄憳鑳藉姏'" ref="personnelCapacity"
+                          :departId="departId"
+                          :isDepartment="isDepartment"></personnel-capacity>
+    </el-tab-pane>
+    <el-tab-pane label="娌熼�氳褰�" name="娌熼�氳褰�">
+      <Communicate v-if="activeName === '娌熼�氳褰�'" ref="communicateRef" :departId="departId" :isDepartment="isDepartment"></Communicate>
+    </el-tab-pane>
+  </el-tabs>
+</template>
+<script>
+import Plan from './components/Plan/index.vue';
+import Records from './components/Records/index.vue';
+import Communicate from './components/Communicate/index.vue';
+import Mandate from './components/Mandate/index.vue';
+import PersonnelList from '../../do/a6-personnel-collect/personnel-list.vue';
+import PersonnelTraining from '../../do/a6-personnel-training/index.vue';
+import JobResponsibilities from '../../do/a6-personnel/job-responsibilities.vue';
+import TrainingRecord from '../../do/a6-personnel/training-record.vue';
+import PersonnelCapacity from '../../do/a6-personnel/personnel-capacity.vue';
+import trackRecord from "../../do/a6-personnel/track-record.vue";
+import rewardPunishmentRecord from "../../do/a6-personnel/reward-punishment-record.vue";
+import PersonnelInformation from "../../do/a6-personnel/personnel-information.vue";
+
+export default {
+  props: {
+    clickNodeVal: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    },
+    departId: {
+      type: Number,
+      default: 0
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    },
+    isShowAll: {
+      type: Boolean,
+      default: false
+    },
+    currentCompaniesList: {
+      type: Array,
+      default: []
+    }
+  },
+  components: {
+    PersonnelInformation,
+    rewardPunishmentRecord,
+    trackRecord,
+    PersonnelCapacity,
+    TrainingRecord,
+    JobResponsibilities,
+    PersonnelTraining,
+    PersonnelList,
+    Plan,
+    Records,
+    Communicate,
+    Mandate
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (newId) {
+          switch (this.activeName) {
+            case '娌熼�氳褰�':
+              this.$refs.communicateRef.getDepart(newId);
+              break;
+            case '浠昏亴鎺堟潈璁板綍':
+              this.$refs.manDateRef.getDepart(newId);
+              break;
+            default:
+              break;
+          }
+        }
+      }
+    }
+  },
+  data() {
+    return {
+      activeName: '浜哄憳鍩烘湰淇℃伅',
+    }
+  },
+  methods:{
+    updatePerson (row) {
+      this.$parent.updatePerson(row);
+    },
+    refreshTree () {
+      this.$parent.refreshTree();
+    },
+  }
+};
+</script>
+<style scoped>
+.box {
+  height: calc(100vh - 11em);
+}
+
+.el-tabs >>> .el-tabs--border-card {
+  box-shadow: unset;
+  border: unset;
+}
+
+.flex_column {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+}
+</style>
diff --git a/src/components/do/a7-Ensure-results-validity/ViewRecord.vue b/src/components/do/a7-Ensure-results-validity/ViewRecord.vue
new file mode 100644
index 0000000..6474112
--- /dev/null
+++ b/src/components/do/a7-Ensure-results-validity/ViewRecord.vue
@@ -0,0 +1,190 @@
+<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="{detailsEvaluateId: info.detailsEvaluateId}"
+                   :headers="headers" :on-error="onError"
+                   :on-success="handleSuccessUp"
+                   :show-file-list="false"
+                   accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
+          <el-button size="small" style="height: 38px" type="primary">闄勪欢涓婁紶</el-button>
+        </el-upload>
+      </div>
+      <div>
+        <ZTTable
+          ref="yearTable"
+          :column="columnData"
+          :height="'calc(100vh - 47em)'"
+          :highlightCurrentRow="true"
+          :table-data="tableData"
+          :table-loading="tableLoading"
+          style="margin-top: 0.5em;">
+        </ZTTable>
+      </div>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="lookDialogVisible"
+      fullscreen
+      title="鏌ョ湅闄勪欢" width="800px">
+      <filePreview v-if="lookDialogVisible" :currentFile="{}"
+                   :fileUrl="javaApi+'/word/'+currentInfo.fileUrl" style="height: 90vh;overflow-y: auto;top: 0"/>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import ZTTable from '../../caorui/ZTTable/index.vue';
+import file from '../../../util/file';
+import filePreview from '../../tool/file-preview.vue';
+
+export default {
+  name: 'ViewRecord',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { filePreview, ZTTable },
+  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
+      this.$axios.get(this.$api.qualityMonitor.getEvaluateFileList + '?detailsEvaluateId=' + this.info.detailsEvaluateId).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
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        file.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+    // 鍒犻櫎
+    delete (row) {
+      this.tableLoading = true
+      this.$axios.get(this.$api.qualityMonitor.delVerifyEvaluateFileList + '?evaluateFileId=' + row.evaluateFileId).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()
+      }
+    },
+    // 鏌ョ湅鏂囦欢
+    handleLook(row){
+      this.currentInfo = row
+      this.lookDialogVisible = true
+    },
+  },
+  computed: {
+    headers() {
+      return {
+        'token': sessionStorage.getItem('token')
+      }
+    },
+    fileAction() {
+      return this.javaApi + this.$api.qualityMonitor.uploadEvaluateFile
+
+    }
+  },
+};
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/components/do/a7-Ensure-results-validity/carryOutDialog.vue b/src/components/do/a7-Ensure-results-validity/carryOutDialog.vue
new file mode 100644
index 0000000..8027a04
--- /dev/null
+++ b/src/components/do/a7-Ensure-results-validity/carryOutDialog.vue
@@ -0,0 +1,352 @@
+<template>
+  <div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false"
+               :visible.sync="formDia"
+               title="瀹炴柦"
+               width="60%" @close="closeCarryOutDia">
+      <el-steps :active="currentStep" align-center finish-status="success">
+        <el-step title="瀹炴柦"></el-step>
+        <el-step title="鎵瑰噯"></el-step>
+      </el-steps>
+      <div style="height: 60vh;overflow-y: auto">
+        <table border="1" cellspacing="10" class="tables">
+          <tr>
+            <td class="td-title">
+              <p>鐩戞帶椤圭洰锛�</p>
+            </td>
+            <td colspan="3">
+              <el-input v-if="currentStep == 0" v-model="form.monitorProject"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small">
+              </el-input>
+              <span v-else class="td-info"> {{ form.monitorProject }}</span>
+            </td>
+            <td class="td-title">
+              <p>鐩戞帶鏃堕棿锛�</p>
+            </td>
+            <td colspan="3">
+              <el-input v-if="currentStep == 0" v-model="form.monitorData"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small">
+              </el-input>
+              <span v-else class="td-info"> {{ form.monitorData }}</span>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="8">
+              <div>
+                <p>鐩戞帶鐩殑锛�</p>
+              </div>
+              <div>
+                <el-input v-if="currentStep == 0" v-model="form.monitorPurpose"
+                          :rows="3"
+                          placeholder="璇疯緭鍏ュ唴瀹�"
+                          size="small"
+                          type="textarea">
+                </el-input>
+                <span v-else class="td-info2"> {{ form.monitorPurpose }}</span>
+              </div>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="8">
+              <div>
+                <p>鐩戞帶鏂规硶锛�</p>
+              </div>
+              <div>
+                <el-input v-if="currentStep == 0" v-model="form.monitorMethod"
+                          :rows="4"
+                          placeholder="璇疯緭鍏ュ唴瀹�"
+                          size="small"
+                          type="textarea">
+                </el-input>
+                <span v-else class="td-info2"> {{ form.monitorMethod }}</span>
+              </div>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="8">
+              <div>
+                <p>鍙傚姞浜哄憳锛�</p>
+              </div>
+              <div>
+                <el-input v-if="currentStep == 0" v-model="form.participant"
+                          :rows="3"
+                          placeholder="璇疯緭鍏ュ唴瀹�"
+                          size="small"
+                          type="textarea">
+                </el-input>
+                <span v-else class="td-info2"> {{ form.participant }}</span>
+              </div>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="8">
+              <div>
+                <p>杩囩▼鎺у埗锛�</p>
+              </div>
+              <div>
+                <el-input v-if="currentStep == 0" v-model="form.processControl"
+                          :rows="3"
+                          placeholder="璇疯緭鍏ュ唴瀹�"
+                          size="small"
+                          type="textarea">
+                </el-input>
+                <span v-else class="td-info2"> {{ form.processControl }}</span>
+              </div>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="8">
+              <div>
+                <p>缁撴灉璇勪环鏍囧噯锛堝浣曡瘎浠凤級锛�</p>
+              </div>
+              <div>
+                <el-input v-if="currentStep == 0" v-model="form.howEvaluate"
+                          :rows="3"
+                          placeholder="璇疯緭鍏ュ唴瀹�"
+                          size="small"
+                          type="textarea">
+                </el-input>
+                <span v-else class="td-info2"> {{ form.howEvaluate }}</span>
+              </div>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="8">
+              <div>
+                <p>缁忚垂棰勭畻锛�</p>
+              </div>
+              <div>
+                <el-input v-if="currentStep == 0" v-model="form.budget"
+                          placeholder="璇疯緭鍏ュ唴瀹�"
+                          size="small">
+                </el-input>
+                <span v-else class="td-info2"> {{ form.budget }}</span>
+              </div>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="4">
+              <div>
+                <p>妫�娴嬮儴闂細</p>
+              </div>
+              <div>
+                <el-input v-if="currentStep == 0" v-model="form.inspectionDepartment"
+                          placeholder="璇疯緭鍏ュ唴瀹�"
+                          size="small">
+                </el-input>
+                <span v-else class="td-info2"> {{ form.inspectionDepartment }}</span>
+              </div>
+            </td>
+            <td colspan="4">
+              <div v-if="currentStep == 0">
+                <div>閫夋嫨鎵瑰噯浜猴細</div>
+                <div>
+                  <el-select v-if="currentStep == 0" v-model="form.ratifyUserId" 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>
+                  <span v-else class="td-info2"> {{ form.ratifyName }}</span>
+                </div>
+              </div>
+              <div v-else>
+                <div>
+                  <p>鎵瑰噯鎰忚锛�</p>
+                </div>
+                <div>
+                  <el-input v-if="currentStep == 1" v-model="form.ratifyOpinion"
+                            :rows="3"
+                            placeholder="璇疯緭鍏ュ唴瀹�"
+                            size="small"
+                            type="textarea">
+                  </el-input>
+                  <span v-if="currentStep == 2" class="td-info2"> {{ form.ratifyOpinion }}</span>
+                  <span v-if="currentStep == 2" class="td-info3"> {{ '鎵瑰噯浜猴細' + form.ratifyName }}</span>
+                </div>
+              </div>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeCarryOutDia">鍙� 娑�</el-button>
+        <el-button v-if="currentStep != 2" :loading="editLoad" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'carryOutDialog',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      currentStep: 0,
+      form: {
+        monitorProject: '',
+        monitorData: '',
+        monitorPurpose: '',
+        monitorMethod: '',
+        participant: '',
+        processControl: '',
+        howEvaluate: '',
+        budget: '',
+        inspectionDepartment: '',
+        ratifyUserId: '',
+        ratifyOpinion: '',
+        qualityMonitorDetailsId: '',
+        ratifyName: '',
+      },
+      personList: [],
+      editLoad: false,
+      isCarryOut: false, // 鏄惁涓哄疄鏂�
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.formDia = true
+      this.searchInfo(row)
+      this.getAuthorizedPerson()
+    },
+    // 鏌ヨ鐩戞帶璁″垝璇︽儏瀹炴柦淇℃伅
+    searchInfo (row) {
+      this.$axios.get(this.$api.qualityMonitor.getQualityMonitorRatify + '?qualityMonitorDetailsId=' + row.qualityMonitorDetailsId).then(res => {
+        if (res.code === 201) return
+        // 鏈塪etailsRatifyId鍒欒鏄庢彁浜よ繃瀹炴柦淇℃伅
+        if (res.data.detailsRatifyId) {
+          // 鏄惁缁撴潫0:鏈粨鏉�, 1:宸茬粨鏉�
+          if (res.data.isFinish == 0) {
+            this.currentStep = 1
+          } else if (res.data.isFinish == 1) {
+            this.currentStep = 2
+          }
+        } else {
+          this.currentStep = 0
+        }
+        this.form = res.data
+      }).catch(err => {
+        console.log('err---', err);
+      })
+    },
+    // 鎻愪氦
+    handleEdit() {
+      this.editLoad = true
+      if (this.currentStep == 0) {
+        this.addInfo()
+      } else {
+        this.editInfo()
+      }
+    },
+    // 鎻愪氦瀹炴柦
+    addInfo () {
+      this.$axios.post(this.$api.qualityMonitor.addQualityMonitorRatify, this.form, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.editLoad = false
+        if (res.code === 201) return
+        this.$message.success('鎿嶄綔鎴愬姛')
+        this.closeCarryOutDia()
+      }).catch(err => {
+        console.log('err---', err);
+        this.editLoad = false
+      })
+    },
+    // 鎻愪氦鎵瑰噯
+    editInfo () {
+      this.$axios.post(this.$api.qualityMonitor.addQualityMonitorRatifyOpinion, this.form, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.editLoad = false
+        if (res.code === 201) return
+        this.$message.success('鎿嶄綔鎴愬姛')
+        this.closeCarryOutDia()
+      }).catch(err => {
+        console.log('err---', err);
+        this.editLoad = false
+      })
+    },
+    // 鍏抽棴寮规
+    closeCarryOutDia () {
+      this.formDia = false
+      this.$emit('closeCarryOutDia')
+    },
+    getAuthorizedPerson() {
+      this.$axios.get(this.$api.user.getUserMenu).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: 20px auto 50px !important;
+}
+.tables {
+  table-layout: fixed;
+  width: 100%;
+  margin-top: 10px;
+}
+.td-title {
+  height: 40px;
+  width: 100px;
+  text-align: center;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+  padding: 6px;
+}
+.td-info {
+  display: inline-block;
+  width: 100%;
+  text-align: center;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+}
+.td-info2 {
+  display: inline-block;
+  width: 90%;
+  text-align: left;
+  font-size: 16px;
+  word-wrap: break-word;
+  white-space: normal;
+  margin-left: 20px;
+}
+.tables td {
+  height: 40px;
+  width: 100px;
+  font-size: 14px;
+  word-wrap: break-word;
+  white-space: normal;
+  padding: 6px;
+}
+.td-info3 {
+  width: 90%;
+  display: inline-block;
+  text-align: right;
+}
+</style>
diff --git a/src/components/do/a7-Ensure-results-validity/detailFormDialog.vue b/src/components/do/a7-Ensure-results-validity/detailFormDialog.vue
new file mode 100644
index 0000000..5c2976d
--- /dev/null
+++ b/src/components/do/a7-Ensure-results-validity/detailFormDialog.vue
@@ -0,0 +1,158 @@
+<template>
+  <div>
+    <el-dialog title="缂栬緫" :visible.sync="formDia"
+               :close-on-click-modal="false"
+               :close-on-press-escape="false"
+               width="80%" @close="closeDia">
+      <el-form :model="form" :rules="rules" ref="form" label-width="140px">
+        <el-col :span="12">
+          <el-form-item label="鐩戞帶鐩殑" prop="monitorPurpose">
+            <el-input v-model="form.monitorPurpose" size="small" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="璁″垝寮�灞曟椂闂�" prop="plannedTime">
+            <el-input v-model="form.plannedTime" size="small" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鐩戞帶椤圭洰" prop="monitorProject">
+            <el-input v-model="form.monitorProject" size="small" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鍙傚姞鍗曚綅锛堜汉鍛橈級" prop="participant">
+            <el-input v-model="form.participant" size="small" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="棰勭畻锛堝厓锛�" prop="budget">
+            <el-input v-model="form.budget" size="small" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="缁勭粐浜哄憳" prop="organization">
+            <el-input v-model="form.organization" size="small" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鐩戞帶鏂瑰紡" prop="monitorWay">
+            <el-input v-model="form.monitorWay" size="small" clearable></el-input>
+          </el-form-item>
+        </el-col>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+					<el-button @click="closeDia">鍙� 娑�</el-button>
+					<el-button type="primary" @click="submitForm" :loading="upLoad">纭� 瀹�</el-button>
+        </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'detailFormDialog',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  props: ['qualityMonitorId'],
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      form: {
+        qualityMonitorDetailsId: '',
+        monitorPurpose: '',
+        plannedTime: '',
+        monitorProject: '',
+        participant: '',
+        budget: '',
+        organization: '',
+        monitorWay: '',
+      },
+      rules: {
+        monitorPurpose: [{ required: true, message: '璇疯緭鍏ョ洃鎺х洰鐨�', trigger: 'blur' }],
+        monitorProject: [{ required: true, message: '璇疯緭鍏ョ洃鎺ч」鐩�', trigger: 'blur' }],
+      },
+      upLoad: false,
+      operationType: '',
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(type, row) {
+      this.formDia = true
+      this.operationType = type
+      if (type === 'edit') {
+        this.searchInfo(row)
+      }
+    },
+    searchInfo (row) {
+      this.form = {...row}
+    },
+    // 鎻愪氦琛ㄥ崟
+    submitForm () {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          if (this.operationType === 'add') {
+            this.handleAdd()
+          } else {
+            this.handleEdit()
+          }
+        }
+      })
+    },
+    // 鎻愪氦鏂板
+    handleAdd () {
+      let entity = this.HaveJson(this.form)
+      entity.qualityMonitorId = this.qualityMonitorId
+      this.upLoad = true
+      this.$axios.post(this.$api.qualityMonitor.addQualityMonitorDetail, entity, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.upLoad = false
+        if (res.code === 201) return
+        this.$message.success('鏂板鎴愬姛')
+        this.closeDia()
+      }).catch(err => {
+        console.log('err---', err);
+        this.upLoad = false
+      })
+    },
+    // 鎻愪氦淇敼
+    handleEdit () {
+      const entity = this.HaveJson(this.form)
+      this.upLoad = true
+      this.$axios.post(this.$api.qualityMonitor.updateQualityMonitorDetail, entity, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.upLoad = false
+        if (res.code === 201) return
+        this.$message.success('淇敼鎴愬姛')
+        this.closeDia()
+      }).catch(err => {
+        console.log('err---', err);
+        this.upLoad = false
+      })
+    },
+    // 鍏抽棴寮规
+    closeDia () {
+      this.$refs.form.resetFields();
+      this.formDia = false
+      this.$emit('closeDia')
+    },
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-dialog__body {
+  max-height: 75vh;
+  overflow-y: auto;
+}
+</style>
diff --git a/src/components/do/a7-Ensure-results-validity/evaluateDialog.vue b/src/components/do/a7-Ensure-results-validity/evaluateDialog.vue
new file mode 100644
index 0000000..a770ee5
--- /dev/null
+++ b/src/components/do/a7-Ensure-results-validity/evaluateDialog.vue
@@ -0,0 +1,351 @@
+<template>
+  <div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false"
+               :visible.sync="formDia"
+               title="璐ㄩ噺鐩戞帶璇勪环"
+               width="60%" @close="closeEvaDia">
+      <div style="text-align: right">
+        <el-button size="small" type="primary" @click="viewTestRecord">闄勪欢涓婁紶</el-button>
+      </div>
+      <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-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.reviewPurpose"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small">
+              </el-input>
+              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.reviewPurpose }}</span>
+            </td>
+          </tr>
+          <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.reviewUser"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small">
+              </el-input>
+              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.reviewUser }}</span>
+            </td>
+          </tr>
+          <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.reviewTime"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small">
+              </el-input>
+              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.reviewTime }}</span>
+            </td>
+          </tr>
+          <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.implementCondition"
+                        :rows="5"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small"
+                        type="textarea">
+              </el-input>
+              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.implementCondition }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 0">
+            <td class="td-title">
+              <p>瀹炴柦閮ㄩ棬锛�</p>
+            </td>
+            <td class="td-info">
+              <span> {{ form.implementDepartment }}</span>
+            </td>
+            <td v-if="currentStep === 0" class="td-title">
+              <p>璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉锛�</p>
+            </td>
+            <td v-if="currentStep === 0" class="td-info">
+              <el-select v-model="form.implementUserId" 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 === 1">
+            <td class="td-title">
+              <p>鐩戞帶缁撴灉璇勪环锛�</p>
+            </td>
+            <td class="td-info" colspan="4">
+              <el-input v-if="showStep === 1 && currentStep === 1" v-model="form.implementResult"
+                        :rows="5"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small"
+                        type="textarea">
+              </el-input>
+              <span v-if="showStep === 1 && currentStep !== 1" class="td-info1"> {{ form.implementResult }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 1">
+            <td class="td-title">
+              <p>褰撳墠璐熻矗浜猴細</p>
+            </td>
+            <td class="td-info" colspan="4">
+              {{form.implementName}}
+            </td>
+          </tr>
+          <tr v-if="showStep === 1">
+            <td v-if="currentStep === 1" class="td-title">
+              <p>璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉锛�</p>
+            </td>
+            <td v-if="currentStep === 1" class="td-info" colspan="4">
+              <el-select v-model="form.ratifyUserId" 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>璇勫缁撹锛堟槸鍚﹂噰鍙栨帾鏂斤級锛�</p>
+            </td>
+            <td class="td-info" colspan="4">
+              <el-input v-if="showStep === 2 && currentStep === 2" v-model="form.ratifyOpinion"
+                        :rows="5"
+                        placeholder="璇疯緭鍏ュ唴瀹�"
+                        size="small"
+                        type="textarea">
+              </el-input>
+              <span v-if="showStep === 2 && currentStep !== 2" class="td-info1"> {{ form.ratifyOpinion }}</span>
+            </td>
+          </tr>
+          <tr v-if="showStep === 2">
+            <td class="td-title">
+              <p>褰撳墠璐熻矗浜猴細</p>
+            </td>
+            <td class="td-info" colspan="4">
+              {{form.ratifyUserName}}
+            </td>
+          </tr>
+          <tr v-if="showStep === 2">
+            <td class="td-title">
+              <p>瀹℃壒鏃ユ湡锛�</p>
+            </td>
+            <td class="td-info" colspan="4">
+              {{form.ratifyTime}}
+            </td>
+          </tr>
+        </table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeEvaDia">鍙� 娑�</el-button>
+        <el-button v-if="currentStep !== 3" :loading="editLoad" type="primary" @click="handleEdit">鎻� 浜�</el-button>
+      </span>
+    </el-dialog>
+    <view-record v-if="ViewRecord" ref="ViewRecord"></view-record>
+  </div>
+</template>
+
+<script>
+import ViewRecord from '../a7-Ensure-results-validity/ViewRecord.vue';
+
+export default {
+  name: 'evaluateDialog',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { ViewRecord },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      formDia: false,
+      currentStep: 0,
+      showStep: 0,
+      form: {
+        implementDepartment: '',
+        reviewPurpose: '',
+        reviewUser: '',
+        reviewTime: '',
+        implementCondition: '',
+        implementName: '',
+        implementUserId: '',
+        implementResult: '',
+        ratifyUserName: '',
+        ratifyUserId: '',
+        ratifyOpinion: '',
+        qualityMonitorDetailsId: '',
+        ratifyTime: '',
+        detailsEvaluateId: '',
+      },
+      editLoad: false,
+      personList: [],
+      ViewRecord: false,
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia (row) {
+      this.formDia = true
+      this.searchInfo(row)
+      this.getAuthorizedPerson()
+      this.getDepartment()
+    },
+    // 鏌ヨ鐩戞帶璁″垝璇︽儏瀹炴柦淇℃伅
+    searchInfo (row) {
+      this.form.qualityMonitorDetailsId = row.qualityMonitorDetailsId
+      this.$axios.get(this.$api.qualityMonitor.getQualityMonitorEvaluate + '?qualityMonitorDetailsId=' + row.qualityMonitorDetailsId).then(res => {
+        if (res.code === 201) return
+        if (res.data === null) {
+          this.showStep = 0
+          this.currentStep = 0
+        } else {
+          this.form = res.data
+          if (res.data.isFinish === 0) {
+            if (res.data.implementUserId && !res.data.ratifyUserId) {
+              this.showStep = 1
+              this.currentStep = 1
+            } else if (res.data.implementUserId && res.data.ratifyUserId) {
+              this.showStep = 2
+              this.currentStep = 2
+            }
+          } else {
+            this.currentStep = 3
+            this.showStep = 2
+          }
+        }
+      }).catch(err => {
+        console.log('err---', err);
+      })
+    },
+    // 鎻愪氦
+    handleEdit () {
+      if (this.currentStep === 2) {
+        this.$axios.post(this.$api.qualityMonitor.addMonitorEvaluateOpinion, this.form, {
+          headers: {
+            "Content-Type": "application/json"
+          },
+          noQs: true
+        }).then(res => {
+          this.editLoad = false
+          if (res.code === 201) return
+          this.$message.success('鎿嶄綔鎴愬姛')
+          this.closeEvaDia()
+        }).catch(err => {
+          console.log('err---', err);
+          this.editLoad = false
+        })
+      } else {
+        if (!this.form.reviewPurpose) {
+          this.$message.warning('璇峰~鍐欒瘎瀹$洰鐨�')
+          return
+        }
+        if (!this.form.reviewUser) {
+          this.$message.warning('璇峰~鍐欒瘎瀹′汉鍛�')
+          return
+        }
+        if (!this.form.reviewTime) {
+          this.$message.warning('璇峰~鍐欒瘎瀹℃棩鏈�')
+          return
+        }
+        if (!this.form.implementCondition) {
+          this.$message.warning('璇峰~鍐欑洃鎺ц鍒掑疄鏂芥儏鍐�')
+          return
+        }
+        if (!this.form.implementUserId) {
+          this.$message.warning('璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉')
+          return
+        }
+        if (this.currentStep === 1) {
+          if (!this.form.ratifyUserId) {
+            this.$message.warning('璇烽�夋嫨涓嬩竴姝ヨ礋璐d汉')
+            return
+          }
+        }
+        this.$axios.post(this.$api.qualityMonitor.addQualityMonitorEvaluate, this.form, {
+          headers: {
+            "Content-Type": "application/json"
+          },
+          noQs: true
+        }).then(res => {
+          this.editLoad = false
+          if (res.code === 201) return
+          this.$message.success('鎿嶄綔鎴愬姛')
+          this.closeEvaDia()
+        }).catch(err => {
+          console.log('err---', err);
+          this.editLoad = false
+        })
+      }
+    },
+    // 鍏抽棴寮规
+    closeEvaDia () {
+      this.formDia = false
+      this.$emit('closeEvaDia')
+    },
+    setStep (step) {
+      this.showStep = step
+    },
+    viewTestRecord () {
+      this.ViewRecord = true
+      this.$nextTick(() => {
+        this.$refs.ViewRecord.openDia( this.form)
+      })
+    },
+    getAuthorizedPerson() {
+      this.$axios.get(this.$api.user.getUserMenu).then(res => {
+        let data = []
+        res.data.forEach(a => {
+          data.push({
+            label: a.name,
+            value: a.id
+          })
+        })
+        this.personList = data
+      })
+    },
+    getDepartment() {
+      this.$axios.get(this.$api.user.selectUserDepartmentLimsName).then(res => {
+        if (res.code === 201) return
+        this.form.implementDepartment = res.data
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+.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/components/view/a7-Ensure-results-validity.vue b/src/components/view/a7-Ensure-results-validity.vue
new file mode 100644
index 0000000..7297006
--- /dev/null
+++ b/src/components/view/a7-Ensure-results-validity.vue
@@ -0,0 +1,668 @@
+<template>
+  <!--  7.7璐ㄩ噺鐩戞帶璁″垝-->
+  <div>
+    <div class="table-card">
+      <TableCard title="骞村害璁″垝琛�">
+        <template v-slot:form>
+          <div class="items_center">
+            <span>璁″垝鍚嶇О锛�</span>
+            <el-input v-model="yearForm.monitorName" class="search" placeholder="璇疯緭鍏�"
+                      size="small"></el-input>
+            <el-button size="small" type="primary" @click="getYearPlanList">鏌ヨ</el-button>
+            <el-button size="small" @click="clearYear">閲嶇疆</el-button>
+          </div>
+          <div>
+            <el-upload ref='upload' :action="action"
+                       :before-upload="beforeUpload" :headers="headers" :on-error="onError"
+                       :on-success="handleSuccessUp" :show-file-list="false" accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'>
+              <el-button :loading="upLoading" size="small" type="primary">瀵煎叆</el-button>
+            </el-upload>
+          </div>
+        </template>
+        <template v-slot:table>
+          <ZTTable
+            ref="yearTable"
+            :column="yearColumnData"
+            :height="'25vh'"
+            :highlightCurrentRow="true"
+            :rowClick="rowClick"
+            :table-data="yearTableData"
+            :table-loading="yearLoading"
+            style="margin-top: 0.5em;padding: 0 15px;"
+          >
+          </ZTTable>
+          <el-divider></el-divider>
+          <!-- 鍒嗛〉 -->
+          <div class="pagination">
+            <div></div>
+            <el-pagination :page-size="yearPage.size" :page-sizes="[10, 20, 30, 40]"
+                           :total="yearPage.total" layout="total, sizes, prev, pager, next, jumper"
+                           @current-change="handleYearCurrent" @size-change="handleYearSizeChange">
+            </el-pagination>
+          </div>
+        </template>
+      </TableCard>
+    </div>
+    <div  class="table-card">
+      <TableCard title="骞村害璁″垝鏄庣粏琛�">
+        <template v-slot:form>
+          <div class="items_center">
+            <span>鐩戞帶鐩殑锛�</span>
+            <el-input v-model="yearDetailForm.monitorPurpose" class="search" placeholder="璇疯緭鍏�" size="small"></el-input>
+            <span>鐩戞帶椤圭洰锛�</span>
+            <el-input v-model="yearDetailForm.monitorProject" class="search" placeholder="璇疯緭鍏�" size="small"></el-input>
+            <el-button size="small" type="primary" @click="getYearDetailPlanList">鏌ヨ</el-button>
+            <el-button size="small" @click="clearDetail">閲嶇疆</el-button>
+          </div>
+          <div>
+            <el-button size="small" type="primary" @click="showDialog('add')">鏂板</el-button>
+          </div>
+        </template>
+        <template v-slot:table>
+          <ZTTable :column="yearDetailColumnData" :height="'25vh'" :table-data="yearDetailTableData"
+                   :table-loading="yearDetailLoading" style="margin-top: 18px; padding: 0 15px;">
+          </ZTTable>
+          <el-divider></el-divider>
+          <!-- 鍒嗛〉 -->
+          <div class="pagination">
+            <div></div>
+            <el-pagination :page-size="yearDetailPage.size" :page-sizes="[10, 20, 30, 40]"
+                           :total="yearDetailPage.total" layout="total, sizes, prev, pager, next, jumper"
+                           @current-change="handleYearDetailCurrent" @size-change="handleYearDetailSizeChange">
+            </el-pagination>
+          </div>
+        </template>
+      </TableCard>
+    </div>
+    <!--鏂板淇敼寮规-->
+    <detail-form-dialog v-if="formDia" ref="formDia" :qualityMonitorId="qualityMonitorId" @closeDia="closeDia"></detail-form-dialog>
+    <!--瀹炴柦娴佺▼寮规-->
+    <carry-out-dialog v-if="carryOutDia" ref="carryOutDia" :qualityMonitorId="qualityMonitorId" @closeDia="closeCarryOutDia"></carry-out-dialog>
+    <!--璇勪环娴佺▼寮规-->
+    <evaluate-dialog v-if="evaluateDialog" ref="evaluateDialog" @closeEvaDia="closeEvaDia"></evaluate-dialog>
+    <el-dialog :visible.sync="examineDialog" title="瀹℃牳" width="30%" @close="closeExamineDia">
+      <span>
+        瀹℃牳澶囨敞锛�
+        <el-input v-model="examineInfo.examineRemark" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="examineLoading" @click="handleReview(0)">涓嶉�氳繃</el-button>
+        <el-button :loading="examineLoading" type="primary" @click="handleReview(1)">閫� 杩�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="ratifyDialog" title="鎵瑰噯" width="30%" @close="closeRatifyDia">
+      <span>
+        鎵瑰噯澶囨敞锛�
+        <el-input v-model="ratifyInfo.ratifyRemark" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="ratifyLoading" @click="handleRatify(0)">涓嶆壒鍑�</el-button>
+        <el-button :loading="ratifyLoading" type="primary" @click="handleRatify(1)">鎵� 鍑�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import UploadExcel from '../caorui/Department/components/Plan/UploadExcel.vue';
+import TableCard from '../caorui/TableCard/index.vue';
+import ZTTable from '../caorui/ZTTable/index.vue';
+import DetailFormDialog from '../do/a7-Ensure-results-validity/detailFormDialog.vue';
+import CarryOutDialog from '../do/a7-Ensure-results-validity/carryOutDialog.vue';
+import EvaluateDialog from '../do/a7-Ensure-results-validity/evaluateDialog.vue';
+import fileDownload from "../../util/file";
+
+export default {
+  name: 'a7-Ensure-results-validity',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: { EvaluateDialog, CarryOutDialog, DetailFormDialog, ZTTable, TableCard, UploadExcel },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      yearForm: {
+        monitorName: '',
+      },
+      yearPage: {
+        current: 1,
+        size: 20,
+        total: 0
+      },
+      yearColumnData: [
+        {
+          label: '璁″垝鍚嶇О',
+          prop: 'monitorName',
+          minWidth: '150px'
+        }, {
+          label: '缂栧埗浜�',
+          prop: 'writeName',
+          minWidth: '100'
+        }, {
+          label: '缂栧埗鏃ユ湡',
+          prop: 'writeTime',
+          minWidth: '160'
+        }, {
+          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: 'examineName',
+          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: 'ratifyName',
+          minWidth: '100'
+        },{
+          label: '鎵瑰噯鏃ユ湡',
+          prop: 'ratifyTime',
+          minWidth: '160'
+        }, {
+          label: '鍒涘缓鏃ユ湡',
+          prop: 'createTime',
+          minWidth: '160'
+        }, {
+          label: '鍒涘缓浜�',
+          prop: 'createUser',
+          minWidth: '100'
+        }, {
+          dataType: 'action',
+          minWidth: '200',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '瀹℃牳',
+              type: 'text',
+              disabled: (row) => {
+                if (row.examineStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+              clickFun: (row) => {
+                this.examinePlan(row)
+              }
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              disabled: (row) => {
+                if (row.ratifyStatus === 1 || row.examineStatus !== 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+              clickFun: (row) => {
+                this.approvalPlan(row)
+              }
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleDown(row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delPlan(row)
+              }
+            }
+          ]
+        }],
+      yearTableData: [],  // 骞磋〃
+      yearLoading: false,
+      yearDetailForm: {
+        monitorPurpose: '',
+        monitorProject: ''
+      },
+      yearDetailColumnData: [
+        {
+          label: '鐩戞帶鐩殑',
+          prop: 'monitorPurpose',
+          width: '150px',
+          showOverflowTooltip: true,
+        }, {
+          label: '璁″垝寮�灞曟椂闂�',
+          prop: 'plannedTime',
+          minWidth: '150px'
+        }, {
+          label: '鐩戞帶椤圭洰',
+          prop: 'monitorProject',
+          minWidth: '150px'
+        }, {
+          label: '鍙傚姞鍗曚綅锛堜汉鍛橈級',
+          prop: 'participant',
+          minWidth: '150px'
+        }, {
+          label: '棰勭畻锛堝厓锛�',
+          prop: 'budget',
+          minWidth: '150px'
+        },{
+          label: '缁勭粐浜哄憳',
+          prop: 'organization',
+          minWidth: '150px'
+        },{
+          label: '鐩戞帶鏂瑰紡',
+          prop: 'monitorWay',
+          minWidth: '150px'
+        }, {
+          dataType: 'action',
+          width: '180',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.showDialog('edit', row)
+              }
+            },
+            {
+              name: '瀹炴柦',
+              type: 'text',
+              clickFun: (row) => {
+                this.carryOut(row)
+              }
+            },
+            {
+              name: '璇勪环',
+              type: 'text',
+              clickFun: (row) => {
+                this.evaluate(row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delYearPlanDetail(row)
+              }
+            }
+          ]
+        }
+      ],
+      yearDetailTableData: [], // 骞存槑缁嗚〃
+      yearDetailLoading: false,
+      yearDetailPage: {
+        current: 1,
+        size: 20,
+        total: 0
+      },
+      formDia: false,
+      qualityMonitorId: '',
+      carryOutDia: false,
+      evaluateDialog: false,
+      examineDialog: false,
+      examineLoading: false,
+      ratifyDialog: false,
+      ratifyLoading: false,
+      examineInfo: {},
+      ratifyInfo: {},
+      upLoading: false,
+    };
+  },
+  mounted() {
+    this.getYearPlanList()
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鏌ヨ骞村害璁″垝琛�
+    getYearPlanList () {
+      const entity = {
+        monitorName: this.yearForm.monitorName,
+      }
+      const page = this.yearPage
+      this.yearLoading = true
+      this.$axios.post(this.$api.qualityMonitor.pageQualityMonitor, { entity, page }, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.yearLoading = false
+        if (res.code === 201) return
+        this.yearTableData = res.data.records
+        this.yearPage.total = res.data.total
+        if (this.yearTableData.length > 0) {
+          this.rowClick(this.yearTableData[0])
+        }
+      }).catch(err => {
+        console.log('err---', err);
+        this.yearLoading = false
+      })
+    },
+    clearYear () {
+      this.yearForm.monitorName = ''
+      this.getYearPlanList()
+    },
+    // 瀵煎叆娴佺▼
+    beforeUpload(file) {
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        return false;
+      } else {
+        this.upLoading = true;
+        return true;
+      }
+    },
+    onError(err, file, fileList) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+    },
+    handleSuccessUp(response) {
+      this.upLoading = false;
+      if (response.code == 200) {
+        this.$message.success('涓婁紶鎴愬姛');
+        this.getYearPlanList()
+      }
+    },
+    // 瀹℃牳
+    examinePlan (row) {
+      this.examineDialog = true
+      this.examineInfo = row
+    },
+    handleReview (examineStatus) {
+      // 瀹℃牳鐘舵�� , 0 涓嶉�氳繃, 1閫氳繃
+      this.examineInfo.examineStatus = examineStatus
+      this.examineLoading = true
+      this.$axios.post(this.$api.qualityMonitor.examineQualityMonitor, this.examineInfo, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.examineLoading = false
+        if (res.code === 201) return
+        this.$message.success('鎿嶄綔鎴愬姛')
+        this.closeExamineDia()
+      }).catch(err => {
+        console.log('err---', err);
+        this.examineLoading = false
+      })
+    },
+    closeExamineDia () {
+      this.examineDialog = false
+      this.examineInfo.examineRemark = ''
+      this.getYearPlanList()
+    },
+    // 鎵瑰噯
+    approvalPlan (row) {
+      this.ratifyDialog = true
+      this.ratifyInfo = row
+    },
+    handleRatify (ratifyStatus) {
+      // 鎵瑰噯鐘舵�� , 0 涓嶉�氳繃, 1閫氳繃
+      this.ratifyInfo.ratifyStatus = ratifyStatus
+      this.ratifyLoading = true
+      this.$axios.post(this.$api.qualityMonitor.ratifyQualityMonitor, this.ratifyInfo, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.ratifyLoading = false
+        if (res.code === 201) return
+        this.$message.success('鎿嶄綔鎴愬姛')
+        this.closeRatifyDia()
+      }).catch(err => {
+        console.log('err---', err);
+        this.ratifyLoading = false
+      })
+    },
+    closeRatifyDia () {
+      this.ratifyDialog = false
+      this.ratifyInfo.ratifyRemark = ''
+      this.getYearPlanList()
+    },
+    // 瀵煎嚭
+    handleDown (row) {
+      this.$axios.get(this.$api.qualityMonitor.exportQualityMonitorDetail + '?qualityMonitorId=' + row.qualityMonitorId,{responseType: "blob"}).then(res => {
+        this.outLoading = false
+        this.$message.success('瀵煎嚭鎴愬姛')
+        const blob = new Blob([res],{ type: 'application/msword' });
+        const url = URL.createObjectURL(blob);
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.monitorName + '.docx';
+        link.click();
+      })
+    },
+    // 鍒犻櫎杩涘害璁″垝琛�
+    delPlan (row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.yearLoading = true
+        this.$axios.get(this.$api.qualityMonitor.delQualitySupervise + '?qualityMonitorId=' + row.qualityMonitorId).then(res => {
+          this.yearLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.getYearPlanList()
+        }).catch(err => {
+          this.yearLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 骞村害璁″垝琛ㄦ牸锛岀偣鍑昏鏁版嵁鍚庡埛鏂拌鎯�
+    rowClick(row) {
+      this.qualityMonitorId = row.qualityMonitorId
+      this.getYearDetailPlanList()
+    },
+    // 鑾峰彇骞村害鏄庣粏琛�
+    getYearDetailPlanList () {
+      const entity = {
+        qualityMonitorId: this.qualityMonitorId,
+        monitorPurpose: this.yearDetailForm.monitorPurpose,
+        monitorProject: this.yearDetailForm.monitorProject,
+      }
+      const page = this.yearDetailPage
+      this.yearDetailLoading = true
+      this.$axios.post(this.$api.qualityMonitor.pageQualityMonitorDetail, { entity, page }, {
+        headers: {
+          "Content-Type": "application/json"
+        },
+        noQs: true
+      }).then(res => {
+        this.yearDetailLoading = false
+        if (res.code === 201) return
+        this.yearDetailTableData = res.data.records
+        this.yearDetailPage.total = res.data.total
+      }).catch(err => {
+        console.log('err---', err);
+        this.yearDetailLoading = false
+      })
+    },
+    // 閲嶇疆鏄庣粏琛�
+    clearDetail () {
+      this.yearDetailForm = {
+        monitorPurpose: '',
+        monitorProject: ''
+      }
+      this.getYearDetailPlanList()
+    },
+    // 鏄庣粏琛ㄥ疄鏂�
+    carryOut (row) {
+      this.carryOutDia = true
+      this.$nextTick(() => {
+        this.$refs.carryOutDia.openDia(row)
+      })
+    },
+    closeCarryOutDia () {
+      this.carryOutDia = false
+      this.getYearDetailPlanList()
+    },
+    // 鎵撳紑璇勪环寮规
+    evaluate (row) {
+      this.evaluateDialog = true
+      this.$nextTick(() => {
+        this.$refs.evaluateDialog.openDia(row)
+      })
+    },
+    closeEvaDia () {
+      this.evaluateDialog = false
+      this.getYearDetailPlanList()
+    },
+    // 鎵撳紑骞村害鏄庣粏鏂板銆佷慨鏀瑰脊妗�
+    showDialog (type, row) {
+      this.formDia = true
+      this.$nextTick(() => {
+        this.$refs.formDia.openDia(type, row)
+      })
+    },
+    closeDia () {
+      this.formDia = false
+      this.getYearDetailPlanList()
+    },
+    delYearPlanDetail (row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.yearDetailLoading = true
+        this.$axios.get(this.$api.qualityMonitor.delQualityMonitorDetail + '?qualityMonitorDetailsId=' + row.qualityMonitorDetailsId).then(res => {
+          this.yearDetailLoading = false
+          if (res.code === 201) return
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.getYearDetailPlanList()
+        }).catch(err => {
+          this.yearDetailLoading = false
+          console.log('err---', err);
+        })
+      })
+    },
+    // 骞磋鍒掑垎椤�
+    handleYearCurrent(page) {
+      this.yearPage.current = page
+      this.getYearPlanList()
+    },
+    handleYearSizeChange(size) {
+      this.yearPage.size = size
+      this.getYearPlanList()
+    },
+    // 骞存槑缁嗚鍒掑垎椤�
+    handleYearDetailCurrent(page) {
+      this.yearDetailPage.current = page
+      this.getYearDetailPlanList()
+    },
+    handleYearDetailSizeChange(size) {
+      this.yearDetailPage.size = size
+      this.getYearDetailPlanList()
+    },
+  },
+  // 鐢ㄤ簬涓婁紶鏂囦欢鐨勪俊鎭�
+  computed: {
+    headers() {
+      return {
+        'token': sessionStorage.getItem('token')
+      }
+    },
+    action() {
+      return this.javaApi + this.$api.qualityMonitor.importQualityMonitor
+    }
+  },
+};
+</script>
+
+<style scoped>
+.table-card {
+  background-color: #ffffff;
+}
+.flex_column {
+  display: flex;
+  height: 80vh;
+  flex-direction: column;
+  overflow: auto;
+  justify-content: space-between;
+}
+
+.pagination {
+  display: flex;
+  justify-content: space-between
+}
+
+.items_center {
+  display: flex;
+  align-items: center;
+}
+
+.date_box {
+  margin: 0 5px;
+}
+
+.search {
+  width: 150px;
+  padding: 0 16px;
+}
+</style>

--
Gitblit v1.9.3