From 09d3728e92b8acc9c26fe177807327eb598118b2 Mon Sep 17 00:00:00 2001 From: jw Date: Wed, 23 Sep 2026 09:52:17 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20=E5=9B=A2=E6=9C=9F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=20A2=20=E6=96=B0=E5=A2=9E=E5=87=BA=E5=8F=82=20subOrde?= =?UTF-8?q?rCount=EF=BC=88#8215=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 活跃子订单户数,与 A3 total / 看板 orderCount 同源同值。 TEST 09:50 三接口同轮实测均为 12(dev-v3 @ fc0508981)。 纯增出参,路径/入参/权限码/其余字段零变化,网关无改动。 前端是否取的就是这个字段名待确认,frontend_status 记 pending。 --- ...期详情补子订单户数字段-修改接口-管理后台.md | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 changelogs-v2/2026-09/23_8215_团期详情补子订单户数字段-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/23_8215_团期详情补子订单户数字段-修改接口-管理后台.md b/changelogs-v2/2026-09/23_8215_团期详情补子订单户数字段-修改接口-管理后台.md new file mode 100644 index 00000000..5211611a --- /dev/null +++ b/changelogs-v2/2026-09/23_8215_团期详情补子订单户数字段-修改接口-管理后台.md @@ -0,0 +1,207 @@ +--- +schema: "hl-changelog/v2" +ticket: "8215" +title: "团期详情(A2)新增出参 subOrderCount——活跃子订单户数,与 A3 total / 看板 orderCount 同源" +consumer: "admin" +author: "jw(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "not_required" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "2026-09-23" +status_note: "团期详情页右上角显示「子订单 0 户」,同页「已建子订单 12 户」「整团名单速览(12 户)」却是 12。2026-09-23 对 TEST 团期 2101506167098511362 逐接口实测,后端四个接口无一返回 0:A2 详情 formingRooms/enrolledRooms/maxRooms 全 12、A3 子订单列表 total=12 且 records 有数据、看板 orderCount=12、财务 items 12 条。右上角三个金额(应收 156760 / 已收 47940 / 待收 108820)与 A2 的 receivableAmount/receivedAmount/unpaidAmount 逐字一致,说明该 UI 绑的就是详情响应对象——而详情原有的 50 个字段里没有任何子订单户数字段,前端取到 undefined 渲染成 0。subOrderCount 这个名字在 order-v3 里原本只存在于看板统计条 VO(GroupBatchSummaryVO,口径是命中筛选的全部团期活跃子订单合计,属列表页统计条)。本次后端兜底:A2 详情新增出参 subOrderCount,取数复用既有契约方法 OrderService#countActiveByProductBatchIds——A3 的 total 与看板 orderCount 走的都是它,口径同为 order_status != CANCELLED 加 @TableLogic 软删过滤,刻意不另写 count,避免「同屏两个数字不一致」换个形式复发。字段恒非 null,无活跃子订单返 0 而非 null。已合并 dev-v3(PR #8216,merge commit fc0508981)并部署测试服,09:50 三接口同轮实测同为 12。路径、入参、权限码、其余出参字段零变化,网关无改动。前端侧需确认该页取的就是 subOrderCount 这个字段名,故 frontend_status 记 pending。" +updated_at: "2026-09-23" +base: "dev-v3" +--- + +# 团期详情(A2)新增出参 subOrderCount(管理后台) + +> **服务**: hl-order-service-v3(端口 8086/8186) + +## 一、接口背景 + +团期详情页右上角同时渲染「成团状态 + 子订单户数 + 整团应收/已收/待收」。其中三个金额来自本接口, +而「子订单户数」在本次之前**本接口并不返回**——前端取到 `undefined`,渲染成 `0`, +与同页「已建子订单 12 户」「整团名单速览(12 户)」同屏打架。 + +本次在本接口补上该字段,取数与 A3 子订单列表、团期看板行**共用同一个契约方法**,三处必然同值。 + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|---|---|---|---|---| +| 1 | A2 团期详情 | GET | `/v3/admin/order/group-batch/{groupBatchId}` | 修改接口 | 新增出参 `subOrderCount`,其余字段与行为零变化 | + +## 三、接口详情 + +### 1. A2 团期详情 `GET /v3/admin/order/group-batch/{groupBatchId}` + +**VO**: `GroupBatchDetailRespVO` + +#### 使用场景 + +团期详情页进入时拉取整团概览:状态机阶段、成团闸/满员闸计数、四项 ready 标志、整团金额三项, +以及本次新增的活跃子订单户数。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| groupBatchId | path | Long | 是 | 正整数,团期聚合主键 | 团期 ID,非法或不存在返 GROUP_BATCH_NOT_FOUND | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| subOrderCount | Integer | **本次新增**。挂在本团期下的活跃子订单张数(户数)。口径:`order_main.product_batch_id` = 本团期 productBatchId 且 `order_status != CANCELLED`,软删由 `@TableLogic` 过滤。与 A3 子订单列表的 `total`、看板行的 `orderCount` 同一取数口径、同一契约方法,三处同值。恒非 null,无活跃子订单为 0 | +| formingRooms | Integer | 成团判定用户数 = 线上已付款活跃订单数 + 产品域线下占位(#7287)。**与 subOrderCount 不是一回事**,有线下占位时必然大于后者 | +| enrolledRooms | Integer | 已用房间数(既有字段,本次未改) | +| receivableAmount | BigDecimal | 整团应收(既有字段,本次未改) | +| receivedAmount | BigDecimal | 整团已收(既有字段,本次未改) | +| unpaidAmount | BigDecimal | 整团待收 = max(0, 应收 − 已收)(既有字段,本次未改) | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/2101506167098511362 HTTP/1.1 +Host: api.test.1814.love:9443 +Authorization: Bearer +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "groupBatchId": "2101506167098511362", + "batchName": "jw测试1期", + "opsStage": "FORMED", + "opsStageName": "已成团", + "subOrderCount": 12, + "formingRooms": 12, + "enrolledRooms": 12, + "maxRooms": 12, + "receivableAmount": "156760.00", + "receivedAmount": "47940.00", + "unpaidAmount": "108820.00" + } +} +``` + +#### 空数据 / 降级响应 + +团期存在但名下没有活跃子订单(全部 CANCELLED,或建团后尚未下单)时,`subOrderCount` 返 `0`, +**不返 null、不缺字段**——null 在前端同样会渲染成空或 0,等于把本次要修的缺陷藏回去。 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "groupBatchId": "2101506167098511363", + "opsStage": "RECRUIT", + "subOrderCount": 0, + "receivableAmount": "0.00", + "receivedAmount": "0.00", + "unpaidAmount": "0.00" + } +} +``` + +#### 错误响应 + +```json +{ + "code": 589501, + "message": "团期不存在", + "data": null +} +``` + +| 错误码 | 触发条件 | +|---|---| +| 589501 | groupBatchId 不存在或已软删 | +| 403 | 缺 `group-batch:view` 权限码,或定制师访问非自己归属的团期 | + +#### 业务边界 + +- `subOrderCount` 只回答「这个团下面挂了几张活跃子订单」,**不含任何产品域线下占位**。 +- 已取消(CANCELLED)子订单不计入;软删由 `@TableLogic` 过滤,与 A3 缺省(`includeCancelled=false`)一致。 +- 与 A3 的 `total` 必然同值:两者调用同一个 `OrderService#countActiveByProductBatchIds` / 同一过滤条件。 +- 退单户(withdraw)在未置 CANCELLED 前仍计入,与 A3 行为一致。 + +## 四、契约约束与正确调用方式 + +- 前端渲染「子订单 N 户」请取 `data.subOrderCount`,**不要取 `formingRooms`**(那是成团判定用数,含线下占位)。 +- 需要逐户明细时仍走 A3 `GET /v3/admin/order/group-batch/{groupBatchId}/orders`,其分页包装为 + `{ records, total, page, pageSize }`——列表字段名是 `records`,不是 `list`。 +- 本字段是纯增出参,老调用方忽略它即可,无需改动。 + +## 五、数据库行为 + +零数据库变更。本次不新增表/列/索引,不写任何数据;`subOrderCount` 的数据来源是既有列 +`order_main.product_batch_id` + `order_main.order_status` 的只读聚合,走既有契约方法,未新增 mapper 查询。 + +## 六、边界行为 + +- 团期不存在 → 589501,不返回半个对象。 +- 团期存在、无活跃子订单 → `subOrderCount: 0`(见「空数据 / 降级响应」)。 +- 团期下既有活跃单又有已取消单 → 只数活跃的,与 A3 缺省口径一致。 + +## 六.6、修改前后对比 + +| 项 | 修改前 | 修改后 | +|---|---|---| +| 出参字段数 | 50 | 51 | +| `subOrderCount` | **不返回**(前端取到 undefined,页面渲染成 0) | 返回活跃子订单户数,恒非 null | +| 其余出参字段 | — | 逐字未变 | +| 路径 / 入参 / 权限码 | — | 逐字未变 | +| 取数来源 | — | 复用 `OrderService#countActiveByProductBatchIds`(A3 与看板同款),未新增查询 | + +## 六.7、影响评估 + +- **兼容性**:纯增出参,老调用方忽略即可,无破坏性。 +- **性能**:详情装配内多一次按单个 productBatchId 的活跃单计数,走既有契约方法(A1 列表/看板/合并行三处已在用), + 单元素入参,无 N+1;落在既有 `@Transactional(readOnly = true)` 的库内装配段,不涉及 Feign。 +- **回滚**:撤销 PR #8216 即可,无数据与配置残留。 +- **未覆盖**:本次只证明后端返对了值。页面上那个 `0` 是否消失,取决于前端该处取的是不是 + `subOrderCount` 这个字段名——属前端侧确认项,`frontend_status` 记 `pending`。 + +## 七、不影响范围 + +- A3 团期下子订单列表、团期看板、团期财务总览:口径与字段零改动。 +- `formingRooms` / `enrolledRooms` / 金额三项:取数来源与数值零改动。 +- 网关:路径未变、无新增路由与权限码,`gateway_status: not_required`。 +- 小程序端:本接口仅管理后台使用,未涉及。 + +## 八、测试环境已验证 + +2026-09-23 09:50 测试服(api.test.1814.love:9443),团期 `2101506167098511362`(jw测试产品·第1期,已成团), +部署 `dev-v3 @ fc0508981`,三接口**同轮**实测: + +| 接口 | 字段 | 读数 | +|---|---|---| +| A2 团期详情 | `subOrderCount` | **12** | +| A3 子订单列表 | `total` | **12** | +| 团期看板 | `orderCount` | **12** | + +同轮 `formingRooms=12`、`enrolledRooms=12`,与 `subOrderCount` 在本团期恰好同值(该团无线下占位)。 + +单元测试:`GroupBatchQueryServiceTest` 80 例 0 失败(新增 3 条,经 surefire XML 核实真执行,无 skipped), +`GroupBatchQueryControllerTest` 9 例 0 失败,合计 89/0。 + +## 十、相关文档 + +- 工单 #8215、PR #8216(merge commit `fc0508981`) +- `formingRooms` 口径出处:#7287 +- A3 分页包装形态(`records` 而非 `list`)出处:#7536 + +## 关联 / 联系人 + +- 后端:jw +- 前端:待确认该页取值字段名(`frontend_status: pending`)