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 4b44abbd6..af9a009a4 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 @@ -4205,28 +4205,31 @@ public class EmisBaseService { cyclePath.add(source.getId()); // 构建详细的错误信息 - StringBuilder errorMsg = new StringBuilder(); - errorMsg.append("检测到循环引用!循环路径:"); - for (int i = 0; i < cyclePath.size(); i++) { - if (i > 0) { - errorMsg.append(" -> "); - } - Long id = cyclePath.get(i); - EmisTransPlanRule node = findNodeById(id); - if (node != null) { - errorMsg.append(node.getLineName()).append("-") - .append(node.getProductTypeName()).append("-") - .append(node.getStartSiteName()).append("-") - .append(node.getNextSiteName()).append("-") - .append(node.getSupplierName()); - } else { - errorMsg.append("节点ID:").append(id); - } - } - errorMsg.append("\n循环引用发生在节点,详细信息见上"); - throw new RuntimeException(errorMsg.toString()); - } - } + StringBuilder errorMsg = new StringBuilder(); + errorMsg.append("检测到循环引用!循环路径:"); + for (int i = 0; i < cyclePath.size(); i++) { + if (i > 0) { + errorMsg.append(" -> "); + } + Long id = cyclePath.get(i); + if (id == null) { + continue; + } + EmisTransPlanRule node = findNodeById(id); + if (node != null) { + errorMsg.append(node.getLineName()).append("-") + .append(node.getProductTypeName()).append("-") + .append(node.getStartSiteName()).append("-") + .append(node.getNextSiteName()).append("-") + .append(node.getSupplierName()); + } else { + errorMsg.append("节点ID:").append(id); + } + } +// errorMsg.append("\n循环引用发生在节点,详细信息见上"); + throw new RuntimeException(errorMsg.toString()); + } + } // 添加到已访问集合和路径中 visitedIds.add(source.getId()); diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTransPlanRuleServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTransPlanRuleServiceImpl.java index 73ebe794c..7b2c30c61 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTransPlanRuleServiceImpl.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTransPlanRuleServiceImpl.java @@ -98,7 +98,18 @@ public class EmisTransPlanRuleServiceImpl extends EmisBaseService implements IEm * @return 结果 */ @Override - public int updateEmisTransPlanRule(EmisTransPlanRule emisTransPlanRule) { + public int updateEmisTransPlanRule(EmisTransPlanRule emisTransPlanRule) throws EmisBizError { + // 校验非空 + checkCode(emisTransPlanRule); + checkDate(emisTransPlanRule); + // 检查重复 + checkDuplicate(emisTransPlanRule); + // 校验循环引用 + EmisTransPlanRule checkRule = new EmisTransPlanRule(); + checkRule.setProductType(emisTransPlanRule.getProductType()); + List allRules = emisTransPlanRuleMapper.selectEmisTransPlanRuleListWithoutName(checkRule); + allRules.add(emisTransPlanRule); + buildTree(allRules, emisTransPlanRule); return emisTransPlanRuleMapper.updateEmisTransPlanRule(emisTransPlanRule); } @@ -362,276 +373,7 @@ public class EmisTransPlanRuleServiceImpl extends EmisBaseService implements IEm } } - // public List buildTree(List allRules, - // EmisTransPlanRule emisTransPlanRule) { - // // 按lineCode分组 - // Map> groupByLine = allRules.stream() - // .collect(Collectors.groupingBy(EmisTransPlanRule::getLineCode)); - // - // List result = new ArrayList<>(); - // - // // 处理每个lineCode分组 - // for (Map.Entry> lineEntry : - // groupByLine.entrySet()) { - // List lineRules = lineEntry.getValue(); - // if (lineRules.isEmpty()) { - // continue; - // } - // - // // - // 按productType分组(支持productType和productTypeName为逗号分隔的多个类型,且一一对应,且每个rule只保留一个type和typeName) - // Map> groupByProductType = new HashMap<>(); - // for (EmisTransPlanRule rule : lineRules) { - // if (rule.getProductType() != null) { - // String[] types = rule.getProductType().split(","); - // String[] typeNames = rule.getProductTypeName() != null ? - // rule.getProductTypeName().split(",") - // : new String[0]; - // for (int i = 0; i < types.length; i++) { - // String type = types[i].trim(); - // if (!type.isEmpty()) { - // EmisTransPlanRule newRule = new EmisTransPlanRule(); - // BeanUtils.copyProperties(rule, newRule); - // newRule.setProductType(type); - // if (i < typeNames.length) { - // newRule.setProductTypeName(typeNames[i].trim()); - // } else { - // newRule.setProductTypeName(null); - // } - // groupByProductType.computeIfAbsent(type, k -> new - // ArrayList<>()).add(newRule); - // } - // } - // } - // } - // // - // 分组内去重(lineCode、productType、startSiteCode、nextSiteCode、supplierCode、startDate、endDate都相同只保留一条) - // for (Map.Entry> entry : - // groupByProductType.entrySet()) { - // List rules = entry.getValue(); - // Set uniqueKeys = new HashSet<>(); - // List deduped = new ArrayList<>(); - // for (EmisTransPlanRule rule : rules) { - // String key = (rule.getLineCode() == null ? "" : rule.getLineCode()) + "|" - // + (rule.getProductType() == null ? "" : rule.getProductType()) + "|" - // + (rule.getStartSiteCode() == null ? "" : rule.getStartSiteCode()) + "|" - // + (rule.getNextSiteCode() == null ? "" : rule.getNextSiteCode()) + "|" - // + (rule.getSupplierCode() == null ? "" : rule.getSupplierCode()) + "|" - // + (rule.getStartDate() == null ? "" : rule.getStartDate().toString()) + "|" - // + (rule.getEndDate() == null ? "" : rule.getEndDate().toString()); - // if (uniqueKeys.add(key)) { - // deduped.add(rule); - // } - // } - // entry.setValue(deduped); - // } - // - // Map> tempMap = new HashMap<>(); - // if (StringUtil.isNotBlank(emisTransPlanRule.getProductType())) { - // Iterator>> iterator = - // groupByProductType.entrySet() - // .iterator(); - // while (iterator.hasNext()) { - // Map.Entry> entry = iterator.next(); - // if (emisTransPlanRule.getProductType().equals(entry.getKey())) { - // tempMap.put(entry.getKey(), entry.getValue()); - // groupByProductType = tempMap; - // break; - // } - // } - // } - // - // // 处理每个productType分组 - // for (Map.Entry> productEntry : - // groupByProductType.entrySet()) { - // List productRules = productEntry.getValue(); - // - // // 构建站点关系树 - // Map> nodeMap = new HashMap<>(); - // for (EmisTransPlanRule rule : productRules) { - // String key = rule.getNextSiteCode() != null ? rule.getNextSiteCode() : - // rule.getStartSiteCode(); - // if (key != null) { - // nodeMap.computeIfAbsent(key, k -> new ArrayList<>()).add(rule); - // } - // } - // - // // 按startSiteCode分组,找出所有可能的父节点 - // Map> parentGroups = productRules.stream() - // .filter(rule -> rule.getStartSiteCode() != null) - // .collect(Collectors.groupingBy(EmisTransPlanRule::getStartSiteCode)); - // - // // 设置父子关系 - // for (Map.Entry> parentGroup : - // parentGroups.entrySet()) { - // String startSiteCode = parentGroup.getKey(); - // List children = parentGroup.getValue(); - // - // // 获取所有可能的父节点 - // List parents = nodeMap.get(startSiteCode); - // if (parents != null) { - // for (EmisTransPlanRule parent : parents) { - // if (parent.getChildren() == null) { - // parent.setChildren(new ArrayList<>()); - // } - // - // // 添加所有子节点到父节点的children列表中 - // for (EmisTransPlanRule child : children) { - // if (!parent.getChildren().contains(child)) { - // parent.getChildren().add(child); - // } - // } - // } - // } - // } - // - // // 找出顶级节点(没有父节点的节点) - // List topLevelNodes = productRules.stream() - // .filter(rule -> { - // // 检查该节点是否作为其他节点的子节点 - // boolean isChild = productRules.stream() - // .anyMatch(potential -> potential.getChildren() != null - // && potential.getChildren().contains(rule)); - // return !isChild; - // }) - // .collect(Collectors.toList()); - // - // // 将顶级节点直接添加到结果中(进行深度复制) - // for (EmisTransPlanRule node : topLevelNodes) { - // result.add(deepCopyNode(node)); - // } - // } - // } - // - // // 递归设置父ID和祖先节点ID(以treeId为准) - // for (EmisTransPlanRule root : result) { - // setParentAndAncestors(root, null, ""); - // } - // - // return result; - // } - // - // /** - // * 递归设置父ID和祖先节点ID - // * - // * @param node 当前节点 - // * @param parentId 父节点ID - // * @param ancestors 祖先节点ID字符串 - // */ - // private void setParentAndAncestors(EmisTransPlanRule node, String parentId, - // String ancestors) { - // if (node == null) { - // return; - // } - // // 设置父ID - // node.setParentId(parentId); - // - // // 设置祖先节点ID - // node.setAncestors(ancestors); - // // 处理子节点,子节点的祖先包含当前节点和当前节点的所有祖先 - // if (node.getChildren() != null && !node.getChildren().isEmpty()) { - // String childAncestors = ancestors.isEmpty() ? node.getTreeId() : ancestors + - // "," + node.getTreeId(); - // for (EmisTransPlanRule child : node.getChildren()) { - // setParentAndAncestors(child, node.getTreeId(), childAncestors); - // } - // } - // } - // - // /** - // * 深度复制节点及其子节点 - // * - // * @param source 源节点 - // * @return 复制后的新节点 - // */ - // private EmisTransPlanRule deepCopyNode(EmisTransPlanRule source) { - // return deepCopyNode(source, new HashSet<>(), new ArrayList<>()); - // } - // - // /** - // * 深度复制节点及其子节点(带循环引用检测) - // * - // * @param source 源节点 - // * @param visitedIds 已访问的节点ID集合 - // * @param visitPath 访问路径,用于记录循环引用的路径 - // * @return 复制后的新节点 - // */ - // private EmisTransPlanRule deepCopyNode(EmisTransPlanRule source, Set - // visitedIds, List visitPath) { - // if (source == null) { - // return null; - // } - // - // // 检查循环引用 - // if (visitedIds.contains(source.getId())) { - // // 找到循环引用的起始位置 - // int cycleStartIndex = visitPath.indexOf(source.getId()); - // if (cycleStartIndex != -1) { - // // 构建循环路径 - // List cyclePath = visitPath.subList(cycleStartIndex, visitPath.size()); - // cyclePath.add(source.getId()); - // - // // 构建详细的错误信息 - // StringBuilder errorMsg = new StringBuilder(); - // errorMsg.append("检测到循环引用!循环路径:"); - // for (int i = 0; i < cyclePath.size(); i++) { - // if (i > 0) { - // errorMsg.append(" -> "); - // } - // Long id = cyclePath.get(i); - // EmisTransPlanRule node = findNodeById(id); - // if (node != null) { - // errorMsg.append(node.getLineName()).append("-") - // .append(node.getProductTypeName()).append("-") - // .append(node.getStartSiteName()).append("-") - // .append(node.getNextSiteName()).append("-") - // .append(node.getSupplierName()); - // } else { - // errorMsg.append("节点ID:").append(id); - // } - // } - // errorMsg.append("\n循环引用发生在节点,详细信息见上"); - // throw new RuntimeException(errorMsg.toString()); - // } - // } - // - // // 添加到已访问集合和路径中 - // visitedIds.add(source.getId()); - // visitPath.add(source.getId()); - // - // EmisTransPlanRule copy = new EmisTransPlanRule(); - // BeanUtils.copyProperties(source, copy); - // - // // 为每个新节点生成唯一treeId - // copy.setTreeId(com.xdadan.erp.common.utils.idgen.UUID.fastUUID().toString()); - // - // // 递归复制子节点 - // if (source.getChildren() != null) { - // List copiedChildren = new ArrayList<>(); - // for (EmisTransPlanRule child : source.getChildren()) { - // copiedChildren.add(deepCopyNode(child, visitedIds, visitPath)); - // } - // copy.setChildren(copiedChildren); - // } - // - // // 从路径中移除当前节点(回溯) - // visitPath.remove(visitPath.size() - 1); - // - // return copy; - // } - // - // // 新增方法:根据ID查找节点 - // private EmisTransPlanRule findNodeById(Long id) { - // // 由于deepCopyNode递归时无法直接访问所有节点,这里可通过全量查询实现,实际生产建议优化 - // List allRules = - // emisTransPlanRuleMapper.selectEmisTransPlanRuleList(new EmisTransPlanRule()); - // for (EmisTransPlanRule rule : allRules) { - // if (rule.getId() != null && rule.getId().equals(id)) { - // return rule; - // } - // } - // return null; - // } + @Override public List checkTree(EmisTransPlanRule emisTransPlanRule) { diff --git a/emis-biz/src/main/resources/mapper/EmisTransPlanRuleMapper.xml b/emis-biz/src/main/resources/mapper/EmisTransPlanRuleMapper.xml index 7ceda2966..a7dbe5388 100644 --- a/emis-biz/src/main/resources/mapper/EmisTransPlanRuleMapper.xml +++ b/emis-biz/src/main/resources/mapper/EmisTransPlanRuleMapper.xml @@ -145,7 +145,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"