259 lines
7.8 KiB
Markdown
259 lines
7.8 KiB
Markdown
# 会员内容上新弹窗接口
|
||
|
||
## 一、业务流程
|
||
|
||
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 条,
|
||
合法范围为 1~20。修改数量会改变 `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 内容下发逻辑。
|