hl-api-changelog/changelogs-v2/2026-05/18_#2521_transport-plan-list-path.md
API Changelog Bot 1001a07f44 changelog(order-v3): 大交通批次 4 接口 (#2521-#2524)
- #2521 list 路径迁移 /transport-plans → /transport-plan/list
- #2522 add 路径 + 错误码 581140-581143 + @Idempotent + @Lock4j
- #2523 edit Method PUT → POST + 错误码 581144
- #2524 delete Method DELETE → POST + 桥接表级联软删

测试服 9443 真测全  (commit 15e2c7eeb 含 hotfix #2550)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:24:44 +08:00

7.8 KiB

大交通批次列表: 接口路径破坏性迁移 (transport-plans → transport-plan/list)

存放目录: 二期(v3,order-v3 标签)→ changelogs-v2/2026-05/

服务: hl-order-v3 (端口 8084) PR: #2544 (squash 后 commit be3badaca) Issue: #2521 日期: 2026-05-18 影响范围: 管理后台「行程安排 - 接送站」区块 - 大交通批次列表


⚠️ 关键变化(破坏性 - 前端必同步)

一行红字说清:

  • 本次变了什么: 大交通批次列表接口路径从 /transport-plans 改为 /transport-plan/list
  • 前端以前以为的是什么: GET /v3/admin/order/{id}/transport-plans (旧式复数资源风格)
  • 实际现在是什么: GET /v3/admin/order/{id}/transport-plan/list (统一 list/add/edit/delete 动词风格)

配套破坏性: §2.6 大交通批次模块 4 个接口路径风格 + 动词 + Method 全部统一迁移,见 #2522/#2523/#2524 changelog。前端需要 4 个接口一并改。


一、背景

V5.48 §2.6 大交通批次模块 4 个接口(list/add/edit/delete)统一为 /transport-plan/{动词} 子路径风格,与订单模块其他子资源(出行人 traveler/list、配房 hotel-requirement 等)保持一致:

风格 旧 (V5.47 之前) 新 (V5.48)
列表 GET /transport-plans GET /transport-plan/list
新增 POST /transport-plans POST /transport-plan/add
编辑 PUT /transport-plans/{planId} POST /transport-plan/{planId}/edit
软删 DELETE /transport-plans/{planId} POST /transport-plan/{planId}/delete

统一动词路径后,网关路由 / 权限 RBAC / 操作审计的资源前缀一致,便于配置和扫描。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 大交通批次列表 GET /v3/admin/order/{id}/transport-plan/list 路径迁移 旧路径 /transport-plans 已下线

三、接口详情

1. 大交通批次列表 GET /v3/admin/order/{id}/transport-plan/list

VO: TransportPlanVO

入参

字段 位置 类型 必填 约束 说明
id Path Long - 订单 ID

出参 Result<List<TransportPlanVO>>

字段 类型 说明
id String 批次 ID(雪花)
orderId String 订单 ID
direction String 方向 ARRIVAL / DEPARTURE
transportType String 类型 FLIGHT / TRAIN / SELF_DRIVE
transportNo String 航班号 / 车次号(SELF_DRIVE 时为 null)
carrier String 航司 / 铁路公司
departStation String 出发站
arriveStation String 到达站
departTime LocalDateTime 出发时间(SELF_DRIVE 时为 null)
arriveTime LocalDateTime 到达时间(SELF_DRIVE 时为 null)
selfDrivePeriod String 仅 SELF_DRIVE: MORNING / AFTERNOON / EVENING
selfDriveEta LocalDateTime 仅 SELF_DRIVE: 预计抵达时间
travelers List 桥接表关联出行人,元素 {id, name}
remark String 备注

请求示例

GET /v3/admin/order/60123456789012/transport-plan/list

响应示例

{
  "code": 200,
  "data": [
    {
      "id": "80012345",
      "orderId": "60123456789012",
      "direction": "ARRIVAL",
      "transportType": "FLIGHT",
      "transportNo": "CA1234",
      "carrier": "中国国际航空",
      "departStation": "北京首都T3",
      "arriveStation": "长春龙嘉",
      "departTime": "2026-06-01T08:30:00",
      "arriveTime": "2026-06-01T10:15:00",
      "selfDrivePeriod": null,
      "selfDriveEta": null,
      "travelers": [
        {"id": "70123456789012", "name": "张三"},
        {"id": "70123456789013", "name": "王小明"}
      ],
      "remark": "需要接机举牌"
    },
    {
      "id": "80012346",
      "orderId": "60123456789012",
      "direction": "DEPARTURE",
      "transportType": "SELF_DRIVE",
      "transportNo": null,
      "carrier": null,
      "departStation": null,
      "arriveStation": null,
      "departTime": null,
      "arriveTime": null,
      "selfDrivePeriod": "AFTERNOON",
      "selfDriveEta": "2026-06-05T15:00:00",
      "travelers": [
        {"id": "70123456789012", "name": "张三"}
      ],
      "remark": null
    }
  ],
  "msg": "success"
}

空数据响应

订单尚未登记任何大交通批次时:

{ "code": 200, "data": [], "msg": "success" }

错误响应

订单不存在:

{
  "code": 581100,
  "msg": "订单不存在",
  "data": null
}

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

正确 / 错误调用对照

场景 请求
新路径 GET /v3/admin/order/60123456789012/transport-plan/list
旧路径(已下线 404) GET /v3/admin/order/60123456789012/transport-plans

字段语义约束

  • direction 取值固定两值: ARRIVAL(到达) / DEPARTURE(离开)
  • transportType 三值: FLIGHT / TRAIN / SELF_DRIVE
  • SELF_DRIVE 类型行: transportNo / departTime / arriveTime 必为 null;selfDrivePeriod 必有值
  • FLIGHT / TRAIN 类型行: transportNo / departTime / arriveTime 必有值;selfDrivePeriod / selfDriveEta 必为 null
  • travelers 数组永远非空(后端保证),元素至少 1 个

五、数据库行为

只读查询,无写动作。

查询步骤 说明
1 order_transport_plan WHERE order_id = ? AND deleted = 0,主表批次记录
2 LEFT JOIN order_transport_plan_traveler WHERE deleted = 0,桥接表关联出行人 ID
3 JOIN order_traveler WHERE deleted = 0,出行人姓名补全
4 内存装配 同一 plan 多 traveler 聚合为 travelers: [{id, name}] 数组

排序: ORDER BY direction ASC, depart_time ASC, id ASC (ARRIVAL 先于 DEPARTURE,同方向按时间升序)。


六、边界行为

  • 未登录 → 401(网关拦截)
  • 订单不存在 → 581100
  • 订单存在但无任何批次 → 200 + data: [](不报错)
  • 批次存在但桥接表全软删 → travelers: [](理论上不应出现,后端保证)
  • 老数据(v2 历史 plan 无 mode 字段)→ 字段为 null,不异常

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

  • 仅影响: 管理后台 F21 行程安排 Tab 「接送站」区块 - 大交通批次列表渲染
  • 零影响:
    • C 端订单详情 mp 接口(不查 plan 表,只查 arrival_plan)
    • 订单创建 / 支付 / 退款主流程
    • 出行人模块(travelers list 仍走 /admin/order/{id}/traveler/list)
    • Feign 内部接口 GET /internal/order/orders/{orderId}/travelers(回传 transportPlanIds,使用的是同表数据但聚合方向相反,不受路径变化影响)

八、测试环境已验证

测试服 9443 网关 + 真 admin token round-trip 验证:

GET https://web.test.1814.love:9443/v3/admin/order/{orderId}/transport-plan/list
  → 200 + data 数组 ✓
  → travelers 嵌套字段返回正确 (id+name) ✓
  → ARRIVAL/DEPARTURE 排序正确 ✓
  → 空订单返 data: [] ✓

(commit 15e2c7eeb 含 hotfix #2550 修复 conflict markers,4 接口一并 9443 真测过)


九、相关历史 PR

PR Issue 说明 是否仍有效
本 PR #2544 #2521 路径破坏性迁移 /transport-plans/transport-plan/list 最新

十、相关文档

  • 关联 Issue: wx/HL#2521
  • 关联 PR: wx/HL#2544
  • API 文档: docs/order-v3/api/API-SPEC-V5.48.html §2.6.1
  • 配套破坏性: 见 18_#2522_transport-plan-add.md / 18_#2523_transport-plan-edit.md / 18_#2524_transport-plan-delete.md