From 050ee6d982a8ae40011f1f723198d23fedae40b3 Mon Sep 17 00:00:00 2001 From: 祖安之光 <11848914+light-of-zuan@user.noreply.gitee.com> Date: 星期二, 15 七月 2025 09:39:13 +0800 Subject: [PATCH] 修改新增 --- src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/components/editDialog.vue | 241 +++ src/views/work/selfProblems/mngAudit/mngAuditPlan/components/editDialog.vue | 386 +++++ public/interCheck.docx | 0 src/views/work/selfProblems/internalAudit/problemMng/improveMng/components/editDialog.vue | 267 +++ src/views/work/selfProblems/mngAudit/mngAuditMeeting/index.vue | 216 +++ src/views/work/selfProblems/internalAudit/problemMng/improveMng/index.vue | 254 +++ public/reviewPlan.docx | 0 src/api/innerReview/meetingReview.js | 201 ++ src/views/work/selfProblems/mngAudit/mngAuditInput/index.vue | 216 +++ src/views/work/selfProblems/mngAudit/mngAuditReport/index.vue | 216 +++ src/views/work/selfProblems/internalAudit/meetingMng/components/editDialog.vue | 236 +++ src/views/work/selfProblems/mngAudit/mngAuditMeeting/components/editDialog.vue | 243 +++ src/views/work/selfProblems/mngAudit/mngAuditPlan/index.vue | 244 +++ src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue | 2 src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue | 3 src/views/work/selfProblems/internalAudit/innerReviewSheet/components/editDialog.vue | 370 +++++ src/views/work/selfProblems/mngAudit/mngAuditReport/components/editDialog.vue | 243 +++ src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/index.vue | 214 +++ src/views/work/selfProblems/mngAudit/mngAuditInput/components/editDialog.vue | 243 +++ src/views/build/conpanyFunctionConsult/orgStructure/departManage/components/departDialog.vue | 7 src/views/work/selfProblems/internalAudit/innerReviewSheet/index.vue | 232 +++ src/views/work/selfProblems/internalAudit/meetingMng/index.vue | 209 ++ 22 files changed, 4,237 insertions(+), 6 deletions(-) diff --git a/public/interCheck.docx b/public/interCheck.docx new file mode 100644 index 0000000..c82c01d --- /dev/null +++ b/public/interCheck.docx Binary files differ diff --git a/public/reviewPlan.docx b/public/reviewPlan.docx new file mode 100644 index 0000000..75cce73 --- /dev/null +++ b/public/reviewPlan.docx Binary files differ diff --git a/src/api/innerReview/meetingReview.js b/src/api/innerReview/meetingReview.js new file mode 100644 index 0000000..ae20803 --- /dev/null +++ b/src/api/innerReview/meetingReview.js @@ -0,0 +1,201 @@ +import request from '@/utils/request' + +export function getMeetingsList(query) { + return request({ + url: '/system/meetings/selectMeetingsList', + method: 'get', + params: query + }) +} + +export function delMeetingsList(query) { + return request({ + url: '/system/meetings/deletedMeetings', + method: 'get', + params: query + }) +} + +export function addMeetingsList(data) { + return request({ + url: '/system/meetings/saveMeetings', + method: 'post', + data: data + }) +} + +export function updateMeetingsList(data) { + return request({ + url: '/system/meetings/updateMeetings', + method: 'post', + data: data + }) +} + +export function getInternalAuditCheck(query) { + return request({ + url: '/system/internalAuditCheck/selectInternalAuditCheckList', + method: 'get', + params: query + }) +} + +export function delInternalAuditCheck(query) { + return request({ + url: '/system/internalAuditCheck/deletedInternalAuditCheck', + method: 'get', + params: query + }) +} + +export function addInternalAuditCheck(data) { + return request({ + url: '/system/internalAuditCheck/saveInternalAuditCheck', + method: 'post', + data: data + }) +} + +export function updateInternalAuditCheck(data) { + return request({ + url: '/system/internalAuditCheck/updateInternalAuditCheck', + method: 'post', + data: data + }) +} + +export function getInternalAuditCheckInfo(query) { + return request({ + url: '/system/internalAuditCheck/internalAuditCheckInfo', + method: 'get', + params: query + }) +} + +export function getSelectCorrection(query) { + return request({ + url: '/system/correction/selectCorrectionList', + method: 'get', + params: query + }) +} + +export function delSelectCorrection(query) { + return request({ + url: '/system/correction/delCorrection', + method: 'get', + params: query + }) +} + +export function addSelectCorrection(data) { + return request({ + url: '/system/correction/saveCorrection', + method: 'post', + data: data + }) +} + +export function updateSelectCorrection(data) { + return request({ + url: '/system/correction/updateCorrection', + method: 'post', + data: data + }) +} + +export function getSelectInconsistent(query) { + return request({ + url: '/system/inconsistent/selectInconsistentList', + method: 'get', + params: query + }) +} + +export function delSelectInconsistent(query) { + return request({ + url: '/system/inconsistent/deletedInconsistent', + method: 'get', + params: query + }) +} + +export function addSelectInconsistent(data) { + return request({ + url: '/system/inconsistent/saveInconsistent', + method: 'post', + data: data + }) +} + +export function updateSelectInconsistent(data) { + return request({ + url: '/system/inconsistent/updateCorrection', + method: 'post', + data: data + }) +} + +export function getSelectMeetings(query) { + return request({ + url: '/system/managementReview/selectMeetingsList', + method: 'get', + params: query + }) +} + +export function delSelectMeetings(query) { + return request({ + url: '/system/managementReview/deletedManagementReview', + method: 'get', + params: query + }) +} + +export function addSelectMeetings(data) { + return request({ + url: '/system/managementReview/saveManagementReview', + method: 'post', + data: data + }) +} + +export function updateSelectMeetings(data) { + return request({ + url: '/system/managementReview/updateManagementReview', + method: 'post', + data: data + }) +} + +export function getManagementPlan(query) { + return request({ + url: '/system/managementPlan/selectManagementPlanList', + method: 'get', + params: query + }) +} + +export function delManagementPlan(query) { + return request({ + url: '/system/managementPlan/deletedManagementPlan', + method: 'get', + params: query + }) +} + +export function addManagementPlan(data) { + return request({ + url: '/system/managementPlan/saveManagementPlan', + method: 'post', + data: data + }) +} + +export function updateManagementPlan(data) { + return request({ + url: '/system/managementPlan/updateManagementPlan', + method: 'post', + data: data + }) +} \ No newline at end of file diff --git a/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue index a5d5418..7c16b55 100644 --- a/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue +++ b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue @@ -229,7 +229,8 @@ if(res.code === 200){ if(!res.data || (res.data.companyIndustryTemplates.length == 0 && res.data.companyQualityPolicies.length == 0 && res.data.companySummaries.length == 0 && res.data.sysFunctionalDistributions .length == 0 && res.data.treeSelects.length == 0)){ - return Promise.reject(new Error('该企业暂无质量数据')); + loading.value = false + return Promise.reject(new Error('该企业暂无质量数据')) } data.companyInfo.summaries = res.data.companySummaries ? res.data.companySummaries[0]?.companySummary : [] data.companyInfo.policies = res.data.companyQualityPolicies ? res.data.companyQualityPolicies[0]?.policy : [] diff --git a/src/views/build/conpanyFunctionConsult/orgStructure/departManage/components/departDialog.vue b/src/views/build/conpanyFunctionConsult/orgStructure/departManage/components/departDialog.vue index 134ef0d..622b664 100644 --- a/src/views/build/conpanyFunctionConsult/orgStructure/departManage/components/departDialog.vue +++ b/src/views/build/conpanyFunctionConsult/orgStructure/departManage/components/departDialog.vue @@ -175,7 +175,7 @@ if(isAdmin){ state.companyList = companyList } - await getUserList() + await getUserList(companyId) await getDepartList(companyId) await getSysClauseList() state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'; @@ -201,8 +201,8 @@ dialogVisible.value = true } -const getUserList = async ()=> { - const res = await listUser({pageIndex: 1,pageSize: 999}) +const getUserList = async (companyId)=> { + const res = await listUser({pageIndex: 1,pageSize: 999, companyId: companyId}) if(res.code == 200){ state.userList = res.data.list?res.data.list:[] }else{ @@ -212,6 +212,7 @@ const getDeptList = async ()=>{ await getDepartList(state.form.companyId) + await getUserList(state.form.companyId) } const getDepartList = async (companyId)=> { diff --git a/src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue b/src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue index 1b20080..fdf779a 100644 --- a/src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue +++ b/src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue @@ -328,7 +328,6 @@ let name = '' data.forEach(item => { name = '' - console.log('item',item) if(item.type == 1){ templatePath.value = '/tableCompanyExample.docx' name = item.companyName @@ -340,7 +339,6 @@ const year = now.getFullYear() const month = (now.getMonth() +1).toString().padStart(2, '0'); item.nowDate = year + '-' + month - console.log('item.qualityTargets',item.qualityTargets) item.tableData = item.qualityTargets.map((i,index) => { return{ ...i, diff --git a/src/views/work/selfProblems/internalAudit/innerReviewSheet/components/editDialog.vue b/src/views/work/selfProblems/internalAudit/innerReviewSheet/components/editDialog.vue new file mode 100644 index 0000000..b7e802e --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/innerReviewSheet/components/editDialog.vue @@ -0,0 +1,370 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable @change="getDeptList"> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="受审核部门:" prop="deptId"> + <el-select + clearable + v-model="state.form.deptId" + :disabled="state.title =='查看'" + filterable + placeholder="选择受审核部门" + style="width: 100%" + @change="getCaluses" + > + <el-option + v-for="item in state.deptList" + :key="item.deptId" + :label="item.deptName" + :value="item.deptId" + /> + </el-select> + </el-form-item> + <el-form-item label="受审核人:" prop="internalAuditCheckPeople"> + <el-select clearable v-model="state.form.internalAuditCheckPeople" :disabled="state.title =='查看'" value-key="userId" filterable multiple placeholder="受审核人" style="width: 100%"> + <el-option + v-for="item in state.userList" + :key="item.userId" + :label="item.name" + :value="item" + /> + </el-select> + </el-form-item> + <el-form-item label="内审员:" prop="auditId"> + <el-select clearable v-model="state.form.auditId" :disabled="state.title =='查看'" filterable placeholder="内审员" style="width: 100%"> + <el-option + v-for="item in state.userList" + :key="item.userId" + :label="item.name" + :value="item.userId" + /> + </el-select> + </el-form-item> + <el-form-item label="内审时间:" prop="auditDate"> + <el-date-picker + v-model="state.form.auditDate" + type="datetime" + value-format="YYYY-MM-DD HH:mm:ss" + placeholder="请选择内审时间" + /> + </el-form-item> + <el-form-item label="对应认证标准条款(过程):" prop="caluseNum"> + <el-input v-model.trim="state.form.caluseNum" type="textarea" readonly :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-form-item label="检查内容:" prop="caluseContent"> + <el-input v-model.trim="state.form.caluseContent" type="textarea" readonly :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-form-item label="检查记录:" prop="checkRecord"> + <el-input v-model.trim="state.form.checkRecord" type="textarea" :readonly="state.title =='查看'" :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-form-item label="不符合标记:" prop="inconsistent"> + <el-input v-model.trim="state.form.inconsistent" type="textarea" :readonly="state.title =='查看'" :autosize="{ minRows: 2 }"></el-input> + </el-form-item> +<!-- <el-form-item label="文件:" prop="filePath">--> +<!-- <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" >--> +<!-- <el-button type="primary">点击上传</el-button>--> +<!-- <template #tip>--> +<!-- <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div>--> +<!-- </template>--> +<!-- </el-upload>--> +<!-- </el-form-item>--> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {Base64} from "js-base64" +import {getToken} from "@/utils/auth"; +import { + addInternalAuditCheck, getInternalAuditCheckInfo, + updateInternalAuditCheck +} from "@/api/innerReview/meetingReview"; +import {getDepart} from "@/api/orgStructure/depart"; +import {listUser} from "@/api/system/user"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + deptId: null, + internalAuditCheckPeople:[], + auditId: null, + auditDate: '', + caluseNum: '', + caluseContent: '', + checkRecord: '', + inconsistent: '', + companyId: null + }, + formRules:{ + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + deptId: [{ required: true, message: '请选择受审核部门', trigger: 'blur' }], + internalAuditCheckPeople: [{ required: true, message: '请选择受审核人', trigger: 'blur' }], + auditId: [{ required: true, message: '请选择内审员', trigger: 'blur' }], + auditDate: [{ required: true, message: '请选择内审时间', trigger: 'blur' }], + checkRecord: [{ required: true, message: '请填写检查记录', trigger: 'blur' }] + }, + isAdmin: false, + companyList: [], + deptList: [], + userList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + await getUserList(companyId) + await getDepartList(companyId) + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + await getInfo(value.id) + + // if(value.filePath) { + // const obj = { + // url: value.filePath, + // name: '模板文件' + // } + // state.fileList = [obj] + // } + } + dialogVisible.value = true +} + + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + state.form.internalAuditCheckPeople = state.form.internalAuditCheckPeople.map(item=>{ + return { + id: item.id || null, + auditUserId: item.userId, + companyId: item.companyId || null, + auditUserName: item.name + } + }) + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addInternalAuditCheck(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateInternalAuditCheck(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const getInfo = async (id)=> { + const res = await getInternalAuditCheckInfo({id: id}) + if(res.code == 200){ + state.form.internalAuditCheckPeople = res.data.internalAuditCheckPeople?.map(item=>{ + return { + id: item.id, + auditId: item.auditId, + userId: item.auditUserId, + name: item.auditUserName, + companyId: item.companyId + } + }) + }else{ + ElMessage.warning(res.message) + } +} + +const getDeptList = async ()=>{ + state.form.deptId = null + state.form.internalAuditCheckPeople = [] + state.form.auditId = null + state.form.caluseNum = '' + state.form.caluseContent = '' + await getDepartList(state.form.companyId) + await getUserList(state.form.companyId) +} + +const getDepartList = async (companyId)=> { + const params = { + companyId: companyId + } + const res = await getDepart(params) + if(res.code == 200){ + state.deptList = res.data + }else{ + ElMessage.warning(res.message) + } +} + +const getUserList = async (companyId,deptId)=> { + const res = await listUser({pageIndex: 1,pageSize: 999, companyId: companyId,deptId: deptId}) + if(res.code == 200){ + state.userList = res.data.list?res.data.list.map(item=>{ + const user = item.id + const {id, ...data} = item + return { + ...data, + userId: user + } + }):[] + }else{ + ElMessage.warning(res.message) + } +} + +const getCaluses = async (value)=>{ + await getUserList(state.form.companyId,value) + const deptCaluses = state.deptList.find(i=>i.deptId == state.form.deptId)?.caluseVO1List + if(deptCaluses && Array.isArray(deptCaluses)){ + state.form.caluseNum = deptCaluses.map(i=>i.clauseNum).join('、') + state.form.caluseContent = deptCaluses.map(i=>i.content).join(';\n') + } +} +// const handleAvatarSuccess = (res, uploadFile) => { +// if(res.code == 200){ +// state.form.filePath = res.data.path +// state.form.format = '.' + res.data.filename.split('.')[1] +// }else{ +// state.fileList = [] +// ElMessage({ +// type: 'warning', +// message: '文件上传失败' +// }) +// } +// } +// +// const showTip =()=>{ +// ElMessage({ +// type: 'warning', +// message: '超出文件上传数量' +// }); +// } +// const picSize = async (rawFile) => { +// if(rawFile.size / 1024 / 1024 > 5){ +// ElMessage({ +// type: 'warning', +// message: '文件大小不能超过5M' +// }); +// return false +// } +// }; +// const handleRemove = async (file, uploadFiles) => { +// let path = state.form.filePath; +// await delPic({path: path}).then(res => { +// if(res.code == 200){ +// // ElMessage({ +// // type: 'success', +// // message: '文件已删除' +// // }) +// state.form.filePath = '' +// state.form.format = '' +// }else{ +// ElMessage({ +// type: 'warning', +// message: res.message +// }) +// } +// }).catch(() => { +// state.form.imgUrl = '' +// }); +// } + +const handleClose = () => { + state.form = { + id: null, + deptId: null, + internalAuditCheckPeople:[], + auditId: null, + auditDate: '', + caluseNum: '', + caluseContent: '', + checkRecord: '', + inconsistent: '', + companyId: null + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/innerReviewSheet/index.vue b/src/views/work/selfProblems/internalAudit/innerReviewSheet/index.vue new file mode 100644 index 0000000..86fa2e4 --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/innerReviewSheet/index.vue @@ -0,0 +1,232 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column type="index" label="序号"></el-table-column> + <el-table-column label="检查表" align="center"> + <template #default="scope"> + {{scope.row.deptName }}内审检查表 + </template> + </el-table-column> + <el-table-column label="操作" align="center"> + <template #default="scope"> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="primary" @click="downloadFile(scope.row.id)">导出</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import { + delInternalAuditCheck, + delMeetingsList, + getInternalAuditCheck, getInternalAuditCheckInfo, + getMeetingsList +} from "@/api/innerReview/meetingReview"; +import {generateWordDocument} from "@/utils/exportWord"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null + }, + total: 0, + dataList: [], + companyList: [], + isAdmin: false +}); + +const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getInternalAuditCheck(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = async (id)=>{ + const res = await getInternalAuditCheckInfo({id: id}) + if(res.code == 200){ + if(res.data){ + let tableData = res.data + tableData.content = res.data.caluseNum.split('、').map((i,index)=>i + res.data.caluseContent.split(';\n')[index]).join('\n') + tableData.interPeople = res.data.internalAuditCheckPeople.map(i=>i.auditUserName) + try { + generateWordDocument('/interCheck.docx', tableData, tableData.deptName +'内审检查表.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + }else{ + ElMessage.warning('暂无数据') + } + }else{ + ElMessage.warning(res.message) + } +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delInternalAuditCheck({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> diff --git a/src/views/work/selfProblems/internalAudit/meetingMng/components/editDialog.vue b/src/views/work/selfProblems/internalAudit/meetingMng/components/editDialog.vue new file mode 100644 index 0000000..1f2f943 --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/meetingMng/components/editDialog.vue @@ -0,0 +1,236 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year"> + <el-date-picker + v-model="state.form.year" + type="year" + value-format="YYYY" + placeholder="请选择年份" + /> + </el-form-item> + <el-form-item label="文件名称:" prop="meetingsName"> + <el-input v-model.trim="state.form.meetingsName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="文件:" prop="filePath"> + <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > + <el-button type="primary">点击上传</el-button> + <template #tip> + <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div> + </template> + </el-upload> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {saveStandardTemp, updateStandardTemp} from "@/api/standardSys/standardSys"; +import {addMeetingsList, updateMeetingsList} from "@/api/innerReview/meetingReview"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + year: '', + meetingsName: '', + filePath: '', + format: '', + companyId: null + }, + formRules:{ + year: [{ required: true, message: '请选择年份', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + meetingsName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }], + filePath: [{ required: true, validator: checkFiles, trigger: 'blur' }] + }, + isAdmin: false, + companyList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + if(value.filePath) { + const obj = { + url: value.filePath, + name: '模板文件' + } + state.fileList = [obj] + } + } + dialogVisible.value = true +} + + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addMeetingsList(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateMeetingsList(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.filePath = res.data.path + state.form.format = '.' + res.data.filename.split('.')[1] + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.format = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + year: '', + meetingsName: '', + filePath: '', + format: '', + companyId: null + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/meetingMng/index.vue b/src/views/work/selfProblems/internalAudit/meetingMng/index.vue new file mode 100644 index 0000000..e4ef47c --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/meetingMng/index.vue @@ -0,0 +1,209 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="meetingsName" align="center"/> + <el-table-column label="年份" prop="year" align="center"/> + <el-table-column label="文件" align="center"> + <template #default="scope"> + <el-link type="primary" @click="openFile(scope.row.filePath)">{{scope.row.meetingsName + scope.row.format}}</el-link> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row.filePath)">下载</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import {delMeetingsList, getMeetingsList} from "@/api/innerReview/meetingReview"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null + }, + total: 0, + dataList: [], + companyList: [], + isAdmin: false +}); + +const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getMeetingsList(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = (path)=>{ + window.open(import.meta.env.VITE_APP_BASE_API + '/' + path) +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delMeetingsList({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> diff --git a/src/views/work/selfProblems/internalAudit/problemMng/improveMng/components/editDialog.vue b/src/views/work/selfProblems/internalAudit/problemMng/improveMng/components/editDialog.vue new file mode 100644 index 0000000..bc734cc --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/problemMng/improveMng/components/editDialog.vue @@ -0,0 +1,267 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable @change="getDeptList"> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="文件名称:" prop="correctionName"> + <el-input v-model.trim="state.form.correctionName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="部门:" prop="deptId"> + <el-select + clearable + v-model="state.form.deptId" + :disabled="state.title =='查看'" + filterable + placeholder="选择部门" + style="width: 100%" + > + <el-option + v-for="item in state.deptList" + :key="item.deptId" + :label="item.deptName" + :value="item.deptId" + /> + </el-select> + </el-form-item> + <el-form-item label="文件:" prop="filePath"> + <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > + <el-button type="primary">点击上传</el-button> + <template #tip> + <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div> + </template> + </el-upload> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {saveStandardTemp, updateStandardTemp} from "@/api/standardSys/standardSys"; +import { + addMeetingsList, + addSelectCorrection, + updateMeetingsList, + updateSelectCorrection +} from "@/api/innerReview/meetingReview"; +import {getDepart} from "@/api/orgStructure/depart"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + deptId: null, + correctionName: '', + filePath: '', + format: '', + companyId: null + }, + formRules:{ + deptId: [{ required: true, message: '请选择部门', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + correctionName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }], + filePath: [{ required: true, validator: checkFiles, trigger: 'blur' }] + }, + isAdmin: false, + companyList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + await getDepartList(companyId) + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + if(value.filePath) { + const obj = { + url: value.filePath, + name: '模板文件' + } + state.fileList = [obj] + } + } + dialogVisible.value = true +} + +const getDeptList = async (value)=>{ + await getDepartList(value) +} + +const getDepartList = async (companyId)=> { + const params = { + companyId: companyId + } + const res = await getDepart(params) + if(res.code == 200){ + state.deptList = res.data + }else{ + ElMessage.warning(res.message) + } +} + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addSelectCorrection(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateSelectCorrection(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.filePath = res.data.path + state.form.format = '.' + res.data.filename.split('.')[1] + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.format = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + deptId: null, + correctionName: '', + filePath: '', + format: '', + companyId: null + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/problemMng/improveMng/index.vue b/src/views/work/selfProblems/internalAudit/problemMng/improveMng/index.vue new file mode 100644 index 0000000..1b996ab --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/problemMng/improveMng/index.vue @@ -0,0 +1,254 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" @change="getDeptList" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="部门:" > + <el-select v-model="data.queryParams.deptId" placeholder="请选择" clearable> + <el-option + v-for="item in deptList" + :key="item.deptId" + :label="item.deptName" + :value="item.deptId"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="correctionName" align="center"/> + <el-table-column label="部门" prop="deptId" align="center"> + <template #default="scope"> + {{getDeptName(scope.row.deptId)}} + </template> + </el-table-column> + <el-table-column label="文件" align="center"> + <template #default="scope"> + <el-link type="primary" @click="openFile(scope.row.filePath)">{{scope.row.correctionName + scope.row.format}}</el-link> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row.filePath)">下载</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import { + delMeetingsList, + delSelectCorrection, + getMeetingsList, + getSelectCorrection +} from "@/api/innerReview/meetingReview"; +import {getDepart} from "@/api/orgStructure/depart"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + deptId: null + }, + total: 0, + dataList: [], + companyList: [], + deptList: [], + isAdmin: false +}); + +const { queryParams, total, dataList,companyList, deptList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getDepartList() + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getSelectCorrection(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const getDeptList = async (value)=>{ + await getDepartList(value) +} + +const getDepartList = async (companyId)=> { + const params = { + companyId: companyId + } + const res = await getDepart(params) + if(res.code == 200){ + data.deptList = res.data + }else{ + ElMessage.warning(res.message) + } +} + +const getDeptName = (id)=>{ + return data.deptList.find(i=>i.deptId == id)?.deptName +} + +const downloadFile = (path)=>{ + window.open(import.meta.env.VITE_APP_BASE_API + '/' + path) +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null, + deptId: null + } + await getCompanyList() + await getDepartList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delSelectCorrection({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> diff --git a/src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/components/editDialog.vue b/src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/components/editDialog.vue new file mode 100644 index 0000000..3903356 --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/components/editDialog.vue @@ -0,0 +1,241 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year"> + <el-date-picker + v-model="state.form.year" + type="year" + value-format="YYYY" + placeholder="请选择年份" + /> + </el-form-item> + <el-form-item label="文件名称:" prop="inconsistentName"> + <el-input v-model.trim="state.form.inconsistentName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="文件:" prop="filePath"> + <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > + <el-button type="primary">点击上传</el-button> + <template #tip> + <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div> + </template> + </el-upload> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {saveStandardTemp, updateStandardTemp} from "@/api/standardSys/standardSys"; +import { + addMeetingsList, + addSelectInconsistent, + updateMeetingsList, + updateSelectInconsistent +} from "@/api/innerReview/meetingReview"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + year: '', + inconsistentName: '', + filePath: '', + format: '', + companyId: null + }, + formRules:{ + year: [{ required: true, message: '请选择年份', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + inconsistentName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }], + filePath: [{ required: true, validator: checkFiles, trigger: 'blur' }] + }, + isAdmin: false, + companyList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + if(value.filePath) { + const obj = { + url: value.filePath, + name: '模板文件' + } + state.fileList = [obj] + } + } + dialogVisible.value = true +} + + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addSelectInconsistent(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateSelectInconsistent(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.filePath = res.data.path + state.form.format = '.' + res.data.filename.split('.')[1] + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.format = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + year: '', + inconsistentName: '', + filePath: '', + format: '', + companyId: null + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/index.vue b/src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/index.vue new file mode 100644 index 0000000..e788f7e --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/problemMng/noConformanceMng/index.vue @@ -0,0 +1,214 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="inconsistentName" align="center"/> + <el-table-column label="年份" prop="year" align="center"/> + <el-table-column label="文件" align="center"> + <template #default="scope"> + <el-link type="primary" @click="openFile(scope.row.filePath)">{{scope.row.inconsistentName + scope.row.format}}</el-link> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row.filePath)">下载</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import { + delMeetingsList, + delSelectInconsistent, + getMeetingsList, + getSelectInconsistent +} from "@/api/innerReview/meetingReview"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null + }, + total: 0, + dataList: [], + companyList: [], + isAdmin: false +}); + +const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getSelectInconsistent(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = (path)=>{ + window.open(import.meta.env.VITE_APP_BASE_API + '/' + path) +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delSelectInconsistent({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditInput/components/editDialog.vue b/src/views/work/selfProblems/mngAudit/mngAuditInput/components/editDialog.vue new file mode 100644 index 0000000..d52c2db --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditInput/components/editDialog.vue @@ -0,0 +1,243 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year"> + <el-date-picker + v-model="state.form.year" + type="year" + value-format="YYYY" + placeholder="请选择年份" + /> + </el-form-item> + <el-form-item label="文件名称:" prop="reviewName"> + <el-input v-model.trim="state.form.reviewName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="文件:" prop="filePath"> + <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > + <el-button type="primary">点击上传</el-button> + <template #tip> + <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div> + </template> + </el-upload> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {saveStandardTemp, updateStandardTemp} from "@/api/standardSys/standardSys"; +import { + addMeetingsList, + addSelectInconsistent, addSelectMeetings, + updateMeetingsList, + updateSelectInconsistent, updateSelectMeetings +} from "@/api/innerReview/meetingReview"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + year: '', + reviewName: '', + filePath: '', + format: '', + companyId: null, + reviewType: 2 + }, + formRules:{ + year: [{ required: true, message: '请选择年份', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + reviewName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }], + filePath: [{ required: true, validator: checkFiles, trigger: 'blur' }] + }, + isAdmin: false, + companyList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + if(value.filePath) { + const obj = { + url: value.filePath, + name: '模板文件' + } + state.fileList = [obj] + } + } + dialogVisible.value = true +} + + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addSelectMeetings(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateSelectMeetings(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.filePath = res.data.path + state.form.format = '.' + res.data.filename.split('.')[1] + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.format = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + year: '', + reviewName: '', + filePath: '', + format: '', + companyId: null, + reviewType: 2 + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditInput/index.vue b/src/views/work/selfProblems/mngAudit/mngAuditInput/index.vue new file mode 100644 index 0000000..3670291 --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditInput/index.vue @@ -0,0 +1,216 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="reviewName" align="center"/> + <el-table-column label="年份" prop="year" align="center"/> + <el-table-column label="文件" align="center"> + <template #default="scope"> + <el-link type="primary" @click="openFile(scope.row.filePath)">{{scope.row.reviewName + scope.row.format}}</el-link> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row.filePath)">下载</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import { + delMeetingsList, + delSelectInconsistent, delSelectMeetings, + getMeetingsList, + getSelectInconsistent, getSelectMeetings +} from "@/api/innerReview/meetingReview"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + reviewType: 2 + }, + total: 0, + dataList: [], + companyList: [], + isAdmin: false +}); + +const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getSelectMeetings(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = (path)=>{ + window.open(import.meta.env.VITE_APP_BASE_API + '/' + path) +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null, + reviewType: 2 + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delSelectMeetings({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditMeeting/components/editDialog.vue b/src/views/work/selfProblems/mngAudit/mngAuditMeeting/components/editDialog.vue new file mode 100644 index 0000000..d7a9d31 --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditMeeting/components/editDialog.vue @@ -0,0 +1,243 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year"> + <el-date-picker + v-model="state.form.year" + type="year" + value-format="YYYY" + placeholder="请选择年份" + /> + </el-form-item> + <el-form-item label="文件名称:" prop="reviewName"> + <el-input v-model.trim="state.form.reviewName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="文件:" prop="filePath"> + <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > + <el-button type="primary">点击上传</el-button> + <template #tip> + <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div> + </template> + </el-upload> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {saveStandardTemp, updateStandardTemp} from "@/api/standardSys/standardSys"; +import { + addMeetingsList, + addSelectInconsistent, addSelectMeetings, + updateMeetingsList, + updateSelectInconsistent, updateSelectMeetings +} from "@/api/innerReview/meetingReview"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + year: '', + reviewName: '', + filePath: '', + format: '', + companyId: null, + reviewType: 1 + }, + formRules:{ + year: [{ required: true, message: '请选择年份', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + reviewName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }], + filePath: [{ required: true, validator: checkFiles, trigger: 'blur' }] + }, + isAdmin: false, + companyList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + if(value.filePath) { + const obj = { + url: value.filePath, + name: '模板文件' + } + state.fileList = [obj] + } + } + dialogVisible.value = true +} + + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addSelectMeetings(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateSelectMeetings(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.filePath = res.data.path + state.form.format = '.' + res.data.filename.split('.')[1] + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.format = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + year: '', + reviewName: '', + filePath: '', + format: '', + companyId: null, + reviewType: 1 + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditMeeting/index.vue b/src/views/work/selfProblems/mngAudit/mngAuditMeeting/index.vue new file mode 100644 index 0000000..164d1d1 --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditMeeting/index.vue @@ -0,0 +1,216 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="reviewName" align="center"/> + <el-table-column label="年份" prop="year" align="center"/> + <el-table-column label="文件" align="center"> + <template #default="scope"> + <el-link type="primary" @click="openFile(scope.row.filePath)">{{scope.row.reviewName + scope.row.format}}</el-link> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row.filePath)">下载</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import { + delMeetingsList, + delSelectInconsistent, delSelectMeetings, + getMeetingsList, + getSelectInconsistent, getSelectMeetings +} from "@/api/innerReview/meetingReview"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + reviewType: 1 + }, + total: 0, + dataList: [], + companyList: [], + isAdmin: false +}); + +const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getSelectMeetings(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = (path)=>{ + window.open(import.meta.env.VITE_APP_BASE_API + '/' + path) +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null, + reviewType: 1 + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delSelectMeetings({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditPlan/components/editDialog.vue b/src/views/work/selfProblems/mngAudit/mngAuditPlan/components/editDialog.vue new file mode 100644 index 0000000..eb0eb45 --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditPlan/components/editDialog.vue @@ -0,0 +1,386 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable @change="getCompanyUser"> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year"> + <el-date-picker + v-model="state.form.year" + type="year" + value-format="YYYY" + placeholder="请选择年份" + /> + </el-form-item> + <el-form-item label="编号:" prop="number"> + <el-input v-model.trim="state.form.number" :readonly="state.title =='查看'" placeholder="编号"></el-input> + </el-form-item> + <el-form-item label="评审目的:" prop="objective"> + <el-input v-model.trim="state.form.objective" type="textarea" :readonly="state.title =='查看'" :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-form-item label="评审内容:" prop="content"> + <el-input v-model.trim="state.form.content" type="textarea" :readonly="state.title =='查看'" :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-form-item label="评审时间、地点及方式:" prop="location"> + <el-input v-model.trim="state.form.location" type="textarea" :readonly="state.title =='查看'" :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-form-item label="参与评审人员:" prop="staff"> + <el-input v-model.trim="state.form.staff" type="textarea" :readonly="state.title =='查看'" :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-form-item label="管理评审输入报告:" prop="report"> + <el-input v-model.trim="state.form.report" type="textarea" :readonly="state.title =='查看'" :autosize="{ minRows: 2 }"></el-input> + </el-form-item> + <el-row> + <el-col :sm="24" :md="12"> + <el-form-item label="编制:" prop="fictionId"> + <el-select clearable v-model="state.form.fictionId" :disabled="state.title =='查看'" filterable placeholder="编制" style="width: 100%"> + <el-option + v-for="item in state.userList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :sm="24" :md="12"> + <el-form-item label="日期:" prop="fictionTime"> + <el-date-picker + v-model="state.form.fictionTime" + type="date" + value-format="YYYY-MM-DD" + placeholder="请选择编制日期" + /> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :sm="24" :md="12"> + <el-form-item label="审核:" prop="checkId"> + <el-select clearable v-model="state.form.checkId" :disabled="state.title =='查看'" filterable placeholder="审核" style="width: 100%"> + <el-option + v-for="item in state.userList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :sm="24" :md="12"> + <el-form-item label="日期:" prop="checkTime"> + <el-date-picker + v-model="state.form.checkTime" + type="date" + value-format="YYYY-MM-DD" + placeholder="请选择审核日期" + /> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :sm="24" :md="12"> + <el-form-item label="批准:" prop="ratifyId"> + <el-select clearable v-model="state.form.ratifyId" :disabled="state.title =='查看'" filterable placeholder="批准" style="width: 100%"> + <el-option + v-for="item in state.userList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :sm="24" :md="12"> + <el-form-item label="日期:" prop="ratifyTime"> + <el-date-picker + v-model="state.form.ratifyTime" + type="date" + value-format="YYYY-MM-DD" + placeholder="请选择批准日期" + /> + </el-form-item> + </el-col> + </el-row> +<!-- <el-form-item label="文件:" prop="filePath">--> +<!-- <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" >--> +<!-- <el-button type="primary">点击上传</el-button>--> +<!-- <template #tip>--> +<!-- <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div>--> +<!-- </template>--> +<!-- </el-upload>--> +<!-- </el-form-item>--> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {saveStandardTemp, updateStandardTemp} from "@/api/standardSys/standardSys"; +import { + addManagementPlan, + addMeetingsList, + addSelectInconsistent, updateManagementPlan, + updateMeetingsList, + updateSelectInconsistent +} from "@/api/innerReview/meetingReview"; +import {listUser} from "@/api/system/user"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + year: '', + number: '', + objective: '', + content: '', + location: '', + staff: '', + report: '', + fictionId: null, + fictionName: '', + fictionTime: '', + checkId: null, + checkName: '', + checkTime: '', + ratifyId: null, + ratifyName: '', + ratifyTime: '', + companyId: null + }, + formRules:{ + year: [{ required: true, message: '请选择年份', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + number: [{ required: true, message: '请输入编号', trigger: 'blur' }], + objective: [{ required: true, message: '请输入评审目的', trigger: 'blur' }], + content: [{ required: true, message: '请输入评审内容', trigger: 'blur' }], + location: [{ required: true, message: '请输入评审时间、地点及方式', trigger: 'blur' }], + staff: [{ required: true, message: '请输入参与评审人员', trigger: 'blur' }], + report: [{ required: true, message: '请输入管理评审输入报告', trigger: 'blur' }], + fictionId: [{ required: true, message: '请选择编制人员', trigger: 'blur' }], + fictionTime: [{ required: true, message: '请选择编制时间', trigger: 'blur' }], + checkId: [{ required: true, message: '请选择审核人员', trigger: 'blur' }], + checkTime: [{ required: true, message: '请选择审核时间', trigger: 'blur' }], + ratifyId: [{ required: true, message: '请选择批准人员', trigger: 'blur' }], + ratifyTime: [{ required: true, message: '请选择批准时间', trigger: 'blur' }], + }, + isAdmin: false, + companyList: [], + userList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + await getUserList(companyId) + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + console.log(state.form,'form1') + // if(value.filePath) { + // const obj = { + // url: value.filePath, + // name: '模板文件' + // } + // state.fileList = [obj] + // } + } + dialogVisible.value = true +} + +const getCompanyUser = async (value)=>{ + state.form.fictionId = null + state.form.checkId = null + state.form.ratifyId = null + state.form.fictionName = '' + state.form.checkName = '' + state.form.ratifyName = '' + await getUserList(value) +} + +const getUserList = async (companyId)=> { + const res = await listUser({pageIndex: 1,pageSize: 999, companyId: companyId}) + if(res.code == 200){ + state.userList = res.data.list?res.data.list:[] + }else{ + ElMessage.warning(res.message) + } +} + +const onSubmit = async () => { + console.log(state.form,'form2') + const valid = await superRef.value.validate(); + if(valid){ + state.form.fictionName = state.userList.find(i=>i.id == state.form.fictionId)?.name + state.form.checkName = state.userList.find(i=>i.id == state.form.checkId)?.name + state.form.ratifyName = state.userList.find(i=>i.id == state.form.ratifyId)?.name + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addManagementPlan(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateManagementPlan(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.filePath = res.data.path + state.form.format = '.' + res.data.filename.split('.')[1] + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.format = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + year: '', + number: '', + objective: '', + content: '', + location: '', + staff: '', + report: '', + fictionId: null, + fictionTime: '', + checkId: null, + checkTime: '', + ratifyId: null, + ratifyTime: '', + companyId: null + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditPlan/index.vue b/src/views/work/selfProblems/mngAudit/mngAuditPlan/index.vue new file mode 100644 index 0000000..4df1a4b --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditPlan/index.vue @@ -0,0 +1,244 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item v-if="isAdmin" label="年份:" > + <el-select v-model="data.queryParams.year" placeholder="请选择" clearable> + <el-option + v-for="item in yearList" + :key="item.value" + :label="item.label" + :value="item.value"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="year" align="center"> + <template #default="scope"> + {{scope.row.year + '年管理评审计划'}} + </template> + </el-table-column> + <el-table-column label="年份" prop="year" align="center"/> +<!-- <el-table-column label="文件" align="center">--> +<!-- <template #default="scope">--> +<!-- <el-link type="primary" @click="openFile(scope.row.filePath)">{{scope.row.inconsistentName + scope.row.format}}</el-link>--> +<!-- </template>--> +<!-- </el-table-column>--> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row)">导出</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import { + delManagementPlan, + delMeetingsList, + delSelectInconsistent, getInternalAuditCheckInfo, getManagementPlan, + getMeetingsList, + getSelectInconsistent +} from "@/api/innerReview/meetingReview"; +import {generateWordDocument} from "@/utils/exportWord"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null + }, + total: 0, + dataList: [], + companyList: [], + yearList: Array.from({ length: 51 }, (_, index) => { + const year = new Date().getFullYear() - index; + return { + label: `${year}年`, + value: year.toString() + }; + }), + isAdmin: false +}); + +const { queryParams, total, dataList,companyList,yearList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getManagementPlan(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = (data)=>{ + try { + generateWordDocument('/reviewPlan.docx', data, data.year +'年管理评审计划.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delManagementPlan({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditReport/components/editDialog.vue b/src/views/work/selfProblems/mngAudit/mngAuditReport/components/editDialog.vue new file mode 100644 index 0000000..62ac746 --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditReport/components/editDialog.vue @@ -0,0 +1,243 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="700px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year"> + <el-date-picker + v-model="state.form.year" + type="year" + value-format="YYYY" + placeholder="请选择年份" + /> + </el-form-item> + <el-form-item label="文件名称:" prop="reviewName"> + <el-input v-model.trim="state.form.reviewName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="文件:" prop="filePath"> + <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > + <el-button type="primary">点击上传</el-button> + <template #tip> + <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div> + </template> + </el-upload> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {saveStandardTemp, updateStandardTemp} from "@/api/standardSys/standardSys"; +import { + addMeetingsList, + addSelectInconsistent, addSelectMeetings, + updateMeetingsList, + updateSelectInconsistent, updateSelectMeetings +} from "@/api/innerReview/meetingReview"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + year: '', + reviewName: '', + filePath: '', + format: '', + companyId: null, + reviewType: 3 + }, + formRules:{ + year: [{ required: true, message: '请选择年份', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + reviewName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }], + filePath: [{ required: true, validator: checkFiles, trigger: 'blur' }] + }, + isAdmin: false, + companyList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + if(value.filePath) { + const obj = { + url: value.filePath, + name: '模板文件' + } + state.fileList = [obj] + } + } + dialogVisible.value = true +} + + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addSelectMeetings(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateSelectMeetings(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.filePath = res.data.path + state.form.format = '.' + res.data.filename.split('.')[1] + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.format = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + year: '', + reviewName: '', + filePath: '', + format: '', + companyId: null, + reviewType: 3 + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/mngAudit/mngAuditReport/index.vue b/src/views/work/selfProblems/mngAudit/mngAuditReport/index.vue new file mode 100644 index 0000000..4f3e74a --- /dev/null +++ b/src/views/work/selfProblems/mngAudit/mngAuditReport/index.vue @@ -0,0 +1,216 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="reviewName" align="center"/> + <el-table-column label="年份" prop="year" align="center"/> + <el-table-column label="文件" align="center"> + <template #default="scope"> + <el-link type="primary" @click="openFile(scope.row.filePath)">{{scope.row.reviewName + scope.row.format}}</el-link> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row.filePath)">下载</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys"; +import { renderAsync } from "docx-preview"; +import { + delMeetingsList, + delSelectInconsistent, delSelectMeetings, + getMeetingsList, + getSelectInconsistent, getSelectMeetings +} from "@/api/innerReview/meetingReview"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + reviewType: 3 + }, + total: 0, + dataList: [], + companyList: [], + isAdmin: false +}); + +const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getSelectMeetings(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = (path)=>{ + window.open(import.meta.env.VITE_APP_BASE_API + '/' + path) +} + +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank'); + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null, + reviewType: 3 + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delSelectMeetings({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> -- Gitblit v1.9.2