文件
hl-api-changelog/changelogs-v2/2026-09/18_7443_接送机用车需求分叉PR1派车入参新增需求类别kind-修改接口-管理后台.md
T
Mimingguang ac12dabe20
changelog-filename-gate / validate (push) Failing after 2s
docs(changelog): #7443 C 车务侧+13_7439/18_7443/20_7990 前端已交付 verified(hl-admin v2.1 662310ea/6c091ef24)
18_7443 挂起期回头补落地(派车弹窗 kind 切换+batch/pickup-dropoff-config 显式 kind);
20_7990 requirementIdentities 已消费;13_7439 硬契约点 A+B 已补(809008/显式 kind/reject 走 query);
20_7443 AC-24 维持 not_required 仅补 C 段实证
2026-09-21 17:52:22 +08:00

35 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 7443 接送机用车需求分叉 PR-1——派车入参新增需求类别kind admin wx(GIT) 修改接口 deployed verified verified mmg 662310eac02ef5afc84c81b242949ca536c79489 v2.1 2026-09-21 后端交付。派车批量与接送机配置入参新增可选 kind 字段;新增 4 个错误码(602200/602201/602202/602205)。[mmg 2026-09-18 判 not_required] kind 可选不传=TRAVEL,契约保证存量请求行为逐字一致。grep 实证:前端两处调用(src/api/fleet/board.js 的 POST /fleet/assignments/batch 与 PUT /fleet/assignments/pickup-dropoff-config)均不传 kind,全仓无 TRANSFER 派车入口;上游写口 809009 开关关闭,产品上产不出 TRANSFER 需求,4 个新错误码仅 kind=TRANSFER 触发、前端不可达;响应信封订正(code 即业务码、无 errorCode)与前端 request.js 拦截器透 message 惯例一致,无需改动。TRANSFER 开放后回头补:batch/pickup-dropoff-config 显式传 kind=TRANSFER、602205 给「先补大交通再重试」引导、TRANSFER 派车行确认/改派待 #7443 AC-24 修复后接入,已记入项目 memory。【mmg 2026-09-21 交付,not_required 翻 verified】挂起期「TRANSFER 开放后回头补」已落地(hl-admin v2.1 662310ea):派单弹窗双需求订单显「本次派车需求」切换器(用户拍板弹窗内方案),batch/pickup-dropoff-config 显式 kind=TRANSFER(仅切换器 scoped order 标记者,TRAVEL 绝不下发);602205 拦截器透「请先在订单侧补齐大交通后重试」引导不改写需求不存在,602200-602202 透 message;确认/改派/候选四端点契约零变化前端零改动(AC-24 纯后端修复,改派按 assignmentId 反查零改动可用)。遗留:TRANSFER 复核确认(confirmHold groups 取整单 activeAssignments 无法按 kind 拆分,待派车行 kind 标签)、我的接单 vehicle 列表 kind 分栏(前端无该页面)。 2026-09-18 dev-v3

fleet: 接送机用车需求分叉 PR-1——派车入参新增需求类别kind

存放目录: changelogs-v2/{YYYY-MM}/

服务: hl-fleet-service PR: #7911(9287e6eb9)、#7912(d2d63bcb6)、#7913(5a6bd95f8) Issue: #7443 AC-6~9 日期: 2026-09-18


关键变化

⚠️ 上游写口关着(2026-09-18 补充,比下面这条已知限制更影响前端排期,请先读这条): 目前没有任何常规途径能创建 TRANSFER(接送机)用车需求。

PUT /v3/admin/order/{id}/vehicle-requirement(提交/修改/调整用车需求)传 kind=TRANSFER 恒返 809009(VehicleRequirementKindErrorCode.TRANSFER_REQUIREMENT_SUBMIT_NOT_OPENED, 文案「接送机用车需求尚未开放提交,请联系管理员确认开放时间(订单 {0})」, VehicleRequirementKindErrorCode.java:95-98)。根因:RequirementService.java:383 的 @Value("${hl.order.requirement.transfer-kind-submit-enabled:false}") 默认 false (application.yml:59,env HL_ORDER_REQUIREMENT_TRANSFER_KIND_SUBMIT_ENABLED),测试服 Nacos 的 hl-order-service-v3-test.yml / hl-common-test.yml 两份配置均未覆盖(2026-09-18 实测)。该字段没有 @RefreshScope(RequirementService.java:338),改配置须重启 order-v3 实例才生效,不能靠 Nacos 热推。

