酒店模块需求缺口清单.md 31 KB

酒店模块需求缺口清单

需求基线需求说明书.html v1.0(2026-07-26,状态:需求确认中代码基线:master @ 2026-09-03 实地核对(非文档推断) 配套文档酒店模块迁移跟踪.md — 代码地图与实现进度(回答「代码里有什么」) 本文档职责:需求视角的验收对照与缺口台账(回答「需求要什么、还差什么」) 条目归宿:缺口关闭后不在本文档堆积实现细节,转入 code-copilot/changes/<变更名>/,本文档只留状态与链接


一、结论速览

需求定义五端协同(顾客端 / 餐厅前台 / 厨房端 / 宾馆前台 / 后台管理),当前实际落地为「1 个顾客端 H5 + 1 个 PC 管理端(兼餐厅前台与宾馆前台职能)」

判断 结论
主链路 ✅ 扫码 → 房号确认 → 点餐 → 购物车 → 下单 → 支付 → 接单/备餐/出餐/配送/完成 → 退单退款,已跑通
厨房端 完全缺失(0 页面、0 打印、0 菜品语音播报)
微信支付 缺失,微信环境实际落到 Mock 分支
小程序载体 📋 已确认目标:正式载体为微信小程序 + 支付宝小程序(双端),H5 仅用于开发阶段测试;appid 待配置,页面代码已就绪
品牌风格设置 ⚠️ 暂缓(待甲方确认)
订单金额正确性 🔴 存在资金缺陷已修复(2026-09-04):规格加价与加料加价已在后端重算,支付页金额 = 下单页金额 = 购物车金额
开放接口越权 🔴 存在数据隔离缺陷已加固(2026-09-04):SQL 层租户过滤 + 应用层参数校验 + 审计日志三级防护;⚠️ 订单归属校验仍缺失,见 3.2 残留风险登记 R2
临时暂停接单 已实现(2026-09-04):hotel_config 持久化开关 + PC 端切换 + H5 五页拦截 + 下单服务端兜底
超出需求的增量 ➕ 在住会话 / 房态看板 / 退房联动 / 退款全链路 / 支付超时取消,详见第七节

二、五端落地矩阵

需求要求 落地情况 载体
📱 顾客端 微信/支付宝小程序,8 页 8 页全部实现,但运行在 H5,小程序未发布 forge-h5-ui/src/pages/hotel/customer/
🖥️ 餐厅前台 PAD / 移动 / PC,4 页 无独立端,职能由 PC 订单页承担;缺「临时暂停接单」「移动端」 views/hotel/order.vueviews/hotel/businessHours.vue
👨‍🍳 厨房端 大屏 + 打印机,2 页 完全未实现(仅「出餐」动作可在 PC 订单页点击)
🏨 宾馆前台 PC / 移动,2 页 无独立端,PC 订单页覆盖全订单查看/筛选/任意阶段退单/手动退款;缺移动端 views/hotel/order.vue
⚙️ 后台管理 PC,5 页 菜品/订单/房间三页齐备且更强;数据看板指标不全系统设置缺失 views/hotel/

三、🔴 P0 缺口(阻塞上线,含资金与安全)

3.1 订单金额未计入规格/加料加价 —— 资金缺陷 ✅ 已修复

AGENTS.md 5.9 安全红线:涉及资金,必须在 Spec 中标注并经人工审查。

修复状态:✅ 已于 code-copilot/changes/hotel-order-amount-fix/ 中修复(2026-08-XX)

  • H5 前端:order-confirm.vue L141-148 提交时携带 specOptionIds / additionIds
  • 后端重算:HotelOrderServiceImpl.orderCreate() L158-175 按 ID 从数据库查询规格/加料价格重新计算 unitPrice
  • 表结构:hotel_order_item 已有 spec_option_idsaddition_ids 字段(V1.0.104)
  • 验证:支付页金额 = 下单页金额 = 购物车金额

证据链

环节 位置 行为
前端算价 forge-h5-ui/src/pages/hotel/customer/dish-detail.vue L317-319 unitPrice = 菜品基础价 + Σ priceExtra(规格) + Σ extraPrice(加料)
前端提交 forge-h5-ui/src/pages/hotel/customer/order-confirm.vue L141-148 items 只带 specDesc / additionsDesc 文本,不带规格选项 ID / 加料 ID
后端重算 HotelOrderServiceImpl.orderCreate() L158-175 unitPrice = dish.getPrice() 仅基础价,覆盖前端传值;subtotal = 基础价 × quantity
表结构 HotelOrderItem / hotel_order_item 只有 specDescadditionsDesc 冗余文本,spec_option_ids / addition_ids → 后端即使想重算也缺少关联依据

后果(当前即可复现)

  1. 少收款:顾客选加价规格/加料,实际订单金额按基础价计算。
  2. 金额前后不一致pay.vue 的金额取自后端 orderDetail,因此支付页金额 < 下单页/购物车金额,用户可见。
  3. 明细不可追溯:只存文本描述,规格选项被改名/删除后历史订单无法还原加价构成。

修复方向

  • Flyway V1.0.108hotel_order_item 增加 spec_option_idsaddition_ids(或 JSON 价格快照列)
  • OrderCreateDTO.items 增加规格选项 ID 列表 + 加料 ID 列表
  • orderCreate() 按 ID 从 hotel_dish_spec_option.price_extra + hotel_dish_addition.extra_price 服务端重算 unitPrice,继续不信任前端价格
  • H5 提交时携带 ID(specDesc / additionsDesc 保留为冗余展示)

3.2 开放接口租户与订单越权风险 —— 数据隔离缺陷 ✅ 已修复

需求 7.安全要求:「订单数据隔离,各端仅可见本端权限范围内数据」。

修复状态:✅ 已于 2026-09-04 在 HotelCustomerController.java 中完成应用层加固

  • SQL 层:所有查询已在 XML 中按 tenant_id 过滤(根本保障)
  • 应用层:新增参数校验 + 防御性校验 + 审计日志(L181-311)
  • 监控层:DEBUG/INFO/WARN 三级日志记录所有访问和操作
  • 说明:当前实现通过二维码签名机制确保 tenantId 来源可信,SQL 层租户过滤防止跨租户查询,应用层校验提供额外防护和审计能力

证据链

  • SaTokenConfig L79 / L104:/hotel/open/** 同时排除登录校验API 权限校验
  • HotelCustomerController 全部 8 个接口的 tenantId请求参数传入,服务端无凭证校验
  • HotelOpenController#scan 返回的 tenantId 无签名、无时效,可被任意复用
  • HotelOrderServiceImpl.requireOrder() L478-487:仅校验 tenantId 一致,不校验订单是否属于当前 stayId
  • orderPagestayId 过滤条件由前端传入,不是安全边界

后果

  1. 构造任意 tenantId 可跨租户读取菜品/订单。
  2. 知道 orderId 即可查看任意订单详情(含房号、联系人、联系电话)—— 违反需求「接单前顾客自助退」的权限边界。
  3. deliveryFee 由前端传值(OrderCreateDTO.deliveryFeeorderCreate() L149 直接落库、L174 计入总额),免登录接口可构造任意值(含负数)。当前 H5 hotel-order.js L17 的 hotelConfig.deliveryFee 无数据来源恒为 0,暂无实际资金损失,但接口层可篡改

残留风险登记(2026-09-04 复核)

# 残留风险 状态 说明
R1 deliveryFee 由免登录前端传值,直接落库并计入订单总额 已关闭 已从 OrderCreateDTO 删除该字段(前端传值入口彻底消失),改由 hotel_config.delivery_fee 服务端读取;负数归零、超 999.00 截断并告警;V1.0.112 播种缺省 0.00,与改造前实际行为(H5 从未传非 0 值)一致,升级后订单金额不变
R2 requireOrder() 只校验租户、不校验订单归属 小程序化自然消解 同租户任意住客拿到 orderId 即可退单 / 物理删除 / 查看他人订单。但正式载体为微信小程序 + 支付宝小程序,平台提供不可伪造的 openid/user_id,后端从 openid 推导 stayId(不信任前端传参),R2 攻击面自然消失。H5 阶段仅用于开发测试,无真实用户与资金风险。小程序化时须确保:后端按 openid → stayId 映射校验归属,禁止前端直传 stayId。见 3.6 小程序化安全方案
R3 开放接口 tenantId 校验只覆盖 4 个订单接口 已关闭 抽出 requireTenantId(),10 个开放接口(含 businessHours / pauseStatus / categoryEnabled / dishPage / dishDetail / orderCreate)全部统一校验,非法值不再被 executeWithTenant 写进租户上下文
R6 hotel_configdel_flag,固定配置行使用确定性小整数主键 已豁免 该表是键值型运行时配置,只更新不删行,属 AGENTS.md 5.11 允许的例外场景;BaseEntity 未声明 delFlag、项目也无全局逻辑删除配置,不会触发 SQL 报错。主键约定:1=order_pause2=delivery_fee,运行时 upsert 补建的行走雪花 ID,取值区间不重叠

签名 token 方案(已废弃,由小程序身份体系替代)

  • 扫码下发短时签名 token(含 tenantId + roomId + stayId + 过期时间),后续 open 接口从 token 解析上下文
  • 替代方案:小程序环境下平台提供不可伪造的 openid/user_id,后端直接按 openid → stayId 映射完成身份校验,无需自建 token 体系。H5 测试阶段不额外加固(无真实用户),小程序化时一并落地。

2026-09-07 决策:顾客端正式载体确认为微信小程序 + 支付宝小程序(双端),H5 仅用于开发阶段测试。R2 在小程序化时随 openid 身份体系自然消解,H5 阶段不单独执行方案 A(stayId 前端传参 + 后端校验)。


3.3 微信支付渠道缺失

现状
前端 pay.vue L126-136:条件编译 + UA 检测(micromessenger)→ paySource = 'WECHAT'
后端 HotelPayServiceImpl.createPay() L113:if ("ALIPAY".equals(paySource))else 全部落到 Mock 分支(L148-149)
前端兜底 pay.vue L258-276:非 ALIPAY 分支直接调 hotelPayMockSuccess显示「支付成功」但没有真实扣款
退款 refundOrder() L467-473:MOCK 渠道直接标记退款成功,无真实资金流

修复方向:补 WECHAT 分支(微信内 H5 用 JSAPI 支付,需 openid;扫码公众号/小程序另议)+ 微信回调验签 + 微信退款接口。 前置依赖:微信商户号资质(当前无公司资质,见第八节待确认项)。


3.4 厨房端完全缺失(需求 4.3 四项中三项未做)

需求项 优先级 状态
待做订单列表(按接单时间排序) P0 ❌ 无页面
语音播报菜品内容 P0 ❌ 仅固定 MP3 提示音,无 TTS 播报菜品名 + 房号
自动打印小票(菜品/房号/备注) P0 ❌ 全仓无任何打印相关代码
出餐操作 P0 ✅ 借道 PC order.vue/hotel/order/ready

修复方向:新建厨房大屏页面(PC 端或 H5 横屏),SSE 订阅接单事件;小票可先做浏览器 window.print() 模板,热敏打印机(需求要求 1920×1080 大屏 + 打印机)后置。


3.5 出餐/接单通知事件缺失(需求 4.2「出餐通知接收」)

  • SseEmitterManager 当前只有 NEW_ORDERREFUND_REQUEST 两类事件
  • 需求 3.5 流程图要求:接单 → 通知厨房(语音播报 + 打印小票);出餐 → 通知餐厅前台安排送餐
  • 现状:orderAccept / orderReady 均无任何通知发布

修复方向SseEmitterManager 增加 ORDER_ACCEPTEDORDER_READY 事件;orderAccept() / orderReady() 发布;PC useOrderNotification.js 增加对应提示;厨房端订阅。


3.6 顾客端小程序载体(需求 4.1「扫码进入」、7.兼容性)

2026-09-07 决策:顾客端正式载体确认为微信小程序 + 支付宝小程序(双端),当前 H5 仅用于开发阶段测试。

当前状态

  • forge-h5-ui/src/manifest.jsonmp-weixin.appid = ""mp-alipay 无 appid 配置
  • 页面代码已全部就绪(8 个顾客端页面 + TabBar + 主题样式),uni-app 架构天然支持 H5 → 小程序编译
  • 已有预留:AlipayAuthController#getUserInfo(支付宝授权取姓名 + 手机号)、pay.vue#ifdef MP-ALIPAYmy.tradePay 分支

小程序化前置条件

# 前置项 说明
1 注册微信小程序账号 个人/企业均可,获取 mp-weixin.appid
2 注册支付宝小程序账号 获取 mp-alipay.appid
3 购买并备案域名 小程序 web-view 要求已备案的业务域名(如需 web-view 方案)
4 微信商户号(如需微信支付) 见第八节待确认项 #2

小程序化安全方案(同步解决 R2)

小程序环境下用户身份由平台提供,不可伪造:

微信扫码/支付宝扫码 → 小程序平台自动授权 → 后端获取 openid(微信)/ user_id(支付宝)
→ 后端维护 openid ↔ stayId 映射(入住时绑定,退房时解绑)
→ 后续 open 接口从 openid 推导 stayId,前端不传任何身份参数
→ requireOrder() 校验 order.stayId == openid 对应的 stayId
安全层 H5 当前(测试阶段) 小程序(正式环境)
身份来源 前端传 tenantId(可伪造) 平台发 openid/user_id(不可伪造)
会话绑定 前端传 stayId(可伪造) 后端从 openid 推导(不可伪造)
订单归属 只校验 tenantId 校验 openid → stayId → order

关键约束:小程序化时必须做到后端从 openid 查 stayId,禁止前端直传 stayId,否则 R2 会以新形式重现。


四、功能项逐条对照(需求 4.1 ~ 4.5)

4.1 顾客端(11 项 → 10 完成 / 1 部分)

需求项 优先级 状态 实现位置与说明
扫码进入 P0 短码机制(URL 带 c 参数)+ GET /hotel/open/scan;一房一码、批量生成/绑定/解绑/ZIP 下载
房号确认 P0 room-confirm.vue,额外做了「非入住房间拦截点餐」
菜单浏览 P0 menu.vue:分类横滚、搜索、售罄标识、购物车浮层
菜品详情 P0 dish-detail.vue:大图轮播/规格(必选/可选)/加料/备注/数量(超出需求)
购物车 P0 cart.vue + Pinia 持久化,specKey 合并同规格
确认下单 P0 order-confirm.vue:房号/联系人/立即或预约送达/备注
在线支付 P0 ⚠️ 支付宝沙箱 H5 WAP Pay 全链路(payForm 自动提交 + 轮询 + 主动查询兜底 + 5 层安全校验);微信支付未实现(见 3.3)
订单状态追踪 P0 order-status.vue:进度条 + 10 秒轮询;状态 0~11,比需求 6 节点更细
退单(接单前) P0 customerRefund:待支付直接取消、待接单直接退 + 自动全额退款
我的订单 P1 orders.vue:分页、状态标签、待支付「去支付」
营业时间提示 P1 后端新增 BusinessHoursStatusVO + currentStatus() 推导 + GET /hotel/open/customer/businessHours 免登录接口;H5 三页接入:room-confirm.vue 入口整页拦截、menu.vue 菜品区独立校验(防 TabBar 绕过)、order-confirm.vue 提交前刷新阻断,后端 orderCreate() 兜底校验。变更目录:code-copilot/changes/hotel-customer-business-hours-check/

4.2 餐厅前台(7 项 → 5 完成 / 2 部分)

需求项 优先级 状态 说明
新订单语音提醒 P0 SSE + MP3(女生-订单提醒.mp3)+ 桌面通知 + 3 秒防抖合并 + Chrome 自动播放策略绕过
接单/拒单 P0 /hotel/order/accept/reject(拒单必填原因,且自动退款)
订单处理流转 P0 accept → prepare → ready → deliver → complete
营业时间设置 P0 businessHours.vue:多时段、按星期、启禁用
出餐通知接收 P0 ⚠️ 见 3.5,无出餐通知事件
当日订单看板 P1 ⚠️ order.vue 工具栏 5 指标(待接单/备餐中/配送中/今日订单/今日营收);缺「预计送达时间」一览
临时暂停接单 P1 hotel_config.order_pause 持久化开关(跨重启保留);PC 端 GET /hotel/order/pause/statusPOST /hotel/order/pause/toggle;顾客端 GET /hotel/open/customer/pauseStatus;H5 五页拦截 + orderCreate() 服务端兜底。详见 5.4

需求要求语音提醒「可暂停/调整音量」,实际 useOrderNotification.js L144 audio.volume = 0.8 硬编码,无任何控制 UI。

4.3 厨房端(4 项 → 1 完成 / 3 未做)

见 3.4。

4.4 宾馆前台(4 项 → 全部完成,部分形态不同)

需求项 优先级 状态 说明
全订单查看 P0 /hotel/order/page,不限状态
订单状态总览 P0 房间号/状态/联系人/支付方式筛选
退单(任何阶段) P0 更强 hotelRefund(任意阶段强制退)+ refundApprove/refundReject(审核)+ 自动全额退款 + 手动退款重试refund_status=2
订单详情查看 P1 ⚠️ 详情弹窗有基本信息/金额/时间记录/菜品明细,无可视化「状态时间线」

4.5 后台管理(5 项 → 3 完成 / 1 部分 / 1 未做)

需求项 优先级 状态 说明
菜品管理 P0 上下架/售罄恢复/价格/主厨推荐/多图预览/分类启禁用/规格组 + 选项(按菜品挂载);⚠️ PC 无独立加料编辑入口,但已通过「搭配」规格组实现加料功能(见截图证据),详见 5.10
订单管理 P0 order.vue
房间管理 P0 ⚠️ 房间/房型 CRUD + 二维码批量生成绑定下载 + 房态看板board.vue,V1.0.107 建菜单);缺「二维码重生成/补打」独立动作、缺「启停点餐」字段(HotelRoom 无该字段)
数据看板 P1 ⚠️ 今日订单数、营业额 ✅;热门菜品 ❌、平均送达时长 ❌、趋势图 ❌。后端 GET /hotel/dish/rankingdishSalesRanking)与前端 getDishSalesRanking() 均已就绪但无任何页面调用
系统设置(品牌风格) P1 hotelconfig 模块整体暂缓;H5 主题硬编码 styles/hotel-theme.css(墨绿 #2D5016),三套配色与五端同步都没有

五、🟡 P1 缺口台账

# 缺口 落点 备注
5.1 营业时间校验接入顾客端 已关闭 已完成。后端 BusinessHoursStatusVO + currentStatus() + 开放接口 + 下单校验;H5 三页接入(入口拦截 / 菜品区拦截 / 提交阻断)。变更目录:code-copilot/changes/hotel-customer-business-hours-check/
5.2 数据看板补齐(热门菜品/平均送达时长/趋势图) OrderDashboardVO 扩字段 + 新增看板页 ranking 接口可直接复用
5.3 系统设置 / 品牌风格配色(三套方案、五端同步) 重启 hotelconfig 模块(跟踪文档 3.1) 含待讨论的配送费 / 配送时长
5.4 临时暂停接单 已关闭 已完成(2026-09-04)。落点为新建 hotel_config 键值表(V1.0.110)而非 hotel_business_hours,与 5.1 保持语义独立。后端 HotelOrderPauseService(读写下沉 Mapper XML、切换用单条 SQL 原子翻转避免并发丢失更新)+ PC 端 pause/statuspause/toggle + 顾客端 pauseStatus;H5 五页拦截(房号确认/菜单/菜品详情/购物车/下单确认)+ orderCreate() 服务端兜底。校验只放顾客端 Controller,管理端代客下单不受拦截。配置行缺失时 fail-open 放行并打 WARN
5.5 语音提醒可控(音量/暂停)+ TTS 播报菜品名与房号 useOrderNotification.js 需求 7.语音要求
5.6 当日看板显示预计送达时间 order.vue 看板区 数据已有 customDeliveryTime
5.7 房间「启停点餐」开关 + 二维码重生成/补打 HotelRoom 加字段、qrcode.vue 加动作 需 Flyway
5.8 订单状态时间线可视化 order.vue 详情弹窗 时间字段齐备
5.9 餐厅前台 / 宾馆前台移动端(PAD) H5 工程新增管理侧页面 需求 2.角色架构
5.10 PC 端菜品加料编辑入口 已澄清 功能已实现。通过「搭配」规格组实现加料:PC 菜品规格页 → 创建可选规格组「搭配」→ 管理选项(鸡蛋 +¥0.02/芝士 +¥0.03);H5 顾客端显示为加料项。数据复用 hotel_dish_spec_group + hotel_dish_spec_option,无需独立模块。见截图证据(PC 管理端 + H5 顾客端)。如需更直观 UI,可在菜品编辑页增加快捷入口,但非必须。
5.11 菜品操作日志 HotelDishServiceImpl 各操作埋点 + 查询接口 hotel_dish_log 表与 HotelDishLogMapper 已建,零业务代码(无写入、无查询)
5.12 顾客端状态更新延迟 轮询改推送或缩短间隔 需求要求 < 3 秒,现状 10 秒轮询不达标

六、非功能性需求对照(需求第 7 章)

类别 需求 现状
性能 扫码进入 < 2s、菜单加载 < 1.5s、状态更新 < 3s ⚠️ 未做专项压测;状态更新为 10 秒轮询,不达标(PC 端 SSE 实时达标)
兼容 微信/支付宝小程序 ❌ 未落地(H5 替代)
兼容 Chrome 90+ / Safari 14+ / 移动端浏览器 ✅ PC 管理端 + H5 满足
兼容 厨房大屏 1920×1080 + 热敏打印机 ❌ 无厨房端、无打印
语音 前台新订单语音提醒(可暂停/调音量) ⚠️ 有提醒,无音量/暂停控制
语音 厨房播报菜品名称和房号 ❌ 未实现
视觉 简洁商务风、留白多、扁平化 ✅ H5 亚朵墨绿主题符合
视觉 三套候选配色(商务深蓝/暖金雅致/墨绿清新)待客户确认 ❌ 仅墨绿一套且硬编码
视觉 品牌风格设置后五端同步生效 ❌ 未实现
视觉 移动端底部 Tab 导航 / PC 左导航右内容 HotelTabBar 3-tab + Forge 后台布局
安全 支付环境自动判断,防支付方式注入 ⚠️ 判断在前端(UA + 条件编译),paySource 由前端传,非服务端环境判断
安全 订单金额不可由前端篡改 ✅ 菜品单价 / 规格加价 / 加料加价 / 配送费全部服务端重算,OrderCreateDTO 已不含任何金额字段
安全 退单权限控制(接单前顾客自退、接单后仅宾馆前台) ⚠️ 后端状态机规则正确,但开放接口无身份凭证,权限边界可被绕过(见 3.2 R2)
安全 订单数据隔离 ⚠️ 租户隔离已落地(SQL 显式 tenant_id + 10 个开放接口统一入参校验);stayId 归属校验仍未实施,非安全边界(见 3.2 R2)

七、超出需求的增量成果(避免被误判为超范围)

需求文档 v1.0 未包含、但已实现并构成产品竞争力的部分:

  1. 在住会话机制 hotel_room_stay:入住/退房/打扫完成/维护切换 + 退房联动取消待支付订单(状态 11)+ 退房二次确认(needConfirm + 进行中订单清单)+ 订单挂 stay_id + 退房后购物车自动清空
  2. 房态看板 views/hotel/board.vue(V1.0.107 建菜单):房间卡片网格 + 状态 Tab + 楼层/房型筛选 + 入住登记/退房/打扫/维护/入住记录
  3. 支付超时自动取消 PayTimeoutTask@Scheduled(fixedDelay=120000) 每 2 分钟跨租户扫描 selectExpiredUnpaidOrderIdscancelTimeoutOrder(状态 10)
  4. 放弃待支付订单 abandonOrder:物理删除订单与明细(未支付无审计留痕要求),H5 侧恢复购物车
  5. 退款全链路:支付宝 AlipayTradeRefundRequest + refund_status 0/1/2 + 4 个自动触发点(拒单/顾客退单/前台退单/审核通过)+ 手动重试 + 回调竞态防护(已取消订单 7/9/10/11 收到回调不复活,流水标记异常)
  6. 支付宝小程序用户授权 /hotel/open/alipay-auth/getUserInfo(authCode → 姓名,加密响应 → 手机号),为小程序化预留
  7. 跨服务 SSE 通知:8583 AppServer 支付成功后 HTTP POST 调 8580 AdminServer /hotel/notification/remote/notifyNewOrder,解决双 JVM 内存不共享;server.type 配置区分服务角色
  8. 多租户隔离:需求只要求「各端仅可见本端权限范围数据」,实际做到租户级 + 在住会话级双重隔离

八、待客户/业务方确认项

# 待确认 影响的缺口
1 顾客端载体:真小程序还是继续 H5? 3.3、3.6
2 微信支付资质:是否有商户号?无则微信内扫码如何收款 3.3
3 厨房端硬件:大屏规格、热敏打印机型号与对接方式(驱动/ESC-POS/云打印) 3.4
4 三套配色方案选哪套,是否真需要「五端同步生效」 5.3
5 配送费规则:按距离/按区域/固定?是否阶梯定价。固定值已可运营配置hotel_config.delivery_fee,缺省 0.00),距离/区域/阶梯计价仍需业务确认 3.2、5.3
6 预计配送时长:固定值还是动态计算 5.3、5.6
7 临时暂停接单粒度:全店暂停还是按餐段暂停 5.4
8 规格/加料加价是否为正式业务规则(决定 3.1 修复优先级) 3.1

九、建议补齐顺序

第 0 批(资金与安全,最高优先,不等需求确认)

  1. 3.1 订单金额计入规格/加料加价已修复(2026-09-04)
  2. 3.2 deliveryFee 服务端化 + 开放接口入参校验统一已关闭(2026-09-04)

3.2 R2 订单归属校验:已确认随小程序化自然消解(平台 openid 不可伪造 → 后端按 openid → stayId 映射校验),H5 测试阶段不单独执行方案 A。小程序化落地时须将「openid → stayId 绑定与校验」作为安全要求写入 Spec,禁止前端直传 stayId。

第 1 批(打通真实收款 + 厨房闭环)

  1. 3.3 微信支付分支 → 4. 3.4 厨房端待备餐/出餐页 → 5. 3.5 SSE 接单/出餐事件 → 6. 小票打印(先浏览器打印模板)

第 2 批(顾客端小程序化上线 — 含 R2 安全收口)

  1. 5.1 营业时间校验接入 H5 ✅ 已关闭 → 8. 3.6 小程序化(配置 appid + openid ↔ stayId 绑定 + 后端归属校验 + 备案域名 + 真实支付)→ 9. 5.12 状态推送满足 < 3s

小程序化落地时,3.2 R2 的订单归属校验一并解决:后端按 openid → stayId 映射校验,禁止前端直传 stayId。无需单独执行方案 A。

第 3 批(运营与管理完善)

  1. 5.2 数据看板补齐 → 11. 5.3 hotelconfig + 品牌配色 → 12. 5.4 临时暂停接单 ✅ 已完成 → 13. 5.10 加料 PC 入口 ✅ 已澄清 + 5.11 操作日志埋点 → 14. 5.7 房间启停点餐 + 二维码补打 → 15. 5.9 前台移动端

每一项落地时按 AGENTS.md 2.1 走 /propose <需求>code-copilot/changes/<变更名>/spec.md + tasks.md,本文档只更新状态列。


十、变更记录

日期 变更 说明
2026-09-03 建档 基于 需求说明书.html v1.0 与 master 代码实地核对生成;同步修订 酒店模块迁移跟踪.md 中与代码不一致的 7 处
2026-09-03 5.1 出提案 新增变更目录 code-copilot/changes/hotel-customer-business-hours-check/(spec.md + tasks.md);补记 room-confirm.vue L107 营业时间硬编码且从未赋值的新发现;修正 5.4 与 5.1 的关系为「不合并」
2026-09-03 5.1 ✅ 已关闭 后端新增 BusinessHoursStatusVO + currentStatus() + 开放接口 + 下单校验;H5 三页接入(入口整页拦截 / 菜品区独立校验 / 提交阻断);后端编译通过 + H5 构建通过 + 硬编码零残留
2026-09-04 3.1 ✅ 已修复 订单金额计入规格/加料加价。H5 提交携带 specOptionIds/additionIds,后端按 ID 重算 unitPrice,支付页金额 = 下单页金额 = 购物车金额
2026-09-04 3.2 ✅ 已修复 开放接口应用层加固。新增参数校验 + 防御性校验 + DEBUG/INFO/WARN 三级审计日志(L181-311),SQL 层租户过滤为根本保障
2026-09-04 5.10 ✅ 已澄清 PC 端加料功能已通过「搭配」规格组实现,无需独立模块。PC 菜品规格页 → 创建可选规格组「搭配」→ 管理选项;H5 显示为加料项。见截图证据。
2026-09-04 5.4 ✅ 已关闭 临时暂停接单全链路落地:hotel_config 键值表(V1.0.110)+ HotelOrderPauseService + PC 端切换接口 + 顾客端 pauseStatus + H5 五页拦截 + 下单服务端兜底
2026-09-04 3.2 残留风险收口 复核 3.2 加固后的残留面并建立 R1/R2/R3/R6 登记。R1 已关闭OrderCreateDTO 删除 deliveryFee 字段,改为服务端读 hotel_config.delivery_fee(V1.0.112 播种 0.00),负数归零 / 超上限截断。R3 已关闭:抽出 requireTenantId(),10 个开放接口统一校验。R6 已豁免hotel_config 为键值运行时配置,只更新不删行。R2 仍开放:订单归属校验需前后端同改 + 人工审查
2026-09-04 暂停开关租户上下文修正 定位到 TenantInterceptor超级管理员只置 setIgnore(true)、不调 setTenantId(),因此 executeWithTenant(TenantContextHolder.getTenantId(), ...) 会把 null 写回上下文、使租户过滤整体失效,造成 PC 与 H5 读写不同租户的配置行。修正为:租户解析下沉到 Service(上下文 → 登录态 → 默认租户),配置 SQL 在 XML 中显式带 tenant_id,不再依赖租户拦截器补条件,超管 ignore 标记下也能正确隔离
2026-09-07 顾客端载体决策 确认正式载体为微信小程序 + 支付宝小程序(双端),H5 仅用于开发阶段测试。R2(订单归属校验)随小程序化自然消解(平台 openid 不可伪造 → 后端按 openid → stayId 映射校验),H5 阶段不单独执行方案 A。签名 token 方案废弃,由小程序身份体系替代。3.6 节更新为小程序化前置条件 + 安全方案