From 181002704e5df616539e6250f975fe7de783b6e2 Mon Sep 17 00:00:00 2001
From: buhuazhen <hua100783@gmail.com>
Date: 星期二, 12 五月 2026 17:56:40 +0800
Subject: [PATCH] feat(productionOrder): 新增修改工艺路线功能,优化绑定弹窗逻辑
---
src/views/productionManagement/productionOrder/BindRouteDialog.vue | 174 ++++++++++++++++++++++++++++++++++---------
src/views/productionManagement/productionOrder/index.vue | 37 +++++++--
2 files changed, 165 insertions(+), 46 deletions(-)
diff --git a/src/views/productionManagement/productionOrder/BindRouteDialog.vue b/src/views/productionManagement/productionOrder/BindRouteDialog.vue
index ea5574f..35ea376 100644
--- a/src/views/productionManagement/productionOrder/BindRouteDialog.vue
+++ b/src/views/productionManagement/productionOrder/BindRouteDialog.vue
@@ -62,7 +62,7 @@
<el-table-column label="鏉愭枡鍚嶇О">
<template #default="{ row, $index }">
<el-tree-select
- v-if="!isDetail"
+ v-if="props.type === 'add'"
v-model="row.productById"
placeholder="璇烽�夋嫨"
clearable
@@ -82,7 +82,7 @@
</template>
<template #default="{ row }">
<el-select
- v-if="!isDetail"
+ v-if="props.type === 'add'"
v-model="row.productModelId"
placeholder="璇烽�夋嫨瑙勬牸"
filterable
@@ -97,8 +97,7 @@
:value="item.id"
/>
</el-select>
- <el-text class="mx-1" v-else>Default</el-text>
-<!-- <span v-else>{{ row.model }}</span>-->
+ <span v-else>{{ row.model }}</span>
</template>
</el-table-column>
<el-table-column label="鏁伴噺">
@@ -108,8 +107,9 @@
</template>
</el-table-column>
<el-table-column label="璁¢噺鍗曚綅">
- <template #default="{ row }">
- <el-input v-model="row.unit" placeholder="璁¢噺鍗曚綅" :disabled="isDetail"/>
+ <template #default="{ row }">
+ <el-input v-if="props.type === 'add'" v-model="row.unit" placeholder="璁¢噺鍗曚綅" :disabled="isDetail"/>
+ <span v-else>{{ row.unit }}</span>
</template>
</el-table-column>
<el-table-column label="鍗曚环">
@@ -461,6 +461,7 @@
const filePreviewRef = ref()
const formData = reactive({
+ id: null,
productOrderList: null,
salesLedgerId: null,
productOrderId: null,
@@ -514,6 +515,8 @@
],
materialInfo: [
{
+ parentId: "",
+ productById: "",
productId: "",
name: "",
productModelId: "",
@@ -562,6 +565,7 @@
const cloneDeep = (val) => JSON.parse(JSON.stringify(val))
const createDefaultFormData = () => ({
+ id: null,
productOrderList: null,
salesLedgerId: null,
productOrderId: null,
@@ -615,6 +619,8 @@
],
materialInfo: [
{
+ parentId: "",
+ productById: "",
productId: "",
name: "",
productModelId: "",
@@ -703,6 +709,7 @@
}
Object.keys(formData).forEach((key) => {
+ if (key === 'id') return
if (source[key] !== undefined) {
formData[key] = Array.isArray(source[key]) ? cloneDeep(source[key]) : source[key]
}
@@ -721,6 +728,20 @@
}))
}
+ if (Array.isArray(formData.materialInfo)) {
+ formData.materialInfo = formData.materialInfo.map((m) => {
+ const parentId = m?.parentId ? String(m.parentId) : ""
+ const productById = m?.productById ? String(m.productById) : ""
+ const name = m?.name ?? ""
+ return {
+ ...m,
+ parentId,
+ productById: productById || parentId || "",
+ name: name || (parentId ? findProductLabelById(productOptions.value, parentId) : "")
+ }
+ })
+ }
+
// 鍏煎 index.vue 閲屽父鐢ㄥ瓧娈靛悕涓庡脊绐楀瓧娈靛悕涓嶄竴鑷寸殑鎯呭喌
if (source.productName === undefined && source.productCategory !== undefined) {
formData.productName = source.productCategory
@@ -736,6 +757,16 @@
}
if (source.productOrderId === undefined && source.id !== undefined) {
formData.productOrderId = source.id
+ }
+
+ // 缂栬緫/鏌ョ湅鏃堕渶瑕佹妸 productionProductInput 鐨� id 甯﹀洖鍘伙紙鍚庣 save 璧版洿鏂帮級
+ // 鍒楄〃琛岄噷涓�鑸槸 printId锛涜鎯呮帴鍙d竴鑸繑鍥� { id, productOrderId, ... }
+ if (source.printId !== undefined && source.printId !== null && source.printId !== '') {
+ formData.id = source.printId
+ } else if (source.productionProductInputId !== undefined && source.productionProductInputId !== null && source.productionProductInputId !== '') {
+ formData.id = source.productionProductInputId
+ } else if (source.productOrderId !== undefined && source.id !== undefined && source.id !== null && source.id !== '') {
+ formData.id = source.id
}
introductionLetterList.value = String(formData.introductionLetter || "")
@@ -767,6 +798,7 @@
(val) => {
mergeRowDataToForm(val)
getProductOrder()
+ Promise.resolve().then(() => hydrateMaterialInfo())
},
{immediate: true, deep: true}
)
@@ -793,14 +825,14 @@
const convertProductOptions = (data) => {
return data.map(item => ({
label: item.label || item.productName || item.name || "",
- value: item.id,
+ value: String(item.id ?? ""),
children: item.children?.length ? convertProductOptions(item.children) : undefined
}))
}
const findProductLabelById = (options, productId) => {
for (const item of options) {
- if (item.value === productId) {
+ if (String(item.value) === String(productId)) {
return item.label
}
if (item.children?.length) {
@@ -813,10 +845,69 @@
return ""
}
+const normalizeId = (v) => {
+ if (v === 0 || v === "0") return "0"
+ if (v === null || v === undefined) return ""
+ const s = String(v)
+ return s === "null" || s === "undefined" ? "" : s
+}
+
+const materialModelOptionsCache = new Map()
+
+const normalizeModelOptions = (res) => {
+ return Array.isArray(res) ? res :
+ Array.isArray(res?.data) ? res.data :
+ Array.isArray(res?.rows) ? res.rows :
+ Array.isArray(res?.data?.records) ? res.data.records :
+ []
+}
+
+const getModelOptionsByParentId = async (parentId) => {
+ const key = normalizeId(parentId)
+ if (!key) return []
+ if (materialModelOptionsCache.has(key)) return materialModelOptionsCache.get(key)
+ const res = await modelList({id: key})
+ const options = normalizeModelOptions(res)
+ materialModelOptionsCache.set(key, options)
+ return options
+}
+
+const hydrateMaterialInfo = async () => {
+ const rows = Array.isArray(formData.materialInfo) ? formData.materialInfo : []
+ await Promise.all(rows.map(async (row) => {
+ if (!row || typeof row !== 'object') return
+ const parentId = normalizeId(row.parentId || row.productById)
+ if (!parentId) return
+
+ row.parentId = parentId
+ row.productById = parentId
+ if (!row.name) {
+ row.name = findProductLabelById(productOptions.value, parentId)
+ }
+
+ if (!Array.isArray(row.modelOptions) || row.modelOptions.length === 0) {
+ row.modelOptions = await getModelOptionsByParentId(parentId)
+ }
+
+ const productModelId = normalizeId(row.productModelId)
+ if (productModelId && Array.isArray(row.modelOptions) && row.modelOptions.length) {
+ const currentModel = row.modelOptions.find(item => normalizeId(item?.id) === productModelId)
+ if (currentModel) {
+ row.model = currentModel?.model || row.model || ""
+ row.unit = currentModel?.unit || row.unit || ""
+ if (!row.productId) {
+ row.productId = currentModel?.id || ""
+ }
+ }
+ }
+ }))
+}
+
const getMaterialProductOptions = () => {
productTreeList().then(res => {
const rawData = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : []
productOptions.value = convertProductOptions(rawData)
+ Promise.resolve().then(() => hydrateMaterialInfo())
})
}
@@ -848,26 +939,31 @@
}
const getModels = async (val, row, index) => {
- const targetRow = formData.materialInfo[index]
- row.productId = val || ""
- row.productById = val || ""
- row.name = val ? findProductLabelById(productOptions.value, val) : ""
+ const targetRow = formData.materialInfo[index] || {}
+ const parentId = val ? String(val) : ""
+ const name = parentId ? findProductLabelById(productOptions.value, parentId) : ""
- row.productModelId = ""
- row.model = ""
- row.unit = ""
- row.modelOptions = []
-
- if (!val) return
-
- const res = await modelList({id: val})
- formData.materialInfo[index] = {
+ const baseRow = {
...targetRow,
- modelOptions: Array.isArray(res) ? res :
- Array.isArray(res?.data) ? res.data :
- Array.isArray(res?.rows) ? res.rows :
- Array.isArray(res?.data?.records) ? res.data.records :
- []
+ parentId,
+ productId: "",
+ productById: parentId,
+ name,
+ productModelId: "",
+ model: "",
+ unit: "",
+ modelOptions: []
+ }
+
+ formData.materialInfo[index] = baseRow
+
+ if (!parentId) return
+
+ const modelOptions = await getModelOptionsByParentId(parentId)
+
+ formData.materialInfo[index] = {
+ ...baseRow,
+ modelOptions
}
// row.modelOptions = Array.isArray(res) ? res :
// Array.isArray(res?.data) ? res.data :
@@ -889,6 +985,8 @@
const addMaterialRow = () => {
formData.materialInfo.push({
id: Date.now().toString(),
+ parentId: "",
+ productById: "",
productId: "",
name: "",
productModelId: "",
@@ -957,24 +1055,24 @@
const materialRows = Array.isArray(formData.materialInfo) ? formData.materialInfo : []
for (let i = 0; i < materialRows.length; i++) {
const row = materialRows[i] || {}
- if (!row.productId) {
+ if (!row.productModelId) {
ElMessage.warning(`鏉愭枡淇℃伅绗�${i + 1}琛岋細 瑙勬牸蹇呭~`)
return
}
}
const rows = Array.isArray(formData.processContent) ? formData.processContent : []
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i] || {}
- if (!row.deviceId) {
- ElMessage.warning(`宸ヨ壓鍔犲伐绗�${i + 1}琛岋細鏈哄彴蹇呭~`)
- return
- }
- if (!Array.isArray(row.reportUserIds) || row.reportUserIds.length === 0) {
- ElMessage.warning(`宸ヨ壓鍔犲伐绗�${i + 1}琛岋細鎶ュ伐浜哄繀濉玚)
- return
- }
- }
+ // for (let i = 0; i < rows.length; i++) {
+ // const row = rows[i] || {}
+ // if (!row.deviceId) {
+ // ElMessage.warning(`宸ヨ壓鍔犲伐绗�${i + 1}琛岋細鏈哄彴蹇呭~`)
+ // return
+ // }
+ // if (!Array.isArray(row.reportUserIds) || row.reportUserIds.length === 0) {
+ // ElMessage.warning(`宸ヨ壓鍔犲伐绗�${i + 1}琛岋細鎶ュ伐浜哄繀濉玚)
+ // return
+ // }
+ // }
const payload = cloneDeep(formData)
delete payload.productOrderList
if (Array.isArray(payload.materialInfo)) {
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 4470b7d..e1aeced 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -111,7 +111,11 @@
const BindRouteDialogRef = ref(null)
const handleBindRouteSubmit = async (data) => {
- const res = await saveProductionProductInput(data)
+ const payload = { ...(data || {}) }
+ if (bindDialogType.value === "edit" && !payload.id) {
+ payload.id = rowData.value?.printId || rowData.value?.id || null
+ }
+ const res = await saveProductionProductInput(payload)
if (res.code === 200) {
proxy.$modal.msgSuccess("缁戝畾鎴愬姛");
bindRouteDialogVisible.value = false
@@ -229,9 +233,17 @@
{
name: "鏌ョ湅宸ヨ壓璺嚎",
type: "text",
- showHide: row => row.printId,
+ showHide: row => row.printId && Number(row?.hasProduct) > 0,
clickFun: row => {
openBindRouteDialog(row, "view");
+ },
+ },
+ {
+ name: "淇敼宸ヨ壓璺嚎",
+ type: "text",
+ showHide: row => row.printId && !(Number(row?.hasProduct) > 0),
+ clickFun: row => {
+ openBindRouteDialog(row, "edit");
},
},
{
@@ -324,15 +336,24 @@
bindRouteLoading.value = true;
try {
BindRouteDialogRef.value?.resetForm?.()
- if (type === "view") {
- bindDialogType.value = "detail"
+ if (type === "view" || type === "edit") {
+ bindDialogType.value = type === "view" ? "detail" : "edit"
const res = await viewGetByProductWordId(row.id)
- if (res?.cuttingFileVo?.id == null) {
- res.cuttingFileVo = []
+
+ const detail = res?.data || res || {}
+ if (detail?.cuttingFileVo?.id == null) {
+ detail.cuttingFileVo = []
} else {
- res.cuttingFileVo = [res.cuttingFileVo]
+ detail.cuttingFileVo = [detail.cuttingFileVo]
}
- rowData.value = res?.data || res
+
+ if (detail.productOrderId == null) {
+ detail.productOrderId = row.id
+ }
+ if (type === "edit" && (detail.id == null || detail.id === "") && row?.printId) {
+ detail.id = row.printId
+ }
+ rowData.value = detail
} else {
bindDialogType.value = "add"
rowData.value = deepClone( row)
--
Gitblit v1.9.3