前端影响:本次(PR #7911/#7912/#7913)交付的是车务侧接住 TRANSFER 需求的能力,不是 订单侧写口;开关打开之前产品上产生不出 TRANSFER 需求,本文档两个接口的 kind=TRANSFER 分支因此暂时无数据可用。前端可以先按契约对接,但不要把它排进本期可演示范围。

⚠️ 已知限制(2026-09-18 补充,前端集成前必读):kind=TRANSFER 建出来的派车行, 目前「确认」和「改派」会失败,返回 605041(AssignmentErrorCode.FINAL_CONFIRMATION_BASELINE_MISMATCH, "订单行程或用车派单已变化,请按逐日差异处理后重试")。批量创建(本文档接口 1)今天已修复 同一基线复核缺口(PR #7913,commit 5a6bd95f8),kind=TRANSFER 建行本身现在可以正常 建行;但确认(POST /requirements/{id}/confirm、POST /{assignmentId}/confirm)与改派 (POST /{assignmentId}/change)三个端点内部的基线复核仍未做 kind 感知,必现 605041。 根因、影响面与跟踪单号见「六、边界行为」。前端本版请只接「建接送机派车行」这一步, 确认/改派暂缓接入,接了必然拿到 605041。

🔧 2026-09-18 订正(原文「三个端点……必现 605041」不准确,仅对其中两个成立):经源码 复核,POST /requirements/{id}/confirm 端点对 kind=TRANSFER 需求实际抛出的是 605905(REQUIREMENT_VERSION_EXPIRED,"需求版本过期")而不是 605041——该端点有一道 更早触发的版本预检门禁 assertRequirementPreflightVersion(AssignmentService.java:3567-3583), 请求根本走不到会抛 605041 的那一层。POST /{assignmentId}/confirm 与 POST /{assignmentId}/change 抛 605041 的描述准确。三个端点均已于当日随 AC-24 一并修复, 详见 同目录《#7443 TRANSFER 派车行确认改派基线复核修复-修改接口-管理后台》(日前缀以实际推送日为准,成稿时为 19_)。原字面保留在 上方两行接 grep,不删除。

  1. BatchCreateAssignmentReqVO 新增可选入参 kind(TRAVEL|TRANSFER,不传=TRAVEL)
  2. PickupDropoffConfigReqVO 新增可选入参 kind(TRAVEL|TRANSFER,不传=TRAVEL)
  3. kind=TRANSFER 时两端点均走接送机需求「四步前置」(无条件回填服务日 → 按结果分流 → strict GET 需求 → 大交通声明日覆盖校验),任一步不通过即失败关闭,新增 4 个错误码: 602200 / 602201 / 602202 / 602205
  4. 向后兼容:kind 不传等于 TRAVEL,存量前端请求形状一个字不变、行为与本次改动前逐字一致
  5. 对前端最要紧的一句:客人没填大交通的订单去派接送机车(kind=TRANSFER),会得到 602205,前端须引导先回订单侧补齐大交通再重试,而不是提示「接送机需求不存在」

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 派车批量创建 POST /admin/fleet/assignments/batch 修改 入参新增可选 kind;kind=TRANSFER 时新增 3 个错误码(602200/602201/602205)
2 接送机配置 PUT /admin/fleet/assignments/pickup-dropoff-config 修改 入参新增可选 kind;kind=TRANSFER 时新增 4 个错误码(602200/602201/602202/602205)

三、接口详情

1. 派车批量创建 POST /admin/fleet/assignments/batch

VO: BatchCreateAssignmentReqVO → BatchAssignmentWriteRespVO

使用场景

车务最终实派方案原子提交(#7067 去槽位化)。本次为其新增可选入参 kind,用于区分本次提交 的是常规行程用车(TRAVEL)还是接送机用车(TRANSFER)需求。kind=TRANSFER 时,服务端在 取需求锁之前按订单 ID 解析当前生效的接送机需求:①无条件调用 order-v3 的服务日回填端点 (幂等);②回填结果为「客人未填大交通」→ 602205 就地失败关闭(不再继续 GET);回填结果为 「该订单没有生效接送机需求」→ 602200;③其余情况 strict GET 该需求,两次调用之间需求被撤 同样按 602200 处理;④需求服务日仍解析为空 → 602205;服务日非空则校验大交通声明要接送的 日期是否都落在服务日内,不覆盖 → 602201。kind 不传或为空一律按 TRAVEL 处理,取需求、 校验、落库路径与本次改动之前逐字一致。

入参(本次新增 1 个,其余 27 个原有参数不变)

覆盖范围:BatchCreateAssignmentReqVO(含内部类 DailyPlanItem,D:/work2/HL-v3 已 ff 到 origin/dev-v3@9287e6eb9)全量 28 个字段,逐一核对源码。

字段 位置 类型 必填 约束 说明
orderId Body Long 是 - 订单 ID
orderNo Body String 否 - 订单号冗余
requirementId Body Long 是 - 当前生效用车需求 ID
kind Body String 否 TRAVEL|TRANSFER 🆕 需求类别:TRAVEL=行程用车(默认),TRANSFER=接送机用车。不传按 TRAVEL,存量前端无需改动;TRANSFER 时服务日取大交通航班日,可以落在行程日窗之外
startDate Body Date 是 - 用车开始日期;TRANSFER 请传接送机服务日的最早一天
endDate Body Date 是 - 用车结束日期
pickupAt Body String 否 - 接客地
dropoffAt Body String 否 - 送客地
headcount Body Integer 否 - 乘客人数
confirmNoVehicleServiceDates Body Boolean 否 - 逐日计划未覆盖全部服务日期(存在不配车日期)时的显式二次确认
sendItinerarySms Body Boolean 否 不传按 false 是否向本批各车师傅发送行程短信;整批统一决策
skipCityJunctionException Body Boolean 否 - 跳过城市衔接例外
fromEntry Body String 否 - 操作来源
requestId Body String 是 ≤64 批次级幂等请求标识
dailyPlan[] Body Array 是 ≤4000 项 按行程日的完整配车列表:逐项为 服务日期×车辆×司机;同一服务日允许多条;需求日期窗内未出现的服务日视为该日不配车
dailyPlan[].serviceDate Body Date 是 - 服务日期
dailyPlan[].vehicleId Body Long 是 - 车辆 ID
dailyPlan[].driverId Body Long 是 - 司机 ID
dailyPlan[].assignmentPrice Body BigDecimal 否 ≥0.00,整数最多10位/小数最多2位 本车当天实际价格;未传按车型价格日历参考价兜底
dailyPlan[].priceAdjustmentReason Body String 否 ≤256 实际价格与价格日历参考价不一致时的调整原因
dailyPlan[].confirmCrossResident Body Boolean 否 - 跨常驻车显式确认
items Body - 否 携带非 null 值即 400 已移除:去槽位化后不再有槽位序号;携带将被 400 拒绝
chargeableServiceDates Body - 否 携带非 null 值即 400 已移除:旧收费日期字段;携带将被 400 拒绝
vehicleFeeWaiverReason Body - 否 携带非 null 值即 400 已移除:旧免费服务日字段;携带将被 400 拒绝
confirmAllServiceDatesFree Body - 否 携带非 null 值即 400 已移除:旧免费服务日字段;携带将被 400 拒绝
holdMode Body - 否 携带非 null 值即 400 已移除:#5827 起一步派定;携带将被 400 拒绝
dailyPlan[].fleetItemIndex Body - 否 携带非 null 值即 400 已移除:稳定车辆槽位序号;携带将被 400 拒绝
dailyPlan[].used Body - 否 携带非 null 值即 400 已移除:用车开关;携带将被 400 拒绝
dailyPlan[].pickupParticipant Body - 否 携带非 null 值即 400 已移除:接机标志改由接送机配置步骤写入;携带将被 400 拒绝

出参(本次无变化)

本次无新增字段。BatchAssignmentWriteRespVO 结构未动,下表为全量 13 个字段(含 pickupDropoffGate 展开):

字段 类型 说明
assignments[] Array 按 fleetItemIndex 升序返回的派单结果
assignments[].fleetItemIndex Integer 当前用车需求展开后的车辆槽位序号
assignments[].assignment Object 复用单槽位派单响应(AssignmentWriteRespVO),本次未展开
finalPlanPublished Boolean 本次是否已发布最终方案;false 表示排车已落库但接送机未配齐,须继续走第③步
pickupDropoffGate Object 接送机门禁状态
pickupDropoffGate.arrivalRequiredDates Array 大交通声明需要接机的服务日
pickupDropoffGate.departureRequiredDates Array 大交通声明需要送机的服务日
pickupDropoffGate.missingPickupDates Array 尚未配置接机车辆的服务日(升序)
pickupDropoffGate.missingDropoffDates Array 尚未配置送机车辆的服务日(升序)
pickupDropoffGate.declared Boolean 该订单大交通是否有任一方向的接送机声明
pickupDropoffGate.satisfied Boolean 门禁是否已满足;false 时不发布最终方案
failedFleetItemIndex Integer 直接派定基线失败的车辆槽位序号
dailyDifferences Array 直接派定基线失败的逐日差异

请求示例

POST /admin/fleet/assignments/batch
{
  "orderId": 1934567890123456789,
  "requirementId": 1934567890123456790,
  "kind": "TRANSFER",
  "startDate": "2026-05-06",
  "endDate": "2026-05-06",
  "requestId": "batch-20260918-0001",
  "dailyPlan": [
    {"serviceDate": "2026-05-06", "vehicleId": 99, "driverId": 88}
  ]
}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "assignments": [
      {"fleetItemIndex": 0, "assignment": {"id": "1234567890123456789", "assignmentStatus": "assigned"}}
    ],
    "finalPlanPublished": false,
    "pickupDropoffGate": {
      "arrivalRequiredDates": ["2026-05-06"],
      "departureRequiredDates": [],
      "missingPickupDates": ["2026-05-06"],
      "missingDropoffDates": [],
      "declared": true,
      "satisfied": false
    },
    "failedFleetItemIndex": null,
    "dailyDifferences": null
  },
  "success": true
}

空数据 / 降级响应

N/A(整批要么受理要么失败关闭,不存在「空成功」形态;assignments[] 恒随 dailyPlan[] 项数非空)。

错误响应

{
  "code": 602205,
  "message": "订单 1934567890123456789 的接送机需求 1934567890123456790 还没有服务日, 请先在订单侧补齐大交通后重试",
  "data": null,
  "success": false
}

其余两个 kind=TRANSFER 专属错误码:

{
  "code": 602200,
  "message": "订单 1934567890123456789 没有生效的接送机用车需求, 无法按接送机派车",
  "data": null,
  "success": false
}
{
  "code": 602201,
  "message": "大交通声明要接送的日期 2026-05-07 不在接送机需求的服务日内, 请回订单侧核对大交通",
  "data": null,
  "success": false
}

⚠️ 响应信封订正:本仓 Result 类(hl-common/hl-common-core/src/main/java/com/hulalv/common/result/Result.java) 只有 code/message/data/traceId 四个字段,业务异常时 code 字段本身就是业务错误码 (见 GlobalExceptionHandler.handleBusiness 第 205 行 Result.error(e.getCode(), message)), HTTP 状态码固定 200(@ResponseStatus(HttpStatus.OK)),不存在独立的 errorCode 字段。 错误响应信封的正确形状:业务失败时 code 就是业务错误码(HTTP 仍为 200),success 由 Result.isSuccess() 按 code == 200 自动得出、是真实字段,没有 errorCode 字段。2026-09-17 的 17_7442 / 17_7443 两份曾写成 "code": 200, ..., "errorCode": <业务码>,已随本次一并订正——前端按 code == 200 判成功即可,不要去读 errorCode。

业务边界

  • kind 不传或空=TRAVEL,存量批量派车零改动,走既有 605906/605905 校验路径
  • kind=TRANSFER 时四步前置顺序钉死,任一步失败即整批拒绝、不落库
  • 602202(同需求同日同方向重复参与)不在本接口触发,仅 PUT /pickup-dropoff-config 校验

2. 接送机配置 PUT /admin/fleet/assignments/pickup-dropoff-config

VO: PickupDropoffConfigReqVO → PickupDropoffConfigRespVO

使用场景

派车第③步:整批幂等覆盖接送机参与标志。本次新增 kind 入参,决定 requirementId 应当 匹配哪一条需求(TRAVEL 走订单详情上下文里那条固定 TRAVEL 需求;TRANSFER 走与批量创建 相同的接送机四步前置解析)。写入落库后额外做「同需求同日同方向唯一参与」校验:kind=TRANSFER 时,同一天同一方向若有多于一条生效派车行标记参与,抛 602202;TRAVEL 需求不受本校验影响 (同日多行标接机是既有合法形态)。

入参(本次新增 1 个,其余 7 个原有参数不变)

覆盖范围:PickupDropoffConfigReqVO(含内部类 Item)全量 8 个字段。

字段 位置 类型 必填 约束 说明
orderId Body Long 是 - 订单 ID
requirementId Body Long 是 - 当前生效用车需求 ID
kind Body String 否 TRAVEL|TRANSFER 🆕 需求类别:TRAVEL=行程用车(默认),TRANSFER=接送机用车。不传按 TRAVEL,存量前端无需改动;决定 requirementId 应匹配哪一条需求,以及归零作用域落在哪一条需求名下
requestId Body String 是 ≤64 幂等请求标识
items[] Body Array 是 ≤4000 项 要标记接送机参与的派车行集合;该订单+当前需求下未出现在 items 中的生效派车行两个方向标志一律归 0
items[].assignmentId Body Long 是 - 派车行 ID(必须是当前需求下的生效派车行)
items[].pickupParticipant Body Boolean 是 - 当日该车是否参与 ARRIVAL 接机/接站
items[].dropoffParticipant Body Boolean 是 - 当日该车是否参与 DEPARTURE 送机/送站;与 pickupParticipant 不可同时为 false

出参(本次无变化)

本次无新增字段。PickupDropoffConfigRespVO 结构未动,下表为全量 10 个字段(含 pickupDropoffGate 展开):

字段 类型 说明
finalPlanPublished Boolean 本次是否发布了最终方案快照(配齐即发)
requirementReopened Boolean 是否已把订单拉回处理中(门禁不满足而订单仍是完成态时触发)
reopenBlockedReason String 本该拉回处理中却没拉回的原因;null=不适用或已成功拉回
pickupDropoffGate Object 写入后的接送机门禁状态
pickupDropoffGate.arrivalRequiredDates Array 大交通声明需要接机的服务日
pickupDropoffGate.departureRequiredDates Array 大交通声明需要送机的服务日
pickupDropoffGate.missingPickupDates Array 尚未配置接机车辆的服务日(升序)
pickupDropoffGate.missingDropoffDates Array 尚未配置送机车辆的服务日(升序)
pickupDropoffGate.declared Boolean 该订单大交通是否有任一方向的接送机声明
pickupDropoffGate.satisfied Boolean 门禁是否已满足;false 时不发布最终方案

请求示例

PUT /admin/fleet/assignments/pickup-dropoff-config
{
  "orderId": 1934567890123456789,
  "requirementId": 1934567890123456790,
  "kind": "TRANSFER",
  "requestId": "pdc-20260918-0001",
  "items": [
    {"assignmentId": 1234567890123456789, "pickupParticipant": true, "dropoffParticipant": false}
  ]
}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "finalPlanPublished": true,
    "requirementReopened": false,
    "reopenBlockedReason": null,
    "pickupDropoffGate": {
      "arrivalRequiredDates": ["2026-05-06"],
      "departureRequiredDates": [],
      "missingPickupDates": [],
      "missingDropoffDates": [],
      "declared": true,
      "satisfied": true
    }
  },
  "success": true
}

