文件
hl-api-changelog/changelogs-v2/2026-10/02_8662_询房预览补权限-修改接口-管理后台.md
T
API Changelog Bot和Claude Opus 5.5 cdcd07d8e5
changelog-filename-gate / validate (push) Failing after 1s
docs(changelog): #8659 房务价格日历与库存口径统一 / #8662 删除旧住宿需求提交口与询房预览补权限
- #8659:候选页 inventoryStatus 按日历状态取值;控房表新增 calendarStatus / calendarStatusName(前端加一列展示);扣减拒绝分 808906 / 808907 / 808901。
- #8662:删除 PUT /v3/admin/order/{id}/hotel-requirement;询房预览补房务读守卫,非房务角色返回 808090。

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 01:15:08 +08:00

9.6 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 8662 询房预览接口补房务读守卫 admin wx(GIT) 修改接口 deployed not_required not_required 2026-10-02 dev-v3

询房预览接口补房务读守卫

存放目录: 二期 → changelogs-v2/2026-10/

服务: hl-order-service-v3 Issue: #8662 日期: 2026-10-02 影响范围: 管理后台房务询房话术预览功能


⚠️ 关键变化

  • 接口 POST /v3/admin/order/inquiry/preview 新增房务读守卫。
  • 非房务角色(定制师、管理员、其他后台角色)调用返回 808090「未登录或非房务角色,无权操作」。
  • 房务角色(房务管理员、超管)放行,功能无改动。

一、背景

二期房务功能收口中,#8390 统一给 16 个旧只读端点(日历 / 房务详情 / 酒店视图 / 转单候选 / 待办 / 月度对账 / 旧抢单池 / 订单房间)挂上房务读守卫,唯独询房话术预览这一个接口漏过,导致定制师、运营等非房务角色能调通,拿到酒店联系人与微信(源码:HouseReadGuard.java 类 javadoc)。本次补上后,受此守卫覆盖的端点共 17 个。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 询房话术预览 POST /v3/admin/order/inquiry/preview 修改 新增房务读守卫,非房务角色返回 808090

三、接口详情

1. 询房话术预览 POST /v3/admin/order/inquiry/preview

VO: InquiryPreviewReqVO → InquiryPreviewRespVO

使用场景

房务在配房弹窗点击「询房」时预览即将发往酒店的话术(所见即所发),确认无误后复制到企业微信。本次修改:非房务角色被拒。

入参

字段 位置 类型 必填 约束 说明
hotelId Body Long ✅ - 酒店 ID;按此取 resource 联系人渲染文案
orderId Body Long ❌ - 订单 ID(取团号);assignmentId 有效时以其所属订单为准
assignmentId Body Long ❌ - 配房 ID;存在且与 hotelId 匹配时,日期/房型/间数/支付方式优先取该配房快照
stayDate Body LocalDate ❌ - 入住日期;assignmentId 命中时被快照值覆盖
roomCount Body Integer ❌ ≥1 房间数;assignmentId 命中时被快照值覆盖;都缺省时按 1 间渲染
roomCategory Body String ❌ 字典 room_category 房型类别;assignmentId 未命中时用于查房型中文名,查不到则原样回退为传入的 code

出参 Result<InquiryPreviewRespVO>

字段 类型 说明
messageBody String 渲染后的固定格式订房确认话术(模板见下)
contactName String 联系人姓名,resource 按 hotelId 带出,前端只读回显
contactWechat String 联系人微信号,resource 按 hotelId 带出,前端只读回显

话术固定模板(InquiryMessageTemplate.SEND_BASE,占位符按 Map 渲染,缺失值替换为空串):

呼籁旅行 - 订房确认书:
团号:${teamNo}
日期:${stayDate}
房型:${roomTypeName}${roomCount}间
备注:${tags}
1.${paymentText},价格保密。
2.${breakfastText}${invoiceText}
3.核房电话:${phone}
辛苦确认后回复 @${replyContacts}

请求示例

{
  "hotelId": 1900000001,
  "orderId": 1900000000,
  "stayDate": "2026-04-28",
  "roomCount": 1
}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "messageBody": "呼籁旅行 - 订房确认书:\n团号:HL20261001A\n日期:4.28\n房型:待补充1间\n备注:协议酒店\n1.领队前台现付,价格保密。\n2.含早含发票\n3.核房电话:0470-8888888\n辛苦确认后回复 @王前台",
    "contactName": "王前台",
    "contactWechat": "hailar_holiday"
  },
  "success": true
}

上例未传 roomCategory、也未传 assignmentId,roomTypeName 按规则取不到任何来源,渲染为空缺省文案(源码常量 EMPTY_VALUE_TEXT)——${roomTypeName}${roomCount}间 模板不插空格,故渲染结果是该空缺省文案与 1间 的无分隔拼接(见上方 JSON 示例的 messageBody),前端如需展示分隔需自行处理,后端不改模板。日期按 M.d 格式渲染(无补零),2026-04-28 → 4.28。ID、团号、酒店联系人等取值均为说明用的构造值。

