From 1fc7fb52c53d1a3dd4bb555ed41102a9ec1e2379 Mon Sep 17 00:00:00 2001 From: aike <17730485278@139.com> Date: Tue, 24 Jun 2025 17:11:44 +0800 Subject: [PATCH] =?UTF-8?q?demand:=20=20=E6=89=AB=E6=8F=8F=E7=BB=84?= =?UTF-8?q?=E6=89=B9=E6=AC=A1=E8=A7=84=E5=88=99=E8=B0=83=E6=95=B4=20commit?= =?UTF-8?q?ter:=20heyu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../erp/emis/service/EmisBaseService.java | 22 +- .../impl/EmisTmsSiteBatchMissServiceImpl.java | 486 +----------------- .../mapper/EmisTmsSiteBatchDtlMapper.xml | 2 +- .../resources/mapper/EmisWaybillMapper.xml | 2 +- 4 files changed, 23 insertions(+), 489 deletions(-) diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java index 9be027760..9752c1d6d 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java @@ -4309,7 +4309,7 @@ public class EmisBaseService { } } - private void saveRecord(int totalProcessed, int successCount, int failCount, long processTime, + public void saveRecord(int totalProcessed, int successCount, int failCount, long processTime, List failedBillCodes, int totalBatchStatusRecords, int totalMissRecords) { EmisTmsSiteBatchMissRecord record = new EmisTmsSiteBatchMissRecord(); record.setTotalProcessed(totalProcessed); @@ -4327,7 +4327,7 @@ public class EmisBaseService { emisTmsSiteBatchMissRecordMapper.insertEmisTmsSiteBatchMissRecord(record); } - private static class ProcessResult { + public static class ProcessResult { private final int successCount; private final int failCount; private final List failedBillCodes; @@ -4364,7 +4364,7 @@ public class EmisBaseService { } } - private EmisBaseService.ProcessResult processWaybillBatch(List waybills, + public EmisBaseService.ProcessResult processWaybillBatch(List waybills, Map> transPlanRulesByLineCode) { int successCount = 0; int failCount = 0; @@ -4442,6 +4442,10 @@ public class EmisBaseService { // 合并相同起始网点和下一网点的批次 Map mergedBatches = new HashMap<>(); for (EmisTmsSiteBatch batch : waybillBatches) { + if (StringUtils.isAnyBlank(batch.getStartSiteCode(), batch.getNextSiteCode(), + batch.getSupplierCode())) { + continue; + } String key = batch.getStartSiteCode() + "_" + batch.getNextSiteCode(); if (mergedBatches.containsKey(key)) { EmisTmsSiteBatch existingBatch = mergedBatches.get(key); @@ -4511,6 +4515,18 @@ public class EmisBaseService { */ private boolean checkBranchMatch(List ruleList, List waybillBatches, EmisWaybill waybill, List missRecords) { + // 根据waybill的startSiteCode或sendSiteCode过滤ruleList + List filteredRuleList; + if (StringUtils.isNotBlank(waybill.getStartSiteCode())) { + filteredRuleList = ruleList.stream() + .filter(rule -> StringUtils.equals(rule.getStartSiteCode(), waybill.getStartSiteCode())) + .collect(Collectors.toList()); + } else { + filteredRuleList = ruleList.stream() + .filter(rule -> StringUtils.equals(rule.getStartSiteCode(), waybill.getSendSiteCode())) + .collect(Collectors.toList()); + } + ruleList = filteredRuleList; // 检查当前节点是否匹配 boolean allNodeMatched = false; List filterRules = Lists.newArrayList(); diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchMissServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchMissServiceImpl.java index 39b2de422..bb9628c70 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchMissServiceImpl.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchMissServiceImpl.java @@ -198,7 +198,7 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements // 创建新的线程池处理数据 executorService = Executors.newFixedThreadPool(processors); - List> processFutures = new ArrayList<>(); + List> processFutures = new ArrayList<>(); for (List batch : batches) { processFutures.add(executorService.submit(() -> processWaybillBatch(batch, transPlanRulesByLineCode))); @@ -207,7 +207,7 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements // 收集处理结果 List allBatchStatus = new ArrayList<>(); List allMissRecords = new ArrayList<>(); - for (Future future : processFutures) { + for (Future future : processFutures) { try { ProcessResult result = future.get(); successCount += result.getSuccessCount(); @@ -264,183 +264,6 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements } } - private void saveRecord(int totalProcessed, int successCount, int failCount, long processTime, - List failedBillCodes, int totalBatchStatusRecords, int totalMissRecords) { - EmisTmsSiteBatchMissRecord record = new EmisTmsSiteBatchMissRecord(); - record.setTotalProcessed(totalProcessed); - record.setSuccessCount(successCount); - record.setFailCount(failCount); - record.setProcessTime(processTime); - record.setTotalBatchStatusRecords(totalBatchStatusRecords); - record.setTotalMissRecords(totalMissRecords); - record.setFailedBillCodes( - CollectionUtil.isNotEmpty(failedBillCodes) ? String.join(",", failedBillCodes) : ""); - record.setCreateBy("system"); - record.setCreateTime(new Date()); - record.setCreateSite("88888"); - - emisTmsSiteBatchMissRecordMapper.insertEmisTmsSiteBatchMissRecord(record); - } - - private static class ProcessResult { - private final int successCount; - private final int failCount; - private final List failedBillCodes; - private final List batchStatusList; - private final List missRecords; - - public ProcessResult(int successCount, int failCount, List failedBillCodes, - List batchStatusList, List missRecords) { - this.successCount = successCount; - this.failCount = failCount; - this.failedBillCodes = failedBillCodes; - this.batchStatusList = batchStatusList; - this.missRecords = missRecords; - } - - public int getSuccessCount() { - return successCount; - } - - public int getFailCount() { - return failCount; - } - - public List getFailedBillCodes() { - return failedBillCodes; - } - - public List getBatchStatusList() { - return batchStatusList; - } - - public List getMissRecords() { - return missRecords; - } - } - - private ProcessResult processWaybillBatch(List waybills, - Map> transPlanRulesByLineCode) { - int successCount = 0; - int failCount = 0; - List failedBillCodes = new ArrayList<>(); - List missRecords = new ArrayList<>(); - List batchStatusList = new ArrayList<>(); - - // 获取所有运单号 - List billCodes = waybills.stream() - .map(EmisWaybill::getBillCode) - .collect(Collectors.toList()); - - // 一次性查询所有运单对应的组批次信息 - List siteBatches = emisTmsSiteBatchMapper - .selectEmisTmsSiteBatchListByBillCodes(billCodes); - - // 按运单号分组 - Map> siteBatchesByBillCode = new HashMap<>(); - for (EmisTmsSiteBatch batch : siteBatches) { - if (batch.getBatchDtlList() != null) { - for (EmisTmsSiteBatchDtl dtl : batch.getBatchDtlList()) { - siteBatchesByBillCode.computeIfAbsent(dtl.getBillCode(), k -> new ArrayList<>()).add(batch); - } - } - } - - for (EmisWaybill waybill : waybills) { - try { - // 获取运单对应的线路规划 - List ruleListByTransLineType = transPlanRulesByLineCode - .get(waybill.getTransLineType()); - if (CollectionUtil.isEmpty(ruleListByTransLineType)) { - // 创建漏组记录 - EmisTmsSiteBatchMiss miss = createMissRecord(waybill); - miss.setMissReason("当前线路没有创建对应的线路规划"); - miss.setMissType("1"); - miss.setLineCode(waybill.getTransLineType()); - miss.setProductType(waybill.getProductType()); - missRecords.add(miss); - successCount++; - continue; - } - - List ruleListByProductType = ruleListByTransLineType.stream() - .filter(i -> StringUtils.isNotBlank(i.getProductType()) - && i.getProductType().contains(waybill.getProductType())) - .collect(Collectors.toList()); - - if (CollectionUtil.isEmpty(ruleListByProductType)) { - // 创建漏组记录 - EmisTmsSiteBatchMiss miss = createMissRecord(waybill); - miss.setMissReason("当前线路没有创建对应的产品类型"); - miss.setMissType("1"); - miss.setLineCode(waybill.getTransLineType()); - miss.setProductType(waybill.getProductType()); - missRecords.add(miss); - successCount++; - continue; - } - - // 获取运单对应的组批次信息 - List waybillBatches = siteBatchesByBillCode.get(waybill.getBillCode()); - if (CollectionUtil.isEmpty(waybillBatches)) { - // 创建漏组记录 - EmisTmsSiteBatchMiss miss = createMissRecord(waybill); - miss.setMissReason("当前运单没有组批次"); - miss.setMissType("2"); - miss.setLineCode(waybill.getTransLineType()); - miss.setProductType(waybill.getProductType()); - missRecords.add(miss); - successCount++; - continue; - } - - // 合并相同起始网点和下一网点的批次 - Map mergedBatches = new HashMap<>(); - for (EmisTmsSiteBatch batch : waybillBatches) { - if (StringUtils.isAnyBlank(batch.getStartSiteCode(), batch.getNextSiteCode(), - batch.getSupplierCode())) { - continue; - } - String key = batch.getStartSiteCode() + "_" + batch.getNextSiteCode(); - if (mergedBatches.containsKey(key)) { - EmisTmsSiteBatch existingBatch = mergedBatches.get(key); - String existingSupplier = existingBatch.getSupplierCode(); - String newSupplier = batch.getSupplierCode(); - if (!existingSupplier.equals(newSupplier)) { - existingBatch.setSupplierCode(existingSupplier + "," + newSupplier); - } - } else { - mergedBatches.put(key, batch); - } - } - waybillBatches = new ArrayList<>(mergedBatches.values()); - - // 检查运单是否匹配线路规划树 - boolean isAnyBranchMatched = checkBranchMatch(ruleListByProductType, waybillBatches, waybill, - missRecords); - - if (isAnyBranchMatched) { - // 创建批次状态记录 - EmisWaybillBatchStatus batchStatus = new EmisWaybillBatchStatus(); - batchStatus.setBillCode(waybill.getBillCode()); - batchStatus.setSiteBatchStatus("1"); // 1表示匹配成功 - Date now = new Date(); - batchStatus.setCreateBy("system"); - batchStatus.setCreateTime(now); - batchStatus.setCreateSite("88888"); - batchStatusList.add(batchStatus); - } - successCount++; - } catch (Exception e) { - log.error("Failed to process waybill: {}", waybill.getBillCode(), e); - failCount++; - failedBillCodes.add(waybill.getBillCode()); - } - } - - return new ProcessResult(successCount, failCount, failedBillCodes, batchStatusList, missRecords); - } - public List selectEmisTransPlanRuleTree(String lineCode) { log.info("Start querying supplier route plan tree (multi-threaded)"); EmisTransPlanRule emisTransPlanRule = new EmisTransPlanRule(); @@ -473,309 +296,4 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements return tree; } - private EmisTmsSiteBatchMiss createMissRecord(EmisWaybill waybill) { - EmisTmsSiteBatchMiss miss = new EmisTmsSiteBatchMiss(); - miss.setBillCode(waybill.getBillCode()); - Date now = new Date(); - miss.setCreateBy("system"); - miss.setCreateTime(now); - miss.setCreateSite("88888"); - return miss; - } - - /** - * 检查一个分支是否完全匹配 - * - * @param waybillBatches 运单批次列表 - * @param waybill - * @param missRecords - * @return 是否匹配 - */ - private boolean checkBranchMatch(List ruleList, List waybillBatches, - EmisWaybill waybill, List missRecords) { - // 检查当前节点是否匹配 - boolean allNodeMatched = false; - List filterRules = Lists.newArrayList(); - for (EmisTransPlanRule rule : ruleList) { - List list = Lists.newArrayList(); - if (checkRule(rule, waybillBatches, list)) { - allNodeMatched = true; - break; - } - if (list.size() > filterRules.size()) { - filterRules = list; - } - } - if (allNodeMatched) { - return allNodeMatched; - } - if (CollectionUtil.isEmpty(filterRules)) { - // 创建漏组记录 - EmisTmsSiteBatchMiss miss = createMissRecord(waybill); - miss.setMissReason("该运单所有组批次信息都不匹配,请仔细核对"); - miss.setMissType("3"); - miss.setLineCode(waybill.getTransLineType()); - miss.setProductType(waybill.getProductType()); - missRecords.add(miss); - return false; - } - EmisTransPlanRule filterRule = filterRules.get(0); - Long ancestor; - if (StringUtils.isEmpty(filterRule.getAncestors())) { - ancestor = filterRule.getId(); - } else { - String[] ancestors = filterRule.getAncestors().split(","); - ancestor = Long.valueOf(ancestors[0]); - } - - List rules = ruleList.stream().filter(i -> i.getId().equals(ancestor)) - .collect(Collectors.toList()); - EmisTransPlanRule rule = rules.get(0); - setMissRecords(missRecords, rule, filterRules, waybill); - return false; - } - - /** - * 比较两个供应商代码字符串是否包含相同的供应商(忽略顺序) - * - * @param supplierCode1 第一个供应商代码字符串 - * @param supplierCode2 第二个供应商代码字符串 - * @return 如果包含相同的供应商返回true,否则返回false - */ - private boolean compareSupplierCodes(String supplierCode1, String supplierCode2) { - if (supplierCode1 == null || supplierCode2 == null) { - return supplierCode1 == supplierCode2; - } - Set suppliers1 = Arrays.stream(supplierCode1.split(",")) - .map(String::trim) - .collect(Collectors.toSet()); - Set suppliers2 = Arrays.stream(supplierCode2.split(",")) - .map(String::trim) - .collect(Collectors.toSet()); - return suppliers1.equals(suppliers2); - } - - private boolean checkRule(EmisTransPlanRule rule, List waybillBatches, - List list) { - // 检查当前节点是否匹配 - boolean currentMatch = false; - for (EmisTmsSiteBatch batch : waybillBatches) { - if (rule.getStartSiteCode().equals(batch.getStartSiteCode()) && - rule.getNextSiteCode().equals(batch.getNextSiteCode()) && - compareSupplierCodes(rule.getSupplierCode(), batch.getSupplierCode()) - && batch.getEtd().before(rule.getEndDate()) - && !batch.getEtd().before(rule.getStartDate())) { - currentMatch = true; - list.add(rule); - break; - } - } - - // 如果是叶子节点,返回当前节点的匹配结果 - if (CollectionUtil.isEmpty(rule.getChildren())) { - return currentMatch; - } - - // 获取当前节点的所有直接子节点(第一级) - Set firstLevelRules = new HashSet<>(rule.getChildren()); - - // 检查第一级是否至少有一个节点匹配 - boolean hasFirstLevelMatch = false; - // 收集所有第一级节点的子节点(第二级) - Set secondLevelRules = new HashSet<>(); - - for (EmisTransPlanRule firstLevelRule : firstLevelRules) { - // 检查第一级节点是否匹配 - boolean firstLevelMatch = false; - for (EmisTmsSiteBatch batch : waybillBatches) { - if (firstLevelRule.getStartSiteCode().equals(batch.getStartSiteCode()) && - firstLevelRule.getNextSiteCode().equals(batch.getNextSiteCode()) && - compareSupplierCodes(firstLevelRule.getSupplierCode(), batch.getSupplierCode()) - && batch.getEtd().before(firstLevelRule.getEndDate()) - && !batch.getEtd().before(firstLevelRule.getStartDate())) { - firstLevelMatch = true; - list.add(firstLevelRule); - break; - } - } - - if (firstLevelMatch) { - hasFirstLevelMatch = true; - } - - // 收集当前第一级节点的所有子节点到第二级集合中 - if (!CollectionUtil.isEmpty(firstLevelRule.getChildren())) { - secondLevelRules.addAll(firstLevelRule.getChildren()); - } - } - - // 如果第二级为空,说明已经到底了,返回当前节点匹配且第一级至少有一个匹配的结果 - if (secondLevelRules.isEmpty()) { - return currentMatch && hasFirstLevelMatch; - } - - // 检查第二级是否至少有一个节点匹配 - boolean hasSecondLevelMatch = false; - // 收集所有第二级节点的子节点(第三级) - Set thirdLevelRules = new HashSet<>(); - - for (EmisTransPlanRule secondLevelRule : secondLevelRules) { - // 检查第二级节点是否匹配 - boolean secondLevelMatch = false; - for (EmisTmsSiteBatch batch : waybillBatches) { - if (secondLevelRule.getStartSiteCode().equals(batch.getStartSiteCode()) && - secondLevelRule.getNextSiteCode().equals(batch.getNextSiteCode()) && - compareSupplierCodes(secondLevelRule.getSupplierCode(), batch.getSupplierCode()) - && batch.getEtd().before(secondLevelRule.getEndDate()) - && !batch.getEtd().before(secondLevelRule.getStartDate())) { - secondLevelMatch = true; - list.add(secondLevelRule); - break; - } - } - - if (secondLevelMatch) { - hasSecondLevelMatch = true; - } - - // 收集当前第二级节点的所有子节点到第三级集合中 - if (!CollectionUtil.isEmpty(secondLevelRule.getChildren())) { - thirdLevelRules.addAll(secondLevelRule.getChildren()); - } - } - - // 递归处理下一级,并收集结果 - boolean hasNextLevelMatch = checkNextLevel(thirdLevelRules, waybillBatches, list); - - // 返回当前节点匹配且每一级都至少有一个匹配的结果 - return currentMatch && hasFirstLevelMatch && hasSecondLevelMatch && hasNextLevelMatch; - } - - /** - * 递归检查下一级节点 - */ - private boolean checkNextLevel(Set currentLevelRules, - List waybillBatches, List list) { - // 如果当前级为空,说明已经到底了,返回true - if (currentLevelRules.isEmpty()) { - return true; - } - - // 检查当前级是否至少有一个节点匹配 - boolean hasCurrentLevelMatch = false; - // 收集所有当前级节点的子节点(下一级) - Set nextLevelRules = new HashSet<>(); - - for (EmisTransPlanRule currentLevelRule : currentLevelRules) { - // 检查当前级节点是否匹配 - boolean currentLevelMatch = false; - for (EmisTmsSiteBatch batch : waybillBatches) { - if (currentLevelRule.getStartSiteCode().equals(batch.getStartSiteCode()) && - currentLevelRule.getNextSiteCode().equals(batch.getNextSiteCode()) && - compareSupplierCodes(currentLevelRule.getSupplierCode(), batch.getSupplierCode()) - && batch.getEtd().before(currentLevelRule.getEndDate()) - && !batch.getEtd().before(currentLevelRule.getStartDate())) { - currentLevelMatch = true; - list.add(currentLevelRule); - break; - } - } - - if (currentLevelMatch) { - hasCurrentLevelMatch = true; - } - - // 收集当前级节点的所有子节点到下一级集合中 - if (!CollectionUtil.isEmpty(currentLevelRule.getChildren())) { - nextLevelRules.addAll(currentLevelRule.getChildren()); - } - } - - // 递归处理下一级,并收集结果 - boolean hasNextLevelMatch = checkNextLevel(nextLevelRules, waybillBatches, list); - - // 返回当前级至少有一个匹配且下一级匹配的结果 - return hasCurrentLevelMatch && hasNextLevelMatch; - } - - private void setMissRecords(List missRecords, EmisTransPlanRule rule, - List filterRules, EmisWaybill waybill) { - // 检查当前节点是否在filterRules中 - boolean isMatched = filterRules.stream() - .anyMatch(filterRule -> filterRule.getStartSiteCode().equals(rule.getStartSiteCode()) && - filterRule.getNextSiteCode().equals(rule.getNextSiteCode()) && - compareSupplierCodes(filterRule.getSupplierCode(), rule.getSupplierCode())); - - if (!isMatched) { - // 创建漏组记录 - EmisTmsSiteBatchMiss miss = createMissRecord(waybill); - miss.setMissReason(String.format("组批次有遗漏/错误,请根据推荐路线排查: %s-%s-%s", - rule.getStartSiteName(), - rule.getNextSiteName(), - rule.getSupplierName())); - setRule(rule, miss); - missRecords.add(miss); - } - - List childrens = rule.getChildren(); - if (CollectionUtil.isEmpty(childrens)) { - return; - } - // 递归处理子节点 - checkChildrens(missRecords, childrens, filterRules, waybill); - } - - private static void setRule(EmisTransPlanRule rule, EmisTmsSiteBatchMiss miss) { - miss.setTransPlanRuleId(rule.getId()); - miss.setLineCode(rule.getLineCode()); - miss.setProductType(rule.getProductType()); - miss.setStartSiteCode(rule.getStartSiteCode()); - miss.setNextSiteCode(rule.getNextSiteCode()); - miss.setManager(rule.getManager()); - miss.setSupplierCode(rule.getSupplierCode()); - miss.setStartDate(rule.getStartDate()); - miss.setEndDate(rule.getEndDate()); - miss.setMissType("0"); - } - - private void checkChildrens(List missRecords, List childrens, - List filterRules, EmisWaybill waybill) { - // 检查子节点是否至少有一个匹配 - boolean hasMatchedChild = childrens.stream() - .anyMatch(childRule -> filterRules.stream() - .anyMatch( - filterRule -> filterRule.getStartSiteCode().equals(childRule.getStartSiteCode()) && - filterRule.getNextSiteCode().equals(childRule.getNextSiteCode()) && - compareSupplierCodes(filterRule.getSupplierCode(), - childRule.getSupplierCode()))); - - if (!hasMatchedChild) { - // 如果所有子节点都不匹配,为每个子节点创建漏组记录 - StringBuilder missReason = new StringBuilder("组批次有遗漏/错误,请根据推荐路线排查: "); - for (int i = 0; i < childrens.size(); i++) { - EmisTransPlanRule childRule = childrens.get(i); - if (i > 0) { - missReason.append(" 或 "); - } - missReason.append(String.format("%s-%s-%s", - childRule.getStartSiteName(), - childRule.getNextSiteName(), - childRule.getSupplierName())); - } - - // 创建漏组记录 - EmisTmsSiteBatchMiss miss = createMissRecord(waybill); - miss.setMissReason(missReason.toString()); - setRule(childrens.get(0), miss); - missRecords.add(miss); - } - - // 递归处理所有子节点 - for (EmisTransPlanRule child : childrens) { - List childList = child.getChildren(); - if (!CollectionUtil.isEmpty(childList)) { - checkChildrens(missRecords, childList, filterRules, waybill); - } - } - } } \ No newline at end of file diff --git a/emis-biz/src/main/resources/mapper/EmisTmsSiteBatchDtlMapper.xml b/emis-biz/src/main/resources/mapper/EmisTmsSiteBatchDtlMapper.xml index 9db188fac..db75737e1 100644 --- a/emis-biz/src/main/resources/mapper/EmisTmsSiteBatchDtlMapper.xml +++ b/emis-biz/src/main/resources/mapper/EmisTmsSiteBatchDtlMapper.xml @@ -186,7 +186,7 @@ - select a.id, a.bill_code,a.trans_line_type, a.product_type + select a.id, a.bill_code,a.trans_line_type, a.product_type,a.start_site_code,a.send_site_code from emis_waybill a left join emis_waybill_batch_status b on a.bill_code = b.bill_code where a.bl_sign = '1'