文件
hl-api-changelog/changelogs-v2/2026-09/13_7439_dayNumber取值域放宽-不再截断接送机服务日-修改接口-管理后台.md
T
2026-09-14 10:22:59 +08:00

11 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, generated
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 generated
hl-changelog/v2 7439 终止退款·dayNumber 字段取值域放宽,不再截断接送机窗外服务日 admin wx(GIT) 修改接口 deployed verified verified mmg e03170eaf52e44858ec04cfa5a41fa252a34ba50 2026-09-14 后端已部署 8c699658a,接收端应对 dayNumber ≤0 或 > 行程天数的情况做边界处理,避免越界或错误渲染【前端 2026-09-14 交付 verified】MidTripRefundModal 接送机窗外服务日边界处理:≤0 标「接」、>tripDays 标「送」并按 departDate+(dayNumber-1) 还原真实日期,行程内恒 Day;day 格判断改 != null(0 接机不落图标分支);车辆组「含接送机日」提示;terminateRefund.js 适配器零改动(本就透传不截断不索引);保险行 null 不变。spec 13/13+terminateRefund 14/14,checkpoint 7 项全绿。ref=e03170ea。 2026-09-13 dev-v3 2026-09-13T22:26:36+08:00

终止退款·dayNumber 字段取值域放宽

服务: hl-order-service-v3 PR: #7639 Issue: #7439 日期: 2026-09-13 影响范围: 管理后台终止行程退款预览接口,用车行的天序号编码

⚠️ 关键变化

接送机服务日现已正常返回,不再被截断丢弃。

  1. 终止退款预览接口出参中,用车行的 dayNumber 不再保证落在 [1, 行程天数] 内
  2. 接送机场景(提前一天接机 → dayNumber ≤ 0;返程后一天送机 → dayNumber > 行程天数)现已正常返回真实值
  3. 原先这类订单因服务日越界会被 581048 拒掉,现在正常预览返回
  4. 前端需对 dayNumber 做边界处理,避免用它直接索引"第几天"数组而越界;保险行 dayNumber 仍为 null(无变化)

一、背景

接送机服务是订单行程的边界服务:出发前接机服务日早于出发日,返程后送机服务日晚于行程结束日。 原先后端按 [1, 行程天数] 硬截断这类服务日,致使真实服务日信息丢失。

现改为:dayNumber 是服务日相对出发日的 1-based 编码,其逆运算 serviceDate = departDate + (dayNumber - 1) 可精确还原服务日。 前端回传释放行时会用这个值,所以后端不再截断、不置空,由前端按业务场景判断是否显示/处理。

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 终止行程·退款预览 POST /{id}/terminate/refund-preview 响应字段取值域放宽 用车行 dayNumber 不再截断

三、接口详情

1. 终止行程·退款预览 POST /{id}/terminate/refund-preview

VO: 没有请求体 → OrderTerminateRefundPreviewRespVO

使用场景

管理后台出行中订单详情页,用户点击「终止行程」时调用,预览该订单所有资源(住宿/门票/用车/保险/备品等)的退款金额,供用户和管理员确认。

入参

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

出参 Result<OrderTerminateRefundPreviewRespVO>

字段 类型 说明
data.orderNo String 订单号
data.tripDays Integer 行程天数
data.departDate LocalDate 出发日(ISO 8601)
data.days List 按天分组的退款资源(含已用/未用统计)
data.days[].dayNumber Integer 第几天(1-based,接送机可能 ≤0 或 > tripDays)
data.days[].items List 该天的资源列表
data.days[].items[].dayNumber Integer 资源对应的天序号 ⚠️ 本次变更重点
data.days[].items[].categoryCode String 资源分类(ROOM/TICKET/SERVICE/VEHICLE/INSURANCE/SUPPLIES)
data.days[].items[].name String 资源名称(酒店名/车型/景点等)
data.days[].items[].dealPrice BigDecimal 单位价格(住宿=元/间·晚;用车=日费)
data.days[].items[].quantity Integer 数量(住宿=间数;用车=车辆数)
data.days[].items[].totalAmount BigDecimal 行合计 = dealPrice × quantity
data.days[].items[].locked Boolean 是否锁定不退(保险等 = true)

请求示例

POST /v3/admin/order/123456789/terminate/refund-preview

响应示例

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": {
    "orderNo": "ORD-2026090100001",
    "tripDays": 3,
    "departDate": "2026-09-15",
    "days": [
      {
        "dayNumber": 0,
        "items": [
          {
            "lineKey": "VEHICLE_ASSIGNMENT:666:1",
            "categoryCode": "VEHICLE",
            "categoryName": "用车",
            "sourceType": "VEHICLE_ASSIGNMENT",
            "sourceId": "666",
            "name": "丰田 RAV4",
            "dayNumber": 0,
            "dealPrice": "380.00",
            "quantity": 1,
            "totalAmount": "380.00",
            "defaultUsed": false,
            "locked": false
          }
        ]
      }
    ]
  }
}

空数据 / 降级响应

{
  "code": 404,
  "message": "订单不存在或不在出行中状态",
  "success": false,
  "data": null
}

错误响应

{
  "code": 581048,
  "message": "终止行程:本地车辆费用服务日与订单行程不一致",
  "success": false,
  "data": null
}

