文件
hl-api-changelog/changelogs-v2/2026-09/27_8401_房务配房台账联动——确认缺团号拒绝808188、清空锁定行拒绝599602-修改接口-管理后台.md
T

19 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 8401 房务配房台账联动:确认缺团号拒绝、清空/改价审计应付行 admin wx(GIT) 修改接口 deployed verified not_required PR #8402 已合入 dev-v3(合并提交 57199b539);2026-09-27 部署测试环境并经网关实测 AC-1 至 AC-4;pre-flight 核对部署 COMMIT=57199b539 STATE=ok【2026-09-27 mmg】前端判 not_required(零代码):808188/599602 grep 前端零引用无错误码字典;五个配房写口全走标准 http 封装无 silentError,消费方三 composable catch 均由 request.js 拦截器统一弹 message(该拦截器对 4xxxxx/5xxxxx 全业务码透 body.message);改价/删除改前本就抛 599600/599601 前端零按码处理,599xxx 同路;§6.7 自述「前端 100% 透明」与实证一致,建议文案「请先完成收款/联系财务解冻」是 UX 建议非契约,后端 message 已可达因。 2026-09-27 dev-v3

房务配房台账联动:确认前置关卡、改价/清空应付行审计

服务: hl-order-service-v3 PR: #8402 | Issue: #8401 | 合并提交: 57199b539 影响范围: 管理后台「房务配房工作台 → 配房确认、改价、删除、清空」、应付款台账行联动


⚠️ 关键变化

确认配房前新增团号检查;改价、删除、清空配房时对应付款台账行作同事务作废与冻结校验。

三类场景导致配房行 CONFIRMED 但缺应付台账行或行被占用:

场景 原行为 新行为
确认配房时团号未生成(收款前) 200 成功但不推台账 拒绝,新错误码 808188
改价/删除该行时其无台账 改前 599601、删前 599601 改后 200(只改价不补推);删后 200(正常软删)
改价/删除/清空时台账被占用 各自独立校验 统一 599602「应付款台账行已锁定」

契约边界:改价只是数值标度不同(265 vs 265.00)不再视作改价,应付行不作废。


一、背景

房务配房成立应付款「该付供应商的钱」的凭据,必须在确认时同事务落应付款台账行。多轮测试发现三处漏洞:

  1. 无团号可确认:订单未收款时 team_no 为空,确认应该被拒,原实现放行确认但不推台账,留下「CONFIRMED 但无台账」。
  2. 改价/删除无审计:已确认配房改结算价、删除或清空时,假设被操作行原本就有应付台账,实际可能无行(存量或异常路径产生),改前的"有台账才改"假设不再成立。
  3. 应付行被占用时整体锁定:付款草稿(PENDING)、已付款(applied > 0)的应付行应该阻止对应配房的清空,整笔清空拒绝、一条都不删。

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 单日确认配房 POST /v3/admin/order/hotel-requirements/{requirementId}/assignments/days/{dayNumber}/confirm 行为变更 订单 team_no 为空时拒绝,新错误码 808188;配房行保持 INQUIRING,不生成应付台账
2 修改单条配房 PUT /v3/admin/order/assignments/{id} 副作用变更 改结算价时,原无应付台账行的只改价不补推;原有台账行的作废旧行按新价重推;只是标度不同不视作改价
3 删除配房 DELETE /v3/admin/order/assignments/{id} 副作用变更 已确认但无应付台账行的配房删除不再报 599601,正常 200 软删
4 清空整需求配房 DELETE /v3/admin/order/hotel-requirements/{requirementId}/assignments 校验变更 清空时同步作废已确认配房的应付台账行;台账行被占用时整体拒绝 599602
5 清空某天配房 DELETE /v3/admin/order/hotel-requirements/{requirementId}/assignments/days/{dayNumber} 校验变更 同接口 4,按日分流

三、接口详情

1. 单日确认配房 POST /v3/admin/order/hotel-requirements/{requirementId}/assignments/days/{dayNumber}/confirm

VO: AssignmentDayConfirmReqVO

使用场景

房务配房工作台选择该天候选配房后点「确认」,调用该接口保留选中行、软删落选行、推送应付款台账。

入参