空数据 / 降级响应

N/A(整批幂等覆盖,items 可传空数组表示"本次不新增任何参与标记,仅把此前未出现在列表中的生效派车行归零",仍返回正常 200 结构,不是独立的空数据形态)。

错误响应

{
  "code": 602202,
  "message": "2026-05-06 的 ARRIVAL 接机 已有多条派车行标记参与(派车行 1234567890123456789,1234567890123456790), 同一天同一方向只能有一条",
  "data": null,
  "success": false
}

本接口同样可能返回 602200 / 602201 / 602205(触发条件与「1. 派车批量创建」一致,见上方示例, 本次不重复贴)。

业务边界

  • kind 不传=TRAVEL,与批量派车保持一致
  • 602202 只对 TRANSFER 需求生效,作用域严格限于本 requirementId 名下;已取消/异常状态的 派车行不计入判据(不代表现状)
  • 跨需求的历史行重复不属本校验范围,归 AC-12 的 602204(本单未实现,预留号)

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

场景 做法
kind=TRANSFER 且客人未填大交通 返 602205,前端须引导先在订单侧补齐大交通再重试(不要提示"接送机需求不存在")
kind=TRANSFER 但订单没有生效接送机需求 返 602200,需回订单侧确认/新建接送机需求
大交通声明的接送日超出接送机需求服务日 返 602201,需回订单侧核对大交通与服务日是否漂了
同需求同日同方向已有多条生效派车行标记参与 返 602202(仅接送机配置端点触发),需人工核对是数据错乱还是业务上确需两辆车
kind 不传或传空字符串 按 TRAVEL 处理,行为与本次改动前逐字一致
kind 传非 TRAVEL/TRANSFER 值 400 参数校验失败(@Pattern 拦在入参层,不到业务码)
kind=TRANSFER 派车行走「确认」POST /requirements/{id}/confirm、POST /{assignmentId}/confirm、「改派」POST /{assignmentId}/change 返 605041(已知限制,三处内部基线复核未做 kind 感知,见「六、边界行为」),前端本版暂不要接入,只接「建接送机派车行」这一步
🔧 2026-09-18 订正 上一行「三处……返 605041」不准确:POST /requirements/{id}/confirm 实际返 605905,另两个端点返 605041 属实;三者均已随 AC-24 修复,详见「六、边界行为」订正与 同目录《#7443 TRANSFER 派车行确认改派基线复核修复-修改接口-管理后台》(日前缀以实际推送日为准,成稿时为 19_)

