此版本包含: 1. 新增位置消息发送与展示功能 2. 完善多语言本地化文案 3. 新增安卓端管理空间Activity与图标背景 4. 优化摇一摇开关逻辑与深度链接配置 5. 新增信息流平台过滤与A/B测试后台功能 6. 更新签名配置与构建脚本 7. 修复若干已知问题与代码优化
44 KiB
闲言工具箱 · 信息流Feed接口文档
@File: API_FEED_DOC.md @Time: 2026-05-13 @Description: 信息流Feed系统API文档,聚合44种内容表为统一信息流 @LastUpdate: v2.3 新增刷新获取新内容接口(/api/feed/refresh_content); 新增用户偏好设置接口(/api/feed/preferences)
📋 目录
- 一、接口概览
- 二、频道列表接口
- 三、信息流列表接口
- 四、信息流详情接口
- 五、互动操作接口
- 六、热门内容接口
- 七、个性化推荐接口
- 八、随机内容接口
- 九、搜索接口
- 十、收藏列表接口
- 十一、点赞列表接口
- 十二、浏览历史接口
- 十三、稍后读列表接口
- 十四、评论列表接口
- 十五、下拉刷新检查接口
- 十六、刷新获取新内容
- 十七、用户偏好设置
- 十八、信息流统计接口
- 十九、关联推荐接口
- 二十、混合信息流接口
- 二十一、频道类型说明
- 二十二、数据结构说明
- 二十三、MySQL优化说明
- 二十四、APP接入指南
- 二十五、测试验证报告
一、接口概览
基础URL:
https://tools.wktyl.com控制器:Feed| 路径前缀:/api/feed/大部分接口无需登录,仅互动操作和收藏/点赞/历史列表需登录
1.1 接口一览
| # | 接口 | 方法 | 路径 | 需登录 | 说明 |
|---|---|---|---|---|---|
| 1 | 频道列表 | GET | /api/feed/channels |
❌ | 获取所有可用频道 |
| 2 | 信息流列表 | GET | /api/feed/list |
❌ | 聚合多类型内容列表(支持lite/游标分页) |
| 3 | 信息流详情 | GET | /api/feed/detail |
❌ | 单条内容详情(浏览+1/记录历史) |
| 4 | 互动操作 | POST | /api/feed/action |
✅ | 点赞/收藏/分享/评论/稍后读/评分 |
| 5 | 热门内容 | GET | /api/feed/trending |
❌ | 各频道热门排行 |
| 6 | 个性化推荐 | GET | /api/feed/recommend |
❌ | 基于兴趣推荐 |
| 7 | 🎲 随机内容 | GET | /api/feed/random |
❌ | 随机获取内容(快速下滑优化) |
| 8 | 🔍 搜索 | GET | /api/feed/search |
❌ | 跨频道关键词搜索 |
| 9 | ⭐ 收藏列表 | GET | /api/feed/favorites |
✅ | 用户收藏内容列表 |
| 10 | 👍 点赞列表 | GET | /api/feed/likes |
✅ | 用户点赞内容列表 |
| 11 | 🕐 浏览历史 | GET | /api/feed/history |
✅ | 用户浏览历史记录 |
| 12 | 📖 稍后读列表 | GET | /api/feed/readlater |
✅ | 用户稍后读列表 |
| 13 | 💬 评论列表 | GET | /api/feed/comments |
❌ | 获取指定内容的评论 |
| 14 | 🔄 刷新检查 | GET | /api/feed/refresh |
❌ | 检查是否有新内容 |
| 15 | 信息流统计 | GET | /api/feed/stats |
❌ | 各频道内容数量和互动统计 |
| 16 | 🔗 关联推荐 | GET | /api/feed/relatedRecommend |
❌ | 详情页相关内容推荐 |
| 17 | 🔀 混合信息流 | GET | /api/feed/mix |
❌ | 多频道混合内容(5种混合模式) |
| 18 | 🔄 刷新获取新内容 | GET | /api/feed/refresh_content |
❌ | 专用刷新接口,排除已看内容,保证不重复 |
| 19 | ⚙️ 用户偏好设置 | GET/POST | /api/feed/preferences |
POST需登录 | 获取/保存用户Feed偏好设置(登录用户跨设备同步) |
1.2 统一响应格式
{
"code": 1,
"msg": "成功",
"time": "1777320000",
"data": {}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| code | int | 1=成功, 0=失败 |
| msg | string | 提示信息 |
| time | string | 服务器时间戳 |
| data | object/null | 返回数据 |
二、频道列表接口
GET /api/feed/channels
无需登录。
平台过滤: 支持
platform参数按平台过滤频道,详见 API_PLATFORM_FILTER_DOC.md
2.1 请求参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| platform | string | ❌ | 从X-Platform请求头读取 | 平台标识(android/ios/harmony/macos/win/web/other) |
2.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| channels | array | 频道列表 |
| channels[].key | string | 频道标识 |
| channels[].name | string | 频道中文名 |
| channels[].icon | string | 频道图标(emoji) |
| channels[].count | int | 该频道内容总数 |
2.2 curl测试
curl -s "https://tools.wktyl.com/api/feed/channels" | python -m json.tool
三、信息流列表接口
GET /api/feed/list
无需登录。
3.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| channel | string | ❌ | all | 频道类型(见频道列表) |
| sort | string | ❌ | newest | 排序: newest/hottest |
| page | int | ❌ | 1 | 页码 |
| limit | int | ❌ | 20 | 每页数量(1-50) |
| last_id | int | ❌ | 0 | 游标分页: 上一页最后ID |
| lite | int | ❌ | 0 | 轻量模式: 1=只返回summary不返回content |
3.2 轻量模式说明
快速下滑优化: 设置
lite=1后,响应中不包含content字段,仅返回summary(前100字摘要)。 适合客户端快速下滑场景,减少数据传输量约60%,提升响应速度。
3.3 游标分页说明
避免深分页: 使用
last_id参数替代page进行游标分页。 传入上一页最后一条的id,服务端使用WHERE id < last_id查询,避免OFFSET性能问题。
3.4 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 内容列表(见统一条目结构) |
| total | int | 总数量 |
| page | int | 当前页码 |
| limit | int | 每页数量 |
| channel | string | 当前频道 |
| sort | string | 当前排序 |
| lite | bool | 是否轻量模式 |
3.5 curl测试
# 全部频道最新
curl -s "https://tools.wktyl.com/api/feed/list?channel=all&sort=newest&limit=5"
# 诗词频道热门
curl -s "https://tools.wktyl.com/api/feed/list?channel=poetry&sort=hottest&limit=5"
# 轻量模式(快速下滑)
curl -s "https://tools.wktyl.com/api/feed/list?channel=all&lite=1&limit=20"
# 游标分页(避免深分页)
curl -s "https://tools.wktyl.com/api/feed/list?channel=wisdom&sort=newest&last_id=1000&limit=10"
四、信息流详情接口
GET /api/feed/detail
无需登录。访问一次浏览量+1,已登录用户自动记录浏览历史。
4.1 请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | ✅ | 内容类型(poetry/wisdom/story等) |
| id | int | ✅ | 内容ID |
4.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| feed_type | string | 内容类型标识 |
| feed_name | string | 类型中文名 |
| feed_icon | string | 类型图标 |
| id | int | 内容ID |
| title | string | 标题 |
| author | string | 作者/来源 |
| content | string | 完整内容 |
| summary | string | 摘要(前100字) |
| views | int | 浏览次数(已+1) |
| createtime | int | 创建时间戳 |
| updatetime | int | 更新时间戳 |
| like_count | int | 点赞数 |
| favorite_count | int | 收藏数 |
| comment_count | int | 评论数 |
| share_count | int | 分享数 |
| is_liked | bool | 当前用户是否已点赞 |
| is_favorited | bool | 当前用户是否已收藏 |
| extra | object | 扩展信息(各类型不同) |
| my_actions | array | 已登录用户对该内容的操作列表(如["like","favorite"]) |
4.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/detail?type=poetry&id=1"
curl -s "https://tools.wktyl.com/api/feed/detail?type=hitokoto&id=1" -H "token: YOUR_TOKEN"
五、互动操作接口
POST /api/feed/action
需登录,Header携带 token。
5.1 请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | ✅ | 操作类型(见下表) |
| feed_type | string | ✅ | 内容类型 |
| feed_id | int | ✅ | 内容ID |
| extra | string | ❌ | 扩展数据JSON(评论内容/评分等) |
5.2 操作类型
| action | 说明 | extra格式 | 对画像影响 | 可逆操作 |
|---|---|---|---|---|
| like | 👍 点赞 | - | 该类型权重+3 | unlike取消 |
| unlike | 取消点赞 | - | - | - |
| favorite | ⭐ 收藏 | - | 该类型权重+5 | unfavorite取消 |
| unfavorite | 取消收藏 | - | - | - |
| share | 📤 分享 | - | 该类型权重+4 | 不可逆 |
| dislike | 👎 不感兴趣 | - | 该类型权重-2 | 不可逆 |
| comment | 💬 评论 | {"content":"评论内容"} |
该类型权重+4 | 不可逆 |
| readlater | 📖 稍后读 | - | 该类型权重+3 | unreadlater取消 |
| unreadlater | 取消稍后读 | - | - | - |
| rating | ⭐ 评分 | {"score":4} (1-5) |
该类型权重+2 | 可更新评分 |
| block | 🚫 屏蔽 | - | 该类型权重-2 | unblock取消 |
| unblock | 取消屏蔽 | - | - | - |
| report | 📢 举报 | {"reason":"举报原因"} |
- | 不可逆 |
| comment_like | 👍 评论点赞 | {"comment_id":1} |
- | comment_unlike取消 |
| comment_unlike | 取消评论点赞 | {"comment_id":1} |
- | - |
| readtime | ⏱️ 阅读时长 | {"duration":30} (秒) |
该类型权重+1 | 不可逆(可多次记录) |
5.3 curl测试
# 点赞
curl -X POST "https://tools.wktyl.com/api/feed/action" \
-H "token: YOUR_TOKEN" \
-d "action=like&feed_type=poetry&feed_id=1"
# 收藏
curl -X POST "https://tools.wktyl.com/api/feed/action" \
-H "token: YOUR_TOKEN" \
-d "action=favorite&feed_type=wisdom&feed_id=1"
# 评论
curl -X POST "https://tools.wktyl.com/api/feed/action" \
-H "token: YOUR_TOKEN" \
-d "action=comment&feed_type=poetry&feed_id=1&extra={\"content\":\"很美的诗\"}"
# 评分(1-5分)
curl -X POST "https://tools.wktyl.com/api/feed/action" \
-H "token: YOUR_TOKEN" \
-d "action=rating&feed_type=poetry&feed_id=1&extra={\"score\":4}"
# 稍后读
curl -X POST "https://tools.wktyl.com/api/feed/action" \
-H "token: YOUR_TOKEN" \
-d "action=readlater&feed_type=story&feed_id=1"
# 取消稍后读
curl -X POST "https://tools.wktyl.com/api/feed/action" \
-H "token: YOUR_TOKEN" \
-d "action=unreadlater&feed_type=story&feed_id=1"
# 取消点赞
curl -X POST "https://tools.wktyl.com/api/feed/action" \
-H "token: YOUR_TOKEN" \
-d "action=unlike&feed_type=poetry&feed_id=1"
六、热门内容接口
GET /api/feed/trending
无需登录。
6.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| channel | string | ❌ | all | 频道类型 |
| limit | int | ❌ | 20 | 返回数量(1-50) |
6.2 curl测试
curl -s "https://tools.wktyl.com/api/feed/trending?limit=10"
curl -s "https://tools.wktyl.com/api/feed/trending?channel=poetry&limit=5"
七、个性化推荐接口
GET /api/feed/recommend
无需登录。已登录用户基于兴趣画像推荐,未登录用户返回每日精选。
7.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| limit | int | ❌ | 20 | 返回数量(1-50) |
7.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 推荐内容列表 |
| limit | int | 返回数量 |
| personalized | bool | true=基于用户兴趣推荐, false=热门精选 |
7.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/recommend?limit=10"
八、随机内容接口
GET /api/feed/random
无需登录。每次请求返回不同内容,适合客户端快速下滑刷新场景。
8.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| channel | string | ❌ | all | 频道类型(all或具体类型) |
| limit | int | ❌ | 10 | 返回数量(1-30) |
| seed | string | ❌ | 随机 | 随机种子(相同种子返回相同内容) |
8.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 随机内容列表 |
| channel | string | 当前频道 |
| limit | int | 返回数量 |
| seed | string | 当前使用的随机种子 |
8.3 随机策略说明
- 使用ID范围随机取值,避免
ORDER BY RAND()性能问题 - 不传seed时每次返回不同内容
- 传入seed时相同seed返回相同内容(缓存30秒)
- 适合客户端"换一批"功能
8.4 curl测试
# 随机获取
curl -s "https://tools.wktyl.com/api/feed/random?limit=10"
# 指定频道随机
curl -s "https://tools.wktyl.com/api/feed/random?channel=poetry&limit=5"
# 固定种子(翻页一致性)
curl -s "https://tools.wktyl.com/api/feed/random?seed=my_seed_123&limit=10"
九、搜索接口
GET /api/feed/search
无需登录。跨频道关键词搜索。
9.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| keyword | string | ✅ | - | 搜索关键词(最长50字符) |
| channel | string | ❌ | all | 频道类型(all=全频道搜索) |
| page | int | ❌ | 1 | 页码 |
| limit | int | ❌ | 20 | 每页数量(1-50) |
9.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 搜索结果列表 |
| total | int | 结果总数 |
| keyword | string | 搜索关键词 |
| channel | string | 搜索频道 |
| page | int | 当前页码 |
| limit | int | 每页数量 |
9.3 curl测试
# 全频道搜索
curl -s "https://tools.wktyl.com/api/feed/search?keyword=李白&limit=5"
# 指定频道搜索
curl -s "https://tools.wktyl.com/api/feed/search?keyword=爱情&channel=lyric&limit=5"
十、收藏列表接口
GET /api/feed/favorites
需登录,Header携带 token。
10.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| page | int | ❌ | 1 | 页码 |
| limit | int | ❌ | 20 | 每页数量(1-50) |
10.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 收藏内容列表(含favorited_at) |
| total | int | 收藏总数 |
| page | int | 当前页码 |
| limit | int | 每页数量 |
10.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/favorites?limit=10" -H "token: YOUR_TOKEN"
十一、点赞列表接口
GET /api/feed/likes
需登录,Header携带 token。
11.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| page | int | ❌ | 1 | 页码 |
| limit | int | ❌ | 20 | 每页数量(1-50) |
11.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 点赞内容列表(含liked_at) |
| total | int | 点赞总数 |
| page | int | 当前页码 |
| limit | int | 每页数量 |
11.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/likes?limit=10" -H "token: YOUR_TOKEN"
十二、浏览历史接口
GET /api/feed/history
需登录,Header携带 token。用户查看详情时自动记录浏览历史。
12.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| page | int | ❌ | 1 | 页码 |
| limit | int | ❌ | 20 | 每页数量(1-50) |
12.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 浏览历史列表(含viewed_at) |
| total | int | 历史总数 |
| page | int | 当前页码 |
| limit | int | 每页数量 |
12.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/history?limit=10" -H "token: YOUR_TOKEN"
十三、稍后读列表接口
GET /api/feed/readlater
需登录,Header携带 token。
13.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| page | int | ❌ | 1 | 页码 |
| limit | int | ❌ | 20 | 每页数量(1-50) |
13.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 稍后读内容列表(含added_at) |
| total | int | 稍后读总数 |
| page | int | 当前页码 |
| limit | int | 每页数量 |
13.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/readlater?limit=10" -H "token: YOUR_TOKEN"
十四、评论列表接口
GET /api/feed/comments
无需登录。获取指定内容的评论列表。
14.1 请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| feed_type | string | ✅ | 内容类型 |
| feed_id | int | ✅ | 内容ID |
| page | int | ❌ | 页码(默认1) |
| limit | int | ❌ | 每页数量(1-50, 默认20) |
14.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 评论列表 |
| list[].id | int | 评论ID |
| list[].user_id | int | 评论者ID |
| list[].username | string | 评论者昵称 |
| list[].avatar | string | 评论者头像URL |
| list[].content | string | 评论内容 |
| list[].like_count | int | 评论点赞数 |
| list[].createtime | int | 评论时间戳 |
| total | int | 评论总数 |
| feed_type | string | 内容类型 |
| feed_id | int | 内容ID |
| page | int | 当前页码 |
| limit | int | 每页数量 |
14.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/comments?feed_type=poetry&feed_id=1"
curl -s "https://tools.wktyl.com/api/feed/comments?feed_type=story&feed_id=5&limit=10"
十五、下拉刷新检查接口
GET /api/feed/refresh
无需登录。检查指定频道是否有新内容,用于客户端下拉刷新判断。
13.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| channel | string | ❌ | all | 频道类型 |
| since_id | int | ✅ | - | 客户端已知的最新ID |
13.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| has_new | bool | 是否有新内容 |
| new_count | int | 新内容数量 |
| latest_id | int | 服务端最新ID |
| channel | string | 当前频道 |
13.3 curl测试
curl -s "https://tools.wktyl.com/api/feed/refresh?channel=poetry&since_id=1000"
十六、刷新获取新内容
URL: GET /api/feed/refresh_content
无需登录 | 不缓存
说明: 专用刷新接口,接收已看ID列表和内容hash,保证返回内容不重复。适用于APP下拉刷新场景,与/api/feed/list分离。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| channel | string | 否 | all | 频道类型(all/poetry/wisdom等) |
| sort | string | 否 | newest | 排序(newest/hottest) |
| limit | int | 否 | 20 | 请求数量,最大50 |
| seen_ids | string | 否 | 已看ID列表,格式: type_id,type_id (如 poetry_1,poetry_2,wisdom_5) | |
| seen_hashes | string | 否 | 已看内容hash列表(MD5前8位,逗号分隔),用于内容去重 |
返回数据结构:
{
"code": 1,
"msg": "成功",
"data": {
"list": [],
"total": 15,
"channel": "all",
"sort": "newest",
"limit": 20
}
}
与/api/feed/list的区别:
| 特性 | /api/feed/list | /api/feed/refresh_content |
|---|---|---|
| 缓存 | 60秒 | 不缓存 |
| seen_ids去重 | 支持(但需客户端传参) | 强制支持 |
| seen_hashes去重 | 不支持 | 支持(内容级去重) |
| 适用场景 | 初始加载/翻页 | 下拉刷新/换一批 |
| 返回结构 | 含page/total/lite | 精简结构 |
curl测试:
curl -s "https://tools.wktyl.com/api/feed/refresh_content?limit=10&seen_ids=poetry_1,poetry_2,wisdom_5" | python -m json.tool
十七、用户偏好设置
URL: GET/POST /api/feed/preferences
GET无需登录(未登录返回默认值) | POST需登录
说明: 获取或保存用户的Feed偏好设置,包括频道开关、混合规则、去重、排序等。登录用户可跨设备同步。
GET参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| action | string | 否 | get | 操作类型: get(获取) |
POST参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| action | string | 是 | 操作类型: save(保存) | |
| data | string | 是 | JSON格式偏好数据 |
偏好数据字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| disabled_channels | string[] | 禁用频道key列表 |
| mix_mode | string | 混合模式: uniform/ratio/specific/random/group |
| mix_channels | string[] | 参与混合的频道列表 |
| mix_ratios | object | 比例模式专用: {"poetry":40,"wisdom":30} |
| group_size | int | 分组循环模式每组条数(默认3) |
| deduplicate | bool | 是否启用内容去重(默认true) |
| sort | string | 排序偏好: newest/hottest |
| home_card_mode | string | 首页卡片混合模式 |
| home_card_channels | string[] | 首页卡片频道列表 |
| per_page | int | 每页加载数量(默认20) |
GET返回数据结构:
{
"code": 1,
"msg": "成功",
"data": {
"disabled_channels": [],
"mix_mode": "random",
"mix_channels": [],
"mix_ratios": {},
"group_size": 3,
"deduplicate": true,
"sort": "newest",
"home_card_mode": "random",
"home_card_channels": [],
"per_page": 20
}
}
POST返回数据结构:
{
"code": 1,
"msg": "保存成功",
"data": {
"disabled_channels": ["drug", "illness"],
"mix_mode": "random",
"deduplicate": true,
"sort": "newest"
}
}
curl测试:
# 获取偏好
curl -s "https://tools.wktyl.com/api/feed/preferences?action=get" | python -m json.tool
# 保存偏好(需登录token)
curl -s -X POST "https://tools.wktyl.com/api/feed/preferences" \
-H "token: YOUR_TOKEN" \
-d "action=save&data={\"deduplicate\":true,\"sort\":\"newest\",\"mix_mode\":\"random\"}" | python -m json.tool
十八、信息流统计接口
GET /api/feed/stats
无需登录,无需参数。
14.1 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| total_content | int | 内容总数 |
| total_views | int | 总浏览量 |
| channel_count | int | 频道数量 |
| channels | array | 各频道统计 |
| channels[].key | string | 频道标识 |
| channels[].name | string | 频道名称 |
| channels[].icon | string | 频道图标 |
| channels[].count | int | 内容数量 |
| channels[].views | int | 浏览量 |
| interactions | array | 互动统计 |
| interactions[].action | string | 操作类型 |
| interactions[].cnt | int | 操作次数 |
| updated_at | string | 更新时间 |
14.2 curl测试
curl -s "https://tools.wktyl.com/api/feed/stats" | python -m json.tool
十九、关联推荐接口
GET /api/feed/relatedRecommend
无需登录。根据指定内容推荐同类型相关内容,用于详情页底部"相关推荐"模块。
17.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| type | string | ✅ | - | 内容类型(poetry/wisdom/story等) |
| id | int | ✅ | - | 内容ID |
| limit | int | ❌ | 5 | 返回数量(1-20) |
17.2 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| source_type | string | 源内容类型 |
| source_id | int | 源内容ID |
| total | int | 推荐结果数量 |
| list | array | 推荐内容列表(统一条目结构) |
17.3 curl测试
# 诗词关联推荐
curl -s "https://tools.wktyl.com/api/feed/relatedRecommend?type=poetry&id=1&limit=5"
# 成语关联推荐
curl -s "https://tools.wktyl.com/api/feed/relatedRecommend?type=chengyu&id=1"
二十、混合信息流接口
GET /api/feed/mix
无需登录。根据用户指定的混合规则,从多个频道获取内容并按规则排列。支持5种混合模式,适合首页卡片、句子广场等场景的多源内容聚合。
18.1 请求参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| mode | string | ❌ | random | 混合模式: uniform/ratio/specific/random/group |
| channels | string | ❌ | 全部频道 | 参与混合的频道(逗号分隔, 如 poetry,wisdom,story) |
| ratios | string | ❌ | - | 比例模式专用(JSON字符串, 如 {"poetry":40,"wisdom":30,"story":30}) |
| group_size | int | ❌ | 3 | 分组循环模式每组条数(1-10) |
| limit | int | ❌ | 20 | 总条数(1-50) |
| sort | string | ❌ | hottest | 排序方式: newest/hottest |
18.2 混合模式说明
| 模式 | key | 说明 | 示例 |
|---|---|---|---|
| 🔀 均匀交叉 | uniform |
各分类轮流出场,每分类各1条循环 | A1 B1 C1 A2 B2 C2 |
| 📊 比例混合 | ratio |
按权重比例分配条数 | 诗词40% 名言30% 故事30% |
| 🎯 仅指定分类 | specific |
只从勾选分类获取,不混合其他 | 仅诗词+名言 |
| 🎲 随机混排 | random |
完全随机获取并打乱顺序 | 随机5条 |
| 🔄 分组循环 | group |
每分类连续N条后切换下一分类 | AAA BBB CCC |
18.3 响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 混合内容列表(统一条目结构) |
| total | int | 返回条数 |
| mode | string | 实际使用的混合模式 |
| channels | array | 参与混合的频道列表 |
| limit | int | 请求条数 |
18.4 各模式详细说明
uniform — 均匀交叉
各频道轮流取1条,循环填充直到达到limit。适合希望内容多样性最大化的场景。
请求: mode=uniform&channels=poetry,wisdom,story&limit=6
结果: [诗词1, 名言1, 故事1, 诗词2, 名言2, 故事2]
ratio — 比例混合
按用户指定比例分配各频道条数。比例值无需加总等于100,系统自动归一化计算。
请求: mode=ratio&channels=poetry,wisdom,story&ratios={"poetry":50,"wisdom":30,"story":20}&limit=10
结果: [诗词×5, 名言×3, 故事×2] (按比例分配后随机排列)
注意: ratios参数需URL编码,如
ratios=%7B%22poetry%22%3A50%7D
specific — 仅指定分类
只从channels指定的频道获取内容,不混合其他频道。适合只想看特定类型的场景。
请求: mode=specific&channels=poetry,wisdom&limit=10
结果: [诗词和名言混合10条,不含其他频道]
random — 随机混排
从所有频道(或指定channels)随机获取内容并打乱顺序。最简单通用的模式。
请求: mode=random&limit=5
结果: [随机5条,频道和顺序均随机]
group — 分组循环
每个频道连续取group_size条后切换下一个频道,循环填充。适合希望同类型内容集中展示的场景。
请求: mode=group&channels=poetry,wisdom,story&group_size=3&limit=9
结果: [诗词1, 诗词2, 诗词3, 名言1, 名言2, 名言3, 故事1, 故事2, 故事3]
18.5 curl测试
# 随机混排(默认模式)
curl -s "https://tools.wktyl.com/api/feed/mix?limit=10" | python -m json.tool
# 均匀交叉
curl -s "https://tools.wktyl.com/api/feed/mix?mode=uniform&channels=poetry,wisdom,story&limit=9" | python -m json.tool
# 比例混合
curl -s "https://tools.wktyl.com/api/feed/mix?mode=ratio&channels=poetry,wisdom,story&ratios=%7B%22poetry%22%3A50%2C%22wisdom%22%3A30%2C%22story%22%3A20%7D&limit=10" | python -m json.tool
# 仅指定分类
curl -s "https://tools.wktyl.com/api/feed/mix?mode=specific&channels=poetry,hitokoto&limit=10" | python -m json.tool
# 分组循环(每组3条)
curl -s "https://tools.wktyl.com/api/feed/mix?mode=group&channels=poetry,wisdom,story&group_size=3&limit=9" | python -m json.tool
18.6 错误码
| 错误信息 | 说明 |
|---|---|
| 不支持的混合模式: xxx | mode参数不在允许列表中 |
| 比例模式需提供ratios参数 | mode=ratio但未传ratios |
| 比例模式ratios格式错误 | ratios不是合法JSON |
| 未找到可用频道数据 | 所有指定频道均无内容 |
二十一、频道类型说明
| key | 名称 | 图标 | 数据表 | 内容说明 | extra字段 |
|---|---|---|---|---|---|
| all | 推荐 | 🔥 | 多表聚合 | 混合推荐所有类型 | - |
| poetry | 古诗词 | 📜 | tool_poetry | 古诗词全文 | {} |
| wisdom | 名言金句 | 💡 | tool_wisdom | 名人名言 | {} |
| story | 故事 | 📚 | tool_story | 故事大全 | {} |
| hitokoto | 一言 | 💬 | tool_hitokoto | 精美句子 | from_source, type_name |
| riddle | 谜语 | 🧩 | tool_riddle | 谜语大全 | hint |
| efs | 歇后语 | 🎭 | tool_efs | 歇后语大全 | {} |
| brainteaser | 脑筋急转弯 | 🧠 | tool_brainteaser | 脑筋急转弯 | {} |
| saying | 俗语 | 🗣️ | tool_saying | 俗语大全 | {} |
| lyric | 歌词 | 🎵 | tool_lyric | 歌词搜索 | {} |
| why | 十万个为什么 | ❓ | tool_why | 科普知识 | {} |
| composition | 作文 | ✍️ | tool_composition | 作文素材 | {} |
| couplet | 对联 | 🏮 | tool_couplet | 对联大全 | {} |
| cs | 常识 | 📖 | tool_cs | 生活常识 | {} |
| drug | 药品 | 💊 | tool_drug | 药品查询 | goods_name |
| herbal | 中草药 | 🌿 | tool_herbal | 中草药大全 | name_alias |
| food | 食物 | 🍽️ | tool_food | 食物功效 | {} |
| wine | 酒方 | 🍷 | tool_wine | 酒方大全 | {} |
| article | 文章 | 📰 | tool_article | 用户投稿文章 | user_id, image |
| chengyu | 成语 | 🔤 | tool_cy | 成语大全 | pinyin, origin, example |
| hanzi | 汉字 | 🈯 | tool_hanzi | 汉字查询 | pinyin, wubi, bushou, bihua, bishun |
| cidian | 词典 | 📚 | tool_zc | 词典查询 | pinyin |
| prescription | 偏方 | 🧪 | tool_prescription | 民间偏方 | {} |
| tisana | 药茶 | 🍵 | tool_tisana | 药茶配方 | recipe |
| joke | 笑话 | 😄 | tool_joke | 笑话大全 | {} |
| zgjm | 周公解梦 | 🌙 | tool_zgjm | 周公解梦 | {} |
| lunyu | 论语 | 📖 | tool_lunyu | 论语 | translation |
| hdnj | 黄帝内经 | ⚕️ | tool_hdnj | 黄帝内经 | translation |
| jgj | 金刚经 | 📿 | tool_jgj | 金刚经 | translation |
| mz | 孟子 | 📜 | tool_mz | 孟子 | translation |
| zz | 庄子 | 🦋 | tool_zz | 庄子 | translation |
| zuozhuan | 左传 | 竹 | tool_zuozhuan | 左传 | translation |
| sj | 史记 | 🏛️ | tool_sj | 史记 | translation |
| sgz | 三国志 | ⚔️ | tool_sgz | 三国志 | translation |
| sbbf | 孙膑兵法 | 🗡️ | tool_sbbf | 孙膑兵法 | translation |
| warring | 兵法 | 🛡️ | tool_warring | 战国策 | translation |
| illness | 疾病 | 🩺 | tool_illness | 疾病查询 | zz, yqys, tlff |
| word | 英语单词 | 🔤 | tool_word | 英语单词 | british, american, jbjs |
| abbr | 缩写 | 📝 | tool_abbr | 英文缩写 | full, meaning, prc |
| surname | 姓氏 | 👤 | tool_surname | 百家姓 | image, initial |
| jieqi | 节气 | 🌤️ | tool_jieqi | 二十四节气 | image, english, section, sanhou, origin, convention, poem, legend, health, note |
| nation | 国家 | 🌍 | tool_nation | 国家信息 | capital, initial, image, subhead, vae, langue, acreage, currency, region |
| wlyh | 网络用语 | 💬 | tool_wlyh | 网络用语 | translation |
| jiufang | 酒方 | 🍶 | tool_jiufang | 酒方大全 | source, usage, ingredients |
| bot | 星座 | ⭐ | tool_bot | 星座查询 | chinese |
二十二、数据结构说明
20.1 信息流条目统一结构
每个条目都包含以下标准字段,确保APP端可统一渲染:
{
"feed_type": "poetry",
"feed_name": "古诗词",
"feed_icon": "📜",
"id": 12345,
"title": "静夜思",
"author": "李白",
"content": "完整内容文本",
"summary": "内容摘要(前100字)",
"views": 12580,
"createtime": 1777320000,
"updatetime": 1777320000,
"extra": {}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| feed_type | string | ✅ | 内容类型标识,用于互动和详情 |
| feed_name | string | ✅ | 类型中文名,用于UI显示 |
| feed_icon | string | ✅ | 类型图标emoji,用于UI显示 |
| id | int | ✅ | 内容ID(对应原表ID),正整数 |
| title | string | ✅ | 标题,用于列表卡片标题 |
| author | string | ✅ | 作者/来源,空字符串表示无作者 |
| content | string | ⚠️ | 完整内容文本(lite模式不返回) |
| summary | string | ✅ | 摘要(前100字),用于列表预览 |
| views | int | ✅ | 浏览次数,非负整数 |
| createtime | int | ✅ | 创建时间戳,用于显示"3小时前" |
| updatetime | int | ✅ | 更新时间戳 |
| extra | object | ✅ | 扩展信息,无额外数据时为空对象{} |
20.2 各类型extra字段详情
| 类型 | extra字段 | 类型 | 说明 |
|---|---|---|---|
| hitokoto | from_source | string | 来源作品名 |
| hitokoto | type_name | string | 分类名(动画/漫画/游戏等) |
| riddle | hint | string | 谜语提示 |
| drug | goods_name | string | 药品商品名 |
| drug | gg | string | 规格 |
| drug | cf | string | 成分 |
| drug | yfyl | string | 用法用量 |
| drug | blfy | string | 不良反应 |
| drug | jj | string | 禁忌 |
| drug | zysx | string | 注意事项 |
| drug | pzwh | string | 批准文号 |
| drug | scqy | string | 生产企业 |
| herbal | name_alias | string | 中草药别名 |
| herbal | image | string | 中草药图片URL |
| herbal | spell | string | 拼音 |
| herbal | english_name | string | 英文名 |
| herbal | medicinal_parts | string | 药用部位 |
| herbal | plant_morphology | string | 植物形态 |
| herbal | origin_distribution | string | 产地分布 |
| herbal | harvest_processing | string | 采收加工 |
| herbal | drug_properties | string | 药物性质 |
| herbal | tropism_taste | string | 性味归经 |
| herbal | clinic | string | 临床应用 |
| herbal | pharmacology | string | 药理作用 |
| herbal | chemical_component | string | 化学成分 |
| herbal | usage_taboo | string | 用药禁忌 |
| herbal | prescription | string | 选方 |
| wine | source | string | 来源 |
| wine | stock | string | 原料 |
| wine | make | string | 制法 |
| wine | usages | string | 用法 |
| wine | taboo | string | 禁忌 |
| article | user_id | int | 作者用户ID |
| article | image | string | 文章封面图 |
| article | tags | string | 标签 |
| article | favorites | int | 收藏数 |
| article | comments | int | 评论数 |
| article | rating_sum | int | 评分总和 |
| article | rating_count | int | 评分人数 |
| poetry | dynasty | string | 朝代 |
| chengyu | pinyin | string | 成语拼音 |
| chengyu | origin | string | 成语出处 |
| chengyu | example | string | 成语例句 |
| chengyu | synonym | string | 近义词 |
| chengyu | antonym | string | 反义词 |
| chengyu | grammar | string | 语法 |
| chengyu | usage | string | 用法 |
| hanzi | pinyin | string | 汉字拼音 |
| hanzi | wubi | string | 五笔编码 |
| hanzi | bushou | string | 部首 |
| hanzi | bihua | int | 笔画数 |
| hanzi | bishun | string | 笔顺 |
| hanzi | image | string | 汉字图片 |
| hanzi | fantizi | string | 繁体字 |
| hanzi | zy | string | 造字 |
| hanzi | wuxing | string | 五行 |
| hanzi | jg | string | 结构 |
| hanzi | unicode | string | Unicode编码 |
| hanzi | bishunm | string | 笔顺码 |
| hanzi | xiefa | string | 写法 |
| hanzi | ziyi | string | 字义 |
| cidian | pinyin | string | 词语拼音 |
| cidian | pinyin_wu | string | 五笔拼音 |
| cidian | zy | string | 造词 |
| cidian | szm | string | 首字母 |
| cidian | cx | string | 词性 |
| cidian | wljs | string | 维量解释 |
| tisana | recipe | string | 药茶配方 |
| tisana | source | string | 来源 |
| tisana | usages | string | 用法 |
| tisana | taboo | string | 禁忌 |
| word | british | string | 英式发音 |
| word | american | string | 美式发音 |
| word | cx | string | 词性 |
| word | lz | string | 例句 |
| abbr | full | string | 全称 |
| abbr | meaning | string | 含义 |
| abbr | prc | string | 中文释义 |
| surname | image | string | 姓氏图片 |
| surname | initial | string | 首字母 |
| jieqi | image | string | 节气图片 |
| jieqi | english | string | 英文名 |
| jieqi | section | string | 所属季节 |
| jieqi | sanhou | string | 三候 |
| jieqi | origin | string | 起源 |
| jieqi | convention | string | 习俗 |
| jieqi | poem | string | 诗词 |
| jieqi | legend | string | 传说 |
| jieqi | health | string | 养生 |
| jieqi | note | string | 备注 |
| nation | capital | string | 首都 |
| nation | initial | string | 首字母 |
| nation | image | string | 国旗图片 |
| nation | subhead | string | 副标题 |
| nation | vae | string | 别名 |
| nation | langue | string | 语言 |
| nation | acreage | string | 面积 |
| nation | currency | string | 货币 |
| nation | region | string | 地区 |
| illness | zz | string | 症状 |
| illness | yqys | string | 易感因素 |
| illness | tlff | string | 治疗方法 |
| jiufang | source | string | 来源 |
| jiufang | usage | string | 用法 |
| jiufang | ingredients | string | 配料 |
| lunyu/hdnj/jgj/mz/zz/zuozhuan/sj/sgz/sbbf/warring/wlyh | translation | string | 译文 |
| bot | chinese | string | 中文名 |
20.3 MySQL表结构
tool_feed_interaction - 互动记录表
对应接口:
/api/feed/action(写入),/api/feed/favorites(读favorite),/api/feed/likes(读like),/api/feed/history(读view),/api/feed/readlater(读readlater),/api/feed/comments(读comment),/api/feed/stats(统计)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int(11) | PK | 主键自增 |
| user_id | int(11) | ✅ | 用户ID |
| feed_type | varchar(30) | ✅ | 内容类型 |
| feed_id | int(11) | ✅ | 内容ID |
| action | varchar(20) | ✅ | 操作类型(like/favorite/share/dislike/view/comment/readlater/rating/block/report/comment_like/readtime) |
| extra | text | ❌ | 扩展数据JSON(评论内容/评分/举报原因/阅读时长等) |
| createtime | int(11) | ✅ | 创建时间戳 |
索引:
idx_user_feed_action(user_id, feed_type, feed_id, action) - 普通索引(允许comment/report/readtime等多条记录)idx_feed_type_id(feed_type, feed_id) - 按类型查内容idx_user_action(user_id, action) - 按用户查操作idx_createtime(createtime) - 时间排序idx_action_createtime(action, createtime) - 按操作类型+时间查询
tool_feed_profile - 用户画像表
对应接口:
/api/feed/recommend(读取偏好),/api/feed/action(更新权重)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int(11) | PK | 主键自增 |
| user_id | int(11) | ✅ | 用户ID(唯一) |
| preferred_types | text | ❌ | 偏好类型JSON: {"poetry":5,"wisdom":3} |
| preferred_channels | varchar(255) | ❌ | 偏好频道 |
| updated_at | int(11) | ✅ | 更新时间戳 |
二十三、MySQL优化说明
17.1 已添加索引
ALTER TABLE tool_poetry ADD INDEX idx_views (views);
ALTER TABLE tool_poetry ADD INDEX idx_id_views (id, views);
ALTER TABLE tool_wisdom ADD INDEX idx_views (views);
ALTER TABLE tool_story ADD INDEX idx_views (views);
ALTER TABLE tool_hitokoto ADD INDEX idx_switch_views (switch, views);
ALTER TABLE tool_riddle ADD INDEX idx_views (views);
ALTER TABLE tool_lyric ADD INDEX idx_views (views);
ALTER TABLE tool_brainteaser ADD INDEX idx_views (views);
ALTER TABLE tool_efs ADD INDEX idx_views (views);
ALTER TABLE tool_article ADD INDEX idx_status_createtime (status, createtime);
ALTER TABLE tool_article ADD INDEX idx_status_views (status, views);
17.2 查询优化策略
| 策略 | 说明 |
|---|---|
| 游标分页 | WHERE id < last_id 替代 OFFSET,避免深分页 |
| 轻量模式 | lite=1 不返回content字段,减少60%数据传输 |
| 缓存层 | ThinkPHP Cache缓存30-600秒 |
| 独立查询 | 各表独立查询后PHP层合并,避免大表UNION |
| 计数缓存 | 频道内容数量缓存600秒 |
| 索引覆盖 | 热门查询使用 idx_views 索引覆盖 |
| 随机优化 | ID范围随机取值,避免 ORDER BY RAND() |
| 搜索保护 | 各表搜索独立try-catch,单表错误不影响整体 |
17.3 缓存时间
| 数据 | 缓存时间 | 说明 |
|---|---|---|
| 随机内容 | 30秒 | 频繁变化 |
| 信息流列表 | 60秒 | 频繁访问 |
| 个性化推荐 | 90秒 | 中等频率 |
| 热门内容 | 120秒 | 变化较少 |
| 搜索结果 | 120秒 | 中等频率 |
| 信息流统计 | 300秒 | 全局统计 |
| 频道计数 | 600秒 | 变化极少 |
二十四、APP接入指南
18.1 Flutter数据模型
class FeedItem {
final String feedType;
final String feedName;
final String feedIcon;
final int id;
final String title;
final String author;
final String? content;
final String summary;
final int views;
final Map<String, dynamic> extra;
FeedItem.fromJson(Map<String, dynamic> json)
: feedType = json['feed_type'] ?? '',
feedName = json['feed_name'] ?? '',
feedIcon = json['feed_icon'] ?? '',
id = json['id'] ?? 0,
title = json['title'] ?? '',
author = json['author'] ?? '',
content = json['content'],
summary = json['summary'] ?? '',
views = json['views'] ?? 0,
extra = json['extra'] ?? {};
}
class FeedChannel {
final String key;
final String name;
final String icon;
final int count;
FeedChannel.fromJson(Map<String, dynamic> json)
: key = json['key'] ?? '',
name = json['name'] ?? '',
icon = json['icon'] ?? '',
count = json['count'] ?? 0;
}
18.2 接入步骤
- 首页信息流 →
/api/feed/list?channel=all&sort=newest&lite=1 - 频道切换 →
/api/feed/channels获取频道列表,用户选择后切换channel参数 - 快速下滑 →
/api/feed/random?limit=10随机获取新内容 - 内容详情 →
/api/feed/detail?type={feed_type}&id={id} - 用户互动 →
/api/feed/action点赞/收藏/分享 - 个性化推荐 →
/api/feed/recommend登录后自动基于兴趣推荐 - 搜索 →
/api/feed/search?keyword=关键词 - 收藏列表 →
/api/feed/favorites - 浏览历史 →
/api/feed/history - 下拉刷新 →
/api/feed/refresh?since_id=最新ID
18.3 快速下滑优化方案
用户快速下滑时:
1. 列表使用 lite=1 轻量模式,不加载content
2. 到达底部时调用 /api/feed/random 获取新内容
3. 游标分页使用 last_id 避免深分页
4. 下拉刷新先调用 /api/feed/refresh 检查是否有新内容
18.4 频道与UI映射
| 频道 | 推荐UI样式 | 说明 |
|---|---|---|
| all | 卡片流 | 混合内容,显示feed_icon+feed_name标签 |
| poetry | 诗词卡片 | 显示标题+作者+内容预览 |
| hitokoto | 一言卡片 | 大字体显示,显示来源 |
| story | 故事卡片 | 标题+摘要+阅读量 |
| riddle | 互动卡片 | 显示谜面+提示按钮 |
| article | 文章卡片 | 标题+摘要+封面图 |
18.5 互动功能接入
Future<void> likeFeed(String feedType, int feedId, String token) async {
await http.post(
Uri.parse('$baseUrl/api/feed/action'),
headers: {'token': token},
body: {'action': 'like', 'feed_type': feedType, 'feed_id': '$feedId'},
);
}
Future<void> favoriteFeed(String feedType, int feedId, String token) async {
await http.post(
Uri.parse('$baseUrl/api/feed/action'),
headers: {'token': token},
body: {'action': 'favorite', 'feed_type': feedType, 'feed_id': '$feedId'},
);
}
18.6 无需登录使用
所有列表、详情、推荐、统计、搜索、随机、刷新检查、混合信息流接口均无需登录即可使用。 仅互动操作(点赞/收藏/分享)和收藏列表/点赞列表/浏览历史需要登录。
二十五、测试验证报告
23.1 混合信息流接口测试
测试时间: 2026-05-01 测试脚本:
docs/toolsapi/scripts/test_feed_mix.py
| 模式 | 参数 | 结果 | 说明 |
|---|---|---|---|
| random | limit=10 |
✅ 通过 | 返回10条随机混合内容 |
| uniform | channels=poetry,wisdom,story&limit=9 |
✅ 通过 | 各频道轮流3条 |
| ratio | channels=poetry,wisdom,story&ratios={"poetry":50,"wisdom":30,"story":20}&limit=10 |
✅ 通过 | 按比例分配5/3/2条 |
| specific | channels=poetry,hitokoto&limit=10 |
✅ 通过 | 仅返回诗词和一言 |
| group | channels=poetry,wisdom,story&group_size=3&limit=9 |
✅ 通过 | 每频道连续3条 |
23.2 测试脚本使用
# 运行全部混合模式测试
cd docs/toolsapi/scripts
python test_feed_mix.py
# 脚本会自动:
# 1. 上传最新Feed.php到服务器
# 2. 依次测试5种混合模式
# 3. 输出每种模式的返回条数和频道分布