入库委托函单卷重置/取消/恢复/指定司机

流程图 v1.0 | 2026-08-14

1

状态流转总览

单卷生命周期全貌
stateDiagram-v2 [*] --> Pending : 创建/重置/恢复 Pending --> Received : 码头同车再发(自动回填) Pending --> Received : assignDriver + 接单 Pending --> Cancelled : cancelCoil Received --> InTransit : 司机出发 Received --> Cancelled : cancelCoil Received --> Pending : resetCoilStatus InTransit --> Completed : 完成运输 InTransit --> Pending : resetCoilStatus InTransit --> Cancelled : cancelCoil Completed --> [*] : 闭环 Cancelled --> Pending : restoreCoil Cancelled --> [*] : 闭环(剩余卷完成) note right of Pending driverId = null excludedDriverId = 原始司机(reset) 或 null(restore) end note note right of Cancelled cargo delFlag = 1 item cancelled end note note right of Completed receivingPushStatus = success 不可回退 end note
Pending 待接单
Received 已接单
InTransit 运输中
Completed 已完成
Cancelled 已取消
2

重置卷状态 (resetCoilStatus)

清回初始态,卷仍在链路
flowchart TD A([管理员调用 resetCoilStatus]) --> B[SELECT FOR UPDATE 行锁查 item] B --> C{receivingPushStatus\n= success?} C -->|是| D[拒绝: 已推送WMS不可重置] C -->|否| E{item 已 cancelled?} E -->|是| F[拒绝: 已取消的卷不可重置] E -->|否| G{订单 lifecycleStatus\n= CLOSED/CANCELLED?} G -->|是| H[拒绝: 终态订单不可重置] G -->|否| I[清除全部操作字段\n回初始枚举值] I --> J[excludedDriverId = 原始 driverId] J --> K[detachAndShrinkDriverOrder\n断开+缩容司机订单] K --> L[写 ACTION_RESET 日志] L --> M[发布 RefreshEvent\n自动重算 executionStatus] M --> N([重置完成]) style D fill:#fee,stroke:#e33 style F fill:#fee,stroke:#e33 style H fill:#fee,stroke:#e33 style I fill:#fef3c7,stroke:#f59e0b style N fill:#d1fae5,stroke:#10b981
3

取消单卷 (cancelCoil)

移出执行链路,可闭环
flowchart TD A([管理员调用 cancelCoil]) --> B[SELECT FOR UPDATE 行锁查 item] B --> C{receivingPushStatus\n= success?} C -->|是| D[拒绝: 已推送WMS不可取消] C -->|否| E[记录原 driverOrderId/driverId/vehicleId] E --> F[item 设 cancelled\nitemStatus/taskStatus/driverOrderStatus] F --> G[软删 cargo\ndelFlag=1\n按 authorizationId+billnumber+coilNo] G --> H[detachAndShrinkDriverOrder\n断开+缩容] H --> I[清理 dispatch task\n司机/车辆快照] I --> J[写 ACTION_CANCEL 日志] J --> K[发布 RefreshEvent] K --> L{剩余卷全部\ncompleted+pushed?} L -->|是| M[executionStatus = completed\n闭环] L -->|否| N([取消完成,未闭环]) M --> O([取消完成,已闭环]) style D fill:#fee,stroke:#e33 style G fill:#fee2e2,stroke:#ef4444 style M fill:#d1fae5,stroke:#10b981 style O fill:#d1fae5,stroke:#10b981 style N fill:#fef3c7,stroke:#f59e0b
4

恢复已取消卷 (restoreCoil)

取消的卷恢复回执行链路
flowchart TD A([管理员调用 restoreCoil]) --> B[SELECT FOR UPDATE 行锁查 item] B --> C{itemStatus\n= cancelled?} C -->|否| D[拒绝: 仅已取消的卷可恢复] C -->|是| E{receivingPushStatus\n= success?} E -->|是| F[拒绝: 已推送WMS不可恢复] E -->|否| G[清除全部操作字段\n与resetCoilStatus一致\n但保留coilReview数据] G --> H[excludedDriverId = null] H --> I["restoreSoftDeletedCargo\n@Update原生SQL\nWHERE del_flag=1\n绕过@TableLogic"] I --> J{restored > 0?} J -->|是| K[cargo delFlag=0 恢复成功] J -->|否| L[警告日志: 参数可能不匹配\ncargo可能已被物理删除] K --> M[写 ACTION_RESTORE 日志] L --> M M --> N[发布 RefreshEvent] N --> O([恢复完成\n卷回到pending态\ndriverId=null需重新指定]) style D fill:#fee,stroke:#e33 style F fill:#fee,stroke:#e33 style I fill:#dcfce7,stroke:#10b981 style K fill:#d1fae5,stroke:#10b981 style L fill:#fef3c7,stroke:#f59e0b style O fill:#d1fae5,stroke:#10b981
5

