feat: 增加 BOM 另存为跨版本内容查重校验
This commit is contained in:
@ -143,7 +143,7 @@ class BomService:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def save_bom(data):
|
def save_bom(data):
|
||||||
"""保存 BOM (支持多版本)"""
|
"""保存 BOM (支持多版本),新增跨版本内容查重"""
|
||||||
bom_no = data.get('bom_no')
|
bom_no = data.get('bom_no')
|
||||||
version = data.get('version', 'V1.0')
|
version = data.get('version', 'V1.0')
|
||||||
parent_id = data['parent_id']
|
parent_id = data['parent_id']
|
||||||
@ -157,6 +157,38 @@ class BomService:
|
|||||||
if child['child_id'] == parent_id:
|
if child['child_id'] == parent_id:
|
||||||
raise ValueError('父件与子件不能是同一物料')
|
raise ValueError('父件与子件不能是同一物料')
|
||||||
|
|
||||||
|
# ===== 跨版本内容查重 =====
|
||||||
|
# 将当前提交的 children 转换为可比较的集合 (child_id, dosage)
|
||||||
|
current_children_set = set()
|
||||||
|
for child in children:
|
||||||
|
# 用 (child_id, dosage) 元组表示,dosage 转为整数比较
|
||||||
|
dosage_val = int(child.get('dosage', 0)) if child.get('dosage') else 0
|
||||||
|
current_children_set.add((child['child_id'], dosage_val))
|
||||||
|
|
||||||
|
# 查询该 bom_no 下所有其他版本的子件配置
|
||||||
|
existing_versions = db.session.query(
|
||||||
|
BomTable.version,
|
||||||
|
BomTable.child_id,
|
||||||
|
BomTable.dosage
|
||||||
|
).filter(
|
||||||
|
BomTable.bom_no == bom_no,
|
||||||
|
BomTable.version != version # 排除当前正在保存的版本
|
||||||
|
).all()
|
||||||
|
|
||||||
|
# 按版本分组,构建每个版本的子件集合
|
||||||
|
version_children = {}
|
||||||
|
for ver, child_id, dosage in existing_versions:
|
||||||
|
if ver not in version_children:
|
||||||
|
version_children[ver] = set()
|
||||||
|
dosage_val = int(dosage) if dosage else 0
|
||||||
|
version_children[ver].add((child_id, dosage_val))
|
||||||
|
|
||||||
|
# 比对每个版本
|
||||||
|
for ver, existing_set in version_children.items():
|
||||||
|
if current_children_set == existing_set:
|
||||||
|
raise ValueError(f'保存失败!当前子件配置与已有版本 {ver} 完全一致,请勿重复保存')
|
||||||
|
|
||||||
|
# ===== 执行保存 =====
|
||||||
# 仅删除当前版本的旧记录
|
# 仅删除当前版本的旧记录
|
||||||
BomTable.query.filter_by(bom_no=bom_no, version=version).delete()
|
BomTable.query.filter_by(bom_no=bom_no, version=version).delete()
|
||||||
|
|
||||||
|
|||||||
@ -224,6 +224,7 @@ const isEditMode = ref(false)
|
|||||||
const isSaveAsMode = ref(false) // 任务1:标记是否为另存为模式
|
const isSaveAsMode = ref(false) // 任务1:标记是否为另存为模式
|
||||||
let originalVersion = '' // 保存原始版本号用于计算升级选项
|
let originalVersion = '' // 保存原始版本号用于计算升级选项
|
||||||
let currentBomNo = '' // 保存当前操作的 BOM 编号用于计算版本避让
|
let currentBomNo = '' // 保存当前操作的 BOM 编号用于计算版本避让
|
||||||
|
let originalChildren: ChildRow[] = [] // 保存原始子件数据用于本地查重
|
||||||
|
|
||||||
const bomList = ref<BomItem[]>([])
|
const bomList = ref<BomItem[]>([])
|
||||||
const materialOptions = ref<MaterialBase[]>([])
|
const materialOptions = ref<MaterialBase[]>([])
|
||||||
@ -441,6 +442,8 @@ const handleSaveAs = async (row: BomItem) => {
|
|||||||
// 保存原始版本号和 BOM 编号用于计算升级选项
|
// 保存原始版本号和 BOM 编号用于计算升级选项
|
||||||
originalVersion = form.version
|
originalVersion = form.version
|
||||||
currentBomNo = row.bom_no // 保存当前操作的 BOM 编号
|
currentBomNo = row.bom_no // 保存当前操作的 BOM 编号
|
||||||
|
// 保存原始子件数据用于本地查重
|
||||||
|
originalChildren = JSON.parse(JSON.stringify(form.children))
|
||||||
// 默认选中次版本升级
|
// 默认选中次版本升级
|
||||||
form.versionUpgradeType = 'minor'
|
form.versionUpgradeType = 'minor'
|
||||||
form.version = versionOptions.value.minor
|
form.version = versionOptions.value.minor
|
||||||
@ -524,6 +527,21 @@ const submitForm = async () => {
|
|||||||
return ElMessage.warning('子件列表中存在重复物料,请合并用量或删除重复项')
|
return ElMessage.warning('子件列表中存在重复物料,请合并用量或删除重复项')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== 另存为本地查重:检查是否修改过 =====
|
||||||
|
if (isSaveAsMode.value && originalChildren.length > 0) {
|
||||||
|
// 将当前 children 和原始 children 转换为 set 进行比较
|
||||||
|
const currentSet = new Set(form.children.map(c => `${c.child_id}-${c.dosage}`))
|
||||||
|
const originalSet = new Set(originalChildren.map(c => `${c.child_id}-${c.dosage}`))
|
||||||
|
|
||||||
|
// 比较两个集合是否完全相同
|
||||||
|
const isIdentical = currentSet.size === originalSet.size &&
|
||||||
|
[...currentSet].every(item => originalSet.has(item))
|
||||||
|
|
||||||
|
if (isIdentical) {
|
||||||
|
return ElMessage.warning('您未修改任何子件,与原版本内容一致,请修改后再保存')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
bom_no: fullBomNo.value,
|
bom_no: fullBomNo.value,
|
||||||
version: form.version,
|
version: form.version,
|
||||||
@ -540,8 +558,11 @@ const submitForm = async () => {
|
|||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
fetchBomList()
|
fetchBomList()
|
||||||
} else { ElMessage.error(res.msg || '保存失败') }
|
} else { ElMessage.error(res.msg || '保存失败') }
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
// 错误已由全局拦截器统一处理
|
// 确保后端返回的错误信息能正确展示
|
||||||
|
if (e.response?.data?.msg) {
|
||||||
|
ElMessage.error(e.response.data.msg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally { saving.value = false }
|
finally { saving.value = false }
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user