文件
hl-api-changelog/changelogs-v2/2026-09/12_7527_团期发起核单端点-新增接口-管理后台.md
T
2026-09-13 10:08:51 +08:00

12 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 7527 团期发起核单端点(TRIP_FINISHED → REVIEWING) admin jw(GIT) 新增接口 deployed verified verified mmg a80b9670 2026-09-13 团期详情/看板需加「发起核单」按钮。重复点击返 200 且 alreadyStarted=true,前端应据此提示「该团期已在核单中」而非再弹一次成功。录成本自动推进的老行为不变,两条入口并存。 前端 2026-09-13 已交付(hl-admin a80b9670):groupBatchFinance.js 新增 startGroupBatchReview;详情页「更多操作」按 batchStatus===TRIP_FINISHED 白名单加「发起核单」,新建 ReviewStartModal 确认弹层;成功按 alreadyStarted 分支(true 幂等命中仅提示「已在核单中」不重复弹成功,false 弹成功并 fetchDetailSafe 刷新);589564/589565/589566/589507 走拦截器透后端 message;看板不加按钮;录成本自动推进老行为零改动。checkpoint 13 项全绿(全量 Vitest+生产构建)。 2026-09-13 dev-v3

order-v3: 团期发起核单端点(TRIP_FINISHED → REVIEWING)

服务: hl-order-service-v3 PR: #7568 Issue: #7527


⚠️ 关键变化

🔴 补的是一个「团期卡死」的入口缺失,不是新功能。 TRIP_FINISHED → REVIEWING 这一跳此前 唯一入口是录共享成本的副作用。于是不用大巴、没请导摄的团根本没有共享成本可录, 就没有触发点,团期永久停在「出行完毕」——既进不了核单,也归不了档, 八桶看板的「核团中」桶对这类团恒为空。

🔴 两条入口并存,老行为一行未改。 「先点发起核单再录成本」与「直接录第一笔成本自动推进」 都继续可用。前端不需要为本端点调整任何现有调用。

🔴 重复点击返 200,不是报错。 用 data.alreadyStarted 区分:false = 本次真的推进了; true = 调用前团期已在核单中,本次是幂等命中、零写入零时间线。 前端若只看 HTTP 码,重复点会连弹两次「已发起核单」。


一、背景

团期生命周期第 6 跳(出行完毕 → 核单中)没有人工入口。运营在八桶看板上点不动「核团中」桶, 只能等财务去改库,或者随便录一笔 0 元成本把状态机「骗」过去。 这是把一个流程动作绑死在一个数据录入动作上的后果。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 发起核单 POST /v3/admin/order/group-batch/{groupBatchId}/review/start 新增 TRIP_FINISHED → REVIEWING 的显式人工入口;重复点幂等返 200

三、接口详情

1. 发起核单 POST /v3/admin/order/group-batch/{groupBatchId}/review/start

VO: GroupBatchReviewStartRespVO

使用场景

hl-ui 管理后台「团期详情 / 团期看板」的「发起核单」按钮。团期返团后(状态「出行完毕」)由 运营或财务点一下,把团期推进到「核单中」,之后才能走验团归档。

入参字段表

字段 位置 类型 必填 约束 说明
groupBatchId Path Long ✅ 雪花 ID,不存在返 589500 团期主订单 ID

无请求体。

出参字段表

字段 类型 说明
groupBatchId String 团期主订单 ID(Long 经 ToStringSerializer 序列化,防精度丢失)
batchStatus String 推进后的团期状态,恒为 REVIEWING
batchStatusDesc String 状态中文名,恒为「核单中」
alreadyStarted Boolean false=本次调用完成了推进;true=调用前团期已在核单中,本次为幂等命中、未产生任何写入与时间线

请求示例

POST /v3/admin/order/group-batch/2089679374176464898/review/start
Authorization: Bearer <admin token>

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "groupBatchId": "2089679374176464898",
    "batchStatus": "REVIEWING",
    "batchStatusDesc": "核单中",
    "alreadyStarted": false
  },
  "success": true
}

空数据 / 降级响应

重复点击(团期已在核单中)返 200,alreadyStarted=true,零写入、零时间线:

{
  "code": 200,
  "message": "成功",
  "data": {
    "groupBatchId": "2089679374176464898",
    "batchStatus": "REVIEWING",
    "batchStatusDesc": "核单中",
    "alreadyStarted": true
  },
  "success": true
}

时间线写入失败时不回滚状态推进,接口仍返成功(时间线不是主链路)。

错误响应

码 符号 触发 建议前端提示
589500 GROUP_BATCH_NOT_FOUND groupBatchId 查不到团期 团期不存在
589507 GROUP_BATCH_PERMISSION_DENIED 角色未持 group-batch:finance:advance 无操作权限
589564 GROUP_BATCH_REVIEW_START_STATUS_INVALID 状态早于「出行完毕」(招募中/资源准备中/物料准备中/待出发/出行中),或库中为脏值 「团队还没返团,返团后才能发起核单」
589565 GROUP_BATCH_REVIEW_START_AFTER_SETTLED 团期已验团归档 「该团已验团归档,如需重新核单请先做验团反确认」,并给一个跳转到反确认的入口
589566 GROUP_BATCH_REVIEW_START_DISBANDED 团期已流团 / 取消 「该团已流团,不能发起核单」,按钮应置灰
{
  "code": 589564,
  "message": "当前团期状态不可发起核单(须为「出行完毕」)",
  "data": null,
  "traceId": null,
  "success": false
}
{
  "code": 589565,
  "message": "团期已验团归档,如需重新核单请先做验团反确认",
  "data": null,
  "traceId": null,
  "success": false
}
{
  "code": 589566,
  "message": "团期已流团,不可发起核单",
  "data": null,
  "traceId": null,
  "success": false
}

