<template>
|
<div>
|
<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="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="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="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="monitorWayList">
|
<el-select v-model="form.monitorWayList" multiple filterable allow-create default-first-option
|
size="small" style="width: 100%" placeholder="可多选,也可输入其他方式">
|
<el-option v-for="item in monitorWayOptions" :key="item" :label="item" :value="item" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<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="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%"
|
:loading="templateBindingLoading" :disabled="!form.standardMethodId"
|
:placeholder="form.standardMethodId ? '请选择原始记录模板' : '请先选择检测标准'"
|
:no-data-text="form.standardMethodId ? '该检测标准暂未绑定原始记录模板' : '请先选择检测标准'">
|
<el-option v-for="item in templateOptions" :key="item.id" :value="item.id" :label="item.name" />
|
</el-select>
|
<div v-if="form.standardMethodId && !templateBindingLoading && templateOptions.length === 0"
|
style="font-size: 12px; line-height: 18px; color: var(--el-color-warning); margin-top: 4px;">
|
该检测标准在标准库中尚未绑定原始记录模板,请先在标准库中完成绑定。
|
</div>
|
</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>
|
<el-button type="primary" @click="submitForm" :loading="upLoad">确 定</el-button>
|
</span></template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import {
|
addQualityMonitorDetail,
|
updateQualityMonitorDetail
|
} from "@/api/cnas/process/ensureResults/qualityMonitor";
|
import { selectStandardMethodList } from '@/api/cnas/process/method/standardMethod';
|
import { selectStandardTemplatePageList } from '@/api/standard/model';
|
import { selectTemplateBindingsByStandardMethod } from '@/api/standard/standardLibrary';
|
import { selectUserCondition } from '@/api/performance/class';
|
|
export default {
|
name: 'detailFormDialog',
|
// import 引入的组件需要注入到对象中才能使用
|
components: {},
|
props: ['qualityMonitorId'],
|
data() {
|
// 这里存放数据
|
return {
|
formDia: false,
|
// LMSY-CX30-2024《质量控制程序》4.1 规定的常用质量控制手段,可多选
|
monitorWayOptions: [
|
'人员比对', '设备比对', '方法比对', '盲样检测',
|
'留样再测', '标准物质监控', '实验室间比对', '能力验证',
|
],
|
form: {
|
qualityMonitorDetailsId: '',
|
sortNo: null,
|
technicalStandardText: '',
|
completionMonth: '',
|
responsibleUserId: null,
|
monitorPurpose: '',
|
plannedTime: '',
|
monitorProject: '',
|
participant: '',
|
budget: '',
|
organization: '',
|
monitorWay: '',
|
monitorWayList: [],
|
itemKind: 'OTHER',
|
standardMethodId: null,
|
templateId: null,
|
templateIds: [],
|
sampleName: '',
|
sampleSpec: '',
|
inspectorUserId: null,
|
evaluatorUserId: null,
|
dueDate: null,
|
},
|
standardOptions: [],
|
allTemplateOptions: [],
|
templateOptions: [],
|
templateBindingLoading: false,
|
userOptions: [],
|
rules: {
|
monitorProject: [{ required: true, message: '请输入质控项目', trigger: 'blur' }],
|
technicalStandardText: [{ required: true, message: '请输入技术标准', trigger: 'blur' }],
|
monitorWayList: [{ required: true, type: 'array', min: 1, message: '请选择质控方式', trigger: 'change' }],
|
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
|
this.operationType = type
|
this.form.monitorWayList = []
|
this.templateOptions = []
|
this.allTemplateOptions = []
|
this.templateBindingLoading = false
|
selectStandardMethodList({ current: 1, size: 1000 }).then(res => { this.standardOptions = res.data?.records || res.data || [] })
|
selectStandardTemplatePageList({ current: 1, size: 1000 }).then(res => { this.allTemplateOptions = res.data?.records || res.data || [] })
|
selectUserCondition({ type: 1 }).then(res => { this.userOptions = res.data || [] })
|
if (type === 'edit') {
|
this.searchInfo(row)
|
if (row.itemKind === 'INSPECTION' && row.standardMethodId) {
|
this.loadBoundTemplates(row.standardMethodId, this.form.templateIds)
|
}
|
}
|
},
|
searchInfo (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,
|
monitorWayList: row.monitorWay ? String(row.monitorWay).split(/[、,,;;]/).map(item => item.trim()).filter(Boolean) : [],
|
}
|
},
|
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
|
// 和委托下单保持一致:选择检测标准后,只展示该标准在标准库中已绑定的原始记录模板
|
this.loadBoundTemplates(id)
|
},
|
loadBoundTemplates(standardMethodId, selectedIds = null) {
|
const currentIds = Array.isArray(selectedIds) ? selectedIds.map(Number) : null
|
this.templateOptions = []
|
if (currentIds === null) this.form.templateIds = []
|
if (!standardMethodId) return
|
this.templateBindingLoading = true
|
selectTemplateBindingsByStandardMethod({ standardMethodId }).then(res => {
|
const bound = (res.data || []).map(item => ({ id: Number(item.templateId), name: item.name }))
|
this.templateOptions = bound
|
if (currentIds === null) {
|
// 新增或切换检测标准时,默认选中该标准已绑定的全部模板
|
this.form.templateIds = bound.map(item => item.id)
|
return
|
}
|
// 编辑时保留原选择;若模板后来被解绑,补充名称避免下拉框只显示 ID
|
const boundIds = new Set(bound.map(item => item.id))
|
currentIds.forEach(id => {
|
if (!boundIds.has(id)) {
|
const template = this.allTemplateOptions.find(item => Number(item.id) === id)
|
if (template) this.templateOptions.push({ id: Number(template.id), name: template.name })
|
}
|
})
|
this.form.templateIds = currentIds
|
}).catch(() => {
|
this.templateOptions = []
|
}).finally(() => {
|
this.templateBindingLoading = false
|
})
|
},
|
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.monitorWay = (this.form.monitorWayList || []).map(item => item.trim()).filter(Boolean).join('、')
|
delete entity.monitorWayList
|
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 {
|
this.handleEdit()
|
}
|
}
|
})
|
},
|
// 提交新增
|
handleAdd () {
|
let entity = this.buildEntity()
|
entity.qualityMonitorId = this.qualityMonitorId
|
this.upLoad = true
|
addQualityMonitorDetail(entity).then(res => {
|
this.upLoad = false
|
this.$message.success('新增成功')
|
this.closeDia()
|
}).catch(err => {
|
console.log('err---', err);
|
this.upLoad = false
|
})
|
},
|
// 提交修改
|
handleEdit () {
|
const entity = this.buildEntity()
|
this.upLoad = true
|
updateQualityMonitorDetail(entity).then(res => {
|
this.upLoad = false
|
this.$message.success('修改成功')
|
this.closeDia()
|
}).catch(err => {
|
console.log('err---', err);
|
this.upLoad = false
|
})
|
},
|
// 关闭弹框
|
closeDia () {
|
this.$refs.form.resetFields();
|
this.formDia = false
|
this.$emit('closeDia')
|
},
|
}
|
};
|
</script>
|
|
<style scoped>
|
:deep(.el-dialog__body) {
|
max-height: 720px;
|
overflow-y: auto;
|
}
|
</style>
|