字段 位置 类型 必填 约束 说明
requirementId Path Long ✅ — 房型需求 id
dayNumber Path Integer ✅ ≥1 第几晚(从 1 开始)
keepAssignmentIds Body List<Long> ❌ 非空时每个 id 须属于该天候选 要保留确认的配房行 id;缺省为空(保留全部)

出参 Result<Void>

字段 类型 说明
data Null 无返回体

请求示例

{
  "keepAssignmentIds": [2104045881147965442]
}

响应示例

确认成功:

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": null
}

空数据 / 降级响应

入参 keepAssignmentIds 为空时视为保留该天全部候选,该天无候选时返回 808118:

{
  "code": 808118,
  "message": "该天无可确认的询房中候选, 请先配房再确认",
  "success": false,
  "data": null
}

错误响应

新增错误码 808188:订单团号未生成(收款前)时拒绝确认:

{
  "code": 808188,
  "message": "订单团号未生成(收款后生成),暂不能确认配房",
  "success": false,
  "data": null
}

保留的配房行不属于该天候选时 fail-fast 拒绝:

{
  "code": 808123,
  "message": "保留的配房行不属于该天询房中候选(可能配房已更新), 请刷新后重试",
  "success": false,
  "data": null
}

业务边界

  • 团号检查:CORE 订单检查 order_main.team_no 非空;GROUP 订单检查班期 batch_no(列定义 NOT NULL,实际打不到)
  • 台账推送时点:确认成功后即事务内推送应付款 NORMAL 行,金额 = settlementPrice × roomCount,团号为键
  • 并发场景:后到的确认请求仍可能收到 599601(两个请求并发取消同一行时)
  • 幂等性:同 (requirementId, dayNumber) 3 秒内重复确认拒绝
  • 存量一致性:确认不改变 SQL 求交逻辑,该天无 INQUIRING 候选照旧报 808118

2. 修改单条配房 PUT /v3/admin/order/assignments/{id}

VO: AssignmentUpdateReqVO

使用场景

房务工作台配房行改价/备注/支付方式时调用;路径参数、出参结构、签名、权限均未变。

入参

字段 位置 类型 必填 约束 说明
id Path Long ✅ — 配房行 id(house_hotel_assignment.id)
protoPrice Body BigDecimal ❌ ≥0 原始供应商报价
settlementPrice Body BigDecimal ❌ ≥0 结算价(现在改后作废旧台账行)
settlementMethod Body String ❌ 枚举值 支付方式
remark Body String ❌ — 备注

出参 Result<Void>

字段 类型 说明
data Null 无返回体

请求示例

改结算价:

{
  "settlementPrice": "380.00",
  "remark": "协议优惠"
}

响应示例

改价成功(原无应付台账行,只改价不补推):

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": null
}

空数据 / 降级响应

无特殊空数据;行不存在或权限不足时返回对应业务码。

错误响应

应付款台账行已被占用(付款申请占用或已付款):

{
  "code": 599602,
  "message": "应付款台账行已锁定",
  "success": false,
  "data": null
}

业务边界

  • 改价判定:值的数值部分不同才视作改价(265.00 与 265.000 视同不改),例如 380.00 → 390.00 才作废旧台账
  • 无台账行的改价:仅改配房行,不补推台账行(存量中部分 CONFIRMED 配房原本就无台账)
  • 有台账行的改价:作废旧 NORMAL 行 + 按新价重推新行(仅限该配房对应的台账)
  • 新价校验:若新价导致 settlementPrice × roomCount ≤ 0,重推 fail-fast 报 599600(与改前逻辑一致)
  • 并发场景:改价与删除/清空并发时,清空可能因台账被占用而拒,改价则进行中

3. 删除配房 DELETE /v3/admin/order/assignments/{id}

VO: StaffAssignmentVO

使用场景

房务工作台删除单条配房行;路径参数、出参结构、签名、权限均未变。

入参

字段 位置 类型 必填 约束 说明
id Path Long ✅ — 配房行 id

出参 Result<Void>

字段 类型 说明
data Null 无返回体

请求示例

DELETE /v3/admin/order/assignments/2100873375659266050

响应示例

删除成功:

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": null
}

空数据 / 降级响应

行不存在或权限不足时返回 808120 或 808110。

错误响应

应付款台账行已被占用:

{
  "code": 599602,
  "message": "应付款台账行已锁定",
  "success": false,
  "data": null
}

