diff --git a/changelogs-v2/2026-09/22_7982_共用关系同批准入多个新成员不再误报605001-修复-管理后台.md b/changelogs-v2/2026-09/22_7982_共用关系同批准入多个新成员不再误报605001-修复-管理后台.md new file mode 100644 index 00000000..1ace1768 --- /dev/null +++ b/changelogs-v2/2026-09/22_7982_共用关系同批准入多个新成员不再误报605001-修复-管理后台.md @@ -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 | ✅ | 成员列表(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 | 入库后的成员列表(含服务端分配的 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