接单自愈机制 (resolveReceivableAuthorizationCargo)

自动恢复卡在 del_flag=1 的 cargo
flowchart TD A([司机接单 receiveTask]) --> B[校验 item 状态为可接单] B --> C{inboundAuthorizationTask\n& receiveMode = ACTIVE?} C -->|否| D[跳过 cargo 绑定] C -->|是| E["selectAllByAuthorizationIds\n@Select原生SQL\n包含del_flag=1记录"] E --> F[findFirstCoilMatch\n按 coilNo 匹配] F --> G{匹配到 cargo?} G -->|否| H[抛异常:\n未匹配到当前委托函钢卷] G -->|是| I{cargo.delFlag\n= 1?} I -->|否| J[正常返回 cargo] I -->|是| K["restoreSoftDeletedCargo\n@Update原生SQL\n自动恢复 del_flag=0"] K --> L[warn日志:\n接单匹配到软删货物, 自动恢复] L --> M[返回已恢复的 cargo] J --> N([继续接单绑定流程]) M --> N style H fill:#fee,stroke:#e33 style E fill:#ede9fe,stroke:#8b5cf6 style K fill:#ede9fe,stroke:#8b5cf6 style L fill:#fef3c7,stroke:#f59e0b style N fill:#d1fae5,stroke:#10b981
自愈路径(绕过 @TableLogic)
正常路径
异常路径
警告路径
6

后台指定司机 (assignDriver)

为重置/恢复后的卷手动指定司机
flowchart TD A([管理员调用 assignDriver]) --> B[查 item] B --> C{taskStatus\n= pending?} C -->|否| D[拒绝: 仅待接单状态可指定] C -->|是| E{driverId\nIS NULL?} E -->|否| F[拒绝: 已绑定司机] E -->|是| G{driverOrderId\nIS NULL?} G -->|否| H[拒绝: 已生成订单] G -->|是| I{传入 pairId?} I -->|是| J[查 VehicleDriverPlanPair\n解析 driverId + vehicleId] I -->|否| K{同时传入\ndriverId + vehicleId?} K -->|是| L[直接使用] K -->|否| M[拒绝: 必须传入 pairId\n或同时传入两者] J --> N[validateDriverAndVehicle\n校验存在性] L --> N N --> O[设 item.driverId + vehicleId\n清除 excludedDriverId] O --> P[发布 RefreshEvent] P --> Q([指定完成\n卷可被司机接单]) style D fill:#fee,stroke:#e33 style F fill:#fee,stroke:#e33 style H fill:#fee,stroke:#e33 style M fill:#fee,stroke:#e33 style Q fill:#d1fae5,stroke:#10b981
7

@TableLogic 问题与原生 SQL 解决方案

为什么需要绕过 MyBatis-Plus 逻辑删除
flowchart LR subgraph 问题 direction TB P1[cancelCoil 软删 cargo\ndel_flag = 1] --> P2[restoreCoil 尝试恢复] P2 --> P3["LambdaUpdateWrapper\n.set(delFlag, 0)"] P3 --> P4["@TableLogic 自动追加\nWHERE ... AND del_flag = 0"] P4 --> P5{匹配 del_flag=1?} P5 -->|否| P6[恢复静默失败\ncargo 卡在 del_flag=1] end subgraph 解决 direction TB S1["restoreSoftDeletedCargo\n@Update 原生SQL"] --> S2["WHERE ... AND del_flag = 1"] S2 --> S3{匹配 del_flag=1?} S3 -->|是| S4[恢复成功\ndel_flag = 0] end subgraph 自愈 direction TB H1["resolveReceivableAuthorizationCargo\nselectList @TableLogic过滤"] --> H2[匹配不到 del_flag=1 的 cargo] H2 --> H3["改用 selectAllByAuthorizationIds\n@Select 原生SQL不过滤"] H3 --> H4[匹配到 del_flag=1 的 cargo] H4 --> H5[自动调用 restoreSoftDeletedCargo] H5 --> H6[恢复成功 继续接单] end P6 -.->|自愈兜底| H5 style P6 fill:#fee,stroke:#e33 style S4 fill:#d1fae5,stroke:#10b981 style H6 fill:#d1fae5,stroke:#10b981