用户使用流程图 — 积分兑换
端口说明: 📱 小程序 | 🖥 管理后台 | 📋 规划师端 | ⚙️ 系统自动
分层说明: 🏠 页面 → 🔗 API → ⚙️ Service → 📦 数据实体
flowchart TD
%% ============ 颜色定义 ============
classDef page fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef api fill:#fff3e0,stroke:#f57c00,stroke-width:1px
classDef service fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
classDef data fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px
classDef external fill:#fce4ec,stroke:#d32f2f,stroke-width:1px,stroke-dasharray:3 2
classDef actor fill:#e1f5fe,stroke:#0288d1,stroke-width:2px,stroke-dasharray:5 3
%% ============ 角色 ============
ROLE_PARENT(("👤 家长")):::actor
ROLE_CHILD(("👶 孩子")):::actor
ROLE_SYSTEM(("⚙️ 积分引擎")):::actor
%% ================================================================
%% 阶段一:积分概览
%% ================================================================
subgraph 阶段一[阶段一:积分概览]
direction TB
P1["🏠 小程序:积分中心"]:::page
P1 -->|"选择操作"| P1_choice{"查看余额 / 流水 / 系统积分"}
P1_choice -->|"查看余额"| P1a["🏠 积分余额页"]
P1a -->|"孩子ID"| A1["🔗 POST /api/points/balance"]:::api
A1 -->|"孩子ID"| S1["⚙️ PointsService.getBalance()"]:::service
S1 -->|"当前积分 + 过期时间"| D1["📦 family_members 表(totalPoints查询)"]:::data
P1_choice -->|"积分流水"| P1b["🏠 积分流水页"]
P1b -->|"孩子ID, 分页"| A2["🔗 POST /api/points/logs"]:::api
A2 -->|"孩子ID, 页码, 页大小"| S2["⚙️ PointsService.getPointsLogs()"]:::service
S2 -->|"积分变动记录(类型+金额+描述)"| D2["📦 points_logs 表"]:::data
P1_choice -->|"按分类筛选"| P1c["🏠 流水分类筛选"]
P1c -->|"孩子ID, 分类, 分页"| A3["🔗 POST /api/points/logs-by-category"]:::api
A3 -->|"分类(task/system)"| S3["⚙️ PointsService.getPointsLogsByCategory()"]:::service
S3 -->|"按分类过滤的流水"| D2
P1_choice -->|"系统积分余额"| P1d["🏠 系统积分页"]
P1d -->|"孩子ID"| A4["🔗 POST /api/points/system-balance"]:::api
A4 -->|"孩子ID"| S4["⚙️ PointsService.getSystemPointsBalance()"]:::service
S4 -->|"系统积分数量"| D1
end
%% ================================================================
%% 阶段二:积分调整
%% ================================================================
subgraph 阶段二[阶段二:积分调整]
D1 -->|"孩子积分"| P2["🖥 管理后台:积分调整页"]:::page
P2 -->|"手动调整"| A5["🔗 POST /api/points/adjust"]:::api
A5 -->|"孩子ID, 调整金额, 原因, 家长密码"| S5["⚙️ PointsService.adjustPoints()"]:::service
S5 -->|"更新余额 + 写入流水"| D1
S5 -->|"调整记录"| D2
P2 -->|"系统发放"| P2a["⚙️ 系统自动奖励"]
P2a -->|"孩子ID, 金额, 原因"| S5a["⚙️ PointsService.awardSystemPoints()"]:::service
S5a -->|"增加系统积分 + 流水"| D1
S5a -->|"奖励记录"| D2
P2a -->|"系统扣除"| P2b["⚙️ 系统自动扣除"]
P2b -->|"孩子ID, 金额, 原因"| S5b["⚙️ PointsService.deductSystemPoints()"]:::service
S5b -->|"余额不足返回-1, 否则扣除"| D1
S5b -->|"扣除记录"| D2
end
%% ================================================================
%% 阶段三:积分兑换商城
%% ================================================================
subgraph 阶段三[阶段三:积分兑换商城]
D1 -->|"积分余额"| P3["📱 小程序:兑换商城页"]:::page
P3 -->|"商品列表"| A6["🔗 POST /api/points/exchange/product/list"]:::api
A6 -->|"分类, 分页"| S6["⚙️ PointsExchangeService.getProductList()"]:::service
S6 -->|"已启用的兑换商品(按排序)"| D3["📦 points_exchange_products 表"]:::data
P3 -->|"商品详情"| P3a["📱 商品详情页"]
P3a -->|"商品ID"| A7["🔗 POST /api/points/exchange/product/detail"]:::api
A7 -->|"商品ID"| S7["⚙️ PointsExchangeService.getProductDetail()"]:::service
S7 -->|"商品完整信息"| D3
P3a -->|"提交兑换"| P3b["📱 兑换确认"]
P3b -->|"商品ID, 孩子ID, 数量"| A8["🔗 POST /api/points/exchange/submit"]:::api
A8 -->|"商品ID, 孩子ID, 数量"| S8["⚙️ PointsExchangeService.exchangeProduct()"]:::service
S8 -->|"校验库存/每日限额/积分→扣积分→生成兑换码"| S8a["⚙️ PointsService.deductSystemPoints()"]:::service
S8a -->|"扣除积分"| D1
S8 -->|"写入兑换记录"| D4["📦 points_exchange_records 表"]:::data
S8 -->|"扣减库存"| D3
P3 -->|"兑换记录"| P3c["📱 兑换记录页"]
P3c -->|"用户ID"| A9["🔗 POST /api/points/exchange/records"]:::api
A9 -->|"用户ID"| S9["⚙️ PointsExchangeService.getExchangeRecords()"]:::service
S9 -->|"兑换记录列表"| D4
P3 -->|"兑换统计"| P3d["📱 今日兑换次数"]
P3d -->|"用户ID"| A10["🔗 POST /api/points/exchange/stats"]:::api
A10 -->|"用户ID"| S10["⚙️ PointsExchangeService.getExchangeStats()"]:::service
S10 -->|"今日兑换次数"| D4
end
%% ================================================================
%% 阶段四:奖励心愿系统
%% ================================================================
subgraph 阶段四[阶段四:奖励心愿系统]
D1 -->|"孩子积分"| P4["📱 孩子端:心愿页"]:::page
P4 -->|"创建心愿"| P4a["📱 心愿表单"]
P4a -->|"标题, 分类"| A11["🔗 POST /api/rewards/create"]:::api
A11 -->|"用户ID, 标题, 分类, 孩子ID"| S11["⚙️ RewardService.createReward()"]:::service
S11 -->|"写入心愿, 状态=available"| D5["📦 rewards 表"]:::data
P4a -->|"创建心愿(孩子→等待家长填积分)"| P4b["📱 孩子创建待审批心愿"]
P4b -->|"标题, 分类"| A11a["🔗 POST /api/reward-wishlist/create"]:::api
A11a -->|"用户ID, 心愿信息"| S11a["⚙️ RewardWishlistService.create()"]:::service
S11a -->|"写入心愿单, 状态=pending"| D6["📦 reward_wishlists 表"]:::data
P4 -->|"心愿列表"| P4c["📱 心愿列表"]
P4c -->|"孩子ID"| A12["🔗 POST /api/rewards/wishlist"]:::api
A12 -->|"孩子ID"| S12["⚙️ RewardService.getWishlist()"]:::service
S12 -->|"可兑换的心愿列表"| D5
P4 -->|"奖励模板"| P4d["📱 奖励模板"]
P4d -->|""| A13["🔗 POST /api/rewards/templates"]:::api
A13 -->|""| S13["⚙️ RewardService.getTemplates()"]:::service
S13 -->|"奖励模板列表"| D5
D5 -->|"可兑换心愿"| P4e["📱 兑换心愿"]
P4e -->|"心愿ID, 孩子ID"| A14["🔗 POST /api/rewards/{id}/exchange"]:::api
A14 -->|"心愿ID, 孩子ID"| S14["⚙️ RewardService.exchangeReward()"]:::service
S14 -->|"校验积分→扣积分→状态=pending"| D1
S14 -->|"记录积分消耗"| D2
S14 -->|"更新心愿状态"| D5
D6 -->|"待审批心愿"| P4f["🖥 家长端:审批心愿页"]
P4f -->|"获取家庭心愿"| A15["🔗 POST /api/reward-wishlist/family"]:::api
A15 -->|"用户ID"| S15["⚙️ RewardWishlistService.getByFamilyId()"]:::service
S15 -->|"家庭所有心愿单"| D6
P4f -->|"审批通过"| P4g["🖥 审批弹窗"]
P4g -->|"心愿ID"| A16["🔗 POST /api/reward-wishlist/{id}/approve"]:::api
A16 -->|"心愿ID, approved=true"| S16["⚙️ RewardWishlistService.approve()"]:::service
S16 -->|"更新状态=exchanged"| D6
P4f -->|"审批拒绝"| P4h["🖥 拒绝弹窗"]
P4h -->|"心愿ID"| A16
S16 -->|"更新状态=rejected"| D6
D5 -->|"待审批兑换"| P4i["🖥 家长端:审批兑换页"]
P4i -->|"审批"| A17["🔗 POST /api/rewards/{id}/approve"]:::api
A17 -->|"心愿ID, approved"| S17["⚙️ RewardService.approveReward()"]:::service
S17 -->|"同意→状态=exchanged; 拒绝→退积分"| D5
P4 -->|"兑换历史"| P4j["📱 兑换历史"]
P4j -->|"孩子ID, 分页"| A18["🔗 POST /api/rewards/exchange-history"]:::api
A18 -->|"孩子ID, 页码, 页大小"| S18["⚙️ RewardService.getExchangeHistory()"]:::service
S18 -->|"已兑换/已拒绝的心愿历史"| D5
end
%% ================================================================
%% 角色关联
%% ================================================================
ROLE_PARENT -.- P1
ROLE_PARENT -.- P2
ROLE_PARENT -.- P4f
ROLE_PARENT -.- P4i
ROLE_CHILD -.- P1
ROLE_CHILD -.- P4
ROLE_CHILD -.- P4e
ROLE_SYSTEM -.- P2a
ROLE_SYSTEM -.- P2b
端点明细
积分概览与流水
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/points/balance |
获取积分余额 |
📱小程序 |
{childId} |
{balance, expireDate} |
POST /api/points/logs |
获取积分流水 |
📱小程序 |
{childId, page, size} |
分页积分流水(类型/金额/描述) |
POST /api/points/logs-by-category |
按分类查询流水 |
📱小程序 |
{childId, category, page, size} |
按分类过滤的流水 |
POST /api/points/system-balance |
系统积分余额 |
📱小程序 |
{childId} |
{systemPoints} |
积分调整
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/points/adjust |
手动调整积分 |
🖥管理后台 |
{childId, amount, reason, password} |
{newBalance} |
POST /api/points/adjust |
手动调整积分 |
📱小程序 |
{childId, amount, reason, password} |
{newBalance} |
积分兑换商城
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/points/exchange/product/list |
兑换商品列表 |
📱小程序 |
{category, pageNum, pageSize} |
分页兑换商品列表 |
POST /api/points/exchange/product/detail |
商品详情 |
📱小程序 |
{id} |
PointsExchangeProduct对象 |
POST /api/points/exchange/submit |
提交兑换 |
📱小程序 |
{productId, childId, quantity} |
PointsExchangeRecord(含兑换码) |
POST /api/points/exchange/records |
兑换记录 |
📱小程序 |
Header: userId |
兑换记录列表 |
POST /api/points/exchange/stats |
兑换统计 |
📱小程序 |
Header: userId |
{todayCount} |
奖励心愿系统
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/rewards/create |
创建奖励(家长直接创建) |
📱小程序 |
{childId, title, pointsRequired, category} |
奖励ID |
POST /api/rewards/wishlist |
获取心愿列表 |
📱小程序 |
{childId} |
可兑换的心愿列表(含进度) |
POST /api/rewards/{id}/exchange |
兑换奖励 |
📱小程序 |
{childId} |
{success, newBalance} |
POST /api/rewards/{id}/approve |
审批奖励(家长) |
📱小程序 |
{approved} |
boolean |
POST /api/rewards/templates |
获取奖励模板 |
📱小程序 |
— |
奖励模板列表 |
POST /api/rewards/exchange-history |
兑换历史 |
📱小程序 |
{childId, page, size} |
分页兑换历史 |
POST /api/reward-wishlist/create |
创建心愿(孩子→待家长审批) |
📱小程序 |
{title, description, category} |
心愿ID |
POST /api/reward-wishlist/my |
我的心愿单 |
📱小程序 |
Header: userId |
心愿单列表 |
POST /api/reward-wishlist/family |
家庭心愿单 |
📱小程序 |
Header: userId |
家庭所有心愿单 |
POST /api/reward-wishlist/{id}/exchange |
兑换心愿 |
📱小程序 |
path: id |
boolean |
POST /api/reward-wishlist/{id}/approve |
审核心愿 |
📱小程序 |
{approved} |
boolean |
数据实体关系
erDiagram
FamilyMember ||--o{ PointsLog : "一个孩子多条积分流水"
FamilyMember ||--o{ Reward : "一个孩子多个心愿"
FamilyMember ||--o{ PointsExchangeRecord : "一个孩子多次兑换"
FamilyMember ||--o{ RewardWishlist : "一个孩子多个心愿单"
PointsExchangeProduct ||--o{ PointsExchangeRecord : "一个商品多次兑换"
FamilyMember {
Long id PK
int totalPoints "总积分"
int systemPoints "系统积分"
string nickname
}
PointsLog {
Long id PK
Long childId FK
int amount "正=收入, 负=支出"
string type "earn / spend / adjust / refund"
string category "task / system"
string description
}
PointsExchangeProduct {
Long id PK
string name
int pointsPrice
int stock "-1=不限"
string category
string status "enabled / disabled"
}
PointsExchangeRecord {
Long id PK
Long userId FK
Long familyMemberId FK
Long productId FK
string productName
int pointsCost
int quantity
string status "completed / expired"
string redeemCode
}
Reward {
Long id PK
Long familyId FK
Long childId FK
string title
int pointsRequired
string category
string status "pending_approval / available / pending / exchanged / rejected"
int exchangeApproved
}
RewardWishlist {
Long id PK
Long familyId FK
Long userId FK
string title
string description
int pointsRequired
string status "pending / exchanged / rejected"
int exchangeApproved
}
完整性分析
| # |
维度 |
评估 |
说明 |
| 1 |
流程完整性 |
✅ 完整 |
覆盖积分概览→积分调整→兑换商城→奖励心愿系统4个阶段,包含家长端、孩子端、管理后台、系统自动4种视角 |
| 2 |
异常路径 |
⚠️ 部分覆盖 |
积分不足、余额为负保护、每日兑换限额、库存不足已覆盖;心愿审批拒绝退积分逻辑已覆盖;密码验证失败等前端校验未在图里展开 |
| 3 |
端点覆盖 |
✅ 完整 |
16个端点全部映射到流程图中,与代码中PointsController、PointsExchangeController、RewardController、RewardWishlistController一致 |
| 4 |
角色覆盖 |
✅ 完整 |
家长(查看/调整积分/审批心愿)、孩子(查看/兑换/创建心愿)、系统(自动奖励/扣除)、管理后台(调整积分)均已覆盖 |
| 5 |
数据实体 |
✅ 完整 |
family_members、points_logs、points_exchange_products、points_exchange_records、rewards、reward_wishlists 6张表均在图中映射 |
| 6 |
一致性 |
✅ 与代码一致 |
所有端点路径与实际Controller中的@PostMapping匹配,Service方法名与代码中的业务方法一致(getBalance/getPointsLogs/exchangeProduct/createReward等) |