文件
hl-api-changelog/changelogs-v2/2026-10/03_8750_团期子订单封掉订单级行程写口-修改接口-管理后台.md
T

17 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 8750 团期子订单封掉订单级行程写口:改行程天 / 增改删节点 4 个接口对团期子订单返回 583066,调整快照不再提示行程与出行日期可编辑 admin jw(GIT) 修改接口 deployed verified pending mmg v2.1 2026-10-03 PR #8762 已合并 dev-v3(e8d83b0cb)并滚动部署 TEST 双实例。订单行程 4 个写口(改行程天、新增 / 修改 / 删除节点)对团期子订单一律返回新码 583066,零写入;团期管理员仍先返回 581008;散客单不变。调整快照 editableTabLocksHint 对团期子订单去掉 ITINERARY / SCHEDULE。TEST 网关实测:团期子订单 4 个写口 583066 且三表逐字一致、散客单增改删回写 200、团期管理员 581008、快照两侧取值符合。前端待办:团期子订单详情行程页签隐藏编辑 / 新增 / 删除按钮;团期行程汇总下钻去掉「跳去改」入口,保留跳转查看。 2026-10-03 dev-v3

order-v3: 团期子订单封掉订单级行程写口

服务: hl-order-service-v3 PR: #8762(已合入 dev-v3,合并提交 e8d83b0cb);文档回写 #8763 Issue: #8750


⚠️ 关键变化

🔴 团期子订单不能再在订单详情里改行程。 改行程天、新增 / 修改 / 删除节点 4 个接口,对团期子订单一律返回新码 583066,整笔零写入。原来定制师还能改成功,现在改不了。

🟢 散客单完全不变。 请求体、响应体结构都没改。

