Files
huangguo_server/会员内容上新弹窗接口.md
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

259 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 会员内容上新弹窗接口
## 一、业务流程
1. App 使用达到产品规定时长后,回到首页时请求“获取会员内容上新弹窗”接口。
2. 后端判断当前用户是否需要展示弹窗:
- 存在尚未展示过的最新 VIP 内容版本时,返回 `show=true`
- 当前内容版本已经展示过,或没有可用配置时,返回 `show=false`
3. `show=true` 时,前端直接使用响应中的 `videos` 渲染最新内容,数量由后台配置。
4. 弹窗实际展示成功后,前端调用“上报弹窗已展示”接口。
5. 上报成功后,同一用户再次请求相同内容版本时返回 `show=false`
6. 后续有新的 VIP 内容上架、内容版本变化后,该用户可以再次收到弹窗。
## 二、获取会员内容上新弹窗
### 请求
```http
GET /api/app/payment/guide?scene=VIP_CONTENT_UPDATE
Authorization: <用户登录Token>
```
### Query 参数
| 参数 | 类型 | 是否必传 | 说明 |
| --- | --- | --- | --- |
| `scene` | String | 是 | 固定传 `VIP_CONTENT_UPDATE` |
### `show=true` 返回示例
```json
{
"code": 200,
"msg": "success",
"data": {
"show": true,
"configId": "6889f6d34a4fcb5012345678",
"contentVersion": "4a7cbdb742c44a47",
"segment": "OLD_NEVER_PAID",
"style": "BOTTOM_SHEET",
"title": "VIP会员特享内容更新上架啦",
"description": "精彩内容抢先看",
"cover": "",
"videos": [
{
"id": "6889f1014a4fcb5012340001",
"title": "视频标题1",
"cover": "https://example.com/video-1.jpg",
"coverThumb": "https://example.com/video-1-thumb.jpg",
"playTime": 1384,
"playCount": 12000
},
{
"id": "6889f1024a4fcb5012340002",
"title": "视频标题2",
"cover": "https://example.com/video-2.jpg",
"coverThumb": "https://example.com/video-2-thumb.jpg",
"playTime": 1062,
"playCount": 9850
},
{
"id": "6889f1034a4fcb5012340003",
"title": "视频标题3",
"cover": "https://example.com/video-3.jpg",
"coverThumb": "https://example.com/video-3-thumb.jpg",
"playTime": 926,
"playCount": 8160
},
{
"id": "6889f1044a4fcb5012340004",
"title": "视频标题4",
"cover": "https://example.com/video-4.jpg",
"coverThumb": "https://example.com/video-4-thumb.jpg",
"playTime": 745,
"playCount": 6300
}
],
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 0,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
}
}
```
### `show=false` 返回示例
```json
{
"code": 200,
"msg": "success",
"data": {
"show": false,
"segment": "OLD_NEVER_PAID"
}
}
```
### 响应字段
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `show` | Boolean | 是否展示弹窗;为 `false` 时前端不展示 |
| `configId` | String | 当前弹窗配置 ID`show=true` 时返回 |
| `contentVersion` | String | 当前最新内容版本;展示回执时原样传回 |
| `segment` | String | 当前用户所属分层 |
| `style` | String | 弹窗样式 |
| `title` | String | 弹窗标题 |
| `description` | String | 弹窗描述 |
| `cover` | String | 弹窗整体封面,没有配置时为空字符串 |
| `videos` | Object[] | 前端渲染使用的最新 VIP 内容列表,数量由后台配置 |
| `productId` | String | 会员商品 ID |
| `durationSeconds` | Integer | 配置的持续时间,单位为秒 |
| `action` | Object | 弹窗按钮操作配置 |
### `videos` 字段
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | String | 视频 ID |
| `title` | String | 视频标题 |
| `cover` | String | 视频封面 |
| `coverThumb` | String | 视频缩略图;优先用于列表展示,为空时使用 `cover` |
| `playTime` | Integer | 视频时长,单位为秒 |
| `playCount` | Integer | 视频展示播放量 |
### 内容筛选和排序
- 仅返回审核通过的 VIP 视频内容。
- 排除免费专区内容。
- 排除金币付费内容。
- 排除不可推荐内容。
- 排除业务配置中不参与该弹窗的模块。
- 按审核通过时间倒序排列。
- 返回数量由付费引导配置的 `videoLimit` 控制;未配置或传 `0` 时默认 4 条,最大 20 条。
- 前端不需要再次排序;如果可用内容不足配置数量,按实际数量返回。
## 三、上报弹窗已展示
### 请求
```http
POST /api/app/payment/guide/impression
Authorization: <用户登录Token>
Content-Type: application/json
```
### 请求体
```json
{
"configId": "6889f6d34a4fcb5012345678",
"scene": "VIP_CONTENT_UPDATE",
"contentVersion": "4a7cbdb742c44a47",
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
```
### 请求参数
| 参数 | 类型 | 是否必传 | 说明 |
| --- | --- | --- | --- |
| `configId` | String | 是 | 获取接口返回的 `configId` |
| `scene` | String | 是 | 固定传 `VIP_CONTENT_UPDATE` |
| `contentVersion` | String | 是 | 获取接口返回的 `contentVersion`,原样传回 |
| `requestId` | String | 是 | 客户端每次展示生成的 UUID,用于请求幂等 |
| `videoId` | String | 否 | 用户点击或当前展示的视频 ID |
### 成功返回
```json
{
"code": 200,
"msg": "success",
"data": ""
}
```
### 调用时机
- 只有弹窗已经实际展示成功时才调用。
- 仅获取数据但未展示弹窗时,不调用展示回执。
- 回执请求失败时可以使用相同的 `requestId` 重试。
## 四、前端处理规则
- `show=false`:不展示弹窗,不调用展示回执。
- `show=true`:使用 `videos` 渲染内容卡片。
- 视频封面优先使用 `coverThumb`,为空时回退到 `cover`
- `playTime` 单位为秒,由前端格式化为 `mm:ss``hh:mm:ss`
- `playCount` 由前端按现有规则格式化,例如 `12000` 显示为 `1.2W`
- 用户点击视频时,使用对应的 `id` 跳转视频详情。
- 用户点击开通会员时,按 `action.type``action.value` 执行跳转。
- 弹窗展示成功后,将 `configId``scene``contentVersion` 和新生成的 `requestId` 上报。
## 五、重复请求行为
| 场景 | 返回结果 |
| --- | --- |
| 同一内容版本尚未上报展示 | 重复请求仍返回 `show=true` 和相同内容 |
| 同一内容版本已经上报展示 | 返回 `show=false` |
| 后续上架新 VIP 内容,内容版本发生变化 | 返回 `show=true` 和新的 `contentVersion` |
| 没有有效弹窗配置 | 返回 `show=false` |
| 没有符合条件的 VIP 内容 | 返回 `show=false` |
## 六、后台返回数量和批量场景配置
付费引导新增、编辑接口的配置对象支持:
```json
{
"scene": "VIP_CONTENT_UPDATE",
"videoLimit": 20
}
```
`videoLimit` 仅用于 `VIP_CONTENT_UPDATE` 场景;不传或传 `0` 时默认 4 条,
合法范围为 120。修改数量会改变 `contentVersion`,已经看过旧内容版本的
用户会按新版本再次满足展示条件。
后台需要将同一份配置一次应用到多个场景时,调用:
```http
POST /api/web/admin/payment-guide/add
Content-Type: application/json
```
```json
{
"scenes": [
"HOME_NEW_USER",
"VIP_CONTENT_UPDATE"
],
"config": {
"segments": [],
"style": "BOTTOM_SHEET",
"title": "VIP会员内容更新上架啦",
"description": "精彩内容抢先看",
"cover": "",
"videoIds": [],
"videoLimit": 4,
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 0,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
},
"enable": true,
"sort": 100
}
}
```
`scenes` 支持当前全部合法场景,单次最多 6 个,不允许重复。后台会为每个场景
生成独立的配置 ID,整批成功或整批回滚。该接口只批量复制配置,不会改变
各场景原有的 App 内容下发逻辑。