9.0 KiB
9.0 KiB
name, overview, design, todos
| name | overview | design | todos | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| dashboard-enrich | 前后端联动丰富运营仪表盘:后端新增趋势统计接口并扩展 summary 的「内容审核 / VIP / 商品」维度,前端引入 ECharts 用折线图、环形图等呈现。 |
|
|
产品概述
在现有运营仪表盘基础上进行可视化升级:保留营收、用户、订单概况与待办横幅,新增时间趋势折线图和内容审核、VIP 会员、商品分类三个分布面板,让运营人员一眼掌握核心数据动态。
核心功能
- 近 7/30 天可切换的趋势折线图:新增用户数、已支付订单量、营收金额(双坐标轴)
- 内容审核概况:穿搭审核状态(待审核/通过/不通过/封禁)、衣物图片处理状态(处理中/成功/失败)、衣柜分享状态(正常/取消/过期/封禁)分布
- VIP 会员概况:有效会员类型分布(月度/年度/体验)及 7 天内即将到期会员数
- 商品分类统计:各类型商品数量分布与上架/下架占比
- 保留现有 summary 各指标与页面布局,新增内容向后兼容、不影响已上线展示
技术栈
- 后端:Go + Gin + GORM(复用现有 StatsDao 直接聚合 MySQL 业务表,不改表结构)
- 前端:Vue 3 + TypeScript + Element Plus + ECharts(新增 echarts 依赖)
- 图表:ECharts 折线图 + 环形饼图
实现方案
后端复用现有 DashboardService 与 StatsDao 模式,将 GET /dashboard/summary 的响应扩展出 content、vip、goods 三个子结构(一次请求拿到全部概况),另新增 GET /dashboard/trends?days=7|30 返回按天对齐的趋势序列(无数据日期补零)。前端引入 ECharts,封装通用 BaseChart.vue 管理实例生命周期,在 DashboardView 内组合趋势折线图与三个环形分布图。
关键决策:
- 趋势单独一个接口:summary 保持轻量只做概况,趋势数据按需加载并支持 7/30 天切换,避免每次都聚合全量日期序列。
- 按天补零在 Go 端完成:SQL 只 group by 有数据的日期,Go 端从起始日期循环补零,保证折线图 x 轴连续、时区正确。
- 双 y 轴:营收(元)与数量量纲不同,趋势图用左轴数量、右轴金额。
- 向后兼容:DashboardResponse 只增字段不改字段,前端旧字段继续渲染,新字段独立面板。
数据口径:
- 趋势新增用户:
users.created_at按日计数;订单量:orders.order_status IN (2,5)且按pay_time计数(与营收同口径);营收:orders.pay_amount求和(分)。 - VIP 有效会员:
vip_type IN (2,3,4) AND vip_expire > now;即将到期:vip_expire BETWEEN now AND now+7*86400。 - 内容审核:穿搭按
audit_status与status=2封禁数;衣物按image_process_status分组(1/2/3 归为处理中、4 成功、5 失败);分享按status分组。
架构设计
flowchart LR
subgraph Frontend
DV[DashboardView.vue] --> BC[BaseChart.vue]
DV --> API[api/dashboard.ts]
DV --> TYPES[types/dashboard.ts]
end
subgraph Backend
H[SummaryHandler / TrendHandler] --> S[DashboardService]
S --> DAO[StatsDao]
DAO --> M[(MySQL 业务表)]
end
API -->|GET /dashboard/summary| H
API -->|GET /dashboard/trends| H
关键数据结构(后端 dto/dashboard.go 扩展)
type DashboardResponse struct {
Users DashboardUsers `json:"users"`
Orders DashboardOrders `json:"orders"`
Revenue DashboardRevenue `json:"revenue"`
Todo DashboardTodo `json:"todo"`
Content DashboardContent `json:"content"`
VIP DashboardVIP `json:"vip"`
Goods DashboardGoods `json:"goods"`
}
type DashboardContent struct {
Outfit DashboardOutfitStats `json:"outfit"`
Clothes DashboardClothesStats `json:"clothes"`
Share DashboardShareStats `json:"share"`
}
type DashboardVIP struct {
MemberTotal int64 `json:"member_total"`
Monthly int64 `json:"monthly"`
Yearly int64 `json:"yearly"`
Trial int64 `json:"trial"`
ExpiringSoon int64 `json:"expiring_soon"`
}
type DashboardGoods struct {
Total int64 `json:"total"`
OnShelf int64 `json:"on_shelf"`
OffShelf int64 `json:"off_shelf"`
ByType []GoodsTypeCount `json:"by_type"`
}
type TrendPoint struct {
Date string `json:"date"` // YYYY-MM-DD
NewUsers int64 `json:"new_users"`
Orders int64 `json:"orders"`
Revenue int64 `json:"revenue"` // 分
}
目录结构
后端 /root/zt-closet-manage-backend/
├── internal/dto/dashboard.go # [MODIFY] 扩展 Content/VIP/Goods 结构与 Trend 请求/响应结构
├── internal/mysqldao/stats.go # [MODIFY] 新增 ContentStatsGet/VIPStatsGet/GoodsStatsGet/TrendStatsGet
├── internal/service/dashboard.go # [MODIFY] Summary 聚合新维度,新增 Trend 方法
├── internal/routers/api/v1/dashboard.go # [MODIFY] 新增 Trend handler
└── internal/routers/router.go # [MODIFY] 注册 GET /dashboard/trends
前端 /root/zt-closet-manage-frontend/
├── package.json # [MODIFY] 新增 echarts 依赖
├── src/components/BaseChart.vue # [NEW] ECharts 通用封装(init/resize/dispose/option 更新)
├── src/types/dashboard.ts # [MODIFY] 新增 Content/VIP/Goods/Trend 类型
├── src/api/dashboard.ts # [MODIFY] 新增 getDashboardTrends
└── src/views/dashboard/DashboardView.vue # [MODIFY] 趋势折线图 + 内容/VIP/商品三个环形图面板
实现要点
- DAO 趋势 SQL 使用
DATE(FROM_UNIXTIME(created_at))/DATE(FROM_UNIXTIME(pay_time))分组,参数为秒级时间戳;返回 map[date]value 后由 service 按起始日期补零。 - StatsDao 各新方法保持
func (d *StatsDao) Xxx(ctx context.Context, ...) (*XxxStats, error)风格,WithContext+span.RecordError,与现有 stats.go 一致。 TrendStatsGet用一次循环构造[]TrendPoint,避免 N+1;days参数在 handler 用ShouldBindQuery校验并限制 1~90。- 前端
BaseChart.vue使用echarts.init,watchoption 深度更新,ResizeObserver监听容器尺寸,onBeforeUnmount时dispose防泄漏。 - 趋势图折线:新增用户/订单量挂左轴,营收挂右轴(
formatMoney转元显示);分布图用 pie 环形,复用现有enumLabel常量映射文案。 - 不改动已有接口字段,保证 summary 旧展示路径不回归;仅在前端
DashboardSummary类型上新增可选字段并渲染新面板。
设计风格
延续现有管理后台的现代清爽风格,在现有渐变 hero 横幅、白底圆角卡片基础上做可视化升级,强调信息密度与层次感。趋势图采用通栏大卡片,内容审核、VIP 会员、商品分类采用三列卡片布局,图表配色与页面既有渐变色系统一。
页面布局
- 顶部保留渐变欢迎横幅与待办数字
- 营收四卡片行保持不变
- 新增通栏「数据趋势」卡片:7 天 / 30 天分段切换 + 双轴折线图
- 新增三列分布卡片:内容审核概况、VIP 会员概况、商品分类统计,各配环形图与关键数字
- 保留原有用户概况、订单概况面板
交互
- 趋势图切换 7/30 天时局部刷新,不整页加载
- 环形图悬停显示数量与占比 tooltip
- 卡片沿用 hover 上浮阴影,保持与现有 stat-card 一致的微动效