| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="单位:" prop="unit"> |
| | | <el-input v-model="form.unit" placeholder="请输入" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="数量:" prop="quantity"> |
| | | <el-form-item label="批号:" prop="batchNo"> |
| | | <el-input |
| | | v-model="form.batchNo" |
| | | placeholder="请输入" |
| | | clearable |
| | | :disabled="operationType === 'edit'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="UID码:" prop="uidNo"> |
| | | <el-input v-model="form.uidNo" placeholder="请输入" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="检品数量:" prop="inspectedQuantity"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.inspectedQuantity" placeholder="请输入" clearable :precision="2"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="总数量:" prop="quantity"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.quantity" placeholder="请输入" clearable :precision="2" :disabled="quantityDisabled"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | |
| | | <el-col :span="12"> |
| | | <el-form-item label="生产日期:" prop="productionDate"> |
| | | <el-date-picker |
| | | v-model="form.productionDate" |
| | | type="date" |
| | | placeholder="请选择日期" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="calculateValidityDate" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="有效期:" prop="validityDate"> |
| | | <el-date-picker |
| | | v-model="form.validityDate" |
| | | type="date" |
| | | placeholder="自动计算或手动选择" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="6"> |
| | | <el-form-item label="检验用粉剂/液情况:" prop="inspectMaterialConditionId"> |
| | | <el-tree-select |
| | | v-model="form.inspectMaterialConditionId" |
| | | placeholder="请选择" |
| | | clearable |
| | | check-strictly |
| | | :data="productOptions" |
| | | :render-after-expand="false" |
| | | style="width: 100%" |
| | | @change="handleInspectMaterialChange" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="规格型号:" prop="inspectProductModelId"> |
| | | <el-select v-model="form.inspectProductModelId" placeholder="请选择" clearable |
| | | filterable readonly @change="handleChangeModels"> |
| | | <el-option v-for="item in inspectProductModel" :key="item.id" :label="item.model" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="批号(新):" prop="inspectBatchNo"> |
| | | <el-select |
| | | v-model="form.inspectBatchNo" |
| | | placeholder="请选择批号" |
| | | clearable |
| | | filterable |
| | | style="width: 100%" |
| | | @change="handleInspectBatchChange" |
| | | > |
| | | <el-option |
| | | v-for="item in inspectBatchOptions" |
| | | :key="item.batchNo" |
| | | :label="item.batchNo" |
| | | :value="item.batchNo" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="生产日期(新):" prop="inspectProductionDate"> |
| | | <el-input v-model="form.inspectProductionDate" placeholder="自动带出" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="有效期(新):" prop="inspectValidityDate"> |
| | | <el-input v-model="form.inspectValidityDate" placeholder="自动计算" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <PIMTable |
| | | rowKey="id" |
| | |
| | | :tableLoading="tableLoading" |
| | | height="400" |
| | | > |
| | | <template #slot="{ row }"> |
| | | <el-input v-model="row.testValue" clearable/> |
| | | </template> |
| | | <template #instrument="{ row }"> |
| | | <el-select |
| | | v-model="row.instrument" |
| | | placeholder="请选择或输入" |
| | | filterable |
| | | allow-create |
| | | default-first-option |
| | | clearable |
| | | style="width: 100%" |
| | | @change="handleInstrumentChange(row)" |
| | | > |
| | | <el-option label="目测" value="目测" /> |
| | | <el-option |
| | | v-for="item in deviceList" |
| | | :key="item.id" |
| | | :label="item.deviceName + (item.deviceModel ? ' / ' + item.deviceModel : '')" |
| | | :value="item.deviceName" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | <template #deviceStatus="{ row }"> |
| | | <el-select |
| | | v-model="row.deviceStatus" |
| | | placeholder="请选择" |
| | | default-first-option |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="正常" value="正常" /> |
| | | <el-option label="停机" value="停机" /> |
| | | <el-option label="运行" value="运行" /> |
| | | <el-option label="维修" value="维修" /> |
| | | <el-option label="/" value="/" /> |
| | | </el-select> |
| | | </template> |
| | | <template #result="{ row }"> |
| | | <el-input v-model="row.result" placeholder="请输入" clearable /> |
| | | </template> |
| | | <template #resultJudgment="{ row }"> |
| | | <el-select v-model="row.resultJudgment" placeholder="请选择" clearable style="width: 100%"> |
| | | <el-option label="合格" value="合格" /> |
| | | <el-option label="不合格" value="不合格" /> |
| | | <el-option label="/" value="/" /> |
| | | </el-select> |
| | | </template> |
| | | </PIMTable> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | |
| | | import {modelList, productTreeList} from "@/api/basicData/product.js"; |
| | | import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import {userListNoPage} from "@/api/system/user.js"; |
| | | import { getStockInventoryListPage } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js"; |
| | | import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js"; |
| | | import {deviceList as qualityInspectParamDeviceList} from "@/api/energyManagement/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref('') |
| | | |
| | | const validateBatchNo = (rule, value, callback) => { |
| | | if (value === undefined || value === null || String(value).trim() === '') { |
| | | callback(new Error('请输入批号')); |
| | | return; |
| | | } |
| | | callback(); |
| | | }; |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | checkTime: "", |
| | |
| | | model: "", |
| | | testStandardId: "", |
| | | unit: "", |
| | | uidNo: "", |
| | | batchNo: "", |
| | | inspectedQuantity: "", |
| | | quantity: "", |
| | | productionDate: "", |
| | | validityDate: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | // 检验用粉剂/液情况相关新字段 |
| | | inspectMaterialConditionId: "", |
| | | inspectMaterialCondition: "", |
| | | inspectProductModelId : "", |
| | | inspectBatchNo: "", |
| | | inspectProductModel: "", |
| | | inspectProductionDate: "", |
| | | inspectValidityDate: "", |
| | | inspectValidityPeriod: "", |
| | | }, |
| | | rules: { |
| | | checkTime: [{ required: true, message: "请输入", trigger: "blur" },], |
| | |
| | | productModelId: [{ required: true, message: "请选择", trigger: "change" }], |
| | | testStandardId: [{required: false, message: "请选择指标", trigger: "change"}], |
| | | unit: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | inspectedQuantity: [ |
| | | { required: true, message: "请输入检品数量", trigger: "blur" }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (value !== '' && value !== null && value !== undefined) { |
| | | const qty = Number(form.value.quantity); |
| | | const inspectedQty = Number(value); |
| | | if (!isNaN(qty) && !isNaN(inspectedQty) && inspectedQty > qty) { |
| | | callback(new Error("检品数量不能大于总数量")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | trigger: "blur" |
| | | } |
| | | ], |
| | | quantity: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | checkCompany: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | batchNo: [{ required: true, validator: validateBatchNo, trigger: "blur" }], |
| | | checkResult: [{ required: true, message: "请输入", trigger: "change" }], |
| | | }, |
| | | }); |
| | |
| | | }); |
| | | const supplierList = ref([]); |
| | | const productOptions = ref([]); |
| | | const inspectProductModel = ref([]); |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "指标", |
| | | label: "检测项目", |
| | | prop: "parameterItem", |
| | | width: 150 |
| | | }, |
| | | { |
| | | label: "单位", |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "标准值", |
| | | label: "标准要求", |
| | | prop: "standardValue", |
| | | width: 180 |
| | | }, |
| | | { |
| | | label: "单位", |
| | | prop: "unit", |
| | | width: 70 |
| | | }, |
| | | { |
| | | label: "检测器具", |
| | | prop: "instrument", |
| | | dataType: 'slot', |
| | | slot: 'instrument', |
| | | width: 220 |
| | | }, |
| | | { |
| | | label: "设备状态", |
| | | prop: "deviceStatus", |
| | | dataType: 'slot', |
| | | slot: 'deviceStatus', |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "检测结果", |
| | | prop: "result", |
| | | dataType: 'slot', |
| | | slot: 'result', |
| | | width: 150 |
| | | }, |
| | | { |
| | | label: "内控值", |
| | | prop: "controlValue", |
| | | }, |
| | | { |
| | | label: "检验值", |
| | | prop: "testValue", |
| | | label: "结果判断", |
| | | prop: "resultJudgment", |
| | | dataType: 'slot', |
| | | slot: 'slot', |
| | | slot: 'resultJudgment', |
| | | width: 120 |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | |
| | | const currentProductId = ref(0); |
| | | const testStandardOptions = ref([]); // 指标选择下拉框数据 |
| | | const modelOptions = ref([]); |
| | | const deviceList = ref([]); |
| | | const inspectBatchOptions = ref([]); |
| | | |
| | | // 打开弹框 |
| | | const openDialog = async (type, row) => { |
| | |
| | | // 先清空表单验证状态,避免闪烁 |
| | | await nextTick(); |
| | | proxy.$refs.formRef?.clearValidate(); |
| | | |
| | | // 加载设备台账列表 |
| | | loadDeviceList(); |
| | | |
| | | // 并行加载基础数据 |
| | | const [userListsRes] = await Promise.all([ |
| | | userListNoPage(), |
| | |
| | | }) |
| | | ]); |
| | | userList.value = userListsRes.data; |
| | | |
| | | |
| | | form.value = {} |
| | | testStandardOptions.value = []; |
| | | tableData.value = []; |
| | | |
| | | |
| | | if (operationType.value === 'edit') { |
| | | // 先保存 testStandardId,避免被清空 |
| | | const savedTestStandardId = row.testStandardId; |
| | |
| | | nextTick(() => { |
| | | proxy.$refs.formRef?.clearValidate(); |
| | | }); |
| | | |
| | | |
| | | // 编辑模式下,并行加载规格型号和指标选项 |
| | | if (currentProductId.value) { |
| | | // 设置产品名称 |
| | | form.value.productName = findNodeById(productOptions.value, currentProductId.value); |
| | | |
| | | |
| | | // 并行加载规格型号和指标选项 |
| | | const params = { |
| | | productId: currentProductId.value, |
| | | inspectType: 2 |
| | | }; |
| | | |
| | | |
| | | Promise.all([ |
| | | modelList({ id: currentProductId.value }), |
| | | qualityInspectDetailByProductId(params) |
| | |
| | | if (selectedModel) { |
| | | form.value.model = selectedModel.model || ''; |
| | | form.value.unit = selectedModel.unit || ''; |
| | | form.value.uidNo = selectedModel.uidNo || ''; |
| | | } |
| | | } |
| | | |
| | | |
| | | // 设置指标选项 |
| | | testStandardOptions.value = testStandardRes.data || []; |
| | | |
| | | |
| | | // 设置 testStandardId 并加载参数列表 |
| | | nextTick(() => { |
| | | if (savedTestStandardId) { |
| | | // 确保类型匹配(item.id 可能是数字或字符串) |
| | | const matchedOption = testStandardOptions.value.find(item => |
| | | const matchedOption = testStandardOptions.value.find(item => |
| | | item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId) |
| | | ); |
| | | if (matchedOption) { |
| | |
| | | // 编辑场景保留已有检验值,直接拉取原参数数据 |
| | | getQualityInspectParamList(row.id); |
| | | }); |
| | | |
| | | // 编辑模式下,加载检验用粉剂/液相关数据 |
| | | loadInspectMaterialData(); |
| | | }); |
| | | } else { |
| | | getQualityInspectParamList(row.id); |
| | | // 即使没有主产品,也尝试加载检验用粉剂/液数据 |
| | | loadInspectMaterialData(); |
| | | } |
| | | } |
| | | } |
| | |
| | | const getModels = (value) => { |
| | | form.value.productModelId = undefined; |
| | | form.value.unit = undefined; |
| | | form.value.uidNo = undefined; |
| | | form.value.batchNo = ""; |
| | | modelOptions.value = []; |
| | | currentProductId.value = value |
| | | form.value.productName = findNodeById(productOptions.value, value); |
| | |
| | | const handleChangeModel = (value) => { |
| | | form.value.model = modelOptions.value.find(item => item.id == value)?.model || ''; |
| | | form.value.unit = modelOptions.value.find(item => item.id == value)?.unit || ''; |
| | | form.value.uidNo = modelOptions.value.find(item => item.id == value)?.uidNo || ''; |
| | | // 选择规格型号后,如果已有生产日期则重新计算有效期 |
| | | if (form.value.productionDate) { |
| | | calculateValidityDate(); |
| | | } |
| | | } |
| | | |
| | | const findNodeById = (nodes, productId) => { |
| | |
| | | if (children && children.length > 0) { |
| | | newItem.children = convertIdToValue(children); |
| | | } |
| | | |
| | | |
| | | return newItem; |
| | | }); |
| | | } |
| | |
| | | } |
| | | const getQualityInspectParamList = (id) => { |
| | | qualityInspectParamInfo(id).then(res => { |
| | | tableData.value = res.data; |
| | | tableData.value = (res.data || []).map(item => ({...item})); |
| | | }) |
| | | } |
| | | |
| | | // 计算有效期(生产日期 + 规格型号中的有效期) |
| | | const calculateValidityDate = async () => { |
| | | if (!form.value.productionDate) { |
| | | form.value.validityDate = ''; |
| | | return; |
| | | } |
| | | // 获取规格型号的有效期 |
| | | const selectedModel = modelOptions.value.find(item => item.id == form.value.productModelId); |
| | | if (selectedModel && selectedModel.validityPeriod) { |
| | | const productionDate = new Date(form.value.productionDate); |
| | | const validityPeriod = parseFloat(selectedModel.validityPeriod); |
| | | const validityDate = new Date(productionDate); |
| | | validityDate.setFullYear(validityDate.getFullYear() + Math.floor(validityPeriod)); |
| | | validityDate.setMonth(validityDate.getMonth() + Math.round((validityPeriod % 1) * 12)); |
| | | form.value.validityDate = validityDate.toISOString().split('T')[0]; |
| | | } |
| | | }; |
| | | |
| | | // 加载检验用粉剂/液情况相关数据(编辑模式回显用) |
| | | const loadInspectMaterialData = () => { |
| | | // 如果有检验用粉剂/液产品ID,加载对应的规格型号 |
| | | if (form.value.inspectMaterialConditionId) { |
| | | modelList({ id: form.value.inspectMaterialConditionId }).then((res) => { |
| | | inspectProductModel.value = res || []; |
| | | // 如果有规格型号ID,加载批号列表 |
| | | if (form.value.inspectProductModelId && inspectProductModel.value.length > 0) { |
| | | const selectedModel = inspectProductModel.value.find(item => item.id == form.value.inspectProductModelId); |
| | | if (selectedModel) { |
| | | form.value.inspectProductModel = selectedModel.model || ''; |
| | | } |
| | | // 根据规格型号查询批号列表 |
| | | getStockInventoryListPage({ |
| | | model: form.value.inspectProductModel, |
| | | pageNum: 1, |
| | | pageSize: -1 |
| | | }).then((res) => { |
| | | inspectBatchOptions.value = res.data.records || []; |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // 选择检验用粉剂/液情况后,根据产品ID查询库存批号列表 |
| | | const handleInspectMaterialChange = (productId) => { |
| | | inspectBatchOptions.value = []; |
| | | form.value.inspectBatchNo = ""; |
| | | form.value.inspectProductModel = ""; |
| | | form.value.inspectProductModelId = ""; |
| | | form.value.inspectProductionDate = ""; |
| | | form.value.inspectValidityDate = ""; |
| | | form.value.inspectValidityPeriod = ""; |
| | | form.value.inspectMaterialCondition = findNodeById(productOptions.value, productId); |
| | | |
| | | modelList({ id: productId }).then((res) => { |
| | | inspectProductModel.value = res; |
| | | }) |
| | | }; |
| | | |
| | | const handleChangeModels = (value) => { |
| | | form.value.inspectProductModel = inspectProductModel.value.find(item => item.id == value)?.model || ''; |
| | | |
| | | getStockInventoryListPage({ |
| | | model: form.value.inspectProductModel, |
| | | pageNum: 1, |
| | | pageSize: -1 |
| | | }).then(res => { |
| | | inspectBatchOptions.value = res.data.records || [] |
| | | // 清空已选择的批号和新字段 |
| | | form.value.inspectBatchNo = ""; |
| | | form.value.inspectProductionDate = ""; |
| | | form.value.inspectValidityDate = ""; |
| | | }); |
| | | if (form.value.productionDate) { |
| | | calculateInspectValidityDate(); |
| | | } |
| | | } |
| | | |
| | | |
| | | const calculateInspectValidityDate = () => { |
| | | if (!form.value.inspectProductionDate) { |
| | | form.value.inspectValidityDate = ''; |
| | | return; |
| | | } |
| | | // 获取规格型号的有效期 |
| | | const selectedModel = inspectProductModel.value.find(item => item.id == form.value.inspectProductModelId); |
| | | if (selectedModel && selectedModel.validityPeriod) { |
| | | const inspectProductionDate = new Date(form.value.inspectProductionDate); |
| | | const validityPeriod = parseFloat(selectedModel.validityPeriod); |
| | | const validityDate = new Date(inspectProductionDate); |
| | | validityDate.setFullYear(validityDate.getFullYear() + Math.floor(validityPeriod)); |
| | | validityDate.setMonth(validityDate.getMonth() + Math.round((validityPeriod % 1) * 12)); |
| | | form.value.inspectValidityDate = validityDate.toISOString().split('T')[0]; |
| | | } |
| | | } |
| | | |
| | | const handleInspectBatchChange = (batchNo) => { |
| | | if (!batchNo) { |
| | | form.value.inspectProductionDate = ""; |
| | | form.value.inspectValidityDate = ""; |
| | | return; |
| | | } |
| | | const selectedBatch = inspectBatchOptions.value.find(item => item.batchNo === batchNo); |
| | | if (selectedBatch) { |
| | | // 带出规格型号和生产日期 |
| | | // form.value.inspectProductModel = selectedBatch.model || ""; |
| | | form.value.inspectProductionDate = selectedBatch.productionDate || ""; |
| | | calculateInspectValidityDate() |
| | | } |
| | | }; |
| | | |
| | | // 获取设备台账列表 |
| | | const loadDeviceList = () => { |
| | | qualityInspectParamDeviceList().then(res => { |
| | | deviceList.value = res.data || []; |
| | | }); |
| | | }; |
| | | |
| | | // 设备状态颜色映射 |
| | | const getDeviceStatusType = (status) => { |
| | | const map = { |
| | | '正常': 'success', |
| | | '运行': 'primary', |
| | | '停机': 'warning', |
| | | '维修': 'danger' |
| | | }; |
| | | return map[status] || 'info'; |
| | | }; |
| | | |
| | | // 检测器具变化时,自动填充设备状态 |
| | | const handleInstrumentChange = (row) => { |
| | | if (row.instrument === '目测') { |
| | | row.deviceId = null; |
| | | row.deviceName = '目测'; |
| | | row.deviceStatus = ''; |
| | | return; |
| | | } |
| | | const device = deviceList.value.find(d => d.deviceName === row.instrument); |
| | | if (device) { |
| | | row.deviceId = device.id; |
| | | row.deviceName = device.deviceName; |
| | | row.deviceStatus = device.status || ''; |
| | | } else { |
| | | row.deviceId = null; |
| | | row.deviceName = row.instrument || ''; |
| | | row.deviceStatus = ''; |
| | | } |
| | | }; |
| | | |
| | | // 关闭弹框 |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | tableData.value = []; |
| | | testStandardOptions.value = []; |
| | | inspectBatchOptions.value = []; |
| | | form.value.testStandardId = ''; |
| | | dialogFormVisible.value = false; |
| | | emit('close') |