业务边界

  • 鉴权: OrderViewGuard 排除房务角色;其他所有角色(产品/运营/财务等)均可调用
  • 车辆已用状态: 按 Order 当前 DAILY_V3 的 serviceDate 与实际终止日对比,前端显示仅供参考,提交时后端权威重算
  • 服务日合法性: 原先 dayNumber < 1 或 > tripDays 时会抛 581048;现已移到 OrderVehicleDailyFeeSnapshotProvider 按车型分流验证
  • 保险: 始终 locked=true,dayNumber=null,不可退

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

此接口返回的 dayNumber 仅是原始编码,不保证在行程窗内。消费方必须按以下流程处理:

dayNumber 情况 含义 前端处理建议
≤ 0 接送机:出发前服务 标记为"接机";不索引"第几天"数组
1 ~ tripDays 行程内 正常按"第 dayNumber 天"渲染
> tripDays 接送机:返程后服务 标记为"送机";不索引"第几天"数组

五、数据库行为

此接口为读接口,无数据库写操作。返回的是现存订单快照中的车辆事实编码。


六、边界行为

  • 未登录 → 401(网关拦截)
  • 无权限(房务角色) → 403(OrderViewGuard 拦截)
  • 订单不存在 → 404
  • 订单非出行中 → 404
  • 下游数据缺失 → 返 [] 对应项,不 500(降级处理)
  • 老数据兼容 → 旧字段为 null,不异常

六.6、修改前后对比

字段级对比

字段 改前 改后
dayNumber(用车) 强制落在 [1, tripDays];越界时异常拒绝(581048) 无约束;可以 ≤0 或 > tripDays;精确编码服务日

行为级对比

行为 改前 改后
接送机订单预览 被 581048 拒绝 正常返回,dayNumber 准确反映接送日期

六.7、影响评估

  • 是否破坏向后兼容: 是
  • 前端是否必须同步上线: 是
  • 前端 workaround 清理点: 原先对接送机订单做的排除逻辑可撤销;dayNumber 直接索引改为先检查边界

七、不影响范围

  • 仅影响: 管理后台终止行程退款预览接口中用车行
  • 零影响:
    • 订单详情/订单列表接口
    • 住宿/门票/保险/备品的 dayNumber
    • 订单创建/修改接口

八、测试环境已验证

部署:hl-order-service-v3 @ dev-v3 / 8c699658a(PR #7639 的 merge commit), 两实例 8086 / 8186 滚动完成并 UP,Nacos(namespaceId=test)两实例 healthy:true。 取证前后各查一次 deploy-status.sh,commit 均为 8c699658a、BEHIND=0/N ⇒ 取证期间无人换分支。

实测请求(路径取自源码 OrderController.java:203,不是照文档猜的):

POST https://api.test.1814.love:9443/v3/admin/order/8880000000000000001/terminate/refund-preview
Authorization: Bearer <token>

实测响应:HTTP 200,code=200,success=true。订单 tripDays=3、departDate=2026-10-01。 refundLines 里六行的 dayNumber 实测值:

行 类别 服务日 dayNumber 实测 说明
ceB00001 用车(接机) 2026-09-30(出发前1 天) 0 🔴 ≤0,改动前会被 581048 拒掉
ceA00001 用车 2026-10-01 1 行程内
ceA00002 用车 2026-10-02 2 行程内
ceA00003 用车 2026-10-03 3 行程内
ceB00002 用车(送机) 2026-10-05(返程后2 天) 5 🔴 > tripDays=3,改动前会被 581048 拒掉
旅行险 保险 — null 保险行仍为 null,此条未变

⇒ 本次改动实际放行的行为已被真实触发并观测到:同一响应里同时出现 0 与 5, 不是全部落在 [1, 3] 内;581048 未出现。

取证用数据说明(供排查时识别,勿动):该订单为本次验证专门新建的独占单 (order_id=8880000000000000001 / order_no=HL88800000000001),未改动任何既有订单; order_main / order_vehicle_requirement / order_vehicle_assignment / insurance_order 的备注字段均带 #7439 AC-27 标记,可直接检索。

本节的已知边界(不外推):

  • 未做前端页面联调——本节只验到接口层。
  • 未调用有副作用的终止提交接口(processTermination),只验了只读的 refund-preview。
  • 该测试单由 SQL 直插创建(DAILY_V3 派车快照涉十余项耦合 CHECK,走真实抢单/派车链路超出本次范围), 未经"定制→支付→出发"业务流程产出。

九、相关历史 PR

PR Issue 说明 是否仍有效
本 PR #7639 #7439 放宽 dayNumber 取值域 ✅ 最新

十、相关文档

  • 端点定义: hl-order-service-v3/.../controller/admin/OrderController.java:203
  • 改动点: hl-order-service-v3/.../settlement/service/TerminateRefundService.java 的 vehicleDayNumber
  • 字段定义: hl-order-service-v3/.../controller/admin/vo/TerminateRefundItemVO.java 的 dayNumber
  • 鉴权: com.hulalv.order.core.guard.OrderViewGuard#assertNotHouseRole(房务/组长 → 581045)

关联 / 联系人

链接

联系人

  • 后端负责人: @wx