构造粉丝树

This commit is contained in:
2026-07-28 18:37:35 +08:00
parent 4d6b3dfe2f
commit 1a7fff68c0
4 changed files with 112 additions and 0 deletions

View File

@@ -91,6 +91,17 @@ public class LbFanManagementController {
return ResponseEntity.internalServerError().body(result); return ResponseEntity.internalServerError().body(result);
} }
@GetMapping("/tree")
@Operation(summary = "获取粉丝树形结构", description = "根据租户ID和父亲手机号递归查询粉丝树形结构父亲手机号为空时查询所有根节点")
public ResponseEntity<Map<String, Object>> getFanTree(
@Parameter(description = "租户ID", required = true)
@RequestParam String tenantId,
@Parameter(description = "父亲手机号(可为空,为空时查询所有根节点)")
@RequestParam(required = false) String parentMobile) {
Map<String, Object> result = lbFanManagementService.getFanTree(tenantId, parentMobile);
return toResponse(result);
}
private ResponseEntity<Map<String, Object>> toResponse(Map<String, Object> result) { private ResponseEntity<Map<String, Object>> toResponse(Map<String, Object> result) {
Boolean success = (Boolean) result.get("success"); Boolean success = (Boolean) result.get("success");
if (success != null && success) { if (success != null && success) {

View File

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -13,6 +14,7 @@ import lombok.EqualsAndHashCode;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
/** /**
* 粉丝管理表 lb_fan_management * 粉丝管理表 lb_fan_management
@@ -30,6 +32,9 @@ public class LbFanManagement implements Serializable {
* 唯一主键,格式:{@code {id}_{tenantId}},如 {@code 98817_xxx-tenant-uuid}。 * 唯一主键,格式:{@code {id}_{tenantId}},如 {@code 98817_xxx-tenant-uuid}。
*/ */
@TableId(value = "id_tenant_id", type = IdType.INPUT) @TableId(value = "id_tenant_id", type = IdType.INPUT)
@Schema(description = "唯一IDid_tenantId新增时可不传由服务端生成") @Schema(description = "唯一IDid_tenantId新增时可不传由服务端生成")
private String idTenantId; private String idTenantId;
@@ -89,4 +94,9 @@ public class LbFanManagement implements Serializable {
@TableField("share_num") @TableField("share_num")
@Schema(description = "分享次数") @Schema(description = "分享次数")
private Integer shareNum; private Integer shareNum;
@TableField(exist = false)
@Schema(description = "子节点列表(树形结构)")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<LbFanManagement> children;
} }

View File

@@ -30,4 +30,12 @@ public interface ILbFanManagementService extends IService<LbFanManagement> {
* 按手机号列表模拟第三方登录:根据 tenantId 读取 lb_third_integration_config.login_api_path 调用接口并解析 JSON。 * 按手机号列表模拟第三方登录:根据 tenantId 读取 lb_third_integration_config.login_api_path 调用接口并解析 JSON。
*/ */
Map<String, Object> simulateLogin(LbFanSimulateLoginRequest request); Map<String, Object> simulateLogin(LbFanSimulateLoginRequest request);
/**
* 根据租户ID和父亲手机号递归查询粉丝树形结构
* @param tenantId 租户ID
* @param parentMobile 父亲手机号(可为空,为空时查询所有根节点)
* @return 树形结构数据
*/
Map<String, Object> getFanTree(String tenantId, String parentMobile);
} }

View File

@@ -767,4 +767,87 @@ public class LbFanManagementServiceImpl
return null; return null;
} }
} }
@Override
public Map<String, Object> getFanTree(String tenantId, String parentMobile) {
Map<String, Object> result = new HashMap<>();
try {
if (tenantId == null || tenantId.trim().isEmpty()) {
result.put("success", false);
result.put("message", "租户ID不能为空");
return result;
}
List<LbFanManagement> allFans = this.list(
new LambdaQueryWrapper<LbFanManagement>()
.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<Long, List<LbFanManagement>> childrenMap = new HashMap<>();
Map<Long, LbFanManagement> 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<LbFanManagement> 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<Long, List<LbFanManagement>> childrenMap) {
List<LbFanManagement> children = childrenMap.get(parent.getId());
if (children != null && !children.isEmpty()) {
parent.setChildren(new ArrayList<>(children));
for (LbFanManagement child : children) {
buildTree(child, childrenMap);
}
}
}
} }