bindbox-game/.trae/documents/实现管理端工作台接口.md
邹方成 87ad4177b1
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(工作台): 实现管理端工作台接口并优化数据展示
feat(抽奖动态): 修复抽奖动态未渲染问题并优化文案展示
fix(用户概览): 修复用户概览无数据显示问题
feat(新用户列表): 在新用户列表显示称号明细
refactor(待办事项): 移除代办模块并全宽展示实时动态
feat(批量操作): 限制为单用户操作并在批量时提醒
fix(称号分配): 防重复分配称号的改造计划
perf(接口性能): 优化新用户和抽奖动态接口性能
feat(订单漏斗): 优化订单转化漏斗指标计算
docs(测试计划): 完善盲盒运营API核查与闭环测试计划
2025-11-16 14:00:29 +08:00

127 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 当前情况
- 管理端“工作台”路由:`web/admin/src/router/modules/dashboard.ts:3-24`
- 工作台页面:`web/admin/src/views/dashboard/console/index.vue`
- 工作台数据源:`web/admin/src/api/dashboard.ts` 全为本地 Mock无真实后端调用
- 后端已存在管理端认证路由分组:`internal/router/router.go:55-151`但未注册任何“dashboard”端点
## 技术栈与约束
- 后端Gin + GORM Gen入口 `main.go:52-67`,路由 `internal/router/router.go`
- 数据模型可用:`internal/repository/mysql/model/*.gen.go`(如 `users``activity_draw_logs``user_item_cards``user_points``guild_members`
- 认证:管理端统一走 `Authorization` 头(`LoginVerifyToken`),同组复用:`internal/router/router.go:56`
## 端点设计(前缀 `/api/admin/dashboard`
1) `GET /cards`
- 入参:`rangeType=today|7d|30d|custom`,可选 `start=YYYY-MM-DD&end=YYYY-MM-DD`custom 时)
- 出参:`CardStat`(与 `web/admin/src/api/dashboard.ts` 一致)
- 统计口径:
- `itemCardSales``user_item_cards.created_at` 范围新增数(`user_item_cards`
- `drawCount``activity_draw_logs.created_at` 范围次数(`activity_draw_logs`
- `newUsers``users.created_at` 范围新增数(`users`
- `totalPoints`:全量有效积分总和(`user_points.points` 过滤 `valid_end` 未过期),实现参考 `internal/service/user/points_balance.go:8-21`
- 环比字段 `*_Change`:与上一等长时间窗口对比百分比(向下取整),无前窗则返回 `+0%`
2) `GET /user_trend`
- 入参:`rangeType``granularity=day|week|month`
- 出参:`UserTrendResp`
- 统计:按粒度聚合 `users.created_at` 计数生成时间序列
3) `GET /draw_trend`
- 入参:同上
- 出参:`DrawTrendResp`
- 统计:按粒度聚合 `activity_draw_logs.created_at` 计数生成时间序列
4) `GET /new_users`
- 入参:`page``page_size`
- 出参:`NewUserListResp`
- 明细项字段:
- `pointsBalance`:用户有效积分余额(复用 `GetPointsBalance` 逻辑 `internal/service/user/points_balance.go:8-21`
- `inventoryCount``user_inventory` 记录数(状态过滤视业务)
- `itemCardCount``user_item_cards` 有效未使用数量(`status=1`
5) `GET /draw_stream`
- 入参:`since_id`(可选)、`limit`(默认 50最大 100
- 出参:`DrawStreamResp`
- 统计:按 `id` 递减拉取最近抽奖日志,关联 `users.nickname``activity_issues.name` 生成展示项;返回 `sinceId = max(id)` 以便前端轮询增量
6) `GET /todos`
- 入参:`limit`(默认 50最大 100
- 出参:`TodoListResp`
- 规则:
- `bind_mobile``users.mobile IS NULL OR ''`
- `join_guild``NOT EXISTS guild_members WHERE user_id=users.id AND status=1`
- 返回 `avatar``nickname``taskLabel` 友好文案
## 后端改动点
- 新增处理器:`internal/api/admin/dashboard_admin.go`
- 采用现有 handler 模式:`internal/api/admin/admin.go:16-42`
- 为每个端点提供 `core.HandlerFunc`,入参校验使用 `ShouldBindForm/JSON``internal/pkg/validation`
- 新增服务层:`internal/service/admin/dashboard_*.go`
- `GetCardStats(ctx, range)`, `GetUserTrend(ctx, range, granularity)`, `GetDrawTrend(...)`
- `ListNewUsersWithStats(ctx, page, pageSize)`多表聚合users + user_points + user_item_cards + user_inventory
- `ListDrawStream(ctx, sinceID, limit)`:抽奖日志联表 users、activity_issues
- `ListTodos(ctx, limit)`:基于 users 与 guild_members 规则
- 路由注册:在管理端认证组添加
- 文件:`internal/router/router.go`
- 组:`adminAuthApiRouter``internal/router/router.go:55-151`
- 注册形如:
- `adminAuthApiRouter.GET("/dashboard/cards", adminHandler.DashboardCards())`
- `adminAuthApiRouter.GET("/dashboard/user_trend", adminHandler.DashboardUserTrend())`
- `adminAuthApiRouter.GET("/dashboard/draw_trend", adminHandler.DashboardDrawTrend())`
- `adminAuthApiRouter.GET("/dashboard/new_users", adminHandler.DashboardNewUsers())`
- `adminAuthApiRouter.GET("/dashboard/draw_stream", adminHandler.DashboardDrawStream())`
- `adminAuthApiRouter.GET("/dashboard/todos", adminHandler.DashboardTodos())`
## 前端改动点
- 更新 `web/admin/src/api/dashboard.ts`
-`request.get` 替换 Mock
- `fetchCardStats(range)``GET admin/dashboard/cards`
- `fetchUserTrend(range, granularity)``GET admin/dashboard/user_trend`
- `fetchDrawTrend(range, granularity)``GET admin/dashboard/draw_trend`
- `fetchNewUsers(page, pageSize)``GET admin/dashboard/new_users`
- `fetchDrawStream(sinceId, limit)``GET admin/dashboard/draw_stream`
- `fetchTodos(limit)``GET admin/dashboard/todos`
- 保持 TS 接口不变,便于无缝替换
## 数据来源与代码参考
- 路由分组:`internal/router/router.go:55-61`
- 抽奖日志分页示例:`internal/service/activity/draw_logs_list.go:9-28`
- 用户积分余额:`internal/service/user/points_balance.go:8-21`
- 用户综合统计:`internal/service/user/stats.go:13-38`
- 数据模型表:`internal/repository/mysql/model/*.gen.go`(如 `users.gen.go:15-29``activity_draw_logs.gen.go:13-24``user_item_cards.gen.go:13-28``guild_members.gen.go:13-23`
## 接口示例返回
- `GET /api/admin/dashboard/cards`
```json
{
"itemCardSales": 1234,
"drawCount": 5678,
"newUsers": 321,
"totalPoints": 98765,
"itemCardChange": "+12%",
"drawChange": "+8%",
"newUserChange": "+5%",
"pointsChange": "+3%"
}
```
- `GET /api/admin/dashboard/user_trend` / `draw_trend``{ "granularity": "day", "list": [{"date":"2025-11-01","value":100}, ...] }`
- 其他返回与 `web/admin/src/api/dashboard.ts` 对齐
## 验证与测试
- Swagger 注解与分组标签:沿用现有风格(参考 `internal/api/admin/users_admin.go:30-46`
- 集成测试:参考 `internal/api/admin/titles_admin_test.go` 新增 API 测试用例(登录获取 Token 后调用)
- 手动验证:
- 后端:`curl -H "Authorization: <token>" "http://localhost:<port>/api/admin/dashboard/cards?rangeType=7d"`
- 前端:工作台各模块正常展示且不再使用随机数据
## 性能与索引建议
-`users.created_at``activity_draw_logs.created_at``user_item_cards.created_at` 建立索引
- 汇总接口注意分页与时间窗口限制,默认范围 7 天,可配置上限 30 天
## 交付范围与验收
- 完成 6 个端点后,前端工作台所有模块均有真实数据源
- 验收:页面展示与接口返回满足 TS 类型Swagger 文档可用;管理员认证校验生效
确认后我将:
- 在后端新增处理器与服务实现并注册路由
- 替换前端 `dashboard.ts` 的 Mock 为真实请求
- 补充必要的 Swagger 注释与最小测试用例