hl-api-changelog/changelogs-v2/2026-08/15_5969_核单车辆费用归其他支出-修改接口-管理后台.md
Mimingguang 5f6d86ea19
一些检查失败了
changelog-filename-gate / validate (push) Failing after 2s
docs(changelogs-v2): #5969 not_required(生产零改动,测试口径跟随固证)
2026-08-15 16:09:14 +08:00

16 KiB

schema, ticket, title, consumer, change_type, author, 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 author backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 5969 核单车辆费用归其他支出——VEHICLE 只留 Fleet 配车日租,5 类车辆费用并入 OTHER_EXPENSE admin 修改接口 yst deployed verified not_required mmg d3fc3cf6 2026-08-15 PR #5970 已合并 dev-v3merge commit 522179ecfe,测试服已验证实证单 HL20260811181352799油费 300 归其他支出块,用车块只剩 3 行 Fleet 日租 3000。破坏性变化单团核算表 vehicleLines 行删 expenseType/expenseTypeName/projectName/expenseDate 4 字段;FUEL/TOLL/PARKING/RENTAL/MAINTENANCE 5 类车辆费用行从 vehicleLines 迁到 otherExpenseLines;otherExpenseLines.expenseType 值域由 OTHER 扩为 6 类。仅出参/归属口径变化,无入参变化、无 DDL。 2026-08-15 dev-v3

【修改接口·管理后台】核单车辆费用归其他支出——VEHICLE 只留 Fleet 配车日租,5 类车辆费用并入 OTHER_EXPENSE#5969

1. 接口背景

单团核算表reports/group是管理后台订单核单页查看整团收入、成本、毛利全貌的只读报表,成本按 8 分类逐项展开(住宿/门票/餐食/用车/导游/摄影/其他支出/保险)。

此前分类口径存在一个错位:油费、过路费、停车费、租车费、维修保养 5 类车辆费用在核单录入界面上本来就是在「其他支出」tab 录入的,但单团核算表却把它们归到「用车VEHICLE」分类下展示,和录入界面不一致,财务看报表时同一笔费用录入位置和归集位置对不上。

本次变更把报表分类口径对齐录入界面:

  • 5 类车辆费用FUEL/TOLL/PARKING/RENTAL/MAINTENANCE从「用车」分类移到「其他支出OTHER_EXPENSE」分类;
  • 「用车VEHICLE」分类此后只承载 Fleet 车务配车日租行vehicle_fee 表逐日明细);
  • 主报账人报账表reports/reimbursement的 OTHER_EXPENSE 展示块归属同步随动。

无入参变化、无新接口、无 DDL;totalCost 总成本口径不变。

2. 变更清单

# 位置 变更 类型
1 vehicleLines[] 行 字段删除expenseType / expenseTypeName / projectName / expenseDate 4 个字段不再下发(车辆费用行已迁出本数组,这 4 个字段失去载体) ⚠️ 破坏性删除
2 vehicleLines[] 行归属 行为变化:数组只含 Fleet 配车日租行sourceType=FLEET;不再出现 5 类车辆费用行 🔧 行为变化
3 otherExpenseLines[] 行归属 行为变化:新增承载 5 类车辆费用行expenseType=FUEL/TOLL/PARKING/RENTAL/MAINTENANCE,与原 OTHER 费用行、PHONE/OVERTIME 补贴行同数组混排(稀疏并集,每行仅本族字段非 null 🔧 行为变化
4 otherExpenseLines[].expenseType 值域扩大:原来恒为 OTHER,现在可能返回 OTHER/FUEL/TOLL/PARKING/RENTAL/MAINTENANCE 6 值之一 枚举值域扩大
5 分类小计口径 vehicleLines 合计下降、otherExpenseLines 合计上升(同一批行搬位置);totalCost / paidCost / unpaidCost / grossProfit 不变 📝 口径声明
6 主报账人报账表 expenseLines OTHER_EXPENSE 展示块type=OTHER_EXPENSE 的行)同步纳入 5 类车辆费用行,其 expenseType 值域同步扩为 6 类 🔧 行为变化
7 预览态未确认行口径 未确认UNCONFIRMED车辆费用行旧口径挂 VEHICLE 下不计入成本;新口径归 OTHER_EXPENSE,与 OTHER 类型原有口径一致计入预览态成本。完成核单finalize门禁要求全行 CONFIRMED,终态金额不变 📝 口径声明

