6. 核心业务流程设计
6.1 待机展示流程
进入屏幕系统
↓
加载屏幕配置、主题配置、播放方案、机器人状态
↓
判断是否存在启用的播放方案
├─ 有播放方案:播放素材广告 / 图片 / 视频
└─ 无播放方案:显示默认欢迎页
↓
用户触摸屏幕或语音唤醒
↓
进入主菜单页
6.2 播报内容插播流程
小主机后端判断播报任务到时
↓
后端读取播报内容文本
↓
后端判断是否已有可用 MP3
├─ 已有且未失效:复用 MP3
└─ 没有或已失效:调用第三方 TTS 生成 MP3
↓
current 接口返回 broadcasting=true、title、content、audioUrl、audioDuration
↓
屏幕前端轮询获取当前播报状态
↓
暂停当前图片轮播或视频播放
↓
显示播报浮层
↓
屏幕端播放 audioUrl 对应 MP3
↓
audio ended 或 audio error
↓
隐藏播报浮层
↓
恢复原待机播放状态
6.3 预约到访流程
访客登记
↓
选择“预约到访”
↓
选择核验方式:身份证读取 / 手机号查询
↓
查询预约记录
├─ 查询成功:展示预约信息确认页
└─ 查询失败:提示未查询到预约,可转现场登记
↓
访客确认预约信息
↓
提交登记
↓
登记成功
6.4 现场登记流程
访客登记
↓
选择“现场登记”
↓
选择身份证读取或手动填写
↓
填写/回填访客姓名、手机号、身份证号、来访单位、被访人、来访事由
↓
提交登记前确认
↓
提交成功
↓
显示登记成功页
现场登记页字段顺序:访客姓名 → 手机号码 → 身份证号 → 来访单位 → 被访人 → 来访事由。被访部门不在机身屏现场登记页展示。
6.5 人脸识别结果进入流程
机器人侧完成人脸识别
↓
识别结果上报小主机后端
↓
屏幕前端轮询获取识别结果
↓
根据结果展示页面
├─ 预约访客:进入预约确认页
├─ 白名单人员:展示欢迎/通行提示
└─ 未识别人员:引导进入访客登记
6.6 语音指令响应流程
语音服务识别用户指令
↓ HTTP
小主机后端接收识别结果
↓
屏幕前端定时轮询最新指令
↓
执行动作
├─ 打开访客登记
├─ 打开路线引导
├─ 打开通知公告
├─ 打开主菜单
└─ 显示提示信息
13. 后续接口设计建议
本章为后续接口对接建议,一期前端可先使用 Mock 数据实现。
| 接口 | 方法 | 说明 | 主要字段 |
| /screen/config | GET | 获取屏幕配置 | robotName、logoUrl、idleTimeout、theme、volume、mute |
| /screen/status | GET | 获取机器人简要状态 | batteryLevel、networkStatus、workStatus、chargeStatus、faultFlag |
| /robot-ops/screen/play-plan/current | GET | 获取当前播放方案 | enabled、planId、planName、loopMode、defaultFitMode、version、items |
| /robot-ops/screen/broadcast/current | GET | 获取当前播报状态 | broadcasting、taskId、contentId、title、content、contentType、audioUrl、audioDuration、playMode、startTime、estimatedEndTime、version |
| /robot-ops/screen/broadcast/ack | POST | 播报播放完成回执 | taskId、contentId、resultStatus、resultMsg、playTime |
| /screen/command/latest | GET | 获取最新语音/系统指令 | commandId、type、action、payload、timestamp |
| /screen/command/ack | POST | 指令处理回执 | commandId、resultStatus、resultMsg |
| /screen/id-card/read | POST | 读取身份证 | name、idCardNo、gender、nation、address、photoUrl |
| /screen/appointment/query | GET | 预约查询 | mobile、idCardNo;返回 appointmentNo、visitorName、visitedPerson、appointmentTime |
| /screen/visitor/register | POST | 提交访客登记 | visitorName、mobile、idCardNo、visitorCompany(或 visitorSource 承接"来访单位")、visitedPerson、visitReason、visitType、registerType、appointmentNo |
| /screen/recognition/latest | GET | 获取最新识别结果 | personType、matchStatus、visitorName、appointmentNo、confidence |
| /screen/destination/list | GET | 目的地列表 | destinationId、name、category、floor、description |
| /screen/navigation/start | POST | 发起导航 | destinationId |
| /screen/navigation/status | GET | 导航状态 | taskId、status、currentPoint、targetName、progress |
| /screen/notice/list | GET | 通知公告列表 | title、content、publishTime、contentType |
| /screen/call-staff | POST | 呼叫工作人员 | callType、pagePath、remark |
| /screen/camera/preview-url | GET | 获取摄像头预览地址 | streamUrl、streamType、expireTime |
| /screen/audio/control | POST | 音量与静音控制 | volume、mute、sourceType |
| /screen/event/report | POST | 屏幕事件上报 | eventType、pagePath、eventData、timestamp |
13.1 当前播放方案接口详细设计
本接口为机身屏待机页播放方案模式的一期核心接口。运维 Web 前端、机身屏前端和后端服务共用同一套数据库与同一个后端服务;运维端负责素材上传和播放方案配置,机身屏前端只读取当前播放方案并播放素材。
13.1.1 接口基本信息
| 项 | 设计内容 |
| 接口地址 | GET /robot-ops/screen/play-plan/current |
| 接口用途 | 供机身屏 /idle 待机页读取当前启用播放方案。前端根据返回结果决定进入播放方案模式或回退默认欢迎页。 |
| 部署关系 | 运维 Web 前端、机身屏前端和后端服务部署在同一台小主机,共用同一套数据库和同一个后端服务。 |
| 素材访问地址 | 屏幕端访问素材统一使用完整 URL,例如 http://192.168.0.30/profile/upload/xxx.mp4。 |
| 是否允许多个当前方案 | 不允许。播放方案主表中同一时间只允许一个方案为当前播放方案。 |
13.1.2 数据来源与字段映射
| 数据表 | 主要字段 | 接口字段 | 说明 |
| robot_ops_play_plan | id | planId | 播放方案 ID。 |
| robot_ops_play_plan | plan_name | planName | 播放方案名称。 |
| robot_ops_play_plan | loop_mode | loopMode | 循环方式,建议支持 loop、once;一期默认 loop。 |
| robot_ops_play_plan | status | enabled 判断依据 | status=1 表示当前播放方案。 |
| robot_ops_play_plan | update_time | version | 可使用更新时间生成版本号,用于前端判断播放方案是否变化。 |
| robot_ops_play_plan_item | id | itemId / id | 播放方案明细 ID。 |
| robot_ops_play_plan_item | asset_id | assetId | 关联素材 ID。 |
| robot_ops_play_plan_item | play_order | sort | 播放顺序,按升序返回。 |
| robot_ops_play_plan_item | stay_seconds | staySeconds / duration | 图片停留秒数;duration = staySeconds × 1000。 |
| robot_ops_media_asset | asset_name | title | 素材名称。 |
| robot_ops_media_asset | asset_type | type | 素材类型,转换为 image 或 video。 |
| robot_ops_media_asset | file_url | url | 素材文件地址,后端需补全为屏幕端可直接访问的完整 URL。 |
| robot_ops_media_asset | thumbnail_url | thumbnailUrl | 缩略图地址,可为空。 |
| robot_ops_media_asset | status | 过滤依据 | 只有启用状态素材可被屏幕端播放。 |
13.1.3 后端取数规则
- 查询
robot_ops_play_plan 中 status=1 的当前播放方案。
- 如果不存在当前播放方案,返回
enabled=false 和空 items。
- 如果存在当前播放方案,查询该方案下的
robot_ops_play_plan_item 明细,并按 play_order 升序排序。
- 关联
robot_ops_media_asset 素材表,获取素材名称、类型、文件地址、缩略图、视频时长、启用状态等。
- 过滤不可播放素材:素材不存在、素材停用、
file_url 为空、asset_type 不是 image/video。
- 如果过滤后素材列表为空,也返回
enabled=false 和空 items。
- 如果存在可播放素材,返回
enabled=true 和已排序的素材列表。
13.1.4 素材 URL 补全规则
后端返回给屏幕端的 url 和 thumbnailUrl 必须是浏览器可直接访问的地址。屏幕端当前约定素材访问前缀为 http://192.168.0.30。
| 数据库 file_url 示例 | 接口返回 url 示例 | 处理规则 |
http://192.168.0.30/profile/upload/a.mp4 | http://192.168.0.30/profile/upload/a.mp4 | 已是完整 URL,原样返回。 |
/profile/upload/a.mp4 | http://192.168.0.30/profile/upload/a.mp4 | 使用资源访问前缀拼接。 |
profile/upload/a.mp4 | http://192.168.0.30/profile/upload/a.mp4 | 补充斜杠后再拼接。 |
建议后端将资源访问前缀配置化,例如 screen.resource-base-url=http://192.168.0.30,避免硬编码到业务代码中。
13.1.5 返回示例
{
"code": 200,
"msg": "查询成功",
"data": {
"enabled": true,
"planId": 1,
"planName": "默认播放方案",
"loopMode": "loop",
"defaultFitMode": "cover",
"version": "20260513153000",
"items": [
{
"id": 1001,
"itemId": 1001,
"assetId": 501,
"type": "image",
"title": "欢迎宣传图",
"url": "http://192.168.0.30/profile/upload/2026/05/welcome.png",
"thumbnailUrl": "http://192.168.0.30/profile/upload/2026/05/welcome.png",
"duration": 8000,
"staySeconds": 8,
"fitMode": "cover",
"showTitle": false,
"sort": 1
},
{
"id": 1002,
"itemId": 1002,
"assetId": 502,
"type": "video",
"title": "机器人介绍视频",
"url": "http://192.168.0.30/profile/upload/2026/05/robot-intro.mp4",
"thumbnailUrl": "http://192.168.0.30/profile/upload/2026/05/robot-intro-cover.jpg",
"duration": null,
"staySeconds": null,
"fitMode": "cover",
"muted": false,
"showTitle": false,
"sort": 2
}
]
},
"timestamp": "2026-05-13 15:30:00"
}
13.1.6 无播放方案或无可播放素材返回示例
{
"code": 200,
"msg": "暂无当前播放方案",
"data": {
"enabled": false,
"planId": null,
"planName": "",
"loopMode": "loop",
"defaultFitMode": "cover",
"version": "",
"items": []
},
"timestamp": "2026-05-13 15:30:00"
}
13.1.7 前端播放规则
enabled=false 或 items 为空时,机身屏回退默认欢迎页。
enabled=true 且 items 有数据时,机身屏进入播放方案模式。
- 图片素材按
staySeconds 控制停留时长,前端使用 duration 毫秒值进行定时切换。
- 视频素材默认完整播放,前端监听
ended 事件后切换下一条,不使用 staySeconds 强制截断。
fitMode 默认 cover,后续可扩展 contain、stretch。
showTitle 默认 false,避免和素材自带文字冲突。
- 屏幕端进入
/idle 待机页时,应立即请求一次 /robot-ops/screen/play-plan/current 当前播放方案接口。
- 待机播放期间,屏幕端应每 60 秒重新请求一次当前播放方案接口,用于检查运维端是否更新了播放方案或素材配置。
- 前端应通过接口返回的
version 字段判断播放方案是否变化;如果 version 未变化,不应重置当前播放进度。
- 如果
version 发生变化,前端应标记新方案待生效,并在当前图片展示结束或当前视频播放结束后切换到新播放方案,不建议直接打断正在播放的视频。
- 如果重新请求后发现无当前播放方案、播放方案禁用或素材为空,前端应在当前素材播放结束后回退默认欢迎页。
13.1.8 播放方案更新检查策略
| 场景 | 处理策略 | 说明 |
| 进入待机页 | 立即请求当前播放方案接口 | 确保屏幕端启动或从业务页面返回待机时读取最新播放配置。 |
| 待机播放中 | 每 60 秒请求一次 /robot-ops/screen/play-plan/current | 一期不单独增加 version 接口,直接轮询 current 接口即可。 |
| version 未变化 | 不重置播放进度 | 避免图片/视频被无意义重播或闪烁。 |
| version 变化 | 当前素材结束后切换新方案 | 图片在本次 duration 结束后切换;视频在 ended 后切换。 |
| 方案被取消或素材为空 | 当前素材结束后回退默认欢迎页 | 避免播放过程中突兀黑屏或直接中断。 |
后续如需降低接口数据量,可扩展轻量版本检查接口 GET /robot-ops/screen/play-plan/version。屏幕端每 30-60 秒请求 version,只有版本变化时再请求 current 完整播放方案。一期建议先使用 current 接口轮询,降低前后端联调复杂度。
13.2 当前播报状态接口详细设计
本接口供机身屏 /idle 待机页获取当前播报状态。前端根据 broadcasting 判断是否显示播报浮层,并暂停或恢复当前素材播放。
13.2.1 接口基本信息
| 项 | 设计内容 |
| 接口地址 | GET /robot-ops/screen/broadcast/current |
| 接口用途 | 供机身屏 /idle 待机页获取当前播报状态。前端根据 broadcasting 判断是否显示播报浮层、播放 MP3,并暂停或恢复当前素材播放。 |
| 数据来源 | 运维端播报内容管理与播报任务管理。后端关联播报任务和播报内容后,生成 MP3 并返回当前播报文本和音频地址。 |
| 轮询频率 | 一期建议待机页每 2 秒轮询一次。 |
| TTS 职责 | 后端负责播报文本转 MP3、音频缓存、任务命中判断和音频地址返回;屏幕端负责根据 audioUrl 播放 MP3、展示播报浮层、暂停和恢复当前素材播放。 |
| 生效范围 | 一期优先只在 /idle 待机页执行播报插播;访客登记、路线引导等业务办理页面暂不强制打断。 |
13.2.2 数据来源与字段映射
| 来源表 | 来源字段 | 接口字段 | 说明 |
| robot_ops_broadcast_task | id | taskId | 播报任务 ID。 |
| robot_ops_broadcast_task | task_name | taskName | 播报任务名称。 |
| robot_ops_broadcast_task | content_id | contentId | 关联播报内容 ID。 |
| robot_ops_broadcast_task | start_time | startTime | 本次播报开始时间。 |
| robot_ops_broadcast_task | end_time、frequency_minutes、cycle_type、cycle_value、status | 后端判断依据 | 由后端根据任务规则判断是否命中当前播报,前端不参与计算。 |
| robot_ops_broadcast_content | content_name | title | 播报标题。 |
| robot_ops_broadcast_content | content_type | contentType | 播报分类,例如通知、宣传、提示、安防提醒、自定义。 |
| robot_ops_broadcast_content | broadcast_text | content | 播报文本,用于屏幕展示,并由后端调用第三方 TTS 生成 MP3。 |
| robot_ops_broadcast_content | status | 过滤依据 | 只有启用状态的播报内容可被任务触发。 |
13.2.3 有播报返回示例
{
"code": 200,
"msg": "查询成功",
"data": {
"broadcasting": true,
"taskId": 12,
"contentId": 35,
"taskName": "大厅整点提醒",
"title": "参观提醒",
"content": "欢迎各位来宾参观,请按照现场工作人员引导有序通行。",
"contentType": "notice",
"level": "normal",
"audioUrl": "http://192.168.0.30/profile/audio/broadcast/35_abc123.mp3",
"audioDuration": 20.5,
"playMode": "once",
"startTime": "2026-05-18 16:30:00",
"estimatedEndTime": "2026-05-18 16:30:20",
"version": "20260518163000"
},
"timestamp": "2026-05-18 16:30:01"
}
13.2.4 无播报返回示例
{
"code": 200,
"msg": "当前无播报",
"data": {
"broadcasting": false,
"taskId": null,
"contentId": null,
"taskName": "",
"title": "",
"content": "",
"contentType": "",
"level": "normal",
"audioUrl": "",
"audioDuration": null,
"playMode": "once",
"startTime": null,
"estimatedEndTime": null,
"version": "20260518163100"
},
"timestamp": "2026-05-18 16:31:00"
}
13.2.5 屏幕端处理规则
- 屏幕端进入
/idle 后立即请求一次当前播报状态接口,并每 2 秒轮询一次。
- 当 broadcasting=true 且 audioUrl 不为空时,屏幕端显示播报浮层,展示播报标题、播报正文和"正在播报"状态。
- 当前为图片素材时,播报开始后暂停图片轮播定时器,并播放 audioUrl 对应 MP3;播报结束后恢复图片轮播。
- 当前为视频素材时,播报开始后暂停视频播放,并播放 audioUrl 对应 MP3;播报结束后继续播放视频。
- 当前为默认欢迎页时,播报开始后显示播报浮层并播放 MP3;播报结束后隐藏播报浮层。
- 屏幕端应通过 audio ended 事件判断播报播放完成。
- 播报插播不应重置当前播放方案和当前素材索引。
- 如果 audioUrl 为空、MP3 加载失败或播放失败,屏幕端应记录 warning 日志,并恢复原素材播放状态。
- 接口请求失败或后端播报服务异常时,不影响当前素材播放。
13.2.6 后端与 TTS 处理建议
- 一期 TTS 不采用流式 TTS,统一采用"第三方 TTS 生成 MP3 文件 + 屏幕端播放 MP3"的方式实现。
- 后端根据播报任务的开始时间、结束时间、频率、循环类型和循环取值判断当前是否命中播报。
- 后端应避免同一任务在同一时间窗口内重复触发。
- 播报任务命中后,后端读取播报内容文本,判断该内容是否已有可用 MP3 文件;如果已有且未失效,则直接复用;如果没有或内容已修改,则调用第三方 TTS 重新生成 MP3。
- MP3 文件建议保存到小主机本地目录,例如
/data/robot/audio/broadcast/,并通过静态资源服务暴露为屏幕端可访问的 audioUrl,例如 http://192.168.0.30/profile/audio/broadcast/35_abc123.mp3。
- MP3 是否需要重新生成,应根据播报文本、音色、语速、音量、TTS 供应商和模型版本等生成 Hash 进行判断;Hash 不一致或本地文件不存在时重新生成。
- 后端在 current 接口中返回 broadcasting=true、audioUrl、audioDuration、title、content 等字段。
- 屏幕端负责播放 MP3。后端不直接控制浏览器音频播放,也不直接负责暂停/恢复素材。
- 后端可根据任务命中状态和播放窗口维护当前播报状态;如增加播放完成回执接口,则以后端收到 ack 后结束本次播报状态。
- 如果 TTS 生成失败,应记录失败原因,并避免影响素材播放;current 接口可返回 broadcasting=false 或返回错误状态,具体按后端实现处理。
- 后端应封装统一 TtsService,不要将第三方 TTS API 直接写死在播报任务逻辑中。
13.2.7 MP3 文件生成与复用规则
| 场景 | 处理规则 | 说明 |
| 首次播报 | 调用第三方 TTS 生成 MP3 | 生成完成后保存本地文件,并记录音频路径、访问 URL、时长、Hash 和生成状态。 |
| 重复播报相同内容 | 复用已生成 MP3 | 避免每次播报都请求第三方 TTS,降低成本和延迟。 |
| 播报文本修改 | 重新生成 MP3 | 文本变化后 Hash 变化,旧音频失效。 |
| 音色/语速/音量/供应商参数修改 | 重新生成 MP3 | 同一文本在不同语音参数下应视为不同音频。 |
| 本地音频文件丢失 | 重新生成 MP3 | 数据库有记录但文件不存在时应自动补偿生成。 |
| MP3 播放失败 | 屏幕端记录失败并恢复素材播放 | 不应阻塞待机素材播放,后续可通过事件上报或运行日志记录。 |
| TTS 生成失败 | 后端记录失败状态和错误信息 | 不返回可播放 audioUrl,屏幕端不进入播报播放状态。 |
建议 Hash 计算口径为:md5(播报文本 + 音色 + 语速 + 音量 + TTS供应商 + 模型版本)
后端应封装统一 TtsService。屏幕端应封装统一音频播放逻辑,用于播放播报 MP3、监听 ended/error 事件,并在播放完成或失败后恢复素材播放。
一期如后端需要确认屏幕端实际播放完成,可提供 POST /robot-ops/screen/broadcast/ack。屏幕端在 audio ended 后上报 success,在 audio error 后上报 failed。若一期暂不做 ack,后端可根据播报窗口或 estimatedEndTime 结束播报状态。