stats-report-flow.md 15 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

    %% ============ 角色 ============
    ROLE_PARENT(("👤 家长")):::actor
    ROLE_ADMIN(("🖥 管理员")):::actor

    %% ================================================================
    %% 阶段一:孩子与家庭统计
    %% ================================================================
    subgraph 阶段一[阶段一:孩子与家庭统计]
        direction TB

        P1["🏠 家长端:孩子数据概览页"]:::page
        P1 -->|"查看孩子统计"| A1["🔗 POST /api/stats/child/overview"]:::api
        A1 -->|"childId"| S1["⚙️ ReportStatsController 直接查询 Mapper"]:::service
        S1 -->|"总积分, 月活跃天数, 任务统计, 游戏统计, 近7日积分趋势"| D1["📦 family_member / points_log / task / game_record"]:::data

        P1 -->|"查看家庭汇总"| A1a["🔗 POST /api/stats/family/summary"]:::api
        A1a -->|"familyId"| S1a["⚙️ ReportStatsController 直接查询 Mapper"]:::service
        S1a -->|"各孩子任务完成数/积分/游戏数, 家庭汇总"| D1a["📦 family_member / task / game_record"]:::data

        P1 -->|"查看积分排行"| A1b["🔗 POST /api/stats/points/ranking"]:::api
        A1b -->|"familyId"| S1b["⚙️ ReportStatsController 直接查询 Mapper"]:::service
        S1b -->|"积分降序排行列表"| D1
    end

    %% ================================================================
    %% 阶段二:管理后台仪表盘
    %% ================================================================
    subgraph 阶段二[阶段二:管理后台数据总览]
        direction TB

        P2["🖥 管理后台:仪表盘页"]:::page
        P2 -->|"查看仪表盘汇总"| A2["🔗 POST /api/stats/dashboard"]:::api
        A2 -->|"无参数"| S2["⚙️ StatsController.getDashboardSummary()"]:::service
        S2 -->|"家庭/家长/孩子/规划师总数, 待审核数"| D2["📦 family / user / guide_package / task / after_sales_request"]:::data

        P2 -->|"查看数据总览(新版)"| A2a["🔗 POST /api/stats/overview"]:::api
        A2a -->|"无参数"| S2a["⚙️ StatsController.getOverview()"]:::service
        S2a -->|"平台核心指标+当月新增+活跃用户"| D2

        P2 -->|"查看收入统计"| A2b["🔗 POST /api/stats/revenue"]:::api
        A2b -->|"无参数"| S2b["⚙️ StatsController.getRevenueStats()"]:::service
        S2b -->|"当月/累计/待结算佣金"| D2b["📦 commission_records 表"]:::data

        P2 -->|"查看会员分布"| A2c["🔗 POST /api/stats/membership"]:::api
        A2c -->|"无参数"| S2c["⚙️ StatsController.getMembershipStats()"]:::service
        S2c -->|"免费/家庭/服务商会员数, 活跃试用数, 本月升级数"| D2c["📦 user / trial_membership / member_upgrade_record"]:::data
    end

    %% ================================================================
    %% 阶段三:任务完成率统计
    %% ================================================================
    subgraph 阶段三[阶段三:任务完成率分析]
        direction TB

        P3["📱 家长端:任务统计页"]:::page
        P3 -->|"查看孩子完成率"| A3["🔗 POST /api/stats/child-completion"]:::api
        A3 -->|"childId, startDate, endDate"| S3["⚙️ TaskStatsService.getChildStats()"]:::service
        S3 -->|"孩子任务完成率统计"| D3["📦 task 表(按时间段过滤)"]:::data

        P3 -->|"查看家庭完成率"| A3a["🔗 POST /api/stats/family-completion"]:::api
        A3a -->|"familyId, startDate, endDate"| S3a["⚙️ TaskStatsService.getFamilyStats()"]:::service
        S3a -->|"家庭任务完成率统计"| D3

        P2 -->|"查看每日趋势"| A3b["🔗 POST /api/stats/trend"]:::api
        A3b -->|"无参数"| S3b["⚙️ StatsController.getTrend()"]:::service
        S3b -->|"近30日家庭/用户日增量趋势"| D3b["📦 family / user 表(30天内)"]:::data
    end

    %% ================================================================
    %% 阶段四:地址区域(四级地址)
    %% ================================================================
    subgraph 阶段四[阶段四:地址区域查询]
        direction TB

        P4["🏠 地址选择器:选择省市区"]:::page
        P4 -->|"获取省份列表"| A4["🔗 POST /api/streets/provinces"]:::api
        A4 -->|"无参数"| S4["⚙️ StreetService.getAllProvinces()"]:::service
        S4 -->|"所有省份列表"| D4["📦 streets 表(level=1)"]:::data

        D4 -->|"parentId"| A4a["🔗 POST /api/streets/children/{parentId}"]:::api
        A4a -->|"parentId(path)"| S4a["⚙️ StreetService.getChildrenByParentId()"]:::service
        S4a -->|"下级地址列表"| D4

        D4 -->|"id"| A4b["🔗 POST /api/streets/{id}"]:::api
        A4b -->|"id(path)"| S4b["⚙️ StreetService.getById()"]:::service
        S4b -->|"地址详情"| D4

        D4 -->|"id"| A4c["🔗 POST /api/streets/{id}/path"]:::api
        A4c -->|"id(path)"| S4c["⚙️ StreetService.getAddressPath()"]:::service
        S4c -->|"省市区街道完整路径"| D4

        D4 -->|"keyword"| A4d["🔗 POST /api/streets/search"]:::api
        A4d -->|"keyword"| S4d["⚙️ StreetService.search()"]:::service
        S4d -->|"模糊匹配地址列表"| D4

        D4 -->|"id"| A4e["🔗 POST /api/streets/{id}/match"]:::api
        A4e -->|"id(path)"| S4e["⚙️ StreetService.matchByStreetWithFallback()"]:::service
        S4e -->|"街道/区县/城市级回退匹配结果"| D4

        D4 -->|"level"| A4f["🔗 POST /api/streets/stats"]:::api
        A4f -->|"level"| S4f["⚙️ StreetService.getStatisticsByLevel()"]:::service
        S4f -->|"指定层级的地址统计"| D4

        P4 -->|"获取省份(旧版)"| A4g["🔗 POST /api/region/provinces"]:::api
        A4g -->|"无参数"| S4g["⚙️ RegionController: 内存数据直接返回"]:::service
        S4g -->|"省份列表(内存数据)"| D4g["📦 内存 ALL_REGIONS 静态数据"]:::data

        A4g -->|"parentId"| A4h["🔗 POST /api/region/cities"]:::api
        A4h -->|"parentId"| S4h["⚙️ RegionController: 内存数据过滤"]:::service
        S4h -->|"城市列表"| D4g

        A4h -->|"parentId"| A4i["🔗 POST /api/region/districts"]:::api
        A4i -->|"parentId"| S4i["⚙️ RegionController: 内存数据过滤"]:::service
        S4i -->|"区县列表"| D4g

        A4i -->|"parentId"| A4j["🔗 POST /api/region/streets"]:::api
        A4j -->|"parentId"| S4j["⚙️ RegionController: 同districts"]:::service
        S4j -->|"街道列表"| D4g
    end

    %% ================================================================
    %% 阶段五:用户收货地址
    %% ================================================================
    subgraph 阶段五[阶段五:用户收货地址管理]
        direction TB

        P5["🏠 收货地址管理页"]:::page
        P5 -->|"查看地址列表"| A5["🔗 POST /api/user/address/list"]:::api
        A5 -->|"userId"| S5["⚙️ UserAddressService.list()"]:::service
        S5 -->|"该用户所有地址"| D5["📦 user_address 表"]:::data

        P5 -->|"查看单个地址"| A5a["🔗 POST /api/user/address/get"]:::api
        A5a -->|"id, userId"| S5a["⚙️ UserAddressService.get()"]:::service
        S5a -->|"地址详情"| D5

        P5 -->|"新增地址"| A5b["🔗 POST /api/user/address/create"]:::api
        A5b -->|"receiverName, phone, province, city, district, street"| S5b["⚙️ UserAddressService.create()"]:::service
        S5b -->|"写入一条地址记录"| D5

        P5 -->|"编辑地址"| A5c["🔗 POST /api/user/address/update"]:::api
        A5c -->|"完整地址对象(含id)"| S5c["⚙️ UserAddressService.update()"]:::service
        S5c -->|"更新地址记录"| D5

        P5 -->|"删除地址"| A5d["🔗 POST /api/user/address/delete"]:::api
        A5d -->|"id"| S5d["⚙️ UserAddressService.delete()"]:::service
        S5d -->|"删除地址记录"| D5

        P5 -->|"设为默认"| A5e["🔗 POST /api/user/address/setDefault"]:::api
        A5e -->|"id"| S5e["⚙️ UserAddressService.setDefault()"]:::service
        S5e -->|"更新is_default字段"| D5
    end

    %% ============ 角色关联 ============
    ROLE_PARENT -.- P1
    ROLE_PARENT -.- P3
    ROLE_PARENT -.- P4
    ROLE_PARENT -.- P5
    ROLE_ADMIN -.- P2

