--- schema: "hl-changelog/v2" ticket: "8418" title: "团期名单 GB-ADM-003 逐户纯增流程 / 核单 / 结算三对状态字段:flowStatus / reviewStatus / settlementStatus 及各自中文名" consumer: "admin" author: "jw(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "pending" frontend_owner: "" frontend_ref: "" target_release: "" verified_at: "" status_note: "PR #8420 已合并 dev-v3(58da1df2a),已部署 TEST 并经网关验收 AC-1~AC-9 全部通过。GET /v3/admin/order/group-batch/{groupBatchId}/orders 的 records[] 每户纯增 6 个只读字段:flowStatus / flowStatusName、reviewStatus / reviewStatusName、settlementStatus / settlementStatusName;入参、判权、分页、排序与既有字段全部不变,零 DDL、零写入。前端需:名单「状态」列改用 flowStatusName(原型里的 processStatus 就是它,后端从未提供过 processStatus);需要单独展示核单 / 结算进度时用 reviewStatusName / settlementStatusName。注意 reviewStatus / settlementStatus 与团期核单 GroupSettlementRespVO(#8361)同名字段含义相反,与财务 tab 的 items[].settleStatus 也不是一回事。" updated_at: "2026-09-27" base: "dev-v3" --- # 团期名单: GB-ADM-003 逐户补流程 / 核单 / 结算三对状态(管理后台) > **存放目录**: 二期(v3) → `changelogs-v2/2026-09/` > > **服务**: hl-order-service-v3 > **PR**: #8420 > **Issue**: #8418 > **日期**: 2026-09-27 > **影响范围**: 管理后台团期详情「子订单」tab 名单的逐户状态列 --- ## ⚠️ 关键变化 1. **纯增 6 个响应字段,既有字段一个不动**:`records[]` 每户新增 `flowStatus` / `flowStatusName`(流程细状态)、`reviewStatus` / `reviewStatusName`(逐户核单)、`settlementStatus` / `settlementStatusName`(逐户结算,即财务复核)。 2. **同名不同义,别拿错**:本名单的 `reviewStatus` 是**逐户核单**、`settlementStatus` 是**逐户结算**;团期核单接口 `GroupSettlementRespVO`(#8361)里同名的 `reviewStatus` 是**团级复核**、`settlementStatus` 是**团级核单**,含义正好相反,而且那边是一团一行。 3. **不是尾款结清**:财务 tab(GB-ADM-040)的 `items[].settleStatus`(已结清 / 待收尾款 / 已退团)表示尾款收没收齐,和本名单的 `settlementStatus` 无关。 4. **旧版接口文档里的 `processStatus` 从未实现**,接口文档 GB-ADM-003 已改为 `flowStatus` / `flowStatusName`,按原型做「状态」列请读 `flowStatusName`。 --- ## 一、背景 团期进入核单以后,运营在团期详情「子订单」tab 里看不出每户走到了核单 / 结算的哪一步,只能逐户点进订单详情看。#8340 / #8341 已让子订单的流程、核单、结算三列跟随团期动作同步写入,本单把这三列连同中文名原样透出到名单上。本单**只读透出**,不改任何写入与流转。 三列由下列动作写入(前端理解状态来源用,本单不改): | 动作 | flowStatus | reviewStatus | settlementStatus | 来源 | |---|---|---|---|---| | 团期出行完毕 | `PENDING_REVIEW` 待核单 | `PENDING` 待核算 | 不写 | #8340 | | 团期发起核单 | `REVIEWING` 核单中 | `IN_PROGRESS` 核算中 | 不写 | #8341 | | 逐户核单提交(定稿) | `PENDING_SETTLE` 待结算 | `COMPLETED` 已完成 | `PENDING` 待财务复核 | 既有 | | 团期结算 `/settle` | `SETTLED` 已结算 | `COMPLETED` 已完成 | `COMPLETED` 已结算 | #8341 | | 团期反结算 `/settle/reopen` | `PENDING_SETTLE` 待结算 | `COMPLETED` 已完成 | `PENDING` 待财务复核 | #8341 | --- ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 团期下子订单列表(GB-ADM-003 名单) | GET | `/v3/admin/order/group-batch/{groupBatchId}/orders` | 出参新增字段 | `records[]` 每户纯增 6 个字段,入参与既有字段不变 | 网关无改动;无新增权限码;无新增错误码;无 DB schema 变更。 --- ## 三、接口详情 ### 1. 团期下子订单列表(GB-ADM-003 名单) `GET /v3/admin/order/group-batch/{groupBatchId}/orders` **VO**: `PageResult` #### 使用场景 管理后台团期详情「子订单」tab 加载名单时调用,一户一行。本次起每行多带流程细状态、逐户核单、逐户结算三对「码 + 中文名」,名单「状态」列与核单 / 结算进度不必再逐户进订单详情查。 #### 入参 本单不变。 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |------|------|------|------|------|------| | groupBatchId | Path | Long | ✅ | 团期须存在 | 团期 ID | | page | Query | Integer | 否 | 缺省 1;<1 归一为 1 | 页码,从 1 起 | | pageSize | Query | Integer | 否 | 缺省 20;<1 归一为 20;>200 截断为 200 | 每页条数 | | includeTravelers | Query | Boolean | 否 | 缺省 true | 是否附出行人明细(证件号 / 手机号一律不返回) | | includeNeeds | Query | Boolean | 否 | 缺省 true | 是否附房数 / 房型 / 特殊需求 | | includeCancelled | Query | Boolean | 否 | 缺省 false | 是否含已取消子订单(缺省只返在团户) | #### 出参 `Result>` 分页信封: | 字段 | 类型 | 说明 | |------|------|------| | records | Array\ | 本页子订单,一户一行(字段见下表) | | total | Integer | 符合条件的子订单总数 | | page | Integer | 当前页码 | | pageSize | Integer | 每页条数 | `records[]` 单行(**加粗为本次新增**,其余不变): | 字段 | 类型 | 说明 | |------|------|------| | orderId | String(Long) | 子订单 ID | | orderNo | String | 订单编号 | | teamNo | String | 团号(订金支付成功后生成;未付订金为 null) | | customerName | String | 客户姓名 | | participantCount | Integer | 出行人总数 | | orderStatus | String | 订单状态码 | | orderStatusName | String | 订单状态中文名 | | **flowStatus** | String | **新增**。流程细状态码,`order_main.flow_status` 原值,与订单详情 `main.flowStatus` 同值;`OrderFlowStatus` 12 值,见六.5 | | **flowStatusName** | String | **新增**。流程细状态中文名,与订单详情 `GET /v3/admin/order/{id}` 的 `main.flowStatusName` 同规则:`AWAITING_PAY` 显示「待补全信息」,其余取枚举中文名;码为 null 时为 null;未知码回落原码 | | **reviewStatus** | String | **新增**。逐户核单状态码,`order_main.review_status`:`NONE` / `PENDING` / `IN_PROGRESS` / `COMPLETED`;出行前为 null | | **reviewStatusName** | String | **新增**。逐户核单状态中文名,与订单详情 `main.reviewStatusName` 同规则:`NONE`、`PENDING` →「待核算」,`IN_PROGRESS` →「核算中」,`COMPLETED` →「已完成」;码为 null 时为 null(不折叠成「待核算」);未知码回落原码 | | **settlementStatus** | String | **新增**。逐户结算状态码(财务复核),`order_main.settlement_status`:`NONE` / `PENDING` / `COMPLETED`,列默认 `NONE` | | **settlementStatusName** | String | **新增**。逐户结算状态中文名:未结算 / 待财务复核 / 已结算;码为 null 时为 null;未知码回落原码 | | payStatus | String | 支付状态 `UNPAID` / `DEPOSIT_PAID` / `FULLY_PAID` | | payStatusName | String | 支付状态中文名 | | contractStatus | String | 合同状态(无合同为 null) | | contractStatusName | String | 合同状态中文名(无合同为 null) | | insuranceStatus | String | 保险状态(无保险为 null) | | insuranceStatusName | String | 保险状态中文名(无保险为 null) | | paidAmount | String(BigDecimal) | 已支付金额 | | balanceAmount | String(BigDecimal) | 待支付尾款金额(≥0) | | hotelRequirementStatus | String | 房需求状态(无有效需求行为 null) | | hotelRequirementStatusName | String | 房需求状态中文名 | | vehicleRequirementStatus | String | 行程用车需求状态(无有效需求行为 null) | | vehicleRequirementStatusName | String | 行程用车需求状态中文名 | | consultantName | String | 定制师姓名 | | totalPrice | String(BigDecimal) | 本户应收(取消单为 `"0.00"`) | | tierCode | String | 档位码,如 `2A1C` | | tierName | String | 档位名,如「2成人1儿童」 | | travelerInfoComplete | Boolean | 出行人资料是否齐全 | | roomCount | Integer | 房数(`includeNeeds=true` 时返回) | | roomType | String | 房型原值(`includeNeeds=true` 时返回) | | roomTypeName | String | 房型中文名 | | specialNeeds | String | 特殊需求(`includeNeeds=true` 时返回) | | contactPhone | String | 联系人手机号(脱敏,前 3 后 4) | | groupChatUnreadCount | Integer | 「联系定制师」团队共享未读数(取不到时为 0) | | travelers | Array\ | 出行人明细(`includeTravelers=true` 时返回):`name` / `type` / `age` / `birthdayInTrip` | #### 请求示例 无请求体。 ```http GET /v3/admin/order/group-batch/2102000000000000001/orders?page=1&pageSize=20 HTTP/1.1 Host: api.test.1814.love Authorization: Bearer ``` #### 响应示例 > 字段结构示意,ID、金额、姓名为示例值。三户分别处于:待结算(核单已提交)、核单中、出行前。 ```json { "code": 200, "message": "成功", "data": { "records": [ { "orderId": "2102000000000000101", "orderNo": "HL20260910100000001", "teamNo": "26-0101", "customerName": "王先生家庭", "participantCount": 3, "orderStatus": "COMPLETED", "orderStatusName": "已完成", "flowStatus": "PENDING_SETTLE", "flowStatusName": "待结算", "reviewStatus": "COMPLETED", "reviewStatusName": "已完成", "settlementStatus": "PENDING", "settlementStatusName": "待财务复核", "payStatus": "FULLY_PAID", "payStatusName": "已付全款", "contractStatus": "SIGNED", "contractStatusName": "已签署", "insuranceStatus": "INSURED", "insuranceStatusName": "已投保", "paidAmount": "12000.00", "balanceAmount": "0.00", "hotelRequirementStatus": "DONE", "hotelRequirementStatusName": "配房完成", "vehicleRequirementStatus": "DONE", "vehicleRequirementStatusName": "配车完成", "consultantName": "张三", "totalPrice": "12000.00", "tierCode": "2A1C", "tierName": "2成人1儿童", "travelerInfoComplete": true, "roomCount": 2, "roomType": "家庭房", "roomTypeName": "家庭房", "specialNeeds": null, "contactPhone": "138****8000", "groupChatUnreadCount": 0, "travelers": [ { "name": "王大明", "type": "ADULT", "age": 38, "birthdayInTrip": false }, { "name": "李小红", "type": "ADULT", "age": 36, "birthdayInTrip": false }, { "name": "王小明", "type": "CHILD", "age": 6, "birthdayInTrip": false } ] }, { "orderId": "2102000000000000102", "orderNo": "HL20260910100000002", "teamNo": "26-0102", "customerName": "刘女士", "participantCount": 2, "orderStatus": "COMPLETED", "orderStatusName": "已完成", "flowStatus": "REVIEWING", "flowStatusName": "核单中", "reviewStatus": "IN_PROGRESS", "reviewStatusName": "核算中", "settlementStatus": "NONE", "settlementStatusName": "未结算", "payStatus": "FULLY_PAID", "payStatusName": "已付全款", "contractStatus": "SIGNED", "contractStatusName": "已签署", "insuranceStatus": "INSURED", "insuranceStatusName": "已投保", "paidAmount": "8000.00", "balanceAmount": "0.00", "hotelRequirementStatus": "DONE", "hotelRequirementStatusName": "配房完成", "vehicleRequirementStatus": "DONE", "vehicleRequirementStatusName": "配车完成", "consultantName": "张三", "totalPrice": "8000.00", "tierCode": "2A", "tierName": "2成人", "travelerInfoComplete": true, "roomCount": 1, "roomType": "大床房", "roomTypeName": "大床房", "specialNeeds": null, "contactPhone": "139****1234", "groupChatUnreadCount": 0, "travelers": [ { "name": "刘芳", "type": "ADULT", "age": 45, "birthdayInTrip": false }, { "name": "陈刚", "type": "ADULT", "age": 47, "birthdayInTrip": true } ] }, { "orderId": "2102000000000000103", "orderNo": "HL20260910100000003", "teamNo": "26-0103", "customerName": "赵先生", "participantCount": 1, "orderStatus": "PENDING_DEPARTURE", "orderStatusName": "待出行", "flowStatus": "PENDING_DEPARTURE", "flowStatusName": "待出行", "reviewStatus": null, "reviewStatusName": null, "settlementStatus": "NONE", "settlementStatusName": "未结算", "payStatus": "DEPOSIT_PAID", "payStatusName": "已付定金", "contractStatus": "SIGNED", "contractStatusName": "已签署", "insuranceStatus": "INSURED", "insuranceStatusName": "已投保", "paidAmount": "1500.00", "balanceAmount": "3500.00", "hotelRequirementStatus": "DONE", "hotelRequirementStatusName": "配房完成", "vehicleRequirementStatus": "DONE", "vehicleRequirementStatusName": "配车完成", "consultantName": "李四", "totalPrice": "5000.00", "tierCode": "1A", "tierName": "1成人", "travelerInfoComplete": true, "roomCount": 1, "roomType": "标间", "roomTypeName": "标间", "specialNeeds": "需要无烟房", "contactPhone": "137****5678", "groupChatUnreadCount": 1, "travelers": [ { "name": "赵磊", "type": "ADULT", "age": 29, "birthdayInTrip": false } ] } ], "total": 3, "page": 1, "pageSize": 20 }, "success": true } ``` #### 空数据 / 降级响应 团期下没有子订单(或页码超出末页)时 `records` 为空数组,`total` 为真实总数;本接口新增字段无远程调用,无降级分支。 ```json { "code": 200, "message": "成功", "data": { "records": [], "total": 0, "page": 1, "pageSize": 20 }, "success": true } ``` 三列为 null 的户(如出行前的 `reviewStatus`),码与中文名都为 null: ```json { "reviewStatus": null, "reviewStatusName": null } ``` #### 错误响应 团期不存在(既有,不变): ```json { "code": 589500, "message": "团期不存在", "success": false, "data": null } ``` 当前角色未授予 `group-batch:view`,或定制师读取不在本人名下的团期(既有,不变): ```json { "code": 589507, "message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)", "success": false, "data": null } ``` #### 业务边界 - 判权不变:需 `group-batch:view`;定制师(CUSTOMIZER)另需该团下有本人名下的在团子订单(#7949),否则 589507。判定顺序为权限码 → 定制师归属 → 团期存在(589500)。 - 分页、排序、既有字段、`includeTravelers` / `includeNeeds` / `includeCancelled` 语义全部不变;`page` 超出末页返回空 `records`,`total` 仍为真实总数。 - 6 个新字段逐户照实读取、只读透出,本接口不写任何状态;`includeCancelled=true` 时已取消户同样照实返回其三列。 - `*Name` 规则:码为 null 时中文名也为 null;遇到枚举外的未知码时中文名回落为原码,不报错。 - `reviewStatus` 出行前为 null;`settlementStatus` 列默认 `NONE`。 - 走 #8361 团核单(finalize / confirm)结算的团,**不回写**这三列,名单照实返回逐户值,可能显示「核算中 / 未结算」;两套口径的收敛归 Epic #8361。 - #8341(2026-09-24)之前就已进入核单的存量团没有回填,这些户的三列可能仍为 null / `NONE`。 --- ## 四、契约约束与正确调用方式 > 本接口是只读 GET,入参规则不变;本节只说明新字段该怎么取、别和哪些同名字段混用。 ### ✅ 正确 / ❌ 错误取值对照 | 场景 | 取值 | |------|------| | ✅ 名单「状态」列(原型里的 `processStatus`) | 读 `flowStatusName`;判定逻辑用 `flowStatus` | | ✅ 单独展示逐户核单进度 | 读 `reviewStatusName`;判定用 `reviewStatus` | | ✅ 单独展示逐户结算(财务复核)进度 | 读 `settlementStatusName`;判定用 `settlementStatus` | | ❌ 按旧版接口文档读 `processStatus` | 该字段从未实现,恒不存在;接口文档 GB-ADM-003 已改为 `flowStatus` / `flowStatusName` | | ❌ 用中文名做判定 | 中文名只用于展示,判定一律用码 | | ❌ 前端自建码 → 中文映射 | 直接显示后端下发的 `*Name`(后端与订单详情同规则) | | ❌ 把 null 渲染成「待核算」 | `reviewStatus` 为 null 表示尚未进入核单,后端不折叠,前端也不要折叠 | ### 同名 / 近名字段对照(易混点) | 出处 | 字段 | 粒度 | 含义 | 取值 | |------|------|------|------|------| | **本名单** GB-ADM-003 `records[]` | `reviewStatus` | 逐户 | 逐户**核单** | `NONE` / `PENDING` / `IN_PROGRESS` / `COMPLETED` | | **本名单** GB-ADM-003 `records[]` | `settlementStatus` | 逐户 | 逐户**结算**(财务复核) | `NONE` / `PENDING` / `COMPLETED` | | **本名单** GB-ADM-003 `records[]` | `flowStatus` | 逐户 | 订单流程细状态 | `OrderFlowStatus` 12 值 | | 团期核单 `GroupSettlementRespVO`(#8361,`GET /v3/admin/order/group-batch/{groupBatchId}/settlement/reports/group` 等) | `reviewStatus` | 团级一行 | 团级**复核** | `PENDING` / `APPROVED` / `RETURNED` | | 团期核单 `GroupSettlementRespVO`(#8361) | `settlementStatus` | 团级一行 | 团级**核单** | `PENDING` / `FINALIZED` / `SETTLED` | | 团期核单 `GroupSettlementRespVO`(#8361) | `flowStatus` | 团级一行 | 团级流程快照 | `TRIP_FINISHED` / `REVIEWING` / `SETTLED` | | 财务 tab GB-ADM-040 `GET /v3/admin/order/group-batch/{groupBatchId}/finance` | `items[].settleStatus` | 逐户 | 尾款是否收齐(实时派生) | 已结清 / 待收尾款 / 已退团 | 结论:本名单的 `reviewStatus` / `settlementStatus` 与 #8361 同名字段**含义相反**,与 GB-ADM-040 的 `settleStatus` **不是一回事**,三处不可互相替代、不可交叉比对。 ### 两套结算口径并存 - 走团期结算 `/settle`(#8341)的团:三列随团期动作同步,名单能看到「已结算」。 - 走 #8361 团核单 confirm 结算的团:这三列**不回写**,名单照实返回逐户值(可能仍是「核算中 / 未结算」)。两套口径的收敛归 Epic #8361,本单不处理。 --- ## 五、数据库行为 零 DDL、零写入。新字段取自订单主表 `order_main` 既有三列(`flow_status` / `review_status` / `settlement_status`),只读;名单查询本就整行读取,不新增 SQL,也不新增远程调用。 --- ## 六、边界行为 - 未登录 → 401(网关拦截)。 - 团期不存在 → 589500;无权限或定制师读非本人名下团期 → 589507(均不变)。 - 团期无子订单 → `records: []`、`total: 0`。 - 三列为 null 的户 → 码与中文名都为 null。 - 未知码 → 中文名回落原码。 - 存量团:#8341(2026-09-24)之前已进入核单的团未回填,三列可能为 null / `NONE`。 - 走 #8361 团核单 confirm 结算的团:三列不回写,名单照实返回。 - 本接口新增字段无远程调用,无降级分支。 --- ## 六.5、枚举 / 数据字典 ### flowStatus(com.hulalv.order.core.enums.OrderFlowStatus) **所属字段**: `GroupBatchOrderItemRespVO.flowStatus` / `flowStatusName` | **类型**: `String` | 值 | 中文(flowStatusName) | 说明 | |----|------|------| | `AWAITING_PAY` | 待补全信息 | 枚举本名「待支付」,名单与订单详情统一显示「待补全信息」 | | `AWAITING_PROFILE` | 待补全信息 | - | | `RESOURCE_PREPARING` | 资源准备 | - | | `PENDING_CONFIRM` | 待确认 | - | | `PENDING_DEPARTURE` | 待出行 | - | | `TRAVELLING` | 出行中 | - | | `PENDING_REVIEW` | 待核单 | 团期出行完毕时写入(#8340) | | `REVIEWING` | 核单中 | 团期发起核单时写入(#8341) | | `PENDING_SETTLE` | 待结算 | 逐户核单提交后;团期反结算退回此态(#8341) | | `SETTLED` | 已结算 | 团期结算 `/settle` 时写入(#8341) | | `COMPLETED` | 已完成 | - | | `CANCELLED` | 已取消 | - | ### reviewStatus(com.hulalv.order.settlement.enums.ReviewStatus,逐户核单) **所属字段**: `GroupBatchOrderItemRespVO.reviewStatus` / `reviewStatusName` | **类型**: `String` | 值 | 中文(reviewStatusName) | 说明 | |----|------|------| | null | null | 出行前未进入核单;不折叠成「待核算」 | | `NONE` | 待核算 | - | | `PENDING` | 待核算 | 团期出行完毕时写入(#8340) | | `IN_PROGRESS` | 核算中 | 团期发起核单时写入(#8341) | | `COMPLETED` | 已完成 | 逐户核单提交后 | ### settlementStatus(com.hulalv.order.settlement.enums.SettlementStatusEnum,逐户结算 / 财务复核) **所属字段**: `GroupBatchOrderItemRespVO.settlementStatus` / `settlementStatusName` | **类型**: `String` | 值 | 中文(settlementStatusName) | 说明 | |----|------|------| | `NONE` | 未结算 | 列默认值 | | `PENDING` | 待财务复核 | 逐户核单提交后;团期反结算退回此态(#8341) | | `COMPLETED` | 已结算 | 团期结算 `/settle` 时写入(#8341) | --- ## 六.6、修改前后对比 ### 字段级对比 | 字段 | 改前 | 改后 | |------|------|------| | `records[].flowStatus` | 无此字段 | **新增**:流程细状态码 | | `records[].flowStatusName` | 无此字段 | **新增**:流程细状态中文名(与订单详情同规则) | | `records[].reviewStatus` | 无此字段 | **新增**:逐户核单状态码(出行前 null) | | `records[].reviewStatusName` | 无此字段 | **新增**:逐户核单中文名(与订单详情同规则) | | `records[].settlementStatus` | 无此字段 | **新增**:逐户结算状态码(默认 `NONE`) | | `records[].settlementStatusName` | 无此字段 | **新增**:逐户结算中文名 | | 其余全部字段 / 入参 / 分页信封 | - | 不变 | ### 行为级对比 | 行为 | 改前 | 改后 | |------|------|------| | 名单看逐户核单 / 结算进度 | 名单无此信息,需逐户进订单详情 | 名单直接返回三对状态 | | 判权、分页、排序 | - | 不变 | | 状态写入与流转 | - | 不变(本单只读透出) | ## 六.7、影响评估 - **是否破坏向后兼容**: 否。只新增响应字段,既有字段的名称、类型、语义不变,旧客户端忽略新字段即可。 - **前端是否必须同步上线**: 否。不接入新字段页面照常工作;接入时名单「状态」列用 `flowStatusName`。 - **前端 workaround 清理点**: 若名单页曾为展示核单 / 结算进度逐户调订单详情 `GET /v3/admin/order/{id}` 取 `main.flowStatusName`,可改读本名单新字段;若曾按旧版接口文档预留 `processStatus`,改为 `flowStatus` / `flowStatusName`。 ## 七、不影响范围 - **仅影响**: `GET /v3/admin/order/group-batch/{groupBatchId}/orders` 响应 `records[]` 新增 6 个字段。 - **零影响**: - 本接口的入参、判权、分页、排序与其余字段 - 团期文档导出与打印(只取订单 ID / 订单号 / 人数 / 房数,不受影响) - 订单详情 `GET /v3/admin/order/{id}` 与订单列表 - #8361 团核单各接口(finalize / confirm / `settlement/reports/group`) - 财务 tab GB-ADM-040 `GET /v3/admin/order/group-batch/{groupBatchId}/finance` - 团期核单、结算、反结算的写入与流转(#8340 / #8341 行为不变) - 小程序端 --- ## 八、测试环境已验证 TEST 已部署 dev-v3@`58da1df2a`(order-v3 双实例 8086/8186 滚动完成,2026-09-27 12:30)。构建身份探针:连打 8 次名单接口,8 次都带 `flowStatus`。经真实网关 `https://api.test.1814.love` 取证,库为 `hl_order_service_v3` 只读查询。 | AC | 场景 | 结果 | |---|---|---| | AC-1 | 每户返回三对新字段,改前改后响应 diff 只多出这 6 个键 | ✅ 5 个团 12 户部署前后各取一次:逐户「改后键 − 改前键」恰为这 6 个;改前的键一个不少,取值逐键比对 0 差异;户集合、顺序、`total` / `page` / `pageSize` 都不变 | | AC-2 | 五种组合各取至少 1 户,三个码与库一致 | ✅ SETTLED/COMPLETED/COMPLETED 4 户、PENDING_SETTLE/COMPLETED/PENDING 3 户、REVIEWING/IN_PROGRESS/NONE 2 户、PENDING_REVIEW/PENDING/NONE 1 户、PENDING_DEPARTURE/null/NONE 2 户:名单三码与 `order_main` 同一分钟内的读数逐户一致 | | AC-3 | 同一订单名单 `flowStatusName` / `reviewStatusName` 与订单详情 `main.*` 逐字一致 | ✅ 五种组合各 1 户对照 `GET /v3/admin/order/{id}` 的 `data.main`:待出行/null、待核单/待核算、核单中/核算中、待结算/已完成、已结算/已完成,逐字一致(详情不含 settlementStatusName,不在对照范围) | | AC-4 | `reviewStatus` 为 null 的户码与中文名都为 null,不折叠成「待核算」 | ✅ 团 2100509904627191810 两户原始响应为 `"reviewStatus":null,"reviewStatusName":null`,库里 `review_status` 为 NULL | | AC-5 | 未知码中文名回落原码 | ✅ 单测:合并提交上 `GroupBatchConverterTest` 的 #8418 用例 48 条执行、0 失败,含三个中文名各自的 `ZZZ_UNKNOWN` 行,以及 `offEnumCodes_sameAsOrderDetail` 5 条(空串 / 空白 / 未知码 / 小写两例) | | AC-6 | 逐户反确认 → 逐户定稿,每步名单与库一致,最终复原 | ✅ 子订单 2102091018323296257:
• 改前 PENDING_SETTLE / COMPLETED / PENDING;
• `…/settlement/final-snapshots/reopen` 后名单与库均为 REVIEWING(核单中)/ IN_PROGRESS(核算中)/ NONE(未结算);
• `…/settlement/finalize` 后均回到 PENDING_SETTLE(待结算)/ COMPLETED(已完成)/ PENDING(待财务复核);
• 快照 v1 → REOPENED,新增 v2 FINALIZED 为当前版本,核单汇总金额与改前一致 | | AC-7 | 名单无新增 SQL / 远程调用,生产代码只改 VO 与转换器 | ✅ 本单生产代码只有 `GroupBatchOrderItemRespVO`、`GroupBatchConverter` 两个文件;`GroupBatchQueryService` / Mapper / `OrderInfoConverter` 零改动 | | AC-8 | order-v3 相关测试不引入新失败 | ✅ 定向 278 条 0 失败(合并提交上复测同样 278/0),16 个 Arch 类 87 条 0 失败;groupbatch 整包 4 个红类在干净基底 `7c69e8227` 上逐类读数吻合,属于既有问题 | | AC-9 | 接口文档 GB-ADM-003 与 API-SPEC §17.3 已更新,changelog 通过校验器 | ✅ 团期接口文档 v2.0、一期实施拆分详设、实施单 02、API-SPEC §17.3、order-v3 CHANGELOG v6.3.30 已随 PR #8420 合入;本条目通过 frontmatter / 文件名校验器 | 反例:不带 Authorization 或签名被篡改的 token,网关返回 HTTP 200 + `code: 401`(「缺少有效的 Authorization 头」/「Token 无效」),与网关既有约定一致,本单未改判权。 --- ## 九、相关历史 PR | PR | Issue | 说明 | 是否仍有效 | |----|-------|------|------------| | #8344 | #8340 | 团期单子订单出发 / 返团跟随团期推进(出行完毕写 `PENDING_REVIEW` / `PENDING`) | ✅ 有效,本单只读其结果 | | #8345 | #8341 | 团期核单 / 结算 / 反结算同步子订单三列 | ✅ 有效,本单只读其结果 | | — | #7949 | 定制师读团期名单的归属校验 | ✅ 有效,判权不变 | | — | #8361 | 团期报销核单一团一张(`GroupSettlementRespVO` 团级同名字段) | ✅ 有效,两套口径收敛归该 Epic | | **本 PR #8420** | **#8418** | 名单逐户补三对状态 | ✅ 最新 | --- ## 十、相关文档 - 关联 Issue: [wx/HL#8418](https://git.1814.love/wx/HL/issues/8418) - 关联 PR: [wx/HL#8420](https://git.1814.love/wx/HL/pulls/8420) - 接口文档:HL `docs/group/团期模块接口文档-v2.0.html` GB-ADM-003(`processStatus` 已改为 `flowStatus` / `flowStatusName`) - API 规格:HL `docs/order-v3/api/API-SPEC.html` §17.3 `GroupBatchOrderItemRespVO` - order-v3 变更记录:HL `docs/order-v3/CHANGELOG.md` v6.3.30 - 数据源:#8340、#8341;口径 Epic:#8361 ## 关联 / 联系人 ### 链接 - **Issue**: [#8418](https://git.1814.love/wx/HL/issues/8418) - **PR**: [#8420](https://git.1814.love/wx/HL/pulls/8420) - **Merge commit**: [58da1df2a](https://git.1814.love/wx/HL/commit/58da1df2ac781414c104b7c49120afab5287195f) ### 联系人 - **后端负责人**: @jw