文件
hl-api-changelog/changelogs-v2/2026-09/24_8329_团期配车确认重复调用不再返602005-修改接口-管理后台.md
T

15 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 8329 团期配车确认重复调用不再返 602005:需求版本校验下沉到幂等分支之后,回写推进版本不再让重复确认变成错误 admin wx(GIT) 修改接口 deployed verified pending mmg v2.1 PR #8332 squash 合并 dev-v3(8675e1ff0)。部署:hl-fleet-service dev-v3 @ 2b4656424(2026-09-24 14:03 滚动部署完成;同批 order-v3 亦为 2b4656424)。测试服网关从零实测(自造团期 groupBatchId=2103003304906936322,正式需求 2103003334258675714 v2,3 条配车行):① reconfigure(requirementVersion=2)→ 200;② confirm 第一次(requirementVersion=2)→ 200,confirmedCount=3、alreadyConfirmedCount=0、requirementAdvanceIntent=CONFIRMED_TO_DISPATCHED,回写把正式需求推到 status=DONE、version=3;③ 用提交时的旧版本再 confirm 一次(requirementVersion=2)→ http 200、code=200、message=成功,confirmedCount=0、alreadyConfirmedCount=3。改前同一形态返 602005「用车需求已更新, 请刷新后重新配车(提交 …/v2, 当前 …/v3)」。定向单测 81 绿(GroupDispatchConfirmTest 23 / GroupDispatchServiceTest 58),fleet spotless:check 901 files clean。闸门按「基线需求状态已是 DISPATCHED/DONE(即本端点回写已落地)」放行,状态停在 CONFIRMED/PENDING_RECONFIRM 时仍 fail-closed 抛 602005。 2026-09-24 dev-v3

fleet 团期配车: 确认重复调用不再返 602005(版本校验下沉)

存放目录: 二期(v3) → changelogs-v2/2026-09/

服务: hl-fleet-service(dispatch 域) PR: wx/HL#8332 Issue: #8329 日期: 2026-09-24 影响范围: 车务「团期配车 → 确认配车」按钮的重复点击 / 刷新后重试


⚠️ 关键变化(非必须,本版与上版行为不同 / 纠错 / 撤销时必写)

  • 重复确认不再返 602005:整团配车确认成功后,本次确认会推进正式用车需求版本(回写);此前这个自己造成的版本前进会让「再点一次确认」被判成「需求已更新」,返回 602005 要求刷新重配——而刷新后拿到的还是同一个已完成的团。现在这一档返回 200,并以 confirmedCount=0 / alreadyConfirmedCount=N 表达「本来就是已确认状态」。
  • 602005 仍然存在,且判据更精确:只有当「本次端点的回写尚未落地」而版本/状态又对不上时才抛(fail-closed),即真正的「业务侧改了需求,你拿的是旧版本」。
  • 602007 的触发面变化:本团一行配车行都没有(assignedCount=0 且 alreadyConfirmedCount=0)时抛 602007「本团没有可确认的配车行」,不再被版本校验抢先报成 602005。
  • 602005 报文的两个占位符统一成 id=…/v… 形态:前端只应按错误码 602005 处置,不要解析 {0} / {1}。

一、背景(选填)

确认配车是定稿动作,它认下的是「这一版需求对应的这套车」,因此入参带了 requirementId + requirementVersion 作为需求身份。问题是这个端点自己有副作用:确认成功会把正式需求从 CONFIRMED 回写成 DISPATCHED,版本因此前进。改前版本校验排在幂等分支之前、且在事务外先跑,于是「重复确认」这条正常操作被自己造成的版本前进判成了错误。实测:POST .../confirm {requirementId:2102982327141556225, requirementVersion:2} → code=602005「用车需求已更新, 请刷新后重新配车(提交 2102982327141556225/v2, 当前 2102982327141556225/v3)」,而同刻回读需求已是 v3——前进正是首次确认自己的回写。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 确认整团配车 POST /admin/fleet/group-dispatch/batches/{groupBatchId}/confirm 行为变更(校验时机 + 报文占位符口径) 重复确认返 200;602005 只在「本端点回写未落地」时抛

三、接口详情

1. 确认整团配车 POST /admin/fleet/group-dispatch/batches/{groupBatchId}/confirm

VO: GroupDispatchConfirmReqVO → GroupDispatchConfirmRespVO

使用场景

车务在团期配车页点「确认配车」,把本团已排的车一次定稿。没有防重提交时间窗:连点多少次都是同一个形态,不会出现「请稍后重试」。

入参

字段 位置 类型 必填 约束 说明
groupBatchId Path Long ✅ - 团期聚合主键
requirementId Body Long ✅ 须等于本团当前正式需求 不等于抛 602005(不受本次改动放宽)
requirementVersion Body Integer ✅ 本次确认所依据的版本 语义细化(本单):版本不一致时——本团仍有「已派车」行待确认,或基线需求状态还停在 CONFIRMED / PENDING_RECONFIRM ⇒ 602005;基线需求状态已是 DISPATCHED / DONE(本端点回写已落地)⇒ 不抛,按 confirmedCount=0 返 200
remark Body String ❌ ≤200 仅日志留痕,不写进配车行(配车行 remark 参与 planDigest,刷进去会让下次重配误判「计划有变更」)

