| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item prop="processLeaderName" label="过程控制负责人"> |
| | | <el-form-item prop="processLeader.name" label="过程控制负责人"> |
| | | <el-input |
| | | v-model="state.formData.processLeaderName" |
| | | v-model="state.formData.processLeader.name" |
| | | size="large" |
| | | placeholder="请选择过程控制负责人" |
| | | @focus="openExperts('过程控制负责人')" |
| | | > |
| | | <template #append> |
| | | <el-button :icon="Search" @click="openExperts('过程控制负责人')"/> |
| | |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-col :span="6"> |
| | | <el-form-item prop="isFullProcess" label="审核结论:是否满足过程控制要求"> |
| | | <el-radio-group v-model="state.formData.isFullProcess" > |
| | | <el-radio :label="1">是</el-radio> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="6"> |
| | | <el-form-item > |
| | | <el-upload accept=".pdf,.doc,.docx" |
| | | :action="state.uploadUrl" |
| | | :disabled="state.disabled" |
| | | :headers="state.header" |
| | | method="post" |
| | | :on-success="handleAvatarSuccess" |
| | | v-model:file-list="state.fileList" |
| | | :on-remove="handleRemove" |
| | | :data="state.uploadData" |
| | | :on-preview="handlePreview" |
| | | > |
| | | <el-button type="primary">附件上传</el-button> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-table :data="state.tableData" :border="true" style="margin-bottom: 20px"> |
| | | <el-table :data="state.tableData" :border="true" style="margin: 20px 0"> |
| | | <el-table-column label="序号" width="60" align="center" type="index"></el-table-column> |
| | | <el-table-column label="过程控制关键点" prop="content" header-align="center" :show-overflow-tooltip="true"/> |
| | | <el-table-column label="审核结果" header-align="center" class-name="small-padding fixed-width" width="175"> |
| | | <template #default="scope"> |
| | | <el-radio-group v-model="scope.row.status" @change="changeRadio(scope.row)" > |
| | | <el-radio-group v-model="scope.row.status" > |
| | | <el-radio :label="1">符合</el-radio> |
| | | <el-radio :label="0">不符合</el-radio> |
| | | </el-radio-group> |
| | |
| | | <el-table-column label="不符合描述" header-align="center" class-name="small-padding fixed-width" width="700"> |
| | | <template #default="scope"> |
| | | <el-input |
| | | v-model="scope.row.des" |
| | | v-model="scope.row.reason" |
| | | size="large" |
| | | :disabled="scope.row.status === 1" |
| | | :disabled="scope.row.status == 1" |
| | | placeholder="如不符合,请填写不符合描述" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-form-item prop="technology" label="存在问题及建议"> |
| | | <el-form-item prop="suggestions" label="存在问题及建议"> |
| | | <el-input |
| | | v-model="state.formData.suggestions" |
| | | :autosize="{ minRows: 6 }" |
| | |
| | | type="textarea"> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="18"> |
| | | <el-form-item label="附件上传" prop="assAccessoryFiles"> |
| | | <el-upload accept="image/*,.pdf,.doc,.docx,.xlsx,.xls" :action="state.uploadUrl" :data="{moduleType: 8,projectId: props.projectId}" :headers="state.header" method="post" :on-success="handleAvatarSuccess" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="handleRemove" :before-remove="beforeRemove"> |
| | | <el-button type="primary">附件上传</el-button> |
| | | <template #tip> |
| | | <div class="el-upload__tip">上传文件尺寸小于5M,最多可上传1份</div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <el-dialog v-model="state.dialogImg"> |
| | | <el-image style="width: 100%; height: 100%" :src="state.dialogImageUrl"/> |
| | |
| | | <script setup> |
| | | |
| | | import {defineEmits, onMounted, reactive, ref} from "vue"; |
| | | import {ElMessage} from "element-plus"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import {Search} from '@element-plus/icons-vue' |
| | | import { |
| | | addProcessAudit, |
| | | addRisk, editProcessAudit, |
| | | editRisk, |
| | | getProcessAuditDetail, |
| | | getRiskDetail |
| | | } from "@/api/projectManage/riskAnalysis" |
| | | import {delFile, getFiles} from "@/api/projectManage/siteCheckRcd" |
| | | import {addProcessCtrl, editProcessCtrl,getProcessCtrlDetail} from "@/api/projectManage/processCtrl" |
| | | import {delPic} from "@/api/login" |
| | | import { getToken } from "@/utils/auth"; |
| | | import Cookies from "js-cookie" |
| | | import ExpertsList from "./expertsList"; |
| | | import axios from "axios"; |
| | | import {delAccessoryFile, getAccessoryFile} from "@/api/projectManage/project"; |
| | | const props = defineProps(['projectId']) |
| | | const emit = defineEmits(["getNextStatus"]); |
| | | |
| | | const state = reactive({ |
| | | formData: { |
| | | id: '', |
| | | id: null, |
| | | projectId: null, |
| | | auditDate: '', |
| | | processLeaderId: '', |
| | | processLeaderName: '', |
| | | isFullProcess: 1, |
| | | processLeader: {name: ''}, |
| | | processLeaderId: null, |
| | | isFullProcess: null, |
| | | suggestions: '' |
| | | }, |
| | | rules: { |
| | | auditDate: [{required: true, message: '请选择审核日期', trigger: 'blur'}], |
| | | processLeaderName: [{required: true, message: '请选择过程控制负责人', trigger: 'change'}], |
| | | 'processLeader.name': [{required: true, message: '请选择过程控制负责人', trigger: 'change'}], |
| | | isFullProcess: [{required: true, message: '请选择审核结论', trigger: 'blur'}] |
| | | }, |
| | | tableData: [ |
| | | {id: 1, content: '风险分析', status: 1, des: ''}, |
| | | {id: 2, content: '签订合同', status: 1, des: ''}, |
| | | {id: 3, content: '评价任务通知书', status: 1, des: ''}, |
| | | {id: 4, content: '编制安全评价项目计划书', status: 1, des: ''}, |
| | | {id: 5, content: '被评价单位提供材料清单', status: 1, des: ''}, |
| | | {id: 6, content: '从业告知', status: 1, des: ''}, |
| | | {id: 7, content: '现场勘验记录及影像资料', status: 1, des: ''}, |
| | | {id: 8, content: '评价报告内部审核', status: 1, des: ''}, |
| | | {id: 9, content: '技术负责人审核', status: 1, des: ''}, |
| | | {id: 10, content: '评价报告外审意见', status: 1, des: ''}, |
| | | {id: 11, content: '评价项目网上信息公开', status: 1, des: ''}, |
| | | {id: 12, content: '二维码的使用', status: 1, des: ''}, |
| | | {id: 13, content: '报告归档材料完整性', status: 1, des: ''}, |
| | | {id: 1, content: '风险分析', status: 1, key:'isRiskAnalyse', reasonKey: 'riskAnalyseDes', reason: ''}, |
| | | {id: 2, content: '签订合同', status: 1, key:'isSignContract', reasonKey: 'signContractDes', reason: ''}, |
| | | {id: 3, content: '评价任务通知书', status: 1, key:'isEstimateTask', reasonKey: 'estimateTaskDes', reason: ''}, |
| | | {id: 4, content: '编制安全评价项目计划书', status: 1, key:'isEstimatePlan', reasonKey: 'estimatePlanDes', reason: ''}, |
| | | {id: 5, content: '被评价单位提供材料清单', status: 1, key:'isProvideMaterials', reasonKey: 'provideMaterialsDes', reason: ''}, |
| | | {id: 6, content: '从业告知', status: 1, key:'isWorkNotification', reasonKey: 'workNotificationDes', reason: ''}, |
| | | {id: 7, content: '现场勘验记录及影像资料', status: 1, key:'isInvestigationSite', reasonKey: 'investigationSiteDes', reason: ''}, |
| | | {id: 8, content: '评价报告内部审核', status: 1, key:'isInteriorAudit', reasonKey: 'interiorAuditDes', reason: ''}, |
| | | {id: 9, content: '技术负责人审核', status: 1, key:'isTechnolgyAudit', reasonKey: 'technolgyAuditDes', reason: ''}, |
| | | {id: 6, content: '评价报告外审意见', status: 1, key:'isExteriorAudit', reasonKey: 'exteriorAuditDes', reason: ''}, |
| | | {id: 7, content: '评价项目网上信息公开', status: 1, key:'isOpenInformation', reasonKey: 'openInformationDes', reason: ''}, |
| | | {id: 8, content: '二维码的使用', status: 1, key:'isUseQrcode', reasonKey: 'useQrcodeDes', reason: ''}, |
| | | {id: 9, content: '报告归档材料完整性', status: 1, key:'isFullMaterials', reasonKey: 'fullMaterialsDes', reason: ''} |
| | | ], |
| | | imgLimit: 1, |
| | | uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile', |
| | | header: { |
| | | Authorization: getToken() |
| | | }, |
| | | dialogImageUrl: '', |
| | | dialogImg: false, |
| | | uploadData: { |
| | | moduleType: 8 |
| | | }, |
| | | disabled: false, |
| | | fileList: [] |
| | | } |
| | | }) |
| | | const props = { |
| | | expandTrigger: 'hover', |
| | | value: 'name', |
| | | label: 'name' |
| | | } |
| | | |
| | | const isAmin = ref(false) |
| | | const formRef = ref() |
| | | const expertsListRef = ref() |
| | |
| | | if(userInfo.identity === 0){ |
| | | isAmin.value = true; |
| | | } |
| | | if(Cookies.get('projectId')){ |
| | | const val = Cookies.get('projectId'); |
| | | state.uploadData.projectId = val; |
| | | const res = getAccessoryFile({projectId: val,moduleType: 8}); |
| | | if(res.code == 200){ |
| | | if(res.data){ |
| | | state.fileList = res.data.accessoryFiles.map(item => { |
| | | return { |
| | | ...item, |
| | | name: item.originName, |
| | | } |
| | | }) |
| | | }else { |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | } |
| | | getProcessFiles(props.projectId) |
| | | }) |
| | | |
| | | const riskOpen = async (type,val) => { |
| | | state.uploadData.projectId = val; |
| | | state.formData.projectId = val |
| | | if(type === 'detail' || type === 'edit' ){ |
| | | const res = await getProcessAuditDetail({projectId: val}); |
| | | if(res.code == 200 ){ |
| | | if(res.data){ |
| | | state.formData = res.data; |
| | | state.fileList = res.data.accessoryFiles.map(item => { |
| | | return { |
| | | ...item, |
| | | name: item.originName, |
| | | const res = await getProcessCtrlDetail({projectId: val}); |
| | | if(res.code == 200){ |
| | | state.formData = res.data |
| | | state.formData.isFullProcess = res.data.isFullProcess==true?1:0 |
| | | for(let key in res.data){ |
| | | for(let item of state.tableData){ |
| | | if(item.key == key){ |
| | | item.status = res.data[key]==true?1:0 |
| | | } |
| | | }) |
| | | state.formData.processLeaderName = res.data.processLeader.name; |
| | | state.formData.isFullProcess = res.data.isFullProcess ? 1 : 0; |
| | | state.tableData[0].status = res.data.isRiskAnalyse ? 1 : 0; |
| | | state.tableData[0].des = res.data.riskAnalyseDes; |
| | | state.tableData[1].status = res.data.isSignContract ? 1 : 0; |
| | | state.tableData[1].des = res.data.signContractDes; |
| | | state.tableData[2].status = res.data.isEstimateTask ? 1 : 0; |
| | | state.tableData[2].des = res.data.estimateTaskDes; |
| | | state.tableData[3].status = res.data.isEstimatePlan ? 1 : 0; |
| | | state.tableData[3].des = res.data.estimatePlanDes; |
| | | state.tableData[4].status = res.data.isProvideMaterials ? 1 : 0; |
| | | state.tableData[4].des = res.data.provideMaterialsDes; |
| | | state.tableData[5].status = res.data.isWorkNotification ? 1 : 0; |
| | | state.tableData[5].des = res.data.workNotificationDes; |
| | | state.tableData[6].status = res.data.isInvestigationSite ? 1 : 0; |
| | | state.tableData[6].des = res.data.investigationSiteDes; |
| | | state.tableData[7].status = res.data.isInteriorAudit ? 1 : 0; |
| | | state.tableData[7].des = res.data.interiorAuditDes; |
| | | state.tableData[8].status = res.data.isTechnolgyAudit ? 1 : 0; |
| | | state.tableData[8].des = res.data.technolgyAuditDes; |
| | | state.tableData[9].status = res.data.isExteriorAudit ? 1 : 0; |
| | | state.tableData[9].des = res.data.exteriorAuditDes; |
| | | state.tableData[10].status = res.data.isOpenInformation ? 1 : 0; |
| | | state.tableData[10].des = res.data.openInformationDes; |
| | | state.tableData[11].status = res.data.isUseQrcode ? 1 : 0; |
| | | state.tableData[11].des = res.data.useQrcodeDes; |
| | | state.tableData[12].status = res.data.isFullMaterials ? 1 : 0; |
| | | state.tableData[12].des = res.data.fullMaterialsDes; |
| | | if(item.reasonKey == key){ |
| | | item.reason = res.data[key] |
| | | } |
| | | } |
| | | } |
| | | }else { |
| | | ElMessage.warning(res.message) |
| | |
| | | ElMessage.warning("当前用户暂无权限"); |
| | | return; |
| | | } |
| | | state.formData.isRiskAnalyse = state.tableData[0].status; |
| | | state.formData.riskAnalyseDes = state.tableData[0].des; |
| | | state.formData.isSignContract = state.tableData[1].status; |
| | | state.formData.signContractDes = state.tableData[1].des; |
| | | state.formData.isEstimateTask = state.tableData[2].status; |
| | | state.formData.estimateTaskDes = state.tableData[2].des; |
| | | state.formData.isEstimatePlan = state.tableData[3].status; |
| | | state.formData.estimatePlanDes = state.tableData[3].des; |
| | | state.formData.isProvideMaterials = state.tableData[4].status; |
| | | state.formData.provideMaterialsDes = state.tableData[4].des; |
| | | state.formData.isWorkNotification = state.tableData[5].status; |
| | | state.formData.workNotificationDes = state.tableData[5].des; |
| | | state.formData.isInvestigationSite = state.tableData[6].status; |
| | | state.formData.investigationSiteDes = state.tableData[6].des; |
| | | state.formData.isInteriorAudit = state.tableData[7].status; |
| | | state.formData.interiorAuditDes = state.tableData[7].des; |
| | | state.formData.isTechnolgyAudit = state.tableData[8].status; |
| | | state.formData.technolgyAuditDes = state.tableData[8].des; |
| | | state.formData.isExteriorAudit = state.tableData[9].status; |
| | | state.formData.exteriorAuditDes = state.tableData[9].des; |
| | | state.formData.isOpenInformation = state.tableData[10].status; |
| | | state.formData.openInformationDes = state.tableData[10].des; |
| | | state.formData.isUseQrcode = state.tableData[11].status; |
| | | state.formData.useQrcodeDes = state.tableData[11].des; |
| | | state.formData.isFullMaterials = state.tableData[12].status; |
| | | state.formData.fullMaterialsDes = state.tableData[12].des; |
| | | if(type === 'add'){ |
| | | const {id,processLeaderName, ...data} = JSON.parse(JSON.stringify(state.formData)) |
| | | data.projectId = val; |
| | | console.log("auditData",data) |
| | | const res = await addProcessAudit(data); |
| | | const {id,processLeader, ...data} = JSON.parse(JSON.stringify(state.formData)) |
| | | for(let i of state.tableData){ |
| | | if(i.status == 1){ |
| | | i.reason = '' |
| | | }else{ |
| | | if(i.reason == ''){ |
| | | ElMessage.warning("请完善不符合项描述"); |
| | | return |
| | | } |
| | | } |
| | | data[i.key] = i.status |
| | | data[i.reasonKey] = i.reason |
| | | } |
| | | const res = await addProcessCtrl(data); |
| | | if (res.code == 200) { |
| | | ElMessage.success('保存成功') |
| | | formRef.value.clearValidate(); |
| | |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }else if(type === 'clickEdit'){ |
| | | const { ...data} = JSON.parse(JSON.stringify(state.formData)) |
| | | const res = await editProcessAudit(data); |
| | | const {processLeader, ...data} = JSON.parse(JSON.stringify(state.formData)) |
| | | for(let i of state.tableData){ |
| | | data[i.key] = i.status |
| | | data[i.reasonKey] = i.reason |
| | | if(i.status == 1){ |
| | | i.reason = '' |
| | | } |
| | | } |
| | | const res = await editProcessCtrl(data); |
| | | if (res.code == 200) { |
| | | ElMessage.success('变更成功') |
| | | formRef.value.clearValidate(); |
| | |
| | | } |
| | | |
| | | const getSelected = (type,obj)=>{ |
| | | state.formData.processLeaderName = obj.name |
| | | state.formData.processLeader.name = obj.name |
| | | state.formData.processLeaderId = obj.id |
| | | } |
| | | |
| | | const handleAvatarSuccess = (res) => { |
| | | if(res.code === 200){ |
| | | console.log("if",state.fileList) |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '文件上传成功' |
| | | }) |
| | | const getProcessFiles = async (id)=>{ |
| | | const res = await getFiles({projectId: id ? id : props.projectId,moduleType: 8}) |
| | | if(res.code == 200){ |
| | | if(res.data && res.data.length>0){ |
| | | state.fileList = res.data.map(i=>{ |
| | | return { |
| | | name: i.fileName, |
| | | url: import.meta.env.VITE_APP_BASE_API + '/' + i.path, |
| | | id: i.id, |
| | | projectId: i.projectId, |
| | | moduleType: i.moduleType |
| | | } |
| | | }) |
| | | }else{ |
| | | state.fileList = [] |
| | | } |
| | | }else { |
| | | ElMessage.warning(res.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 handlePictureCardPreview = (uploadFile) => { |
| | | axios.get(uploadFile.url,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{ |
| | | if (res) { |
| | | const link = document.createElement('a') |
| | | let blob = new Blob([res.data],{type: res.data.type}) |
| | | link.style.display = "none"; |
| | | link.href = URL.createObjectURL(blob); // 创建URL |
| | | window.open(link.href) |
| | | } else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件读取失败' |
| | | }); |
| | | } |
| | | }) |
| | | }; |
| | | |
| | | |
| | | const handleAvatarSuccess = (res, uploadFile) => { |
| | | if(res.code == 200){ |
| | | getProcessFiles() |
| | | }else{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件上传失败' |
| | | }) |
| | | } |
| | | } |
| | | const handlePreview = (file) => { |
| | | let path = ""; |
| | | if(file.path){ |
| | | path = file.path |
| | | }else { |
| | | path = file.response.data.path |
| | | |
| | | } |
| | | const url = import.meta.env.VITE_APP_BASE_API + '/' + path |
| | | axios.get( url,{ |
| | | headers: |
| | | { |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization':getToken(), |
| | | }, |
| | | responseType: 'blob' |
| | | } |
| | | ).then(res=>{ |
| | | if (res) { |
| | | const link = document.createElement('a') |
| | | let blob = new Blob([res.data],{type: res.data.type}) |
| | | link.style.display = "none"; |
| | | link.href = URL.createObjectURL(blob); // 创建URL |
| | | link.setAttribute("download", file.name); |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | } else { |
| | | this.$message.error('获取文件失败') |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const handleRemove = async (file, uploadFiles) => { |
| | | console.log("file",file) |
| | | let accessoryFileId = ""; |
| | | if(file.id){ |
| | | accessoryFileId = file.id |
| | | }else { |
| | | accessoryFileId = file.response.data.id |
| | | |
| | | } |
| | | const res = await delAccessoryFile(accessoryFileId) |
| | | if(res.code == 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '文件已删除' |
| | | }) |
| | | }else{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.message |
| | | }) |
| | | } |
| | | } |
| | | const changeRadio = (val) => { |
| | | if(val.status === 1 && val.des !== ''){ |
| | | state.tableData.forEach((item,index) => { |
| | | if(item.id === val.id){ |
| | | state.tableData[index].des = '' |
| | | } |
| | | }) |
| | | } |
| | | const handleRemove = async (file, uploadFile) => { |
| | | ElMessageBox.confirm( |
| | | '确定删除该附件?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await delFile(file.id) |
| | | if(res.code == 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '文件已删除' |
| | | }) |
| | | await getProcessFiles() |
| | | }else{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.message |
| | | }) |
| | | } |
| | | }) |
| | | .catch(()=>{ |
| | | getProcessFiles() |
| | | }) |
| | | } |
| | | |
| | | defineExpose({ |