docs/:系统梳理、架构优化方案、CR-02 三端功能设计修订(含 §15 三端一致性同步与平台统计分析)、公寓端/应用端/平台端分册、公寓统计分析与排名报表、公寓端小步迭代开发计划(IT-0~IT-8) dev/:RuoYi-Vue-master(后端)与 RuoYi-Vue2-master(前端)官方上游基线,未改动
12 KiB
12 KiB
06 食堂与自助终端模块
本模块包含 6 个“终端型”界面:自助登记、点餐、结算、后厨、保洁,以及值班台复用的选房/房间维护组件。它们共同的特点是:无导航、固定 URL、部分公寓/终端标识硬编码、状态靠整页刷新或广播同步。
1. 自助登记终端 /ykt_main
文件:src/shijinpeng/main.vue(943 行)。
1.1 定位与配置
- 面向乘务员本人,部署在公寓大厅触摸屏一体机。
- 页面内固定:
gyid: "SYBXC"
gymc: "沈阳站公寓"
- 后端查询房间时也使用该
gyid,换公寓必须改代码或改成运行时可配。 - 连接
ws://{apiRoot}/yktgl/rlywebsocket/test33(main.vue:379),任何消息都会触发“入寓登记,请刷脸!”。
1.2 业务模式
| 模式 | 入口方法 | ryzt |
流程 |
|---|---|---|---|
| 入寓登记 | rydj() |
1 |
弹窗 → 刷脸 → getRyxx(ryid) 取人员 → getBtje_info 取餐补 → finalCheck 只广播 channel_rly_jc 并整页刷新,不调用后端 |
| 出乘离寓 | ccly() |
3 |
刷脸 → getJcxxByRyid(ryid) 取叫乘记录 → 合并房间信息 → finalCheck 调 /jcgl/submitAll → 成功广播并整页刷新 |
| 就餐补助 | jcbz() |
5 |
刷脸 → getBtje_infoMeal3 → updateMeal3 领取第三餐补 |
入寓登记的关键代码在 rydj_submit()(main.vue:426),但这行:
import { ..., getRyxx, ... } from "@/api/jcgl/jcgl"
jcgl.js 并没有导出 getRyxx,实际函数名是 getRyXxByRyId。刷脸确认时会抛 TypeError: getRyxx is not a function,入寓登记链路目前是断的。
1.3 录像与刷脸
- 使用
navigator.mediaDevices.getDisplayMedia录屏(invokeGetDisplayMedia/captureScreen/startRecording,main.vue:751 起)。 - 一体机需要允许屏幕捕获权限;普通浏览器会弹权限框,不适合无人值守。
- 录像在提交后未显式上传,
stopRecording的结果处理需结合后端设备协议确认。
1.4 房间选择
- 页面自行拉取
getRoomList,按row_sort分组,状态统计使用zd_roomStatus_groupName。 - 可选房间规则与
Room.vue类似:状态1/3/5/6。 - 选择后
select_room(item)把房间字段合并进jcxx,finalCheck时一并提交。
1.5 跨页广播
finalCheck 通过 BroadcastChannel("channel_rly_jc") 发送 JSON 字符串(main.vue:676、:685)。仓库内没有任何监听 channel_rly_jc 的代码,这条广播目前是空写;如果要让值班台实时感知,需要在 JcXx.vue 增加监听或改用 WebSocket。
更关键的是 finalCheck 的分支(main.vue:675):
if (this.jcxx.ryzt == '1') { // 入寓登记
channelObj.postMessage(...)
this.$router.go(0) // 没有 submitAll
}
if (this.jcxx.ryzt == '3') { // 出乘离寓
submitAll(this.jcxx)...
}
也就是说,自助终端的入寓登记即使修好 getRyxx,也不会把登记写回后端,只广播给一个不存在的监听者后刷新页面。这是比导入错误更根本的断链。
2. 点餐终端 /MealsOrdering
文件:src/zhengchuang/views/MealsOrdering.vue(988 行)。
2.1 点餐流程
sequenceDiagram
participant U as 乘务员
participant P as MealsOrdering
participant B as 后端 /Meals
participant K as 后厨 chefOrders
U->>P: 选择主食/副食/小菜,加入购物车
U->>P: 点击确定
P->>P: 显示等待刷脸,30 秒倒计时
B-->>P: WS 推送 {code:'5', icName}
P->>B: POST /Meals/consume?ryid&xfje
alt 扣款成功
P->>B: POST /Meals/createOrder
loop 每个购物车项
P->>B: POST /Meals/addOrders_MX
end
opt 偏餐 mcb=3
P->>K: BroadcastChannel("myChannel").postMessage("2603")
end
P->>P: 显示成功,3 秒后关闭弹窗
else 余额不足
P->>U: MessageBox 提示“卡内余额不足”
end
关键点:
- 人脸/刷卡结果来自
ws://{apiRoot}/yktgl/MealsWebsocket/test33(MealsOrdering.vue:392)。 - 先扣款、后建单,且建单与明细没有事务:
consume成功但createOrder失败时,钱已扣、订单不存在;addOrders_MX失败被空catch吞掉,会出现订单少明细。 - 成功后 3 秒自动关闭弹窗(
timeCount3),等待刷脸 30 秒超时则window.location.reload()。
2.2 已知缺陷
| 缺陷 | 位置 | 影响 |
|---|---|---|
isMealsClass() 使用未定义的 this.hours |
:262、:269 | 条件永远为 false,餐次永远是“偏餐”,mcb 恒为 3 |
setInterval(this.getMealsInfo, ...),但方法不存在 |
:257 | 30 分钟后定时器报错;菜单不会自动刷新 |
queryParams 中 mcb 重复声明 |
:229、:235 | 后者覆盖前者,当前值 null |
consume() 方法内调用未定义的 updateMoney() |
:436 | 若走该路径会报错(实际扣款走 API 的 consume) |
destroyed 调用 websocketclose() |
:450 | 方法内 location.reload(),离开页面即刷新 |
| WebSocket 断开即刷新 | :440 附近 | 网络抖动导致点餐页反复重载 |
3. 结算终端 /paymentPlatform
文件:src/zhengchuang/views/paymentPlatform.vue(570 行)。
- 复用点餐的菜品/订单 API,页面职责是“录入金额 + 刷脸结算”。
mounted()中this.initWebSocket()被注释(paymentPlatform.vue:212),刷脸回调不会触发;initWebSocket方法本身仍在(:376)。isHoliday()(:224)在节假日把金额锁定:早餐 10 元、正餐 20 元,否则允许手工输入。handleConfirm→ 30 秒倒计时等待刷脸 →handleSuccess→createOrder+ 明细。- 该页只导入了
getMeals/createOrder/addOrders_MX/getCsLb,完全没有调用/Meals/consume;即使恢复 WebSocket,也只是建单、不扣款。 - 结论:当前结算页只能录入金额和生成订单,不能完成真实扣款闭环,上线前必须确认是否启用。
4. 后厨终端 /chefOrders
文件:src/zhengchuang/views/chefOrders.vue(532 行)。
- 拉取待处理订单:
OrdersSearch(:341),查看明细:OrderMX_search(:349)。 - 完成订单:
updateStatus(order_id)(:359),成功后 1 秒关闭弹窗并刷新。 - 新单提示:监听
BroadcastChannel("myChannel"),收到"2603"时刷新并播放newOrderTip.mp3(:394–:406)。 - 缺陷:
beforeDestroy里新建了另一个BroadcastChannel实例再removeEventListener(:412–:413),监听器不会被移除;在单页应用内多次进入会重复响应。
5. 保洁终端 /roomService
文件:src/zhengchuang/views/roomService.vue(339 行)。
- 固定
gyid: "SYBXC"、room_floor: "1"(roomService.vue:190)。 northRoomSearch/southRoomSearch分别按room_face拉取南北两侧房间,生成房间卡片。- 点击房间 →
roomClick→cleanStart打开弹窗并启动秒表。 cleanComplete()(:260)只弹“已完成清扫”并重置计时,不调用/clean/endCleaning,房间状态不会变化。- 弹窗里的布草/备品/报修区域没有对应接口,属于未接线界面。
6. 选房与房间维护
6.1 Room.vue 选房器
- 数据:
getRoomList(),按room_floor分组,统计各状态数量。 - 状态颜色:
room_status |
含义 | 按钮类型 |
|---|---|---|
1 |
空闲 | success |
2 |
住满 | info |
3 |
待清扫 | warning |
4 |
不能入住 | danger |
5 |
未满 | primary |
6 |
正在保洁 | 默认(紫色样式) |
select_room(Room.vue:209)只允许1/3/5/6;其他状态提示“仅状态为 1、3、5、6 的房间可选择入住”。- 推荐房来自父组件传入的
recommendations,点击后按room_no回查真实房间再选中;推荐理由直接显示recommend_reason。 - 确认时
$emit('childByValue', room);父组件JcXx.vue的childByValue根据当前弹窗把房间合并进入寓表单或换房列表。 - 缺陷:状态
6可以选择,但zd_roomStatus_statusName没有6分支,确认框会显示“房屋状态:undefined”。
6.2 RoomLook.vue 房间维护
- 数据:
getRoomList(),状态统计包含6。 - 支持多选相同状态的房间(
select_room,RoomLook.vue:279),混合状态会拒绝。 - 批量操作:
| 操作 | 方法 | 接口 | 前置条件 |
|---|---|---|---|
| 开始保洁 | startCleanSelected |
/clean/startCleaning |
选中状态 3(待清扫) |
| 结束保洁 | endCleanSelected |
/clean/endCleaning |
选中状态 6(正在保洁) |
| 设为不能入住 | setSelectedRoomsUnavailable |
/jcgl/modifyRoomStatus?zt=4 |
状态 1/2/3/5 且房间无人 |
| 恢复可入住 | restoreSelectedRoomsAvailable |
/jcgl/modifyRoomStatus?zt=1 |
选中状态 4 |
batchRun用Promise.all并发调用,任一失败会整体 reject,但已成功的房间不会回滚;界面只显示成功提示(失败被catch吞掉)。- 保洁时长由
bjkssj计算,仅用于展示。
7. 跨页面广播矩阵
| 通道 | 写入方 | 读取方 | 消息 | 状态 |
|---|---|---|---|---|
myChannel |
MealsOrdering(偏餐下单)、paymentPlatform |
chefOrders |
"2603" |
可用(后厨监听器移除有 bug) |
channel_rly_jc |
shijinpeng/main.vue |
无 | JSON 登记数据 | 空写,无人监听 |
localStorage.gyid / loginAccount |
Login.vue |
所有页面/路由守卫 | 登录痕迹 | 可用,但可被手工篡改 |
location.reload() / $router.go(0) |
各终端 | — | 整页刷新 | 事实上的“状态同步”手段 |
8. 终端模块风险汇总
| 级别 | 问题 | 位置 |
|---|---|---|
| P0 | 自助终端 getRyxx 未导出,且入寓分支不调 submitAll,登记链路双重断裂 |
shijinpeng/main.vue:280、:428、:675 |
| P0 | 结算页刷脸链接被注释,且未调用扣款接口,结算闭环不成立 | paymentPlatform.vue:212、:314 |
| P1 | 点餐餐次判断恒为偏餐 | MealsOrdering.vue:262 |
| P1 | 点餐 30 分钟定时器调用不存在的方法 | MealsOrdering.vue:257 |
| P1 | 扣款与建单无事务,可能钱扣了没订单 | MealsOrdering.vue:334 起 |
| P1 | 保洁完成不回写后端 | roomService.vue:260 |
| P1 | 公寓/终端标识硬编码(SYBXC、test33) |
main.vue:291、roomService.vue:190、各 WS URL |
| P2 | 后厨广播监听器泄漏 | chefOrders.vue:412 |
| P2 | channel_rly_jc 无人监听 |
main.vue:285 |
| P2 | 状态 6 选房确认文案 undefined | Room.vue:229 |
| P2 | 批量操作无失败回滚/提示 | RoomLook.vue:313 |
9. 修改落点
| 需求 | 位置 |
|---|---|
| 自助终端支持多公寓 | main.vue 的 gyid/gymc、WS 路径、roomService.vue 的 queryParams.gyid |
| 修复入寓登记 | main.vue:280 改导入 getRyXxByRyId,同步改 :428 调用 |
| 启用结算刷脸 | paymentPlatform.vue:212 取消注释,并补齐扣款调用 |
| 改点餐餐次 | MealsOrdering.vue/paymentPlatform.vue 的 isMealsClass,用 minute 计算而非 hours |
| 改后厨提示 | chefOrders.vue:394 的 handleReceivedMessage |
| 改保洁闭环 | roomService.vue:260 接 /clean/endCleaning |
| 改选房规则 | Room.vue:210、RoomLook.vue:287、:318 起 |