|
|
@@ -4730,8 +4730,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
|
|
|
@Override
|
|
|
public ResponseEntity<Resource> exportTree(Long contractId, HttpServletResponse response) throws IOException, InvalidFormatException {
|
|
|
- String templatePath = "/mnt/sdc/Users/hongchuangyanfa/Desktop/excel/gcdcTemplate.xlsx";
|
|
|
- //String templatePath = "C:\\upload\\excel\\gcdc.xlsx";
|
|
|
+ //String templatePath = "/mnt/sdc/Users/hongchuangyanfa/Desktop/excel/gcdcTemplate.xlsx";
|
|
|
+ String templatePath = "C:\\upload\\excel\\gcdc.xlsx";
|
|
|
// 查询数据
|
|
|
String sql = "select *,CONCAT(ancestors_p_id, ',', p_key_id) AS ancestors_p_id from m_wbs_tree_contract where contract_id = " + contractId +
|
|
|
" and is_deleted = 0 and type = 1 and node_type != 6 and p_id != 0";
|
|
|
@@ -4753,13 +4753,30 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
|
|
|
// 按单位工程分组
|
|
|
Map<Long, List<WbsTreeContract>> unitProjectMap = list.stream()
|
|
|
- .filter(item -> item.getNodeType() == 18) // 单位工程
|
|
|
+ .filter(item -> item.getNodeType() == 18)
|
|
|
+ .sorted(Comparator.comparing((WbsTreeContract unit) -> {
|
|
|
+ // 先按父节点的sort排序
|
|
|
+ if (unit.getPId() != null) {
|
|
|
+ // 查找父节点
|
|
|
+ Optional<WbsTreeContract> parent = list.stream()
|
|
|
+ .filter(p -> p.getPKeyId().equals(unit.getPId()))
|
|
|
+ .findFirst();
|
|
|
+ if (parent.isPresent()) {
|
|
|
+ return parent.get().getSort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null; // 如果没有父节点,返回null
|
|
|
+ }, Comparator.nullsLast(Comparator.naturalOrder()))
|
|
|
+ .thenComparing(WbsTreeContract::getSort,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder()))) // 再按自身的sort排序
|
|
|
.collect(Collectors.toMap(
|
|
|
WbsTreeContract::getPKeyId,
|
|
|
unit -> list.stream()
|
|
|
.filter(item -> item.getAncestorsPId() != null &&
|
|
|
item.getAncestorsPId().contains(unit.getPKeyId().toString()))
|
|
|
- .collect(Collectors.toList())
|
|
|
+ .collect(Collectors.toList()),
|
|
|
+ (existing, replacement) -> existing,
|
|
|
+ LinkedHashMap::new
|
|
|
));
|
|
|
|
|
|
// 为每个单位工程创建sheet
|
|
|
@@ -4783,6 +4800,13 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
String validSheetName = WorkbookUtil.createSafeSheetName(safeUnitName);
|
|
|
|
|
|
// 创建sheet并设置名称
|
|
|
+ //Sheet sheet = workbook.createSheet(validSheetName);
|
|
|
+ String baseSheetName = validSheetName;
|
|
|
+ int counter = 1;
|
|
|
+ while (workbook.getSheet(validSheetName) != null) {
|
|
|
+ validSheetName = baseSheetName + "(" + counter + ")";
|
|
|
+ counter++;
|
|
|
+ }
|
|
|
Sheet sheet = workbook.createSheet(validSheetName);
|
|
|
|
|
|
// 创建表头(两行)- 使用模板sheet
|
|
|
@@ -5356,17 +5380,17 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
// 1. 先找子分项工程 (节点类型5)
|
|
|
leafNodes = projects.stream()
|
|
|
.filter(item -> item.getNodeType() == 5)
|
|
|
+ .sorted(Comparator.comparing(WbsTreeContract::getSort,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
.collect(Collectors.toList());
|
|
|
-
|
|
|
- if (!leafNodes.isEmpty()) {
|
|
|
- sortLeafNodes(leafNodes);
|
|
|
- }
|
|
|
ancestorIds= leafNodes.stream()
|
|
|
.map(WbsTreeContract::getAncestorsPId)
|
|
|
.filter(Objects::nonNull)
|
|
|
+ .filter(ancestors -> !ancestors.equals("null"))
|
|
|
.flatMap(ancestors -> Arrays.stream(ancestors.split(",")))
|
|
|
.map(String::trim)
|
|
|
.filter(id -> !id.isEmpty())
|
|
|
+ .filter(id -> !id.equals("null"))
|
|
|
.map(Long::parseLong)
|
|
|
.collect(Collectors.toSet());
|
|
|
|
|
|
@@ -5374,6 +5398,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
Set<Long> finalAncestorIds = ancestorIds;
|
|
|
List<WbsTreeContract> items=projects.stream()
|
|
|
.filter(item -> item.getNodeType() == 4 && !finalAncestorIds.contains(item.getPKeyId()))
|
|
|
+ .sorted(Comparator.comparing(WbsTreeContract::getSort,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
.collect(Collectors.toList());
|
|
|
if(!items.isEmpty()&&items.size()>0){
|
|
|
leafNodes.addAll(items);
|
|
|
@@ -5381,9 +5407,11 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
ancestorIds = leafNodes.stream()
|
|
|
.map(WbsTreeContract::getAncestorsPId)
|
|
|
.filter(Objects::nonNull)
|
|
|
+ .filter(ancestors -> !ancestors.equals("null"))
|
|
|
.flatMap(ancestors -> Arrays.stream(ancestors.split(",")))
|
|
|
.map(String::trim)
|
|
|
.filter(id -> !id.isEmpty())
|
|
|
+ .filter(id -> !id.equals("null"))
|
|
|
.map(Long::parseLong)
|
|
|
.collect(Collectors.toSet());
|
|
|
|
|
|
@@ -5391,6 +5419,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
Set<Long> finalAncestorIds1 = ancestorIds;
|
|
|
List<WbsTreeContract> subDivisional = projects.stream()
|
|
|
.filter(item -> item.getNodeType() == 3&& !finalAncestorIds1.contains(item.getPKeyId()))
|
|
|
+ .sorted(Comparator.comparing(WbsTreeContract::getSort,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
.collect(Collectors.toList());
|
|
|
if(!subDivisional.isEmpty()&&subDivisional.size()>0){
|
|
|
leafNodes.addAll(subDivisional);
|
|
|
@@ -5398,15 +5428,19 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
ancestorIds = leafNodes.stream()
|
|
|
.map(WbsTreeContract::getAncestorsPId)
|
|
|
.filter(Objects::nonNull)
|
|
|
+ .filter(ancestors -> !ancestors.equals("null"))
|
|
|
.flatMap(ancestors -> Arrays.stream(ancestors.split(",")))
|
|
|
.map(String::trim)
|
|
|
.filter(id -> !id.isEmpty())
|
|
|
+ .filter(id -> !id.equals("null"))
|
|
|
.map(Long::parseLong)
|
|
|
.collect(Collectors.toSet());
|
|
|
Set<Long> finalAncestorIds2 = ancestorIds;
|
|
|
// 4. 如果没有子分部,找分部工程 (节点类型2)
|
|
|
List<WbsTreeContract> divisional = projects.stream()
|
|
|
.filter(item -> item.getNodeType() == 2&& !finalAncestorIds2.contains(item.getPKeyId()))
|
|
|
+ .sorted(Comparator.comparing(WbsTreeContract::getSort,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
.collect(Collectors.toList());
|
|
|
if(!divisional.isEmpty()&&divisional.size()>0){
|
|
|
leafNodes.addAll(divisional);
|
|
|
@@ -5414,9 +5448,11 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
ancestorIds = leafNodes.stream()
|
|
|
.map(WbsTreeContract::getAncestorsPId)
|
|
|
.filter(Objects::nonNull)
|
|
|
+ .filter(ancestors -> !ancestors.equals("null"))
|
|
|
.flatMap(ancestors -> Arrays.stream(ancestors.split(",")))
|
|
|
.map(String::trim)
|
|
|
.filter(id -> !id.isEmpty())
|
|
|
+ .filter(id -> !id.equals("null"))
|
|
|
.map(Long::parseLong)
|
|
|
.collect(Collectors.toSet());
|
|
|
Set<Long> finalAncestorIds3 = ancestorIds;
|
|
|
@@ -5424,28 +5460,126 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
|
|
|
// 5. 最后找单位工程 (节点类型18)
|
|
|
List<WbsTreeContract> unit = projects.stream()
|
|
|
.filter(item -> item.getNodeType() == 18&&!finalAncestorIds3.contains(item.getPKeyId()))
|
|
|
+ .sorted(Comparator.comparing(WbsTreeContract::getSort,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
.collect(Collectors.toList());
|
|
|
if(!unit.isEmpty()&&unit.size()>0){
|
|
|
leafNodes.addAll(unit);
|
|
|
}
|
|
|
- return sortLeafNodes(leafNodes);
|
|
|
+ return sortLeafNodes(leafNodes,projects);
|
|
|
}
|
|
|
|
|
|
// 排序方法:先按pId排序,pId相同则按sort排序(null值排在最后)
|
|
|
- private List<WbsTreeContract> sortLeafNodes(List<WbsTreeContract> nodes) {
|
|
|
+ // 排序方法:按照层级顺序排序(分部 -> 子分部 -> 分项 -> 子分项)
|
|
|
+ private List<WbsTreeContract> sortLeafNodes(List<WbsTreeContract> nodes, List<WbsTreeContract> projects) {
|
|
|
return nodes.stream()
|
|
|
- .sorted(Comparator
|
|
|
- .comparing(WbsTreeContract::getPId)
|
|
|
- .thenComparing(
|
|
|
- Comparator.comparing(
|
|
|
- WbsTreeContract::getSort,
|
|
|
- Comparator.nullsLast(Comparator.naturalOrder())
|
|
|
- )
|
|
|
- )
|
|
|
- )
|
|
|
+ .sorted((node1, node2) -> {
|
|
|
+ // 解析祖级节点ID
|
|
|
+ List<Long> ancestors1 = parseAncestors(node1.getAncestorsPId());
|
|
|
+ List<Long> ancestors2 = parseAncestors(node2.getAncestorsPId());
|
|
|
+
|
|
|
+ // 按照层级顺序比较
|
|
|
+ int result;
|
|
|
+
|
|
|
+ // 1. 先比较分部工程(nodeType=2)的sort
|
|
|
+ result = compareByNodeType(ancestors1, ancestors2, projects, 2);
|
|
|
+ if (result != 0) return result;
|
|
|
+
|
|
|
+ // 2. 再比较子分部工程(nodeType=3)的sort
|
|
|
+ result = compareByNodeType(ancestors1, ancestors2, projects, 3);
|
|
|
+ if (result != 0) return result;
|
|
|
+
|
|
|
+ // 3. 再比较分项工程(nodeType=4)的sort
|
|
|
+ result = compareByNodeType(ancestors1, ancestors2, projects, 4);
|
|
|
+ if (result != 0) return result;
|
|
|
+
|
|
|
+ // 4. 最后比较子分项工程(nodeType=5)的sort
|
|
|
+ result = compareByNodeType(ancestors1, ancestors2, projects, 5);
|
|
|
+ if (result != 0) return result;
|
|
|
+
|
|
|
+ // 5. 如果所有层级sort都相同,按当前节点sort排序
|
|
|
+ return compareSortValue(node1.getSort(), node2.getSort());
|
|
|
+ })
|
|
|
.collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 解析祖级节点ID
|
|
|
+ */
|
|
|
+ private List<Long> parseAncestors(String ancestorsPId) {
|
|
|
+ if (ancestorsPId == null || ancestorsPId.equals("null")) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ return Arrays.stream(ancestorsPId.split(","))
|
|
|
+ .map(String::trim)
|
|
|
+ .filter(id -> !id.isEmpty() && !id.equals("null"))
|
|
|
+ .map(Long::parseLong)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按照指定节点类型比较sort值
|
|
|
+ */
|
|
|
+ private int compareByNodeType(List<Long> ancestors1, List<Long> ancestors2,
|
|
|
+ List<WbsTreeContract> projects, int nodeType) {
|
|
|
+ // 从祖级节点中查找指定类型的节点
|
|
|
+ WbsTreeContract node1 = findNodeByTypeInAncestors(ancestors1, projects, nodeType);
|
|
|
+ WbsTreeContract node2 = findNodeByTypeInAncestors(ancestors2, projects, nodeType);
|
|
|
+
|
|
|
+ // 获取sort值进行比较
|
|
|
+ Integer sort1 = node1 != null ? node1.getSort() : null;
|
|
|
+ Integer sort2 = node2 != null ? node2.getSort() : null;
|
|
|
+
|
|
|
+ return compareSortValue(sort1, sort2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在祖级节点中查找指定类型的节点
|
|
|
+ */
|
|
|
+ private WbsTreeContract findNodeByTypeInAncestors(List<Long> ancestors,
|
|
|
+ List<WbsTreeContract> projects, int nodeType) {
|
|
|
+ if (ancestors.isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 在祖级节点中查找指定类型的节点
|
|
|
+ for (Long ancestorId : ancestors) {
|
|
|
+ WbsTreeContract node = findNodeByIdAndType(projects, ancestorId, nodeType);
|
|
|
+ if (node != null) {
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据ID和类型查找节点
|
|
|
+ */
|
|
|
+ private WbsTreeContract findNodeByIdAndType(List<WbsTreeContract> list, Long id, int nodeType) {
|
|
|
+ return list.stream()
|
|
|
+ .filter(item -> item.getPKeyId().equals(id) && item.getNodeType() == nodeType)
|
|
|
+ .findFirst()
|
|
|
+ .orElse(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 比较sort值(处理null值情况)
|
|
|
+ */
|
|
|
+ private int compareSortValue(Integer sort1, Integer sort2) {
|
|
|
+ if (sort1 == null && sort2 == null) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (sort1 == null) {
|
|
|
+ return 1; // null值排在后面
|
|
|
+ }
|
|
|
+ if (sort2 == null) {
|
|
|
+ return -1; // null值排在后面
|
|
|
+ }
|
|
|
+ return sort1.compareTo(sort2);
|
|
|
+ }
|
|
|
+
|
|
|
// 根据叶子节点类型填充工程数据
|
|
|
private void fillEngineeringDataByLeafType(Row row, List<WbsTreeContract> projects, List<Long> ancestorIds,
|
|
|
Map<Integer, List<CellRangeAddress>> mergeMap, int rowNum,
|