wish-management-flow.md 11 KB

用户使用流程图 — 心愿管理

端口说明: 📱 小程序 | 🖥 管理后台 | 📋 规划师端 | ⚙️ 系统自动

分层说明: 🏠 页面 → 🔗 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 actor fill:#e1f5fe,stroke:#0288d1,stroke-width:2px,stroke-dasharray:5 3
    classDef decision fill:#fce4ec,stroke:#d32f2f,stroke-width:1px

    %% ============ 角色 ============
    CHILD(("👶 孩子")):::actor
    PARENT(("👤 家长")):::actor
    POINTS(("💎 积分系统")):::actor

    %% ================================================================
    %% 阶段一:心愿创建与审批
    %% ================================================================
    subgraph 阶段一[阶段一:心愿创建与审批]
        direction TB

        P1["🏠 孩子端:创建心愿页"]:::page
        P1 -->|"标题, 描述, 分类"| A1["🔗 POST /api/wishes/create"]:::api
        A1 -->|"role=child → createByChild"| S1["⚙️ WishService.createByChild()"]:::service
        S1 -->|"状态=draft, 未定价"| D1["📦 wishes 表(待定价)"]:::data

        D1 -->|"家庭ID"| P2["🏠 家长端:待处理列表"]:::page
        P2 -->|"查看家庭待办"| A2["🔗 POST /api/wishes/pending"]:::api
        A2 -->|"familyId, 筛选draft状态"| S2["⚙️ WishService.getParentPendingWishes()"]:::service
        S2 -->|"待定价 + 待审批 + 待兑现列表"| D1

        P2 -->|"定价"| P2a["🏠 家长端:定价弹窗"]:::page
        P2a -->|"心愿ID, 所需积分"| A3["🔗 POST /api/wishes/{id}/set-price"]:::api
        A3 -->|"wishId, parentId, pointsRequired"| S3["⚙️ WishService.setPrice()"]:::service
        S3 -->|"状态draft→active, 记录定价者"| D1

        P2 -->|"拒绝"| P2b["🏠 家长端:拒绝弹窗"]:::page
        P2b -->|"心愿ID, 拒绝原因"| A4["🔗 POST /api/wishes/{id}/reject"]:::api
        A4 -->|"wishId, parentId, reason"| S4["⚙️ WishService.rejectWish()"]:::service
        S4 -->|"状态→rejected, 拒绝次数+1"| D1

        %% 家长直接创建
        P2 -->|"家长直接创建"| P2c["🏠 家长端:创建心愿页"]:::page
        P2c -->|"标题, 描述, 目标孩子, 积分"| A1
        A1 -->|"role=parent → createByParent"| S1a["⚙️ WishService.createByParent()"]:::service
        S1a -->|"状态=active, 已定价"| D1
    end

    %% ================================================================
    %% 阶段二:兑换申请与审批
    %% ================================================================
    subgraph 阶段二[阶段二:兑换申请与审批]
        D1 -->|"孩子ID, active状态"| P3["🏠 孩子端:心愿列表"]:::page
        P3 -->|"查看待攒积分心愿"| A5["🔗 POST /api/wishes/list"]:::api
        A5 -->|"role=child → childId"| S5["⚙️ WishService.getChildWishes()"]:::service
        S5 -->|"该孩子所有心愿(含积分进度)"| D1

        P3 -->|"申请兑换"| P3a["🏠 孩子端:申请兑换确认"]:::page
        P3a -->|"心愿ID"| A6["🔗 POST /api/wishes/{id}/exchange"]:::api
        A6 -->|"wishId, childId"| S6["⚙️ WishService.requestExchange()"]:::service
        S6 -->|"检查积分≥所需? 无其他待审批?"| CHECK{"积分充足且无冲突?"}:::decision
        CHECK -->|"是"| D1a["📦 wishes 表(状态→pending_exchange)"]:::data
        CHECK -->|"否"| P3b["🏠 孩子端:提示失败原因"]:::page

        D1a -->|"家庭ID, pending_exchange"| P4["🏠 家长端:待审批兑换列表"]:::page
        P4 -->|"审批兑换"| P4a["🏠 家长端:审批弹窗"]:::page
        P4a -->|"心愿ID, 是否批准"| A7["🔗 POST /api/wishes/{id}/approve-exchange"]:::api
        A7 -->|"wishId, parentId, approved"| S7["⚙️ WishService.approveExchange()"]:::service
        S7 -->|"批准: 扣积分, 状态→approved"| D1b["📦 wishes 表 + family_members 扣积分 + points_logs"]:::data
        S7 -->|"拒绝: 状态→active, 拒绝次数+1"| D1
    end

    %% ================================================================
    %% 阶段三:兑现与收货
    %% ================================================================
    subgraph 阶段三[阶段三:兑现与收货]
        D1b -->|"状态=approved"| P5["🏠 家长端:待兑现列表"]:::page
        P5 -->|"标记已购买"| P5a["🏠 家长端:标记已购买"]:::page
        P5a -->|"心愿ID"| A8["🔗 POST /api/wishes/{id}/fulfill"]:::api
        A8 -->|"wishId, parentId"| S8["⚙️ WishService.markFulfilled()"]:::service
        S8 -->|"状态→exchanging, 记录兑现者"| D1c["📦 wishes 表(状态→exchanging)"]:::data

        D1c -->|"状态=exchanging"| P6["🏠 孩子端:待收货列表"]:::page
        P6 -->|"确认收货"| P6a["🏠 孩子端:确认收货"]:::page
        P6a -->|"心愿ID"| A9["🔗 POST /api/wishes/{id}/confirm"]:::api
        A9 -->|"wishId, childId"| S9["⚙️ WishService.confirmReceived()"]:::service
        S9 -->|"状态→fulfilled, 记录确认时间"| D1d["📦 wishes 表(状态→fulfilled)"]:::data
    end

    %% ================================================================
    %% 阶段四:取消与查询
    %% ================================================================
    subgraph 阶段四[阶段四:取消与查询]
        D1 -->|"draft或active状态"| P7["🏠 心愿详情页"]:::page
        P7 -->|"查看"| A10["🔗 POST /api/wishes/{id}"]:::api
        A10 -->|"wishId"| S10["⚙️ WishService.getWishById()"]:::service
        S10 -->|"心愿完整信息(含状态文本)"| D1

        P7 -->|"取消"| P7a["🏠 取消确认"]:::page
        P7a -->|"心愿ID, 取消原因"| A11["🔗 POST /api/wishes/{id}/cancel"]:::api
        A11 -->|"wishId, userId, reason"| S11["⚙️ WishService.cancelWish()"]:::service
        S11 -->|"状态→cancelled"| D1

        P4 -->|"查看家庭全部"| P7b["🏠 家长端:家庭心愿列表"]:::page
        P7b -->|"家庭ID"| A12["🔗 POST /api/wishes/list?familyId=xxx"]:::api
        A12 -->|"familyId, role=parent"| S12["⚙️ WishService.getFamilyWishes()"]:::service
        S12 -->|"家庭所有心愿(含各孩子)"| D1
    end

    %% ================================================================
    %% 角色关联
    %% ================================================================
    CHILD -.- P1
    CHILD -.- P3
    CHILD -.- P6
    PARENT -.- P2
    PARENT -.- P4
    PARENT -.- P5
    POINTS -.- S7

