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 |
是 |
人员角色 |
仅允许 LEADER、DRIVER、GUIDE、PHOTOGRAPHER、OTHER |
items[].staffId |
Long/String |
否 |
关联人员分配 ID |
多人聚合行可为空 |
items[].detail |
Object |
是 |
按 staffRole 区分的明细 JSON |
不能省略;各角色结构见下表 |
items[].reimburse |
Decimal/String |
否 |
小额报销金额 |
必须大于等于 0;为空按 0 处理 |
items[].paymentMethod |
String |
否 |
统一付款类型 |
仅允许 CASH_PAID、COMPANY_PAID、SIGNED |
items[].voucherUrls |
Array |
否 |
人员费用凭证 URL 数组 |
最多 9 个;每个元素必须是 http/https URL,单个最多 1024 字符 |
items[].settlementConfirmStatus |
String |
否 |
人员费用核单确认状态 |
仅允许 UNCONFIRMED、CONFIRMED |
items[].settleStatus |
String |
否 |
辅助人员结算状态 |
仅允许 PENDING、COMPLETED;主报账人行可为空 |
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_date、daily_fee |
GUIDE |
{ "persons": [{ "name": "导游A", "days": 3, "per_day": "300.00", "note": "" }] } |
persons[] 必须存在;每个元素必须包含 name、days、per_day |
PHOTOGRAPHER |
{ "persons": [{ "name": "摄影A", "days": 3, "per_day": "400.00", "note": "" }] } |
persons[] 必须存在;每个元素必须包含 name、days、per_day |
LEADER |
{ "days": 3, "per_day": "500.00" } |
days、per_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.00、frozen=false |
5.3 data.items[] 人员费用明细
| 字段 |
类型 |
说明 |
id |
String |
人员费用行 ID |
staffRole |
String |
人员角色:LEADER、DRIVER、GUIDE、PHOTOGRAPHER、OTHER |
staffId |
String/null |
关联人员分配 ID |
staffName |
String/null |
人员姓名快照 |
totalPlannedCost |
String(decimal) |
计划成本 |
totalActualCost |
String(decimal) |
实际成本 |
detail |
Object |
按 staffRole 区分的明细 JSON |
reimburse |
String(decimal) |
小额报销金额 |
paymentMethod |
String/null |
人员费用付款类型:CASH_PAID、COMPANY_PAID、SIGNED |
voucherUrls |
Array |
凭证 URL 数组 |
settlementConfirmStatus |
String |
核单确认状态:UNCONFIRMED、CONFIRMED |
settleStatus |
String/null |
辅助人员结算状态:PENDING、COMPLETED;主报账人行可为空 |
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_PAID、SIGNED、COMPANY_PAID |
paymentTypeName |
String/null |
车辆费用付款类型名称 |
amount |
String(decimal) |
本条核单金额 |
autoVehicleFeeTotal |
String(decimal) |
自动计算车辆费用金额 |
autoVehicleFeeComplete |
Boolean |
自动计算金额是否完整 |
vehicleFeeTotal |
String(decimal) |
本条车辆费用金额,兼容旧字段名 |
vehicleFeeSource |
String |
费用来源:AUTO 或 MANUAL |
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[].paymentMethod、data.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=false、settlementReady=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-fees 和 POST /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_PAID、SIGNED、COMPANY_PAID;不要用人员费用的 paymentMethod 去覆盖车辆费用字段。
totalAmount 与 totalVehicleFee 都表示车辆费用总金额;为兼容旧页面,当前两者应按同一金额展示。
frozen=false 不等于接口失败;无有效车辆需求或车辆费用尚未满足核单条件时都可能返回未冻结块。
13. 关联 / 联系人
13.1 链接
13.2 联系人