文件
hl-api-changelog/changelogs-v2/2026-09/06_7190_团期状态新增出行完毕TRIP_FINISHED看板八桶-修改接口-管理后台.md
T
Mimingguang d2ed4973f7
changelog-filename-gate / validate (push) Failing after 2s
chore(changelog): 回写批次A(#7188/#7189/#7190/#7250)与 #7291 前端交付验证
五条均 frontend_status verified、owner mmg、verified_at 2026-09-08;批次A 四项 frontend_ref=2eb27845,#7291 frontend_ref=41f0bacc(均 hl-admin v2.1 可达)。
2026-09-08 08:02:04 +08:00

20 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, updated_at, base, status_note
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at updated_at base status_note
hl-changelog/v2 7190 团期状态新增「出行完毕」TRIP_FINISHED,看板七桶扩八桶 admin wx(GIT) 修改接口 deployed verified verified mmg 2eb27845 2026-09-08 2026-09-08 dev-v3 前端已交付并验证(commit 2eb27845, 汇总工单项3):batchLifecycle OPS_STAGES/OPS_STAT_TABS/BATCH_STATUS_TO_OPS 三处插 TRIP_FINISHED「出行完毕」单射,位置在出行中与待审核之间,统计条按键名读 buckets.TRIP_FINISHED;batchLifecycle.spec 硬断言扩八键顺序+TRIP_FINISHED 单射。

团期模块:状态九态(新增「出行完毕」)与看板八桶

⚠️ 关键变化

  • 团期状态 8 → 9 态:新增 TRIP_FINISHED「出行完毕」,位于 TRAVELLING「出行中」之后、REVIEWING「核单中」之前。九态与中文名:RECRUITING 招募中 / RESOURCE_PREPARING 资源准备中 / MATERIAL_PREPARING 物料准备中 / PENDING_DEPARTURE 待出发 / TRAVELLING 出行中 / TRIP_FINISHED 出行完毕 / REVIEWING 核单中 / SETTLED 已结算 / CANCELLED 已取消。
  • 看板运营阶段 7 桶 → 8 桶:新增桶 TRIP_FINISHED「出行完毕」,位于 TRAVELLING 之后、AUDITING 之前。八桶顺序:RECRUIT, FORMED, PENDING_TRIP, TRAVELLING, TRIP_FINISHED, AUDITING, CHECKED, DISBANDED。GB-ADM-009 统计条 buckets 固定键由 7 个变 8 个;GB-ADM-001 / GB-ADM-008 的 opsStage 多一个可选值。
  • 推进由两个定时任务按日自动完成(出发日 ≤ 今天:待出发 → 出行中;返团日 < 今天:出行中 → 出行完毕;日期取 product 侧实时班期日期,不取团期快照)。上线时两个 sys_job 为 PAUSED,「出行完毕 → 核单中」发起核单入口落地前不会 resume,所以近期页面上不会自然出现该态,但契约已变,前端要先把桶/页签/映射补齐,否则出现时页签少一个、桶键被忽略。
  • 联动:出行完毕团期的房/车/导/摄芯片恒 DONE(与已返团同硬规则);对其子订单退团被拒 589501;预支入口在该态仍开放;转期/调容量/需求提报按既有规则在该态均拒。

一、背景

现象

wx 2026-09-06 要求看板状态页签在「出行中」后增加「出行完毕」。排查发现团期八态的后半段(待出发 → 出行中 → 核单中 → 已结算)此前没有任何代码推进(订单级有按日期推进的 job,团期级没有),测试库全部团期都停在已成团。本单新增正式状态并补齐团期级按日推进。

调用链

  1. hl-user-service sys_job(Quartz)groupBatchLifecycleJob.processDepartures() / processTripFinishes() → 桥接 bean 经 Feign → order-v3 POST /v3/internal/jobs/group-batch-departure/run、/group-batch-trip-finish/run(内部端点,网关不开放)
  2. order-v3 GroupBatchLifecycleJobService:取候选(PENDING_DEPARTURE / TRAVELLING)→ 按产品经 Feign 取 product 实时班期日期 → GroupBatchLifecycleTxService.advanceOne 同一事务 CAS 改状态 + 写时间线(BATCH_DEPART「系统自动发团」/ 新事件 BATCH_TRIP_FINISH「系统自动出行完毕」)
  3. 看板读侧:GroupBatchStageBuckets 九态折叠八桶 → GB-ADM-001 records[].batchStatus / batchStatusName、GB-ADM-009 buckets、GB-ADM-008 导出 opsStage

地面真相(测试服 dev-v3,2026-09-06 21:38-21:42,团期房务会话临时造数)

团期 造数 触发 job 后 说明
A 2096495107078328322(#7158验收班期) 状态 → PENDING_DEPARTURE;product 侧出发日 12-20 → 09-05;order 快照出发日仍 12-20 第一轮(出发日 12-20,未来)不动;第二轮(09-05)→ TRAVELLING 读 product 实时日期,快照未动
B 2096510069465088002(#7178验收班期) 状态 → TRAVELLING;product 侧返团日 12-28 → 09-05;order 快照返团日仍 12-27 第一轮不动;第二轮 → TRIP_FINISHED「出行完毕」 同上

两轮 sys_job 1041 / 1042 执行日志均 SUCCESS(毫秒级)。造数已由团期房务会话复原。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 团期看板分页(GB-ADM-001) GET /v3/admin/order/group-batch 入参枚举扩展 + 响应取值扩展 opsStage / batchStatus 新增 TRIP_FINISHED;records[].batchStatus 可为 TRIP_FINISHED、batchStatusName="出行完毕"
2 团期看板统计条(GB-ADM-009) GET /v3/admin/order/group-batch/summary 响应结构扩展 buckets 固定键 7 → 8,新增 TRIP_FINISHED,total = 八桶之和
3 团期看板导出(GB-ADM-008) GET /v3/admin/order/group-batch/export 入参枚举扩展 opsStage 新增 TRIP_FINISHED

三、接口详情

1. 团期看板分页 GET /v3/admin/order/group-batch

VO: GroupBatchListReqVO → Result<PageResult<GroupBatchPageItemRespVO>>

使用场景

团期看板列表(hl-ui src/stores/orderV2Batch.js:93-97 getGroupBatchPage());点「出行完毕」页签时传 opsStage=TRIP_FINISHED。

入参

字段 位置 类型 必填 约束 说明
productId query Long(字符串) 否 雪花 ID 按产品筛选
opsStage query String 否 RECRUIT / FORMED / PENDING_TRIP / TRAVELLING / TRIP_FINISHED / AUDITING / CHECKED / DISBANDED 新增 TRIP_FINISHED;非法值忽略不报错
batchStatus query String 否 九态之一 可传 TRIP_FINISHED
month query String 否 yyyy-MM 出发月份
keyword query String 否 已转义 班期编号 / 名称模糊
deadlineFrom / deadlineTo query String 否 yyyy-MM-dd 报名截止日区间
pageNo query Integer 否 默认 1 页码
pageSize query Integer 否 默认 20,最大 100 每页条数

出参 Result<PageResult<GroupBatchPageItemRespVO>>

字段 类型 说明
data.records[] Array 团期行(分页容器 records / total / page / pageSize)
data.records[].groupBatchId String(Long) 团期主订单 ID
data.records[].batchStatus String 九态之一,可为 TRIP_FINISHED
data.records[].batchStatusName String 中文名,TRIP_FINISHED 对应「出行完毕」
data.records[].chips Object 六芯片;TRIP_FINISHED 团期房/车/导/摄恒 DONE(硬规则,与已返团同)
其余字段 — 不变(productBatchId / productId / productName / batchNo / batchName / batchLabel / maxRooms / maxParticipants / enrolledPeople / enrolledRooms / remainRooms / remainParticipants / orderCount / enrollDeadline / departDate / endDate / receivableAmount / receivedAmount)

请求示例

GET /v3/admin/order/group-batch?productId=2056947670512971778&opsStage=TRIP_FINISHED&pageSize=10 HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

第二轮造数后实测(2026-09-06 21:42):

{
  "code": 200,
  "message": "成功",
  "data": {
    "records": [
      {
        "groupBatchId": "2096510069465088002",
        "productId": "2056947670512971778",
        "productName": "测试小蒙马-多档-固定金额",
        "batchName": "#7178验收班期",
        "batchStatus": "TRIP_FINISHED",
        "batchStatusName": "出行完毕",
        "orderCount": 1,
        "departDate": "2026-12-27",
        "endDate": "2026-12-28"
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 10
  },
  "success": true
}

空数据 / 降级响应

opsStage=TRIP_FINISHED 在 sys_job 未 resume 期间通常无命中:records 为空数组、total=0,不是错误。

{
  "code": 200,
  "message": "成功",
  "data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
  "success": true
}

错误响应

{
  "code": 589507,
  "message": "无操作权限(非团期管理员 / 非本定制师名下)",
  "data": null,
  "success": false
}

业务边界

  • opsStage 与 batchStatus 的映射:TRIP_FINISHED 桶 = TRIP_FINISHED 态(单射,不是复合桶;FORMED 仍是 RESOURCE_PREPARING + MATERIAL_PREPARING 复合桶)
  • #7189 合入后有「班期范围」筛选,默认「未结束」按返团日过滤;出行完毕/待审核/已审核的团期返团日必然已过,前端点这三个页签时应自动把范围切到「全部」

2. 团期看板统计条 GET /v3/admin/order/group-batch/summary

VO: Result<GroupBatchSummaryVO>(查询参数 productId / month / keyword,无请求 VO)

使用场景

看板页签计数(hl-ui orderV2Batch.js:74 getGroupBatchSummary()),与 GB-ADM-001 同筛选、不含 opsStage。

入参

字段 位置 类型 必填 约束 说明
productId query Long(字符串) 否 雪花 ID 按产品
month query String 否 yyyy-MM 出发月份
keyword query String 否 已转义 班期编号 / 名称模糊

出参 Result<GroupBatchSummaryVO>

字段 类型 说明
data.total Integer 命中团期总数 = 八桶之和
data.buckets Object 固定 8 键,顺序 RECRUIT, FORMED, PENDING_TRIP, TRAVELLING, TRIP_FINISHED, AUDITING, CHECKED, DISBANDED,无命中为 0(改前 7 键,无 TRIP_FINISHED)
data.subOrderCount Integer 命中团期活跃子订单合计(不变)

请求示例

GET /v3/admin/order/group-batch/summary?productId=2056947670512971778 HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

第二轮造数后实测(21:42):

{
  "code": 200,
  "message": "成功",
  "data": {
    "total": 6,
    "buckets": {
      "RECRUIT": 0,
      "FORMED": 2,
      "PENDING_TRIP": 0,
      "TRAVELLING": 1,
      "TRIP_FINISHED": 1,
      "AUDITING": 0,
      "CHECKED": 0,
      "DISBANDED": 2
    },
    "subOrderCount": 4
  },
  "success": true
}

空数据 / 降级响应

无命中团期时 total=0、subOrderCount=0,buckets 仍固定返回 8 键全 0。

{
  "code": 200,
  "message": "成功",
  "data": { "total": 0, "buckets": { "RECRUIT": 0, "FORMED": 0, "PENDING_TRIP": 0, "TRAVELLING": 0, "TRIP_FINISHED": 0, "AUDITING": 0, "CHECKED": 0, "DISBANDED": 0 }, "subOrderCount": 0 },
  "success": true
}

错误响应

{
  "code": 589507,
  "message": "无操作权限(非团期管理员 / 非本定制师名下)",
  "data": null,
  "success": false
}

业务边界

  • 桶键由后端枚举顺序生成,前端按对象键顺序或按自己的页签表读取都可以,但不要按索引位置取第 5 个当「待审核」(改前第 5 个是 AUDITING,改后是 TRIP_FINISHED)
  • 老前端未加新键时:多出的 TRIP_FINISHED 键被忽略,total 与页签计数之和会差出该桶的数量

3. 团期看板导出 GET /v3/admin/order/group-batch/export

VO: 无请求 VO(查询参数) → CSV 文件流 text/csv

使用场景

看板「导出」按钮(hl-ui exportGroupBatch()),筛选参数与 GB-ADM-001 同义、不含分页。

入参

字段 位置 类型 必填 约束 说明
productId query Long(字符串) 否 雪花 ID 按产品
month query String 否 yyyy-MM 出发月份
keyword query String 否 已转义 班期编号 / 名称模糊
opsStage query String 否 八桶之一 新增 TRIP_FINISHED

出参 CSV 文件流

字段 类型 说明
(响应体) text/csv 列与改前一致;状态列可出现「出行完毕」

请求示例

GET /v3/admin/order/group-batch/export?productId=2056947670512971778&opsStage=TRIP_FINISHED HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

{
  "code": 200,
  "message": "文件流(Content-Type: text/csv; Content-Disposition: attachment),此处仅示意,实际响应体为 CSV"
}

空数据 / 降级响应

无命中时返回只有表头的 CSV;命中 > 2000 行返回 589517。

{
  "code": 589517,
  "message": "导出行数超过上限,请缩小筛选范围",
  "data": null,
  "success": false
}

错误响应

{
  "code": 589507,
  "message": "无操作权限(非团期管理员 / 非本定制师名下)",
  "data": null,
  "success": false
}

业务边界

  • 权限 group-batch:export
  • opsStage 非法值忽略(与 GB-ADM-001 一致)

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

三个接口均为只读 GET,无请求体;本节写的是前端消费九态/八桶的规则。

✅ 正确 / ❌ 错误 payload 对照

场景 payload / 处理
✅ 页签 → 筛选 点「出行完毕」页签传 opsStage=TRIP_FINISHED(与其它页签同一套 opsStage)
✅ 状态 → 桶 八态映射表加 TRIP_FINISHED: 'TRIP_FINISHED';未知状态值按灰/默认样式,不抛错
✅ 统计条 按键名读 buckets.TRIP_FINISHED,不按索引
❌ 硬编码七桶数组 少一个页签、total 对不上
❌ 把 TRIP_FINISHED 当「已完成」终态 它之后还有核单中 / 已结算;核单入口在后续单

切换状态时的必要动作

无写接口。团期进入 TRIP_FINISHED 只由 sys_job 1042 完成(当前 PAUSED);前端不需要也不能手动推进。


五、数据库行为

order_group_batch.batch_status 为 VARCHAR(32),直接存新值 TRIP_FINISHED,无表变更、无 Flyway(order-v3)。hl-user-service Flyway V20260906_005__register_group_batch_lifecycle_jobs.sql 种子两行 sys_job(1041 团期出发推进 0 10 0 * * ?、1042 团期出行完毕推进 0 20 0 * * ?,job_group=ORDER,status=PAUSED)。

job 扫描条件 推进 时间线事件
1041 PENDING_DEPARTURE 且 product 侧出发日 ≤ 今天 → TRAVELLING BATCH_DEPART 系统自动发团
1042 TRAVELLING 且 product 侧返团日 < 今天 → TRIP_FINISHED BATCH_TRIP_FINISH 系统自动出行完毕

状态 CAS 与时间线在同一事务内原子提交;日期取不到 product 实时值时回退团期快照并记 WARN。


六、边界行为

  • 未登录 → 网关 401;无权限 → 589507
  • opsStage / batchStatus 传未知值 → 忽略该筛选,不报错
  • 返团日当天仍算出行中(< 今天 才推进);出发日当天即算出行中(≤ 今天)
  • 出行完毕团期:退团 → 589501;转期 / 调满团名额 / 需求提报按既有阶段门拒绝;预支仍可发起
  • HTTP 始终 200,按 code 判断

六.5、枚举 / 数据字典

batchStatus(com.hulalv.order.groupbatch.enums.GroupBatchStatus)

值 中文名 桶(GroupBatchStageBuckets.Bucket)
RECRUITING 招募中 RECRUIT
RESOURCE_PREPARING 资源准备中 FORMED
MATERIAL_PREPARING 物料准备中 FORMED
PENDING_DEPARTURE 待出发 PENDING_TRIP
TRAVELLING 出行中 TRAVELLING
TRIP_FINISHED 出行完毕(新增) TRIP_FINISHED(新增)
REVIEWING 核单中 AUDITING
SETTLED 已结算 CHECKED
CANCELLED 已取消 DISBANDED

opsStage / buckets 键(GroupBatchStageBuckets.Bucket)

RECRUIT 招募中 / FORMED 已成团 / PENDING_TRIP 待出行 / TRAVELLING 出行中 / TRIP_FINISHED 出行完毕 / AUDITING 待审核 / CHECKED 已审核 / DISBANDED 流团(前端页签文案沿用现有)。

六.6、修改前后对比

字段级对比

字段 修改前 修改后
GB-ADM-001 / 008 opsStage 取值 7 值 8 值(+ TRIP_FINISHED)
GB-ADM-001 records[].batchStatus 取值 8 值 9 值(+ TRIP_FINISHED,中文名「出行完毕」)
GB-ADM-009 buckets 键 7 键 8 键,TRIP_FINISHED 插在 TRAVELLING 与 AUDITING 之间

行为级对比

场景 修改前 修改后
待出发团期到出发日 无人推进,永远待出发 sys_job 1041(resume 后)每日 00:10 → 出行中
出行中团期过返团日 无人推进,永远出行中 sys_job 1042(resume 后)每日 00:20 → 出行完毕
出行完毕团期芯片 不存在该态 房/车/导/摄恒 DONE(与已返团同)
出行完毕团期退团 不存在该态 589501
原七桶各自口径 — 不变

六.7、影响评估

  • 向后兼容:只增枚举值/键,不改字段名;老前端不改代码不报错,但页签少「出行完毕」、统计条多出的键被忽略
  • 前端是否必须同步上线:否(job PAUSED 期间不会出现该态数据);但应在 job resume 前补齐
  • 数据:order-v3 无表变更;user-service 只有 sys_job 种子

七、不影响范围

  • 仅影响: 团期看板页签/统计条/导出的桶集合,团期状态取值
  • 零影响:
    • #7204 导/摄芯片零指派口径、房/车/约/保芯片
    • 订单(子订单)状态机与订单接口
    • 团期成团 / 取消成团 / 流团 / 物资确认 / 结算守卫(仍要求核单中)
    • 小程序

八、测试环境已验证

真实接口输出(测试服 api.test.1814.love,2026-09-06 21:38-21:42,登录后切 ADMIN / 触发 job 切 SUPER_ADMIN):

GET /v3/admin/order/group-batch/summary?productId=2044306857534636034                       → 200, buckets 键序 RECRUIT,FORMED,PENDING_TRIP,TRAVELLING,TRIP_FINISHED,AUDITING,CHECKED,DISBANDED ✓
POST /admin/job/1041/trigger、/admin/job/1042/trigger(第一轮,造数期均为未来日期)           → sys_job_log SUCCESS,A/B 状态不动 ✓
POST /admin/job/1041/trigger、/admin/job/1042/trigger(第二轮,product 侧日期改到 09-05)    → SUCCESS,A→TRAVELLING、B→TRIP_FINISHED,order 快照日期未动 ✓
GET /v3/admin/order/group-batch?productId=2056947670512971778&opsStage=TRIP_FINISHED        → 200, 1 行 B「出行完毕」 ✓
GET /v3/admin/order/group-batch/summary?productId=2056947670512971778                       → TRAVELLING=1, TRIP_FINISHED=1 ✓
GET /v3/admin/order/group-batch/2096510069465088002/chips/hotel                             → aggregateStatus=DONE(硬规则) ✓
POST /v3/admin/order/group-batch/2096510069465088002/sub-order/2096510069234401282/withdraw → 589501 ✓

验证团期: A 2096495107078328322、B 2096510069465088002(产品 2056947670512971778「测试小蒙马-多档-固定金额」),造数已复原。单测:GroupBatchStageBucketsTest 12/0、GroupBatchSummaryVOTest 2/0、GroupBatchStatusTest 6/0、GroupBatchLifecycleJobServiceTest 11/0、GroupBatchLifecycleTxServiceTest 4/0、GroupBatchLifecycleJobTest 3/0、GroupBatchMapperIT 13/0;合入后 dev-v3 HEAD 全量 order-v3 8726/0、hl-user-service QuartzJobExecutorTest 16/0。部署:Deploy Panel 21:20-21:22 双实例滚动完成(order-v3 + user-service),分支 dev-v3。


十、相关文档

  • 关联 Issue: wx/HL#7190
  • 关联 PR: wx/HL#7212
  • 同现场: #7188(「第N期」序号)、#7189(看板以产品全班期为基底 + 班期范围筛选)、#7204(导/摄芯片零指派口径)
  • 后续单: 「出行完毕 → 核单中」发起核单入口(落地前两个 sys_job 保持 PAUSED)

关联 / 联系人

链接

联系人

  • 后端负责人: @wx