端点明细

心愿创建与定价

端点 说明 端口 请求数据 响应数据
POST /api/wishes/create 创建心愿(孩子→draft,家长→active) 📱小程序 {title, description, category, childId(家长), pointsRequired(家长)} {id: Long}
POST /api/wishes/{id}/set-price 家长定价(draft→active) 📱小程序 path: id, body: {pointsRequired} {success}
POST /api/wishes/{id}/reject 家长拒绝心愿(draft→rejected) 📱小程序 path: id, body: {reason} {success}
POST /api/wishes/{id}/cancel 取消心愿(draft/active→cancelled) 📱小程序 path: id, body: {reason} {success}

兑换流程

端点 说明 端口 请求数据 响应数据
POST /api/wishes/{id}/exchange 孩子申请兑换(active→pending_exchange) 📱小程序 path: id {success}
POST /api/wishes/{id}/approve-exchange 家长审批兑换 📱小程序 path: id, body: {approved, reason} {success}
POST /api/wishes/{id}/fulfill 家长标记已购买(approved→exchanging) 📱小程序 path: id {success}
POST /api/wishes/{id}/confirm 孩子确认收货(exchanging→fulfilled) 📱小程序 path: id {success}

查询接口

端点 说明 端口 请求数据 响应数据
POST /api/wishes/list 获取心愿列表(孩子/家长视角) 📱小程序 {childId?, familyId?, status?} [WishDTO](含积分进度)
POST /api/wishes/pending 获取待处理列表(家长) 📱小程序 {familyId} [WishDTO](待定价/待审批/待兑现)
POST /api/wishes/{id} 获取心愿详情 📱小程序 path: id WishDTO(含状态文本)

数据实体关系

erDiagram
    Wish {
        Long id PK
        Long familyId FK "家庭ID"
        Long childId FK "目标孩子"
        Long createdBy "创建者"
        string creatorType "child/parent"
        string title "心愿标题"
        string description "描述"
        string category "分类"
        int pointsRequired "所需积分"
        Long pointsSetBy "定价者ID"
        string status "draft/active/pending_exchange/approved/exchanging/fulfilled/cancelled/rejected"
        int rejectCount "拒绝计数"
        string rejectReason
        string cancelReason
    }

    PointsLog {
        Long id PK
        Long childId FK
        int amount "变动量(负=消耗)"
        string type "wish_exchange"
        string description "兑换心愿:xxx"
    }

    FamilyMember ||--o{ Wish : "一个孩子多个心愿"
    FamilyMember ||--o{ PointsLog : "积分流水"
    Wish ||--o{ PointsLog : "兑换产生积分流水"

完整性分析

# 维度 评估 说明
1 流程完整性 ✅ 完整 覆盖心愿完整生命周期:创建(孩子/家长)→定价→兑换申请→审批(含拒绝回退)→标记购买→确认收货→取消,共7种状态的流转
2 异常路径 ✅ 完整 覆盖积分不足检查、同时存在待审批申请、家长拒绝(含原因)、取消(仅draft/active可取消)、并发扣分二次校验
3 端点覆盖 ✅ 完整 12个端点全部映射到流程图,与WishController@PostMapping一致
4 角色覆盖 ✅ 完整 孩子(创建+兑换+收货)和家长(定价+审批+兑现+创建)各有独立流程路径
5 数据实体 ✅ 完整 wishes表、family_members(积分扣减)、points_logs(流水记录)均在图中映射
6 一致性 ✅ 与代码一致 状态机:draft→active→pending_exchange→approved→exchanging→fulfilled,拒绝/取消为终态