diff --git a/changelogs-v2/2026-09/01_6903_团期看板六芯片逐户明细-GB-ADM-090~095-新增接口-管理后台.md b/changelogs-v2/2026-09/01_6903_团期看板六芯片逐户明细-GB-ADM-090~095-新增接口-管理后台.md new file mode 100644 index 00000000..788cd57d --- /dev/null +++ b/changelogs-v2/2026-09/01_6903_团期看板六芯片逐户明细-GB-ADM-090~095-新增接口-管理后台.md @@ -0,0 +1,748 @@ +--- +schema: "hl-changelog/v2" +ticket: "6903" +title: "团期看板六芯片逐户明细 GB-ADM-090~095" +consumer: "admin" +author: "wx(GIT)" +change_type: "新增接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "2026-09-01" +status_note: "2026-09-01 部署测试服 dev-v3@1159c8949,6 端点网关实测 200 全通过,团期不存在 589500 / 参数错误 400 已核验" +updated_at: "2026-09-01" +base: "dev-v3" +--- + +# 团期看板:六芯片逐户明细(GB-ADM-090~095,房/车/导/摄/约/保) + +> **存放目录**: 二期(order-v3)→ `changelogs-v2/2026-09/` +> +> **服务**: hl-order-service-v3 +> **Issue**: [#6903](https://git.1814.love:8443/wx/HL/issues/6903) +> **日期**: 2026-09-01 +> **影响范围**: 管理后台团期看板行右侧六芯片(配房/配车/配导游/配摄影/合同/保险)点击后的逐户下钻 + +--- + +## ⚠️ 关键变化 + +**新增能力,无破坏性变化**:先前看板芯片只有整团聚合色块(GB-ADM-001 `chips.X`)、没有逐户下钻;本次把「点芯片看每户到哪一步」补成可调用接口。数据(order_main 六态列)早已落库并被房务/车队/地接等 Service 消费,本组接口只读透出,不改变任何业务状态。 + +--- + +## 一、背景(选填) + +团期看板行右侧有「房/车/导/摄/约/保」六个芯片,点击后按需展开该项的**逐户明细**。逐户口径与整团聚合、看板芯片(GB-ADM-001 `chips.X`)同源同算法(共享地基 `GroupBatchChipResolver`,#6902/#6916)。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | GB-ADM-090 配房逐户明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/hotel` | 新增接口 | 房芯片逐户下钻 | +| 2 | GB-ADM-091 配车逐户明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/vehicle` | 新增接口 | 车芯片逐户下钻 | +| 3 | GB-ADM-092 配导游逐户明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/guide` | 新增接口 | 导芯片逐户下钻 | +| 4 | GB-ADM-093 配摄影逐户明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/photo` | 新增接口 | 摄芯片逐户下钻 | +| 5 | GB-ADM-094 合同逐户明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/contract` | 新增接口 | 约芯片逐户下钻 | +| 6 | GB-ADM-095 保险逐户明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/insurance` | 新增接口 | 保芯片逐户下钻 | + +--- + +## 三、接口详情 + +六个接口共用 `GroupBatchChipDetailVO` / `GroupBatchChipItemRespVO`,正文各自自包含。 + +### 1. GB-ADM-090 配房逐户明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/hotel` + +**VO**: `GroupBatchChipDetailVO` + +#### 使用场景 + +团期看板行右侧「房」芯片点击展开:返回该团期每户的配房进度(哪一户到哪一步),前端展开列表展示。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| Authorization | Header | String | ✅ | - | 管理端登录令牌 | +| X-Admin-Id | Header | Long | ✅ | 网关注入 | 受信管理员 ID;客户端传值一律忽略(不校验客户端值) | +| groupBatchId | Path | String | ✅ | 团期 ID(Snowflake) | 不存在/非团期/已软删 → 589500 | + +无查询参数、无请求体。 + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|------|------|------| +| batchId | String | 团期 ID | +| chipLabel | String | 固定「配房」 | +| aggregateStatus | String | 整团聚合态 四态取值与看板 GB-ADM-001 `chips.X` 的 `aggregateStatus` 完全一致(整团待办/进行中/已完成/异常),与 GB-ADM-001 `chips.hotel` 同源同算法 | +| totalCount | Integer | 计入统计的子订单数(免闸户不计入分母) | +| doneCount | Integer | 已完成户数(`status==DONE`) | +| items[].orderId | String | 子订单 ID(JSON String 化) | +| items[].orderNo | String | 子订单编号 | +| items[].contactName | String | 联系人/客户姓名 | +| items[].peopleCount | Integer | 本户人数 = adult+child+youngChild+baby | +| items[].status | String | 本户配房状态,`RequirementStatus` 6 值,见「六.5」;无需/未开始为 null | +| items[].statusText | String | 状态中文名(服务端给出,见「六.5」) | +| items[].needsIt | Boolean | 本户是否需要配房(`order_main.needs_hotel`);false=免闸户,status=null、置灰、不计入计数 | +| items[].updateTime | String | 配房最后变更时间;六状态列无独立时间戳时为 null | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/90211/chips/hotel +Authorization: Bearer **** +X-Admin-Id: 3301 +``` + +#### 响应示例 + +```json +{ + "code": 200, + "data": { + "batchId": "90211", + "chipLabel": "配房", + "aggregateStatus": "DOING", + "totalCount": 7, + "doneCount": 5, + "items": [ + { "orderId": "770152", "orderNo": "GT-26-0096", "contactName": "陈昊", + "peopleCount": 2, "status": "DONE", "statusText": "配房完成", + "needsIt": true, "updateTime": null }, + { "orderId": "770153", "orderNo": "GT-26-0097", "contactName": "林婉清", + "peopleCount": 3, "status": null, "statusText": "无需", + "needsIt": false, "updateTime": null } + ] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +```json +{ "code": 200, "data": { "batchId": "90211", "chipLabel": "配房", + "aggregateStatus": "整团待办", "totalCount": 0, "doneCount": 0, "items": [] }, + "success": true } +``` + +#### 错误响应 + +```json +{ "code": 589500, "message": "团期不存在", "success": false, "data": null } +``` + +#### 业务边界 + +- 授权码 `group-batch:view`;未配置权限 → 589507。 +- 只读(READ_ONLY 事务),无锁、无幂等、不改变任何状态。 +- 免闸户(`needsIt=false`):status=null、statusText=「无需」、前端置灰、不计入 totalCount/doneCount 分子分母。 +- 已取消子订单不计入(活跃口径与共享地基一致)。 +- 团期已流团(CANCELLED)→ aggregateStatus 恒整团待办(wire 值同看板 chips.X),但逐户明细仍如实返回(不造假计数)。 + +--- + +### 2. GB-ADM-091 配车逐户明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/vehicle` + +**VO**: `GroupBatchChipDetailVO` + +#### 使用场景 + +团期看板行右侧「车」芯片点击展开:返回每户配车进度。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| Authorization | Header | String | ✅ | - | 管理端登录令牌 | +| X-Admin-Id | Header | Long | ✅ | 网关注入 | 受信管理员 ID;客户端传值忽略 | +| groupBatchId | Path | String | ✅ | 团期 ID(Snowflake) | 不存在/非团期/已软删 → 589500 | + +无查询参数、无请求体。 + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|------|------|------| +| batchId | String | 团期 ID | +| chipLabel | String | 固定「配车」 | +| aggregateStatus | String | 整团聚合态 四态取值与看板 GB-ADM-001 `chips.X` 的 `aggregateStatus` 完全一致(整团待办/进行中/已完成/异常),与 GB-ADM-001 `chips.vehicle` 同源 | +| totalCount | Integer | 计入统计的子订单数(免闸户不计入) | +| doneCount | Integer | 已完成户数(`status==DONE`) | +| items[].orderId | String | 子订单 ID(JSON String 化) | +| items[].orderNo | String | 子订单编号 | +| items[].contactName | String | 联系人/客户姓名 | +| items[].peopleCount | Integer | 本户人数 = adult+child+youngChild+baby | +| items[].status | String | 本户配车状态,`RequirementStatus` 6 值,见「六.5」;无需/未开始为 null | +| items[].statusText | String | 状态中文名(服务端给出,与房同文案,见「六.5」) | +| items[].needsIt | Boolean | 本户是否需要配车(`order_main.needs_vehicle`);false=免闸户置灰不计入 | +| items[].updateTime | String | 配车最后变更时间;无独立时间戳时为 null | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/90211/chips/vehicle +Authorization: Bearer **** +X-Admin-Id: 3301 +``` + +#### 响应示例 + +```json +{ + "code": 200, + "data": { + "batchId": "90211", + "chipLabel": "配车", + "aggregateStatus": "DONE", + "totalCount": 3, + "doneCount": 3, + "items": [ + { "orderId": "770160", "orderNo": "GT-26-0101", "contactName": "王强", + "peopleCount": 2, "status": "DONE", "statusText": "配房完成", + "needsIt": true, "updateTime": null } + ] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +```json +{ "code": 200, "data": { "batchId": "90211", "chipLabel": "配车", + "aggregateStatus": "整团待办", "totalCount": 0, "doneCount": 0, "items": [] }, + "success": true } +``` + +#### 错误响应 + +```json +{ "code": 589500, "message": "团期不存在", "success": false, "data": null } +``` + +#### 业务边界 + +- 授权码 `group-batch:view`;未配置权限 → 589507。 +- 只读(READ_ONLY 事务),无锁、无幂等、不改变任何状态。 +- 免闸户(`needsIt=false`):status=null、statusText=「无需」、前端置灰、不计入计数。 +- 已取消子订单不计入;流团团期聚合恒 整团待办、明细如实返回。 + +--- + +### 3. GB-ADM-092 配导游逐户明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/guide` + +**VO**: `GroupBatchChipDetailVO` + +#### 使用场景 + +团期看板行右侧「导」芯片点击展开:返回每户配导游进度。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| Authorization | Header | String | ✅ | - | 管理端登录令牌 | +| X-Admin-Id | Header | Long | ✅ | 网关注入 | 受信管理员 ID;客户端传值忽略 | +| groupBatchId | Path | String | ✅ | 团期 ID(Snowflake) | 不存在/非团期/已软删 → 589500 | + +无查询参数、无请求体。 + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|------|------|------| +| batchId | String | 团期 ID | +| chipLabel | String | 固定「配导游」 | +| aggregateStatus | String | 整团聚合态 四态取值与看板 GB-ADM-001 `chips.X` 的 `aggregateStatus` 完全一致(整团待办/进行中/已完成/异常) | +| totalCount | Integer | 计入统计的子订单数(免闸户不计入) | +| doneCount | Integer | 已完成户数(`status==DONE`) | +| items[].orderId | String | 子订单 ID(JSON String 化) | +| items[].orderNo | String | 子订单编号 | +| items[].contactName | String | 联系人/客户姓名 | +| items[].peopleCount | Integer | 本户人数 = adult+child+youngChild+baby | +| items[].status | String | 本户配导游状态,3 值:`NONE` 无需/未开始 / `PENDING` 待指派 / `DONE` 已指派,见「六.5」 | +| items[].statusText | String | 状态中文名(服务端给出,见「六.5」) | +| items[].needsIt | Boolean | 本户是否需要配导游(`order_main.needs_guide`);false=免闸户 status 恒 `NONE`、不计入计数 | +| items[].updateTime | String | 配导游最后变更时间;无独立时间戳时为 null | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/90211/chips/guide +Authorization: Bearer **** +X-Admin-Id: 3301 +``` + +#### 响应示例 + +```json +{ + "code": 200, + "data": { + "batchId": "90211", + "chipLabel": "配导游", + "aggregateStatus": "DOING", + "totalCount": 4, + "doneCount": 2, + "items": [ + { "orderId": "770170", "orderNo": "GT-26-0102", "contactName": "周磊", + "peopleCount": 2, "status": "DONE", "statusText": "已指派", "needsIt": true, "updateTime": null }, + { "orderId": "770171", "orderNo": "GT-26-0103", "contactName": "吴芳", + "peopleCount": 1, "status": "NONE", "statusText": "无需", "needsIt": false, "updateTime": null } + ] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +```json +{ "code": 200, "data": { "batchId": "90211", "chipLabel": "配导游", + "aggregateStatus": "整团待办", "totalCount": 0, "doneCount": 0, "items": [] }, + "success": true } +``` + +#### 错误响应 + +```json +{ "code": 589500, "message": "团期不存在", "success": false, "data": null } +``` + +#### 业务边界 + +- 授权码 `group-batch:view`;未配置权限 → 589507。 +- 只读(READ_ONLY 事务),无锁、无幂等、不改变任何状态。 +- **免闸户(needsIt=false)status 为 `NONE`(非 null)**,与房/车(null)区分;前端按 NONE 置灰。 +- 读侧只认 `DONE`,其余非免闸状态一律 `PENDING`;已取消子订单不计入;流团团期聚合恒 整团待办。 + +--- + +### 4. GB-ADM-093 配摄影逐户明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/photo` + +**VO**: `GroupBatchChipDetailVO` + +#### 使用场景 + +团期看板行右侧「摄」芯片点击展开:返回每户配摄影进度。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| Authorization | Header | String | ✅ | - | 管理端登录令牌 | +| X-Admin-Id | Header | Long | ✅ | 网关注入 | 受信管理员 ID;客户端传值忽略 | +| groupBatchId | Path | String | ✅ | 团期 ID(Snowflake) | 不存在/非团期/已软删 → 589500 | + +无查询参数、无请求体。 + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|------|------|------| +| batchId | String | 团期 ID | +| chipLabel | String | 固定「配摄影」 | +| aggregateStatus | String | 整团聚合态 四态取值与看板 GB-ADM-001 `chips.X` 的 `aggregateStatus` 完全一致(整团待办/进行中/已完成/异常) | +| totalCount | Integer | 计入统计的子订单数(免闸户不计入) | +| doneCount | Integer | 已完成户数(`status==DONE`) | +| items[].orderId | String | 子订单 ID(JSON String 化) | +| items[].orderNo | String | 子订单编号 | +| items[].contactName | String | 联系人/客户姓名 | +| items[].peopleCount | Integer | 本户人数 = adult+child+youngChild+baby | +| items[].status | String | 本户配摄影状态,3 值:`NONE` 无需/未开始 / `PENDING` 待指派 / `DONE` 已指派,见「六.5」 | +| items[].statusText | String | 状态中文名(服务端给出,见「六.5」) | +| items[].needsIt | Boolean | 本户是否需要配摄影(`order_main.needs_photographer`);false=免闸户 status 恒 `NONE`、不计入计数 | +| items[].updateTime | String | 配摄影最后变更时间;无独立时间戳时为 null | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/90211/chips/photo +Authorization: Bearer **** +X-Admin-Id: 3301 +``` + +#### 响应示例 + +```json +{ + "code": 200, + "data": { + "batchId": "90211", + "chipLabel": "配摄影", + "aggregateStatus": "整团待办", + "totalCount": 1, + "doneCount": 0, + "items": [ + { "orderId": "770180", "orderNo": "GT-26-0104", "contactName": "郑浩", + "peopleCount": 2, "status": "PENDING", "statusText": "待指派", "needsIt": true, "updateTime": null } + ] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +```json +{ "code": 200, "data": { "batchId": "90211", "chipLabel": "配摄影", + "aggregateStatus": "整团待办", "totalCount": 0, "doneCount": 0, "items": [] }, + "success": true } +``` + +#### 错误响应 + +```json +{ "code": 589500, "message": "团期不存在", "success": false, "data": null } +``` + +#### 业务边界 + +- 授权码 `group-batch:view`;未配置权限 → 589507。 +- 只读(READ_ONLY 事务),无锁、无幂等、不改变任何状态。 +- 免闸户(needsIt=false)status 为 `NONE`(非 null),与导芯片一致。 +- 读侧只认 `DONE`,其余非免闸状态一律 `PENDING`;已取消子订单不计入;流团团期聚合恒 整团待办。 + +--- + +### 5. GB-ADM-094 合同逐户明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/contract` + +**VO**: `GroupBatchChipDetailVO` + +#### 使用场景 + +团期看板行右侧「约」芯片点击展开:返回每户合同(签约)进度。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| Authorization | Header | String | ✅ | - | 管理端登录令牌 | +| X-Admin-Id | Header | Long | ✅ | 网关注入 | 受信管理员 ID;客户端传值忽略 | +| groupBatchId | Path | String | ✅ | 团期 ID(Snowflake) | 不存在/非团期/已软删 → 589500 | + +无查询参数、无请求体。 + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|------|------|------| +| batchId | String | 团期 ID | +| chipLabel | String | 固定「合同」 | +| aggregateStatus | String | 整团聚合态 四态取值与看板 GB-ADM-001 `chips.X` 的 `aggregateStatus` 完全一致(整团待办/进行中/已完成/异常);房车导摄四项未全 DONE 前恒整团待办(硬规则;wire 值同看板 chips.X) | +| totalCount | Integer | 计全部活跃子订单(约/保无免闸户) | +| doneCount | Integer | 已完成户数(`status==SIGNED`) | +| items[].orderId | String | 子订单 ID(JSON String 化) | +| items[].orderNo | String | 子订单编号 | +| items[].contactName | String | 联系人/客户姓名 | +| items[].peopleCount | Integer | 本户人数 = adult+child+youngChild+baby | +| items[].status | String | 本户合同状态,`ContractStatus` 8 值,见「六.5」;无合同为 null | +| items[].statusText | String | 状态中文名(服务端给出,见「六.5」) | +| items[].needsIt | Boolean | 恒 true(约/保无免闸) | +| items[].updateTime | String | 合同最后变更时间;无独立时间戳时为 null | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/90211/chips/contract +Authorization: Bearer **** +X-Admin-Id: 3301 +``` + +#### 响应示例 + +```json +{ + "code": 200, + "data": { + "batchId": "90211", + "chipLabel": "合同", + "aggregateStatus": "DOING", + "totalCount": 2, + "doneCount": 1, + "items": [ + { "orderId": "770190", "orderNo": "GT-26-0105", "contactName": "钱进", + "peopleCount": 2, "status": "SIGNED", "statusText": "已签署", "needsIt": true, "updateTime": null }, + { "orderId": "770191", "orderNo": "GT-26-0106", "contactName": "孙丽", + "peopleCount": 2, "status": "PENDING", "statusText": "待出具", "needsIt": true, "updateTime": null } + ] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +```json +{ "code": 200, "data": { "batchId": "90211", "chipLabel": "合同", + "aggregateStatus": "整团待办", "totalCount": 0, "doneCount": 0, "items": [] }, + "success": true } +``` + +#### 错误响应 + +```json +{ "code": 589500, "message": "团期不存在", "success": false, "data": null } +``` + +#### 业务边界 + +- 授权码 `group-batch:view`;未配置权限 → 589507。 +- 只读(READ_ONLY 事务),无锁、无幂等、不改变任何状态。 +- needsIt 恒 true(约/保无免闸户);doneCount 只按 `SIGNED`;作废中/已作废计入整团 ERROR。 +- 约/保整团聚合在房车导摄四芯片未全部 DONE 前恒 整团待办(硬规则);已取消子订单不计入;流团团期聚合恒 整团待办。 + +--- + +### 6. GB-ADM-095 保险逐户明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/insurance` + +**VO**: `GroupBatchChipDetailVO` + +#### 使用场景 + +团期看板行右侧「保」芯片点击展开:返回每户保险进度。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| Authorization | Header | String | ✅ | - | 管理端登录令牌 | +| X-Admin-Id | Header | Long | ✅ | 网关注入 | 受信管理员 ID;客户端传值忽略 | +| groupBatchId | Path | String | ✅ | 团期 ID(Snowflake) | 不存在/非团期/已软删 → 589500 | + +无查询参数、无请求体。 + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|------|------|------| +| batchId | String | 团期 ID | +| chipLabel | String | 固定「保险」 | +| aggregateStatus | String | 整团聚合态 四态取值与看板 GB-ADM-001 `chips.X` 的 `aggregateStatus` 完全一致(整团待办/进行中/已完成/异常);房车导摄未全 DONE 前恒整团待办(硬规则;wire 值同看板 chips.X) | +| totalCount | Integer | 计全部活跃子订单(约/保无免闸户) | +| doneCount | Integer | 已完成户数(`status==INSURED`) | +| items[].orderId | String | 子订单 ID(JSON String 化) | +| items[].orderNo | String | 子订单编号 | +| items[].contactName | String | 联系人/客户姓名 | +| items[].peopleCount | Integer | 本户人数 = adult+child+youngChild+baby | +| items[].status | String | 本户保险状态,4 值:`INSURING` 投保中 / `INSURED` 已出单 / `CANCELLED` 已取消 / `FAILED` 出单失败;无保险为 null | +| items[].statusText | String | 状态中文名(服务端给出,见「六.5」) | +| items[].needsIt | Boolean | 恒 true(约/保无免闸) | +| items[].updateTime | String | 保险最后变更时间;无独立时间戳时为 null | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/90211/chips/insurance +Authorization: Bearer **** +X-Admin-Id: 3301 +``` + +#### 响应示例 + +```json +{ + "code": 200, + "data": { + "batchId": "90211", + "chipLabel": "保险", + "aggregateStatus": "DOING", + "totalCount": 2, + "doneCount": 1, + "items": [ + { "orderId": "770200", "orderNo": "GT-26-0107", "contactName": "李娜", + "peopleCount": 2, "status": "INSURED", "statusText": "已出单", "needsIt": true, "updateTime": null }, + { "orderId": "770201", "orderNo": "GT-26-0108", "contactName": "赵敏", + "peopleCount": 3, "status": "INSURING", "statusText": "出单中", "needsIt": true, "updateTime": null } + ] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +```json +{ "code": 200, "data": { "batchId": "90211", "chipLabel": "保险", + "aggregateStatus": "整团待办", "totalCount": 0, "doneCount": 0, "items": [] }, + "success": true } +``` + +#### 错误响应 + +```json +{ "code": 589500, "message": "团期不存在", "success": false, "data": null } +``` + +#### 业务边界 + +- 授权码 `group-batch:view`;未配置权限 → 589507。 +- 只读(READ_ONLY 事务),无锁、无幂等、不改变任何状态。 +- needsIt 恒 true;doneCount 只按 `INSURED`;已取消/出单失败计入整团 ERROR。 +- 约/保整团聚合在房车导摄未全 DONE 前恒 整团待办(硬规则);已取消子订单不计入;流团团期聚合恒 整团待办。 + +--- + +## 四、契约约束与正确调用方式(接口类必写) + +> 本节只写后端接受/拒绝请求的规则,不写 UI 渲染建议。 + +### ✅ 正确 / ❌ 错误调用对照 + +| 场景 | 说明 | +|------|------| +| ✅ 网关已注入 X-Admin-Id,调任一芯片端点 | 返回 `Result`,code=200 | +| ✅ 免闸户(needsIt=false) | 房/车 status=null;导/摄 status=NONE;不计入 totalCount/doneCount | +| ❌ 未配置 `group-batch:view` 权限 | 589507 无操作权限 | +| ❌ groupBatchId 不存在/非团期/已软删 | 589500 团期不存在 | +| ❌ 客户端自行传 X-Admin-Id | 以网关注入值为准,客户端值一律忽略(不校验客户端值) | + +### 切换状态时的必要动作 + +无状态切换——六个端点均为只读 GET、无请求体;前端点击芯片即查询,请求方不需要携带任何业务状态字段,也不修改任何状态。 + +--- + +## 五、数据库行为(涉及写操作时必写) + +本组接口**无写操作**(READ_ONLY 事务),无表变更、无字段变更、无数据迁移。数据来源即为现有 order_main 六态列(needs_hotel/needs_vehicle/needs_guide/needs_photographer/合同状态/保险状态),由共享地基读取投影。 + +--- + +## 六、边界行为 + +- 未登录/无有效 token → 401(网关拦截,本组接口不允许匿名访问)。 +- 未配置 `group-batch:view` 权限 → 589507 无操作权限。 +- 团期不存在/非团期/已软删 → 589500 团期不存在。 +- 任意芯片端点输入非法(groupBatchId 非数字)→ 400 参数错误(框架级)。 +- 空团期/无活跃子订单 → data 正常返回:totalCount=0、doneCount=0、items=[],不 500 不降级。 +- 下游数据缺失(老数据无对应需求/合同/保险记录)→ 对应 status 为 null(房/车/约/保)或 NONE(导/摄),不异常。 +- 团期流团(CANCELLED)→ aggregateStatus 恒整团待办(wire 值同看板 chips.X),明细仍如实返回。 +- 已返团(审核/结算)→ 房车导摄恒 DONE 聚合。 +- 列表查询与整团伙计数一次性内存聚合(防 N+1),单次请求最多一次 `listByProductBatchId` 查询。 + +--- + +## 六.5、枚举 / 数据字典(接口出现枚举时必写) + +### items[].status(配房/配车,`com.hulalv.order.core.enums.RequirementStatus`) + +**所属字段**: `GroupBatchChipItemRespVO.status` | **类型**: `String` + +| 值 | 中文(statusText) | 说明 | +|----|------|------| +| `PENDING` | 待房务配 | 待房务/车队配 | +| `PROCESSING` | 配房中 | 配置进行中 | +| `DONE` | 配房完成 | 已完成(房/车同文案) | +| `PENDING_REVIEW` | 待审核 | 待复核 | +| `REJECTED_TO_CONSULTANT` | 驳回给定制师 | 失败态(计入整团 ERROR) | +| `REJECTED_TO_ADMIN` | 驳回给管理员 | 失败态(计入整团 ERROR) | + +### items[].status(配导游/配摄影) + +**所属字段**: `GroupBatchChipItemRespVO.status` | **类型**: `String` + +| 值 | 中文(statusText) | 说明 | +|----|------|------| +| `NONE` | 无需 | 免闸户/未开始(免闸户恒 NONE) | +| `PENDING` | 待指派 | 读侧非免闸非 DONE 一律 PENDING | +| `DONE` | 已指派 | 已完成 | + +### items[].status(合同,`com.hulalv.order.*.ContractStatus`) + +**所属字段**: `GroupBatchChipItemRespVO.status` | **类型**: `String` + +| 值 | 中文(statusText) | 说明 | +|----|------|------| +| `PENDING` | 待出具 | 待生成 | +| `GENERATED` | 已生成 | - | +| `REPORTED` | 已报备 | - | +| `UPLOADED` | 已上传 | - | +| `SIGNING` | 签署中 | - | +| `SIGNED` | 已签署 | doneCount 判定值 | +| `VOIDING` | 作废中 | 失败态(计入整团 ERROR) | +| `VOIDED` | 已作废 | 失败态(计入整团 ERROR) | + +### items[].status(保险) + +**所属字段**: `GroupBatchChipItemRespVO.status` | **类型**: `String` + +| 值 | 中文(statusText) | 说明 | +|----|------|------| +| `INSURING` | 出单中 | 投保中 | +| `INSURED` | 已出单 | doneCount 判定值 | +| `CANCELLED` | 已取消 | 失败态(计入整团 ERROR) | +| `FAILED` | 出单失败 | 失败态(计入整团 ERROR) | + +--- + +## 七、不影响范围(显式声明, 帮前端/QA 缩小排查面) + +- **仅影响**: 管理后台团期看板六芯片的逐户明细展示层接口(GB-ADM-090~095)。 +- **零影响**: + - 看板整团聚合接口(GB-ADM-001 `chips.X` 结构不变) + - 房务/车队/地接/合同/保险的任何写接口与业务流程(本组只读) + - 一期(v2)所有接口 + - 数据库结构、网关路由、权限点(复用既有 `group-batch:view`) + +--- + +## 八、测试环境已验证 + +**JUnit 定向测试**: `GroupBatchChipServiceTest`(12 用例)+ `GroupBatchChipControllerTest`(7 用例)+ 共享地基 `GroupBatchChipResolverTest`(18 用例)全绿,覆盖六端点、聚合态、免闸户、错误码 589500/589507、权限校验。 + +真实接口网关验证(2026-09-01 部署 dev-v3 @1159c8949 后实测): + +测试团期: `groupBatchId=2089713777065832450`(batch Q202610312089667212070612994,RESOURCE_PREPARING,含 1 活跃子订单) + +> 聚合态 `aggregateStatus` wire 英文四态值与看板 GB-ADM-001 `chips.X` 完全一致(读侧同源同算法);下表按中文态名展示实测结果。 + +``` +GET /v3/admin/order/group-batch/2089713777065832450/chips/hotel → 200 code=200 aggregateStatus=整团待办 total=1 done=0 items=1 ✓ +GET /v3/admin/order/group-batch/2089713777065832450/chips/vehicle → 200 code=200 aggregateStatus=整团待办 total=1 done=0 items=1 ✓ +GET /v3/admin/order/group-batch/2089713777065832450/chips/guide → 200 code=200 aggregateStatus=整团待办 total=0 items=1(needsIt=false 免闸不计 total,"无需")✓ +GET /v3/admin/order/group-batch/2089713777065832450/chips/photo → 200 code=200 aggregateStatus=整团待办 total=0 items=1(免闸,"无需")✓ +GET /v3/admin/order/group-batch/2089713777065832450/chips/contract → 200 code=200 aggregateStatus=整团待办 total=1 items=1(无合同 → statusText="无合同")✓ +GET /v3/admin/order/group-batch/2089713777065832450/chips/insurance→ 200 code=200 aggregateStatus=整团待办 total=1 items=1(无保险 → statusText="无保险")✓ +GET /v3/admin/order/group-batch/999999999999999999/chips/hotel → 200 code=589500 message="团期不存在" ✓ +GET /v3/admin/order/group-batch/abc/chips/hotel → 200 code=400 message="参数 groupBatchId 格式错误,请检查后重试" ✓ +``` + +验证通道: 统一网关 `https://api.test.1814.love:9443`,管理员登录 token + 网关注入 `X-Admin-Id`。 + +--- + +## 九、相关历史 PR(纠错 / 功能演进时必写) + +| PR | Issue | 说明 | 是否仍有效 | +|----|-------|------|------------| +| #6916 | #6915 | 共享地基 statusText 契约文案修正 + 测试补齐(本单契约基础) | ✅ 有效 | +| 本 PR(#6903 分支合并) | #6903 | 六芯片逐户明细接口交付 | ✅ 最新 | + +--- + +## 十、相关文档 + +- 关联 Issue: [wx/HL#6903](https://git.1814.love:8443/wx/HL/issues/6903) +- 关联 PR: [wx/HL#6918](https://git.1814.love:8443/wx/HL/pulls/6918)(squash 合并至 dev-v3 @1159c8949) +- 共享地基: #6902(Resolver/看板聚合)、#6916(statusText 契约修正) + +## 关联 / 联系人 + +### 链接 + +- **Issue**: [#6903](https://git.1814.love:8443/wx/HL/issues/6903) +- **PR**: 合并后回填 +- **Merge commit**: 合并后回填 + +### 联系人 + +- **后端负责人**: @wx(GIT) \ No newline at end of file