活跃子订单户数,与 A3 total / 看板 orderCount 同源同值。 TEST 09:50 三接口同轮实测均为 12(dev-v3 @ fc0508981)。 纯增出参,路径/入参/权限码/其余字段零变化,网关无改动。 前端是否取的就是这个字段名待确认,frontend_status 记 pending。
9.6 KiB
schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
| schema | ticket | title | consumer | author | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | 8215 | 团期详情(A2)新增出参 subOrderCount——活跃子订单户数,与 A3 total / 看板 orderCount 同源 | admin | jw(GIT) | 修改接口 | deployed | not_required | pending | 2026-09-23 | 团期详情页右上角显示「子订单 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。 | 2026-09-23 | 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, 应收 − 已收)(既有字段,本次未改) |
请求示例
GET /v3/admin/order/group-batch/2101506167098511362 HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <admin token>
响应示例
{
"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,等于把本次要修的缺陷藏回去。
{
"code": 200,
"message": "成功",
"data": {
"groupBatchId": "2101506167098511363",
"opsStage": "RECRUIT",
"subOrderCount": 0,
"receivableAmount": "0.00",
"receivedAmount": "0.00",
"unpaidAmount": "0.00"
}
}
错误响应
{
"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)