出参 Result<GroupDispatchConfirmRespVO>

字段 类型 说明
confirmedCount Integer 本次真正由 ASSIGNED 转 CONFIRMED 的行数;重复确认时为 0
alreadyConfirmedCount Integer 本次之前就已是 CONFIRMED 的行数
requirementId / requirementVersion String / Integer 本次提交的需求身份(照原样回显)
planVersion Integer 配车计划版本
requirementAdvanceIntent String 回写意图,如 CONFIRMED_TO_DISPATCHED
coverage Object 按组覆盖读数(groups / missingGroupCodes / satisfied)

请求示例

{
  "requirementId": "2103003334258675714",
  "requirementVersion": 2,
  "remark": "与地接确认车辆无误"
}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "groupBatchId": "2103003304906936322",
    "confirmedCount": 0,
    "alreadyConfirmedCount": 3,
    "requirementId": "2103003334258675714",
    "requirementVersion": 2,
    "planVersion": 2,
    "requirementAdvanceIntent": "CONFIRMED_TO_DISPATCHED",
    "coverage": { "satisfied": true, "missingGroupCodes": [] }
  },
  "success": true
}

空数据 / 降级响应

  • 本团没有任何配车行时不是空成功,而是 602007(见「错误响应」)。
  • 本团有配车行但已全部 CONFIRMED:200 + confirmedCount=0、alreadyConfirmedCount=N。
{ "code": 200, "message": "成功", "data": { "confirmedCount": 0, "alreadyConfirmedCount": 3 }, "success": true }

错误响应

{
  "code": 602005,
  "message": "用车需求已更新, 请刷新后重新配车(提交 id=2103003334258675714/v2, 当前 id=2103003334258675714/v4)",
  "success": false,
  "data": null
}
{
  "code": 602007,
  "message": "本团没有可确认的配车行, 请先提交配车计划",
  "success": false,
  "data": null
}

业务边界

  • 真实的判定顺序(改后):事务外只做需求 ID 校验(602005 的一种形态);进事务、取团锁、锁内重读配车行后依次判 —— 行数都为 0 ⇒ 602007;本端点回写是否已落地(基线需求状态 ∈ DISPATCHED / DONE)⇒ 落地则跳过版本/状态校验(幂等重放),未落地则照旧 fail-closed 抛 602005 / 602006;随后做按组覆盖校验(602008),再 CAS 确认。
  • 跳过的条件不是「没有待确认行」,而是「本端点的回写已经落地」:状态停在 CONFIRMED / PENDING_RECONFIRM 而版本不等 ⇒ 推进版本的不是我们,是业务侧改了需求,必须照旧 602005。不要按 assignedCount==0 一刀切。
  • 需求被整份换过(requirementId 都变了)时拿不到「提交版本」,报文只有 ID 那一半;两支统一拼 id=… 前缀。
  • 重配端点(reconfigure)未变:仍整份调用身份校验。

四、契约约束与正确调用方式(接口类必写)

  • 前端按码处置,不解析报文:602005 = 需求被业务侧改过,刷新重配;200 且 confirmedCount=0 = 本来就是已确认,无需任何动作。
  • 不要把「重复确认」当成需要防抖的操作:本端点没有防重提交时间窗,按钮可以做防抖,但服务端保证重复调用不报错。
  • 确认成功后若要改车,走重配端点(reconfigure)而不是再点确认。

✅ 正确 / ❌ 错误处置对照

✅ 200 + confirmedCount=0 → 已是确认态,直接展示「已确认」,不要提示失败
✅ 602005 → 提示「需求已更新,请刷新后重新配车」
❌ 把 200 + confirmedCount=0 渲染成错误或重复提交警告
❌ 发现 602005 后原地重试同一个 requirementVersion(版本不会自己回来)

切换状态时的必要动作

  • 重配(reconfigure)成功后配车行回到 ASSIGNED/待确认,需要再点一次确认;本单未改这条链路。

五、数据库行为(涉及写操作时必写)

  • 无表结构变更、无 Flyway。
  • 确认成功的写入是「把本团存活配车行由 ASSIGNED 置 CONFIRMED」+「事务内意图记录回写需求状态」;重复确认时 CAS 命中 0 行,零写入。
  • 602005 / 602006 / 602007 / 602008 都在写库之前抛出,可回读需求版本与配车行状态确认未变。

六、边界行为

  • 并发下的保护未变:确认前取团级变更锁并在锁内重读配车行,命中行数与 assignedCount 不符即判并发。
  • 受控重开窗口(602012 / 602013)语义未变。
  • 需求被整份换过仍抛 602005,不受本次放宽影响。

