| | |
| | | default() { |
| | | return []; |
| | | } |
| | | }, |
| | | labelWidth: { |
| | | type: Number, |
| | | default: 120 |
| | | }, |
| | | /** 本次生产数量(成型工序用于计算投入重量/数量) */ |
| | | quantity: { |
| | | type: Number, |
| | | default: null |
| | | }, |
| | | /** 当前工序是否为「成型」 */ |
| | | isFormingProcess: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | /** 工单 BOM 投入重量,非成型工序回显到「投入重量/数量」 */ |
| | | bomInputQty: { |
| | | type: Number, |
| | | default: null |
| | | } |
| | | }); |
| | | |
| | |
| | | list: [] as any[], |
| | | }); |
| | | |
| | | const INPUT_WEIGHT_PARAM_ITEM = "投入重量/数量"; |
| | | |
| | | /** 参数项展示名(兼容库内旧名「投入重量」) */ |
| | | const displayParameterItem = (name) => { |
| | | const trimmed = String(name ?? "").trim(); |
| | | if (trimmed === "投入重量") return INPUT_WEIGHT_PARAM_ITEM; |
| | | return trimmed; |
| | | }; |
| | | |
| | | const fieldLabel = (item: any) => { |
| | | const parameterItem = displayParameterItem(item.parameterItem); |
| | | if (!item.unit || item.unit === "/") { |
| | | return item.parameterItem; |
| | | return parameterItem; |
| | | } |
| | | return `${item.parameterItem}(${item.unit})`; |
| | | return `${parameterItem}(${item.unit})`; |
| | | }; |
| | | |
| | | const getType = (item: any) => item.type || "文本格式"; |
| | |
| | | const result: Record<string, any[]> = {}; |
| | | formData.list.forEach((item, index) => { |
| | | if (String(item.isRequired) === "1") { |
| | | result[`list.${index}.value`] = [{required: true, message: `请输入${item.parameterItem}`, trigger: "blur"}]; |
| | | result[`list.${index}.value`] = [{ |
| | | required: true, |
| | | message: `请输入${displayParameterItem(item.parameterItem)}`, |
| | | trigger: "blur" |
| | | }]; |
| | | } |
| | | }); |
| | | return result; |
| | |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const normalizeUnit = (unit) => String(unit ?? "").trim().toLowerCase(); |
| | | |
| | | const isInputWeightItem = (item) => { |
| | | const name = String(item?.parameterItem ?? "").trim(); |
| | | return (name === "投入重量" || name.includes(INPUT_WEIGHT_PARAM_ITEM)) && |
| | | normalizeUnit(item?.unit) === "kg"; |
| | | }; |
| | | |
| | | const isBlankCoeffItem = (item) => |
| | | String(item?.parameterItem ?? "").includes("生坯系数") && |
| | | normalizeUnit(item?.unit) === "g"; |
| | | |
| | | /** 投入重量/数量(KG) = 本次生产数量 × 生坯系数(g) / 1000 */ |
| | | const syncFormingInputWeight = () => { |
| | | if (!props.isFormingProcess) return; |
| | | const weightItem = formData.list.find(isInputWeightItem); |
| | | if (!weightItem) return; |
| | | |
| | | const qty = Number(props.quantity); |
| | | const coeffItem = formData.list.find(isBlankCoeffItem); |
| | | const coeff = coeffItem?.value === null || coeffItem?.value === undefined || coeffItem?.value === "" |
| | | ? NaN |
| | | : Number(coeffItem.value); |
| | | |
| | | if (!Number.isFinite(qty) || qty < 1 || !Number.isFinite(coeff)) { |
| | | return; |
| | | } |
| | | |
| | | weightItem.value = Number(((qty * coeff) / 1000).toFixed(4)); |
| | | }; |
| | | |
| | | /** 非成型:投入重量/数量取工单 bomInputQty(仅回显,不覆盖用户已编辑的值) */ |
| | | const syncBomInputWeight = (force = false) => { |
| | | if (props.isFormingProcess) return; |
| | | const weightItem = formData.list.find(isInputWeightItem); |
| | | if (!weightItem) return; |
| | | const bom = props.bomInputQty; |
| | | if (bom === null || bom === undefined || Number.isNaN(Number(bom))) { |
| | | return; |
| | | } |
| | | const current = weightItem.value; |
| | | const isEmpty = |
| | | current === null || current === undefined || current === ""; |
| | | if (!force && !isEmpty) { |
| | | return; |
| | | } |
| | | weightItem.value = Number(bom); |
| | | }; |
| | | |
| | | const syncInputWeight = () => { |
| | | if (props.isFormingProcess) { |
| | | syncFormingInputWeight(); |
| | | } else { |
| | | syncBomInputWeight(); |
| | | } |
| | | }; |
| | | |
| | | const cloneParamList = (list) => |
| | | JSON.parse(JSON.stringify(list || [])); |
| | | |
| | | const initData = () => { |
| | | formData.list = props.list || []; |
| | | formData.list = cloneParamList(props.list); |
| | | formData.list.forEach(item => { |
| | | if (item.value === undefined) { |
| | | item.value = null; |
| | | } |
| | | }); |
| | | loadDeviceName() |
| | | loadDeviceName(); |
| | | if (props.isFormingProcess) { |
| | | syncFormingInputWeight(); |
| | | } else { |
| | | syncBomInputWeight(true); |
| | | } |
| | | }; |
| | | |
| | | const submitData = async () => { |
| | |
| | | () => { |
| | | initData(); |
| | | }, |
| | | {immediate: true, deep: true} |
| | | {immediate: true} |
| | | ); |
| | | |
| | | watch( |
| | | () => [props.quantity, props.isFormingProcess], |
| | | () => { |
| | | if (props.isFormingProcess) { |
| | | syncFormingInputWeight(); |
| | | } |
| | | } |
| | | ); |
| | | |
| | | watch( |
| | | () => { |
| | | const coeffItem = formData.list.find(isBlankCoeffItem); |
| | | return coeffItem?.value; |
| | | }, |
| | | () => { |
| | | if (props.isFormingProcess) { |
| | | syncFormingInputWeight(); |
| | | } |
| | | } |
| | | ); |
| | | |
| | | watch( |
| | | () => [props.bomInputQty, props.isFormingProcess], |
| | | () => { |
| | | if (!props.isFormingProcess) { |
| | | syncBomInputWeight(); |
| | | } |
| | | } |
| | | ); |
| | | |
| | | defineExpose({ |
| | | submitData |
| | | submitData, |
| | | syncFormingInputWeight, |
| | | syncBomInputWeight, |
| | | syncInputWeight |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px"> |
| | | <el-form-item |
| | | v-for="(item, index) in formData.list" |
| | | :key="item.id" |
| | | :label="fieldLabel(item)" |
| | | :prop="`list.${index}.value`" |
| | | > |
| | | <el-input-number |
| | | v-if="getType(item) === '数值格式'" |
| | | v-model="item.value" |
| | | :controls="false" |
| | | style="width: 100%" |
| | | placeholder="请输入" |
| | | /> |
| | | <el-date-picker |
| | | v-else-if="getType(item) === '时间格式'" |
| | | v-model="item.value" |
| | | type="datetime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | placeholder="请选择" |
| | | style="width: 100%" |
| | | /> |
| | | <el-date-picker |
| | | v-else-if="getType(item) === '日期格式'" |
| | | v-model="item.value" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | placeholder="请选择" |
| | | style="width: 100%" |
| | | /> |
| | | <el-select |
| | | v-else-if="getType(item) === '是/否选框'" |
| | | v-model="item.value" |
| | | placeholder="请选择" |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="是" value="是"/> |
| | | <el-option label="否" value="否"/> |
| | | </el-select> |
| | | <el-select |
| | | v-else-if="getType(item) === '机台选择'" |
| | | v-model="item.value" |
| | | placeholder="请选择" |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.deviceName" |
| | | ></el-option> |
| | | </el-select> |
| | | <el-input |
| | | v-else |
| | | v-model="item.value" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form ref="formRef" :model="formData" :rules="rules" :label-width="`${labelWidth}px`"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12" v-for="(item, index) in formData.list" :key="item.id"> |
| | | <el-form-item |
| | | :label="fieldLabel(item)" |
| | | :prop="`list.${index}.value`" |
| | | > |
| | | <el-input-number |
| | | v-if="getType(item) === '数值格式'" |
| | | v-model="item.value" |
| | | :controls="false" |
| | | style="width: 100%" |
| | | placeholder="请输入" |
| | | /> |
| | | <el-date-picker |
| | | v-else-if="getType(item) === '时间格式'" |
| | | v-model="item.value" |
| | | type="datetime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | placeholder="请选择" |
| | | style="width: 100%" |
| | | /> |
| | | <el-date-picker |
| | | v-else-if="getType(item) === '日期格式'" |
| | | v-model="item.value" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | placeholder="请选择" |
| | | style="width: 100%" |
| | | /> |
| | | <el-select |
| | | v-else-if="getType(item) === '是/否选框'" |
| | | v-model="item.value" |
| | | placeholder="请选择" |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="是" value="是"/> |
| | | <el-option label="否" value="否"/> |
| | | </el-select> |
| | | <el-select |
| | | v-else-if="getType(item) === '机台选择'" |
| | | v-model="item.value" |
| | | placeholder="请选择" |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="(device, deviceIndex) in deviceOptions" |
| | | :key="deviceIndex" |
| | | :label="device.deviceName" |
| | | :value="device.deviceName" |
| | | ></el-option> |
| | | </el-select> |
| | | <el-input |
| | | v-else |
| | | v-model="item.value" |
| | | placeholder="请输入" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </template> |