🟢 调整快照的 editableTabLocksHint 对团期子订单不再含 ITINERARY / SCHEDULE。 这两个页签在调整里一提交就是 587045(#8350),提示与实际行为现在一致。


一、背景

#8350(2026-09-24)定案:团期子订单不能在子订单里调整出行日期和行程,但当时只封了 POST /v3/admin/order/:id/adjustment/submit 一个入口。订单详情行程页签直接调的 4 个写接口仍然开着:团期管理员被按角色拦住,定制师仍能改团期子订单的行程。团期层本来就不提供行程编辑(#7378 AC-I7)。jw 2026-10-03 定:封。

封口后,团期子订单的行程只来自下单时的产品快照,随团期转期、改期同步,没有人工编辑通路。订单调整、转期重排、改期同步、下单物化这些内部路径不走这 4 个接口,不受影响。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 修改行程天 PUT /v3/admin/order/:orderId/itinerary/days/:dayId 行为变更 + 新增错误码 团期子订单返回 583066
2 新增行程节点 POST /v3/admin/order/:orderId/itinerary/nodes 行为变更 + 新增错误码 团期子订单返回 583066
3 修改行程节点 PUT /v3/admin/order/:orderId/itinerary/nodes/:nodeId 行为变更 + 新增错误码 团期子订单返回 583066
4 删除行程节点 DELETE /v3/admin/order/:orderId/itinerary/nodes/:nodeId 行为变更 + 新增错误码 团期子订单返回 583066
5 调整快照 GET /v3/admin/order/:id/adjustment/snapshot 返回值变更 团期子订单 editableTabLocksHint 去掉 ITINERARY / SCHEDULE

三、接口详情

1. 修改行程天 PUT /v3/admin/order/:orderId/itinerary/days/:dayId

VO: ItineraryDayUpsertReqVO → Result<ItineraryDayRespVO>

使用场景

订单详情行程页签改某一天的叙事内容(标题、描述、封面图、三餐等)。本次只改变团期子订单的放行规则。

入参字段表

字段 位置 类型 必填 约束 说明
orderId Path Long ✅ 订单 ID 不变;团期子订单直接返回 583066
dayId Path Long ✅ 该订单的行程天 ID 不变
dayTitle 等叙事字段 Body — ❌ 同改前 不变

出参字段表

字段 类型 说明
data ItineraryDayRespVO 不变(散客单);团期子订单返回 583066,data 为 null

请求示例

{
  "dayTitle": "海拉尔—额尔古纳 湿地观景",
  "description": "上午出发前往额尔古纳湿地,午后登观景台"
}

响应示例

散客单(不变):

{
  "code": 200,
  "message": "成功",
  "data": { "id": "7700000000001", "dayNumber": 2, "dayDate": "2026-10-12", "dayTitle": "海拉尔—额尔古纳 湿地观景" },
  "success": true
}

空数据 / 降级响应

写接口无空数据场景。

错误响应

团期子订单(本次新增):

{ "code": 583066, "message": "团期子订单的行程随团期产品,不支持在子订单中修改", "data": null, "success": false }

团期管理员角色(存量,先于 583066 判定):

{ "code": 581008, "message": "无权查看此订单", "data": null, "success": false }

业务边界

  • 判团口径与 #8350 相同:订单归属团期(group_batch_id 非空)即为团期子订单。
  • 先判团期管理员角色(581008),再判团期子订单(583066),都在任何写之前,拒绝即零写入。
  • 订单不存在时不在这里拦,仍按原逻辑返回 583050(行程天不存在)。

2. 新增行程节点 POST /v3/admin/order/:orderId/itinerary/nodes

VO: ItineraryNodeUpsertReqVO → Result<ItineraryNodeRespVO>

使用场景

订单详情行程页签在某一天新增一个节点(景点 / 餐厅 / 活动 / 服务)。

入参字段表

字段 位置 类型 必填 约束 说明
orderId Path Long ✅ 订单 ID 不变;团期子订单直接返回 583066
dayId Body Long ✅ 该订单的行程天 ID 不变
nodeType Body String ✅ SCENIC / RESTAURANT / ACTIVITY / SERVICE 不变
nodeName Body String ✅ ≤128 不变
其余字段 Body — ❌ 同改前 不变

出参字段表

字段 类型 说明
data ItineraryNodeRespVO 不变(散客单);团期子订单返回 583066,data 为 null

请求示例

{
  "dayId": "7700000000001",
  "nodeType": "SCENIC",
  "nodeName": "呼伦湖",
  "startTime": "09:30"
}

响应示例

散客单(不变):

{
  "code": 200,
  "message": "成功",
  "data": { "id": "8800000000001", "dayId": "7700000000001", "nodeType": "SCENIC", "sortOrder": 3, "nodeName": "呼伦湖" },
  "success": true
}

空数据 / 降级响应

写接口无空数据场景。

错误响应

团期子订单(本次新增):

{ "code": 583066, "message": "团期子订单的行程随团期产品,不支持在子订单中修改", "data": null, "success": false }

业务边界

  • 同接口 1:团期管理员 581008 先判,团期子订单 583066 后判,都在写之前。
  • 散客单的节点类型校验、资源名反查、自费售价校验(583064)等全部不变。

3. 修改行程节点 PUT /v3/admin/order/:orderId/itinerary/nodes/:nodeId

VO: ItineraryNodeUpsertReqVO → Result<ItineraryNodeRespVO>

使用场景

订单详情行程页签修改某个节点的叙事字段和结算字段。

入参字段表

字段 位置 类型 必填 约束 说明
orderId Path Long ✅ 订单 ID 不变;团期子订单直接返回 583066
nodeId Path Long ✅ 该订单的节点 ID 不变
nodeName Body String ✅ ≤128 不变
其余字段 Body — ❌ 同改前 不变

出参字段表

字段 类型 说明
data ItineraryNodeRespVO 不变(散客单);团期子订单返回 583066,data 为 null

请求示例

{
  "nodeType": "SCENIC",
  "nodeName": "呼伦湖",
  "description": "湖畔栈道步行约 40 分钟"
}

响应示例

散客单(不变):

{
  "code": 200,
  "message": "成功",
  "data": { "id": "8800000000001", "nodeName": "呼伦湖", "description": "湖畔栈道步行约 40 分钟" },
  "success": true
}

空数据 / 降级响应

写接口无空数据场景。

错误响应

团期子订单(本次新增):

{ "code": 583066, "message": "团期子订单的行程随团期产品,不支持在子订单中修改", "data": null, "success": false }

业务边界

  • 同接口 1。
  • 订单调整(adjustment/submit)内部改节点不走本接口,不受 583066 影响;它对团期子订单带行程已由 587045 拦截(#8350)。

4. 删除行程节点 DELETE /v3/admin/order/:orderId/itinerary/nodes/:nodeId

VO: ItineraryNodeDeleteReqVO(可不传)→ Result<ItineraryNodeRespVO>

使用场景

订单详情行程页签删除某个节点(软删)。

入参字段表

字段 位置 类型 必填 约束 说明
orderId Path Long ✅ 订单 ID 不变;团期子订单直接返回 583066
nodeId Path Long ✅ 该订单的节点 ID 不变
editReason Body String ❌ ≤500 不变

出参字段表

字段 类型 说明
data ItineraryNodeRespVO 不变(散客单,删除前快照);团期子订单返回 583066,data 为 null

请求示例

DELETE /v3/admin/order/2100743225424621570/itinerary/nodes/8800000000001
Authorization: Bearer <管理端令牌>

响应示例

散客单(不变):

{
  "code": 200,
  "message": "成功",
  "data": { "id": "8800000000001", "nodeName": "呼伦湖" },
  "success": true
}

空数据 / 降级响应

写接口无空数据场景。

错误响应

团期子订单(本次新增):

{ "code": 583066, "message": "团期子订单的行程随团期产品,不支持在子订单中修改", "data": null, "success": false }

业务边界

  • 同接口 1。
  • 散客单删除节点时的应付款台账联动(599602 锁定拦截等)不变。

5. 调整快照 GET /v3/admin/order/:id/adjustment/snapshot

VO: Result<AdjustmentSnapshotRespVO>

使用场景

「调整订单」弹窗打开时取快照;editableTabLocksHint 告诉前端哪些页签可编辑。

入参字段表

字段 位置 类型 必填 约束 说明
id Path Long ✅ 订单 ID 不变
scope Query String ❌ 逗号分隔子域 不变

出参字段表

字段 类型 说明
data.editableTabLocksHint Array<String> 🔁 团期子订单不再含 ITINERARY / SCHEDULE;散客单不变
其余字段 — 不变

请求示例

GET /v3/admin/order/2100743225424621570/adjustment/snapshot
Authorization: Bearer <管理端令牌>

响应示例

团期子订单(资源准备中):

{
  "code": 200,
  "message": "成功",
  "data": {
    "basic": { "orderNo": "HL20260924171304411" },
    "editableTabLocksHint": ["BASIC", "PEOPLE", "HOTEL_REQ", "VEHICLE_REQ", "FEE"]
  },
  "success": true
}

空数据 / 降级响应

无变化:订单不存在等错误与改前一致。

{ "code": 200, "message": "成功", "data": { "editableTabLocksHint": ["BASIC"] }, "success": true }

错误响应

非法 scope(存量):

{ "code": 587003, "message": "调整范围取值非法", "data": null, "success": false }

业务边界

  • 只对团期子订单从集合里去掉 ITINERARY / SCHEDULE,其余页签按原来的流程状态规则给出。
  • 传单个 scope 时原来是原样回显该 scope;团期子订单传 ITINERARY 或 SCHEDULE 现在返回空集合。

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

场景 调用 结果
❌ 团期子订单改行程天 / 增改删节点 接口 1~4 583066,零写入
❌ 团期管理员改任意订单行程 接口 1~4 581008(存量,先于 583066)
✅ 散客单改行程 接口 1~4 同改前
✅ 团期子订单打开调整弹窗 接口 5 editableTabLocksHint 不含 ITINERARY / SCHEDULE
  • 前端对团期子订单应隐藏行程页签的编辑、新增、删除按钮,避免用户点了才看到 583066。
  • 团期行程汇总下钻(GB-ADM-019)不再提供「跳去改」入口,保留跳转查看即可。

五、数据库行为

  • 无 Flyway migration、无 DDL、无新增写入。
  • 团期子订单调接口 1~4:在任何写之前拒绝,order_itinerary_day / order_itinerary_node / order_main 零写入。
  • 散客单:写入行为与改前一致。
  • 接口 5 只读。

六、边界行为

  • 团期子订单调接口 1~4 → 583066。
  • 团期管理员调接口 1~4 → 581008(不论散客还是团期子订单)。
  • 订单不存在 → 不在守卫拦,按原逻辑报 583050 / 583051。
  • 团期子订单调接口 5 → editableTabLocksHint 不含 ITINERARY / SCHEDULE。
  • 散客单 → 全部不变。

六.6、修改前后对比

行为(团期子订单) 改前 改后
定制师 / 管理员改行程天、增改删节点 200,写入成功 583066,零写入
团期管理员改行程 581008 581008(不变)
调整快照 editableTabLocksHint(全量) 含 ITINERARY,流程状态早时含 SCHEDULE 两者都不含
调整快照单 scope=ITINERARY / SCHEDULE 回显该 scope 空集合

六.7、影响评估

  • 是否破坏向后兼容: 请求 / 响应结构不变;团期子订单原来能成功的行程编辑现在返回 583066。
  • 前端是否必须同步上线: 建议同步。行程页签对团期子订单要隐藏编辑、新增、删除按钮;团期行程汇总下钻去掉「跳去改」入口。不改前端也不会写坏数据,只是用户点了会看到 583066 提示。
  • 前端 workaround 清理点: 调整弹窗里对团期子订单置灰出行日期 / 行程页签的自判逻辑,现在可以直接读 editableTabLocksHint。

七、不影响范围

  • 散客(非团期)订单的全部行程编辑与调整行为。
  • 订单调整统一提交(adjustment/submit),团期子订单仍按 #8350 返回 587045。
  • 团期转期、改期同步、下单物化行程等内部路径。
  • 团期用餐口径(#8230 / #8343)、团期行程汇总与下钻(GB-ADM-018 / 019)的读取结果。
  • POST /v3/admin/order/:id/confirm-itinerary(只确认状态、不改行程内容)。

八、测试环境已验证

真实网关(TEST,https://api.test.1814.love,自签 admin token),部署检出 b9f22e3ad(含合并提交 e8d83b0cb),造数:团期子订单 HL20260929154809598(团号 T26-0352,资源准备中)、散客单 HL20260810141518677(资源准备中):

用例 请求 结果 库内读数
团期子订单改行程天 / 增 / 改 / 删节点 接口 1~4,管理员 token 583066 ×4 订单主表、行程天 7 行、节点 28 行前后逐字一致
散客单原值回写行程天 接口 1 200 该天整行未变
散客单新增「莫日格勒河」→ 改描述 → 删除 接口 2 → 3 → 4 200 ×3 新节点写入、描述更新、软删;原有 14 个节点无变化
团期管理员改散客单行程 接口 1~4,团期管理员 token 581008 ×4 三表前后逐字一致
团期管理员改团期子订单行程天 接口 1,团期管理员 token 581008 角色守卫先于 583066
团期子订单调整快照 接口 5 200 editableTabLocksHint = BASIC / PEOPLE / HOTEL_REQ / VEHICLE_REQ / FEE
散客单调整快照 接口 5 200 editableTabLocksHint 七项齐全,与改前规则一致
不带令牌 接口 1 401 零写入

单元测试:定向集(行程 / 调整 / 错误码 / 架构包 + 转期改期回归)67 类 825 例,失败 2、错误 0;2 条失败在干净基底上逐条复现,属 #8714 既有,与本次无关。本次新增 13 例全部通过,含 ArchTest:订单行程写端点必须调团期子订单守卫、守卫只许该控制器调用。

部署: PR #8762 已合并 dev-v3(合并提交 e8d83b0cb),TEST 双实例滚动部署完成。


十、相关文档

关联 / 联系人

链接

联系人

  • 后端负责人: @jw