docs: 添加文档设计
This commit is contained in:
parent
3e1c6c309b
commit
b0b47e4608
299
backend/docs/AI-Chat-Service/status_text标签系统设计方案.md
Normal file
299
backend/docs/AI-Chat-Service/status_text标签系统设计方案.md
Normal file
@ -0,0 +1,299 @@
|
||||
# status_text 标签系统设计方案
|
||||
|
||||
## 1. 概述
|
||||
|
||||
### 1.1 需求背景
|
||||
|
||||
用户在我的点赞作品页面需要看到每个作品的动态状态标签(如"屠榜顶流"、"火速破圈"等),用于直观展示作品的热度和表现。
|
||||
|
||||
### 1.2 实现方案
|
||||
|
||||
采用 **后端计算返回** 方案:由后端计算每个作品的 `status_text` 状态标签,前端直接展示。
|
||||
|
||||
### 1.3 优势
|
||||
|
||||
- 后端拥有完整的排行榜数据和用户行为数据,可准确计算
|
||||
- 前端无需关心业务逻辑复杂度,保持轻量
|
||||
- 状态计算逻辑集中,便于维护和修改
|
||||
- 减少前后端字段依赖,减少数据冗余
|
||||
|
||||
---
|
||||
|
||||
## 2. 标签体系定义
|
||||
|
||||
### 2.1 标签分类
|
||||
|
||||
| 优先级 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| T0 | 收益型 | 最高优先级,用户点赞后作品表现极佳 |
|
||||
| T1 | 排名型 | 排行榜相关,作品在榜上表现优秀 |
|
||||
| T3 | 状态型 | 涨粉速度,体现作品热度变化 |
|
||||
| T4 | 状态型 | 涨粉速度,体现作品热度变化 |
|
||||
|
||||
### 2.2 标签详情
|
||||
|
||||
| 优先级 | 标签名 | 显示条件 | 背后逻辑 |
|
||||
|--------|--------|----------|----------|
|
||||
| **T0** | 眼光拉满 | 用户点赞后,新增点赞≥50 且作品仍在展出 | 用户点赞后作品持续火热,用户收益已达峰值 |
|
||||
| **T1** | 屠榜顶流TopX | 排行榜排名为 1、2、3、4、5 | 作品稳居排行榜前五,顶级流量 |
|
||||
| **T1** | 第Y爆款 | 排行榜排名为 Y(10≥Y>5) | 作品进入排行榜前10但未进前5 |
|
||||
| **T1** | 排名破Z | 排行榜排名达到 Z(Z∈{20,50,100,200}) | 里程碑式突破,达到特定门槛 |
|
||||
| **T3** | 火速破圈 | 过去1小时新增点赞≥20 | 作品热度急剧上升中 |
|
||||
| **T4** | 小爆出圈 | 过去1小时新增点赞:20>新增点赞≥10 | 作品热度稳步上升 |
|
||||
| **T4** | 热度积累 | 过去1小时新增点赞:10>新增点赞≥5 | 作品热度温和增长 |
|
||||
| **T4** | 缓慢涨粉 | 过去1小时新增点赞:5>新增点赞≥0 | 作品热度缓慢增长 |
|
||||
| - | 潜力待挖 | 无任何标签满足 | 默认状态,等待挖掘 |
|
||||
|
||||
### 2.3 优先级规则
|
||||
|
||||
当多个标签条件同时满足时,按优先级取最高级别(T0>T1>T3>T4)。
|
||||
|
||||
**计算流程:**
|
||||
```
|
||||
1. 检查 T0「眼光拉满」→ 满足则返回
|
||||
2. 检查 T1 排名型(屠榜顶流/第Y爆款/排名破Z)→ 满足则返回
|
||||
3. 检查 T3/T4 状态型(火速破圈/小爆出圈/热度积累/缓慢涨粉)→ 满足则返回
|
||||
4. 默认返回「潜力待挖」
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 后端接口设计
|
||||
|
||||
### 3.1 修改接口
|
||||
|
||||
| 接口 | 方法 | 说明 |
|
||||
|------|------|------|
|
||||
| `/api/v1/me/liked-assets` | GET | 获取我点赞的作品列表 |
|
||||
|
||||
### 3.2 响应新增字段
|
||||
|
||||
在 `GetMyLikedAssets` 接口的响应 `items` 数组元素中新增:
|
||||
|
||||
```json
|
||||
{
|
||||
"asset_id": 12345,
|
||||
"name": "作品名称",
|
||||
"cover_url": "https://...",
|
||||
"like_count": 1000,
|
||||
"liked_at": "2026-05-26T10:00:00Z",
|
||||
"earnings": 500.00,
|
||||
"hourly_earnings": 10.00,
|
||||
"is_lenticular": false,
|
||||
"expire_at": "2026-05-27T10:00:00Z",
|
||||
"status_text": "屠榜顶流Top3"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| status_text | string | 动态状态标签,默认「潜力待挖」 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 后端实现设计
|
||||
|
||||
### 4.1 数据依赖
|
||||
|
||||
| 字段 | 来源 | 说明 |
|
||||
|------|------|------|
|
||||
| 用户点赞时间 | liked_assets 表 | 用于计算用户点赞后新增点赞数 |
|
||||
| 用户点赞后新增点赞数 | likes 表聚合 | 用户点赞时刻起到当前时刻,作品累计新增点赞数 |
|
||||
| 排行榜排名 | ranking 或 likes 表 | 当前作品排名 |
|
||||
| 过去1小时新增点赞 | likes 表聚合 | 需要按时间窗口聚合 |
|
||||
|
||||
### 4.2 Service 层计算逻辑
|
||||
|
||||
```go
|
||||
// pkg/service/social_service.go
|
||||
|
||||
func (s *SocialService) GetMyLikedAssets(ctx context.Context, req *pbSocial.GetMyLikedAssetsRequest) (*pbSocial.GetMyLikedAssetsResponse, error) {
|
||||
// 1. 获取用户点赞作品列表
|
||||
items, total, hasMore := s.getLikedAssetsList(ctx, userID, page, pageSize)
|
||||
|
||||
// 2. 批量获取用户点赞时间
|
||||
likedAtMap := s.batchGetUserLikedAtMap(ctx, userID, assetIDs)
|
||||
|
||||
// 3. 批量获取作品排名
|
||||
rankMap := s.batchGetAssetRanks(ctx, assetIDs)
|
||||
|
||||
// 4. 批量获取过去1小时新增点赞
|
||||
hourlyNewLikesMap := s.batchGetHourlyNewLikes(ctx, assetIDs)
|
||||
|
||||
// 5. 为每个作品计算 status_text
|
||||
for _, item := range items {
|
||||
item.UserLikedAt = likedAtMap[item.AssetId]
|
||||
item.Rank = rankMap[item.AssetId]
|
||||
item.HourlyNewLikes = hourlyNewLikesMap[item.AssetId]
|
||||
item.StatusText = computeStatusText(item)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 status_text 计算函数
|
||||
|
||||
```go
|
||||
func computeStatusText(item *LikedAssetItem) string {
|
||||
// T0: 眼光拉满 - 用户点赞后新增点赞≥50 且仍在展出
|
||||
if item.UserLikedCountAfter >= 50 && !item.IsExpired {
|
||||
return "眼光拉满"
|
||||
}
|
||||
|
||||
// T1: 排名型
|
||||
if item.Rank >= 1 && item.Rank <= 5 {
|
||||
return fmt.Sprintf("屠榜顶流Top%d", item.Rank)
|
||||
}
|
||||
if item.Rank > 5 && item.Rank <= 10 {
|
||||
return fmt.Sprintf("第%d爆款", item.Rank)
|
||||
}
|
||||
if item.Rank == 20 || item.Rank == 50 || item.Rank == 100 || item.Rank == 200 {
|
||||
return fmt.Sprintf("排名破%d", item.Rank)
|
||||
}
|
||||
|
||||
// T3/T4: 状态型
|
||||
if item.HourlyNewLikes >= 20 {
|
||||
return "火速破圈"
|
||||
}
|
||||
if item.HourlyNewLikes >= 10 {
|
||||
return "小爆出圈"
|
||||
}
|
||||
if item.HourlyNewLikes >= 5 {
|
||||
return "热度积累"
|
||||
}
|
||||
if item.HourlyNewLikes >= 0 {
|
||||
return "缓慢涨粉"
|
||||
}
|
||||
|
||||
// 默认
|
||||
return "潜力待挖"
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 新增字段结构
|
||||
|
||||
```protobuf
|
||||
// proto/social.proto
|
||||
|
||||
message LikedAssetItem {
|
||||
int64 asset_id = 1;
|
||||
string name = 2;
|
||||
string cover_url = 3;
|
||||
int32 like_count = 4;
|
||||
int64 liked_at = 5;
|
||||
double earnings = 6;
|
||||
double hourly_earnings = 7;
|
||||
bool is_lenticular = 8;
|
||||
int64 expire_at = 9;
|
||||
// 新增字段
|
||||
string status_text = 10;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 前端修改设计
|
||||
|
||||
### 5.1 修改文件
|
||||
|
||||
`frontend/pages/profile/myWorks.vue`
|
||||
|
||||
### 5.2 修改点
|
||||
|
||||
**修改前 (line 919):**
|
||||
```javascript
|
||||
status_text: index < 3 ? '排名进榜' : '潜力待挖',
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```javascript
|
||||
status_text: item.status_text || '潜力待挖',
|
||||
```
|
||||
|
||||
### 5.3 完整修改的代码块
|
||||
|
||||
```javascript
|
||||
if (res.data && res.data.items) {
|
||||
likedWorks.value = res.data.items.map((item, index) => ({
|
||||
id: item.asset_id,
|
||||
cover_url: item.cover_url,
|
||||
like_count: item.like_count,
|
||||
earnings: item.earnings,
|
||||
liked_at: item.liked_at,
|
||||
expire_at: item.expire_at,
|
||||
name: item.name,
|
||||
is_lenticular: item.is_lenticular ?? false,
|
||||
status_text: item.status_text || '潜力待挖', // 直接使用后端返回
|
||||
score: item.like_count,
|
||||
reward: Math.floor(item.earnings || 0),
|
||||
}));
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 测试用例
|
||||
|
||||
### 6.1 标签测试用例
|
||||
|
||||
| 用例编号 | 前提条件 | 输入 | 预期输出 |
|
||||
|----------|----------|------|----------|
|
||||
| TC-01 | 用户点赞后作品新增≥50点赞 | status_text | 眼光拉满 |
|
||||
| TC-02 | 作品排名第1 | status_text | 屠榜顶流Top1 |
|
||||
| TC-03 | 作品排名第3 | status_text | 屠榜顶流Top3 |
|
||||
| TC-04 | 作品排名第7 | status_text | 第7爆款 |
|
||||
| TC-05 | 作品排名第20 | status_text | 排名破20 |
|
||||
| TC-06 | 过去1小时新增点赞=25 | status_text | 火速破圈 |
|
||||
| TC-07 | 过去1小时新增点赞=15 | status_text | 小爆出圈 |
|
||||
| TC-08 | 过去1小时新增点赞=7 | status_text | 热度积累 |
|
||||
| TC-09 | 过去1小时新增点赞=2 | status_text | 缓慢涨粉 |
|
||||
| TC-10 | 无任何标签满足 | status_text | 潜力待挖 |
|
||||
|
||||
### 6.2 优先级测试用例
|
||||
|
||||
| 用例编号 | 前提条件 | 预期输出 | 说明 |
|
||||
|----------|----------|----------|------|
|
||||
| TC-11 | 排名第2 且 过去1小时新增点赞=25 | 眼光拉满 | T0 > T1 |
|
||||
| TC-12 | 排名第5 且 过去1小时新增点赞=30 | 屠榜顶流Top5 | T1 > T3 |
|
||||
| TC-13 | 排名第15 且 过去1小时新增点赞=22 | 火速破圈 | 无T0/T1满足 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 里程碑
|
||||
|
||||
| 阶段 | 任务 | 负责人 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 1 | 后端 proto/social.proto 新增 status_text 字段 | 后端 | - |
|
||||
| 2 | 后端 Service 层实现 computeStatusText 逻辑 | 后端 | - |
|
||||
| 3 | 后端修改 GetMyLikedAssets 接口返回 status_text | 后端 | - |
|
||||
| 4 | 前端 myWorks.vue 修改 status_text 取值逻辑 | 前端 | - |
|
||||
| 5 | 联调测试 + 回归测试 | 前端+后端 | - |
|
||||
|
||||
---
|
||||
|
||||
## 8. 附录
|
||||
|
||||
### 8.1 标签文案汇总
|
||||
|
||||
| 标签名 | 字数 |
|
||||
|--------|------|
|
||||
| 眼光拉满 | 4 |
|
||||
| 屠榜顶流Top1~5 | 6~7 |
|
||||
| 第6~10爆款 | 4~5 |
|
||||
| 排名破20/50/100/200 | 5~6 |
|
||||
| 火速破圈 | 4 |
|
||||
| 小爆出圈 | 4 |
|
||||
| 热度积累 | 4 |
|
||||
| 缓慢涨粉 | 4 |
|
||||
| 潜力待挖 | 4 |
|
||||
|
||||
### 8.2 相关文件
|
||||
|
||||
| 文件路径 | 说明 |
|
||||
|----------|------|
|
||||
| backend/proto/social.proto | Protobuf 定义 |
|
||||
| backend/pkg/service/social_service.go | Service 层实现 |
|
||||
| backend/gateway/controller/social_controller.go | Controller 层(返回格式) |
|
||||
| frontend/pages/profile/myWorks.vue | 前端页面 |
|
||||
1969
backend/docs/AI-Chat-Service设计方案.md
Normal file
1969
backend/docs/AI-Chat-Service设计方案.md
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user