# 推荐页配置 · 前端对接文档 > 功能:设备厂商 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` ```json { "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` ```json { "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}` ```json { "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` **前端只需传必要字段,影片名/海报由后端从橘视厅自动同步:** ```json { "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`(已存在的接口) ```json { "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` / `` 无法带 token,**必须用 axios blob 方式**: ```javascript 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 # 排版与拉起规则说明 ```