58 KiB
短视频应用接口文档
- 版本:v1.1
- 日期:2026-10-18
- Base URL:
https://api.example.com/api/v1
注意:App 不硬编码 Base URL。启动时优先解析
txt.256kb.top的 DNS TXT 记录获取真实 API 域名;解析失败时按md5(yyyyMM) + "_jsnbhh.vip"计算兜底域名(详见《01-开发文档》5.5 节)。本文示例域名仅为占位。
1. 通用说明
1.1 请求头
| Header | 必填 | 说明 |
|---|---|---|
| Content-Type | 是 | application/json(文件上传为 multipart/form-data) |
| Authorization | 登录接口必填 | Bearer <access_token> |
| X-Device-ID | 是 | 设备唯一标识(游客计费依赖,首启生成 UUID 持久化) |
| X-App-Version | 是 | App 版本号(如 1.2.0),用于版本检查与灰度 |
| X-Platform | 是 | 平台标识:ios / android |
| X-Request-ID | 建议 | 客户端请求唯一 ID,用于幂等与链路追踪 |
1.2 统一响应结构
{
"code": 0,
"message": "ok",
"data": {},
"request_id": "8f3c2a1e-..."
}
code = 0表示成功;非 0 为错误码,message为可展示的错误文案- HTTP 状态码:业务错误统一 200 + 业务 code;401/403/429/500 使用标准语义
1.3 通用错误码
| code | 说明 |
|---|---|
| 0 | 成功 |
| 1001 | 参数错误 |
| 1002 | 未登录或 Token 无效/过期 |
| 1003 | 无权限(功能需登录/已被封禁) |
| 1004 | 验证码错误或已过期 |
| 1005 | 请求过于频繁(限流) |
| 1006 | 资源不存在 |
| 1009 | 账号已注销(冻结期内登录可撤销) |
| 2001 | 积分不足 |
| 2002 | 今日免费观看次数已用完(游客需登录) |
| 2003 | 视频不存在或未发布 |
| 2004 | 已是终身会员,无需再开通 |
| 3001 | 订单不存在 |
| 3002 | 订单状态异常(已支付/已关闭) |
| 3003 | 支付金额不匹配 |
| 5000 | 服务器内部错误 |
| 4001 | 无管理员权限或角色不允许该操作 |
| 4002 | 该操作必须填写原因(reason) |
| 2101 | 邀请码无效或不可绑定(已绑定/绑定自己/同设备已注册) |
| 2102 | 资产余额不足 |
| 2103 | 低于最低提现额度 |
| 2104 | 已有审核中的提现申请 |
| 2105 | 内容包含敏感词 |
| 2106 | 请勿重复举报 |
| 2107 | 无权操作(非作者本人) |
1.4 分页约定
- Feed 流:游标分页。请求
cursor(首次不传)+limit;响应返回next_cursor(null 表示没有更多) - 普通列表:
page(从 1 开始)+page_size(默认 20,最大 50),响应含total
2. 接口总览
| # | 模块 | 方法 | 路径 | 说明 | 登录 |
|---|---|---|---|---|---|
| 1 | 认证 | POST | /auth/sms/send | 发送短信验证码 | 否 |
| 2 | 认证 | POST | /auth/email/send | 发送邮箱验证码 | 否 |
| 3 | 认证 | POST | /auth/register | 注册(手机/邮箱,可填邀请码,可配置赠送体验会员) | 否 |
| 4 | 认证 | POST | /auth/login | 登录 | 否 |
| 5 | 认证 | POST | /auth/token/refresh | 刷新令牌 | 否(带refresh) |
| 6 | 认证 | POST | /auth/logout | 退出登录 | 是 |
| 7 | 认证 | POST | /auth/password/reset | 找回密码 | 否 |
| 8 | 用户 | GET | /users/me | 获取个人信息 | 是 |
| 9 | 用户 | PUT | /users/me | 修改资料 | 是 |
| 10 | 用户 | POST | /users/me/avatar | 上传头像 | 是 |
| 11 | 用户 | GET | /users/me/wallet | 钱包/积分余额 | 是 |
| 12 | 用户 | GET | /users/me/points/records | 积分明细 | 是 |
| 13 | 用户 | POST | /users/me/deactivate | 注销账号(7天冻结期) | 是 |
| 14 | 用户 | GET | /users/{user_id} | 用户公开主页 | 否 |
| 15 | 用户 | GET | /users/{user_id}/videos | 他人作品列表 | 否 |
| 16 | 视频 | GET | /videos/feed | 视频流(recommend/latest/hot/liked/viewed) | 否 |
| 17 | 视频 | GET | /videos/{video_id} | 视频详情(登录返回续播进度) | 否 |
| 18 | 视频 | POST | /videos/{video_id}/watch | 观看上报(计费,可带播放进度) | 否 |
| 19 | 视频 | POST | /videos/{video_id}/watch/complete | 完整观看上报(创作收益计数) | 否 |
| 20 | 视频 | POST | /videos/upload/token | 获取上传凭证 | 是 |
| 21 | 视频 | POST | /videos | 发布视频(上传完成回调) | 是 |
| 22 | 视频 | PUT | /videos/{video_id} | 编辑视频(仅作者) | 是 |
| 23 | 视频 | DELETE | /videos/{video_id} | 删除视频(仅作者,软删除) | 是 |
| 24 | 视频 | GET | /users/me/videos | 我的作品 | 是 |
| 25 | 视频 | GET | /videos/categories | 分类列表 | 否 |
| 26 | 视频 | GET | /tags/{tag_name}/videos | 标签视频列表 | 否 |
| 27 | 视频 | GET | /videos/search | 视频搜索 | 否 |
| 28 | 视频 | GET | /search/hot | 热搜榜 | 否 |
| 29 | 互动 | POST | /videos/{video_id}/like | 点赞/取消点赞 | 是 |
| 30 | 互动 | POST | /videos/{video_id}/favorite | 收藏/取消收藏 | 是 |
| 31 | 互动 | GET | /videos/{video_id}/comments | 评论列表 | 否 |
| 32 | 互动 | POST | /videos/{video_id}/comments | 发表评论 | 是 |
| 33 | 互动 | DELETE | /comments/{comment_id} | 删除评论 | 是 |
| 34 | 互动 | GET | /users/me/favorites | 我的收藏 | 是 |
| 35 | 互动 | GET | /users/me/history | 观看历史 | 是 |
| 36 | 会员 | GET | /membership/plans | 会员套餐列表 | 否 |
| 37 | 会员 | GET | /membership/me | 我的会员状态 | 是 |
| 38 | 会员 | POST | /membership/redeem | 积分开通会员 | 是 |
| 39 | 支付 | GET | /payments/packages | 充值套餐列表(后台可配) | 是 |
| 40 | 支付 | POST | /payments/recharge | 创建充值订单 | 是 |
| 41 | 支付 | GET | /payments/orders/{order_no} | 查询订单状态 | 是 |
| 42 | 支付 | POST | /payments/orders/{order_no}/cancel | 取消订单 | 是 |
| 43 | 回调 | POST | /callbacks/alipay | 支付宝异步通知 | 平台调用 |
| 44 | 回调 | POST | /callbacks/wechat | 微信支付异步通知 | 平台调用 |
| 45 | 激励 | GET | /referral/me | 我的邀请信息 | 是 |
| 46 | 激励 | POST | /referral/bind | 绑定邀请码 | 是 |
| 47 | 激励 | GET | /assets/me | 资产钱包 | 是 |
| 48 | 激励 | GET | /assets/records | 资产流水 | 是 |
| 49 | 激励 | POST | /assets/withdraw | 申请提现 | 是 |
| 50 | 激励 | GET | /assets/withdraw/records | 提现记录 | 是 |
| 51 | 推广归因 | POST | /invite/click | 推广点击埋点(H5 落地页打开即上报) | 否 |
| 52 | 推广归因 | POST | /invite/match | App 首启归因匹配 | 否 |
| 53 | 推广归因 | GET | /r/{code} | H5 推广落地页(根路径,非 /api/v1 前缀) | 否 |
| 54 | 通用 | GET | /app/version | 版本检查 | 否 |
| 55 | 消息 | GET | /notifications | 通知列表 | 是 |
| 56 | 消息 | GET | /notifications/unread_count | 未读数 | 是 |
| 57 | 消息 | POST | /notifications/read | 标记已读 | 是 |
| 58 | 通用 | POST | /reports | 提交举报 | 是 |
| 59 | 视频 | GET | /videos/series/{series_id} | 系列详情 + 全部集数列表 | 否 |
| 60 | 视频 | GET | /videos/{video_id}/series | 当前视频所属系列 + 上下集 | 否 |
| 61 | 通用 | GET | /m3u8/proxy | m3u8 播放列表代理(回源拉取,TS 分片不经过服务器) | 否 |
| 62~105 | 后台管理 | * | /admin/** | 登录、看板、审核、视频/系列/评论管理、用户(含重置密码)、积分、订单、补单/退款、套餐、赠送、提现审核、推荐风控、举报处理、敏感词、平台配置、采集源/采集同步、分类、标签、日志,见第 11 章 | 管理员 |
3. 认证模块
3.1 发送短信验证码 POST /auth/sms/send
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| phone | string | 是 | 手机号,11 位 |
| scene | string | 是 | 场景:register / login / reset |
请求示例
{ "phone": "13800138000", "scene": "register" }
响应示例
{ "code": 0, "message": "ok", "data": { "expire_seconds": 300, "retry_after": 60 } }
限制:同号码 60 秒 1 条,同号码每天 10 条,同 IP 每小时 5 条;注册场景下已注册号码返回错误码 1001("该账号已注册"),login/reset 场景下未注册号码同样返回 1001。未配置短信通道时(开发环境)响应额外返回 dev_code 并仅记日志。
3.2 发送邮箱验证码 POST /auth/email/send
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| string | 是 | 邮箱地址 | |
| scene | string | 是 | register / login / reset |
验证码由服务端通过 SMTP 真实发送(STARTTLS),并写入 Redis(email:code:{scene}:{email},10 分钟有效,验证通过即删除)。响应结构同 3.1,expire_seconds=600;限流规则同 3.1(同邮箱 60 秒 1 条、每天 10 条、同 IP 每小时 5 条)。未配置 SMTP 时按开发模式处理:响应额外返回 dev_code 并仅记日志。
3.3 注册 POST /auth/register
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | 是 | phone 或 email |
| phone | string | type=phone 时必填 | 手机号 |
| string | type=email 时必填 | 邮箱 | |
| code | string | 是 | 验证码 |
| password | string | 是 | 密码,8-32 位,须含字母和数字 |
| nickname | string | 否 | 昵称,默认"用户+随机尾号" |
| invite_code | string | 否 | 推荐人邀请码(App 解析分享口令自动预填;未填时服务端取首启模糊归因结果,见 9.7~9.9) |
请求示例
{ "type": "phone", "phone": "13800138000", "code": "825314", "password": "abc12345", "nickname": "小明" }
响应示例
{
"code": 0,
"message": "ok",
"data": {
"user_id": 100023,
"access_token": "eyJhbGciOi...",
"refresh_token": "d9f2...",
"expires_in": 7200,
"user": { "user_id": 100023, "nickname": "小明", "avatar_url": "", "is_member": true },
"trial_granted": { "plan_code": "trial", "plan_name": "体验会员", "days": 1, "end_at": "2026-10-15 12:00:00" }
}
}
trial_granted:注册赠送的体验会员;后台关闭赠送开关(register_gift_trial.enabled=0)时为null,is_member相应为 false
错误码:1004 验证码错误;1001 手机号/邮箱已注册。
3.4 登录 POST /auth/login
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | 是 | phone_password / phone_code / email_password |
| phone | string | 手机方式必填 | |
| string | 邮箱方式必填 | ||
| password | string | 密码方式必填 | |
| code | string | 验证码方式必填 | |
| revoke | bool | 否 | 注销冻结期内确认撤销注销(默认 false,见 4.6) |
请求示例
{ "type": "phone_password", "phone": "13800138000", "password": "abc12345" }
响应:同 3.3。连续失败 5 次锁定 15 分钟(错误码 1005,按 IP 维度计数)。
登录账号仅支持手机号或邮箱(按 type 使用对应字段),不支持昵称登录。冻结期内账号登录返回 1009 且
data.can_revoke=true;确认撤销后带"revoke": true重试即恢复账号并正常签发 Token。
3.5 刷新令牌 POST /auth/token/refresh
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| refresh_token | string | 是 | 刷新令牌 |
响应:同 3.3 的 token 部分;refresh_token 旋转(旧值立即失效)。
Token 体系:access_token 有效期 2 小时,refresh_token 30 天(Redis 白名单 Set,支持多端同时在线)。服务端按用户维护令牌纪元
auth:epoch:{user_id},签发时写入 Token 的ep声明,每次请求都校验:修改/重置密码、后台重置密码(11.34)后纪元递增并清空 refresh 白名单,该用户所有旧 Token(含未过期的 access)立即失效。
3.6 退出登录 POST /auth/logout(需登录)
无参数。响应 { "code": 0 }。服务端将 access_token 的 jti 加入黑名单并删除 refresh 白名单。
3.7 找回密码 POST /auth/password/reset
通过已验证的手机号/邮箱 + 验证码重置密码。重置成功后该用户所有旧 Token(access + refresh)立即失效,需重新登录。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | 是 | phone 或 email |
| phone | string | type=phone 时必填 | 手机号 |
| string | type=email 时必填 | 邮箱 | |
| code | string | 是 | 验证码(scene=reset) |
| new_password | string | 是 | 新密码,8-32 位,须含字母和数字 |
请求示例
{ "type": "phone", "phone": "13800138000", "code": "825314", "new_password": "newabc123" }
响应:{ "code": 0, "message": "密码已重置,请重新登录" }
错误码:1004 验证码错误或已过期;1001 账号不存在。
4. 用户模块
4.1 获取个人信息 GET /users/me(需登录)
响应示例
{
"code": 0,
"data": {
"user_id": 100023,
"phone": "138****8000",
"email": null,
"nickname": "小明",
"avatar_url": "https://cdn.example.com/avatar/100023.jpg",
"bio": "",
"is_member": true,
"member_plan": "monthly",
"member_expire_at": "2026-11-13 12:00:00",
"points": 86
}
}
4.2 修改资料 PUT /users/me(需登录)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nickname | string | 否 | 2-20 字 |
| bio | string | 否 | ≤200 字 |
| gender | int | 否 | 0/1/2 |
响应返回更新后的完整用户对象(同 4.1)。
4.3 上传头像 POST /users/me/avatar(需登录)
multipart/form-data,字段名file,jpg/png,≤ 5MB- 响应:
{ "code": 0, "data": { "avatar_url": "https://..." } }
4.4 钱包信息 GET /users/me/wallet(需登录)
响应示例
{
"code": 0,
"data": {
"points": 86,
"total_recharge": 100,
"total_earned": 6,
"total_consumed": 20,
"comment_reward_progress": { "current": 4, "target": 10, "today_rewarded": 1, "daily_limit": 5 }
}
}
4.5 积分明细 GET /users/me/points/records(需登录)
查询参数:page、page_size、biz_type(可选:1充值 2观看 3评论奖励 4会员 5赠送 6调整 7扣回)
响应示例
{
"code": 0,
"data": {
"total": 35,
"list": [
{ "id": 9001, "change_amount": -1, "balance_after": 86, "biz_type": 2, "remark": "观看视频", "created_at": "2026-10-14 12:01:00" },
{ "id": 8990, "change_amount": 1, "balance_after": 87, "biz_type": 3, "remark": "评论奖励", "created_at": "2026-10-14 11:30:00" }
]
}
}
4.6 注销账号 POST /users/me/deactivate(需登录)
用户主动注销。提交后进入 7 天冻结期:期间再次登录即自动撤销注销;到期后账号匿名化(手机号/邮箱置空释放、昵称头像清空、作品全部下架、钱包余额清零作废),Token 立即失效。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| password | string | 是 | 当前登录密码(二次确认) |
// 响应
{ "code": 0, "data": { "deactivate_at": "2026-10-22 12:00:00", "revoke_before": "2026-10-22 12:00:00" } }
说明:冻结期内登录返回错误码 1009 并附带 can_revoke=true,App 弹窗询问是否撤销注销。
4.7 用户公开主页 GET /users/{user_id}(游客可)
{
"code": 0,
"data": {
"user_id": 100023,
"nickname": "小明",
"avatar_url": "https://...",
"bio": "",
"video_count": 12,
"total_likes": 3456
}
}
4.8 他人作品列表 GET /users/{user_id}/videos(游客可)
仅返回"已发布"状态作品。
查询参数:page、page_size
响应:list 结构同 Feed 单条,含 total。
5. 视频模块
5.1 推荐视频流 GET /videos/feed(游客可)
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | string | 否 | 上一页返回的 next_cursor |
| limit | int | 否 | 默认 10,最大 20 |
| category_id | int | 否 | 分类筛选 |
| type | string | 否 | 策略:recommend(默认,个性化)/ latest(最新发布)/ hot(热度)/ liked(口碑,按点赞量倒序)/ viewed(热播,按播放量倒序) |
响应示例
{
"code": 0,
"data": {
"next_cursor": "eyJwIjoxNzYwfQ==",
"list": [
{
"video_id": 88001,
"title": "海边日落",
"cover_url": "https://cdn.example.com/hls/88001/cover.jpg",
"video_url": "https://cdn.example.com/hls/88001/index.m3u8",
"duration": 32,
"author": { "user_id": 100023, "nickname": "小明", "avatar_url": "https://..." },
"view_count": 12034,
"like_count": 456,
"comment_count": 78,
"favorite_count": 90,
"tags": ["日落", "海边"],
"is_liked": false,
"is_favorited": false
}
]
}
}
is_liked/is_favorited仅登录用户返回真实值,游客恒为 false。recommend 策略:以"当天日期 + 用户/设备"为随机种子每日重排(同一用户每天的推荐顺序不同、同一天内多次刷新顺序稳定);当日已观看的视频尽量不再出现(候选不足时放开过滤兜底);个性化基于近 7 天观看/点赞/收藏视频的标签偏好加权,游客及新用户退化为热度排序。
游标格式(均为 base64url 编码的 JSON,客户端无需解析,原样回传即可):
liked/viewed:「值,id」双键游标{"n": 末条点赞数/播放数, "i": 末条 video_id},按"值 DESC, id DESC"严格翻页,点赞/播放数变化不影响已翻过的页latest:{"p": 末条发布时间戳, "i": 末条 video_id}recommend/hot:当日种子下的偏移游标
5.2 视频详情 GET /videos/{video_id}(游客可)
响应字段同 Feed 单条,另含 description、category、published_at。
登录用户额外返回 my_position(本人上次观看进度,秒;无记录为 0),用于断点续播。
错误码:2003 视频不存在或未发布。
5.3 观看上报(计费接口)POST /videos/{video_id}/watch(游客可)
开始播放时调用。客户端本地按 video_id+日期 去重,同日同视频只上报一次。
请求参数(身份取自 Token 或 X-Device-ID)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| position | int | 否 | 当前播放进度(秒),服务端记录用于续播 |
响应示例(扣费场景)
{
"code": 0,
"data": {
"cost_type": 1,
"cost_points": 1,
"remaining_points": 86,
"free_remaining_today": 0
}
}
cost_type 说明
| 值 | 含义 | cost_points |
|---|---|---|
| 0 | 占用今日免费额度 | 0 |
| 1 | 积分扣减 | 1 |
| 2 | 会员免费 | 0 |
| 3 | 重复观看/本人作品,不计费 | 0 |
错误响应(游客超限)
{ "code": 2002, "message": "今日免费观看次数已用完,登录后继续观看", "data": { "need_login": true } }
错误响应(积分不足)
{ "code": 2001, "message": "积分不足,请充值或开通会员", "data": { "points": 0 } }
5.4 完整观看上报 POST /videos/{video_id}/watch/complete(游客可)
播放进度 ≥95% 或自然播完时调用,用于创作者收益计数(每 1000 次完整观看 = 1 资产)。服务端校验 watch_duration 合理性(不得明显低于视频时长),同一用户/设备同一视频每日仅首次有效。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| watch_duration | int | 是 | 本次实际观看时长(秒) |
// 请求
{ "watch_duration": 31 }
// 响应
{ "code": 0, "data": { "credited": true } }
credited=false:今日已计数、观看的是本人作品、或时长校验未通过。
5.5 获取上传凭证 POST /videos/upload/token(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file_name | string | 是 | 原始文件名 |
| file_size | int | 是 | 字节数,≤ 配置上限 |
| upload_mode | string | 否 | raw(默认,服务端转码) / hls(已转码的m3u8包) |
响应示例
{
"code": 0,
"data": {
"upload_type": "oss_sts",
"sts": { "access_key_id": "STS.xxx", "access_key_secret": "xxx", "security_token": "xxx", "expiration": "2026-10-14T13:00:00Z" },
"object_key": "upload/tmp/20261014/uuid.mp4",
"bucket": "video-upload",
"endpoint": "https://oss-cn-hangzhou.aliyuncs.com"
}
}
小部署环境可返回
upload_type: "server",客户端改用POST /videos/upload/file(multipart)经服务端中转。
5.6 发布视频 POST /videos(需登录)
上传完成后调用,创建视频记录并进入转码/审核流程。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| object_key | string | 是 | 5.4 返回的 object_key(raw 模式) |
| m3u8_url | string | hls 模式必填 | 已上传 m3u8 的地址 |
| title | string | 是 | 1-100 字 |
| description | string | 否 | ≤500 字 |
| category_id | int | 是 | 分类 ID |
| duration | int | hls 模式必填 | 时长(秒) |
| tags | array[string] | 否 | 标签,0 |
请求示例
{ "object_key": "upload/tmp/20261014/uuid.mp4", "title": "海边日落", "description": "拍摄于青岛", "category_id": 3, "tags": ["日落", "海边"] }
响应示例
{
"code": 0,
"data": { "video_id": 88001, "status": 0, "status_text": "转码中", "is_priority": true }
}
status:0转码中 1待审核 2已发布 3拒绝 4下架 5转码失败。会员 is_priority=true 进入优先转码队列。
5.7 我的作品 GET /users/me/videos(需登录)
查询参数:page、page_size、status(可选)。
响应列表项同 Feed 单条,另含 status、status_text、reject_reason。
5.8 分类列表 GET /videos/categories
{ "code": 0, "data": [ { "category_id": 1, "name": "生活" }, { "category_id": 2, "name": "美食" } ] }
5.9 标签视频列表 GET /tags/{tag_name}/videos(游客可)
播放页点击标签后跳转页面调用本接口。
路径参数:tag_name — 标签名(URL 编码)
查询参数:page、page_size、sort(hot 默认 / latest)
响应示例
{
"code": 0,
"data": {
"tag": "日落",
"total": 236,
"list": [
{
"video_id": 88001,
"title": "海边日落",
"tags": ["日落", "海边"],
"cover_url": "https://cdn.example.com/hls/88001/cover.jpg",
"video_url": "https://cdn.example.com/hls/88001/index.m3u8",
"author": { "user_id": 100023, "nickname": "小明", "avatar_url": "https://..." },
"view_count": 12034, "like_count": 456, "comment_count": 78, "favorite_count": 90
}
]
}
}
5.10 视频搜索 GET /videos/search(游客可)
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| keyword | string | 是 | 关键词,1-30 字;命中敏感词返回空结果 |
| sort | string | 否 | hot(默认)/ latest |
| page | int | 否 | 页码 |
| page_size | int | 否 | 默认 20,最大 50 |
响应:list 结构同 Feed 单条,另含 total;搜索行为计入热搜统计(Redis search:hot)。
5.11 热搜榜 GET /search/hot(游客可)
{ "code": 0, "data": { "words": ["日落", "美食教程", "猫咪"] } }
返回 Top 10 热搜词,来源于 Redis ZSet search:hot(搜索计数,定时衰减)。
5.12 编辑视频 PUT /videos/{video_id}(需登录,仅作者)
请求参数(均可选,传哪个改哪个)
| 参数 | 类型 | 说明 |
|---|---|---|
| title | string | 1-100 字 |
| description | string | ≤500 字 |
| category_id | int | 分类 ID |
| tags | array[string] | 标签,0 |
响应:{ "code": 0, "data": { "video_id": 88001 } }
错误码:2107 无权操作(非作者本人);2003 视频不存在。
5.13 删除视频 DELETE /videos/{video_id}(需登录,仅作者)
软删除,立即下架不可见;互动计数保留用于后台审计。
响应:{ "code": 0 }
错误码:2107 无权操作(非作者本人);2003 视频不存在。
5.14 系列详情 GET /videos/series/{series_id}(游客可)
返回系列信息 + 全部已发布集数(按 episode_no 升序),用于短剧播放页选集。
响应示例
{
"code": 0,
"data": {
"series": { "id": 12, "title": "霸道总裁", "cover_url": "https://...", "description": "...", "total_episodes": 80 },
"episodes": [
{ "video_id": 88001, "episode_no": 1, "title": "第1集", "cover_url": "https://...", "duration": 95, "video_url": "https://.../index.m3u8" }
]
}
}
错误码:1006 系列不存在或已隐藏。
5.15 当前视频所属系列 GET /videos/{video_id}/series(游客可)
用于 PlayerScreen 系列抽屉入口。视频不属于任何系列(或未发布)时返回 { "has_series": false };否则返回系列信息、全部集数(字段同 5.14)及 current_episode_no / prev_video_id / next_video_id(无上下集时为 null)。
6. 互动模块
6.1 点赞/取消 POST /videos/{video_id}/like(需登录)
无 body,切换式接口(已点赞则取消)。
响应示例
{ "code": 0, "data": { "is_liked": true, "like_count": 457 } }
6.2 收藏/取消 POST /videos/{video_id}/favorite(需登录)
{ "code": 0, "data": { "is_favorited": true, "favorite_count": 91 } }
6.3 评论列表 GET /videos/{video_id}/comments(游客可)
查询参数:page、page_size、parent_id(查二级回复时传父评论 ID)
响应示例
{
"code": 0,
"data": {
"total": 78,
"list": [
{
"comment_id": 55001,
"user": { "user_id": 100030, "nickname": "阿花", "avatar_url": "https://..." },
"content": "拍得真好",
"like_count": 12,
"reply_count": 3,
"created_at": "2026-10-14 10:00:00"
}
]
}
}
6.4 发表评论 POST /videos/{video_id}/comments(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| content | string | 是 | 1-500 字;≥5 字才计入积分奖励进度 |
| parent_id | int | 否 | 回复某评论时传其 ID |
| reply_to_user_id | int | 否 | 被回复人 ID |
请求示例
{ "content": "这个日落太美了,求定位!" }
响应示例
{
"code": 0,
"data": {
"comment_id": 55010,
"reward_progress": { "current": 5, "target": 10, "rewarded_this_time": false }
}
}
当 current 满 10 时服务端自动发放 1 积分并清零进度,此时返回 rewarded_this_time: true, reward_points: 1。
6.5 删除评论 DELETE /comments/{comment_id}(需登录)
本人评论或本人视频下的评论可删。已计入奖励进度的评论删除时进度回退(奖励已发的扣回)。
响应:{ "code": 0, "data": { "reward_progress": { "current": 4, "target": 10 } } }
6.6 我的收藏 GET /users/me/favorites(需登录)
分页列表,结构同 Feed 单条。
6.7 观看历史 GET /users/me/history(需登录)
分页列表,每项:video(同 Feed 单条)+ watched_at + cost_type。
7. 会员模块
7.1 套餐列表 GET /membership/plans(游客可)
响应示例(价格来自服务端配置,前端不硬编码)
{
"code": 0,
"data": [
{ "plan_code": "trial", "name": "体验会员", "days": 1, "points": 5, "enabled": true, "desc": "1天体验,活动同享" },
{ "plan_code": "monthly", "name": "月卡", "days": 30, "points": 300, "enabled": true, "desc": "30天无限观看" },
{ "plan_code": "yearly", "name": "年卡", "days": 365, "points": 3650, "enabled": true, "desc": "365天无限观看" },
{ "plan_code": "lifetime", "name": "终身卡", "days": 0, "points": 10000, "enabled": true, "desc": "永久无限观看" }
],
"benefits": ["无限观看视频", "优先上传(转码/审核优先)"]
}
7.2 我的会员 GET /membership/me(需登录)
{
"code": 0,
"data": {
"is_member": true,
"is_lifetime": false,
"current_plan": "monthly",
"plan_name": "月卡",
"expire_at": "2026-11-13 12:00:00",
"remaining_days": 30,
"history": [
{ "order_no": "M20261014120001", "plan_name": "月卡", "points_cost": 300, "start_at": "2026-10-14 12:00:00", "end_at": "2026-11-13 12:00:00", "source": 1 }
]
}
}
7.3 积分开通会员 POST /membership/redeem(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| plan_code | string | 是 | trial/monthly/yearly/lifetime |
请求示例
{ "plan_code": "monthly" }
响应示例
{
"code": 0,
"message": "ok",
"data": {
"order_no": "M20261014120001",
"plan_name": "月卡",
"points_cost": 300,
"remaining_points": 86,
"expire_at": "2026-11-13 12:00:00"
}
}
规则:有效期内重复开通时长叠加;终身卡用户调用返回错误码 2004;积分不足返回 2001。
8. 支付模块
8.1 充值套餐 GET /payments/packages(需登录)
{
"code": 0,
"data": {
"packages": [
{ "id": 1, "amount_yuan": 10, "points": 100, "bonus": 0 },
{ "id": 2, "amount_yuan": 30, "points": 300, "bonus": 0 },
{ "id": 3, "amount_yuan": 100, "points": 1000, "bonus": 50 },
{ "id": 4, "amount_yuan": 200, "points": 2000, "bonus": 150 }
],
"custom": { "enabled": true, "min_yuan": 1, "max_yuan": 10000, "points_per_yuan": 10 },
"pay_methods": [
{ "method": 1, "name": "支付宝" },
{ "method": 2, "name": "微信支付" },
{ "method": 3, "name": "USDT (TRC20)" }
],
"usdt_rate": 7.2
}
}
充值档位由管理后台实时维护(增删改/上下架/排序),前端不硬编码;
points = amount_yuan × points_per_yuan,自定义金额同样按此汇率换算。
8.2 创建充值订单 POST /payments/recharge(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| amount_yuan | int | 是 | 充值金额(元),须为后台已上架档位,或 custom.enabled=true 时的自定义金额 |
| pay_method | int | 是 | 1支付宝 2微信 3USDT |
请求示例
{ "amount_yuan": 30, "pay_method": 1 }
响应示例(支付宝)
{
"code": 0,
"data": {
"order_no": "R20261014123000001",
"pay_method": 1,
"amount_yuan": 30,
"points": 300,
"expire_at": "2026-10-14 13:00:00",
"pay_params": { "order_string": "alipay_sdk=alipay-sdk-php-dynamic&app_id=..." }
}
}
响应示例(微信):pay_params 含 appid/partnerid/prepayid/package/noncestr/timestamp/sign,供 App SDK 调起。
响应示例(USDT)
{
"code": 0,
"data": {
"order_no": "R20261014123000002",
"pay_method": 3,
"amount_yuan": 30,
"points": 300,
"usdt_rate": 7.2,
"usdt_amount": "4.167",
"receive_address": "TXYz...abc",
"network": "TRC20",
"expire_at": "2026-10-14 13:00:00"
}
}
USDT 金额含随机尾差用于订单匹配;用户须按显示金额精确转账,满 19 个区块确认后自动到账。
8.3 查询订单 GET /payments/orders/{order_no}(需登录)
App 调起支付后每 2 秒轮询,直至 status != 0 或超过 30 次。
响应示例
{
"code": 0,
"data": {
"order_no": "R20261014123000001",
"status": 1,
"status_text": "已支付",
"points": 300,
"paid_at": "2026-10-14 12:35:20",
"wallet_points": 386
}
}
status:0待支付 1已支付 2已关闭 3已退款。
8.4 取消订单 POST /payments/orders/{order_no}/cancel(需登录)
仅"待支付"可取消。响应 { "code": 0 }。
8.5 支付宝回调 POST /callbacks/alipay(平台 → 服务端)
- Content-Type:
application/x-www-form-urlencoded - 服务端处理:RSA2 验签 → 校验
out_trade_no/total_amount→ 幂等入账 → 返回纯文本success - App 不直接调用本接口
8.6 微信支付回调 POST /callbacks/wechat(平台 → 服务端)
- V3 回调:验签(
Wechatpay-Signature头)→ AES-GCM 解密resource→ 幂等入账 → 返回{ "code": "SUCCESS" }
8.7 USDT 到账说明
USDT 无支付平台回调,由服务端每 15 秒轮询 TronGrid:
匹配条件 = 收款地址一致 + 金额(含尾差)精确相等 + 转账时间在订单有效期内 + 确认数 ≥ 19。
匹配成功即入账(tx_hash 写入 third_trade_no,唯一索引保证幂等);超时未匹配订单自动关闭。
9. 激励模块
资产体系:10 资产 = 1 元,资产存放于资产钱包,可申请提现(后台人工审核打款)。推荐奖励与充值返利仅在推荐人为会员时发放(发放时点校验会员身份)。
9.1 我的邀请 GET /referral/me(需登录)
响应示例
{
"code": 0,
"data": {
"invite_code": "K7X2M9",
"invite_url": "https://app.example.com/r/K7X2M9",
"eligible": true,
"total_invitees": 12,
"activated_count": 8,
"reward_points_total": 80,
"rebate_assets_total": 150.0
}
}
eligible:当前是否会员(false 时被推荐人仍可绑定,但不产生奖励)
9.2 绑定邀请码 POST /referral/bind(需登录)
注册时未填邀请码的用户,注册后 24 小时内可补绑一次(每人仅能绑定一次)。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| invite_code | string | 是 | 推荐人邀请码 |
// 请求
{ "invite_code": "K7X2M9" }
// 响应
{ "code": 0, "data": { "bound": true, "status": 0, "status_text": "待激活" } }
错误码:2101(邀请码无效 / 已绑定过 / 绑定自己 / 同设备已注册其他账号)
被推荐人激活(72h 内累计观看 ≥3 个视频且次日有登录)后,推荐人获得 10 积分(可配置,不限量)。被推荐人此后每次充值成功,推荐人获得"充值积分 × 5%"的资产(不限量)。
9.3 资产钱包 GET /assets/me(需登录)
响应示例
{
"code": 0,
"data": {
"assets": 236.5,
"assets_value_yuan": 23.65,
"total_earned": 400.0,
"total_withdrawn": 163.5,
"min_withdraw_assets": 100,
"has_pending_withdraw": false
}
}
9.4 资产流水 GET /assets/records(需登录)
查询参数:page、page_size、biz_type(可选:1充值返利 2完整观看收益 3点赞收益 4提现 5提现退回 6返利扣回 7后台调整)
响应示例
{
"code": 0,
"data": {
"total": 21,
"list": [
{ "id": 301, "change_amount": 1.0, "balance_after": 236.5, "biz_type": 2, "remark": "视频完整观看收益(视频88001)", "created_at": "2026-10-14 15:00:00" },
{ "id": 300, "change_amount": 15.0, "balance_after": 235.5, "biz_type": 1, "remark": "推荐用户充值返利", "created_at": "2026-10-14 14:20:00" }
]
}
}
9.5 申请提现 POST /assets/withdraw(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assets | number | 是 | 提现资产数,≥100(可配置),按 10 资产 = 1 元折算 |
| channel | int | 是 | 1支付宝 2微信 3USDT |
| account | string | 是 | 收款账号(支付宝账号/微信号/USDT 地址) |
// 请求
{ "assets": 150, "channel": 1, "account": "user@example.com" }
// 响应
{ "code": 0, "data": { "withdraw_no": "W20261014153000001", "assets": 150.0, "amount_yuan": 15.0, "status": 0, "status_text": "待审核" } }
错误码:2102 资产余额不足;2103 低于最低提现额度;2104 已有审核中的提现申请。
提交即冻结扣减资产,后台人工审核后打款;审核拒绝资产自动退回资产钱包。
9.6 提现记录 GET /assets/withdraw/records(需登录)
响应示例
{
"code": 0,
"data": {
"total": 2,
"list": [
{ "withdraw_no": "W20261014153000001", "assets": 150.0, "amount_yuan": 15.0, "channel": 1, "status": 0, "status_text": "待审核", "created_at": "2026-10-14 15:30:00" }
]
}
}
9.7 推广点击埋点 POST /invite/click(无需登录)
H5 推广落地页(9.9)打开时自动调用,记录「邀请码 + IP + UA」用于后续归因。同 IP+code 60 秒内重复上报自动去重。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 是 | 推广链接中的邀请码(8 位,自动转大写) |
// 请求
{ "code": "K7X2M9AB" }
// 响应
{ "code": 0, "data": { "recorded": true } }
IP 取自
X-Real-IP头(Nginx 反代透传)或直连来源;点击记录存 Redis 24h 有效。
9.8 首启归因匹配 POST /invite/match(无需登录)
App 首次启动且剪贴板无分享口令时调用一次(每安装仅一次)。服务端按 IP 取最近 24h 内最近点击的邀请码,命中则按 device_id 缓存 7 天;用户注册时自动消费该缓存完成推荐绑定(客户端无需也无法回传)。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | string | 是 | 设备指纹(与 X-Device-ID 一致) |
// 请求
{ "device_id": "a1b2c3d4-..." }
// 响应(未命中)
{ "code": 0, "data": { "matched": false } }
// 响应(命中)
{ "code": 0, "data": { "matched": true, "invite_code": "K7X2M9AB" } }
命中后重复调用直接返回缓存结果(幂等);注册绑定优先级:显式 invite_code(口令/手填)> 本接口归因缓存。
9.9 H5 推广落地页 GET /r/{code}(浏览器访问,HTML)
分享推广链接指向的落地页(根路径,非 /api/v1 前缀),返回 HTML:
- 页面展示邀请人昵称、"复制邀请口令"按钮(口令格式
#短视频邀请码{code}#,供被邀请人首启剪贴板解析) - system_configs
app.download_url已配置时展示"下载 APP"按钮 - 页面加载即自动调用 9.7 完成点击埋点
无效邀请码正常渲染通用页面(不报错),保证分享链接永可用。
10. 通用与消息模块
10.1 版本检查 GET /app/version(游客可)
App 启动时调用,检查版本更新与公告。
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| platform | string | 是 | ios / android |
| version_code | int | 是 | 当前 App 版本号 |
响应示例
{
"code": 0,
"data": {
"latest_version": "1.2.0",
"latest_version_code": 12,
"force_update": false,
"update_url": "https://app.example.com/download",
"notice": "新版本优化了播放体验"
}
}
force_update=true 时 App 弹强制更新弹窗(不可跳过)。
10.2 通知列表 GET /notifications(需登录)
查询参数:type(可选:1审核结果 2提现进度 3系统公告 4评论回复)、page、page_size
响应示例
{
"code": 0,
"data": {
"total": 3,
"list": [
{ "id": 701, "type": 1, "title": "视频审核通过", "content": "你发布的《海边日落》已通过审核", "biz_id": "88001", "is_read": false, "created_at": "2026-10-14 15:00:00" }
]
}
}
10.3 未读数 GET /notifications/unread_count(需登录)
{ "code": 0, "data": { "unread": 3 } }
App 我的页消息入口红点依赖本接口(直接读 Redis notif:unread:{user_id})。
10.4 标记已读 POST /notifications/read(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ids | array[int] | 否 | 通知 ID 数组;与 all 二选一 |
| all | bool | 否 | true 表示全部标记已读 |
响应:{ "code": 0 }
10.5 提交举报 POST /reports(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| target_type | int | 是 | 1视频 2评论 |
| target_id | int | 是 | 举报对象 ID |
| reason_type | int | 是 | 1色情低俗 2暴力血腥 3侵权 4广告营销 5其他 |
| remark | string | 否 | 补充说明,≤200 字 |
// 请求
{ "target_type": 1, "target_id": 88001, "reason_type": 1, "remark": "包含不适内容" }
// 响应
{ "code": 0, "message": "已收到举报,我们会尽快处理" }
错误码:2106 请勿重复举报(同一用户对同一对象仅一次有效举报,唯一索引 uk_user_target 保证);限流 10 次/天。
10.6 m3u8 播放列表代理 GET /m3u8/proxy(游客可)
采集内容源站的 m3u8 内 TS 链接带时效签名,需经服务端每次回源拉取新鲜播放列表;TS 分片不经过本服务器,由客户端按播放列表中的源站地址直连下载。
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | 源站播放列表的相对资源路径(防 SSRF:仅允许字母数字及 /._-,禁止 ..),1-300 字 |
响应:非统一 JSON 包装,直接返回 m3u8 文本(Content-Type: application/vnd.apple.mpegurl,Cache-Control: no-cache,Access-Control-Allow-Origin: *)。
错误码:1001 非法路径;1006 播放列表获取失败(源站非 200 或内容非 m3u8)。
11. 管理后台接口
通用约定:
- 前缀
/api/v1/admin,统一响应结构同 App 接口 - 认证:
Authorization: Bearer <admin_token>(Token payloadtype="admin",有效期 12h,与 App 用户体系互不相通) - 角色:
super(全部)/reviewer(仅审核)/operator(套餐、活动、看板、采集源/采集同步、系列/分类/标签查询);越权返回 4001 - 所有写操作记录操作日志;标注【敏感】的接口
reason必填,缺失返回 4002
11.1 管理员登录 POST /admin/auth/login
// 请求
{ "username": "admin", "password": "xxxx" }
// 响应
{ "code": 0, "data": { "admin_token": "eyJ...", "expires_in": 43200, "admin": { "id": 1, "name": "超管", "role": "super" } } }
11.2 仪表盘 GET /admin/dashboard
{
"code": 0,
"data": {
"today": { "dau": 1520, "new_users": 86, "recharge_yuan": 4600, "points_issued": 46000, "points_consumed": 12300, "views": 30211 },
"pending_review_count": 17,
"total": { "users": 50210, "videos": 8200, "recharge_yuan": 128000 }
}
}
11.3 待审核视频列表 GET /admin/videos/pending
查询参数:page、page_size。响应列表项含视频全部字段(含 video_url 供在线预览)+ 作者信息。
11.4 审核视频 POST /admin/videos/{video_id}/review
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | approve / reject |
| reason | string | reject 时必填 | 拒绝原因(回显给作者) |
// 请求
{ "action": "approve" }
// 响应
{ "code": 0, "data": { "video_id": 88001, "status": 2, "status_text": "已发布" } }
11.5 下架视频 POST /admin/videos/{video_id}/offline【敏感】
{ "reason": "内容违规" }
11.6 用户列表 GET /admin/users
查询参数:keyword(ID/手机号/邮箱)、status、page、page_size。
响应列表项:用户基础信息 + points + is_member + video_count。
11.7 用户详情 GET /admin/users/{user_id}
响应:用户信息 + 钱包 + 会员状态 + 近 10 条积分流水 + 作品数/获赞数。
11.8 封禁/解封用户 PUT /admin/users/{user_id}/status【敏感】
{ "status": 2, "reason": "发布违规内容" }
status:1 正常 / 2 封禁。封禁后该用户 Token 立即失效(Redis 白名单剔除)。
11.9 积分调整 POST /admin/points/adjust【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int | 是 | 目标用户 |
| change_amount | int | 是 | 正=加,负=减 |
| reason | string | 是 | 调整原因 |
// 响应
{ "code": 0, "data": { "user_id": 100023, "change_amount": 100, "balance_after": 486 } }
11.10 积分流水查询 GET /admin/points/records
查询参数:user_id、biz_type、page、page_size。响应结构同 App 端积分明细。
11.11 充值订单查询 GET /admin/orders
查询参数:order_no、user_id、pay_method、status、start_date、end_date、page。
响应列表项:订单全字段(含 usdt_amount / third_trade_no)。
11.12 人工补单 POST /admin/orders/{order_no}/resettle【敏感】
用于"用户已付款但回调未到账"的异常单。核实支付平台/链上确已收款后调用,走与回调相同的幂等入账流程。
{ "reason": "微信回调丢失,商户后台已核实收款", "third_trade_no": "4200001234567890" }
11.13 充值套餐列表 GET /admin/packages
返回全部套餐(含下架),字段同 App 端 8.1 的 packages 项 + status、sort。
11.14 新增套餐 POST /admin/packages
// 请求(points 由服务端按汇率计算,也可显式传入覆盖)
{ "amount_yuan": 50, "bonus_points": 20, "sort": 10 }
// 响应
{ "code": 0, "data": { "id": 5, "amount_yuan": 50, "points": 500, "bonus_points": 20, "sort": 10, "status": 1 } }
11.15 修改套餐 PUT /admin/packages/{package_id}
可改 amount_yuan / bonus_points / sort / status,实时生效。
11.16 删除套餐 DELETE /admin/packages/{package_id}
物理删除或下架(存在历史订单引用的套餐仅允许下架)。
11.17 赠送会员/积分 POST /admin/gift【敏感】
// 请求:赠送体验会员
{ "user_ids": [100023, 100024], "gift_type": "membership", "plan_code": "trial", "reason": "国庆活动" }
// 请求:赠送积分
{ "user_ids": [100023], "gift_type": "points", "points": 100, "reason": "客服补偿" }
// 响应
{ "code": 0, "data": { "success": 2, "failed": 0 } }
赠送会员写入 membership_orders(source=2,points_cost=0);赠送积分写积分流水(biz_type=5)。
11.18 操作日志 GET /admin/logs
查询参数:admin_id、action、page。仅 super 可查。
11.19 提现列表 GET /admin/withdrawals
查询参数:status、user_id、page、page_size。
响应列表项:提现单全字段 + 用户昵称。
11.20 提现审核 POST /admin/withdrawals/{withdraw_no}/review【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | approve(已完成线下打款,确认)/ reject(拒绝并退回资产) |
| reason | string | reject 时必填 | 拒绝原因 |
// 请求
{ "action": "reject", "reason": "收款账号信息有误" }
// 响应
{ "code": 0, "data": { "withdraw_no": "W20261014153000001", "status": 2, "refunded_assets": 150.0 } }
11.21 推荐关系列表 GET /admin/referrals
查询参数:inviter_id、status、risk_flag、page、page_size。
响应列表项:推荐关系全字段 + 双方用户昵称。
11.22 推荐风控处理 POST /admin/referrals/{referral_id}/review【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | release(解冻,恢复待激活流程)/ invalid(判无效,奖励不发放) |
| reason | string | 是 | 处理说明 |
{ "action": "invalid", "reason": "同设备批量注册小号" }
11.23 平台配置列表 GET /admin/configs
返回 system_configs 全部键值。
{
"code": 0,
"data": {
"list": [
{ "config_key": "register_gift_trial.enabled", "config_value": "1", "description": "注册赠送体验会员开关(1开/0关)", "updated_at": "2026-10-14 10:00:00" },
{ "config_key": "register_gift_trial.days", "config_value": "1", "description": "注册赠送体验会员天数", "updated_at": "2026-10-14 10:00:00" }
]
}
}
11.24 修改平台配置 PUT /admin/configs/{config_key}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| value | string | 是 | 新配置值 |
// 请求:关闭注册赠送体验会员
{ "value": "0" }
// 响应
{ "code": 0, "data": { "config_key": "register_gift_trial.enabled", "config_value": "0" } }
修改实时生效(服务端配置缓存 60s 自动失效),操作写入 admin_logs。
11.25 视频列表 GET /admin/videos
查询参数:keyword(ID/标题)、status、author_id、page、page_size。
响应列表项:视频全字段 + 作者昵称。
11.26 评论列表 GET /admin/comments
查询参数:video_id、user_id、keyword(评论内容)、page、page_size。
响应列表项:评论全字段 + 用户昵称 + 视频标题。
11.27 删除评论 DELETE /admin/comments/{comment_id}【敏感】
{ "reason": "垃圾广告" }
删除后触发评论奖励回退(已计入进度回退、已发奖励扣回),与作者自删逻辑一致。
11.28 举报列表 GET /admin/reports
查询参数:status、target_type、page、page_size。
响应列表项:举报全字段 + 举报人昵称 + 被举报对象摘要(视频标题/评论内容)。
11.29 举报处理 POST /admin/reports/{report_id}/review【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | offline_video(下架视频)/ delete_comment(删除评论)/ reject(驳回举报) |
| reason | string | 是 | 处理说明 |
// 请求
{ "action": "offline_video", "reason": "核实违规,下架处理" }
// 响应
{ "code": 0, "data": { "report_id": 301, "status": 1, "status_text": "已处理" } }
处理结果通过站内通知(type=1)告知举报人;下架/删除动作复用对应业务流程(含作者通知、评论奖励回退)。
11.30 敏感词列表 GET /admin/sensitive-words
查询参数:keyword、page、page_size。
{ "code": 0, "data": { "total": 120, "list": [ { "id": 1, "word": "违禁词", "created_at": "2026-10-14 10:00:00" } ] } }
11.31 添加敏感词 POST /admin/sensitive-words
// 请求
{ "word": "新违禁词" }
// 响应
{ "code": 0, "data": { "id": 121, "word": "新违禁词" } }
重复添加返回错误码 1001;添加后 Redis 词库缓存(words:sensitive)失效重建,实时生效。
11.32 删除敏感词 DELETE /admin/sensitive-words/{id}
响应 { "code": 0 },同样触发词库缓存重建。
11.33 重置用户密码 PUT /admin/users/{user_id}/password【敏感】(仅 super)
客服场景下由后台直接重置某个 App 用户的登录密码。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| new_password | string | 是 | 新密码,6-100 位(bcrypt 入库,不校验字母数字组合) |
| reason | string | 是 | 操作原因(写入 admin_logs,action=user_password_reset) |
// 请求
{ "new_password": "newpass123", "reason": "用户申诉核实通过" }
// 响应
{ "code": 0 }
重置后该用户全端 Token 立即失效:服务端递增 auth:epoch:{user_id} 并删除 refresh 白名单(机制见 3.5),用户需用新密码重新登录。
错误码:1006 用户不存在;1001 账号已注销不可操作。
11.34 退款登记 POST /admin/orders/{order_no}/refund【敏感】(仅 super)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| reason | string | 是 | 退款原因 |
11.35 修改管理员密码 PUT /admin/auth/password(仅 super)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| old_password | string | 是 | 当前密码 |
| new_password | string | 是 | 新密码,6-100 位 |
响应 { "code": 0 }。
11.36 后台新增视频 POST /admin/videos(仅 super)
两种模式二选一:
- upload_token 模式:先调
POST /admin/videos/upload拿凭证 →POST /admin/videos/upload/file上传 mp4/mov/mkv/avi(multipart,字段file+ querytoken)→ 拿到upload_token后调本接口(服务端自动转码) - video_url 模式:直接填已转码的 m3u8 地址(外站/CDN 资源)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 是 | 1-100 字 |
| description | string | 否 | ≤500 字 |
| category_id | int | 是 | 分类 ID |
| tag_names | array[string] | 否 | 标签 |
| upload_token | string | 模式A必填 | upload/file 返回的凭证(封面可选 cover_upload_token) |
| video_url | string | 模式B必填 | m3u8 地址 |
| cover_url | string | 模式B可选 | 封面 |
| duration | int | 否 | 时长(秒),1-36000 |
| status | int | 否 | 1待审核(默认)/ 2直接发布 |
配套接口:
POST /admin/videos/upload:获取 admin 上传凭证,返回{ upload_url, method, token, expire_seconds: 3600 }POST /admin/videos/upload/file?token=xxx:接收文件落盘 server/uploads,返回{ upload_token, object_key, file_size }(凭证一次性,upload_token 24h 内有效)POST /admin/upload/image:通用图片上传(封面/头像/系列图,jpg/jpeg/png/webp/gif),返回可直接访问的完整 URL{ url, file_size }
11.37 后台编辑视频 PUT /admin/videos/{video_id}(仅 super)
均可选,传哪个改哪个:title(1-100)/ description / cover_url / video_url / category_id / series_id / episode_no(≥1)/ status(0-5)。series_id 显式传 null 表示移出系列(同时清空 episode_no)。响应 { "code": 0, "data": { "video_id": 88001 } }。
11.38 后台删除视频 DELETE /admin/videos/{video_id}(仅 super)
物理删除:先解绑系列,再级联删除标签/点赞/收藏/评论/观看记录/收益/举报等全部关联数据。响应 { "code": 0, "data": { "video_id": 88001, "deleted": true } }。
11.39 系列管理
| 方法 | 路径 | 角色 | 说明 |
|---|---|---|---|
| GET | /admin/series | operator | 系列分页列表(keyword 按标题模糊),含 source_id(采集来源标记,供"同步更新"按钮) |
| POST | /admin/series | super | 新建系列:title(1-100 必填)、cover_url、description、category_id |
| PUT | /admin/series/{series_id} | super | 改 title / cover_url / description / category_id / status(0隐藏 1正常) |
| DELETE | /admin/series/{series_id} | super | 删除系列(集数视频的 series_id 需先解绑) |
| POST | /admin/videos/{video_id}/series | super | 绑定视频到系列:{ "series_id": 12, "episode_no": 3 },自动重算 series.total_episodes(仅计已发布) |
11.40 短剧采集同步(operator)
POST /admin/collection/sync/{series_id}:手动同步单部采集短剧(补充源站新出的集数);非采集内容返回 1006。响应为同步统计{新增集数等},写 admin_logs(action=collection_sync)POST /admin/collection/sync-all:触发内置短剧源增量同步,后台异步执行,立即返回{ "started": true, "pages": 2 }。入参pages(1-20,默认 2)为增量同步的列表页数;已有任务进行中返回 1005
11.41 采集源管理(单视频类,自助添加)
采集源 = "分类名 + 列表页 URL 模板",URL 必须包含 {{page}} 页码占位符;创建/改名时按名称自动建/找分类。
| 方法 | 路径 | 角色 | 说明 |
|---|---|---|---|
| GET | /admin/collection/sources | operator | 全部源列表(id/name/list_url/category_id/status/last_sync_at/created_at) |
| POST | /admin/collection/sources | operator | 新增源:name(1-50)、list_url(须含 {{page}},否则 1001) |
| PUT | /admin/collection/sources/{source_id} | operator | 改 name / list_url / status(0停用 1启用) |
| DELETE | /admin/collection/sources/{source_id} | super | 删除源 |
| POST | /admin/collection/sources/batch | operator | 批量添加:body { "text": "分类名 URL\n..." } 每行一条(URL 可带反引号);返回 created/skipped/failed 清单,新建源自动触发后台采集 |
| POST | /admin/collection/sources/{source_id}/sync | operator | 同步单个源(后台异步):入参 max_pages(0=不限,增量自动提前停止,上限 200);该源同步中返回 1005 |
| POST | /admin/collection/sources/sync-all | operator | 同步全部启用源(后台异步),返回 { "started": [...], "skipped_running": [...] } |
11.42 分类管理
| 方法 | 路径 | 角色 | 说明 |
|---|---|---|---|
| GET | /admin/categories | operator | 全部启用分类(不分页,供下拉框):[{id, name}] |
| GET | /admin/categories/admin | operator | 分页列表(keyword 模糊),含 sort / status / 实时统计的 video_count |
| POST | /admin/categories | super | 新建:name、sort(默认0)、status(默认1);重名返回错误 |
| PUT | /admin/categories/{cid} | super | 改 name / sort / status |
| DELETE | /admin/categories/{cid} | super | 删除;分类下仍有视频时拒绝并提示数量 |
11.43 标签管理
| 方法 | 路径 | 角色 | 说明 |
|---|---|---|---|
| GET | /admin/tags | operator | 分页列表(keyword 模糊,page_size 默认 50 最大 200),video_count 由 video_tags 实时统计 |
| POST | /admin/tags | super | 新建:name(去空格,空名报错);已存在返回错误 |
| PUT | /admin/tags/{tid} | super | 改名 |
| DELETE | /admin/tags/{tid} | super | 删除标签并清理全部视频关联 |
12. App 端关键调用时序
12.1 启动与域名发现
App 启动 → 解析 txt.256kb.top 的 DNS TXT 记录(DoH)
├─ 成功 → 以 TXT 内容作为 API Base URL(写入本地缓存)
└─ 失败/为空 → 计算 md5(yyyyMM) + "_jsnbhh.vip" 作为 Base URL
→ 进入首页拉取 Feed;缓存域名连续请求失败达阈值时重新执行发现流程
12.2 播放计费
App 滑入视频 → 本地查"今日已上报"集合
├─ 已上报 → 直接播放
└─ 未上报 → POST /videos/{id}/watch
├─ code=0 → 记录已上报;若 cost_type=1 弹 Toast"本次消耗 1 积分"
├─ code=2002 → 弹登录引导(游客)
└─ code=2001 → 弹"积分不足"(去充值 / 开通会员)
12.3 充值
选套餐+支付方式 → POST /payments/recharge → 按 pay_method:
支付宝/微信 → 调起 SDK → 返回 App → 轮询 GET /payments/orders/{order_no} → 成功刷新钱包
USDT → 展示金额/地址/二维码+倒计时 → 用户转账 → 轮询订单 → 到账刷新钱包
12.4 开通会员
GET /membership/plans → 选择套餐 → POST /membership/redeem
├─ code=0 → 刷新 /users/me 与会员状态
└─ code=2001 → 跳充值页(带回跳)