From cafeb1e232da42b68572c2095b47723d555fdb3b Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Mon, 24 Nov 2025 14:39:10 +0800 Subject: [PATCH] =?UTF-8?q?RFQ=20BOM=E5=A4=8D=E5=88=B6=E6=A0=91=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=A1=AE=E5=AE=9E=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/part/mapper/BomSearch3Mapper.java | 21 +++ .../service/impl/BomSearch3ServiceImpl.java | 107 ++++++++++++- .../mapper/part/BomSearch3Mapper.xml | 150 ++++++++++++++++++ 3 files changed, 275 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/xujie/sys/modules/part/mapper/BomSearch3Mapper.java b/src/main/java/com/xujie/sys/modules/part/mapper/BomSearch3Mapper.java index b65fd672..665ffb21 100644 --- a/src/main/java/com/xujie/sys/modules/part/mapper/BomSearch3Mapper.java +++ b/src/main/java/com/xujie/sys/modules/part/mapper/BomSearch3Mapper.java @@ -6,6 +6,7 @@ import com.xujie.sys.modules.part.entity.*; import com.xujie.sys.modules.part.vo.BomComponentVo; import com.xujie.sys.modules.part.vo.BomDetailVo; import com.xujie.sys.modules.part.vo.BomHeaderVo; +import com.xujie.sys.modules.part.entity.PlmQuicklyBomInfoEntity; import com.xujie.sys.modules.quote.entity.QuoteDetailRouting; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -72,4 +73,24 @@ public interface BomSearch3Mapper { void saveStandardOperation(List collect); void updateCopyTempBom(CopyTempBom data); + + List queryOriginalBomNodeTree(@Param("site") String site, @Param("originalPartNo") String originalPartNo); + + void batchInsertQuicklyBomInfo(@Param("list") List list); + + void deleteBomHeaderForCopy(@Param("bomId") Long bomId, @Param("createBy") String createBy); + + void deleteBomDetailForCopy(@Param("bomId") Long bomId, @Param("createBy") String createBy); + + void deleteRoutingHeaderForCopy(@Param("bomId") Long bomId, @Param("createBy") String createBy); + + void deleteRoutingDetailForCopy(@Param("bomId") Long bomId, @Param("createBy") String createBy); + + void saveBomHeaderFromTemp(@Param("bomId") Long bomId, @Param("createBy") String createBy); + + void saveBomDetailFromTemp(@Param("bomId") Long bomId, @Param("createBy") String createBy); + + void saveRoutingHeaderFromTemp(@Param("bomId") Long bomId, @Param("createBy") String createBy); + + void saveRoutingDetailFromTemp(@Param("bomId") Long bomId, @Param("createBy") String createBy); } diff --git a/src/main/java/com/xujie/sys/modules/part/service/impl/BomSearch3ServiceImpl.java b/src/main/java/com/xujie/sys/modules/part/service/impl/BomSearch3ServiceImpl.java index 23af5cc2..541ce75f 100644 --- a/src/main/java/com/xujie/sys/modules/part/service/impl/BomSearch3ServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/part/service/impl/BomSearch3ServiceImpl.java @@ -593,11 +593,49 @@ public class BomSearch3ServiceImpl implements BomSearch3Service { if (!"Y".equals(bomTreeHeader.getChangeFlag())) { throw new RuntimeException("成品物料未变更!"); } - // 新增BOM + + log.info("=== 开始保存完整BOM数据 ==="); + log.info("原BOM物料: {}, 新BOM物料: {}", data.getPartNo(), bomTreeHeader.getPartNo()); + + // 步骤0: 清理已存在的数据(幂等性设计) + log.info("步骤0: 清理已存在的BOM数据"); + //bomSearch3Mapper.deleteBomHeaderForCopy(data.getBomId(), data.getCreateBy()); + bomSearch3Mapper.deleteBomDetailForCopy(data.getBomId(), data.getCreateBy()); + bomSearch3Mapper.deleteRoutingHeaderForCopy(data.getBomId(), data.getCreateBy()); + bomSearch3Mapper.deleteRoutingDetailForCopy(data.getBomId(), data.getCreateBy()); + + // 1. 新增BOM header(主表) + log.info("步骤1: 保存BOM header"); + //bomSearch3Mapper.saveBomHeaderFromTemp(data.getBomId(), data.getCreateBy()); + + // 2. 新增BOM detail(明细表) + log.info("步骤2: 保存BOM detail"); + bomSearch3Mapper.saveBomDetailFromTemp(data.getBomId(), data.getCreateBy()); + + // 3. 新增BOM component(子物料) + log.info("步骤3: 保存BOM component"); bomSearch3Mapper.saveBomComponentFromTemp(data.getBomId(), data.getCreateBy()); - // 新增Routing + + // 4. 新增Routing header(主表) + log.info("步骤4: 保存Routing header"); + bomSearch3Mapper.saveRoutingHeaderFromTemp(data.getBomId(), data.getCreateBy()); + + // 5. 新增Routing detail(明细表) + log.info("步骤5: 保存Routing detail"); + bomSearch3Mapper.saveRoutingDetailFromTemp(data.getBomId(), data.getCreateBy()); + + // 6. 新增Routing component(工艺路线) + log.info("步骤6: 保存Routing component"); bomSearch3Mapper.saveRoutingComponentFromTemp(data.getBomId(), data.getCreateBy()); - // 新增物料属性 + + // 7. 新增BOM节点树到快速创建BOM表 + log.info("步骤7: 保存BOM节点树"); + // data.getPartNo() = 原BOM的物料编码, bomTreeHeader.getPartNo() = 新BOM的物料编码 + saveQuicklyBomInfoFromTemp(data.getSite(), data.getPartNo(), bomTreeHeader.getPartNo(), data.getCreateBy()); + + log.info("=== 完整BOM数据保存完成 ==="); + + // 8. 新增物料属性 List itemValues = copyTempItemValueMapper.selectList(new LambdaQueryWrapper().eq(CopyTempItemValue::getTreeId, bomTreeHeader.getId())); if (!itemValues.isEmpty()) { for (CopyTempBomTree bomTree : bomTrees) { @@ -630,6 +668,69 @@ public class BomSearch3ServiceImpl implements BomSearch3Service { .eq(CopyTempItemValue::getCreateBy, data.getCreateBy())); } + /** + * 复制原BOM的节点树到新的mainPart下 + * @param site 站点 + * @param originalPartNo 原BOM物料编码(被复制的) + * @param newPartNo 新BOM物料编码(复制目标) + * @param createBy 创建人 + */ + private void saveQuicklyBomInfoFromTemp(String site, String originalPartNo, String newPartNo, String createBy) { + log.info("=== 开始复制BOM节点树到快速创建表 ==="); + log.info("site: {}, 原BOM物料: {}, 新BOM物料: {}, 创建人: {}", site, originalPartNo, newPartNo, createBy); + + // 查询原BOM的节点树结构 + List originalNodes = bomSearch3Mapper.queryOriginalBomNodeTree(site, originalPartNo); + + if (originalNodes.isEmpty()) { + log.warn("原BOM没有节点树数据,不执行复制。originalPartNo: {}", originalPartNo); + log.warn("这可能是因为原BOM不是通过快速创建BOM功能创建的"); + return; + } + + log.info("找到原BOM节点树,共{}个节点", originalNodes.size()); + + // 复制节点树,修改mainPart和part_no(根节点) + List newNodes = new ArrayList<>(); + for (PlmQuicklyBomInfoEntity originalNode : originalNodes) { + PlmQuicklyBomInfoEntity newNode = new PlmQuicklyBomInfoEntity(); + + // 复制所有字段(保留原节点结构) + newNode.setSite(originalNode.getSite()); + newNode.setTemplateNo(originalNode.getTemplateNo()); + newNode.setNodeId(originalNode.getNodeId()); + newNode.setNodeName(originalNode.getNodeName()); + newNode.setId(originalNode.getId()); + newNode.setpId(originalNode.getpId()); + newNode.setEngChgLevel(originalNode.getEngChgLevel()); + newNode.setRoutingRevision(originalNode.getRoutingRevision()); + newNode.setCreateBy(createBy); + + // 修改mainPart为新物料编码 + newNode.setMainPart(newPartNo); + + // 如果是根节点(p_id = '0'),修改part_no为新物料编码 + if ("0".equals(originalNode.getpId())) { + newNode.setPartNo(newPartNo); + log.info("复制根节点: id={}, 原partNo={} → 新partNo={}", + originalNode.getId(), originalNode.getPartNo(), newPartNo); + } else { + // 子节点保持原来的part_no + newNode.setPartNo(originalNode.getPartNo()); + log.debug("复制子节点: id={}, partNo={}", originalNode.getId(), originalNode.getPartNo()); + } + + newNodes.add(newNode); + } + + // 批量插入 + if (!newNodes.isEmpty()) { + bomSearch3Mapper.batchInsertQuicklyBomInfo(newNodes); + log.info("=== BOM节点树复制完成!共复制{}个节点 ===", newNodes.size()); + log.info("新BOM物料编码: {}, 可在quicklyCreateBom页面查看", newPartNo); + } + } + @Override @Transactional public void saveStandardOperationByCopy(CopyTempRouting data) { diff --git a/src/main/resources/mapper/part/BomSearch3Mapper.xml b/src/main/resources/mapper/part/BomSearch3Mapper.xml index d007be86..8682e24c 100644 --- a/src/main/resources/mapper/part/BomSearch3Mapper.xml +++ b/src/main/resources/mapper/part/BomSearch3Mapper.xml @@ -637,6 +637,156 @@ where tree_id = #{treeId} + + + delete from plm_bom_header + where site = (select top 1 site from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and bu_no = (select top 1 bu_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and part_no = (select top 1 part_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and eng_chg_level = (select top 1 eng_chg_level from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and bom_type = (select top 1 bom_type from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + + + + + insert into plm_bom_header + (site, bu_no, part_no, eng_chg_level, bom_type, note_text, eff_phase_in_date, eng_revision, type_flag, net_weight, create_date, create_by, process_unit) + select distinct + site, + bu_no, + part_no, + eng_chg_level, + bom_type, + null as note_text, + getDate() as eff_phase_in_date, + 1 as eng_revision, + null as type_flag, + 0 as net_weight, + getDate() as create_date, + #{createBy} as create_by, + null as process_unit + from plm_copy_temp_bom_tree + where bom_id = #{bomId} and username = #{createBy} and change_flag = 'Y' and level = 0 + + + + + delete from plm_bom_detail + where site = (select top 1 site from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and bu_no = (select top 1 bu_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and part_no = (select top 1 part_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and eng_chg_level = (select top 1 eng_chg_level from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and bom_type = (select top 1 bom_type from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + + + + + insert into plm_bom_detail + (site, bu_no, part_no, eng_chg_level, bom_type, alternative_no, alternative_description, status, min_lot_qty, default_flag, note_text, create_date, create_by) + select distinct + site, + bu_no, + part_no, + eng_chg_level, + bom_type, + alternative_no, + '*' as alternative_description, + 'Released' as status, + 1 as min_lot_qty, + 'Y' as default_flag, + null as note_text, + getDate() as create_date, + #{createBy} as create_by + from plm_copy_temp_bom_tree + where bom_id = #{bomId} and username = #{createBy} and change_flag = 'Y' and level = 0 + + + + + delete from plm_routing_header + where site = (select top 1 site from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and bu_no = (select top 1 bu_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and part_no = (select top 1 part_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and routing_revision = (select top 1 eng_chg_level from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and routing_type = (select top 1 bom_type from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + + + + + insert into plm_routing_header + (site, bu_no, part_no, routing_revision, routing_type, note_text, phase_in_date, create_date, create_by) + select distinct + site, + bu_no, + part_no, + eng_chg_level as routing_revision, + bom_type as routing_type, + null as note_text, + getDate() as phase_in_date, + getDate() as create_date, + #{createBy} as create_by + from plm_copy_temp_bom_tree + where bom_id = #{bomId} and username = #{createBy} and change_flag = 'Y' and level = 0 + + + + + delete from plm_routing_detail + where site = (select top 1 site from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and bu_no = (select top 1 bu_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and part_no = (select top 1 part_no from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and routing_revision = (select top 1 eng_chg_level from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + and routing_type = (select top 1 bom_type from plm_copy_temp_bom_tree where bom_id = #{bomId} and username = #{createBy} and level = 0) + + + + + insert into plm_routing_detail + (site, bu_no, part_no, routing_revision, routing_type, alternative_no, status, create_date, create_by) + select distinct + site, + bu_no, + part_no, + eng_chg_level as routing_revision, + bom_type as routing_type, + alternative_no, + 'Released' as status, + getDate() as create_date, + #{createBy} as create_by + from plm_copy_temp_bom_tree + where bom_id = #{bomId} and username = #{createBy} and change_flag = 'Y' and level = 0 + + + + + + + + INSERT INTO plm_quickly_bom_Info + (site, template_no, node_id, main_part, part_no, id, p_id, create_date, create_by, node_name, eng_chg_level, routing_revision) + VALUES + + (#{item.site}, #{item.templateNo}, #{item.nodeId}, #{item.mainPart}, #{item.partNo}, + #{item.id}, #{item.pId}, getDate(), #{item.createBy}, #{item.nodeName}, + #{item.engChgLevel}, #{item.routingRevision}) + + + update plm_copy_temp_bom set component_part = #{newPartNo}