文件
hl-api-changelog/changelogs-v2/2026-09/07_7189_团期看板产品全班期基底与scope范围筛选-修改接口-管理后台.md
Mimingguang d2ed4973f7
changelog-filename-gate / validate (push) Failing after 2s
chore(changelog): 回写批次A(#7188/#7189/#7190/#7250)与 #7291 前端交付验证
五条均 frontend_status verified、owner mmg、verified_at 2026-09-08;批次A 四项 frontend_ref=2eb27845,#7291 frontend_ref=41f0bacc(均 hl-admin v2.1 可达)。
2026-09-08 08:02:04 +08:00

33 KiB

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, updated_at, base, status_note
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at updated_at base status_note
hl-changelog/v2 7189 团期看板基底改为产品全班期(含未建团行)+ 新增班期范围 scope 筛选默认未结束 + 产品页签期数改 product 侧计数 admin wx(GIT) 修改接口 deployed verified verified mmg 2eb27845 2026-09-08 2026-09-08 dev-v3 前端已交付并验证(commit 2eb27845, 汇总工单项2/项4):scope 入 store filter 单一事实源默认 ONGOING,fetchSummary/fetchBatchPage/onExport 三处同传,SearchForm 加班期范围下拉即选即查,点后段桶且 scope 非 ALL 自动切 ALL,pickProduct/onResetFilter 打回 ONGOING;未建团行 groupBatchId==null 不展开/无进入团期只留新增子订单深链,孤儿行加班期已删灰标签,index.vue 行 key 补 productBatchId 修撞 key。

团期模块:看板以产品全班期为基底 + 班期范围 scope 筛选 + 页签期数

⚠️ 关键变化

  • 列表基底变了(传 productId 时):GB-ADM-001 分页与 GB-ADM-009 统计条改以「产品侧全部班期 ∪ 订单侧团期」为基底,返回三类行:命中行(有团期)、未建团行(groupBatchId=null,产品建了班期但还没人下单)、孤儿行(productBatchRemoved=true,产品侧班期已删但团期还有活跃子订单)。改前只查 order_group_batch,产品建了 8 期看板只显 1 期,运营点不到「新增子订单」。
  • 新增筛选 scope(四端点同名同义):ONGOING 未结束(返团日 ≥ 今天或未填)/ FINISHED 已结束 / ALL 全部。缺省值按 productId 定:有 productId → ONGOING;无 productId → ALL(老调用行集不变);board 恒默认 ALL。前端范围下拉默认「未结束」,summary / export 必须与列表同传 scope,否则统计条与列表对不上账。
  • 范围 ∩ 桶是严格交集:默认 ONGOING 下点后段桶 TRIP_FINISHED / AUDITING / CHECKED(返团日必已过)会得到空列表;前端点这三个页签时自动把范围切成「全部」(或提示)。
  • 传 productId 时排序改为出发日升序(改前 create_time 倒序),分页在内存完成,pageSize 仍 ≤ 100。
  • 未建团行:batchStatus=RECRUITING(落 RECRUIT 桶)、orderCount=0、金额 0、chips 六项 TODO;enrolledRooms = 产品侧占房数(含线下占位)、remainRooms = maxRooms - 占房(不限房 → null);新增 productBatchStatus / productBatchStatusLabel(产品侧售卖状态:报名中 / 即将满额 / 已满额 / 已结束 / 取消中 / 已取消,与团期九态是两套口径)。前端对 groupBatchId=null 的行只放「新增子订单」,不展开子订单、不做任何团期操作。
  • 命中行 batchNo / batchName / batchLabel / departDate / endDate / enrollDeadline 改取 product 实时值(改名改期即时生效),孤儿行回落订单快照。
  • 子订单为 0 的行 chips 六项固定 TODO,不再为 null(含 productId 缺省路径)。
  • GB-ADM-000 产品页签 batchCount 改为 product 侧未删班期数(与传该 productId + scope=ALL 的列表行数一致),改前是订单侧团期数。

一、背景

现象

wx 2026-09-06 看测试服「团期订单」看板:产品「冻干粉发短信给」建了 8 期,看板只显 1 期(10-01,唯一有团期的班期),其余班期没有入口下单;且没有「未结束 / 已结束」筛选,历史班期与在售班期混在一起。

调用链

  1. hl-ui src/stores/orderV2Batch.js getGroupBatchPage() → GET /v3/admin/order/group-batch(GB-ADM-001)→ order-v3 GroupBatchQueryService.listPage:productId 有值 → GroupBatchMergedRowsService.listMergedRows(Feign GET /internal/product/group/{productId}/detail 取产品全班期 + order_group_batch 该产品团期 → 合并三类行 → 内存筛选 / 出发日升序 / 内存分页);productId 缺省 → 原 DB 分页 + end_date 条件
  2. 统计条 GET /v3/admin/order/group-batch/summary(GB-ADM-009)→ GroupBatchBoardStatsService.summary 同一合并基底分桶
  3. 导出 GET /v3/admin/order/group-batch/export(GB-ADM-008)→ 仍以 order_group_batch 为基底(不含未建团行),scope 按 product 实时返团日过滤
  4. 产品页签 GET /v3/admin/order/group-batch/products(GB-ADM-000)→ Feign GET /internal/product/group/all 的 batchCount(product 侧 countByProductIds 一次 in 投影)

地面真相(测试服 dev-v3 ac0ffb02dfc3aa6d1edbba2788ba2542a9cb686b,2026-09-07 00:47-00:49,产品 2044306857534636034「冻干粉发短信给」,product 侧 8 期:06-04 / 07-03 / 07-10 / 07-17 / 07-24 / 07-31 已返团,10-01 有团期,12-01 未建团)

接口 结果
分页 scope=ALL 8 行出发日升序;10-01 行 groupBatchId 非空 batchLabel="7";其余 7 行 groupBatchId=null batchStatus=RECRUITING chips 六项 TODO
分页默认(=ONGOING) 2 行(10-01、12-01);scope=FINISHED 6 行
summary 默认 RECRUIT=1 FORMED=1 其余 0 total=2;scope=ALL → total=8 RECRUIT=7 FORMED=1
products 该产品 batchCount=8
board 8 行(默认 ALL),scope=ONGOING 2 行;改前/改后 JSON 逐字段 diff:键集合无增减(batchLabel 已由 #7188 先行加入),仅 10-01 行 orderCount/enrolledRooms/enrolledPeople/remainRooms 因期间新增 4 单变化
06-04 期(线下占位 9 房 / 限 11 房,未建团) enrolledRooms=9 remainRooms=2

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 团期看板分页(GB-ADM-001) GET /v3/admin/order/group-batch 入参新增 + 响应新增字段 + 基底/排序变化 新增 scope;productId 有值时基底改合并三类行、出发日升序;records[] 新增 productBatchStatus / productBatchStatusLabel / productBatchRemoved
2 团期看板统计条(GB-ADM-009) GET /v3/admin/order/group-batch/summary 入参新增 + 基底变化 新增 scope;与 GB-ADM-001 同基底,未建团行计入 RECRUIT
3 团期看板导出(GB-ADM-008) GET /v3/admin/order/group-batch/export 入参新增 新增 scope;基底不变(不含未建团行);productId 场景新增 589515
4 团期看板合并层列表 GET /v3/admin/order/group-batch/board 入参新增(可选) 新增 scope,缺省 ALL;产品班期全删时不再返回空(孤儿行照常输出)
5 团期产品页签(GB-ADM-000) GET /v3/admin/order/group-batch/products 响应字段语义变化 batchCount 由订单侧团期数改为 product 侧未删班期数

三、接口详情

1. 团期看板分页 GET /v3/admin/order/group-batch

VO: GroupBatchListReqVO → Result<PageResult<GroupBatchPageItemRespVO>>

使用场景

团期看板列表;传 productId 时显示该产品全部班期(含未建团行),范围下拉默认「未结束」。

入参

字段 位置 类型 必填 约束 说明
productId query Long(字符串) 否 雪花 ID 有值 → 基底 = 产品全班期 ∪ 订单团期;缺省 → 只查订单侧团期(行集与改前一致)
scope query String 否 ONGOING / FINISHED / ALL;非法值按缺省处理 新增。班期范围。缺省:productId 有值 → ONGOING,缺省 → ALL
opsStage query String 否 RECRUIT / FORMED / PENDING_TRIP / TRAVELLING / TRIP_FINISHED / AUDITING / CHECKED / DISBANDED 桶筛选;与 scope 取交集;未建团行按 RECRUITING 落 RECRUIT
batchStatus query String 否 团期九态 未建团行按 RECRUITING 匹配
month query String 否 yyyy-MM 出发月份(未建团行按 product 侧出发日)
keyword query String 否 已转义 班期编号 / 名称模糊(命中行 / 未建团行按 product 实时名)
deadlineFrom / deadlineTo query String 否 yyyy-MM-dd 报名截止日区间
page query Integer 否 默认 1 页码
pageSize query Integer 否 默认 20,最大 100 每页条数

出参 Result<PageResult<GroupBatchPageItemRespVO>>

字段 类型 说明
data.records[] Array 团期行(records / total / page / pageSize);传 productId 时按出发日升序
data.records[].groupBatchId String(Long) 未建团行为 null,前端据此只放「新增子订单」
data.records[].productBatchId / productId String 三类行都有值
data.records[].batchNo / batchName / batchLabel String 命中行 / 未建团行取 product 实时值;孤儿行取订单快照
data.records[].batchStatus / batchStatusName String 团期九态;未建团行固定 RECRUITING / 招募中
data.records[].productBatchStatus String 新增。product 侧售卖状态 code:ENROLLING / NEARLY_FULL / FULL / FINISHED / CANCELLING / CANCELLED;孤儿行 null
data.records[].productBatchStatusLabel String 新增。上项中文:报名中 / 即将满额 / 已满额 / 已结束 / 取消中 / 已取消
data.records[].productBatchRemoved Boolean 新增。孤儿行 true(product 侧班期已删)
data.records[].departDate / endDate / enrollDeadline String(yyyy-MM-dd) 命中行 / 未建团行 product 实时;孤儿行快照
data.records[].maxRooms / enrolledRooms / remainRooms Integer 未建团行:enrolledRooms = product 占房数(含线下占位),remainRooms = maxRooms − 占房(不限房 null)
data.records[].orderCount / receivableAmount / receivedAmount Integer / String 未建团行 0 / "0" / "0"(实测金额串为 "0")
data.records[].chips Object hotel / vehicle / guide / photo / insurance / contract 六项(键名 photo 不是 photographer);子订单为 0 的行六项固定 TODO(不再为 null)
其余字段 — 不变

请求示例

GET /v3/admin/order/group-batch?productId=2044306857534636034&scope=ALL&pageSize=50 HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

实测(2026-09-07,只列本单相关字段;8 行中取命中行 10-01 与未建团行 12-01):

{
  "code": 200,
  "message": "成功",
  "data": {
    "records": [
      {
        "groupBatchId": "2096412454643802114",
        "productBatchId": "2052935476557328386",
        "productId": "2044306857534636034",
        "batchNo": "Q202610012052935476548939777",
        "batchName": " 没,那你",
        "batchLabel": "7",
        "batchStatus": "RESOURCE_PREPARING",
        "batchStatusName": "资源准备中",
        "productBatchStatus": "ENROLLING",
        "productBatchStatusLabel": "报名中",
        "productBatchRemoved": false,
        "departDate": "2026-10-01",
        "endDate": "2026-10-03",
        "enrollDeadline": "2026-09-30",
        "maxRooms": 8,
        "enrolledRooms": 4,
        "remainRooms": 4,
        "orderCount": 4,
        "receivableAmount": "23400.00",
        "receivedAmount": "4000.00",
        "chips": {
          "hotel": "DOING",
          "vehicle": "TODO",
          "guide": "TODO",
          "photo": "TODO",
          "contract": "TODO",
          "insurance": "TODO"
        }
      },
      {
        "groupBatchId": null,
        "productBatchId": "2096631555760807938",
        "productId": "2044306857534636034",
        "batchNo": "Q202612012096631555752419329",
        "batchName": "QA-7189-1201",
        "batchLabel": "8",
        "batchStatus": "RECRUITING",
        "batchStatusName": "招募中",
        "productBatchStatus": "ENROLLING",
        "productBatchStatusLabel": "报名中",
        "productBatchRemoved": false,
        "departDate": "2026-12-01",
        "endDate": "2026-12-03",
        "enrollDeadline": "2026-11-30",
        "maxRooms": 4,
        "enrolledRooms": 0,
        "remainRooms": 4,
        "orderCount": 0,
        "receivableAmount": "0",
        "receivedAmount": "0",
        "chips": {
          "hotel": "TODO",
          "vehicle": "TODO",
          "guide": "TODO",
          "photo": "TODO",
          "contract": "TODO",
          "insurance": "TODO"
        }
      }
    ],
    "total": 8,
    "page": 1,
    "pageSize": 50
  },
  "success": true
}

空数据 / 降级响应

传 productId 且 product 侧无班期、订单侧也无团期 → records=[];默认 ONGOING 下点后段桶(TRIP_FINISHED / AUDITING / CHECKED)交集为空也返回 records=[],前端应自动切 scope=ALL。

{
  "code": 200,
  "message": "成功",
  "data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
  "success": true
}

错误响应

{
  "code": 589515,
  "message": "获取团期产品列表失败,请稍后重试",
  "data": null,
  "success": false
}

productId 有值时依赖产品域(Feign 取全班期),产品域不可用返回 589515;productId 缺省不依赖产品域。另:589507 无操作权限。HTTP 始终 200,按 code 判断。

业务边界

  • 权限 group-batch:view
  • scope 判定用 product 实时返团日(命中 / 未建团行);孤儿行用快照;返团日未填视为未结束
  • 传 productId 时排序固定出发日升序(无出发日排最后),分页在内存完成
  • 未建团行 groupBatchId=null:不能展开子订单、不能做任何团期操作,只能「新增子订单」(深链预填 productId + productBatchId)

2. 团期看板统计条 GET /v3/admin/order/group-batch/summary

VO: Result<GroupBatchSummaryVO>(查询参数 productId / scope / month / keyword,无请求 VO)

使用场景

看板顶部桶计数;必须与列表同传 productId / scope / month / keyword。

入参

字段 位置 类型 必填 约束 说明
productId query Long(字符串) 否 雪花 ID 同 GB-ADM-001
scope query String 否 ONGOING / FINISHED / ALL 新增。缺省规则同 GB-ADM-001
month / keyword query String 否 同 GB-ADM-001 逐字同义

出参 Result<GroupBatchSummaryVO>

字段 类型 说明
data.buckets Object 固定 8 键(RECRUIT / FORMED / PENDING_TRIP / TRAVELLING / TRIP_FINISHED / AUDITING / CHECKED / DISBANDED);传 productId 时未建团行计入 RECRUIT
data.total Integer 8 桶之和 = 同筛选下 GB-ADM-001 的 total
data.subOrderCount Integer 有效子订单合计(未建团行贡献 0)

请求示例

GET /v3/admin/order/group-batch/summary?productId=2044306857534636034 HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

实测(默认 ONGOING):

{
  "code": 200,
  "message": "成功",
  "data": {
    "total": 2,
    "buckets": {
      "RECRUIT": 1,
      "FORMED": 1,
      "PENDING_TRIP": 0,
      "TRAVELLING": 0,
      "TRIP_FINISHED": 0,
      "AUDITING": 0,
      "CHECKED": 0,
      "DISBANDED": 0
    },
    "subOrderCount": 4
  },
  "success": true
}

空数据 / 降级响应

无命中时 8 键全 0、total=0,不省略键。

{
  "code": 200,
  "message": "成功",
  "data": { "buckets": { "RECRUIT": 0, "FORMED": 0, "PENDING_TRIP": 0, "TRAVELLING": 0, "TRIP_FINISHED": 0, "AUDITING": 0, "CHECKED": 0, "DISBANDED": 0 }, "total": 0, "subOrderCount": 0 },
  "success": true
}

错误响应

{
  "code": 589515,
  "message": "获取团期产品列表失败,请稍后重试",
  "data": null,
  "success": false
}

业务边界

  • 桶计数不受 opsStage 影响(本接口不接受 opsStage)
  • 传 productId 时与 GB-ADM-001 共用同一合并基底与筛选,逐桶 = 列表按该桶筛选的 total

3. 团期看板导出 GET /v3/admin/order/group-batch/export

VO: 无请求 VO(查询参数 productId / scope / month / keyword / opsStage) → CSV 文件流 text/csv

使用场景

导出当前列表;与列表同传 scope。

入参

字段 位置 类型 必填 约束 说明
scope query String 否 ONGOING / FINISHED / ALL 新增。缺省规则同 GB-ADM-001;按 product 实时返团日过滤
productId / month / keyword / opsStage query — 否 不变 不变

出参 CSV 文件流

字段 类型 说明
(响应体) text/csv BOM + 表头 团期号,期号,日期,出团日,满团名额,已售,剩余,状态,子订单数,整团应收,列与改前一致
行集 — 不含未建团行(只导有团期的行);行数 = 同 scope 下 GB-ADM-001 中 groupBatchId 非空的行数(例外:产品侧班期已删且 0 活跃单的残留团期会出现在导出、不出现在列表)
日期列 — 行内「日期 / 出团日」仍是订单快照;scope 的未结束判定用 product 实时返团日(AC-14 实测:改期后行进入导出,日期列仍显快照)

请求示例

GET /v3/admin/order/group-batch/export?productId=2044306857534636034&scope=ALL HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

文件流(Content-Type: text/csv; Content-Disposition: attachment),JSON 仅示意:

{
  "code": 200,
  "message": "文件流(text/csv),实际响应体为下方 CSV"
}

实测(2026-09-07):scope=ALL 表头 + 1 行(10-01 团期);默认 ONGOING 1 行;scope=FINISHED 0 行。

团期号,期号,日期,出团日,满团名额,已售,剩余,状态,子订单数,整团应收
Q202610012052935476548939777,没,那你,2026-10-01~2026-10-03,2026-10-01,8,4,4,已成团,4,23400.00

空数据 / 降级响应

无命中只返回表头一行;命中 > 2000 行返回 589517。

{
  "code": 589517,
  "message": "导出行数超过上限,请缩小筛选范围",
  "data": null,
  "success": false
}

错误响应

productId 有值且 scope≠ALL 时会调产品域取实时返团日,产品域不可用返回 589515(改前导出不依赖产品域)。

{
  "code": 589515,
  "message": "获取团期产品列表失败,请稍后重试",
  "data": null,
  "success": false
}

业务边界

  • 权限 group-batch:export
  • 导出基底与列表基底不同(不含未建团行),前端导出按钮旁如需提示请用「仅导出已建团期」

4. 团期看板合并层列表 GET /v3/admin/order/group-batch/board

VO: Result<List<GroupBatchBoardItemRespVO>>(查询参数 productId 必填、scope 可选)

使用场景

以产品全部班期为基底的看板(hl-ui 当前未调用);本单只加可选 scope,响应结构不变。

入参

字段 位置 类型 必填 约束 说明
productId query Long(字符串) 是 雪花 ID 不变
scope query String 否 ONGOING / FINISHED / ALL 新增。缺省 ALL(保持既有行集)

出参 Result<List<GroupBatchBoardItemRespVO>>

字段 类型 说明
data[] Array 行集:命中 / 未建团 / 孤儿三类行,出发日升序;本单结构不变
data[].groupBatchId String(Long) 未建团行 null(不变)
data[].productBatchRemoved Boolean 孤儿行 true;行为变化:产品班期全部删除时不再提前返回空,仍有活跃子订单的孤儿行照常输出
data[].batchLabel / batchName / batchNo / departureDate / endDate String 命中 / 未建团行 product 实时,孤儿行快照(不变)
其余字段 — 不变

请求示例

GET /v3/admin/order/group-batch/board?productId=2044306857534636034&scope=ONGOING HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

实测默认(ALL)8 行、scope=ONGOING 2 行;改前/改后逐字段 diff 见「地面真相」。

{
  "code": 200,
  "message": "成功",
  "data": [
    {
      "productBatchId": "2052935476557328386",
      "groupBatchId": "2096412454643802114",
      "departureDate": "2026-10-01",
      "endDate": "2026-10-03",
      "batchName": " 没,那你",
      "batchLabel": "7",
      "batchStatus": "RESOURCE_PREPARING",
      "productBatchRemoved": false,
      "orderCount": 4,
      "enrolledRooms": 4,
      "remainRooms": 4
    },
    {
      "productBatchId": "2096631555760807938",
      "groupBatchId": null,
      "departureDate": "2026-12-01",
      "endDate": "2026-12-03",
      "batchName": "QA-7189-1201",
      "batchLabel": "8",
      "batchStatus": "RECRUITING",
      "productBatchRemoved": false,
      "orderCount": 0,
      "enrolledRooms": 0,
      "remainRooms": 4
    }
  ],
  "success": true
}

空数据 / 降级响应

产品无班期且无团期 → data=[]。

{
  "code": 200,
  "message": "成功",
  "data": [],
  "success": true
}

错误响应

{
  "code": 589515,
  "message": "获取团期产品列表失败,请稍后重试",
  "data": null,
  "success": false
}

另:589507 无操作权限。

业务边界

  • 与 GB-ADM-001 共用 GroupBatchMergedRowsService 合并逻辑,三类行判定一致

5. 团期产品页签 GET /v3/admin/order/group-batch/products

VO: Result<List<GroupBatchProductItemRespVO>>

使用场景

看板左侧产品页签「N 期」徽标。

入参

字段 位置 类型 必填 约束 说明
(无) — — — — 无查询参数,返回当前账号可见的全部团期产品

出参 Result<List<GroupBatchProductItemRespVO>>

字段 类型 说明
data[].batchCount Integer 语义变化:改前 = 订单侧团期数(只有下过单的班期才算),改后 = product 侧未删班期数,与传该 productId + scope=ALL 的列表行数一致
其余字段 — 不变

请求示例

GET /v3/admin/order/group-batch/products HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

实测(只列该产品):

{
  "code": 200,
  "message": "成功",
  "data": [
    {
      "productId": "2044306857534636034",
      "productName": "冻干粉发短信给",
      "productNo": "G260415004",
      "category": "family",
      "subtitle": "发短信给对方搞定",
      "coverImageUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/test/material/2026/03/07/ed278d1da74c3827cb06b7f0cf6091fe.jpg",
      "lineId": "2044248925572919297",
      "lineName": "阿斯蒂芬撒点",
      "tripDays": 3,
      "tripNights": 2,
      "status": "PUBLISHED",
      "sortOrder": 0,
      "batchCount": 8,
      "regionText": null
    }
  ],
  "success": true
}

空数据 / 降级响应

无团期产品 → data=[];产品无班期 → batchCount=0。

{
  "code": 200,
  "message": "成功",
  "data": [],
  "success": true
}

错误响应

{
  "code": 589515,
  "message": "获取团期产品列表失败,请稍后重试",
  "data": null,
  "success": false
}

业务边界

  • 徽标直接显示 batchCount,不要用列表 total 反推(列表默认 ONGOING 只含未结束)

四、契约约束与正确调用方式

四个 GET 接口均只读;本节写前端消费规则。

✅ 正确 / ❌ 错误 payload 对照

场景 payload / 处理
✅ 看板默认加载 列表 ?productId=X(不传 scope = ONGOING)+ 统计条 ?productId=X 同样不传
✅ 用户切范围 列表 / 统计条 / 导出三处同时带 scope=FINISHED 或 ALL
✅ 点后段桶 opsStage=TRIP_FINISHED / AUDITING / CHECKED 时把范围切成 scope=ALL 再请求
✅ 未建团行 groupBatchId == null → 只渲染「新增子订单」(深链带 productId + productBatchId),隐藏展开 / 操作列
✅ 孤儿行 productBatchRemoved == true → 标「班期已删」,仍可看子订单
✅ 状态展示 团期态用 batchStatus;售卖态用 productBatchStatusLabel(两套口径,不要互相推导)
❌ 只给列表传 scope、统计条不传 统计条会按默认 ONGOING,与列表对不上账
❌ 用列表 total 当页签期数 默认 ONGOING 不含已结束期;徽标用 batchCount
❌ 对 groupBatchId=null 的行调详情 / 子订单 / 团期操作 后端 589500 团期不存在
❌ 把 chips 为 TODO 的未建团行当「待办」 未建团行没有子订单,六项 TODO 只是零户占位

切换状态时的必要动作

无写接口。范围切换 / 页签切换后同时刷新列表与统计条(同一组参数)。


五、数据库行为

无表变更、无 Flyway。读路径变化:

时点 读取
GB-ADM-001 / 009 传 productId Feign GET /internal/product/group/{productId}/detail(product 全班期,含 occupiedRooms / manualOrderCount)+ order_group_batch 该产品团期 → 内存合并
GB-ADM-001 / 009 / 008 缺省 productId order_group_batch 单表;scope 落 end_date >= 今天 OR end_date IS NULL / end_date < 今天
GB-ADM-000 Feign GET /internal/product/group/all 的 batchCount(product 侧 group_tour_batch 按 productId 一次 in 投影计数,软删不计)

写路径不变(建团 / 下单刷新快照见 #7188)。


六、边界行为

  • 未登录 → 网关 401;无权限 → 589507
  • 传 productId 时产品域不可用 → 589515(列表 / 统计条 / 导出三处;缺省 productId 不依赖产品域)
  • scope 非法值(如 scope=xxx)→ 按缺省规则处理,不报错
  • 返团日未填的班期 / 团期 → 视为未结束(ONGOING 含、FINISHED 不含)
  • 默认 ONGOING 下 opsStage 取后段桶 → 空列表(交集),不报错
  • 产品班期全删但团期仍有活跃子订单 → 列表 / board 都输出孤儿行;0 活跃单的残留团期不输出(导出仍会导出它)
  • 合并行超过 500 记 WARN(护栏,不截断)

六.5、枚举 / 数据字典

枚举 值 说明
scope ONGOING / FINISHED / ALL 未结束(返团日 ≥ 今天或未填)/ 已结束(返团日 < 今天)/ 全部
productBatchStatus ENROLLING / NEARLY_FULL / FULL / FINISHED / CANCELLING / CANCELLED 报名中 / 即将满额 / 已满额 / 已结束 / 取消中 / 已取消(product 侧售卖态)
batchStatus(未建团行) RECRUITING 固定值,落 RECRUIT 桶

六.6、修改前后对比

字段级对比

字段 修改前 修改后
GB-ADM-001 / 009 / 008 / board scope 无 新增(缺省按 productId:有 → ONGOING,无 → ALL;board → ALL)
GB-ADM-001 records[].productBatchStatus / productBatchStatusLabel / productBatchRemoved 无 新增
GB-ADM-001 records[].groupBatchId 恒非空 未建团行 null
GB-ADM-001 records[].chips(0 子订单行) null 六项 TODO
GB-ADM-001 records[].batchNo / batchName / 日期(命中行) 订单快照 product 实时
GB-ADM-000 data[].batchCount 订单侧团期数 product 侧未删班期数
product GET /internal/product/group/all batchCount、/group/{productId}/detail batches[].occupiedRooms / manualOrderCount 无 新增(内部接口,前端不直接调)

行为级对比

场景 修改前 修改后
传 productId 的列表 只显有团期的班期(8 期显 1 期) 显全部班期(8 行),未建团行可「新增子订单」
传 productId 的排序 create_time 倒序 出发日升序
默认范围 无范围概念,全部 传 productId 默认只显未结束;缺省 productId 仍全部
统计条 只统计有团期的 与列表同基底,未建团行计入 RECRUIT
产品班期全删 board 返回空(有客人的团期被藏) 孤儿行照常输出
页签期数 下过单的班期数 产品班期数

六.7、影响评估

  • 向后兼容:缺省 productId 的调用行集与排序不变;传 productId 的老调用行数与排序会变(多出未建团行、按出发日升序、默认只含未结束),hl-ui 看板必须按第四节处理 groupBatchId=null
  • 前端是否必须同步上线:是(否则看板会出现不可操作的未建团行、点后段桶得空列表)
  • 数据:无表变更;依赖产品域可用性(589515)

七、不影响范围

  • 仅影响: 团期看板列表 / 统计条 / 导出 / board / 产品页签
  • 零影响:
    • 团期详情 GB-ADM-002、子订单 GB-ADM-003、芯片明细 GB-ADM-092/093(仍按 groupBatchId 查)
    • 创单 / 报价 / 状态机 / 按日推进 job(#7190,仍 PAUSED)
    • 小程序、product 管理端班期列表

八、测试环境已验证

真实接口输出(测试服 api.test.1814.love,2026-09-07 00:47-00:49,登录后切 ADMIN 角色):

GET /v3/admin/order/group-batch?productId=2044306857534636034&scope=ALL&pageSize=50   → 200, total=8,出发日升序 06-04..12-01;10-01 行 groupBatchId=2096412454643802114 batchLabel="7";其余 7 行 groupBatchId=null batchStatus=RECRUITING orderCount=0 receivableAmount="0" chips 六项 TODO productBatchStatus 有值 ✓
GET /v3/admin/order/group-batch?productId=2044306857534636034&pageSize=50             → 200, 默认 ONGOING total=2(10-01、12-01)✓;scope=FINISHED total=6 ✓
GET /v3/admin/order/group-batch/summary?productId=2044306857534636034                 → RECRUIT=1 FORMED=1 其余 0 total=2 subOrderCount=4 ✓;scope=ALL → total=8 RECRUIT=7 FORMED=1 ✓
GET /v3/admin/order/group-batch?productId=…&scope=ALL&opsStage=RECRUIT                → total=7 = summary(ALL).RECRUIT ✓;默认范围 opsStage=RECRUIT → total=1(12-01)= summary.RECRUIT ✓
GET /v3/admin/order/group-batch?productId=…&scope=ALL&month=2026-10                   → total=1(10-01)✓;keyword=没 → total=1(10-01)✓
GET /v3/admin/order/group-batch/products                                              → 该产品 batchCount=8 ✓
GET /v3/admin/order/group-batch?pageSize=100(缺省 productId)                        → 改前/改后 20 行 groupBatchId 集合与顺序完全一致 ✓;scope=ONGOING 全部 endDate ≥ 今天 ✓;行内差异仅 chips(0 单行 null→六项 TODO,16 行)与 10-01 行计数(期间他人新下 4 单)
GET /v3/admin/order/group-batch/board?productId=2044306857534636034                   → 8 行,改前/改后逐字段 diff:键集合无增减,仅 10-01 行 orderCount/enrolledRooms/enrolledPeople/remainRooms 因新增 4 单变化 ✓;scope=ONGOING → 2 行 ✓
GET /v3/admin/order/group-batch/export?productId=…&scope=ALL|默认|FINISHED            → 数据行 1 / 1 / 0 = 列表同 scope 下 groupBatchId 非空行数 ✓
GET /v3/admin/order/group-batch?productId=2061640294608134146&scope=ALL               → 造数 maxRooms=0+manual=3 期 enrolledRooms=3 remainRooms=null ✓;maxRooms=5+manual=2 期 enrolledRooms=2 remainRooms=3 ✓;P1 06-04 期(线下 9/11)enrolledRooms=9 remainRooms=2 ✓
AC-14:PUT /admin/product/item/2056944943066132481/schedule 把班期 2089667211995115522 出发日 09-05→09-13(返团日昨天→下周),不下单:分页默认 total 8→9 且含团期 2089667627927437313(departDate=2026-09-13 endDate=2026-09-14)✓、summary FORMED 5→6 ✓、export 数据行 6→7 含该班期号 ✓;随后改回 09-05,三处恢复 8 / 5 / 6 ✓

验证产品:productId=2044306857534636034(冻干粉发短信给,8 期)、AC-13 载体 2061640294608134146(副本,造 maxRooms=0/manual=3 与 maxRooms=5/manual=2 两期)、AC-14 载体 2056944943066132481 班期 2089667211995115522(返团日昨天 → 改出发日到下周 → 三处出现 → 改回)。单测:order-v3 全量 JAVA_TOOL_OPTIONS=-Xmx3g mvn -pl hl-order-service-v3 test 8658/0/0(Skipped 7,ArchTest 六道门禁全绿)、product-v2 全量 1556/0/0;触点定向 ConverterTest 49 / QueryServiceTest 37 / ConsoleQueryServiceTest 27 / BoardStatsServiceTest 21 / MergedRowsServiceTest 18 / MapperIT 17(Testcontainers)/ ScopeResolverTest 9 / QueryControllerTest 8 / BoardStatsControllerTest 7 = 234/0/0。部署:Deploy Panel 00:47-00:49 product-v2 与 order-v3 滚动完成,分支 dev-v3。


十、相关文档

  • 关联 Issue: wx/HL#7189
  • 关联 PR: wx/HL#7219
  • 同现场: #7188(batchLabel「第N期」)、#7190(TRIP_FINISHED 九态 / 八桶)、#7204(导/摄芯片零指派口径)
  • 前端缺陷 changelog: 06_frontend_团期看板展开行子订单列表恒空-前端缺陷-管理后台.md

关联 / 联系人

链接

联系人

  • 后端负责人: @wx