# 短视频应用接口文档 - 版本:v1.0 - 日期:2026-10-14 - 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 ` | | X-Device-ID | 是 | 设备唯一标识(游客计费依赖,首启生成 UUID 持久化) | | X-App-Version | 是 | App 版本号(如 1.2.0),用于版本检查与灰度 | | X-Platform | 是 | 平台标识:`ios` / `android` | | X-Request-ID | 建议 | 客户端请求唯一 ID,用于幂等与链路追踪 | ### 1.2 统一响应结构 ```json { "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) | 否 | | 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~90 | 后台管理 | * | /admin/** | 登录、看板、审核、视频/评论管理、用户、积分、订单、补单、套餐、赠送、提现审核、推荐风控、举报处理、敏感词、平台配置、日志,见第 11 章 | 管理员 | --- ## 3. 认证模块 ### 3.1 发送短信验证码 `POST /auth/sms/send` **请求参数** | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | phone | string | 是 | 手机号,11 位 | | scene | string | 是 | 场景:`register` / `login` / `reset` | **请求示例** ```json { "phone": "13800138000", "scene": "register" } ``` **响应示例** ```json { "code": 0, "message": "ok", "data": { "expire_seconds": 300, "retry_after": 60 } } ``` **限制**:同号码 60 秒 1 条,同号码每天 10 条;注册场景下已注册号码返回错误码 1001("该手机号已注册")。 ### 3.2 发送邮箱验证码 `POST /auth/email/send` | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | email | string | 是 | 邮箱地址 | | scene | string | 是 | `register` / `login` / `reset` | 响应同 3.1,`expire_seconds=600`。 ### 3.3 注册 `POST /auth/register` **请求参数** | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | type | string | 是 | `phone` 或 `email` | | phone | string | type=phone 时必填 | 手机号 | | email | string | type=email 时必填 | 邮箱 | | code | string | 是 | 验证码 | | password | string | 是 | 密码,8-32 位,须含字母和数字 | | nickname | string | 否 | 昵称,默认"用户+随机尾号" | | invite_code | string | 否 | 推荐人邀请码(App 解析分享口令自动预填;未填时服务端取首启模糊归因结果,见 9.7~9.9) | **请求示例** ```json { "type": "phone", "phone": "13800138000", "code": "825314", "password": "abc12345", "nickname": "小明" } ``` **响应示例** ```json { "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 | 手机方式必填 | | | email | string | 邮箱方式必填 | | | password | string | 密码方式必填 | | | code | string | 验证码方式必填 | | **请求示例** ```json { "type": "phone_password", "phone": "13800138000", "password": "abc12345" } ``` **响应**:同 3.3。连续失败 5 次锁定 15 分钟(错误码 1005)。 ### 3.5 刷新令牌 `POST /auth/token/refresh` | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | refresh_token | string | 是 | 刷新令牌 | **响应**:同 3.3 的 token 部分;refresh_token 旋转(旧值立即失效)。 ### 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 时必填 | 手机号 | | email | string | type=email 时必填 | 邮箱 | | code | string | 是 | 验证码(scene=`reset`) | | new_password | string | 是 | 新密码,8-32 位,须含字母和数字 | **请求示例** ```json { "type": "phone", "phone": "13800138000", "code": "825314", "new_password": "newabc123" } ``` **响应**:`{ "code": 0, "message": "密码已重置,请重新登录" }` **错误码**:1004 验证码错误或已过期;1001 账号不存在。 --- ## 4. 用户模块 ### 4.1 获取个人信息 `GET /users/me`(需登录) **响应示例** ```json { "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`(需登录) **响应示例** ```json { "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扣回) **响应示例** ```json { "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 | 是 | 当前登录密码(二次确认) | ```json // 响应 { "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}`(游客可) ```json { "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` | **响应示例** ```json { "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 天观看/点赞/收藏视频的标签偏好加权,游客及新用户退化为热度排序。 ### 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 | 否 | 当前播放进度(秒),服务端记录用于续播 | **响应示例(扣费场景)** ```json { "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 | **错误响应(游客超限)** ```json { "code": 2002, "message": "今日免费观看次数已用完,登录后继续观看", "data": { "need_login": true } } ``` **错误响应(积分不足)** ```json { "code": 2001, "message": "积分不足,请充值或开通会员", "data": { "points": 0 } } ``` ### 5.4 完整观看上报 `POST /videos/{video_id}/watch/complete`(游客可) 播放进度 ≥95% 或自然播完时调用,用于创作者收益计数(每 1000 次完整观看 = 1 资产)。服务端校验 `watch_duration` 合理性(不得明显低于视频时长),同一用户/设备同一视频每日仅首次有效。 **请求参数** | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | watch_duration | int | 是 | 本次实际观看时长(秒) | ```json // 请求 { "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包) | **响应示例** ```json { "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~5 个,每个 1~20 字 | **请求示例** ```json { "object_key": "upload/tmp/20261014/uuid.mp4", "title": "海边日落", "description": "拍摄于青岛", "category_id": 3, "tags": ["日落", "海边"] } ``` **响应示例** ```json { "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` ```json { "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`) **响应示例** ```json { "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`(游客可) ```json { "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~5 个,每个 1~20 字 | **响应**:`{ "code": 0, "data": { "video_id": 88001 } }` **错误码**:2107 无权操作(非作者本人);2003 视频不存在。 ### 5.13 删除视频 `DELETE /videos/{video_id}`(需登录,仅作者) 软删除,立即下架不可见;互动计数保留用于后台审计。 **响应**:`{ "code": 0 }` **错误码**:2107 无权操作(非作者本人);2003 视频不存在。 --- ## 6. 互动模块 ### 6.1 点赞/取消 `POST /videos/{video_id}/like`(需登录) 无 body,切换式接口(已点赞则取消)。 **响应示例** ```json { "code": 0, "data": { "is_liked": true, "like_count": 457 } } ``` ### 6.2 收藏/取消 `POST /videos/{video_id}/favorite`(需登录) ```json { "code": 0, "data": { "is_favorited": true, "favorite_count": 91 } } ``` ### 6.3 评论列表 `GET /videos/{video_id}/comments`(游客可) **查询参数**:`page`、`page_size`、`parent_id`(查二级回复时传父评论 ID) **响应示例** ```json { "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 | **请求示例** ```json { "content": "这个日落太美了,求定位!" } ``` **响应示例** ```json { "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`(游客可) **响应示例**(价格来自服务端配置,前端不硬编码) ```json { "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`(需登录) ```json { "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 | **请求示例** ```json { "plan_code": "monthly" } ``` **响应示例** ```json { "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`(需登录) ```json { "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 | **请求示例** ```json { "amount_yuan": 30, "pay_method": 1 } ``` **响应示例(支付宝)** ```json { "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)** ```json { "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 次。 **响应示例** ```json { "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`(需登录) **响应示例** ```json { "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 | 是 | 推荐人邀请码 | ```json // 请求 { "invite_code": "K7X2M9" } // 响应 { "code": 0, "data": { "bound": true, "status": 0, "status_text": "待激活" } } ``` **错误码**:2101(邀请码无效 / 已绑定过 / 绑定自己 / 同设备已注册其他账号) > 被推荐人激活(72h 内累计观看 ≥3 个视频且次日有登录)后,推荐人获得 10 积分(可配置,不限量)。被推荐人此后每次充值成功,推荐人获得"充值积分 × 5%"的资产(不限量)。 ### 9.3 资产钱包 `GET /assets/me`(需登录) **响应示例** ```json { "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后台调整) **响应示例** ```json { "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 地址) | ```json // 请求 { "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`(需登录) **响应示例** ```json { "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 位,自动转大写) | ```json // 请求 { "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 一致) | ```json // 请求 { "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 版本号 | **响应示例** ```json { "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` **响应示例** ```json { "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`(需登录) ```json { "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 字 | ```json // 请求 { "target_type": 1, "target_id": 88001, "reason_type": 1, "remark": "包含不适内容" } // 响应 { "code": 0, "message": "已收到举报,我们会尽快处理" } ``` **错误码**:2106 请勿重复举报(同一用户对同一对象仅一次有效举报,唯一索引 `uk_user_target` 保证);限流 10 次/天。 --- ## 11. 管理后台接口 通用约定: - 前缀 `/api/v1/admin`,统一响应结构同 App 接口 - 认证:`Authorization: Bearer `(Token payload `type="admin"`,有效期 12h,与 App 用户体系互不相通) - 角色:`super`(全部)/ `reviewer`(仅审核)/ `operator`(套餐、活动、看板);越权返回 4001 - 所有写操作记录操作日志;标注【敏感】的接口 `reason` 必填,缺失返回 4002 ### 11.1 管理员登录 `POST /admin/auth/login` ```json // 请求 { "username": "admin", "password": "xxxx" } // 响应 { "code": 0, "data": { "admin_token": "eyJ...", "expires_in": 43200, "admin": { "id": 1, "name": "超管", "role": "super" } } } ``` ### 11.2 仪表盘 `GET /admin/dashboard` ```json { "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 时必填 | 拒绝原因(回显给作者) | ```json // 请求 { "action": "approve" } // 响应 { "code": 0, "data": { "video_id": 88001, "status": 2, "status_text": "已发布" } } ``` ### 11.5 下架视频 `POST /admin/videos/{video_id}/offline`【敏感】 ```json { "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`【敏感】 ```json { "status": 2, "reason": "发布违规内容" } ``` `status`:1 正常 / 2 封禁。封禁后该用户 Token 立即失效(Redis 白名单剔除)。 ### 11.9 积分调整 `POST /admin/points/adjust`【敏感】 | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | user_id | int | 是 | 目标用户 | | change_amount | int | 是 | 正=加,负=减 | | reason | string | 是 | 调整原因 | ```json // 响应 { "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`【敏感】 用于"用户已付款但回调未到账"的异常单。核实支付平台/链上确已收款后调用,走与回调相同的幂等入账流程。 ```json { "reason": "微信回调丢失,商户后台已核实收款", "third_trade_no": "4200001234567890" } ``` ### 11.13 充值套餐列表 `GET /admin/packages` 返回全部套餐(含下架),字段同 App 端 8.1 的 packages 项 + `status`、`sort`。 ### 11.14 新增套餐 `POST /admin/packages` ```json // 请求(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`【敏感】 ```json // 请求:赠送体验会员 { "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 时必填 | 拒绝原因 | ```json // 请求 { "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 | 是 | 处理说明 | ```json { "action": "invalid", "reason": "同设备批量注册小号" } ``` ### 11.23 平台配置列表 `GET /admin/configs` 返回 system_configs 全部键值。 ```json { "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 | 是 | 新配置值 | ```json // 请求:关闭注册赠送体验会员 { "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}`【敏感】 ```json { "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 | 是 | 处理说明 | ```json // 请求 { "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`。 ```json { "code": 0, "data": { "total": 120, "list": [ { "id": 1, "word": "违禁词", "created_at": "2026-10-14 10:00:00" } ] } } ``` ### 11.31 添加敏感词 `POST /admin/sensitive-words` ```json // 请求 { "word": "新违禁词" } // 响应 { "code": 0, "data": { "id": 121, "word": "新违禁词" } } ``` 重复添加返回错误码 1001;添加后 Redis 词库缓存(`words:sensitive`)失效重建,实时生效。 ### 11.32 删除敏感词 `DELETE /admin/sensitive-words/{id}` 响应 `{ "code": 0 }`,同样触发词库缓存重建。 --- ## 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 → 跳充值页(带回跳) ```