From dc3af0cbb4a6d105bdff497b510cc0a87b3e8d0a Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期五, 28 二月 2025 17:53:44 +0800 Subject: [PATCH] Merge branch 'dev' of http://114.132.189.42:9002/r/lims-ruoyi-before into dev --- src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue | 802 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 802 insertions(+), 0 deletions(-) diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue new file mode 100644 index 0000000..46c637d --- /dev/null +++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue @@ -0,0 +1,802 @@ +<!-- 浜哄憳鍩硅 --> +<template> + <div class="flex_column"> + <div v-if="!editPlanShow && isDepartment"> + <div class="title"> + <span style="font-weight: bold">骞村害璁″垝</span> + </div> + <div style="display: flex;justify-content: space-between;"> + <el-form :model="page" ref="page" size="small" :inline="true"> + <el-form-item label="缂栧埗浜�"> + <el-input v-model="page.compilerName" clearable></el-input> + </el-form-item> + <el-form-item> + <el-button size="small" type="primary" @click="getYearPlanList(departId)">鏌� 璇�</el-button> + </el-form-item> + </el-form> + <div> + <el-button size="small" type="primary" @click="uploadDia = true, getUserList()">瀵煎叆</el-button> + </div> + </div> + <lims-table :tableData="yearPlanTableData" :column="yearPlanColumn" + :currentChange="currentChange" + @pagination="pagination" height="40vh" + :page="page" :tableLoading="yearLoading"></lims-table> + </div> + <div v-if="!editPlanShow" class="table"> + <div> + <div class="title"> + <span style="font-weight: bold">骞村害璁″垝鏄庣粏</span> + </div> + <div style="display: flex;justify-content: space-between;"> + <el-form :model="inDetailForm" ref="inDetailForm" size="small" :inline="true"> + <el-form-item label="鍩硅璁插笀"> + <el-input v-model="inDetailForm.trainingLecturerName" class="search" clearable placeholder="璇疯緭鍏�" size="small"></el-input> + </el-form-item> + <el-form-item label="鍩硅鏃ユ湡"> + <el-date-picker v-model="inDetailForm.trainingDate" clearable + format="yyyy-MM-dd" placeholder="閫夋嫨鏃ユ湡" size="small" + type="date" value-format="yyyy-MM-dd"></el-date-picker> + </el-form-item> + <el-form-item> + <el-button size="small" type="primary" @click="searchTable">鏌� 璇�</el-button> + </el-form-item> + </el-form> + <div> + <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" @click="batchDelete">鎵归噺鍒犻櫎</el-button> + <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" type="primary" @click="addTrainingPlan('add')">鏂板</el-button> + </div> + </div> + <lims-table :tableData="inDetailPlanTableData" :column="inDetailPlanColumn" + :height="isDepartment ? '40vh' : '62vh' " + :isSelection="true" :handleSelectionChange="handleSelectionChange" + @pagination="pagination1" + :page="inDetailPagination" :tableLoading="yearDetailLoading"></lims-table> + </div> + </div> + <Add ref="addPlan" :currentChangeRow="currentChangeRow" @search="getInDetailPlan(currentRowId, departId)"></Add> + <Edit + v-if="editPlanShow" + ref="editPlan" + :currentRow="currentRow" + @del="getInDetailPlan(currentRowId, departId)" + @goBack="goBack" + ></Edit> + <el-dialog :visible.sync="reviewDialog" title="瀹℃牳" width="30%" @close="auditRemarks = ''"> + <span> + 瀹℃牳澶囨敞锛� + <el-input v-model="auditRemarks" type="textarea"></el-input> + </span> + <span style="margin-top: 10px;display: inline-block"> + 鎵瑰噯浜猴細 + <el-select v-model="approverId" clearable + filterable size="small" style="width: 70%;"> + <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id"> + </el-option> + </el-select> + </span> + <span slot="footer" class="dialog-footer"> + <el-button :loading="reviewLoading" @click="handleReview(2)">涓嶉�氳繃</el-button> + <el-button :loading="reviewLoading" type="primary" @click="handleReview(1)">閫� 杩�</el-button> + </span> + </el-dialog> + <el-dialog :visible.sync="approvalDialog" title="鎵瑰噯" width="30%" @close="approvalRemarks = ''"> + <span> + 鎵瑰噯澶囨敞锛� + <el-input v-model="approvalRemarks" type="textarea"></el-input> + </span> + <span slot="footer" class="dialog-footer"> + <el-button :loading="approvalLoading" @click="handleApproval(2)">涓嶆壒鍑�</el-button> + <el-button :loading="reviewLoading" type="primary" @click="handleApproval(1)">鎵� 鍑�</el-button> + </span> + </el-dialog> + <el-dialog :visible.sync="uploadDia" title="鏁版嵁瀵煎叆" width="500px"> + <div style="display: flex;align-items: center;"> + <div style="width: 70px">骞翠唤锛�</div> + <el-date-picker + v-model="planYear" + type="year" + value-format="yyyy" + clearable + size="small" + format="yyyy" + placeholder="閫夋嫨骞�"> + </el-date-picker> + </div> + <div style="display: flex;align-items: center;margin: 10px 0"> + <div style="width: 70px">瀹℃牳浜猴細</div> + <el-select v-model="reviewerId" clearable + filterable size="small" style="width: 50%;"> + <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id"> + </el-option> + </el-select> + </div> + <div style="margin: 0 auto;"> + <el-upload ref="upload" :action="javaApi + '/personTraining/personTrainingImport' + '?planYear=' + planYear + '&reviewerId=' + reviewerId" + :auto-upload="false" :before-upload="beforeUpload" :file-list="fileList" :headers="uploadHeader" + :limit="1" :on-error="onError" :on-success="onSuccess" accept=".xlsx" drag + name="file"> + <i class="el-icon-upload"></i> + <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div> + </el-upload> + </div> + <span slot="footer" class="dialog-footer"> + <el-button @click="uploadDia = false">鍙� 娑�</el-button> + <el-button :loading="uploading" type="primary" @click="submitUpload()">涓� 浼�</el-button> + </span> + </el-dialog > + <view-record v-if="ViewRecord" ref="ViewRecord"></view-record> + </div> +</template> + +<script> +import Add from '../components/AddInDetail.vue'; +import Edit from '../components/Edit.vue'; +import ViewRecord from "../components/ViewRecord.vue"; +import limsTable from "@/components/Table/lims-table.vue"; +import {mapGetters} from "vuex"; +import { + approveAnnualPersonnelTraining, deleteAnnualPlanDetailTable, exportPersonTraining, exportPersonTrainingRecord, + personTraining, + personTrainingDelete, + queryTheAnnualPlanDetailsTable, reviewAnnualPersonnelTraining +} from "@/api/cnas/personal/personalTraining"; +import {selectUserCondition} from "@/api/system/user"; + +export default { + name: 'PersonnelTraining', + components: {limsTable, ViewRecord, Add, Edit }, + props: { + departId: { + type: Number, + default: () => { + return null; + } + }, + isDepartment: { + type: Boolean, + default: false + } + }, + computed: { + ...mapGetters(["userId"]), + }, + data() { + return { + planYear: '', + reviewerId: '', + responsibleOptions: [], + search: {}, + superviseForm: {}, + inDetailForm: { + trainingLecturerName: '', + trainingDate: '', + }, + yearLoading: false, + yearDetailLoading: false, + yearPlanTableData: [], // 骞村害璁″垝琛ㄦ暟鎹� + yearPlanColumn: [ + { + label: '鏂囦欢鍚嶇О', + width: '160px', + prop: 'fileName' + }, { + label: '鍒涘缓鏃堕棿', + width: '160px', + prop: 'createTime' + },{ + label: '缂栧埗浜�', + prop: 'compilerName' + }, { + label: '缂栧埗鏃ユ湡', + width: '160px', + prop: 'compilationDate' + }, { + label: '瀹℃牳浜�', + prop: 'reviewerName', + minWidth: '100px', + }, { + dataType: 'tag', + label: '瀹℃牳鐘舵��', + prop: 'reviewerStatus', + width: '100px', + formatData: (params) => { + if (params == 1) { + return '閫氳繃'; + } else if (params == 2) { + return '涓嶉�氳繃'; + } else { + return null + } + }, + formatType: (params) => { + if (params == 1) { + return 'success'; + } else if (params == 2) { + return 'danger'; + } else { + return null + } + } + }, { + label: '瀹℃牳澶囨敞', + prop: 'auditRemarks', + minWidth: '100px', + }, { + label: '瀹℃牳鏃ユ湡', + width: '160px', + prop: 'auditDate' + }, { + label: '鎵瑰噯浜�', + prop: 'approverName', + minWidth: '100px', + }, { + label: '鎵瑰噯澶囨敞', + prop: 'approvalRemarks', + minWidth: '100px', + }, { + dataType: 'tag', + label: '鎵瑰噯鐘舵��', + minWidth: '100px', + prop: 'approvalStatus', + formatData: (params) => { + if (params == 1) { + return '鎵瑰噯'; + } else if (params == 2) { + return '涓嶆壒鍑�'; + } else { + return null + } + }, + formatType: (params) => { + if (params == 1) { + return 'success'; + } else if (params == 2) { + return 'danger'; + } else { + return null + } + } + }, { + label: '鎵瑰噯鏃ユ湡', + width: '160px', + prop: 'approvalDate' + }, { + dataType: 'action', + width: '180px', + label: '鎿嶄綔', + fixed: 'right', + operation: [ + { + name: '瀵煎嚭', + type: 'text', + disabled: (row) => { + if(row.approvalStatus === 1 && row.reviewerStatus === 1) { + return false; + } else { + return true; + } + }, + clickFun: (row) => { + this.downLoadPost(row); + } + }, + { + name: '瀹℃牳', + type: 'text', + disabled: (row) => { + if(row.reviewerStatus === 1 || this.userId != row.reviewerId) { + return true; + } else { + return false; + } + }, + clickFun: (row) => { + this.handleCheck(row.id); + } + }, + { + name: '鎵瑰噯', + type: 'text', + disabled: (row) => { + if(row.approvalStatus === 1 || this.userId != row.approverId || row.reviewerStatus != 1) { + return true; + } else { + return false; + } + }, + clickFun: (row) => { + this.handleApprove(row.id); + } + }, + { + name: '鍒犻櫎', + type: 'text', + color: '#f56c6c', + clickFun: (row) => { + this.deleteFun(row.id); + }, + disabled: (row) => { + if(row.reviewerStatus === 1) { + return true; + } else { + return false; + } + }, + } + ] + }], + inDetailPlanTableData: [], // 骞村害璁″垝鏄庣粏琛ㄨ〃鏁版嵁 + inDetailPlanColumn: [ + { + label: '鍩硅鐩爣', + prop: 'trainingObjectives', + width: '100px', + }, { + label: '鍩硅鍐呭', + prop: 'trainingContent', + width: '100px', + }, { + label: '鍩硅鏂瑰紡', + prop: 'trainingMode', + width: '100px', + }, { + dataType: 'tag', + label: '璇剧▼鐘舵��', + width: '100px', + prop: 'state', + formatData: (params) => { + if (params == 1) { + return '宸插畬鎴�'; + } else if (params == 2) { + return '寰呰瘎浠�'; + } else if (params == 3) { + return '鏈紑濮�'; + } else { + return null + } + }, + formatType: (params) => { + if (params == 1) { + return 'success'; + } else if (params == 2) { + return 'warning'; + } else if (params == 3) { + return 'primary'; + } else if (params == 4) { + return 'info'; + } else { + return null + } + } + }, { + label: '鍙傚姞瀵硅薄', + prop: 'participants', + width: '100px', + }, { + label: '涓惧姙閮ㄩ棬', + prop: 'holdingDepartment', + width: '100px', + }, { + label: '鍩硅璁插笀', + prop: 'trainingLecturerName', + width: '100px', + }, { + label: '鍩硅鏃ユ湡', + prop: 'trainingDate', + width: '100px', + }, { + label: '寮�濮嬫椂闂�', + prop: 'openingTime', + width: '100px', + }, { + label: '璇炬椂', + prop: 'classHour', + width: '100px', + }, { + label: '澶囨敞', + prop: 'remarks', + width: '100px', + }, { + dataType: 'action', + width: '200', + label: '鎿嶄綔', + fixed: 'right', + operation: [ + { + name: '缂栬緫', + type: 'text', + clickFun: (row) => { + this.addTrainingPlan('edit', row); + }, + }, + { + name: '缁撴灉鏄庣粏', + type: 'text', + clickFun: (row) => { + this.editInDetail(row); + }, + showHide: () => { + if (this.isDepartment) { + return true; + } else { + return false; + } + } + }, + { + name: '闄勪欢', + type: 'text', + clickFun: (row) => { + this.viewRecord(row); + }, + }, + { + name: '瀵煎嚭', + type: 'text', + clickFun: (row) => { + this.downLoadInDetail(row); + } + }, + + ] + }], + page: { + total:0, + size:10, + current:1, + compilerName: "" + }, + inDetailPagination: { + total:0, + size:10, + current:1, + }, + editPlanShow: false, + currentRow: {}, + currentRowId: null, // 褰撳墠閫変腑鏁版嵁鐨刬d + auditRemarks: '', // 瀹℃牳澶囨敞 + reviewDialog: false, // 瀹℃牳寮规 + reviewLoading: false, // 瀹℃牳鎻愪氦鎸夐挳 + approvalRemarks: '', // 瀹℃牳澶囨敞 + approvalDialog: false, // 瀹℃牳寮规 + approvalLoading: false, // 瀹℃牳鎻愪氦鎸夐挳 + multipleSelection: [], // 骞村害鏄庣粏琛ㄩ�変腑鐨勬暟鎹� + uploadDia: false, + uploading: false, + isOperation: false, + ViewRecord: false, + fileList: [], + currentChangeRow: {}, + approverId: '' + }; + }, + mounted() { + if (this.isDepartment) { + this.getYearPlanList(this.departId) + } else { + this.getInDetailPlan('', this.departId) + } + }, + methods: { + searchTable () { + this.getInDetailPlan(this.currentRowId) + }, + // 鏌ヨ-骞村害璁″垝琛� + getYearPlanList(userId) { + this.yearLoading = true + const params = this.isDepartment ? + { + departmentId: userId, + size: this.page.size, + current: this.page.current, + compilerName: this.page.compilerName, + }: { + userId: userId, + size: this.page.size, + current: this.page.current, + compilerName: this.page.compilerName, + } + personTraining(params).then(res => { + this.yearLoading = false + this.yearPlanTableData = res.data.records; + this.pagination.total = res.data.total; + if (this.yearPlanTableData.length > 0) { + this.currentRowId = this.yearPlanTableData[0].id + this.currentChange(this.yearPlanTableData[0]) + } + }).catch(err => { + this.yearLoading = false + }) + }, + pagination (page) { + this.page.size = page.limit + this.getYearPlanList() + }, + currentChange (row) { + const now = new Date(); + const currentYear = now.getFullYear(); + if (row) { + this.currentChangeRow = row + this.currentRowId = row.id + if (row.createTime.slice(0,4) == currentYear) { + this.isOperation = true; + } else { + this.isOperation = false; + } + this.getInDetailPlan(row.id) + } + }, + getInDetailPlan (id) { + if (this.inDetailForm.trainingDate === null) { + this.inDetailForm.trainingDate = '' + } + const userId = this.isDepartment ? '' : this.departId + const params = + { + userId: userId, + size: this.inDetailPagination.pageSize, + current: this.inDetailPagination.current, + id: id, + trainingLecturerName: this.inDetailForm.trainingLecturerName, + trainingDate: this.inDetailForm.trainingDate, + } + this.yearDetailLoading = true + queryTheAnnualPlanDetailsTable(params).then(res => { + this.yearDetailLoading = false + this.inDetailPlanTableData = res.data.records; + this.inDetailPagination.total = res.data.total; + }).catch(err => { + this.yearDetailLoading = false + }) + }, + pagination1 (page) { + this.inDetailPagination.size = page.limit + this.getInDetailPlan(this.currentRowId) + }, + // 鏂板骞村害璁″垝鏄庣粏琛� + addTrainingPlan(type, row) { + if (!this.currentRowId) { + this.$message.warning('璇烽�夋嫨涓�鏉¤鍒掕繘琛屾柊澧�') + return + } + this.$refs.addPlan.showDialog(this.currentRowId, type, row); + }, + // 骞村害璁″垝琛�-鍒犻櫎 + deleteFun(id) { + this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { + personTrainingDelete({id: id}).then(res => { + this.$message.success('鍒犻櫎鎴愬姛锛�'); + this.getYearPlanList(this.departId); + }); + }).catch(() => { + this.$message({ + type: 'info', + message: '宸插彇娑堝垹闄�' + }); + }); + }, + // 骞村害璁″垝琛�-瀹℃牳 + handleCheck(id) { + this.currentRowId = id + this.reviewDialog = true + this.getUserList() + }, + // 鎻愪氦瀹℃牳 + handleReview (status) { + const personTrainingUpdateDto = { + id: this.currentRowId, + auditRemarks: this.auditRemarks, + reviewerStatus: status, + approverId: this.approverId + } + this.reviewLoading = true + reviewAnnualPersonnelTraining(personTrainingUpdateDto).then(res => { + if (res.code === 200) { + this.$message.success('鎻愪氦鎴愬姛锛�'); + this.reviewDialog = false + this.getYearPlanList(this.departId); + } + this.reviewLoading = false + }).catch(() => { + this.reviewLoading = false + }) + }, + // 骞村害璁″垝琛�-鎵瑰噯 + handleApprove(id) { + this.currentRowId = id + this.approvalDialog = true + }, + // 鎻愪氦鎵瑰噯 + handleApproval (status) { + const personTrainingUpdateDto = { + id: this.currentRowId, + approvalRemarks: this.approvalRemarks, + approvalStatus: status + } + this.approvalLoading = true + approveAnnualPersonnelTraining(personTrainingUpdateDto).then(res => { + if (res.code === 200) { + this.$message.success('鎻愪氦鎴愬姛锛�'); + this.approvalDialog = false + this.getYearPlanList(this.departId); + } + this.approvalLoading = false + }).catch(() => { + this.approvalLoading = false + }) + }, + // 骞村害璁″垝琛�-涓嬭浇 + downLoadPost(row) { + exportPersonTraining({id: row.id}).then(res => { + this.outLoading = false + const blob = new Blob([res],{ type: 'application/msword' }); + this.$download.saveAs(blob, row.fileName + '.docx') + this.$message.success('瀵煎嚭鎴愬姛') + }) + }, + // 骞村害璁″垝-瀵煎叆 + submitUpload() { + if (this.$refs.upload.uploadFiles.length == 0) { + this.$message.error('鏈�夋嫨鏂囦欢') + return + } + this.uploading = true + this.$refs.upload.submit(); + this.uploading = false + }, + onSuccess(response, file, fileList) { + this.$refs.upload.clearFiles() + this.uploadDia = false + this.uploading = false + if (response.code != 200) { + this.$message.error(response.msg) + return + } + this.$message.success('涓婁紶鎴愬姛') + this.standardList = [] + this.productList = [] + this.getYearPlanList(this.departId) + }, + onError(err, file, fileList) { + this.$message.error('涓婁紶澶辫触') + this.$refs.upload.clearFiles() + this.uploading = false + }, + beforeUpload(file, fileList) { + if (file.type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') { + this.$message.error('涓婁紶鏂囦欢鏍煎紡涓嶆纭�'); + this.$refs.upload.clearFiles() + return false; + } + }, + // 骞村害璁″垝鏄庣粏琛�-缂栬緫 + editInDetail(row) { + this.editPlanShow = true; + this.currentRow = row + }, + // + goBack() { + this.editPlanShow = false; + this.getInDetailPlan(this.currentRowId) + }, + viewRecord (row) { + this.ViewRecord = true + this.$nextTick(() => { + this.$refs.ViewRecord.openDia(row) + }) + }, + // 骞村害璁″垝鏄庣粏琛�-涓嬭浇 + downLoadInDetail(row) { + exportPersonTrainingRecord({id: row.id}).then(res => { + this.outLoading = false + const blob = new Blob([res],{ type: 'application/msword' }); + this.$download.saveAs(blob, '浜哄憳鍩硅涓庤�冩牳璁板綍.docx') + this.$message.success('瀵煎嚭鎴愬姛') + }) + }, + // 骞村害璁″垝鏄庣粏琛�-澶氶�� + handleSelectionChange(list) { + this.multipleSelection = list + }, + // 骞村害鏄庣粏琛�-鍒犻櫎 + batchDelete () { + if (this.multipleSelection.length > 0) { + let ids = [] + this.multipleSelection.forEach(item => { + ids.push(item.id) + }) + this.$confirm('鏄惁纭鍒犻櫎鎵�閫夋嫨鐨勬暟鎹�?', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { + deleteAnnualPlanDetailTable({ids: ids.join(',')}).then(res => { + if (res.code == 200) { + this.$message.success('鍒犻櫎鎴愬姛'); + this.getInDetailPlan(this.currentRowId); + } + }); + }).catch(() => { + this.$message.warning('鍙栨秷鍒犻櫎'); + }); + } else { + this.$message.warning('璇烽�夋嫨闇�瑕佸垹闄ょ殑鏁版嵁') + } + }, + handleSizeChange(val) { + this.inDetailPagination.size = val; + this.getInDetailPlan(this.currentChangeRow.id) + }, + handleCurrentChange(val) { + this.inDetailPagination.current = val; + this.getInDetailPlan(this.currentChangeRow.id) + }, + // 鑾峰彇璐熻矗浜轰俊鎭帴鍙� + getUserList() { + selectUserCondition().then(res => { + if (res.code == 200) { + this.responsibleOptions = res.data + } + }); + } + }, + watch: { + // 鐩戝惉鐐瑰嚮el-tree鐨勬暟鎹紝杩涜鏁版嵁鍒锋柊 + departId: { + handler(newId, oldId) { + if (this.isDepartment) { + this.getYearPlanList(newId); + } else { + this.getInDetailPlan('') + } + } + }, + currentRowId: { + handler(newId, oldId) { + if (newId) { + console.log('newId', newId); + this.inDetailPagination.current = 1 + this.getInDetailPlan(this.currentChangeRow.id) + } + } + } + } +} +</script> +<style scoped> +.flex_column { + display: flex; + height: 80vh; + flex-direction: column; + overflow: auto; + justify-content: space-between; +} +.search { + width: 150px; + margin: 0 16px; +} +.title { + position: relative; + font-size: 16px; + color: #333; + font-weight: 400; + padding-left: 10px; + margin-bottom: 10px; +} + +.title::before { + position: absolute; + left: 0; + top: 4px; + content: ''; + width: 4px; + height: 16px; + background-color: #3A7BFA; + border-radius: 2px; +} +</style> -- Gitblit v1.9.3