From 28f295e0fcea7bf429cf8e3b79468e70e3a2d3ef Mon Sep 17 00:00:00 2001
From: chenrui <1187576398@qq.com>
Date: 星期五, 28 二月 2025 11:18:52 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 src/views/CNAS/personnel/personnelInfo/index.vue                         |  325 +++
 src/api/cnas/personal/personalList.js                                    |  179 +
 src/api/cnas/personal/personalTraining.js                                |  141 +
 src/api/system/user.js                                                   |    8 
 src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue        |  783 +++++++
 src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue              |  249 ++
 src/views/CNAS/personnel/personalOverview/index.vue                      |    0 
 src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue           |  317 +++
 src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue          |  336 +++
 src/api/cnas/personal/personalOverview.js                                |    0 
 src/views/CNAS/personnel/personnelInfo/components/Edit.vue               |  453 ++++
 src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue         |  179 +
 src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue    | 1115 +++++++++++
 src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue        |  175 +
 src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue |  358 +++
 src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue                  |  276 ++
 src/views/business/materialOrder/index.vue                               |   24 
 src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue     |  393 +++
 src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue       |  621 ++++++
 19 files changed, 5,927 insertions(+), 5 deletions(-)

diff --git a/src/api/cnas/personal/personalList.js b/src/api/cnas/personal/personalList.js
new file mode 100644
index 0000000..567c481
--- /dev/null
+++ b/src/api/cnas/personal/personalList.js
@@ -0,0 +1,179 @@
+import request from "@/utils/request";
+
+// 鍒犻櫎浜哄憳鏄庣粏鎵�鍦ㄧ粍缁囨灦鏋�
+export function delUserDepardLimsId(query) {
+  return request({
+    url: "/system/newUser/delUserDepardLimsId",
+    method: "delete",
+    params: query,
+  });
+}
+// 淇敼浜哄憳鏄庣粏鎵�鍦ㄧ粍缁囨灦鏋�
+export function upUserDepardLimsId(query) {
+  return request({
+    url: "/system/newUser/upUserDepardLimsId",
+    method: "post",
+    data: query,
+  });
+}
+// 瀵煎嚭
+export function exportPersonBasicInfo(query) {
+  return request({
+    url: "/personBasicInfo/exportPersonBasicInfo",
+    method: "get",
+    data: query,
+    responseType: "blob"
+  });
+}
+// 瀵煎嚭
+export function exportPersonBasicInfoById(query) {
+  return request({
+    url: "/personBasicInfo/exportPersonBasicInfoById",
+    method: "get",
+    data: query,
+    responseType: "blob"
+  });
+}
+// 鑾峰彇浜哄憳鍒楄〃
+export function basicInformationOfPersonnelSelectPage(query) {
+  return request({
+    url: "/personBasicInfo/basicInformationOfPersonnelSelectPage",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎閮ㄩ棬
+export function delDepartmentLims(query) {
+  return request({
+    url: "/department/delDepartmentLims",
+    method: "delete",
+    params: query
+  });
+}
+// 娣诲姞閮ㄩ棬
+export function addDepartmentLims(query) {
+  return request({
+    url: "/department/addDepartmentLims",
+    method: "post",
+    data: query
+  });
+}
+// 鏌ヨCNAS浜哄憳渚ц竟鏍�
+export function selectCNSAPersonTree() {
+  return request({
+    url: "/personBasicInfo/selectCNSAPersonTree",
+    method: "get"
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅闄勪欢鍒楄〃
+export function getBasicInfoFileList(query) {
+  return request({
+    url: "/personBasicInfo/getBasicInfoFileList",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎闄勪欢
+export function delBasicInfoFileList(query) {
+  return request({
+    url: "/personBasicInfo/delBasicInfoFileList",
+    method: "delete",
+    params: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻鏂板
+export function addBasicInfoWork(query) {
+  return request({
+    url: "/personBasicInfo/addBasicInfoWork",
+    method: "post",
+    data: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻淇敼
+export function updateBasicInfoWorkList(query) {
+  return request({
+    url: "/personBasicInfo/updateBasicInfoWorkList",
+    method: "post",
+    data: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻鍒犻櫎
+export function delBasicInfoWorkList(query) {
+  return request({
+    url: "/personBasicInfo/delBasicInfoWorkList",
+    method: "delete",
+    params: query
+  });
+}
+// 浜哄憳鍩硅鍩烘湰淇℃伅宸ヤ綔缁忓巻鏌ヨ
+export function getBasicInfoWorkList(query) {
+  return request({
+    url: "/personBasicInfo/getBasicInfoWorkList",
+    method: "get",
+    params: query
+  });
+}
+// 鑾峰彇闄勪欢
+export function getAnnex(query) {
+  return request({
+    url: "/personBasicInfo/getAnnex",
+    method: "get",
+    params: query
+  });
+}
+// 鏇存柊闄勪欢
+export function updateAnnex(query) {
+  return request({
+    url: "/personBasicInfo/updateAnnex",
+    method: "post",
+    data: query
+  });
+}
+// 鏇存柊闄勪欢
+export function getAnnexByUserId(query) {
+  return request({
+    url: "/personBasicInfo/getAnnexByUserId",
+    method: "get",
+    params: query
+  });
+}
+// 娣诲姞闄勪欢
+export function addAnnex(query) {
+  return request({
+    url: "/personBasicInfo/addAnnex",
+    method: "post",
+    data: query
+  });
+}
+// 鍒犻櫎闄勪欢
+export function deleteAnnex(query) {
+  return request({
+    url: "/personBasicInfo/deleteAnnex",
+    method: "delete",
+    params: query
+  });
+}
+// 浜哄憳鍩烘湰淇℃伅鏌ヨ
+export function getCNASPersonnelInfo(query) {
+  return request({
+    url: "/personBasicInfo/getCNASPersonnelInfo",
+    method: "get",
+    params: query
+  });
+}
+// 浜哄憳鍩烘湰淇℃伅淇濆瓨
+export function saveCNASPersonnelInfo(query) {
+  return request({
+    url: "/personBasicInfo/saveCNASPersonnelInfo",
+    method: "post",
+    data: query
+  });
+}
+// 鍒犻櫎鏂囦欢
+export function deleteCNASFile(query) {
+  return request({
+    url: "/personBasicInfo/deleteCNASFile",
+    method: "delete",
+    params: query
+  });
+}
diff --git a/src/api/cnas/personnel/personnelOverview.js b/src/api/cnas/personal/personalOverview.js
similarity index 100%
rename from src/api/cnas/personnel/personnelOverview.js
rename to src/api/cnas/personal/personalOverview.js
diff --git a/src/api/cnas/personal/personalTraining.js b/src/api/cnas/personal/personalTraining.js
new file mode 100644
index 0000000..d814ce4
--- /dev/null
+++ b/src/api/cnas/personal/personalTraining.js
@@ -0,0 +1,141 @@
+import request from "@/utils/request";
+
+// 鏌ヨ浜哄憳鍩硅
+export function personTraining(query) {
+  return request({
+    url: "/personTraining/personTraining",
+    method: "get",
+    params: query
+  });
+}
+// 鏌ヨ鍩硅璁″垝骞村害璁″垝鏄庣粏琛�
+export function queryTheAnnualPlanDetailsTable(query) {
+  return request({
+    url: "/personTraining/queryTheAnnualPlanDetailsTable",
+    method: "get",
+    params: query
+  });
+}
+// 鍒犻櫎浜哄憳鍩硅淇℃伅
+export function personTrainingDelete(query) {
+  return request({
+    url: "/personTraining/personTrainingDelete",
+    method: "delete",
+    params: query
+  });
+}
+// 瀹℃牳 骞村害浜哄憳鍩硅
+export function reviewAnnualPersonnelTraining(query) {
+  return request({
+    url: "/personTraining/reviewAnnualPersonnelTraining",
+    method: "post",
+    data: query
+  });
+}
+// 鎵瑰噯 骞村害浜哄憳鍩硅
+export function approveAnnualPersonnelTraining(query) {
+  return request({
+    url: "/personTraining/approveAnnualPersonnelTraining",
+    method: "post",
+    data: query
+  });
+}
+// 瀵煎嚭浜哄憳鍩硅
+export function exportPersonTraining(query) {
+  return request({
+    url: "/personTraining/exportPersonTraining",
+    method: "get",
+    params: query,
+    responseType: "blob"
+  });
+}
+// 瀵煎嚭浜哄憳鍩硅涓庤�冩牳璁板綍
+export function exportPersonTrainingRecord(query) {
+  return request({
+    url: "/personTraining/exportPersonTrainingRecord",
+    method: "get",
+    params: query,
+    responseType: "blob"
+  });
+}
+// 鎵归噺鍒犻櫎 骞村害璁″垝鏄庣粏琛�
+export function deleteAnnualPlanDetailTable(query) {
+  return request({
+    url: "/personTraining/deleteAnnualPlanDetailTable",
+    method: "delete",
+    params: query
+  });
+}
+// 鎵归噺鍒犻櫎 骞村害璁″垝鏄庣粏琛�
+export function addOrUpdatePersonTrainingDetailed(query) {
+  return request({
+    url: "/personTraining/addOrUpdatePersonTrainingDetailed",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳璁板綍 鏌ヨ
+export function trainingAndAssessmentRecordsPage(query) {
+  return request({
+    url: "/personTraining/trainingAndAssessmentRecordsPage",
+    method: "get",
+    params: query
+  });
+}
+// 鍩硅涓庤�冩牳 澶辩劍鏇存柊
+export function outOfFocusPreservation(query) {
+  return request({
+    url: "/personTraining/outOfFocusPreservation",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳 鏂板浜哄憳
+export function newPersonnelAddedToTrainingRecords(query) {
+  return request({
+    url: "/personTraining/newPersonnelAddedToTrainingRecords",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳 鍒犻櫎浜哄憳
+export function deleteTrainingAndAssessmentRecords(query) {
+  return request({
+    url: "/personTraining/deleteTrainingAndAssessmentRecords",
+    method: "delete",
+    params: query
+  });
+}
+// 鍩硅涓庤�冩牳璁板綍 鎻愪氦
+export function trainingAndAssessmentRecordsAdded(query) {
+  return request({
+    url: "/personTraining/trainingAndAssessmentRecordsAdded",
+    method: "post",
+    data: query
+  });
+}
+// 鍩硅涓庤�冩牳璁板綍 鎻愪氦璇勪环
+export function trainingAndAssessmentRecordsEvaluate(query) {
+  return request({
+    url: "/personTraining/trainingAndAssessmentRecordsEvaluate",
+    method: "post",
+    data: query
+  });
+}
+
+// 浜哄憳鍩硅璇︽儏闄勪欢鍒楄〃
+export function getTrainingDetailedFileList(query) {
+  return request({
+    url: "/personTraining/getTrainingDetailedFileList",
+    method: "get",
+    params: query
+  });
+}
+// 浜哄憳鍩硅璇︽儏闄勪欢鍒犻櫎
+export function delTrainingDetailedFileList(query) {
+  return request({
+    url: "/personTraining/delTrainingDetailedFileList",
+    method: "delete",
+    params: query
+  });
+}
diff --git a/src/api/system/user.js b/src/api/system/user.js
index 14b4c2b..8ecfc5a 100644
--- a/src/api/system/user.js
+++ b/src/api/system/user.js
@@ -187,3 +187,11 @@
     method: 'get'
   })
 }
+// 鑾峰彇鐢ㄦ埛鍒楄〃
+export function selectUserCondition(query) {
+  return request({
+    url: "/system/newUser/selectUserCondition",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/views/CNAS/personnel/personnelOverview/index.vue b/src/views/CNAS/personnel/personalOverview/index.vue
similarity index 100%
rename from src/views/CNAS/personnel/personnelOverview/index.vue
rename to src/views/CNAS/personnel/personalOverview/index.vue
diff --git a/src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue b/src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue
new file mode 100644
index 0000000..564fee1
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue
@@ -0,0 +1,175 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="addTrainingPlanDia" title="鏂板鍩硅璁″垝" width="50%" @close="closeAdd">
+      <div class="body">
+        <el-form ref="trainingPlanForm" :model="trainingPlan" label-position="right" label-width="90px" :rules="trainingPlanRules">
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鏃ユ湡:" prop="trainingDate">
+                <el-date-picker v-model="trainingPlan.trainingDate" format="yyyy-MM"
+                                placeholder="閫夋嫨鏃ユ湡" size="small" value-format="yyyy-MM"
+                                type="month" style="width: 100%"></el-date-picker>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="璇炬椂:" prop="classHour">
+                <el-input type="number" v-model="trainingPlan.classHour" label="鎻忚堪鏂囧瓧" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鐩爣:" prop="trainingObjectives">
+                <el-input v-model="trainingPlan.trainingObjectives" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍙傚姞瀵硅薄:" prop="participants">
+                <el-input v-model="trainingPlan.participants" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鍐呭:" prop="trainingContent">
+                <el-input v-model="trainingPlan.trainingContent" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅璁插笀:" prop="trainingLecturerId">
+                <el-select v-model="trainingPlan.trainingLecturerId"
+                           clearable filterable
+                           placeholder="璇烽�夋嫨" size="small" style="width: 100%;">
+                  <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍩硅鏂瑰紡:" prop="trainingMode">
+                <el-input v-model="trainingPlan.trainingMode" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="涓惧姙閮ㄩ棬:" prop="holdingDepartment">
+                <el-input v-model="trainingPlan.holdingDepartment" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="澶囨敞:" prop="remarks">
+                <el-input v-model="trainingPlan.remarks" placeholder="璇疯緭鍏�" size="small"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+				<el-button @click="closeAdd">鍙� 娑�</el-button>
+        <el-button type="primary" :loading="submitAddLoading" @click="submitAdd">纭� 瀹�</el-button>
+			</span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {addOrUpdatePersonTrainingDetailed} from "@/api/cnas/personal/personalTraining";
+import {selectUserCondition} from "@/api/system/user";
+
+export default {
+  props: {
+    currentChangeRow: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+  },
+  name: 'Add',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {},
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      addTrainingPlanDia: false,
+      submitAddLoading: false,
+      trainingPlan: {
+        planId: '',
+        id: '',
+        trainingDate: '',
+        classHour: '',
+        trainingObjectives: '',
+        participants: '',
+        trainingContent: '',
+        trainingLecturerId: '',
+        trainingMode: '',
+        holdingDepartment: '',
+        remarks: '',
+      },
+      trainingPlanRules: {
+        trainingDate: [{ required: true, message: '璇烽�夋嫨鍩硅鏃ユ湡', trigger: 'change' }],
+        trainingContent: [{ required: true, message: '璇疯緭鍏ュ煿璁唴瀹�', trigger: 'blur' }],
+        trainingLecturerId: [{ required: true, message: '璇烽�夋嫨鍩硅璁插笀', trigger: 'blur' }],
+      },
+      responsibleOptions: [],
+      operationType: ''
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    showDialog(id, type, row) {
+      this.addTrainingPlanDia = true;
+      this.operationType = type
+      if (this.operationType === 'edit') {
+        this.trainingPlan = this.HaveJson(row)
+      } else {
+        this.trainingPlan = {
+          id: '',
+          trainingDate: '',
+          classHour: '',
+          trainingObjectives: '',
+          participants: '',
+          trainingContent: '',
+          trainingLecturerId: '',
+          trainingMode: '',
+          holdingDepartment: '',
+          remarks: '',
+        }
+      }
+      this.trainingPlan.planId = id
+      this.getUserList()
+    },
+    // 鎻愪氦鏂板
+    submitAdd() {
+      this.$refs.trainingPlanForm.validate((valid) => {
+        if (valid) {
+          this.submitAddLoading = true
+          this.trainingPlan.planId = this.currentChangeRow.id
+          const personTrainingDetailed = this.trainingPlan
+          addOrUpdatePersonTrainingDetailed(personTrainingDetailed).then(res => {
+            this.submitAddLoading = false
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.closeAdd();
+            }
+          }).catch(() => {
+            this.submitAddLoading = false
+          })
+        }
+      })
+    },
+    // 鍏抽棴寮规
+    closeAdd() {
+      this.$refs['trainingPlanForm'].resetFields();
+      this.$emit('search')
+      this.addTrainingPlanDia = false;
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      selectUserCondition().then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      })
+    },
+  },
+};
+</script>
+
+<style scoped>
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/components/Edit.vue b/src/views/CNAS/personnel/personnelInfo/components/Edit.vue
new file mode 100644
index 0000000..6dff2e6
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/Edit.vue
@@ -0,0 +1,453 @@
+<template>
+  <div>
+    <div class="page-header">
+      <h4><span class="line"></span><span>鍩硅涓庤�冩牳璁板綍</span></h4>
+      <div class="btns">
+        <el-button size="small" type="primary" @click="submitForm(3)" v-if="this.currentRow.state !== 1">鎾ら攢</el-button>
+        <el-button size="small" type="primary" @click="submitForm(0)" v-if="this.currentRow.state !== 1">鎻愪氦</el-button>
+        <el-button size="small" @click="$emit('goBack')">杩斿洖</el-button>
+      </div>
+    </div>
+    <div class="form_title">
+      <el-row>
+        <el-col :span="7">
+          <span class="form_label">鍩硅鍐呭锛�</span>
+          <span> {{ trainingForm.trainingContent }} </span>
+        </el-col>
+        <el-col :span="5">
+          <span class="form_label">鐘舵�侊細</span>
+          <el-tag v-if="trainingForm.state === 1" type="success">宸插畬鎴�</el-tag>
+          <el-tag v-if="trainingForm.state === 2" type="warning">寰呰瘎浠�</el-tag>
+          <el-tag v-if="trainingForm.state === 3" type="primary">鏈紑濮�</el-tag>
+        </el-col>
+        <el-col :span="4">
+          <span class="form_label">鍩硅璁插笀锛�</span>
+          <span> {{ trainingForm.trainingLecturerName }} </span>
+        </el-col>
+      </el-row>
+      <el-row style="margin: 15px 0">
+        <el-form>
+          <el-row>
+          <el-col :span="5">
+            <el-form-item label="鍩硅鏃ユ湡:">
+              <el-date-picker v-model="trainingForm.openingTime" format="yyyy-MM-dd" :disabled="currentRow.state !== 3"
+                              placeholder="閫夋嫨鏃ユ湡" size="small" value-format="yyyy-MM-dd"
+                              type="date" style="width: 60%"></el-date-picker>
+            </el-form-item>
+          </el-col>
+            <el-col :span="7">
+              <el-form-item label="鍩硅鍦扮偣">
+                <el-input v-model="trainingForm.placeTraining" :disabled="currentRow.state !== 3" :rows="2" placeholder="璇疯緭鍏�"
+                          size="small" style="width: 60%" type="text"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="璇勪环浜�">
+                <el-select v-model="trainingForm.assessmentUserId" :disabled="currentRow.state !== 3" placeholder="璇烽�夋嫨" size="small" style="width: 50%">
+                  <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鑰冩牳鏂瑰紡">
+                <el-input v-model="trainingForm.assessmentMethod" :disabled="currentRow.state !== 3" :rows="2" placeholder="璇疯緭鍏�"
+                          size="small" style="width: 79%" type="textarea"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="璇勪环鏃堕棿">
+                <el-date-picker v-model="trainingForm.assessmentDate" :disabled="currentRow.state !== 2 || isDisabled"
+                                type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" size="small"
+                                placeholder="閫夋嫨鏃ユ湡">
+                </el-date-picker>
+              </el-form-item>
+            </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏈鍩硅缁煎悎璇勪环">
+              <el-input v-model="trainingForm.comprehensiveAssessment" :disabled="currentRow.state !== 2 || isDisabled" :rows="2" placeholder="璇疯緭鍏�"
+                        size="small" style="width: 68%" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+          </el-row>
+        </el-form>
+      </el-row>
+    </div>
+    <el-divider>浜哄憳璇︽儏</el-divider>
+    <div>
+      <div class="items_center">
+        <span>濮撳悕</span>
+        <el-input v-model="userName" class="search" placeholder="璇疯緭鍏�"
+                  size="small"></el-input>
+        <el-button size="small" type="primary" @click="getInfo">鏌ヨ</el-button>
+      </div>
+      <div class="items_btn">
+        <el-button :disabled="currentRow.state === 1" size="small" type="primary" @click="addPerson">鏂板浜哄憳</el-button>
+        <el-button :disabled="currentRow.state === 1" size="small" @click="batchDelete">鎵归噺鍒犻櫎</el-button>
+      </div>
+      <el-table :data="trainingTableData" height="calc(100vh - 30em)" stripe style="width: 100%"
+                @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column label="搴忓彿" type="index" width="60"></el-table-column>
+        <el-table-column label="濮撳悕" prop="userName"></el-table-column>
+        <el-table-column label="宸ュ彿" prop="account"></el-table-column>
+        <el-table-column label="瑙掕壊" prop="roleName"></el-table-column>
+        <el-table-column label="鐢佃瘽鍙风爜" prop="phone"></el-table-column>
+        <el-table-column label="鑰冩牳缁撴灉" prop="examinationResults">
+          <template v-slot="scope">
+            <el-input v-model="scope.row.examinationResults" :disabled="currentRow.state === 1" clearable size="small" style="width: 100%" @blur="updatePersonResult(scope.row)"></el-input>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <el-dialog :visible.sync="selectUserDia" title="閫夋嫨鐢ㄦ埛" width="70%">
+      <div class="search" style="margin-bottom: 9px;">
+        <div class="search_thing">
+          <div class="search_label">鐢ㄦ埛鍚嶏細</div>
+          <div class="search_input">
+            <el-input
+              v-model="addUserTableInfo.name"
+              clearable
+              placeholder="璇疯緭鍏�"
+              size="small"
+              @keyup.enter.native="selectUserList"
+            ></el-input>
+          </div>
+        </div>
+      </div>
+      <div v-if="selectUserDia" class="body" style="height: 60vh;">
+        <lims-table :tableData="tableData1" :column="column1"
+                    :isSelection="true" :handleSelectionChange="selectMethod"
+                    @pagination="pagination1" :height="'calc(100vh - 290px)'"
+                    :page="page1" :tableLoading="tableLoading1"></lims-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="selectUserDia = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="selectUser">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+import limsTable from "@/components/Table/lims-table.vue";
+import {selectUserCondition} from "@/api/business/inspectionTask";
+import {mapGetters} from "vuex";
+import {
+  newPersonnelAddedToTrainingRecords,
+  outOfFocusPreservation, trainingAndAssessmentRecordsAdded, trainingAndAssessmentRecordsEvaluate,
+  trainingAndAssessmentRecordsPage
+} from "@/api/cnas/personal/personalTraining";
+
+export default {
+  name: 'Edit',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {limsTable},
+  props: {
+    currentRow: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+  },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      isSelectedList: [], // 绂佺敤鐨勫閫�
+      userName: undefined,
+      trainingForm: {
+        code: '111111',
+        date: '2024-10-10',
+      },
+      trainingColumn: [
+        {
+          label: '濮撳悕',
+          prop: 'userName'
+        },
+        {
+          label: '宸ュ彿',
+          prop: 'account'
+        },
+        {
+          label: '瑙掕壊',
+          prop: 'roleName'
+        },
+        {
+          label: '鐢佃瘽鍙风爜',
+          prop: 'phone'
+        },
+        {
+          label: '鑰冩牳缁撴灉',
+          prop: 'result'
+        }
+      ],
+      trainingTableData: [],
+      trainingLoading: false,
+      isDisabled: false,
+      selectUserDia: false, // 娣诲姞浜哄憳寮规
+      tableData1: [],
+      tableLoading1: false,
+      column1: [
+        {label: '濮撳悕', prop: 'name'},
+        {label: '璐﹀彿', prop: 'account'},
+        {label: '瑙掕壊', prop: 'roleName'},
+        {
+          dataType: 'tag',
+          label: '鐘舵��',
+          prop: 'status',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鍚敤'
+            } else {
+              return ''
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'success'
+            } else {
+              return 'danger'
+            }
+          }
+        },
+        {label: '鐢佃瘽鍙风爜', prop: 'phone'},
+      ],
+      page1: {
+        total:0,
+        size:10,
+        current:1
+      },
+      addUserTableInfo: {
+        name: null,
+        departLimsId: '1',
+      },
+      multipleSelection: [],
+      userList: [],
+    };
+  },
+  computed: {
+    ...mapGetters(["userId"]),
+  },
+  mounted() {
+    this.trainingForm = this.currentRow
+    this.getInfo()
+    this.getUserList()
+    this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    // 鑾峰彇褰撳墠鏁版嵁
+    async getInfo() {
+      this.trainingLoading = true
+      await trainingAndAssessmentRecordsPage({
+        trainingDetailedId: this.currentRow.id,
+        userName: this.userName
+      }).then(res => {
+        if (res.code === 200) {
+          this.trainingTableData = res.data
+        }
+        this.trainingLoading = false
+      })
+    },
+    updatePersonResult(row) {
+      outOfFocusPreservation(row).then(res => {
+        this.$message.success("鎿嶄綔鎴愬姛锛�")
+      })
+    },
+    addPerson() {
+      this.isSelectedList = this.trainingTableData.map(item => item.userId)
+      this.selectUserDia = true;
+    },
+    selectUserList () {
+      this.tableLoading1 = true
+      selectUserCondition({...this.addUserTableInfo}).then(res => {
+        this.tableData1 = res.data.records
+        this.page1.total = res.data.total
+      }).catch(err => {
+        this.tableLoading1 = false
+      })
+    },
+    pagination1 (page) {
+      this.page1.size = page.limit
+      this.selectUserList()
+    },
+    // 琛ㄦ牸閫夋嫨鏂规硶
+    selectMethod(val) {
+      this.multipleSelection = val
+    },
+    selectUser() {
+      let selects = this.multipleSelection;
+      if (selects.length == 0) {
+        this.$message.error('鏈�夋嫨鏁版嵁');
+        return;
+      }
+      let list = []
+      selects.forEach(a => {
+        const obj = {
+          courseId: this.currentRow.id,
+          examinationResults: "",
+          userId: a.id
+        }
+        list.push(obj)
+      });
+      newPersonnelAddedToTrainingRecords(list).then(res => {
+        this.isSelectedList = []
+        this.selectUserDia = false;
+        this.getInfo()
+      })
+    },
+    // 鎵归噺鍒犻櫎
+    handleSelectionChange(list) {
+      this.multipleSelection = list
+    },
+    batchDelete() {
+      if (this.multipleSelection.length > 0) {
+        let ids = this.multipleSelection.map(item => item.trainingRecordId)
+        this.$confirm('鏄惁纭鍒犻櫎鎵�閫夋嫨鐨勬暟鎹�?', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          let formData = new FormData()
+          formData.append('ids', ids)
+          deleteTrainingAndAssessmentRecords(formData).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鍒犻櫎鎴愬姛');
+              this.getInfo()
+            }
+          });
+        }).catch(() => {
+          this.$message.warning('鍙栨秷鍒犻櫎');
+        });
+      } else {
+        this.$message.warning('璇烽�夋嫨闇�瑕佸垹闄ょ殑鏁版嵁')
+      }
+    },
+    handleSizeChange(val) {
+      this.search.size = val;
+      this.getInfo();
+    },
+    handleCurrentChange(val) {
+      this.search.current = val;
+      this.getInfo();
+    },
+    /**
+     * @desc 鎻愪氦琛ㄥ崟
+     */
+    async submitForm(status) {
+      let state = this.currentRow.state
+      if (this.trainingForm.assessmentUserId) {
+        state = 2
+      }
+      if (this.trainingForm.comprehensiveAssessment) {
+        state = 1
+      }
+      if (status === 3) {
+        state = 3
+      }
+      let data = {
+        assessmentMethod: this.trainingForm.assessmentMethod,
+        openingTime: this.trainingForm.openingTime,
+        placeTraining: this.trainingForm.placeTraining,
+        comprehensiveAssessment: this.trainingForm.comprehensiveAssessment,
+        trainingDetailedId: this.trainingForm.id,
+        assessmentUserId: this.trainingForm.assessmentUserId,
+        assessmentDate: this.trainingForm.assessmentDate,
+        state: state
+      }
+      let code = {}
+      if (state === 2) {
+        code = await trainingAndAssessmentRecordsAdded(data)
+      } else {
+        code = await trainingAndAssessmentRecordsEvaluate(data)
+      }
+      this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
+      if(code.code === 200) {
+        this.currentRow.state = state
+        this.$message.success("鎿嶄綔鎴愬姛")
+      }
+    },
+    getUserList(){
+      selectUserCondition({ type: 0 }).then((res) => {
+        this.userList = res.data;
+      })
+    },
+  }
+};
+</script>
+
+<style scoped>
+.page-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 20px;
+  margin-bottom: 10px;
+}
+
+h4 {
+  display: flex;
+  align-items: center;
+}
+
+h4 .line {
+  display: inline-block;
+  width: 3px;
+  height: 16px;
+  background: #3A7BFA;
+  margin-right: 4px;
+}
+
+.form_title {
+  font-size: 14px;
+  padding: 0 20px;
+  margin-bottom: 10px;
+}
+
+.el-divider {
+  margin: 0 1em 1em 0;
+}
+
+.form__input_label {
+  width: 90px;
+  margin-right: 6px;
+  color: #606266;
+}
+
+.form__input_label2 {
+  width: 210px;
+  margin-right: 6px;
+  color: #606266;
+}
+.search_thing {
+  display: flex;
+  align-items: center
+}
+.search_label {
+  width: 120px;
+}
+.pagination {
+  display: flex;
+  justify-content: space-between
+}
+
+.items_center {
+  float: left;
+  width: 50%;
+  text-align: left;
+}
+.items_btn {
+  text-align: right;
+  width: 50%;
+  float: right;
+  margin-bottom: 1em;
+}
+
+.search {
+  width: 180px;
+  padding: 0 16px;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue b/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue
new file mode 100644
index 0000000..36364cf
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue
@@ -0,0 +1,179 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="filesDialogVisible" title="闄勪欢涓婁紶" width="80%" @closed="closeFilesLook">
+      <div style="display: flex;justify-content: space-between;">
+        <el-upload ref='upload'
+                   :action="fileAction"
+                   :auto-upload="true"
+                   :before-upload="fileBeforeUpload" :data="{trainingDetailedId: info.id}"
+                   :headers="uploadHeader" :on-error="onError"
+                   :on-success="handleSuccessUp"
+                   :show-file-list="false"
+                   accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
+          <el-button size="small" style="height: 38px" type="primary">闄勪欢涓婁紶</el-button>
+        </el-upload>
+      </div>
+      <div>
+        <lims-table :tableData="tableData" :column="columnData"
+                    :height="'calc(100vh - 47em)'"
+                    :highlightCurrentRow="true"
+                    :tableLoading="tableLoading"></lims-table>
+      </div>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="lookDialogVisible"
+      fullscreen
+      title="鏌ョ湅闄勪欢" width="800px">
+      <filePreview v-if="lookDialogVisible" :currentFile="{}"
+                   :fileUrl="javaApi+'/word/'+currentInfo.fileUrl" style="height: 90vh;overflow-y: auto;top: 0"/>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import file from '@/utils/file';
+import filePreview from '@/components/Preview/filePreview.vue';
+import limsTable from "@/components/Table/lims-table.vue";
+import {delTrainingDetailedFileList, getTrainingDetailedFileList} from "@/api/cnas/personal/personalTraining";
+
+export default {
+  name: 'ViewRecord',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {limsTable, filePreview },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      filesDialogVisible: false,
+      tableLoading: false,
+      filesLookInfo: {},
+      columnData: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '棰勮',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleLook(row)
+              }
+            },
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.upload(row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delete(row)
+              }
+            }
+          ]
+        }
+      ],
+      tableData: [],
+      info: {},
+      currentInfo:{},
+      lookDialogVisible: false,
+    };
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    openDia(row) {
+      this.filesDialogVisible = true
+      this.info = row
+      this.searchTableList()
+    },
+    // 鏌ヨ闄勪欢鍒楄〃
+    searchTableList () {
+      this.tableLoading = true
+      getTrainingDetailedFileList({trainingDetailedId: this.info.id}).then(res => {
+        this.tableLoading = false
+        this.tableData = res.data
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    closeFilesLook () {
+      this.filesDialogVisible = false
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        file.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+    // 鍒犻櫎
+    delete (row) {
+      this.tableLoading = true
+      delTrainingDetailedFileList({detailedFileId: row.detailedFileId}).then(res => {
+        this.tableLoading = false
+        this.$message.success('鍒犻櫎鎴愬姛')
+        this.searchTableList()
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    // 涓婁紶楠岃瘉
+    fileBeforeUpload(file) {
+      let flag = true
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        flag = false
+      }
+      if (!flag) {
+        return Promise.reject(flag); //姝g‘鐨勭粓姝�
+      }
+    },
+    onError(err, file, fileList,type) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+    },
+    handleSuccessUp(response, ) {
+      this.upLoading = false;
+      if (response.code == 200) {
+        this.$message.success('涓婁紶鎴愬姛');
+        this.searchTableList()
+      }
+    },
+    // 鏌ョ湅鏂囦欢
+    handleLook(row){
+      this.currentInfo = row
+      this.lookDialogVisible = true
+    },
+  },
+  computed: {
+    fileAction() {
+      return this.javaApi + '/personTraining/delTrainingDetailedFileList'
+
+    }
+  },
+};
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/index.vue b/src/views/CNAS/personnel/personnelInfo/index.vue
new file mode 100644
index 0000000..a55381e
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/index.vue
@@ -0,0 +1,325 @@
+<template>
+  <div class="main">
+    <div class="main_left">
+      <el-row>
+        <el-col :span="20">
+          <el-input
+            v-model="search"
+            class="div_left_input"
+            clearable
+            placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
+            size="small"
+            suffix-icon="el-icon-search"
+            @blur="searchFilter"
+            @clear="searchFilter"
+            @keyup.enter.native="searchFilter"
+          ></el-input>
+        </el-col>
+        <el-col :span="4" style="text-align: center;line-height: 30px; margin-top: 14px">
+          <el-button circle icon="el-icon-plus" size="mini" type="primary" @click="handleAdd"></el-button>
+        </el-col>
+      </el-row>
+      <el-tree
+        ref="tree"
+        :data="list"
+        :default-expanded-keys="[22]"
+        :expand-on-click-node="false"
+        :filter-node-method="filterNode"
+        :props="{ children: 'children', label: 'name' }"
+        highlight-current
+        node-key="id"
+        style="height:calc(100% - 70px);overflow-y: scroll;scrollbar-width: none;"
+        @node-click="handleNodeClick"
+        @node-expand="nodeOpen"
+        @node-collapse="nodeClose"
+      >
+        <div slot-scope="{ node, data }" class="custom-tree-node">
+          <el-row style="width: 100%;">
+            <el-col :span="22" style="text-align: left;">
+              <span><i
+                :class="`node_i ${data.children != undefined&&data.children.length>0 ? 'el-icon-folder-opened' : 'el-icon-tickets'}`"></i>
+                {{ data.name }}</span>
+            </el-col>
+            <el-col v-if="node.level>1 && data.id !== null" :span="2" style="text-align: right;">
+              <el-button size="mini" type="text" @click.stop="remove(node, data)">
+                <i class="el-icon-delete"></i>
+              </el-button>
+            </el-col>
+          </el-row>
+        </div>
+      </el-tree>
+    </div>
+    <div class="main_right">
+      <el-tabs v-model="activeName" :lazy="true" type="border-card">
+        <el-tab-pane label="浜哄憳鍩烘湰淇℃伅" name="浜哄憳鍩烘湰淇℃伅">
+          <PersonnelList v-if="activeName === '浜哄憳鍩烘湰淇℃伅' && isShowAll" ref="personnelList" :currentCompaniesList="currentCompaniesList"
+                         :departId="departId" @refreshTree="refreshTree"
+                         @updatePerson="updatePerson"></PersonnelList>
+          <personnelInformation v-if="activeName === '浜哄憳鍩烘湰淇℃伅' && !isShowAll" :clickNodeVal="clickNodeVal"></personnelInformation>
+        </el-tab-pane>
+<!--        <el-tab-pane label="鍩硅璁″垝" name="鍩硅璁″垝">-->
+<!--          <PersonnelTraining v-if="activeName === '鍩硅璁″垝'" ref="personnelTraining"-->
+<!--                             :departId="departId" :isDepartment="isDepartment"></PersonnelTraining>-->
+<!--        </el-tab-pane>-->
+<!--        <el-tab-pane label="宀椾綅鑱岃矗" name="宀椾綅鑱岃矗">-->
+<!--          <job-responsibilities v-if="activeName === '宀椾綅鑱岃矗'" ref="jobResponsibilities"-->
+<!--                                :departId="departId"-->
+<!--                                :isDepartment="isDepartment"></job-responsibilities>-->
+<!--        </el-tab-pane>-->
+<!--        <el-tab-pane label="濂栨儵璁板綍" name="濂栨儵璁板綍">-->
+<!--          <rewardPunishmentRecord v-if="activeName === '濂栨儵璁板綍'"-->
+<!--                                  :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord>-->
+<!--        </el-tab-pane>-->
+<!--        <el-tab-pane label="鍩硅璁板綍" name="鍩硅璁板綍">-->
+<!--          <training-record v-if="activeName === '鍩硅璁板綍'" ref="trainingRecord"-->
+<!--                           :departId="departId"-->
+<!--                           :isDepartment="isDepartment"></training-record>-->
+<!--        </el-tab-pane>-->
+<!--        <el-tab-pane label="浠昏亴鎺堟潈璁板綍" name="浠昏亴鎺堟潈璁板綍">-->
+<!--          <Mandate v-if="activeName === '浠昏亴鎺堟潈璁板綍'" ref="manDateRef" :departId="departId" :isDepartment="isDepartment"></Mandate>-->
+<!--        </el-tab-pane>-->
+<!--        <el-tab-pane label="浜哄憳鑳藉姏" name="浜哄憳鑳藉姏">-->
+<!--          <personnel-capacity v-if="activeName === '浜哄憳鑳藉姏'" ref="personnelCapacity"-->
+<!--                              :departId="departId"-->
+<!--                              :isDepartment="isDepartment"></personnel-capacity>-->
+<!--        </el-tab-pane>-->
+<!--        <el-tab-pane label="娌熼�氳褰�" name="娌熼�氳褰�">-->
+<!--          <Communicate v-if="activeName === '娌熼�氳褰�'" ref="communicateRef" :departId="departId" :isDepartment="isDepartment"></Communicate>-->
+<!--        </el-tab-pane>-->
+      </el-tabs>
+    </div>
+    <el-dialog :visible.sync="addDia" title="鏋舵瀯鏂板" width="400px">
+      <div class="body">
+        <el-row style="line-height: 50px;">
+          <el-col :span="6" style="text-align: right;">
+            <span class="required-span">* </span>鏋舵瀯鍚嶇О锛�
+          </el-col>
+          <el-col :offset="1" :span="16">
+            <el-input v-model="addOb.name" clearable placeholder="璇疯緭鍏ユ灦鏋勫悕绉�" size="small" @keyup.enter.native="addStandardTree"></el-input>
+          </el-col>
+        </el-row>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="addDia = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="addStandardTree">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import PersonnelList from './tabs/personnel-list.vue'
+import personnelInformation from './tabs/personnel-information.vue'
+import PersonnelTraining from './tabs/personnelTraining';
+import JobResponsibilities from './tabs/job-responsibilities.vue';
+import rewardPunishmentRecord from "./tabs/reward-punishment-record.vue";
+import TrainingRecord from './tabs/training-record.vue';
+import Mandate from './tabs/mandate.vue';
+import PersonnelCapacity from './tabs/personnel-capacity.vue';
+import Communicate from './tabs/communicate.vue'
+import {addDepartmentLims, delDepartmentLims, selectCNSAPersonTree} from "@/api/cnas/personal/personalList";
+export default {
+  components: {
+    PersonnelList, personnelInformation, PersonnelTraining, JobResponsibilities, rewardPunishmentRecord, TrainingRecord, Mandate, PersonnelCapacity, Communicate
+  },
+  data() {
+    return {
+      isShowAll: true, //  鏄惁灞曠ず鏍囩鏍�
+      activeName: '浜哄憳鍩烘湰淇℃伅',
+      departId: 1,
+      list: [],
+      addDia: false,
+      addOb: {
+        name: '',
+        fatherId: ''
+      },
+      search: '',
+      clickNodeVal: {},
+      addUserForm: {
+        name: ''
+      },
+      currentCompaniesList: [],
+      entity: {
+        name: '',
+        departLimsId: '',
+        orderBy: {
+          field: 'id',
+          order: 'asc'
+        }
+      },
+      overallRecord: '浜哄憳鍒楄〃',
+      isDepartment: false,
+    };
+  },
+  mounted() {
+    this.geList();
+  },
+  methods: {
+    remove(node, data) {
+      this.$confirm("鏄惁鍒犻櫎璇ュ眰绾�", "鎻愮ず", {
+        type: "error"
+      }).then(() => {
+        delDepartmentLims({
+          id: data.id
+        }).then(res => {
+          this.$message.success('宸插垹闄�')
+          this.geList();
+        })
+      }).catch(e => {})
+    },
+    addStandardTree() {
+      if (this.addOb.name == null || this.addOb.factory == '') {
+        this.$message.error('鏋勬灦鍚嶇О鏄繀濉」')
+        return
+      }
+      addDepartmentLims(this.addOb).then(res => {
+        this.$message.success('娣诲姞鎴愬姛')
+        this.addDia = false
+        this.geList();
+        this.addOb.name = ''
+        this.addOb.fatherId = ''
+      })
+    },
+    handleAdd() {
+      if (this.addOb.fatherId) {
+        this.addDia = true;
+      } else {
+        this.$message.error('璇烽�夋嫨涓�涓灦鏋勫眰绾�')
+      }
+    },
+    // 浜哄憳鍒楄〃缂栬緫
+    updatePerson(row) {
+      const node = this.findNodeById(this.list, row.name);
+      if (node) {
+        this.handleNodeClick(node);
+      } else {
+        this.$message.warning('鏈壘鍒拌浜哄憳');
+      }
+    },
+    // 鏂板缓浜哄憳鍚庡埛鏂版爲
+    refreshTree () {
+      this.geList()
+    },
+    findNodeById(treeData, name) {
+      for (let i = 0; i < treeData.length; i++) {
+        if (treeData[i].name === name) {
+          return treeData[i]; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
+        }
+        if (treeData[i].children && treeData[i].children.length > 0) {
+          const foundNode = this.findNodeById(treeData[i].children, name);
+          if (foundNode) {
+            return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
+          }
+        }
+      }
+      return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+    },
+    searchFilter() {
+      this.$refs.tree.filter(this.search);
+    },
+    // 鑾峰彇鏍�
+    geList() {
+      selectCNSAPersonTree().then(res => {
+        this.list = res.data;
+        if(this.list.length > 0) {
+          this.isDepartment = true;
+        }
+      });
+    },
+    filterNode(value, data) {
+      if (!value) return true;
+      return data.name.indexOf(value) !== -1;
+    },
+    nodeClose(data, node, el) {
+      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder');
+    },
+    nodeOpen(data, node, el) {
+      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder-opened');
+    },
+    handleNodeClick(val, node, el) {
+      //鏍戠殑鍊�
+      this.clickNodeVal = val;
+      // 瀛樺偍鐖剁骇鑺傜偣绾ф暟
+      if (node) {
+        this.getNodeParent(node);
+        this.clickNodeVal.level = node.level;
+        this.clickNodeVal.parent = node.parent.data;
+      }
+      this.entity.departLimsId = val.id;
+      this.addOb.fatherId = val.id;
+      // 鏄惁鏄剧ず璁惧璇︽儏
+      this.isShowAll = val.id !== null;
+      if (val.id) {	// 濡傛灉鏄疄楠屽
+        this.departId = val.id;
+        this.isDepartment = true;
+      }
+      if (val.userId) { // 鏄汉鍛�
+        this.departId = val.userId;
+        this.isDepartment = false
+      }
+    },
+    getNodeParent(val) {
+      if (val.parent != null) {
+        this.currentCompaniesList[val.level - 1] = val.data.id;
+        this.selectTree += ' - ' + val.label;
+        this.getNodeParent(val.parent);
+      }
+    }
+  }
+};
+</script>
+
+<style scoped>
+>>>.el-table__body-wrapper::-webkit-scrollbar {
+  height: 14px;
+  /* 璁剧疆婊氬姩鏉″搴� */
+}
+.custom-tree-node {
+  width: 80%;
+  line-height: 32px;
+}
+.custom-tree-node .el-icon-delete {
+  color: #3A7BFA;
+  opacity: 0;
+  font-size: 15px;
+}
+
+.custom-tree-node:hover .el-icon-delete {
+  opacity: 1;
+}
+
+.main {
+  display: flex;
+  padding: 15px 0;
+}
+
+.main_left {
+  background: #ffffff;
+  text-align: center;
+  height: calc(100vh - 8em);
+  width: 270px;
+  border-radius: 15px;
+}
+
+.main_right {
+  width: calc(100% - 288px);
+  border-radius: 15px;
+}
+
+.div_left_input {
+  margin: 15px 0;
+  width: 90%;
+}
+
+>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item {
+  border: 0 none;
+}
+
+>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
+  color: black;
+}
+
+>>> .el-tabs--border-card > .el-tabs__header {
+  border-bottom: none;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue b/src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue
new file mode 100644
index 0000000..4ae47d9
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue
@@ -0,0 +1,249 @@
+<template>
+    <div class="flex_column">
+<!--        <TableCard :showForm="isDepartment" title="娌熼�氳褰�">-->
+<!--            <template v-slot:form >-->
+<!--                <div v-if="isDepartment" class="w100 items_center justify_between">-->
+<!--                    <div></div>-->
+<!--                    <div>-->
+<!--                        &lt;!&ndash; <el-button type="primary" size="small">瀵煎嚭</el-button> &ndash;&gt;-->
+<!--                        <el-button size="small" type="primary" @click="openDialog">鏂板</el-button>-->
+<!--                    </div>-->
+<!--                </div>-->
+<!--            </template>-->
+<!--            <template v-slot:table>-->
+<!--                <ZTTable-->
+<!--                    :column="columnData"-->
+<!--                    :height="'calc(100vh - 21em)'"-->
+<!--                    :table-data="tableData"-->
+<!--                    :table-loading="loading"-->
+<!--                    style="margin-top: 18px; padding: 0 15px;"-->
+<!--                ></ZTTable>-->
+<!--                <el-divider></el-divider>-->
+<!--                <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=""-->
+<!--                        @size-change=""-->
+<!--                    >-->
+<!--                    </el-pagination>-->
+<!--                </div>-->
+<!--            </template>-->
+<!--        </TableCard>-->
+        <Add ref="communicateModal" @submit="getTableData"></Add>
+    </div>
+</template>
+<script>
+// import Add from "./Add.vue"
+
+export default {
+    components: {
+        // 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
+            }
+            const blob = new Blob([res],{ type: 'application/octet-stream' });
+            //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆
+            let reader = new FileReader();
+            reader.readAsText(blob, 'utf-8');
+            reader.onload = () => {
+              try {
+                let result = JSON.parse(reader.result);
+                if (result.message) {
+                  this.$message.error(result.message);
+                } else {
+                  const url = URL.createObjectURL(blob);
+                  const link = document.createElement('a');
+                  link.href = url;
+                  link.download = row.userName+'-娌熼�氳褰�'+'.docx';
+                  link.click();
+                  this.$message.success('瀵煎嚭鎴愬姛')
+                }
+              } catch (err) {
+                console.log(err);
+                const url = URL.createObjectURL(blob);
+                const link = document.createElement('a');
+                link.href = url;
+                link.download = row.userName+'-娌熼�氳褰�'+'.docx';
+                link.click();
+                this.$message.success('瀵煎嚭鎴愬姛')
+              }
+            }
+          })
+        }
+    },
+  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/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue b/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue
new file mode 100644
index 0000000..2f7d422
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue
@@ -0,0 +1,393 @@
+<!-- 宀椾綅鑱岃矗 -->
+<template>
+  <div class="view">
+    <div style="text-align: left; margin-bottom: 15px;padding: 0 10px">
+      <label>鍛樺伐锛�</label>
+      <el-input v-model="userName" clearable placeholder="璇疯緭鍏ュ憳宸�" size="small" style="width: 20vh;"></el-input>
+      <el-button size="small" type="primary" @click="refreshTable">鏌ヨ</el-button>
+      <div v-if="isDepartment" style="float: right;">
+        <el-button size="small" type="primary" @click="addPost">鏂板</el-button>
+        <!--        <el-button size="small" type="primary">瀵煎嚭excel</el-button>-->
+      </div>
+    </div>
+    <div class="table" style="padding: 0 10px">
+      <el-table :data="tableData" height="70vh" style="width: 100%">
+        <el-table-column label="搴忓彿" type="index" width="60"></el-table-column>
+        <el-table-column label="鍛樺伐缂栧彿" min-width="120" prop="account"></el-table-column>
+        <el-table-column label="宀椾綅鍚嶇О" min-width="180" prop="postName"></el-table-column>
+        <el-table-column label="鎵�灞為儴闂�" min-width="180" prop="departLimsName"></el-table-column>
+        <el-table-column label="宸ヤ綔鐩爣" min-width="180" prop="jobObjective"></el-table-column>
+        <el-table-column label="宀椾綅鑱岃矗" min-width="180" prop="jobResponsibilities"></el-table-column>
+        <el-table-column label="浠昏亴浜�" min-width="180" prop="incumbentName"></el-table-column>
+        <el-table-column label="浠昏亴浜哄鏍告棩鏈�" min-width="180" prop="incumbentDate"></el-table-column>
+        <el-table-column label="涓荤" min-width="180" prop="supervisorName"></el-table-column>
+        <el-table-column label="涓荤瀹℃牳鏃ユ湡" min-width="180" prop="supervisorDate"></el-table-column>
+        <el-table-column fixed="right" label="鎿嶄綔" width="140">
+          <template v-slot="scope">
+            <el-button v-if="!isDepartment || scope.row.currentState === '鍏抽棴'" size="small" type="text"
+                       @click="handleViewClick(scope.row, 'view')">鏌ョ湅
+            </el-button>
+            <el-button v-if="isDepartment && scope.row.currentState !== '鍏抽棴'" size="small" type="text"
+                       @click="handleViewClick(scope.row, 'edit')">缂栬緫
+            </el-button>
+            <el-button size="small" type="text" @click="downLoadPost(scope.row)">瀵煎嚭</el-button>
+            <el-button v-if="isDepartment" size="small" type="text" @click="deletePost(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]"
+                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
+                     @size-change="handleSizeChange"
+                     @current-change="handleCurrentChange">
+      </el-pagination>
+    </div>
+    <!-- 鏂板宀椾綅鑱岃矗 -->
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="dialogVisible"
+               title="鏂板宀椾綅鑱岃矗"
+               width="50%" @close="resetForm">
+      <el-steps :active="currentStep" align-center finish-status="success">
+        <el-step v-for="(v, i) in steps" :key="i" :title="v" style="cursor:pointer"
+                 @click.native="choiceStep(i)"></el-step>
+      </el-steps>
+      <el-form ref="form" :model="form" :rules="rules" label-width="130px">
+        <div>
+          <el-card style="margin-top: 1em; height: 40vh; overflow-y: scroll;">
+            <!-- 鏂板璁惧浜嬭褰曞崱鐗� -->
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="宀椾綅鍚嶇О锛�" prop="postName">
+                  <el-input v-model="form.postName" :disabled="currentStep !== 0 || operationType === 'view'"
+                            size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="宸ヤ綔鐩爣锛�" prop="jobObjective">
+                  <el-input v-model="form.jobObjective" :disabled="currentStep !== 0 || operationType === 'view'"
+                            size="small"
+                            type="textarea"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="宀椾綅鑱岃矗锛�" prop="jobResponsibilities">
+                  <el-input v-model="form.jobResponsibilities" :disabled="currentStep !== 0 || operationType === 'view'"
+                            size="small"
+                            type="textarea"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col v-if="currentStep === 0 || operationType === 'view'" :span="12">
+                <el-form-item
+                  :rules="[{ required: currentStep === 0, message: '璇烽�夋嫨浠昏亴浜�', trigger: 'change' }]"
+                  label="浠昏亴浜猴細"
+                  prop="incumbentId">
+                  <el-select v-model="form.incumbentId" :disabled="operationType === 'view'" clearable
+                             filterable
+                             placeholder="璇烽�夋嫨浠昏亴浜�" size="small" style="width: 100%;">
+                    <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col v-if="currentStep === 1 || operationType === 'view'" :span="12">
+                <el-form-item
+                  :rules="[{ required: currentStep === 1, message: '璇烽�夋嫨涓荤', trigger: 'blur' }]"
+                  label="涓荤锛�"
+                  prop="supervisorId">
+                  <el-select v-model="form.supervisorId" :disabled="currentStep !== 1 || operationType === 'view'"
+                             clearable filterable
+                             placeholder="璇烽�夋嫨涓荤" size="small" style="width: 100%;">
+                    <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-card>
+          <el-row style="margin-top: 1em;">
+            <el-col :span="4">
+              鎿嶄綔浜猴細{{ form.submitPerson }}
+            </el-col>
+            <el-col :span="6">
+              鏃ユ湡锛歿{ form.submitDate }}
+            </el-col>
+          </el-row>
+        </div>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="currentStep !== 0 && currentStep !== 3" @click="submitForm('3reject')">椹冲洖</el-button>
+        <el-button v-if="currentStep === 0" @click="submitForm('2save')">淇濆瓨</el-button>
+        <el-button v-if="currentStep !== 3" type="primary"
+                   @click="submitForm('1submit')">{{ currentStep === 0 ? '鎻愪氦' : '閫氳繃' }}</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// import { dateFormat } from '../../../util/date';
+
+export default {
+  data() {
+    return {
+      userName: '',
+      tableData: [],
+      responsibleOptions: [],
+      search: {
+        size: 20,
+        current: 1,
+        total: 0
+      },
+      dialogVisible: false,
+      currentStep: 0, // 姝ラ鏉℃樉绀虹鍑犳
+      currentStepClick: 0, // 鐐瑰嚮姝ラ鏉″彉鍖�
+      operationType: '',
+      steps: ['鎻愪氦', '浠昏亴浜虹‘璁�', '涓荤纭'],
+      form: {
+        postName: '', // 宀椾綅鍚嶇О
+        jobObjective: '', // 宸ヤ綔鐩爣
+        jobResponsibilities: '', // 宀椾綅鑱岃矗
+        incumbentId: '', // 浠昏亴浜�
+        supervisorId: '' // 涓荤
+      },
+      rules: {
+        postName: [{ required: true, message: '璇疯緭鍏ュ矖浣嶅悕绉�', trigger: 'blur' }],
+        jobObjective: [{ required: true, message: '璇疯緭鍏ュ伐浣滅洰鏍�', trigger: 'blur' }],
+        jobResponsibilities: [{ required: true, message: '璇疯緭鍏ュ矖浣嶈亴璐�', trigger: 'blur' }],
+        incumbentId: [{ required: true, message: '璇烽�夋嫨浠昏亴浜�', trigger: 'change' }],
+        supervisorId: [{ required: true, message: '璇烽�夋嫨涓荤', trigger: 'change' }]
+      }
+      // departId: 0
+    };
+  },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted() {
+    this.getPostList(this.departId);
+  },
+  methods: {
+    addPost() {
+      this.dialogVisible = true;
+      this.form = {
+        postName: '', // 宀椾綅鍚嶇О
+        jobObjective: '', // 宸ヤ綔鐩爣
+        jobResponsibilities: '', // 宀椾綅鑱岃矗
+        incumbentId: '', // 浠昏亴浜�
+        supervisorId: '', // 鎿嶄綔浜�
+        submitPerson: '', // 涓荤
+        submitDate: '', // 鏃ユ湡
+        currentStep: 0 // 鏃ユ湡
+      };
+      this.currentStep = 0;
+      this.getUserList();
+    },
+    // 鏌ヨ鍒楄〃淇℃伅
+    getPostList(userId) {
+      this.search.userId = userId;
+      const name = this.isDepartment ? 'departmentId' : 'userId';
+      this.$axios.get(this.$api.personnel.personJobResponsibilitiesSelect + '?userName=' + this.userName + `&${name}=` + this.search.userId + '&size=' + this.search.size + '&current=' + this.search.current).then(res => {
+        if (res.code === 201) return;
+        this.tableData = res.data.records;
+        this.search.total = res.data.total;
+      });
+    },
+    //鎻愪氦琛ㄥ崟
+    async submitForm(saveState) {
+      this.$refs.form.validate((valid) => {
+        if (valid === true || saveState !== '1submit') {
+          // 缁欏綋鍓嶇幆鑺傝缃垱寤轰汉涓庢椂闂�
+          let user = JSON.parse(localStorage.getItem('user'));
+          const dateTime = dateFormat(new Date());
+          // 鑾峰彇褰撳墠鐜妭鎿嶄綔浜轰笌鏃ユ湡
+          switch (this.currentStep) {
+            case 0:
+              this.form.submittingOperator = user.name;
+              this.form.submittingDate = dateTime;
+              break;
+            case 1:
+              this.form.incumbentOperator = user.name;
+              this.form.incumbentDate = dateTime;
+              break;
+            case 2:
+              this.form.supervisorOperator = user.name;
+              this.form.supervisorDate = dateTime;
+              break;
+            default:
+              break;
+          }
+          // 鑾峰彇褰撳墠鐜妭璐熻矗浜�
+          switch (saveState === '3reject' ? this.currentStep - 1 : this.currentStep) {
+            case 1:
+              this.form.currentResponsible = this.form.submittingOperator;
+              break;
+            case 2:
+              this.form.currentResponsible = this.form.incumbentOperator;
+              break;
+            default:
+              break;
+          }
+          let currentStepAction;
+          // 璁剧疆璇ユ搷浣滃垽鏂槸鍚︿负鎻愪氦锛屼繚瀛橈紝椹冲洖锛岄�氳繃
+          switch (saveState) {
+            // 鎻愪氦锛岄�氳繃
+            case '1submit':
+              currentStepAction = this.currentStep + 1;
+              break;
+            // 淇濆瓨
+            case '2save':
+              currentStepAction = this.currentStep;
+              break;
+            // 椹冲洖
+            case '3reject':
+              currentStepAction = this.currentStep - 1;
+              break;
+            default:
+              break;
+          }
+          // 鑾峰彇褰撳墠鐘舵��
+          this.form.currentState = currentStepAction === 3 ? '鍏抽棴' : this.steps[currentStepAction];
+          this.$axios.post(this.$api.personnel.personJobResponsibilitiesSave, this.form, {
+            headers: {
+              'Content-Type': 'application/json'
+            },
+            noQs: true
+          }).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.getPostList(this.departId);
+              this.dialogVisible = false;
+            }
+          });
+        } else {
+          let step = this.steps[this.currentStep];
+          this.$message.warning(step + '  娴佺▼涓湁蹇呭~椤规湭濉紒');
+        }
+      });
+    },
+    // 缂栬緫
+    handleViewClick(row, type) {
+      this.operationType = type;
+      this.getUserList();
+      row.incumbentId = Number(row.incumbentId);
+      this.form = { ...row };
+      switch (row.currentState) {
+        case '鎻愪氦':
+          this.currentStep = 0;
+          break;
+        case '浠昏亴浜虹‘璁�':
+          this.currentStep = 1;
+          this.form.submitPerson = row.submittingOperator;
+          this.form.submitDate = row.submittingDate;
+          break;
+        case '涓荤纭':
+          this.currentStep = 2;
+          this.form.submitPerson = row.incumbentOperator;
+          this.form.submitDate = row.incumbentDate;
+          break;
+        case '鍏抽棴':
+          this.currentStep = 3;
+          this.form.submitPerson = row.supervisorOperator;
+          this.form.submitDate = row.supervisorDate;
+          break;
+        default:
+          break;
+      }
+      this.form.currentState = this.currentStep;
+      this.currentStepClick = this.currentStep === 3 ? 0 : this.currentStep
+      console.log('this.form---', this.form);
+      this.dialogVisible = true;
+    },
+    // 涓嬭浇宀椾綅鑱岃矗
+    downLoadPost(row) {
+      this.$axios.post(this.$api.personPostAuthorizationRecord.exportPersonJobResponsibilities,{id:row.id},{responseType: "blob"}).then(res => {
+        const blob = new Blob([res],{ type: 'application/octet-stream' });
+        //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆
+        let reader = new FileReader();
+        reader.readAsText(blob, 'utf-8');
+        reader.onload = () => {
+          try {
+            let result = JSON.parse(reader.result);
+            if (result.message) {
+              this.$message.error(result.message);
+            } else {
+              const url = URL.createObjectURL(blob);
+              const link = document.createElement('a');
+              link.href = url;
+              link.download = row.incumbentName+'-宀椾綅鑱岃矗'+'.docx';
+              link.click();
+              this.$message.success('瀵煎嚭鎴愬姛')
+            }
+          } catch (err) {
+            console.log(err);
+            const url = URL.createObjectURL(blob);
+            const link = document.createElement('a');
+            link.href = url;
+            link.download = row.incumbentName+'-宀椾綅鑱岃矗'+'.docx';
+            link.click();
+            this.$message.success('瀵煎嚭鎴愬姛')
+          }
+        }
+      })
+    },
+    // 鍒犻櫎宀椾綅鑱岃矗
+    deletePost(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎姝ゆ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.$axios.delete(this.$api.personnel.personJobResponsibilitiesDelete + '?id=' + row.id).then(res => {
+          if (res.code == 200) {
+            this.$message.success('鍒犻櫎鎴愬姛');
+            this.getPostList(this.departId);
+          }
+        });
+      }).catch(() => {
+        this.$message.error('鍒犻櫎澶辫触');
+      });
+    },
+    resetForm() {
+      this.$refs.form.resetFields();
+    },
+    refreshTable() {
+      this.getPostList(this.departId);
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      this.$axios.get(this.$api.deviceScope.selectUserList).then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data;
+        }
+      });
+    },
+    choiceStep(index) {
+      this.currentStepClick = index;
+    },
+    handleSizeChange(val) {
+      this.search.size = val;
+      this.getPostList(this.departId);
+    },
+    handleCurrentChange(val) {
+      this.search.current = val;
+      this.getPostList(this.departId);
+    }
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        this.getPostList(newId);
+      }
+    }
+  }
+};
+</script>
+<style scoped>
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue b/src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue
new file mode 100644
index 0000000..72b75ba
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue
@@ -0,0 +1,276 @@
+<template>
+    <div class="flex_column">
+<!--        <TableCard :showForm="isDepartment" title="浠昏亴鎺堟潈璁板綍">-->
+<!--            <template v-slot:form>-->
+<!--                <div v-if="isDepartment" class="w100 items_center justify_between">-->
+<!--                    <div></div>-->
+<!--                    <div>-->
+<!--                        <el-button size="small" type="primary" @click="openDialog">鏂板</el-button>-->
+<!--                    </div>-->
+<!--                </div>-->
+<!--            </template>-->
+<!--            <template v-slot:table>-->
+<!--                <ZTTable-->
+<!--                    :column="columnData"-->
+<!--                    :height="'calc(100vh - 21em)'"-->
+<!--                    :table-data="tableData"-->
+<!--                    :table-loading="loading"-->
+<!--                    style="margin-top: 18px; padding: 0 15px;"-->
+<!--                ></ZTTable>-->
+<!--                <el-divider></el-divider>-->
+<!--                <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>-->
+        <Add ref="mandateModal" @refresh="getTableData"></Add>
+    </div>
+</template>
+<script>
+// import Add from "./Add.vue"
+
+export default {
+    components: {
+        // 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,
+                fixed: 'right',
+                    operation: [
+                        {
+                            name: '缂栬緫',
+                            type: 'text',
+                            clickFun: (row) => {
+                                this.openDialog(row, true)
+                            }
+                        }, {
+                            name: '涓嬭浇',
+                            type: 'text',
+                            clickFun: (row) => {
+                                this.handleDown(row)
+                            }
+                        }, {
+                            name: '鍒犻櫎',
+                            type: 'text',
+                            color: '#f56c6c',
+                            clickFun: (row) => {
+                                this.deleteNotify(row.id)
+                            }
+                        }
+                    ]
+                },
+            ],
+            tableData: [],
+            pagination: {
+                current: 1,
+                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
+          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
+            }
+            const blob = new Blob([res],{ type: 'application/octet-stream' });
+            //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆
+            let reader = new FileReader();
+            reader.readAsText(blob, 'utf-8');
+            reader.onload = () => {
+              try {
+                let result = JSON.parse(reader.result);
+                if (result.message) {
+                  this.$message.error(result.message);
+                } else {
+                  const url = URL.createObjectURL(blob);
+                  const link = document.createElement('a');
+                  link.href = url;
+                  link.download = '浠昏亴鎺堟潈-'+row.certificateNumber+'-'+row.post + '.docx';
+                  link.click();
+                  this.$message.success('瀵煎嚭鎴愬姛')
+                }
+              } catch (err) {
+                console.log(err);
+                const url = URL.createObjectURL(blob);
+                const link = document.createElement('a');
+                link.href = url;
+                link.download = '浠昏亴鎺堟潈-'+row.certificateNumber+'-'+row.post + '.docx';
+                link.click();
+                this.$message.success('瀵煎嚭鎴愬姛')
+              }
+            }
+          })
+        }
+    },
+//   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/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue
new file mode 100644
index 0000000..b6dc914
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue
@@ -0,0 +1,621 @@
+<!-- 浜哄憳鑳藉姏 -->
+<template>
+  <div>
+    <div style="text-align: left; margin-bottom: 15px;padding: 0 16px">
+      <label>濮撳悕</label>
+      <el-input v-model="userName" placeholder="璇疯緭鍏ュ鍚�" size="small" style="width: 20vh;"></el-input>
+      <el-button size="small" type="primary" @click="refreshTable">鏌ヨ</el-button>
+      <div v-if="!isDepartment" style="float: right;">
+        <el-button size="small" type="primary" @click="addAppointPost('add')">鏂板</el-button>
+      </div>
+    </div>
+    <div class="table">
+      <TableCard :showForm="false" :showTitle="false">
+        <template v-slot:table>
+          <ZTTable
+            :column="yearColumnData"
+            :height="'calc(100vh - 20em)'"
+            :table-data="tableData"
+            :table-loading="yearLoading"
+            style="padding: 0 15px;margin-bottom: 16px"
+          >
+            <div slot="jobResponsibilities" slot-scope="scope">
+              <div v-html="changeLine(scope.row.responsibilities)"></div>
+            </div>
+            <div slot="placeWorkSlot" slot-scope="scope">
+              <div v-html="changeLine(scope.row.placeWork)"></div>
+            </div>
+          </ZTTable>
+        </template>
+      </TableCard>
+      <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]"
+                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
+                     @size-change="handleSizeChange"
+                     @current-change="handleCurrentChange">
+      </el-pagination>
+    </div>
+    <!--鏂板鑳藉姏璁ゅ畾寮规-->
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :title="title"
+               :visible.sync="dialogVisible"
+               width="80%" @close="resetForm">
+      <el-form v-if="dialogVisible" ref="infoForm" :model="form" :rules="rules">
+        <el-col :span="12">
+          <el-form-item label="浜哄憳锛�" label-width="110px" prop="userId">
+            <el-select v-model="form.userId" disabled clearable
+                       filterable size="small" style="width: 100%;">
+              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+<!--        <el-col :span="12">-->
+<!--          <el-form-item label="鑱岀О锛�" label-width="110px" prop="technicalPost">-->
+<!--            <el-input v-model="form.technicalPost" :disabled="operationType === 'view'" clearable size="small" style="width: 100%;"/>-->
+<!--          </el-form-item>-->
+<!--        </el-col>-->
+        <el-col :span="24">
+          <div style="display: flex;justify-content: space-evenly;font-weight: 600">
+            <span>鏌ユ牳缁撴灉</span>
+            <span>绗﹀悎涓庡惁</span>
+            <span>澶囨敞</span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="瀛﹀巻锛�" label-width="110px" prop="academicDegree">
+            <el-input v-model="form.academicDegree" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="academicConformNot" style="text-align: center">
+            <el-radio-group v-model="form.academicConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="academicRemarks">
+            <el-input v-model="form.academicRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鐩稿叧骞撮檺锛�" label-width="110px" prop="relatedYears">
+            <el-input v-model="form.relatedYears" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="relatedYearsConformNot" style="text-align: center">
+            <el-radio-group v-model="form.relatedYearsConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="relatedYearsRemarks	">
+            <el-input v-model="form.relatedYearsRemarks	" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鐩稿叧鍩硅锛�" label-width="110px" prop="relatedTraining">
+            <el-input v-model="form.relatedTraining" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="relatedTrainingConformNot" style="text-align: center">
+            <el-radio-group v-model="form.relatedTrainingConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="relatedTrainingRemarks">
+            <el-input v-model="form.relatedTrainingRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
+                      size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鐩稿叧缁忛獙锛�" label-width="110px" prop="relevantExperience">
+            <el-input v-model="form.relevantExperience" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="relevantExperienceConformNot" style="text-align: center">
+            <el-radio-group v-model="form.relevantExperienceConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="relevantExperienceRemarks">
+            <el-input v-model="form.relevantExperienceRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
+                      size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="涓婂矖璇侊細" label-width="110px" prop="workLicense">
+            <el-input v-model="form.workLicense" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"
+                      style="width: 100%">
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="workLicenseConformNot" style="text-align: center">
+            <el-radio-group v-model="form.workLicenseConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="workLicenseRemarks">
+            <el-input v-model="form.workLicenseRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="宀椾綅鑱岃矗锛�" label-width="110px" prop="jobResponsibilitiesTem" style="height: 450px">
+            <el-checkbox-group v-model="form.jobResponsibilitiesTem" :disabled="operationType === 'view' || operationType === 'confirm'"
+                               @change="selectResponsibilities">
+              <el-checkbox v-for="city in responsibilities" :key="city.value" :label="city.label"
+                           :value="city.value"></el-checkbox>
+            </el-checkbox-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item class="radio-group" prop="jobResponsibilitiesConformNot"
+                        style="text-align: center;height: 420px">
+            <el-radio-group v-model="form.jobResponsibilitiesConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
+              <el-radio :label="1">绗﹀悎</el-radio>
+              <el-radio :label="2">涓嶇鍚�</el-radio>
+              <el-radio :label="3">涓嶉�傜敤</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item prop="jobResponsibilitiesRemarks" style="height: 420px">
+            <el-input v-model="form.jobResponsibilitiesRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
+                      size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <span style="padding-left: 110px;font-size: 14px">澶囨敞锛氬矖浣嶈亴璐h揪鍒�5椤瑰強5椤逛互涓婁负绗﹀悎</span>
+        </el-col>
+        <el-col :span="16">
+          <el-form-item label="缁煎悎璇勪环锛�" label-width="110px" prop="comprehensiveAssessment">
+            <el-radio-group v-model="form.comprehensiveAssessment" :disabled="operationType === 'view' || operationType === 'confirm'">
+              <el-radio label="Qualified this position">鍙儨浠昏宀椾綅</el-radio>
+              <el-radio label="You can work while training">鍙竟鍩硅杈逛笂宀�</el-radio>
+              <el-radio label="Iconpetent for the position">涓嶈儨浠昏宀椾綅</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item prop="confirmOperatingPersonnelId" label="纭浜猴細">
+            <el-select v-model="form.confirmOperatingPersonnelId" clearable :disabled="operationType === 'view' || operationType === 'confirm'"
+                       filterable size="small" style="width: 50%;">
+              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button v-if="operationType !== 'view'" @click="resetForm">鍙栨秷</el-button>
+        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm">淇濆瓨</el-button>
+        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm1">鎻愪氦骞堕�氱煡</el-button>
+        <el-button v-if="operationType === 'confirm'" type="primary" @click="verifyGet">纭</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+export default {
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  components: {
+
+  },
+  data() {
+    return {
+      userName: '',
+      tableData: [],
+      search: {
+        size: 20,
+        current: 1,
+        total: 0
+      },
+      title: '鏂板鑳藉姏璁ゅ畾',
+      operationType: '',
+      yearColumnData: [
+        {
+          label: '宀椾綅',
+          prop: 'postName',
+          minWidth: '100'
+        }, {
+          label: '濮撳悕',
+          prop: 'userName',
+          minWidth: '100'
+        }, {
+          label: '瀛﹀巻',
+          prop: 'academicDegree',
+          minWidth: '100'
+        }, {
+          label: '涓撲笟',
+          prop: 'major',
+          minWidth: '100'
+        }, {
+          label: '鑱岀О',
+          prop: 'professionalTitle',
+          minWidth: '100'
+        }, {
+          dataType: 'slot',
+          label: '宀椾綅鑱岃矗',
+          prop: 'jobResponsibilities',
+          minWidth: '200px',
+          slot: 'jobResponsibilities'
+        }, {
+          dataType: 'tag',
+          label: '缁煎悎璇勪环',
+          minWidth: '140px',
+          prop: 'comprehensiveAssessment',
+          formatData: (params) => {
+            if (params == 'Qualified this position') {
+              return '鍙儨浠昏宀椾綅';
+            } else if (params == 'You can work while training') {
+              return '鍙竟鍩硅杈逛笂宀�';
+            } else {
+              return '涓嶈儨浠昏宀椾綅';
+            }
+          },
+          formatType: (params) => {
+            if (params == 'Qualified this position') {
+              return 'success';
+            } else if (params == 'You can work while training') {
+              return 'warning';
+            } else {
+              return 'danger';
+            }
+          }
+        }, {
+          label: '纭浜�',
+          prop: 'confirmOperatingPersonnelName',
+          minWidth: '100'
+        }, {
+          label: '纭鏃ユ湡',
+          prop: 'confirmDate',
+          minWidth: '160'
+        }, {
+          dataType: 'action',
+          minWidth: '220',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleViewClick('edit', row);
+              },
+              disabled: (row) => {
+                if (row.confirmDate) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鏌ョ湅',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleViewClick('view', row);
+              }
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.downLoadPost(row);
+              }
+            },
+            {
+              name: '纭',
+              type: 'text',
+              clickFun: (row) => {
+                this.handleViewClick('confirm', row);
+              },
+              disabled: (row) => {
+                if (row.confirmDate || JSON.parse(localStorage.getItem("user")).userId != row.confirmOperatingPersonnelId) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deletePost(row.id);
+              },
+              disabled: (row) => {
+                if (row.confirmDate) {
+                  return true
+                } else {
+                  return false
+                }
+              }
+            }
+          ]
+        }],
+      yearLoading: false,
+      dialogVisible: false,
+      verifyGetId: '',
+      form: {
+        jobResponsibilitiesTem: []
+      },
+      responsibleOptions: [],
+      rules: {
+        confirmOperatingPersonnelId: [{ required: true, message: '璇烽�夋嫨纭浜�', trigger: 'change' }],
+        userId: [{ required: true, message: '璇烽�夋嫨浜哄憳', trigger: 'change' }],
+        academicDegree: [{ required: true, message: '璇疯緭鍏ュ鍘嗘煡鏍哥粨鏋�', trigger: 'blur' }],
+        academicConformNot: [{ required: true, message: '璇烽�夋嫨瀛﹀巻绗﹀悎涓庡惁', trigger: 'change' }],
+        relatedYears: [{ required: true, message: '璇疯緭鍏ョ浉鍏冲勾闄愭煡鏍哥粨鏋�', trigger: 'blur' }],
+        relatedYearsConformNot: [{ required: true, message: '璇烽�夋嫨鐩稿叧骞撮檺绗﹀悎涓庡惁', trigger: 'change' }],
+        relatedTraining: [{ required: true, message: '璇疯緭鍏ョ浉鍩硅闄愭煡鏍哥粨鏋�', trigger: 'blur' }],
+        relatedTrainingConformNot: [{ required: true, message: '璇烽�夋嫨鐩稿叧鍩硅绗﹀悎涓庡惁', trigger: 'change' }],
+        relevantExperience: [{ required: true, message: '璇疯緭鍏ョ浉鍏崇粡楠屾煡鏍哥粨鏋�', trigger: 'blur' }],
+        relevantExperienceConformNot: [{ required: true, message: '璇烽�夋嫨鐩稿叧缁忛獙绗﹀悎涓庡惁', trigger: 'change' }],
+        workLicense: [{ required: true, message: '璇疯緭鍏ヤ笂宀楄瘉鏌ユ牳缁撴灉', trigger: 'blur' }],
+        workLicenseConformNot: [{ required: true, message: '璇烽�夋嫨涓婂矖璇佺鍚堜笌鍚�', trigger: 'change' }],
+        jobResponsibilitiesTem: [{ required: true, message: '璇烽�夋嫨宀椾綅鑱岃矗鏌ユ牳缁撴灉', trigger: 'change' }],
+        jobResponsibilitiesConformNot: [{ required: true, message: '璇烽�夋嫨宀椾綅鑱岃矗绗﹀悎涓庡惁', trigger: 'change' }],
+        comprehensiveAssessment: [{ required: true, message: '璇烽�夋嫨缁煎悎璇勪环', trigger: 'change' }]
+      },
+      responsibilities: []
+    };
+  },
+  mounted() {
+    this.getList(this.departId);
+  },
+  methods: {
+    // 涓嬭浇
+    downLoadPost(row) {
+      this.$axios.get(this.$api.personnel.exportPersonnelCapacity + '?id=' + row.id,{responseType: "blob"}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆
+        let reader = new FileReader();
+        reader.readAsText(blob, 'utf-8');
+        reader.onload = () => {
+          try {
+            let result = JSON.parse(reader.result);
+            if (result.message) {
+              this.$message.error(result.message);
+            } else {
+              const url = URL.createObjectURL(blob);
+              const link = document.createElement('a');
+              link.href = url;
+              link.download = "浜哄憳鑳藉姏瀵煎嚭" + '.docx';
+              link.click();
+              this.$message.success('瀵煎嚭鎴愬姛')
+            }
+          } catch (err) {
+            console.log(err);
+            const url = URL.createObjectURL(blob);
+            const link = document.createElement('a');
+            link.href = url;
+            link.download = "浜哄憳鑳藉姏瀵煎嚭" + '.docx';
+            link.click();
+            this.$message.success('瀵煎嚭鎴愬姛')
+          }
+        }
+      })
+    },
+    // 鏌ヨ
+    refreshTable() {
+      this.getList(this.departId);
+    },
+    // 鑾峰彇浜哄憳鑳藉姏鍒楄〃淇℃伅
+    getList(userId) {
+      this.search.userId = userId;
+      const name = this.isDepartment ? 'departmentId' : 'userId';
+      this.yearLoading = true
+      this.$axios.get(this.$api.personnel.personPersonnelCapacityPage + '?userName=' + this.userName + `&${name}=` + this.search.userId + '&size=' + this.search.size + '&current=' + this.search.current).then(res => {
+        this.yearLoading = false
+        if (res.code === 201) return;
+        this.tableData = res.data.records;
+        this.search.total = res.data.total;
+      }).catch(err => {
+        console.log(err);
+        this.yearLoading = false
+      })
+    },
+    selectResponsibilities(arr) {
+      let arrTem = [];
+      arr.map(val => {
+        const index = this.responsibilities.findIndex(item => item.label === val);
+        if (index > -1) {
+          arrTem.push(this.responsibilities[index].value);
+        }
+      });
+      this.form.jobResponsibilities = arrTem.join(',');
+    },
+    getResponsibilities() {
+      this.$axios.post(this.$api.enums.selectEnumByCategory, {
+        category: '宀椾綅鑱岃矗'
+      }).then(res => {
+        this.responsibilities = res.data;
+      });
+    },
+    changeLine (val) {
+      if(val) {
+        return val.replace(/,/g, '<br>')
+      } else {
+        return
+      }
+    },
+    // 鏂板
+    addAppointPost(type) {
+      this.operationType = type;
+      this.title = '鏂板鑳藉姏璁ゅ畾'
+      this.dialogVisible = true;
+      console.log('this.departId---', this.departId)
+      this.form = {
+        jobResponsibilitiesTem: []
+      }
+      this.form.userId = this.departId
+      this.getUserList();
+      this.getResponsibilities();
+
+    },
+    // 缂栬緫/鏌ョ湅
+    handleViewClick(type, row) {
+      this.operationType = type;
+      this.verifyGetId = row.id
+      this.title = this.operationType === 'edit' ? '淇敼鑳藉姏璁ゅ畾' : '鏌ョ湅鑳藉姏璁ゅ畾'
+      this.dialogVisible = true;
+      this.form = {...row}
+      if(this.form.responsibilities) {
+        this.$set(this.form, 'jobResponsibilitiesTem', this.form.responsibilities.split(","))
+      } else {
+        this.$set(this.form, 'jobResponsibilitiesTem', [])
+      }
+      this.getUserList();
+      this.getResponsibilities();
+    },
+    // 淇濆瓨
+    submitForm() {
+      this.$refs.infoForm.validate((valid) => {
+        if (valid) {
+          this.$axios.post(this.$api.personnel.addOrUpdatePersonPersonnelCapacity, this.form, {
+            headers: {
+              'Content-Type': 'application/json'
+            }
+          }).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.getList(this.departId);
+              this.dialogVisible = false;
+            }
+          });
+        }
+      });
+    },
+    // 鎻愪氦骞堕�氱煡
+    submitForm1() {
+      this.$refs.infoForm.validate((valid) => {
+        if (valid) {
+          this.$axios.post(this.$api.personnel.submitConfirmPersonnelCapability, this.form, {
+            headers: {
+              'Content-Type': 'application/json'
+            }
+          }).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鎻愪氦鎴愬姛');
+              this.getList(this.departId);
+              this.dialogVisible = false;
+            }
+          });
+        }
+      });
+    },
+    verifyGet () {
+      this.$axios.get(this.$api.personnel.confirmPersonnelCapability + '?id=' + this.verifyGetId).then(res => {
+        if (res.code == 200) {
+          this.$message.success('纭鎴愬姛');
+          this.resetForm()
+          this.getList(this.departId);
+        }
+      });
+    },
+    // 鍒犻櫎宀椾綅鑱岃矗
+    deletePost(id) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎姝ゆ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.$axios.delete(this.$api.personnel.deletePersonPersonnelCapacity + '?id=' + id).then(res => {
+          if (res.code == 200) {
+            this.$message.success('鍒犻櫎鎴愬姛');
+            this.getList(this.departId);
+          }
+        });
+      }).catch(() => {
+        this.$message.error('鍒犻櫎澶辫触');
+      });
+    },
+    resetForm() {
+      this.$refs.infoForm.resetFields();
+      this.dialogVisible = false;
+    },
+    getUserList(){
+      this.$axios.get(this.$api.user.selectDepartmentLimsUserList).then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      })
+    },
+    handleSizeChange(val) {
+      this.search.size = val;
+      this.getList(this.departId);
+    },
+    handleCurrentChange(val) {
+      this.search.current = val;
+      this.getList(this.departId);
+    }
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    departId: {
+      handler(newId, oldId) {
+        this.getList(newId);
+      }
+    },
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    isDepartment: {
+      handler(newId, oldId) {
+        this.getList(this.departId);
+      }
+    },
+  }
+};
+</script>
+<style scoped>
+>>>.el-dialog {
+  margin: 6vh auto 50px !important;
+}
+>>> .el-dialog__body {
+  max-height: 70vh;
+  overflow-y: auto;
+}
+
+.radio-group >>> .el-form-item__error {
+  padding-left: 38px;
+}
+>>>.el-checkbox__label {
+  width: 212px;
+  white-space: pre-wrap;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue
new file mode 100644
index 0000000..2b71f75
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue
@@ -0,0 +1,1115 @@
+<template>
+  <div>
+    <div style="text-align: right;margin-bottom: 10px">
+<!--       <el-button size="small" @click="$emit('goBackList')">杩斿洖</el-button>-->
+      <el-button size="small" type="primary" @click="downPerson">涓嬭浇妗f</el-button>
+      <el-button size="small" type="primary" @click="dialogVisible = true">浜哄憳鍒嗙被</el-button>
+      <el-button :loading="saveLoading" size="small" type="primary" @click="save">淇濆瓨</el-button>
+    </div>
+    <div>
+      <div style="display: flex;flex-direction: row;">
+        <div style="width: 12em">
+          <el-image :src="javaApi + '/img/' + form.pictureUrl" fit="fill"
+                    style="width:100%;height: 300px;border: 1px solid #000;border-radius: 10px;margin-left: 6px;margin-top: 10px;">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
+            </div>
+          </el-image>
+          <el-image :src="javaApi + '/img/' + form.signatureUrl" fit="fill"
+                    style="width:80%;height: 50px;border: 1px solid #000;border-radius: 10px;margin-left: 22px;margin-top: 20px;">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
+            </div>
+          </el-image>
+        </div>
+        <div style="height: calc(100vh - 14em);overflow-y: auto">
+          <el-form ref="form" :model="form" label-width="110px">
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="濮撳悕">
+                  <el-input disabled v-model="form.name" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="宸ュ彿">
+                  <el-input disabled v-model="form.account" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="褰撳墠鐘舵��">
+                  <el-radio-group v-model="form.currentState">
+                    <el-radio label="1formal" size="mini">姝e紡</el-radio>
+                    <el-radio label="2intern" size="mini">瀹炰範</el-radio>
+                    <el-radio label="3leaveOffice" size="mini">绂昏亴</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鎬у埆">
+                  <el-radio-group v-model="form.sex">
+                    <el-radio label="1" size="mini">鐢�</el-radio>
+                    <el-radio label="0" size="mini">濂�</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍏徃鍚嶇О">
+                  <el-input v-model="form.corporateName" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鎵�灞為儴闂�">
+                  <el-cascader v-model="form.departLimsId" :options="department" :props="{ label: 'name', value: 'id',checkStrictly: true }"  filterable style="width: 100%;"></el-cascader>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="宀椾綅鍚嶇О">
+                  <el-input v-model="form.postName" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍏ラ泦鍥㈡椂闂�">
+                  <el-date-picker v-model="form.groupTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍔冲姩鍏崇郴">
+                  <el-radio-group v-model="form.laborRelations">
+                    <el-radio :label=0 size="mini">鍚堝悓宸�</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鍏徃閭">
+                  <el-input v-model="form.email" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="宸ヤ綔鏃堕棿">
+                  <el-date-picker v-model="form.workingTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍚堝悓鍒版湡鏃堕棿">
+                  <el-date-picker v-model="form.contractLifeTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鑱岀О">
+                  <el-input v-model="form.professionalTitle" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="16" style="text-align: left;">
+                <el-form-item label="浜哄憳鍒嗙被">
+                  <span style="color: #000;">{{ form.personnelClassification }}</span>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鍑虹敓鏃ユ湡">
+                  <el-date-picker v-model="form.dateBirth" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                                  @change="getAge"
+                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="绫嶈疮">
+                  <el-input v-model="form.nativePlace" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="姘戞棌">
+                  <el-input v-model="form.nation" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="韬唤璇佸彿">
+                  <el-input v-model="form.identityCard" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="骞撮緞">
+                  <el-input-number v-model="form.age" :max="130" :min="1"
+                                   controls-position="right" size="small" style="width: 99%;"></el-input-number>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="濠氬Щ鐘跺喌">
+                  <el-radio-group v-model="form.maritalStatus">
+                    <el-radio :label=0 size="mini">宸插</el-radio>
+                    <el-radio :label=1 size="mini">鏈</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="璇佷欢鏈夋晥鏈�">
+                  <el-date-picker v-model="form.validityPeriod" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="璇佷欢鍦板潃">
+                  <el-input v-model="form.idAddress" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="璇佷欢璇︾粏鍦板潃">
+                  <el-input v-model="form.idDetailAddress" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鏀挎不闈㈣矊">
+                  <el-input v-model="form.politicalStatus" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍏ュ厷/鍥㈡椂闂�">
+                  <el-date-picker v-model="form.dumplingTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鎵嬫満鍙�">
+                  <el-input v-model="form.telephone" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鏈�楂樺鍘�">
+                  <el-input v-model="form.officialAcademicRedentials" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鏈�楂樺浣�">
+                  <el-input v-model="form.highestDegree" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟闄㈡牎1">
+                  <el-input v-model="form.graduatedInstitutions1" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="涓撲笟1">
+                  <el-input v-model="form.major1" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟鏃堕棿1">
+                  <el-date-picker v-model="form.graduationTime1" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟闄㈡牎2">
+                  <el-input v-model="form.graduatedInstitutions2" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="涓撲笟2">
+                  <el-input v-model="form.major2" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="姣曚笟鏃堕棿2">
+                  <el-date-picker v-model="form.graduationTime2" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="鐧昏鏃堕棿">
+                  <el-date-picker v-model="form.lastUpdateTime" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡"
+                                  size="small" style="width: 99%;" type="date"
+                                  value-format="yyyy-MM-dd HH:mm:ss">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="澶囨敞">
+                  <el-input type="textarea" v-model="form.remarks" clearable size="small"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="18">
+                <el-form-item label="涓汉鐓х墖">
+                  <el-input v-model="form.pictureUrl" disabled size="small">
+                    <el-button v-if="form.pictureUrl" slot="append" icon="el-icon-delete-solid"
+                               @click="deleteFile(form.pictureUrl, 'pictureUrl')"></el-button>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-upload ref="upload" :action="action"
+                           :headers="uploadHeader"
+                           :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'pictureUrl')"
+                           :show-file-list="false"
+                           style="float: left; margin: 0 10px 0 10px;">
+                  <el-button slot="trigger" class="uploadFile" size="mini" type="primary">涓婁紶</el-button>
+                </el-upload>
+                <el-button v-if="form.pictureUrl" class="uploadFile" size="mini"
+                           type="primary" @click="downloadFile(form.pictureUrl)">涓嬭浇</el-button>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="18">
+                <el-form-item label="鐢靛瓙绛惧悕">
+                  <el-input v-model="form.signatureUrl" disabled size="small">
+                    <el-button v-if="form.signatureUrl" slot="append" icon="el-icon-delete-solid"
+                               @click="deleteFile(form.signatureUrl, 'signatureUrl')"></el-button>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-upload ref="upload" :action="action"
+                           :headers="uploadHeader"
+                           :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'signatureUrl')"
+                           :show-file-list="false"
+                           style="float: left; margin: 0 10px 0 10px;">
+                  <el-button slot="trigger" class="uploadFile" size="small" type="primary">涓婁紶</el-button>
+                </el-upload>
+                <el-button v-if="form.signatureUrl" class="uploadFile" size="small"
+                           type="primary" @click="downloadFile(form.signatureUrl)">涓嬭浇</el-button>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="20">
+                <el-form-item label="璇佷功璧勬枡" >
+                </el-form-item>
+              </el-col>
+              <el-col :span="4">
+                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd(0)">鏂板</el-button>
+              </el-col>
+            </el-row>
+            <lims-table :tableData="annexList" :column="columnData2" style="width: 96%;margin-left: 34px"
+                        height="200" :tableLoading="tableLoading2"></lims-table>
+            <el-row style="margin-top: 10px">
+              <el-col :span="20">
+                <el-form-item label="闄勪欢璧勬枡" >
+                </el-form-item>
+              </el-col>
+              <el-col :span="4">
+                <el-upload ref='upload'
+                           :action="fileAction"
+                           :auto-upload="true" :data="{userId: clickNodeVal.userId}"
+                           :before-upload="fileBeforeUpload"
+                           :headers="uploadHeader" :on-error="onError"
+                           :on-success="handleSuccessUp"
+                           :show-file-list="false"
+                           accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
+                  <el-button size="small" type="primary">闄勪欢涓婁紶</el-button>
+                </el-upload>
+              </el-col>
+            </el-row>
+            <lims-table :tableData="tableData" :column="columnData" style="width: 96%;float: right;"
+                        height="200" :tableLoading="tableLoading"></lims-table>
+            <el-row style="margin-top: 10px">
+              <el-col :span="20">
+                <el-form-item label="宸ヤ綔缁忓巻" >
+                </el-form-item>
+              </el-col>
+              <el-col :span="4">
+                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd1('add')">鏂板</el-button>
+              </el-col>
+            </el-row>
+            <el-table :data="tableData1" border height="200" style="width: 96%;float: right;" v-loading="tableLoading1">
+              <el-table-column label="搴忓彿" type="index" width="55px" align="center">
+              </el-table-column>
+              <el-table-column label="宸ヤ綔缁忓巻" prop="workExperience">
+              </el-table-column>
+              <el-table-column align="center" label="鎿嶄綔">
+                <template slot-scope="scope">
+                  <el-button type="text" size="mini" @click="annexAdd1('edit',scope.row)">缂栬緫</el-button>
+                  <el-button type="text" size="mini" @click="deleteAnnex1(scope.row)" style="color: #f56c6c">鍒犻櫎</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form>
+        </div>
+      </div>
+    </div>
+    <!-- 浜哄憳鍒嗙被寮规 -->
+    <el-dialog :visible.sync="dialogVisible" title="鎻愮ず" width="40%" @open="getComparisonList">
+      <div style="height: 30vh;">
+        <el-row>
+          <el-col :span="4">
+            浜哄憳鍒嗙被锛�
+          </el-col>
+          <el-col :span="20" style="text-align: left;">
+            <el-checkbox-group v-model="checkList">
+              <el-checkbox v-for="v in dict.type.personnl_type" :key="v.value"
+                           :label="v.value"></el-checkbox>
+            </el-checkbox-group>
+          </el-col>
+        </el-row>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="clickPersonnelClassificationSure">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 鏂板闄勪欢璧勬枡 -->
+    <el-dialog :before-close="handleClose" :title="title" :visible.sync="dialogVisible1" width="40%" @open="getComparisonList">
+      <el-form ref="annex" :model="annex" :rules="rules" label-width="100px">
+        <el-row>
+          <el-col :span="16">
+            <el-form-item label="璇佷欢鍙�" prop="idNumber">
+              <el-input v-model="annex.idNumber" clearable size="small" style="width: 100%;"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鍙戣瘉鍗曚綅" prop="issueUnit">
+              <el-input v-model="annex.issueUnit" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="绾у埆">
+              <el-input v-model="annex.level" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鏈夋晥鏈�" prop="periodValidity">
+              <el-input v-model="annex.periodValidity" clearable size="small"></el-input>
+<!--              <el-date-picker v-model="annex.periodValidity" format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"-->
+<!--                              style="width: 99%;" type="date" value-format="yyyy-MM-dd">-->
+<!--              </el-date-picker>-->
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="澶嶅嵃浠�">
+              <el-input v-model="annex.copy" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鍘熶欢">
+              <el-input v-model="annex.original" clearable size="small"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row style="margin-top: 15px">
+          <el-col :span="16">
+            <el-form-item label="鏂囦欢">
+              <el-upload
+                :action="action"
+                :before-upload="beforeAvatarUpload"
+                :headers="uploadHeader"
+                :on-success="(response,file,fileList) => onSuccess(response, file, fileList, 'fileName')"
+                :show-file-list="false">
+                <span v-if="annex.fileName">{{annex.fileName}}</span>
+<!--                <img v-if="imageUrl" :src="imageUrl" class="avatar">-->
+                <i v-else class="el-icon-upload avatar-uploader-icon"></i>
+              </el-upload>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="cancellation">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+    <!-- 鏂板宸ヤ綔缁忓巻 -->
+    <el-dialog @close="handleClose2" title="娣诲姞宸ヤ綔缁忓巻" :visible.sync="dialogVisible2" width="40%">
+      <el-form ref="annex2" :model="annex2" label-width="100px">
+        <el-row>
+          <el-col :span="16">
+            <el-form-item label="宸ヤ綔缁忓巻" prop="idNumber">
+              <el-input type="textarea" v-model="annex2.workExperience" clearable size="small" style="width: 100%;"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose2">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitForm2">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import fileDownload from '@/utils/file'
+import {
+  addAnnex,
+  addBasicInfoWork,
+  delBasicInfoFileList,
+  delBasicInfoWorkList,
+  deleteAnnex, deleteCNASFile,
+  exportPersonBasicInfoById,
+  getAnnex,
+  getAnnexByUserId,
+  getBasicInfoFileList,
+  getBasicInfoWorkList,
+  getCNASPersonnelInfo,
+  saveCNASPersonnelInfo,
+  updateAnnex,
+  updateBasicInfoWorkList
+} from "@/api/cnas/personal/personalList";
+import limsTable from "@/components/Table/lims-table.vue";
+
+export default {
+  props: {
+    clickNodeVal: {
+      type: Object,
+      default: () => { return {} }
+    },
+  },
+  dicts: ['personnl_type'],
+  data() {
+    return {
+      operationType: '',
+      basicInfoWorkId: '',
+      dialogVisible2: false,
+      annex2: {
+        workExperience: ''
+      },
+      tableLoading: false,
+      tableData: [],
+      columnData: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '100',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.upload(row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.delete(row)
+              }
+            }
+          ]
+        }
+      ],
+      columnData2: [
+        {
+          label: '璇佷欢鍙�',
+          prop: 'idNumber',
+          minWidth: '150px'
+        },{
+          label: '鍙戣瘉鍗曚綅',
+          prop: 'issueUnit',
+          minWidth: '150px'
+        },{
+          label: '鏂囦欢鍚嶇О',
+          prop: 'fileName',
+          minWidth: '200px'
+        },{
+          label: '绾у埆',
+          prop: 'level',
+          minWidth: '150px'
+        },{
+          label: '鏈夋晥鏈�',
+          prop: 'periodValidity',
+          minWidth: '150px'
+        },{
+          label: '娣诲姞鏃堕棿',
+          prop: 'createTime',
+          minWidth: '150px'
+        },
+        {
+          dataType: 'action',
+          minWidth: '130',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '涓嬭浇',
+              type: 'text',
+              clickFun: (row) => {
+                this.downloadFile(row.fileName)
+              }
+            },
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.annexAdd(1,row)
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deleteAnnex(row)
+              }
+            }
+          ]
+        }
+      ],
+      tableLoading1: false,
+      tableLoading2: false,
+      tableData1: [],
+      addOrupdate: null,
+      title: '',
+      annexList: [],
+      imageUrl: '',
+      annex: {
+        userId: '',
+        idNumber: '',
+        issueUnit: '',
+        level: '',
+        periodValidity: '',
+        copy: '',
+        original: '',
+        fileName: ''
+      },
+      rules: {
+        idNumber: [
+          { required: true, message: '璇疯緭鍏ヨ瘉浠跺彿', trigger: 'blur' }
+        ],
+        issueUnit: [
+          { required: true, message: '璇疯緭鍏ュ彂璇佸崟浣�', trigger: 'blur' }
+        ],
+        periodValidity: [
+          { required: false, message: '璇烽�夋嫨鏈夋晥鏈�', trigger: 'blur' }
+        ]
+      },
+      dialogVisible1: false,
+      form: {
+        userId: '',
+        name: '',
+        account: '',
+        currentState: '',
+        sex: '',
+        corporateName: '',
+        department: '',
+        departLimsId: [],
+        postName: '',
+        groupTime: '',
+        laborRelations: '',
+        workingTime: '',
+        contractLifeTime: '',
+        personnelClassification: '',
+        dateBirth: '',
+        nativePlace: '',
+        nation: '',
+        identityCard: '',
+        age: '',
+        validityPeriod: '',
+        maritalStatus: '',
+        idAddress: '',
+        idDetailAddress: '',
+        politicalStatus: '',
+        dumplingTime: '',
+        telephone: '',
+        email: '',
+        officialAcademicRedentials: '',
+        highestDegree: '',
+        graduatedInstitutions1: '',
+        major1: '',
+        graduationTime1: '',
+        graduatedInstitutions2: '',
+        major2: '',
+        graduationTime2: '',
+        lastUpdateTime: '',
+        pictureUrl: '',
+        signatureUrl: '',
+        professionalTitle: '',
+        remarks: '',
+      },
+      department: [],
+      saveLoading: false,
+      dialogVisible: false,
+      checkList: [],
+      successFileList: [], // 闃叉鍚庣鍑虹幇鑴忔暟鎹�
+      isSave: false,
+    }
+  },
+  components: {limsTable, fileDownload},
+  created() {
+    this.init()
+    this.searchTableList()
+    this.searchTableList2()
+  },
+  computed: {
+    action() {
+      return this.javaApi + '/personBasicInfo/saveCNASFile'
+    },
+    fileAction() {
+      return this.javaApi + '/personBasicInfo/uploadBasicInfoFile'
+    },
+  },
+  methods: {
+    // 涓嬭浇妗f
+    downPerson(){
+      exportPersonBasicInfoById({id: this.clickNodeVal.userId}).then(res => {
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, '浜哄憳妗f.docx');
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 涓婁紶楠岃瘉
+    fileBeforeUpload(file) {
+      let flag = true
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        flag = false
+      }
+      if (!flag) {
+        return Promise.reject(flag); //姝g‘鐨勭粓姝�
+      }
+    },
+    onError(err, file, fileList,type) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+    },
+    handleSuccessUp(response, ) {
+      this.upLoading = false;
+      if (response.code == 200) {
+        this.$message.success('涓婁紶鎴愬姛');
+        this.searchTableList()
+      } else {
+        this.$message.error(response.message);
+      }
+    },
+    // 鏌ヨ闄勪欢鍒楄〃
+    searchTableList () {
+      this.tableLoading = true
+      getBasicInfoFileList({userId: this.clickNodeVal.userId}).then(res => {
+        this.tableLoading = false
+        this.tableData = res.data
+      }).catch(err => {
+        this.tableLoading = false
+        console.log('err---', err);
+      })
+    },
+    // 涓嬭浇
+    upload (row) {
+      let url = '';
+      if(row.type==1){
+        url = this.javaApi+'/img/'+row.fileUrl
+        fileDownload.downloadIamge(url,row.fileName)
+      }else{
+        url = this.javaApi+'/word/'+row.fileUrl
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = row.fileName;
+        link.click();
+      }
+    },
+    // 鍒犻櫎
+    delete (row) {
+      this.$confirm('姝ゆ搷浣滃皢鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading = true
+        delBasicInfoFileList({basicInfoFileId: row.basicInfoFileId}).then(res => {
+          this.tableLoading = false
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchTableList();
+        }).catch(err => {
+          this.tableLoading = false
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      })
+    },
+    // 鎵撳紑宸ヤ綔缁忓巻鎺㈠喌
+    annexAdd1 (type, row) {
+      this.operationType = type
+      if (type === 'edit') {
+        this.basicInfoWorkId = row.basicInfoWorkId
+        this.annex2.workExperience = row.workExperience
+      } else {
+        this.basicInfoWorkId = ''
+        this.annex2.workExperience = ''
+      }
+      this.dialogVisible2 = true
+    },
+    // 鎻愪氦宸ヤ綔缁忓巻
+    submitForm2 () {
+      const params = {
+        workExperience: this.annex2.workExperience,
+        userId: this.clickNodeVal.userId,
+        basicInfoWorkId: this.basicInfoWorkId
+      }
+      this.tableLoading1 = true
+      if (this.operationType === 'add') {
+        addBasicInfoWork(params).then(res => {
+          this.tableLoading1 = false
+          if (res.code == 200) {
+            this.dialogVisible2 = false
+            this.$message.success('鏂板鎴愬姛')
+            this.searchTableList2();
+          }
+        }).catch(err => {
+          this.tableLoading1 = false
+        })
+      } else {
+        updateBasicInfoWorkList(params).then(res => {
+          this.tableLoading1 = false
+          this.dialogVisible2 = false
+          this.$message.success('淇敼鎴愬姛')
+          this.searchTableList2();
+        }).catch(err => {
+          this.tableLoading1 = false
+        })
+      }
+    },
+    // 鍏抽棴宸ヤ綔缁忓巻寮规
+    handleClose2 () {
+      this.dialogVisible2 = false
+      this.annex2.workExperience = ''
+    },
+    // 鍒犻櫎宸ヤ綔缁忓巻
+    deleteAnnex1 (row) {
+      this.$confirm('姝ゆ搷浣滃皢鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.tableLoading1 = true
+        delBasicInfoWorkList({basicInfoWorkId: row.basicInfoWorkId}).then(res => {
+          this.tableLoading1 = false
+          this.$message.success('鍒犻櫎鎴愬姛')
+          this.searchTableList2();
+        }).catch(err => {
+          this.tableLoading1 = false
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 鏌ヨ宸ヤ綔缁忓巻鍒楄〃
+    searchTableList2 () {
+      this.tableLoading1 = true
+      getBasicInfoWorkList({userId: this.clickNodeVal.userId}).then(res => {
+        this.tableLoading1 = false
+        this.tableData1 = res.data
+      }).catch(err => {
+        this.tableLoading1 = false
+        console.log('err---', err);
+      })
+    },
+    annexAdd(type,row) {
+      if(type === 1) {
+        this.title = '缂栬緫闄勪欢璧勬枡'
+        this.addOrupdate = 1
+        getAnnex({id: row.id}).then(res => {
+          this.annex = res.data
+          this.imageUrl = this.javaApi + '/img/' + res.data.fileName
+        })
+      }else {
+        this.title = '鏂板闄勪欢璧勬枡'
+        this.addOrupdate = 2
+      }
+      this.dialogVisible1 = true
+    },
+    submitForm() {
+      this.$refs['annex'].validate((valid) => {
+        if (valid) {
+          this.addAnnex()
+        } else {
+          return false
+        }
+      })
+    },
+    addAnnex() {
+      if(this.annex.fileName == "" || this.annex.fileName == null || this.annex.fileName == undefined) {
+        this.$message.error("璇蜂笂浼犳枃浠�")
+        return
+      }
+      this.annex.userId = this.clickNodeVal.userId
+      if(this.addOrupdate === 1) {
+        updateAnnex(this.annex).then(res => {
+          if(res.code == 200) {
+            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
+              this.imageUrl = ''
+              this.resetForm('annex')
+              this.annexList = res.data
+              this.dialogVisible1 = false
+              this.$message.success('鏇存柊鎴愬姛锛�')
+            })
+          }
+        })
+      }else {
+        this.annex.id = null
+        addAnnex(this.annex).then(res => {
+          if(res.code == 200) {
+            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
+              this.imageUrl = ''
+              this.resetForm('annex')
+              this.annexList = res.data
+              this.dialogVisible1 = false
+              this.$message.success('淇濆瓨鎴愬姛')
+            })
+          }
+        })
+      }
+    },
+    deleteAnnex(row) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        deleteAnnex({id: row.id}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛锛�')
+          this.annexList = this.annexList.filter(item => item.id != row.id)
+        })
+      })
+    },
+    beforeAvatarUpload(file) {
+      let flag = true
+      if (file.size > 1024 * 1024 * 10) {
+        this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+        this.$refs.upload.clearFiles()
+        flag = false
+      }
+      if (!flag) {
+        return Promise.reject(flag); //姝g‘鐨勭粓姝�
+      }
+    },
+    downloadFile(fileName) {
+      let state = /\.(jpg|jpeg|png|gif)$/i.test(fileName)
+      if (state) {
+        let url = this.javaApi + '/img/' + fileName;
+        fileDownload.downloadIamge(url, fileName)
+      } else {
+        const url = this.javaApi + '/word/' + fileName
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = fileName;
+        link.click();
+        this.$message.success('涓嬭浇鎴愬姛')
+      }
+    },
+    async onSuccess(response, file, fileList, entityVal) {
+      if(entityVal == 'fileName') {
+        this.annex.fileName = response.data
+      }
+      // 鍦ㄤ繚瀛樿祴鍊兼柊鏂囦欢
+      this.successFileList.push(response.data)
+      this.$set(this.form, entityVal, response.data)
+    },
+    // 鍒濆鍖栬皟鐢�
+    init() {
+      if (!this.clickNodeVal.userId) {
+        let user = JSON.parse(localStorage.getItem('user'))
+        this.getUserBasisInfo(user.userId)
+        this.clickNodeVal.userId = user.userId
+      } else {
+        this.getUserBasisInfo(this.clickNodeVal.userId)
+      }
+    },
+    getUserBasisInfo(userId) {
+      getCNASPersonnelInfo({userId: userId}).then(res => {
+        this.form = res.data.PersonBasicInfoDto
+        this.department = res.data.department
+        this.annexList = res.data.annexList
+        this.form.departLimsId = res.data.PersonBasicInfoDto.departLimsId.split(',').filter(a => a != "").map(Number)
+      })
+    },
+    async save() {
+      this.saveLoading = true
+      this.form.userId = this.clickNodeVal.userId
+      if(Array.isArray(this.form.departLimsId)) {
+        if(this.form.departLimsId.length > 0) {
+          this.form.departLimsId = this.form.departLimsId.join(',').trim() + ','
+        }else {
+          this.form.departLimsId = ''
+        }
+      }
+      saveCNASPersonnelInfo(this.form).then(res => {
+        this.saveLoading = false
+        this.isSave = true
+        this.getUserBasisInfo(this.clickNodeVal.userId)
+        this.$message.success('淇濆瓨鎴愬姛锛�')
+      })
+    },
+    // 鍙栦汉鍛樺垎绫荤殑瀛楀吀
+    getComparisonList() {
+      if (this.checkList.length > 0) {
+        this.form.personnelClassification = this.checkList.split('锛�')
+      }
+    },
+    clickPersonnelClassificationSure() {
+      this.dialogVisible = false
+      this.form.personnelClassification = this.checkList.filter(m=>m).join('锛�')
+    },
+    async deleteFile(fileName, entityVal) {
+      await deleteCNASFile({fileName: fileName}).then(res => {
+        this.$message.success('鍒犻櫎鎴愬姛锛�')
+        this.$set(this.form, entityVal, null)
+        let index = this.successFileList.indexOf(fileName)
+        if (index != -1) {
+          this.successFileList.splice(index, 1)
+        }
+      })
+    },
+    cancellation() {
+      this.dialogVisible1 = false
+      this.imageUrl = ''
+      this.resetForm('annex')
+    },
+    handleClose(done) {
+      this.imageUrl = ''
+      this.annex = {
+        userId: '',
+        idNumber: '',
+        issueUnit: '',
+        level: '',
+        periodValidity: '',
+        copy: '',
+        original: '',
+        fileName: ''
+      }
+      done();
+    },
+    resetForm(formName) {
+      this.$refs[formName].resetFields();
+    },
+    getAge (val) {
+      this.form.age = this.calculateAge(val)
+    },
+    calculateAge(birthDateString) {
+      // 瑙f瀽鍑虹敓鏃ユ湡瀛楃涓蹭负鏃ユ湡瀵硅薄
+      const birthDate = new Date(birthDateString);
+
+      // 鑾峰彇褰撳墠鏃ユ湡
+      const currentDate = new Date();
+
+      // 璁$畻骞翠唤宸�
+      let age = currentDate.getFullYear() - birthDate.getFullYear();
+
+      // 妫�鏌ユ槸鍚﹀凡缁忚繃浜嗕粖骞寸殑鐢熸棩
+      const currentMonth = currentDate.getMonth();
+      const currentDay = currentDate.getDate();
+      const birthMonth = birthDate.getMonth();
+      const birthDay = birthDate.getDate();
+
+      if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
+        // 濡傛灉杩樻病鍒颁粖骞寸殑鐢熸棩锛屽勾榫勫噺1
+        age--;
+      }
+
+      return age;
+    }
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    clickNodeVal: {
+      handler(newVal, oldVal) {
+        if (newVal.userId) {
+          this.getUserBasisInfo(newVal.userId)
+          this.searchTableList()
+          this.searchTableList2()
+        }
+      },
+    }
+  }
+}
+</script>
+
+<style scoped>
+>>>.el-table__body-wrapper::-webkit-scrollbar {
+  height: 12px;
+  /* 璁剧疆婊氬姩鏉″搴� */
+}
+>>>.el-form-item {
+    margin-bottom: 3px;
+}
+
+.el-input {
+    border-radius: 15px;
+}
+
+.el-icon-picture-outline {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+}
+
+.uploadFile {
+    margin-top: 2px;
+    float: left;
+}
+  .avatar-uploader-icon {
+    font-size: 28px;
+    color: #0f8bf1;
+    width: 178px;
+    height: 50px;
+    text-align: center;
+    border: 1px solid #d9d9d9;
+  }
+  .avatar {
+    width: 178px;
+    height: 178px;
+    display: block;
+  }
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue
new file mode 100644
index 0000000..edf7b44
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue
@@ -0,0 +1,317 @@
+<template>
+  <div>
+    <div style="display: flex;justify-content: space-between;">
+      <el-form :model="entity" ref="entity" size="small" :inline="true">
+        <el-form-item label="浜哄憳鍚嶇О">
+          <el-input v-model="entity.name" clearable></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="small" style="margin-left: 10px" @click="refresh()">閲� 缃�</el-button>
+          <el-button size="small" type="primary" @click="refreshTable()">鏌� 璇�</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button
+          :loading="outLoading"
+          size="small"
+          type="primary"
+          @click="handleDown">瀵煎嚭</el-button>
+        <el-button size="small" type="primary" @click="openSelectUserDia">鏂板缓</el-button>
+      </div>
+    </div>
+    <div class="search-table">
+      <el-table v-loading="tableLoading" :data="tableData" border height="calc(100vh - 21em)" style="width: 100%;">
+        <el-table-column align="center" label="搴忓彿" type="index" width="60"></el-table-column>
+        <el-table-column label="鍛樺伐缂栧彿" prop="account" width="150"></el-table-column>
+        <el-table-column label="濮撳悕" prop="name" width="120"></el-table-column>
+        <el-table-column label="绫嶈疮" prop="nativePlace" width="120"></el-table-column>
+        <el-table-column label="璇佷欢鍦板潃" prop="idAddress" show-overflow-tooltip width="100"></el-table-column>
+        <el-table-column label="鎵嬫満鍙�" prop="telephone" show-overflow-tooltip width="100"></el-table-column>
+        <el-table-column label="姣曚笟闄㈡牎" prop="graduatedInstitutions1" width="100"></el-table-column>
+        <el-table-column label="鎵�瀛︿笓涓�" prop="major1" width="100"></el-table-column>
+        <el-table-column label="姣曚笟鏃堕棿" prop="graduationTime1" width="100"></el-table-column>
+        <el-table-column label="鏈�楂樺鍘�" prop="officialAcademicRedentials" width="100"></el-table-column>
+        <el-table-column label="鏈�楂樺浣�" prop="highestDegree" width="100"></el-table-column>
+        <el-table-column label="鑱岀О" prop="professionalTitle" width="100"></el-table-column>
+        <el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
+          <template slot-scope="scope">
+            <el-button size="small" type="text" @click="$emit('updatePerson', scope.row)">缂栬緫</el-button>
+            <el-button size="small" type="text" @click="deletePerson(scope.row)" style="color: #f56c6c">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        :current-page="1"
+        :current-page.sync="page.current"
+        :page-size="page.size"
+        :page-sizes="[10, 20, 30, 50, 100]"
+        :total="page.total"
+        background
+        layout="->,total, sizes, prev, pager, next, jumper"
+        style="margin-top: 16px"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      >
+      </el-pagination>
+    </div>
+    <el-dialog :visible.sync="selectUserDia" title="閫夋嫨鐢ㄦ埛" width="70%">
+      <div class="search" style="margin-bottom: 9px;">
+        <div class="search_thing">
+          <div class="search_label">鐢ㄦ埛鍚嶏細</div>
+          <div class="search_input">
+            <el-input
+              v-model="addUserTableInfo.name"
+              clearable
+              placeholder="璇疯緭鍏�"
+              size="small"
+              @change="selectUserList"
+            ></el-input>
+          </div>
+          <el-button size="small" style="margin-left: 10px" type="primary" @click="selectUserList">鏌ヨ</el-button>
+        </div>
+      </div>
+      <div v-if="selectUserDia" class="body" style="height: 60vh;">
+        <lims-table :tableData="tableData1" :column="column1"
+                    :isSelection="true" :handleSelectionChange="selectMethod"
+                    :height="'calc(100vh - 290px)'"
+                    :tableLoading="tableLoading1"></lims-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="selectUserDia = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="selectUser">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {selectUserCondition} from "@/api/business/inspectionTask";
+import limsTable from "@/components/Table/lims-table.vue";
+import {
+  basicInformationOfPersonnelSelectPage,
+  delUserDepardLimsId,
+  exportPersonBasicInfo,
+  upUserDepardLimsId
+} from "@/api/cnas/personal/personalList";
+import store from "@/store";
+import {Message} from "element-ui";
+
+export default {
+  name: 'PersonnelList',
+  // import 寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
+  components: {limsTable},
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    },
+    currentCompaniesList: {
+      type: Array,
+      default: []
+    }
+  },
+  data() {
+    // 杩欓噷瀛樻斁鏁版嵁
+    return {
+      page: {
+        size: 20,
+        current: 1,
+      },
+      outLoading: false,
+      tableLoading: false,
+      tableData: [], // 浜哄憳鎬诲垪琛ㄦ暟鎹�
+      tableData1: [],
+      tableLoading1: false,
+      column1: [
+        {label: '濮撳悕', prop: 'name'},
+        {label: '璐﹀彿', prop: 'account'},
+        {label: '瑙掕壊', prop: 'roleName'},
+        {
+          dataType: 'tag',
+          label: '鐘舵��',
+          prop: 'status',
+          formatData: (params) => {
+            if (params == 0) {
+              return '鍚敤'
+            } else {
+              return ''
+            }
+          },
+          formatType: (params) => {
+            if (params == 0) {
+              return 'success'
+            } else {
+              return 'danger'
+            }
+          }
+        },
+        {label: '鐢佃瘽鍙风爜', prop: 'phone'},
+      ],
+      page1: {
+        total:0,
+        size:10,
+        current:1
+      },
+      selectUserDia: false, // 娣诲姞浜哄憳寮规
+      entity: {
+        name: '',
+        orderBy: {
+          field: 'id',
+          order: 'asc'
+        }
+      },
+      addUserTableInfo: {
+        name: null,
+        isCustom: 0,
+      },
+      multipleSelection: []
+    };
+  },
+  mounted() {
+    this.refreshTable();
+  },
+  // 鏂规硶闆嗗悎
+  methods: {
+    /**
+     * @desc 鑾峰彇璁惧id
+     */
+    // 閲嶇疆
+    refresh() {
+      this.page = {
+        size: 20,
+        current: 1,
+      };
+      this.entity.name = ''
+      this.refreshTable();
+    },
+    // 鏌ヨ浜哄憳鍒楄〃鏁版嵁
+    refreshTable() {
+      this.tableLoading = true;
+      this.entity.departLimsId = this.departId;
+      const params = {
+        size: this.page.size,
+        current: this.page.current,
+        departmentId: this.entity.departLimsId,
+        name: this.entity.name,
+      }
+      basicInformationOfPersonnelSelectPage(params).then(res => {
+        this.tableLoading = false;
+        this.page.total = res.data.total;
+        this.tableData = res.data.records;
+      }).catch(err => {
+        this.tableLoading = false;
+      })
+    },
+    // 鍒犻櫎浜哄憳
+    deletePerson(row) {
+      this.$confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', '璀﹀憡', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        delUserDepardLimsId({id: row.userId}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛');
+          this.refreshTable();
+          this.$emit('refreshTree')
+        }).catch(e => {
+          this.$message.error('鍒犻櫎澶辫触');
+        });
+      }).catch(() => {
+      });
+    },
+    handleSizeChange(val) {
+      this.page.size = val;
+      this.refreshTable();
+    },
+    handleCurrentChange(val) {
+      this.page.current = val;
+      this.refreshTable();
+    },
+    // 鎵撳紑鏂板浜哄憳寮规
+    openSelectUserDia () {
+      this.selectUserDia = true;
+      this.selectUserList()
+    },
+    // 鏌ヨ鏂板寮规鐨勪汉鍛樺垪琛�
+    selectUserList () {
+      this.tableLoading1 = true
+      selectUserCondition().then(res => {
+        this.tableLoading1 = false
+        this.tableData1 = res.data
+      }).catch(err => {
+        this.tableLoading1 = false
+      })
+    },
+    // 琛ㄦ牸閫夋嫨鏂规硶
+    selectMethod(val) {
+      this.multipleSelection = val
+    },
+    // 鎻愪氦闇�瑕佹坊鍔犵殑浜哄憳
+    selectUser() {
+      if (!this.currentCompaniesList.length > 0) {
+        this.$message.warning("璇烽�夋嫨閮ㄩ棬锛�")
+        return;
+      }
+      let selects = this.HaveJson(this.multipleSelection)
+      if (selects.length === 0) {
+        this.$message.error('鏈�夋嫨鏁版嵁');
+        return;
+      }
+      let ids = [];
+      selects.forEach(a => {
+        ids.push(a.id);
+      });
+      let str = '';
+      this.currentCompaniesList.forEach(a => {
+        if (a) {
+          str += a + ',';
+        }
+      });
+      upUserDepardLimsId({
+        ids: JSON.stringify(ids),
+        id: str
+      }).then(res => {
+        this.selectUserDia = false;
+        this.$message.success('娣诲姞鎴愬姛');
+        this.refreshTable();
+        this.$emit('refreshTree')
+      });
+    },
+    // 瀵煎嚭浜哄憳淇℃伅
+    handleDown() {
+      this.outLoading = true;
+      let entity = this.HaveJson(this.entity)
+      delete entity.orderBy;
+      exportPersonBasicInfo({...entity}).then(res => {
+        this.outLoading = false;
+        const blob = new Blob([res], {type: 'application/octet-stream'});
+        this.$download.saveAs(blob, '浜哄憳淇℃伅.xlsx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (newId) {
+          this.page.current = 1
+          this.refreshTable();
+        }
+      }
+    }
+  }
+};
+</script>
+
+<style scoped>
+.search_thing {
+  display: flex;
+  align-items: center;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue
new file mode 100644
index 0000000..8af11b0
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue
@@ -0,0 +1,783 @@
+<!-- 浜哄憳鍩硅 -->
+<template>
+  <div class="flex_column">
+    <div v-if="!editPlanShow && isDepartment">
+      <div style="display: flex;justify-content: space-between;">
+        <el-form :model="page" ref="page" size="small" :inline="true">
+          <el-form-item label="缂栧埗浜�">
+            <el-input v-model="page.compilerName" clearable></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" @click="getYearPlanList(departId)">鏌� 璇�</el-button>
+          </el-form-item>
+        </el-form>
+        <div>
+          <el-button size="small" type="primary" @click="uploadDia = true, getUserList()">瀵煎叆</el-button>
+        </div>
+      </div>
+      <lims-table :tableData="yearPlanTableData" :column="yearPlanColumn"
+                  :currentChange="currentChange"
+                  @pagination="pagination" :height="'calc(100vh - 290px)'"
+                  :page="page" :tableLoading="yearLoading"></lims-table>
+    </div>
+    <div v-if="!editPlanShow" class="table">
+      <div v-if="!editPlanShow && isDepartment">
+        <div style="display: flex;justify-content: space-between;">
+          <el-form :model="inDetailForm" ref="inDetailForm" size="small" :inline="true">
+            <el-form-item label="鍩硅璁插笀">
+              <el-input v-model="inDetailForm.trainingLecturerName" class="search" clearable placeholder="璇疯緭鍏�" size="small"></el-input>
+            </el-form-item>
+            <el-form-item label="鍩硅鏃ユ湡">
+              <el-date-picker v-model="inDetailForm.trainingDate" clearable
+                              format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small"
+                              type="date" value-format="yyyy-MM-dd"></el-date-picker>
+            </el-form-item>
+            <el-form-item>
+              <el-button size="small" type="primary" @click="searchTable">鏌� 璇�</el-button>
+            </el-form-item>
+          </el-form>
+          <div>
+            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" @click="batchDelete">鎵归噺鍒犻櫎</el-button>
+            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" type="primary" @click="addTrainingPlan('add')">鏂板</el-button>
+          </div>
+        </div>
+        <lims-table :tableData="inDetailPlanTableData" :column="inDetailPlanColumn"
+                    :currentChange="currentChange" :height="isDepartment ? '45vh' : '68vh' "
+                    :isSelection="true" :handleSelectionChange="handleSelectionChange"
+                    @pagination="pagination1"
+                    :page="inDetailPagination" :tableLoading="yearLoading"></lims-table>
+      </div>
+    </div>
+    <Add ref="addPlan" :currentChangeRow="currentChangeRow" @search="getInDetailPlan(currentRowId, departId)"></Add>
+    <Edit
+      v-if="editPlanShow"
+      ref="editPlan"
+      :currentRow="currentRow"
+      @del="getInDetailPlan(currentRowId, departId)"
+      @goBack="goBack"
+    ></Edit>
+    <el-dialog :visible.sync="reviewDialog" title="瀹℃牳" width="30%" @close="auditRemarks = ''">
+      <span>
+        瀹℃牳澶囨敞锛�
+        <el-input v-model="auditRemarks" type="textarea"></el-input>
+      </span>
+      <span style="margin-top: 10px;display: inline-block">
+        鎵瑰噯浜猴細
+        <el-select v-model="approverId" clearable
+                   filterable size="small" style="width: 70%;">
+          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+          </el-option>
+        </el-select>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="reviewLoading" @click="handleReview(2)">涓嶉�氳繃</el-button>
+        <el-button :loading="reviewLoading" type="primary" @click="handleReview(1)">閫� 杩�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="approvalDialog" title="鎵瑰噯" width="30%" @close="approvalRemarks = ''">
+      <span>
+        鎵瑰噯澶囨敞锛�
+        <el-input v-model="approvalRemarks" type="textarea"></el-input>
+      </span>
+      <span slot="footer" class="dialog-footer">
+        <el-button :loading="approvalLoading" @click="handleApproval(2)">涓嶆壒鍑�</el-button>
+        <el-button :loading="reviewLoading" type="primary" @click="handleApproval(1)">鎵� 鍑�</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog :visible.sync="uploadDia" title="鏁版嵁瀵煎叆" width="500px">
+      <div style="display: flex;align-items: center;">
+        <div style="width: 70px">骞翠唤锛�</div>
+        <el-date-picker
+          v-model="planYear"
+          type="year"
+          value-format="yyyy"
+          clearable
+          size="small"
+          format="yyyy"
+          placeholder="閫夋嫨骞�">
+        </el-date-picker>
+      </div>
+      <div style="display: flex;align-items: center;margin: 10px 0">
+        <div style="width: 70px">瀹℃牳浜猴細</div>
+        <el-select v-model="reviewerId" clearable
+                   filterable size="small" style="width: 50%;">
+          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+          </el-option>
+        </el-select>
+      </div>
+      <div style="margin: 0 auto;">
+        <el-upload ref="upload" :action="javaApi + '/personTraining/personTrainingImport' + '?planYear=' + planYear + '&reviewerId=' + reviewerId"
+                   :auto-upload="false" :before-upload="beforeUpload" :file-list="fileList" :headers="uploadHeader"
+                   :limit="1" :on-error="onError" :on-success="onSuccess" accept=".xlsx" drag
+                   name="file">
+          <i class="el-icon-upload"></i>
+          <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        </el-upload>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="uploadDia = false">鍙� 娑�</el-button>
+        <el-button :loading="uploading" type="primary" @click="submitUpload()">涓� 浼�</el-button>
+      </span>
+    </el-dialog >
+    <view-record v-if="ViewRecord" ref="ViewRecord"></view-record>
+  </div>
+</template>
+
+<script>
+import Add from '../components/AddInDetail.vue';
+import Edit from '../components/Edit.vue';
+import ViewRecord from "../components/ViewRecord.vue";
+import limsTable from "@/components/Table/lims-table.vue";
+import {mapGetters} from "vuex";
+import {
+  approveAnnualPersonnelTraining, deleteAnnualPlanDetailTable, exportPersonTraining, exportPersonTrainingRecord,
+  personTraining,
+  personTrainingDelete,
+  queryTheAnnualPlanDetailsTable, reviewAnnualPersonnelTraining
+} from "@/api/cnas/personal/personalTraining";
+import {selectUserCondition} from "@/api/system/user";
+
+export default {
+  name: 'PersonnelTraining',
+  components: {limsTable, ViewRecord, Add, Edit },
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    ...mapGetters(["userId"]),
+  },
+  data() {
+    return {
+      planYear: '',
+      reviewerId: '',
+      responsibleOptions: [],
+      search: {},
+      superviseForm: {},
+      inDetailForm: {
+        trainingLecturerName: '',
+        trainingDate: '',
+      },
+      yearLoading: false,
+      yearPlanTableData: [], // 骞村害璁″垝琛ㄦ暟鎹�
+      yearPlanColumn: [
+        {
+          label: '鏂囦欢鍚嶇О',
+          width: '160px',
+          prop: 'fileName'
+        }, {
+          label: '鍒涘缓鏃堕棿',
+          width: '160px',
+          prop: 'createTime'
+        },{
+          label: '缂栧埗浜�',
+          prop: 'compilerName'
+        }, {
+          label: '缂栧埗鏃ユ湡',
+          width: '160px',
+          prop: 'compilationDate'
+        }, {
+          label: '瀹℃牳浜�',
+          prop: 'reviewerName',
+          minWidth: '100px',
+        }, {
+          dataType: 'tag',
+          label: '瀹℃牳鐘舵��',
+          prop: 'reviewerStatus',
+          width: '100px',
+          formatData: (params) => {
+            if (params == 1) {
+              return '閫氳繃';
+            } else if (params == 2) {
+              return '涓嶉�氳繃';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 1) {
+              return 'success';
+            } else if (params == 2) {
+              return 'danger';
+            } else {
+              return null
+            }
+          }
+        }, {
+          label: '瀹℃牳澶囨敞',
+          prop: 'auditRemarks',
+          minWidth: '100px',
+        }, {
+          label: '瀹℃牳鏃ユ湡',
+          width: '160px',
+          prop: 'auditDate'
+        }, {
+          label: '鎵瑰噯浜�',
+          prop: 'approverName',
+          minWidth: '100px',
+        }, {
+          label: '鎵瑰噯澶囨敞',
+          prop: 'approvalRemarks',
+          minWidth: '100px',
+        }, {
+          dataType: 'tag',
+          label: '鎵瑰噯鐘舵��',
+          minWidth: '100px',
+          prop: 'approvalStatus',
+          formatData: (params) => {
+            if (params == 1) {
+              return '鎵瑰噯';
+            } else if (params == 2) {
+              return '涓嶆壒鍑�';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 1) {
+              return 'success';
+            } else if (params == 2)  {
+              return 'danger';
+            } else {
+              return null
+            }
+          }
+        }, {
+          label: '鎵瑰噯鏃ユ湡',
+          width: '160px',
+          prop: 'approvalDate'
+        }, {
+          dataType: 'action',
+          width: '180px',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              disabled: (row) => {
+                if(row.approvalStatus === 1 && row.reviewerStatus === 1) {
+                  return false;
+                } else {
+                  return true;
+                }
+              },
+              clickFun: (row) => {
+                this.downLoadPost(row);
+              }
+            },
+            {
+              name: '瀹℃牳',
+              type: 'text',
+              disabled: (row) => {
+                if(row.reviewerStatus === 1 || this.userId != row.reviewerId) {
+                  return true;
+                } else {
+                  return false;
+                }
+              },
+              clickFun: (row) => {
+                this.handleCheck(row.id);
+              }
+            },
+            {
+              name: '鎵瑰噯',
+              type: 'text',
+              disabled: (row) => {
+                if(row.approvalStatus === 1 || this.userId != row.approverId) {
+                  return true;
+                } else {
+                  return false;
+                }
+              },
+              clickFun: (row) => {
+                this.handleApprove(row.id);
+              }
+            },
+            {
+              name: '鍒犻櫎',
+              type: 'text',
+              color: '#f56c6c',
+              clickFun: (row) => {
+                this.deleteFun(row.id);
+              },
+              disabled: (row) => {
+                if(row.reviewerStatus === 1) {
+                  return true;
+                } else {
+                  return false;
+                }
+              },
+            }
+          ]
+        }],
+      inDetailPlanTableData: [], // 骞村害璁″垝鏄庣粏琛ㄨ〃鏁版嵁
+      inDetailPlanColumn: [
+       {
+          label: '鍩硅鐩爣',
+          prop: 'trainingObjectives',
+          width: '100px',
+        }, {
+          label: '鍩硅鍐呭',
+          prop: 'trainingContent',
+          width: '100px',
+        }, {
+          label: '鍩硅鏂瑰紡',
+          prop: 'trainingMode',
+          width: '100px',
+        }, {
+          dataType: 'tag',
+          label: '璇剧▼鐘舵��',
+          width: '100px',
+          prop: 'state',
+          formatData: (params) => {
+            if (params == 1) {
+              return '宸插畬鎴�';
+            } else if (params == 2) {
+              return '寰呰瘎浠�';
+            } else if (params == 3) {
+              return '鏈紑濮�';
+            } else {
+              return null
+            }
+          },
+          formatType: (params) => {
+            if (params == 1) {
+              return 'success';
+            } else if (params == 2) {
+              return 'warning';
+            } else if (params == 3) {
+              return 'primary';
+            } else if (params == 4) {
+              return 'info';
+            } else {
+              return null
+            }
+          }
+        }, {
+          label: '鍙傚姞瀵硅薄',
+          prop: 'participants',
+          width: '100px',
+        }, {
+          label: '涓惧姙閮ㄩ棬',
+          prop: 'holdingDepartment',
+          width: '100px',
+        }, {
+          label: '鍩硅璁插笀',
+          prop: 'trainingLecturerName',
+          width: '100px',
+        }, {
+          label: '鍩硅鏃ユ湡',
+          prop: 'trainingDate',
+          width: '100px',
+        }, {
+          label: '寮�濮嬫椂闂�',
+          prop: 'openingTime',
+          width: '100px',
+        }, {
+          label: '璇炬椂',
+          prop: 'classHour',
+          width: '100px',
+        }, {
+          label: '澶囨敞',
+          prop: 'remarks',
+          width: '100px',
+        }, {
+          dataType: 'action',
+          width: '200',
+          label: '鎿嶄綔',
+          fixed: 'right',
+          operation: [
+            {
+              name: '缂栬緫',
+              type: 'text',
+              clickFun: (row) => {
+                this.addTrainingPlan('edit', row);
+              },
+            },
+            {
+              name: '缁撴灉鏄庣粏',
+              type: 'text',
+              clickFun: (row) => {
+                this.editInDetail(row);
+              },
+              showHide: () => {
+                if (this.isDepartment) {
+                  return true;
+                } else {
+                  return false;
+                }
+              }
+            },
+            {
+              name: '闄勪欢',
+              type: 'text',
+              clickFun: (row) => {
+                this.viewRecord(row);
+              },
+            },
+            {
+              name: '瀵煎嚭',
+              type: 'text',
+              clickFun: (row) => {
+                this.downLoadInDetail(row);
+              }
+            },
+
+          ]
+        }],
+      page: {
+        total:0,
+        size:10,
+        current:1,
+        compilerName: ""
+      },
+      inDetailPagination: {
+        total:0,
+        size:10,
+        current:1,
+      },
+      editPlanShow: false,
+      currentRow: {},
+      currentRowId: null, // 褰撳墠閫変腑鏁版嵁鐨刬d
+      auditRemarks: '', // 瀹℃牳澶囨敞
+      reviewDialog: false, // 瀹℃牳寮规
+      reviewLoading: false, // 瀹℃牳鎻愪氦鎸夐挳
+      approvalRemarks: '', // 瀹℃牳澶囨敞
+      approvalDialog: false, // 瀹℃牳寮规
+      approvalLoading: false, // 瀹℃牳鎻愪氦鎸夐挳
+      multipleSelection: [], // 骞村害鏄庣粏琛ㄩ�変腑鐨勬暟鎹�
+      uploadDia: false,
+      uploading: false,
+      isOperation: false,
+      ViewRecord: false,
+      fileList: [],
+      currentChangeRow: {},
+      approverId: ''
+    };
+  },
+  mounted() {
+    if (this.isDepartment) {
+      this.getYearPlanList(this.departId)
+    } else {
+      this.getInDetailPlan('', this.departId)
+    }
+  },
+  methods: {
+    searchTable () {
+      this.getInDetailPlan(this.currentRowId)
+    },
+    // 鏌ヨ-骞村害璁″垝琛�
+    getYearPlanList(userId) {
+      const params = this.isDepartment ?
+      {
+        departmentId: userId,
+        size: this.page.size,
+        current: this.page.current,
+        compilerName: this.page.compilerName,
+      }: {
+          userId: userId,
+          size: this.page.size,
+          current: this.page.current,
+          compilerName: this.page.compilerName,
+        }
+      personTraining(params).then(res => {
+        this.yearPlanTableData = res.data.records;
+        this.pagination.total = res.data.total;
+        if (this.yearPlanTableData.length > 0) {
+          this.currentRowId = this.yearPlanTableData[0].id
+          this.currentChange(this.yearPlanTableData[0])
+        }
+      });
+    },
+    pagination (page) {
+      this.page.size = page.limit
+      this.getYearPlanList()
+    },
+    currentChange (row) {
+      const now = new Date();
+      const currentYear = now.getFullYear();
+      if (row) {
+        this.currentChangeRow = row
+        this.currentRowId = row.id
+        if (row.createTime.slice(0,4) == currentYear) {
+          this.isOperation = true;
+        } else {
+          this.isOperation = false;
+        }
+        this.getInDetailPlan(row.id)
+      }
+    },
+    getInDetailPlan (id) {
+      if (this.inDetailForm.trainingDate === null) {
+        this.inDetailForm.trainingDate = ''
+      }
+      const userId = this.isDepartment ? '' : this.departId
+      const params =
+        {
+          userId: userId,
+          size: this.inDetailPagination.pageSize,
+          current: this.inDetailPagination.current,
+          id: id,
+          trainingLecturerName: this.inDetailForm.trainingLecturerName,
+          trainingDate: this.inDetailForm.trainingDate,
+        }
+      queryTheAnnualPlanDetailsTable(params).then(res => {
+        this.inDetailPlanTableData = res.data.records;
+        this.inDetailPagination.total = res.data.total;
+      });
+    },
+    pagination1 (page) {
+      this.inDetailPagination.size = page.limit
+      this.getInDetailPlan(this.currentRowId)
+    },
+    // 鏂板骞村害璁″垝鏄庣粏琛�
+    addTrainingPlan(type, row) {
+      if (!this.currentRowId) {
+        this.$message.warning('璇烽�夋嫨涓�鏉¤鍒掕繘琛屾柊澧�')
+        return
+      }
+      this.$refs.addPlan.showDialog(this.currentRowId, type, row);
+    },
+    // 骞村害璁″垝琛�-鍒犻櫎
+    deleteFun(id) {
+      this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        personTrainingDelete({id: id}).then(res => {
+          this.$message.success('鍒犻櫎鎴愬姛锛�');
+          this.getYearPlanList(this.departId);
+        });
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
+    },
+    // 骞村害璁″垝琛�-瀹℃牳
+    handleCheck(id) {
+      this.currentRowId = id
+      this.reviewDialog = true
+      this.getUserList()
+    },
+    // 鎻愪氦瀹℃牳
+    handleReview (status) {
+      const personTrainingUpdateDto = {
+        id: this.currentRowId,
+        auditRemarks: this.auditRemarks,
+        reviewerStatus: status,
+        approverId: this.approverId
+      }
+      this.reviewLoading = true
+      reviewAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.reviewDialog = false
+          this.getYearPlanList(this.departId);
+        }
+        this.reviewLoading = false
+      }).catch(() => {
+        this.reviewLoading = false
+      })
+    },
+    // 骞村害璁″垝琛�-鎵瑰噯
+    handleApprove(id) {
+      this.currentRowId = id
+      this.approvalDialog = true
+    },
+    // 鎻愪氦鎵瑰噯
+    handleApproval (status) {
+      const personTrainingUpdateDto = {
+        id: this.currentRowId,
+        approvalRemarks: this.approvalRemarks,
+        approvalStatus: status
+      }
+      this.approvalLoading = true
+      approveAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
+        if (res.code === 200) {
+          this.$message.success('鎻愪氦鎴愬姛锛�');
+          this.approvalDialog = false
+          this.getYearPlanList(this.departId);
+        }
+        this.approvalLoading = false
+      }).catch(() => {
+        this.approvalLoading = false
+      })
+    },
+    // 骞村害璁″垝琛�-涓嬭浇
+    downLoadPost(row) {
+      exportPersonTraining({id: row.id}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, row.fileName + '.docx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 骞村害璁″垝-瀵煎叆
+    submitUpload() {
+      if (this.$refs.upload.uploadFiles.length == 0) {
+        this.$message.error('鏈�夋嫨鏂囦欢')
+        return
+      }
+      this.uploading = true
+      this.$refs.upload.submit();
+      this.uploading = false
+    },
+    onSuccess(response, file, fileList) {
+      this.$refs.upload.clearFiles()
+      this.uploadDia = false
+      this.uploading = false
+      if (response.code != 200) {
+        this.$message.error(response.message)
+        return
+      }
+      this.$message.success('涓婁紶鎴愬姛')
+      this.standardList = []
+      this.productList = []
+      this.getYearPlanList(this.departId)
+    },
+    onError(err, file, fileList) {
+      this.$message.error('涓婁紶澶辫触')
+      this.$refs.upload.clearFiles()
+      this.uploading = false
+    },
+    beforeUpload(file, fileList) {
+      if (file.type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
+        this.$message.error('涓婁紶鏂囦欢鏍煎紡涓嶆纭�');
+        this.$refs.upload.clearFiles()
+        return false;
+      }
+    },
+    // 骞村害璁″垝鏄庣粏琛�-缂栬緫
+    editInDetail(row) {
+      this.editPlanShow = true;
+      this.currentRow = row
+    },
+    //
+    goBack() {
+      this.editPlanShow = false;
+      this.getInDetailPlan(this.currentRowId)
+    },
+    viewRecord (row) {
+      this.ViewRecord = true
+      this.$nextTick(() => {
+        this.$refs.ViewRecord.openDia(row)
+      })
+    },
+    // 骞村害璁″垝鏄庣粏琛�-涓嬭浇
+    downLoadInDetail(row) {
+      exportPersonTrainingRecord({id: row.id}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        this.$download.saveAs(blob, '浜哄憳鍩硅涓庤�冩牳璁板綍.docx')
+        this.$message.success('瀵煎嚭鎴愬姛')
+      })
+    },
+    // 骞村害璁″垝鏄庣粏琛�-澶氶��
+    handleSelectionChange(list) {
+      this.multipleSelection = list
+    },
+    // 骞村害鏄庣粏琛�-鍒犻櫎
+    batchDelete () {
+      if (this.multipleSelection.length > 0) {
+        let ids = []
+        this.multipleSelection.forEach(item => {
+          ids.push(item.id)
+        })
+        this.$confirm('鏄惁纭鍒犻櫎鎵�閫夋嫨鐨勬暟鎹�?', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          deleteAnnualPlanDetailTable({ids: ids.join(',')}).then(res => {
+            if (res.code == 200) {
+              this.$message.success('鍒犻櫎鎴愬姛');
+              this.getInDetailPlan(this.currentRowId);
+            }
+          });
+        }).catch(() => {
+          this.$message.warning('鍙栨秷鍒犻櫎');
+        });
+      } else {
+        this.$message.warning('璇烽�夋嫨闇�瑕佸垹闄ょ殑鏁版嵁')
+      }
+    },
+    handleSizeChange(val) {
+      this.inDetailPagination.size = val;
+      this.getInDetailPlan(this.currentChangeRow.id)
+    },
+    handleCurrentChange(val) {
+      this.inDetailPagination.current = val;
+      this.getInDetailPlan(this.currentChangeRow.id)
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      selectUserCondition().then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      });
+    }
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    departId: {
+      handler(newId, oldId) {
+        if (this.isDepartment) {
+          this.getYearPlanList(newId);
+        } else {
+          this.getInDetailPlan('')
+        }
+      }
+    },
+    currentRowId: {
+      handler(newId, oldId) {
+        if (newId) {
+          console.log('newId', newId);
+          this.inDetailPagination.current = 1
+          this.getInDetailPlan(this.currentChangeRow.id)
+        }
+      }
+    }
+  }
+}
+</script>
+<style scoped>
+.flex_column {
+  display: flex;
+  height: 80vh;
+  flex-direction: column;
+  overflow: auto;
+  justify-content: space-between;
+}
+
+.pagination {
+  display: flex;
+  justify-content: space-between
+}
+
+.items_center {
+  display: flex;
+  align-items: center;
+}
+
+.date_box {
+  margin: 0 5px;
+}
+
+.search {
+  width: 150px;
+  margin: 0 16px;
+}
+</style>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue b/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue
new file mode 100644
index 0000000..344051f
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue
@@ -0,0 +1,358 @@
+<!-- 濂栨儵璁板綍 -->
+<template>
+  <div>
+    <div style="text-align: left; margin-bottom: 15px;">
+      <label>濮撳悕</label>
+      <el-input v-model="search.userName" clearable placeholder="璇疯緭鍏ュ叧閿瓧" size="small" style="width: 20vh;"></el-input>
+      <label style="margin-left: 1em">濂栨儵鏃ユ湡</label>
+      <el-date-picker
+        v-model="search.searchTimeList"
+        :picker-options="pickerOptions"
+        align="right"
+        clearable
+        end-placeholder="缁撴潫鏃ユ湡"
+        format="yyyy-MM-dd"
+        range-separator="鑷�"
+        size="small"
+        start-placeholder="寮�濮嬫棩鏈�"
+        style="width: 20%"
+        type="daterange"
+        unlink-panels
+        value-format="yyyy-MM-dd 00:00:00">
+      </el-date-picker>
+      <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button>
+      <div style="float: right;">
+        <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">瀵煎嚭</el-button>
+        <el-button size="small" type="primary" @click="addRow">鏂板</el-button>
+      </div>
+    </div>
+    <div class="table">
+      <el-table :data="tableData" height="70vh" style="width: 100%">
+        <el-table-column label="搴忓彿" type="index" width="120">
+          <template v-slot="scope">
+            <span>{{ (search.current - 1) * search.size + scope.$index + 1 }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍛樺伐缂栧彿" min-width="180" prop="account">
+        </el-table-column>
+        <el-table-column label="濮撳悕" min-width="180" prop="userName">
+        </el-table-column>
+        <el-table-column label="濂栨儵绾у埆" min-width="180" prop="rewardPunishLevel">
+        </el-table-column>
+        <el-table-column label="濂栨儵鏃堕棿" min-width="180" prop="rewardPunishTime">
+        </el-table-column>
+        <el-table-column label="濂栨儵鍚嶇О" min-width="180" prop="rewardPunishName">
+        </el-table-column>
+        <el-table-column label="濂栨儵鍏蜂綋鍐呭" min-width="120" prop="rewardPunishContent">
+        </el-table-column>
+        <el-table-column label="濂栨儵鍗曚綅" min-width="180" prop="rewardPunishWorkUnit">
+        </el-table-column>
+        <el-table-column label="鍒涘缓浜�" min-width="180" prop="createUserName">
+        </el-table-column>
+        <el-table-column fixed="right" label="鎿嶄綔" width="100">
+          <template v-slot="scope">
+            <el-button size="small" type="text" @click="editForm(scope.row)">缂栬緫</el-button>
+            <el-button size="small" type="text" @click="deleteRow(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]"
+                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
+                     @size-change="handleSizeChange"
+                     @current-change="handleCurrentChange">
+      </el-pagination>
+    </div>
+    <el-dialog
+      :visible.sync="dialogVisible"
+      title="鎻愮ず"
+      width="50%"
+      @open="getUserList">
+      <div style="height: 40vh">
+        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+          <el-col :span="12">
+            <el-form-item label="鍛樺伐缂栧彿">
+              <el-input v-model="form.account" disabled size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍛樺伐濮撳悕" prop="userId">
+              <el-select v-model="form.userId" placeholder="璇烽�夋嫨" size="small" style="width: 100%" value-key="id"
+                         @change="selectUserChange" :disabled="!isDepartment">
+                <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵绾у埆" prop="rewardPunishLevel">
+              <el-input v-model="form.rewardPunishLevel" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵鍚嶇О" prop="rewardPunishName">
+              <el-input v-model="form.rewardPunishName" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵鏃堕棿" prop="rewardPunishTime">
+              <el-date-picker
+                v-model="form.rewardPunishTime"
+                format="yyyy-MM-dd HH:mm:ss"
+                placeholder="閫夋嫨鏃ユ湡"
+                size="small"
+                style="width: 100%"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濂栨儵鍗曚綅" prop="rewardPunishWorkUnit">
+              <el-input v-model="form.rewardPunishWorkUnit" size="small"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="濂栨儵鍐呭">
+              <el-input v-model="form.rewardPunishContent" :rows="2" size="small" type="textarea"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+    <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+    <el-button type="primary" @click="saveOrUpdate">纭� 瀹�</el-button>
+  </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      tableData: [],
+      search: {
+        size: 20,
+        current: 1,
+        total: 0,
+        userName: '',
+        searchTimeList: []
+      },
+      form: {},
+      dialogVisible: false,
+      outLoading: false,
+      pickerOptions: {
+        shortcuts: [{
+          text: '鏈�杩戜竴鍛�',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '鏈�杩戜竴涓湀',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '鏈�杩戜笁涓湀',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      rules: {
+        userId: [{
+          required: true, message: '璇烽�夋嫨鍛樺伐', trigger: 'change'
+        }],
+        rewardPunishLevel: [{
+          required: true, message: '璇疯緭鍏ュ鎯╃骇鍒�', trigger: 'blur'
+        }],
+        rewardPunishName: [{
+          required: true, message: '璇疯緭鍏ュ鎯╁悕绉�', trigger: 'blur'
+        }],
+        rewardPunishTime: [{
+          required: true, message: '璇疯緭鍏ュ鎯╂椂闂�', trigger: 'blur'
+        }],
+        rewardPunishWorkUnit: [{
+          required: true, message: '璇疯緭鍏ュ鎯╁崟浣�', trigger: 'blur'
+        }]
+      },
+      responsibleOptions: []
+    };
+  },
+  mounted() {
+    this.getPersonnelTraining(this.departId);
+  },
+  methods: {
+    handleSizeChange(val) {
+      this.search.size = val
+      this.getPersonnelTraining(this.departId);
+    },
+    handleCurrentChange(val) {
+      this.search.current = val
+      this.getPersonnelTraining(this.departId);
+    },
+    async getPersonnelTraining() {
+      const {code, data} = await this.$axios({
+        method: 'get',
+        url: rewardPunishmentPageApi,
+        params: {
+          userId: this.isDepartment ? '' : this.departId,
+          departmentId: this.isDepartment ? this.departId : '',
+          current: this.search.curent,
+          size: this.search.size,
+          userName: this.search.userName,
+          startTime: this.search.searchTimeList && this.search.searchTimeList[0],
+          endTime: this.search.searchTimeList && this.search.searchTimeList[1],
+        }
+      })
+      if (code == 200) {
+        this.tableData = data.records
+        this.search.total = data.total
+      }
+    },
+    addRow () {
+      this.dialogVisible = true
+      if (!this.isDepartment) {
+        this.form.userId = this.departId
+        this.selectUserChange(this.form.userId)
+      }
+    },
+    handleDown(){
+      this.outLoading = true
+      this.$axios.post(this.$api.deviceCheck.rewardPunishmentExport,{
+        userId: this.isDepartment ? '' : this.departId,
+        departmentId: this.isDepartment ? this.departId : '',
+        userName: this.search.userName,
+        startTime: this.search.searchTimeList && this.search.searchTimeList[0],
+        endTime: this.search.searchTimeList && this.search.searchTimeList[1]
+      },{responseType: 'blob'}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res], {
+          type: 'application/force-download'
+        })
+        //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆
+        let reader = new FileReader();
+        reader.readAsText(blob, 'utf-8');
+        reader.onload = () => {
+          try {
+            let result = JSON.parse(reader.result);
+            if (result.message) {
+              this.$message.error(result.message);
+            } else {
+              // 鍒涘缓涓�涓秴閾炬帴锛屽皢鏂囦欢娴佽祴杩涘幓锛岀劧鍚庡疄鐜拌繖涓秴閾炬帴鐨勫崟鍑讳簨浠�
+              const elink = document.createElement('a')
+              elink.download = decodeURI('濂栨儵璁板綍'+'.xlsx')
+              elink.style.display = 'none'
+              elink.href = URL.createObjectURL(blob)
+              document.body.appendChild(elink)
+              elink.click();
+              URL.revokeObjectURL(elink.href) // 閲婃斁URL 瀵硅薄
+              document.body.removeChild(elink)
+              this.$message.success('瀵煎嚭鎴愬姛')
+            }
+          } catch (err) {
+            console.log(err);
+            // 鍒涘缓涓�涓秴閾炬帴锛屽皢鏂囦欢娴佽祴杩涘幓锛岀劧鍚庡疄鐜拌繖涓秴閾炬帴鐨勫崟鍑讳簨浠�
+            const elink = document.createElement('a')
+            elink.download = decodeURI('濂栨儵璁板綍'+'.xlsx')
+            elink.style.display = 'none'
+            elink.href = URL.createObjectURL(blob)
+            document.body.appendChild(elink)
+            elink.click();
+            URL.revokeObjectURL(elink.href) // 閲婃斁URL 瀵硅薄
+            document.body.removeChild(elink)
+            this.$message.success('瀵煎嚭鎴愬姛')
+          }
+        }
+      })
+    },
+    // 鑾峰彇璐熻矗浜轰俊鎭帴鍙�
+    getUserList() {
+      this.$axios.get(this.$api.deviceScope.selectUserList).then(res => {
+        if (res.code == 200) {
+          this.responsibleOptions = res.data
+        }
+      })
+    },
+    selectUserChange(val) {
+      const index = this.responsibleOptions.findIndex(item => item.id === val)
+      if (index > -1) {
+        this.form.userName = this.responsibleOptions[index].name
+        this.form.account = this.responsibleOptions[index].account
+      }
+    },
+    editForm(row) {
+      this.dialogVisible = true
+      this.form = {...row};
+    },
+    saveOrUpdate() {
+      this.$refs.form.validate(async (valid) => {
+        if (valid) {
+          this.dialogVisible = false
+          const {code, data} = await this.$axios({
+            method: 'post',
+            url: addOrUpdateRewardPunishmentApi,
+            data: this.form,
+            headers: {
+              'Content-Type': 'application/json'
+            },
+            noQs: true
+          })
+          if (code == 200) {
+            this.$message.success("鎿嶄綔鎴愬姛锛�")
+            this.getPersonnelTraining(this.departId);
+          }
+        }
+      })
+    },
+    async deleteRow(row) {
+      const {code, data} = await this.$axios({
+        method: 'delete',
+        url: deleteRewardPunishmentApi,
+        params: {
+          id: row.id
+        }
+      })
+      if (code == 200) {
+        this.$message.success("鎿嶄綔鎴愬姛锛�")
+        this.getPersonnelTraining(this.departId);
+      }
+    }
+  },
+  watch: {
+    // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊
+    departId: {
+      handler(newId, oldId) {
+        this.getPersonnelTraining(newId);
+      }
+    },
+    dialogVisible(newVal) {
+      if (newVal === false) {
+        this.form = {}
+        this.$refs['form'].resetFields()
+      }
+    }
+  }
+};
+</script>
diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue b/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue
new file mode 100644
index 0000000..6ac536f
--- /dev/null
+++ b/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue
@@ -0,0 +1,336 @@
+<!-- 鍩硅璁板綍 -->
+<template>
+  <div>
+    <div class="flex_table">
+      <div v-if="isDepartment" style="width: 50%">
+<!--        <TableCard :showTitle="false">-->
+<!--          <template v-slot:form>-->
+<!--            <div class="items_center">-->
+<!--              <span>濮撳悕</span>-->
+<!--              <el-input v-model="trainingPagination.userName" class="search" clearable placeholder="璇疯緭鍏�" size="small"></el-input>-->
+<!--              <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button>-->
+<!--            </div>-->
+<!--            <div>-->
+<!--&lt;!&ndash;              <el-button :loading="outLoading" size="small" type="primary" @click="exportExcel">瀵煎嚭</el-button>&ndash;&gt;-->
+<!--            </div>-->
+<!--          </template>-->
+<!--          <template v-slot:table>-->
+<!--            <ZTTable-->
+<!--              :column="trainingColumn"-->
+<!--              :currentChange="currentChange"-->
+<!--              :height="'calc(100vh - 18em)'"-->
+<!--              :highlightCurrentRow="true"-->
+<!--              :table-data="trainingTableData"-->
+<!--              :table-loading="trainingLoading"-->
+<!--              style="padding: 0 15px;">-->
+<!--            </ZTTable>-->
+<!--            <div class="pagination">-->
+<!--              <div></div>-->
+<!--              <el-pagination-->
+<!--                :page-size="trainingPagination.size"-->
+<!--                :page-sizes="[10, 20, 30, 40]"-->
+<!--                :total="trainingPagination.total"-->
+<!--                layout="total, sizes, prev, pager, next, jumper"-->
+<!--                @current-change="handleYearCurrentTraining"-->
+<!--                @size-change="handleYearSizeChangeTraining">-->
+<!--              </el-pagination>-->
+<!--            </div>-->
+<!--          </template>-->
+<!--        </TableCard>-->
+<!--      </div>-->
+<!--      <div :style="`width: ${isDepartment ? '50%' : '100%'};`">-->
+<!--        <TableCard :showTitle="false">-->
+<!--          <template v-slot:form>-->
+<!--            <div class="items_center">-->
+<!--              <span>骞翠唤</span>-->
+<!--              <el-date-picker-->
+<!--                v-model="searchForm.trainingDate"-->
+<!--                clearable-->
+<!--                format="yyyy"-->
+<!--                placeholder="閫夋嫨骞�"-->
+<!--                size="small"-->
+<!--                style="margin: 0 10px"-->
+<!--                type="year"-->
+<!--                value-format="yyyy">-->
+<!--              </el-date-picker>-->
+<!--              <el-button size="small" type="primary" @click="queryPersonnelDetailsPage(currentChangeRow.userId)">鏌ヨ</el-button>-->
+<!--              <el-button size="small" type="primary" @click="openDownloadDia(currentChangeRow)">瀵煎嚭</el-button>-->
+<!--            </div>-->
+<!--          </template>-->
+<!--          <template v-slot:table>-->
+<!--            <ZTTable-->
+<!--              :column="trainingPersonColumn"-->
+<!--              :height="'calc(100vh - 18em)'"-->
+<!--              :table-data="trainingPersonTableData"-->
+<!--              :table-loading="trainingPersonLoading"-->
+<!--              style="padding: 0 15px;">-->
+<!--            </ZTTable>-->
+<!--            <div class="pagination">-->
+<!--              <div></div>-->
+<!--              <el-pagination-->
+<!--                :page-size="trainingPersonPagination.size"-->
+<!--                :page-sizes="[10, 20, 30, 40]"-->
+<!--                :total="trainingPersonPagination.total"-->
+<!--                layout="total, sizes, prev, pager, next, jumper"-->
+<!--                @current-change="handleYearCurrentPagination"-->
+<!--                @size-change="handleYearSizeChangePagination">-->
+<!--              </el-pagination>-->
+<!--            </div>-->
+<!--          </template>-->
+<!--        </TableCard>-->
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+
+export default {
+  components: {},
+  props: {
+    departId: {
+      type: Number,
+      default: () => {
+        return null;
+      }
+    },
+    isDepartment: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      outLoading: false,
+      trainingForm: {},
+      trainingColumn: [
+        {
+          label: '鍛樺伐缂栧彿',
+          prop: 'account',
+          width: '100'
+        }, {
+          label: '濮撳悕',
+          prop: 'name'
+        }, {
+          label: '鎵�鍦ㄩ儴闂�',
+          prop: 'departLimsName',
+          width: '150'
+        }, {
+          label: '鑱岀О',
+          prop: 'professionalTitle'
+        }, {
+          label: '鏈�楂樺鍘�',
+          prop: 'officialAcademicRedentials',
+          width: '100'
+        }, {
+          label: '鍏ュ崟浣嶆椂闂�',
+          prop: 'unitTime',
+          width: '150'
+        },
+        // {
+        //   fixed: 'right',
+        //   dataType: 'action',
+        //   width: 80,
+        //   label: '鎿嶄綔',
+        //   operation: [
+        //     {
+        //       name: '瀵煎嚭',
+        //       type: 'text',
+        //       clickFun: (row) => {
+        //         this.openDownloadDia(row)
+        //       }
+        //     }
+        //   ]
+        // }
+      ],
+      trainingTableData: [],
+      trainingLoading: false,
+      trainingPagination: {
+        size: 20,
+        total: 0,
+        current: 1,
+        userName: null
+      },
+      searchForm: {
+        trainingDate: ''
+      },
+      trainingPersonColumn: [
+        {
+          label: '鍩硅鏃ユ湡',
+          prop: 'trainingDate'
+        }, {
+          label: '鍩硅鍐呭',
+          prop: 'trainingContent'
+        }, {
+          label: '鍩硅璇炬椂',
+          prop: 'educationBackground'
+        }, {
+          label: '璇炬椂',
+          prop: 'classHour'
+        }, {
+          label: '鍩硅缁撴灉',
+          prop: 'examinationResults',
+        }, {
+          label: '澶囨敞',
+          prop: 'remarks'
+        }
+      ],
+      trainingPersonTableData: [],
+      trainingPersonLoading: false,
+      trainingPersonPagination: {
+        size: 20,
+        current: 1,
+        total: 0
+      },
+      currentChangeRow: '',
+    };
+  },
+  mounted() {
+    this.getPersonnelTraining(this.departId);
+  },
+  methods: {
+    // exportExcel() {
+    //   this.outLoading = true;
+    //   const name = this.isDepartment ? 'departmentId' : 'userId';
+    //   this.$axios.get(this.$api.personal.personTrackRecordExport + `&${name}=` + this.departId, { responseType: 'blob' }).then(res => {
+    //     this.outLoading = false;
+    //     this.$message.success('瀵煎嚭鎴愬姛');
+    //     const blob = new Blob([res], { type: 'application/octet-stream' });
+    //     const url = URL.createObjectURL(blob);
+    //     const link = document.createElement('a');
+    //     link.href = url;
+    //     link.download = '鍩硅璁板綍.xlsx';
+    //     link.click();
+    //   }).catch(err => {
+    //     this.outLoading = false;
+    //   })
+    // },
+    // 鏌ヨ
+    refreshTable() {
+      this.getPersonnelTraining(this.departId);
+    },
+    // 鍩硅璁板綍瀵煎嚭
+    openDownloadDia (row) {
+      let date = this.searchForm.trainingDate
+      if (!date) {
+        date = this.$moment().format('YYYY')
+      }
+      console.log('date----', date);
+      this.$axios.get( this.$api.personnel.exportTrainingRecord+ '?userId=' + row.userId + '&trainingDate=' + date,{responseType: "blob"}).then(res => {
+        this.outLoading = false
+        const blob = new Blob([res],{ type: 'application/msword' });
+        //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆
+        let reader = new FileReader();
+        reader.readAsText(blob, 'utf-8');
+        reader.onload = () => {
+          try {
+            let result = JSON.parse(reader.result);
+            if (result.message) {
+              this.$message.error(result.message);
+            } else {
+              const url = URL.createObjectURL(blob);
+              const link = document.createElement('a');
+              link.href = url;
+              link.download = '鍩硅璁板綍瀵煎嚭' + '.docx';
+              link.click();
+              this.$message.success('瀵煎嚭鎴愬姛')
+            }
+          } catch (err) {
+            console.log(err);
+            const url = URL.createObjectURL(blob);
+            const link = document.createElement('a');
+            link.href = url;
+            link.download = '鍩硅璁板綍瀵煎嚭' + '.docx';
+            link.click();
+            this.$message.success('瀵煎嚭鎴愬姛')
+          }
+        }
+      })
+    },
+    // 鑾峰彇瀹為獙瀹�-鍩硅璁″垝鍒楄〃淇℃伅
+    getPersonnelTraining(departId) {
+      // const name = this.isDepartment ? 'departmentId' : 'userId';
+      this.$axios.get(`${this.$api.personnel.trainingSelectTrainingRecord}?departmentId=${departId}&size=${this.trainingPagination.size}&current=${this.trainingPagination.current}&userName=${this.trainingPagination.userName}`).then(res => {
+        this.trainingTableData = res.data.records;
+        this.trainingPagination.total = res.data.total;
+        if (this.trainingTableData.length > 0) {
+          this.currentChange(this.trainingTableData[0]);
+        }
+      });
+    },
+    // 鑾峰彇涓汉-鍩硅璁″垝鍒楄〃淇℃伅
+    currentChange(row) {
+      this.currentChangeRow = row
+      if (row === null) {
+        row = this.trainingTableData[0]
+      }
+      this.queryPersonnelDetailsPage(row.userId)
+    },
+    queryPersonnelDetailsPage(userId) {
+      if (this.searchForm.trainingDate === null) {
+        this.searchForm.trainingDate = ''
+      }
+      this.$axios.get(`${this.$api.personnel.queryPersonnelDetails}?userId=${userId}&size=${this.trainingPersonPagination.size}&current=${this.trainingPersonPagination.current}&trainingDate=${this.searchForm.trainingDate}`).then(res => {
+        this.trainingPersonTableData = res.data.records;
+        this.trainingPersonPagination.total = res.data.total;
+      });
+    },
+    // 鍒嗛〉
+    handleYearCurrentTraining(page) {
+      this.trainingPagination.curent = page;
+      this.getPersonnelTraining(this.departId);
+    },
+    handleYearSizeChangeTraining(size) {
+      this.trainingPagination.size = size;
+      this.getPersonnelTraining(this.departId);
+    },
+    // 鍒嗛〉
+    handleYearCurrentPagination(page) {
+      this.trainingPersonPagination.curent = page;
+      this.queryPersonnelDetailsPage(this.currentChangeRow.userId);
+    },
+    handleYearSizeChangePagination(size) {
+      this.trainingPersonPagination.size = size;
+      this.queryPersonnelDetailsPage(this.currentChangeRow.userId);
+    }
+  },
+  watch: {
+    departId: {
+      handler(newId, oldId) {
+        if (this.isDepartment) {
+          this.getPersonnelTraining(newId);
+        } else {
+          this.queryPersonnelDetailsPage(newId)
+        }
+      }
+    }
+  }
+};
+</script>
+<style scoped>
+>>> .el-form-item {
+  margin-bottom: 13px;
+}
+
+.flex_table {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+}
+
+.pagination {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 10px;
+}
+
+.items_center {
+  display: flex;
+  align-items: center;
+}
+
+.search {
+  width: 150px;
+  padding: 0 6px;
+}
+</style>
diff --git a/src/views/business/materialOrder/index.vue b/src/views/business/materialOrder/index.vue
index c8e8854..3c09dec 100644
--- a/src/views/business/materialOrder/index.vue
+++ b/src/views/business/materialOrder/index.vue
@@ -72,30 +72,38 @@
         </div>
         <!--寰呬笅鍗�-->
         <div class="table">
