20 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 | 7204 | 团期看板导/摄芯片聚合态:零指派灰、部分指派橙、全部指派绿 | admin | wx(GIT) | 修改接口 | deployed | verified | not_required | 2026-09-06 | 2026-09-06 | dev-v3 | 后端已合并(PR #7207,合并提交 7c705b80)并于 2026-09-06 19:54 部署测试服 dev-v3,网关复测通过(零指派改前 DOING → 改后 TODO);前端无需改代码,建议补芯片图例/tooltip。 |
团期模块:看板导/摄芯片聚合态口径调整(零指派返未开始)
⚠️ 关键变化
只改一条聚合规则,不改任何字段名、枚举值集或户级明细。 导游(guide)/ 摄影(photo)两枚芯片的整团聚合态 aggregateStatus(同一份值也就是 GB-ADM-001 records[].chips.guide / chips.photo):
| 计入户(needsIt=true)情况 | 改前 | 改后 |
|---|---|---|
| 一户都没指派(doneCount = 0,totalCount > 0) | DOING(橙「进行中」) |
TODO(灰「未开始」) |
| 部分已指派(0 < doneCount < totalCount) | DOING |
DOING(不变) |
| 全部已指派(doneCount = totalCount > 0) | DONE |
DONE(不变) |
| 没有计入户(totalCount = 0,全部免闸或无子订单) | TODO |
TODO(不变) |
根因:户级 guide_status / photographer_status 为 NULL(从未指派)时读侧归一为 PENDING「待指派」,而 PENDING 又在导/摄的「进行中」集合里,于是只要有户需要导游就恒 DOING。wx 2026-09-06 拍板改为与房/车「未提需求=灰、提了需求=橙、配完=绿」同一直觉。
前端影响:hl-ui src/views/order-v2/batch/_shared/batchLifecycle.js chipAggState 已把 TODO 映射为灰、DOING 橙、DONE 绿、ERROR 红,无需改代码;效果是「一户都没指派」的团期导/摄从橙变灰。建议:芯片区补图例或 tooltip(灰=未开始、橙=进行中、绿=已完成、红=异常)——运营把橙读成「配置完了」是本单起因。
房 / 车 / 约 / 保四芯片、GB-ADM-090~095 户级明细的 items[].status(NONE / PENDING / DONE)与 statusText(无需 / 待指派 / 已指派)均不变。
一、背景
现象
2026-09-06 测试服「团期订单」看板,产品「冻干粉发短信给」班期 2026-10-01 行,只有 1 个需要导游/摄影但从未指派的活跃子订单,「导 / 摄」芯片却是橙色(DOING),运营误读为「已配置完」。
调用链
- hl-ui
src/stores/orderV2Batch.js:93-97getGroupBatchPage()→GET /v3/admin/order/group-batch(GB-ADM-001)→records[].chips.guide / photo - hl-ui 点击芯片 →
getGroupBatchChip(groupBatchId, 'guide'|'photo')→GET /v3/admin/order/group-batch/{groupBatchId}/chips/guide|photo(GB-ADM-092/093)→aggregateStatus - hl-order-service-v3:两处共用
order/groupbatch/helper/GroupBatchChipResolver.resolveAggregateStatus;本次在「失败→ERROR」「全完成→DONE」之后、扫描进行中值之前,对 GUIDE / PHOTOGRAPHER 增加doneCount == 0返TODO的分支 - 硬规则不变:流团(CANCELLED)六芯片恒
TODO;已返团(REVIEWING / SETTLED)房车导摄恒DONE;约 / 保在房车导摄四项全DONE前恒TODO
地面真相(测试服 dev-v3,团期 groupBatchId=2096412454643802114)
| 时点 | 子订单 | chips/guide 响应要点 |
|---|---|---|
| 改前 17:20(部署前) | 1 户,needs_guide=1,guide_status=NULL | aggregateStatus="DOING",totalCount=1,doneCount=0,items[0].status=PENDING「待指派」 |
| 改后 19:58(部署 7c705b80 后,另造 1 户零指派测试单 2096568044598820866,测完已取消) | 同上 | aggregateStatus="TODO",totalCount=1,doneCount=0,items[0].status=PENDING「待指派」(户级不变) |
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 团期看板分页(GB-ADM-001) | GET | /v3/admin/order/group-batch |
响应值语义变化 | records[].chips.guide / chips.photo 零指派由 DOING 改为 TODO |
| 2 | 导游芯片逐户明细(GB-ADM-092) | GET | /v3/admin/order/group-batch/{groupBatchId}/chips/guide |
响应值语义变化 | aggregateStatus 零指派由 DOING 改为 TODO;items[] 不变 |
| 3 | 摄影芯片逐户明细(GB-ADM-093) | GET | /v3/admin/order/group-batch/{groupBatchId}/chips/photo |
响应值语义变化 | 同上 |
三、接口详情
1. 团期看板分页 GET /v3/admin/order/group-batch
VO: GroupBatchListReqVO → Result<PageResult<GroupBatchPageItemRespVO>>
使用场景
团期看板列表(hl-ui getGroupBatchPage());本次只有 records[].chips.guide / chips.photo 的取值语义变化,其余字段与参数不变。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| productId | query | Long(字符串) | 否 | 雪花 ID | 按产品筛选 |
| opsStage | query | String | 否 | RECRUIT / FORMED / PENDING_TRIP / TRAVELLING / AUDITING / CHECKED / DISBANDED | 七桶筛选 |
| month | query | String | 否 | yyyy-MM | 出发月份 |
| keyword | query | String | 否 | 已转义 | 班期编号 / 名称模糊 |
| batchStatus | query | String | 否 | 团期状态码 | 可选 |
| deadlineFrom / deadlineTo | query | String | 否 | yyyy-MM-dd | 报名截止日区间 |
| pageNo | query | Integer | 否 | 默认 1 | 页码 |
| pageSize | query | Integer | 否 | 默认 20,最大 100 | 每页条数 |
出参 Result<PageResult<GroupBatchPageItemRespVO>>
| 字段 | 类型 | 说明 |
|---|---|---|
| data.records[] | Array | 团期行(分页容器字段为 records / total / page / pageSize) |
| data.records[].groupBatchId | String(Long) | 团期主订单 ID |
| data.records[].productBatchId | String(Long) | product 侧班期 ID |
| data.records[].batchStatus / batchStatusName | String | 团期状态码 / 中文名 |
| data.records[].orderCount | Integer | 活跃子订单数 |
| data.records[].chips | Object | 六键固定:hotel / vehicle / guide / photo / contract / insurance,值为 TODO / DOING / DONE / ERROR 字符串;无活跃子订单时整个 chips 为 null |
| data.records[].chips.guide | String | 本次变化:零指派 TODO,部分指派 DOING,全部指派 DONE(导/摄没有失败值,不会出现 ERROR) |
| data.records[].chips.photo | String | 同 chips.guide |
| 其余字段 | — | 不变(enrolledRooms / remainRooms / receivableAmount / receivedAmount / departDate / endDate …) |
请求示例
GET /v3/admin/order/group-batch?productId=2044306857534636034&pageNo=1&pageSize=20 HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>
响应示例
改后(2026-09-06 19:58 实测,该行 1 户零指派、未提房车需求):
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"groupBatchId": "2096412454643802114",
"productBatchId": "2052935476557328386",
"productId": "2044306857534636034",
"batchName": " 没,那你",
"batchStatus": "RESOURCE_PREPARING",
"batchStatusName": "资源准备中",
"orderCount": 1,
"chips": {
"hotel": "TODO",
"vehicle": "TODO",
"guide": "TODO",
"photo": "TODO",
"contract": "TODO",
"insurance": "TODO"
}
}
],
"total": 1,
"page": 1,
"pageSize": 20
},
"success": true
}
改前同一场景 chips.guide / chips.photo 为 "DOING"。
空数据 / 降级响应
没有命中团期时 records 为空数组;团期无活跃子订单时该行 chips 为 null(前端六芯片全灰,不要当字符串解析)。
{
"code": 200,
"message": "成功",
"data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
"success": true
}
错误响应
{
"code": 589507,
"message": "无操作权限(非团期管理员 / 非本定制师名下)",
"data": null,
"success": false
}
HTTP 始终 200,按 code 判断。
业务边界
- 权限
group-batch:view chips.guide/chips.photo与 GB-ADM-092/093 的aggregateStatus同源同算法,两处必然一致- 硬规则优先:流团行六芯片恒
TODO;已返团行房车导摄恒DONE;约/保在房车导摄四项全DONE前恒TODO
2. 导游芯片逐户明细 GET /v3/admin/order/group-batch/{groupBatchId}/chips/guide
VO: Result<GroupBatchChipDetailRespVO>(无请求 VO,仅路径参数)
使用场景
看板行点击「导」芯片时拉逐户明细(hl-ui getGroupBatchChip(id, 'guide'));头部 aggregateStatus 即看板 chips.guide。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | path | Long(字符串) | 是 | 团期主订单 ID | 不是 product 侧 productBatchId |
出参 Result<GroupBatchChipDetailRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| data.batchId | String(Long) | 团期主订单 ID |
| data.chipLabel | String | 「配导游」 |
| data.aggregateStatus | String | 本次变化:TODO(零指派)/ DOING(部分指派)/ DONE(全部指派);导/摄不会出现 ERROR |
| data.totalCount | Integer | 计入户数(needsIt=true 的活跃子订单) |
| data.doneCount | Integer | 已指派户数 |
| data.items[] | Array | 逐户明细(不变) |
| data.items[].orderId / orderNo / contactName / peopleCount | String / String / String / Integer | 户标识与人数 |
| data.items[].status | String | NONE(免闸)/ PENDING(待指派)/ DONE(已指派) |
| data.items[].statusText | String | 无需 / 待指派 / 已指派 |
| data.items[].needsIt | Boolean | 是否需要导游 |
| data.items[].updateTime | String | 恒 null(无独立时间列) |
请求示例
GET /v3/admin/order/group-batch/2096412454643802114/chips/guide HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>
响应示例
改后(2026-09-06 19:58 实测):
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2096412454643802114",
"chipLabel": "配导游",
"aggregateStatus": "TODO",
"totalCount": 1,
"doneCount": 0,
"items": [
{
"orderId": "2096568044598820866",
"orderNo": "HL20260906195548607",
"contactName": "7204复测",
"peopleCount": 1,
"status": "PENDING",
"statusText": "待指派",
"needsIt": true,
"updateTime": null
}
]
},
"success": true
}
改前(17:20 实测,同一团期另一户零指派)除 aggregateStatus="DOING" 外结构相同。
空数据 / 降级响应
团期无活跃子订单或全部免闸:totalCount=0、doneCount=0、aggregateStatus="TODO";items[] 为全部活跃户(免闸户 status="NONE"),无活跃户时为空数组。
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2096412454643802114",
"chipLabel": "配导游",
"aggregateStatus": "TODO",
"totalCount": 0,
"doneCount": 0,
"items": []
},
"success": true
}
错误响应
{
"code": 589500,
"message": "团期不存在",
"data": null,
"success": false
}
另:589507 无操作权限。
业务边界
- 免闸户(needsIt=false)不计入
totalCount / doneCount,status="NONE" aggregateStatus只读派生,不落库;在团期详情「配置导游」后扇出到全部子订单即DONE
3. 摄影芯片逐户明细 GET /v3/admin/order/group-batch/{groupBatchId}/chips/photo
VO: Result<GroupBatchChipDetailRespVO>(无请求 VO,仅路径参数)
使用场景
看板行点击「摄」芯片时拉逐户明细(hl-ui getGroupBatchChip(id, 'photo'));头部 aggregateStatus 即看板 chips.photo。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | path | Long(字符串) | 是 | 团期主订单 ID | 同上 |
出参 Result<GroupBatchChipDetailRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| data.chipLabel | String | 「配摄影」 |
| data.aggregateStatus | String | 本次变化:规则同导游 |
| data.totalCount / doneCount | Integer | 同导游 |
| data.items[] | Array | 结构与导游接口完全相同,items[].needsIt 取需要摄影 |
请求示例
GET /v3/admin/order/group-batch/2096412454643802114/chips/photo HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>
响应示例
改后(19:58 实测):
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2096412454643802114",
"chipLabel": "配摄影",
"aggregateStatus": "TODO",
"totalCount": 1,
"doneCount": 0,
"items": [
{
"orderId": "2096568044598820866",
"orderNo": "HL20260906195548607",
"contactName": "7204复测",
"peopleCount": 1,
"status": "PENDING",
"statusText": "待指派",
"needsIt": true,
"updateTime": null
}
]
},
"success": true
}
空数据 / 降级响应
同导游接口:无计入户时 totalCount=0、aggregateStatus="TODO"。
{
"code": 200,
"message": "成功",
"data": { "batchId": "2096412454643802114", "chipLabel": "配摄影", "aggregateStatus": "TODO", "totalCount": 0, "doneCount": 0, "items": [] },
"success": true
}
错误响应
{
"code": 589500,
"message": "团期不存在",
"data": null,
"success": false
}
业务边界
- 同导游接口
四、契约约束与正确调用方式
三个接口均为只读 GET,无请求体;本节写的是前端消费聚合态的规则。
✅ 正确 / ❌ 错误 payload 对照
| 场景 | payload / 处理 |
|---|---|
| ✅ 按四值渲染 | chips.guide ∈ TODO / DOING / DONE / ERROR → 灰 / 橙 / 绿 / 红;未知值按灰 |
✅ chips 为 null |
六芯片全灰,不请求 090~095 明细 |
| ✅ 弹层头部与看板一致 | chips/guide.aggregateStatus 与 records[].chips.guide 同源,勿各算各的 |
❌ 用户级 items[].status 反推整团态 |
户级 PENDING「待指派」不等于整团进行中:零指派时整团是 TODO |
❌ 把 DOING 当「已配置」 |
DOING 只表示部分户已指派 |
切换状态时的必要动作
无写接口;指派动作走团期详情「配置导游 / 摄影」,完成后重新拉 GB-ADM-001 或 090~095 即可看到 DONE。
五、数据库行为
本次无写操作、无表变更。aggregateStatus / chips.* 为读时派生(GroupBatchChipResolver 内存计算),不落库;户级来源仍是 order_main.guide_status / photographer_status(取值只有 DONE 或 NULL)。
| 计入户情况 | 派生结果 |
|---|---|
| doneCount = 0,totalCount > 0 | TODO |
| 0 < doneCount < totalCount | DOING |
| doneCount = totalCount > 0 | DONE |
| totalCount = 0 | TODO |
六、边界行为
- 未登录 → 网关 401;无
group-batch:view→589507 - 团期不存在 →
589500 - 流团团期 → 六芯片恒
TODO(硬规则 1);已返团团期 → 房车导摄恒DONE(硬规则 2) - 约 / 保在房车导摄四项未全
DONE前恒TODO(硬规则 3,本次导/摄零指派落TODO后约/保同样保持TODO) - HTTP 始终 200,按
code判断
六.5、枚举 / 数据字典
aggregateStatus / chips.*(com.hulalv.order.groupbatch.helper.GroupBatchChipResolver 常量 AGGREGATE_TODO / AGGREGATE_DOING / AGGREGATE_DONE / AGGREGATE_ERROR)
| 值 | 含义 | 前端色 |
|---|---|---|
TODO |
未开始(导/摄:零指派;房/车:未提需求) | 灰 |
DOING |
进行中(导/摄:部分指派;房/车:需求已提交/处理中/待审核) | 橙 |
DONE |
已完成 | 绿 |
ERROR |
异常(房/车驳回、约作废、保失败;导/摄不会出现) | 红 |
items[].status(导/摄户级,GroupBatchChipResolver.readGuideStatus)
| 值 | 含义 | statusText |
|---|---|---|
NONE |
该户无需导游/摄影(免闸,不计入) | 无需 |
PENDING |
需要且未指派 | 待指派 |
DONE |
已指派 | 已指派 |
六.6、修改前后对比
字段级对比
| 字段 | 修改前 | 修改后 |
|---|---|---|
records[].chips.guide / chips.photo、aggregateStatus 取值集 |
TODO / DOING / DONE |
不变 |
| 零指派场景取值 | DOING |
TODO |
行为级对比
| 场景 | 修改前 | 修改后 |
|---|---|---|
| 零指派(doneCount=0,totalCount=1) | DOING(橙) |
TODO(灰) |
| 部分指派(doneCount=1,totalCount=2) | DOING(橙) |
DOING(橙) |
| 全部指派(doneCount=2,totalCount=2) | DONE(绿) |
DONE(绿) |
| 全部免闸(totalCount=0) | TODO |
TODO |
| 已返团(REVIEWING / SETTLED) | DONE(硬规则) |
DONE |
| 流团(CANCELLED) | TODO(硬规则) |
TODO |
六.7、影响评估
- 向后兼容:字段名、枚举值集不变,只是零指派场景的取值变化;老前端不改也能正确渲染
- 前端是否必须同步上线:否
- 数据:无表变更、无迁移;聚合态实时派生不落库
七、不影响范围
- 仅影响: 管理后台团期看板行「导 / 摄」芯片颜色,以及 090~095 弹层头部聚合态
- 零影响:
- 房 / 车 / 约 / 保四芯片
- 户级明细
items[](值与文案不变) - 团期详情
hotelReady / guideReady / photographerReady标志 - 指派流程、团期状态机、订单接口
- 小程序
八、测试环境已验证
真实接口输出(测试服 api.test.1814.love,2026-09-06,登录后切 ADMIN 角色):
GET /v3/admin/order/group-batch/2096412454643802114/chips/guide → 200, aggregateStatus=TODO, total=1, done=0, items[0]=PENDING/待指派 ✓(改前 17:20 同场景 DOING)
GET /v3/admin/order/group-batch/2096412454643802114/chips/photo → 200, aggregateStatus=TODO, total=1, done=0 ✓
GET /v3/admin/order/group-batch?productId=2044306857534636034 → 200, 该行 chips.guide=TODO, chips.photo=TODO, hotel=TODO, vehicle=TODO ✓
验证团期: groupBatchId=2096412454643802114(产品 2044306857534636034「冻干粉发短信给」,班期 2026-10-01);造的零指派测试单 2096568044598820866 已取消。
单测:GroupBatchChipResolverTest 30/0/0(新增零指派 / 部分指派 / 全部指派 / 免闸 / 房车不受影响五例)、GroupBatchChipServiceTest 14/0、GroupBatchQueryServiceTest 23/0、ArchTest 门禁 41/0。部署:Deploy Panel 19:54 双实例滚动完成,分支 dev-v3。
十、相关文档
- 关联 Issue: wx/HL#7204
- 关联 PR: wx/HL#7207
- 同现场: #7188(「第N期」序号)、#7189(看板以产品全班期为基底 + 班期范围筛选)、#7190(「出行完毕」状态与八桶)
- 前端缺陷 changelog:
06_frontend_团期看板展开行子订单列表恒空-前端缺陷-管理后台.md
关联 / 联系人
链接
联系人
- 后端负责人: @wx