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>--> +<!-- <!– <el-button type="primary" size="small">瀵煎嚭</el-button> –>--> +<!-- <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 + '¤t=' + 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 + '¤t=' + 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>--> +<!--<!– <el-button :loading="outLoading" size="small" type="primary" @click="exportExcel">瀵煎嚭</el-button>–>--> +<!-- </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}¤t=${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}¤t=${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