# 大交通批次软删: Method 破坏性变更 (DELETE → POST) + 桥接表级联软删 > **存放目录**: 二期(v3,`order-v3` 标签)→ `changelogs-v2/2026-05/` > > **服务**: hl-order-v3 (端口 8084) > **PR**: #2547 (commit `68887aba0`) > **Issue**: #2524 > **日期**: 2026-05-18 > **影响范围**: 管理后台「行程安排 - 接送站」区块 - 大交通批次删除 --- ## ⚠️ 关键变化(破坏性 - 前端必同步) 一行红字说清: - **本次变了什么**: 删除大交通批次接口 **Method 从 `DELETE` 改为 `POST`** + 路径子段从 `/transport-plans/{planId}` 改为 `/transport-plan/{planId}/delete` - **前端以前以为的是什么**: `DELETE /v3/admin/order/{id}/transport-plans/{planId}` - **实际现在是什么**: `POST /v3/admin/order/{id}/transport-plan/{planId}/delete` **Method 变化提醒**: `axios.delete(...)` 必须改 `axios.post(...)`;部分浏览器/代理对 `DELETE` 体行为不一致,统一 POST 后规避。 **配套破坏性**: §2.6 大交通批次模块 4 个接口路径风格 + 动词 + Method 全部统一迁移,见 #2521/#2522/#2523。 --- ## 一、背景 V5.48 §2.6.4 与 §2.6.3 编辑接口同步,统一 POST + 动词路径风格(对齐订单核心模块、出行人模块写动作)。 软删行为: 主表 + 桥接表**同事务级联软删**,均置 `deleted=1`,不丢历史,可被审计回溯。 --- ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 大交通批次软删 | POST | `/v3/admin/order/{id}/transport-plan/{planId}/delete` | Method + 路径双破坏 | 旧 `DELETE /transport-plans/{planId}` 下线 | --- ## 三、接口详情 ### 1. 大交通批次软删 `POST /v3/admin/order/{id}/transport-plan/{planId}/delete` #### 入参 | 字段 | 位置 | 类型 | 必填 | 说明 | |------|------|------|:----:|------| | `id` | Path | Long | ✅ | 订单 ID | | `planId` | Path | Long | ✅ | 批次 ID | > 无 Body。 #### 出参 `Result` | 字段 | 类型 | 说明 | |------|------|------| | `data` | Boolean | 始终 `true`(失败走错误码,不会返 `false`)| #### 请求示例 ``` POST /v3/admin/order/60123456789012/transport-plan/80012345/delete ``` #### 响应示例 ```json { "code": 200, "data": true, "msg": "success" } ``` #### 错误响应 | 错误码 | 含义 | 触发场景 | |--------|------|----------| | `581100` | 订单不存在 | path 中 orderId 无效 | | `581121` | plan 不属于该订单 | path orderId 与 plan.order_id 不一致 / planId 不存在 / 已软删 | > **错误码段位说明**: 本接口复用 §2 模块 baseline `581121`(plan 归属校验),而非 §2.6 add/edit 新增的 `581144`,这是 V5.48 §2.6.4 文档的有意约定(删除场景与新增/编辑的归属校验语义区分)。前端可对 `581121` / `581144` 做同样的"批次不存在"提示。 示例 `581121`: ```json { "code": 581121, "msg": "大交通批次不属于该订单: planId=80099999", "data": null } ``` --- ## 四、契约约束与正确调用方式 ### ✅ 正确 / ❌ 错误调用对照 | 场景 | 请求 | 结果 | |------|------|------| | ✅ 新调用 | `POST /transport-plan/80012345/delete` | 200 + `data:true` | | ❌ 沿用旧 DELETE | `DELETE /transport-plans/80012345` | 404 / 405 | | ❌ planId 跨单 | path orderId=A,planId 属于 B | `581121` | | ❌ 重复 delete | 已 `deleted=1` 的 plan 再 delete | `581121`(被软删的 plan 视同不存在) | ### 幂等语义 - `@Idempotent(timeout = 3)`: 同 admin 3 秒内重复 POST 同 path 直接拿首次结果,防双击重复 - `@Lock4j(keys = "#id")`: 同订单 30 秒锁,串行化 add/edit/delete - 即使去掉幂等保护,二次 delete 也会因 `581121`(已软删视同不存在)被业务层正确拒绝,不会出现"软删后再软删"的脏数据 --- ## 五、数据库行为 单事务执行,失败整体回滚: | 步骤 | 表 | 动作 | |------|-----|------| | 1 | `order_transport_plan` | UPDATE `deleted=1` WHERE `id = ? AND order_id = ? AND deleted = 0`,`update_time` 自动刷新 | | 2 | `order_transport_plan_traveler` | UPDATE `deleted=1` WHERE `plan_id = ?`(级联软删所有桥接行) | > **级联软删而非物理删**: 桥接表保留 `deleted=1` 历史行,审计能查"曾经哪些出行人在该 plan",支持事后回溯。与 edit 接口的「全量重建桥接表用物理 DELETE」语义有意不同 — edit 重建后旧关联失去业务意义,delete 软删后旧关联是审计证据。 校验顺序: 1. 订单存在性 → `581100` 2. plan 归属 + 未软删 → `581121`(若 UPDATE 影响 0 行表示 plan 不存在或已删 或 order_id 不匹配) --- ## 六、边界行为 - 未登录 → 401(网关拦截) - 订单不存在 → `581100` - planId 不存在 / 已软删 / 跨单 → `581121`(用 UPDATE WHERE 复合条件一次判定,影响行数=0 即归一处理) - 软删后,#2521 list 接口该 plan 不再返回(因 WHERE deleted=0 过滤) - 软删后,该 plan 占用的"同方向同 traveler"释放,该出行人可在同方向 add 新 plan(`581143` 判定 WHERE deleted=0) - 老数据 `order_transport_plan_traveler` 历史无 `deleted` 字段 → schema 已保证字段存在(V5.48 配套迁移已完成) --- ## 七、不影响范围 - **仅影响**: 管理后台 F21 「接送站」删除按钮 - **零影响**: - C 端订单详情 / mp 抵达计划接口 - 出行人模块本身(traveler 行不动,只动桥接关联) - 订单状态机 - 已签合同的 PDF 内容(合同生成时是快照,不会回溯查 plan) --- ## 八、测试环境已验证 测试服 9443 网关 + 真 admin token round-trip 验证: ``` POST https://web.test.1814.love:9443/v3/admin/order/{orderId}/transport-plan/{planId}/delete → 200 + data:true ✓ → DB 验证 order_transport_plan.deleted=1 ✓ → DB 验证 order_transport_plan_traveler.deleted=1 (级联) ✓ → planId 不存在 → 581121 ✓ → planId 跨单 → 581121 ✓ → 重复 delete → 581121 (软删后视同不存在) ✓ → delete 后 list 不再返回该 plan ✓ → delete 后 add 同方向同 traveler 成功 (581143 占用释放) ✓ → 3s 内重复 POST → 幂等返同结果 ✓ ``` (commit `15e2c7eeb` 含 hotfix #2550,4 接口一并 9443 真测过) --- ## 九、相关历史 PR | PR | Issue | 说明 | 是否仍有效 | |----|-------|------|------------| | **本 PR #2547** | **#2524** | Method DELETE→POST + 路径迁移 + 桥接表级联软删 | ✅ 最新 | --- ## 十、相关文档 - 关联 Issue: [wx/HL#2524](https://git.1814.love:8443/wx/HL/issues/2524) - 关联 PR: [wx/HL#2547](https://git.1814.love:8443/wx/HL/pulls/2547) - API 文档: `docs/order-v3/api/API-SPEC-V5.48.html` §2.6.4 - 配套破坏性: 见 `18_#2521_transport-plan-list-path.md` / `18_#2522_transport-plan-add.md` / `18_#2523_transport-plan-edit.md`