| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="产品名称:" prop="productId"> |
| | | <el-tree-select |
| | | v-if="operationType !== 'edit'" |
| | | v-model="form.productId" |
| | | placeholder="请选择" |
| | | clearable |
| | |
| | | @change="getModels" |
| | | :data="productOptions" |
| | | :render-after-expand="false" |
| | | :disabled="operationType === 'edit'" |
| | | style="width: 100%" |
| | | /> |
| | | <!-- 编辑态:不依赖下拉选项回显,直接展示文本 --> |
| | | <el-input |
| | | v-else |
| | | v-model="form.productName" |
| | | disabled |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="规格型号:" prop="productModelId"> |
| | | <el-select |
| | | v-if="operationType !== 'edit'" |
| | | v-model="form.productModelId" |
| | | placeholder="请选择" |
| | | clearable |
| | | :disabled="operationType === 'edit'" |
| | | filterable |
| | | readonly |
| | | @change="handleChangeModel" |
| | | > |
| | | <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" /> |
| | | <el-option |
| | | v-for="item in modelOptions" |
| | | :key="item.id" |
| | | :label="item.model" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | <!-- 编辑态:不展示规格型号列表,直接展示文本 --> |
| | | <el-input |
| | | v-else |
| | | v-model="form.model" |
| | | disabled |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | }, |
| | | rules: { |
| | | checkTime: [{ required: true, message: "请选择检测日期", trigger: "change" }], |
| | | checkUserName: [{ required: true, message: "请选择检验员", trigger: "change" }], |
| | | checkName: [{ required: true, message: "请选择检验员", trigger: "change" }], |
| | | productId: [{ required: true, message: "请选择产品名称", trigger: "change" }], |
| | | productModelId: [{ required: true, message: "请选择规格型号", trigger: "change" }], |
| | | batchNo: [{ required: true, message: "请输入批号", trigger: "blur" }], |
| | |
| | | const modelOptions = ref([]) |
| | | |
| | | // 打开弹框 |
| | | const openDialog = (type, row) => { |
| | | const openDialog = async (type, row) => { |
| | | operationType.value = type; |
| | | userListNoPage().then(res => { |
| | | userList.value = res.data || []; |
| | | }) |
| | | dialogFormVisible.value = true; |
| | | form.value = {} |
| | | getProductOptions(); |
| | | |
| | | // 编辑态不校验规格型号(prop 仍绑定 productModelId,但编辑态改为文本展示) |
| | | data.rules.productModelId = [ |
| | | { |
| | | required: type !== "edit", |
| | | message: "请选择规格型号", |
| | | trigger: "change", |
| | | }, |
| | | ]; |
| | | |
| | | // 先加载下拉选项,确保编辑数据可以正确匹配回显 |
| | | const userRes = await userListNoPage(); |
| | | userList.value = userRes.data || []; |
| | | |
| | | await getProductOptions(); |
| | | |
| | | // 处理结果默认“报废”,且不可选择其它项 |
| | | form.value.dealResult = getScrapDealResultValue(); |
| | | if (operationType.value === 'edit') { |
| | | getQualityUnqualifiedInfo(row.id).then(res => { |
| | | const { inspectState, ...rest } = (res.data || {}) |
| | | form.value = { ...rest, dealResult: getScrapDealResultValue() } |
| | | }) |
| | | const fallback = row || {}; |
| | | const res = await getQualityUnqualifiedInfo(fallback.id); |
| | | const { inspectState, ...rest } = res.data || {}; |
| | | |
| | | // 先用列表行数据把“必回显字段”直接填上,避免详情接口字段名不一致导致全空。 |
| | | const productName = rest?.productName ?? fallback?.productName; |
| | | const modelName = rest?.model ?? fallback?.model; |
| | | |
| | | const checkTypeValue = rest?.checkType ?? fallback?.checkType; |
| | | const checkNameValue = |
| | | rest?.checkName ?? |
| | | rest?.checkUserName ?? |
| | | fallback?.checkName ?? |
| | | fallback?.checkUserName; |
| | | |
| | | const productId = |
| | | rest?.productId ?? |
| | | findProductIdByLabel(productOptions.value, productName); |
| | | |
| | | // 先回填字段(productModelId 需要依赖 modelOptions,稍后再补) |
| | | const normalizedProductId = normalizeProductIdByOptions(productId); |
| | | |
| | | // 编辑态产品名称展示只展示 label,避免树组件回显依赖 value 匹配 |
| | | const productNameLabel = |
| | | rest?.productName ?? |
| | | fallback?.productName ?? |
| | | findNodeById(productOptions.value, normalizedProductId) ?? |
| | | productName; |
| | | form.value = { |
| | | ...rest, |
| | | productName: productNameLabel, |
| | | productId: normalizedProductId, |
| | | productModelId: rest?.productModelId ?? undefined, |
| | | model: rest?.model ?? fallback?.model, |
| | | unit: rest?.unit ?? fallback?.unit, |
| | | batchNo: rest?.batchNo ?? fallback?.batchNo ?? "", |
| | | checkType: |
| | | checkTypeValue === undefined || checkTypeValue === null |
| | | ? undefined |
| | | : Number(checkTypeValue), |
| | | checkName: checkNameValue ?? "", |
| | | checkTime: rest?.checkTime ?? fallback?.checkTime ?? "", |
| | | defectivePhenomena: |
| | | rest?.defectivePhenomena ?? fallback?.defectivePhenomena ?? "", |
| | | dealName: rest?.dealName ?? fallback?.dealName ?? "", |
| | | dealTime: rest?.dealTime ?? fallback?.dealTime ?? "", |
| | | dealResult: getScrapDealResultValue(), |
| | | }; |
| | | |
| | | // 规格型号下拉需要依赖 productId |
| | | await loadModelsForProductId(form.value.productId); |
| | | |
| | | // 规格型号回显(如详情没给 productModelId,就用 model 名称反查) |
| | | if (!form.value.productModelId) { |
| | | form.value.productModelId = findModelIdByModel( |
| | | modelOptions.value, |
| | | modelName |
| | | ); |
| | | } |
| | | |
| | | // 根据 productModelId 回填 model/unit |
| | | if (form.value.productModelId) { |
| | | form.value.productModelId = normalizeModelIdByOptions(form.value.productModelId); |
| | | handleChangeModel(form.value.productModelId); |
| | | } else if (modelName) { |
| | | // productModelId 仍然拿不到时,至少保证 model/unit 文本回显 |
| | | const matched = |
| | | (modelOptions.value || []).find((m) => { |
| | | const model = String(m?.model ?? ""); |
| | | const id = String(m?.id ?? ""); |
| | | const target = String(modelName ?? ""); |
| | | return model === target || id === target; |
| | | }) ?? null; |
| | | if (matched) { |
| | | form.value.model = matched.model ?? form.value.model; |
| | | form.value.unit = matched.unit ?? form.value.unit; |
| | | } else { |
| | | form.value.model = modelName; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | const getProductOptions = () => { |
| | | productTreeList().then((res) => { |
| | | productOptions.value = convertIdToValue(res); |
| | | }); |
| | | const getProductOptions = async () => { |
| | | const res = await productTreeList(); |
| | | productOptions.value = convertIdToValue(res); |
| | | }; |
| | | const getModels = (value) => { |
| | | form.value.productName = findNodeById(productOptions.value, value); |
| | |
| | | }) |
| | | }; |
| | | |
| | | // 编辑模式/或任意需要时:只拉取规格型号列表,不清空已回填的字段 |
| | | const loadModelsForProductId = async (productId) => { |
| | | if (!productId) return; |
| | | const res = await modelList({ id: productId }); |
| | | modelOptions.value = res || []; |
| | | |
| | | // 让单位/型号等字段保持与当前 productModelId 一致 |
| | | if (form.value.productModelId) { |
| | | form.value.productModelId = normalizeModelIdByOptions(form.value.productModelId); |
| | | handleChangeModel(form.value.productModelId); |
| | | } |
| | | }; |
| | | |
| | | 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 || ''; |
| | | }; |
| | | |
| | | // 解决回显时类型不一致导致 el-tree-select / el-select 只显示 value(id) |
| | | const normalizeProductIdByOptions = (productId) => { |
| | | if (productId === undefined || productId === null) return productId; |
| | | const target = String(productId); |
| | | const stack = Array.isArray(productOptions.value) ? [...productOptions.value] : []; |
| | | while (stack.length) { |
| | | const node = stack.shift(); |
| | | if (node && String(node?.value ?? "") === target) return node?.value; |
| | | if (node?.children?.length) stack.push(...node.children); |
| | | } |
| | | return productId; |
| | | }; |
| | | |
| | | const normalizeModelIdByOptions = (modelId) => { |
| | | if (modelId === undefined || modelId === null) return modelId; |
| | | const target = String(modelId); |
| | | return (modelOptions.value || []).find((m) => String(m?.id ?? "") === target)?.id ?? modelId; |
| | | }; |
| | | const findNodeById = (nodes, productId) => { |
| | | for (let i = 0; i < nodes.length; i++) { |
| | |
| | | } |
| | | return null; // 没有找到节点,返回null |
| | | }; |
| | | |
| | | // 根据树节点 label 回填 value(编辑回显兜底用) |
| | | const findProductIdByLabel = (nodes, label) => { |
| | | const target = String(label ?? ""); |
| | | if (!target) return undefined; |
| | | |
| | | const stack = Array.isArray(nodes) ? [...nodes] : []; |
| | | while (stack.length) { |
| | | const node = stack.shift(); |
| | | if (node && String(node?.label ?? "") === target) return node?.value; |
| | | if (node?.children?.length) stack.push(...node.children); |
| | | } |
| | | return undefined; |
| | | }; |
| | | |
| | | // 根据规格型号名称反查 id(编辑回显兜底用) |
| | | const findModelIdByModel = (models, model) => { |
| | | const target = String(model ?? ""); |
| | | if (!target) return undefined; |
| | | return ( |
| | | (models || []).find((m) => { |
| | | const mModel = String(m?.model ?? ""); |
| | | const mId = String(m?.id ?? ""); |
| | | return mModel === target || mId === target; |
| | | })?.id |
| | | ); |
| | | }; |
| | | function convertIdToValue(data) { |
| | | return data.map((item) => { |
| | | const { id, children, ...rest } = item; |