diff --git a/inventory-web/src/views/bom/BomManage.vue b/inventory-web/src/views/bom/BomManage.vue
index 963b729..2f42584 100644
--- a/inventory-web/src/views/bom/BomManage.vue
+++ b/inventory-web/src/views/bom/BomManage.vue
@@ -35,7 +35,7 @@
- {{ row.bom_no }}
+ {{ row.bom_no }}
@@ -51,9 +51,8 @@
-
+
- 编辑
另存为
删除
@@ -80,7 +79,7 @@
:remote-method="(q: string) => handleRemoteSearch(q, 'parent')"
:loading="selectLoading"
style="width: 100%"
- :disabled="isEditMode"
+ :disabled="isReadOnlyMode || isEditMode"
class="beautified-select"
popper-class="bom-loadmore-popper parent-popper"
@visible-change="(visible: boolean) => handleVisibleChange(visible, 'parent')"
@@ -99,7 +98,7 @@
-
+
@@ -131,19 +130,19 @@
-
+
-
+
升级次版本 ({{ versionOptions.minor }})
升级主版本 ({{ versionOptions.major }})
-
+
@@ -160,6 +159,7 @@
clearable
style="width: 300px; margin-bottom: 10px;"
:prefix-icon="Search"
+ :disabled="isReadOnlyMode"
/>
@@ -178,6 +178,7 @@
:loading="selectLoading"
:loading-text="`正在加载第 ${childQueryParams.page} 页...`"
:popper-class="`bom-loadmore-popper child-popper-${row.rowKey}`"
+ :disabled="isReadOnlyMode"
@visible-change="(visible: boolean) => handleVisibleChange(visible, 'child', row.rowKey)"
>
-
+
-
+
-
+
- 删
+ 删
-
+
添加一行子件
@@ -280,6 +281,7 @@ const dialogVisible = ref(false)
const saving = ref(false)
const isEditMode = ref(false)
const isSaveAsMode = ref(false)
+const isReadOnlyMode = ref(false)
let originalVersion = ''
let currentBomNo = ''
let originalChildren: ChildRow[] = []
@@ -674,27 +676,80 @@ const handleCreate = () => {
dialogTitle.value = '新建 BOM'
isEditMode.value = false
isSaveAsMode.value = false
+ isReadOnlyMode.value = false
dialogVisible.value = true
}
-const handleEdit = async (row: BomItem) => {
+const handleView = async (row: BomItem) => {
await loadDetail(row.bom_no, row.version)
- dialogTitle.value = '编辑 BOM'
- isEditMode.value = true
+ dialogTitle.value = '查看 BOM'
+ isEditMode.value = false
isSaveAsMode.value = false
+ isReadOnlyMode.value = true
dialogVisible.value = true
}
const handleSaveAs = async (row: BomItem) => {
- await loadDetail(row.bom_no, row.version)
- dialogTitle.value = '另存为新版/变体'
- isEditMode.value = true
- isSaveAsMode.value = true
- originalVersion = form.version
+ // 1. 重置 form 基础状态
+ resetForm()
+
+ // 2. 获取源 BOM 详情(不通过 loadDetail,显式走"深拷贝+清 ID"路径)
+ const res = await getBomDetail(row.bom_no, row.version)
+ if (res.code !== 200) return
+ const raw = JSON.parse(JSON.stringify(res.data))
+
+ // 3. ★ 核心:显式深拷贝 + 清除所有主键 ID(防止后端误判为更新操作)
+ if ('id' in raw) delete raw.id
+ if ('bom_id' in raw) delete raw.bom_id
+ if (Array.isArray(raw.children)) {
+ raw.children.forEach((c: any) => {
+ if ('id' in c) delete c.id
+ if ('bom_id' in c) delete c.bom_id
+ })
+ }
+
+ // 4. 把"已清除 ID 的纯净数据"写入 form(保留子件下拉回显 + 父件下拉回显)
+ form.children = raw.children.map((child: any, idx: number) => ({
+ rowKey: idx,
+ child_id: child.child_id,
+ dosage: child.dosage,
+ remark: child.remark || ''
+ }))
+ form.children.forEach((child, idx) => {
+ initChildDropdownState(idx)
+ if (child.child_id) {
+ const state = childDropdownStates.value.get(idx)!
+ state.options = [{
+ id: raw.children[idx].child_id,
+ name: raw.children[idx].child_name || '未知物料',
+ spec: raw.children[idx].child_spec || ''
+ }]
+ state.hasMore = false
+ }
+ })
+ if (raw.parent_id) {
+ form.parent_id = raw.parent_id
+ parentOptions.value = [{
+ id: raw.parent_id,
+ name: raw.parent_name || '未知产品',
+ spec: raw.parent_spec || ''
+ }]
+ }
+ form.bom_no = (raw.parent_spec || row.bom_no).split('/')[0].trim()
+ form.remark = raw.remark || ''
+
+ // 5. 设置"另存为"模式特有状态(版本升级单选 + 子件变更检测)
+ originalVersion = raw.version || ''
currentBomNo = row.bom_no
originalChildren = JSON.parse(JSON.stringify(form.children))
form.versionUpgradeType = 'minor'
form.version = versionOptions.value.minor
+
+ // 6. 弹窗状态机:标题"新增 BOM",父件可改,启用版本升级单选
+ dialogTitle.value = '新增 BOM'
+ isEditMode.value = false
+ isSaveAsMode.value = true
+ isReadOnlyMode.value = false
dialogVisible.value = true
}
@@ -768,6 +823,7 @@ const resetForm = () => {
form.is_enabled = true
form.children = []
isSaveAsMode.value = false
+ isReadOnlyMode.value = false
originalVersion = ''
currentBomNo = ''
childSearchKeyword.value = ''
@@ -864,9 +920,9 @@ onMounted(() => {
}
if (existingBom) {
- // ★ 情况 A:已经有BOM了,直接打开编辑(查看)弹窗
+ // ★ 情况 A:已经有BOM了,直接打开只读查看弹窗
ElMessage.success('检测到该物料已有 BOM,已自动为您打开');
- handleEdit(existingBom);
+ handleView(existingBom);
} else {
// ★ 情况 B:还没建过BOM,打开新建并注入父件
handleCreate();