changelog-filename-gate / validate (push) Successful in 2s
前端据 H1 看板过滤 CANCELLED 的行为,推断「整团释放」按钮无可达路径。 该推断的关键环节不成立:我的团(GET /v3/admin/order/grab-pool/my-claims/ group-batches)刻意不按 batch_status 过滤,H2 详情也没有阶段闸门, CANCELLED 团期经「我的团 → H2 详情」完全可达。 根因在我方:#7322 的 changelog 从未写过这条行为,前端看不到 javadoc。 本次一并补记,并在需求单上答复 status=answered-no-backend-change。 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
154 行
10 KiB
Markdown
154 行
10 KiB
Markdown
---
|
||
schema: "hl-backend-request/v1"
|
||
title: "放开 H1 看板列表 batchStatus 对 CANCELLED 的过滤(让整团释放入口可达)"
|
||
consumer: "backend"
|
||
requester: "mmg(前端)"
|
||
author: "mmg"
|
||
target_service: "hl-order-service-v3"
|
||
status: "answered-no-backend-change"
|
||
related_issue: "7324"
|
||
related_frontend_commit: "6710ad4a"
|
||
created_at: "2026-09-11"
|
||
answered_at: "2026-09-11"
|
||
answered_by: "Claude(后端管理者)"
|
||
backend_verdict: "可达路径已存在,后端零改动;我方 #7322 changelog 漏写「我的团」不过滤 batch_status,前端的判断在当时信息下是合理的"
|
||
---
|
||
|
||
# 需求:放开 H1 看板列表 `batchStatus` 对 `CANCELLED` 的过滤
|
||
|
||
> **来源工单**: #7324 房务团期看板与整团按日订房计划 CRUD
|
||
> **服务**: `hl-order-service-v3`
|
||
> **提出方**: 前端(mmg),2026-09-11
|
||
> **状态**: 待后端评估 / 排期
|
||
|
||
---
|
||
|
||
## 一、一句话需求
|
||
|
||
房务团期看板列表 `GET /v3/admin/house/group-batches`(H1)当前把 `batchStatus=CANCELLED` 从过滤里**忽略**(传了被静默丢弃,回退默认四态),导致已流团团期永远进不了看板列表;而「整团释放」写口仅对 CANCELLED 团期放行,前端「整团释放」按钮因此**没有任何用户可达路径**。请放开 H1 对 CANCELLED 的过滤,让已认领的已流团团期能进入看板列表。
|
||
|
||
---
|
||
|
||
## 二、现状行为(契约原文,#7324 changelog)
|
||
|
||
`#7324` changelog 两处明确了当前过滤行为:
|
||
|
||
1. H1 `batchStatus` 入参表:「传 `CANCELLED` **被忽略**」——默认四态 = `RESOURCE_PREPARING, MATERIAL_PREPARING, PENDING_DEPARTURE, TRAVELLING`(`HouseGroupBatchBoardManager.java:60-64`)。
|
||
2. 边界行为:「`batchStatus` 若传入非法状态码或全部被过滤掉(如只传 `CANCELLED`),**静默回退为默认四态**,不报错」(`HouseGroupBatchBoardManager.java:224-236`)。
|
||
|
||
链路后果:
|
||
|
||
- 看板列表 H1 **结构性不返回** CANCELLED 团期。
|
||
- 详情弹层(H2)只能从 H1 行点开,所以永远拿不到一个 `batchStatus==='CANCELLED'` 的 detail。
|
||
- 前端「整团释放」按钮的显隐条件是 `detail.batchStatus === 'CANCELLED'`(`canReleaseAll`),恒为 false,按钮永不渲染。
|
||
- release-all 端点 `POST .../room-plans/release-all` 本身仅对 CANCELLED 放行(其它态 808618,`HouseGroupBatchPlanGate.PLAN_RELEASE_ONLY_STATUSES` 只含 CANCELLED),端点行为自洽、无 bug——**只是前端够不到一个 CANCELLED 团期去调它**。
|
||
|
||
---
|
||
|
||
## 三、期望行为
|
||
|
||
让 H1 在「按认领维度」下能返回已流团(CANCELLED)团期,二选一均可:
|
||
|
||
- **方案 A(推荐)**:`batchStatus` 入参放开 `CANCELLED`——前端显式传 `batchStatus=CANCELLED` 时后端按此过滤,不再忽略/回退。改动最小,不影响不传参时的默认四态。
|
||
- **方案 B**:新增一个独立查询参数(如 `includeCancelled=true` 或 `scope` 扩展),在认领维度下附带返回 CANCELLED 团期。
|
||
|
||
无论哪个方案,都请保持「未认领团不进本页」的既有边界(H1 业务边界第 1 条),CANCELLED 放开只作用于「已被房务认领」的团。
|
||
|
||
---
|
||
|
||
## 四、为什么安全 / 不破坏既有
|
||
|
||
- **阶段闸门已天然兜住写口**:`HouseGroupBatchPlanGate.PLAN_WRITABLE_STATUSES`(可写六态)不含 CANCELLED,H4/H5 对 CANCELLED 团期本就走 808600;H6/release-all 走更宽的 `releaseOnly` 分支(CANCELLED 放行)。放开 H1 过滤**不改变任何写口的阶段闸门判定**——只是让 CANCELLED 团期「能被看见」,写口权限仍由各端点自己的闸门控制。
|
||
- **release-all 端点无需改**:它已正确地对 CANCELLED 放行、对其它态 808618,本次只动 H1 读侧。
|
||
- **向后兼容**:不传 `batchStatus` 的既有调用方仍走默认四态,行为零变化;只有显式传 `CANCELLED` 的调用方才看到新返回。
|
||
|
||
---
|
||
|
||
## 五、前端配套(已就绪,零改动等待)
|
||
|
||
前端「整团释放」按钮与 release-all 调用**已实现并保留**(`#7324` 前端 commit `6710ad4a`),显隐条件 `canReleaseAll` 已按「`batchStatus==='CANCELLED'` 且非组长只读」写好。后端一旦放开 H1 的 CANCELLED 过滤,CANCELLED 团期进入看板 → 详情弹层 `detail.batchStatus` 即为 CANCELLED → 按钮自动出现并可点,**前端无需任何改动**。
|
||
|
||
后端部署后通知前端即可,前端会回归验证「整团释放」入口可达。
|
||
|
||
---
|
||
|
||
## 关联
|
||
|
||
- Issue: [#7324](https://git.1814.love:8443/wx/HL/issues/7324)
|
||
- 后端 PR: [#7465](https://git.1814.love:8443/wx/HL/pulls/7465)
|
||
- 前端交付 commit: `6710ad4a`(hl-admin `v2.1`)
|
||
- 相关源码: `HouseGroupBatchBoardManager.java`(H1 编排,`:60-64` 默认四态、`:224-236` batchStatus 过滤)、`HouseGroupBatchPlanGate.java`(阶段闸门,无需改)
|
||
|
||
|
||
---
|
||
|
||
## 🔧 后端答复(2026-09-11)
|
||
|
||
> **结论:本单不需要后端改动——可达路径已经存在。而你们不知道它存在,是因为我们的 #7322 changelog 漏写了一条关键行为。这个缺口在我方。**
|
||
|
||
### 一、结论先行
|
||
|
||
「整团释放按钮没有任何用户可达路径」这一判断**不成立**。已经存在的路径是:
|
||
|
||
```
|
||
GET /v3/admin/order/grab-pool/my-claims/group-batches ← 我的团(#7322 已交付且已验收)
|
||
↓ 该列表不过滤 batch_status,已流团(CANCELLED)团期就在里面
|
||
↓ 行上直接带 groupBatchId / batchStatus / batchStatusLabel
|
||
GET /v3/admin/house/group-batches/{groupBatchId} ← H2 详情(无阶段闸门)
|
||
↓ detail.batchStatus === 'CANCELLED' → canReleaseAll 成立
|
||
POST /v3/admin/house/group-batches/{groupBatchId}/room-plans/release-all
|
||
```
|
||
|
||
### 二、逐环节证据(五条,全部对源码复核过,不是从文档转述)
|
||
|
||
| # | 环节 | 证据 |
|
||
|---|---|---|
|
||
| 1 | **我的团不过滤 `batch_status`** | `HouseGroupGrabService.listMyGroups` javadoc 原话:「**不限制 batch_status**:已认领的团可能已流团 / 已结束,本单不自动释放指针,**房务仍要看得见并手动释放**」。代码 `q.setBatchStatus(req.getBatchStatus())` 原样下推,**不传就是不加这个条件**,没有 H1 那种「过滤空了回退默认四态」的逻辑 |
|
||
| 2 | **服务层也不注入状态** | `GroupBatchService.pageHouseClaimed` 直接把 query 下推 mapper,零注入 |
|
||
| 3 | **同一文件里的对照(最强证据)** | 紧挨着的 `GroupBatchService.pageHouseGrabPool` 却**强制**写死 `q.setBatchStatuses(REQUIREMENT_CONFIRMABLE_STATUSES)`。一个注入、一个不注入,**是刻意区分不是遗漏** |
|
||
| 4 | **我的团的行携带判定所需字段** | `HouseMyGroupItemRespVO extends HouseGroupGrabPoolItemRespVO`,父类有 `groupBatchId`、`batchStatus`、`batchStatusLabel` |
|
||
| 5 | **H2 详情没有阶段闸门** | `HouseGroupBatchBoardController.detail` 的门**只有归属**(未认领 808612 / 他人认领 808613),**不判 `batchStatus`**——CANCELLED 团只要是本人认领的就能打开 |
|
||
|
||
你对 release-all 端点本身的判断是对的:它只对 CANCELLED 放行、其它态 808618,端点自洽无 bug。
|
||
|
||
### 三、H1 过滤掉 CANCELLED 是刻意设计,且原注释就指明了入口在详情页
|
||
|
||
`HouseGroupBatchBoardManager.resolveBatchStatuses` 上方注释原话:
|
||
|
||
> 「为什么已流团的团不许出现在看板:本页是『要干活的团』,流团团的唯一动作是整团释放,**那个入口在详情页而不是列表页**;混在一起会让房务每天都在列表里看到一堆做不了任何事的团。」
|
||
|
||
注释写明了「详情页」,**但没写明从哪个列表进详情页**——这就是这次误判的接缝所在。
|
||
|
||
### 四、这次的根因在我方,不在你们
|
||
|
||
你们的推理链条本身是严密的:读 #7324 changelog → H1 明确写了「传 CANCELLED 被忽略」→ 详情从 H1 点开 → 因此 CANCELLED 详情不可达。**在你们掌握的信息里,这个结论是对的。**
|
||
|
||
问题出在 **#7322 的 changelog 从头到尾没有提过「我的团」不过滤 `batch_status`**(我逐行搜过那篇,零命中)。这条行为是后端刻意设计并写进 javadoc 的,却**没有进入交接件**——而 javadoc 你们看不到。
|
||
|
||
**所以这是我方的文档缺口,不是你们的疏忽。** #7322 的 changelog 我会补这一条。
|
||
|
||
### 五、前端需要做什么(如果需要)
|
||
|
||
把「我的团」列表行接到 H2 详情弹层——同一个弹层,入参就是行上已有的 `groupBatchId`。两端 API 都已交付并验收过(#7322 changelog `frontend_status: verified`),这是**接线**不是新功能。
|
||
|
||
如果「我的团」页当前打开的不是 H2 那个弹层,这一步是前端改动;**后端仍然零改动**。
|
||
|
||
补一条使用上的细节:我的团的 `batchStatus` 入参是**透传**的,所以
|
||
|
||
- 不传 → 全部已认领团(含 CANCELLED);
|
||
- 传 `CANCELLED` → **只看已流团的团**,做一个「待释放」筛选很自然。
|
||
|
||
这和 H1 的行为正好相反(H1 传 `CANCELLED` 会被丢弃并回退默认四态),**两个列表的 `batchStatus` 语义不同,别套用同一套前端逻辑**。
|
||
|
||
### 六、留给 wx 的产品判断(这一条不是 bug,是口径)
|
||
|
||
方案 A(H1 放开 CANCELLED)实现成本确实很低,你对「不破坏既有」的分析也站得住:写口闸门 `PLAN_WRITABLE_STATUSES` 不含 CANCELLED,放开读侧不影响任何写口判定——这点我复核过,属实。
|
||
|
||
**但我不建议改**,理由是它与「看板 = 要干活的团」这条既有定案直接冲突,而该定案是有成文理由的(见第三节注释)。已流团团期在看板里是纯噪声:房务对它只能做一个动作,而那个动作有专门的入口。
|
||
|
||
如果 wx 判断「房务更习惯在看板里找」,那我照做——**但那时它是一次产品口径调整,不是修 bug**,会另开工单并同步改注释里的定案说明。这个判断我交给 wx,不自行拍板。
|
||
|
||
---
|
||
|
||
**后端本单零改动。#7322 的 changelog 会补「我的团不过滤 batch_status」一条。**
|