docs:ai搭子修改,热门模块新增,字段判断基础文档
This commit is contained in:
parent
b0b47e4608
commit
9b0c3ee3a9
File diff suppressed because it is too large
Load Diff
48
backend/migrations/ai_chat.sql
Normal file
48
backend/migrations/ai_chat.sql
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
-- AI Chat Service 数据库迁移
|
||||||
|
-- 创建时间: 2026-05-27
|
||||||
|
-- 说明: AI Chat Service 所需的数据库表
|
||||||
|
|
||||||
|
-- =============================================
|
||||||
|
-- 1. ai_personas (人设表)
|
||||||
|
-- =============================================
|
||||||
|
CREATE TABLE IF NOT EXISTS ai_personas (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id BIGINT NOT NULL,
|
||||||
|
name VARCHAR(64) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
avatar_url VARCHAR(512),
|
||||||
|
talk_style VARCHAR(256),
|
||||||
|
system_prompt TEXT NOT NULL,
|
||||||
|
is_default BOOLEAN DEFAULT FALSE,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 索引
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ai_personas_user_id ON ai_personas(user_id);
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_ai_personas_user_default ON ai_personas(user_id) WHERE is_default = TRUE;
|
||||||
|
|
||||||
|
-- =============================================
|
||||||
|
-- 2. ai_user_memories (长期记忆表)
|
||||||
|
-- =============================================
|
||||||
|
CREATE TABLE IF NOT EXISTS ai_user_memories (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id BIGINT NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
keywords TEXT[],
|
||||||
|
weight INTEGER DEFAULT 50,
|
||||||
|
is_core BOOLEAN DEFAULT FALSE,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 索引
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ai_user_memories_user_id ON ai_user_memories(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ai_user_memories_keywords ON ai_user_memories USING GIN(keywords);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ai_user_memories_weight ON ai_user_memories(weight DESC);
|
||||||
|
|
||||||
|
-- =============================================
|
||||||
|
-- 回滚语句 (如需回滚)
|
||||||
|
-- =============================================
|
||||||
|
-- DROP TABLE IF EXISTS ai_user_memories;
|
||||||
|
-- DROP TABLE IF EXISTS ai_personas;
|
||||||
1035
docs/superpowers/plans/2026-05-27-热门推荐模块实现.md
Normal file
1035
docs/superpowers/plans/2026-05-27-热门推荐模块实现.md
Normal file
File diff suppressed because it is too large
Load Diff
476
docs/superpowers/specs/2026-05-27-热门推荐模块设计.md
Normal file
476
docs/superpowers/specs/2026-05-27-热门推荐模块设计.md
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
# 热门推荐模块设计方案
|
||||||
|
|
||||||
|
## 一、需求概述
|
||||||
|
|
||||||
|
在广场页面顶部新增 4 个热门分类区块,每个分类显示 8 张高点赞作品,支持单个分类刷新和查看更多分页。
|
||||||
|
|
||||||
|
### 页面结构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ BannerCarousel │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ 热门推荐 (8张图) │
|
||||||
|
│ [刷新] [查看更多 >] │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ 热门星卡 (8张图) │
|
||||||
|
│ [刷新] [查看更多 >] │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ 热门吧唧 (8张图) │
|
||||||
|
│ [刷新] [查看更多 >] │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ 热门海报 (8张图) │
|
||||||
|
│ [刷新] [查看更多 >] │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ (CreationGrid 组件 - 不变) │
|
||||||
|
│ [热门作品] [最新作品] [星卡] ... │
|
||||||
|
└─────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 分类配置
|
||||||
|
|
||||||
|
| 区块 | type值 | 说明 |
|
||||||
|
|-----|-------|------|
|
||||||
|
| 热门推荐 | `hot_recommend` | 混合所有类型,高点赞作品 |
|
||||||
|
| 热门星卡 | `hot_star_card` | 只展示星卡 |
|
||||||
|
| 热门吧唧 | `hot_badge` | 只展示吧唧 |
|
||||||
|
| 热门海报 | `hot_poster` | 只展示海报 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、接口设计
|
||||||
|
|
||||||
|
### 2.1 接口清单
|
||||||
|
|
||||||
|
| 接口 | 方法 | 参数 | 说明 |
|
||||||
|
|-----|------|------|------|
|
||||||
|
| `/api/v1/inspiration-flow/hot/batch` | GET | 无 | 页面加载批量获取 |
|
||||||
|
| `/api/v1/inspiration-flow/hot` | GET | `type` | 单个分类刷新 |
|
||||||
|
| `/api/v1/inspiration-flow/hot/more` | GET | `type`, `cursor`, `limit` | 查看更多分页 |
|
||||||
|
| `/api/v1/inspiration-flow` | GET | `type`, `cursor`, `limit`, `direction` | 灵感瀑布流(逻辑调整) |
|
||||||
|
|
||||||
|
### 2.2 调用时序
|
||||||
|
|
||||||
|
```
|
||||||
|
页面加载 → 批量请求(1次)
|
||||||
|
└── GET /api/v1/inspiration-flow/hot/batch
|
||||||
|
|
||||||
|
刷新 → 单个分类刷新(点击哪个刷新请求哪个)
|
||||||
|
└── GET /api/v1/inspiration-flow/hot?type=hot_star_card
|
||||||
|
|
||||||
|
查看更多 → 新页面分页
|
||||||
|
└── GET /api/v1/inspiration-flow/hot/more?type=hot_star_card&cursor=xxx&limit=20
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 批量获取热门分类
|
||||||
|
|
||||||
|
**接口**: `GET /api/v1/inspiration-flow/hot/batch`
|
||||||
|
|
||||||
|
**请求参数**: 无
|
||||||
|
|
||||||
|
**业务逻辑**:
|
||||||
|
1. 计算各分类作品的点赞平均值
|
||||||
|
2. 筛选点赞数 ≥ 平均值的作品
|
||||||
|
3. 基于时间窗口伪随机排序取 8 条
|
||||||
|
4. 后端动态返回分类数据,前端根据返回的分类动态渲染
|
||||||
|
5. **排序说明**:使用随机排序,同一分类每次请求返回的作品可能不同
|
||||||
|
|
||||||
|
**响应结构**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"data": {
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"type": "hot_recommend",
|
||||||
|
"title": "热门推荐",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"asset_id": "xxx",
|
||||||
|
"cover_url": "https://xxx.jpg",
|
||||||
|
"owner_nickname": "用户名",
|
||||||
|
"owner_avatar": "https://xxx.jpg",
|
||||||
|
"likes": 1234
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hot_star_card",
|
||||||
|
"title": "热门星卡",
|
||||||
|
"items": [...]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hot_badge",
|
||||||
|
"title": "热门吧唧",
|
||||||
|
"items": [...]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hot_poster",
|
||||||
|
"title": "热门海报",
|
||||||
|
"items": [...]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**空分类处理**: 如果某个分类没有作品或查询失败,该分类不返回。
|
||||||
|
|
||||||
|
### 2.4 单个分类刷新
|
||||||
|
|
||||||
|
**接口**: `GET /api/v1/inspiration-flow/hot`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|-----|------|------|------|
|
||||||
|
| `type` | string | 是 | `hot_recommend` / `hot_star_card` / `hot_badge` / `hot_poster` |
|
||||||
|
|
||||||
|
**业务逻辑**:
|
||||||
|
1. 计算该分类作品的点赞平均值
|
||||||
|
2. 筛选点赞数 ≥ 平均值的作品
|
||||||
|
3. 基于时间窗口伪随机排序取 8 条
|
||||||
|
4. **排序说明**:批量和刷新接口使用随机排序,每次刷新可能看到不同作品
|
||||||
|
|
||||||
|
**响应结构**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"data": {
|
||||||
|
"type": "hot_star_card",
|
||||||
|
"title": "热门星卡",
|
||||||
|
"items": [...]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 查看更多分页
|
||||||
|
|
||||||
|
**接口**: `GET /api/v1/inspiration-flow/hot/more`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|-----|------|------|------|
|
||||||
|
| `type` | string | 是 | 分类类型(`hot_recommend`/`hot_star_card`/`hot_badge`/`hot_poster`) |
|
||||||
|
| `cursor` | string | 否 | 翻页游标(Base64 编码的 JSON,包含 `like_count` 和 `asset_id`) |
|
||||||
|
| `limit` | int | 否 | 每页数量,默认 20 |
|
||||||
|
|
||||||
|
**业务逻辑**:
|
||||||
|
1. 计算该分类作品点赞平均值
|
||||||
|
2. 筛选点赞数 ≥ 平均值的作品
|
||||||
|
3. 按点赞数 DESC、asset_id DESC 排序
|
||||||
|
4. Cursor 分页返回(游标编码 last_like_count 和 last_asset_id)
|
||||||
|
|
||||||
|
**Cursor 编码格式**:
|
||||||
|
```json
|
||||||
|
// Base64 编码 {"like_count": 1234, "asset_id": 5678}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应结构**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"data": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"asset_id": "xxx",
|
||||||
|
"cover_url": "https://xxx.jpg",
|
||||||
|
"owner_nickname": "用户名",
|
||||||
|
"owner_avatar": "https://xxx.jpg",
|
||||||
|
"likes": 1234,
|
||||||
|
"material_type": "star_card",
|
||||||
|
"sub_type": "raster"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cursor": "xxx",
|
||||||
|
"has_more": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意**:`material_type` 表示素材类型(`star_card`/`badge`/`poster`),不是热门分类类型。
|
||||||
|
|
||||||
|
### 2.6 灵感瀑布流(逻辑调整)
|
||||||
|
|
||||||
|
**接口**: `GET /api/v1/inspiration-flow`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|-----|------|------|------|
|
||||||
|
| `type` | string | 否 | 素材类型过滤:`badge`/`poster`/`original`/`all`,默认 `all` |
|
||||||
|
| `cursor` | string | 否 | 翻页游标 |
|
||||||
|
| `direction` | string | 否 | 滚动方向:`right`(加载新数据)/ `left`(加载历史) |
|
||||||
|
| `limit` | int | 否 | 每页数量,默认 20 |
|
||||||
|
| `session_id` | string | 否 | 会话 ID(用于去重,排除已展示的作品) |
|
||||||
|
|
||||||
|
**业务逻辑(调整后)**:
|
||||||
|
1. 计算该分类作品的点赞平均值(基于展出中的作品 JOIN assets)
|
||||||
|
2. **第一段**:点赞 > 平均值的作品,基于时间窗口伪随机排列,取前 20 条
|
||||||
|
3. **第二段**:如果不够 20 条,从点赞 ≥ 平均值的作品中(排除第一段已选的)补充,伪随机排列
|
||||||
|
4. 两段组合返回
|
||||||
|
5. 通过 `session_id` 排除已展示的作品(`excludeIDs`)
|
||||||
|
|
||||||
|
**响应结构**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"data": {
|
||||||
|
"items": [...],
|
||||||
|
"cursor": "xxx",
|
||||||
|
"has_more": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意**:灵感瀑布的 `type` 参数与热门推荐接口的 `type` 参数含义完全不同:
|
||||||
|
- 灵感瀑布:`badge`/`poster`/`original`/`all`(素材类型过滤)
|
||||||
|
- 热门推荐:`hot_recommend`/`hot_star_card`/`hot_badge`/`hot_poster`(分类类型)
|
||||||
|
|
||||||
|
### 2.7 热门分类 type 与资产类型映射
|
||||||
|
|
||||||
|
| 热门分类 type | 对应 assetType | 说明 |
|
||||||
|
|-------------|---------------|------|
|
||||||
|
| `hot_recommend` | 空字符串 `""` | 混合所有类型,不过滤 |
|
||||||
|
| `hot_star_card` | `star_card` | 只展示星卡 |
|
||||||
|
| `hot_badge` | `badge` | 只展示吧唧 |
|
||||||
|
| `hot_poster` | `poster` | 只展示海报 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、数据模型
|
||||||
|
|
||||||
|
### 3.1 数据库表结构
|
||||||
|
|
||||||
|
参考现有 `assets` 表,无需新建表。
|
||||||
|
|
||||||
|
### 3.2 伪 SQL(以 star_card 为例)
|
||||||
|
|
||||||
|
**说明**:热门作品基于**展出中的作品**筛选,只有在 `exhibitions` 表中有有效展出记录且未过期的作品才能参与热门排名。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 计算该分类作品的点赞平均值(基于展出中的作品)
|
||||||
|
AVG_LIKES := SELECT AVG(a.like_count)
|
||||||
|
FROM exhibitions e
|
||||||
|
JOIN assets a ON a.id = e.asset_id
|
||||||
|
WHERE e.occupier_star_id = :star_id
|
||||||
|
AND e.expire_at > :now
|
||||||
|
AND e.deleted_at IS NULL
|
||||||
|
AND a.status = 1 AND a.is_active = true
|
||||||
|
AND a.asset_type = 'star_card';
|
||||||
|
|
||||||
|
-- 随机取8条(基于时间窗口的伪随机,避免 ORDER BY RANDOM())
|
||||||
|
WINDOW_SEED := :now / 30000 % 10; -- 每30秒变化一次
|
||||||
|
|
||||||
|
SELECT e.id as exhibition_id, e.asset_id, a.name, a.cover_url, a.like_count,
|
||||||
|
fp.nickname as owner_nickname, fp.avatar_url as owner_avatar
|
||||||
|
FROM exhibitions e
|
||||||
|
JOIN assets a ON a.id = e.asset_id
|
||||||
|
JOIN fan_profiles fp ON e.occupier_uid = fp.user_id AND e.occupier_star_id = fp.star_id
|
||||||
|
WHERE e.occupier_star_id = :star_id
|
||||||
|
AND e.expire_at > :now
|
||||||
|
AND e.deleted_at IS NULL
|
||||||
|
AND a.status = 1 AND a.is_active = true
|
||||||
|
AND a.asset_type = 'star_card'
|
||||||
|
AND a.like_count >= :AVG_LIKES
|
||||||
|
AND e.id % 10 = :WINDOW_SEED
|
||||||
|
ORDER BY e.id
|
||||||
|
LIMIT 8;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 随机算法说明
|
||||||
|
|
||||||
|
避免 `ORDER BY RANDOM()`(大表性能差),改用基于时间窗口的伪随机:
|
||||||
|
|
||||||
|
- `WINDOW_SEED = now / 30000 % 10` — 每 30 秒变化一次
|
||||||
|
- 通过 `exhibition_id % 10 = WINDOW_SEED` 筛选作品
|
||||||
|
- 同一时间窗口内结果固定,不同时间窗口返回不同作品
|
||||||
|
- 如果数量不够,再补充查询(不加窗口过滤)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、后端实现
|
||||||
|
|
||||||
|
### 4.1 文件改动
|
||||||
|
|
||||||
|
| 文件 | 改动内容 |
|
||||||
|
|-----|---------|
|
||||||
|
| `backend/proto/gallery.proto` | 新增 Proto 消息定义 |
|
||||||
|
| `backend/pkg/proto/gallery/gallery.pb.go` | 重新生成 Proto 代码 |
|
||||||
|
| `backend/gateway/controller/gallery_controller.go` | 新增 `GetHotInspirationFlowBatch`、`GetHotInspirationFlow`、`GetHotInspirationFlowMore` 方法 |
|
||||||
|
| `backend/gateway/router/router.go` | 新增 `/inspiration-flow/hot/*` 路由注册 |
|
||||||
|
| `backend/gateway/dto/gallery_dto.go` | 新增 DTO 结构体 |
|
||||||
|
| `backend/gateway/dto/gallery_converter.go` | 新增 DTO 转换函数 |
|
||||||
|
| `backend/services/galleryService/service/gallery_service.go` | 新增 `GetHotInspirationFlowBatch`、`GetHotInspirationFlow`、`GetHotInspirationFlowMore` Service 方法 |
|
||||||
|
| `backend/services/galleryService/repository/gallery_repository.go` | 新增 Repository 方法 |
|
||||||
|
| `backend/pkg/database/redis.go` | 新增热门推荐缓存辅助函数 |
|
||||||
|
|
||||||
|
### 4.2 性能优化
|
||||||
|
|
||||||
|
1. **并行查询** — 批量接口用 goroutine 并行查 4 个分类
|
||||||
|
2. **缓存平均值** — 每个分类的点赞均值独立缓存(TTL: 5 分钟),避免重复计算
|
||||||
|
3. **结果缓存** — 热门列表缓存 30-60 秒,降低数据库压力
|
||||||
|
4. **随机优化** — 避免 `ORDER BY RANDOM()`,使用基于时间窗口的伪随机
|
||||||
|
|
||||||
|
### 4.3 缓存策略
|
||||||
|
|
||||||
|
| 缓存项 | TTL | 说明 |
|
||||||
|
|-------|-----|------|
|
||||||
|
| 分类点赞均值 | 5 分钟 | 每个分类单独缓存,减少重复计算平均值 |
|
||||||
|
| 热门列表(批量) | 30 秒 | `/hot/batch` 结果缓存,降低数据库压力 |
|
||||||
|
| 热门列表(单个刷新) | **不缓存** | 用户主动刷新应获取新数据,只缓存点赞均值 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、前端实现
|
||||||
|
|
||||||
|
### 5.1 文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
frontend/pages/square/
|
||||||
|
├── square.vue # 修改:集成4个热门分类区块
|
||||||
|
├── components/
|
||||||
|
│ └── HotCategoryBlock.vue # 新增:单个热门分类区块组件
|
||||||
|
└── hot-category-more.vue # 新增:热门分类查看更多页面
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 新增文件
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|-----|------|
|
||||||
|
| `pages/square/components/HotCategoryBlock.vue` | 单个热门分类区块组件 |
|
||||||
|
| `pages/square/hot-category-more.vue` | 热门分类查看更多页面 |
|
||||||
|
|
||||||
|
### 5.3 修改文件
|
||||||
|
|
||||||
|
| 文件 | 改动内容 |
|
||||||
|
|-----|---------|
|
||||||
|
| `frontend/pages/square/square.vue` | 顶部新增 4 个 HotCategoryBlock |
|
||||||
|
| `frontend/utils/api.js` | 新增批量获取、单个刷新、查看更多 API |
|
||||||
|
|
||||||
|
### 5.4 HotCategoryBlock 组件
|
||||||
|
|
||||||
|
```
|
||||||
|
HotCategoryBlock.vue
|
||||||
|
├── props: { categoryType } // 传入后端返回的 type(如 "hot_star_card")
|
||||||
|
├── 状态: items, loading, refreshing, title
|
||||||
|
├── 方法: handleRefresh(), handleViewMore()
|
||||||
|
└── 模板:
|
||||||
|
├── 标题 (title)
|
||||||
|
├── 4x2 网格 (items) + loading 骨架屏
|
||||||
|
├── 刷新按钮 (loading 状态)
|
||||||
|
└── 查看更多按钮
|
||||||
|
```
|
||||||
|
|
||||||
|
**说明**:
|
||||||
|
- `categoryType` 直接使用后端返回的 type(如 `hot_star_card`)
|
||||||
|
- 刷新时调用 `getHotInspirationFlowApi(categoryType)`
|
||||||
|
- 查看更多时调用 `getHotInspirationFlowMoreApi(categoryType, ...)`
|
||||||
|
|
||||||
|
**刷新交互**:
|
||||||
|
- 整个区块显示骨架屏 loading
|
||||||
|
- 刷新按钮显示 loading 状态
|
||||||
|
- 刷新完成后正常显示
|
||||||
|
|
||||||
|
### 5.5 hot-category-more.vue 页面
|
||||||
|
|
||||||
|
```
|
||||||
|
hot-category-more.vue
|
||||||
|
├── onLoad: 获取 type 参数
|
||||||
|
├── 状态: items, cursor, loading, hasMore, title
|
||||||
|
├── 方法: loadMore(), loadData()
|
||||||
|
└── 模板:
|
||||||
|
├── 返回按钮 + 标题
|
||||||
|
└── 分页网格列表
|
||||||
|
```
|
||||||
|
|
||||||
|
**星卡子标签**(仅星卡分类显示):
|
||||||
|
|
||||||
|
| 子标签 | value | 说明 |
|
||||||
|
|-------|-------|------|
|
||||||
|
| 全部 | `all` | 全部星卡 |
|
||||||
|
| 光栅卡 | `raster` | 光栅卡类型 |
|
||||||
|
| 镭射卡 | `holographic` | 镭射卡类型 |
|
||||||
|
| 撕拉卡 | `tear_off` | 撕拉卡类型 |
|
||||||
|
| 拍立得 | `polaroid` | 拍立得类型 |
|
||||||
|
|
||||||
|
### 5.6 API 封装
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 批量获取热门分类(页面加载用)
|
||||||
|
export function getHotInspirationFlowBatchApi() {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/inspiration-flow/hot/batch',
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单个分类刷新
|
||||||
|
export function getHotInspirationFlowApi(type) {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/inspiration-flow/hot',
|
||||||
|
method: 'GET',
|
||||||
|
data: { type }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看更多分页
|
||||||
|
export function getHotInspirationFlowMoreApi(type, cursor = '', limit = 20) {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/inspiration-flow/hot/more',
|
||||||
|
method: 'GET',
|
||||||
|
data: { type, cursor, limit }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**调用示例**:
|
||||||
|
```javascript
|
||||||
|
// 批量加载(页面初始化)
|
||||||
|
const res = await getHotInspirationFlowBatchApi()
|
||||||
|
res.data.categories.forEach(cat => {
|
||||||
|
// cat.type: "hot_recommend", cat.title: "热门推荐", cat.items: [...]
|
||||||
|
console.log(cat.type, cat.items.length)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 单个刷新(点击刷新按钮)
|
||||||
|
const refreshRes = await getHotInspirationFlowApi('hot_star_card')
|
||||||
|
|
||||||
|
// 查看更多(跳转 hot-category-more.vue)
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/square/hot-category-more?type=${type}&title=${encodeURIComponent(title)}`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、实现步骤
|
||||||
|
|
||||||
|
### 后端
|
||||||
|
|
||||||
|
- [ ] **Phase 1**: 新增 `/api/v1/inspiration-flow/hot/batch` 批量接口(并行查询 + 缓存)
|
||||||
|
- [ ] **Phase 2**: 新增 `/api/v1/inspiration-flow/hot` 单个分类接口
|
||||||
|
- [ ] **Phase 3**: 新增 `/api/v1/inspiration-flow/hot/more` 查看更多接口
|
||||||
|
- [ ] **Phase 4**: 修改 `/api/v1/inspiration-flow` 逻辑(分段填充)
|
||||||
|
|
||||||
|
### 前端
|
||||||
|
|
||||||
|
- [ ] **Phase 5**: 新增 `utils/api.js` API 方法
|
||||||
|
- [ ] **Phase 6**: 新增 `HotCategoryBlock.vue` 组件
|
||||||
|
- [ ] **Phase 7**: 新增 `hot-category-more.vue` 页面
|
||||||
|
- [ ] **Phase 8**: 修改 `square.vue` 集成 4 个热门分类区块
|
||||||
|
- [ ] **Phase 9**: CreationGrid 保持不变
|
||||||
|
|
||||||
|
### 联调
|
||||||
|
|
||||||
|
- [ ] **Phase 10**: 前后端联调测试
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、注意事项
|
||||||
|
|
||||||
|
1. **后端动态返回分类** — 前端无需硬编码分类,根据接口返回的 `categories` 动态渲染
|
||||||
|
2. **空分类不显示** — 如果某个分类没有作品,该分类不返回或前端忽略
|
||||||
|
3. **扩展性** — 后续增加新分类(如"热门贴纸"),只需后端调整,前端无需改动
|
||||||
|
4. **性能优先** — 后端必须做好并行查询和缓存优化,确保批量接口响应时间 < 200ms
|
||||||
Loading…
Reference in New Issue
Block a user