文件
hl-api-changelog/changelogs-v2/2026-09/21_7105_团期合同保险出具门已打通撤销恒失败说明-修复-管理后台.md
T
2026-09-21 16:31:15 +08:00

167 行
9.0 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
---
schema: "hl-changelog/v2"
ticket: "7105"
title: "团期合同保险出具门已打通,撤销上一版「按钮恒失败」的说明"
consumer: "admin"
author: "jw(GIT)"
change_type: "修复"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "verified"
frontend_owner: "mmg"
frontend_ref: "f3a22be3a9efa374aaa6442302780d6a02b8ce8e"
target_release: "v2.1"
verified_at: "2026-09-21"
status_note: "更正 2026-09-07 那条 #7105 的首段警告。彼时说「酒店 ready 线上无写入方(#4132),故 issuable 恒 false、手动开/作废重开恒返 589548」——两个前提现已都不成立:#7248/PR#7249 把出具门从「判团期状态」改成「资源准备中+四项 ready 全 true 即放行」;house 域已有三处回填 hotel_ready。2026-09-21 TEST 实测:RESOURCE_PREPARING 团期 issuable=true,issue 端点返 200 逐户结果而非整单 589548,四项配齐团期里 40 户已确认行程的子订单合同全 SIGNED、保险全 INSURED。前端需调整:不要再把出具按钮按恒失败处理,失败语义从整单 BusinessException 改为 200+逐户 outcome=FAILED+message。接口契约零变更,无需改调用代码。【前端交付 2026-09-21 mmg:实证两处要求早已具备——按钮按面板 issuable 字段置灰(ChipItemsPanel)、逐户失败 200+outcome=FAILED+message 逐行原样展示(ContractActionModal),行为零改动;仅清理过期口径:出具置灰 tooltip 去掉「(#4132 待后端)」用户可见标注 + 五处注释更新,hl-admin v2.1 f3a22be3。】"
updated_at: "2026-09-21"
base: "dev-v3"
---
# 团期「合同保险」:出具门已打通,撤销上一版的「按钮恒失败」说明
> **服务**: hl-order-service-v3 (端口 8086/8186)
> **Issue**: #7105(本条更正)、#7248 / PR #7249(实际修复)
> **日期**: 2026-09-21
> **影响范围**: 管理后台「团期详情 → 合同保险」Tab 的按钮可用性判断与失败处理分支。
---
## ⚠️ 关键变化
上一版 `2026-09/07_7105_团期合同保险面板与逐户出具-新增接口-管理后台.md` 开头那段
「**当前不可用的部分(重要)**」说:
> 酒店 ready 线上**没有**写入方(HL#4132)→ `issuable` **恒为 false**、
> 手动开 / 作废重开 **恒返 589548**、团期单合同与保险**不会自动出具**。
**这段话现已失效,本条予以撤销。** 实际现在是:
- `issuable` **会返 true**,团期停在「资源准备中」也能返 true
- 手动开 / 作废重开 **不再整单返 589548**
- 团期单的合同与保险 **会自动出具**
**接口契约(路径、入参、出参字段、返回值结构)零变更**,前端不必改调用代码,
但**要改按钮可用性与失败处理这两处判断**,详见第三节。
---
## 一、上一版为什么会写错
两条前提当时都成立,之后各自被改掉了:
| 前提 | 当时 | 现在 |
|---|---|---|
| 出具门怎么判 | 判「团期状态已进入 MATERIAL_PREPARING 及之后」 | #7248 / PR #7249(`9f47f620f`,2026-09-07)改判四个 ready 标志:**资源准备中 + 四项 ready 全 true 即放行** |
| `hotel_ready` 有没有写入方 | 没有,挂在一个从未发出的事件上(#4132) | 有,house 域三处在回填 |
当时那个判法和 #7023 的进阶门首尾相接,构成完全死锁:
```
要出合同 → 需 MATERIAL_PREPARING → 需合同全部已签 → 需先出过合同
```
`hotel_ready` 现有的三处写入方:
| 写入点 | 文件 |
|---|---|
| 团期逐日房态确认 | `house/groupbatch/manager/GroupBatchRoomDayConfirmManager.java:457` |
| 同上(另一条分支) | `house/groupbatch/manager/GroupBatchRoomDayConfirmManager.java:767` |
| 团期整团配房 | `house/service/HouseGroupBatchAssignmentService.java:201` |
> ℹ️ #4132 工单本身在 Gitea 上仍是 open / 待处理,**光看工单状态会以为还堵着**。
> 它描述的那条 baseline 事件链路确实还没做,但 `hotel_ready` 的回填已由上面三处覆盖,
> 出具门不再依赖 #4132。
---
## 二、现在的实际行为
### 出具门判定(`GroupBatchContractResolver.issuable`)
| 团期状态 | 是否放行 |
|---|---|
| 招募中 RECRUITING | ❌ 不放行(未成团,四项必不全) |
| **资源准备中 RESOURCE_PREPARING** | ✅ **四项 ready 全 true 就放行**(原死锁点,本次变化就在这一行) |
| 物资准备中 MATERIAL_PREPARING 及之后(待出行 / 出行中 / 核验中 / 已结算) | ✅ 放行(必然已配齐过,不依赖存量标志是否回填) |
| 已流团 CANCELLED | ❌ 不放行 |
### 失败语义(前端最需要注意的一点)
`589548`(四项未配齐)现在只在**整单**层面出现,且只在团期真的没配齐时出现。
门过了之后,**逐户的失败不再是 589548,而是 HTTP 200 + 逐户 `outcome=FAILED` + `message`**:
```json
{
"code": 200, "message": "成功", "success": true,
"data": {
"totalCount": 1, "successCount": 0, "failCount": 1, "skipCount": 0,
"results": [
{ "orderId": "2099947354713993217", "target": "CONTRACT",
"outcome": "FAILED", "message": "请先确认行程后再创建合同" }
]
}
}
```
最常见的一条逐户失败是 **`请先确认行程后再创建合同`**(合同域 `510220`):
合同只能在子订单处于 `PENDING_DEPARTURE` 或 `TRAVELLING` 时创建
(`ContractCreateService.CONTRACT_CREATABLE_ORDER_STATUSES`)。
也就是说,**团期四项配齐只是开了团期这道门,子订单自己还没确认行程的户依然出不了合同**,
这是两道独立的前置,页面上要能把这条 `message` 原样显示给操作人,不要吞掉。
---
## 三、前端要改的两处
| # | 改前(按上一版说明写的) | 改后 |
|---|---|---|
| 1 | 出具类按钮按「反正恒失败」处理(常驻置灰 / 挂提示 / 干脆不接) | **按 `issuable` 字段置灰**。它现在会真的返 true,按钮要能点 |
| 2 | 失败一律当 589548 整单报错 | 先看 HTTP 层 `code`:`589548` 仍是整单拒绝(四项未配齐);`code=200` 时要**逐户读 `results[].outcome`**,`FAILED` 的户把 `message` 原样展示 |
其余不用动:三态徽标继续用后端 `contractStateText` / `insuranceStateText`,
不要自己映射;权限码仍是读 `group-batch:view`、写 `group-batch:contract:issue`。
---
## 四、TEST 实测记录(2026-09-21)
均经真实网关 `api.test.1814.love`,非单测。
| # | 验证项 | 结果 |
|---|---|---|
| 1 | `GET .../group-batch/2100129355043627009/contracts` | `issuable=true`,`batchStatus=RESOURCE_PREPARING`。**旧实现在此状态下必为 false**,这条直接证明门已改 |
| 2 | `GET .../group-batch/2099947334803632130/contracts` | 同上,`issuable=true`,3 户明细正常返回 |
| 3 | `POST .../contracts/issue`(`target=CONTRACT`) | 返 `code=200` + 逐户结果,**不再是整单 589548**;该户因自身未确认行程返 `outcome=FAILED` / `请先确认行程后再创建合同` |
| 4 | TEST 库 `order_group_batch` 四项 ready 全 1 的团期 | 共 28 个(物资准备中 17、资源准备中 5、核验中 2、待出行 2、出行中 1、行程结束 1);`hotel_ready=1` 的记录共 52 条 |
| 5 | 上述团期下**已确认行程**的子订单合同 / 保险状态 | 40 户(已完成 23 + 出行中 10 + 待出行 7)**合同全部 SIGNED、保险全部 INSURED**,无一户卡在「已确认行程但合同未出」,最新一条更新时间 2026-09-21 15:31 |
第 5 条是自动出具链路当前工作正常的证据:如果门还锁着,这些户会全部停在「未出」。
**未实测**:单次「手动开 → 合同真的开出来」的正向成功路径。TEST 上四项配齐的团期里,
已确认行程的户合同都已由自动链路出过(无可补开的户),未确认行程的户被 `510220` 挡住,
现成数据里没有可打的靶子;造一个需要先补该订单的酒店供应商字段。
门已通的结论由第 1、3、5 条支撑,不依赖这一条。
**取证范围仅 TEST**。正式环境本机无查询通道,上一版原文里的「线上」二字本条不予断言。
---
## 五、不影响范围
- **接口契约零变更**:四个端点的路径、方法、入参、出参字段、错误码全部未动
- **散客单不受影响**:`productBatchId` 为空的订单在出具门上恒放行,从头到尾没被这个问题波及
- **零影响**:小程序端、订单侧合同 / 保险接口(`create-by-scheme` / `purchase-by-scheme` 等)、网关配置、权限码
---
## 六、相关文档
- 被本条更正的条目:`changelogs-v2/2026-09/07_7105_团期合同保险面板与逐户出具-新增接口-管理后台.md`
- 修复提交:`9f47f620f`(`fix(group): 合同出具门改判四项 ready,解开与 #7023 的死锁 Closes #7248`)
- 接口文档:`docs/group/团期模块接口文档-v2.0.html` GB-ADM-030 / GB-ADM-031 章节
## 关联 / 联系人
- 后端:jw
- 相关工单:#7105(原交付)、#7248 / PR #7249(门锁修复)、#7023(进阶门)、#4132(仍 open,但已不阻塞本功能)