- 7 个固定槽位(1920×1080 两行网格),槽位定义/校验/橘视厅元数据同步 - 海报按槽位自动选:竖图槽取 posterimg、横图槽取 thumbimg,支持自定义覆盖 - 一键导出 zip 交付包:海报按槽位精确尺寸居中裁剪 + config.json + README(am start 拉起命令) - 管理后台接口 6 个(/manage/recommend-page/*),前端对接文档 FE-RECOMMEND-GUIDE.md
9.1 KiB
推荐页配置 · 前端对接文档
功能:设备厂商 1920×1080 整屏电影推荐页,运营在后台选片配置 7 个固定槽位,一键导出 zip 交付包发给厂商。 后端已上线,本文档为前端实施所需全部信息。
1. 通用约定
- 鉴权:所有接口走管理后台 JWT,请求头带
token(与现有 /manage 接口一致) - 返回格式:
{ code: 0, msg: "", data: {...} },code=0 成功,非 0 失败(msg 为错误信息) - 新增菜单:「媒资管理 → 推荐页配置」,路由
manage/recommend-page(后台 sys_menu 已配置 id=126,超管自动可见,其他角色需在角色管理勾选)
2. 槽位定义(固定 7 个,不可增减)
整屏排版(1920×1080 两行网格,槽位间距 20px,左右边距 70px):
┌────────────────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ slot_01 │ │slot_02│ │slot_03│ │slot_04│ ← 上行
│ 700×400 │ │340×440│ │340×440│ │340×440│
└────────────────┘ └─────┘ └─────┘ └─────┘
┌──────────────┐ ┌──────────────┐ ┌─────────┐
│ slot_05 │ │ slot_06 │ │ slot_07 │ ← 下行
│ 700×300 │ │ 700×300 │ │ 340×300 │
└──────────────┘ └──────────────┘ └─────────┘
| 槽位 | 类型 | 尺寸 | 说明 | 影片 |
|---|---|---|---|---|
| slot_01 | MAIN 主推 | 700×400 | 横图 | 必填 contentcode |
| slot_02 | PORTRAIT 竖图 | 340×440 | 竖图 | 必填 |
| slot_03 | PORTRAIT 竖图 | 340×440 | 竖图 | 必填 |
| slot_04 | PORTRAIT 竖图 | 340×440 | 竖图 | 必填 |
| slot_05 | LANDSCAPE 横图 | 700×300 | 横图 | 必填 |
| slot_06 | LANDSCAPE 横图 | 700×300 | 横图 | 必填 |
| slot_07 | MORE 更多入口 | 340×300 | 无影片,点击拉起橘视厅 | 不填,必填海报 URL |
编辑页建议:按 0.25 倍缩放渲染线框(175×100 / 85×110 / 175×75 / 85×75),每槽位显示海报缩略图 + 影片名 + 尺寸标注。
3. 接口清单
Base:/manage/recommend-page
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /list |
分页列表,参数 page、limit、name(可选) |
| GET | /info/{id} |
详情(slots 已解析为数组) |
| GET | /slot-definitions |
槽位定义(渲染线框用,见 §3.1) |
| POST | /save |
新建或更新(有 id 更新,无 id 新建) |
| POST | /delete |
软删除,body: [1, 2](id 数组) |
| GET | /export/{id} |
导出 zip 交付包(必须 blob 方式下载,见 §6) |
3.1 槽位定义 GET /slot-definitions
{
"code": 0,
"data": {
"slots": {
"slot_01": { "slotCode": "slot_01", "slotType": "MAIN", "width": 700, "height": 400,
"defaultActionType": "DETAIL", "mediaRequired": true, "posterField": "thumbimg" },
"slot_02": { "slotCode": "slot_02", "slotType": "PORTRAIT", "width": 340, "height": 440,
"defaultActionType": "DETAIL", "mediaRequired": true, "posterField": "posterimg" }
// ... slot_03~07
}
}
}
3.2 列表 GET /list?page=1&limit=10
{
"code": 0,
"data": {
"page": {
"totalCount": 5, "pageSize": 10, "currPage": 1, "totalPage": 1,
"list": [
{ "id": 1, "name": "2026年10月推荐", "remark": "备注", "deleteFlag": "UNDEL",
"createdAt": "2026-09-26 15:00:00", "updatedAt": "2026-09-26 15:00:00" }
]
}
}
}
3.3 详情 GET /info/{id}
{
"code": 0,
"data": {
"recommendPage": { "id": 1, "name": "2026年10月推荐", "remark": "", "slots": "[...原始JSON字符串...]", "createdAt": "..." },
"slots": [
{
"slotCode": "slot_01",
"slotType": "MAIN",
"width": 700, "height": 400,
"contentcode": "23010012026061709581101832",
"mediaName": "影片名(后端从橘视厅同步)",
"posterUrl": "https://imgcms.jetsenx.huashi.tv/.../448x252_xxx.png",
"customPoster": false,
"actionType": "DETAIL",
"actionParam": "am start -n tv.huashi.jetsenx.jetsenfilx.jsttv.home/com.pukka.jiecheng.MainActivity --es media_id \"{contentcode}\"",
"rawMedia": { "...橘视厅完整元数据(posterimg/thumbimg/description等)..." }
},
{
"slotCode": "slot_07",
"slotType": "MORE",
"width": 340, "height": 300,
"contentcode": null,
"mediaName": "更多影片",
"posterUrl": "https://.../more.jpg",
"customPoster": true,
"actionType": "LAUNCH",
"actionParam": "am start -n tv.huashi.jetsenx.jetsenfilx.jsttv.home/com.pukka.jiecheng.MainActivity",
"rawMedia": null
}
]
}
}
前端渲染用
data.slots(已解析),按 slotCode 匹配到线框位置。
3.4 保存 POST /save
前端只需传必要字段,影片名/海报由后端从橘视厅自动同步:
{
"id": null,
"name": "2026年10月推荐",
"remark": "备注(可选)",
"slots": [
{ "slotCode": "slot_01", "contentcode": "23010012026061709581101832" },
{ "slotCode": "slot_02", "contentcode": "..." },
{ "slotCode": "slot_03", "contentcode": "..." },
{ "slotCode": "slot_04", "contentcode": "..." },
{ "slotCode": "slot_05", "contentcode": "..." },
{ "slotCode": "slot_06", "contentcode": "..." },
{ "slotCode": "slot_07", "posterUrl": "https://.../more.jpg" }
]
}
槽位可选字段:
| 字段 | 说明 |
|---|---|
posterUrl |
自定义海报 URL。横图槽位(slot_01/05/06/07)默认用橘视厅横版图,效果不佳时运营可手动填横图 URL 覆盖 |
actionParam |
自定义拉起命令(一般不填,用后端默认值) |
后端校验规则(错误信息会原样返回 msg):
- 期名 name 必填
- slots 必须 7 个、slotCode 齐全不重复
- slot_01~06 contentcode 必填;无效 contentcode 报错
contentcode 无效: xxx(保存时后端实时调橘视厅校验) - slot_07 必填 posterUrl
- 影片无海报时报错
影片 xxx 无可用海报
成功返回:{ code: 0, data: { recommendPage: { id: 1, ... } } }
4. 选片弹窗(复用已有媒资接口)
搜索:GET /manage/jetsen-media/search?keyword=xxx&pageindex=1&pagesize=20(已存在的接口)
{
"code": 0,
"data": {
"list": [
{ "contentcode": "23010022026090109192132084", "name": "后悔没有好好爱过你",
"posterimg": "https://...", "categoryname": "电影", "score": "8.0",
"releaseyear": "2026", "originalcountry": "中国大陆" }
],
"totalCount": 100, "currPage": 1, "pageSize": 20, "totalPage": 5
}
}
弹窗交互:搜索框 → 结果列表(海报缩略图 + 片名 + contentcode)→ 选中回填槽位。
槽位预览图可直接用选中结果的 posterimg(保存后以 info 接口返回的 posterUrl 为准)。
5. 页面结构
5.1 列表页 /recommend(路由建议)
| 列 | 说明 |
|---|---|
| 期名 | name |
| 备注 | remark |
| 创建时间 | createdAt |
| 操作 | 编辑 / 复制新一期 / 导出zip / 删除 |
复制新一期:调 info/{id} 取 slots 预填新建表单(id 置 null),运营只改差异影片。
5.2 编辑页
- 顶部表单:期名(必填)、备注
- 槽位线框区(§2 尺寸 × 0.25 缩放)
- slot_01~06:点槽位 → 打开选片弹窗 → 回填 contentcode + 预览图
- 每个槽位可展开「自定义海报 URL」输入框(可选,横图槽位补横版图用)
- slot_07:仅海报 URL 输入(必填)+ 可选拉起参数
- 工具栏:保存、导出 zip(保存后才可导出,需有 id)
前端预校验(7 槽位齐、slot_01~06 contentcode 齐、slot_07 海报齐),后端保存时再校验一遍。
6. 导出下载(重要:不能用 window.open)
导出接口走 JWT 请求头,window.open / <a href> 无法带 token,必须用 axios blob 方式:
axios.get(`/manage/recommend-page/export/${id}`, {
responseType: 'blob',
headers: { token: getToken() }
}).then(res => {
const url = window.URL.createObjectURL(new Blob([res.data]))
const link = document.createElement('a')
link.href = url
link.download = `推荐页_${name}.zip`
link.click()
window.URL.revokeObjectURL(url)
})
注意:导出需实时下载 7 张海报并裁剪,耗时约 5~15 秒,建议按钮加 loading 态。失败时(如某海报下载失败)返回 JSON 错误而非 zip,前端可判断 res.data.type === 'application/json' 提示错误。
7. zip 交付包结构(导出结果,无需前端处理,仅供了解)
推荐页_2026年10月推荐.zip
├── images/slot_01.png ~ slot_07.png # 已按槽位精确尺寸居中裁剪
├── recommend_config.json # contentcode + actionType + actionParam(占位符已替换真实值)
└── README.txt # 排版与拉起规则说明