14 KiB
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 | 8783 | 团期核单确认门禁订正:blocking 非空服务端硬拦 589568 + 负金额改抛 589753 + 零值金额统一 0.00 | admin | yst | 修改接口 | merged | not_required | implemented | mmg | aef8ddd60341b789429a9dd9432e8a7f56783190 | v2.1 | 2026-10-04 | 订正 04_8714 团期核单重做 changelog 的契约行为描述:confirm 在 blocking 非空时此前仅 panel 透出前端置灰、服务端 200 放行,现服务端硬拦 589568;行内负金额由此前 400 参数校验改为契约错误码 589753;panel/tab 空集合金额统一序列化为 0.00 两位小数。已合 dev-v3 未部署测试服。前端已交付(2026-10-04):确认核单 catch 增 589568 分支重读 panel 刷新 version 与 blockingOrderIds 置灰态(message 自带未定稿清单拦截器透);负金额输入既有 :min=0 无 400 特判、零值展示走 formatPrice 数值化无 "0" 等值判断,两处天然零适配,提交 aef8ddd60。 | 2026-10-04 | dev-v3 |
order-v3 groupbatch:团期核单确认门禁订正(管理后台)—— 订正 04_8714
⚠️ 本文是订正 changelog,修订《04_8714_团期核单重做8类tab明细+公摊拆账-修改接口-管理后台.md》中三处契约行为描述。原文件保留不改动;两处描述不一致时以本文为准。接口路径、入参结构、出参结构均无变化,变化只在服务端行为 / 错误码 / 金额序列化格式三处。
1. 接口背景
#8714 团期核单重做落地后,#8783(PR #8784)补齐三处契约缺口:
- 确认门禁漏拦:原契约 panel 透出
blockingOrderIds供前端把确认按钮置灰,但服务端 confirm 端点并未校验——前端绕过置灰直接调POST …/settlement/panel/confirm时,团内仍有子订单第 1 层核单未定稿也能 200 确认成功。现服务端补上硬校验,blocking 非空即拒绝。 - 负金额错误码不合契约:行内金额/单价/数量为负时,此前由 Bean Validation(
@DecimalMin)拦截返通用 400,不属于核单域错误码体系。现删除字段级@DecimalMin,改在 Service 层 resolveSplits 入口统一校验,按契约抛 589753。 - 零值金额格式不统一:panel 各分类合计、户视图已摊成本/收入、tab
allocatedTotal等空集合金额,此前部分路径序列化为"0"(无小数位),与 tab 两位小数口径不一致。现统一为"0.00"。
2. 变更清单
| # | 接口 | 变更点 | 类型 |
|---|---|---|---|
| 1 | POST /v3/admin/order/group-batch/{groupBatchId}/settlement/panel/confirm |
新增服务端门禁:在团子订单第 1 层核单未全部定稿(blocking 非空)时拒绝确认,抛 589568(此前 200 放行,仅 panel 透出 blockingOrderIds 供前端置灰) | 🔧 行为变更 |
| 2 | PUT …/settlement/{8 个 tab} / POST …/settlement/lines / POST …/settlement/alloc-preview |
行内金额/单价/数量为负,由 Bean Validation 400(通用参数错误)改为契约错误码 589753;涉及字段见 §4 | ⚠️ 错误码变化 |
| 3 | GET …/settlement/panel / GET …/settlement/{tab} |
空集合金额(分类合计 / 户 allocatedCost/allocatedIncome / tab allocatedTotal 等)序列化由可能为 "0" 统一为 "0.00"(两位小数) |
🔧 出参格式统一 |
路径前缀统一为 /v3/admin/order/group-batch/{groupBatchId}/settlement,下文用 … 代指。接口签名(路径 / 入参字段 / 出参字段)零变化。
3. 接口详情
| 项 | 说明 |
|---|---|
| 服务 | hl-order-service-v3(端口 8086) |
| 路径前缀 | /v3/admin/order/group-batch/{groupBatchId}/settlement |
| 使用场景 | 管理后台 → 团期详情 → 核单 Tab:确认核单、明细行金额录入 |
| 认证 | 管理后台登录态(JWT);网关既有路由 /v3/admin/**,无新增网关配置 |
| 权限码 | group-batch:audit:allocate(确认核单);group-batch:audit:edit(tab PUT / lines 新增);缺码一律 589507 |
| 幂等性 | 与 04_8714 一致:写口不加 @Idempotent,由 main 主行锁 + expectedVersion CAS 兜底(过期 589573) |
| 限流 | 无特殊限流 |
4. 接口入参
入参结构与 04_8714 §4 完全一致,此处只列本次行为变化涉及的字段(GroupSettleLineSaveReqVO 及其 splits[]):
| 字段 | 类型 | 必填 | 原约束(@DecimalMin,删) | 现约束(Service 校验) |
|---|---|---|---|---|
| budgetAmount | number | 可空 | ≥0,违例 400 | 为负抛 589753 |
| actualAmount | number | ✅ | ≥0,违例 400 | 为负抛 589753 |
| unitPrice | number | 可空 | ≥0,违例 400 | 为负抛 589753(住宿/餐食/其他收入) |
| ticketUnitPrice | number | 可空 | ≥0,违例 400 | 为负抛 589753(门票·游玩) |
| quantity | number | 可空 | ≥0,违例 400 | 为负抛 589753(餐食/其他收入) |
| dailyPrice | number | 可空 | ≥0,违例 400 | 为负抛 589753(车辆) |
| perDayFee | number | 可空 | ≥0,违例 400 | 为负抛 589753(导游/摄影师) |
| splits[].ratio | number | 可空 | ≥0,违例 400 | 为负抛 589753 |
| splits[].amount | number | 可空 | ≥0,违例 400 | 为负抛 589753 |
POST …/settlement/panel/confirm 入参不变:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| expectedVersion | int | ✅ | 乐观锁版本(GET panel/tab 返回的 version 原样回传) |
5. 出参字段
出参结构与 04_8714 §5 完全一致。唯一变化是零值金额的序列化格式:
| 字段 | 原来(空集合时可能) | 现在(统一) |
|---|---|---|
panel categories[].actualAmount / allocatedAmount / unallocatedAmount |
"0" |
"0.00" |
panel households[].allocatedCost / allocatedIncome / grossProfit |
"0" |
"0.00" |
tab allocatedTotal / actualTotal |
"0" |
"0.00" |
非零金额不受影响(此前已是两位小数)。金额仍为 JSON 字符串,前端按字符串处理即可;若有对 "0" 的等值判断 / 解析分支需放宽为兼容 "0.00"(建议统一 Number(x) 或字符串比较改为数值比较)。
GET …/settlement/panel 中与本门禁相关的字段(不变,重述便于对照):
| 字段 | 类型 | 说明 |
|---|---|---|
| readyToAllocate | boolean | 各户第 1 层核单是否全部定稿;false 时 confirm 必吃 589568 |
| blockingOrderIds | string[] | 第 1 层核单未定稿的子订单 ID;非空时 confirm 必吃 589568 |
6. 枚举 / 数据字典
本次无枚举 / 字典变化。
7. 错误码
| 错误码 | 文案({0} 为动态定位串) | 触发场景 | 本次变化 |
|---|---|---|---|
| 589568 | 整团核单当前状态不允许该操作:{0} | ① CONFIRMED 后任何写操作(原有);② 确认核单时在团子订单第 1 层核单未全部定稿——{0} 带未定稿订单号清单,「、」分隔,与 panel 的 blockingOrderIds 一一对应 | ⚠️ 新增触发场景②(此前 confirm 不校验,200 放行) |
| 589753 | 核单拆账入参非法:{0} | 金额/单价/数量为负、未知费用类别等入参层非法;{0} 指明具体字段与值 | ⚠️ 负金额场景由此前 400 改为 589753(删 @DecimalMin,改 Service 层 resolveSplits 入口校验) |
其余错误码(589507 / 589567 / 589571 / 589572 / 589573 / 589750 / 589751 / 589752 / 589754 / 589755)与 04_8714 §7 一致,无变化。
前端适配点:
- 589568 的 toast / 弹窗需覆盖「确认时 blocking 非空」场景——message 里已带未定稿订单号清单,可直接展示;建议同时刷新 panel 更新 blockingOrderIds。
- 负金额入参不再走 400 分支,改走 589753 分支;若前端此前对 400 做通用「参数错误」提示,现在会收到带具体字段定位的 589753 message,体验更好。
8. 示例
8.1 典型:确认核单时有子订单第 1 层核单未定稿,被 589568 拒绝
请求:
POST /v3/admin/order/group-batch/1934567890123456789/settlement/panel/confirm
Content-Type: application/json
{ "expectedVersion": 5 }
响应(业务失败,团内订单 HL20261001001、HL20261001003 第 1 层核单未定稿):
{
"code": 589568,
"message": "整团核单当前状态不允许该操作:以下订单未完成核单:HL20261001001、HL20261001003"
}
对照:GET …/settlement/panel 此时返回 "readyToAllocate": false、"blockingOrderIds": ["1934567890123450001", "1934567890123450003"]。订正前:同样的请求返回 200 确认成功(服务端不拦);订正后:服务端硬拦,前端置灰只是体验层,不再是唯一防线。
8.2 边界:明细行金额为负,抛 589753(不再是 400)
请求:
PUT /v3/admin/order/group-batch/1934567890123456789/settlement/hotels
Content-Type: application/json
{
"expectedVersion": 3,
"lines": [
{
"lineId": null,
"allocMode": "SHARED",
"allocRule": "PER_HEAD_AVG",
"actualAmount": -100.00,
"hotelName": "图嘎营地",
"roomCount": 5,
"unitPrice": 380.00
}
]
}
响应:
{
"code": 589753,
"message": "核单拆账入参非法:actualAmount 不能为负(-100.00)"
}
订正前:同样请求由 Bean Validation 拦截,返回 HTTP 400 / 通用参数校验错误(不在核单域错误码体系内);订正后:统一走契约错误码 589753,message 带字段名与具体值。splits[].amount / splits[].ratio / dailyPrice / perDayFee 等其余 §4 列出的字段为负时同样抛 589753。
8.3 业务失败:expectedVersion 过期(589573,既有行为不变,供对照)
请求:
POST /v3/admin/order/group-batch/1934567890123456789/settlement/panel/confirm
{ "expectedVersion": 3 }
(库中当前 version 已为 5)
响应:
{
"code": 589573,
"message": "整团核单数据已被他人修改(当前版本 5,提交版本 3),请刷新后重试"
}
处理方式不变:重新 GET panel 读回全量(含新 version)再重试,不能本地 version+1。
9. 业务边界
适用:
- 团期核单确认(panel/confirm)的服务端兜底校验——所有在团子订单第 1 层核单定稿后才允许确认。
- 明细行金额录入的合法性校验——全部金额/单价/数量/比例字段不允许为负。
不适用:
- 逐子订单第 1 层核单本身的确认流程(那是子订单核单域的事,本门禁只消费其结果)。
- 确认后修改:CONFIRMED 不可逆(与 04_8714 一致)。
特殊边界:
- 置灰 ≠ 防线:panel
blockingOrderIds/readyToAllocate仍正常透出,前端应继续据此置灰确认按钮提升体验;但服务端现在会真拦,前端必须处理 589568 回执(toast message + 刷新 panel),不能假设按钮置灰后用户永远触发不到。 - 零值金额判断:前端若有
amount === "0"之类的字符串等值判断,需改为数值比较或兼容"0.00"。
10. 修改前后对比
行为级对比
| 行为 | 原来(04_8714 描述 / 订正前实现) | 现在(#8784 订正后) |
|---|---|---|
| confirm 时 blocking 非空 | 服务端不校验,200 放行确认成功;blockingOrderIds 只在 panel 透出供前端置灰 | 服务端硬拦,抛 589568,message 带未定稿订单号清单(「、」分隔) |
| 行内金额/单价/数量为负 | Bean Validation @DecimalMin 拦截,HTTP 400 通用参数错误 |
Service 层 resolveSplits 入口校验,契约错误码 589753,message 带字段定位 |
| 空集合金额序列化 | 部分路径输出 "0"(无小数位),与 tab 两位小数口径不一致 |
统一 "0.00"(两位小数) |
字段级对比
无字段增删 / 改名 / 类型变化;仅 §4 列出字段的校验位置与错误码变化(@DecimalMin 注解删除,改 Service 校验)。
11. 影响评估 / 回滚
- 破坏兼容:轻微。接口签名零变化;行为变化三处——① confirm 新增拒绝场景(原先能确认成功的请求现在被拒,属安全收紧,前端需新增 589568 处理分支);② 负金额错误码 400 → 589753(前端若按 400 特判需改判 589753);③ 零值金额
"0"→"0.00"(前端若有字符串等值判断需放宽)。 - 前端必须同步上线:否(后端已合 dev-v3 未部署测试服;前端适配可在联调窗口内完成)。前端原有「blocking 置灰」逻辑保留,只是不再唯一依赖它。
- workaround 清理点:若前端此前因服务端不拦而自行做了 confirm 前的 blocking 预校验弹窗,可保留(体验层);若有对负金额 400 的特判文案,改挂 589753。
- 回滚方案:后端回滚 = revert PR #8784 即可(纯代码改动,无 DDL / 无数据迁移)。
12. 注意事项
- 本文优先于 04_8714:两份 changelog 对 confirm 门禁 / 负金额错误码 / 零值金额格式的描述不一致时,以本文为准。04_8714 的其余内容(接口清单 / 出入参结构 / 枚举字典 / 拆账规则 / CAS 语义)继续有效。
- 589568 message 可直接展示:未定稿订单号清单已内嵌 message(「、」分隔),前端无需自行查 blockingOrderIds 拼装;但建议同时刷新 panel 让置灰状态与服务端一致。
- 负金额提示走 589753:不要再期待 400;message 带字段名与非法值,可直接 toast。
- 金额仍按字符串处理:
"0.00"统一后前端解析逻辑应天然兼容,只需清理对"0"的硬编码等值判断。
13. 关联 / 联系人
- Issue:wx/HL#8783
- PR:wx/HL#8784
- Commit(squash merge):https://git.1814.love/wx/HL/commit/d414d7d00705
- 被订正的原 changelog:
changelogs-v2/2026-10/04_8714_团期核单重做8类tab明细+公摊拆账-修改接口-管理后台.md(同仓同目录) - 后端负责人:@yst