六.5、枚举 / 数据字典(接口出现枚举时必写)

码 触发(改后) 报文
602005 requirementId 不等于基线;或本端点回写未落地(需求状态非 DISPATCHED/DONE)而 requirementVersion 不等于基线当前版本 用车需求已更新, 请刷新后重新配车(提交 {0}, 当前 {1}),两个占位符均为 id=需求ID/v版本
602006(不变) 需求状态不允许配车(回写未落地时的状态判据) 正式用车需求当前状态不允许配车: {0}
602007(触发面变更) 本团 assignedCount=0 且 alreadyConfirmedCount=0 本团没有可确认的配车行, 请先提交配车计划
602008(不变) 库里现存计划仍不满足按组覆盖 配车尚未覆盖完整, 不能确认: {0}

六.6、修改前后对比(修改/删除类接口必写,新增跳过)

字段级对比

字段 改前 改后
请求 / 响应字段 — 无新增、无删除,结构不变
602005 的 {0} 「换版」支不带前缀词 两支统一为 id=…/v…

行为级对比

行为 改前 改后
首次确认成功 200,confirmedCount=N 200,confirmedCount=N(不变)
需求版本已被本端点回写推进后再确认(旧版本) 602005(要求刷新重配) 200,confirmedCount=0、alreadyConfirmedCount=N
业务侧改了需求、本团仍有待确认行 602005 602005(不变,fail-closed)
业务侧改了需求、本团早已确认完(回写已落地) 602005 200(幂等重放)
本团一行配车行都没有 可能先被版本校验报成 602005 602007

六.7、影响评估(修改/删除类必写)

  • 是否破坏向后兼容:不破坏——只把「自己造成的版本前进」这一档从错误放宽成幂等成功;报文占位符口径变化不影响按码处置的前端。
  • 前端是否必须同步上线:不必须。建议把 confirmedCount=0 渲染成「已确认」而不是失败。
  • 存量数据影响:无迁移、无重算。
  • 上线风险:放宽的闸门以「基线需求状态已是 DISPATCHED / DONE」为唯一理由,状态未落地时判据与改前完全一致,因此不会掩盖「业务侧改需求」这一真实冲突。

七、不影响范围(显式声明, 帮前端/QA 缩小排查面)

  • 仅影响:POST /admin/fleet/group-dispatch/batches/{groupBatchId}/confirm 的版本/状态校验时机与 602005 报文占位符形态。
  • 零影响:
    • 重配端点 POST .../reconfigure(仍整份校验身份)。
    • 602006 / 602008 / 602012 / 602013 的判据与报文。
    • 按组覆盖校验、并发锁、受控重开窗口。
    • order-v3 侧对回写意图的幂等消费口径。
    • readiness / overview / 配车行数据结构、数据库、网关路由。

八、测试环境已验证

部署读数:hl-fleet-service dev-v3 @ 2b4656424,2026-09-24 14:03 滚动部署完成。

网关真实请求与响应(https://api.test.1814.love,自造团期 groupBatchId=2103003304906936322,正式需求 2103003334258675714,3 条配车行):

① POST /admin/fleet/group-dispatch/batches/2103003304906936322/reconfigure
   {requirementId:2103003334258675714, requirementVersion:2, demands:[3 天 × BUS × 1 辆]}
   → http 200, code=200;addedCount=3、aliveCount=3  ✓

② POST .../confirm {requirementId:2103003334258675714, requirementVersion:2}
   → http 200, code=200, confirmedCount=3, alreadyConfirmedCount=0,
     requirementAdvanceIntent=CONFIRMED_TO_DISPATCHED  ✓
   回读 GET /v3/admin/order/group-batch/2103003304906936322/vehicle-requirement
   → status=DONE, version=3(版本被本次回写推进)✓

③ POST .../confirm {requirementId:2103003334258675714, requirementVersion:2}   ← 用提交时的旧版本重复确认
   → http 200, code=200, message=成功, confirmedCount=0, alreadyConfirmedCount=3  ✓(改前此处为 602005)

定向测试逐类读数(mvn -o -pl hl-fleet-service -am test -Dtest='GroupDispatchConfirmTest,GroupDispatchServiceTest' -DfailIfNoTests=false -Dhl.surefire.failIfNoTests=false,81 绿):

测试类 Tests run
GroupDispatchServiceTest 58
GroupDispatchConfirmTest 23

fleet spotless:check:901 files clean、0 needs changes。


十、相关文档

  • 确认配车端点与 GroupDispatchConfirmReqVO 原始设计:#7442
  • 受控重开窗口(602012 / 602013):#8308 系列 → changelogs-v2/2026-09/
  • 团期配车就绪检查:#8294 → changelogs-v2/2026-09/24_8294_团期配车就绪检查座位不足黄牌扣司机座,新增-passengerSeatTotal-修改接口-管理后台.md

关联 / 联系人

链接

联系人

  • 后端: wx