docs(changelog): #7456 团期生命周期后半段——核团开工自动推进 + 验团归档 + 反确认
changelog-filename-gate / validate (push) Successful in 2s
changelog-filename-gate / validate (push) Successful in 2s
这个提交包含在:
@@ -0,0 +1,348 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7456"
|
||||
title: "团期生命周期后半段打通:核团开工自动推进 + 验团归档 + 验团反确认"
|
||||
consumer: "admin"
|
||||
author: "jw(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "mmg"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-09-10"
|
||||
status_note: "团期生命周期此前在「出行完毕」之后就断了——核团(REVIEWING)与验团(SETTLED)两个状态是死枚举,全 order-v3 没有任何代码能推进到它们,看板的「核团中」「已验团」两个桶恒为 0,团期共享成本录入端点因状态门写死 REVIEWING 而根本调不通。本次照订单核单范式补上两跳:① 首次录团期共享成本时把团期从「出行完毕」自动推进到「核团中」(不靠定时任务、不靠日期,与订单侧 advanceSettlementReviewing 同构);② 新增验团归档端点把「核团中」推到「已验团」终态;③ 新增验团反确认端点,验错了能退回核团中。前端三条必看:① 录共享成本这个既有端点现在有了状态副作用,调用后请重取团期详情刷新状态;② 验团与反确认走财务口径(超管/管理员/财务),与订单核单的 finalize/confirm 同一套角色判据;③ 已验团是终态,流团、改容量、录成本都会被既有状态门挡住。⚠️ 已知缺口:验团前置目前只校验到「状态是 REVIEWING」,原型要求的「核团提交」依赖尚未建的核团四表(GB-ADM-050~052),在那之前验团可能在成本没录完时被点掉,反确认端点兜住一部分。无表变更、无 Flyway,新增错误码 589555。"
|
||||
updated_at: "2026-09-10"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 团期生命周期后半段:核团开工 + 验团归档 + 反确认
|
||||
|
||||
## 一、给前端的一句话
|
||||
|
||||
团期以前走到「出行完毕」就**卡死了**——核团、验团两个状态在代码里推不进去,看板那两个桶永远是 0。
|
||||
现在通了:**首次录团期共享成本**会自动把团期推进到「核团中」,**新增的验团归档端点**把它推到「已验团」终态,
|
||||
验错了还有**反确认端点**能退回去。
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| 1 | 团期验团归档 | POST | `/v3/admin/order/group-batch/:groupBatchId/settle` | 新增 | 核团中 → 已验团(终态) |
|
||||
| 2 | 团期验团反确认 | POST | `/v3/admin/order/group-batch/:groupBatchId/settle/reopen` | 新增 | 已验团 → 核团中,给验错了留退路 |
|
||||
| 3 | 录入团期共享成本 | POST | `/v3/admin/order/group-batch/:groupBatchId/settlement/cost` | 修改 | **新增状态副作用**:团期处于「出行完毕」时,首次录入会先把它推进到「核团中」 |
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 团期验团归档 `POST /v3/admin/order/group-batch/:groupBatchId/settle`
|
||||
|
||||
**VO**: `无请求体,返回 Result<Void>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
核团完成后,团期管理员或财务在团期详情页点「验团归档」,团期进入终态。
|
||||
对应原型状态生命周期表的阶段六:责任人「团期管理员 / 财务」,期间「整团验团复核,确认无误,归档结束」,退出「— 终态」。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| `groupBatchId` | path | Long | 是 | 雪花 ID,按字符串传 | 团期 ID |
|
||||
|
||||
无 body。
|
||||
|
||||
#### 出参
|
||||
|
||||
`Result<Void>`。
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data` | null | 无返回体;状态变化请重取团期详情 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /v3/admin/order/group-batch/2089713777065832450/settle
|
||||
Authorization: Bearer <admin token>
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{ "code": 200, "message": "成功", "data": null, "success": true }
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
写口,无空数据形态。团期不存在报 `589500`。
|
||||
**验团时间不落新列**——`order_group_batch` 没有 `settled_at`(那是 `order_main` 的列),
|
||||
验团时间从 `GET .../status-logs` 里 `BATCH_SETTLE`「验团结算」那条的 `changedAt` 读,`#7304` 已开了这个读端点。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
团期已验团归档,重复调用:
|
||||
|
||||
```json
|
||||
{ "code": 589555, "message": "该团期已验团归档,不可重复验团", "data": null, "success": false }
|
||||
```
|
||||
|
||||
团期状态不是「核团中」:
|
||||
|
||||
```json
|
||||
{ "code": 589501, "message": "团期状态不允许当前操作", "data": null, "success": false }
|
||||
```
|
||||
|
||||
无权限(非超管 / 管理员 / 财务):
|
||||
|
||||
```json
|
||||
{ "code": 589507, "message": "无操作权限(非团期管理员 / 非本定制师名下)", "data": null, "success": false }
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 前置:团期状态必须是 `REVIEWING`(核团中),CAS 推进,并发下只有一个请求成功。
|
||||
- 同事务写一条 `group_batch_status_log`,事件类型 `BATCH_SETTLE`「验团结算」,`REVIEWING → SETTLED`。
|
||||
- **已验团是终态**:流团报 `589544`、改容量报 `589538`、录成本报 `589501`——都是既有状态门,本次一行未补。
|
||||
- ⚠️ **已知缺口**:前置目前只校验「状态是 `REVIEWING`」。原型要求的「核团提交」依赖尚未建的核团四表
|
||||
(GB-ADM-050~052),在那之前**验团可能在成本没录完时被点掉**,靠下面的反确认端点兜。
|
||||
- 判权借用订单核单 `SettlementWriteGuard` 的角色判据(超管 / 管理员 / 财务),错误码用团期域的 `589507`。
|
||||
|
||||
### 2. 团期验团反确认 `POST /v3/admin/order/group-batch/:groupBatchId/settle/reopen`
|
||||
|
||||
**VO**: `无请求体,返回 Result<Void>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
验团点早了、或归档后发现成本有误,把团期退回「核团中」继续处理。
|
||||
形状照订单核单的 `final-snapshots/reopen`——那边验错了有退路,团期这边不该没有。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| `groupBatchId` | path | Long | 是 | 雪花 ID,按字符串传 | 团期 ID |
|
||||
|
||||
无 body。
|
||||
|
||||
#### 出参
|
||||
|
||||
`Result<Void>`。
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data` | null | 无返回体;状态变化请重取团期详情 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /v3/admin/order/group-batch/2089713777065832450/settle/reopen
|
||||
Authorization: Bearer <admin token>
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{ "code": 200, "message": "成功", "data": null, "success": true }
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
写口,无空数据形态。团期不存在报 `589500`。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
团期不是「已验团」状态(比如已经被别人退回过):
|
||||
|
||||
```json
|
||||
{ "code": 589501, "message": "团期状态不允许当前操作", "data": null, "success": false }
|
||||
```
|
||||
|
||||
无权限:
|
||||
|
||||
```json
|
||||
{ "code": 589507, "message": "无操作权限(非团期管理员 / 非本定制师名下)", "data": null, "success": false }
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 前置:团期状态必须是 `SETTLED`,CAS 推进,并发下只有一个请求成功。
|
||||
- 同事务写 `group_batch_status_log`,`SETTLED → REVIEWING`。
|
||||
- 退回后可继续录共享成本、可再次验团(TEST 已实测走通一整圈)。
|
||||
- 判权与验团归档同一套角色判据。
|
||||
|
||||
### 3. 录入团期共享成本 `POST /v3/admin/order/group-batch/:groupBatchId/settlement/cost`
|
||||
|
||||
**VO**: `RecordBatchCostReqVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
核团阶段录整团共享成本(大巴 / 领队 / 摄影 / 其它),后续按户分摊。
|
||||
**这个端点本身不是新的,本次变的是它的状态副作用**——在此之前,团期根本进不到 `REVIEWING`,
|
||||
而这个端点的状态门写死「仅 `REVIEWING` 允许」,所以**它实际上一直调不通**。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| `groupBatchId` | path | Long | 是 | 雪花 ID | 团期 ID |
|
||||
| `costType` | body | String(枚举) | 是 | `BUS` / `LEADER` / `PHOTOGRAPHER` / `OTHER` | 成本分类 |
|
||||
| `amount` | body | BigDecimal | 是 | — | 金额 |
|
||||
| `source` | body | String | 是 | — | 来源 |
|
||||
| `remark` | body | String | 否 | — | 备注 |
|
||||
|
||||
#### 出参
|
||||
|
||||
`Result<Long>`。
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `data` | String | 成本行 ID(雪花,按字符串下发) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /v3/admin/order/group-batch/2089713777065832450/settlement/cost
|
||||
Authorization: Bearer <admin token>
|
||||
Content-Type: application/json
|
||||
|
||||
{"costType":"BUS","amount":1200.00,"source":"MANUAL","remark":"大巴费用"}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{ "code": 200, "message": "成功", "data": "2097990074078580737", "success": true }
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
写口,无空数据形态。**入参、出参、既有错误码本次一律未变**,变的只是状态副作用。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
团期既不是「出行完毕」也不是「核团中」:
|
||||
|
||||
```json
|
||||
{ "code": 589501, "message": "团期状态不允许当前操作", "data": null, "success": false }
|
||||
```
|
||||
|
||||
无权限(该端点走 `group-batch:finance:advance`,#7411 已接):
|
||||
|
||||
```json
|
||||
{ "code": 589507, "message": "无操作权限(非团期管理员 / 非本定制师名下)", "data": null, "success": false }
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- **新增副作用**:团期处于 `TRIP_FINISHED`(出行完毕)时,本端点会**先把它 CAS 推进到 `REVIEWING`**(核团中),
|
||||
再执行原有的成本录入。同事务写 `BATCH_TRIP_END`「返团核团」时间线。
|
||||
- 团期已在 `REVIEWING` 时不重复推进、不重复写时间线(幂等)。
|
||||
- **推进不靠定时任务、不靠日期**——与订单侧「第一次录核单明细自动把订单从待核单转成核单中」逐字同构。
|
||||
- ⚠️ **前端请注意**:调用成功后团期状态可能已经变了,**请重取团期详情刷新状态与按钮可用性**。
|
||||
- 已验团(`SETTLED`)的团期调本端点报 `589501`,不会被带回核团中(有单测钉住)。
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
1. **录共享成本之后要重取团期详情**。它现在有状态副作用,页面上的阶段条、按钮可用性都会变。
|
||||
2. **验团 / 反确认走财务口径**:超管 / 管理员 / 财务,与订单核单的 `finalize` / `confirm` 同一套角色判据。
|
||||
定制师、房务、车务等角色会拿到 `589507`。
|
||||
3. **验团时间不要找 `settled_at` 字段**——团期表没有这一列。从 `GET .../status-logs` 里
|
||||
`BATCH_SETTLE` 那条的 `changedAt` 读。
|
||||
4. **已验团是终态**:流团 `589544`、改容量 `589538`、录成本 `589501`。界面上这些按钮应当置灰。
|
||||
5. **`589555` 是「已验团归档,不可重复验团」**,与 `589501`「状态不允许」分开——前者告诉用户「已经做过了」,
|
||||
后者告诉用户「现在这个阶段做不了」,提示文案建议区分。
|
||||
6. **雪花 ID 一律按字符串处理**。
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
- **无表变更、无 Flyway、无数据迁移**——验团时间复用 `group_batch_status_log`,不加 `settled_at` 列。
|
||||
- 两次状态推进都是 **CAS**(`TRIP_FINISHED → REVIEWING`、`REVIEWING → SETTLED`、`SETTLED → REVIEWING`),
|
||||
并发下只有一个请求成功,重复调用不重复写流水。
|
||||
- 新增错误码 **589555**(团期段 589500-589599,此前占用到 589554)。
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 团期在「出行完毕」,首次录共享成本 | 先推进到「核团中」+ 写 `BATCH_TRIP_END`,再录成本 |
|
||||
| 团期已在「核团中」,再录成本 | 不重复推进、不重复写时间线,正常录入 |
|
||||
| 团期在「已验团」,录成本 | `589501`,**不会被带回核团中** |
|
||||
| 验团时团期不是「核团中」 | `589501` |
|
||||
| 重复验团 | `589555` |
|
||||
| 反确认时团期不是「已验团」 | `589501` |
|
||||
| 反确认后 | 回到「核团中」,可继续录成本、可再次验团 |
|
||||
| 已验团后流团 / 改容量 | `589544` / `589538`(既有状态门,本次未补) |
|
||||
| 无权限调验团 / 反确认 | `589507` |
|
||||
| 并发验团 | CAS 保证只有一个成功,另一个拿 `589555` 或 `589501` |
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 项 | 改前 | 改后 |
|
||||
|---|---|---|
|
||||
| `TRIP_FINISHED → REVIEWING` | **没有任何代码能推进**(全 order-v3 对 `GroupBatchStatus.REVIEWING` 的命中只有读判据) | 首次录共享成本时 CAS 推进 |
|
||||
| `REVIEWING → SETTLED` | **没有任何代码能推进** | 新增验团归档端点 |
|
||||
| `SETTLED → REVIEWING` | 无 | 新增反确认端点 |
|
||||
| 录共享成本端点 | 状态门写死 `REVIEWING`,而团期进不到该状态 → **实际调不通** | 可从「出行完毕」直接调,端点自己把状态带过去 |
|
||||
| 看板「核团中」「已验团」桶 | **恒为 0** | 能真正出数 |
|
||||
| 时间线 `BATCH_TRIP_END` / `BATCH_SETTLE` | 枚举定义了但**零引用** | 两跳各写一条 |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
**新增的两个端点**对现有调用方零影响——没有人在调它们。
|
||||
|
||||
**录共享成本端点的副作用是增量的**:改前团期不可能处于 `TRIP_FINISHED` 还能调通这个端点(状态门直接拒),
|
||||
所以**不存在「改前能调通、改后行为变了」的调用方**。改后只是多了一条此前走不到的成功路径。
|
||||
|
||||
**权限**:验团 / 反确认走超管 / 管理员 / 财务。这与原型状态生命周期表里验团责任人「团期管理员 / 财务」完全对上。
|
||||
没有选 `group-batch:manage` 是因为该码**没有授予 FINANCE**,选它会把财务挡在验团之外。
|
||||
|
||||
**运营侧可见变化**:团期看板的「核团中」「已验团」两个桶从此会有数据;此前这两个桶恒空,运营看不到任何在核或已归档的团。
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 不改订单侧核单(`settlement` 域)的任何端点与语义。
|
||||
- 不改团期前半段(招募 / 成团 / 资源 / 物资 / 待出发 / 出行中)的任何推进逻辑。
|
||||
- 不做核团四表、主 / 次报账人记账、成本平均分摊到各子订单(GB-ADM-050~052)——本单只做状态推进骨架。
|
||||
- 无表变更、无 Flyway、无网关路由新增。
|
||||
- 只滚 `hl-order-service-v3` 一个服务。
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
TEST(`api.test.1814.love`)真实网关,团期 `2089713777065832450` 走完整圈(2026-09-10)。
|
||||
造数:把该团期状态临时置为 `TRIP_FINISHED`(0 活跃户,不影响其它验收),**验完已全部回滚**
|
||||
(状态复原 `RESOURCE_PREPARING`、造的成本行与 4 条时间线均已删除,复核残留为 0)。
|
||||
|
||||
| 步 | 实测 |
|
||||
|---|---|
|
||||
| ① 起始状态 | `TRIP_FINISHED` |
|
||||
| ② 录共享成本 | `200`,返回成本行 ID |
|
||||
| ③ **录后状态自动变成 `REVIEWING`** | ✅ 时间线 `BATCH_TRIP_END`「返团核团」`TRIP_FINISHED → REVIEWING` |
|
||||
| ④ 验团归档 | `200`;状态 → `SETTLED`;时间线 `BATCH_SETTLE`「验团结算」`REVIEWING → SETTLED` |
|
||||
| ⑤ 重复验团 | `589555`「该团期已验团归档,不可重复验团」 |
|
||||
| ⑥ 终态约束:录成本 | `589501` |
|
||||
| ⑦ 终态约束:流团 | `589544`「团期已出行,不可发起或批复流团」 |
|
||||
| ⑧ 终态约束:改容量 | `589538`「物料准备开始后不可再调整满团名额」 |
|
||||
| ⑨ 判权:`CUSTOMIZER` 调反确认 | `589507` |
|
||||
| ⑩ 判权:`FINANCE` 调反确认 | `200` —— 财务口径生效,与原型「团期管理员 / 财务」对上 |
|
||||
| ⑪ 反确认后状态 | `REVIEWING`;时间线 `BATCH_SETTLE` `SETTLED → REVIEWING` |
|
||||
| ⑫ 反确认后可再次验团 | `200`,回到 `SETTLED` |
|
||||
|
||||
完整链路 `TRIP_FINISHED → REVIEWING → SETTLED → REVIEWING → SETTLED` **全通**。
|
||||
|
||||
**本机全量**:`mvn -o -pl hl-order-service-v3 test` → **Tests run: 9654, Failures: 0, Errors: 0, Skipped: 7, BUILD SUCCESS**。
|
||||
新增单测 `GroupBatchSettleServiceTest` 10 例 + `GroupBatchSettlementServiceTest` 补 5 例。
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- 工单:`#7456`(本单)
|
||||
- 原型:团期详情 → 状态生命周期 Tab(阶段六「核团」「验团」两行)
|
||||
- 范式来源:订单核单 `settlement` 域的 `advanceSettlementReviewing` / `finalize` / `confirm` / `reopenFinalSnapshot`
|
||||
- 前序:`#7190`(出行段两跳 `PENDING_DEPARTURE → TRAVELLING → TRIP_FINISHED`,本单接着它往下做)、`#7304`(时间线读端点)
|
||||
- 后续:GB-ADM-050~052 核团四表落地后,验团前置要补上「核团已提交」这一条(代码里已留 `TODO` 锚点)
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
- 工单:https://git.1814.love:8443/wx/HL/issues/7456
|
||||
- PR:https://git.1814.love:8443/wx/HL/pulls/7485
|
||||
- 后端:jw;前端:mmg
|
||||
在新工单中引用
屏蔽一个用户