From e3f9f14755c8d63c8db103a74174fd9d5d5a13bd Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Tue, 28 Jul 2026 11:36:08 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20=E8=AE=B0=E5=BD=95=E6=9C=80?= =?UTF-8?q?=E7=BB=88=E6=B4=BE=E8=BD=A6=E6=96=B9=E6=A1=88=E4=BB=A3=E9=99=85?= =?UTF-8?q?=20(#5308)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...终派车方案取消恢复代际-修改接口-管理后台.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 changelogs-v2/2026-07/28_5308_最终派车方案取消恢复代际-修改接口-管理后台.md diff --git a/changelogs-v2/2026-07/28_5308_最终派车方案取消恢复代际-修改接口-管理后台.md b/changelogs-v2/2026-07/28_5308_最终派车方案取消恢复代际-修改接口-管理后台.md new file mode 100644 index 0000000..9434b6f --- /dev/null +++ b/changelogs-v2/2026-07/28_5308_最终派车方案取消恢复代际-修改接口-管理后台.md @@ -0,0 +1,93 @@ +--- +schema: "hl-changelog/v2" +ticket: "5308" +title: "最终派车方案取消恢复代际" +consumer: "admin" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "not_required" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "仅修正 Fleet 内部最终方案身份、取消恢复与需求完成语义;接口路径、请求响应字段和前端交互均不变" +updated_at: "2026-07-28" +base: "dev-v3" +--- + +# Fleet:最终派车方案取消恢复代际 + +> **服务**:`hl-fleet-service` +> **Issue**:#5308 +> **影响页面**:管理后台车务管理 → 逐日派车方案保存、手工取消/恢复、DIRECT/HOLD 改派 +> **兼容性**:接口路径、方法、请求/响应字段、错误码及业务五态不变;仅修正内部最终方案身份和需求完成闭环 + +## 问题与目标 + +自定义最终方案完成后,手工取消某个稳定车辆槽位会触发需求重开,恢复后应重新完成。旧实现只有布尔型最终标记,无法区分当前方案、合法改派 tombstone 和后续重提的新方案;多槽部分取消时,剩余槽位可能被误判为新的完整方案,旧取消行也可能在新方案后被错误恢复。 + +本次为 Fleet 内部最终派车方案增加持久化代际。代际是数据库内部不透明令牌,不进入 API、完成回调或前端状态。 + +## 变更接口(既有语义修正) + +### `POST /admin/fleet/assignments/batch` + +请求和响应形状不变: + +1. 每次最终方案提交会按精确 `assignmentIds` 将全部当前可变切片标记为同一新代,并严格核对实际更新行数;精确重提、仅价格原因重提和 partial daily rewrite 均按新当前代收敛。 +2. 当前方案按 `stable slotId × serviceDate` 全拓扑校验。多个非空 current generation、当前代外 active 行、孤儿 generation,以及存在退休历史但没有可解析非空 current 代的场景均 fail closed,不再回退为订单建议数量的“看似完整”方案。 +3. 滚动发布窗口仅兼容“单一非空 current generation + `dispatchPlanFinalized=1` 的 legacy null 行”;这些行按同代完整拓扑校验,不按 generation 数值大小推断先后。 + +### 既有取消、恢复与改派接口 + +路径和字段均不变: + +- 手工取消保留当前代身份;只恢复一个被取消槽位时仍保持不完整,全部当前代逻辑 key 恢复后才重新生成或重启 `REQUIREMENT_DONE`。 +- REOPEN 先到时,恢复后按相同 topology fingerprint 重新激活完成事件;恢复先到时,迟到 REOPEN 会因当前拓扑已完整而跳过,不回退需求状态。 +- DIRECT/HOLD 正常改派的 replacement 继承当前代。合法 canceled tombstone 在存在唯一同代 active replacement 时不污染完整性;HOLD 在确认前仍不完整。 +- 已退休旧代、已有同代 active replacement 的 tombstone、以及全局失效后仅保留退休代际证据的取消行均禁止恢复。 +- driver reject、daily rewrite、订单/需求系统取消会退休 current 标记并保留 generation 作为禁止恢复证据;跨 requirement rebind 会清除旧身份,下一次最终提交建立新代。 +- `completed`、`canceled` 业务状态和历史/完结/关账只读规则不变;generation 不进入完成 topology fingerprint。 + +## 数据库迁移 + +新增 Fleet 内部 nullable BIGINT:`fleet_assignment.dispatch_plan_generation`。 + +- 迁移先把存量 `canceled + dispatch_plan_finalized=1` 的历史改派 tombstone 退休为非 current。 +- 再仅对非 canceled 的存量 current 行按 requirement 回填兼容 generation。 +- canceled 历史不猜测代际;无新增索引,读取仍按 `requirement_id` 批量完成。 + +## 前端处理 + +无需修改前端代码: + +- 继续使用现有逐日方案保存、取消、恢复、DIRECT/HOLD 改派接口和状态字段; +- 不新增 `generation` 请求或响应字段,不应在前端推断方案代际; +- 状态刷新、错误提示和页面交互保持现状。 + +因此 `frontend_status=not_required`,且不修改 `hl-ui`。 + +## 不影响范围 + +- 不修改 Controller mapping、请求/响应 DTO/VO/BO、Feign、shared Java、枚举或错误码。 +- 不修改车辆/司机冲突规则、费用、保险、对账或业务五态。 +- 不按 Snowflake 数值比较代际先后。 +- 不产生逐槽或逐候选 N+1。 + +## 验证证据 + +- 后端 PR [wx/HL#5312](https://git.1814.love:8443/wx/HL/pulls/5312) 已 squash 合并至 `dev-v3`,合并提交 `883fc61a0`。 +- `hl-fleet-service` 已滚动部署测试环境,8087/8187 双实例健康;验证部署任务 `493f862d` 成功。 +- 定向 `AssignmentServiceTest`:302 tests,0 failures,0 errors,0 skipped。 +- Fleet reactor verify:2507 tests,0 failures,0 errors,1 skipped;Spotless 629 Java files clean。 +- 真表 BIGINT 落库读回、全局失效退休证据及迁移先退休 tombstone 再回填 active 的行为测试通过。 +- 两轮独立 Reviewer 共发现 4 个 P1,均已修复并补充回归测试;无未解决 P0/P1。 +- 真实测试网关只读验证:矩阵精确状态筛选和统计守恒、看板 assigned/unassigned 互斥、Long ID 字符串及手机号脱敏均保持兼容,全程无业务写入。 +- 内部 generation 不通过网关暴露,且取消/恢复正例必须产生业务写入,因此未伪造网关正例;完整代际生命周期由 Service、Mapper 真表和迁移测试覆盖。 +- 网关证据:`D:/work2/HL-v3/.tmp/5308-gateway.json`,SHA-256 `3778da1c8c0d270e3d1da75821e54bfce49ea25bc36f09e8440932ed6e4efa07`。 +- OpenAPI 与 Spring Cloud Contract:`not_required`,因为无 API/Feign/shared Java 契约形状变化。 + +当前状态:后端已合并、部署并通过网关兼容探针,前端无需改造。 + +关联:#5308、#5292、#5305。 -- 2.43.0