--- schema: "hl-changelog/v2" ticket: "7987" title: "团期时间线新增开窗与重配两类事件,事件类型枚举扩展" consumer: "admin" author: "wx(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "not_required" frontend_owner: "" frontend_ref: "" target_release: "" verified_at: "" status_note: "⚠️ 2026-09-21 清空 frontend_owner/frontend_ref:按 BACKEND_CHANGELOG_DELIVERY_GUIDE,not_required 条目**任何人(含前端)不得回写** frontend_owner / frontend_ref / target_release / verified_at——这 4 个是「前端需要动作」的认领标记,填了会被发布门禁 E_FRONTEND 残留校验拦下(2026-08-19 #6077 就是这么被拦的)。前端表达「已知悉」用评论/口头即可,不动 frontmatter。本文件能推上去是因为门禁**只扫新增路径**,不是因为合规。mmg 的实证本身保留在下文。 gateway_status=verified 的依据:2026-09-20 18:22-18:46 经网关 https://api.test.1814.love:9443 实测(账号 cw_test_7444)。GET /v3/admin/order/group-batch/{id}/status-logs 在两个批次上分别取到 BATCH_VEHICLE_REQUIREMENT_REOPENED(开窗,extra 含 windowMinutes/blockedStage/expiresAt/scopeGroupCodes/scopeDates 五项齐全)与 BATCH_VEHICLE_DISPATCH_RECONFIGURED(重配),eventType/eventTypeName/changeType=DATA/extra 各字段逐一对照一致。⚠️ 本次实测发现并已订正一处契约偏差:重配事件的 operatorId 原写字符串 SYSTEM,实测为 null(与库里其它 SYSTEM 类事件惯例一致),判为文档写错而非实现错,已在字段表/字段值/JSON 示例/注意事项共 5 处改完。前端若按原文档判空会得到相反预期,故这条订正与发布同一批。 前端实证翻 not_required(mmg 2026-09-20):前端无自建 eventType 映射表,StatusLogsPanel 渲染 `eventTypeName || eventType || '事件'`(后端直供中文名+原码兜底),operatorType=SYSTEM 时 operatorId=null/operatorName「系统」是该面板注释钉住的既有口径,两类新事件与 operatorId 订正均自动正常显示,零改动。 【上一轮原注】backend_status=deployed 的判据(2026-09-20 18:35 复核):hl-order-service-v3 测试服部署点 e179e09bd(2026-09-20 17:55:02 发布),`git merge-base --is-ancestor ab92377c7 e179e09bd` = true,故本篇端点的代码确已在测试服运行的字节里。⚠️ 这是一次**时点读数**:测试服由多会话共用,随时可能被滚到别的提交;origin/dev-v3 在本次复核时已前进到 f56692a51,落后的是部署点不是本篇。 gateway_status 保持 pending——本会话未对本篇端点做任何真实网关调用,正文示例值的来源已在各小节逐处标注(单元测试字面量 / @ApiModelProperty example 声明),不是抓包。待网关复验后再置 verified,**不得为了让门禁变绿改这个位**。" updated_at: "2026-09-20" base: "dev-v3" --- # order-v3: 团期时间线新增开窗与重配两类事件 > **存放目录**: 二期(v3) → `changelogs-v2/{YYYY-MM}/` > > **服务**: hl-order-v3 (端口 8021) > **PR**: #8039 > **Issue**: #7987 > **日期**: 2026-09-20 > **影响范围**: 管理后台 - 团期详情页 - 状态流水/时间线 --- ## ⚠️ 关键变化 后端在团期时间线(`group_batch_status_log` 表)新增两种事件记录: - **BATCH_VEHICLE_REQUIREMENT_REOPENED**(开窗事件)—— 管理员显式开启受控重配窗口时写入 - **BATCH_VEHICLE_DISPATCH_RECONFIGURED**(重配事件)—— fleet 回调确认重配生效时写入 ~~**前端必须新增这两个 event_type 值的渲染分支**,否则这两类事件在管理后台团期时间线上将无法正常显示其标签名(见下文「③ 前端渲染缺口」)。~~ ✅ **2026-09-20 mmg 实证推翻了上面这句,前端零改动**(原句划掉保留接 grep):`StatusLogsPanel` 渲染的是 `eventTypeName || eventType || '事件'`,**后端直供中文名 + 原码兜底**,前端**没有**自建 eventType 映射表 ⇒ 两类新事件与 `operatorId` 那处订正都会自动正常显示。 📌 下文「③ 前端渲染缺口」一节同样按这条实证作废——**它描述的缺口在当前前端实现里不存在**。⚠️ 但这个结论依赖「后端继续直供 `eventTypeName`」:哪天后端让该字段返回 null(正文「注意事项」里写的历史脏值场景就是一例),前端会退化成显示原始 code,那时这条渲染缺口会重新成立。 --- ## 一、背景 #7987 实施"受控重配窗口"机制:管理员可在团期进入待出发后仍显式开一个时间限制的窗口,允许车务在此期间重新排车。此前这两件事的事实只落在需求行的三个字段(`reconfigure_reason` / `reconfigure_opened_by` / `reconfigure_opened_at`),但运营打开团期详情页时看不到这些列,无法追溯窗口何时开过。 本次变更补上团期时间线的留痕,让管理员在团期详情页就能看到「谁在何时以什么原因开了重配窗口」与「窗口内换车是否生效」。 --- ## 二、变更接口清单 既存接口(#7304 落地)返回值扩展: | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 团期状态流水查询 | GET | `/v3/admin/order/group-batch/{id}/status-logs` | 响应新增 event_type 值 | 新增两种事件类型 | --- ## 三、接口详情 ### 1. 团期状态流水查询 `GET /v3/admin/order/group-batch/{id}/status-logs` **VO**: `GroupBatchStatusLogItemVO` (既存响应 VO,新增 eventTypeName 映射值) #### 使用场景 管理后台团期详情页的状态流水/时间线面板,用于向运营展示该团期的历史状态变化与重要操作记录。本次变更使该时间线新增两类事件的可见性。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |------|------|------|------|------|------| | id | Path | Long | ✅ | - | 团期主订单 ID | #### 出参 `Result>` | 字段 | 类型 | 说明 | |------|------|------| | logId | String | 流水记录 ID | | groupBatchId | Long | 团期主订单 ID | | changeType | String | 变更类型:STATUS(状态流转) / DATA(数据变更) | | eventType | String | 事件类型代码(如 BATCH_VEHICLE_REQUIREMENT_REOPENED) | | eventTypeName | String | 事件类型中文名(**新增两种**:团车受控重开·已开配车窗口 / 团车受控重配·车辆安排已变更) | | fromStatus | String | 状态前值代码(如 PENDING_DEPARTURE) | | fromStatusName | String | 状态前值中文名 | | toStatus | String | 状态后值代码 | | toStatusName | String | 状态后值中文名 | | content | String | 事件文本内容(前端直接渲染) | | reason | String | 事件原因/备注(可为 null) | | operatorType | String | 操作人类型:ADMIN / SYSTEM / MQ | | operatorId | String | 操作人 ID。⚠️ **2026-09-20 网关实测订正**:**`operatorType=SYSTEM` 时本字段是 `null`,不是字符串 `"SYSTEM"`**(与库里其它 SYSTEM 类事件如 `BATCH_VEHICLE_REQUIREMENT_DONE` 的惯例一致)。前端判空请按 `null` 处理 | | operatorName | String | 操作人名称 | | extra | Map | 结构化附加数据,字段随事件类型变化(见下文"新增事件详解") | | changedAt | String | 事件发生时刻(ISO 8601) | #### 新增事件类型详解 **BATCH_VEHICLE_REQUIREMENT_REOPENED 事件** - `eventType`: `"BATCH_VEHICLE_REQUIREMENT_REOPENED"` - `eventTypeName`: `"团车受控重开·已开配车窗口"` - `changeType`: `"DATA"` (状态内数据变更,fromStatus = toStatus) - `operatorType`: `"ADMIN"` - `operatorId`: 开窗管理员 ID - `operatorName`: 开窗管理员真名 - `content`: "开启受控重配窗口:允许车务在 X 分钟内重新安排本团车辆(授权 N 个乘车分组 / M 个行程日,2026-09-20 10:30:00 前有效)。此前团期已进入「待出发」,正常不可再配车。" - `reason`: 管理员必填的开窗原因(如"团期特殊变更") - `extra`: 结构化数据 ```json { "requirementId": "需求行主键(字符串)", "requirementVersion": 需求行版本号(整数), "blockedStage": "PENDING_DEPARTURE", "windowMinutes": 120, "expiresAt": "2026-09-20T12:30:00", "scopeGroupCodes": ["乘车分组编号数组"], "scopeDates": ["2026-09-21", "2026-09-22"] } ``` **BATCH_VEHICLE_DISPATCH_RECONFIGURED 事件** - `eventType`: `"BATCH_VEHICLE_DISPATCH_RECONFIGURED"` - `eventTypeName`: `"团车受控重配·车辆安排已变更"` - `changeType`: `"DATA"` (状态内数据变更,fromStatus = toStatus) - `operatorType`: `"SYSTEM"` - `operatorId`: **`null`**(⚠️ **2026-09-20 网关实测订正**:原写 `"SYSTEM"`,实测为 `null`) - `operatorName`: `"系统"` - `content`: "本团车辆安排已被重新排定:车务在受控重配窗口内完成换车,新的配车计划(版本 20260920_v1)已生效,原计划作废。开窗授权人:张三;具体经办人见车务配车记录。" - `reason`: 开窗时管理员填写的原因(沿用窗口的 reason,非重配操作人的备注) - `extra`: 结构化数据 ```json { "requirementId": "需求行主键(字符串)", "requirementVersion": 需求行版本号(整数), "planVersion": "fleet 配车计划版本号(字符串)", "reconfigureOpenedBy": "开窗管理员 ID(与前一条事件的 operatorId 对应)", "reconfigureOpenedAt": "2026-09-20T10:15:30" } ``` #### 请求示例 ```json GET /v3/admin/order/group-batch/8000001/status-logs ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": [ { "logId": "12345", "groupBatchId": "8000001", "changeType": "DATA", "eventType": "BATCH_VEHICLE_REQUIREMENT_REOPENED", "eventTypeName": "团车受控重开·已开配车窗口", "fromStatus": "PENDING_DEPARTURE", "fromStatusName": "待出发", "toStatus": "PENDING_DEPARTURE", "toStatusName": "待出发", "content": "开启受控重配窗口:允许车务在 120 分钟内重新安排本团车辆(授权 2 个乘车分组 / 3 个行程日,2026-09-20T12:30:00 前有效)。此前团期已进入「待出发」,正常不可再配车。", "reason": "临时增加3人,需调整座位分组与用车方案", "operatorType": "ADMIN", "operatorId": "1001", "operatorName": "李四", "extra": { "requirementId": "7000001", "requirementVersion": 2, "blockedStage": "PENDING_DEPARTURE", "windowMinutes": 120, "expiresAt": "2026-09-20T12:30:00", "scopeGroupCodes": ["GRP001", "GRP002"], "scopeDates": ["2026-09-21", "2026-09-22", "2026-09-23"] }, "changedAt": "2026-09-20T10:30:00" }, { "logId": "12346", "groupBatchId": "8000001", "changeType": "DATA", "eventType": "BATCH_VEHICLE_DISPATCH_RECONFIGURED", "eventTypeName": "团车受控重配·车辆安排已变更", "fromStatus": "PENDING_DEPARTURE", "fromStatusName": "待出发", "toStatus": "PENDING_DEPARTURE", "toStatusName": "待出发", "content": "本团车辆安排已被重新排定:车务在受控重配窗口内完成换车,新的配车计划(版本 20260920_v1)已生效,原计划作废。开窗授权人:李四;具体经办人见车务配车记录。", "reason": "临时增加3人,需调整座位分组与用车方案", "operatorType": "SYSTEM", "operatorId": null, "operatorName": "系统", "extra": { "requirementId": "7000001", "requirementVersion": 2, "planVersion": "20260920_v1", "reconfigureOpenedBy": "1001", "reconfigureOpenedAt": "2026-09-20T10:30:00" }, "changedAt": "2026-09-20T11:45:00" } ], "success": true } ``` #### 空数据 / 降级响应 ```json { "code": 200, "data": [], "success": true } ``` #### 错误响应 ```json { "code": 589500, "message": "团期不存在", "success": false, "data": null } ``` #### 业务边界 - 接口返回的时间线按 `changedAt` 升序排列(从最早到最新) - 两个新事件都属于 `DATA` 类(状态内数据变更),不涉及团期主状态 `batch_status` 变化 - 库里若有历史脏值或未知 event_type,后端 eventTypeLabel 返回 null,前端需兜底显示原始 code 值 --- ## 四、契约约束与正确调用方式 > 本节说明后端接受请求、返回响应的规则。 ### ✅ 正确 / ❌ 错误请求对照 | 场景 | 请求示例 | 结果 | |------|---------|------| | ✅ 查询既存团期的时间线 | `GET /v3/admin/order/group-batch/8000001/status-logs` | 200 + 时间线列表 | | ✅ 无流水时返回空列表 | `GET /v3/admin/order/group-batch/9999999/status-logs`(不存在团期) | 200 + `data: []` | | ❌ 团期 ID 非数字 | `GET /v3/admin/order/group-batch/abc/status-logs` | 400 | ### 字段约束与兼容性规则 - **eventType 兼容性**:库里可能存在本版本未定义的历史 event_type 值 → 后端 eventTypeLabel 返回 null → 前端应兜底显示原始 code 值,而不是报错 - **extra 字段**:根据 eventType 不同而变化(见下文详解);前端需根据 eventType 判断应读取哪些 extra 字段,勿假设所有事件的 extra 结构相同 - **operatorType 非 ADMIN 时**:⚠️ **2026-09-20 网关实测订正**:**`operatorId` 是 `null`、`operatorName` 是 `"系统"`——两个字段形态不同,不要当成同一回事**(原文把它们合并描述成「可能不是真实人名」,会让前端以为 `operatorId` 也有值) → 前端应按类型判断如何渲染,勿硬编码为"管理员" - **reason 字段**:可为 null(仅新增事件强制填写,既有历史事件可能无此字段) → 前端应做 null check --- ## 六.5、枚举:新增事件类型 ### eventType(GroupBatchLogEventType) **所属字段**: `GroupBatchStatusLogItemVO.eventType` | **类型**: `String` | **枚举类**: `com.hulalv.order.groupbatch.enums.GroupBatchLogEventType` 新增两个枚举值(共有 N+2 个值): | 值 | 中文名 | 说明 | changeType | 何时写入 | |----|------|------|-----------|---------| | `BATCH_VEHICLE_REQUIREMENT_REOPENED` | 团车受控重开·已开配车窗口 | 管理员显式开启受控重配窗口,允许车务在时间限制内重新排车 | DATA | 调用 POST `/v3/admin/order/group-batch/{id}/vehicle-requirement/reopen` 时 | | `BATCH_VEHICLE_DISPATCH_RECONFIGURED` | 团车受控重配·车辆安排已变更 | fleet 就绪回调确认重配生效,新车辆计划已应用,原计划作废 | DATA | fleet Outbox 回调解除受控重开阻断时 | ### operatorType(操作人类型) **所属字段**: `GroupBatchStatusLogItemVO.operatorType` | **类型**: `String` 既有三种值,新增事件涉及的分别是: | 值 | 中文名 | 说明 | 示例事件 | |----|------|------|---------| | `ADMIN` | 管理员 | 真实的管理后台登录用户 | BATCH_VEHICLE_REQUIREMENT_REOPENED | | `SYSTEM` | 系统 | 无 HTTP 请求上下文的自动操作(MQ / 定时任务 / 回调) | BATCH_VEHICLE_DISPATCH_RECONFIGURED | | `MQ` | MQ 事件 | MQ 消费触发(如支付/退款回调) | 既有其他事件 | --- ## 四、前端需求与缺口说明 ### ① eventTypeLabel 映射(前端渲染分支) **后端实现**(`GroupBatchStatusLogService.java:237-248`): ```java private String eventTypeLabel(String value) { if (value == null) { return null; } for (GroupBatchLogEventType type : GroupBatchLogEventType.values()) { if (type.getValue().equals(value)) { return type.getLabel(); } } return null; // 未知值返回 null } ``` **当前状况**: - 后端遍历枚举查找 event_type,找到则返回 label,否则返回 null - 前端收到的 eventTypeName 字段值为 null 时,该行事件在时间线上**显示为空白**(既不报错、也不显示原始值,这是现状) **前端必须新增的映射**: ```typescript // 示例伪码 const eventTypeLabels = { "BATCH_VEHICLE_REQUIREMENT_REOPENED": "团车受控重开·已开配车窗口", "BATCH_VEHICLE_DISPATCH_RECONFIGURED": "团车受控重配·车辆安排已变更", // ... 既有其他 event_type ... }; ``` **不加分支的后果**:这两类事件在管理后台团期时间线上无法显示其事件名称,运营只看得到时刻/操作人/备注,但看不出"这是什么事件",影响运营追溯。 ### ② 重配事件的操作人恒为 SYSTEM(不能拿 extra 字段顶替) **源码事实**(`GroupBatchService.java:1089-1118`,recordReconfigureTrail 方法): ```java // 就绪回调中,无 HTTP 请求上下文,operatorResolver.resolve() 返回 SYSTEM Operator operator = operatorResolver.resolve(); // → Operator.system() groupBatchStatusLogService.recordDataChange(groupBatchId, GroupBatchLogEventType.BATCH_VEHICLE_DISPATCH_RECONFIGURED, batch == null ? null : GroupBatchStatus.fromCode(batch.getBatchStatus()), content, window.reason(), extra); ``` **重配事件的字段值**: - `operatorType`: `"SYSTEM"` - `operatorId`: **`null`**(⚠️ **2026-09-20 网关实测订正**:原写 `"SYSTEM"`,实测为 `null`) - `operatorName`: `"系统"` - `extra.reconfigureOpenedBy`: 开窗管理员 ID(**不是**重配操作人) - `extra.reconfigureOpenedAt`: 开窗时刻(**不是**重配时刻,重配时刻在 changedAt) **这不是 bug,是设计**: - 重配的真实经办人(谁在车务后台点的"重配"按钮)只存在于 fleet 侧的 `fleet_group_dispatch.updated_by` - order-v3 是接收者,fleet 回调进来时没有经办人载荷 - `extra.reconfigureOpenedBy` 答的是"**谁授权开的窗**"(过去的管理动作),与"**谁换的车**"(当前的车务动作)是两个不同的人、不同的时刻 **前端若把 `extra.reconfigureOpenedBy` 显示成"经办人",就是把一个错误的责任人写到审计页面上**。 - ✅ 正确做法:operatorName 显示"系统",content 或 extra.reconfigureOpenedBy 里可补充说明"开窗人是谁" - ❌ 错误做法:拿 extra.reconfigureOpenedBy 冒充 operatorId/operatorName 展示成经办人 ### ③ 开窗事件的操作人是真实人(与重配事件不同) **源码事实**(`GroupVehicleRequirementService.java:2305-2347`,recordReopenTrail 方法): ```java public GroupVehicleReopenRespVO doReopen(Long groupBatchId, GroupVehicleRequirementReopenReqVO req, String operatorId) { // ... 业务逻辑 ... recordReopenTrail(groupBatchId, batch, active, req, windowMinutes, expiresAt); } private void recordReopenTrail(...) { // recordDataChange 内部调 operatorResolver.resolve(),因为这是 HTTP 请求上下文 // 会从 AdminAuthInterceptor 注入的 AdminContext 里取当前登录管理员 groupBatchStatusLogService.recordDataChange(groupBatchId, GroupBatchLogEventType.BATCH_VEHICLE_REQUIREMENT_REOPENED, GroupBatchStatus.fromCode(batch.getBatchStatus()), content, req.getReason(), extra); } ``` **开窗事件的操作人**: - `operatorType`: `"ADMIN"`(不是 SYSTEM) - `operatorId`: 调用 reopen 端点的管理员 ID(真实人) - `operatorName`: 管理员真名 **两个事件的操作人不同的原因**: - 开窗:用户通过管理后台 HTTP 端点主动触发 → 上下文有 AdminContext → operatorResolver 返回真实人 - 重配:fleet 异步回调 → 无 HTTP 请求上下文 → operatorResolver 返回 SYSTEM **前端不能混淆**:别以为所有时间线事件的 operatorName 都是真实人,重配这条特殊。 --- ## 五、数据库行为 新增行落在 `group_batch_status_log` 表: | 事件 | 写入时机 | from_status | to_status | change_type | 示例 | |------|----------|------------|-----------|-------------|------| | BATCH_VEHICLE_REQUIREMENT_REOPENED | 调用 POST `/v3/admin/order/group-batch/{id}/vehicle-requirement/reopen` 时 | PENDING_DEPARTURE | PENDING_DEPARTURE | DATA | 管理员张三在 2026-09-20 10:30 开窗 | | BATCH_VEHICLE_DISPATCH_RECONFIGURED | fleet 就绪回调解除受控重开阻断时 | PENDING_DEPARTURE | PENDING_DEPARTURE | DATA | fleet 确认换车后在 2026-09-20 11:45 生效 | **关键**:两个事件都不改变团期 batch_status,`from_status` 与 `to_status` 相同。 --- ## 六、边界行为 - **库里存在历史脏值** → 后端 eventTypeLabel 返回 null → 前端时间线该行显示空白或兜底处理 - **并发写入** → 开窗事务与重配事务独立,都跟随各自的外层事务(不丢失) - **幂等性** → 开窗已有生效窗口时幂等返回既有令牌(不重复写库);普通首配回调、常规刷新回调若无受控重开阻断时 → CAS 0 行返回 → 不落本事件(常态) --- ## 六.6、修改前后对比 ### 接口行为对比 | 行为 | 改前 | 改后 | |------|------|------| | 时间线中开窗操作的可见性 | 三个字段存库但页面不展示 | 新增一条 DATA 类事件,时间线上可见 | | 时间线中重配操作的可见性 | 无记录 | 新增一条 DATA 类事件,标明"车已换、谁开的窗、老计划作废" | | 事件类型枚举 | 共 N 种 | 新增 2 种,共 N+2 种 | | 前端事件渲染 | 既有 N 种 event_type 的映射 | 需新增 BATCH_VEHICLE_REQUIREMENT_REOPENED / BATCH_VEHICLE_DISPATCH_RECONFIGURED 两条映射 | --- ## 六.7、影响评估 - **是否破坏向后兼容**: 否。既存接口返回值扩展,老 event_type 不变 - **前端是否必须同步上线**: **是**。不新增渲染映射会导致新增两类事件在时间线上显示为空白 - **前端 workaround 清理点**: - 若前端已有"event_type 未知时显示原始 code"的兜底逻辑,可临时显示 `BATCH_VEHICLE_REQUIREMENT_REOPENED` 等原始值 - 但正式上线必须使用中文标签,不能长期显示原始值(运营不认识) --- ## 七、不影响范围 - **仅影响**: 管理后台 - 团期详情页 - 状态流水/时间线面板(新增两类事件的渲染) - **零影响**: - 团期主状态推进(batch_status 机制不变) - 用车需求状态机(需求行读写逻辑不变) - 订单详情、C 端行程页面(无此数据源) - 旧团期数据(存量团期的时间线不会补充新事件) --- ## 八、测试环境已验证 后端逻辑验证(提交 ab92377c7): ``` POST /v3/admin/order/group-batch/8000001/vehicle-requirement/reopen 请求体: { "scopeGroupCodes": ["GRP001"], "scopeDates": ["2026-09-21"], "reason": "test reason" } → 200, group_batch_status_log 新增 1 行 BATCH_VEHICLE_REQUIREMENT_REOPENED ✓ fleet 就绪回调(模拟) request: {"groupBatchId": 8000001, "requirementId": 7000001, "requirementVersion": 2, "planVersion": "v1"} → 200, group_batch_status_log 新增 1 行 BATCH_VEHICLE_DISPATCH_RECONFIGURED ✓ GET /v3/admin/order/group-batch/8000001/status-logs → 200, 返回值中 eventTypeName 正确映射(后端已验证) ✓ 前端渲染验证:**待前端补充映射后联调** ``` --- ## 九、相关历史 PR | PR | Issue | 说明 | 是否仍有效 | |-------|-------|------|---------| | #7986 | #7986 | 受控重配窗口核心机制(团车需求侧) | ✅ 有效 | | #8039 | #7987 | 本 PR - 补团期时间线留痕 | ✅ 最新 | --- ## 十、相关文档 - **后端枚举定义**: [`hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/enums/GroupBatchLogEventType.java`](https://git.1814.love:8443/wx/HL/blob/dev-v3/hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/enums/GroupBatchLogEventType.java) - BATCH_VEHICLE_REQUIREMENT_REOPENED 定义:第 314-344 行 - BATCH_VEHICLE_DISPATCH_RECONFIGURED 定义:第 347-376 行 - **时间线服务**: [`hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/service/GroupBatchStatusLogService.java`](https://git.1814.love:8443/wx/HL/blob/dev-v3/hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/service/GroupBatchStatusLogService.java) - eventTypeLabel 实现:第 237-248 行 - **开窗留痕**: [`hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/service/GroupVehicleRequirementService.java`](https://git.1814.love:8443/wx/HL/blob/dev-v3/hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/service/GroupVehicleRequirementService.java) - recordReopenTrail 方法:第 2329-2387 行 - **重配留痕**: [`hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/service/GroupBatchService.java`](https://git.1814.love:8443/wx/HL/blob/dev-v3/hl-order-service-v3/src/main/java/com/hulalv/order/groupbatch/service/GroupBatchService.java) - recordReconfigureTrail 方法:第 1089-1118 行 --- ## 关联 / 联系人 ### 链接 - **Issue**: [#7987](https://git.1814.love:8443/wx/HL/issues/7987) - **PR**: [#8039](https://git.1814.love:8443/wx/HL/pulls/8039) - **Merge commit**: [ab92377c7](https://git.1814.love:8443/wx/HL/commit/ab92377c7) ### 联系人 - **后端负责人**: @wx - **前端对接人**: @mmg(hl-ui 仓库,需新增 eventTypeLabel 映射)