Browse Source

Merge remote-tracking branch 'origin/master'

master
Rui_Li 2 weeks ago
parent
commit
1b3fbcb95c
  1. 86
      src/main/java/com/spring/modules/quote/service/impl/QuoteDetailBomTreeServiceImpl.java

86
src/main/java/com/spring/modules/quote/service/impl/QuoteDetailBomTreeServiceImpl.java

@ -50,6 +50,9 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl<QuoteDetailBomTre
@Autowired
private QuoteDetailToolMapper quoteDetailToolMapper;
@Autowired
private org.springframework.transaction.support.TransactionTemplate transactionTemplate;
private Server server = null;
/** IFS 成本查询并行线程数,限制 4 路并发,避免对 IFS 造成过大压力 */
@ -332,12 +335,14 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl<QuoteDetailBomTre
// =========================================================================
@Override
@Transactional
public void changeQuoteDetailBomTree(QuoteDetailBomTree tree) {
QuoteDetail detail = null;
BomNodeData nodeData = null;
Long newParentId = 0L;
QuoteDetailBomTree bomTree = null;
if (Objects.nonNull(tree.getId())) {
QuoteDetailBomTree bomTree = getById(tree.getId());
bomTree = getById(tree.getId());
detail = quoteDetailService.getById(bomTree.getQuoteDetailId());
detail.setPartNo(tree.getPartNo());
@ -349,25 +354,9 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl<QuoteDetailBomTre
// 先在事务外完成所有 IFS 调用和数据收集避免 IFS 阻塞期间持有数据库行锁
Supplier<Server> ifsConFactory = resolveIfsConFactory();
Long newParentId = bomTree.getParentId();
newParentId = bomTree.getParentId();
Integer newLevel = Optional.ofNullable(tree.getLevel()).orElse(0);
BomNodeData nodeData = collectBomData(detail, newParentId, newLevel, ifsConFactory);
// 数据已就绪开始执行 DML事务持有锁的时间仅限于纯 DB 写入阶段
List<Long> ids = getAllChildIds(detail, bomTree.getId());
ids.add(bomTree.getId());
lambdaUpdate().in(QuoteDetailBomTree::getId, ids).remove();
quoteDetailBomService.lambdaUpdate().in(QuoteDetailBom::getTreeId, ids).remove();
quoteDetailRoutingService.lambdaUpdate().in(QuoteDetailRouting::getTreeId, ids).remove();
long bomId = 0;
if (nodeData != null) {
bomId = doSaveBomDataRecursive(nodeData, detail, newParentId);
}
quoteDetailBomService.lambdaUpdate()
.set(QuoteDetailBom::getBomId, bomId)
.eq(QuoteDetailBom::getBomId, bomTree.getId())
.update();
nodeData = collectBomData(detail, newParentId, newLevel, ifsConFactory);
} else {
detail = new QuoteDetail();
detail.setQuoteId(tree.getQuoteId());
@ -383,22 +372,53 @@ public class QuoteDetailBomTreeServiceImpl extends ServiceImpl<QuoteDetailBomTre
// 先收集数据再写入
Supplier<Server> ifsConFactory = resolveIfsConFactory();
BomNodeData nodeData = collectBomData(detail, 0L, 0, ifsConFactory);
if (nodeData != null) {
doSaveBomDataRecursive(nodeData, detail, 0L);
}
nodeData = collectBomData(detail, 0L, 0, ifsConFactory);
}
if (Boolean.TRUE.equals(tree.getRecalculateCost()) && detail != null) {
log.info("[BOM_SWITCH] Recalculate cost is enabled, executing cost calculation for QuoteDetailId: {}", detail.getId());
try {
quoteDetailService.queryQuoteDetailCost(detail);
log.info("[BOM_SWITCH] Cost calculation completed successfully for QuoteDetailId: {}", detail.getId());
} catch (Exception e) {
log.error("[BOM_SWITCH] Cost calculation failed for QuoteDetailId: {}, Error: {}", detail.getId(), e.getMessage(), e);
throw new RuntimeException("成本计算失败: " + e.getMessage());
// 数据已就绪开启短事务执行纯 DB 写入和成本计算
final QuoteDetail finalDetail = detail;
final BomNodeData finalNodeData = nodeData;
final Long finalNewParentId = newParentId;
final QuoteDetailBomTree finalBomTree = bomTree;
transactionTemplate.execute(status -> {
// 1. 执行 BOM 结构切换的 DB 写入
if (Objects.nonNull(tree.getId())) {
List<Long> ids = getAllChildIds(finalDetail, finalBomTree.getId());
ids.add(finalBomTree.getId());
lambdaUpdate().in(QuoteDetailBomTree::getId, ids).remove();
quoteDetailBomService.lambdaUpdate().in(QuoteDetailBom::getTreeId, ids).remove();
quoteDetailRoutingService.lambdaUpdate().in(QuoteDetailRouting::getTreeId, ids).remove();
long bomId = 0;
if (finalNodeData != null) {
bomId = doSaveBomDataRecursive(finalNodeData, finalDetail, finalNewParentId);
}
quoteDetailBomService.lambdaUpdate()
.set(QuoteDetailBom::getBomId, bomId)
.eq(QuoteDetailBom::getBomId, finalBomTree.getId())
.update();
} else {
if (finalNodeData != null) {
doSaveBomDataRecursive(finalNodeData, finalDetail, 0L);
}
}
}
// 2. 重新计算成本 (如果开启)
// 将其放在同一个事务中如果计算失败BOM 切换也会一并回滚保证数据一致性
if (Boolean.TRUE.equals(tree.getRecalculateCost()) && finalDetail != null) {
log.info("[BOM_SWITCH] Recalculate cost is enabled, executing cost calculation for QuoteDetailId: {}", finalDetail.getId());
try {
quoteDetailService.queryQuoteDetailCost(finalDetail);
log.info("[BOM_SWITCH] Cost calculation completed successfully for QuoteDetailId: {}", finalDetail.getId());
} catch (Exception e) {
log.error("[BOM_SWITCH] Cost calculation failed for QuoteDetailId: {}, Error: {}", finalDetail.getId(), e.getMessage(), e);
// 抛出 RuntimeException 以触发 transactionTemplate 回滚
throw new RuntimeException("成本计算失败: " + e.getMessage());
}
}
return null;
});
}
// =========================================================================

Loading…
Cancel
Save