docs(#7982): 创建共用关系同批准入多个新成员不再误报 605001
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
工单 #7982 修复 PR #7983 与测试补强 #8096 已部署,现补发前端交接件 changelog。 修复了创建共用关系时同批请求传入多个待准入成员会从第二个开始误报冲突码 605001 的缺陷(投影缺列),修复后允许一次请求完成多成员的关系创建。 接口契约无变化;修复在测试服 fleet 已验证;frontend_status=not_required(前端无需改代码)。 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,298 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7982"
|
||||
title: "fleet: 创建共用关系时同批准入多个新成员不再误报冲突码 605001(行为修复,无接口字段变化)"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "修复"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "not_required"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "backend_status=deployed:修复 PR #7983(`e7cecb6d7`)+ 测试补强 PR #8096(`970f9a187`)已合入 dev-v3;fleet 测试服部署点 `bd19b79c8`(2026-09-22 02:50),`git merge-base --is-ancestor e7cecb6d7 bd19b79c8` 与 `970f9a187 bd19b79c8` **均为真**。gateway_status=verified:2026-09-22 02:50 测试服真实调用实测,POST /admin/fleet/group-dispatch/batches/{groupBatchId}/share-groups 传入 3 个成员(1 个 GROUP_DISPATCH/OCCUPYING + 2 个 ASSIGNMENT/PENDING_ADMISSION)、2 个待准入分属海拉尔东山机场与满洲里西郊机场 → HTTP 200、`success=true`、`status=ACTIVE`、响应 members 数组长度 3;服务端 DB 三成员行齐全、状态一致。frontend_status=not_required:接口形状(路径、入参、响应字段、错误码)**完全未变**,本次仅修复冲突判定的内部投影缺列。"
|
||||
updated_at: "2026-09-22"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# fleet: 创建共用关系时同批准入多个新成员不再误报冲突码 605001(行为修复,无接口字段变化)
|
||||
|
||||
> **存放目录**: 二期(fleet 车务)→ `changelogs-v2/2026-09/`
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
**接口契约零变化**——路径、方法、请求参数、响应字段、错误码全部不动。
|
||||
|
||||
**变的是冲突判定的投影**。从本次修复上线起:
|
||||
|
||||
1. 创建共用关系时,**同一个 POST 请求里传入 2 个或更多「待准入」成员**(`members` 里 `admissionIntent=PENDING_ADMISSION` 的 `ASSIGNMENT` 类型项),且这些成员分属**不同城市**的行程(即不同出行中户,资源占用冲突判定的基准单位)时,**从第二个成员开始不再误报错误码 605001**;
|
||||
2. 修复后同一请求返回 HTTP 200,关系状态 `ACTIVE`,全部成员入库。
|
||||
|
||||
🔴 **这个误报此前在同批多成员场景下是 100% 必现的**(不是"偶尔会触发",是判定逻辑数据缺列导致每次都做错对端认证)。
|
||||
|
||||
## 一、背景
|
||||
|
||||
### 缺陷形态
|
||||
|
||||
创建共用关系时的冲突判定有两层:
|
||||
1. **第一层**:按既有共用关系逐一检查新增成员是否与它们的成员产生冲突;
|
||||
2. **第二层**(回退):若找不到既有关系可对标,则按**新增成员间的相互关系**判定冲突。
|
||||
|
||||
第一层是正常路径,拿得到全量数据。第二层回退判定在**同批请求内做多成员间相互认对**时,其数据投影缺了**申请人字段**(`applicant_id`),导致对端"这个人有没有被授权共用"这一核心前提始终查不出来。
|
||||
|
||||
⇒ **在同批多成员且无既有关系的场景下,从第二个成员开始每一个都会命中「无法确认对端身份」这条分支,必定返回 605001。**
|
||||
|
||||
### 这个判断怎么坐实的
|
||||
|
||||
修复前后在同一测试环境同一个请求体上对跑:
|
||||
|
||||
| 读数 | 修复前 | 修复后 |
|
||||
|---|---|---|
|
||||
| 同批传 3 成员(GROUP_DISPATCH + 2×ASSIGNMENT PENDING_ADMISSION)的 HTTP 状态码 | **605001**(业务码) | **200** |
|
||||
| 响应 `success` 字段 | **false** | **true** |
|
||||
| DB 共用关系 `status` | 未入库 | **ACTIVE** |
|
||||
| DB 成员行数 | 0 | **3** |
|
||||
|
||||
不是推测,是**修复前的请求在修复后一字不改直接过了**。
|
||||
|
||||
### 修复
|
||||
|
||||
PR #7983(`e7cecb6d7`):把缺失的 `applicant_id` 字段加入第二层回退判定的数据投影,使其真正能判断"对端是否被授权"。
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
本条**不新增、不修改、不删除**任何 HTTP 接口,也不改动任何请求/响应字段与错误码。
|
||||
|
||||
下列既有端点的**冲突判定行为**得到修复(契约形状不变):
|
||||
|
||||
| METHOD | Path | 变化 |
|
||||
|---|---|---|
|
||||
| POST | `/admin/fleet/group-dispatch/batches/{groupBatchId}/share-groups` | 同批创建多个待准入成员时,冲突判定不再误报 605001;允许创建多成员共用关系一次请求完成 |
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 创建团期共用关系 `POST /admin/fleet/group-dispatch/batches/{groupBatchId}/share-groups`
|
||||
|
||||
**VO**: `CreateShareGroupReqVO → ShareGroupCreateRespVO`(**字段无增删改**)
|
||||
|
||||
#### 使用场景
|
||||
|
||||
管理后台「团期配车」页,车务操作「绑定共用」。一次请求可以准入多个派车行成员进入同一个共用关系,这次修复消除了多成员时的冲突误判。
|
||||
|
||||
#### 入参(**本次无变化**)
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| dimension | String | ✅ | 共用维度:`VEHICLE`(共用车辆)或 `DRIVER`(共用司机) |
|
||||
| resourceId | Long | ✅ | 资源 ID(车辆 id 或司机 id) |
|
||||
| members | List<Member> | ✅ | 成员列表(GROUP_DISPATCH 与 ASSIGNMENT 的混合) |
|
||||
| members[i].sourceType | String | ✅ | 成员来源类型:`GROUP_DISPATCH` 或 `ASSIGNMENT` |
|
||||
| members[i].sourceId | Long | ✅ | 成员来源 ID |
|
||||
| members[i].admissionIntent | String | ✅ | 准入意向:`OCCUPYING`(已占用)或 `PENDING_ADMISSION`(待准入) |
|
||||
|
||||
#### 出参(**本次无变化**,字段来源:`ShareGroupCreateRespVO` 的 `@ApiModelProperty` 声明)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| shareGroupId | String | 共用关系 ID(雪花 ID,`@JsonSerialize(ToStringSerializer)` 按字符串序列化) |
|
||||
| status | String | 关系状态:`ACTIVE`(已激活)或 `PENDING`(待激活) |
|
||||
| dimension | String | 共用维度:`VEHICLE` 或 `DRIVER` |
|
||||
| resourceId | String | 资源 ID(字符串序列化) |
|
||||
| members | List<Member> | 入库后的成员列表(含服务端分配的 id、timestamps) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
POST /admin/fleet/group-dispatch/batches/{groupBatchId}/share-groups HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {token}
|
||||
|
||||
{
|
||||
"dimension": "VEHICLE",
|
||||
"resourceId": "2065329519232720897",
|
||||
"members": [
|
||||
{
|
||||
"sourceType": "GROUP_DISPATCH",
|
||||
"sourceId": "2101524548279238658",
|
||||
"admissionIntent": "OCCUPYING"
|
||||
},
|
||||
{
|
||||
"sourceType": "ASSIGNMENT",
|
||||
"sourceId": "360022177073991680",
|
||||
"admissionIntent": "PENDING_ADMISSION"
|
||||
},
|
||||
{
|
||||
"sourceType": "ASSIGNMENT",
|
||||
"sourceId": "360022539151478784",
|
||||
"admissionIntent": "PENDING_ADMISSION"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
以下为 2026-09-22 02:50 测试服实测的真实取值(自建团、2 个待准入 ASSIGNMENT 分属海拉尔东山机场与满洲里西郊机场,修复提交 e7cecb6d7 与 970f9a187 均在部署里):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"shareGroupId": "{shareGroupId}",
|
||||
"status": "ACTIVE",
|
||||
"dimension": "VEHICLE",
|
||||
"resourceId": "2065329519232720897",
|
||||
"members": [
|
||||
{
|
||||
"id": "360030157818200064",
|
||||
"sourceType": "GROUP_DISPATCH",
|
||||
"sourceId": "2101524548279238658",
|
||||
"admissionIntent": "OCCUPYING",
|
||||
"createdAt": "2026-09-22T02:50:15Z",
|
||||
"admissionAt": null
|
||||
},
|
||||
{
|
||||
"id": "360030157818200065",
|
||||
"sourceType": "ASSIGNMENT",
|
||||
"sourceId": "360022177073991680",
|
||||
"admissionIntent": "PENDING_ADMISSION",
|
||||
"createdAt": "2026-09-22T02:50:15Z",
|
||||
"admissionAt": null
|
||||
},
|
||||
{
|
||||
"id": "360030157818200066",
|
||||
"sourceType": "ASSIGNMENT",
|
||||
"sourceId": "360022539151478784",
|
||||
"admissionIntent": "PENDING_ADMISSION",
|
||||
"createdAt": "2026-09-22T02:50:15Z",
|
||||
"admissionAt": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
库内复核:三条成员行入库,状态一致,未被截断。
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
- 若请求的成员列表仅包含一个成员,创建成功但关系进入 `PENDING` 状态(等待第二个成员加入),响应会指示 `status: "PENDING"`。
|
||||
- 本接口是单次同步写操作,不查 Feign、不查 MQ,没有降级响应形态。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
以下为修复前的真实响应(同批传入 2+ 待准入成员、第二个开始命中旧缺陷):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 605001,
|
||||
"message": "成员冲突:无法确认对端是否被授权共用该资源",
|
||||
"data": null,
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
修复后同一请求返回 HTTP 200。
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 鉴权:需管理后台已登录且具备 `fleet:group-dispatch:write` 权限点,未登录/无权限按网关与全局鉴权统一规则处理。
|
||||
- 成员类型混合:同一请求可混合 GROUP_DISPATCH(已占用)与 ASSIGNMENT(待准入),服务端会自动编排合法的启动态。
|
||||
- 资源冲突判定:两个层级各自独立运作;修复仅影响第二层(新增成员间的相互认对)的数据完整性。
|
||||
- 冲突误报点(**本次修复消除**):同批 2+ 待准入成员、无既有关系可对标时,原第二层投影缺 `applicant_id`,导致每个新增成员都无法判证对端身份,第二个开始必报 605001。
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
本接口在**表层契约**上无任何变化。修复前后的入参格式、响应字段、HTTP 状态码、业务错误码全部一致——差别仅在内部判定逻辑的数据完整性。
|
||||
|
||||
### ✅ 正确 / ❌ 错误 payload 对照
|
||||
|
||||
| 场景 | payload | 修复前 | 修复后 |
|
||||
|------|---------|--------|--------|
|
||||
| ✅ 同批准入 2 个跨城成员 | 如上"请求示例" | **605001**(误报) | **200**(正确) |
|
||||
| ✅ 单个待准入成员 | 仅 1 个 PENDING_ADMISSION | 200,`status=PENDING` | 200,`status=PENDING`(不变) |
|
||||
| ✅ 无待准入成员(全 OCCUPYING) | 仅 GROUP_DISPATCH + 资源占用者 | 200,`status=ACTIVE` | 200,`status=ACTIVE`(不变) |
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
**入库行为**:修复后,同批多待准入成员会全部入库成共用关系的成员行(`fleet_group_dispatch_share_member` 表),关系状态进入 `ACTIVE`(若仅 1 个待准入则为 `PENDING`)。
|
||||
|
||||
修复前,第二个待准入成员开始会触发回滚,整个请求的写入都不落地。
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
- 未登录 → 401(网关拦截)
|
||||
- 无 `fleet:group-dispatch:write` 权限 → 403
|
||||
- `groupBatchId` 不存在 → 业务码 603xxx(依具体情况)
|
||||
- `dimension` 不是 `VEHICLE` 或 `DRIVER` → 400(参数校验)
|
||||
- `resourceId` 指向不存在的车/司机 → 业务码 604xxx(依具体情况)
|
||||
- 成员列表为空 → 400
|
||||
- 修复点:同批 2+ 待准入成员时**不再误报 605001**;允许多成员创建一次完成(此前的 workaround 是"拆成多次请求、一个成员发一次")
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
### 冲突判定行为对比
|
||||
|
||||
| 场景 | 修复前 | 修复后 |
|
||||
|------|--------|--------|
|
||||
| 同批 1 个待准入成员 | 200(`PENDING`) | 200(`PENDING`)—— 不变 |
|
||||
| 同批 2+ 待准入成员 | **605001**(从第 2 个开始必报) | **200(`ACTIVE`)—— 已修** |
|
||||
| 入参字段、响应字段 | — | 完全不变 |
|
||||
| 错误码列表 | — | 完全不变 |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- **是否破坏向后兼容**: 否——请求/响应字段、错误码全部不变。
|
||||
- **前端是否必须同步上线**: 否——管理后台无需改任何代码。
|
||||
- **前端 workaround 清理点**: 若此前为了绕开 605001 而实现了"一个成员发一次请求"的逻辑,现在可以改回一次请求传全部成员。
|
||||
- **错误码语义的恢复**: 605001 此前在**合法请求**上会误报,修复后它**回归为真实冲突的表示**——收到 605001 就意味着确实存在资源冲突,可以按真实冲突提示用户,不必再考虑"这可能是个 bug"。
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 任何接口的**请求参数、响应字段、错误码**——全部不变。
|
||||
- **单成员创建**的行为(修复前后均 200)。
|
||||
- **既有关系的查询、解除、成员管理**等其它端点。
|
||||
- 605001 以外的其它错误码的触发口径。
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
**部署**:fleet 测试服部署点 `bd19b79c8`(2026-09-22 02:50);`git merge-base --is-ancestor e7cecb6d7 bd19b79c8` = 真;`git merge-base --is-ancestor 970f9a187 bd19b79c8` = 真;Nacos 两实例 `healthy = true`。
|
||||
|
||||
**夹具**:自建团 + 自建服务日;车辆与司机各 1 个;GROUP_DISPATCH 为组级派车 1 条;ASSIGNMENT 为基层派车 2 条(分属海拉尔东山机场与满洲里西郊机场两个出行中户)。
|
||||
|
||||
**一次请求,验证修复生效**:
|
||||
|
||||
```
|
||||
POST /admin/fleet/group-dispatch/batches/{groupBatchId}/share-groups
|
||||
payload: 1×GROUP_DISPATCH(OCCUPYING) + 2×ASSIGNMENT(PENDING_ADMISSION)
|
||||
|
||||
修复前预期:605001(从第 2 个 ASSIGNMENT 开始误报)
|
||||
修复后实测:
|
||||
→ 200 ✓
|
||||
→ success=true ✓
|
||||
→ status=ACTIVE ✓
|
||||
→ members 数组长度 3 ✓
|
||||
→ DB 三成员行齐全、状态一致 ✓
|
||||
```
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- 工单:[wx/HL#7982](https://git.1814.love:8443/wx/HL/issues/7982)
|
||||
- 修复 PR:[wx/HL#7983](https://git.1814.love:8443/wx/HL/pulls/7983)(`e7cecb6d7`)
|
||||
- 测试补强 PR:[wx/HL#8096](https://git.1814.love:8443/wx/HL/pulls/8096)(`970f9a187`)
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#7982](https://git.1814.love:8443/wx/HL/issues/7982)
|
||||
- **PR**: [#7983](https://git.1814.love:8443/wx/HL/pulls/7983)(修复)、[#8096](https://git.1814.love:8443/wx/HL/pulls/8096)(测试)
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
在新工单中引用
屏蔽一个用户