业务流程图集¶
跨模块端到端流程,供测试设计用例与新人理解业务。每图附关键校验点。 功能全景见 产品需求总览;业务规则见 membership-agent-sales-guide.md;表结构见 data-model.md。
1. 用户注册 → 购买会员 → 生图¶
sequenceDiagram
participant U as 用户
participant BE as backend
participant DB as DB
participant PAY as 支付渠道
U->>BE: POST /api/auth/send-code
BE->>U: 发短信
U->>BE: POST /api/auth/login
BE->>DB: 创建/查 users
BE-->>U: User JWT
U->>BE: GET /api/billing/plans
U->>BE: POST /api/billing/orders
BE->>DB: orders(pending)
U->>BE: POST /api/billing/orders/{id}/prepay
U->>PAY: 支付
PAY->>BE: POST /api/payment/notify/{method}
BE->>BE: mark_paid(验签+幂等)
BE->>DB: subscriptions + usage_quotas(+积分) + transaction_ledger + commission_records(accrued)
BE-->>PAY: OK
U->>BE: 生图请求(扣点)
BE->>DB: usage_quotas.used += credits + consumption_records
BE-->>U: 生成结果(落 OSS 占容)
校验点:
- 支付回调幂等:同
transaction_id重复 notify 不重复加配额 - 配额不足生图 → 402
- 生成图必须落 OSS 并占容(见流程 4)
2. 代理推广 → 客户绑定 → 分账 → 提现¶
sequenceDiagram
participant A as 代理商
participant C as 客户
participant BE as backend
participant DB as DB
A->>BE: 登录(as_agent=true)
BE->>DB: 创建 agents 行
A->>BE: GET /api/agents/me(拿 agent_code)
C->>BE: GET /api/landing/{referral_code}
BE->>DB: agent_link_clicks+1
C->>BE: POST /api/landing/{code}/bind(登录后)
BE->>DB: customer_agent_bindings(唯一约束)
C->>BE: 购买会员支付成功
BE->>DB: commission_records(accrued) 按规则生成
Note over BE,DB: accrued 不增加 balance_commission
A->>BE: POST /api/admin/commission-settlements/close
BE->>DB: accrued→settled + balance_commission += 汇总(幂等)
A->>BE: POST /api/billing/agents/me/withdraw
BE->>DB: withdrawals(pending) + balance_commission 预占
Note over BE: Admin 审批
BE->>DB: approve → withdrawn += ; reject → 回滚预占
校验点:
- 客户只能绑一个代理(
customer_agent_bindings唯一) - 未月结的 accrued 不可提现
- 月结关账幂等:重复关账不双加
- 提现 reject 回滚预占余额
3. L1/L2 二级代理分账¶
flowchart LR
L1["一级代理<br/>sub_agent_share_rate=30"]
L2["二级代理<br/>(parent=L1)"]
Cust["二级代理的客户"]
L1 -->|"promote-sub-agent"| L2
Cust -->|"下单支付成功"| Calc["计提佣金池"]
Calc -->|"二级规则一笔"| L2Pool["二级 accrued"]
Calc -->|"L1 佣金池 × share_rate"| L2Extra["二级额外 accrued"]
Calc -->|"L1 佣金池 × (1-share_rate)"| L1Pool["一级 accrued"]
校验点:
sub_agent_share_rate仅一级代理档案持有(0~50)- 二级客户成交产生:二级一笔 + 一级再一笔(池内按 share_rate 拆)
- 提拔二级前客户须已绑定该一级
4. 存储占容全生命周期¶
flowchart TD
Upload["用户上传 / 生成图落 OSS"]
Check{"assert<br/>used + size ≤ total?"}
UploadOK["上传成功"]
Commit["used += size"]
UploadFail["拒绝(存储空间不足)"]
Delete["删除资产 / 软删任务"]
Release["used -= size"]
Upload --> Check
Check -->|"是"| UploadOK --> Commit
Check -->|"否"| UploadFail
Delete --> Release
占容入口:
| 场景 | 入口 | 字段 |
|---|---|---|
| 画布 presign 上传 | /canvas/assets/confirm-upload |
object_key, size |
| 画布代传 | /canvas/upload |
成功即 commit |
| 工作区参考图 | /user/storage/upload |
成功即 commit |
| 用户资产 | /user-assets/upload |
落库即 commit |
| AI 生成图 | Worker / 同步生图 | generation_storage_persist |
释容入口:
| 场景 | 入口 |
|---|---|
| 画布删资产 | /canvas/assets/release-storage |
| 用户资产软删 | UserAssetService.delete_asset |
| Admin 软删任务 | TaskService.soft_delete_task(按 image_sizes) |
校验点:
- 上传超限 → 400「存储空间不足」
used不为负- 首次创建 storage 桶时
used初始化为未软删user_assets.size合计 - 订阅激活同步
total,不重置used
5. 日终对账与单户回放¶
sequenceDiagram
participant OP as 运营/Admin
participant BE as backend
participant DB as DB
OP->>BE: POST /api/admin/billing/recon/run (run_date)
BE->>DB: 扫描全体用户/代理账本
BE->>DB: 写 recon_batches(差异列表)
BE-->>OP: 批次结果(绿灯/红灯)
alt 发现差异
OP->>BE: POST /api/admin/billing/replay/user (phone)
BE->>DB: 重算该户账本
BE->>DB: 修复余额(以账本为准)
BE-->>OP: 修复结果
end
校验点:
- 对账恒等式:物化余额 ≈ Σ(ledger) ≈ Σ(业务表)
- 单户回放以账本为真相源修复余额
biz_date(列表筛选)≠run_date(对账执行日)
6. 画布项目乐观锁¶
sequenceDiagram
participant U1 as 用户TabA
participant U2 as 用户TabB
participant BE as backend
participant DB as DB
U1->>BE: POST /api/canvas/projects(创建)
BE->>DB: project(revision=0)
U2->>BE: GET project(拿到 revision=0)
U1->>BE: PUT project (expectedRevision=0)
BE->>DB: revision=1
BE-->>U1: 200 OK (revision=1)
U2->>BE: PUT project (expectedRevision=0)
BE-->>U2: 409 冲突
U2->>BE: GET project(拿 revision=1 重试)
校验点:
expectedRevision不匹配 → HTTP 409- 项目按
user_id隔离,UserA 不可读写 UserB 项目 - 删文件夹 → 项目
folder_id变 NULL,项目不删