hl-api-changelog/changelogs-v2/2026-07/28_5295_Step3聚合车辆费用-修改接口-管理后台.md
yaosutu 86e4be1cf0
一些检查失败了
changelog-filename-gate / validate (push) Failing after 2s
通知前端 Step3 聚合车辆费用
2026-07-28 09:16:16 +08:00

23 KiB

schema, ticket, title, consumer, 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 change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 5295 Step3 聚合车辆费用 admin 修改接口 merged not_required pending 2026-07-27 GET/PUT Step3 响应新增 vehicleFees;旧车辆费用 GET/confirm 保留兼容,新页面应停止单独确认动作 2026-07-28 dev-v3

【修改接口·管理后台】Step3 聚合车辆费用 (#5295)

PR: #5297 | 更新时间: 2026-07-28 00:00

1. 接口背景

核单 Step3 页面原来需要分别读取人员费用和车辆总车费,并且车辆费用还有额外确认动作。本次把车辆费用聚合到 Step3 查询和保存响应里:进入 Step3 时同屏拿到人员费用与车辆费用;保存人员费用时,同一次保存会校验车辆费用是否满足核单条件,满足时随响应返回已冻结的车辆费用块。

2. 变更清单

# 接口 方法 路径 变更类型 说明
1 Step 3 查询人员费用核单明细 GET /v3/admin/order/{orderId}/settlement/step3 修改接口 响应新增 vehicleFees,包含车辆费用顶层状态、总金额和逐日明细
2 Step 3 录人员费用核单明细 PUT /v3/admin/order/{orderId}/settlement/step3 修改接口 保存人员费用时校验车辆费用;满足条件时返回冻结后的 vehicleFees
3 查询核单车辆总车费 GET /v3/admin/order/{orderId}/settlement/vehicle-fees 保留兼容 旧接口仍可用;新 Step3 页面应优先读取 Step3 响应内的 vehicleFees
4 确认并冻结核单车辆总车费 POST /v3/admin/order/{orderId}/settlement/vehicle-fees/confirm 保留兼容 旧接口仍可用;新 Step3 页面应移除单独确认车辆费用的动作

3. 接口详情

3.1 GET Step 3 查询人员费用核单明细

  • 方法 + 路径: GET /v3/admin/order/{orderId}/settlement/step3
  • 接口名: Step 3 查询人员费用核单明细
  • 使用场景: 进入核单 Step3 页面时调用,展示人员费用表和车辆费用块。
  • 认证: 需要管理后台登录态;无权限或未登录按统一鉴权错误返回。
  • 幂等性: 幂等,只读查询。
  • 限流: 无接口级特殊限流。
  • 响应类型: Result<SettlementStaffFeesSaveRespVO>

3.2 PUT Step 3 录人员费用核单明细

  • 方法 + 路径: PUT /v3/admin/order/{orderId}/settlement/step3
  • 接口名: Step 3 录人员费用核单明细
  • 使用场景: 用户保存 Step3 人员费用时调用。保存成功后,响应内同时回传人员费用结果和车辆费用块。
  • 认证: 需要管理后台登录态和核单资金写权限。
  • 幂等性: 同一 items 内容重复提交,人员费用结果保持一致;车辆费用已冻结后再次保存仍返回冻结块。
  • 限流: 无接口级特殊限流。
  • 响应类型: Result<SettlementStaffFeesSaveRespVO>

4. 接口入参

4.1 路径参数 / Query 参数

字段 类型 必填 适用接口 说明
orderId Long/String GET、PUT 订单 ID,必须大于 0;JSON 示例中按字符串展示,避免大整数精度问题

GET 无 Query 参数,无请求体。

4.2 PUT 请求体字段

字段 类型 必填 说明 校验规则
items Array 人员费用行数组,全量替换语义 数组字段必须存在;数组元素按下表校验
items[].id Long/String 已存在行 ID;为空表示新增 已有行更新时传
items[].staffRole String 人员角色 仅允许 LEADERDRIVERGUIDEPHOTOGRAPHEROTHER
items[].staffId Long/String 关联人员分配 ID 多人聚合行可为空
items[].detail Object staffRole 区分的明细 JSON 不能省略;各角色结构见下表
items[].reimburse Decimal/String 小额报销金额 必须大于等于 0;为空按 0 处理
items[].paymentMethod String 统一付款类型 仅允许 CASH_PAIDCOMPANY_PAIDSIGNED
items[].voucherUrls Array 人员费用凭证 URL 数组 最多 9 个;每个元素必须是 http/https URL,单个最多 1024 字符
items[].settlementConfirmStatus String 人员费用核单确认状态 仅允许 UNCONFIRMEDCONFIRMED
items[].settleStatus String 辅助人员结算状态 仅允许 PENDINGCOMPLETED;主报账人行可为空
items[].settledDate String(date) 辅助人员结算日期 格式 YYYY-MM-DD
items[].transferRef String 条件必填 辅助人员结算转账流水号 settleStatus=COMPLETED 时必填,最多 128 字符
items[].remark String 备注 最多 500 字符

4.3 detail 字段结构

staffRole detail 结构 必填说明
DRIVER { "days": [{ "service_date": "2026-07-29", "vehicle_brief": "蒙A****", "daily_fee": "700.00", "is_used": true, "note": "" }], "extra_cost": "0.00", "extra_breakdown": [] } days[] 必须存在;每个元素必须包含 service_datedaily_fee
GUIDE { "persons": [{ "name": "导游A", "days": 3, "per_day": "300.00", "note": "" }] } persons[] 必须存在;每个元素必须包含 namedaysper_day
PHOTOGRAPHER { "persons": [{ "name": "摄影A", "days": 3, "per_day": "400.00", "note": "" }] } persons[] 必须存在;每个元素必须包含 namedaysper_day
LEADER { "days": 3, "per_day": "500.00" } daysper_day 必须存在
OTHER { "items": [{ "name": "其他人员费用", "amount": "100.00", "note": "" }] } items[] 用于其他人员费用明细

5. 出参字段

5.1 统一响应包装

字段 类型 说明
code Integer 业务状态码;200 表示成功
data Object/null 成功时为 SettlementStaffFeesSaveRespVO;失败时通常为 null
message String 响应消息

5.2 data 字段

字段 类型 说明
addedIds Array PUT 成功时新增的人员费用行 ID;GET 可为空数组
updatedIds Array PUT 成功时更新的人员费用行 ID;GET 可为空数组
deletedIds Array PUT 成功时软删的人员费用行 ID;GET 可为空数组
totalActualCost String(decimal) 人员费用实际成本合计
items Array 人员费用明细行
vehicleFees Object 本次新增:车辆费用块;无有效车辆需求时仍返回对象,items=[]、金额为 0.00frozen=false

5.3 data.items[] 人员费用明细

字段 类型 说明
id String 人员费用行 ID
staffRole String 人员角色:LEADERDRIVERGUIDEPHOTOGRAPHEROTHER
staffId String/null 关联人员分配 ID
staffName String/null 人员姓名快照
totalPlannedCost String(decimal) 计划成本
totalActualCost String(decimal) 实际成本
detail Object staffRole 区分的明细 JSON
reimburse String(decimal) 小额报销金额
paymentMethod String/null 人员费用付款类型:CASH_PAIDCOMPANY_PAIDSIGNED
voucherUrls Array 凭证 URL 数组
settlementConfirmStatus String 核单确认状态:UNCONFIRMEDCONFIRMED
settleStatus String/null 辅助人员结算状态:PENDINGCOMPLETED;主报账人行可为空
settledDate String(date)/null 辅助人员结算日期
transferRef String/null 辅助人员结算转账流水号
isPrimaryReporter Boolean 是否主报账人
remark String/null 备注

5.4 data.vehicleFees 车辆费用顶层

字段 类型 说明
orderId String 订单 ID
frozen Boolean 车辆费用是否已冻结;PUT 成功冻结后为 true
requirementId String/null 当前车辆需求 ID;无有效车辆需求时为 null
settlementReady Boolean 车辆费用是否满足核单条件;为 false 时 PUT 可能返回 584101
totalAmount String(decimal) 车辆费用总金额
totalVehicleFee String(decimal) 车辆费用总金额,兼容旧字段名;前端展示可读取该字段
items Array 车辆费用逐日明细;无有效车辆需求时为空数组

5.5 data.vehicleFees.items[] 车辆费用明细

字段 类型 说明
sourceDetailId String/null 逐日费用来源明细 ID;冻结后的旧数据可能为空
serviceDate String(date)/null 逐日服务日期
assignmentGroupId String/null 派车组 ID;逐日来源可为空
assignmentSlotId String/null 派车明细 ID;逐日来源可为空
vehicleId String/null 车辆 ID
vehiclePlate String/null 车牌号
vehicleModelId String/null 车型 ID
vehicleModelName String/null 车型名称
vehicleModel String/null 车型展示文本,兼容旧字段
driverId String/null 司机 ID
driverName String/null 司机姓名
startDate String(date)/null 费用服务开始日期;逐日费用通常等于 serviceDate
endDate String(date)/null 费用服务结束日期;逐日费用通常等于 serviceDate
chargeableServiceDates Array<String(date)> 计费服务日期列表
freeServiceDates Array<String(date)> 免费服务日期列表
vehicleFeeWaiverReason String/null 免车费原因
dailyPrice String(decimal) 当日车费
paymentTypeCode String 车辆费用付款类型编码:CASH_PAIDSIGNEDCOMPANY_PAID
paymentTypeName String/null 车辆费用付款类型名称
amount String(decimal) 本条核单金额
autoVehicleFeeTotal String(decimal) 自动计算车辆费用金额
autoVehicleFeeComplete Boolean 自动计算金额是否完整
vehicleFeeTotal String(decimal) 本条车辆费用金额,兼容旧字段名
vehicleFeeSource String 费用来源:AUTOMANUAL
vehicleFeeAdjustmentReason String/null 手工调整原因
vehicleFeeAdjustedBy String/null 手工调整人 ID
vehicleFeeAdjustedAt String(datetime)/null 手工调整时间
settlementReady Boolean 本条车辆费用是否满足核单条件

6. 枚举 / 数据字典

6.1 paymentTypeCode(车辆费用付款类型)

所属字段: data.vehicleFees.items[].paymentTypeCode | 类型: String | 必填: 是

中文 说明
CASH_PAID 现付 车辆费用已由现场现金或等价方式支付
SIGNED 签单 车辆费用采用签单方式结算
COMPANY_PAID 公司支付 车辆费用由公司统一支付

6.2 paymentMethod(人员费用付款类型)

所属字段: items[].paymentMethoddata.items[].paymentMethod | 类型: String | 必填: 否

中文 说明
CASH_PAID 现付 人员费用已现场支付
COMPANY_PAID 公司支付 人员费用由公司支付
SIGNED 签单 人员费用采用签单方式

7. 错误码

code 含义 触发场景
584100 车辆总车费暂时不可用 GET 或 PUT Step3 读取车辆费用失败,或车辆费用响应与当前订单不匹配
584101 存在未完结派车或未确认车辆总车费,暂不能核单 PUT Step3 保存时,当前车辆费用 settlementReady=false,或任一车辆费用明细未满足冻结条件
584102 当前用车需求没有可核单的车辆总车费 PUT Step3 保存时存在有效车辆需求,但车辆费用明细为空

8. 示例

8.1 典型成功GET Step3 返回 9 行车辆费用

请求:

GET /v3/admin/order/2079454953641836546/settlement/step3
Authorization: Bearer <token>

响应:

{
  "code": 200,
  "message": "success",
  "data": {
    "addedIds": [],
    "updatedIds": [],
    "deletedIds": [],
    "totalActualCost": "3600.00",
    "items": [
      {
        "id": "9300000000001",
        "staffRole": "DRIVER",
        "staffId": "6800001001",
        "staffName": "司机A",
        "totalPlannedCost": "2100.00",
        "totalActualCost": "2100.00",
        "detail": {
          "days": [
            {
              "service_date": "2026-07-29",
              "vehicle_brief": "蒙A12345",
              "daily_fee": "700.00",
              "is_used": true,
              "note": ""
            }
          ],
          "extra_cost": "0.00",
          "extra_breakdown": []
        },
        "reimburse": "0.00",
        "paymentMethod": "COMPANY_PAID",
        "voucherUrls": [],
        "settlementConfirmStatus": "UNCONFIRMED",
        "settleStatus": "PENDING",
        "settledDate": null,
        "transferRef": null,
        "isPrimaryReporter": false,
        "remark": ""
      }
    ],
    "vehicleFees": {
      "orderId": "2079454953641836546",
      "frozen": false,
      "requirementId": "2079000000000000001",
      "settlementReady": true,
      "totalAmount": "6780.00",
      "totalVehicleFee": "6780.00",
      "items": [
        {
          "sourceDetailId": "2080000000000000001",
          "serviceDate": "2026-07-29",
          "assignmentGroupId": null,
          "assignmentSlotId": null,
          "vehicleId": "300000000000000001",
          "vehiclePlate": "蒙A12345",
          "vehicleModelId": "400000000000000001",
          "vehicleModelName": "商务车",
          "vehicleModel": "商务车",
          "driverId": "500000000000000001",
          "driverName": "宝音德力格尔",
          "startDate": "2026-07-29",
          "endDate": "2026-07-29",
          "chargeableServiceDates": ["2026-07-29"],
          "freeServiceDates": [],
          "vehicleFeeWaiverReason": null,
          "dailyPrice": "700.00",
          "paymentTypeCode": "COMPANY_PAID",
          "paymentTypeName": "公司支付",
          "amount": "700.00",
          "autoVehicleFeeTotal": "700.00",
          "autoVehicleFeeComplete": true,
          "vehicleFeeTotal": "700.00",
          "vehicleFeeSource": "AUTO",
          "vehicleFeeAdjustmentReason": null,
          "vehicleFeeAdjustedBy": null,
          "vehicleFeeAdjustedAt": null,
          "settlementReady": true
        },
        {
          "sourceDetailId": "2080000000000000002",
          "serviceDate": "2026-07-29",
          "assignmentGroupId": null,
          "assignmentSlotId": null,
          "vehicleId": "300000000000000002",
          "vehiclePlate": "蒙A23456",
          "vehicleModelId": "400000000000000002",
          "vehicleModelName": "越野车",
          "vehicleModel": "越野车",
          "driverId": "500000000000000002",
          "driverName": "阿拉坦",
          "startDate": "2026-07-29",
          "endDate": "2026-07-29",
          "chargeableServiceDates": ["2026-07-29"],
          "freeServiceDates": [],
          "vehicleFeeWaiverReason": null,
          "dailyPrice": "700.00",
          "paymentTypeCode": "SIGNED",
          "paymentTypeName": "签单",
          "amount": "700.00",
          "autoVehicleFeeTotal": "700.00",
          "autoVehicleFeeComplete": true,
          "vehicleFeeTotal": "700.00",
          "vehicleFeeSource": "AUTO",
          "vehicleFeeAdjustmentReason": null,
          "vehicleFeeAdjustedBy": null,
          "vehicleFeeAdjustedAt": null,
          "settlementReady": true
        },
        {
          "sourceDetailId": "2080000000000000003",
          "serviceDate": "2026-07-29",
          "assignmentGroupId": null,
          "assignmentSlotId": null,
          "vehicleId": "300000000000000003",
          "vehiclePlate": "蒙A34567",
          "vehicleModelId": "400000000000000003",
          "vehicleModelName": "中巴",
          "vehicleModel": "中巴",
          "driverId": "500000000000000003",
          "driverName": "巴雅尔",
          "startDate": "2026-07-29",
          "endDate": "2026-07-29",
          "chargeableServiceDates": ["2026-07-29"],
          "freeServiceDates": [],
          "vehicleFeeWaiverReason": null,
          "dailyPrice": "860.00",
          "paymentTypeCode": "CASH_PAID",
          "paymentTypeName": "现付",
          "amount": "860.00",
          "autoVehicleFeeTotal": "860.00",
          "autoVehicleFeeComplete": true,
          "vehicleFeeTotal": "860.00",
          "vehicleFeeSource": "AUTO",
          "vehicleFeeAdjustmentReason": null,
          "vehicleFeeAdjustedBy": null,
          "vehicleFeeAdjustedAt": null,
          "settlementReady": true
        }
      ]
    }
  }
}

说明:上例只展开 2026-07-29 的 3 行;同一订单还可能继续返回 2026-07-30、2026-07-31 的逐日车辆费用。验收样例中 3 天 x 3 司机共 9 行,合计 6780.00

8.2 边界情况:无有效车辆需求时返回空未冻结块

请求:

GET /v3/admin/order/2079576729147338754/settlement/step3
Authorization: Bearer <token>

响应:

{
  "code": 200,
  "message": "success",
  "data": {
    "addedIds": [],
    "updatedIds": [],
    "deletedIds": [],
    "totalActualCost": "0.00",
    "items": [],
    "vehicleFees": {
      "orderId": "2079576729147338754",
      "frozen": false,
      "requirementId": null,
      "settlementReady": false,
      "totalAmount": "0.00",
      "totalVehicleFee": "0.00",
      "items": []
    }
  }
}

8.3 业务失败PUT 时车辆费用未满足核单条件

请求:

PUT /v3/admin/order/2079454953641836546/settlement/step3
Authorization: Bearer <token>
Content-Type: application/json
{
  "items": [
    {
      "id": "9300000000001",
      "staffRole": "DRIVER",
      "staffId": "6800001001",
      "detail": {
        "days": [
          {
            "service_date": "2026-07-29",
            "vehicle_brief": "蒙A12345",
            "daily_fee": "700.00",
            "is_used": true,
            "note": ""
          }
        ],
        "extra_cost": "0.00",
        "extra_breakdown": []
      },
      "reimburse": "0.00",
      "paymentMethod": "COMPANY_PAID",
      "voucherUrls": [],
      "settlementConfirmStatus": "UNCONFIRMED",
      "settleStatus": "PENDING",
      "settledDate": null,
      "transferRef": null,
      "remark": ""
    }
  ]
}

响应:

{
  "code": 584101,
  "message": "存在未完结派车或未确认车辆总车费,暂不能核单",
  "data": null
}

9. 业务边界

  • 适用场景: 核单 Step3 页面查询和保存;页面需要同时展示人员费用与车辆费用时,直接使用 Step3 响应。
  • 车辆费用可为空的场景: 订单没有有效车辆需求时,GET Step3 返回 vehicleFees.items=[]frozen=falsesettlementReady=false、金额为 0.00
  • PUT 保存门禁: 存在有效车辆需求时,PUT Step3 会校验车辆费用是否满足核单条件;不满足时返回 584101,本次人员费用保存不视为成功。
  • 空明细门禁: 存在有效车辆需求但没有可核单车辆费用明细时,PUT Step3 返回 584102
  • 已冻结场景: 车辆费用已冻结后,GET/PUT Step3 都返回冻结后的 vehicleFees

10. 修改前后对比

10.1 字段级对比

字段 改前 改后
data.vehicleFees GET/PUT Step3 不返回 GET/PUT Step3 均返回车辆费用块
data.vehicleFees.frozen 返回车辆费用是否冻结
data.vehicleFees.requirementId 返回当前车辆需求 ID;无有效车辆需求时为 null
data.vehicleFees.settlementReady 返回车辆费用是否满足核单条件
data.vehicleFees.totalAmount 返回车辆费用总金额
data.vehicleFees.totalVehicleFee 返回车辆费用总金额兼容字段
data.vehicleFees.items[] 返回逐日车辆费用明细
data.vehicleFees.items[].sourceDetailId 返回逐日费用来源明细 ID
data.vehicleFees.items[].serviceDate 返回逐日服务日期
data.vehicleFees.items[].dailyPrice 返回当日车费
data.vehicleFees.items[].paymentTypeCode 返回车辆费用付款类型编码
data.vehicleFees.items[].paymentTypeName 返回车辆费用付款类型名称
data.vehicleFees.items[].amount 返回本条核单金额
data.vehicleFees.items[].settlementReady 返回本条车辆费用是否满足核单条件

10.2 行为级对比

行为 改前 改后
进入 Step3 页面 需要单独读取人员费用和车辆费用 调用 GET Step3 即可拿到人员费用与车辆费用
保存 Step3 只保存人员费用 保存人员费用时同步校验车辆费用;满足条件时返回冻结后的车辆费用
车辆费用确认 前端可能单独调用 POST /settlement/vehicle-fees/confirm 新 Step3 页面应停止单独调用,移除额外确认动作
旧 GET 车辆费用 作为车辆费用主要读取入口 保留兼容;新 Step3 页面优先读 data.vehicleFees
无有效车辆需求 需要前端自行处理独立接口空态 GET Step3 内直接返回空未冻结 vehicleFees

11. 影响评估 / 回滚

11.1 影响评估

  • 是否破坏向后兼容: 否。Step3 响应新增 vehicleFees,旧字段保留;旧车辆费用 GET 和确认 POST 保留兼容。
  • 前端是否必须同步上线: 否,但建议管理后台 Step3 页面尽快切到 data.vehicleFees,并移除额外车辆费用确认动作。
  • 旧页面兼容: 继续调用旧 GET /v3/admin/order/{orderId}/settlement/vehicle-feesPOST /v3/admin/order/{orderId}/settlement/vehicle-fees/confirm 不会因本次变更直接失效。

11.2 回滚方案

  • 回滚后前端表现: 如果回滚到旧契约,GET/PUT Step3 不再包含 data.vehicleFees;前端需要保留对 vehicleFees 缺失的空值兼容。
  • 前端兼容建议: 读取 data.vehicleFees 前先判空;为空时可降级到旧车辆费用 GET。

12. 注意事项

  • 新 Step3 页面不要再单独调用 POST /v3/admin/order/{orderId}/settlement/vehicle-fees/confirm 作为额外确认按钮或保存后动作。
  • 新 Step3 页面读取车辆费用时优先使用 GET /v3/admin/order/{orderId}/settlement/step3 返回的 data.vehicleFees
  • paymentTypeCode 是车辆费用付款类型字段,枚举值为 CASH_PAIDSIGNEDCOMPANY_PAID;不要用人员费用的 paymentMethod 去覆盖车辆费用字段。
  • totalAmounttotalVehicleFee 都表示车辆费用总金额;为兼容旧页面,当前两者应按同一金额展示。
  • frozen=false 不等于接口失败;无有效车辆需求或车辆费用尚未满足核单条件时都可能返回未冻结块。

13. 关联 / 联系人

13.1 链接

13.2 联系人

  • 接口负责人: @yaosutu