From 1a7fff68c064c3a9c60f6142970d4159f803f90d Mon Sep 17 00:00:00 2001 From: cst61 Date: Tue, 28 Jul 2026 18:37:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9E=84=E9=80=A0=E7=B2=89=E4=B8=9D=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LbFanManagementController.java | 11 +++ .../java/com/rj/entity/LbFanManagement.java | 10 +++ .../rj/service/ILbFanManagementService.java | 8 ++ .../impl/LbFanManagementServiceImpl.java | 83 +++++++++++++++++++ 4 files changed, 112 insertions(+) diff --git a/src/main/java/com/rj/controller/LbFanManagementController.java b/src/main/java/com/rj/controller/LbFanManagementController.java index 6f507b9..53b2ade 100644 --- a/src/main/java/com/rj/controller/LbFanManagementController.java +++ b/src/main/java/com/rj/controller/LbFanManagementController.java @@ -91,6 +91,17 @@ public class LbFanManagementController { return ResponseEntity.internalServerError().body(result); } + @GetMapping("/tree") + @Operation(summary = "获取粉丝树形结构", description = "根据租户ID和父亲手机号递归查询粉丝树形结构,父亲手机号为空时查询所有根节点") + public ResponseEntity> getFanTree( + @Parameter(description = "租户ID", required = true) + @RequestParam String tenantId, + @Parameter(description = "父亲手机号(可为空,为空时查询所有根节点)") + @RequestParam(required = false) String parentMobile) { + Map result = lbFanManagementService.getFanTree(tenantId, parentMobile); + return toResponse(result); + } + private ResponseEntity> toResponse(Map result) { Boolean success = (Boolean) result.get("success"); if (success != null && success) { diff --git a/src/main/java/com/rj/entity/LbFanManagement.java b/src/main/java/com/rj/entity/LbFanManagement.java index f7268f9..678ba17 100644 --- a/src/main/java/com/rj/entity/LbFanManagement.java +++ b/src/main/java/com/rj/entity/LbFanManagement.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -13,6 +14,7 @@ import lombok.EqualsAndHashCode; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; /** * 粉丝管理表 lb_fan_management @@ -30,6 +32,9 @@ public class LbFanManagement implements Serializable { * 唯一主键,格式:{@code {id}_{tenantId}},如 {@code 98817_xxx-tenant-uuid}。 */ @TableId(value = "id_tenant_id", type = IdType.INPUT) + + + @Schema(description = "唯一ID(id_tenantId,新增时可不传由服务端生成)") private String idTenantId; @@ -89,4 +94,9 @@ public class LbFanManagement implements Serializable { @TableField("share_num") @Schema(description = "分享次数") private Integer shareNum; + + @TableField(exist = false) + @Schema(description = "子节点列表(树形结构)") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; } diff --git a/src/main/java/com/rj/service/ILbFanManagementService.java b/src/main/java/com/rj/service/ILbFanManagementService.java index 5f4fc60..136b7b7 100644 --- a/src/main/java/com/rj/service/ILbFanManagementService.java +++ b/src/main/java/com/rj/service/ILbFanManagementService.java @@ -30,4 +30,12 @@ public interface ILbFanManagementService extends IService { * 按手机号列表模拟第三方登录:根据 tenantId 读取 lb_third_integration_config.login_api_path 调用接口并解析 JSON。 */ Map simulateLogin(LbFanSimulateLoginRequest request); + + /** + * 根据租户ID和父亲手机号递归查询粉丝树形结构 + * @param tenantId 租户ID + * @param parentMobile 父亲手机号(可为空,为空时查询所有根节点) + * @return 树形结构数据 + */ + Map getFanTree(String tenantId, String parentMobile); } diff --git a/src/main/java/com/rj/service/impl/LbFanManagementServiceImpl.java b/src/main/java/com/rj/service/impl/LbFanManagementServiceImpl.java index c82faa1..41a13e2 100644 --- a/src/main/java/com/rj/service/impl/LbFanManagementServiceImpl.java +++ b/src/main/java/com/rj/service/impl/LbFanManagementServiceImpl.java @@ -767,4 +767,87 @@ public class LbFanManagementServiceImpl return null; } } + + @Override + public Map getFanTree(String tenantId, String parentMobile) { + Map result = new HashMap<>(); + try { + if (tenantId == null || tenantId.trim().isEmpty()) { + result.put("success", false); + result.put("message", "租户ID不能为空"); + return result; + } + + List allFans = this.list( + new LambdaQueryWrapper() + .eq(LbFanManagement::getTenantId, tenantId.trim()) + ); + + if (allFans == null || allFans.isEmpty()) { + result.put("success", true); + result.put("message", "查询成功"); + result.put("data", new ArrayList<>()); + return result; + } + + Map> childrenMap = new HashMap<>(); + Map fanMap = new HashMap<>(); + + for (LbFanManagement fan : allFans) { + fanMap.put(fan.getId(), fan); + Long pid = fan.getPid(); + if (pid != null && pid > 0) { + childrenMap.computeIfAbsent(pid, k -> new ArrayList<>()).add(fan); + } + } + + List tree; + + if (parentMobile != null && !parentMobile.trim().isEmpty()) { + LbFanManagement parentFan = allFans.stream() + .filter(f -> parentMobile.trim().equals(f.getMobile())) + .findFirst() + .orElse(null); + + if (parentFan == null) { + result.put("success", true); + result.put("message", "未找到指定手机号的父亲节点"); + result.put("data", new ArrayList<>()); + return result; + } + + buildTree(parentFan, childrenMap); + tree = List.of(parentFan); + } else { + tree = new ArrayList<>(); + for (LbFanManagement fan : allFans) { + if (fan.getPid() == null || fan.getPid() == 0) { + buildTree(fan, childrenMap); + tree.add(fan); + } + } + } + + result.put("success", true); + result.put("message", "查询成功"); + result.put("data", tree); + return result; + + } catch (Exception e) { + log.error("获取粉丝树形结构异常", e); + result.put("success", false); + result.put("message", "获取粉丝树形结构异常:" + e.getMessage()); + return result; + } + } + + private void buildTree(LbFanManagement parent, Map> childrenMap) { + List children = childrenMap.get(parent.getId()); + if (children != null && !children.isEmpty()) { + parent.setChildren(new ArrayList<>(children)); + for (LbFanManagement child : children) { + buildTree(child, childrenMap); + } + } + } }