空数据 / 降级响应

  • 酒店联系信息查询抛异常(loadHotelExtended 捕获全部 RuntimeException):静默降级,contactName/contactWechat 返回空字符串 ""(不是 NULL),messageBody 仍正常渲染,缺省字段分别落空值常量(EMPTY_VALUE_TEXT)/空标签常量(EMPTY_TAG_TEXT)/现付默认文案。
  • assignmentId 传了但查不到记录、或与 hotelId 不匹配:静默降级为按请求参数 + 资源数据重新生成(不报错,仅记一条 log.warn),不是 assignment 快照。
  • assignmentId 命中但与请求里的 orderId 不一致:忽略请求 orderId,改用该配房记录的真实 orderId(同样静默降级,仅记日志)。
  • 不落库,房务可反复调用,无状态。

错误响应

{
  "code": 808090,
  "message": "未登录或非房务角色,无权操作",
  "data": null,
  "success": false
}

其他错误:

code message 触发
400 hotelId 不能为空 hotelId 未传
400 房间数最小为 1 roomCount 传了但 < 1

业务边界

  • 只校验角色(房务管理员/超管放行),不校验订单归属:房务可预览任意订单的询房话术,与 #8390 覆盖的其余 16 个只读端点行为一致。
  • 该守卫只拦「有角色但非房务」;零角色账号(网关未透传 X-Admin-Role)按既有口径仍放行,不受本次改动影响(HouseReadGuard.java 类 javadoc,#7609 G-2 定案)。
  • 预览不落库,无副作用,可反复调用。
  • contactWechat 仅供复制,前端不做交互(不拨电话、不主动跳转)。

四、契约约束与正确调用方式

权限对照

角色 改前 改后 说明
房务管理员 200 放行 200 放行 无改动
超管 200 放行 200 放行 无改动
定制师(CUSTOMIZER) 200 放行(缺陷) 808090 拒绝 新增限制
其他后台角色(如 ADMIN) 200 放行(缺陷) 808090 拒绝 新增限制
零角色账号(网关未透传 X-Admin-Role) 放行 放行 无改动(#7609 G-2 口径,本次刻意不收)

五、数据库行为

不落库,本接口无数据写入。


六、边界行为

  • 错误码 808090 与所有同域房务读端点保持一致,可统一处理。
  • 权限守卫受 Nacos 开关 group-batch.acl.enforce.house-read-role 控制。测试服 2026-09-30~10-02 期间该开关为开启状态(实测 ADMIN/CUSTOMIZER 均返回 808090,见「八、测试环境已验证」);生产环境以当时的配置为准,前端按本文档的错误码契约接即可,无需关心开关本身的开关状态。

六.5 枚举

不适用(接口无新增枚举)。


六.6、修改前后对比

项 改前 改后
权限校验 ❌ 无房务守卫,任何角色可调 ✅ 新增房务读守卫,非房务返回 808090
功能逻辑 预览话术、返回联系人 不变(仅权限改动)

六.7、影响评估

  • 前端无需改动:经 hl-ui v2.1 核实,该接口的封装函数(src/api/housekeeper/inquiry.js 的 previewInquiry)仅有一处调用——src/views/housekeeper/components/useHousekeeperInquiryCopy.js,位于房务专属视图目录下,本就只在房务角色登录后的界面里被触达。非房务角色(定制师等)侧没有调用这个接口的代码,本次收紧权限不会让任何现有页面报错。

七、不影响范围

  • 房务配房流程(使用此接口的场景)功能不变。
  • 小程序端、H5 端接口无改动。
  • #8390 已覆盖的其余 16 个旧只读端点本身无行为变化,本次只是把本端点补入同一套守卫。

八、测试环境已验证

测试服环境,2026-09-30~10-02,经网关实测,与修前基线逐字段比对(基线快照:p50_ac3_room_manager.json/p50_ac3_super_admin.json;本轮:p6_ac3_roommanager.json/p6_ac3_superadmin.json/p6_ac3_admin.json/p6_ac3_consultant.json)。

POST /v3/admin/order/inquiry/preview
  房务管理员(ROOM_MANAGER):200,messageBody/contactName/contactWechat 与修前基线逐字节相同 ✓
  超管(SUPER_ADMIN):200,messageBody/contactName/contactWechat 与修前基线逐字节相同 ✓
  管理员(ADMIN):808090 未登录或非房务角色,无权操作 ✓
  定制师(CUSTOMIZER):808090 未登录或非房务角色,无权操作 ✓

十、相关文档

  • Issue: #8662
  • PR: #8705
  • 背景工单: #8390(原覆盖 16 个读端点统一守卫,本次 #8662 补上第 17 个——即本端点)

关联 / 联系人

关联工单: #8662
同批删除: 旧住宿需求提交接口
后端负责人: @wx