feat(quality-monitor): 重构质量监控计划模块并集成检验任务流程
| | |
| | | // è´¨éçæ§è®¡å页é¢ç¸å
³æ¥å£ |
| | | import request from '@/utils/request' |
| | | |
| | | export function createAnnualPlan(data) { |
| | | return request({ url: '/qualityMonitor/createAnnualPlan', method: 'post', data }) |
| | | } |
| | | |
| | | export function getAnnualPlan(params) { |
| | | return request({ url: '/qualityMonitor/getAnnualPlan', method: 'get', params }) |
| | | } |
| | | |
| | | export function submitAnnualPlan(qualityMonitorId) { |
| | | return request({ url: '/qualityMonitor/submitAnnualPlan', method: 'post', data: { qualityMonitorId } }) |
| | | } |
| | | |
| | | export function dispatchInspectionTask(qualityMonitorDetailsId) { |
| | | return request({ url: '/qualityMonitor/dispatchInspectionTask', method: 'post', data: { qualityMonitorDetailsId } }) |
| | | } |
| | | |
| | | export function cancelInspectionTask(qualityMonitorDetailsId) { |
| | | return request({ url: '/qualityMonitor/cancelInspectionTask', method: 'post', data: { qualityMonitorDetailsId } }) |
| | | } |
| | | |
| | | export function getInspectionEvaluation(qualityMonitorDetailsId) { |
| | | return request({ url: '/qualityMonitor/getInspectionEvaluation', method: 'get', params: { qualityMonitorDetailsId } }) |
| | | } |
| | | |
| | | export function submitInspectionEvaluation(data) { |
| | | return request({ url: '/qualityMonitor/submitInspectionEvaluation', method: 'post', data }) |
| | | } |
| | | |
| | | export function approveInspectionEvaluation(data) { |
| | | return request({ url: '/qualityMonitor/approveInspectionEvaluation', method: 'post', data }) |
| | | } |
| | | |
| | | // çæ§å¹´åº¦è®¡åå表 |
| | | export function pageQualityMonitor(query) { |
| | | return request({ |
| | |
| | | }) |
| | | } |
| | | |
| | | // æå½åæé设å¤å®æ¶è¯»åæ ¡åè¯ä¹¦ |
| | | export function getCurrentCalibrationFiles(query) { |
| | | return request({ |
| | | url: '/processMethodVerify/getCurrentCalibrationFiles', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹æ åæ¹æ³éªè¯ |
| | | export function updateMethodVerify(data) { |
| | | return request({ |
| | |
| | | :label="item.label" |
| | | :prop="item.prop" |
| | | :show-overflow-tooltip="item.dataType === 'action' || item.dataType === 'slot' ? false : true" |
| | | :min-width="columnWidth(item)" |
| | | :min-width="columnMinWidth(item)" |
| | | :sortable="item.sortable ? true : false" |
| | | :type="item.type" |
| | | :width="columnWidth(item)" |
| | |
| | | }) |
| | | |
| | | function columnWidth(item) { |
| | | if (item.minWidth) return undefined |
| | | return item.dataType === 'action' ? actionColumnWidth.value : item.width |
| | | } |
| | | |
| | | // é
ç½® minWidth æ¶åªçº¦ææå°å®½åº¦ï¼æå©ä½ç©ºé´äº¤ç» Element Plus èªå¨åé
ã |
| | | // æªé
ç½® minWidth çæ§é¡µé¢ç»§ç»æ²¿ç¨åæåºå® width è¡ä¸ºã |
| | | function columnMinWidth(item) { |
| | | if (item.minWidth) return item.minWidth |
| | | return item.dataType === 'action' ? actionColumnWidth.value : item.width |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog title="ç¼è¾" v-model="formDia" |
| | | <el-dialog :title="operationType === 'add' ? 'æ°å¢è´¨æ§é¡¹ç®' : 'ç¼è¾è´¨æ§é¡¹ç®'" v-model="formDia" |
| | | :close-on-click-modal="false" |
| | | :close-on-press-escape="false" |
| | | width="80%" @close="closeDia"> |
| | | <el-form :model="form" :rules="rules" ref="form" label-width="140px"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="çæ§ç®ç" prop="monitorPurpose"> |
| | | <el-input v-model="form.monitorPurpose" size="small" clearable></el-input> |
| | | <el-form-item label="åºå·" prop="sortNo"> |
| | | <el-input-number v-model="form.sortNo" :min="1" style="width:100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="计åå¼å±æ¶é´" prop="plannedTime"> |
| | | <el-input v-model="form.plannedTime" size="small" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="çæ§é¡¹ç®" prop="monitorProject"> |
| | | <el-form-item label="è´¨æ§é¡¹ç®" prop="monitorProject"> |
| | | <el-input v-model="form.monitorProject" size="small" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åå åä½ï¼äººåï¼" prop="participant"> |
| | | <el-input v-model="form.participant" size="small" clearable></el-input> |
| | | <el-form-item label="ææ¯æ å" prop="technicalStandardText"> |
| | | <el-input v-model="form.technicalStandardText" size="small" clearable placeholder="æ åç¼å·ååç§°ï¼éæ£æµç±»å¯å¡«åç¨åºæä»¶æ/" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¢ç®ï¼å
ï¼" prop="budget"> |
| | | <el-input v-model="form.budget" size="small" clearable></el-input> |
| | | <el-form-item label="è´¨æ§æ¹å¼" prop="monitorWay"> |
| | | <el-input v-model="form.monitorWay" size="small" clearable placeholder="å¦ç²æ ·æ£æµãäººåæ¯å¯¹ãçç£æ£æ¥" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»ç»äººå" prop="organization"> |
| | | <el-input v-model="form.organization" size="small" clearable></el-input> |
| | | <el-form-item label="宿æ¶é" prop="completionMonth"> |
| | | <el-date-picker v-model="form.completionMonth" type="month" value-format="YYYY-MM" format="YYYY.MM" style="width:100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="çæ§æ¹å¼" prop="monitorWay"> |
| | | <el-input v-model="form.monitorWay" size="small" clearable></el-input> |
| | | <el-form-item label="è´è´£äºº" prop="responsibleUserId"> |
| | | <el-select v-model="form.responsibleUserId" filterable style="width:100%"> |
| | | <el-option v-for="item in userOptions" :key="item.id" :value="item.id" :label="item.name" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="äºé¡¹ç±»å«" prop="itemKind"> |
| | | <el-select v-model="form.itemKind" style="width: 100%"> |
| | | <el-option label="鿣æµç±»" value="OTHER" /> |
| | | <el-option label="æ£æµç±»" value="INSPECTION" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <template v-if="form.itemKind === 'INSPECTION'"> |
| | | <el-col :span="12"><el-form-item label="æ£æµæ å" prop="standardMethodId"> |
| | | <el-select v-model="form.standardMethodId" filterable style="width: 100%" placeholder="è¯·éæ©æ£æµæ å" @change="handleStandardChange"> |
| | | <el-option v-for="item in standardOptions" :key="item.id" :value="item.id" :label="`${item.code || ''} ${item.name || ''}`" /> |
| | | </el-select> |
| | | </el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="åå§è®°å½æ¨¡æ¿" prop="templateIds"> |
| | | <el-select v-model="form.templateIds" multiple collapse-tags filterable style="width: 100%" placeholder="å¯éæ©å¤ä¸ªæ¨¡æ¿"> |
| | | <el-option v-for="item in templateOptions" :key="item.id" :value="item.id" :label="item.name" /> |
| | | </el-select> |
| | | </el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="æ ·ååç§°"><el-input v-model="form.sampleName" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="æ ·åè§æ ¼"><el-input v-model="form.sampleSpec" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="æ£æµå"><el-select v-model="form.inspectorUserId" filterable style="width: 100%"> |
| | | <el-option v-for="item in userOptions" :key="item.id" :value="item.id" :label="item.name" /> |
| | | </el-select></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="è¯ä»·äºº"><el-select v-model="form.evaluatorUserId" filterable style="width: 100%"> |
| | | <el-option v-for="item in userOptions" :key="item.id" :value="item.id" :label="item.name" /> |
| | | </el-select></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="任塿ªæ¢æ¥"> |
| | | <el-date-picker v-model="form.dueDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" /> |
| | | </el-form-item></el-col> |
| | | </template> |
| | | </el-form> |
| | | <template #footer><span class="dialog-footer"> |
| | | <el-button @click="closeDia">å æ¶</el-button> |
| | |
| | | addQualityMonitorDetail, |
| | | updateQualityMonitorDetail |
| | | } from "@/api/cnas/process/ensureResults/qualityMonitor"; |
| | | import { selectStandardMethodList } from '@/api/cnas/process/method/standardMethod'; |
| | | import { selectStandardTemplatePageList } from '@/api/standard/model'; |
| | | import { selectUserCondition } from '@/api/performance/class'; |
| | | |
| | | export default { |
| | | name: 'detailFormDialog', |
| | |
| | | formDia: false, |
| | | form: { |
| | | qualityMonitorDetailsId: '', |
| | | sortNo: null, |
| | | technicalStandardText: '', |
| | | completionMonth: '', |
| | | responsibleUserId: null, |
| | | monitorPurpose: '', |
| | | plannedTime: '', |
| | | monitorProject: '', |
| | |
| | | budget: '', |
| | | organization: '', |
| | | monitorWay: '', |
| | | itemKind: 'OTHER', |
| | | standardMethodId: null, |
| | | templateId: null, |
| | | templateIds: [], |
| | | sampleName: '', |
| | | sampleSpec: '', |
| | | inspectorUserId: null, |
| | | evaluatorUserId: null, |
| | | dueDate: null, |
| | | }, |
| | | standardOptions: [], |
| | | templateOptions: [], |
| | | userOptions: [], |
| | | rules: { |
| | | monitorPurpose: [{ required: true, message: '请è¾å
¥çæ§ç®ç', trigger: 'blur' }], |
| | | monitorProject: [{ required: true, message: '请è¾å
¥çæ§é¡¹ç®', trigger: 'blur' }], |
| | | monitorProject: [{ required: true, message: '请è¾å
¥è´¨æ§é¡¹ç®', trigger: 'blur' }], |
| | | technicalStandardText: [{ required: true, message: '请è¾å
¥ææ¯æ å', trigger: 'blur' }], |
| | | monitorWay: [{ required: true, message: '请è¾å
¥è´¨æ§æ¹å¼', trigger: 'blur' }], |
| | | completionMonth: [{ required: true, message: 'è¯·éæ©å®ææ¶é', trigger: 'change' }], |
| | | responsibleUserId: [{ required: true, message: 'è¯·éæ©è´è´£äºº', trigger: 'change' }], |
| | | templateIds: [{ required: true, type: 'array', min: 1, message: '请è³å°éæ©ä¸ä¸ªåå§è®°å½æ¨¡æ¿', trigger: 'change' }], |
| | | }, |
| | | upLoad: false, |
| | | operationType: '', |
| | |
| | | methods: { |
| | | openDia(type, row) { |
| | | this.formDia = true |
| | | selectStandardMethodList({ current: 1, size: 1000 }).then(res => { this.standardOptions = res.data?.records || res.data || [] }) |
| | | selectStandardTemplatePageList({ current: 1, size: 1000 }).then(res => { this.templateOptions = res.data?.records || res.data || [] }) |
| | | selectUserCondition({ type: 1 }).then(res => { this.userOptions = res.data || [] }) |
| | | this.operationType = type |
| | | if (type === 'edit') { |
| | | this.searchInfo(row) |
| | | } |
| | | }, |
| | | searchInfo (row) { |
| | | this.form = {...row} |
| | | const templateIds = row.templateIds |
| | | ? String(row.templateIds).split(',').filter(Boolean).map(id => Number(id)) |
| | | : (row.templateId ? [Number(row.templateId)] : []) |
| | | this.form = {...row, itemKind: row.itemKind || 'OTHER', templateIds} |
| | | }, |
| | | handleStandardChange(id) { |
| | | const standard = this.standardOptions.find(item => Number(item.id) === Number(id)) |
| | | if (standard) this.form.technicalStandardText = `${standard.code || ''} ${standard.name || ''}`.trim() |
| | | this.form.templateIds = [] |
| | | this.form.templateId = null |
| | | }, |
| | | buildEntity () { |
| | | const entity = this.HaveJson(this.form) |
| | | const templateIds = Array.isArray(this.form.templateIds) |
| | | ? this.form.templateIds.map(id => Number(id)).filter(id => Number.isInteger(id) && id > 0) |
| | | : [] |
| | | entity.templateIds = templateIds.join(',') || null |
| | | entity.templateId = templateIds.length ? templateIds[0] : null |
| | | entity.reviewerUserId = null |
| | | return entity |
| | | }, |
| | | // æäº¤è¡¨å |
| | | submitForm () { |
| | | this.$refs['form'].validate((valid) => { |
| | | if (valid) { |
| | | if (this.form.itemKind === 'INSPECTION') { |
| | | const required = ['standardMethodId','sampleName','inspectorUserId','evaluatorUserId','dueDate'] |
| | | if (required.some(key => !this.form[key])) { |
| | | this.$message.warning('è¯·è¡¥é½æ£æµæ åãæ¨¡æ¿ãæ ·åãæ£æµåãè¯ä»·äººå任塿ªæ¢æ¥') |
| | | return |
| | | } |
| | | if (!Array.isArray(this.form.templateIds) || !this.form.templateIds.length) { |
| | | this.$message.warning('请è³å°éæ©ä¸ä¸ªåå§è®°å½æ¨¡æ¿') |
| | | return |
| | | } |
| | | if (this.form.inspectorUserId === this.form.evaluatorUserId) { |
| | | this.$message.warning('æ£æµåä¸è½åæ¶æ
ä»»è¯ä»·äºº') |
| | | return |
| | | } |
| | | if (this.form.dueDate.slice(0, 7) > this.form.completionMonth) { |
| | | this.$message.warning('任塿ªæ¢æ¥ä¸è½æäºè®¡å宿æä»½') |
| | | return |
| | | } |
| | | } |
| | | if (this.operationType === 'add') { |
| | | this.handleAdd() |
| | | } else { |
| | |
| | | }, |
| | | // æäº¤æ°å¢ |
| | | handleAdd () { |
| | | let entity = this.HaveJson(this.form) |
| | | let entity = this.buildEntity() |
| | | entity.qualityMonitorId = this.qualityMonitorId |
| | | this.upLoad = true |
| | | addQualityMonitorDetail(entity).then(res => { |
| | |
| | | }, |
| | | // æäº¤ä¿®æ¹ |
| | | handleEdit () { |
| | | const entity = this.HaveJson(this.form) |
| | | const entity = this.buildEntity() |
| | | this.upLoad = true |
| | | updateQualityMonitorDetail(entity).then(res => { |
| | | this.upLoad = false |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" title="è´¨éæ§å¶è¯ä»·è®°å½" width="min(960px, 94vw)" @closed="$emit('close')"> |
| | | <div class="record-code">è®°å½ç¼å·ï¼LMSY-CX30-JL03</div> |
| | | <el-alert v-if="row" |
| | | :title="`çæ§ä»»å¡ ${row.inspectionTaskCode || row.entrustCode || ''} · ${row.monitorProject || ''}`" |
| | | type="info" |
| | | :closable="false"/> |
| | | <el-alert v-if="!canEdit" :title="editNotice" :type="loaded ? 'warning' : 'info'" |
| | | :closable="false" style="margin-top:8px"/> |
| | | <el-form :model="form" label-width="110px" style="margin-top: 16px"> |
| | | <el-row :gutter="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£æµé¡¹ç®"> |
| | | <el-input :model-value="row?.monitorProject" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£æµæ¶é´"> |
| | | <el-input :model-value="inspectionDateDisplay" readonly placeholder="åå§è®°å½å¤æ ¸åèªå¨å¸¦å
¥"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£æµæ ·å"> |
| | | <el-input :model-value="row?.sampleName || row?.sample" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æç¨è®¾å¤"> |
| | | <el-input :model-value="form.rawEquipmentDescription || ''" type="textarea" |
| | | :autosize="{ minRows: 1, maxRows: 6 }" readonly placeholder="åå§è®°å½å¤æ ¸åèªå¨å¸¦å
¥"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤è§æ ¼"> |
| | | <el-input :model-value="form.rawEquipmentSpec || ''" type="textarea" :autosize="{ minRows: 1, maxRows: 6 }" |
| | | readonly/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤ç¼å·"> |
| | | <el-input :model-value="form.rawEquipmentCode || ''" type="textarea" :autosize="{ minRows: 1, maxRows: 6 }" |
| | | readonly/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="çç£å"> |
| | | <el-select v-model="form.supervisorUserId" filterable style="width: 100%" :disabled="!canEdit"> |
| | | <el-option v-for="person in supervisorOptions" :key="person.id" :value="person.id" :label="person.name"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="被çç£äººå"> |
| | | <el-input :model-value="supervisedPersonName" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="æ£æµæ
åµåè¯ä»·"> |
| | | <el-input v-model="form.evaluationConclusion" type="textarea" :rows="4" :disabled="!canEdit"/> |
| | | </el-form-item> |
| | | <el-table :data="form.resultRows" border style="width:100%"> |
| | | <el-table-column label="人åå§å" min-width="120"> |
| | | <template #default>{{ supervisedPersonName }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="彿¥æ£æµæ°æ®" min-width="180"> |
| | | <template #default="{ row: item }"><span :title="item.itemName || ''">{{ |
| | | item.measuredValue |
| | | }} {{ item.unit === '/' ? '' : item.unit }}</span></template> |
| | | </el-table-column> |
| | | <el-table-column label="ç²æ ·å¼" min-width="180"> |
| | | <template #default="{ row: item }"> |
| | | <el-input v-model="item.referenceValue" :disabled="!canEdit" placeholder="è¯ä»·äººå¡«å"/> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-checkbox v-if="canEdit" v-model="form.measurementConfirmed" style="margin:12px 0"> |
| | | å·²æ ¸å¯¹å½æ¥æ£æµæ°æ®ä¸å·²å¤æ ¸åå§è®°å½ä¸è´ |
| | | </el-checkbox> |
| | | <el-form-item label="è¯ä»·äººåç¾å"> |
| | | <el-input |
| | | :model-value="form.reviewUser ? `${form.reviewUser} ${form.reviewTime || ''}` : 'æäº¤åè®°å½è¯ä»·äººåæ¥æ'" |
| | | disabled/> |
| | | </el-form-item> |
| | | <el-form-item label="çº æ£æªæ½åé¢é²æªæ½"> |
| | | <el-input v-model="form.correctiveAction" type="textarea" :rows="2" :disabled="!canEdit"/> |
| | | </el-form-item> |
| | | <el-row :gutter="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="çº æ£è´£ä»»äºº"> |
| | | <el-select v-model="form.correctiveResponsibleUserId" filterable clearable style="width:100%" |
| | | :disabled="!canEdit"> |
| | | <el-option v-for="person in people" :key="person.id" :value="person.id" :label="person.name"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å®ææ¥æ"> |
| | | <el-date-picker v-model="form.correctiveDueDate" type="date" value-format="YYYY-MM-DD" style="width:100%" |
| | | :disabled="!canEdit"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="éªè¯æ
åµ"> |
| | | <el-input v-model="form.verificationResult" type="textarea" :rows="2" :disabled="!canEdit"/> |
| | | </el-form-item> |
| | | <el-row :gutter="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éªè¯è´£ä»»äºº"> |
| | | <el-select v-model="form.verificationResponsibleUserId" filterable clearable style="width:100%" |
| | | :disabled="!canEdit"> |
| | | <el-option v-for="person in people" :key="person.id" :value="person.id" :label="person.name"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éªè¯æ¥æ"> |
| | | <el-date-picker v-model="form.verificationDate" type="date" value-format="YYYY-MM-DD" style="width:100%" |
| | | :disabled="!canEdit"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item v-if="form.ratifyOpinion" label="æ¹åæè§"> |
| | | <el-input :model-value="form.ratifyOpinion" disabled/> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="visible = false">å
³é</el-button> |
| | | <el-button v-if="canEdit" type="primary" :loading="loading" @click="save">æäº¤è¯ä»·</el-button> |
| | | <template v-if="canApprove"> |
| | | <el-button :loading="loading" @click="approve(false)">éåè¯ä»·</el-button> |
| | | <el-button type="primary" :loading="loading" @click="approve(true)">æ¹å彿¡£</el-button> |
| | | </template> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import {mapGetters} from '@/utils/store-compat'; |
| | | import {selectUserCondition} from '@/api/performance/class'; |
| | | import { |
| | | getInspectionEvaluation, |
| | | submitInspectionEvaluation, |
| | | approveInspectionEvaluation |
| | | } from '@/api/cnas/process/ensureResults/qualityMonitor'; |
| | | |
| | | export default { |
| | | name: 'InspectionEvaluationDialog', |
| | | emits: ['close'], |
| | | data() { |
| | | return {visible: false, loading: false, loaded: false, loadError: '', row: null, people: [], form: {resultRows: []}} |
| | | }, |
| | | computed: { |
| | | ...mapGetters(['userId']), |
| | | canEdit() { |
| | | return this.loaded && this.form.evaluationEditable === true |
| | | }, |
| | | inspectionDateDisplay() { |
| | | const dates = this.form.rawInspectionDates || [] |
| | | if (!dates.length) return '' |
| | | return dates.length === 1 ? dates[0] : `${dates[0]} ï½ ${dates[dates.length - 1]}` |
| | | }, |
| | | editNotice() { |
| | | if (!this.loaded) return 'æ£å¨è¯»åè¯ä»·è®°å½åç¼è¾æéâ¦' |
| | | return this.loadError || this.form.evaluationEditReason || 'å½åè´¦å·åªè½æ¥çè¯ä»·è®°å½' |
| | | }, |
| | | canApprove() { |
| | | return !!this.form.detailsEvaluateId && this.form.isFinish !== 1 && Number(this.userId) === Number(this.row?.planRatifyUserId) |
| | | }, |
| | | supervisedPersonName() { |
| | | const id = this.form.inspectorUserId || this.row?.inspectorUserId |
| | | return this.people.find(person => Number(person.id) === Number(id))?.name || '' |
| | | }, |
| | | supervisorOptions() { |
| | | const inspectorId = Number(this.form.inspectorUserId || this.row?.inspectorUserId) |
| | | const evaluatorId = Number(this.row?.evaluatorUserId) |
| | | return this.people.filter(person => Number(person.id) !== inspectorId && Number(person.id) !== evaluatorId) |
| | | } |
| | | }, |
| | | methods: { |
| | | open(row) { |
| | | this.row = row |
| | | this.loaded = false |
| | | this.loadError = '' |
| | | this.form = { |
| | | qualityMonitorDetailsId: row.qualityMonitorDetailsId, |
| | | inspectorUserId: row.inspectorUserId, |
| | | resultRows: [], |
| | | measurementConfirmed: false |
| | | } |
| | | this.visible = true |
| | | selectUserCondition({type: 1}).then(res => { |
| | | this.people = res.data || [] |
| | | }) |
| | | getInspectionEvaluation(row.qualityMonitorDetailsId).then(res => { |
| | | if (res.data) this.form = {...res.data, resultRows: res.data.resultRows || [], measurementConfirmed: false} |
| | | }).catch(() => { |
| | | this.loadError = 'è¯ä»·è®°å½è¯»å失败ï¼è¯·å·æ°åéè¯' |
| | | }).finally(() => { |
| | | this.loaded = true |
| | | }) |
| | | }, |
| | | save() { |
| | | if (!this.form.supervisorUserId || !this.form.evaluationConclusion?.trim() || !this.form.resultRows?.length || this.form.resultRows.some(item => !item.measuredValue || !item.referenceValue?.trim()) || !this.form.measurementConfirmed) { |
| | | this.$message.warning('è¯·éæ©çç£åï¼å¡«åæ£æµæ
åµåè¯ä»·ãç²æ ·å¼ï¼å¹¶æ ¸å¯¹åå§è®°å½æ£æµæ°æ®') |
| | | return |
| | | } |
| | | this.loading = true |
| | | submitInspectionEvaluation(this.form).then(() => { |
| | | this.$message.success('è¯ä»·å·²æäº¤') |
| | | this.visible = false |
| | | }).finally(() => { |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | approve(approved) { |
| | | this.$prompt('请è¾å
¥æ¹åæéåæè§', approved ? 'æ¹åè¯ä»·' : 'éåè¯ä»·', {inputValue: this.form.ratifyOpinion || ''}).then(({value}) => { |
| | | this.loading = true |
| | | approveInspectionEvaluation({ |
| | | qualityMonitorDetailsId: this.row.qualityMonitorDetailsId, |
| | | approved, |
| | | opinion: value |
| | | }).then(() => { |
| | | this.$message.success(approved ? 'è¯ä»·å·²å½æ¡£' : 'è¯ä»·å·²éå') |
| | | this.visible = false |
| | | }).finally(() => { |
| | | this.loading = false |
| | | }) |
| | | }).catch(() => { |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | |
| | | <template> |
| | | <!-- 7.7è´¨éçæ§è®¡å--> |
| | | <div class="app-container"> |
| | | <div class="table-card"> |
| | | <div style="display: flex;justify-content: space-between"> |
| | | <div style="display: flex;"> |
| | | <div style="margin-bottom: 18px;margin-right: 10px;display: flex;align-items: center;line-height: 32px;"> |
| | | <span style="width: 88px;font-size: 14px;font-weight: 700;color: var(--lims-text-2);">计ååç§°</span> |
| | | <el-input size="small" placeholder="请è¾å
¥" clearable v-model="yearForm.monitorName" |
| | | @keyup.enter="getYearPlanList"></el-input> |
| | | </div> |
| | | <div style="line-height: 30px;"> |
| | | <section v-if="pageMode === 'list'" class="plan-list-card"> |
| | | <div class="plan-list-toolbar"> |
| | | <div class="plan-list-filters"> |
| | | <span class="annual-plan-label">计å年度</span> |
| | | <el-date-picker v-model="selectedYear" type="year" value-format="YYYY" format="YYYYå¹´" :clearable="false" |
| | | size="small" style="width: 130px" @change="handleYearChange" /> |
| | | <span class="filter-label">计ååç§°</span> |
| | | <el-input v-model="yearForm.monitorName" clearable placeholder="请è¾å
¥" size="small" style="width: 220px" |
| | | @keyup.enter="getYearPlanList" /> |
| | | <el-button type="primary" size="small" @click="getYearPlanList">æ¥è¯¢</el-button> |
| | | <el-button size="small" @click="clearYear">éç½®</el-button> |
| | | </div> |
| | | </div> |
| | | <div style="line-height: 30px;"> |
| | | <el-button size="small" type="primary" @click="leadInto">导å
¥</el-button> |
| | | <div class="plan-list-actions"> |
| | | <el-button size="small" @click="leadInto">导å
¥</el-button> |
| | | <el-button type="primary" size="small" @click="openCreatePlan">æ°å»ºå¹´åº¦è®¡å</el-button> |
| | | </div> |
| | | </div> |
| | | <lims-table :tableData="yearTableData" :column="yearColumnData" :page="yearPage" :tableLoading="yearLoading" |
| | | :height="'calc(100vh - 34em)'" @pagination="pagination" :rowClick="rowClick" key="yearTableData"></lims-table> |
| | | <lims-table :tableData="yearTableData" :column="yearColumnData" :page="yearPage" |
| | | :tableLoading="yearLoading" :height="'calc(100vh - 11em)'" @pagination="pagination" key="yearTableData"> |
| | | <template #planActions="{ row }"> |
| | | <div class="detail-actions"> |
| | | <el-button link type="primary" size="small" @click="openPlan(row)">æ¥ç计å</el-button> |
| | | <el-button v-if="canReviewRow(row)" link type="primary" size="small" @click="examinePlan(row)">å®¡æ ¸</el-button> |
| | | <el-button v-if="canApproveRow(row)" link type="primary" size="small" @click="approvalPlan(row)">æ¹å</el-button> |
| | | <el-dropdown trigger="click" @command="command => handlePlanCommand(command, row)"> |
| | | <el-button link type="primary" size="small">æ´å¤â</el-button> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="export" :disabled="row.ratifyStatus !== 1">导åºå¹´åº¦è®¡å</el-dropdown-item> |
| | | <el-dropdown-item command="delete" divided :disabled="!canDeleteRow(row)">å é¤</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | <div style="margin-top: 20px"> |
| | | <div style="display: flex;justify-content: space-between"> |
| | | </template> |
| | | </lims-table> |
| | | </section> |
| | | |
| | | <template v-else> |
| | | <div class="annual-plan-header"> |
| | | <div class="annual-plan-main"> |
| | | <el-button link type="primary" size="small" @click="backToPlanList">â è¿å年度计å</el-button> |
| | | <span class="annual-plan-label">{{ selectedYear }}年度</span> |
| | | <template v-if="currentPlan"> |
| | | <strong>{{ currentPlan.monitorName }}</strong> |
| | | <el-tag :type="planStatusType">{{ planStatusText }}</el-tag> |
| | | <span>ç¼å¶ï¼{{ currentPlan.writeName || '-' }} {{ formatDate(currentPlan.writeTime) }}</span> |
| | | <span>å®¡æ ¸ï¼{{ currentPlan.examineName || '-' }}</span> |
| | | <span>æ¹åï¼{{ currentPlan.ratifyName || '-' }}</span> |
| | | </template> |
| | | <el-tag v-else type="info">è¯¥å¹´åº¦å°æªå»ºç«è®¡å</el-tag> |
| | | </div> |
| | | <div class="annual-plan-actions"> |
| | | <el-button v-if="canEditPlan" type="primary" size="small" @click="submitPlan">æäº¤å®¡æ ¸</el-button> |
| | | <el-button v-if="canReviewPlan" type="primary" size="small" @click="examinePlan(currentPlan)">å®¡æ ¸</el-button> |
| | | <el-button v-if="canApprovePlan" type="primary" size="small" @click="approvalPlan(currentPlan)">æ¹å</el-button> |
| | | <el-button size="small" @click="leadInto">导å
¥</el-button> |
| | | <el-button v-if="currentPlan" size="small" :disabled="currentPlan.ratifyStatus !== 1" @click="handleDown(currentPlan)">导åºå¹´åº¦è®¡å</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="plan-detail-card"> |
| | | <div class="plan-detail-toolbar"> |
| | | <div style="display: flex;"> |
| | | <span class="section-title">è´¨æ§é¡¹ç®</span> |
| | | <div style="margin-bottom: 18px;margin-right: 10px;display: flex;align-items: center;line-height: 32px;"> |
| | | <span style="width: 88px;font-size: 14px;font-weight: 700;color: var(--lims-text-2);">çæ§ç®ç</span> |
| | | <el-input v-model="yearDetailForm.monitorPurpose" placeholder="请è¾å
¥" size="small" |
| | | @keyup.enter="getYearDetailPlanList"></el-input> |
| | | </div> |
| | | <div style="margin-bottom: 18px;margin-right: 10px;display: flex;align-items: center;line-height: 32px;"> |
| | | <span style="width: 88px;font-size: 14px;font-weight: 700;color: var(--lims-text-2);">çæ§é¡¹ç®</span> |
| | | <span style="width: 88px;font-size: 14px;font-weight: 700;color: var(--lims-text-2);">è´¨æ§é¡¹ç®</span> |
| | | <el-input v-model="yearDetailForm.monitorProject" placeholder="请è¾å
¥" size="small" |
| | | @keyup.enter="getYearDetailPlanList"></el-input> |
| | | </div> |
| | | <div style="margin-bottom: 18px;margin-right: 10px;display: flex;align-items: center;line-height: 32px;"> |
| | | <span style="width: 70px;font-size: 14px;font-weight: 700;color: var(--lims-text-2);">è´è´£äºº</span> |
| | | <el-select v-model="yearDetailForm.responsibleUserId" clearable filterable size="small" style="width: 160px"> |
| | | <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | </div> |
| | | <div style="line-height: 30px;"> |
| | | <el-button type="primary" size="small" @click="getYearDetailPlanList">æ¥è¯¢</el-button> |
| | |
| | | </div> |
| | | </div> |
| | | <div style="line-height: 30px;"> |
| | | <el-button size="small" type="primary" @click="exportSignatureTemplate">导åºç¾å模æ¿</el-button> |
| | | <el-button size="small" type="primary" @click="showDialog('add')">æ°å¢</el-button> |
| | | <!-- <el-button size="small" type="primary" @click="exportSignatureTemplate">导åºç¾å模æ¿</el-button>--> |
| | | <el-button size="small" type="primary" :disabled="!canEditPlan" @click="showDialog('add')">æ°å¢è´¨æ§é¡¹ç®</el-button> |
| | | </div> |
| | | </div> |
| | | <lims-table :tableData="yearDetailTableData" :column="yearDetailColumnData" :page="yearDetailPage" |
| | | :tableLoading="yearDetailLoading" :height="'calc(100vh - 34em)'" @pagination="pagination1" ref="yearDetailTableData" |
| | | key="yearDetailTableData"></lims-table> |
| | | :tableLoading="yearDetailLoading" :height="'calc(100vh - 15em)'" @pagination="pagination1" ref="yearDetailTableData" |
| | | key="yearDetailTableData"> |
| | | <template #detailActions="{ row }"> |
| | | <div class="detail-actions"> |
| | | <el-button link type="primary" size="small" :disabled="!canEditPlan || !!row.inspectionTaskId" |
| | | @click="showDialog('edit', row)">ç¼è¾</el-button> |
| | | |
| | | <el-button v-if="row.itemKind !== 'INSPECTION'" link type="primary" size="small" |
| | | @click="carryOut(row)">宿½</el-button> |
| | | <el-button v-else-if="!row.inspectionTaskId" link type="primary" size="small" |
| | | :disabled="row.planRatifyStatus !== 1" @click="dispatchTask(row)">ä¸åä»»å¡</el-button> |
| | | <el-button v-else link type="primary" size="small" @click="evaluate(row)"> |
| | | {{ row.inspectionTaskState === 5 ? 'è¯ä»·è®°å½' : 'è¯ä»·è¦æ±' }} |
| | | </el-button> |
| | | |
| | | <el-dropdown trigger="click" @command="command => handleDetailCommand(command, row)"> |
| | | <el-button link type="primary" size="small">æ´å¤â</el-button> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item v-if="row.itemKind !== 'INSPECTION'" command="complete">宿æ¥å</el-dropdown-item> |
| | | <el-dropdown-item v-if="row.itemKind !== 'INSPECTION'" command="evaluate">è¯ä»·</el-dropdown-item> |
| | | <el-dropdown-item v-if="row.itemKind === 'INSPECTION' && !row.inspectionTaskId" command="requirement">è¯ä»·è¦æ±</el-dropdown-item> |
| | | <el-dropdown-item v-if="row.itemKind === 'INSPECTION' && row.inspectionTaskId" command="cancel" |
| | | :disabled="row.inspectionTaskOrderState !== 1 || row.inspectionTaskState !== 0">åæ¶ä»»å¡</el-dropdown-item> |
| | | <el-dropdown-item command="attachment">éä»¶ä¸ä¼ </el-dropdown-item> |
| | | <el-dropdown-item command="export">导åº</el-dropdown-item> |
| | | <el-dropdown-item command="delete" divided |
| | | :disabled="!canEditPlan || !!row.inspectionTaskId">å é¤</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </template> |
| | | </lims-table> |
| | | </div> |
| | | </template> |
| | | <el-dialog v-model="createPlanDialog" title="æ°å»ºå¹´åº¦è´¨éæ§å¶è®¡å" width="520px"> |
| | | <el-form :model="planForm" label-width="90px"> |
| | | <el-form-item label="年度"> |
| | | <el-date-picker v-model="planForm.monitorYear" type="year" value-format="YYYY" format="YYYYå¹´" |
| | | :clearable="false" style="width: 100%" placeholder="è¯·éæ©å¹´åº¦" /> |
| | | </el-form-item> |
| | | <el-form-item label="计ååç§°"><el-input v-model="planForm.monitorName" /></el-form-item> |
| | | <el-form-item label="å®¡æ ¸äºº"> |
| | | <el-select v-model="planForm.examineUserId" filterable style="width:100%"> |
| | | <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="createPlanDialog=false">åæ¶</el-button> |
| | | <el-button type="primary" :loading="createPlanLoading" @click="createPlan">ç¡®å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <!--æ°å¢ä¿®æ¹å¼¹æ¡--> |
| | | <detail-form-dialog v-if="formDia" ref="formDia" :qualityMonitorId="qualityMonitorId" |
| | | @closeDia="closeDia"></detail-form-dialog> |
| | |
| | | @closeCarryOutDia="closeCarryOutDia"></carry-out-dialog> |
| | | <!--è¯ä»·æµç¨å¼¹æ¡--> |
| | | <evaluate-dialog v-if="evaluateDialog" ref="evaluateDialog" @closeEvaDia="closeEvaDia"></evaluate-dialog> |
| | | <inspection-evaluation-dialog v-if="inspectionEvaluateDialog" ref="inspectionEvaluateDialog" |
| | | @close="closeInspectionEvaluateDialog" /> |
| | | <el-dialog v-model="examineDialog" title="å®¡æ ¸" width="30%" @close="closeExamineDia"> |
| | | <span> |
| | | å®¡æ ¸å¤æ³¨ï¼ |
| | |
| | | |
| | | <script> |
| | | import DetailFormDialog from './components/detailFormDialog.vue'; |
| | | import InspectionEvaluationDialog from './components/inspectionEvaluationDialog.vue'; |
| | | import CarryOutDialog from './components/carryOutDialog.vue'; |
| | | import EvaluateDialog from './components/evaluateDialog.vue'; |
| | | import filePreview from "@/components/Preview/filePreview.vue"; |
| | | import limsTable from "@/components/Table/lims-table.vue"; |
| | | import { |
| | | createAnnualPlan, getAnnualPlan, submitAnnualPlan, |
| | | delQualityMonitorDetail, |
| | | delQualitySupervise, |
| | | examineQualityMonitor, exportQualityMonitorDetail, exportQualityMonitorEvaluate, exportQualityMonitorRatify, |
| | | pageQualityMonitor, pageQualityMonitorDetail, ratifyFinishReport, |
| | | ratifyQualityMonitor |
| | | } from "@/api/cnas/process/ensureResults/qualityMonitor"; |
| | | import { dispatchInspectionTask, cancelInspectionTask } from "@/api/cnas/process/ensureResults/qualityMonitor"; |
| | | import { selectUserCondition } from "@/api/performance/class"; |
| | | import { mapGetters } from "@/utils/store-compat"; |
| | | import ViewRecord from "./components/ViewRecord.vue"; |
| | |
| | | export default { |
| | | name: 'EnsureResultsValidity', |
| | | // import å¼å
¥çç»ä»¶éè¦æ³¨å
¥å°å¯¹è±¡ä¸æè½ä½¿ç¨ |
| | | components: {ViewRecord, limsTable, filePreview, EvaluateDialog, CarryOutDialog, DetailFormDialog }, |
| | | components: {ViewRecord, limsTable, filePreview, EvaluateDialog, CarryOutDialog, DetailFormDialog, InspectionEvaluationDialog }, |
| | | data() { |
| | | // è¿éåæ¾æ°æ® |
| | | return { |
| | | ViewRecord: false, |
| | | inspectionEvaluateDialog: false, |
| | | pageMode: 'list', |
| | | selectedYear: String(new Date().getFullYear()), |
| | | currentPlan: null, |
| | | selectedPlanId: null, |
| | | createPlanDialog: false, |
| | | createPlanLoading: false, |
| | | planForm: { monitorYear: String(new Date().getFullYear()), monitorName: '', examineUserId: null }, |
| | | examineUserId: '', |
| | | responsibleOptions: [], |
| | | yearForm: { |
| | |
| | | { |
| | | label: '计ååç§°', |
| | | prop: 'monitorName', |
| | | width: '150px' |
| | | minWidth: '220px' |
| | | }, { |
| | | label: '计å年度', |
| | | prop: 'monitorYear', |
| | | width: '100px' |
| | | }, { |
| | | dataType: 'tag', |
| | | label: '计åç¶æ', |
| | | prop: 'workflowStatus', |
| | | width: '110px', |
| | | formatData: (value, row) => this.planWorkflowText(value), |
| | | formatType: value => this.planWorkflowType(value) |
| | | }, { |
| | | label: 'ç¼å¶äºº', |
| | | prop: 'writeName', |
| | | width: '100' |
| | | minWidth: '100px' |
| | | }, { |
| | | label: 'ç¼å¶æ¥æ', |
| | | prop: 'writeTime', |
| | | width: '160' |
| | | }, { |
| | | dataType: 'tag', |
| | | label: 'å®¡æ ¸ç¶æ', |
| | | prop: 'examineStatus', |
| | | width: '100', |
| | | formatData: (params) => { |
| | | if (params === 0) { |
| | | return 'ä¸éè¿'; |
| | | } else if (params === 1) { |
| | | return 'éè¿'; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params === 0) { |
| | | return 'danger'; |
| | | } else if (params === 1) { |
| | | return 'success'; |
| | | } else { |
| | | return null; |
| | | } |
| | | } |
| | | }, { |
| | | label: 'å®¡æ ¸å
容', |
| | | prop: 'examineRemark', |
| | | width: '100' |
| | | minWidth: '150px', |
| | | formatData: value => this.formatDate(value) |
| | | }, { |
| | | label: 'å®¡æ ¸äºº', |
| | | prop: 'examineName', |
| | | width: '100' |
| | | minWidth: '100px' |
| | | }, { |
| | | label: 'å®¡æ ¸æ¥æ', |
| | | prop: 'examineTime', |
| | | width: '160' |
| | | }, { |
| | | dataType: 'tag', |
| | | label: 'æ¹åç¶æ', |
| | | prop: 'ratifyStatus', |
| | | width: '100', |
| | | formatData: (params) => { |
| | | if (params === 0) { |
| | | return '䏿¹å'; |
| | | } else if (params === 1) { |
| | | return 'æ¹å'; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params === 0) { |
| | | return 'danger'; |
| | | } else if (params === 1) { |
| | | return 'success'; |
| | | } else { |
| | | return null; |
| | | } |
| | | } |
| | | }, { |
| | | label: 'æ¹åå
容', |
| | | prop: 'ratifyRemark', |
| | | width: '100' |
| | | minWidth: '150px', |
| | | formatData: value => this.formatDate(value) |
| | | }, { |
| | | label: 'æ¹å人', |
| | | prop: 'ratifyName', |
| | | width: '100' |
| | | minWidth: '100px' |
| | | }, { |
| | | label: 'æ¹åæ¥æ', |
| | | prop: 'ratifyTime', |
| | | width: '160' |
| | | minWidth: '150px', |
| | | formatData: value => this.formatDate(value) |
| | | }, { |
| | | dataType: 'action', |
| | | dataType: 'slot', |
| | | slot: 'planActions', |
| | | label: 'æä½', |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: 'å®¡æ ¸', |
| | | type: 'text', |
| | | disabled: (row) => { |
| | | if (row.examineStatus === 1 || this.userId != row.examineUserId) { |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | }, |
| | | clickFun: (row) => { |
| | | this.examinePlan(row) |
| | | } |
| | | }, |
| | | { |
| | | name: 'æ¹å', |
| | | type: 'text', |
| | | disabled: (row) => { |
| | | if (row.ratifyStatus === 1 || row.examineStatus !== 1 || this.userId != row.ratifyUserId) { |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | }, |
| | | clickFun: (row) => { |
| | | this.approvalPlan(row) |
| | | } |
| | | }, |
| | | { |
| | | name: '导åº', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.handleDown(row) |
| | | }, |
| | | disabled: (row) => { |
| | | if (row.ratifyStatus !== 1) { |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | name: 'å é¤', |
| | | type: 'text', |
| | | color: 'var(--el-color-danger)', |
| | | clickFun: (row) => { |
| | | this.delPlan(row) |
| | | }, |
| | | disabled: (row) => { |
| | | if (row.examineStatus === 1) { |
| | | return true; |
| | | } else { |
| | | return false; |
| | | } |
| | | }, |
| | | } |
| | | ] |
| | | width: '220px' |
| | | }], |
| | | yearTableData: [], // 年表 |
| | | yearLoading: false, |
| | | yearDetailForm: { |
| | | monitorPurpose: '', |
| | | monitorProject: '', |
| | | responsibleUserId: null, |
| | | }, |
| | | yearDetailColumnData: [ |
| | | { |
| | | label: 'çæ§ç®ç', |
| | | prop: 'monitorPurpose', |
| | | width: '150px', |
| | | showOverflowTooltip: true, |
| | | }, { |
| | | label: '计åå¼å±æ¶é´', |
| | | prop: 'plannedTime', |
| | | width: '150px' |
| | | }, { |
| | | label: 'çæ§é¡¹ç®', |
| | | label: 'è´¨æ§é¡¹ç®', |
| | | prop: 'monitorProject', |
| | | width: '150px' |
| | | minWidth: '140px' |
| | | }, { |
| | | label: 'åå åä½ï¼äººåï¼', |
| | | prop: 'participant', |
| | | width: '190px' |
| | | label: 'ææ¯æ å', |
| | | prop: 'technicalStandardText', |
| | | minWidth: '220px' |
| | | }, { |
| | | label: 'é¢ç®ï¼å
ï¼', |
| | | prop: 'budget', |
| | | width: '150px' |
| | | }, { |
| | | label: 'ç»ç»äººå', |
| | | prop: 'organization', |
| | | width: '150px' |
| | | }, { |
| | | label: 'çæ§æ¹å¼', |
| | | label: 'è´¨æ§æ¹å¼', |
| | | prop: 'monitorWay', |
| | | width: '150px' |
| | | minWidth: '120px' |
| | | },{ |
| | | dataType: 'tag', |
| | | label: '宿½ç¶æ', |
| | | prop: 'detailsRatifyStatus', |
| | | width: '100', |
| | | formatData: (params) => { |
| | | if (params === 0) { |
| | | return 'æªå¼å§'; |
| | | } else if (params === 1) { |
| | | return 'å¾
è¯ä»·'; |
| | | } else if (params === 2) { |
| | | return '䏿¹å'; |
| | | } else if (params === 3) { |
| | | return 'å·²æ¹å'; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params === 0) { |
| | | return ''; |
| | | } else if (params === 1) { |
| | | return 'warning'; |
| | | } else if (params === 2) { |
| | | return 'danger'; |
| | | } else if (params === 3) { |
| | | return 'success'; |
| | | } else { |
| | | return null; |
| | | } |
| | | } |
| | | label: '宿æ¶é', |
| | | prop: 'completionMonth', |
| | | width: '110px', |
| | | formatData: value => value ? value.replace('-', '.') : '' |
| | | },{ |
| | | dataType: 'tag', |
| | | label: 'æ¥åç¶æ', |
| | | prop: 'reportStatus', |
| | | width: '100', |
| | | formatData: (params) => { |
| | | if (params === 0) { |
| | | return 'æªå¼å§'; |
| | | } else if (params === 1) { |
| | | return 'å¾
è¯ä»·'; |
| | | } else if (params === 2) { |
| | | return '䏿¹å'; |
| | | } else if (params === 3) { |
| | | return 'å·²æ¹å'; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params === 0) { |
| | | return ''; |
| | | } else if (params === 1) { |
| | | return 'warning'; |
| | | } else if (params === 2) { |
| | | return 'danger'; |
| | | } else if (params === 3) { |
| | | return 'success'; |
| | | } else { |
| | | return null; |
| | | } |
| | | } |
| | | label: 'è´è´£äºº', |
| | | prop: 'responsibleName', |
| | | minWidth: '100px' |
| | | }, { |
| | | label: 'è¯ä»·äºº', |
| | | prop: 'evaluatorName', |
| | | minWidth: '100px' |
| | | }, { |
| | | label: 'äºé¡¹ç±»å«', prop: 'itemKind', width: '100px', |
| | | formatData: value => value === 'INSPECTION' ? 'æ£æµç±»' : '鿣æµç±»' |
| | | }, { |
| | | label: 'çæ§ä»»å¡ç¼å·', prop: 'inspectionTaskCode', minWidth: '150px' |
| | | }, { |
| | | label: 'ä»»å¡ç¶æ', prop: 'inspectionTaskState', width: '100px', |
| | | formatData: value => this.inspectionTaskStatus(value) |
| | | },{ |
| | | dataType: 'tag', |
| | | label: 'è¯ä»·ç¶æ', |
| | |
| | | } |
| | | } |
| | | }, { |
| | | dataType: 'action', |
| | | dataType: 'slot', |
| | | slot: 'detailActions', |
| | | label: 'æä½', |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: 'ç¼è¾', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.showDialog('edit', row) |
| | | } |
| | | }, |
| | | { |
| | | name: '宿½', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.carryOut(row) |
| | | } |
| | | }, |
| | | { |
| | | name: '宿æ¥å', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.record(row) |
| | | }, |
| | | }, |
| | | { |
| | | name: 'è¯ä»·', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.evaluate(row) |
| | | } |
| | | }, |
| | | { |
| | | name: 'éä»¶ä¸ä¼ ', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.viewTestRecord(row) |
| | | } |
| | | }, |
| | | { |
| | | name: '导åº', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.downLoadPost(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: 'å é¤', |
| | | type: 'text', |
| | | color: 'var(--el-color-danger)', |
| | | clickFun: (row) => { |
| | | this.delYearPlanDetail(row) |
| | | } |
| | | } |
| | | ] |
| | | width: '220px' |
| | | } |
| | | ], |
| | | yearDetailTableData: [], // å¹´æç»è¡¨ |
| | |
| | | }; |
| | | }, |
| | | mounted() { |
| | | this.getUserList() |
| | | this.getYearPlanList() |
| | | }, |
| | | // æ¹æ³éå |
| | | methods: { |
| | | // æ¥è¯¢å¹´åº¦è®¡å表 |
| | | getYearPlanList() { |
| | | const entity = { |
| | | monitorName: this.yearForm.monitorName, |
| | | } |
| | | const page = this.yearPage |
| | | this.yearLoading = true |
| | | pageQualityMonitor({ ...entity, ...page }).then(res => { |
| | | this.yearLoading = false |
| | | this.yearTableData = res.data.records |
| | | this.yearPage.total = res.data.total |
| | | if (this.yearTableData.length > 0) { |
| | | this.rowClick(this.yearTableData[0]) |
| | | const entity = { |
| | | monitorYear: this.selectedYear, |
| | | monitorName: this.yearForm.monitorName |
| | | } |
| | | }).catch(err => { |
| | | console.log('err---', err); |
| | | return pageQualityMonitor({ ...entity, ...this.yearPage }).then(res => { |
| | | this.yearTableData = res.data?.records || [] |
| | | this.yearPage.total = res.data?.total || 0 |
| | | }).finally(() => { |
| | | this.yearLoading = false |
| | | }) |
| | | }, |
| | | loadAnnualPlan() { |
| | | if (!this.selectedPlanId) return Promise.resolve() |
| | | return this.loadPlanVersion() |
| | | }, |
| | | loadPlanVersion() { |
| | | if (!this.selectedPlanId) return Promise.resolve() |
| | | return getAnnualPlan({ monitorYear: this.selectedYear, qualityMonitorId: this.selectedPlanId }).then(res => { |
| | | this.currentPlan = res.data || null |
| | | this.qualityMonitorId = this.currentPlan?.qualityMonitorId || '' |
| | | this.yearDetailPage.current = 1 |
| | | return this.getYearDetailPlanList() |
| | | }) |
| | | }, |
| | | openPlan(row, addFirstDetail = false) { |
| | | this.selectedYear = String(row.monitorYear || this.selectedYear) |
| | | this.selectedPlanId = row.qualityMonitorId |
| | | this.pageMode = 'detail' |
| | | return this.loadPlanVersion().then(() => { |
| | | if (addFirstDetail) this.showDialog('add') |
| | | }) |
| | | }, |
| | | backToPlanList() { |
| | | this.pageMode = 'list' |
| | | this.currentPlan = null |
| | | this.qualityMonitorId = '' |
| | | this.yearDetailForm = { monitorProject: '', responsibleUserId: null } |
| | | this.getYearPlanList() |
| | | }, |
| | | handleYearChange() { |
| | | this.yearPage.current = 1 |
| | | this.getYearPlanList() |
| | | }, |
| | | openCreatePlan() { |
| | | this.planForm = { |
| | | monitorYear: String(new Date().getFullYear()), |
| | | monitorName: '', |
| | | examineUserId: null |
| | | } |
| | | this.createPlanDialog = true |
| | | }, |
| | | createPlan() { |
| | | if (!this.planForm.monitorYear || !this.planForm.monitorName || !this.planForm.examineUserId) { |
| | | this.$message.warning('è¯·éæ©å¹´åº¦ãå¡«å计ååç§°å¹¶éæ©å®¡æ ¸äºº') |
| | | return |
| | | } |
| | | this.createPlanLoading = true |
| | | createAnnualPlan({ ...this.planForm }).then(res => { |
| | | this.createPlanDialog = false |
| | | this.selectedYear = String(res.data.monitorYear) |
| | | this.yearPage.current = 1 |
| | | this.$message.success('年度计åå·²å建ï¼è¯·å¡«å第ä¸ä¸ªè´¨æ§é¡¹ç®') |
| | | return this.getYearPlanList().then(() => this.openPlan(res.data, true)) |
| | | }).finally(() => { this.createPlanLoading = false }) |
| | | }, |
| | | submitPlan() { |
| | | this.$confirm('æäº¤åè´¨æ§é¡¹ç®å°éå®ï¼ç¡®è®¤æäº¤å®¡æ ¸ï¼', 'æäº¤å®¡æ ¸').then(() => { |
| | | submitAnnualPlan(this.qualityMonitorId).then(() => { |
| | | this.$message.success('å·²æäº¤å®¡æ ¸') |
| | | this.loadPlanVersion() |
| | | this.getYearPlanList() |
| | | }) |
| | | }).catch(() => {}) |
| | | }, |
| | | clearYear() { |
| | | this.yearForm.monitorName = '' |
| | | this.yearPage.current = 1 |
| | | this.getYearPlanList() |
| | | }, |
| | | pagination({ page, limit }) { |
| | |
| | | pagination1({ page, limit }) { |
| | | this.yearDetailPage.current = page; |
| | | this.yearDetailPage.size = limit; |
| | | this.getYearPlanList(); |
| | | this.getYearDetailPlanList(); |
| | | }, |
| | | leadInto() { |
| | | this.uploadDia = true |
| | | this.planYear = this.selectedYear |
| | | this.getUserList() |
| | | }, |
| | | // 导å
¥æµç¨ |
| | |
| | | this.timer = setTimeout(() => { |
| | | this.uploadDia = false |
| | | this.fileList = [] |
| | | this.planYear = '' |
| | | this.planYear = this.selectedYear |
| | | this.examineUserId = '' |
| | | this.getYearPlanList() |
| | | }, 1000) |
| | |
| | | return; |
| | | } |
| | | if (!this.examineUserId) { |
| | | this.$message.warning('è¯·éæ©æ¹å人') |
| | | this.$message.warning('è¯·éæ©å®¡æ ¸äºº') |
| | | return; |
| | | } |
| | | this.$refs.upload.submit(); |
| | |
| | | closeExamineDia() { |
| | | this.examineDialog = false |
| | | this.examineInfo.examineRemark = '' |
| | | this.getYearPlanList() |
| | | this.refreshPlanData() |
| | | }, |
| | | // æ¹å |
| | | approvalPlan(row) { |
| | |
| | | closeRatifyDia() { |
| | | this.ratifyDialog = false |
| | | this.ratifyInfo.ratifyRemark = '' |
| | | this.getYearPlanList() |
| | | this.refreshPlanData() |
| | | }, |
| | | refreshPlanData() { |
| | | return this.getYearPlanList().then(() => { |
| | | if (this.pageMode === 'detail' && this.selectedPlanId) { |
| | | return this.loadPlanVersion() |
| | | } |
| | | }) |
| | | }, |
| | | // æ¹åæ¥å |
| | | handleApproval(status) { |
| | |
| | | getYearDetailPlanList() { |
| | | const entity = { |
| | | qualityMonitorId: this.qualityMonitorId, |
| | | monitorPurpose: this.yearDetailForm.monitorPurpose, |
| | | monitorProject: this.yearDetailForm.monitorProject, |
| | | responsibleUserId: this.yearDetailForm.responsibleUserId, |
| | | } |
| | | const page = this.yearDetailPage |
| | | this.yearDetailLoading = true |
| | |
| | | this.yearDetailLoading = false |
| | | this.yearDetailTableData = res.data.records |
| | | this.yearDetailPage.total = res.data.total |
| | | this.$refs.yearDetailTableData.$refs.multipleTable.doLayout() |
| | | this.$nextTick(() => this.$refs.yearDetailTableData?.$refs?.multipleTable?.doLayout()) |
| | | }).catch(err => { |
| | | console.log('err---', err); |
| | | this.yearDetailLoading = false |
| | |
| | | // éç½®æç»è¡¨ |
| | | clearDetail() { |
| | | this.yearDetailForm = { |
| | | monitorPurpose: '', |
| | | monitorProject: '' |
| | | monitorProject: '', |
| | | responsibleUserId: null |
| | | } |
| | | this.getYearDetailPlanList() |
| | | }, |
| | |
| | | // end |
| | | // æå¼è¯ä»·å¼¹æ¡ |
| | | evaluate(row) { |
| | | if (row.itemKind === 'INSPECTION') { |
| | | this.inspectionEvaluateDialog = true |
| | | this.$nextTick(() => this.$refs.inspectionEvaluateDialog.open(row)) |
| | | return |
| | | } |
| | | this.evaluateDialog = true |
| | | this.$nextTick(() => { |
| | | this.$refs.evaluateDialog.openDia(row) |
| | |
| | | closeEvaDia() { |
| | | this.evaluateDialog = false |
| | | this.getYearDetailPlanList() |
| | | }, |
| | | closeInspectionEvaluateDialog() { |
| | | this.inspectionEvaluateDialog = false |
| | | this.getYearDetailPlanList() |
| | | }, |
| | | dispatchTask(row) { |
| | | this.$confirm(`确认ä¸åâ${row.monitorProject}âçè´¨éçæ§æ£éªä»»å¡ï¼`, 'ä¸åä»»å¡').then(() => { |
| | | dispatchInspectionTask(row.qualityMonitorDetailsId).then(res => { |
| | | this.$message.success(`å·²ä¸åçæ§ä»»å¡ï¼${res.data.entrustCode}`) |
| | | this.getYearDetailPlanList() |
| | | }) |
| | | }).catch(() => {}) |
| | | }, |
| | | cancelTask(row) { |
| | | this.$confirm(`ç¡®è®¤åæ¶çæ§ä»»å¡â${row.inspectionTaskCode}âï¼å·²åæ¶ä»»å¡ä¼ä¿çåå²è®°å½ã`, 'åæ¶ä»»å¡').then(() => { |
| | | cancelInspectionTask(row.qualityMonitorDetailsId).then(() => { |
| | | this.$message.success('ä»»å¡å·²åæ¶') |
| | | this.getYearDetailPlanList() |
| | | }) |
| | | }).catch(() => {}) |
| | | }, |
| | | // éä»¶ä¸ä¼ |
| | | viewTestRecord (row) { |
| | |
| | | }, |
| | | // æå¼å¹´åº¦æç»æ°å¢ãä¿®æ¹å¼¹æ¡ |
| | | showDialog(type, row) { |
| | | if (!this.qualityMonitorId) { |
| | | this.$message.warning('请å
æ°å»ºå¹´åº¦è´¨éæ§å¶è®¡å') |
| | | return |
| | | } |
| | | if (!this.canEditPlan) { |
| | | this.$message.warning('å½å计åç¶æä¸è½ç»´æ¤è´¨æ§é¡¹ç®') |
| | | return |
| | | } |
| | | this.formDia = true |
| | | this.$nextTick(() => { |
| | | this.$refs.formDia.openDia(type, row) |
| | |
| | | link.target = '_blank'; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | }, |
| | | formatDate(value) { |
| | | return value ? String(value).slice(0, 10) : '-' |
| | | }, |
| | | planWorkflowText(value) { |
| | | return ({ |
| | | DRAFT: 'è稿', |
| | | PENDING_REVIEW: 'å¾
å®¡æ ¸', |
| | | REVIEW_REJECTED: 'å®¡æ ¸éå', |
| | | PENDING_APPROVAL: 'å¾
æ¹å', |
| | | APPROVAL_REJECTED: 'æ¹åéå', |
| | | APPROVED: 'å·²æ¹å' |
| | | })[value] || 'åå²è®¡å' |
| | | }, |
| | | planWorkflowType(value) { |
| | | return ({ |
| | | DRAFT: 'info', |
| | | PENDING_REVIEW: 'warning', |
| | | REVIEW_REJECTED: 'danger', |
| | | PENDING_APPROVAL: 'warning', |
| | | APPROVAL_REJECTED: 'danger', |
| | | APPROVED: 'success' |
| | | })[value] || 'info' |
| | | }, |
| | | canReviewRow(row) { |
| | | return row.workflowStatus === 'PENDING_REVIEW' |
| | | && Number(this.userId) === Number(row.examineUserId) |
| | | }, |
| | | canApproveRow(row) { |
| | | return row.workflowStatus === 'PENDING_APPROVAL' |
| | | && Number(this.userId) === Number(row.ratifyUserId) |
| | | }, |
| | | canDeleteRow(row) { |
| | | return Number(this.userId) === Number(row.writeUserId) |
| | | && ['DRAFT', 'REVIEW_REJECTED', 'APPROVAL_REJECTED'].includes(row.workflowStatus || 'DRAFT') |
| | | }, |
| | | handlePlanCommand(command, row) { |
| | | if (command === 'export') this.handleDown(row) |
| | | if (command === 'delete') this.delPlan(row) |
| | | }, |
| | | inspectionTaskStatus(value) { |
| | | const map = { 0: 'å¾
æ£æµ', 1: 'æ£æµä¸', 2: 'æ£æµä¸', 3: 'å¾
夿 ¸', 4: '夿 ¸éå', 5: 'å¾
è¯ä»·' } |
| | | return value === null || value === undefined ? 'æªä¸å' : (map[value] || 'å¤çä¸') |
| | | }, |
| | | handleDetailCommand(command, row) { |
| | | const handlers = { |
| | | complete: () => this.record(row), |
| | | evaluate: () => this.evaluate(row), |
| | | requirement: () => this.evaluate(row), |
| | | cancel: () => this.cancelTask(row), |
| | | attachment: () => this.viewTestRecord(row), |
| | | export: () => this.downLoadPost(row), |
| | | delete: () => this.delYearPlanDetail(row) |
| | | } |
| | | handlers[command]?.() |
| | | } |
| | | }, |
| | | // ç¨äºä¸ä¼ æä»¶çä¿¡æ¯ |
| | | computed: { |
| | | ...mapGetters(["userId", "nickName"]), |
| | | effectivePlanStatus() { |
| | | if (!this.currentPlan) return '' |
| | | if (this.currentPlan.workflowStatus) return this.currentPlan.workflowStatus |
| | | if (this.currentPlan.ratifyStatus === 1) return 'APPROVED' |
| | | if (this.currentPlan.ratifyStatus === 0) return 'APPROVAL_REJECTED' |
| | | if (this.currentPlan.examineStatus === 1) return 'PENDING_APPROVAL' |
| | | if (this.currentPlan.examineStatus === 0) return 'REVIEW_REJECTED' |
| | | return 'DRAFT' |
| | | }, |
| | | planStatusText() { |
| | | return ({DRAFT:'è稿',PENDING_REVIEW:'å¾
å®¡æ ¸',REVIEW_REJECTED:'å®¡æ ¸éå',PENDING_APPROVAL:'å¾
æ¹å',APPROVAL_REJECTED:'æ¹åéå',APPROVED:'å·²æ¹å'})[this.effectivePlanStatus] || 'åå²è®¡å' |
| | | }, |
| | | planStatusType() { |
| | | return ({DRAFT:'info',PENDING_REVIEW:'warning',REVIEW_REJECTED:'danger',PENDING_APPROVAL:'warning',APPROVAL_REJECTED:'danger',APPROVED:'success'})[this.effectivePlanStatus] || 'info' |
| | | }, |
| | | canEditPlan() { |
| | | return !!this.currentPlan && Number(this.userId) === Number(this.currentPlan.writeUserId) |
| | | && ['DRAFT','REVIEW_REJECTED','APPROVAL_REJECTED'].includes(this.effectivePlanStatus) |
| | | }, |
| | | canReviewPlan() { |
| | | return !!this.currentPlan && this.effectivePlanStatus === 'PENDING_REVIEW' |
| | | && Number(this.userId) === Number(this.currentPlan.examineUserId) |
| | | }, |
| | | canApprovePlan() { |
| | | return !!this.currentPlan && this.effectivePlanStatus === 'PENDING_APPROVAL' |
| | | && Number(this.userId) === Number(this.currentPlan.ratifyUserId) |
| | | }, |
| | | action() { |
| | | return this.javaApi + '/qualityMonitor/importQualityMonitor' |
| | | }, |
| | |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | <style scoped> |
| | | .plan-list-card { |
| | | min-width: 0; |
| | | padding: 14px 16px; |
| | | background: var(--lims-card-bg, var(--el-bg-color)); |
| | | border: 1px solid var(--el-border-color-light); |
| | | border-radius: 4px; |
| | | } |
| | | .plan-list-toolbar, |
| | | .plan-list-filters, |
| | | .plan-list-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | } |
| | | .plan-list-toolbar { |
| | | justify-content: space-between; |
| | | margin-bottom: 14px; |
| | | } |
| | | .filter-label { |
| | | margin-left: 8px; |
| | | font-size: 14px; |
| | | font-weight: 700; |
| | | color: var(--lims-text-2); |
| | | white-space: nowrap; |
| | | } |
| | | .annual-plan-header { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | gap: 16px; |
| | | padding: 14px 16px; |
| | | margin-bottom: 16px; |
| | | background: var(--lims-card-bg, var(--el-bg-color)); |
| | | border: 1px solid var(--el-border-color-light); |
| | | border-radius: 4px; |
| | | } |
| | | .annual-plan-main, .annual-plan-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | } |
| | | .annual-plan-label { font-weight: 700; color: var(--lims-text-2); } |
| | | .plan-detail-card { |
| | | min-width: 0; |
| | | background: var(--lims-card-bg, var(--el-bg-color)); |
| | | } |
| | | .plan-detail-toolbar { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | } |
| | | .section-title { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | margin-right: 18px; |
| | | font-size: 15px; |
| | | font-weight: 700; |
| | | color: var(--lims-text-1, var(--el-text-color-primary)); |
| | | white-space: nowrap; |
| | | } |
| | | .detail-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | white-space: nowrap; |
| | | } |
| | | @media (max-width: 1200px) { |
| | | .annual-plan-header { |
| | | align-items: flex-start; |
| | | flex-direction: column; |
| | | } |
| | | .annual-plan-actions { |
| | | width: 100%; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <div> |
| | | <el-dialog v-model="filesDialogVisible" title="æ¥çæ ¡åè¯ä¹¦" width="80%" @closed="closeFilesLook"> |
| | | <div> |
| | | <el-alert v-if="!tableLoading && tableData.length === 0" type="info" :closable="false" |
| | | title="æéè®¾å¤ææ æ ¡åè¯ä¹¦"/> |
| | | <limsTable |
| | | ref="yearTable" |
| | | :column="columnData" |
| | |
| | | fullscreen |
| | | title="æ¥çéä»¶" top="5vh" width="800px"> |
| | | <filePreview v-if="lookDialogVisible" :currentFile="{}" |
| | | :fileUrl="javaApi+'/img/'+currentInfo.fileUrl" style="max-height: 90vh;overflow-y: auto;"/> |
| | | :fileUrl="fileUrl(currentInfo)" style="max-height: 90vh;overflow-y: auto;"/> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | import filePreview from '@/components/Preview/filePreview.vue'; |
| | | import limsTable from '@/components/Table/lims-table.vue' |
| | | import file from '@/utils/file'; |
| | | import { getCurrentCalibrationFiles } from '@/api/cnas/process/method/methodVerification' |
| | | |
| | | export default { |
| | | name: 'calibrationsFileDia', |
| | |
| | | }, |
| | | // æ¹æ³éå |
| | | methods: { |
| | | openDia(row) { |
| | | fileUrl(row) { |
| | | const image = /\.(png|jpe?g|gif|bmp|webp)$/i.test(row.fileUrl || '') |
| | | return this.javaApi + (image ? '/img/' : '/word/') + row.fileUrl |
| | | }, |
| | | openDia(row = {}) { |
| | | this.filesDialogVisible = true |
| | | this.info = row |
| | | this.tableData = this.info.calibrationsFileList |
| | | this.tableData = row.calibrationsFileList || [] |
| | | if (row.useCurrentDevices) { |
| | | const deviceIds = [...new Set((row.machineAttachmentList || []).map(device => device.deviceId).filter(Boolean))] |
| | | if (!deviceIds.length) return |
| | | this.tableLoading = true |
| | | getCurrentCalibrationFiles({deviceIds: deviceIds.join(',')}).then(res => { |
| | | if (res.code === 200) this.tableData = res.data || [] |
| | | }).finally(() => { |
| | | this.tableLoading = false |
| | | }) |
| | | } |
| | | }, |
| | | closeFilesLook () { |
| | | this.filesDialogVisible = false |
| | |
| | | // ä¸è½½ |
| | | upload (row) { |
| | | let url = ''; |
| | | if(row.type==1){ |
| | | if (/\.(png|jpe?g|gif|bmp|webp)$/i.test(row.fileUrl || '')) { |
| | | url = this.javaApi+'/img/'+row.fileUrl |
| | | file.downloadIamge(url,row.fileName) |
| | | }else{ |
| | |
| | | <el-select v-model="form.confirmUser" multiple :multiple-limit="5" placeholder="è¯·éæ©æ£æµäººå" :disabled="isView"> |
| | | <el-option v-for="user in userList" :key="user.id" :label="user.name" :value="user.id"/> |
| | | </el-select> |
| | | <el-link v-if="operationType !== 'add'" type="primary" @click="viewWorkPermit">æ¥çä¸å²è¯</el-link> |
| | | <el-link type="primary" @click="viewWorkPermit">æ¥çä¸å²è¯</el-link> |
| | | </div> |
| | | <div v-if="item.key === 'equipment'" class="row-extra"> |
| | | <el-link type="primary" @click="viewDevice">æ¥ç设å¤</el-link> |
| | | <el-link v-if="operationType !== 'add'" type="primary" @click="viewCalibrationsFileDia">æ¥çæ ¡åè¯ä¹¦ |
| | | <el-link type="primary" @click="viewCalibrationsFileDia">æ¥çæ ¡åè¯ä¹¦ |
| | | </el-link> |
| | | </div> |
| | | </td> |
| | |
| | | this.openChild('deviceVisible', 'device', this.form) |
| | | }, |
| | | viewCalibrationsFileDia() { |
| | | this.openChild('calibrationVisible', 'calibration', this.form) |
| | | if (this.operationType === 'add' && !(this.form.machineAttachmentList || []).some(device => device.deviceId)) { |
| | | this.$message.warning('请å
éæ©è®¾å¤') |
| | | return |
| | | } |
| | | this.openChild('calibrationVisible', 'calibration', { |
| | | ...this.form, |
| | | useCurrentDevices: this.operationType === 'add' |
| | | }) |
| | | }, |
| | | viewTestRecord() { |
| | | this.openChild('recordVisible', 'record', this.info) |
| | |
| | | <div style="height: 100%"> |
| | | <div class="search"> |
| | | <el-form :model="queryParams" ref="queryParams" size="small" :inline="true"> |
| | | <el-form-item label="å§æç¼å·" prop="entrustCode"> |
| | | <el-form-item :label="taskSource === 'QUALITY_MONITOR' ? 'çæ§ä»»å¡ç¼å·' : 'å§æç¼å·'" prop="entrustCode"> |
| | | <el-input v-model="queryParams.entrustCode" clearable placeholder="请è¾å
¥" size="small" |
| | | @keyup.enter="refreshTable()"></el-input> |
| | | </el-form-item> |
| | |
| | | <div class="center" v-loading="tableLoading"> |
| | | <div class="center-options"> |
| | | <div style="display: flex; align-items: center"> |
| | | <span style="font-size: 14px">è¯éªå®¤:</span> |
| | | <span style="font-size: 14px">任塿¥æº:</span> |
| | | <ul class="tab"> |
| | | <li v-for="(m, i) in tabList" :key="i" :class="{ active: i == tabIndex }" @click="handleTab(m, i)"> |
| | | {{ m.label.replace("è¯éªå®¤", "") }} |
| | |
| | | <span>{{ page.total }}</span> |
| | | </div> |
| | | </div> |
| | | <lims-table :tableData="tableData" :column="column" :page="page" |
| | | <lims-table :tableData="tableData" :column="displayColumns" :page="page" |
| | | :rowClassName="rowClassName" :height="'calc(100vh - 300px)'" @pagination="pagination" |
| | | key="tableData0"> |
| | | <template #action="scope"><div> |
| | |
| | | (scope.row.userName && !scope.row.userName.includes(nickName)) |
| | | )" |
| | | @click="handleInspection(scope.row)">æ£éª</el-button> |
| | | <el-button link type="primary" size="small" :disabled="( |
| | | <el-button v-if="scope.row.taskSource !== 'QUALITY_MONITOR'" link type="primary" size="small" :disabled="( |
| | | scope.row.userName == null || |
| | | scope.row.insState == 5 || |
| | | scope.row.insState == 3 || |
| | |
| | | )" |
| | | @click="handleConnect(scope.row)">交æ¥</el-button> |
| | | <el-button link type="primary" size="small" @click="viewInspectInfo(scope.row)">åå§è®°å½</el-button> |
| | | <el-popover placement="bottom" trigger="hover" style="margin-left: 6px" :disabled="(scope.row.insState != 3 || scope.row.userName == null ||(scope.row.userName && !scope.row.userName.includes(nickName)))"> |
| | | <el-button v-if="scope.row.taskSource === 'QUALITY_MONITOR'" link type="primary" size="small" @click="showMonitorRequirement(scope.row)">{{ Number(scope.row.insState) === 5 ? 'è¯ä»·è®°å½' : 'è¯ä»·è¦æ±' }}</el-button> |
| | | <el-popover v-if="scope.row.taskSource !== 'QUALITY_MONITOR'" placement="bottom" trigger="hover" style="margin-left: 6px" :disabled="(scope.row.insState != 3 || scope.row.userName == null ||(scope.row.userName && !scope.row.userName.includes(nickName)))"> |
| | | <template #reference> |
| | | <el-button link type="primary" size="small" :disabled="(scope.row.insState != 3 || scope.row.userName == null || |
| | | <el-button link type="primary" size="small" :disabled="(scope.row.taskSource === 'QUALITY_MONITOR' || scope.row.insState != 3 || scope.row.userName == null || |
| | | (scope.row.userName && !scope.row.userName.includes(nickName)))">æ´å¤</el-button> |
| | | </template> |
| | | <div> |
| | | <div v-if="scope.row.taskSource !== 'QUALITY_MONITOR'"> |
| | | <el-button :disabled="(scope.row.insState != 3 || scope.row.userName == null || |
| | | (scope.row.userName && !scope.row.userName.includes(nickName)))" style="margin-left: 10px" link type="primary" size="small" @click="download(scope.row)">ä¸è½½æ¥å</el-button> |
| | | <el-button :disabled="(scope.row.insState != 3 || scope.row.userName == null || |
| | |
| | | </lims-table> |
| | | </div> |
| | | </div> |
| | | <el-dialog v-model="monitorRequirementVisible" title="è´¨éçæ§è¯ä»·è¦æ±" width="560px"> |
| | | <el-descriptions :column="1" border> |
| | | <el-descriptions-item label="çæ§ä»»å¡ç¼å·">{{ monitorRequirement.entrustCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="çæ§é¡¹ç®">{{ monitorRequirement.monitorProject }}</el-descriptions-item> |
| | | <el-descriptions-item label="çæ§ç®ç">{{ monitorRequirement.monitorPurpose }}</el-descriptions-item> |
| | | <el-descriptions-item label="çæ§æ¹å¼">{{ monitorRequirement.monitorWay }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ£æµæ å">{{ monitorRequirement.standardCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ ·ååè§æ ¼">{{ monitorRequirement.sample }} {{ monitorRequirement.sampleSpec }}</el-descriptions-item> |
| | | <el-descriptions-item label="宿æé">{{ monitorRequirement.dueDate }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <p>请å¨âåå§è®°å½âä¸å¡«åæ£æµæ°æ®ï¼å¤æ ¸éè¿åç±è¯ä»·äººåå¡«åè´¨éæ§å¶è¯ä»·è®°å½ã</p> |
| | | <template #footer> |
| | | <el-button @click="monitorRequirementVisible=false">å
³é</el-button> |
| | | <el-button v-if="Number(monitorRequirement.insState) === 5" type="primary" @click="openMonitorEvaluation">æå¼è¯ä»·è®°å½</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <inspection-evaluation-dialog v-if="inspectionEvaluateDialog" ref="inspectionEvaluateDialog" @close="inspectionEvaluateDialog=false" /> |
| | | <el-dialog v-model="claimVisible" title="æç¤º" width="400px"> |
| | | æ¯å¦è®¤é¢å§æç¼å·<span style="color: #33c130">{{ |
| | | sampleUserForm.entrustCode |
| | |
| | | import {getRetestResult} from "@/api/business/rawMaterialOrder"; |
| | | import onlyoffice from "@/components/Onlyoffice/onlyoffice.vue"; |
| | | import filePreview from "@/components/Preview/filePreview.vue"; |
| | | import InspectionEvaluationDialog from "@/views/CNAS/process/ensureResults/ensureResultsValidity/components/inspectionEvaluationDialog.vue"; |
| | | export default { |
| | | name: 'InspectionTask', |
| | | components: { |
| | | filePreview, onlyoffice, |
| | | filePreview, onlyoffice, InspectionEvaluationDialog, |
| | | limsTable, |
| | | viewManHourDia, |
| | | UnPassRetestResult |
| | |
| | | dicts: ["urgency_level", "inspection_task_state","material_prop_type"], |
| | | computed: { |
| | | ...mapGetters(["nickName", "userId"]), |
| | | displayColumns() { |
| | | return this.column.filter(item => this.taskSource === 'QUALITY_MONITOR' |
| | | ? !['typeSource', 'orderType'].includes(item.prop) |
| | | : !['monitorProject', 'dueDate'].includes(item.prop)) |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | issuedVisible: false, |
| | | monitorRequirementVisible: false, |
| | | monitorRequirement: {}, |
| | | inspectionEvaluateDialog: false, |
| | | fullscreen: false, |
| | | lookDialogVisible: false, |
| | | option: null, |
| | |
| | | }, |
| | | claimVisible: false, |
| | | tabList: [ |
| | | { label: "å§æ", value: -1 }, |
| | | { label: "å§æ", value: "ENTRUSTED" }, |
| | | { label: "è´¨éçæ§", value: "QUALITY_MONITOR" }, |
| | | // { label: "åææ", value: 1 }, |
| | | // { label: "å¤è´", value: 0 }, |
| | | ], |
| | |
| | | insStateList: [], |
| | | state: 0, // 0:å°è´¦é¡µï¼1ï¼æ£éªé¡µé¢,2æ£éªé¡µé¢(夿 ¸)ï¼é»è®¤ä¸º0,3æ°æ®æ¥ç |
| | | typeSource: -1, // 0:å¤è´æåä¸åï¼1ï¼åææä¸å |
| | | taskSource: 'ENTRUSTED', |
| | | sonLaboratory: null, // 0:å§æï¼1ï¼åææ |
| | | activeFace: 0, // 1ï¼ä¸åï¼2ï¼æ¥çï¼3ï¼å®¡æ ¸ï¼é»è®¤ä¸º0 |
| | | currentId: null, |
| | |
| | | tableData: [], |
| | | column: [ |
| | | { |
| | | label: "å§æç¼å·", |
| | | label: "ä»»å¡ç¼å·", |
| | | prop: "entrustCode", |
| | | width: "160px", |
| | | dataType: "link", |
| | | linkMethod: "selectAllByOne", |
| | | }, |
| | | { label: "çæ§é¡¹ç®", prop: "monitorProject", width: "150px" }, |
| | | { label: "计åæé", prop: "dueDate", width: "120px" }, |
| | | { label: "æ ·ååç§°", prop: "sample", width: "160px" }, |
| | | { |
| | | label: "ä¸åç±»å«", |
| | |
| | | this.getAuthorizedPerson(); |
| | | this.queryParams.userId = this.userId; |
| | | this.queryParams.typeSource = this.typeSource |
| | | this.queryParams.taskSource = this.taskSource |
| | | this.currentTime = getYearAndMonthAndDays(); |
| | | this.getDicts("urgency_level").then((response) => { |
| | | this.urgencyLevel = this.dictToValue(response.data); |
| | |
| | | this.inspectionTaskState = this.dictToValue(response.data); |
| | | }); |
| | | this.queryParams.typeSource = this.typeSource |
| | | this.queryParams.taskSource = this.taskSource |
| | | this.refreshTable(); |
| | | }, |
| | | methods: { |
| | | showMonitorRequirement(row) { |
| | | this.monitorRequirement = row |
| | | this.monitorRequirementVisible = true |
| | | }, |
| | | openMonitorEvaluation() { |
| | | this.monitorRequirementVisible = false |
| | | this.inspectionEvaluateDialog = true |
| | | this.$nextTick(() => this.$refs.inspectionEvaluateDialog.open(this.monitorRequirement)) |
| | | }, |
| | | getList() { |
| | | this.tableLoading = true; |
| | | let param = { ...this.queryParams, ...this.page }; |
| | |
| | | refreshTable(e) { |
| | | this.page.current = 1; |
| | | this.queryParams.tabLabel = this.tabLabel; |
| | | this.queryParams.typeSource = this.typeSource; |
| | | this.queryParams.taskSource = this.taskSource; |
| | | this.queryParams.typeSource = this.taskSource === 'ENTRUSTED' ? -1 : null; |
| | | this.getList(); |
| | | }, |
| | | // ä¸è½½æ¥å |
| | |
| | | }, |
| | | handleTab(m, i) { |
| | | this.tabIndex = i; |
| | | this.typeSource =m.value; |
| | | this.taskSource = m.value; |
| | | this.queryParams.sonLaboratory = ""; |
| | | this.refreshTable(); |
| | | }, |
| | | selectAllByOne(row) { |
| | | if (row.taskSource === 'QUALITY_MONITOR') { |
| | | this.viewInspectInfo(row) |
| | | return |
| | | } |
| | | this.isCopper = row.isCopper; |
| | | this.customsInspection = row; |
| | | this.activeFace = 2; |
| | |
| | | sonLaboratory: this.sonLaboratory, |
| | | state: this.state, |
| | | typeSource: this.typeSource, |
| | | taskSource: row.taskSource, |
| | | orderId: this.orderId |
| | | }, |
| | | }); |
| | |
| | | sonLaboratory: this.sonLaboratory, |
| | | state: this.state, |
| | | typeSource: this.typeSource, |
| | | taskSource: row.taskSource, |
| | | orderId: this.orderId, |
| | | }, |
| | | }); |
| | |
| | | </div> |
| | | <div class="search_input" style="width: 100%"> |
| | | <el-select v-model="verifyUser" clearable filterable placeholder="è¯·éæ©" size="small" style="width: 100%"> |
| | | <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value"> |
| | | <el-option v-for="(item, i) in reviewerOptions" :key="i" :label="item.label" :value="item.value"> |
| | | </el-option> |
| | | </el-select> |
| | | </div> |
| | |
| | | state: null, |
| | | inspectorList: null, |
| | | typeSource: null, |
| | | taskSource: null, |
| | | sagData: [], |
| | | sagForm: { |
| | | sampleCode: null, |
| | |
| | | // ç¨äºä¸ä¼ æä»¶çä¿¡æ¯ |
| | | computed: { |
| | | ...mapGetters(["userId"]), |
| | | reviewerOptions() { |
| | | return this.taskSource === 'QUALITY_MONITOR' |
| | | ? this.personList.filter(item => Number(item.value) !== Number(this.userId)) |
| | | : this.personList; |
| | | }, |
| | | action() { |
| | | return this.javaApi + "/insOrderPlan/uploadFile"; |
| | | }, |
| | |
| | | }, |
| | | methods: { |
| | | syncRouteContext() { |
| | | const { sonLaboratory, orderId, state, inspectorList, typeSource } = this.$route.query; |
| | | const { sonLaboratory, orderId, state, inspectorList, typeSource, taskSource } = this.$route.query; |
| | | const orderChanged = this.id !== orderId; |
| | | this.sonLaboratory = sonLaboratory; |
| | | this.orderId = orderId; |
| | | this.state = state; |
| | | this.inspectorList = inspectorList; |
| | | this.typeSource = typeSource; |
| | | this.taskSource = taskSource; |
| | | if (orderChanged) { |
| | | if (taskSource === 'QUALITY_MONITOR') this.verifyUser = null; |
| | | this.tableLists = []; |
| | | this.tableList = []; |
| | | this.sampleProduct = []; |
| | |
| | | laboratory: this.sonLaboratory, |
| | | }).then(async (res) => { |
| | | this.insOrder = res.data.insOrder; |
| | | this.taskSource = this.insOrder.taskSource || this.taskSource; |
| | | if(res.data.insOrder.ifsOrderType==='02wg'){ |
| | | //æ¥è¯¢é¶ä»¶å±æ§ |
| | | this.getPartProps(res.data.insOrder.ifsInventoryId) |
| | |
| | | } |
| | | }, |
| | | openAddCheck() { |
| | | if (this.taskSource === 'QUALITY_MONITOR') { |
| | | this.upInsReview(1); |
| | | return; |
| | | } |
| | | this.addCheck = true; |
| | | }, |
| | | // æ¶é模æ¿çº§æ£æµæ¡ä»¶çç¼ºå¤±é¡¹ï¼æ¯ä¸ªæ¨¡æ¿é½è¦å¡«å
¨ï¼ |