端点明细

孩子与家庭统计

端点 说明 端口 请求数据 响应数据
POST /api/stats/child/overview 孩子数据概览(积分/任务/游戏) 📱小程序 {childId} {totalPoints, monthActiveDays, taskStats, gameStats, pointsTrend}
POST /api/stats/family/summary 家庭汇总统计 📱小程序 {familyId} {children[各孩子统计], familyTotalTasks, familyCompletionRate, familyTotalGames, childCount}
POST /api/stats/points/ranking 家庭内积分排行榜 📱小程序 {familyId} [{rank, childId, childName, points}]

管理后台仪表盘

端点 说明 端口 请求数据 响应数据
POST /api/stats/dashboard 仪表盘汇总(旧版) 🖥管理后台 {totalFamilies, totalParents, totalChildren, totalTeachers, pendingGuideCount, pendingPackageCount, pendingRefundCount, recentTasks}
POST /api/stats/overview 数据总览(新版) 🖥管理后台 {totalFamilies, totalParents, totalChildren, totalTeachers, monthFamilies, monthParents, pendingGuides, pendingPackages, activeUsers}
POST /api/stats/revenue 收入统计 🖥管理后台 {monthCommission, totalCommission, pendingCommission}
POST /api/stats/membership 会员分布统计 🖥管理后台 {freeCount, familyCount, providerCount, trialCount, monthUpgrades}

