15 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 | 8413 | 团期看板导出与统计条补齐列表新筛选:导出接收团期状态 / 截止日 / 出发区间 / 排序(看到什么导什么),统计条接收截止日 / 出发区间;三接口截止日非法值改为忽略 | admin | jw(GIT) | 修改接口 | deployed | verified | verified | mmg | 31e17e92726aa8d4251e60b107dc2d6ea8fb67d3 | v2.1 | 2026-09-27 | jw 2026-09-27 定:统计条只跟截止日、出发区间(不跟团期状态 / 看板桶 / 排序);导出看到什么导什么(传排序同列表,不传与列表各自默认一致:按产品 = 出发日升序、不按产品 = 建团时间倒序);导出不带分页、保持 2000 行上限。PR #8417(主体)+ #8432(截止日宽容解析)已合 dev-v3(dada3a8f4)并部署 TEST。2026-09-27 11:54~15:12 经真实网关实测:按产品与全局两种基底、团期状态 / 截止日 / 出发区间组合与三个排序字段 × 升降序、不传排序,导出行集与顺序均与列表已建团行逐一致;产品侧改期(快照 12-10 / 实时 12-15)后按实时日期筛,列表与导出同时命中、按快照日期同时不命中;统计条 total = 列表 total = 七桶之和,filteredOutCount 非零场景(8 / 15)与「ALL − ONGOING」一致;统计条多传团期状态 / 看板桶 / 排序结果不变;非法截止日期三接口均 200 且等同不传该条件(改前列表与导出 500)。TEST 全库团期仅 298 条,2000 行上限由单测覆盖。前端需把列表当前筛选同步传给统计条与导出,故 frontend_status 记 pending。前端已交付:看板 UI 无团期状态/报名截止日筛选控件(grep 实证筛选事实源仅产品/桶/月/关键词/出团区间/排序),batchStatus/deadline 三参无事实源不落;store fetchSummary 补 depart 对(空值不落参,排序/桶仍不带),onExport 补 depart 对+sortBy/sortOrder(看到什么导什么);截止日非法值忽略对前端无影响。store spec 13 例+看板页 spec 10 例全绿,checkpoint 全量通过。 | 2026-09-27 | dev-v3 |
团期看板:导出与统计条跟上列表筛选(管理后台)
服务: hl-order-service-v3(端口 8086/8186) PR: #8417、#8432 Issue: #8413 日期: 2026-09-27 影响范围: 管理后台「团期订单」看板的统计条与「导出」按钮;列表接口仅截止日非法值的处理变化
⚠️ 关键变化
- 导出新增入参:
batchStatus、deadlineFrom/deadlineTo、departFrom/departTo、sortBy/sortOrder,与列表同名同义。前端把列表当前的全部筛选和排序原样传给导出,导出的行和顺序就与列表一致(导出不含未建团行,这一点不变)。 - 导出不传排序时的默认顺序变了(仅不按产品时):以前一律按出发日升序;现在与列表一致——按产品看 = 出发日升序,不按产品看 = 建团时间倒序。
- 统计条新增入参:
deadlineFrom/deadlineTo、departFrom/departTo。不接收团期状态、看板桶、排序——统计条是按桶分组的计数,前端传了也会被忽略。 - 报名截止日非法值不再报 500:列表、导出、统计条传非法截止日期(如
bad-date、2026-02-30)时忽略该条件,与出发区间一致。以前列表和导出会整页返回 500。
一、背景
列表先后加了团期状态、报名截止日、出发区间(#7770)和排序(#7770),导出和统计条没跟上:运营在列表上筛完,顶部统计条数字对不上,导出拿到的也是没筛的全量、顺序也不同。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 导出团期列表 | GET | /v3/admin/order/group-batch/export |
修改 | 新增团期状态 / 截止日 / 出发区间 / 排序入参;不按产品时默认顺序改为建团时间倒序 |
| 2 | 团期看板统计条 | GET | /v3/admin/order/group-batch/summary |
修改 | 新增截止日 / 出发区间入参 |
| 3 | 团期分页列表 | GET | /v3/admin/order/group-batch |
修改 | 截止日非法值由 500 改为忽略该条件 |
三、接口详情
1. 导出团期列表 GET /v3/admin/order/group-batch/export
VO: GroupBatchListReqVO(入参,与列表同一个)→ CSV 附件(固定 10 列,不变)
使用场景
看板点「导出」,导出当前筛选下的全部已建团团期(不分页,单次上限 2000 行)。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| productId | query | Long | 否 | — | 原有 |
| month | query | String | 否 | yyyy-MM | 原有,决定文件名 |
| keyword | query | String | 否 | — | 原有 |
| opsStage | query | String | 否 | 七桶 code | 原有 |
| scope | query | String | 否 | ONGOING / FINISHED / ALL | 原有 |
| batchStatus | query | String | 否 | 九态 code | 新增,精确匹配 |
| deadlineFrom / deadlineTo | query | String | 否 | yyyy-MM-dd,非法值忽略 | 新增,报名截止日区间 |
| departFrom / departTo | query | String | 否 | yyyy-MM-dd,非法值忽略 | 新增,出团日期区间 |
| sortBy | query | String | 否 | departDate / enrollDeadline / createTime,非法值忽略 | 新增 |
| sortOrder | query | String | 否 | asc / desc,缺省或非法 asc | 新增 |
pageNo / pageSize 即使传了也不生效(导出不分页)。
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| (CSV 附件) | text/csv | 列:团期号、期号、日期、出团日、满团名额、已售、剩余、状态、子订单数、整团应收;不变 |
请求示例
GET /v3/admin/order/group-batch/export?productId=2056944943066132481&scope=ALL&batchStatus=RECRUITING&deadlineFrom=2026-10-01&deadlineTo=2026-12-31&departFrom=2026-10-01&departTo=2027-01-31&sortBy=departDate&sortOrder=desc
Authorization: Bearer <admin token>
响应示例
成功时直接返回 CSV 文件流(Content-Disposition: attachment),不套 Result 信封。
{
"说明": "成功响应为 CSV 附件,此处仅示意首行表头",
"header": "团期号,期号,日期,出团日,满团名额,已售,剩余,状态,子订单数,整团应收"
}
空数据 / 降级响应
无命中时返回只含表头的 CSV。按产品导出时要调产品服务取实时日期,产品服务不可用返回 589515(与列表、统计条一致):
{
"code": 589515,
"message": "获取团期产品列表失败,请稍后重试",
"data": null,
"success": false
}
错误响应
| code | 触发条件 |
|---|---|
589517 |
全部筛选后命中超过 2000 行 |
589515 |
按产品导出时产品服务不可用 |
589507 |
无导出权限(group-batch:export,未改) |
{
"code": 589517,
"message": "导出数据量超过单次上限,请缩小筛选范围后重试",
"data": null,
"success": false
}
业务边界
- 看到什么导什么:同一组参数下,导出行 = 列表里已建团的行,顺序一致(未建团行本来就不导出)。
- 不传排序:按产品看 = 出发日升序;不按产品看 = 建团时间倒序(以前一律出发日升序)。
- 按产品导出时,班期范围、截止日、出发区间按产品侧实时日期筛选和排序,与列表一致;产品改期后不会再出现「列表里有、导出里没有」。
- 2000 行上限在全部筛选之后判断。
2. 团期看板统计条 GET /v3/admin/order/group-batch/summary
VO: GroupBatchSummaryVO(不变)
使用场景
看板顶部统计条(总数 + 七桶计数 + 被过滤条数),随列表的截止日、出发区间一起刷新。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| productId / month / keyword / scope | query | — | 否 | — | 原有 |
| deadlineFrom / deadlineTo | query | String | 否 | yyyy-MM-dd,非法值忽略 | 新增 |
| departFrom / departTo | query | String | 否 | yyyy-MM-dd,非法值忽略 | 新增 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| total | Integer | 命中团期数(与列表同条件、不筛团期状态和看板桶时的 total 相等) |
| buckets | Map | 七桶计数(之和 = total)+ 旧八桶别名键(#8271 过渡期兼容,不变) |
| subOrderCount / minToForm / maxRooms | Integer | 不变 |
| effectiveScope | String | 生效的班期范围,不变 |
| filteredOutCount | Integer | 因班期范围被过滤掉的条数,现在带上截止日与出发区间计算 |
请求示例
GET /v3/admin/order/group-batch/summary?productId=2056944943066132481&scope=ONGOING&departFrom=2026-05-01&departTo=2026-12-31
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": {
"total": 22,
"buckets": {
"RECRUIT": 4, "CONFIGURE": 7, "CONFIRM": 0, "TRIP": 0, "REVIEW": 7, "SETTLE": 1, "DISBANDED": 3,
"FORMED": 7, "PENDING_TRIP": 0, "TRAVELLING": 0, "TRIP_FINISHED": 0, "AUDITING": 7, "CHECKED": 1
},
"subOrderCount": 42,
"minToForm": null,
"maxRooms": null,
"effectiveScope": "ONGOING",
"filteredOutCount": 8
},
"success": true
}
空数据 / 降级响应
无命中时 total=0、各桶为 0:
{
"code": 200,
"message": "成功",
"data": { "total": 0, "buckets": { "RECRUIT": 0 }, "filteredOutCount": 0 },
"success": true
}
错误响应
判权未改(group-batch:list)。
{
"code": 589507,
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
"data": null,
"success": false
}
业务边界
- 不接收
batchStatus、opsStage、sortBy、sortOrder,传了也忽略(统计条要给出全部桶的计数)。 - 不传新参数时结果与改前一致。
3. 团期分页列表 GET /v3/admin/order/group-batch
VO: GroupBatchListReqVO → PageResult<GroupBatchPageItemRespVO>(均不变)
使用场景
看板列表。本次只改报名截止日非法值的处理。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| deadlineFrom / deadlineTo | query | String | 否 | yyyy-MM-dd | 非法值改为忽略该条件(以前 500) |
| 其余 | query | — | 否 | — | 不变 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| (全部) | — | 不变 |
请求示例
GET /v3/admin/order/group-batch?deadlineFrom=bad-date&pageNo=1&pageSize=20
Authorization: Bearer <admin token>
响应示例
{
"code": 200,
"message": "成功",
"data": { "records": [], "total": 298, "page": 1, "pageSize": 20 },
"success": true
}
空数据 / 降级响应
不变。
{
"code": 200,
"message": "成功",
"data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
"success": true
}
错误响应
判权未改。
{
"code": 589507,
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
"data": null,
"success": false
}
业务边界
- 非法截止日期等同不传该条件,服务端记 warn 日志。
四、契约约束与正确调用方式
- 前端把列表当前的筛选参数同一份传给统计条和导出:
- 导出:
productId / month / keyword / opsStage / scope / batchStatus / deadlineFrom / deadlineTo / departFrom / departTo / sortBy / sortOrder; - 统计条:
productId / month / keyword / scope / deadlineFrom / deadlineTo / departFrom / departTo。
- 导出:
- 统计条不要传团期状态和看板桶;传了会被忽略,但不要依赖这一点做业务判断。
五、数据库行为
- 零表结构变更、零迁移脚本;三个接口均只读(导出成功后照旧写导出留痕,逻辑未改)。
- 三个接口的筛选条件由同一段代码生成,不按产品时下推数据库,按产品时日期类条件按产品侧实时日期在内存筛选。
六、边界行为
- 导出单次上限 2000 行不变,判断在全部筛选之后。
- 按产品导出时,
month与keyword按订单侧快照匹配、CSV「日期 / 出团日」列打印订单侧快照:产品侧改过期或改过名的班期,这两处可能与列表显示不同。
六.6、修改前后对比
| 项 | 改前 | 改后 |
|---|---|---|
| 导出可用筛选 | productId / month / keyword / opsStage / scope | 另加 batchStatus / 截止日 / 出发区间 / 排序 |
| 导出默认顺序(不按产品) | 出发日升序 | 建团时间倒序(与列表一致) |
| 导出默认顺序(按产品) | 出发日升序(订单快照) | 出发日升序(产品侧实时) |
| 统计条可用筛选 | productId / month / keyword / scope | 另加截止日 / 出发区间 |
| 非法截止日期 | 列表、导出 500 | 三接口忽略该条件 |
六.7、影响评估
- 前端:统计条与导出要补传参数才生效;不补传时统计条结果不变,导出仅「不按产品」时默认顺序变化。
- 列表:只有非法截止日期的处理变化,合法请求不受影响。
七、不影响范围
- 导出 CSV 的列与格式、导出留痕、判权码。
- 看板列表
GET /v3/admin/order/group-batch/board、产品选择器、团期详情。
八、测试环境已验证
部署 dev-v3 @ 7c69e8227(主体)与 dada3a8f4(截止日宽容解析)后,经真实网关 https://api.test.1814.love 实测:
| 用例 | 期望 | 实测 |
|---|---|---|
| 构建身份:统计条 departFrom=2099-01-01 | total 由 33 变 0 | 通过 |
| 按产品:scope=ALL 不传排序 / 团期状态+截止日+出发区间 / 3 排序字段 × 升降序 | 导出行集与顺序 = 列表已建团行 | 8 组全部一致(列表 34 条含 5 条未建团,导出 29 行) |
| 全局:出发区间不传排序 / 团期状态+截止日 / 3 排序字段 × 升降序 | 同上 | 8 组全部一致(169 / 165 / 260 行) |
| 产品侧改期(快照 12-10、实时 12-15) | 按实时日期命中、按快照不命中,列表与导出一致 | 出发区间与截止日各两组,通过 |
| 统计条 截止日+出发区间(按产品 / 全局,ALL / ONGOING) | total = 列表 total = 七桶之和 | 通过(21 / 23 / 229 / 260) |
| 统计条 filteredOutCount 非零场景 | = ALL − ONGOING | 8 / 15,通过 |
| 统计条多传团期状态 / 看板桶 / 排序 | 结果不变 | 通过 |
非法截止日期 bad-date / 2026-02-30 |
三接口 200,等同不传 | 通过(改前列表与导出 500) |
| 非法出发日期 / 非法排序 | 忽略 | 通过 |
| 不带 token | 401 | 通过 |
TEST 全库团期 298 条,2000 行上限(589517)由单测覆盖。造数已清理(产品侧日期已改回、班期已取消)。
十、相关文档
- Issue #8413、PR #8417、PR #8432
- 列表出团区间与排序:Issue #7770
- 统计条被过滤条数:Issue #7939
关联 / 联系人
- 后端:jw
- 前端:mmg