docs: 添加数据看板文档设计
This commit is contained in:
parent
a7854a4fe7
commit
20e3fcedc4
732
docs/figma-analysis-data-dashboard.md
Normal file
732
docs/figma-analysis-data-dashboard.md
Normal file
@ -0,0 +1,732 @@
|
|||||||
|
# 数据看板页面 - 完整设计文档
|
||||||
|
|
||||||
|
> **Figma Source**: [数据看板 - 节点 29-40](https://www.figma.com/design/EMJR1LQpXBnJNSfea4kq4o/数据看板?node-id=29-40)
|
||||||
|
> **页面名称**: 数据看板 / Data Dashboard
|
||||||
|
> **画板尺寸**: 375 × 1281 (iPhone 12/13/14)
|
||||||
|
> **版本**: 初版设计稿 v0.1
|
||||||
|
> **文档版本**: 1.0
|
||||||
|
> **最后更新**: 2026-06-02
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 〇、文档概览
|
||||||
|
|
||||||
|
| 项目 | 内容 |
|
||||||
|
|------|------|
|
||||||
|
| 目标用户 | 已入驻顶粉星城的活跃用户 |
|
||||||
|
| 核心价值 | 让用户一目了然地看到自己的水晶收益、藏品表现、升级进度 |
|
||||||
|
| 页面定位 | 粉丝应援类数据可视化页(与 square 排行、exhibition 展出、tasks 任务并列) |
|
||||||
|
| 入口位置 | 个人中心 / 顶部 Banner 入口 / 任务完成跳转 |
|
||||||
|
| 主要功能 | 6 大模块:水晶概览、7日曲线、展出收益、点赞收益、藏品矩阵、升级进度 |
|
||||||
|
| 技术栈 | Vue + uni-app(前端) / Go + gRPC(后端,galleryService + userService) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、页面布局结构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────┐ 0px
|
||||||
|
│ ⌚ iPhone Status Bar │ 44px
|
||||||
|
├──────────────────────────────────────┤
|
||||||
|
│ 🟣 毛绒怪头像 "数据看板" 渐变标题 │ 77px
|
||||||
|
│ [水晶相关] [赛季总览] Tab 切换 │ 133px
|
||||||
|
│ ╭──────────╮ ╭──────────╮ │
|
||||||
|
│ │ 水晶余额 │ │ 今日收益 │ │ 184px
|
||||||
|
│ │ 2713 │ │ + 213 │ │
|
||||||
|
│ ╰──────────╯ ╰──────────╯ │
|
||||||
|
├──────────────────────────────────────┤
|
||||||
|
│ 📈 七日收益曲线 │ 184-288px
|
||||||
|
│ + 312 2026.06.01 柱状+折线图 │
|
||||||
|
├──────────────────────────────────────┤
|
||||||
|
│ 🖼 展出收益中心 │ 295px
|
||||||
|
│ 21/33 712:13:56 39721 │ 顶部3联统计
|
||||||
|
│ ┌──┬─────────┬──────┬──────┐ │
|
||||||
|
│ │图│144:13:56│ 2173 │ 15/H │ │ 5行藏品表格
|
||||||
|
│ │图│ 77:13:56│ 1332 │ 15/H │ │
|
||||||
|
│ │图│ 64:15:37│ 1201 │ 12/H │ │
|
||||||
|
│ │图│ 51:22:12│ 783 │ 12/H │ │
|
||||||
|
│ │图│ 51:22:12│ 783 │ 12/H │ │
|
||||||
|
│ └──┴─────────┴──────┴──────┘ │
|
||||||
|
├──────────────────────────────────────┤
|
||||||
|
│ ❤️ 点赞收益看板 │ 580px
|
||||||
|
│ 累积点赞 231 │ 等级 │ 收益 │
|
||||||
|
│ 累计收益 12719 │ UR │ 723 │
|
||||||
|
│ │ SSR │ 381 │
|
||||||
|
│ │ SR │ 233 │
|
||||||
|
│ │ SR │ 169 │
|
||||||
|
│ │ R │ 57 │
|
||||||
|
├──────────────────────────────────────┤
|
||||||
|
│ 🏆 藏品矩阵 │ 870px
|
||||||
|
│ ┌─ 历史藏品收益TOP5 ──────────────┐ │
|
||||||
|
│ │ [图1] [图2] [图3] [图4] [图5] │ │
|
||||||
|
│ │ TOP1 TOP2 TOP3 TOP4 TOP5 │ │
|
||||||
|
│ └─────────────────────────────────┘ │
|
||||||
|
│ ┌─ 藏品等级分布(环形) ──────────┐ │
|
||||||
|
│ │ ⓤ ⓢ ⓢ ⓡ ⓝ │ │
|
||||||
|
│ │ 1 2 5 6 0 │ │
|
||||||
|
│ │ 3% 6% 13% 17% 0% │ │
|
||||||
|
│ └─────────────────────────────────┘ │
|
||||||
|
│ ┌─ 即将升级藏品 ┐ ┌─ 最近升级藏品 ┐│
|
||||||
|
│ │ [图1] 73%/92% │ │ [图1] Lv UP ││
|
||||||
|
│ │ [图2] 75%/96% │ │ [图2] Lv UP ││
|
||||||
|
│ │ [图3] 97%/71% │ │ [图3] Lv UP ││
|
||||||
|
│ └───────────────┘ └────────────────┘│
|
||||||
|
└──────────────────────────────────────┘ 1281px
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、核心组件详解
|
||||||
|
|
||||||
|
### 2.1 状态栏 (iPhone=Status Bar)
|
||||||
|
- 引用 Figma Component Set `11:6` (Iphone) 的 `11:7` 实例
|
||||||
|
- 高 44px,黑底白字,y: 0-44
|
||||||
|
|
||||||
|
### 2.2 顶部装饰区 (y: 77-178)
|
||||||
|
| 元素 | 类型 | 位置 (x, y) | 尺寸 | 关键样式 |
|
||||||
|
|------|------|-------------|------|----------|
|
||||||
|
| 毛绒怪头像 | 图片 | (141, 77) | 104×99 | 红色模糊阴影 `box-shadow: 2px 2px 4px rgba(242, 21, 21, 0.47)` + 模糊 `blur(29.8px)` |
|
||||||
|
| "数据看板" 标题 | 文字 | (229, 37) | 127×33 | 渐变文字 + 黑色投影 |
|
||||||
|
| Tab 1 - 水晶相关 | 文字 | (165, 92) | 60×18 | Inter Bold 15px, 白字+阴影 |
|
||||||
|
| Tab 2 - 赛季总览 | 文字 | (275, 101) | 60×18 | 同上 |
|
||||||
|
| Tab 胶囊背景 | 渐变矩形 | (16, 133) (192, 133) | 168×45 | 紫蓝粉渐变 `231deg, #A8A6ED → #88C8D8 → #F380EF` |
|
||||||
|
| 装饰光晕 | 渐变 + 模糊 | (0, -350) | 375×2393 | `linear-gradient(179deg, #FFE5E5 → #F3A0A1 → #FF9C9C 86% → #FF2024)` + `blur(4px)` |
|
||||||
|
|
||||||
|
### 2.3 数据卡片 - 双列 (y: 184-288)
|
||||||
|
|
||||||
|
| 字段 | 数值 | 字体 | 颜色 | 阴影 |
|
||||||
|
|------|------|------|------|------|
|
||||||
|
| 水晶余额 | 2713 | Baloo Bhai 35px | #FFFABD 金黄 | `-1px 1px 4px rgba(206, 9, 9, 0.84)` |
|
||||||
|
| 今日收益 | + 213 | Baloo Bhai 35px | #FFFABD | 同上 |
|
||||||
|
| 标签 - 水晶余额 | - | Inter Medium 12px | #FFFFFF | `0px 4px 4px rgba(164, 60, 60, 0.55)` |
|
||||||
|
| 标签 - 今日收益 | - | 同上 | 同上 | 同上 |
|
||||||
|
|
||||||
|
### 2.4 七日收益曲线 (y: 184-288)
|
||||||
|
- **背景**: 渐变卡片 `135deg, #FFDF77 → #8E95E2 → #F48CFF` + 红色投影
|
||||||
|
- **柱状图**: 3 根渐变柱(左下到右上排列)尺寸 106×40px
|
||||||
|
- 柱 1 渐变: `135deg, #FFDF77 → #B984FF → #FF8183`
|
||||||
|
- **折线 + 高亮**: 蓝黄渐变线 `90deg, #1BAFEE → #FFCC14`
|
||||||
|
- 高亮点数据: `+ 312` (2026.06.01)
|
||||||
|
- **日期标签**: "2026.06.01" - Inter 9px
|
||||||
|
- **标题**: "七日收益曲线" - Inter 12px Medium
|
||||||
|
|
||||||
|
### 2.5 展出收益中心 (y: 295-574)
|
||||||
|
- **标题**: "展出收益中心" - Inter Bold 18px
|
||||||
|
- **装饰圆点**: Ellipse 4 (装饰性发光圆)
|
||||||
|
- **3 联顶部统计**:
|
||||||
|
| 字段 | 数值 | 字体 |
|
||||||
|
|------|------|------|
|
||||||
|
| 展出中/星册中 | 21 / 33 | Baloo Bhai 14px |
|
||||||
|
| 累计展出时长 | 712:13:56 | Baloo Bhai 14px |
|
||||||
|
| 累计展出收益 | 39721 | Baloo Bhai 14px |
|
||||||
|
- **数据表格**(5行):
|
||||||
|
| 七日展出时长 | 七日收益 | 平均收益 |
|
||||||
|
| 144:13:56 | 2173 | 15 / H |
|
||||||
|
| 77:13:56 | 1332 | 15 / H |
|
||||||
|
| 64:15:37 | 1201 | 12 / H |
|
||||||
|
| 51:22:12 | 783 | 12 / H |
|
||||||
|
| 51:22:12 | 783 | 12 / H |
|
||||||
|
- 每行左侧 4×5 网格布局的藏品缩略图(3px 圆角,5 种渐变 fill)
|
||||||
|
|
||||||
|
### 2.6 点赞收益看板 (y: 580-870)
|
||||||
|
- **标题**: "点赞收益看板" - Inter Bold 18px
|
||||||
|
- **左侧双统计**:
|
||||||
|
- 累积点赞次数: `231` (Baloo Bhai 18px)
|
||||||
|
- 累计点赞收益: `12719` (Baloo Bhai 18px)
|
||||||
|
- **右侧等级列表**:
|
||||||
|
| 藏品 | 等级 | 水晶收益 |
|
||||||
|
| [图] | UR | 723 |
|
||||||
|
| [图] | SSR | 381 |
|
||||||
|
| [图] | SR | 233 |
|
||||||
|
| [图] | SR | 169 |
|
||||||
|
| [图] | R | 57 |
|
||||||
|
- 等级徽章有 5 种不同的渐变背景
|
||||||
|
|
||||||
|
### 2.7 藏品矩阵 (y: 870-1281)
|
||||||
|
|
||||||
|
#### 2.7.1 历史藏品收益TOP5
|
||||||
|
- 5 张缩略图水平排列,间距均匀
|
||||||
|
- 每张图下方有渐变 TOP 徽章 (TOP 1 ~ TOP 5)
|
||||||
|
- 徽章背景: `opacity 0.66` 渐变 + 投影
|
||||||
|
|
||||||
|
#### 2.7.2 藏品等级分布(环形进度图)
|
||||||
|
- 5 个圆形,分别对应 UR/SSR/SR/R/N 等级
|
||||||
|
- 数据(中心数字 + 百分比):
|
||||||
|
- UR: 1 (3%)
|
||||||
|
- SSR: 2 (6%)
|
||||||
|
- SR: 5 (13%)
|
||||||
|
- R: 6 (17%)
|
||||||
|
- N: 0 (0%)
|
||||||
|
- 圆环粗细: 17px(外环)/ 5px(内环),发光效果
|
||||||
|
|
||||||
|
#### 2.7.3 即将升级藏品(左列,3 行)
|
||||||
|
- 每行结构: 藏品缩略图 + 双进度条
|
||||||
|
- 进度条颜色:
|
||||||
|
- 上行(获赞数): `90deg, #5EDFFF → #FFC8C8` 渐变
|
||||||
|
- 下行(展出时长): `90deg, #FFF375 → #FF6B84` 渐变
|
||||||
|
- 进度条背景: `rgba(217, 217, 217, 0.2)`
|
||||||
|
- 当前显示数据:
|
||||||
|
- 藏品1: 73% / 92%
|
||||||
|
- 藏品2: 75% / 96%
|
||||||
|
- 藏品3: 97% / 71%
|
||||||
|
|
||||||
|
#### 2.7.4 最近升级藏品(右列,3 行)
|
||||||
|
- 每行结构: 藏品缩略图 + "Lv UP" 文字 + 等级徽章
|
||||||
|
- 等级徽章顺序(自上而下): SSR、SR、SR
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、设计令牌(Design Tokens)
|
||||||
|
|
||||||
|
### 3.1 颜色
|
||||||
|
|
||||||
|
| Token | 值 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| `--color-bg-gradient` | `linear-gradient(153deg, #FF9597 0%, #80DFFF 33%, #B8B8B8 74%, #D9D9D9 100%)` | 页面主背景 |
|
||||||
|
| `--color-text-primary` | `#FFFFFF` | 主文字 |
|
||||||
|
| `--color-text-data` | `#FFFABD` | 数字(水晶、收益) |
|
||||||
|
| `--color-text-dark` | `#000000` | 状态栏 |
|
||||||
|
| `--color-tab-active` | `linear-gradient(231deg, #A8A6ED 0%, #88C8D8 64%, #F380EF 100%)` | Tab 选中态 |
|
||||||
|
| `--color-tab-bg-1` | `linear-gradient(135deg, #FFDF77 0%, #8E95E2 40%, #F48CFF 100%)` | 卡片 1(水晶) |
|
||||||
|
| `--color-tab-bg-2` | `linear-gradient(137deg, #FFDF77 0%, #8E95E2 40%, #F48CFF 100%)` + 蓝绿红 | 卡片 2(今日收益) |
|
||||||
|
| `--color-progress-pink` | `linear-gradient(90deg, #FFF375 0%, #FF6B84 100%)` | 进度条 |
|
||||||
|
| `--color-progress-cyan` | `linear-gradient(90deg, #5EDFFF 0%, #FFC8C8 100%)` | 进度条 |
|
||||||
|
| `--color-bar-blue-yellow` | `linear-gradient(90deg, #1BAFEE 0%, #FFCC14 100%)` | 折线/柱状图 |
|
||||||
|
|
||||||
|
### 3.2 阴影
|
||||||
|
|
||||||
|
| Token | 值 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| `--shadow-card` | `0px 4px 4px rgba(189, 50, 50, 0.25)` | 卡片通用阴影 |
|
||||||
|
| `--shadow-data-text` | `-1px 1px 4px rgba(206, 9, 9, 0.84)` | 数字文字阴影 |
|
||||||
|
| `--shadow-mascot` | `2px 2px 4px rgba(242, 21, 21, 0.47) blur(29.8px)` | 头像光晕 |
|
||||||
|
| `--shadow-tab` | `0px 4px 4px rgba(0, 0, 0, 0.25)` | Tab 胶囊阴影 |
|
||||||
|
| `--shadow-inner-card` | `0px 4px 4px rgba(96, 13, 13, 0.25)` | 内嵌卡片阴影 |
|
||||||
|
| `--blur-bg` | `blur(4px)` | 背景模糊 |
|
||||||
|
| `--blur-mascot` | `blur(29.8px)` | 头像发光模糊 |
|
||||||
|
| `--blur-portrait` | `blur(68.7px)` | 装饰人物模糊 |
|
||||||
|
|
||||||
|
### 3.3 圆角
|
||||||
|
|
||||||
|
| Token | 值 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| `--radius-thumb` | 3px | 藏品缩略图 |
|
||||||
|
| `--radius-progress` | 6px | 进度条 |
|
||||||
|
| `--radius-top-badge` | 8px | TOP 徽章 |
|
||||||
|
| `--radius-card-sm` | 14px | 小卡片 |
|
||||||
|
| `--radius-card-md` | `17px 14px 14px 14px` | 主卡片(异形) |
|
||||||
|
| `--radius-card-lg` | 22px | 胶囊/大容器 |
|
||||||
|
|
||||||
|
### 3.4 字体
|
||||||
|
|
||||||
|
| Token | 字体 | 字号 | 字重 | 用途 |
|
||||||
|
|------|------|------|------|------|
|
||||||
|
| `--font-num-xl` | Baloo Bhai | 35px | 400 | 顶部水晶/收益数字 |
|
||||||
|
| `--font-num-lg` | Baloo Bhai | 18px | 400 | 点赞统计数字 |
|
||||||
|
| `--font-num-md` | Baloo Bhai | 14px | 400 | 表格数字 |
|
||||||
|
| `--font-num-sm` | Baloo Bhai | 9px | 400 | 进度条百分比 |
|
||||||
|
| `--font-title-lg` | Inter | 18-20px | 700 | 模块大标题("展出收益中心") |
|
||||||
|
| `--font-title-md` | Inter | 15px | 700 | Tab 文字 |
|
||||||
|
| `--font-label` | Inter | 12px | 500 | 字段标签 |
|
||||||
|
| `--font-stat-label` | Baloo Bhai | 5-9px | 400 | 进度条小标签("获赞数"等) |
|
||||||
|
|
||||||
|
### 3.5 间距
|
||||||
|
|
||||||
|
| Token | 值 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| `--space-card-pad` | 16px | 卡片外边距(左右) |
|
||||||
|
| `--space-card-pad-y` | 8px | 卡片内边距(上下) |
|
||||||
|
| `--space-section` | 24px | 模块间垂直间距 |
|
||||||
|
| `--space-cell` | 12px | 表格行间距 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、数据模型与 API 设计
|
||||||
|
|
||||||
|
### 4.1 数据来源
|
||||||
|
|
||||||
|
设计稿中需要的数据均已存在于 backend 现有 proto 中,本节梳理 **复用 + 新增** 接口。
|
||||||
|
|
||||||
|
| 模块 | 数据 | 数据源 proto | 是否需要新增 |
|
||||||
|
|------|------|-------------|------------|
|
||||||
|
| 水晶余额 | `crystal_balance` | `user.proto::FanProfile.crystal_balance` | ❌ 复用 |
|
||||||
|
| 今日收益 | `+ 213` | 新增 `daily_income` 聚合字段 | ✅ 新增 |
|
||||||
|
| 七日收益曲线 | 7 天 daily 数据 | 新增接口 `Get7DayIncomeCurve` | ✅ 新增 |
|
||||||
|
| 展出收益中心 | 顶部 3 联 | 聚合 `gallery.proto` + `task.proto::ExhibitionRevenueItem` | ✅ 新增聚合 |
|
||||||
|
| 展出收益 - 表格 5 行 | 5 条按收益排序的展出记录 | 复用 `task.proto::ExhibitionRevenueItem` | ❌ 复用(限定 limit=5) |
|
||||||
|
| 点赞收益 - 累计 | 点赞总数、收益总数 | 复用 `gallery.proto::AssetInfo.like_count/earnings` | ❌ 复用 |
|
||||||
|
| 点赞收益 - 等级 | 按等级分组的点赞收益 | 新增接口 `GetLikeIncomeByLevel` | ✅ 新增 |
|
||||||
|
| 藏品矩阵 - TOP5 | 收益前 5 藏品 | 新增接口 `GetTopAssetsByEarning` | ✅ 新增 |
|
||||||
|
| 藏品矩阵 - 等级分布 | 各等级数量 | 新增接口 `GetAssetLevelDistribution` | ✅ 新增 |
|
||||||
|
| 即将升级藏品 | 升级进度数据 | 新增接口 `GetUpcomingLevelUpAssets` | ✅ 新增 |
|
||||||
|
| 最近升级藏品 | 最近升级记录 | 新增接口 `GetRecentLevelUpAssets` | ✅ 新增 |
|
||||||
|
|
||||||
|
### 4.2 新增 Proto 定义(建议)
|
||||||
|
|
||||||
|
> 新增位置: `backend/proto/dashboard.proto`(新建文件)
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
syntax = "proto3";
|
||||||
|
package dashboard;
|
||||||
|
option go_package = "github.com/topfans/backend/pkg/proto/dashboard";
|
||||||
|
|
||||||
|
// ============ 数据看板聚合接口 ============
|
||||||
|
|
||||||
|
// 七日收益曲线
|
||||||
|
message Get7DayIncomeCurveRequest {
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 star_id = 2; // 顶粉星城 ID(区分赛季)
|
||||||
|
}
|
||||||
|
|
||||||
|
message DailyIncomePoint {
|
||||||
|
string date = 1; // "2026.05.27"
|
||||||
|
int64 income = 2; // 当日收益
|
||||||
|
bool is_today = 3; // 是否今日
|
||||||
|
bool is_peak = 4; // 是否 7 日最高(用于高亮显示)
|
||||||
|
}
|
||||||
|
|
||||||
|
message Get7DayIncomeCurveResponse {
|
||||||
|
repeated DailyIncomePoint points = 1;
|
||||||
|
int64 total_income = 2; // 7 日累计
|
||||||
|
int64 avg_income = 3; // 7 日日均
|
||||||
|
}
|
||||||
|
|
||||||
|
// 今日收益概览
|
||||||
|
message GetTodayOverviewRequest {
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 star_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetTodayOverviewResponse {
|
||||||
|
int64 crystal_balance = 1; // 水晶余额
|
||||||
|
int64 today_income = 2; // 今日收益
|
||||||
|
int32 week_rank = 3; // 本周排名(可选)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 展出收益中心聚合
|
||||||
|
message GetExhibitionIncomeSummaryRequest {
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 star_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExhibitionIncomeSummary {
|
||||||
|
int32 exhibiting_count = 1; // 展出中数量
|
||||||
|
int32 starbook_count = 2; // 星册中数量
|
||||||
|
string total_duration = 3; // "712:13:56"
|
||||||
|
int64 total_earnings = 4; // 39721
|
||||||
|
repeated TopExhibitionItem top5 = 5; // 表格 5 行
|
||||||
|
}
|
||||||
|
|
||||||
|
message TopExhibitionItem {
|
||||||
|
int64 asset_id = 1;
|
||||||
|
string asset_name = 2;
|
||||||
|
string asset_thumb = 3;
|
||||||
|
string duration_7d = 4; // "144:13:56"
|
||||||
|
int64 earnings_7d = 5; // 2173
|
||||||
|
int32 avg_earnings = 6; // 15 (单位: /H)
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetExhibitionIncomeSummaryResponse {
|
||||||
|
ExhibitionIncomeSummary data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点赞收益按等级分组
|
||||||
|
message GetLikeIncomeByLevelRequest {
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 star_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LikeIncomeLevelItem {
|
||||||
|
string level = 1; // "UR" / "SSR" / "SR" / "R" / "N"
|
||||||
|
int32 asset_count = 2;
|
||||||
|
int64 total_income = 3; // 723
|
||||||
|
string thumb = 4; // 第一个该等级藏品的缩略图
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetLikeIncomeByLevelResponse {
|
||||||
|
int64 total_like_count = 1; // 累积点赞次数
|
||||||
|
int64 total_income = 2; // 累计点赞收益
|
||||||
|
repeated LikeIncomeLevelItem levels = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 藏品矩阵 - 历史 TOP5
|
||||||
|
message GetTopAssetsByEarningRequest {
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 star_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TopAssetItem {
|
||||||
|
int64 asset_id = 1;
|
||||||
|
string asset_name = 2;
|
||||||
|
string asset_thumb = 3;
|
||||||
|
int64 total_earnings = 4;
|
||||||
|
int32 rank = 5; // 1-5
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetTopAssetsByEarningResponse {
|
||||||
|
repeated TopAssetItem items = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 藏品矩阵 - 等级分布
|
||||||
|
message GetAssetLevelDistributionRequest {
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 star_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AssetLevelItem {
|
||||||
|
string level = 1; // "UR"
|
||||||
|
int32 count = 2; // 1
|
||||||
|
int32 total = 3; // 33(藏品总数,用于计算百分比)
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetAssetLevelDistributionResponse {
|
||||||
|
repeated AssetLevelItem items = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 藏品矩阵 - 即将升级 / 最近升级
|
||||||
|
message GetAssetUpgradeProgressRequest {
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 star_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpcomingLevelUpItem {
|
||||||
|
int64 asset_id = 1;
|
||||||
|
string asset_name = 2;
|
||||||
|
string asset_thumb = 3;
|
||||||
|
int32 like_progress = 4; // 73
|
||||||
|
int32 duration_progress = 5; // 92
|
||||||
|
}
|
||||||
|
|
||||||
|
message RecentLevelUpItem {
|
||||||
|
int64 asset_id = 1;
|
||||||
|
string asset_name = 2;
|
||||||
|
string asset_thumb = 3;
|
||||||
|
string new_level = 4; // "SSR"
|
||||||
|
int64 upgrade_time = 5; // ms timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetAssetUpgradeProgressResponse {
|
||||||
|
repeated UpcomingLevelUpItem upcoming = 1;
|
||||||
|
repeated RecentLevelUpItem recent = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ Service 定义 ============
|
||||||
|
service DashboardService {
|
||||||
|
rpc GetTodayOverview(GetTodayOverviewRequest) returns (GetTodayOverviewResponse);
|
||||||
|
rpc Get7DayIncomeCurve(Get7DayIncomeCurveRequest) returns (Get7DayIncomeCurveResponse);
|
||||||
|
rpc GetExhibitionIncomeSummary(GetExhibitionIncomeSummaryRequest) returns (GetExhibitionIncomeSummaryResponse);
|
||||||
|
rpc GetLikeIncomeByLevel(GetLikeIncomeByLevelRequest) returns (GetLikeIncomeByLevelResponse);
|
||||||
|
rpc GetTopAssetsByEarning(GetTopAssetsByEarningRequest) returns (GetTopAssetsByEarningResponse);
|
||||||
|
rpc GetAssetLevelDistribution(GetAssetLevelDistributionRequest) returns (GetAssetLevelDistributionResponse);
|
||||||
|
rpc GetAssetUpgradeProgress(GetAssetUpgradeProgressRequest) returns (GetAssetUpgradeProgressResponse);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 后端实现位置
|
||||||
|
|
||||||
|
| 新服务 | 路径 | 备注 |
|
||||||
|
|------|------|------|
|
||||||
|
| `dashboardService` | `backend/services/dashboardService/` | 全新服务,参考 `galleryService` 目录结构 |
|
||||||
|
| 聚合查询 | `service/dashboard_service.go` | 主要逻辑 |
|
||||||
|
| 数据访问 | `repository/dashboard_repository.go` | 跨表聚合(exhibition + asset + crystal_log) |
|
||||||
|
| Proto | `backend/proto/dashboard.proto` | 新建 |
|
||||||
|
| 路由 | `backend/gateway/router/router.go` | `/api/v1/dashboard/*` 网关路由 |
|
||||||
|
| Controller | `backend/gateway/controller/dashboard_controller.go` | HTTP 网关层 |
|
||||||
|
|
||||||
|
### 4.4 数据来源 SQL 聚合(伪代码)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 七日收益曲线
|
||||||
|
SELECT
|
||||||
|
DATE(FROM_UNIXTIME(created_at/1000)) AS date,
|
||||||
|
SUM(crystal_change) AS income
|
||||||
|
FROM crystal_log
|
||||||
|
WHERE user_id = ? AND star_id = ?
|
||||||
|
AND created_at >= UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL 7 DAY)) * 1000
|
||||||
|
AND change_type IN ('exhibition_revenue', 'level_up_bonus')
|
||||||
|
GROUP BY DATE(FROM_UNIXTIME(created_at/1000))
|
||||||
|
ORDER BY date ASC;
|
||||||
|
|
||||||
|
-- 展出收益中心聚合
|
||||||
|
SELECT
|
||||||
|
COUNT(DISTINCT CASE WHEN e.status='active' THEN e.id END) AS exhibiting_count,
|
||||||
|
COUNT(DISTINCT CASE WHEN e.status='starbook' THEN e.id END) AS starbook_count,
|
||||||
|
SUM(e.accumulated_duration) AS total_duration,
|
||||||
|
SUM(e.accumulated_earnings) AS total_earnings
|
||||||
|
FROM exhibitions e
|
||||||
|
WHERE e.user_id = ? AND e.star_id = ?;
|
||||||
|
|
||||||
|
-- 点赞收益按等级
|
||||||
|
SELECT
|
||||||
|
a.level,
|
||||||
|
COUNT(DISTINCT a.id) AS asset_count,
|
||||||
|
SUM(li.crystal_amount) AS total_income
|
||||||
|
FROM assets a
|
||||||
|
LEFT JOIN like_income_log li ON li.asset_id = a.id AND li.user_id = a.user_id
|
||||||
|
WHERE a.user_id = ? AND a.star_id = ?
|
||||||
|
GROUP BY a.level
|
||||||
|
ORDER BY FIELD(a.level, 'UR', 'SSR', 'SR', 'R', 'N');
|
||||||
|
|
||||||
|
-- 藏品等级分布
|
||||||
|
SELECT
|
||||||
|
a.level,
|
||||||
|
COUNT(*) AS count,
|
||||||
|
(SELECT COUNT(*) FROM assets WHERE user_id = ? AND star_id = ?) AS total
|
||||||
|
FROM assets a
|
||||||
|
WHERE a.user_id = ? AND a.star_id = ?
|
||||||
|
GROUP BY a.level;
|
||||||
|
|
||||||
|
-- 即将升级藏品(按升级进度倒序,取前 3)
|
||||||
|
SELECT a.id, a.name, a.thumb, a.like_progress, a.duration_progress
|
||||||
|
FROM assets a
|
||||||
|
WHERE a.user_id = ? AND a.star_id = ? AND a.like_progress < 100
|
||||||
|
ORDER BY GREATEST(a.like_progress, a.duration_progress) DESC
|
||||||
|
LIMIT 3;
|
||||||
|
|
||||||
|
-- 最近升级藏品(升级时间倒序)
|
||||||
|
SELECT a.id, a.name, a.thumb, a.level, a.upgrade_time
|
||||||
|
FROM asset_upgrade_log aul
|
||||||
|
JOIN assets a ON a.id = aul.asset_id
|
||||||
|
WHERE aul.user_id = ? AND aul.star_id = ?
|
||||||
|
ORDER BY aul.upgrade_time DESC
|
||||||
|
LIMIT 3;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、前端实现
|
||||||
|
|
||||||
|
### 5.1 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
frontend/
|
||||||
|
├── pages/
|
||||||
|
│ └── dashboard/
|
||||||
|
│ ├── dashboard.vue # 主页面
|
||||||
|
│ └── components/
|
||||||
|
│ ├── DashboardHeader.vue # 顶部装饰 + Tab
|
||||||
|
│ ├── CrystalOverview.vue # 顶部双卡(水晶余额+今日收益)
|
||||||
|
│ ├── IncomeCurve.vue # 七日收益曲线
|
||||||
|
│ ├── ExhibitionCenter.vue # 展出收益中心
|
||||||
|
│ ├── LikeIncomeBoard.vue # 点赞收益看板
|
||||||
|
│ ├── CollectionMatrix.vue # 藏品矩阵容器
|
||||||
|
│ ├── TopFiveAssets.vue # 历史 TOP5
|
||||||
|
│ ├── LevelDistribution.vue # 等级分布环形图
|
||||||
|
│ ├── UpcomingUpgrades.vue # 即将升级(左)
|
||||||
|
│ └── RecentUpgrades.vue # 最近升级(右)
|
||||||
|
├── api/
|
||||||
|
│ └── dashboard.js # API 封装
|
||||||
|
├── store/
|
||||||
|
│ └── modules/
|
||||||
|
│ └── dashboard.js # Vuex 模块
|
||||||
|
└── static/
|
||||||
|
└── dashboard/
|
||||||
|
├── mascot-star.png # 毛绒怪头像
|
||||||
|
├── tab-bg-active.png # Tab 选中态背景
|
||||||
|
├── progress-cyan.png # 青粉进度条
|
||||||
|
├── progress-pink.png # 黄红进度条
|
||||||
|
└── top-badge.png # TOP 徽章
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 组件职责拆分
|
||||||
|
|
||||||
|
| 组件 | 职责 | Props | 关键状态 |
|
||||||
|
|------|------|-------|----------|
|
||||||
|
| `dashboard.vue` | 页面容器,负责 Tab 切换和数据请求分发 | - | `activeTab: 'crystal' \| 'season'` |
|
||||||
|
| `DashboardHeader` | 装饰背景 + 标题 + Tab | - | - |
|
||||||
|
| `CrystalOverview` | 显示水晶余额+今日收益 | `{ balance, today }` | - |
|
||||||
|
| `IncomeCurve` | 七日柱状+折线图 | `{ points, peak }` | - |
|
||||||
|
| `ExhibitionCenter` | 顶部 3 联 + 5 行表格 | `{ summary }` | - |
|
||||||
|
| `LikeIncomeBoard` | 左侧统计 + 右侧等级列表 | `{ stats, levels }` | - |
|
||||||
|
| `CollectionMatrix` | 嵌套 4 个子组件 | `{ topFive, levels, upcoming, recent }` | - |
|
||||||
|
| `TopFiveAssets` | TOP5 水平卡片 | `{ items }` | - |
|
||||||
|
| `LevelDistribution` | 5 个环形图 | `{ levels }` | - |
|
||||||
|
| `UpcomingUpgrades` | 进度条列表 | `{ items }` | - |
|
||||||
|
| `RecentUpgrades` | Lv UP 列表 | `{ items }` | - |
|
||||||
|
|
||||||
|
### 5.3 API 封装(`frontend/api/dashboard.js`)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
const PREFIX = '/api/v1/dashboard';
|
||||||
|
|
||||||
|
export const dashboardApi = {
|
||||||
|
// 今日收益概览
|
||||||
|
getTodayOverview: (starId) =>
|
||||||
|
request.get(`${PREFIX}/today-overview`, { params: { star_id: starId } }),
|
||||||
|
|
||||||
|
// 七日收益曲线
|
||||||
|
get7DayIncomeCurve: (starId) =>
|
||||||
|
request.get(`${PREFIX}/income-curve`, { params: { star_id: starId } }),
|
||||||
|
|
||||||
|
// 展出收益中心
|
||||||
|
getExhibitionSummary: (starId) =>
|
||||||
|
request.get(`${PREFIX}/exhibition-summary`, { params: { star_id: starId } }),
|
||||||
|
|
||||||
|
// 点赞收益按等级
|
||||||
|
getLikeIncomeByLevel: (starId) =>
|
||||||
|
request.get(`${PREFIX}/like-income-by-level`, { params: { star_id: starId } }),
|
||||||
|
|
||||||
|
// 藏品 TOP5
|
||||||
|
getTopAssets: (starId) =>
|
||||||
|
request.get(`${PREFIX}/top-assets`, { params: { star_id: starId } }),
|
||||||
|
|
||||||
|
// 藏品等级分布
|
||||||
|
getLevelDistribution: (starId) =>
|
||||||
|
request.get(`${PREFIX}/level-distribution`, { params: { star_id: starId } }),
|
||||||
|
|
||||||
|
// 升级进度(即将+最近)
|
||||||
|
getUpgradeProgress: (starId) =>
|
||||||
|
request.get(`${PREFIX}/upgrade-progress`, { params: { star_id: starId } }),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.4 Vuex Store 模块(`frontend/store/modules/dashboard.js`)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { dashboardApi } from '@/api/dashboard';
|
||||||
|
|
||||||
|
const state = () => ({
|
||||||
|
loading: false,
|
||||||
|
activeTab: 'crystal', // 'crystal' | 'season'
|
||||||
|
currentStarId: null, // 当前顶粉星城 ID
|
||||||
|
today: { balance: 0, income: 0 },
|
||||||
|
incomeCurve: [],
|
||||||
|
exhibitionSummary: null,
|
||||||
|
likeIncome: { total: 0, income: 0, levels: [] },
|
||||||
|
topAssets: [],
|
||||||
|
levelDistribution: [],
|
||||||
|
upgradeProgress: { upcoming: [], recent: [] },
|
||||||
|
});
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
async loadAll({ commit, state }) {
|
||||||
|
commit('setLoading', true);
|
||||||
|
try {
|
||||||
|
const starId = state.currentStarId;
|
||||||
|
const [today, curve, exh, like, top, level, up] = await Promise.all([
|
||||||
|
dashboardApi.getTodayOverview(starId),
|
||||||
|
dashboardApi.get7DayIncomeCurve(starId),
|
||||||
|
dashboardApi.getExhibitionSummary(starId),
|
||||||
|
dashboardApi.getLikeIncomeByLevel(starId),
|
||||||
|
dashboardApi.getTopAssets(starId),
|
||||||
|
dashboardApi.getLevelDistribution(starId),
|
||||||
|
dashboardApi.getUpgradeProgress(starId),
|
||||||
|
]);
|
||||||
|
commit('setToday', today);
|
||||||
|
commit('setIncomeCurve', curve.points);
|
||||||
|
commit('setExhibitionSummary', exh);
|
||||||
|
commit('setLikeIncome', like);
|
||||||
|
commit('setTopAssets', top.items);
|
||||||
|
commit('setLevelDistribution', level.items);
|
||||||
|
commit('setUpgradeProgress', up);
|
||||||
|
} finally {
|
||||||
|
commit('setLoading', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// ... mutations
|
||||||
|
};
|
||||||
|
|
||||||
|
export default { namespaced: true, state, actions, mutations };
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.5 pages.json 注册
|
||||||
|
|
||||||
|
在 `frontend/pages.json` 的 `pages` 数组中添加:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"path": "pages/dashboard/dashboard",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "数据看板",
|
||||||
|
"app-plus": { "bounce": "none" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.6 关键技术点
|
||||||
|
|
||||||
|
| 点 | 实现方式 |
|
||||||
|
|------|------|
|
||||||
|
| 七日柱状图 | 使用 Canvas 2D 手绘(轻量);或引入 `uCharts`(如果项目未引入,需评估) |
|
||||||
|
| 环形进度图 | CSS `conic-gradient` 实现 5 种等级环(无需额外依赖) |
|
||||||
|
| 渐变文字 | `-webkit-background-clip: text; color: transparent` |
|
||||||
|
| 玻璃拟态 | `backdrop-filter: blur(10px)` + 半透明白色背景 |
|
||||||
|
| Tab 切换 | 简单 v-show,不做路由切换(页面无滚动状态保持) |
|
||||||
|
| 数据懒加载 | 首屏只请求前 3 个接口,滚动到底部再请求矩阵接口 |
|
||||||
|
| 空数据 | 所有模块必须有空态(暂无数据插画 + 引导文案) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、实施计划
|
||||||
|
|
||||||
|
### 6.1 阶段划分
|
||||||
|
|
||||||
|
| 阶段 | 内容 | 工期估算 | 验收 |
|
||||||
|
|------|------|----------|------|
|
||||||
|
| **M1 - 后端基础** | 创建 `dashboard.proto`、实现 7 个 RPC、SQL 聚合、单元测试 | 3 天 | gRPC 接口联调通过 |
|
||||||
|
| **M2 - 前端骨架** | `pages.json` 注册、空页面路由、Vuex 模块、API 封装 | 1 天 | 页面可访问,loading 态正常 |
|
||||||
|
| **M3 - 模块实现 P1** | Header + CrystalOverview + IncomeCurve(顶部三模块) | 2 天 | 视觉稿 1:1 还原 |
|
||||||
|
| **M4 - 模块实现 P2** | ExhibitionCenter + LikeIncomeBoard | 2 天 | 视觉稿 1:1 还原 |
|
||||||
|
| **M5 - 模块实现 P3** | CollectionMatrix(含 4 个子组件) | 3 天 | 视觉稿 1:1 还原 |
|
||||||
|
| **M6 - 联调优化** | 接口联调、空态、错误处理、动效打磨 | 2 天 | 全链路通过 |
|
||||||
|
| **总计** | | **13 工作日** | |
|
||||||
|
|
||||||
|
### 6.2 依赖与风险
|
||||||
|
|
||||||
|
| 风险 | 影响 | 应对 |
|
||||||
|
|------|------|------|
|
||||||
|
| 7 日曲线跨表聚合性能 | M1 阶段 | 加索引 `crystal_log(user_id, star_id, created_at)` |
|
||||||
|
| uCharts 体积(如果引入) | 包体积+200KB | 优先 Canvas 手绘,复杂图表才用 uCharts |
|
||||||
|
| 藏品等级排序国际化 | 显示顺序 | 后端按 `FIELD()` 硬编码 UR > SSR > SR > R > N |
|
||||||
|
| 升级进度算法 | 业务复杂度 | 与产品确认升级公式(是点赞数+展出时长加权,还是分开的双进度条) |
|
||||||
|
| 资源下载 | 头像/徽章 | 用 `mcp__figma-developer-mcp__download_figma_images` 批量下载到 `static/dashboard/` |
|
||||||
|
|
||||||
|
### 6.3 验收清单
|
||||||
|
|
||||||
|
- [ ] 视觉还原:1:1 还原 Figma 稿,色差 ΔE < 5
|
||||||
|
- [ ] 性能:首屏 < 1.5s,完整加载 < 3s
|
||||||
|
- [ ] 兼容性:iOS 13+ / Android 7+
|
||||||
|
- [ ] 数据准确性:与 `tasks/revenue.vue` 页面的数字一致
|
||||||
|
- [ ] 空态:所有模块有"暂无数据"占位
|
||||||
|
- [ ] 错误处理:网络异常时 Toast 提示 + 重试按钮
|
||||||
|
- [ ] 加载态:骨架屏(Skeleton)
|
||||||
|
- [ ] 单元测试:核心 store action 覆盖率 > 80%
|
||||||
|
- [ ] E2E:用 Playwright 跑通 1 条用户路径(进入页面 → 切换 Tab → 下拉刷新)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、附录
|
||||||
|
|
||||||
|
### 7.1 资源文件清单
|
||||||
|
|
||||||
|
需要从 Figma 下载的素材:
|
||||||
|
- 毛绒怪头像: `mascot-star.png` (104×99)
|
||||||
|
- Tab 选中态背景: `tab-bg-active.png` (168×45)
|
||||||
|
- TOP 徽章: `top-badge-1~5.png` (80×33)
|
||||||
|
- 等级徽章: `level-badge-ur/ssr/sr/r/n.png` (40×40)
|
||||||
|
- 装饰人物图: `decoration-portrait.png` (580×296)
|
||||||
|
|
||||||
|
### 7.2 参考文档
|
||||||
|
|
||||||
|
- Figma 文件: [数据看板 - 节点 29-40](https://www.figma.com/design/EMJR1LQpXBnJNSfea4kq4o/数据看板?node-id=29-40)
|
||||||
|
- 现有 Figma 分析参考: `docs/figma-analysis-topfans-ranking.md`
|
||||||
|
- 收益相关 Proto: `backend/proto/task.proto`(ExhibitionRevenueItem)
|
||||||
|
- 用户水晶 Proto: `backend/proto/user.proto`(FanProfile.crystal_balance)
|
||||||
|
- 展出 Proto: `backend/proto/gallery.proto`(ExhibitionService)
|
||||||
|
|
||||||
|
### 7.3 后续可扩展
|
||||||
|
|
||||||
|
- 数据看板分享:生成海报图片分享到站外
|
||||||
|
- 7 日曲线交互:点击柱子查看当日收益明细弹窗
|
||||||
|
- 升级提醒:达到 95% 进度时推送通知
|
||||||
|
- 多赛季切换:赛季结束后归档数据,Tab 2 "赛季总览" 展示历史赛季
|
||||||
|
- 对比模式:本周 vs 上周水晶收益对比柱状图
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**文档维护**: 任何与本页面相关的需求变更或技术调整,请同步更新本文档。
|
||||||
|
**负责人**: 待指派
|
||||||
|
**Review**: 待指派
|
||||||
Loading…
Reference in New Issue
Block a user