Kaynağa Gözat

docs: 团队层级树与推荐关系可视化设计文档

- 新增 specs/2026-09-09-team-hierarchy-design.md
- 更新 PROJECT-OVERVIEW.md 记录
- 涵盖:富页面去推荐码、我的页面推荐人卡片+团队入口、树形页面从下往上生长、团队消费额分级统计(默认3级可配)、直推成员消费/CF明细、4个后端接口新增/扩展
- audit 通过(0 error)
Sisyphus 1 hafta önce
ebeveyn
işleme
6497e5599a

+ 1 - 0
docs/superpowers/PROJECT-OVERVIEW.md

@@ -369,6 +369,7 @@
 | `2026-08-31-coupon-family-based-design.md` | 🟡 设计稿 | 优惠券全链路改为家庭维度(新建 family_coupon / family_coupon_grant_log 表,6 条发放路径全部改家庭,消费/核销同步;API 路径与响应字段保持不变) |
 | `2026-08-31-coupon-family-based-design.md` | 🟡 设计稿 | 优惠券全链路改为家庭维度(新建 family_coupon / family_coupon_grant_log 表,6 条发放路径全部改家庭,消费/核销同步;API 路径与响应字段保持不变) |
 | `2026-08-31-self-check-reminder-design.md` | 🟡 设计稿(15 天复检周期 + 首页入口显示自检分数 + 题目轮换 + 后端忽略记录,纯设计方案) | 五维家庭自检 15 天复检周期与题目轮换设计 |
 | `2026-08-31-self-check-reminder-design.md` | 🟡 设计稿(15 天复检周期 + 首页入口显示自检分数 + 题目轮换 + 后端忽略记录,纯设计方案) | 五维家庭自检 15 天复检周期与题目轮换设计 |
 | `2026-08-31-self-check-ai-integration-design.md` | 🟡 设计稿(P0-1 纯AI替换静态建议 + P0-2 用户点击生成健康计划 + P1-1 历史趋势AI解读 + P1-2 Chat上下文注入,P2延后) | 五维家庭自检 AI 结合设计 |
 | `2026-08-31-self-check-ai-integration-design.md` | 🟡 设计稿(P0-1 纯AI替换静态建议 + P0-2 用户点击生成健康计划 + P1-1 历史趋势AI解读 + P1-2 Chat上下文注入,P2延后) | 五维家庭自检 AI 结合设计 |
+| `2026-09-09-team-hierarchy-design.md` | 🟡 设计稿(团队层级树从下往上生长 + 团队消费额分级统计 + 直推成员消费/CF明细 + 我的推荐人展示 + 去掉富页面推荐码) | 团队层级与推荐关系可视化 |
 | `api/API_REFERENCE.md` | 🟢 已建立(2026-08-18;200+ 接口清单;废弃接口标注;新增接口检查流程;2026-09-06 补充家庭成员切换/回收箱接口:`/leave`、`/kick` 回收箱分流、`/recycle`) | 后台接口参考文档 |
 | `api/API_REFERENCE.md` | 🟢 已建立(2026-08-18;200+ 接口清单;废弃接口标注;新增接口检查流程;2026-09-06 补充家庭成员切换/回收箱接口:`/leave`、`/kick` 回收箱分流、`/recycle`) | 后台接口参考文档 |
 
 
 ### 实施计划(plans/)
 ### 实施计划(plans/)

+ 337 - 0
docs/superpowers/specs/2026-09-09-team-hierarchy-design.md

