diff --git a/aucma-base/src/main/java/com/aucma/base/domain/OrderBomInfo.java b/aucma-base/src/main/java/com/aucma/base/domain/OrderBomInfo.java
index 23a35a6..a8ae1c8 100644
--- a/aucma-base/src/main/java/com/aucma/base/domain/OrderBomInfo.java
+++ b/aucma-base/src/main/java/com/aucma/base/domain/OrderBomInfo.java
@@ -53,6 +53,14 @@ public class OrderBomInfo extends TreeStringEntity {
@Excel(name = "父物料编号")
private String parentId;
+ /**
+ * 父级BOM节点主键
+ *
+ * 业务上同一个物料编码可能出现在多条BOM分支中,新增子节点时必须记录
+ * “挂在哪一条父节点记录下面”,否则仅靠 parentId 会把祖级链算错。
+ */
+ private Long parentObjId;
+
/**
* 父物料名称
*/
@@ -152,6 +160,14 @@ public class OrderBomInfo extends TreeStringEntity {
this.parentName = parentName;
}
+ public Long getParentObjId() {
+ return parentObjId;
+ }
+
+ public void setParentObjId(Long parentObjId) {
+ this.parentObjId = parentObjId;
+ }
+
public String getParentMaterialType() {
return parentMaterialType;
}
@@ -300,6 +316,7 @@ public class OrderBomInfo extends TreeStringEntity {
.append("materialType", getMaterialType())
.append("standardAmount", getStandardAmount())
.append("parentId", getParentId())
+ .append("parentObjId", getParentObjId())
.append("isFlag", getIsFlag())
.append("createdBy", getCreatedBy())
.append("createdTime", getCreatedTime())
diff --git a/aucma-base/src/main/java/com/aucma/base/service/impl/OrderBomInfoServiceImpl.java b/aucma-base/src/main/java/com/aucma/base/service/impl/OrderBomInfoServiceImpl.java
index b5d97c4..091d23c 100644
--- a/aucma-base/src/main/java/com/aucma/base/service/impl/OrderBomInfoServiceImpl.java
+++ b/aucma-base/src/main/java/com/aucma/base/service/impl/OrderBomInfoServiceImpl.java
@@ -2,6 +2,7 @@ package com.aucma.base.service.impl;
import java.util.List;
+import com.aucma.common.exception.base.BaseException;
import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -55,8 +56,10 @@ public class OrderBomInfoServiceImpl implements IOrderBomInfoService
@Override
public int insertOrderBomInfo(OrderBomInfo orderBomInfo)
{
- // 当前业务改为手工维护父子关系,这里只维护树查询必需的祖级链,不再做任何跨模块同步。
- orderBomInfo.setAncestors(buildManualAncestors(orderBomInfo.getParentId(), orderBomInfo.getMaterialCode()));
+ // 当前业务改为手工维护父子关系。这里先把父节点唯一定位到具体 BOM 记录,
+ // 避免同一物料编码出现在多个分支时,祖级链被挂到错误的父节点上。
+ normalizeParentNode(orderBomInfo);
+ orderBomInfo.setAncestors(buildManualAncestors(orderBomInfo));
orderBomInfo.setCreatedTime(DateUtils.getNowDate());
return orderBomInfoMapper.insertOrderBomInfo(orderBomInfo);
}
@@ -71,7 +74,8 @@ public class OrderBomInfoServiceImpl implements IOrderBomInfoService
public int updateOrderBomInfo(OrderBomInfo orderBom)
{
OrderBomInfo oldBomInfo = orderBomInfoMapper.selectOrderBomInfoByObjId(orderBom.getObjId());
- String newAncestors = buildManualAncestors(orderBom.getParentId(), orderBom.getMaterialCode());
+ normalizeParentNode(orderBom);
+ String newAncestors = buildManualAncestors(orderBom);
orderBom.setAncestors(newAncestors);
if (StringUtils.isNotNull(oldBomInfo) && StringUtils.isNotEmpty(oldBomInfo.getAncestors()))
{
@@ -89,13 +93,28 @@ public class OrderBomInfoServiceImpl implements IOrderBomInfoService
* @param materialCode 当前物料编号
* @return 祖级链
*/
- private String buildManualAncestors(String parentId, String materialCode)
+ private String buildManualAncestors(OrderBomInfo orderBomInfo)
{
+ String parentId = orderBomInfo.getParentId();
+ String materialCode = orderBomInfo.getMaterialCode();
// 根节点直接以自身编码作为祖级,便于前端按成品或顶层节点筛子树。
if (isRootNode(parentId))
{
return materialCode;
}
+ if (StringUtils.isNotNull(orderBomInfo.getParentObjId()) && orderBomInfo.getParentObjId() > 0L)
+ {
+ OrderBomInfo parentBomInfo = orderBomInfoMapper.selectOrderBomInfoByObjId(orderBomInfo.getParentObjId());
+ if (StringUtils.isNull(parentBomInfo))
+ {
+ throw new BaseException("父级BOM节点不存在,无法维护当前BOM结构");
+ }
+ if (StringUtils.isNotEmpty(parentBomInfo.getAncestors()))
+ {
+ return parentBomInfo.getAncestors() + "," + materialCode;
+ }
+ return parentBomInfo.getMaterialCode() + "," + materialCode;
+ }
OrderBomInfo parentBomInfo = orderBomInfoMapper.selectOrderBomInfoByMaterialCode(parentId);
if (StringUtils.isNotNull(parentBomInfo) && StringUtils.isNotEmpty(parentBomInfo.getAncestors()))
{
@@ -116,6 +135,34 @@ public class OrderBomInfoServiceImpl implements IOrderBomInfoService
return StringUtils.isEmpty(parentId) || "0".equals(parentId);
}
+ /**
+ * 根据前端传入的父节点主键回填父物料编码
+ *
+ * 订单BOM允许同一物料编码出现在多条分支下,所以保存前必须把 parentObjId
+ * 解析成确定的父节点记录,再反填 parentId,避免后续查询仍然退化成模糊匹配。
+ *
+ * @param orderBomInfo 当前待保存BOM
+ */
+ private void normalizeParentNode(OrderBomInfo orderBomInfo)
+ {
+ if (StringUtils.isNull(orderBomInfo.getParentObjId()) || orderBomInfo.getParentObjId() <= 0L)
+ {
+ if (isRootNode(orderBomInfo.getParentId()))
+ {
+ orderBomInfo.setParentObjId(0L);
+ orderBomInfo.setParentId("0");
+ }
+ return;
+ }
+ OrderBomInfo parentBomInfo = orderBomInfoMapper.selectOrderBomInfoByObjId(orderBomInfo.getParentObjId());
+ if (StringUtils.isNull(parentBomInfo))
+ {
+ throw new BaseException("父级BOM节点不存在,无法维护当前BOM结构");
+ }
+ // 统一以父节点真实物料编码落库,兼容历史查询和列表展示。
+ orderBomInfo.setParentId(parentBomInfo.getMaterialCode());
+ }
+
/**
* 修改子元素关系
*
diff --git a/aucma-base/src/main/resources/mapper/base/OrderBomInfoMapper.xml b/aucma-base/src/main/resources/mapper/base/OrderBomInfoMapper.xml
index ac3ce47..7e4a22a 100644
--- a/aucma-base/src/main/resources/mapper/base/OrderBomInfoMapper.xml
+++ b/aucma-base/src/main/resources/mapper/base/OrderBomInfoMapper.xml
@@ -12,6 +12,7 @@
+
@@ -34,6 +35,7 @@
bm.MATERIAL_SUBCLASS material_type,
ob.standard_amount,
ob.parent_id,
+ ob.parent_obj_id,
mp.MATERIAL_NAME parentName,
mp.MATERIAL_SUBCLASS parentMaterialType,
ob.is_flag,
@@ -100,6 +102,7 @@
material_type,
standard_amount,
parent_id,
+ parent_obj_id,
is_flag,
created_by,
created_time,
@@ -119,6 +122,7 @@
#{materialType},
#{standardAmount},
#{parentId},
+ #{parentObjId},
#{isFlag},
#{createdBy},
#{createdTime},
@@ -141,6 +145,7 @@
material_type = #{materialType},
standard_amount = #{standardAmount},
parent_id = #{parentId},
+ parent_obj_id = #{parentObjId},
is_flag = #{isFlag},
created_by = #{createdBy},
created_time = #{createdTime},