-          <lims-table :tableData="tableData" :column="column" v-if="tabIndex === 0" @pagination="pagination"
-            :height="'calc(100vh - 290px)'" key="tableData" :page="page" :tableLoading="tableLoading"></lims-table>
+          <lims-table :tableData="tableData" :column="column"
+                      v-if="tabIndex === 0" @pagination="pagination"
+                      :rowClassName="changeRowClass"
+                      :height="'calc(100vh - 290px)'" key="tableData"
+                      :page="page" :tableLoading="tableLoading"></lims-table>
         </div>
         <!--妫�楠屼腑-->
         <div class="table">
-          <lims-table :tableData="tableData1" :column="column1" v-if="tabIndex === 1" :isSelection="true"
-            :handleSelectionChange="selectMethod" @pagination="pagination1" :height="'calc(100vh - 290px)'"
-            key="tableData1" :page="page1" :tableLoading="tableLoading1"></lims-table>
+          <lims-table :tableData="tableData1" :column="column1"
+                      v-if="tabIndex === 1" :isSelection="true"
+                      :rowClassName="changeRowClass"
+                      :handleSelectionChange="selectMethod" @pagination="pagination1" :height="'calc(100vh - 290px)'"
+                      key="tableData1" :page="page1" :tableLoading="tableLoading1"></lims-table>
         </div>
         <!--宸叉楠�-->
         <div class="table">
           <lims-table :tableData="tableData2" :column="column2" v-if="tabIndex === 2" :isSelection="true"