@@ -0,0 +1,337 @@
+# 团队层级树与推荐关系可视化设计
+
+**版本:** v1.0
+**日期:** 2026-09-09
+**状态:** 待审查
+**关联需求:** 用户需求记录
+
+---
+
+## 一、概述
+
+**用户故事:**
+> 作为家长用户,我想在「我的」页面查看我的推荐人、分享人数、团队层级树(从下往上生长)、团队总消费额、直推成员的消费额和我获得的 CF 值,以便直观了解我的推广成果与团队结构。
+
+**核心目标:**
+1. 去掉富页面的推荐码展示
+2. 我的页面新增「我的推荐人」卡片
+3. 我的页面新增「团队层级」入口,跳转独立树形页面(从下往上生长)
+4. 树形页面展示:团队总消费额(默认 3 级,后台可配)、直推成员列表含消费额+我获得的 CF 值
+5. 后端新增/扩展接口支撑上述功能
+
+---
+
+## 二、验收标准
+
+### 2.1 富页面
+- [ ] 删除「我的邀请码」横条(`referral-code-bar` 区块)
+- [ ] 保留「邀请人数」显示
+
+### 2.2 我的页面
+- [ ] 新增「我的推荐人」卡片(显示推荐人昵称、头像、邀请码、绑定时间)
+- [ ] 新增「团队层级」入口按钮,点击跳转树形页面
+- [ ] 保留现有「推广收益」成就卡片
+
+### 2.3 团队层级树页面(新建 `/pages/profile/team-tree`)
+- [ ] 树形结构从下往上生长(根节点在底部,分支向上延伸)
+- [ ] 顶部展示:团队总消费额(默认统计 3 级)、团队人数
+- [ ] 支持折叠/展开每个节点
+- [ ] 每个节点显示:头像、昵称、层级标识(L1/L2/L3)、消费额、我的 CF 获得
+- [ ] 点击成员可查看详情(预留)
+
+### 2.4 后端接口
+- [ ] `POST /api/commission/team/list` 扩展:返回中每个成员新增 `memberConsumption`、`myCfEarnedFromMember`
+- [ ] `POST /api/commission/team/consumption` 新增:团队总消费额分级汇总
+- [ ] `POST /api/commission/my-referrer` 新增:获取我的推荐人信息
+- [ ] `POST /api/commission/team/tree` 新增:团队树形扁平数据(含层级、父子关系)
+
+### 2.5 配置化
+- [ ] 后台可配置团队消费统计最大层级(默认 3 级)
+
+---
+
+## 三、技术方案
+
+### 3.1 数据模型关系
+
+| 表 | 关键字段 | 用途 |
+|---|---|---|
+| `users` | `id`, `referrerId`, `referralCode`, `nickname`, `avatar` | 用户与推荐关系 |
+| `referral_tree` | `parentId`, `childId`, `level`, `path` | 物化全层级推荐树 |
+| `product_orders` | `buyerId`, `totalAmount`, `status`, `paidAt` | 消费订单 |
+| `commission_records` | `referrerId`, `buyerId`, `commissionAmount`, `level`, `status` | 佣金记录(L1/L2) |
+| `user_platform_balance` | `userId`, `totalEarned`, `available`, `frozen`, `withdrawn` | CF 值钱包 |
+| `cf_rate_tier` | `minTeamSize`, `ratePercent`, `enabled` | 返佣阶梯(现有) |
+
+> 注:`referral_tree.level` = 代际差(1=直推,2=间推...),`path` = `/最远祖先/.../直接推荐人/`
+
+### 3.2 后端接口设计
+
+#### 3.2.1 扩展 `/api/commission/team/list`
+
+**请求:** `{ page, size, level }`(level: ALL/L1/L2)
+
+**响应扩展字段:**
+```json
+{
+  "records": [
+    {
+      "userId": 123,
+      "nickname": "用户名",
+      "avatarUrl": "https://...",
+      "createdAt": "2026-01-01",
+      "orderCount": 5,
+      "commissionEarned": 15000,
+      "memberConsumption": 32000,       // 新增:该成员 completed 订单总额
+      "myCfEarnedFromMember": 9600      // 新增:我从该成员消费获得的 CF(佣金)总额
+    }
+  ],
+  "total": 10,
+  "page": 1,
+  "size": 20
+}
+```
+
+**实现逻辑:**
+- `memberConsumption`:查 `product_orders` 表 `buyerId = 该成员` 且 `status IN ('completed', 'paid', 'received')` 的 `totalAmount` 总和
+- `myCfEarnedFromMember`:查 `commission_records` 表 `referrerId = 我` 且 `buyerId = 该成员` 且 `status != 'cancelled'` 的 `commissionAmount` 总和
+
+#### 3.2.2 新增 `/api/commission/team/consumption`
+
+**请求:** `{ maxLevel: 3 }`(默认 3,可选)
+
+**响应:**
+```json
+{
+  "totalConsumption": 125000,
+  "levelBreakdown": [
+    { "level": 1, "memberCount": 5, "consumption": 80000 },
+    { "level": 2, "memberCount": 12, "consumption": 35000 },
+    { "level": 3, "memberCount": 8, "consumption": 10000 }
+  ],
+  "totalMembers": 25,
+  "maxLevel": 3
+}
+```
+
+**实现逻辑:**
+1. 查 `referral_tree` 表 `parentId = 我` 且 `level <= maxLevel` 的所有 `childId`
+2. 按 `level` 分组统计 `memberCount`
+3. 查这些 `childId` 的 `product_orders`(completed 状态)`totalAmount` 总和,按 `level` 汇总
+
+**配置化:**
+- 读取 `cf_rate_tier` 表中 `enabled=1` 的记录,或新增 `commission_config` 表存储 `team_consumption_max_level`(默认 3)
+- 后端管理接口:`POST /api/admin/cf-rate-tier/setting`(扩展现有)或新增
+
+#### 3.2.3 新增 `/api/commission/my-referrer`
+
+**请求:** 空
+
+**响应:**
+```json
+{
+  "referrerId": 456,
+  "nickname": "推荐人昵称",
+  "avatar": "https://...",
+  "referralCode": "ABC123XY",
+  "bindTime": "2026-01-15 10:30:00"
+}
+```
+
+**实现逻辑:**
+- 查 `users` 表 `id = 当前用户.referrerId`
+- 若 `referrerId` 为空,返回 `{ hasReferrer: false }`
+
+#### 3.2.4 新增 `/api/commission/team/tree`
+
+**请求:** `{ maxLevel: 3 }`(默认 3)
+
+**响应:**
+```json
+{
+  "nodes": [
+    { "userId": 100, "nickname": "我", "level": 0, "parentId": null, "referrerId": 456 },
+    { "userId": 101, "nickname": "直推A", "level": 1, "parentId": 100, "referrerId": 100 },
+    { "userId": 102, "nickname": "间推B", "level": 2, "parentId": 101, "referrerId": 101 },
+    { "userId": 103, "nickname": "直推C", "level": 1, "parentId": 100, "referrerId": 100 }
+  ],
+  "totalMembers": 3,
+  "maxLevel": 3
+}
+```
+
+**实现逻辑:**
+1. 查 `referral_tree` `parentId = 我` 且 `level <= maxLevel` → 后代集合 `{childId, level}`
+2. 对每个 `childId`,查 `users` 表得 `nickname`, `avatar`, `referrerId`
+3. `referrerId` 即为树中的直接父节点(`referrerId = 我` 则父节点为我)
+4. 组装扁平数组,前端递归渲染树形
+
+> 也可复用 `DistributionService.getTeamTree` 逻辑,但该服务基于 `distribution_relations` 表,当前推荐体系基于 `users.referrerId` + `referral_tree`,建议在 `CommissionService` 新增实现。
+
+---
+
+### 3.3 前端改动清单
+
+| 文件 | 变更类型 | 详情 |
+|---|---|---|
+| `pages/wealth/index.vue` | 删除 | 移除 `referral-code-bar`(第 161-165 行) |
+| `pages/profile-main/profile.vue` | 新增 | 1.「我的推荐人」卡片<br>2.「团队层级」入口按钮 → `navigateTo('/pages/profile/team-tree')` |
+| `pages/profile/team-tree.vue` | **新建** | 树形页面:<br>- 顶部统计卡(总消费、人数)<br>- 树形组件(从下往上生长,flex column-reverse + 递归)<br>- 节点组件:头像、昵称、层级标签、消费额、我的 CF 获得<br>- 折叠/展开交互 |
+| `utils/api.js` | 新增 | `getTeamConsumption(maxLevel)`、`getMyReferrer()`、`getTeamTree(maxLevel)`、`getTeamList` 扩展字段 |
+| `pages.json` | 注册 | 新增 `pages/profile/team-tree` 页面 |
+
+**树形 UI 实现思路(从下往上生长):**
+```vue
+<!-- 树形容器:flex column-reverse,根节点在底部 -->
+<view class="tree-container" style="flex-direction: column-reverse;">
+  <!-- 递归组件 TreeNode -->
+  <TreeNode :node="rootNode" :level="0" :maxLevel="maxLevel" />
+</view>
+
+<!-- TreeNode.vue -->
+<view class="tree-node" :style="{ 'padding-left': level * 30 + 'rpx' }">
+  <view class="node-main" @click="toggle">
+    <image :src="node.avatar" />
+    <text>{{ node.nickname }}</text>
+    <tag v-if="node.level > 0">L{{ node.level }}</tag>
+    <text class="consumption">消费: ¥{{ node.memberConsumption/100 }}</text>
+    <text class="my-cf">我得CF: ¥{{ node.myCfEarnedFromMember/100 }}</text>
+    <icon :name="expanded ? 'up' : 'down'" />
+  </view>
+  <!-- 子节点:因为父容器 column-reverse,子节点会在上方渲染 -->
+  <view v-if="expanded && node.children" class="children">
+    <TreeNode v-for="child in node.children" :key="child.userId" :node="child" :level="level+1" />
+  </view>
+  <!-- 连接线:::before 画竖线,父节点中心向上 -->
+</view>
+```
+
+---
+
+### 3.4 后端实现要点
+
+**新增 Service 方法(`CommissionService`):**
+
+```java
+// 1. 团队消费统计
+public Map<String, Object> getTeamConsumption(Long userId, Integer maxLevel)
+
+// 2. 我的推荐人
+public Map<String, Object> getMyReferrer(Long userId)
+
+// 3. 团队树形数据
+public Map<String, Object> getTeamTree(Long userId, Integer maxLevel)
+
+// 4. 扩展 getTeamList:查询 memberConsumption、myCfEarnedFromMember
+```
+
+**依赖注入需补充:**
+- `ProductOrderMapper`
+- `ReferralTreeMapper`
+- `UserPlatformBalanceMapper`(如需)
+
+**新增 Controller 方法(`CommissionController`):**
+```java
+@PostMapping("/team/consumption")
+public Result<Map<String, Object>> teamConsumption(@RequestAttribute("userId") Long userId,
+                                                    @RequestBody Map<String, Object> params)
+
+@PostMapping("/my-referrer")
+public Result<Map<String, Object>> myReferrer(@RequestAttribute("userId") Long userId)
+
+@PostMapping("/team/tree")
+public Result<Map<String, Object>> teamTree(@RequestAttribute("userId") Long userId,
+                                            @RequestBody Map<String, Object> params)
+```
+
+---
+
+## 四、API 设计汇总
+
+| 接口 | 方法 | 请求体 | 响应关键字段 | 备注 |
+|---|---|---|---|---|
+| `/api/commission/team/list` | POST | `{page,size,level}` | `records[].memberConsumption`, `records[].myCfEarnedFromMember` | 扩展现有 |
+| `/api/commission/team/consumption` | POST | `{maxLevel}` | `totalConsumption`, `levelBreakdown[]`, `totalMembers` | 新增 |
+| `/api/commission/my-referrer` | POST | `{}` | `referrerId`, `nickname`, `avatar`, `referralCode`, `bindTime` | 新增 |
+| `/api/commission/team/tree` | POST | `{maxLevel}` | `nodes[]`, `totalMembers` | 新增 |
+
+---
+
+## 五、配置项
+
+| 配置键 | 默认值 | 说明 | 维护位置 |
+|---|---|---|---|
+| `team_consumption_max_level` | 3 | 团队消费统计最大层级 | 后台管理 - CF返佣阶梯配置扩展 |
+
+> 建议复用 `AdminCfRateTierController` 新增设置接口,或新增 `CommissionConfigController`
+
+---
+
+## 六、边界情况处理
+
+| 场景 | 处理 |
+|---|---|
+| 用户无推荐人(`referrerId` 为空) | 我的推荐人卡片显示"暂无推荐人",不显示邀请码 |
+| 团队成员无消费订单 | 消费额显示 0,CF 获得显示 0 |
+| `maxLevel` 超过实际层级 | 按实际最大层级统计 |
+| `referral_tree` 数据不一致 | 以 `users.referrerId` 为准,`referral_tree` 为辅助加速查询 |
+| 订单状态:仅统计 `completed`/`paid`/`received` | 排除 `cancelled`/`refunding`/`refunded` |
+
+---
+
+## 七、测试用例
+
+| 用例 | 输入 | 预期输出 |
+|---|---|---|
+| 无推荐人用户访问我的页面 | 登录用户,referrerId=null | 推荐人卡片显示"暂无推荐人" |
+| 有推荐人用户访问我的页面 | 登录用户,referrerId=456 | 显示推荐人昵称、头像、邀请码、绑定时间 |
+| 空团队访问树形页面 | 无下级 | 仅显示根节点(自己),统计为 0 |
+| 3层团队消费统计 | maxLevel=3 | 正确汇总 L1/L2/L3 消费额 |
+| 直推成员列表 | level=L1 | 每行含 memberConsumption、myCfEarnedFromMember |
+| 折叠/展开交互 | 点击节点图标 | 子节点显示/隐藏,连接线正确 |
+
+---
+
+## 八、关联文档
+
+- `docs/superpowers/api/API_REFERENCE.md` - 接口参考(新增接口需同步记录)
+- `cfc-backend/AGENTS.md` - 后端规范
+- `cfc-frontend/AGENTS.md` - 前端规范
+
+---
+
+## 九、实施顺序建议
+
+1. **后端先行**(1-2 天):
+   - 新增 3 个接口 + 扩展 1 个接口
+   - 单元测试验证查询逻辑
+   - 更新 `API_REFERENCE.md`
+
+2. **前端并行**(1-2 天):
+   - 删除富页面推荐码
+   - 我的页面新增推荐人卡片 + 团队入口
+   - 新建 team-tree 页面(树形组件复用/新建)
+   - 接入 API
+
+3. **配置化**(0.5 天):
+   - 后台 CF 阶梯配置页扩展 `maxLevel` 字段
+   - 接口读取配置
+
+4. **联调验证**(0.5 天):
+   - 真实数据跑通
+   - 边界情况验证
+
+---
+
+## 十、风险与对策
+
+| 风险 | 等级 | 对策 |
+|---|---|---|
+| `referral_tree` 数据量大,树形查询慢 | 中 | 限制 `maxLevel`≤5,加索引 `idx_parent_level(parentId, level)` |
+| 消费额统计包含退款订单 | 高 | 严格筛选 `status` 仅 completed/paid/received |
+| 树形 UI 在小程序渲染卡顿 | 低 | 虚拟列表/分页加载,层级>3 懒加载 |
+| 后台配置未生效(缓存) | 低 | 配置读取走 Redis,更新后清理 |
+
+---
+
+**文档结束**