3. 接口详情

方法 + 路径 GET /v3/admin/order/{orderId}/settlement/reports/group
接口名 查询单团核算表
使用场景 管理后台订单核单页,查看整团收入/成本/毛利只读报表(含逐项明细)
认证 管理后台 JWT/v3/admin/* 走网关鉴权)
角色限制 房务角色HOUSE不可访问,调了会被拦截错误码 581045
幂等性 只读查询,幂等
限流 走网关默认限流,无接口级特殊限流

同步受影响的接口(同 PR 一并说明,结构无变化、仅 OTHER_EXPENSE 展示块行归属随动):

方法 + 路径 GET /v3/admin/order/{orderId}/settlement/reports/reimbursement
接口名 查询主报账人报账表
变化点 expenseLines 中 type=OTHER_EXPENSE 的展示行纳入 5 类车辆费用行;expenseType 值域同步扩为 6 类

4. 接口入参

4.1 路径参数

参数 类型 必填 说明
orderId Long 订单 ID,必须 ≥ 1,否则 400 参数校验失败

4.2 请求体

无请求体,无 Query 参数。

5. 出参字段

顶层结构不变(沿用 #5963 拍平后结构):抬头字段 + 收入/汇总金额字段 + incomeLines + 7 个成本分类明细数组hotelLines/ticketLines/mealLines/vehicleLines/guideLines/photographerLines/otherExpenseLines+ insuranceInfo。本 PR 只影响 vehicleLines 行结构与 otherExpenseLines 行归属/值域。

所有行 VO 均带 JsonInclude(NON_NULL)null 字段不下发该键,前端取值请用可选链。

5.1 vehicleLines[] 行(变更后,只含 Fleet 配车日租行)

字段 类型 说明
serviceDate String(yyyy-MM-dd) 服务日期
startDate String(yyyy-MM-dd) 服务开始日期
endDate String(yyyy-MM-dd) 服务结束日期
vehiclePlate String 车牌号,如「蒙A-5376」
vehicleModelName String 车型名称,如「坦克500」
driverName String 司机姓名
dailyPrice BigDecimal 日单价(即"核算单价"列),保留两位小数
paymentTypeName String 车务付款类型名称,如「现金已付」
amount BigDecimal 核算金额,保留两位小数,恒有值
paymentMethod String 付款方式CASH_PAID/COMPANY_PAID/SIGNED
paymentMethodName String 付款方式中文名(字典 settlement_payment_method,缺值回退硬编码
sourceType String 明细来源类型,本数组恒为 FLEET
sourceTypeName String 来源中文名,本数组恒为「车务」
remark String 备注;无备注时不下发
voucherUrls String[] 凭证 URL 数组;无凭证时不下发

已删除(不再下发)expenseType / expenseTypeName / projectName / expenseDate。quantity 恒 null 本就不输出。

5.2 otherExpenseLines[] 行(变更后,费用行 6 类 + 补贴行稀疏并集)

字段 类型 说明
expenseDate String(yyyy-MM-dd) 费用发生日期
projectName String 项目名称,如「全程油费」「全程矿泉水」
expenseType String [EXPENSE 族] 费用类型,值域 6 值OTHER/FUEL/TOLL/PARKING/RENTAL/MAINTENANCE
expenseTypeName String [EXPENSE 族] 费用类型中文名(字典 expense_type,后端已回填,前端无需再调字典
subsidyType String [SUBSIDY 族] 补贴类型PHONE/OVERTIME
subsidyTypeName String [SUBSIDY 族] 补贴类型中文名(字典 subsidy_type
amount BigDecimal 核算金额(实际金额),保留两位小数,恒有值
paymentMethod String 付款方式CASH_PAID/COMPANY_PAID/SIGNED
paymentMethodName String 付款方式中文名(字典 settlement_payment_method,缺值回退硬编码
sourceType String 明细来源类型;无来源时不下发
sourceTypeName String 来源中文名SettlementDetailSourceType 枚举 label
remark String 备注;无备注时不下发
voucherUrls String[] 凭证 URL 数组;无凭证时不下发

稀疏并集规则:EXPENSE 族行只输出 expenseType/expenseTypeName,SUBSIDY 族行只输出 subsidyType/subsidyTypeName,两族字段互斥,另一族恒 null不下发。判别方式expenseType 键存在即费用行,subsidyType 键存在即补贴行。

6. 枚举 / 数据字典

6.1 expenseType字典 expense_type,存量字典已含 6 值,前端无需改字典配置)

中文名 说明
FUEL 油费 本次从 VEHICLE 迁入
TOLL 过路费 本次从 VEHICLE 迁入
PARKING 停车费 本次从 VEHICLE 迁入
RENTAL 租车费 本次从 VEHICLE 迁入
MAINTENANCE 维修保养 本次从 VEHICLE 迁入
OTHER 其他 原有,保持不变

6.2 subsidyType字典 subsidy_type,本接口仅出现 2 值)

中文名
PHONE 话补
OVERTIME 加班补贴

6.3 paymentMethod字典 settlement_payment_method

中文名
CASH_PAID 现金已付
COMPANY_PAID 公司支付
SIGNED 签单

6.4 sourceTypeSettlementDetailSourceType 枚举 label,非字典

中文名
MANUAL 手工
HOUSE_ASSIGNMENT 配房结果
SCENIC_ASSIGNMENT 景区
ACTIVITY_ASSIGNMENT 游玩项目
MEAL_ASSIGNMENT 餐饮安排
FLEET 车务
STAFF_ASSIGNMENT 人员安排
ORDER_SURCHARGE 订单增费
SYSTEM 系统

7. 错误码

错误码 文案 触发条件
581007 订单不存在 orderId 对应的订单不存在(或已软删)
581045 房务角色无权查看订单详情,房务仅可配房 房务角色HOUSE调用本接口
400 订单 ID 必须大于 0 orderId < 1参数校验失败

8. 示例

8.1 典型成功(测试服实证单 HL20260811181352799 口径:油费 300 归其他支出,用车只剩 Fleet 日租行)

请求:

GET /v3/admin/order/197820050123456789/settlement/reports/group

响应(只截取本次变化的两个数组,其余字段省略):

{
  "code": 200,
  "data": {
    "id": "197820050123456789",
    "orderId": "197820050123456789",
    "orderNo": "HL20260811181352799",
    "totalCost": 3300.00,
    "vehicleLines": [
      {
        "serviceDate": "2026-08-12",
        "startDate": "2026-08-12",
        "endDate": "2026-08-14",
        "vehiclePlate": "蒙A-5376",
        "vehicleModelName": "坦克500",
        "driverName": "司机甲",
        "dailyPrice": 1000.00,
        "paymentTypeName": "现金已付",
        "amount": 1000.00,
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "sourceType": "FLEET",
        "sourceTypeName": "车务"
      }
    ],
    "otherExpenseLines": [
      {
        "expenseDate": "2026-08-12",
        "projectName": "全程油费",
        "expenseType": "FUEL",
        "expenseTypeName": "油费",
        "amount": 300.00,
        "paymentMethod": "CASH_PAID",
        "paymentMethodName": "现金已付",
        "sourceType": "MANUAL",
        "sourceTypeName": "手工",
        "remark": "途中加油"
      },
      {
        "expenseDate": "2026-08-13",
        "projectName": "司机话补",
        "subsidyType": "PHONE",
        "subsidyTypeName": "话补",
        "amount": 50.00,
        "paymentMethod": "COMPANY_PAID",
        "paymentMethodName": "公司支付"
      }
    ]
  },
  "msg": "success"
}

要点:油费行的 expenseType=FUEL 出现在 otherExpenseLines;vehicleLines 里没有任何带 expenseType 的行。

8.2 边界(无车辆费用 + 无配车:两数组均为空)

{
  "code": 200,
  "data": {
    "orderNo": "HL20260810100000001",
    "totalCost": 0.00,
    "vehicleLines": [],
    "otherExpenseLines": []
  },
  "msg": "success"
}

要点:空分类固定返回空数组 [],不返回 null;前端判空渲染空态即可。

8.3 业务失败(订单不存在)

请求:

GET /v3/admin/order/999999999999/settlement/reports/group

响应:

{
  "code": 581007,
  "data": null,
  "msg": "订单不存在"
}

9. 业务边界

  • 适用:所有进入核单流程、需要查看整团成本构成的订单(含预览态与 finalize 终态)。
  • 不适用房务角色HOUSE不可调本接口581045
  • 特殊边界
    • 5 类车辆费用行的录入入口本来就在核单「其他支出」tab,本次只是报表归集对齐,不需要重新录入历史数据
    • 预览态存在未确认UNCONFIRMED车辆费用行时,新口径计入 otherExpenseLines 预览成本(旧口径挂 VEHICLE 不计成本;finalize 门禁要求全行 CONFIRMED,终态两口径金额一致。
    • 核单已 finalize 的订单,报表行来自终态快照,口径以快照冻结时为准;反确认reopen后重新生成走新口径。

10. 修改前后对比

10.1 字段级

位置 修改前 修改后
vehicleLines[] 行.expenseType FUEL/TOLL/PARKING/RENTAL/MAINTENANCE 删除,不下发
vehicleLines[] 行.expenseTypeName 有(油费等) 删除,不下发
vehicleLines[] 行.projectName 有(车辆费用项目名) 删除,不下发
vehicleLines[] 行.expenseDate 有(费用发生日期) 删除,不下发
otherExpenseLines[].expenseType 恒 OTHER OTHER/FUEL/TOLL/PARKING/RENTAL/MAINTENANCE 6 值之一
5 类车辆费用行所在数组 vehicleLines otherExpenseLines

10.2 行为级

场景 修改前 修改后
一笔 300 元油费CASH_PAID 出现在 vehicleLines,带 expenseType=FUEL/projectName/expenseDate 出现在 otherExpenseLines,字段同族expenseType=FUEL/projectName/expenseDate/amount/...
vehicleLines 内容 Fleet 日租行 + 5 类车辆费用行混排 只含 Fleet 日租行sourceType=FLEET
用车分类小计vehicleLines 合计) 含 5 类车辆费用 只含 Fleet 日租,数值下降
其他支出小计otherExpenseLines 合计) 只含 OTHER 费用 + 补贴 增加 5 类车辆费用,数值上升
totalCost / grossProfit —— 不变
报账表 OTHER_EXPENSE 展示块 只含 OTHER 费用 + 补贴展示行 纳入 5 类车辆费用展示行

11. 影响评估 / 回滚

  • 破坏性⚠️ 是。vehicleLines 行 4 个字段删除 + 5 类费用行跨数组迁移,前端若按旧结构渲染「用车」块会丢车辆费用行。
  • 前端需要同步上线的改动
    1. 「用车」块/页签只渲染 Fleet 日租行,删除对 vehicleLines[].expenseType/expenseTypeName/projectName/expenseDate 的读取(键已不下发);
    2. 5 类车辆费用行改到「其他支出」块渲染,复用 otherExpenseLines 现有 EXPENSE 族渲染逻辑expenseTypeName 后端已回填中文,前端无需改字典);
    3. 若有 workaround 代码把车辆费用从用车块搬到其他支出块展示,可清理;
    4. 分类小计若前端自算,无需改公式(数组内容已就位)。
  • 回滚方案:后端 revert PR #5970 即恢复旧口径;纯代码口径调整,无 DDL、无数据迁移,回滚无副作用。前端若已按新结构上线,后端回滚需前端同步回退。

12. 注意事项

  1. 行 VO 均带 JsonInclude(NON_NULL)null 字段不下发该键,前端取值用可选链 / 默认值兜底,不要假定键一定存在。
  2. expenseTypeName / subsidyTypeName / paymentMethodName / sourceTypeName 全部后端回填,前端不要再自行映射字典。
  3. 判别 otherExpenseLines 行族expenseType 键存在 = 费用行(含 6 类,subsidyType 键存在 = 补贴行,两族字段互斥。
  4. 报账表reports/reimbursementexpenseLines 中 type=OTHER_EXPENSE 展示行的 expenseType 实际值域同步扩为 6 类;该字段 Swagger 注解的 allowableValues 暂未同步更新,以本文档与实际返回值为准
  5. 本次无入参变化、无新接口、无 DDL、无字典数据变更expense_type 字典 6 值为存量)。

13. 关联 / 联系人