业务边界

  • 已确认无台账的删除:改前报 599601,改后正常 200 软删(存量或异常路径产生的 CONFIRMED 无台账行)
  • 已确认有台账的删除:行被占用时报 599602,阻止删除;未被占用时正常软删并同步作废应付行
  • 幂等性:同一行删除后重删报 808120(行已软删、再读不到)
  • 与清空互斥:单行删除与整需求/整天清空互斥,串行化执行

4. 清空整需求配房 DELETE /v3/admin/order/hotel-requirements/{requirementId}/assignments

VO: AssignmentClearRespVO

使用场景

房务工作台清空整个住宿需求下全部配房行,调用该接口一次性清空、同步作废应付台账。

入参

字段 位置 类型 必填 约束 说明
requirementId Path Long ✅ — 房型需求 id

出参 Result<AssignmentClearRespVO>

字段 类型 说明
clearedCount Integer 清空行数

请求示例

DELETE /v3/admin/order/hotel-requirements/2104045736624820226/assignments

响应示例

清空成功:

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "clearedCount": 2
  }
}

空数据 / 降级响应

需求无配房行时 clearedCount=0,接口仍 200:

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "clearedCount": 0
  }
}

错误响应

清空范围内任一配房的应付台账行被付款申请占用或已付款,整体拒绝(一条都不删):

{
  "code": 599602,
  "message": "应付款台账行已锁定",
  "success": false,
  "data": null
}

业务边界

  • 整体性:检查待清空全部 CONFIRMED 行的应付台账,任一被占用则整笔拒绝(失败时零行被删)
  • 应付行同步作废:清空成功后同事务作废该需求对应的全部 NORMAL 台账行(无论是否被占用)
  • 不动抢单:清空仅删配房,不释放抢单人、不回抢单池
  • 幂等性:同需求 3 秒内重复清空拒绝
  • 部分被占用的场景:假设需求 2 个 CONFIRMED 行,其中 1 个台账被占用,整批拒、2 行都保留

5. 清空某天配房 DELETE /v3/admin/order/hotel-requirements/{requirementId}/assignments/days/{dayNumber}

VO: AssignmentClearRespVO

使用场景

房务工作台行程日行内「清空」按钮,调用该接口清空该天全部配房,无关其他天。

入参

字段 位置 类型 必填 约束 说明
requirementId Path Long ✅ — 房型需求 id
dayNumber Path Integer ✅ ≥1 第几晚(从 1 开始)

出参 Result<AssignmentClearRespVO>

字段 类型 说明
clearedCount Integer 清空行数

请求示例

DELETE /v3/admin/order/hotel-requirements/2104045736624820226/assignments/days/1

响应示例

清空成功:

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "clearedCount": 1
  }
}

空数据 / 降级响应

该天无配房行时 clearedCount=0,接口仍 200:

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "clearedCount": 0
  }
}

错误响应

该天清空范围内任一配房的应付台账行被占用,整体拒绝:

{
  "code": 599602,
  "message": "应付款台账行已锁定",
  "success": false,
  "data": null
}

业务边界

  • 按日分流:仅清空该天配房,不影响其他晚次
  • 应付行同步:清空成功后同事务作废该天对应的应付台账行
  • 台账冻结:该天任一台账被占用,整天清空拒绝
  • 幂等性:同 (requirementId, dayNumber) 3 秒内重复清空拒绝
  • 与单行删除互斥:整天清空与单行删除由同一分布式锁保护

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

  • 团号时点:收款后(manual-receipt 或 transition 路径产生团号),确认前 team_no 必须非空
  • 应付台账键:落库应付行时以 team_no 为业务键,确认失败时台账行零行存在
  • 改价与标度:小数点后补零(265 → 265.00)不视作改价,应付行不变;需财务的驳回或重新定价时前端提示「联系财务调整」
  • 台账被占用判定:fin_payable_line.applied > 0(付款申请已占用)或支付单已删除但 applied 未清零时视作被占用
  • 清空原子性:清空失败为原子操作,检查与删除在同一事务内,失败时零行被删
  • 权限一致性:全部接口遵循现有权限校验规则,本单无权限变更

五、数据库行为

无 DDL、无迁移、无新增列。行为变化:

表 列 变化
house_hotel_assignment confirm_status 确认拒绝 808188 时保持 INQUIRING(不翻态)
fin_payable_line — 改价/删除/清空时按新规则作废旧行(deleted_at = 当前时刻)
fin_payable_line applied 作废时 applied 不清零,保留历史记录
其他表 — 无变化

���、边界行为

  • 确认前团号为空 → 808188,拒绝,配房行保持 INQUIRING,台账零行
  • 改价无台账行 → 200,只改配房行
  • 改价有台账行 → 200,作废旧行按新价重推
  • 改价新价非法 → 599600,与改前一致
  • 删除无台账行 → 200,正常软删
  • 删除有台账被占用 → 599602,拒绝
  • 清空全部被占用 → 599602,整批拒
  • 清空部分被占用 → 599602,整批拒(一条都不删)

六.5、枚举 / 数据字典

本次新增错误码 808188 HOUSE_TEAM_NO_MISSING:「订单团号未生成(收款后生成),暂不能确认配房」。

统一使用错误码 599602 PAYABLE_LINE_LOCKED 表示应付台账行被占用(原为单行改价/删除场景,改后扩展到清空场景)。

六.6、修改前后对比

项 变更前 变更后
无团号确认 200 成功但不推台账 808188 拒绝
无台账改价 599601 回滚 200 成功(只改价)
无台账删除 599601 回滚 200 成功(正常删除)
有台账改价 599601 / 200 异常组合 200 成功(作废旧+新推)
清空整需求 无台账冻结校验 任一被占用则整体拒
清空按天 无台账冻结校验 该天任一被占用则整天拒
台账占用拒绝码 599602(单行)/ 零(清空) 统一 599602
路径、入参、出参结构 — 全部不变

六.7、影响评估

维度 评估
兼容性 对前端 100% 透明。路径、入参、出参结构、HTTP 方法均未变;行为变更仅增加拒绝场景(无团号确认、台账被占用),不破坏现有成功调用
前端 无需改动。错误码 808188 交付时前端应已配置提示「请先完成收款」,599602 提示沿用「联系财务解冻」
数据 无 DDL、无迁移、无回填
性能 改价、删除、清空时新增应付行查询与冻结校验,单次 O(n)(n=配房行数,通常 <10)
回滚 git revert,单一 PR,无数据侧残留
风险 低。前置检查只能降低風险、不会升高;应付行作废改为同事务内原子操作,消除中间态

七、不影响范围

  • 零影响:所有接口的路径、HTTP 方法、入参结构
  • 零影响:出参结构(均为 Result 或 Result)
  • 零影响:权限校验、鉴权闸口
  • 零影响:库存扣减逻辑(确认失败不改库存,改价/删除不再动库存)
  • 零影响:房型快照、房型冻结逻辑
  • 零影响:与定制师的交互(改期、驳回等)
  • 零影响:订单状态机推进(resource_ready / confirm 等)

八、测试环境已验证

✅ 2026-09-27 于测试环境网关实测,真实鉴权(房务端)。

  • 网关 https://api.test.1814.love,分支 dev-v3,部署提交 57199b539
  • pre-flight:ssh -p 2220 root@192.168.100.236 bash /opt/hulalv/scripts/deploy-status.sh 确认 COMMIT=57199b539 STATE=ok
# 用例 期望 实测
AC-1 无台账行改价 / 删除 200,无台账新增 ✅ 改价 0→0;删除 0→0(夹具:2 条存量行)
AC-2 确认后删除、清空、改价 200,应付行同步作废 ✅ confirmed→deleted_at(SQL 验证)
AC-3 清空时付款草稿占用 599602,0 行被删 ✅ 整天拒,deleted_at 仍 NULL
AC-4 team_no 为空确认 808188 拒绝 ✅ INQUIRING 未翻态,fin_payable_line COUNT=0

观察:部署后服务无重启,双实例持续 running,日志最近 200 行 ERROR / Exception 命中 0 条。

存量数据:测试环境所造数据一律 AC-* 前缀,验证后已物理删除,残留合计 0 条。


十、相关文档

  • 房务配房 API 规范:docs/apis/house/assignments/(dev-v3 分支)
  • 应付款台账设计:docs/finance/payable-lines.md
  • 团号生成规则:docs/order/team-no-generation.md

关联 / 联系人

  • Issue: #8401
  • PR: #8402(合并提交 57199b539)