+                      :rowClassName="changeRowClass"
             :handleSelectionChange="selectMethod" @pagination="pagination2" :height="'calc(100vh - 290px)'"
             key="tableData2" :page="page2" :tableLoading="tableLoading2"></lims-table>
         </div>
         <!--鍏ㄩ儴-->
         <div class="table">
           <lims-table :tableData="tableData3" :column="column3" v-if="tabIndex === 3" :isSelection="true"
+                      :rowClassName="changeRowClass"
             :handleSelectionChange="selectMethod" @pagination="pagination3" :height="'calc(100vh - 290px)'"
             key="tableData3" :page="page3" :tableLoading="tableLoading3"></lims-table>
         </div>
         <!--瀛e害妫�楠�-->
         <div class="table">
           <lims-table :tableData="tableData4" :column="column4" v-if="tabIndex === 4" :isSelection="true"
+                      :rowClassName="changeRowClass"
             :handleSelectionChange="selectMethod" @pagination="pagination4" :height="'calc(100vh - 290px)'"
             key="tableData4" :page="page4" :tableLoading="tableLoading4"></lims-table>
         </div>
@@ -1108,6 +1116,12 @@
     selectMethod(val) {
       this.multipleSelection = val
     },
+    changeRowClass({row, rowIndex}) {
+      if (row.isFirst == 1) {
+        return 'highlight-danger-row-border'
+      }
+      return ''
+    },
   },
 }
 </script>

--
Gitblit v1.9.3