snapshot 出参:basic 每次必返+承载订单号/产品名/团号+5金额,删顶层 discounts/surcharges/金额,行程改 days[].nodes[] 带价; submit 入参:删 editReason/tabLocks/confirmDiffHash/basic/feeChanges,行程改 days[].nodes[];出参精简为仅 success。
10 KiB
订单调整 snapshot / submit 契约重制——basic 承载订单信息+金额、行程 tab 定价化、submit 入出参大幅精简
端类型:管理后台 变更类型:修改接口(破坏性,前端需同步改造) 涉及接口:
GET /v3/admin/order/{id}/adjustment/snapshot(调整弹窗预填快照)POST /v3/admin/order/{id}/adjustment/submit(调整统一提交)
背景
订单调整弹窗的预填快照与统一提交接口经一轮重制:snapshot 的 basic 改为每次必返并承载订单身份+金额、行程 tab 升级为带价展示、删除前端用不到的优惠/附加费列表;submit 入参删除若干无用/已不支持字段、行程改嵌套结构、出参精简为只剩成功标志。两个接口的入出参结构均有破坏性变化,前端需按本文同步改造。
一、GET /v3/admin/order/{id}/adjustment/snapshot(出参重制)
入参(不变)
| 位置 | 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| path | id |
Long | 是 | 订单 ID |
| query | scope |
String | 否 | 限定返回子域,逗号分隔,不传返全部。枚举:BASIC/PEOPLE/SCHEDULE/ITINERARY/HOTEL_REQ/VEHICLE_REQ(FEE 已移除) |
关键变更
basic每次必返(不再受scope限制,传任意 scope 都返回 basic)。basic新增订单身份字段:orderNo/productName/teamNo/productType(只读展示)。- 订单金额从顶层移入
basic:orderAmount/surchargeAmount/discountAmount/receivableAmount/balanceAmount。其中receivableAmount(应收总额)为新增字段。 - 删除顶层字段:
discounts[]、surcharges[]、orderAmount、surchargeAmount、discountAmount、balanceAmount(金额已并入 basic;优惠/附加费列表下线)。 - 行程
itinerary改嵌套带价:原顶层nodes[]删除,节点改挂在days[].nodes[]下,并新增单价/数量/小计/本日合计。
出参 basic(OrderBasicVO)
| 字段 | 类型 | 说明 |
|---|---|---|
orderNo |
String | 订单号(只读)🆕 |
productName |
String | 产品名(快照,只读)🆕 |
teamNo |
String | 团号(订金支付后生成,未支付为 null,只读)🆕 |
productType |
String | 订单类型 CORE/ROUTE/CUSTOM/GROUP(只读)🆕 |
customerName |
String | 客户姓名(脱敏) |
customerPhone |
String | 客户手机(脱敏) |
emergencyContact |
String | 紧急联系人 |
customerRemark |
String | 客户备注 |
consultantRemark |
String | 顾问备注(内部) |
tags |
String[] | 订单标签 |
adultCount / childCount / youngChildCount / babyCount |
Integer | 成人/儿童/幼童/婴儿人数 |
orderAmount |
String(金额) | 订单基价(由顶层迁入)🔁 |
surchargeAmount |
String(金额) | 已有附加费合计(由顶层迁入)🔁 |
discountAmount |
String(金额) | 已有优惠合计(由顶层迁入)🔁 |
receivableAmount |
String(金额) | 应收总额 = 基价+附加费−优惠,≥0,取消单为 0 🆕 |
balanceAmount |
String(金额) | 待付尾款 = 应收−净已付,≥0,取消单为 0(由顶层迁入)🔁 |
金额字段均序列化为字符串(防 JS 精度丢失)。
出参 itinerary(ItineraryEditVO,嵌套带价)
| 路径 | 字段 | 类型 | 说明 |
|---|---|---|---|
| days[] | id/dayNumber/dayDate/theme |
- | 行程天信息 |
| days[] | nodes[] |
数组 | 当天节点(已过滤 HOTEL 节点)🆕 |
| days[] | dayTotal |
金额 | 本日合计 = Σ节点 subtotal,后端派生只读 🆕 |
| days[].nodes[] | id/dayId/nodeType/title/startTime/sortOrder |
- | 节点信息 |
| days[].nodes[] | unitPrice |
金额 | 单价(叙事展示;非 SCENIC 节点当前为 0)🆕 |
| days[].nodes[] | quantity |
Integer | 数量(默认 1)🆕 |
| days[].nodes[] | subtotal |
金额 | 小计 = unitPrice×quantity,后端派生只读 🆕 |
⚠️ 原顶层
itinerary.nodes[]已删除,全部迁入days[].nodes[]。 其余子域travelers/schedule/hotelRequirement/hotelDayDefaults/vehicleRequirement/lockedDays/editableTabLocksHint不变。
snapshot 出参示例(节选)
{
"code": 200,
"data": {
"basic": {
"orderNo": "HL202608010001",
"productName": "长白山深度5日游",
"teamNo": "GB202608001",
"productType": "CORE",
"customerName": "张*",
"adultCount": 4,
"orderAmount": "12000.00",
"surchargeAmount": "800.00",
"discountAmount": "200.00",
"receivableAmount": "12600.00",
"balanceAmount": "3000.00"
},
"itinerary": {
"days": [
{
"id": "1001", "dayNumber": 1, "dayDate": "2026-08-01", "theme": "天池徒步",
"nodes": [
{ "id": "2001", "nodeType": "SCENIC", "title": "长白山天池门票", "unitPrice": "128.00", "quantity": 1, "subtotal": "128.00" },
{ "id": "2002", "nodeType": "RESTAURANT", "title": "午餐", "unitPrice": "0", "quantity": 1, "subtotal": "0" }
],
"dayTotal": "128.00"
}
]
}
}
}
二、POST /v3/admin/order/{id}/adjustment/submit(入参 + 出参重制)
入参 AdjustmentSubmitReqVO
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
updates |
对象 | 是 | 各子域改动(按需填,未改置 null,但不能全 null) |
⚠️ 删除入参字段:
editReason(原必填)、tabLocks、confirmDiffHash。这三个一律不再传。
updates(AdjustmentUpdatesVO)—— 现仅 5 个子域
| 子域 | 类型 | 说明 |
|---|---|---|
travelers |
对象 | 出行人增删改:add[] / update[](含 id)/ remove[](id 列表) |
schedule |
对象 | 改期:departDate(新出发日 yyyy-MM-dd,本子域存在时必填,不可同原值) |
itinerary |
对象 | 行程:days[].nodes[](见下) |
hotelRequirement |
对象 | 房需求完整新版本:totalRoomCount/roomTypeSummary/specialTags[]/remark/days[] |
vehicleRequirement |
对象 | 车需求完整新版本:vehicleType/requiredSeats/remark/fleet[] |
⚠️ 删除子域:
basic(订单基础信息不再在调整弹窗修改)、feeChanges(手动加优惠/附加费下线)。
updates.itinerary 行程入参
| 路径 | 字段 | 类型 | 说明 |
|---|---|---|---|
| days[] | id/dayNumber |
- | 定位天;days 数量比现有多/少 → 后端差量增/减天 |
| days[].nodes[] | id |
Long | 定位要改的节点;为 null 视为新建(本期不支持,忽略) |
| days[].nodes[] | unitPrice / quantity |
- | 传了即改单价/数量(patch,不传不动) |
| days[].nodes[] | deleted |
Boolean | true=删除该节点 |
出参 AdjustmentSubmitRespVO(精简)
| 字段 | 类型 | 说明 |
|---|---|---|
success |
Boolean | 提交是否成功 |
⚠️ 出参从原 15 字段精简为仅
success。删除:appliedScopes/affectedRows/newHotelRequirementId/newHotelVersion/newVehicleRequirementId/newVehicleVersion/assignmentDeletedCount/statusLogId/changedDims/affectedDays/priceDelta/newDepartDate/newReturnDate/newFlowStatus。 失败时统一走全局异常:HTTP 200 +Result{code: 587xxx, message: "..."},前端按已有错误码机制读code/message。
submit 入参示例
{
"updates": {
"schedule": { "departDate": "2026-09-01" },
"itinerary": {
"days": [
{ "id": "1001", "dayNumber": 1, "nodes": [
{ "id": "2001", "unitPrice": "150.00", "quantity": 2 },
{ "id": "2003", "deleted": true }
]}
]
},
"travelers": { "remove": [70001005] }
}
}
submit 成功出参示例
{ "code": 200, "message": "success", "data": { "success": true } }
submit 失败出参示例(如:减员致有效总额低于已付)
{ "code": 587032, "message": "调整后总额低于已支付金额,不允许本次调整", "data": null }
三、错误码(submit 失败可能返回,前端按 code/message 展示)
| code | message | 含义 |
|---|---|---|
| 587002 | 订单已是终态,不可调整 | 订单 COMPLETED/CANCELLED 不可调整 |
| 587012 | updates 所有子领域均为空,无实际修改 | 未提交任何子域 |
| 587032 | 调整后总额低于已支付金额,不允许本次调整 | 防超付 |
| 587034 | 已出行,出行人不可调整 | 出行中改出行人被拦 |
| 587035 | 行程已确认,出发日期不可修改 | 改期窗口已关 |
| 587036 | 团期子订单不支持通过调整弹窗增删出行人,请前往团期管理台操作 | 团期出行人增删拦截 |
注:上表为常见项,完整错误码以后端 IErrorCode 段位为准;前端只需读
code/message。
四、业务边界 / 注意
- 团期(GROUP)订单不能在调整弹窗改人数:团期增删出行人被拦截,且基础信息子域已删,故团期人数变更不在本弹窗。非团期订单通过增减出行人(
travelers)改人数。 - 行程单价为叙事展示价,不进结算、不影响订单应付总额(改单价不触发算价)。
- HOTEL 节点不在
itinerary.days[].nodes[]出现(配房默认值另走hotelDayDefaults)。 - 人数/天数/行程改动触发的自动价差仍会写入订单加费/优惠(后端处理,前端无需关心)。
五、影响评估 / 前端改造点
- snapshot:金额与订单号/产品名/团号读取改从
data.basic.*(原顶层金额字段已无);不再渲染discounts/surcharges列表。 - snapshot:行程 tab 改读
itinerary.days[].nodes[](含单价/数量/小计/本日合计),原顶层itinerary.nodes[]不存在。 - submit:请求体去掉
editReason/tabLocks/confirmDiffHash/updates.basic/updates.feeChanges;行程改提交days[].nodes[]。 - submit:响应只读
data.success(其余字段已删);失败读code/message。
六、关联
- Issue:#4488(行程 tab 定价化)/ #4498(应收总额)/ #4502(金额挪 basic + basic 恒返 + 身份字段)/ #4509(submit 删 editReason/tabLocks)/ #4516(submit 删 confirmDiffHash/basic/feeChanges + 出参精简)
- PR:#4497 / #4500 / #4504 / #4521
- 负责人:腰苏图(yst)