五、数据库行为

操作 影响
kind=TRANSFER 且四步前置全部通过 正常写入/更新 fleet_assignment 行,落库结构不因 kind 改变
kind=TRANSFER 但前置任一步失败(602200/602201/602205) 直接拒绝,批量场景整批不落库
configurePickupDropoff 写后校验 602202 抛出时整个事务回滚,本次接送机标志更新不落库
kind 不传或 TRAVEL 行为与改动前一致,无新增数据库副作用

六、边界行为

  • kind 传空字符串/null:按 TRAVEL 处理
  • kind 传非 TRAVEL/TRANSFER 枚举值:400 参数校验失败
  • kind=TRANSFER 且回填端点返回「客人未填大交通」(NO_TRANSPORT):602205,不再继续 GET
  • kind=TRANSFER 但回填端点返回「无生效接送机需求」(NOT_FOUND):602200
  • kind=TRANSFER 且回填/GET 之间需求被撤(回填说有、GET 说没有):按 602200 处理(fail-closed,不当成"还在")
  • kind=TRANSFER 且服务日解析仍为空(未知 outcome,或 strict GET 后 serviceDates 为空):602205(fail-closed,不兜底成行程日)
  • 大交通声明要接送的日期不在接送机服务日内:602201(判据方向"声明日 ⊆ 服务日",服务日多出来的部分不算异常)
  • 同需求同日同方向已有另一条生效派车行标记参与(仅 TRANSFER,仅 configurePickupDropoff):602202;TRAVEL 需求下同日多行标接机仍是既有合法形态,不受影响
  • 已取消(canceled)/异常(exception)状态的派车行不计入 602202 判据
  • ⚠️ kind=TRANSFER 派车行建成后走「确认」「改派」必现 605041(已知限制,2026-09-18 查实):POST /requirements/{id}/confirm(confirmRequirement)、POST /{assignmentId}/confirm(confirm,含其 HOLDING 分支与基线变更后复验 revalidateAssignedAfterBaselineChange 两条内部路径)、POST /{assignmentId}/change (改派 doChangeInLock)——这四处内部调用 assertFinalConfirmationBaseline 时基线需求 参数仍传 null,于是取用 order-v3 详情上下文里恒为 TRAVEL 的那条需求 (getFleetDetailContextStrict 写死 kind=TRAVEL)去和派车行的 requirementId 比对, TRANSFER 需求 ID 必然不等,差异类型记为 REQUIREMENT_VERSION_MISMATCH("用车需求已更新, 请刷新后按最新需求重新派车"),整体抛 605041 FINAL_CONFIRMATION_BASELINE_MISMATCH ("订单行程或用车派单已变化,请按逐日差异处理后重试")。根因:ConfirmAssignmentCommand/ ChangeAssignmentCommand/ConfirmRequirementCommand 三个内部命令对象均不携带 kind、 FleetAssignmentDO 也无 kind 列,RequirementKindResolver 明确不提供按 requirementId 反查 kind 的入口;这四处调用又都在 @Transactional 事务内,临时补一次远程读会撞事务内 同步 Feign 的红线。已在 Gitea #7443 的 AC-24 登记,需单独设计(补齐三个命令对象的 kind 字段,或由 order-v3 在 OrderFleetDetailContextDTO 里一并带回 TRANSFER 那条需求)后再修, 属跨服务契约变更,本单不实现。前端本版暂不要对接 TRANSFER 派车行的确认/改派操作。
  • 🔧 2026-09-18 订正(原文首句「三个端点……必现 605041」不准确,仅对其中两个成立): 经源码复核,上面这三个端点里,POST /requirements/{id}/confirm(confirmRequirement) 对 kind=TRANSFER 实际可观测的报错是 605905(REQUIREMENT_VERSION_EXPIRED,"需求版本 过期"),不是 605041——该端点在到达上文所述的 assertFinalConfirmationBaseline 之前,先有 一道版本预检门禁 assertRequirementPreflightVersion(AssignmentService.java:3567-3583): 该方法直接读 preflightContext.getVehicleRequirement()(恒 TRAVEL)与请求体里的 requirementId(TRANSFER)比对,必不等,请求根本走不到本条描述的那一层 (confirmRequirement 自己内部对 assertFinalConfirmationBaseline 的调用点在 AssignmentService.java:3969,理论上也会抛 605041,但 TRANSFER 请求永远到不了那一行)。 POST /{assignmentId}/confirm(HOLDING 分支两处调用 :4237-4238/:4270-4271, ASSIGNED 复核分支经 revalidateAssignedAfterBaselineChange 于 :4452)与 POST /{assignmentId}/change(doChangeInLock 于 :5794-5795)抛 605041 的描述准确、 行号与上述一致(均取自 origin/dev-v3 当前源码,与本文档描述的状态一致)。三个端点已于 2026-09-18 随 AC-24 一并修复(fleet 侧新增 baselineRequirementFor、order-v3 侧 OrderFleetDetailContextDTO 新增可空字段 transferVehicleRequirement),详见 同目录《#7443 TRANSFER 派车行确认改派基线复核修复-修改接口-管理后台》(日前缀以实际推送日为准,成稿时为 19_)。上方原字面保留接 grep, 不删除。⚠️ 本条订正基于源码,未经网关复测——2026-09-18 那轮网关实测覆盖的是原文描述的 主链路(kind 入参、四步前置、602200-602205 四个新错误码),不含本条错误码判定:当时 要么没覆盖 confirmRequirement 对 TRANSFER 需求的确认路径,要么覆盖了但记录时把码记错, 两者哪个成立本条未查证。 (原文此处引用过 frontmatter 的 verified_at,该字段已于 2026-09-19 按门禁要求清空—— frontend_status: not_required 的条目不得保留验证时间,实测时间改由本段与 status_note 承载。)
  • 与之相对:POST /admin/fleet/assignments/batch(本文档接口 1)的同一基线复核缺口已于 2026-09-18 修复(PR #7913,commit 5a6bd95f8)——批量创建改传锁内按 kind 复核过的 lockedRequirement 做基线,kind=TRANSFER 批量创建不再必现 605041

六.5 枚举(新增错误码)

新增 4 个错误码(TransferDispatchErrorCode,段位 602200-602299,归属 hl-fleet-service):

错误码 常量名 文案(含占位符)
602200 TRANSFER_REQUIREMENT_NOT_FOUND 订单 {0} 没有生效的接送机用车需求, 无法按接送机派车
602201 TRANSFER_SERVICE_DATES_MISMATCH 大交通声明要接送的日期 {0} 不在接送机需求的服务日内, 请回订单侧核对大交通
602202 TRANSFER_DUPLICATE_PARTICIPANT {0} 的 {1} 已有多条派车行标记参与(派车行 {2}), 同一天同一方向只能有一条
602205 TRANSFER_SERVICE_DATES_UNRESOLVED 订单 {0} 的接送机需求 {1} 还没有服务日, 请先在订单侧补齐大交通后重试

错误码段位(TransferDispatchErrorCode 内部规划):

  • 602200-602203/602205: 本工单(#7443)已用(602203 属上一 PR #7864,已在 2026-09-17 的 changelog 中交付,本文件不重复交付)
  • 602204: 预留给 AC-12(存量认领撞上互斥历史生效行),本单未实现

六.6、修改前后对比

项目 改前 改后
BatchCreateAssignmentReqVO.kind 不存在 新增可选字段(TRAVEL|TRANSFER,不传=TRAVEL)
PickupDropoffConfigReqVO.kind 不存在 新增可选字段(同上)
POST /admin/fleet/assignments/batch(kind=TRANSFER) 不支持按接送机需求分叉,恒取 TRAVEL 需求派车 按 kind 分流,TRANSFER 走独立四步前置校验
PUT /pickup-dropoff-config(kind=TRANSFER) 同上;无同日同方向重复参与校验 同上,另加写后 602202 校验(仅 TRANSFER)
TransferDispatchErrorCode 段内已用码 仅 602203(#7443 上一 PR #7864) 新增 602200/602201/602202/602205

六.7、影响评估

  • 向后兼容: 是
    • 新增参数可选,不传=TRAVEL,存量前端请求形状一个字不变
    • kind 不传或为 TRAVEL 时两端点行为与改动前逐字一致
  • 前端同步: 是(必须)
    • kind=TRANSFER 场景需处理 4 个新错误码,尤其 602205 要引导先补大交通再重试
    • 若前端已有/将有"按接送机派车"的入口,需在请求体带上 kind=TRANSFER
  • 数据: 无需迁移,落库结构未变

七、不影响范围

  • 单笔创建派单 POST /admin/fleet/assignments(该 VO 无 kind 入参,未改动)
  • 车务确认执行 POST /{assignmentId}/confirm、按需求原子确认 POST /requirements/{id}/confirm、 改派 POST /{assignmentId}/change(三者 VO/入参本次均未改动;但 kind=TRANSFER 派车行走到 这三个端点目前必现 605041,是已知限制而非本次刻意变更,见「⚠️ 关键变化」与「六、边界行为」) 🔧 2026-09-18 订正:确切地说,POST /requirements/{id}/confirm 必现的是 605905 不是 605041(另两个端点 605041 属实),已随 AC-24 修复,见「六、边界行为」的订正段与 同目录《#7443 TRANSFER 派车行确认改派基线复核修复-修改接口-管理后台》(日前缀以实际推送日为准,成稿时为 19_)
  • 声明/撤销整段不用车 POST|DELETE /requirements/{id}/no-vehicle
  • 看板列表、矩阵日订单等查询接口
  • kind 不传或=TRAVEL 时两端点的既有校验与落库路径

八、测试环境已验证

2026-09-18 已做网关端到端,AC-6 / AC-7 均通过:

  • 环境(取证前后各跑一次 deploy-status.sh,三行 COMMIT 未变): hl-gateway 631baab0c / hl-order-service-v3 9287e6eb9 / hl-fleet-service 5a6bd95f8
  • POST /admin/fleet/assignments/batch,kind="TRANSFER",dailyPlan 含 2026-10-11 与 2026-10-17 ⇒ code=200,落库两行(fleet_assignment)服务日分别为 10-11 与 10-17、 requirement_id 都指向该 TRANSFER 需求,未出现 605041 / 605062 / 605905。
  • 两方向独立性:两行车辆/司机不同;单独改接机行后,送机行的 service_date / vehicle_id / driver_id / status 逐字段未变。

⚠️ 必须同时写明的限定:那条 TRANSFER 需求行是 SQL 构造的,不是走真实写口建的 (因为「⚠️ 关键变化」里那个 809009 开关)。⇒ 已验证的是「车务侧拿到活跃 TRANSFER 需求 后能把车派到行程窗外」;「订单侧真实写口能产出等价需求行」不在本次证据范围内。 不许把这条限定省掉写成"端到端全链路已验证"。

单元层证据:

mvn -o -pl hl-fleet-service -am test(全量)→ Tests run: 4220, Failures: 0, Errors: 0, Skipped: 4,BUILD SUCCESS
完整性核对:322 个测试类 / 322 应跑(全部执行,无遗漏)
spotless:check → 846 files clean, 0 changed

代码已部署到测试环境:hl-fleet-service 跑在 dev-v3 分支的 5a6bd95f8 上(含 2026-09-18 的 605041 批次基线修复 PR #7913;Nacos healthy)。

以下三处不属于"未验证",而是"已知会失败"(AC-24 修完前不应验,验也是必现 605041, 详见「六、边界行为」):

POST /requirements/{id}/confirm、POST /{assignmentId}/confirm、POST /{assignmentId}/change
  对 kind=TRANSFER 派车行的确认/改派 — 已知必现 605041,非本单验收范围

🔧 2026-09-18 订正:上面代码块第一行三个端点中,POST /requirements/{id}/confirm 已知必现 的准确错误码是 605905,不是 605041(另两个端点 605041 属实)。三者均已随 AC-24 修复,详见 同目录《#7443 TRANSFER 派车行确认改派基线复核修复-修改接口-管理后台》(日前缀以实际推送日为准,成稿时为 19_)。上方代码块原字面保留接 grep,不删除。


十、相关文档

  • Issue: #7443
  • PR: #7911(AC-6~9 主体,merge 9287e6eb9)/ #7912(AC-9 兜底落点对照测试,merge d2d63bcb6)/ #7913(605041 批次基线修复,merge 5a6bd95f8——仅修复批量创建,确认/改派 缺口仍在,登记为 AC-24)

关联 / 联系人

链接

  • Issue: #7443
  • PR: #7911(已合并,9287e6eb9)、 #7912(已合并,d2d63bcb6)、 #7913(已合并,5a6bd95f8,仅修复批量创建, 确认/改派缺口登记为 AC-24)

联系人