diff --git a/laws-modules/src/main/java/com/jero/modules/laws/club/controller/LawsClubController.java b/laws-modules/src/main/java/com/jero/modules/laws/club/controller/LawsClubController.java index 92057188..3143b99c 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/club/controller/LawsClubController.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/club/controller/LawsClubController.java @@ -8,6 +8,7 @@ import com.jero.common.aspect.annotation.Translation; import com.jero.common.system.base.controller.JeroController; import com.jero.modules.laws.club.entity.LawsClub; import com.jero.modules.laws.club.service.ILawsClubService; +import com.jero.modules.laws.club.vo.LawsClubTreeNodeModel; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -43,9 +44,10 @@ public class LawsClubController extends JeroController queryTreeAll(@RequestParam(name = "nodeType", required = false, defaultValue = "") String nodeType) { - List tree = lawsClubService.getTreeStructure("Part", nodeType); + List tree = lawsClubService.getTreeStructure("Part", nodeType); return Result.OK(tree); } diff --git a/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClub.java b/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClub.java index df40695d..8d11618d 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClub.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClub.java @@ -1,14 +1,10 @@ package com.jero.modules.laws.club.entity; import com.baomidou.mybatisplus.annotation.*; - -import java.time.LocalDateTime; import java.io.Serializable; import java.util.Date; import java.util.List; - import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; import com.jero.common.aspect.annotation.Dict; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -85,10 +81,6 @@ public class LawsClub implements Serializable { @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date updateTime; - @ApiModelProperty(value = "是否是叶子节点") - @TableField(exist = false) - private boolean leafFlag; - @TableField(exist = false) @ApiModelProperty(value = "入团信息列表数据") @ExcelCollection(name = "入团信息") @@ -112,10 +104,6 @@ public class LawsClub implements Serializable { @ExcelCollection(name = "征集调研信息") private List lawsClubResearchInformations; - @TableField(exist = false) - @ApiModelProperty(value = "子节点") - private List children; - @TableField(exist = false) @ApiModelProperty(value = "公钥") private String rsaPublicKey; diff --git a/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeeting.java b/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeeting.java index ba847091..4c4c3dae 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeeting.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeeting.java @@ -3,13 +3,10 @@ package com.jero.modules.laws.club.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; -import java.time.LocalDate; -import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableId; import java.io.Serializable; import java.util.Date; import java.util.List; - import com.fasterxml.jackson.annotation.JsonFormat; import com.jero.common.aspect.annotation.Dict; import io.swagger.annotations.ApiModel; @@ -18,7 +15,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import org.jeecgframework.poi.excel.annotation.Excel; -import org.jeecgframework.poi.excel.annotation.ExcelCollection; import org.springframework.format.annotation.DateTimeFormat; /** @@ -46,17 +42,21 @@ public class LawsClubMeeting implements Serializable { private String clubId; @ApiModelProperty(value = "会议名称") + @Excel(name = "会议名称", width = 20) private String meetingName; @ApiModelProperty(value = "会议日期") @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") @DateTimeFormat(pattern="yyyy-MM-dd") + @Excel(name = "会议日期", width = 20, format = "yyyy-MM-dd") private Date meetingDate; @ApiModelProperty(value = "会议费用") + @Excel(name = "会议费用", width = 20) private String meetingCost; @ApiModelProperty(value = "线下/线上地点") + @Excel(name = "线下/线上地点", width = 20) private String meetingPlace; @ApiModelProperty(value = "计划完成日期") diff --git a/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeetingMember.java b/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeetingMember.java index 3b778d15..4f2e7c5e 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeetingMember.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/club/entity/LawsClubMeetingMember.java @@ -56,7 +56,7 @@ public class LawsClubMeetingMember implements Serializable { private String departId; @ApiModelProperty(value = "参会报告文件id") - @Excel(name = "参会报告文件", width = 20) + @Excel(name = "参会报告文件", width = 20, dictTable = "oss_file", dicCode = "id", dicText = "file_name") @Dict(dictTable = "oss_file", dicCode = "id", dicText = "file_name") private String meetingFileId; diff --git a/laws-modules/src/main/java/com/jero/modules/laws/club/service/ILawsClubService.java b/laws-modules/src/main/java/com/jero/modules/laws/club/service/ILawsClubService.java index 010c02e5..b3a5466f 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/club/service/ILawsClubService.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/club/service/ILawsClubService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.jero.common.api.vo.Result; import com.jero.modules.laws.club.entity.LawsClub; +import com.jero.modules.laws.club.vo.LawsClubTreeNodeModel; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.List; @@ -38,5 +39,5 @@ public interface ILawsClubService extends IService { Result importExcel(HttpServletRequest request); - List getTreeStructure(String part, String nodeType); + List getTreeStructure(String part, String nodeType); } diff --git a/laws-modules/src/main/java/com/jero/modules/laws/club/service/impl/LawsClubServiceImpl.java b/laws-modules/src/main/java/com/jero/modules/laws/club/service/impl/LawsClubServiceImpl.java index b58f3448..1f92755d 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/club/service/impl/LawsClubServiceImpl.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/club/service/impl/LawsClubServiceImpl.java @@ -18,8 +18,7 @@ import com.jero.modules.laws.club.entity.*; import com.jero.modules.laws.club.mapper.LawsClubMapper; import com.jero.modules.laws.club.service.*; import com.jero.modules.laws.club.vo.LawsClubMeetingExcel; -import com.jero.modules.system.service.ISysDepartService; -import com.jero.modules.system.service.ISysUserService; +import com.jero.modules.laws.club.vo.LawsClubTreeNodeModel; import org.apache.commons.lang3.StringUtils; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; @@ -60,61 +59,104 @@ public class LawsClubServiceImpl extends ServiceImpl i @Resource private ILawsClubResearchInformationService lawsClubResearchInformationService; @Resource - private ISysUserService sysUserService; - @Resource - private ISysDepartService sysDepartService; - @Resource private RedisUtil redisUtil; @Override - public List getTreeStructure(String parentId, String nodeType) { + public List getTreeStructure(String parentId, String nodeType) { // 查询所有节点 - List allNodes = list(); - // 构建节点映射 - Map nodeMap = allNodes.parallelStream() - .collect(Collectors.toConcurrentMap(LawsClub::getId, Function.identity())); - // 构建父子关系映射 - Map> parentChildMap = allNodes.parallelStream() - .collect(Collectors.groupingBy(LawsClub::getParentId)); + List clubList = list(); + List allNode = clubList.stream() + .map(lawsClub -> { + LawsClubTreeNodeModel model = new LawsClubTreeNodeModel(); + BeanUtils.copyProperties(lawsClub, model); + return model; + }).collect(Collectors.toList()); + // 构建节点映射和父子关系映射 + Map nodeMap = allNode.stream() + .collect(Collectors.toMap(LawsClubTreeNodeModel::getId, Function.identity())); + Map> parentChildMap = allNode.stream() + .collect(Collectors.groupingBy(LawsClubTreeNodeModel::getParentId)); // 如果 nodeType 为空,则返回完整树结构 if (StringUtils.isBlank(nodeType)) { - return buildTreeStructure(parentId, parentChildMap, nodeMap); // 构建并返回完整的树形结构 + return buildTreeStructure(parentId, parentChildMap, nodeMap); } // 查找 nodeType 对应的目标节点 - List targetNodes = allNodes.stream() + List targetNodes = allNode.stream() .filter(node -> node.getNodeType() != null && node.getNodeType().contains(nodeType)) .collect(Collectors.toList()); if (targetNodes.isEmpty()) { - // 如果没有找到与 nodeType 模糊匹配的节点,返回空列表 return Collections.emptyList(); } // 创建结果列表 - List result = new ArrayList<>(); - // 处理每个匹配到的目标节点 - for (LawsClub targetNode : targetNodes) { - // 查找目标节点的直接上级节点 - LawsClub parentNode = nodeMap.get(targetNode.getParentId()); + Set nodesSet = new HashSet<>(); + for (LawsClubTreeNodeModel targetNode : targetNodes) { + nodesSet.addAll(findPathToRoot(allNode, targetNode)); + } + // 如果结果集中只有根节点,则仅返回根节点 + List result = new ArrayList<>(); + if (nodesSet.size() <= 1) { + LawsClubTreeNodeModel parentNode = allNode.stream().filter(node -> "Part".equals(node.getParentId())) + .collect(Collectors.toList()).get(0); + result.add(parentNode); + } else { + result = new ArrayList<>(nodesSet); + } + // 生成树结构 + return buildTree(result); + } - if (parentNode != null) { - // 如果上级节点未添加到结果中,添加上级节点 - if (!result.contains(parentNode)) { - // 初始化上级节点的children列表 - parentNode.setChildren(new ArrayList<>()); - result.add(parentNode); - } - // 将目标节点添加到上级节点的children列表中 - if (parentNode.getChildren() == null) { - parentNode.setChildren(new ArrayList<>()); - } - if (!parentNode.getChildren().contains(targetNode)) { - parentNode.getChildren().add(targetNode); + public static List buildTree(List recordList) { + // 创建节点映射,方便快速查找节点 + Map nodeMap = recordList.stream() + .collect(Collectors.toMap(LawsClubTreeNodeModel::getId, Function.identity())); + // 用于存储树结构 + List tree = new ArrayList<>(); + // 遍历节点列表,构建树结构 + for (LawsClubTreeNodeModel node : recordList) { + if ("Part".equals(node.getParentId())) { + // 根节点 + tree.add(node); + } else { + // 将子节点添加到其父节点的子列表中 + LawsClubTreeNodeModel parent = nodeMap.get(node.getParentId()); + if (parent != null) { + if (parent.getChildren() == null) { + parent.setChildren(new ArrayList<>()); + } + parent.getChildren().add(node); } } } - // 返回结果 - return result; + // 设置叶子节点标志 + setLeafFlags(tree); + return tree; } + private static void setLeafFlags(List treeList) { + for (LawsClubTreeNodeModel node : treeList) { + if (node.getChildren() == null || node.getChildren().isEmpty()) { + node.setLeafFlag(true); + } else { + node.setLeafFlag(false); + setLeafFlags(node.getChildren()); + } + } + } + + public static Set findPathToRoot(List allNodes, LawsClubTreeNodeModel node) { + Set pathNodes = new HashSet<>(); + LawsClubTreeNodeModel[] currentHolder = new LawsClubTreeNodeModel[1]; + currentHolder[0] = node; + while (currentHolder[0] != null) { + pathNodes.add(currentHolder[0]); + currentHolder[0] = allNodes.stream() + .filter(n -> n.getId().equals(currentHolder[0].getParentId())) + .findFirst().orElse(null); + } + return pathNodes; + } + + /** * 递归构建树结构 * @param parentId 父节点ID @@ -122,30 +164,33 @@ public class LawsClubServiceImpl extends ServiceImpl i * @param nodeMap 节点映射 * @return 树结构的根节点列表 */ - private List buildTreeStructure(String parentId, Map> parentChildMap, Map nodeMap) { + private List buildTreeStructure(String parentId, Map> parentChildMap, Map nodeMap) { // 获取当前父节点下的所有子节点 - List children = parentChildMap.get(parentId); - + List children = parentChildMap.get(parentId); if (children == null || children.isEmpty()) { return Collections.emptyList(); // 没有子节点,返回空列表 } - // 遍历所有子节点,递归设置其子节点 children.parallelStream().forEach(child -> { - List grandChildren = buildTreeStructure(child.getId(), parentChildMap, nodeMap); + List grandChildren = buildTreeStructure(child.getId(), parentChildMap, nodeMap); child.setChildren(grandChildren); // 设置当前节点的子节点列表 child.setLeafFlag(grandChildren.isEmpty()); // 如果没有子节点则设置为叶子节点 }); - return children; } @Override public IPage queryPageList(LawsClub lawsClub, Integer pageNo, Integer pageSize, HttpServletRequest req) { String parentId = req.getParameter("parentId"); + if (StringUtils.isBlank(parentId)) { + throw new JeroBootException(ResultCommon.EMPTY_COMMON, "parentId"); + } + // 1. 查找 parentId 及所有子孙节点的 ID 列表 + Set descendantIds = findDescendantsIds(parentId); + // 2. 创建 LambdaQueryWrapper 来查询符合条件的记录 LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.and(wrapper -> - wrapper.eq(LawsClub::getParentId, parentId) + wrapper.in(LawsClub::getParentId, descendantIds) .or().eq(LawsClub::getId, parentId)); if (StringUtils.isNotBlank(lawsClub.getClubName())) { lambdaQueryWrapper.like(LawsClub::getClubName, lawsClub.getClubName()); @@ -153,10 +198,11 @@ public class LawsClubServiceImpl extends ServiceImpl i if (StringUtils.isNotBlank(lawsClub.getNodeType())) { lambdaQueryWrapper.like(LawsClub::getNodeType, lawsClub.getNodeType()); } - lambdaQueryWrapper.orderByDesc(LawsClub::getCreateTime); - // 查找 parentId 对应的所有子孙节点的 ID 列表 + lambdaQueryWrapper.orderByAsc(LawsClub::getCreateTime); + // 3. 执行分页查询 Page page = new Page<>(pageNo, pageSize); Page pageResult = page(page, lambdaQueryWrapper); + // 4. 解密联系方式 List records = pageResult.getRecords(); for (LawsClub record : records) { // 解密联系方式 @@ -168,6 +214,26 @@ public class LawsClubServiceImpl extends ServiceImpl i return pageResult; } + private Set findDescendantsIds(String parentId) { + Set ids = new HashSet<>(); + List allNodes = list(); // 获取所有节点 + collectDescendantIds(allNodes, parentId, ids); + return ids; + } + + private void collectDescendantIds(List allNodes, String parentId, Set ids) { + // 添加当前节点的 ID + ids.add(parentId); + // 查找子节点并递归调用 + List children = allNodes.stream() + .filter(node -> parentId.equals(node.getParentId())) + .collect(Collectors.toList()); + for (LawsClub child : children) { + collectDescendantIds(allNodes, child.getId(), ids); + } + } + + @Override public Result addOrEdit(LawsClub lawsClub) { if (Objects.isNull(lawsClub)) { diff --git a/laws-modules/src/main/java/com/jero/modules/laws/club/vo/LawsClubTreeNodeModel.java b/laws-modules/src/main/java/com/jero/modules/laws/club/vo/LawsClubTreeNodeModel.java new file mode 100644 index 00000000..33a624ae --- /dev/null +++ b/laws-modules/src/main/java/com/jero/modules/laws/club/vo/LawsClubTreeNodeModel.java @@ -0,0 +1,26 @@ +package com.jero.modules.laws.club.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.util.List; + +@Data +public class LawsClubTreeNodeModel { + + @ApiModelProperty(value = "主键id") + private String id; + + @ApiModelProperty(value = "上级节点id") + private String parentId; + + @ApiModelProperty(value = "节点类型") + private String nodeType; + + @ApiModelProperty(value = "是否是叶子节点") + private boolean leafFlag; + + @ApiModelProperty(value = "子节点") + private List children; + + +}