文件
hl-api-changelog/changelogs-v2/2026-09/22_8114_司机拒接退回待派记录留痕-修改接口-管理后台.md
2026-09-22 05:07:13 +08:00

28 KiB

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 8114 派单操作时间线新增司机拒接记录留痕 admin wx(GIT) 修改接口 deployed not_required not_required backend_status=deployed: hl-fleet-service 测试服部署 sha=10ed12133,与本单 PR #8139 的合并提交完全一致,STATE=ok(该结论由管理者侧执行 deploy-status.sh 核验后转达,本会话未持有目标机器 SSH 权限、未亲自运行该脚本,如实披露)。gateway_status=not_required 特指网关路由层:driver-reject 写口与 operation-log 读口均为存量路由,本单未新增/改动任何 hl-gateway 路由配置;本会话对 driver-reject 写口做过真实网关实测(见八节,2026-09-22 04:00 前后),命中的是「非 holding 状态」守卫分支(605020),该守卫早于本单存在、与本单新增代码不重叠;受限于测试环境仅有 #5827 后新建的 assigned 态数据、没有存量 holding 派单,未能网关实测出「拒接成功→写入 driver_rejected→读侧可见」这条正向链路,该正向链路的验证依据是 AC-1/AC-2 的真库集成测试(H2 MODE=MySQL + 真 Flyway + 真 MyBatis + 真 AssignmentService Bean),非网关活测,已在三/八节如实注明并附逐字 dump。frontend_status=pending: 未获得 mmg 对 operation_type 白名单现状的新鲜核验,不认定 not_required。 2026-09-22 dev-v3

fleet: 派单操作时间线新增司机拒接记录留痕

存放目录: changelogs-v2/2026-09/

服务: hl-fleet-service (端口 8003) PR: #8139 Issue: #8114 日期: 2026-09-22 影响范围: 司机拒接/车务退回待派链路;派单操作时间线接口返回的操作记录


⚠️ 关键变化

司机拒接/车务退回待派(POST /admin/fleet/assignments/{assignmentId}/driver-reject,仅 holding 状态可调用,成功后派单回到 unassigned)以前在 fleet_assignment 表清空车辆/司机字段后不留任何痕迹。现已补齐写口留痕:fleet_assignment_operation_log 新增 driver_rejected 操作类型——与 #8068 已上线的 soft_cleared 是两个独立取值,不共用。

前端影响:派单看板订单卡片「查看日志」时间线会新增这类记录。如果前端按 operation_type 做了白名单过滤,driver_rejected 需要加进去——不加会静默漏渲染。

覆盖边界:driver_rejected 只在司机拒接/退回待派成功执行时写入,而该写口只接受 holding 状态的派单(组)。自 #5827 起,新建派单提交即派定,落库恒为 assigned(holding 仅剩发版前的存量数据)——因此在测试环境用新建的派单去调 driver-reject 会拿到 605020(本会话已实测复现,见八节),不会触发这条新留痕;能触发它的只有 #5827 发版前遗留、目前仍停留在 holding 的存量派单(组)。


一、背景