业务边界

  • 幂等:由 CAS 的 from = TRIP_FINISHED 条件天然保证。重复调用与并发双击的败者都落到 alreadyStarted=true 的成功分支,不会写出第二条时间线。前端无需做防抖去重(做了更好)。
  • 三个错误码刻意分开,不共用通用的 589501「团期状态不允许当前操作」:这三种拒绝对运营的 下一步动作完全不同(等团回来 / 去做验团反确认 / 这团已经流了),共用一个码前端只能给出 一句无法行动的提示。
  • 成功后团期进入「核单中」,共享成本录入端点 POST .../settlement/cost 与验团归档端点 POST .../settle 随之可用。
  • 权限码与录成本端点同一个(group-batch:finance:advance):今天能录成本的人就能发起核单, 没有人凭空多出权限,前端的按钮可见性判据可直接复用录成本那一套。

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

  • 不要把 200 当成「推进成功」:必须看 data.alreadyStarted。true 时提示「该团期已在核单中」, 不要再弹一次「发起成功」。
  • 不要用它做状态查询:本端点是写动作,读团期状态请用团期详情接口。
  • 不要为它做重试:幂等安全,但重试没有意义——失败的三个码都是业务拒绝,重试结果相同。
  • 589565 要给出口:提示里带上「验团反确认」的跳转,对应端点 POST /v3/admin/order/group-batch/{groupBatchId}/settle/reopen。
  • 老入口不变:POST /v3/admin/order/group-batch/{groupBatchId}/settlement/cost 在 TRIP_FINISHED 上录第一笔成本仍会自动推进到 REVIEWING,行为一行未改。

五、数据库行为

无表变更、无 Flyway、无新增列。 本端点只写两处既有的地方:

  • order_group_batch.batch_status:由 TRIP_FINISHED CAS 更新为 REVIEWING(幂等命中时不写);
  • group_batch_status_log:追加一条 event_type=BATCH_TRIP_END / from_status=TRIP_FINISHED / to_status=REVIEWING / content=发起核单(管理员手动) 的时间线(幂等命中时不写)。

时间线写入失败仅记 WARN 降级,不回滚状态推进——流水不是主链路,不能因为它写失败把 状态推进撤销掉。


六、边界行为

场景 行为
团期在「出行完毕」 200,alreadyStarted=false,状态变「核单中」,时间线 +1
团期已在「核单中」 200,alreadyStarted=true,零写入、零时间线
并发双击 / 与录成本并发 只有一个请求 CAS 成功;败者重读状态后也返 200 alreadyStarted=true
团期早于「出行完毕」 589564
团期已「已结算」 589565
团期已「已取消」(流团) 589566
团期不存在 589500
无权限 589507,零落库
库中 batch_status 为枚举外脏值 589564(业务码,不是 500)
时间线写入失败 状态已推进,接口仍返 200

七、不影响范围

  • POST /v3/admin/order/group-batch/{groupBatchId}/settlement/cost 一行未改——其内嵌的 TRIP_FINISHED → REVIEWING 副作用保持原样,两条入口并存。
  • 验团归档 POST .../settle 与验团反确认 POST .../settle/reopen 未改动。
  • 无 Mapper 改动(复用既有 casAdvanceToReviewing)、无 Entity 改动、无网关路由改动 (命中已有 /v3/admin/** 通配)、无 hl-user-service 权限种子改动(复用既有权限码)。
  • 核团业务内容(核团四表、主次报账人记账、成本分摊)不在本单,仍归 GB-ADM-050~052。

八、测试环境已验证

部署:hl-order-service-v3 @ feat/7527-group-batch-review-start / 9f3ee37d9,双实例滚动重启完成。 全部实测经真实网关 api.test.1814.love:9443 + Bearer 鉴权,载体是 TEST 上一个 0 子订单的空闲团期 2089679374176464898。

场景 请求 响应
出行完毕 → 发起 POST .../2089679374176464898/review/start 200,alreadyStarted=false,batchStatus=REVIEWING;库 batch_status 变 REVIEWING;group_batch_status_log 新增 BATCH_TRIP_END / TRIP_FINISHED → REVIEWING / 发起核单(管理员手动)
再点一次 同上 200,alreadyStarted=true;状态不变,时间线条数不变
出行中 同上 589564「当前团期状态不可发起核单(须为「出行完毕」)」
已结算 同上 589565「团期已验团归档,如需重新核单请先做验团反确认」
已取消 同上 589566「团期已流团,不可发起核单」
团期不存在 POST .../999999999/review/start 589500「团期不存在」
无权限角色 同上(roleKey=GUIDE / CUSTOMER_SERVICE) 589507
老行为零回归 在「出行完毕」上 POST .../settlement/cost 200,库 batch_status 仍自动变 REVIEWING

前置条件达成方式:TRIP_FINISHED / TRAVELLING / SETTLED / CANCELLED 四态在 TEST 上一个都不存在 (它们由 GroupBatchLifecycleJobService 按班期日期定时推进),故用 SQL 直更 batch_status 逐个构造前置态, 取证后已还原为原始的 RESOURCE_PREPARING。该路径没有验到状态机上游的推进逻辑,只验本端点自身的判据。

本地全量:mvn -o -pl hl-order-service-v3 -am test → 9935 例 / Failures 0; RedLineArchTest / LayerEnforcementTest / MapperBoundaryArchTest 均通过(非 Skipped)。 本单新增 10 例单测。


十、相关文档


关联 / 联系人

  • 后端:jw
  • 前端(hl-ui 管理后台):mmg
  • 需求定案:wx