docs(changelog): 单团核算表出参重构——收入拍平逐项+成本7分类明细数组+保险独立子块(#5963)
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s
- 删 perCapita 人均三指标 + hotelCost 等 7 个成本分类小计 + costCategories 套层 + incomeLines[].details 嵌套 - incomeLines 拍平逐项行(4 type 各至少一行,无明细给占位行 amount=聚合值) - 成本改 hotelLines 等 7 分类明细数组平铺顶层,空分类 [] - 新增 insuranceInfo 保险子块;insurancePremium 顶层保留且计入 totalCost - PR #5966 已合并 dev-v3(c8cae25131),测试服部署 + 网关实调验证通过
这个提交包含在:
父节点
84c22ea77a
当前提交
34e50005f9
@ -0,0 +1,728 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "5963"
|
||||
title: "单团核算表出参重构——收入拍平逐项+成本7分类明细数组+保险独立子块"
|
||||
consumer: "admin"
|
||||
change_type: "修改接口"
|
||||
author: "yst"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "PR #5966 已合并 dev-v3(merge commit c8cae25131)。破坏性契约变化:删除 perCapitaRevenue/perCapitaCost/perCapitaProfit 人均三指标、hotelCost 等 7 个成本分类小计、costCategories 套层与 incomeLines[].details 嵌套;incomeLines 拍平为逐项行(4 type 各至少一行,无明细给占位行 amount=聚合值);成本改 hotelLines 等 7 个分类明细数组平铺顶层;新增 insuranceInfo 保险子块。仅出参变化,无入参/枚举值/DDL 变化。"
|
||||
updated_at: "2026-08-14"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 【修改接口·管理后台】单团核算表出参重构——收入拍平逐项 + 成本 7 分类明细数组 + 保险独立子块(#5963)
|
||||
|
||||
## 1. 接口背景
|
||||
|
||||
单团核算表(reports/group)是管理后台订单核单页查看整团收入、成本、毛利全貌的只读报表:抬头是订单/产品/客户信息,中部是收入与成本逐项明细,底部是净收入、总成本、毛利汇总。
|
||||
|
||||
此前出参有两层嵌套套层:收入是「4 个汇总行 + 每行内嵌 details 明细数组」,成本是「costCategories 8 个分类行 + 每类内嵌 lines 明细数组」,外加 7 个成本分类小计字段和 3 个人均指标字段。前端渲染明细要钻两层嵌套,小计/人均字段与明细数组存在重复表达。
|
||||
|
||||
本次变更把出参**拍平**:
|
||||
|
||||
- 收入 `incomeLines` 去 details 嵌套,逐项明细直接平铺为多行,每行带全列;
|
||||
- 成本删 `costCategories` 套层,改 7 个分类明细数组(`hotelLines` 等)平铺顶层,空分类给 `[]`;
|
||||
- 删除 7 个成本分类小计字段(前端自算各分类数组 sum)与人均三指标;
|
||||
- 保险从成本分类中独立出来,新增 `insuranceInfo` 子块;顶层 `insurancePremium` 保留且仍计入 totalCost。
|
||||
|
||||
## 2. 变更清单
|
||||
|
||||
| # | 位置 | 变更 | 类型 |
|
||||
|---|------|------|------|
|
||||
| 1 | perCapitaRevenue / perCapitaCost / perCapitaProfit | **字段删除**:人均营收/人均成本/人均毛利不再透出(需要时前端用 汇总值 ÷ travelerCount 自算) | ⚠️ 破坏性删除 |
|
||||
| 2 | hotelCost / ticketCost / mealCost / vehicleCost / guideCost / photographerCost / otherExpenseCost | **字段删除**:7 个成本分类小计不再透出,前端改为自算对应分类明细数组的 amount 合计 | ⚠️ 破坏性删除 |
|
||||
| 3 | costCategories | **结构删除**:成本套层(8 个分类行各内嵌 lines)整体下线,改 7 个分类明细数组平铺顶层(见 #5);原 INSURANCE 分类行由 insuranceInfo 子块 + insurancePremium 替代 | ⚠️ 破坏性删除 |
|
||||
| 4 | incomeLines[].details | **结构删除**:收入行内嵌明细数组下线,逐项明细直接拍平为 incomeLines 多行 | ⚠️ 破坏性删除 |
|
||||
| 5 | hotelLines / ticketLines / mealLines / vehicleLines / guideLines / photographerLines / otherExpenseLines | **新增**:7 个成本分类明细数组平铺顶层,行结构 = 原 costCategories[].lines 的分类专属行;无明细的分类给空数组 `[]` | ✨ 新增字段 |
|
||||
| 6 | incomeLines[] 行结构 | **结构变化**:每行在 type/typeName/amount 基础上补齐 itemName/content/unitPrice/headCount/quantity/paymentMethod/paymentMethodName/source/sourceName/sourceType/sourceTypeName/remark/voucherUrls 全列;同一 type 多条平铺多行;某 type 无逐项明细时给一行占位行(仅 type/typeName/amount,amount=该 type 聚合值) | 🔧 结构变化 |
|
||||
| 7 | insuranceInfo | **新增**:保险子块(insured/productName/bizType/bizTypeName/extPolicyNo/totalPremium);无有效保单时 insured=false、保单字段不下发、totalPremium=0 | ✨ 新增字段 |
|
||||
| 8 | 抬头区 + 汇总金额字段(baseOrderAmount … grossProfitRate / travelerCount / insurancePremium) | **保留**,口径不变;insurancePremium 是原 8 个小计中唯一保留的,仍计入 totalCost | 📝 口径声明(数值零漂移) |
|
||||
|
||||
无入参变化、无新接口、无枚举值/字典变化、无 DDL。净收入 netRevenueAmount、总成本 totalCost、毛利 grossProfit/grossProfitRate 数值口径**零漂移**。
|
||||
|
||||
## 3. 接口详情
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 方法 + 路径 | GET /v3/admin/order/{orderId}/settlement/reports/group |
|
||||
| 接口名 | 查询单团核算表 |
|
||||
| 使用场景 | 管理后台订单核单页,查看整团收入/成本/毛利只读报表(含逐项明细) |
|
||||
| 认证 | 管理后台 JWT(/v3/admin/* 走网关鉴权) |
|
||||
| 角色限制 | 房务角色(HOUSE)不可访问,调了会被 403 拦截 |
|
||||
| 幂等性 | 只读查询,幂等 |
|
||||
| 限流 | 走网关默认限流,无接口级特殊限流 |
|
||||
|
||||
## 4. 接口入参
|
||||
|
||||
### 4.1 路径参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| orderId | Long | 是 | 订单 ID,必须大于 0(否则 400「订单 ID 必须大于 0」) |
|
||||
|
||||
### 4.2 请求体 / Query
|
||||
|
||||
无请求体、无 Query 参数。
|
||||
|
||||
## 5. 出参字段
|
||||
|
||||
返回 `Result<SettlementGroupReportRespVO>`。`data` 块结构:**抬头区字段 + 汇总金额字段 + incomeLines 收入逐项行数组 + 7 个成本分类明细数组 + insuranceInfo 保险子块**。costCategories 与 details 两层嵌套已彻底下线。
|
||||
|
||||
### 5.1 抬头区 + 汇总金额(保留字段,口径不变)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Long(String) | 核单记录 ID;未生成时不输出该键 |
|
||||
| orderId | Long(String) | 订单 ID |
|
||||
| orderNo | String | 订单号 |
|
||||
| teamNo | String | 团号(订金未支付为 null,不输出该键) |
|
||||
| productName | String | 产品名 |
|
||||
| productType | String | 产品类型枚举(如 CORE) |
|
||||
| productTypeName | String | 产品类型中文名(字典 product_type 回填) |
|
||||
| customerName | String | 客户姓名 |
|
||||
| departDate | String | 出团日期,格式 yyyy-MM-dd |
|
||||
| returnDate | String | 返回日期,格式 yyyy-MM-dd |
|
||||
| consultantName | String | 定制师姓名 |
|
||||
| travelerComposition | String | 出行人构成(数量为 0 的档不显示,全空为 null),如「1大」「2大 1儿童」 |
|
||||
| travelerCount | Integer | 出行人总数 |
|
||||
| baseOrderAmount | BigDecimal | 订单应收(基础团费),保留两位小数 |
|
||||
| otherIncomeAmount | BigDecimal | 其他收入合计,保留两位小数 |
|
||||
| discountAmount | BigDecimal | 优惠合计(正数表达,冲减应收),保留两位小数 |
|
||||
| adjustedReceivableAmount | BigDecimal | 调整后应收 = baseOrderAmount + otherIncomeAmount − discountAmount,保留两位小数 |
|
||||
| paidAmount | BigDecimal | 已收金额合计(线上 SUCCESS + 线下手工收款),保留两位小数 |
|
||||
| actualRefundedAmount | BigDecimal | 实际退款合计,保留两位小数 |
|
||||
| netRevenueAmount | BigDecimal | 净收入 = 调整后应收 − 实际退款 = incomeLines 各行 amount 合计,保留两位小数 |
|
||||
| netReceivedAmount | BigDecimal | 净实收 = 已收 − 实际退款,保留两位小数 |
|
||||
| outstandingAmount | BigDecimal | 未收金额 = 调整后应收 − 已收(负截 0),保留两位小数 |
|
||||
| ~~hotelCost 等 7 个分类小计~~ | — | **已删除**(见 §10) |
|
||||
| insurancePremium | BigDecimal | 保费合计(原 8 个小计中唯一保留),计入 totalCost,保留两位小数 |
|
||||
| totalCost | BigDecimal | 总成本 = 7 个成本分类明细数组 amount 合计 + insurancePremium,保留两位小数 |
|
||||
| paidCost | BigDecimal | 已付成本,保留两位小数 |
|
||||
| unpaidCost | BigDecimal | 未付成本,保留两位小数 |
|
||||
| grossProfit | BigDecimal | 毛利 = netRevenueAmount − totalCost,保留两位小数 |
|
||||
| grossProfitRate | BigDecimal | 毛利率 = grossProfit ÷ netRevenueAmount,小数表达(如 0.139100 = 13.91%),保留六位小数 |
|
||||
| ~~perCapitaRevenue / perCapitaCost / perCapitaProfit~~ | — | **已删除**(见 §10) |
|
||||
|
||||
### 5.2 incomeLines 收入逐项行(拍平结构,去 details 嵌套)
|
||||
|
||||
固定 4 个 type:BASE_ORDER 订单应收 / OTHER_INCOME 其他收入 / DISCOUNT 优惠(负值)/ ACTUAL_REFUND 实际退款(负值)。同一 type 有多条逐项明细时平铺为多行(用 type + itemName 区分);**某 type 无逐项明细时给一行占位行**(仅 type/typeName/amount,amount = 该 type 聚合值,可能为 0),保证 4 个 type 各至少一行、各行 amount 合计 = netRevenueAmount 不丢数。本数组**不含已收/未收维度**(已收看顶层 paidAmount/outstandingAmount)。
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| type | String | 行类型:BASE_ORDER / OTHER_INCOME / DISCOUNT / ACTUAL_REFUND |
|
||||
| typeName | String | 行类型中文名(字典 settlement_report_line_type) |
|
||||
| itemName | String | 项目名(如 订单应收/增费项目名/优惠名称/退款来源);占位行不下发 |
|
||||
| content | String | 内容说明(如 规格/退款原因);无则不下发 |
|
||||
| source | String | 人工返还来源(仅 ACTUAL_REFUND 人工返还行透出):DRIVER_ONSITE / COMPANY_COMPENSATION |
|
||||
| sourceName | String | 人工返还来源中文名(字典 settlement_refund_source,缺值回退硬编码) |
|
||||
| unitPrice | BigDecimal | 单价,保留两位小数;无单价概念时不下发 |
|
||||
| headCount | Integer | 人数;无人数概念时不下发 |
|
||||
| quantity | BigDecimal | 数量;无数量概念时不下发 |
|
||||
| amount | BigDecimal | 金额,保留两位小数;DISCOUNT / ACTUAL_REFUND 行为**负数**;占位行为该 type 聚合值 |
|
||||
| paymentMethod | String | 付款方式:CASH_PAID / COMPANY_PAID / SIGNED;无则不下发 |
|
||||
| paymentMethodName | String | 付款方式中文名(字典 settlement_payment_method,缺值回退硬编码) |
|
||||
| sourceType | String | 来源:MANUAL / HOUSE_ASSIGNMENT / SCENIC_ASSIGNMENT / ACTIVITY_ASSIGNMENT / MEAL_ASSIGNMENT / FLEET / STAFF_ASSIGNMENT / ORDER_SURCHARGE / SYSTEM;无则不下发 |
|
||||
| sourceTypeName | String | 来源中文名(SettlementDetailSourceType 枚举 label) |
|
||||
| remark | String | 备注;无则不下发 |
|
||||
| voucherUrls | String[] | 凭证 URL 数组;无凭证时不下发 |
|
||||
|
||||
### 5.3 成本 7 个分类明细数组(平铺顶层,空分类给 `[]`)
|
||||
|
||||
7 个数组:**hotelLines(住宿)/ ticketLines(门票)/ mealLines(餐食)/ vehicleLines(用车)/ guideLines(导游)/ photographerLines(摄影)/ otherExpenseLines(其他支出)**。无明细的分类返回空数组 `[]`(不是不下发)。各分类小计由前端自算数组内 amount 合计;7 分类合计 + insurancePremium = totalCost。
|
||||
|
||||
公共列(每个分类行都有,语义相同,下表不再重复):`amount`(核算金额/实际成本,BigDecimal 两位小数,必填)、`paymentMethod`/`paymentMethodName`(付款方式 + 中文名)、`sourceType`/`sourceTypeName`(来源 + 中文名)、`remark`(备注)、`voucherUrls`(凭证 URL 数组)。
|
||||
|
||||
#### 5.3.1 hotelLines 住宿行
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| stayDate | String | 入住日期,yyyy-MM-dd |
|
||||
| hotelName | String | 酒店名称 |
|
||||
| roomTypeName | String | 房型名称 |
|
||||
| roomCount | Integer | 房间数 |
|
||||
| unitPrice | BigDecimal | 单价,两位小数 |
|
||||
| plannedCost | BigDecimal | 计划成本,两位小数 |
|
||||
|
||||
#### 5.3.2 ticketLines 门票行
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| dayDate | String | 游玩日期,yyyy-MM-dd |
|
||||
| scenicName | String | 景区/项目名称 |
|
||||
| specName | String | 规格名称(如 成人票) |
|
||||
| ticketCount | Integer | 票数 |
|
||||
| ticketUnitPrice | BigDecimal | 门票单价,两位小数 |
|
||||
| sellPrice | BigDecimal | 销售价,两位小数;无则不下发 |
|
||||
| plannedCost | BigDecimal | 计划成本,两位小数 |
|
||||
|
||||
#### 5.3.3 mealLines 餐食行
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| mealDate | String | 用餐日期,yyyy-MM-dd |
|
||||
| mealName | String | 餐食名称 |
|
||||
| mealType | String | 餐食类型:BREAKFAST / LUNCH / DINNER / SELF |
|
||||
| mealTypeName | String | 餐食类型中文名(字典 meal_type) |
|
||||
| quantity | Integer | 份数 |
|
||||
| unitPrice | BigDecimal | 单价,两位小数 |
|
||||
|
||||
#### 5.3.4 vehicleLines 用车行(VEHICLE_FEE 逐日车费行 + EXPENSE 车辆费用行的稀疏并集,每行仅本族字段非 null)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| 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 | BigDecimal | [VEHICLE_FEE] 日单价(核算单价列),两位小数 |
|
||||
| paymentTypeName | String | [VEHICLE_FEE] 车务付款类型名称(如 现金已付) |
|
||||
| expenseType | String | [EXPENSE] 车辆费用类型:FUEL / TOLL / PARKING / RENTAL / MAINTENANCE |
|
||||
| expenseTypeName | String | [EXPENSE] 车辆费用类型中文名(字典 expense_type) |
|
||||
| projectName | String | [EXPENSE] 项目名称(如 全程油费) |
|
||||
| expenseDate | String | [EXPENSE] 费用发生日期,yyyy-MM-dd |
|
||||
|
||||
说明:vehicleLines **只含已确认行**(与车辆成本口径一致);无单价/数量概念,quantity 恒不下发。
|
||||
|
||||
#### 5.3.5 guideLines / photographerLines 人员费用行(两数组同一行结构)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| serviceDate | String | 服务日期,yyyy-MM-dd;无服务日时不下发 |
|
||||
| name | String | 人员姓名 |
|
||||
| serviceType | String | 服务类型:GUIDE / PHOTOGRAPHER |
|
||||
| serviceTypeName | String | 服务类型中文名(字典 staff_role) |
|
||||
|
||||
说明:人员费用无单价/数量概念,均不下发。
|
||||
|
||||
#### 5.3.6 otherExpenseLines 其他支出行(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,如 话补) |
|
||||
|
||||
### 5.4 insuranceInfo 保险子块(新增)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| insured | Boolean | 是否已投保(有有效保单),恒下发 |
|
||||
| productName | String | 保险产品名称;无有效保单时不下发 |
|
||||
| bizType | String | 业务类型:ORDER / DRIVER;无有效保单时不下发 |
|
||||
| bizTypeName | String | 业务类型中文名(字典 insurance_biz_type,缺值回退硬编码:ORDER 订单险 / DRIVER 司机险) |
|
||||
| extPolicyNo | String | 外部保单号;无有效保单时不下发 |
|
||||
| totalPremium | BigDecimal | 保费合计(与顶层 insurancePremium 同口径,计入 totalCost),两位小数,恒下发(无保单为 0) |
|
||||
|
||||
## 6. 枚举 / 数据字典
|
||||
|
||||
本次无新增/变更枚举值,以下为出参涉及的既有枚举与字典(值 + 中文名):
|
||||
|
||||
| 字典/枚举 | 取值 → 中文名 | 用于字段 |
|
||||
|-----------|--------------|----------|
|
||||
| settlement_report_line_type(字典) | BASE_ORDER → 订单应收;OTHER_INCOME → 其他收入;DISCOUNT → 优惠;ACTUAL_REFUND → 实际退款 | incomeLines[].typeName |
|
||||
| settlement_payment_method(字典) | CASH_PAID → 现金已付;COMPANY_PAID → 公司支付;SIGNED → 签单 | 各行 paymentMethodName |
|
||||
| settlement_refund_source(字典) | DRIVER_ONSITE → 司机现场返还;COMPANY_COMPENSATION → 公司赔付 | incomeLines[].sourceName(仅 ACTUAL_REFUND 人工返还行) |
|
||||
| SettlementDetailSourceType(枚举) | MANUAL → 手工;HOUSE_ASSIGNMENT → 配房结果;SCENIC_ASSIGNMENT → 景区;ACTIVITY_ASSIGNMENT → 游玩项目;MEAL_ASSIGNMENT → 餐饮安排;FLEET → 车务;STAFF_ASSIGNMENT → 人员安排;ORDER_SURCHARGE → 订单增费;SYSTEM → 系统 | 各行 sourceTypeName |
|
||||
| meal_type(字典) | BREAKFAST → 早餐;LUNCH → 午餐;DINNER → 晚餐;SELF → 自理 | mealLines[].mealTypeName |
|
||||
| staff_role(字典) | GUIDE → 导游;PHOTOGRAPHER → 摄影师 | guideLines/photographerLines[].serviceTypeName |
|
||||
| expense_type(字典) | FUEL → 油费;TOLL → 过路费;PARKING → 停车费;RENTAL → 租车费;MAINTENANCE → 维保费;OTHER → 其他 | vehicleLines[].expenseTypeName / otherExpenseLines[].expenseTypeName |
|
||||
| subsidy_type(字典) | PHONE → 话补;OVERTIME → 加班补贴 | otherExpenseLines[].subsidyTypeName |
|
||||
| insurance_biz_type(字典) | ORDER → 订单险;DRIVER → 司机险 | insuranceInfo.bizTypeName |
|
||||
|
||||
原 costCategories 用的 settlement_category 字典(HOTEL/TICKET/MEAL/VEHICLE/GUIDE/PHOTOGRAPHER/OTHER_EXPENSE/INSURANCE 8 值)随套层下线**不再出现于本接口出参**;7 个分类改由数组名(hotelLines 等)直接判别,无需 category 字段窄化。
|
||||
|
||||
## 7. 错误码
|
||||
|
||||
本次无新增错误码,沿用既有:
|
||||
|
||||
| code | message | 触发场景 |
|
||||
|------|---------|----------|
|
||||
| 400 | 订单 ID 必须大于 0 | orderId 路径参数校验失败 |
|
||||
| 403 | 无权限访问 | 房务角色(HOUSE)JWT 调用 |
|
||||
| 581007 | 订单不存在 | orderId 查不到订单 |
|
||||
|
||||
## 8. 示例
|
||||
|
||||
### 8.1 典型成功(含住宿/门票/车辆多分类成本 + 已投保的真实单)
|
||||
|
||||
以下为部署后网关实调的真实返回(订单 2087487607792463873,2026-08-14 测试服实测):3 天行程,住宿 2 晚 × 320、门票 6 项、用车 3 天 × 1080.50,已投保订单险 88.00;无增费/优惠/退款,incomeLines 后 3 行为占位行。
|
||||
|
||||
GET /v3/admin/order/2087487607792463873/settlement/reports/group
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"id": "2087487623802122242",
|
||||
"orderId": "2087487607792463873",
|
||||
"orderNo": "HL20260812183323909",
|
||||
"teamNo": "26-6276",
|
||||
"productName": "测试核心产品-多档-固定订金",
|
||||
"productType": "CORE",
|
||||
"productTypeName": "核心产品",
|
||||
"customerName": "沈梦瑶",
|
||||
"departDate": "2026-08-28",
|
||||
"returnDate": "2026-08-30",
|
||||
"consultantName": "dzs_yst",
|
||||
"travelerComposition": "1大",
|
||||
"baseOrderAmount": 5000.0,
|
||||
"otherIncomeAmount": 0,
|
||||
"discountAmount": 0,
|
||||
"adjustedReceivableAmount": 5000.0,
|
||||
"paidAmount": 5000.0,
|
||||
"actualRefundedAmount": 0,
|
||||
"netRevenueAmount": 5000.0,
|
||||
"netReceivedAmount": 5000.0,
|
||||
"outstandingAmount": 0.0,
|
||||
"insurancePremium": 88.0,
|
||||
"totalCost": 4304.5,
|
||||
"paidCost": 4304.5,
|
||||
"unpaidCost": 0,
|
||||
"grossProfit": 695.5,
|
||||
"grossProfitRate": 0.1391,
|
||||
"travelerCount": 1,
|
||||
"incomeLines": [
|
||||
{
|
||||
"type": "BASE_ORDER",
|
||||
"typeName": "订单应收",
|
||||
"itemName": "订单应收",
|
||||
"amount": 5000.0
|
||||
},
|
||||
{
|
||||
"type": "OTHER_INCOME",
|
||||
"typeName": "其他收入",
|
||||
"amount": 0
|
||||
},
|
||||
{
|
||||
"type": "DISCOUNT",
|
||||
"typeName": "优惠",
|
||||
"amount": 0
|
||||
},
|
||||
{
|
||||
"type": "ACTUAL_REFUND",
|
||||
"typeName": "实际退款",
|
||||
"amount": 0
|
||||
}
|
||||
],
|
||||
"hotelLines": [
|
||||
{
|
||||
"stayDate": "2026-08-28",
|
||||
"hotelName": "呼伦贝尔香格里拉大酒店",
|
||||
"roomTypeName": "大床房",
|
||||
"roomCount": 1,
|
||||
"unitPrice": 320.0,
|
||||
"plannedCost": 320.0,
|
||||
"amount": 320.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "HOUSE_ASSIGNMENT",
|
||||
"sourceTypeName": "配房结果",
|
||||
"remark": "裸HTTP派房D1"
|
||||
},
|
||||
{
|
||||
"stayDate": "2026-08-29",
|
||||
"hotelName": "呼伦贝尔香格里拉大酒店",
|
||||
"roomTypeName": "大床房",
|
||||
"roomCount": 1,
|
||||
"unitPrice": 320.0,
|
||||
"plannedCost": 320.0,
|
||||
"amount": 320.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "HOUSE_ASSIGNMENT",
|
||||
"sourceTypeName": "配房结果",
|
||||
"remark": "裸HTTP派房D2"
|
||||
}
|
||||
],
|
||||
"ticketLines": [
|
||||
{
|
||||
"dayDate": "2026-08-29",
|
||||
"scenicName": "额尔古纳湿地漂流",
|
||||
"specName": "成人票",
|
||||
"ticketCount": 1,
|
||||
"ticketUnitPrice": 119.0,
|
||||
"plannedCost": 119.0,
|
||||
"amount": 119.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "ACTIVITY_ASSIGNMENT",
|
||||
"sourceTypeName": "游玩项目"
|
||||
},
|
||||
{
|
||||
"dayDate": "2026-08-30",
|
||||
"scenicName": "超长冰滑梯(不限次)",
|
||||
"specName": "成人票",
|
||||
"ticketCount": 1,
|
||||
"ticketUnitPrice": 29.0,
|
||||
"plannedCost": 29.0,
|
||||
"amount": 29.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "ACTIVITY_ASSIGNMENT",
|
||||
"sourceTypeName": "游玩项目"
|
||||
},
|
||||
{
|
||||
"dayDate": "2026-08-29",
|
||||
"scenicName": "呼和诺尔草原旅游区",
|
||||
"specName": "成人票",
|
||||
"ticketCount": 1,
|
||||
"ticketUnitPrice": 59.0,
|
||||
"plannedCost": 59.0,
|
||||
"amount": 59.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "SCENIC_ASSIGNMENT",
|
||||
"sourceTypeName": "景区"
|
||||
},
|
||||
{
|
||||
"dayDate": "2026-08-29",
|
||||
"scenicName": "套娃景区",
|
||||
"specName": "成人票",
|
||||
"ticketCount": 1,
|
||||
"ticketUnitPrice": 99.0,
|
||||
"plannedCost": 99.0,
|
||||
"amount": 99.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "SCENIC_ASSIGNMENT",
|
||||
"sourceTypeName": "景区"
|
||||
},
|
||||
{
|
||||
"dayDate": "2026-08-30",
|
||||
"scenicName": "恩和俄罗斯民族乡",
|
||||
"specName": "成人票",
|
||||
"ticketCount": 1,
|
||||
"ticketUnitPrice": 29.0,
|
||||
"plannedCost": 29.0,
|
||||
"amount": 29.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "SCENIC_ASSIGNMENT",
|
||||
"sourceTypeName": "景区"
|
||||
},
|
||||
{
|
||||
"dayDate": "2026-08-30",
|
||||
"scenicName": "蓝房子(乌苏浪子湖)",
|
||||
"specName": "成人票",
|
||||
"ticketCount": 1,
|
||||
"ticketUnitPrice": 0.0,
|
||||
"plannedCost": 0.0,
|
||||
"amount": 0.0,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "SCENIC_ASSIGNMENT",
|
||||
"sourceTypeName": "景区"
|
||||
}
|
||||
],
|
||||
"mealLines": [],
|
||||
"vehicleLines": [
|
||||
{
|
||||
"serviceDate": "2026-08-28",
|
||||
"startDate": "2026-08-28",
|
||||
"endDate": "2026-08-28",
|
||||
"vehiclePlate": "蒙A-S6666",
|
||||
"vehicleModelName": "丰田赛那",
|
||||
"driverName": "菜单师傅",
|
||||
"dailyPrice": 1080.5,
|
||||
"paymentTypeName": "现金已付",
|
||||
"amount": 1080.5,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "FLEET",
|
||||
"sourceTypeName": "车务",
|
||||
"voucherUrls": []
|
||||
},
|
||||
{
|
||||
"serviceDate": "2026-08-29",
|
||||
"startDate": "2026-08-29",
|
||||
"endDate": "2026-08-29",
|
||||
"vehiclePlate": "蒙A-S6666",
|
||||
"vehicleModelName": "丰田赛那",
|
||||
"driverName": "菜单师傅",
|
||||
"dailyPrice": 1080.5,
|
||||
"paymentTypeName": "现金已付",
|
||||
"amount": 1080.5,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "FLEET",
|
||||
"sourceTypeName": "车务",
|
||||
"voucherUrls": []
|
||||
},
|
||||
{
|
||||
"serviceDate": "2026-08-30",
|
||||
"startDate": "2026-08-30",
|
||||
"endDate": "2026-08-30",
|
||||
"vehiclePlate": "蒙A-S6666",
|
||||
"vehicleModelName": "丰田赛那",
|
||||
"driverName": "菜单师傅",
|
||||
"dailyPrice": 1080.5,
|
||||
"paymentTypeName": "现金已付",
|
||||
"amount": 1080.5,
|
||||
"paymentMethod": "CASH_PAID",
|
||||
"paymentMethodName": "现金已付",
|
||||
"sourceType": "FLEET",
|
||||
"sourceTypeName": "车务",
|
||||
"voucherUrls": []
|
||||
}
|
||||
],
|
||||
"guideLines": [],
|
||||
"photographerLines": [],
|
||||
"otherExpenseLines": [],
|
||||
"insuranceInfo": {
|
||||
"insured": true,
|
||||
"productName": "“保游天下”平安自驾游综合保障计划",
|
||||
"bizType": "ORDER",
|
||||
"bizTypeName": "订单险",
|
||||
"extPolicyNo": "MOCKPOL-2087487619058364419",
|
||||
"totalPremium": 88.0
|
||||
}
|
||||
},
|
||||
"traceId": null,
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
勾稽验证(以上真实数据):incomeLines 合计 = 5000 + 0 + 0 + 0 = 5000.00 = netRevenueAmount ✅;hotelLines(640) + ticketLines(335) + mealLines(0) + vehicleLines(3241.50) + guideLines(0) + photographerLines(0) + otherExpenseLines(0) + insurancePremium(88) = 4304.50 = totalCost ✅;netRevenueAmount − totalCost = 695.50 = grossProfit ✅。
|
||||
|
||||
### 8.2 边界情况(无逐项明细的 type 给占位行 amount=聚合值 + 空成本分类给 `[]`)
|
||||
|
||||
场景:订单有 500 元其他收入(手工录入、无逐项明细来源)和 200 元优惠(无逐项明细),无退款;餐食/导游/摄影/其他支出均无明细。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"orderId": "2087487607792463899",
|
||||
"orderNo": "HL20260814001",
|
||||
"baseOrderAmount": 5000.00,
|
||||
"otherIncomeAmount": 500.00,
|
||||
"discountAmount": 200.00,
|
||||
"adjustedReceivableAmount": 5300.00,
|
||||
"paidAmount": 5300.00,
|
||||
"actualRefundedAmount": 0,
|
||||
"netRevenueAmount": 5300.00,
|
||||
"netReceivedAmount": 5300.00,
|
||||
"outstandingAmount": 0.00,
|
||||
"insurancePremium": 0,
|
||||
"totalCost": 640.00,
|
||||
"paidCost": 640.00,
|
||||
"unpaidCost": 0,
|
||||
"grossProfit": 4660.00,
|
||||
"grossProfitRate": 0.879245,
|
||||
"travelerCount": 2,
|
||||
"incomeLines": [
|
||||
{ "type": "BASE_ORDER", "typeName": "订单应收", "itemName": "订单应收", "amount": 5000.00 },
|
||||
{ "type": "OTHER_INCOME", "typeName": "其他收入", "amount": 500.00 },
|
||||
{ "type": "DISCOUNT", "typeName": "优惠", "amount": -200.00 },
|
||||
{ "type": "ACTUAL_REFUND", "typeName": "实际退款", "amount": 0 }
|
||||
],
|
||||
"hotelLines": [
|
||||
{
|
||||
"stayDate": "2026-08-28",
|
||||
"hotelName": "草原明珠大酒店",
|
||||
"roomTypeName": "标间",
|
||||
"roomCount": 1,
|
||||
"unitPrice": 320.00,
|
||||
"plannedCost": 320.00,
|
||||
"amount": 640.00,
|
||||
"paymentMethod": "COMPANY_PAID",
|
||||
"paymentMethodName": "公司支付",
|
||||
"sourceType": "HOUSE_ASSIGNMENT",
|
||||
"sourceTypeName": "配房结果"
|
||||
}
|
||||
],
|
||||
"ticketLines": [],
|
||||
"mealLines": [],
|
||||
"vehicleLines": [],
|
||||
"guideLines": [],
|
||||
"photographerLines": [],
|
||||
"otherExpenseLines": [],
|
||||
"insuranceInfo": { "insured": false, "totalPremium": 0 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
边界要点:
|
||||
|
||||
1. **OTHER_INCOME / DISCOUNT 占位行**:只有 type/typeName/amount 三键,amount = 该 type 聚合值(500 / −200,**不是 0**),占位行也参与「各行合计 = 净收入」勾稽;
|
||||
2. **空成本分类给 `[]`**:ticketLines 等空分类是空数组,不是不下发该键;
|
||||
3. **未投保**:insuranceInfo 恒下发,insured=false、保单字段(productName/bizType/bizTypeName/extPolicyNo)键不存在、totalPremium=0;顶层 insurancePremium=0;
|
||||
4. 占位行无 itemName 等明细列(NON_NULL 省略),前端按「只有 type/typeName/amount 三键」识别占位行。
|
||||
|
||||
### 8.3 业务失败(已删字段读取 undefined——新旧结构对比)
|
||||
|
||||
**旧代码读法全部失效**(字段不是 null,是键不存在):
|
||||
|
||||
```json
|
||||
// ❌ 修改前(旧结构,已下线)
|
||||
{
|
||||
"data": {
|
||||
"hotelCost": 640.00,
|
||||
"ticketCost": 335.00,
|
||||
"perCapitaRevenue": 5000.00,
|
||||
"perCapitaCost": 4304.50,
|
||||
"perCapitaProfit": 695.50,
|
||||
"incomeLines": [
|
||||
{
|
||||
"type": "OTHER_INCOME",
|
||||
"typeName": "其他收入",
|
||||
"amount": 500.00,
|
||||
"details": [
|
||||
{ "itemName": "增费-升级房型", "amount": 500.00, "unitPrice": 500.00, "quantity": 1 }
|
||||
]
|
||||
}
|
||||
],
|
||||
"costCategories": [
|
||||
{
|
||||
"category": "HOTEL",
|
||||
"categoryName": "住宿",
|
||||
"amount": 640.00,
|
||||
"lines": [ { "stayDate": "2026-08-28", "hotelName": "草原明珠大酒店", "amount": 640.00 } ]
|
||||
},
|
||||
{ "category": "INSURANCE", "categoryName": "保险", "amount": 88.00, "lines": [] }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
// ✅ 修改后(新结构,同一份数据)
|
||||
{
|
||||
"data": {
|
||||
"insurancePremium": 88.00,
|
||||
"incomeLines": [
|
||||
{ "type": "OTHER_INCOME", "typeName": "其他收入", "itemName": "增费-升级房型", "unitPrice": 500.00, "quantity": 1, "amount": 500.00 }
|
||||
],
|
||||
"hotelLines": [ { "stayDate": "2026-08-28", "hotelName": "草原明珠大酒店", "amount": 640.00 } ],
|
||||
"ticketLines": [],
|
||||
"mealLines": [],
|
||||
"vehicleLines": [],
|
||||
"guideLines": [],
|
||||
"photographerLines": [],
|
||||
"otherExpenseLines": [],
|
||||
"insuranceInfo": { "insured": true, "productName": "保游畅享境内游保险", "bizType": "ORDER", "bizTypeName": "订单险", "extPolicyNo": "PY20260814001", "totalPremium": 88.00 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
另附通用业务失败响应(与修改前一致):
|
||||
|
||||
```json
|
||||
{ "code": 403, "message": "无权限访问", "success": false }
|
||||
```
|
||||
|
||||
```json
|
||||
{ "code": 581007, "message": "订单不存在", "success": false }
|
||||
```
|
||||
|
||||
## 9. 业务边界
|
||||
|
||||
**适用**:
|
||||
|
||||
- 核单页查看整团收入逐项、成本 7 分类逐项、保险信息、毛利汇总;各分类小计与占比由前端自算。
|
||||
|
||||
**不适用**:
|
||||
|
||||
- 已收/未收维度分析 —— incomeLines 是**应收口径**(不含收款维度),已收/未收看顶层 paidAmount / outstandingAmount / netReceivedAmount。
|
||||
|
||||
**特殊边界(前端必知)**:
|
||||
|
||||
1. **勾稽关系(可用来校验渲染)**:
|
||||
- `incomeLines 各行 amount 合计 = netRevenueAmount`(占位行也参与合计);
|
||||
- `7 个成本分类明细数组 amount 合计 + insurancePremium = totalCost`;
|
||||
- `netRevenueAmount − totalCost = grossProfit`。
|
||||
2. **占位行不丢数**:某 type 无逐项明细时仍有一行,amount = 该 type 聚合值(可能非 0)。前端按 type 固定渲染 4 块时,不要因为「没有 details」就不渲染该块。
|
||||
3. **DISCOUNT / ACTUAL_REFUND 行 amount 为负数**,合计时直接相加即可,不要取绝对值。
|
||||
4. **空成本分类是 `[]` 不是键不存在**;行内 null 字段才是键不存在(NON_NULL 省略)。
|
||||
5. **insuranceInfo 恒下发**:无有效保单时 insured=false、保单字段键不存在、totalPremium=0;不要按「insuranceInfo 不存在」判未投保。
|
||||
6. **vehicleLines 只含已确认行**(与车辆成本口径一致),未确认/已取消的派单不出现在数组里。
|
||||
7. **vehicleLines / otherExpenseLines 是稀疏并集行**:每行只有本族字段非 null(VEHICLE_FEE 族 vs EXPENSE 族、EXPENSE vs SUBSIDY),渲染列时按字段是否存在判别行种。
|
||||
|
||||
## 10. 修改前后对比
|
||||
|
||||
### 10.1 字段级对比
|
||||
|
||||
| 位置 | 字段 | 修改前 | 修改后 |
|
||||
|------|------|--------|--------|
|
||||
| 顶层 | perCapitaRevenue | 人均营收 | **已删除**(需要时 自算 netRevenueAmount ÷ travelerCount) |
|
||||
| 顶层 | perCapitaCost | 人均成本 | **已删除**(自算 totalCost ÷ travelerCount) |
|
||||
| 顶层 | perCapitaProfit | 人均毛利 | **已删除**(自算 grossProfit ÷ travelerCount) |
|
||||
| 顶层 | hotelCost / ticketCost / mealCost / vehicleCost / guideCost / photographerCost / otherExpenseCost | 7 个成本分类小计 | **已删除**(自算对应分类数组 amount 合计) |
|
||||
| 顶层 | costCategories | 成本套层:8 分类行(含 INSURANCE),每行 {category, categoryName, amount, lines[]} | **已删除**,改 7 个分类明细数组平铺顶层 |
|
||||
| 顶层 | hotelLines … otherExpenseLines | 无(明细埋在 costCategories[].lines) | **新增** 7 个分类明细数组,行结构不变(原 lines 元素直接上移),空分类 `[]` |
|
||||
| 顶层 | insurancePremium | 保费合计,8 小计之一 | **保留**,口径不变,仍计入 totalCost |
|
||||
| 顶层 | insuranceInfo | 无(保险只是 costCategories 里一行汇总) | **新增** 保险子块(insured/productName/bizType/bizTypeName/extPolicyNo/totalPremium) |
|
||||
| incomeLines[] | details | 每行内嵌逐项明细数组 | **已删除**,逐项明细拍平为多行 |
|
||||
| incomeLines[] | itemName/content/unitPrice/headCount/quantity/paymentMethod(+/Name)/source(+/Name)/sourceType(+/Name)/remark/voucherUrls | 在 details 元素上 | **上移到行本身**,每行带全列 |
|
||||
| incomeLines[] | 行数 | 固定 4 行(每 type 一行汇总) | 每 type ≥ 1 行:有明细平铺多行,无明细给占位行(amount=聚合值) |
|
||||
| 顶层 | 抬头区 + 汇总金额其余字段 | 原样 | **零变化** |
|
||||
|
||||
### 10.2 行为级对比
|
||||
|
||||
| 场景 | 修改前 | 修改后 |
|
||||
|------|--------|--------|
|
||||
| 渲染收入明细 | 遍历 incomeLines[4],钻每行 details 数组 | 直接遍历 incomeLines 多行,按 type 分组渲染;占位行只有三键 |
|
||||
| 渲染成本明细 | 遍历 costCategories[8],按 category 窄化 lines 元素结构 | 直接按数组名取 7 个分类数组,行结构即分类专属结构,无需窄化 |
|
||||
| 成本分类小计 | 读 hotelCost 等 7 字段 / costCategories[].amount | **前端自算**各分类数组 amount 合计 |
|
||||
| 保险信息 | costCategories 里 category=INSURANCE 一行汇总金额 | insuranceInfo 子块(产品名/保单号/保费合计)+ 顶层 insurancePremium |
|
||||
| 人均指标 | 直接读 perCapita* 三字段 | **前端自算**(汇总值 ÷ travelerCount,注意 travelerCount=0 时不展示) |
|
||||
| 分类判别 | category 枚举(settlement_category 字典) | 数组名(hotelLines 等),settlement_category 不再出现于出参 |
|
||||
|
||||
## 11. 影响评估 / 回滚
|
||||
|
||||
### 11.1 影响评估
|
||||
|
||||
- **破坏兼容性**:⚠️ **破坏性变更**。删除 13 处出参(3 个人均指标 + 7 个成本分类小计 + costCategories 套层 + incomeLines[].details 嵌套 + INSURANCE 分类行),凡读取这些字段的前端代码必须改造。
|
||||
- **前端是否必须同步上线**:**是**。后端上线后旧字段立即消失,读旧结构的页面会得到 undefined/空白,前端新结构改造需与后端同窗口上线。
|
||||
- **改造点清单**:
|
||||
1. 删 perCapitaRevenue/perCapitaCost/perCapitaProfit 所有读取,需要人均处改自算;
|
||||
2. 删 hotelCost 等 7 个小计字段读取,改自算 7 个分类数组 amount 合计;
|
||||
3. 成本渲染从 costCategories 两层遍历改为直读 7 个分类数组,去掉按 category 窄化的判别逻辑;
|
||||
4. 收入渲染从 incomeLines[].details 改为 incomeLines 平铺多行,按 type 分组;适配占位行(仅 type/typeName/amount);
|
||||
5. 保险区块改读 insuranceInfo + insurancePremium;
|
||||
6. 空分类按 `[]` 空态渲染,未投保按 insured=false 空态渲染。
|
||||
- **无 DDL、无枚举值、无字典变更**;汇总金额数值口径零漂移(netRevenueAmount/totalCost/grossProfit 修改前后同值)。
|
||||
|
||||
### 11.2 回滚方案
|
||||
|
||||
- 后端回滚 = revert PR #5966(merge commit c8cae25131),重启 hl-order-service-v3,旧结构(costCategories/details/小计/人均)恢复。
|
||||
- 前端若已按新结构上线而后端回滚,新字段读到 undefined → 前端回滚需同步;建议前后端同窗口切换。
|
||||
- 零 DDL / 零数据迁移,回滚无数据残留风险。
|
||||
|
||||
## 12. 注意事项
|
||||
|
||||
1. **NON_NULL 省略**:全出参带 @JsonInclude(NON_NULL),null 字段不下发该键(不是下 null);占位行只有 type/typeName/amount 三键,前端读取可空字段必须兜底。
|
||||
2. **空数组与键不存在的区别**:7 个成本分类数组空分类下 `[]`(键存在);行内可空列是键不存在。不要混用两种判空。
|
||||
3. **Long 主键序列化为字符串**(id / orderId),前端按 string 处理,不要 Number() 转换。
|
||||
4. **金额保留两位小数**,BigDecimal JSON 输出为 number(如 5000.00);grossProfitRate 是六位小数的小数(0.139100 = 13.91%),展示百分比需 ×100。
|
||||
5. **DISCOUNT / ACTUAL_REFUND 行 amount 为负数**,合计直接相加;占位行 amount 也可能是非 0 聚合值。
|
||||
6. **占位行参与勾稽**:「incomeLines 合计 = netRevenueAmount」成立的前提是把占位行也算进去;若前端只渲染有 itemName 的行,合计校验会对不上。
|
||||
7. 本变更只影响单团核算表(reports/group);主报账人报账表(reports/reimbursement)结构不受影响。
|
||||
|
||||
## 13. 关联 / 联系人
|
||||
|
||||
- Issue #5963:https://git.1814.love:8443/wx/HL/issues/5963
|
||||
- PR #5966:https://git.1814.love:8443/wx/HL/pulls/5966
|
||||
- Commit:https://git.1814.love:8443/wx/HL/commit/c8cae25131
|
||||
- 服务:hl-order-service-v3(端口 8086)
|
||||
- 后端负责人:yst(腰苏图)
|
||||
|
||||
## 14. 验证证据
|
||||
|
||||
- 代码已合并 dev-v3(PR #5966,merge commit c8cae25131)并部署测试服,网关实调验证通过(§8.1 为真实返回,订单 2087487607792463873,2026-08-14 实测)。
|
||||
- 勾稽实证:incomeLines 合计 5000.00 = netRevenueAmount;7 分类合计 4216.50 + insurancePremium 88.00 = 4304.50 = totalCost;5000.00 − 4304.50 = 695.50 = grossProfit。
|
||||
- 前端联调验证点:旧 13 处字段消费点全部改造;§8.2 占位行(amount=聚合值非 0)与空分类 `[]` 渲染;§8.3 新旧结构对照迁移;未投保 insuranceInfo 空态。
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户