topfans/docs/PRD-Rankings.md
2026-04-07 22:28:50 +08:00

10 KiB
Raw Blame History

TopFans 排行榜功能需求文档

1. 功能概述

1.1 产品背景

排行榜功能旨在提升用户活跃度和参与度,通过展示热门藏品和自制佳作榜单,激励用户创作和互动。

1.2 排行榜类型

排行类型 统计维度 数据来源
热度排行 展示中 / 本月 / 全部 藏品点赞数
自制排行 展示中 / 本月 / 全部 自制藏品点赞数

注意: 活动排行榜功能待后续单独设计


2. 数据模型设计

2.1 现有数据分析

Asset (藏品表)

  • LikeCount - 点赞数(累计)
  • OwnerUID - 拥有者ID
  • StarID - 粉丝身份ID
  • CreatedAt - 创建时间

AssetLike (点赞记录表)

  • AssetID - 藏品ID
  • UserID - 点赞用户ID
  • CreatedAt - 点赞时间(用于本月统计)

Exhibition (展品展示表)

  • AssetID - 展品ID
  • StartTime - 开始展示时间
  • ExpireAt - 过期时间(用于"展示中"判定)

2.2 新增数据模型

2.2.1 藏品表扩展

在 Asset 表中增加 IsOriginal 字段true=自制藏品):

type Asset struct {
    // ... 现有字段
    IsOriginal bool `gorm:"default:false;column:is_original"` // 是否自制藏品
}

3. API 接口设计

3.1 通用响应格式

{
  "code": 200,
  "message": "ok",
  "data": {
    "items": [],
    "page": 1,
    "page_size": 10,
    "total": 100
  }
}

3.2 热度排行榜

3.2.1 获取热度排行榜

接口: GET /api/v1/rankings/hot

认证: 需认证 (JWT Token)

Query 参数:

参数 类型 必填 说明
dimension string 统计维度: displaying(展示中) / month(本月) / total(全部)
star_id int64 粉丝身份ID筛选不传则返回当前身份数据
page int 页码默认1
page_size int 每页数量默认10

返回示例:

{
  "code": 200,
  "message": "ok",
  "data": {
    "my_ranking": {
      "rank": 5,
      "asset_id": 1005,
      "asset_name": "我的藏品",
      "cover_url": "https://...",
      "like_count": 88,
      "status": "ranked"
    },
    "items": [
      {
        "rank": 1,
        "asset_id": 1001,
        "asset_name": "战战生贺",
        "cover_url": "https://...",
        "owner_uid": 12345,
        "owner_nickname": "爱战战",
        "like_count": 999,
        "is_original": false
      },
      {
        "rank": 2,
        "asset_id": 1002,
        "asset_name": "肖战同框",
        "cover_url": "https://...",
        "owner_uid": 12346,
        "owner_nickname": "小飞侠",
        "like_count": 888,
        "is_original": true
      }
    ],
    "page": 1,
    "page_size": 10,
    "total": 100
  }
}

我的排名返回说明:

状态 rank 说明
上榜 5 在 Top N 内,显示具体排名
未上榜 null 不在 Top N 内,显示差距

上榜返回示例 (my_ranking):

{
  "my_ranking": {
    "rank": 5,
    "asset_id": 1005,
    "asset_name": "我的藏品",
    "cover_url": "https://...",
    "like_count": 88,
    "status": "ranked"
  }
}

未上榜返回示例 (my_ranking):

{
  "my_ranking": {
    "rank": null,
    "asset_id": 1005,
    "asset_name": "我的藏品",
    "cover_url": "https://...",
    "like_count": 50,
    "status": "unranked",
    "diff_to_rank": 50
  }
}

统计逻辑:

维度 说明
displaying 统计当前正在展示的藏品的点赞数Exhibition.ExpireAt > Now()
month 统计当前自然月内2026年3月1日-3月31日获得的点赞数
total 统计藏品累计点赞数

多藏品处理:

  • 用户有多个藏品时,返回排行最高的那个藏品排名

分页规则:

  • 每次返回 10 条page_size 默认 10
  • 榜单最多显示前 100 名(可配置)

3.3 自制排行榜

3.3.1 获取自制排行榜

接口: GET /api/v1/rankings/original

认证: 需认证 (JWT Token)

Query 参数:

参数 类型 必填 说明
dimension string 统计维度: displaying(展示中) / month(本月) / total(全部)
star_id int64 粉丝身份ID筛选不传则返回当前身份数据
page int 页码默认1
page_size int 每页数量默认10

返回示例:

