diff --git a/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailBomTreeServiceImpl.java b/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailBomTreeServiceImpl.java index 4d13c83a..bf10d15b 100644 --- a/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailBomTreeServiceImpl.java +++ b/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailBomTreeServiceImpl.java @@ -104,7 +104,8 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl ifsConFactory = resolveIfsConFactory(); - BomNodeData rootNode = collectBomData(detail, parentId, level, ifsConFactory); + Map costCache = new ConcurrentHashMap<>(); + BomNodeData rootNode = collectBomData(detail, parentId, level, ifsConFactory, costCache); if (rootNode == null) { return 0; } @@ -128,7 +129,7 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl ifsConFactory) { + private BomNodeData collectBomData(QuoteDetail detail, Long parentId, Integer level, Supplier ifsConFactory, Map costCache) { // 确定 BOM 类型 if (parentId.equals(0L)) { detail.setBomType("Manufacturing"); @@ -189,7 +190,7 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl ifsConFactory = resolveIfsConFactory(); newParentId = bomTree.getParentId(); Integer newLevel = Optional.ofNullable(tree.getLevel()).orElse(0); - nodeData = collectBomData(detail, newParentId, newLevel, ifsConFactory); + Map costCache = new ConcurrentHashMap<>(); + nodeData = collectBomData(detail, newParentId, newLevel, ifsConFactory, costCache); + log.info("[PERF_LOG] Phase 1: collectBomData (including IFS calls) took {} ms", (System.currentTimeMillis() - collectStartTime)); } else { detail = new QuoteDetail(); detail.setQuoteId(tree.getQuoteId()); @@ -371,8 +378,11 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl ifsConFactory = resolveIfsConFactory(); - nodeData = collectBomData(detail, 0L, 0, ifsConFactory); + Map costCache = new ConcurrentHashMap<>(); + nodeData = collectBomData(detail, 0L, 0, ifsConFactory, costCache); + log.info("[PERF_LOG] Phase 1: collectBomData (including IFS calls) took {} ms", (System.currentTimeMillis() - collectStartTime)); } // 数据已就绪,开启短事务执行纯 DB 写入和成本计算 @@ -381,6 +391,7 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl { // 1. 执行 BOM 结构切换的 DB 写入 if (Objects.nonNull(tree.getId())) { @@ -400,24 +411,30 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl costCache) { final int MAX_RETRY_COUNT = 2; final long RETRY_INTERVAL_MS = 500; String partNo = component.getComponentPart(); String site = component.getSite(); + + String cacheKey = site + "_" + partNo; + BigDecimal cachedCost = costCache.get(cacheKey); + if (cachedCost != null) { + component.setUnitPrice(cachedCost); + component.setActualPrice(cachedCost); + component.setQuotePrice(cachedCost); + log.info("[COST_QUERY] 从缓存读取成功 - PartNo: {}, Site: {}, UnitCost: {}", partNo, site, cachedCost); + return; + } log.info("[COST_QUERY] 开始查询物料成本 - PartNo: {}, Site: {}", partNo, site); @@ -723,6 +750,7 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl queryQuoteDetailCost(QuoteDetail detail) { - log.info("========== [COST_CALC] START - QuoteDetailId: {} ==========", detail.getId()); + long perfTotalStartTime = System.currentTimeMillis(); + log.info("========== [COST_CALC] [PERF_LOG] START - QuoteDetailId: {} ==========", detail.getId()); QuoteDetail quoteDetail = getById(detail.getId()); Map map = new HashMap<>(); + + // 用于缓存IFS接口获取的物料预估成本,避免在循环中重复调用降低性能 + Map estimatedCostCache = new HashMap<>(); + + long perfAttrStartTime = System.currentTimeMillis(); // 1、工具成本 BigDecimal toolCost = computedToolCost(quoteDetail.getId()); // 2、其他成本 @@ -218,9 +224,15 @@ public class QuoteDetailServiceImpl extends ServiceImpl roots = quoteDetailBomTreeService.lambdaQuery() .eq(QuoteDetailBomTree::getQuoteDetailId, quoteDetail.getId()) - .eq(QuoteDetailBomTree::getParentId, 0L).one(); + .eq(QuoteDetailBomTree::getParentId, 0L) + .orderByDesc(QuoteDetailBomTree::getId) + .list(); + QuoteDetailBomTree one = roots.isEmpty() ? null : roots.get(0); // 3、工艺成本 BigDecimal labourCost = BigDecimal.ZERO;// 人工成本 @@ -237,12 +249,13 @@ public class QuoteDetailServiceImpl extends ServiceImpl routingList = quoteDetailRoutingService.queryQuoteDetailRouting(queryRouting); Map> routingMap = routingList.stream().collect(Collectors.groupingBy(QuoteDetailRouting::getTreeId)); - log.info("[COST_CALC] Total routing records loaded: {}", routingList.size()); + log.info("[COST_CALC] [PERF_LOG] Fetching and grouping {} Routing records took {} ms", routingList.size(), (System.currentTimeMillis() - perfRoutingStartTime)); + long perfBomStartTime = System.currentTimeMillis(); // 查询 BOM QuoteDetailBom quoteDetailBom = new QuoteDetailBom(); quoteDetailBom.setQuoteDetailId(quoteDetail.getId()); @@ -259,10 +273,14 @@ public class QuoteDetailServiceImpl extends ServiceImpl bomList = quoteDetailBomService.queryQuoteDetailBom(quoteDetailBom); Map> bomMap = bomList.stream().collect(Collectors.groupingBy(QuoteDetailBom::getTreeId)); - log.info("[COST_CALC] Total BOM component records loaded: {}", bomList.size()); + log.info("[COST_CALC] [PERF_LOG] Fetching and grouping {} BOM component records took {} ms", bomList.size(), (System.currentTimeMillis() - perfBomStartTime)); long treeId = 0; int nodeIndex = 0; + + long perfConvolutionStartTime = System.currentTimeMillis(); + long totalUpdateDbTime = 0; + // 第一层BOM for (QuoteDetailBomTree bomTree : list) { nodeIndex++; @@ -307,8 +325,13 @@ public class QuoteDetailServiceImpl extends ServiceImpl { + long ifsStart = System.currentTimeMillis(); + BigDecimal cost = quoteDetailBomTreeService.queryEstimatedMaterialCost(bomTree.getSite(), bomTree.getPartNo()); + log.info("[COST_CALC] [PERF_LOG] Fetched estimated material cost for {} from IFS/DB in {} ms", bomTree.getPartNo(), (System.currentTimeMillis() - ifsStart)); + return cost == null ? BigDecimal.ZERO : cost; + }); bomQuotePrice = bomQuotePrice.add(estimatedMaterialCost); log.info("[COST_CALC] Semi-finished product {} is Purchase type, add estimated material cost {}, accumulated cost is {}", bomTree.getPartNo(), estimatedMaterialCost, bomQuotePrice); @@ -353,12 +376,11 @@ public class QuoteDetailServiceImpl extends ServiceImpl