任务完成率

端点 说明 端口 请求数据 响应数据
POST /api/stats/child-completion 孩子任务完成率 📱小程序 {childId, startDate, endDate} TaskStats 对象
POST /api/stats/family-completion 家庭任务完成率 📱小程序 {startDate, endDate} TaskStats 对象
POST /api/stats/trend 每日数据趋势(近30天) 🖥管理后台 {familyTrend, userTrend}

地址区域(数据库版)

端点 说明 端口 请求数据 响应数据
POST /api/streets/provinces 获取所有省份 📱小程序 List<Street>
POST /api/streets/children/{parentId} 获取子级地址 📱小程序 path: parentId List<Street>
POST /api/streets/{id} 获取地址详情 📱小程序 path: id Street
POST /api/streets/{id}/path 获取地址完整路径 📱小程序 path: id List<Street>(省市区街道)
POST /api/streets/search 搜索地址 📱小程序 {keyword} List<Street>
POST /api/streets/{id}/match 区域回退匹配 📱小程序 path: id {streetMatch, districtMatch, cityMatch}
POST /api/streets/stats 按区域统计 📱小程序 {level} {按层级的地址统计}

地址区域(内存版/旧版)

端点 说明 端口 请求数据 响应数据
POST /api/region/provinces 获取省份列表 📱小程序 [{id, name}]
POST /api/region/cities 获取城市列表 📱小程序 {parentId} [{id, name}]
POST /api/region/districts 获取区县列表 📱小程序 {parentId} [{id, name}]
POST /api/region/streets 获取街道列表 📱小程序 {parentId} [{id, name}]

用户收货地址

端点 说明 端口 请求数据 响应数据
POST /api/user/address/list 地址列表 📱小程序 List<UserAddress>
POST /api/user/address/get 获取单个地址 📱小程序 {id} UserAddress
POST /api/user/address/create 新建地址 📱小程序 {receiverName, phone, province, city, district, street} {success}
POST /api/user/address/update 更新地址 📱小程序 {id, receiverName, phone, ...} {success}
POST /api/user/address/delete 删除地址 📱小程序 {id} {success}
POST /api/user/address/setDefault 设为默认地址 📱小程序 {id} {success}

数据实体关系

erDiagram
    Family ||--o{ FamilyMember : "一个家庭多个成员"
    FamilyMember ||--o{ PointsLog : "积分流水"
    FamilyMember ||--o{ Task : "任务记录"
    FamilyMember ||--o{ GameRecord : "游戏记录"
    User ||--o{ UserAddress : "一个用户多个地址"

    Family {
        Long id PK
        date createdAt
    }

    FamilyMember {
        Long id PK
        Long familyId FK
        string nickname
        int totalPoints
    }

    UserAddress {
        Long id PK
        Long userId FK
        string receiverName
        string phone
        string province
        string city
        string district
        string street
        int isDefault
    }

    Street {
        Long id PK
        Long parentId FK
        string province
        string city
        string district
        string street
        string fullName
        int level
    }

    CommissionRecord {
        Long id PK
        Long orderId
        string status "pending/settled"
        int commissionAmount
    }

完整性分析

# 维度 评估 说明
1 流程完整性 ✅ 完整 覆盖5大统计模块:孩子/家庭统计、管理后台仪表盘、任务完成率分析、四级地址查询、用户收货地址管理,数据流向清晰
2 异常路径 ⚠️ 部分覆盖 管理后台仪表盘使用CompletableFuture+try-catch处理统计失败;地址相关接口校验在Service层处理;收人统计返回默认0.0而非报错
3 端点覆盖 ✅ 完整 25个端点全部映射到流程图中,与实际Controller(ReportStatsController、StatsController、StreetController、RegionController、UserAddressController)的@PostMapping一致
4 角色覆盖 ✅ 完整 家长端查看孩子/家庭/任务统计、地址选择和管理;管理后台查看仪表盘/收入/会员/趋势数据
5 数据实体 ✅ 完整 覆盖family_member、points_log、task、game_record、family、user、commission_records、trial_membership、member_upgrade_record、streets、user_address共11个数据表
6 一致性 ✅ 与代码一致 所有端点路径、请求参数、响应字段与实际Controller代码匹配。注意:/api/region/*(RegionController)使用内存数据,/api/streets/*(StreetController)使用数据库数据