{
  "code": 200,
  "message": "ok",
  "data": {
    "my_ranking": {
      "rank": 3,
      "asset_id": 1002,
      "asset_name": "自制海报",
      "cover_url": "https://...",
      "like_count": 666,
      "status": "ranked"
    },
    "items": [
      {
        "rank": 1,
        "asset_id": 1002,
        "asset_name": "自制海报",
        "cover_url": "https://...",
        "owner_uid": 12346,
        "owner_nickname": "小飞侠",
        "like_count": 888,
        "material_url": "https://...",
        "is_original": true
      }
    ],
    "page": 1,
    "page_size": 10,
    "total": 50
  }
}

统计逻辑:

  • 仅统计 is_original = true 的自制藏品
  • 其他维度逻辑同热度排行榜

4. 前端界面设计

4.1 排行榜入口

在首页广场添加"排行榜"Tab或在个人中心添加入口。

4.2 排行榜页面结构

┌─────────────────────────────┐
│        排行榜               │
├─────────────────────────────┤
│  [热度] [自制]              │  ← Tab 切换
├─────────────────────────────┤
│                             │
│  🥇 用户A      999 赞       │
│     [图片]                  │
│                             │
│  🥈 用户B      888 赞       │
│     [图片]                  │
│                             │
│  🥉 用户C      777 赞       │
│     [图片]                  │
│                             │
├─────────────────────────────┤
│  [展示中] [本月] [全部]     │  ← 维度切换
└─────────────────────────────┘

4.3 我的排名吸底展示

上榜状态:

┌─────────────────────────────┐
│        排行榜               │
│  ...                        │
│  8. 用户H      100 赞       │
│  [图片]                     │
│  9. 用户I      99 赞        │
│  [图片]                     │
│  10. 用户J     98 赞        │
│  [图片]                     │
├─────────────────────────────┤
│  🏆 我的排名: 第5名         │
│  ❤️ [图片] 我的藏品  88赞  │
└─────────────────────────────┘

未上榜状态:

┌─────────────────────────────┐
│        排行榜               │
│  ...                        │
│  98. 用户H     60 赞        │
│  [图片]                     │
│  99. 用户I     59 赞        │
│  [图片]                     │
│  100. 用户J    58 赞        │
│  [图片]                     │
├─────────────────────────────┤
│  😢 未上榜                 │
│  距离上榜还差 8 热度        │
│  [图片] 我的藏品  50赞      │
└─────────────────────────────┘

空状态:

┌─────────────────────────────┐
│        排行榜               │
├─────────────────────────────┤
│                             │
│   暂无数据,快去创作吧      │
│                             │
│        [去铸造]             │
└─────────────────────────────┘

5. 数据库变更

5.1 藏品表扩展

ALTER TABLE assets ADD COLUMN is_original BOOLEAN DEFAULT FALSE;

6. 性能优化

6.1 缓存策略

数据 缓存策略 过期时间
热度排行榜 Redis ZSet 5分钟
自制排行榜 Redis ZSet 5分钟

6.2 定时任务

  1. 排行榜定时刷新 - 每5分钟更新一次排行榜缓存
  2. 排名计算 - 每日凌晨重新计算精确排名

7. 业务流程

7.1 点赞时更新排行榜

用户点赞藏品
    ↓
AssetLike 表新增记录 (记录点赞时间用于本月统计)
    ↓
Asset.LikeCount +1
    ↓
更新 Redis 热度/自制排行 ZSet

7.2 展示中藏品统计

定时任务扫描 Exhibition 表
    ↓
筛选 ExpireAt > Now() 的记录
    ↓
关联 Asset 表获取点赞数
    ↓
更新 Redis 展示中排行 ZSet

7.3 本月统计

用户查询本月排行时
    ↓
计算当月起始时间戳 (2026-03-01 00:00:00)
    ↓
筛选 AssetLike.CreatedAt >= 月起始时间
    ↓
按 AssetID 分组统计点赞数
    ↓
返回排行结果

7.4 我的排名计算

用户请求排行榜
    ↓
获取用户在该粉丝身份下所有藏品
    ↓
找出点赞数最高的藏品
    ↓
查询该藏品在榜单中的排名
    ↓
如果不在 Top 100计算与第100名差距
    ↓
返回 my_ranking 信息(含 cover_url

8. 待确认问题

  1. 粉丝身份隔离: 排行榜是否需要按粉丝身份隔离?

    • 已确认:按当前用户的 star_id 过滤
  2. 展示中判定: 展位被占后4小时自动下架如何处理

    • Exhibition.ExpireAt > Now() 即为展示中
  3. 本月统计: 自然月切换时如3月1日是否需要清理缓存

    • 待定:建议跨月时刷新缓存
  4. Top N 默认值: 默认显示前多少名?

    • 已确认:默认 100

9. 版本历史

版本 日期 说明
V1.0 2026-03-11 初始版本
V1.1 2026-03-12 移除活动排行榜,补充我的排名、差距计算、分页规则
V1.2 2026-03-12 my_ranking 补充 cover_url 字段