29 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 | 5781 | 单团核算表扩充逐项明细出参(incomeLines.details / costCategories.lines) | admin | 修改接口 | yaosutu(GIT) | deployed | verified | implemented | mmg | 3993f15a | 2026-08-11 | 前端已实现(3993f15a):单团核算表收入行 incomeLines[].details、成本分类 costCategories[].lines 逐项明细行内展开——detailColumns 显式剔除 details/lines/voucherUrls 父列(否则嵌套结构被 detailCellValue JSON.stringify 成多余列,后端已 deployed 老前端会自动渲出),新增 expand 列+renderChildTable 渲染逐项子表(仅当行确有非空逐项才显示展开入口,空数组不渲染);REPORT_FIELD_LABELS 补逐项字段中文表头(stayDate/hotelName/dailyPrice/totalPremium 等),REPORT_CODE_TO_NAME_FIELD 补 source/serviceType/bizType code→Name(后端回填 sourceName/serviceTypeName/bizTypeName,缺名回退 code)。负数金额不取绝对值、*Name 中文名直接展示均遵循 changelog 边界。ReportModal.spec 新增展开用例:父表不渲 JSON 列、展开后显示逐项子表。核单域 spec 全过,checkpoint 全绿。 | 2026-08-11 | dev-v3 |
【✨ 修改接口·管理后台】单团核算表扩充逐项明细出参(#5781)
PR: #5786 | 服务: hl-order-service-v3 | 更新时间: 2026-08-10
1. 接口背景
单团核算表(GET /v3/admin/order/{orderId}/settlement/reports/group)此前只返回「4 行收入合计 + 8 行成本合计」,财务/运营在核对某一行合计时看不到它是由哪些逐项明细加总出来的,只能跳回各分类明细页签逐条对账。
本次变更为纯出参增量:在每条收入行下挂 details(收入逐项明细)、在每个成本分类下挂 lines(成本逐项明细,分类专属结构),让前端在核算表内直接展开逐项,无需再跳页签拼装。
不变的部分:顶部汇总字段(baseOrderAmount / totalCost / grossProfit 等全部金额字段)、incomeLines 仍固定 4 行、costCategories 仍固定 8 行、各行 amount 合计口径,全部与变更前一致。
2. 变更清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 查询单团核算表 | GET | /v3/admin/order/{orderId}/settlement/reports/group | 修改(出参纯增量) | incomeLines[i] 新增 details 数组;costCategories[i] 新增 lines 数组(元素结构随 category 不同而不同,按 category 窄化) |
配套数据字典(前端可调 GET /admin/dict/data/{dictType} 动态渲染中文名):
| 字典 type | 用途 | 本次状态 |
|---|---|---|
| settlement_category | 成本分类中文名 | 已存在(不变) |
| settlement_payment_method | 付款方式中文名 | 已存在(不变) |
| settlement_report_line_type | 收入行类型中文名 | 已存在(不变) |
| insurance_biz_type | 保险业务类型中文名 | 本次新增 |
| settlement_refund_source | 人工返还来源中文名 | 本次新增 |
3. 接口详情
3.1 查询单团核算表
- 使用场景:核单工作台「单团核算」页签,财务/运营查看单团收入成本毛利全貌及逐项明细
- 认证:管理后台 JWT;房务角色(ROOM_MANAGER / HOUSE_KEEPER_LEAD)无权调用(返 581045)
- 幂等性:是(GET 只读)
- 限流:无
4. 接口入参
4.1 路径参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
orderId |
Long | ✅ | 订单 ID,必须 > 0,否则返参数校验错误 |
4.2 请求体字段
无请求体。
5. 出参(响应)
响应类型:Result<SettlementGroupReportRespVO>(code=200 表示成功,data 为下表结构)。
5.1 顶层字段(SettlementGroupReportRespVO)
⚠️ 本表全部字段与变更前一致,本次无增删改,列出仅为自包含。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
String | 报表 ID(Long 序列化为字符串,无落库记录时可能缺省) |
orderId |
String | 订单 ID(Long 序列化为字符串) |
reportStatus |
String | 报表状态:GENERATED=已生成(实时组装)/ CONFIRMED=已确认(终态快照回放) |
baseOrderAmount |
Number | 订单应收金额,两位小数 |
otherIncomeAmount |
Number | 其他收入合计 |
discountAmount |
Number | 优惠合计(负数) |
adjustedReceivableAmount |
Number | 调整后应收 |
paidAmount |
Number | 已收金额 |
actualRefundedAmount |
Number | 实际退款合计(负数) |
netRevenueAmount |
Number | 净收入 |
netReceivedAmount |
Number | 实收净额 |
outstandingAmount |
Number | 未收尾款 |
hotelCost / ticketCost / mealCost / vehicleCost / guideCost / photographerCost / otherExpenseCost / insurancePremium |
Number | 8 个成本分类合计(住宿/门票/餐食/车辆/导游/摄影/其他支出/保险) |
totalCost |
Number | 成本总计 |
paidCost |
Number | 已付成本合计 |
unpaidCost |
Number | 未付成本合计 |
grossProfit |
Number | 毛利 |
grossProfitRate |
Number | 毛利率 |
travelerCount |
Number | 出行人数 |
perCapitaRevenue / perCapitaCost / perCapitaProfit |
Number | 人均收入 / 人均成本 / 人均毛利 |
incomeLines |
Array | 收入行,固定 4 行,结构见 5.2 |
costCategories |
Array | 成本分类行,固定 8 行,结构见 5.3 |
generatedBy / generatedByName / generatedAt |
String / String / String | 生成人 ID / 姓名 / 生成时间 |
confirmedBy / confirmedByName / confirmedAt |
String / String / String | 确认人 ID / 姓名 / 确认时间(未确认时缺省) |
5.2 收入行(SettlementGroupIncomeLineVO)
| 字段 | 类型 | 说明 |
|---|---|---|
type |
String | 行类型:BASE_ORDER=订单应收 / OTHER_INCOME=其他收入 / DISCOUNT=优惠 / ACTUAL_REFUND=实际退款 |
typeName |
String | 行类型中文名(字典 settlement_report_line_type 回填) |
amount |
Number | 行合计金额,两位小数;DISCOUNT / ACTUAL_REFUND 为负数 |
details |
Array | ✨ 本次新增:收入逐项明细(SettlementGroupIncomeDetailVO),无逐项时为空数组 [] |
5.3 收入逐项明细(SettlementGroupIncomeDetailVO)✨ 本次新增
| 字段 | 类型 | 说明 |
|---|---|---|
itemName |
String | 项目名(订单应收 / 增费项目名 / 优惠名称 / 退款来源中文名) |
content |
String | 内容说明(如规格、退款原因) |
source |
String | 人工返还来源 code,仅 ACTUAL_REFUND 下的人工返还行透出:DRIVER_ONSITE / COMPANY_COMPENSATION |
sourceName |
String | 人工返还来源中文名(字典 settlement_refund_source) |
unitPrice |
Number | 单价,两位小数;无单价概念时缺省 |
headCount |
Number | 人数;无人数概念时缺省 |
quantity |
Number | 数量;无数量概念时缺省 |
amount |
Number | 金额,两位小数;DISCOUNT / ACTUAL_REFUND 明细为负数 |
paymentMethod |
String | 付款方式:CASH_PAID / COMPANY_PAID / SIGNED;无付款方式时缺省 |
paymentMethodName |
String | 付款方式中文名(字典 settlement_payment_method) |
sourceType |
String | 来源类型(9 值,见 §6.6);无来源时缺省 |
sourceTypeName |
String | 来源中文名 |
remark |
String | 备注 |
voucherUrls |
Array<String> | 凭证 URL 数组 |
各 type 下 details 的内容口径:
| type | details 内容 |
|---|---|
BASE_ORDER |
订单应收一行汇总(订单侧无逐项时单行) |
OTHER_INCOME |
其他收入逐项 |
DISCOUNT |
优惠逐项(金额取负) |
ACTUAL_REFUND |
实际退款逐项:线上退款 + 人工返还(source = DRIVER_ONSITE / COMPANY_COMPENSATION),金额取负 |
5.4 成本分类行(SettlementGroupCostCategoryVO)
| 字段 | 类型 | 说明 |
|---|---|---|
category |
String | 费用类别:HOTEL / TICKET / MEAL / VEHICLE / GUIDE / PHOTOGRAPHER / OTHER_EXPENSE / INSURANCE |
categoryName |
String | 费用类别中文名(字典 settlement_category) |
amount |
Number | 分类合计金额,两位小数 |
lines |
Array | ✨ 本次新增:成本逐项明细,元素结构随 category 不同而不同(分类专属行 VO),无逐项时为空数组 [];前端按 category 判别窄化到 5.5~5.11 的对应结构 |
5.5 成本逐项行 · HOTEL 住宿(SettlementGroupHotelLineVO)✨
| 字段 | 类型 | 说明 |
|---|---|---|
stayDate |
String | 入住日期,yyyy-MM-dd |
hotelName |
String | 酒店名称 |
roomTypeName |
String | 房型名称 |
roomCount |
Number | 房间数 |
unitPrice |
Number | 单价,两位小数 |
plannedCost |
Number | 计划成本,两位小数 |
amount |
Number | 核算金额(实际成本),两位小数 |
paymentMethod / paymentMethodName |
String | 付款方式 code / 中文名 |
sourceType / sourceTypeName |
String | 来源类型 code / 中文名 |
remark |
String | 备注 |
voucherUrls |
Array<String> | 凭证 URL 数组 |
5.6 成本逐项行 · TICKET 门票(SettlementGroupTicketLineVO)✨
| 字段 | 类型 | 说明 |
|---|---|---|
dayDate |
String | 游玩日期,yyyy-MM-dd |
scenicName |
String | 景区/项目名称 |
specName |
String | 规格名称(如 成人票) |
ticketCount |
Number | 票数 |
ticketUnitPrice |
Number | 门票单价,两位小数 |
sellPrice |
Number | 销售价,两位小数 |
plannedCost |
Number | 计划成本,两位小数 |
amount |
Number | 核算金额(实际成本),两位小数 |
paymentMethod / paymentMethodName |
String | 付款方式 code / 中文名 |
sourceType / sourceTypeName |
String | 来源类型 code / 中文名 |
remark |
String | 备注 |
voucherUrls |
Array<String> | 凭证 URL 数组 |
5.7 成本逐项行 · MEAL 餐食(SettlementGroupMealLineVO)✨
| 字段 | 类型 | 说明 |
|---|---|---|
mealDate |
String | 用餐日期,yyyy-MM-dd |
mealName |
String | 餐食名称 |
mealType |
String | 餐食类型:BREAKFAST / LUNCH / DINNER / SELF |
mealTypeName |
String | 餐食类型中文名(字典 meal_type) |
quantity |
Number | 份数 |
unitPrice |
Number | 单价,两位小数 |
amount |
Number | 核算金额(实际金额),两位小数 |
paymentMethod / paymentMethodName |
String | 付款方式 code / 中文名 |
sourceType / sourceTypeName |
String | 来源类型 code / 中文名;餐食明细无来源时缺省 |
remark |
String | 备注 |
voucherUrls |
Array<String> | 凭证 URL 数组 |
5.8 成本逐项行 · VEHICLE 用车(SettlementGroupVehicleLineVO)✨
车务逐日行(VEHICLE_FEE 族)与车辆费用行(EXPENSE 族:油费/过路费等)的稀疏并集:每行仅本族字段非空,另一族字段整体缺省。无单价/数量概念,
dailyPrice即核算单价列。
| 字段 | 类型 | 说明 |
|---|---|---|
serviceDate |
String | [VEHICLE_FEE] 服务日期,yyyy-MM-dd |
startDate |
String | [VEHICLE_FEE] 服务开始日期,yyyy-MM-dd |
endDate |
String | [VEHICLE_FEE] 服务结束日期,yyyy-MM-dd |
vehiclePlate |
String | [VEHICLE_FEE] 车牌号 |
vehicleModelName |
String | [VEHICLE_FEE] 车型名称 |
driverName |
String | [VEHICLE_FEE] 司机姓名 |
dailyPrice |
Number | [VEHICLE_FEE] 日单价(即核算单价列),两位小数 |
paymentTypeName |
String | [VEHICLE_FEE] 车务付款类型名称 |
amount |
Number | 核算金额,两位小数 |
paymentMethod / paymentMethodName |
String | 付款方式 code / 中文名 |
sourceType / sourceTypeName |
String | 来源类型 code / 中文名 |
expenseType |
String | [EXPENSE] 车辆费用类型:FUEL / TOLL / PARKING / RENTAL / MAINTENANCE |
expenseTypeName |
String | [EXPENSE] 车辆费用类型中文名(字典 expense_type) |
projectName |
String | [EXPENSE] 项目名称 |
expenseDate |
String | [EXPENSE] 费用发生日期,yyyy-MM-dd |
remark |
String | 备注 |
voucherUrls |
Array<String> | 凭证 URL 数组 |
5.9 成本逐项行 · GUIDE 导游 / PHOTOGRAPHER 摄影(SettlementGroupStaffLineVO,两分类共用)✨
| 字段 | 类型 | 说明 |
|---|---|---|
serviceDate |
String | 服务日期,yyyy-MM-dd;无服务日时缺省 |
name |
String | 人员姓名 |
serviceType |
String | 服务类型:GUIDE / PHOTOGRAPHER |
serviceTypeName |
String | 服务类型中文名(字典 staff_role) |
amount |
Number | 核算金额,两位小数 |
paymentMethod / paymentMethodName |
String | 付款方式 code / 中文名 |
sourceType / sourceTypeName |
String | 来源类型 code / 中文名;无来源时缺省 |
remark |
String | 备注 |
voucherUrls |
Array<String> | 凭证 URL 数组 |
5.10 成本逐项行 · OTHER_EXPENSE 其他支出(SettlementGroupOtherExpenseLineVO)✨
其他费用行(EXPENSE 族)与补贴行(SUBSIDY 族)的稀疏并集:每行仅本族字段非空。无单价/数量概念。
| 字段 | 类型 | 说明 |
|---|---|---|
expenseDate |
String | 费用发生日期,yyyy-MM-dd |
projectName |
String | 项目名称 |
expenseType |
String | [EXPENSE] 其他费用类型:固定 OTHER |
expenseTypeName |
String | [EXPENSE] 其他费用类型中文名(字典 expense_type) |
subsidyType |
String | [SUBSIDY] 补贴类型:PHONE / OVERTIME |
subsidyTypeName |
String | [SUBSIDY] 补贴类型中文名(字典 subsidy_type) |
amount |
Number | 核算金额(实际金额),两位小数 |
paymentMethod / paymentMethodName |
String | 付款方式 code / 中文名 |
sourceType / sourceTypeName |
String | 来源类型 code / 中文名;无来源时缺省 |
remark |
String | 备注 |
voucherUrls |
Array<String> | 凭证 URL 数组 |
5.11 成本逐项行 · INSURANCE 保险(SettlementGroupInsuranceLineVO)✨
| 字段 | 类型 | 说明 |
|---|---|---|
productName |
String | 保险产品名称 |
bizType |
String | 业务类型:ORDER / DRIVER |
bizTypeName |
String | 业务类型中文名(字典 insurance_biz_type,本次新增) |
totalPremium |
Number | 保费(即核算金额列),两位小数 |
extPolicyNo |
String | 外部保单号 |
voucherUrls |
Array<String> | 凭证 URL 数组(电子保单 PDF) |
保险行无
plannedCost/sourceType字段,不输出。
6. 枚举 / 数据字典
6.1 incomeLines[].type(字典 settlement_report_line_type)
| 值 | 中文 | 说明 |
|---|---|---|
BASE_ORDER |
订单应收 | 订单应收行 |
OTHER_INCOME |
其他收入 | 其他收入行 |
DISCOUNT |
优惠 | 优惠行(金额为负) |
ACTUAL_REFUND |
实际退款 | 实际退款行(金额为负) |
6.2 costCategories[].category(字典 settlement_category)
| 值 | 中文 | 对应 lines 行结构 |
|---|---|---|
HOTEL |
住宿 | §5.5 |
TICKET |
门票/游玩项目 | §5.6 |
MEAL |
餐食 | §5.7 |
VEHICLE |
车辆 | §5.8 |
GUIDE |
导游 | §5.9 |
PHOTOGRAPHER |
摄影 | §5.9(与 GUIDE 共用) |
OTHER_EXPENSE |
其他支出 | §5.10 |
INSURANCE |
保险 | §5.11 |
6.3 paymentMethod(字典 settlement_payment_method)
出现于:收入逐项明细、HOTEL / TICKET / MEAL / VEHICLE / 人员 / 其他支出各成本逐项行。
| 值 | 中文 |
|---|---|
CASH_PAID |
现金已付 |
COMPANY_PAID |
公司支付 |
SIGNED |
签单 |
6.4 details[].source(字典 settlement_refund_source,✨ 本次新增字典)
仅 ACTUAL_REFUND 下人工返还行透出。
| 值 | 中文 |
|---|---|
DRIVER_ONSITE |
司机现场返还 |
COMPANY_COMPENSATION |
公司赔付 |
6.5 lines[].bizType(字典 insurance_biz_type,✨ 本次新增字典)
仅 INSURANCE 保险行。
| 值 | 中文 |
|---|---|
ORDER |
订单险 |
DRIVER |
司机险 |
6.6 sourceType(后端枚举 SettlementDetailSourceType)
出现于:收入逐项明细、HOTEL / TICKET / MEAL / VEHICLE / 人员 / 其他支出各成本逐项行。
| 值 | 中文 |
|---|---|
MANUAL |
手工 |
HOUSE_ASSIGNMENT |
配房结果 |
SCENIC_ASSIGNMENT |
景区 |
ACTIVITY_ASSIGNMENT |
游玩项目 |
MEAL_ASSIGNMENT |
餐饮安排 |
FLEET |
车务 |
STAFF_ASSIGNMENT |
人员安排 |
ORDER_SURCHARGE |
订单增费 |
SYSTEM |
系统 |
6.7 lines[].mealType(字典 meal_type)
仅 MEAL 餐食行。
| 值 | 中文 |
|---|---|
BREAKFAST |
早餐 |
LUNCH |
午餐 |
DINNER |
晚餐 |
SELF |
自理 |
6.8 lines[].serviceType(字典 staff_role)
仅 GUIDE / PHOTOGRAPHER 人员行。本接口只会出现 GUIDE / PHOTOGRAPHER 两个值(字典另有 助理导游/领队/司机/其他,不在本接口出现)。
| 值 | 中文 |
|---|---|
GUIDE |
导游 |
PHOTOGRAPHER |
摄影师 |
6.9 lines[].expenseType(字典 expense_type)
VEHICLE 行(EXPENSE 族):FUEL=油费 / TOLL=过路费 / PARKING=停车费 / RENTAL=租车费 / MAINTENANCE=维修保养。
OTHER_EXPENSE 行(EXPENSE 族):固定 OTHER=其他。
6.10 lines[].subsidyType(字典 subsidy_type)
仅 OTHER_EXPENSE 行(SUBSIDY 族)。
| 值 | 中文 |
|---|---|
PHONE |
话补 |
OVERTIME |
加班补贴 |
6.11 reportStatus
| 值 | 中文 | 说明 |
|---|---|---|
GENERATED |
已生成 | 未核单订单,实时组装 |
CONFIRMED |
已确认 | 已核单(SETTLED)订单,终态快照回放 |
7. 错误码
| code | 含义 | 触发场景 |
|---|---|---|
| 400 | 参数校验失败 | orderId 缺失或 < 1 |
| 581007 | 订单不存在 | orderId 对应订单不存在或已删除 |
| 581045 | 房务角色无权查看订单详情,房务仅可配房 | 房务管理员 / 房务组长角色调用 |
8. 示例(3 组:典型 / 边界 / 异常)
8.1 典型成功(已核单订单,逐项明细完整填充)
请求:
GET /v3/admin/order/1956112233445566778/settlement/reports/group
Authorization: Bearer <admin JWT>
(无请求体)
响应(节选,仅展示本次新增结构所在的 incomeLines / costCategories,顶层汇总字段与变更前一致故省略):
{
"code": 200,
"data": {
"id": "1957000000000000001",
"orderId": "1956112233445566778",
"reportStatus": "CONFIRMED",
"incomeLines": [
{
"type": "BASE_ORDER",
"typeName": "订单应收",
"amount": 12800.00,
"details": [
{
"itemName": "订单应收",
"content": "小红书(孙雷) 王彧琪",
"unitPrice": 1280.00,
"headCount": 10,
"amount": 12800.00
}
]
},
{
"type": "OTHER_INCOME",
"typeName": "其他收入",
"amount": 200.00,
"details": [
{
"itemName": "现场加收骑马费",
"unitPrice": 100.00,
"quantity": 2,
"amount": 200.00,
"paymentMethod": "CASH_PAID",
"paymentMethodName": "现金已付",
"sourceType": "ORDER_SURCHARGE",
"sourceTypeName": "订单增费",
"remark": "现场加收"
}
]
},
{
"type": "DISCOUNT",
"typeName": "优惠",
"amount": -500.00,
"details": [
{
"itemName": "早鸟优惠",
"amount": -500.00
}
]
},
{
"type": "ACTUAL_REFUND",
"typeName": "实际退款",
"amount": -300.00,
"details": [
{
"itemName": "司机现场返还",
"content": "少住一晚退房差",
"source": "DRIVER_ONSITE",
"sourceName": "司机现场返还",
"amount": -300.00,
"paymentMethod": "CASH_PAID",
"paymentMethodName": "现金已付",
"remark": "现场返还现金"
}
]
}
],
"costCategories": [
{
"category": "HOTEL",
"categoryName": "住宿",
"amount": 3600.00,
"lines": [
{
"stayDate": "2026-07-30",
"hotelName": "草原明珠大酒店",
"roomTypeName": "标间",
"roomCount": 3,
"unitPrice": 400.00,
"plannedCost": 1200.00,
"amount": 1200.00,
"paymentMethod": "CASH_PAID",
"paymentMethodName": "现金已付",
"sourceType": "HOUSE_ASSIGNMENT",
"sourceTypeName": "配房结果",
"remark": "含早",
"voucherUrls": ["https://oss/v1.jpg"]
}
]
},
{
"category": "VEHICLE",
"categoryName": "车辆",
"amount": 1760.00,
"lines": [
{
"serviceDate": "2026-07-30",
"startDate": "2026-07-30",
"endDate": "2026-07-31",
"vehiclePlate": "蒙A-5376",
"vehicleModelName": "坦克500",
"driverName": "司机甲",
"dailyPrice": 880.00,
"amount": 880.00,
"paymentMethod": "CASH_PAID",
"paymentMethodName": "现金已付",
"sourceType": "FLEET",
"sourceTypeName": "车务"
},
{
"expenseType": "FUEL",
"expenseTypeName": "油费",
"projectName": "全程油费",
"expenseDate": "2026-07-31",
"amount": 880.00,
"paymentMethod": "COMPANY_PAID",
"paymentMethodName": "公司支付",
"sourceType": "FLEET",
"sourceTypeName": "车务"
}
]
},
{
"category": "GUIDE",
"categoryName": "导游",
"amount": 1600.00,
"lines": [
{
"serviceDate": "2026-07-30",
"name": "导游乙",
"serviceType": "GUIDE",
"serviceTypeName": "导游",
"amount": 1600.00,
"paymentMethod": "SIGNED",
"paymentMethodName": "签单",
"sourceType": "STAFF_ASSIGNMENT",
"sourceTypeName": "人员安排"
}
]
},
{
"category": "INSURANCE",
"categoryName": "保险",
"amount": 150.00,
"lines": [
{
"productName": "保游畅享境内游保险",
"bizType": "ORDER",
"bizTypeName": "订单险",
"totalPremium": 150.00,
"extPolicyNo": "PY20260730001",
"voucherUrls": ["https://oss/policy1.pdf"]
}
]
}
]
},
"msg": ""
}
8.2 边界情况(无任何逐项明细 / 金额为 0)
场景说明:订单无任何其他收入、优惠、退款,且各成本分类未录入任何逐项 —— details / lines 返回空数组 [](不是 null),对应分类 amount 可为 0.00。所有 null 的可选字段(unitPrice / headCount / paymentMethod / remark / voucherUrls 等)整体缺省不出现在 JSON 中。
请求:
GET /v3/admin/order/1956112233445566889/settlement/reports/group
Authorization: Bearer <admin JWT>
(无请求体)
响应(节选):
{
"code": 200,
"data": {
"orderId": "1956112233445566889",
"reportStatus": "GENERATED",
"incomeLines": [
{ "type": "BASE_ORDER", "typeName": "订单应收", "amount": 12800.00, "details": [
{ "itemName": "订单应收", "unitPrice": 1280.00, "headCount": 10, "amount": 12800.00 }
] },
{ "type": "OTHER_INCOME", "typeName": "其他收入", "amount": 0.00, "details": [] },
{ "type": "DISCOUNT", "typeName": "优惠", "amount": 0.00, "details": [] },
{ "type": "ACTUAL_REFUND", "typeName": "实际退款", "amount": 0.00, "details": [] }
],
"costCategories": [
{ "category": "HOTEL", "categoryName": "住宿", "amount": 0.00, "lines": [] },
{ "category": "TICKET", "categoryName": "门票/游玩项目", "amount": 0.00, "lines": [] },
{ "category": "MEAL", "categoryName": "餐食", "amount": 0.00, "lines": [] },
{ "category": "VEHICLE", "categoryName": "车辆", "amount": 0.00, "lines": [] },
{ "category": "GUIDE", "categoryName": "导游", "amount": 0.00, "lines": [] },
{ "category": "PHOTOGRAPHER", "categoryName": "摄影", "amount": 0.00, "lines": [] },
{ "category": "OTHER_EXPENSE", "categoryName": "其他支出", "amount": 0.00, "lines": [] },
{ "category": "INSURANCE", "categoryName": "保险", "amount": 0.00, "lines": [] }
]
},
"msg": ""
}
8.3 业务失败(订单不存在 / 房务角色越权)
场景说明 A:orderId 不存在 → 581007。
请求:
GET /v3/admin/order/999999999/settlement/reports/group
Authorization: Bearer <admin JWT>
(无请求体)
响应:
{ "code": 581007, "msg": "订单不存在", "data": null }
场景说明 B:房务管理员角色调用 → 581045。
{ "code": 581045, "msg": "房务角色无权查看订单详情,房务仅可配房", "data": null }
9. 业务边界
- ✅ 适用场景:订单存在即可调;未核单订单(
reportStatus=GENERATED)走实时组装,已核单订单(reportStatus=CONFIRMED)走终态快照回放,两条路径出参结构完全一致,前端无需区分 - ❌ 不适用场景:房务角色(ROOM_MANAGER / HOUSE_KEEPER_LEAD)调用 → 581045
- ⚠️ 特殊边界:
- 逐项明细不出已付/未付逐行列,逐行只有单价/数量/核算金额(
paidCost/unpaidCost仍是顶层分类维度的合计口径,不在逐项层) - VEHICLE / OTHER_EXPENSE 两分类的行是同数组内两族结构稀疏并集(见 §5.8 / §5.10),前端渲染列时按「本族字段是否出现」判别
DISCOUNT/ACTUAL_REFUND行及其明细金额均为负数,前端不要自行取绝对值
- 逐项明细不出已付/未付逐行列,逐行只有单价/数量/核算金额(
10. 修改前后对比
10.1 字段级对比
| 字段 | 改前 | 改后 |
|---|---|---|
incomeLines[].details |
无此字段 | ✨ 新增 Array<SettlementGroupIncomeDetailVO>,无逐项时为 [] |
costCategories[].lines |
无此字段 | ✨ 新增 Array(分类专属行结构,按 category 窄化),无逐项时为 [] |
| 顶层汇总字段 / 4 行收入合计 / 8 行成本合计 | 现状 | 不变 |
10.2 行为级对比
| 行为 | 改前 | 改后 |
|---|---|---|
| 核算表核对逐项明细 | 只能看到行合计,需跳各分类明细页签逐条对账 | 行内直接展开 details / lines 逐项 |
| 数据字典 | 无 insurance_biz_type / settlement_refund_source |
✨ 新增两个字典(保险业务类型 / 人工返还来源) |
11. 影响评估 / 回滚
11.1 影响评估
- 是否破坏向后兼容:否。纯出参增量,原有字段名 / 类型 / 结构 / 合计口径零变化;老前端不读
details/lines不受影响 - 前端是否必须同步上线:否。前端按自身排期接入逐项展开即可
11.2 回滚方案
- 回滚方式:revert PR #5786
- 回滚后清理:无(无 DDL、无缓存、无脏数据;两个字典
insurance_biz_type/settlement_refund_source保留无害)
12. 注意事项
- null 字段整体缺省:所有行 VO 标注了 null 不序列化,可选字段(unitPrice / headCount / quantity / paymentMethod / sourceType / remark / voucherUrls 等)为 null 时该 key 不出现在 JSON 中,前端按可选字段处理,不要断言 key 必存在
details/lines无逐项时是空数组[]而不是字段缺省,可直接.length判空- 行结构窄化:
costCategories[].lines元素是多态结构,前端必须先按category判别再取分类专属字段(GUIDE / PHOTOGRAPHER 共用人员行结构) - 金额符号:
DISCOUNT/ACTUAL_REFUND的行金额与明细金额均为负数;成本各行为正数 - 中文名渲染:
*Name字段后端已回填中文名(字典缺值时回退硬编码),可直接展示;如需动态字典渲染,调GET /admin/dict/data/{dictType},dictType 见 §6 各子节 - 无历史 workaround 需要清理(本能力此前不存在)
13. 关联 / 联系人
13.1 链接
13.2 联系人
- 后端负责人: @yaosutu