@@ -0,0 +1,335 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8159"
|
||||
title: "团级配车成员共用候选查询"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "新增接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: ""
|
||||
updated_at: "2026-09-22"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 团级配车成员共用候选查询(#8159)
|
||||
|
||||
> **服务**: hl-fleet-service(端口 8060)
|
||||
> **PR**: #8188
|
||||
> **Issue**: #8159
|
||||
> **日期**: 2026-09-22
|
||||
> **影响范围**: 管理后台团级配车页面成员共用选举
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
新增查询端点返回「成员共用」候选列表。**重点提醒**:`resourceId` 字段语义需特别关注——未传时 `selectable` 返 `null`(未判定),**不能当 `false` 用禁用勾选**,也不能当 `true` 用放开勾选,需用户先确认资源维度。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景(选填)
|
||||
|
||||
团级配车支持多个成员(派车行、团级配车行)共享同一车或司机资源的场景。选举新成员进关系时,需先查询该服务日下哪些成员行可选。本接口支持按资源维度(车/司机)和具体资源 ID 筛选候选。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 查询成员共用候选 | GET | `/admin/fleet/group-dispatch/batches/{groupBatchId}/share-member-candidates` | 新增接口 | 返回该团服务日下可选成员清单 |
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 查询成员共用候选 `GET /admin/fleet/group-dispatch/batches/{groupBatchId}/share-member-candidates`
|
||||
|
||||
**VO**: `ShareMemberCandidateRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
管理后台团级配车页面「成员共用」选举弹窗打开时,调用本接口获取候选成员清单。前端先让用户选择资源维度(车 / 司机),再传 `resourceId` 重新查询,获得勾选框可选状态。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| `groupBatchId` | Path | Long | ✅ | — | 团期 ID(`group_batch_id`)。🔴 **这不是 `product_batch_id`**;维度错误不报参数校验错,只返 `data: []` |
|
||||
| `serviceDate` | Query | String(`yyyy-MM-dd`) | ✅ | 必须在团期服务日窗内 | 服务日。窗外日期返 `code: 602104` |
|
||||
| `resourceType` | Query | String | ✅ | `VEHICLE` / `DRIVER` | 资源维度。缺失或非法值返 `code: 100001` |
|
||||
| `resourceId` | Query | Long | ❌ | — | 具体资源 ID(车 ID / 司机 ID)。**不传时 `occupying` / `selectable` 返 `null`**(未判定状态,见业务边界第 1 条) |
|
||||
|
||||
#### 出参 `Result<List<ShareMemberCandidateVO>>`
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `sourceType` | String | `ASSIGNMENT`(派车行)/ `GROUP_DISPATCH`(团级配车行) |
|
||||
| `sourceId` | String | 雪花 ID,**字符串形态**(19 位,前端一律当字符串处理,禁转 Number) |
|
||||
| `requirementId` | String | 需求 ID(派车行有值,团级配车行可能 null) |
|
||||
| `orderId` | String / null | 订单 ID。`GROUP_DISPATCH` 行可能为 null |
|
||||
| `orderNo` | String | 订单号 |
|
||||
| `customerName` | String | 客户名称 |
|
||||
| `headcount` | Integer | 人数 |
|
||||
| `pickupAt` | String | 上车地点 |
|
||||
| `dropoffAt` | String / null | 下车地点,可能为 null |
|
||||
| `pickupParticipant` | Integer | 上车人数 |
|
||||
| `dropoffParticipant` | Integer | 下车人数 |
|
||||
| `groupCode` | String / null | 团号,可能为 null |
|
||||
| `vehicleModel` | String / null | 车型 |
|
||||
| `occupiedVehicleId` | String / null | 该行实际占用的车 ID;未占用时 null |
|
||||
| `occupiedVehiclePlate` | String / null | 该行实际占用的车牌号 |
|
||||
| `occupiedDriverId` | String / null | 该行实际占用的司机 ID;未占用时 null |
|
||||
| `occupiedDriverName` | String / null | 该行实际占用的司机名称 |
|
||||
| `occupying` | Boolean / **null** | 本行在 `(serviceDate, resourceType, resourceId)` 上是否活跃占用。**`resourceId` 未传时为 `null`**(未判定) |
|
||||
| `shareGroupId` | String / null | 本行所属的 ACTIVE 共用关系 ID;不属任何关系时 null |
|
||||
| `selectable` | Boolean / **null** | 是否可勾选。`true` = 可选;`false` = 不可选(此时 `unselectableReason` 非空);**`null` = 未判定**(仅当 `resourceId` 未传、且本行未被永久性约束击中时出现) |
|
||||
| `unselectableReason` | String / null | 不可选原因枚举值(见六.5 章节);`selectable=true` 时为 null |
|
||||
| `unselectableDetail` | String / null | 人类可读的补充说明,如「订单 HLxxxx 已在车 A 关系中」 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
GET /admin/fleet/group-dispatch/batches/2102125467954044929/share-member-candidates?serviceDate=2026-12-25&resourceType=VEHICLE&resourceId=2085539421276286978
|
||||
```
|
||||
|
||||
无请求体。Authorization 头由网关透传(管理后台 JWT)。
|
||||
|
||||
#### 响应示例
|
||||
|
||||
成功响应(带具体资源 ID 的正常清单):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": [
|
||||
{
|
||||
"sourceType": "ASSIGNMENT",
|
||||
"sourceId": "2102125764705181697",
|
||||
"requirementId": "2102125585692295169",
|
||||
"orderId": "2102125467924684801",
|
||||
"orderNo": "HL20260922035901739",
|
||||
"customerName": "#8114AC8-X",
|
||||
"headcount": 1,
|
||||
"pickupAt": "满洲里口岸",
|
||||
"dropoffAt": null,
|
||||
"pickupParticipant": 0,
|
||||
"dropoffParticipant": 0,
|
||||
"groupCode": null,
|
||||
"vehicleModel": "丰田普拉多",
|
||||
"occupiedVehicleId": "2085539421276286978",
|
||||
"occupiedVehiclePlate": "蒙A-E2E99",
|
||||
"occupiedDriverId": "2065272150012444674",
|
||||
"occupiedDriverName": "道尔吉",
|
||||
"occupying": true,
|
||||
"shareGroupId": null,
|
||||
"selectable": true,
|
||||
"unselectableReason": null,
|
||||
"unselectableDetail": null
|
||||
}
|
||||
],
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
**示例说明**:示例值取自测试环境某次真实调用,不构成可复现夹具。
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
该团该服务日无任何在飞派单与活跃团级配车行时返 `code: 200, data: []`(**不是 null、不抛错**)。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": [],
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
下游不可用(权威基线 Feign 失败,失败关闭)时,接口返 `code: 999` 或 5xx,网关记日志,前端需重试或展示加载失败。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
**服务日不在团期窗内**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 602104,
|
||||
"message": "服务日不在团期服务日窗内: 2026-12-28",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**参数非法**(缺 `resourceType` 或传非法值):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 100001,
|
||||
"message": "参数非法: 资源维度非法: HOUSE",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
1. **`resourceId` 未传时的 null 三态语义**(最重要):
|
||||
- `occupying`:**`null`**(= 未判定,不是 `false`)
|
||||
- `selectable`:**`null`**(= 未判定,不是 `true` / `false`)
|
||||
- `unselectableReason`、`unselectableDetail`:都为 null
|
||||
|
||||
前端在浏览态(用户尚未选择具体资源)**不能**把 `selectable == null` 当成 `false` 禁用勾选、也不能当成 `true` 放开;这是第三种状态,需等用户明确选定车或司机后再查一遍、获得真实判定。
|
||||
|
||||
2. **候选是时点快照**:本接口返回的 `selectable=true` 是**查询那一刻**的结论。前端提交共用关系时仍可能撞到 `code: 602106`(该行在这期间被别人加进了另一个共用关系)。前端**必须保留提交失败的错误处理分支**,不能因为候选查询说可选就假定提交一定成功。
|
||||
|
||||
3. **`group_batch_id` 为 NULL 的派单行不在本端点覆盖范围**:查询条件是 `eq(group_batch_id, ?)`,这类行无法查出;若前端观察到「某些派单没出现在候选里」,原因可能是该派单的 `group_batch_id` 字段为 null(结构性特征,非数据错误)。
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
### ✅ 正确 / ❌ 错误请求对照
|
||||
|
||||
| 场景 | 请求 | 预期 |
|
||||
|------|------|------|
|
||||
| ✅ 浏览态,看全清单 | `?serviceDate=2026-12-25&resourceType=VEHICLE`(无 resourceId) | `data[]` 中所有行 `occupying=null, selectable=null` |
|
||||
| ✅ 选定车后判可选 | `?serviceDate=2026-12-25&resourceType=VEHICLE&resourceId=2085539421276286978` | `data[]` 中各行 `occupying=true/false, selectable=true/false/null` |
|
||||
| ✅ 跨服务日查询 | `?serviceDate=2026-12-26&resourceType=VEHICLE&resourceId=xxx` | 若 2026-12-26 在服务窗内,照常返回候选;若不在返 602104 |
|
||||
| ❌ 维度错填 | `?serviceDate=2026-12-25&resourceType=HOUSE&resourceId=xxx` | 400 `100001: 参数非法: 资源维度非法: HOUSE` |
|
||||
| ❌ 缺维度参数 | `?serviceDate=2026-12-25&resourceId=xxx`(无 resourceType) | 400 `100001: 参数非法: 资源维度不能为空` |
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
本接口仅读操作,无 DB 写入。查询涉及表:`order_requirement`(派车行),`group_dispatch_line`(团级配车行),`group_batch`(团期基础),`vehicle`(车辆),`driver`(司机)。
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
- **未登录** → 401(网关统一鉴权)
|
||||
- **无访问权限** → 403(订单顾问、财务相关角色可访)
|
||||
- **团期不存在** → `data: []`(无候选)
|
||||
- **资源维度非法** → 100001
|
||||
- **服务日超出团期窗** → 602104
|
||||
- **下游服务不可用** → 5xx,前端重试
|
||||
|
||||
---
|
||||
|
||||
## 六.5 枚举 / 数据字典
|
||||
|
||||
### sourceType(行源类型)
|
||||
|
||||
**所属字段**: `sourceType` | **类型**: `String`
|
||||
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| `ASSIGNMENT` | 派车行 | 订单需求对应的派车行 |
|
||||
| `GROUP_DISPATCH` | 团级配车行 | 团级配车单位产生的配车行 |
|
||||
|
||||
### resourceType(资源维度)
|
||||
|
||||
**所属字段**: `resourceType`(查询参数) | **类型**: `String`
|
||||
|
||||
| 值 | 中文 | 说明 |
|
||||
|---|---|---|
|
||||
| `VEHICLE` | 车辆 | 按车 ID 筛选候选 |
|
||||
| `DRIVER` | 司机 | 按司机 ID 筛选候选 |
|
||||
|
||||
### unselectableReason(不可选原因)
|
||||
|
||||
**所属字段**: `unselectableReason` | **类型**: `String`
|
||||
|
||||
| 值 | 含义 | 触发条件 |
|
||||
|---|---|---|
|
||||
| `CROSS_BATCH` | 602103 | 本行所属团期与目标团期不同 |
|
||||
| `NOT_OCCUPYING` | 602102 | 本行在目标 `(serviceDate, resourceType, resourceId)` 上未占用 |
|
||||
| `ALREADY_IN_ANOTHER_GROUP` | 602106 | 本行已属于另一个 ACTIVE 共用关系 |
|
||||
| `GROUP_DISPATCH_INVALID` | 602105 | 团级配车行的基础数据不完整或状态异常 |
|
||||
|
||||
**说明**:这些值**不是**接口级错误码,而是本字段的业务枚举。提交共用关系时若失败,才会返回 `code: 602103` / `602106` 等(整请求级错误码)。
|
||||
|
||||
---
|
||||
|
||||
## 六.6 修改前后对比
|
||||
|
||||
无,本接口为新增。
|
||||
|
||||
---
|
||||
|
||||
## 六.7 影响评估
|
||||
|
||||
- **破坏兼容**:否,新增接口
|
||||
- **前端同步上线要求**:否,新接口不影响现有流程
|
||||
- **workaround 清理**:无
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- **仅影响**:管理后台团级配车页面成员共用选举功能
|
||||
- **零影响**:
|
||||
- 派车行的查询 / 新增 / 编辑
|
||||
- 订单创建 / 支付流程
|
||||
- 团期成团 / 分配等其他流程
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
真实接口调用结果(hl-fleet-service 已部署 `dev-v3 @ cf9dc85a4`,merge commit `a584bd087`):
|
||||
|
||||
```
|
||||
GET /admin/fleet/group-dispatch/batches/2102125467954044929/share-member-candidates
|
||||
?serviceDate=2026-12-25&resourceType=VEHICLE&resourceId=2085539421276286978
|
||||
→ 200 + 候选清单(occupying=true/false, selectable=true/false) ✓
|
||||
|
||||
GET /admin/fleet/group-dispatch/batches/2102125467954044929/share-member-candidates
|
||||
?serviceDate=2026-12-25&resourceType=VEHICLE
|
||||
→ 200 + 候选清单(occupying=null, selectable=null) ✓
|
||||
|
||||
GET /admin/fleet/group-dispatch/batches/2102125467954044929/share-member-candidates
|
||||
?serviceDate=2026-12-28&resourceType=VEHICLE&resourceId=xxx
|
||||
→ 602104(服务日不在团期服务日窗内) ✓
|
||||
|
||||
GET /admin/fleet/group-dispatch/batches/2102125467954044929/share-member-candidates
|
||||
?serviceDate=2026-12-25&resourceType=HOUSE
|
||||
→ 100001(参数非法: 资源维度非法: HOUSE) ✓
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、相关历史 PR
|
||||
|
||||
无,本接口为新增。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- 关联 Issue: [wx/HL#8159](https://git.1814.love:8443/wx/HL/issues/8159)
|
||||
- 关联 PR: [wx/HL#8188](https://git.1814.love:8443/wx/HL/pulls/8188)
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#8159](https://git.1814.love:8443/wx/HL/issues/8159)
|
||||
- **PR**: [#8188](https://git.1814.love:8443/wx/HL/pulls/8188)
|
||||
- **Merge commit**: [a584bd087](https://git.1814.love:8443/wx/HL/commit/a584bd087)
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
在新工单中引用
屏蔽一个用户