# 短视频推荐接口 本文仅提供前端联调需要的接口变更。公共请求头、登录态、签名、加密及错误处理均沿用现有项目。 ## 一、App/H5接口 ### 1. 短视频推荐列表 修改现有接口: ```http GET /api/app/recommend/vid/list?pageNumber=1&pageSize=20 ``` 请求: | 字段 | 类型 | 说明 | |---|---|---| | `pageNumber` | int | 沿用现有传参 | | `pageSize` | int | 固定传20 | 响应: ```json { "vInfos": [], "totalPages": 100, "hasNext": true, "queueVersion": "20260724" } ``` 新增字段: | 字段 | 类型 | 说明 | |---|---|---| | `hasNext` | bool | 是否可以继续加载,以该字段为准 | | `queueVersion` | string | 推荐队列版本,仅用于日志排查 | 前端不上传已看视频ID或offset,不再使用 `totalPages` 判断结束。 短视频分享时,现有接口补传视频ID: ```http POST /api/app/share/output ``` ```json { "content": "分享链接", "videoID": "短视频ID" } ``` `videoID` 用于累计真实分享推荐分;旧客户端不传仍可正常生成分享内容,但不会累计本次分享分。 ### 2. 免费观看次数 修改现有接口: ```http GET /api/app/vid/user/count?vid={videoId} ``` 响应增加: ```json { "isCan": true, "watchCount": 2, "totalWatchCount": 3 } ``` | 字段 | 类型 | 说明 | |---|---|---| | `watchCount` | uint64 | 当前剩余免费观看次数 | | `totalWatchCount` | uint64 | 免费观看总次数,本次新增 | 传或不传 `vid` 时都返回 `totalWatchCount`。 ### 3. 模块配置 修改现有接口: ```http GET /api/app/modules/list ``` 排序项增加: ```json { "val": 2, "name": "热门推荐", "refreshMode": "RANDOM_TOP_N", "randomCandidateN": 30 } ``` 前端只根据 `refreshMode` 判断随机刷新,禁止匹配 `name` 或硬编码 `val`。 枚举: ```text DEFAULT RANDOM_TOP_N ``` 兼容说明:后台历史数据没有 `refreshMode` 时,后端会把稳定排序值 `val=2` 归一为 `RANDOM_TOP_N`;标题即使配置错误也不会影响刷新功能。 ### 4. 亚模块热门随机刷新 新增接口: ```http GET /api/app/vid/module/{subModuleId}/refresh ``` 请求: | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `moduleSort` | int | 是 | 当前排序项的 `val` | | `pageSize` | int | 否 | 最大30 | | `refreshToken` | string | 是 | 每次刷新生成UUID | 响应: ```json { "allVideoInfo": [], "candidateCount": 30, "hasNext": true, "refreshMode": "RANDOM_TOP_N", "refreshToken": "uuid" } ``` 候选池未变化时,同一个 `refreshToken` 重试会得到相同顺序;用户主动再次下拉时 必须生成新的 `refreshToken`。`candidateCount` 是本次实际进入候选池的视频数, 可能小于30。`hasNext` 表示候选池中是否还有本次未返回的视频,即 `candidateCount > allVideoInfo.length`。 ### 5. 亚模块受限视频 搜索结果中的视频增加: ```json { "searchAccessTicket": "short-lived-ticket" } ``` 从搜索进入详情时携带: ```http GET /api/app/vid/info?id={videoId}&searchAccessTicket={ticket} ``` 从搜索进入播放时继续携带 `searchAccessTicket`。非搜索来源不传。 ### 6. 首页更新红点 新增接口: ```http GET /api/app/content/update-markers ``` 响应: ```json { "homeLatestAt": "2026-07-24T08:00:00Z", "todayLatestAt": "2026-07-24T08:00:00Z", "modules": [ { "moduleId": "moduleId", "latestAt": "2026-07-24T08:00:00Z" } ] } ``` 前端在本地保存最后查看时间并判断红点。 ### 7. AI女友V2 入口展示继续读取: ```http GET /api/app/ping/v ``` 当 `data.aiGirlFriend=true` 时展示入口。点击后调用: ```http POST /api/app/aimatev2/url ``` 无需请求体,成功返回: ```json { "url": "https://example.com/ai" } ``` 前端打开 `data.url`。用户关闭页面或返回 App 后,调用: ```http GET /api/app/mine/wallet ``` 后端会在获取 URL 时自动上分,并在查询钱包时先尝试下分;钱包响应结构不变。新版不再调用 `/api/app/aimate/*`,也不再直接使用 `aiMateH5`。 ### 8. 获取付费引导 新增接口: ```http GET /api/app/payment/guide?scene={scene}&videoId={videoId} ``` 场景: ```text HOME_NEW_USER HOME_OLD_USER VIDEO_PREVIEW_END VIDEO_BACK VIP_CENTER VIP_CONTENT_UPDATE ``` 响应: ```json { "show": true, "configId": "configId", "segment": "OLD_NEVER_PAID", "style": "BOTTOM_SHEET", "title": "查看完整影片", "description": "开通会员后可观看", "cover": "https://example.com/cover.jpg", "videoIds": ["videoId"], "productId": "productId", "durationSeconds": 7200, "action": { "type": "VIP_PRODUCT", "value": "productId" } } ``` `show=false` 时不弹。播放5分钟、试看3秒和App活跃3分钟均由前端计时。 用户分层枚举: ```text NEW_NEVER_PAID OLD_NEVER_PAID PAID_UPGRADE MAX_VIP NORMAL UNREGISTERED ``` 未付费用户注册不足 24 小时按 `NEW_NEVER_PAID` 处理,达到 24 小时后按 `OLD_NEVER_PAID` 处理。免费观看次数不会改变该分层;次数用完时只关闭 `HOME_NEW_USER_FREE_TRIAL` 的展示。过期会员按 `OLD_NEVER_PAID` 处理;退款后会员权益已回收时同样按未付费处理。 ### 9. 付费引导展示回执 新增接口: ```http POST /api/app/payment/guide/impression ``` 请求: ```json { "configId": "configId", "scene": "VIP_CONTENT_UPDATE", "videoId": "videoId", "requestId": "uuid" } ``` 只有弹窗实际展示成功后调用。 回执成功后,同一用户、同一 `configId`、同一 `scene` 不再返回该引导。 ### 10. 视频免费试看角标 所有视频列表对象增加: ```json { "showFreeTrialBadge": true, "freeTrialRemaining": 2, "canUseFreeTrial": true } ``` 前端直接根据 `showFreeTrialBadge` 展示角标,不自行组合判断条件。 ### 11. 评论区Banner 新增接口: ```http GET /api/app/banner/list?scene=COMMENT_TOP ``` 响应: ```json { "list": [ { "id": "bannerId", "imageUrl": "https://example.com/banner.gif", "mediaType": "GIF", "linkType": "INTERNAL", "linkValue": "video://detail?id=videoId", "sort": 100 } ] } ``` 枚举: ```text mediaType: IMAGE | GIF linkType: INTERNAL | EXTERNAL | NONE ``` `COMMENT_TOP` 支持配置多条图片或 GIF,按 `sort` 从大到小返回,前端按返回顺序轮播。 未启用或不在有效时间内的配置不会返回;没有有效配置时返回空数组。 ### 12. VIP套餐及A/B 修改现有接口: ```http GET /api/app/vip/product ``` 现有套餐字段保持不变,响应增加实验信息;每个套餐对象增加 `badgeType`、`badgeText`: ```json { "experimentId": "vip-card-202607-v1", "variant": "A", "defaultProductId": "productId", "list": [ { "showType": 2, "position": "vip", "list": [ { "productID": "productId", "productName": "全尊新人卡", "badgeType": "MOST_POPULAR", "badgeText": "最受欢迎" } ] } ], "integralList": [], "daichong": {}, "isNewUser": true } ``` 角标枚举: ```text MOST_POPULAR 最受欢迎 NEW_USER_OFFER 新人特惠 空值或未知值 不展示 ``` 前端只按套餐对象的 `badgeType` 判断是否展示角标,显示内容使用 `badgeText`;不得通过套餐名称、`sort`、数组位置或默认套餐判断。基础配置与 A/B 配置的合并由后端完成,前端不处理配置优先级。前端下单时原样回传 `experimentId` 和 `variant`。实际价格以该接口和下单结果为准。 ### 13. VIP卡片统计事件 新增接口: ```http POST /api/app/analytics/events ``` 请求: ```json { "events": [ { "eventId": "uuid", "eventName": "VIP_PRODUCT_IMPRESSION", "sessionId": "uuid", "occurredAt": "2026-07-24T08:00:00Z", "experimentId": "vip-card-202607-v1", "variant": "A", "productId": "productId" } ] } ``` 事件: ```text VIP_CARD_PAGE_VIEW VIP_PRODUCT_IMPRESSION VIP_CARD_CLOSE_WITHOUT_PURCHASE ``` 曝光必须在UI实际展示后上报。 ### 14. 创建订单 修改现有接口: ```http POST /api/app/mine/topay ``` 新增非必填字段: ```json { "sourcePage": "VIDEO_BOTTOM_SHEET", "sourceRef": "videoId", "videoId": "videoId", "activityId": "activityId", "experimentId": "vip-card-202607-v1", "experimentVariant": "A", "sessionId": "uuid" } ``` 来源枚举: ```text HOME_USER_SEGMENT VIDEO_BOTTOM_BANNER VIDEO_BOTTOM_SHEET VIP_CENTER H5_ACTIVITY UNKNOWN ``` ### 15. 动漫漫画最新列表 修改现有接口: ```http GET /api/app/media/list?pageNumber=1&pageSize=20 ``` 媒体对象增加: ```json { "updateTime": "2026-07-24T08:00:00Z", "latestPublishedAt": "2026-07-24T08:00:00Z" } ``` 前端按后端返回顺序展示,不自行排序。 ## 二、管理后台接口 ### 1. 亚模块配置 修改现有: ```text POST /api/web/admin/module/conf/add POST /api/web/admin/module/conf/edit ``` 增加: ```json { "onlineAt": "2026-07-24T00:00:00Z", "offlineAt": "2026-08-24T00:00:00Z", "excludeLatest": true, "excludeRecommend": false, "searchOnlyWhenInactive": true, "haiJiaoStyle": { "sortRules": [ { "val": 2, "name": "热门推荐", "refreshMode": "RANDOM_TOP_N", "randomCandidateN": 30 } ] } } ``` ### 2. 付费引导配置 ```text GET /api/web/admin/payment-guide/list POST /api/web/admin/payment-guide/add POST /api/web/admin/payment-guide/edit DELETE /api/web/admin/payment-guide/delete?id={id} ``` 新增/编辑使用完整配置对象,编辑时必须带 `id`: ```json { "id": "编辑时必传,新增不传", "scene": "VIDEO_PREVIEW_END", "segments": ["OLD_NEVER_PAID"], "style": "BOTTOM_SHEET", "title": "查看完整影片", "description": "开通会员后可观看", "cover": "https://example.com/cover.jpg", "videoIds": ["videoId"], "productId": "productId", "durationSeconds": 7200, "action": { "type": "VIP_PRODUCT", "value": "productId" }, "enable": true, "sort": 100, "startAt": "2026-07-24T00:00:00Z", "endAt": "2026-08-24T00:00:00Z" } ``` `startAt/endAt` 可不传;编辑时不传表示清空时间限制。 `segments` 传空数组表示所有用户分层。已展示过的配置如果要重新触达用户,应新增 配置生成新的 `configId`,不要直接复用原配置。 ### 3. 评论Banner配置 ```text GET /api/web/admin/banner/list?scene=COMMENT_TOP POST /api/web/admin/banner/add POST /api/web/admin/banner/edit DELETE /api/web/admin/banner/delete?id={id} ``` 新增/编辑使用完整配置对象,编辑时必须带 `id`: ```json { "id": "编辑时必传,新增不传", "scene": "COMMENT_TOP", "imageUrl": "https://example.com/banner.gif", "mediaType": "GIF", "linkType": "INTERNAL", "linkValue": "video://detail?id=videoId", "sort": 100, "enable": true, "startAt": "2026-07-24T00:00:00Z", "endAt": "2026-08-24T00:00:00Z" } ``` `COMMENT_TOP` 支持新增多条配置。每条配置独立设置图片/GIF、内外链、排序、启用状态及 上下架时间;前端按 App 接口返回顺序轮播。 ### 4. VIP卡片实验 ```text GET /api/web/admin/vip-card-experiment/current POST /api/web/admin/vip-card-experiment/publish POST /api/web/admin/vip-card-experiment/disable GET /api/web/admin/vip-card-experiment/statistics?experimentId={id} ``` 发布请求中的每个变体增加套餐角标配置: ```json { "variantA": { "defaultProductId": "productId", "productIds": { "1": "第1张卡片的productId", "2": "第2张卡片的productId" }, "productBadges": [ { "productId": "productId", "badgeType": "MOST_POPULAR", "badgeText": "最受欢迎" } ] } } ``` `productIds` 的 key 是从 `1` 开始且连续的卡片顺序,value 是商品ID;发布和查询接口均使用该结构。 同一变体内排序号和商品ID都不能重复。App/H5 套餐接口保持旧版本的独立 `position` 分组和外层顺序: 会员卡、预售卡仍分别返回;同一分组内严格按该数字顺序排列,不支持跨 `position` 穿插排序。 同一变体最多配置一个 `MOST_POPULAR`;`productId` 必须属于该变体的 `productIds`。 ### 5. 免费试看角标开关 复用现有系统配置接口,配置项: ```text freeTrialBadgeEnabled = true | false ``` ### 6. 动漫漫画更新 复用现有接口: ```text POST /api/web/admin/media/update POST /api/web/admin/media_content/create POST /api/web/admin/media_content/update ``` 列表响应增加: ```json { "contentUpdateTime": "2026-07-24T08:00:00Z", "latestPublishedAt": "2026-07-24T08:00:00Z" } ``` ### 7. 视频置顶排序 复用现有视频编辑接口。`sort` 放开0~99限制,并允许多个视频填写相同值。前端不需要交换或修改其他视频的排序号。 ## 三、无需新增后端接口 - 金币支付半屏:复用现有支付接口。 - 播放页Banner放大:纯UI。 - 删除支付温馨提示:纯UI。 - iOS搜索回车:纯客户端事件。