docs(changelog): #8354 团期人员名册实时姓名手机(staffStatus/liveInfoDegraded)+ 单人删除/更换接口
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,433 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8354"
|
||||
title: "团期配导游 / 配摄影已配置人员列表化:名册姓名手机按人员 ID 实时查询(新增 staffStatus / liveInfoDegraded)+ 新增单人删除、单人更换接口"
|
||||
consumer: "admin"
|
||||
author: "jw(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "mmg"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "jw 2026-09-24 定:已配置人员改为列表展示(角色、姓名、手机号三列),做单人接口,姓名手机按人员 ID 实时查询,不动二期 #8258。PR #8357 已合 dev-v3(f457074ba)并部署 TEST,2026-09-24 17:54~18:00 经真实网关实测:名册接口把团期快照名「旧快照名」覆盖为资源库实时姓名;资源库已删除 / 已下架的人照常列出并分别标 NOT_FOUND / OFF_SHELF;对 order-v3 单个 Feign 客户端 staffBriefFeignClient 注入 1ms 超时(17:55:59~17:59:41,还原后 nacos 原文 SHA-256 逐字节一致)期间名册接口仍 200、全部行 liveInfoDegraded=true、值为快照;单人删除只删目标人,其他人的团期行与子订单副本 ID 不变;单人更换主报账人后报账人等级随行转移、预支候选变为新人;删除主报账人后 primaryReporterRemoved=true、预支候选为空;删光导游 / 摄影且有子订单需要该项时就绪位回落 0;不在本团 589508、新旧相同 100001、新人已在本团 589582、类型不符 582114、新人已下架 582118、缺 newStaffId 400、已确认团期 589598,均零写入;不带 token 401。前端需把「已配置人员」改为表格并接两个新接口,且须先修 24_frontend 配置弹窗误传团期 ID 的缺陷,故 frontend_status 记 pending。"
|
||||
updated_at: "2026-09-24"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 团期人员配置:名册实时姓名手机 + 单人删除 / 更换(管理后台)
|
||||
|
||||
> **服务**: hl-order-service-v3(端口 8086/8186)
|
||||
> **PR**: #8357
|
||||
> **Issue**: #8354
|
||||
> **日期**: 2026-09-24
|
||||
> **影响范围**: 管理后台团期详情页「配导游」「配摄影」两个页签的「已配置人员」区域
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
1. **名册接口的姓名、手机号改为实时值**。以前是保存配置时存下的快照,资源库改了名或换了手机也不会变;现在每次查询都按人员 ID 实时取资源库。新增两个字段:`staffStatus`(人员在资源库的状态)和 `liveInfoDegraded`(资源服务不可用时回落快照)。原有字段不变。
|
||||
2. **新增单人删除**:`DELETE /v3/admin/group-batch/{productBatchId}/staff/{staffId}`,只删这一个人,其他人不动,同步从各子订单上移除。
|
||||
3. **新增单人更换**:`PUT /v3/admin/group-batch/{productBatchId}/staff/{staffId}/replace`,新人接替原人的角色位、排序、备注和报账人等级,同步替换到各子订单。
|
||||
4. 以上三个接口的路径变量都是**产品侧排期 ID**(`detail.productBatchId`),**不是**路由上的团期 ID。传错会拿到空名册或 589553,见 `24_frontend_团期详情配导游配摄影保存报589553弹窗误传团期ID-前端缺陷-管理后台.md`。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
「已配置人员」原来是一行文字(`领队 · 巴特尔 · 139****1011 领队 · 萨仁高娃 · 139****1008`),人多了看不清,也不能对单个人操作。jw 2026-09-24 定:改为表格,列为角色、姓名、手机号;做单人删除 / 更换接口;姓名手机按人员 ID 实时查询;继续使用 `order_batch_staff`,不动二期 #8258。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| 1 | 查询团期人员名册 | GET | `/v3/admin/group-batch/{productBatchId}/staff` | 修改 | 姓名 / 手机改为实时值;新增 `staffStatus` / `liveInfoDegraded` |
|
||||
| 2 | 团期单人删除 | DELETE | `/v3/admin/group-batch/{productBatchId}/staff/{staffId}` | 新增 | 只删一人并同步子订单 |
|
||||
| 3 | 团期单人更换 | PUT | `/v3/admin/group-batch/{productBatchId}/staff/{staffId}/replace` | 新增 | 一人换一人并同步子订单 |
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 查询团期人员名册 `GET /v3/admin/group-batch/{productBatchId}/staff`
|
||||
|
||||
**VO**: `List<BatchStaffConfigRespVO.BatchStaffItemVO>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
「配导游」「配摄影」页签打开时拉取已配置人员,前端按 `staffRole` 分到导游位(`GUIDE` / `LEADER`)和摄影位(`PHOTOGRAPHER`)两张表,展示角色、姓名、手机号。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| productBatchId | path | Long | 是 | 产品侧排期 ID | 取 `detail.productBatchId`,不是团期 ID |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | Long(String) | 团期人员记录 ID(整位保存后会变,单人操作请用 `staffId`) |
|
||||
| staffId | Long | 人员 ID,单人删除 / 更换的路径参数 |
|
||||
| staffRole / staffRoleName | String | 角色及中文(领队 / 导游 / 摄影) |
|
||||
| staffName | String | **实时姓名**;`staffStatus` 不是 `ON_SHELF` 时为配置时快照 |
|
||||
| staffPhone | String | **实时手机号**,脱敏前 3 后 4;非 `ON_SHELF` 时为快照(可能为 null) |
|
||||
| avatarUrl | String | 头像(快照) |
|
||||
| sortOrder | Integer | 排序 |
|
||||
| remark | String | 备注 |
|
||||
| reporterRank / reporterRankName | String | 报账人等级及中文 |
|
||||
| staffStatus | String | **新增**。`ON_SHELF` 上架(实时值)/ `OFF_SHELF` 已下架 / `NOT_FOUND` 资源库查不到(已删除)/ `UNKNOWN` 资源服务不可用 |
|
||||
| liveInfoDegraded | Boolean | **新增**。`true` = 资源服务不可用,本行姓名手机为快照 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
GET /v3/admin/group-batch/2101502082564407299/staff
|
||||
Authorization: Bearer <admin token>
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": [
|
||||
{
|
||||
"id": "2103044654230642690",
|
||||
"staffId": 1011,
|
||||
"staffRole": "LEADER",
|
||||
"staffRoleName": "领队",
|
||||
"staffName": "巴特尔",
|
||||
"staffPhone": "139****1011",
|
||||
"sortOrder": 1,
|
||||
"reporterRank": "NONE",
|
||||
"reporterRankName": "非报账人",
|
||||
"staffStatus": "ON_SHELF",
|
||||
"liveInfoDegraded": false
|
||||
},
|
||||
{
|
||||
"id": "8354000000001006",
|
||||
"staffId": 1006,
|
||||
"staffRole": "GUIDE",
|
||||
"staffRoleName": "导游",
|
||||
"staffName": "赵丽娜",
|
||||
"staffPhone": null,
|
||||
"sortOrder": 9,
|
||||
"reporterRank": "NONE",
|
||||
"reporterRankName": "非报账人",
|
||||
"staffStatus": "OFF_SHELF",
|
||||
"liveInfoDegraded": false
|
||||
}
|
||||
],
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
未配置人员返回 `[]`。资源服务不可用时仍返回 200,姓名手机为快照:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": [
|
||||
{
|
||||
"staffId": 1011,
|
||||
"staffRole": "LEADER",
|
||||
"staffName": "巴特尔",
|
||||
"staffPhone": "139****1011",
|
||||
"staffStatus": "UNKNOWN",
|
||||
"liveInfoDegraded": true
|
||||
}
|
||||
],
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误响应
|
||||
|
||||
判权未改动(`group-batch:view`)。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 589507,
|
||||
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
|
||||
"data": null,
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 整团只调一次资源服务批量接口;资源服务异常、超时、返回失败时整体降级为快照。
|
||||
- 已下架、已删除的人**照常列出**,不会从名册里消失,前端可按 `staffStatus` 加提示(如「已下架」)。
|
||||
- 保存接口(`PUT .../staff`)的响应里这两个新字段为 `null`,只有本查询接口会填。
|
||||
|
||||
### 2. 团期单人删除 `DELETE /v3/admin/group-batch/{productBatchId}/staff/{staffId}`
|
||||
|
||||
**VO**: `BatchStaffRemoveRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
名册表格某一行点「删除」,只移除这一个人。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| productBatchId | path | Long | 是 | 产品侧排期 ID | 同名册接口 |
|
||||
| staffId | path | Long | 是 | 须在本团名册中 | 取名册行的 `staffId` |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| productBatchId | Long(String) | 回显 |
|
||||
| groupBatchId | Long(String) | 运营团期 ID |
|
||||
| removedStaffId | Long | 被删除的人员 ID |
|
||||
| removedStaffRole | String | 被删除人员的角色 |
|
||||
| primaryReporterRemoved | Boolean | 被删的是否是主报账人;`true` 时本团已无主报账人 |
|
||||
| affectedOrderCount | Integer | 同步删除副本的活跃子订单数 |
|
||||
| staffList | Array | 删除后的名册(快照值,需要实时值请重新调名册接口) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
DELETE /v3/admin/group-batch/2103060031777988611/staff/1008
|
||||
Authorization: Bearer <admin token>
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"productBatchId": "2103060031777988611",
|
||||
"groupBatchId": "2103060033518661633",
|
||||
"removedStaffId": 1008,
|
||||
"removedStaffRole": "LEADER",
|
||||
"primaryReporterRemoved": false,
|
||||
"affectedOrderCount": 2,
|
||||
"staffList": []
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
写接口,无空数据形态;校验失败零写入,返回下方错误码。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
| code | 触发条件 |
|
||||
|---|---|
|
||||
| `589508` | 此人不在本团(文案为「报账人不是该团期已派员工」,前端建议按码值自定义为「该人员不在本团」) |
|
||||
| `589598` | 团期已确认(物料准备中及以后)或已取消 |
|
||||
| `589553` | 团期未建团(通常是路径传成了团期 ID) |
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 589508,
|
||||
"message": "报账人不是该团期已派员工",
|
||||
"data": null,
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 只删目标人,本团其他人的记录一行不动。
|
||||
- 同步删除团内各活跃子订单上此人的副本,并同步子订单导游 / 摄影状态。
|
||||
- 删光导游位或摄影位、且团内有子订单需要该项时,对应就绪位回落为未就绪。
|
||||
- `primaryReporterRemoved=true` 时建议提示「主报账人已移除,团期预支需重新设置主报账人」。
|
||||
|
||||
### 3. 团期单人更换 `PUT /v3/admin/group-batch/{productBatchId}/staff/{staffId}/replace`
|
||||
|
||||
**VO**: `BatchStaffReplaceReqVO` → `BatchStaffReplaceRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
名册表格某一行点「更换」,从候选里选一个新人替换原人。候选用既有的 `GET .../staff/candidates/page?role=GUIDE|PHOTOGRAPHER`。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| productBatchId | path | Long | 是 | 产品侧排期 ID | 同名册接口 |
|
||||
| staffId | path | Long | 是 | 须在本团名册中 | 被换下的人 |
|
||||
| newStaffId | body | Long | 是 | 上架、类型符合原配置位、不在本团、不等于 staffId | 换上的人 |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| productBatchId / groupBatchId | Long(String) | 回显 / 运营团期 ID |
|
||||
| oldStaffId / newStaffId | Long | 被换下 / 换上的人员 ID |
|
||||
| staffRole | String | 新人落库角色(导游位按新人真实类型存 `GUIDE` 或 `LEADER`) |
|
||||
| reporterRank | String | 新人继承的报账人等级 |
|
||||
| primaryReporterTransferred | Boolean | 被换下的是否是主报账人;`true` 时主报账人已转给新人 |
|
||||
| affectedOrderCount | Integer | 同步替换副本的活跃子订单数 |
|
||||
| staffList | Array | 更换后的名册(快照值) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
{
|
||||
"newStaffId": 1010
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"productBatchId": "2103060031777988611",
|
||||
"groupBatchId": "2103060033518661633",
|
||||
"oldStaffId": 1011,
|
||||
"newStaffId": 1010,
|
||||
"staffRole": "LEADER",
|
||||
"reporterRank": "PRIMARY",
|
||||
"primaryReporterTransferred": true,
|
||||
"affectedOrderCount": 2,
|
||||
"staffList": []
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
写接口,无空数据形态;校验失败零写入。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
| code | 触发条件 |
|
||||
|---|---|
|
||||
| `400` | 缺 `newStaffId` |
|
||||
| `100001` | 新旧相同 |
|
||||
| `589508` | 原人不在本团 |
|
||||
| `589582` | 新人已在本团 |
|
||||
| `582114` | 新人类型不符合该配置位(如把摄影换进导游位) |
|
||||
| `582118` | **新增**。新人在资源库已下架 |
|
||||
| `582103` | 资源库取不到新人(文案为「请稍后重试」,可能是新人不存在) |
|
||||
| `589598` / `589553` | 团期已确认或已取消 / 未建团 |
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 582118,
|
||||
"message": "所选人员已下架,不能配置到团期,请重新选择",
|
||||
"data": null,
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 配置位不变:导游位只能换成导游或领队,摄影位只能换成摄影。
|
||||
- 新人继承原人的排序、备注、报账人等级;本团其他人一行不动。
|
||||
- 各活跃子订单上原人的副本换成新人,并同步子订单状态。
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
- 三个接口的 `productBatchId` 一律取 `detail.productBatchId`。
|
||||
- 单人操作用名册行的 `staffId`,不要用 `id`(`id` 在整位保存后会变)。
|
||||
- 删除或更换成功后重新调名册接口刷新表格(响应里的 `staffList` 是快照值)。
|
||||
- 删除 / 更换主报账人后,团期预支的领款人候选会随之变化(删除后为空、更换后为新人)。
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
- 零表结构变更、零迁移脚本,继续读写 `order_batch_staff`。
|
||||
- 单人删除:软删此人团期行 + 软删本团活跃子订单上此人的 `order_staff_assignment`(`source=GROUP_BATCH`)副本。
|
||||
- 单人更换:软删原人团期行并插入新人一行;子订单上软删原人副本、插入新人副本。
|
||||
- 名册查询只读。
|
||||
- 所有校验失败零写入(TEST 实测写前写后比对一致)。
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
- 两个写接口与整位保存共用同一把团期锁,同一团期的写操作串行。
|
||||
- 已知窗口:若刚做过整位保存、其异步同步尚未完成就执行单人删除,被删的人可能在个别子订单上被那一轮同步写回;设置报账人等级有同类窗口。实际操作间隔秒级以上时不会出现。
|
||||
|
||||
---
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 项 | 改前 | 改后 |
|
||||
|---|---|---|
|
||||
| 名册姓名 / 手机 | 保存配置时的快照 | 资源库实时值;不可用时回落快照 |
|
||||
| 名册新增字段 | 无 | `staffStatus`、`liveInfoDegraded` |
|
||||
| 删除一个人 | 把整个配置位的名单去掉此人后重新整体保存 | `DELETE .../staff/{staffId}` |
|
||||
| 换一个人 | 同上,整体保存 | `PUT .../staff/{staffId}/replace` |
|
||||
| 其他人的记录 | 每次整体保存都会重建 | 单人操作不动其他人 |
|
||||
|
||||
---
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- 前端:名册改表格、接两个新接口、按 `staffStatus` / `liveInfoDegraded` 加提示;原有字段不变,不改也不会报错。
|
||||
- 性能:名册查询多一次资源服务批量调用。
|
||||
- 出团通知书等内部读取名册的地方仍用快照,不受影响。
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 整位保存 `PUT /v3/admin/group-batch/{productBatchId}/staff`、候选分页、设置报账人等级三个接口的契约。
|
||||
- 订单侧人员接口(`/v3/admin/order/{orderId}/staff*`)。
|
||||
- 二期 #8258 团期人员改表。
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
部署 dev-v3 @ `f457074ba` 后,2026-09-24 17:54~18:00 经真实网关 `https://api.test.1814.love` 实测(自造团期 `2103060033518661633`,一户需要导游和摄影):
|
||||
|
||||
| 用例 | 期望 | 实测 |
|
||||
|---|---|---|
|
||||
| 构建身份:名册接口带 `staffStatus` | 新字段出现 | 4 次均带 |
|
||||
| 团期快照名改成「旧快照名」后查名册 | 返回资源库实时姓名 | 返回「萨仁高娃」 |
|
||||
| 资源库已删除 / 已下架的人 | 照常列出,`NOT_FOUND` / `OFF_SHELF` | 通过 |
|
||||
| 注入资源服务客户端 1ms 超时 | 200,`liveInfoDegraded=true`,快照值 | 通过;还原后 nacos 原文 SHA-256 一致,复核恢复 `ON_SHELF` |
|
||||
| 删除萨仁高娃 | 只删目标,其他人团期行 / 子订单副本 ID 不变 | 通过 |
|
||||
| 删除不在本团的人 | 589508 零写入 | 通过 |
|
||||
| 更换:新旧相同 / 原人不在本团 / 新人已在本团 / 类型不符 / 新人已下架 / 缺参 | 100001 / 589508 / 589582 / 582114 / 582118 / 400,零写入 | 通过 |
|
||||
| 更换主报账人 巴特尔 → 乌日娜 | 等级转移,预支候选变为乌日娜 | 通过 |
|
||||
| 删除主报账人 | `primaryReporterRemoved=true`,预支候选为空 | 通过 |
|
||||
| 删光摄影 / 导游(有户需要) | 对应就绪位回落 0 | 通过 |
|
||||
| 已确认团期删除 / 更换 | 589598 零写入 | 通过 |
|
||||
| 不带 token | 401 | 通过 |
|
||||
|
||||
造数已清理:订单取消、成团取消、产品侧班期取消。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue #8354、PR #8357
|
||||
- 前端缺陷:`24_frontend_团期详情配导游配摄影保存报589553弹窗误传团期ID-前端缺陷-管理后台.md`
|
||||
- 预支领款人限定主报账人:`24_8322_团期预支核单前均可发起与领款人限定主报账人-修改接口-管理后台.md`
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
- 后端:jw
|
||||
- 前端:mmg
|
||||
在新工单中引用
屏蔽一个用户