fleet_assignment 的 vehicle_id / driver_id 会因两类写口被清空:车务手动软清(#8068,已补齐留痕)与司机拒接/车务退回待派(本单)。此前拒接写口(AssignmentService#doDriverRejectInLock,覆盖 updateDriverReject 单派与 updateDriverRejectGroup 组派两条路径)在 CAS 清空成功后不写任何操作日志,事后无法查证「是谁拒的、拒掉的是哪位司机哪台车」——与 #8068 描述的是同一个洞,只是入口不同(工单 #8051 #8068 #8114)。

本次补齐留痕机制:每次拒接成功都在 fleet_assignment_operation_log 写一行 operation_type = driver_rejected,记录被清空前的身份快照及操作范围,形状与 #8068 的 soft_cleared 一致(锚点行 + clearedRows[]),但两者是两个独立的枚举取值——读侧 AssignmentOperationLogQueryService 没有 operation_type 白名单,共用会让「车务主动清空」与「司机拒接退回」在时间线上无法区分,而两者的责任归属不同。

触发本次留痕的写口端点本身未变:POST /admin/fleet/assignments/{assignmentId}/driver-reject(单派/组派共用同一端点,按当前派单是否属于某个派车组自动分流),请求体/响应结构/错误码均未调整。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 派单操作时间线 GET /admin/fleet/orders/{orderId}/operation-log 响应新增操作类型 新增 driver_rejected 枚举值 + detail_json 字段扩展

三、接口详情

1. 派单操作时间线 GET /admin/fleet/orders/{orderId}/operation-log

VO: FleetOperationLogItemVO → FleetOrderOperationLogRespVO

使用场景

车务在派车看板订单卡片内点「查看日志」,实时呈现该订单全部派车操作的不可变时间线。新操作类型 driver_rejected 会在司机拒接/车务退回待派成功执行后出现在此时间线中。

入参

字段 位置 类型 必填 约束 说明
orderId Path Long ✅ 雪花 ID 订单 ID
page Query Long ❌ 默认 1,上限 100000 分页页码
pageSize Query Long ❌ 默认 50,上限 200 每页条数
keyword Query String ❌ 最长 32 按操作人/摘要模糊匹配
sortBy Query String ❌ 如 time,desc / time,asc 排序字段,默认按 create_time 倒序
startDate / endDate Query LocalDateTime ❌ ISO 格式 yyyy-MM-dd'T'HH:mm:ss 时间范围过滤

出参 Result<FleetOrderOperationLogRespVO>

字段 类型 说明
data.records List 当前页操作日志行
data.records[].id String 日志行 ID(雪花号,以字符串返回防精度丢失)
data.records[].time LocalDateTime 操作时间
data.records[].opType String 操作类型英文枚举值,含新增的 driver_rejected
data.records[].opTypeLabel String 操作类型中文标签(由后端从枚举翻译,driver_rejected → "司机拒接/退回待派")
data.records[].summary String 可读摘要(固定文案:"司机拒接/退回待派,清空车与司机,派车行置待选择")
data.records[].operatorName String 操作人(企微名优先,无则用户名,系统动作显示"系统")
data.records[].effectiveDate LocalDate 生效日期(取锚点行的 serviceDate)
data.records[].detailJson String 明细 JSON(字符串化),格式见下节
data.total Long 总条数
data.page Integer 当前页码
data.pageSize Integer 本页条数

新增字段详情

opType 新增枚举值

值 中文标签 触发场景
driver_rejected 司机拒接/退回待派 司机拒接本次排车锁定,或车务确认锁定无效,调用 driver-reject 端点成功清空车辆/司机字段

detailJson 字段(当 opType="driver_rejected" 时)

响应的 detailJson 是字符串化的 JSON。字段与顺序如下(取自真实集成测试落库结果,逐字未改;单派场景,DriverRejectWritebackTraceIntegrationTest AC-1):

{"scope":"SINGLE","assignmentGroupId":"8114100001","statusBefore":"holding","rejectReason":"司机临时车辆抛锚,退回待派","clearedRowCount":1,"vehicleIdBefore":"8114300001","driverIdBefore":"8114400001","vehiclePlateSnapshot":"蒙A-81141","driverNameSnapshot":"拒接司机甲","clearedRows":[{"assignmentId":"8114100001","serviceDate":"2031-07-03","vehicleIdBefore":"8114300001","vehiclePlateBefore":"蒙A-81141","driverIdBefore":"8114400001","driverNameBefore":"拒接司机甲"}]}

组派场景(一次拒接影响整组多行,AC-2):

{"scope":"GROUP","assignmentGroupId":"8114200001","statusBefore":"holding","rejectReason":"司机拒接整组行程,退回待派","clearedRowCount":2,"vehicleIdBefore":"8114300011","driverIdBefore":"8114400011","vehiclePlateSnapshot":"蒙A-81142","driverNameSnapshot":"拒接司机乙","clearedRows":[{"assignmentId":"8114100011","serviceDate":"2031-07-10","vehicleIdBefore":"8114300011","vehiclePlateBefore":"蒙A-81142","driverIdBefore":"8114400011","driverNameBefore":"拒接司机乙"},{"assignmentId":"8114100012","serviceDate":"2031-07-11","vehicleIdBefore":"8114300012","vehiclePlateBefore":"蒙A-81143","driverIdBefore":"8114400011","driverNameBefore":"拒接司机乙"}]}

字段说明(LinkedHashMap 插入顺序,来自 AssignmentService#clearedIdentitySnapshot):

字段 类型 说明
scope String 拒接范围,SINGLE 单派、GROUP 按派车组整组拒接
assignmentGroupId String 派车组 ID(字符串格式;见下方「关键说明 1」的类型对照)
statusBefore String 清空前状态,恒为 holding(拒接只放行 holding → unassigned 这一种迁移,非 holding 一律 605020,不写日志)
rejectReason String 拒接/退回原因,与请求体 rejectReason 同一份取值(仅存证,不参与任何判定)
clearedRowCount Integer 本次清空涉及的派车行数(单派恒为 1,组派为组内行数)
vehicleIdBefore String 清空前的车辆 ID(锚点行,字符串返回)
driverIdBefore String 清空前的司机 ID(锚点行,字符串返回)
vehiclePlateSnapshot String 清空前的车牌号(可读值快照)
driverNameSnapshot String 清空前的司机名(可读值快照)
clearedRows Array 本次实际被清空的每一行明细:assignmentId / serviceDate / vehicleIdBefore / vehiclePlateBefore / driverIdBefore / driverNameBefore(组派时逐切片各自的车/司机可能不同,不是锚点行的复制,见下方「关键说明 2」)

关键说明 1:所有 ID 字段都以字符串返回,但 DB 列类型不代表 JSON 字段类型

detail_json 里的 vehicleIdBefore / driverIdBefore / assignmentId / clearedRows[].assignmentId 等 ID,均由后端 AssignmentService#idText(Object) 转换为字符串后再落 JSON(javadoc 原文:「可空 ID 转字符串(雪花 ID 落 JSON 防 JS 精度丢失;null 原样保留)」)。雪花 ID 是 19 位数字,JavaScript 的 Number 只能精确表示到 16 位,若以数字解析会在末位静默丢精度、无任何报错提示。

⚠️ 不要把 DB 列类型和 JSON 字段类型混为一谈:fleet_assignment_operation_log 表的 assignment_group_id 列在数据库里是 BIGINT NOT NULL(这一列是这一行日志自身的分组归属,落值就是数字,不在 detail_json 里);而 detail_json 内部的 assignmentGroupId 键是经 idText(...) 转换后的字符串——两者字段名相近,是两个不同的东西。前端通过这个 JSON 接口只会消费到后者(字符串),不会直接看到 DB 列。

关键说明 2:组拒接只写一行——锚点 + clearedRows[],不是逐槽位各写一条

一次组派拒接会清空组内全部行(上面示例是 2 行),但 fleet_assignment_operation_log 只 INSERT 一行:锚点行(组内第一行)写 operation_type=driver_rejected,组内其余被清空的行不会各自再产生一条独立的日志行,它们清空前的身份只出现在这一行的 detail_json.clearedRows[] 数组里。

实测依据(AC-2):把查询条件放宽成只按 order_id 扫描整张表(不加 assignment_id 过滤、不加 operation_type 过滤),针对一次影响 2 行的组拒接,整单也只返回 1 行日志(assignment_id 为锚点行 8114100011),组内另一行 8114100012 名下没有独立的日志行。⇒ 前端如果按 assignmentId 去时间线表里找某一行派车行「自己的」拒接记录,组内非锚点行是找不到的,需要改为解析锚点行的 clearedRows[]。

关键说明 3:若按 operation_type 白名单过滤,需要加入新取值

时间线读侧(AssignmentOperationLogQueryService)没有 operation_type 白名单,新取值会自动随查询结果返回。但如果前端渲染时自行对 operation_type 做了白名单过滤,必须把 driver_rejected 加入白名单,否则这条记录会被过滤掉、静默漏渲染(不报错、不提示)。

关键说明 4:新记录只出现在存量 holding 派单(组)被拒接时

产生 driver_rejected 记录的前提是 driver-reject 写口调用成功,而该写口只接受 holding 状态的派单(组)——FleetAssignmentMapper.updateDriverReject / updateDriverRejectGroup 均带 .eq(assignment_status, holding) 的 CAS 条件,非 holding 一律返回 605020、不写任何日志。自 #5827 起新建派单提交即派定,落库恒为 assigned(holding 仅剩发版前的存量数据,CreateAssignmentCommand javadoc 原文:"落库目标态:#5827 起提交即派定,最终态恒 assigned(holding 只是同事务内的瞬时中间态)")。⇒ 在测试环境用新建的派单调用 driver-reject 会拿到 605020(本会话已实测复现,详见八节的真实网关响应),不会产生 driver_rejected 记录;要看到这条新记录的渲染效果,需要用 #5827 发版前遗留、目前仍处于 holding 的存量派单(组),或等真实司机拒接场景产生新数据——这是该端点自身的既有前置条件,不是本次改动新增的限制。

请求示例

GET /admin/fleet/orders/8114000001/operation-log?page=1&pageSize=50 HTTP/1.1
Host: {后台域名}
Authorization: Bearer {token}
Accept: application/json

响应示例

以下 records[0] 按 FleetOperationLogItemVO 字段映射规则,从 AC-1 集成测试真实落库结果重新组装(detailJson 内容逐字符取自该次真库 IT 结果;id/time/effectiveDate 取自同一行的 operation_id/create_time/effective_date;operatorName 为该 IT 用例夹具下的 actor_name 原值「系统」——集成测试未经过网关鉴权链路、没有设置 operator_id,真实生产场景下这里通常是执行拒接操作的车务人员姓名,机制与其他写口的 operatorName 完全一致,本单未改动。整份响应信封本身未经网关活捕获,参见八节的受限说明):

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "records": [
      {
        "id": "2102121618417971202",
        "time": "2026-09-22T03:43:44",
        "opType": "driver_rejected",
        "opTypeLabel": "司机拒接/退回待派",
        "summary": "司机拒接/退回待派,清空车与司机,派车行置待选择",
        "operatorName": "系统",
        "effectiveDate": "2031-07-03",
        "detailJson": "{\"scope\":\"SINGLE\",\"assignmentGroupId\":\"8114100001\",\"statusBefore\":\"holding\",\"rejectReason\":\"司机临时车辆抛锚,退回待派\",\"clearedRowCount\":1,\"vehicleIdBefore\":\"8114300001\",\"driverIdBefore\":\"8114400001\",\"vehiclePlateSnapshot\":\"蒙A-81141\",\"driverNameSnapshot\":\"拒接司机甲\",\"clearedRows\":[{\"assignmentId\":\"8114100001\",\"serviceDate\":\"2031-07-03\",\"vehicleIdBefore\":\"8114300001\",\"vehiclePlateBefore\":\"蒙A-81141\",\"driverIdBefore\":\"8114400001\",\"driverNameBefore\":\"拒接司机甲\"}]}",
        "changeDetail": null
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 50
  }
}

空数据 / 降级响应

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

错误响应

{
  "code": 404,
  "message": "订单不存在",
  "success": false,
  "data": null
}

业务边界

  • 权限:网关 /admin/fleet/** 统一鉴权,车务/管理员可访问
  • 分页上限:pageSize 最高 200,page 最高 100000
  • ID 精度:所有雪花号均以字符串返回,前端切勿转为 Number 类型
  • operation_type 白名单:若前端自行维护白名单过滤时间线渲染,必须加入 driver_rejected,否则静默漏渲染
  • 组拒接留痕形状:一次组拒接只在 fleet_assignment_operation_log 里产生一行(锚点行),组内其余行的清空前身份只存在于该行 detail_json.clearedRows[] 数组内,不能按 assignmentId 直接从时间线表里查到独立行
  • 可达性边界:driver_rejected 只在拒接 holding 状态的存量派单(组)成功时产生;测试环境新建的派单调用 driver-reject 恒得 605020,不会产生这条记录

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

✅ 正确 / ❌ 错误 payload 对照

此接口为只读 GET,无请求体。正确调用示例:

场景 URL
✅ 第一页,默认排序 GET /admin/fleet/orders/{orderId}/operation-log?page=1&pageSize=50
✅ 处理 detailJson 字符串 JSON.parse(record.detailJson) 转为对象后访问字段
❌ ID 作为 Number parseInt(record.id) / Number(detail.vehicleIdBefore) 会导致末位精度丢失
❌ 按 assignmentId 直查组内非锚点行的独立日志 组内非锚点行没有独立日志行,需解析锚点行的 clearedRows[]

处理 detailJson 的正确方式

// ✅ 正确:先 parse,再按需读取 driver_rejected 专属字段
const detail = JSON.parse(record.detailJson);
if (record.opType === 'driver_rejected') {
  const rejectReason = detail.rejectReason;      // 拒接原因
  const clearedRows = detail.clearedRows;        // 组内逐行明细,SINGLE 场景长度恒为 1
  const vehicleId = detail.vehicleIdBefore;      // String,保持精度,不转 Number
}

// ❌ 禁止转数字
const id = Number(detail.vehicleIdBefore);  // 末位被四舍五入

operation_type 白名单排查清单(若前端有)

  • 渲染时间线的组件是否存在 operation_type 白名单/枚举映射?
  • 若存在,是否已加入 driver_rejected → "司机拒接/退回待派"?
  • 图标/颜色映射表是否需要为 driver_rejected 配一个默认展示(未配置时不应崩溃或空白)?

五、数据库行为

场景 数据库表 操作
司机拒接(单派)执行成功 fleet_assignment UPDATE vehicle_id = null, driver_id = null 等字段(CAS 条件 assignment_status = holding)
司机拒接(组派)执行成功 fleet_assignment 按 assignment_group_id 批量 UPDATE 组内多行,同上 CAS 条件
拒接留痕写口 fleet_assignment_operation_log INSERT 一行,operation_type = 'driver_rejected',detail_json 记录清空前的身份(锚点行 1 条,覆盖整组)

六、边界行为

  • 派单不存在 → 605009
  • 非 holding 状态 → 605020(不允许退回待派;自 #5827 起新建派单落库恒为 assigned,holding 仅剩发版前的存量数据——对新建派单调用会必得 605020,这不是缺陷,见「关键说明 4」)
  • rejectReason 为空 → 400001
  • 旧 HOLD 通知结果正在确认中 → 605042(可稍后重试;此次不改变派单状态、不清空车辆/司机身份、不改变资源占用,也不写留痕)
  • 无鉴权 → 401(网关拦截);权限不足(非车务/管理员)→ 403
  • 历史数据:本次新增的 driver_rejected 仅出现在部署后发生的拒接成功操作中,不影响此前已有的操作日志记录

六.5、枚举 / 数据字典

operation_type 枚举(AssignmentOperationTypeEnum)

所属字段: FleetOperationLogItemVO.opType | 类型: String

新增值:

值 中文标签 说明
driver_rejected 司机拒接/退回待派 司机拒接锁定或车务确认锁定无效,调用 driver-reject 成功后清空派车行的车辆/司机字段

现有值(不含全列表,仅示例,与 driver_rejected 语义最接近的一项一并列出对照):

值 中文标签 说明
assignment_created 新建派单 订单新建派单时
change_completed 修改派单完成 改派操作完成
soft_cleared 清空司机/车辆 车务手动清空派车行的车辆/司机字段(#8068,与 driver_rejected 是同形状但独立的取值,不共用)
confirmed 确认执行 司机确认执行派单
completed 完结派单 派单完成

六.6、修改前后对比

响应字段级对比

字段 改前 改后 备注
records[].opType 不含 driver_rejected 新增 driver_rejected 前端若按白名单过滤需要加入
records[].detailJson 已有其他操作类型的内容 新增 opType="driver_rejected" 时的结构 含 rejectReason 等专属字段,见三节

行为级对比

行为 改前 改后
司机拒接/退回待派留痕 派车行 vehicle_id/driver_id 直接清空,无操作日志 调用 driver-reject 成功后同事务在 fleet_assignment_operation_log 写一行,记录清空前的车/司机
时间线查询 拒接操作不可见 拒接操作以 driver_rejected 行显示在时间线中
事后取证 无法查证谁拒的、拒掉了谁 detail_json 中记录清空前的 vehicleId/driverId 等快照,支持事后追溯

六.7、影响评估

  • 是否破坏向后兼容:否

    • 新增操作类型 driver_rejected 不影响既有类型的解析
    • 响应字段无删除,仅新增返回内容(仅当 opType=driver_rejected 时出现新的 detail_json 结构)
  • 前端是否必须同步上线:否(但需适配白名单过滤)

    • 后端接口变更无必须的前端代码改动
    • 但是:如果前端渲染时间线时对 operation_type 做了白名单过滤,白名单中必须加入 driver_rejected,否则该操作会静默漏渲染
  • 前端 workaround 清理点:

    • 若有硬编码的 operation_type 白名单,需补充 'driver_rejected'
    • 若用了枚举常量或字典,确保下发的字典已包含 driver_rejected 标签
  • 覆盖边界(前端自测数据来源受限,需知悉):

    • driver_rejected 只在「存量 holding 派单(组)」被拒接成功时产生。自 #5827 起,新建派单提交即派定,落库恒为 assigned——因此对着测试环境新建的派单调用 driver-reject 会返回 605020,不会产生这条新记录;能触发它的只有 #5827 发版前遗留、目前仍处于 holding 的存量派单(组)。
    • 前端要验证 driver_rejected 的渲染效果,需要去找这类存量数据(或等真实司机拒接场景产生新数据),而不是自己新建一条派单来复现——这是该端点自身的既有前置条件(holding 状态限定,非本单引入),不是本次改动新增的限制。

七、不影响范围

  • 仅影响:派单操作时间线接口 /admin/fleet/orders/{orderId}/operation-log 的响应内容
  • 零影响:
    • driver-reject 端点自身的请求体/响应结构/错误码(一律未改)
    • updateDriverReject / updateDriverRejectGroup 两个 Mapper default 方法(一行未改)
    • 派车创建/改派/确认等其他业务流程
    • 订单详情接口
    • 其他模块的操作日志接口(如房务)
    • 前端派车列表/派车详情等其他功能模块

八、测试环境已验证

后端部署:hl-fleet-service 测试服部署 sha 10ed12133,与本单 PR #8139 的合并提交完全一致,STATE=ok。⚠️ 该结论由管理者侧执行 deploy-status.sh 核验后转达,本会话未持有目标机器的 SSH 访问权限、未亲自运行该脚本,如实披露。

网关实测(本会话 2026-09-22 04:00 前后,真实发起,非构造):

对一条刚通过 POST /admin/fleet/assignments/batch 新建、状态为 assigned 的派单(assignmentId=2102125764705181697,04:00:12 创建)调用拒接端点:

POST /admin/fleet/assignments/2102125764705181697/driver-reject
  ↓
HTTP 200,code=605020,msg=当前派单状态不允许此操作

这与「关键说明 4」描述的可达性边界完全吻合:新建派单落库恒为 assigned,非 holding 一律 605020。同时执行了两组反例校验:

POST /admin/fleet/assignments/2102125764705181697999/driver-reject(ID 格式非法)
  ↓ HTTP 200,code=400,msg=参数 assignmentId 格式错误,请检查后重试

POST /admin/fleet/assignments/2102125764705181698/driver-reject(格式合法但不存在)
  ↓ HTTP 200,code=605009,msg=派单不存在

调用前后对该派单行与 fleet_assignment_operation_log 的 SELECT 复核:拒接调用前后该行 vehicle_id/driver_id/assignment_status 均无变化(assigned,2085539421276286978/2065272150012444674),operation_type='driver_rejected' 的行数前后均为 0——确认失败调用没有副作用、也没有写出留痕,符合预期。

受限说明:本会话测试环境内没有可用的存量 holding 派单(组),因此上面这组网关实测只覆盖了 driver-reject 的失败分支,没有现场网关实测出「拒接成功 → 写入 driver_rejected → 时间线读侧可见」这条正向链路(该限制本身正是「关键说明 4」所述的可达性边界,不是本次验证的疏漏)。正向链路的验证依据是集成测试真库取证(见下):

用例:DriverRejectWritebackTraceIntegrationTest(test profile 的 H2 MODE=MySQL + 真 Flyway DDL + 真 MyBatis 生成 SQL + 真 AssignmentService Bean,非 MySQL 8 容器)。

  • 单派(AC-1):拒接前该行 vehicle_id=8114300001, driver_id=8114400001, assignment_status=holding;拒接后同一行 vehicle_id=null, driver_id=null, assignment_status=unassigned;同时写出一行 fleet_assignment_operation_log(operation_id=2102121618417971202, operation_type=driver_rejected),其 detail_json.vehicleIdBefore="8114300001" / .driverIdBefore="8114400001" 与清空前的 DB 值一致——排除了「UPDATE 之后再 reload 导致全 null」这一最强反例。
  • 组派(AC-2):两个切片清空前分别持有不同的车/司机(8114300011/8114400011 与 8114300012/8114400011),拒接后按 order_id 全表扫描整单只返回 1 行日志(锚点 assignment_id=8114100011),第二个切片 8114100012 名下无独立日志行,两切片各自的清空前身份分别体现在锚点行 detail_json.clearedRows[0] 与 [1] 里——确认了「关键说明 2」所述的锚点+clearedRows[]留痕形状。

三节的响应示例即按上述 AC-1 真库 IT 结果、按 FleetOperationLogItemVO 字段映射规则重新组装(非网关活捕获,已在三节标注)。


十、相关文档

  • 关联 Issue: wx/HL#8114
  • 关联 PR: wx/HL#8139
  • 相关工单: #8068(软清留痕,同形状参照实现),#5827(取消司机确认环节,holding 状态自此变为遗留态)

关联 / 联系人

链接

联系人

  • 后端负责人: @wx