docs(changelog): 补 #7023 团期物资阶段门(验收补做时发现缺 changelog)
changelog-filename-gate / validate (push) Successful in 2s

#7023 三端点新增阶段门(非 MATERIAL_PREPARING 返 589520)+ 合同保险前置门,
属接口行为变更但原工单未列 changelog。走验收标准时补上。

已合入 dev-v3;2026-09-07 TEST 网关实测非物资准备态 POST supplies 返 589520。
纯服务端拒绝,前端按错误码提示(frontend not_required)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
这个提交包含在:
jw
2026-09-07 16:43:53 +08:00
共同撰写人 Claude Opus 4.8
父节点 a246b25e22
当前提交 c276b2790c
@@ -0,0 +1,281 @@
---
schema: "hl-changelog/v2"
ticket: "7023"
title: "团期物资三端点补阶段门,合同保险作为进物资准备的前置门"
consumer: "admin"
author: "jw(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "已合入 dev-v3。2026-09-07 部署测试服并过网关实测:非 MATERIAL_PREPARING 阶段 POST supplies 返回 589520 阶段门拒绝。纯服务端拒绝逻辑,前端按错误码提示即可(not_required)。"
updated_at: "2026-09-07"
base: "dev-v3"
---
# 团期物资: 三端点补阶段门 + 确认留痕 + 合同保险前置门
> **服务**: hl-order-service-v3
> **影响范围**: 管理后台团期物资清单的增/删/改三端点 + 团期状态推进(合同保险闸门)
---
## ⚠️ 关键变化
物资清单的增删改**只能在「准备物资」(`MATERIAL_PREPARING`) 阶段**操作,其余阶段返回 `589520`。
此前无阶段限制。另:四资源就绪后,**合同/保险未出齐则团期停在资源筹备中**,不进物资准备阶段。
前端无需改造,按错误码提示即可(本单纯服务端)。
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 新增团期备品 | POST | `/v3/admin/order/group-batch/:groupBatchId/supplies` | 新增阶段门 | 非 MATERIAL_PREPARING 返 589520 |
| 2 | 调整备品数量 | PUT | `/v3/admin/order/group-batch/supplies/:batchSuppliesId/quantity` | 新增阶段门 | 同上;数量非法优先返 589522 |
| 3 | 删除备品行 | DELETE | `/v3/admin/order/group-batch/supplies/:batchSuppliesId` | 新增阶段门 | 同上 |
---
## 三、接口详情
### 1. 新增团期备品 `POST /v3/admin/order/group-batch/:groupBatchId/supplies`
**VO**: `AddSuppliesReqVO`
#### 使用场景
团期详情「物资」Tab 添加备品。只有团期处于「准备物资」阶段才允许。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | ✅ | - | 团期主订单 ID |
| suppliesResourceId | Body | Long | ❌ | 与 suppliesName 二选一 | 传则从备品库带出名称/分类/计费方式(见 #6986)|
| suppliesName | Body | String | ❌ | 与 suppliesResourceId 二选一 | 纯手填时用 |
| quantity | Body | Integer | ✅ | 正整数 | ≤0 返 589522 |
#### 出参 `Result<Void>`
| 字段 | 类型 | 说明 |
|------|------|------|
| data | null | 无数据体,成功仅 code=200 |
#### 请求示例
```json
{ "suppliesResourceId": 1001, "quantity": 5 }
```
#### 响应示例
```json
{ "code": 200, "message": "成功", "success": true }
```
#### 空数据 / 降级响应
无数据体接口,无空数据形态。
#### 错误响应
```json
{ "code": 589520, "message": "物资清单只能在「准备物资」阶段配置", "success": false, "data": null }
```
#### 业务边界
- **阶段门**:仅 `MATERIAL_PREPARING` 放行,其余阶段(招募中/资源筹备中/待出发/…)返 `589520`。
- **确认后仍可改**:`material_confirmed=true` 后不转只读,只要仍在 MATERIAL_PREPARING 就放行(jw 两次明确)。
- **创单固化不受门限**:`freezeFromProduct`(首单懒建固化备品)是系统行为,不走阶段门。
### 2. 调整备品数量 `PUT /v3/admin/order/group-batch/supplies/:batchSuppliesId/quantity`
**VO**: `AdjustSuppliesQuantityReqVO`
#### 使用场景
物资 Tab 改数量。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| batchSuppliesId | Path | Long | ✅ | - | 备品行 ID(反查所属团期判阶段)|
| quantity | Body | Integer | ✅ | 正整数 | ≤0 优先返 589522 |
#### 出参 `Result<Void>`
| 字段 | 类型 | 说明 |
|------|------|------|
| data | null | 无数据体 |
#### 请求示例
```json
{ "quantity": 8 }
```
#### 响应示例
```json
{ "code": 200, "message": "成功", "success": true }
```
#### 空数据 / 降级响应
无数据体接口。
#### 错误响应
```json
{ "code": 589522, "message": "备品数量必须为正整数", "success": false, "data": null }
```
#### 业务边界
- **错误码可区分**:数量非法先返 `589522`(参数校验),阶段不符返 `589520`(阶段门),两码不同。
- 阶段门口径同端点 1。
### 3. 删除备品行 `DELETE /v3/admin/order/group-batch/supplies/:batchSuppliesId`
**VO**: `无请求体`
#### 使用场景
物资 Tab 删除一行备品。仅 MATERIAL_PREPARING 阶段可删。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| batchSuppliesId | Path | Long | ✅ | - | 备品行 ID(反查所属团期判阶段)|
#### 出参 `Result<Void>`
| 字段 | 类型 | 说明 |
|------|------|------|
| data | null | 无数据体 |
#### 请求示例
```http
DELETE /v3/admin/order/group-batch/supplies/1932847562341 HTTP/1.1
Authorization: Bearer <admin-token>
```
#### 响应示例
```json
{ "code": 200, "message": "成功", "success": true }
```
#### 空数据 / 降级响应
无数据体接口。
#### 错误响应
```json
{ "code": 589520, "message": "物资清单只能在「准备物资」阶段配置", "success": false, "data": null }
```
#### 业务边界
- 阶段门口径同端点 1:仅 MATERIAL_PREPARING 放行,其余阶段返 589520。
- 删除是软删;确认后(material_confirmed=true)仍可删,不转只读。
---
## 四、契约约束与正确调用方式
| 场景 | 结果 |
|------|------|
| ✅ MATERIAL_PREPARING 阶段增删改 | 200 |
| ❌ 招募中 / 资源筹备中 / 待出发 等阶段 | 589520 |
| ❌ 数量 ≤ 0 | 589522(优先于阶段门)|
---
## 五、数据库行为
无表变更、无 Flyway。`markMaterialConfirmed` 后**无条件**记一条 `changeType=DATA` 的确认物资流水
(含操作人与时间),与状态推进的 STATUS 流水分开;双门未满足时也留痕。
---
## 六、边界行为
- 未登录 → 401(网关拦截)
- 团期不存在 → 589500
- 阶段不符 → 589520;数量非法 → 589522
- 创单固化备品 `freezeFromProduct` → 不受阶段门影响
## 六.5、枚举 / 数据字典
### 团期阶段(`GroupBatchStatus`)与物资门
**所属字段**: 服务端判定 | **类型**: `String`
| 阶段 | 物资增删改 |
|------|-----------|
| `RECRUITING` / `RESOURCE_PREPARING` / `PENDING_DEPARTURE` 等 | 拒(589520)|
| `MATERIAL_PREPARING` | 放行 |
## 六.6、修改前后对比
| 行为 | 改前 | 改后 |
|------|------|------|
| 非物资准备态增删改物资 | 允许 | 拒 589520 |
| 四就绪齐但合同保险未出齐 | 进 MATERIAL_PREPARING | 停在 RESOURCE_PREPARING |
| markMaterialConfirmed 留痕 | 依赖状态推进流水 | 无条件先记一条 DATA 流水 |
## 六.7、影响评估
- 破坏向后兼容:否(新增拒绝分支,正常阶段操作不变)
- 前端必须同步上线:否(按错误码提示)
- 存量团期:已在 MATERIAL_PREPARING 及之后的不被新门卡回(新门只对新进入的团期生效)
## 七、不影响范围
- 仅影响:团期物资增删改三端点的阶段限制 + 合同保险前置门
- 零影响:confirmMaterial 双门推进(保留)、创单固化、C 端、其余团期端点
---
## 八、测试环境已验证
✅ **已验证。** 2026-09-07 部署 dev-v3 到测试服并经网关实测(真实管理端鉴权)。
产品 2044306857534636034 第 7 期(`RESOURCE_PREPARING` 态,非物资准备):
| 用例 | 期望 | 实测 |
|------|------|------|
| 非 MATERIAL_PREPARING 打 POST supplies | 589520 阶段门拒绝 | ✅ `589520 物资清单只能在「准备物资」阶段配置` |
码层核实(子代理)AC-1~AC-13 全部成立:三端点阶段门、确认后仍可改、confirmMaterial 双门保留、
markMaterialConfirmed 无条件 DATA 流水、freezeFromProduct 不受门限、589520/589522 可区分、
合同保险前置门(isContractInsuranceReady)、存量团期不回退。
## 九、相关历史 PR
| PR | Issue | 说明 |
|----|-------|------|
| — | #7023 | 团期物资阶段门 + 确认留痕 + 合同保险前置门 |
## 十、相关文档
- 关联 Issue: [wx/HL#7023](https://git.1814.love:8443/wx/HL/issues/7023)
- 口径:AC-TD-13 / AC-TD-15 / AC-TD-16(jw 定案)
## 关联 / 联系人
- **Issue**: [#7023](https://git.1814.love:8443/wx/HL/issues/7023)
- **后端负责人**: @jw