1791 行
81 KiB
Markdown
1791 行
81 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "8468"
|
||
title: "团期导领摄配置加服务日期与基础日薪,选人列表与名册显示占用状态,导摄芯片去掉逐户人员"
|
||
consumer: "admin"
|
||
author: "jw(GIT)"
|
||
change_type: "修改接口"
|
||
backend_status: "deployed"
|
||
gateway_status: "verified"
|
||
frontend_status: "implemented"
|
||
frontend_owner: "mmg"
|
||
frontend_ref: "838b80d69dd1ff5a96e6a95e886d979dac5f452c"
|
||
target_release: "v2.1"
|
||
verified_at: "2026-09-28"
|
||
status_note: "PR #8475(bf65803b7)与 #8476(623c932bd)已合入 dev-v3,TEST 的 hl-resource-service 与 hl-order-service-v3 均运行 dev-v3 623c932bd;经网关 api.test.1814.love 用真实 admin token 实测 AC-1、3、6~13、15、16 主路径全部通过,金额字段字符串形态已复验。前端需接:选人弹窗展示等级、服务区域、擅长、基础日薪与占用标签,占用明细弹层,保存弹窗编辑服务日期,服务人员管理基础日薪回显与列表列,导摄页签与看板芯片弹层去掉逐户人员表(见第四节交接清单),故 frontend_status 记 pending。前端已交付(人员画像/占用标签/服务日期三态+导摄芯片去逐户人员),详见 hl-admin v2.1 提交 838b80d6。"
|
||
updated_at: "2026-09-28"
|
||
base: "dev-v3"
|
||
---
|
||
|
||
# 团期人员配置:服务日期、基础日薪与占用状态(管理后台)
|
||
|
||
> **服务**: hl-order-service-v3(团期人员配置、导/摄芯片明细)、hl-resource-service(服务人员管理)
|
||
> **PR**: #8475(主体,合入 dev-v3 为 `bf65803b7`)、#8476(金额字段改字符串输出,合入 dev-v3 为 `623c932bd`)
|
||
> **Issue**: #8468
|
||
> **日期**: 2026-09-28
|
||
> **影响范围**: 团期详情「配导游」「配摄影」的选人弹窗、已配置人员名册与保存弹窗,看板导/摄芯片弹层,服务人员管理新建/编辑/详情/列表
|
||
|
||
---
|
||
|
||
## ⚠️ 关键变化
|
||
|
||
1. **名册与候选新增占用**:已配置人员名册(以及保存、更换、删除响应里的 `staffList[]`)和两个候选接口的每一项都新增 `occupancyStatus`(`FREE` 空闲 / `PARTIAL` 部分占用 / `FULL` 全程占用)、`occupiedDays`、`freeRanges`、`occupancies[]`。占用**只提示、不拦截**,有占用照样能保存。
|
||
2. **名册新增服务日期与基础日薪**:`serviceStartDate`、`serviceEndDate`、`serviceDateCustom`、`baseDailyWage`。保存接口每人可选传 `serviceStartDate` / `serviceEndDate`;日期不合法返回**新错误码 `582119`**(文案带人名,整批不写入)。
|
||
3. **候选新增人员画像并改为全局排序**:候选项新增 `level`、`serviceAreas`、`specialties`、`baseDailyWage`;排序改为「本团本位已选 → 空闲 → 部分占用 → 全程占用 → 等级从高到低 → `sortOrder` 升序 → `staffId` 升序」,分页版逐页翻完不重不漏。
|
||
4. **金额字段是 JSON 字符串**:order-v3 的 `baseDailyWage` 与服务人员管理的 `basePrice` 都以字符串输出(如 `"600.00"`)。做数值运算、比较大小或回填数字输入框前先 `Number()`。
|
||
5. **导/摄芯片不再逐户返回人员**:`GET .../chips/guide`、`GET .../chips/photo` 的 `items` 恒为 `[]`,只看 `staffList`(团期名册)。`aggregateStatus` / `totalCount` / `doneCount` 口径不变。
|
||
6. **修复:保存导游位后主报账人与备注被重置**。保留下来的人(即使请求只带 `staffId`、`staffRole`、`sortOrder`)沿用原来的报账人等级、备注、服务日期与日薪。随之 **`remark` 口径变化**:不传(`null`)= 沿用原备注;要清空请传空串 `""`。
|
||
|
||
---
|
||
|
||
## 一、背景
|
||
|
||
选人弹窗原来只有姓名、手机号、类型,看不到等级、服务区域、擅长和日薪,也看不出这个人同一时段是否已派到别的团或订单;导游/摄影页签下的逐户表把团期名册在每个子订单上重复列一遍;每保存一次导游位,主报账人被重置、备注被清空;服务人员管理的「基础日薪」输入框填了不保存。
|
||
|
||
jw 2026-09-28 定案口径:
|
||
|
||
| # | 口径 |
|
||
|---|---|
|
||
| D1 | 基础日薪在选人时从服务人员管理的「基础日薪」带出,团期里不能改。更换人员取新人的档案值。档案值为 0 或空时返回 null。快照为空时,下次保存补取一次档案当前值;已有值不刷新 |
|
||
| D2 | 服务日期不填就跟随团期:读的时候换算成团期出发日和结束日,团期改期后自动跟着变。提交的日期和团期起止相同也按跟随团期处理 |
|
||
| D3 | 招募中(还没成团)的团期里派了的人,也算占用 |
|
||
| D4 | 日期段两端都算:前一个团结束当天、后一个团出发,这种首尾相接也算占用 |
|
||
| D5 | 占用只提示,不拦截。有占用照样能保存,也不要求二次确认 |
|
||
| D6 | 保存时,保留下来的人员沿用原来那一行的报账人等级、备注、服务日期和日薪;请求里传了的以请求为准 |
|
||
| D7 | 占用有两个来源:①其他团期的人员配置;②普通订单(不属于任何团期)上定制师直接派的人。团期同步到子订单的人员副本不重复计算。已取消的订单不算,其余订单状态都算 |
|
||
| D8 | 占用分三档:被占 0 天为空闲,被占满整段为全程占用,其余为部分占用 |
|
||
| D9 | 本单不做「只看空闲」筛选 |
|
||
| D10 | 导游/摄影不再按子订单逐户展示配置人员,看团期整体名册即可 |
|
||
|
||
---
|
||
|
||
## 二、变更接口清单
|
||
|
||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||
|---|------|------|------|----------|------|
|
||
| 1 | 保存团期人员配置 | PUT | `/v3/admin/group-batch/{productBatchId}/staff` | 修改:入参加字段、新错误码、出参加字段 | 每人可选 `serviceStartDate`、`serviceEndDate`;日薪由服务端带出;新错误码 582119;保留人员沿用原等级、备注、日期、日薪 |
|
||
| 2 | 查询团期人员名册 | GET | `/v3/admin/group-batch/{productBatchId}/staff` | 修改:出参加字段 | 每人加服务日期、是否自定义、基础日薪与四个占用字段 |
|
||
| 3 | 团期单人更换 | PUT | `/v3/admin/group-batch/{productBatchId}/staff/{staffId}/replace` | 修改:行为、新错误码、出参加字段 | 新人沿用原人服务日期,日薪取新人档案;可能返回 582119 |
|
||
| 4 | 团期单人删除 | DELETE | `/v3/admin/group-batch/{productBatchId}/staff/{staffId}` | 修改:出参加字段 | 响应 `staffList[]` 加字段 |
|
||
| 5 | 团期人员候选分页 | GET | `/v3/admin/group-batch/{productBatchId}/staff/candidates/page` | 修改:出参加字段、排序变化 | 加等级、区域、擅长、日薪与占用;全局排序后分页 |
|
||
| 6 | 团期人员候选列表 | GET | `/v3/admin/group-batch/{productBatchId}/staff/candidates` | 修改:出参加字段、排序变化 | 与 5 相同(全量版) |
|
||
| 7 | 配导游芯片明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/guide` | 修改:出参取值变化 | `items` 恒为 `[]`,只看 `staffList` |
|
||
| 8 | 配摄影芯片明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/photo` | 修改:出参取值变化 | `items` 恒为 `[]`,只看 `staffList` |
|
||
| 9 | 新建服务人员 | POST | `/admin/staff` | 修改:入参加字段、出参加字段 | 可传 `basePrice`;响应 `basePrice` 为字符串 |
|
||
| 10 | 编辑服务人员 | PUT | `/admin/staff/{staffId}` | 修改:入参加字段、出参加字段 | `basePrice` 可改,不传不改;负数或超过 2 位小数返回 400 |
|
||
| 11 | 服务人员详情 | GET | `/admin/staff/{staffId}` | 修改:出参加字段 | 返回字符串 `basePrice` |
|
||
| 12 | 服务人员列表 | GET | `/admin/staff/list` | 修改:出参加字段 | 每条返回字符串 `basePrice` |
|
||
|
||
---
|
||
|
||
## 三、接口详情
|
||
|
||
### 1. 保存团期人员配置 `PUT /v3/admin/group-batch/{productBatchId}/staff`
|
||
|
||
**VO**: `BatchStaffConfigReqVO` → `BatchStaffConfigRespVO`
|
||
|
||
#### 使用场景
|
||
|
||
「配导游」「配摄影」保存弹窗点「保存」时调用。本单起弹窗里可以给每个人填服务开始 / 结束日期(不填 = 跟随团期);基础日薪只读展示,不提交。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| productBatchId | Path | Long | 是 | 产品侧排期 ID | 取 `detail.productBatchId`,不是团期 ID(既有) |
|
||
| scopeRoles | Body | String[] | 否 | 传了就不能是 `[]`;导游位必须同时含 `GUIDE` 与 `LEADER` | 本次覆盖的角色范围;不传 = 整期覆盖(既有) |
|
||
| staffList | Body | Object[] | 是 | 显式传 `[]` = 清空覆盖范围 | 覆盖范围内的最终名单(既有) |
|
||
| staffList[].staffId | Body | Long | 是 | - | 人员 ID(既有) |
|
||
| staffList[].staffRole | Body | String | 是 | 取值域不变 | 角色,如 `LEADER`、`GUIDE`、`PHOTOGRAPHER`(既有) |
|
||
| staffList[].sortOrder | Body | Integer | 否 | 缺省 0 | 展示排序(既有;不沿用原值) |
|
||
| staffList[].remark | Body | String | 否 | ≤500 字 | **口径变化**:不传(`null`)时,保留下来的人沿用原备注;传空串 `""` 才是清空;新选的人不传即无备注 |
|
||
| staffList[].serviceStartDate | Body | String(yyyy-MM-dd) | 否 | 有效开始日不晚于有效结束日,且在团期出发日到结束日之间,否则 582119 | **新增**。服务开始日。不传:保留下来的人沿用原值,新选的人跟随团期。与团期出发日相同按跟随团期处理。要把自定义日期改回跟随团期,传团期出发日本身 |
|
||
| staffList[].serviceEndDate | Body | String(yyyy-MM-dd) | 否 | 同上 | **新增**。服务结束日,口径同上,对照团期结束日 |
|
||
| staffList[].baseDailyWage | Body | - | 否 | 不接收 | 请求里带了会被忽略(不报错、不落库);日薪一律由服务端从服务人员档案带出 |
|
||
|
||
#### 出参 `Result<BatchStaffConfigRespVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| productBatchId | String | 回显路径参数(既有) |
|
||
| groupBatchId | String | 运营团期 ID(既有) |
|
||
| affectedOrderCount | Integer | 同步到的活跃子订单数(既有) |
|
||
| staffList | Object[] | 保存后的整期名单(既有)。既有字段 `id`、`staffId`、`staffRole`、`staffRoleName`、`staffName`、`staffPhone`、`avatarUrl`、`sortOrder`、`remark`、`reporterRank`、`reporterRankName` 不变;`staffStatus`、`liveInfoDegraded` 在本接口为 null(既有) |
|
||
| staffList[].serviceStartDate | String(yyyy-MM-dd) | **新增**。有效服务开始日:没自定义 = 团期出发日(团期改期后跟着变);自定义值原样显示;只有团期出发日为空时为 null |
|
||
| staffList[].serviceEndDate | String(yyyy-MM-dd) | **新增**。有效服务结束日,口径同上,对照团期结束日 |
|
||
| staffList[].serviceDateCustom | Boolean | **新增**。开始或结束任一自定义过为 `true`;都跟随团期为 `false`;恒非 null |
|
||
| staffList[].baseDailyWage | String | **新增**。基础日薪快照,字符串如 `"1000.00"`;档案未填或为 0 时为 null;前端运算前 `Number()` |
|
||
| staffList[].occupancyStatus | String | **新增**。`FREE` / `PARTIAL` / `FULL`,按这个人在本团的服务日期段比对;本团期未建或团期起止不全时为 null |
|
||
| staffList[].occupiedDays | Integer | **新增**。服务日期段内被占的天数(两端都算);`occupancyStatus` 为 null 时为 0 |
|
||
| staffList[].freeRanges | String[] | **新增**。可派日期段,形如 `2026-10-28~2026-10-28`,按日期升序;全程占用或 `occupancyStatus` 为 null 时为 `[]` |
|
||
| staffList[].occupancies | Object[] | **新增**。占用明细,按 `startDate` 升序;空闲或 `occupancyStatus` 为 null 时为 `[]` |
|
||
| staffList[].occupancies[].sourceType | String | 来源:`GROUP_BATCH` 其他团期的人员配置 / `ORDER` 普通订单上定制师直派 |
|
||
| staffList[].occupancies[].sourceId | String | 来源 ID:`GROUP_BATCH` 为运营团期 ID,`ORDER` 为订单 ID |
|
||
| staffList[].occupancies[].refNo | String | 团期号 / 订单号;源数据为空时为 null |
|
||
| staffList[].occupancies[].title | String | 团期名称(为空时取产品名)/ 订单的产品名;都为空时为 null |
|
||
| staffList[].occupancies[].statusName | String | 来源当前状态中文名,如「招募中」「待出行」 |
|
||
| staffList[].occupancies[].staffRole / staffRoleName | String | 他在那边的角色及中文名(跨角色也计入占用) |
|
||
| staffList[].occupancies[].startDate / endDate | String(yyyy-MM-dd) | 他在那边的服务起止:团期为他在那个团的有效服务日期(自定义日期先夹进那个团当前起止);订单为出发日到返回日(返回日为空按出发日当天) |
|
||
| staffList[].occupancies[].overlapStartDate / overlapEndDate | String(yyyy-MM-dd) | 与本团服务日期段重叠的起止,两端都算,恒在本团服务日期段内 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
PUT /v3/admin/group-batch/2104455374549721090/staff
|
||
Authorization: Bearer <admin token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"scopeRoles": ["GUIDE", "LEADER"],
|
||
"staffList": [
|
||
{
|
||
"staffId": 1005,
|
||
"staffRole": "LEADER",
|
||
"sortOrder": 1,
|
||
"remark": "负责额尔古纳段",
|
||
"serviceStartDate": "2026-10-27",
|
||
"serviceEndDate": "2026-10-28"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测(班期 10-26 ~ 10-28,刘大山 10-27 已被一张普通订单派为领队;金额按当前契约写成字符串):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"productBatchId": "2104455374549721090",
|
||
"groupBatchId": "2104455377657724930",
|
||
"staffList": [
|
||
{
|
||
"id": "2104456232708509698",
|
||
"staffId": 1005,
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"staffName": "刘大山",
|
||
"staffPhone": "138****1005",
|
||
"avatarUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/test/material/2026/03/26/45d9abebc569ca7b7ab13cac212ca38a.png",
|
||
"sortOrder": 1,
|
||
"remark": "负责额尔古纳段",
|
||
"reporterRank": "NONE",
|
||
"reporterRankName": "非报账人",
|
||
"staffStatus": null,
|
||
"liveInfoDegraded": null,
|
||
"serviceStartDate": "2026-10-27",
|
||
"serviceEndDate": "2026-10-28",
|
||
"serviceDateCustom": true,
|
||
"baseDailyWage": "1000.00",
|
||
"occupancyStatus": "PARTIAL",
|
||
"occupiedDays": 1,
|
||
"freeRanges": ["2026-10-28~2026-10-28"],
|
||
"occupancies": [
|
||
{
|
||
"sourceType": "ORDER",
|
||
"sourceId": "2100743225424621570",
|
||
"refNo": "HL20260918082629372",
|
||
"title": "测试核心产品-单档-固定比例",
|
||
"statusName": "待出行",
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"startDate": "2026-10-25",
|
||
"endDate": "2026-10-27",
|
||
"overlapStartDate": "2026-10-27",
|
||
"overlapEndDate": "2026-10-27"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"affectedOrderCount": 1
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
- `staffList: []`(清空覆盖范围):照常 200,响应 `staffList` 是保存后的整期名单,范围内的人已移除(既有)。
|
||
- 团期起止任一端为空时:名册项 `serviceStartDate` / `serviceEndDate` 可能为 null,占用四字段为 `null` / `0` / `[]` / `[]`。
|
||
- 占用不影响保存结果:有占用、全程占用都照样 200。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{
|
||
"code": 582119,
|
||
"message": "萨仁高娃 的服务日期(2026-11-16 至 2026-11-19)不合法:开始日期不能晚于结束日期,且须在团期日期(2026-11-17 至 2026-11-19)之内",
|
||
"data": null,
|
||
"traceId": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
| code | 触发条件 |
|
||
|---|---|
|
||
| `582119` | **新增**。某人的有效服务开始日晚于结束日,或越出团期出发日到结束日;文案里是人名和他的有效起止、团期起止(团期日期不全时写「未定」);整批不写入 |
|
||
| `582115` / `582116` | 角色超出 `scopeRoles` / 只声明了半个配置位(既有;同时触犯时先报这两个) |
|
||
| `589553` / `589598` | 团期尚未创建 / 团期已确认或已取消(既有) |
|
||
| `400` | 缺 `staffList`、`remark` 超 500 字、日期格式不对等参数校验(既有机制) |
|
||
|
||
#### 业务边界
|
||
|
||
- 判权未改:需要团期管理权限 `group-batch:manage`。
|
||
- 「保留下来的人」= 本次提交里、且在本次覆盖范围内原本就有记录的人(按 `staffId` 认)。他们的报账人等级一律沿用(本接口改不了等级,改等级走 `PUT .../staff/{staffId}/reporter-rank`);备注、服务日期请求没传时沿用;日薪原快照非空时沿用。
|
||
- 日薪(D1):新选的人取服务人员档案当前的基础日薪(0 或空 → null);保留下来的人原快照非空不刷新,原快照为空时补取一次档案当前值;请求里的 `baseDailyWage` 一律忽略。
|
||
- 服务日期(D2):与团期起止相同按跟随团期处理,名册 `serviceDateCustom=false`;自定义才算 `true`。开始、结束两端各自判断。
|
||
- 582119 校验的是本次所有要写入的人,**包括沿用来的旧日期**:团期改期后旧的自定义日期可能已落在新团期外,这时保存同样返回 582119,文案点名,先把那个人的日期改到团期内再保存。
|
||
- 返回 582119 时整批不写入:原名册一行不变。
|
||
- 占用只提示不拦截(D5)。
|
||
|
||
### 2. 查询团期人员名册 `GET /v3/admin/group-batch/{productBatchId}/staff`
|
||
|
||
**VO**: `List<BatchStaffConfigRespVO.BatchStaffItemVO>`
|
||
|
||
#### 使用场景
|
||
|
||
「配导游」「配摄影」页签打开时拉已配置人员,前端按 `staffRole` 分到导游位(`GUIDE` / `LEADER`)与摄影位(`PHOTOGRAPHER`)两张表。本单起每行可展示服务日期、基础日薪与占用标签。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| productBatchId | Path | Long | 是 | 产品侧排期 ID | 取 `detail.productBatchId`,不是团期 ID(既有) |
|
||
|
||
#### 出参 `Result<List<BatchStaffItemVO>>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | String | 团期人员记录 ID(既有;整位保存后会变,单人操作用 `staffId`) |
|
||
| staffId | Long | 人员 ID(既有) |
|
||
| staffRole / staffRoleName | String | 角色及中文名(既有) |
|
||
| staffName / staffPhone / avatarUrl | String | 姓名、脱敏手机号、头像(既有) |
|
||
| sortOrder | Integer | 排序(既有) |
|
||
| remark | String | 备注(既有) |
|
||
| reporterRank / reporterRankName | String | 报账人等级及中文名(既有) |
|
||
| staffStatus / liveInfoDegraded | String / Boolean | 人员在资源库的状态、是否降级为快照(既有,仅本接口填充) |
|
||
| serviceStartDate | String(yyyy-MM-dd) | **新增**。有效服务开始日:没自定义 = 团期出发日(团期改期后跟着变);自定义值原样显示;只有团期出发日为空时为 null |
|
||
| serviceEndDate | String(yyyy-MM-dd) | **新增**。有效服务结束日,口径同上,对照团期结束日 |
|
||
| serviceDateCustom | Boolean | **新增**。开始或结束任一自定义过为 `true`;恒非 null |
|
||
| baseDailyWage | String | **新增**。基础日薪快照,字符串如 `"1000.00"`;档案未填或为 0 时为 null;前端运算前 `Number()` |
|
||
| occupancyStatus | String | **新增**。`FREE` / `PARTIAL` / `FULL`,按这个人在本团的服务日期段比对;本团期未建或团期起止不全时为 null |
|
||
| occupiedDays | Integer | **新增**。服务日期段内被占天数(两端都算);`occupancyStatus` 为 null 时为 0 |
|
||
| freeRanges | String[] | **新增**。可派日期段 `yyyy-MM-dd~yyyy-MM-dd`,升序;全程占用或 `occupancyStatus` 为 null 时为 `[]` |
|
||
| occupancies | Object[] | **新增**。占用明细,按 `startDate` 升序;空闲或 `occupancyStatus` 为 null 时为 `[]` |
|
||
| occupancies[].sourceType | String | `GROUP_BATCH` 其他团期的人员配置 / `ORDER` 普通订单上定制师直派 |
|
||
| occupancies[].sourceId | String | `GROUP_BATCH` 为运营团期 ID,`ORDER` 为订单 ID |
|
||
| occupancies[].refNo | String | 团期号 / 订单号;源数据为空时为 null |
|
||
| occupancies[].title | String | 团期名称(为空时取产品名)/ 订单的产品名;都为空时为 null |
|
||
| occupancies[].statusName | String | 来源当前状态中文名,如「招募中」「待出行」 |
|
||
| occupancies[].staffRole / staffRoleName | String | 他在那边的角色及中文名(跨角色也计入占用) |
|
||
| occupancies[].startDate / endDate | String(yyyy-MM-dd) | 他在那边的服务起止:团期为他在那个团的有效服务日期(自定义日期先夹进那个团当前起止);订单为出发日到返回日(返回日为空按出发日当天) |
|
||
| occupancies[].overlapStartDate / overlapEndDate | String(yyyy-MM-dd) | 与本团服务日期段重叠的起止,两端都算 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /v3/admin/group-batch/2104455359768993795/staff
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测(班期 11-17 ~ 11-19;白云飞跟随团期,萨仁高娃自定义为 11-18 单日;金额按当前契约写成字符串):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": [
|
||
{
|
||
"id": "2104455839127633921",
|
||
"staffId": 1007,
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"staffName": "白云飞",
|
||
"staffPhone": "139****1007",
|
||
"avatarUrl": null,
|
||
"sortOrder": 1,
|
||
"remark": null,
|
||
"reporterRank": "NONE",
|
||
"reporterRankName": "非报账人",
|
||
"staffStatus": "ON_SHELF",
|
||
"liveInfoDegraded": false,
|
||
"serviceStartDate": "2026-11-17",
|
||
"serviceEndDate": "2026-11-19",
|
||
"serviceDateCustom": false,
|
||
"baseDailyWage": "800.00",
|
||
"occupancyStatus": "FREE",
|
||
"occupiedDays": 0,
|
||
"freeRanges": ["2026-11-17~2026-11-19"],
|
||
"occupancies": []
|
||
},
|
||
{
|
||
"id": "2104455839131828226",
|
||
"staffId": 1008,
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"staffName": "萨仁高娃",
|
||
"staffPhone": "139****1008",
|
||
"avatarUrl": null,
|
||
"sortOrder": 2,
|
||
"remark": null,
|
||
"reporterRank": "NONE",
|
||
"reporterRankName": "非报账人",
|
||
"staffStatus": "ON_SHELF",
|
||
"liveInfoDegraded": false,
|
||
"serviceStartDate": "2026-11-18",
|
||
"serviceEndDate": "2026-11-18",
|
||
"serviceDateCustom": true,
|
||
"baseDailyWage": null,
|
||
"occupancyStatus": "FREE",
|
||
"occupiedDays": 0,
|
||
"freeRanges": ["2026-11-18~2026-11-18"],
|
||
"occupancies": []
|
||
}
|
||
],
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
- 未配置人员:`data: []`(测试服未建团期的班期实测即为 `[]`)。
|
||
- 本团期未建或团期起止不全:每行 `occupancyStatus=null`、`occupiedDays=0`、`freeRanges=[]`、`occupancies=[]`。
|
||
- 资源服务不可用:姓名手机回落快照、`liveInfoDegraded=true`(既有);本单新增的服务日期、日薪、占用字段照常返回,不依赖资源服务。
|
||
|
||
#### 错误响应
|
||
|
||
判权未改动(`group-batch:view`)。
|
||
|
||
```json
|
||
{
|
||
"code": 589507,
|
||
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 名册项**不含**等级、服务区域、擅长(这几列只在两个候选接口返回);名册要展示时从候选接口按 `staffId` 取。
|
||
- 占用比对用的日期段 = 这个人在本团的有效服务日期,先夹进本团当前起止;展示的 `serviceStartDate` / `serviceEndDate` 不夹。团期改期后旧的自定义日期越出团期时,名册照实显示越界日期,保存时会 582119。
|
||
- 占用来源口径见第六节;占用只提示不拦截。
|
||
|
||
### 3. 团期单人更换 `PUT /v3/admin/group-batch/{productBatchId}/staff/{staffId}/replace`
|
||
|
||
**VO**: `BatchStaffReplaceReqVO` → `BatchStaffReplaceRespVO`
|
||
|
||
#### 使用场景
|
||
|
||
名册表格某一行点「更换」,从候选里选一个新人替换原人。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| productBatchId | Path | Long | 是 | 产品侧排期 ID | 同名册接口(既有) |
|
||
| staffId | Path | Long | 是 | 须在本团名册中 | 被换下的人(既有) |
|
||
| newStaffId | Body | Long | 是 | 上架、类型符合原配置位、不在本团、不等于 `staffId` | 换上的人(既有) |
|
||
|
||
#### 出参 `Result<BatchStaffReplaceRespVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| productBatchId / groupBatchId | String | 回显 / 运营团期 ID(既有) |
|
||
| oldStaffId / newStaffId | Long | 被换下 / 换上的人员 ID(既有) |
|
||
| staffRole | String | 新人落库角色(既有) |
|
||
| reporterRank | String | 新人继承的报账人等级(既有) |
|
||
| primaryReporterTransferred | Boolean | 主报账人是否转给了新人(既有) |
|
||
| affectedOrderCount | Integer | 同步替换的活跃子订单数(既有) |
|
||
| staffList | Object[] | 更换后的整期名单(既有字段不变,`staffStatus`、`liveInfoDegraded` 为 null) |
|
||
| staffList[].serviceStartDate / serviceEndDate | String(yyyy-MM-dd) | **新增**。有效服务起止;新人沿用原人的服务日期 |
|
||
| staffList[].serviceDateCustom | Boolean | **新增**。是否自定义过服务日期 |
|
||
| staffList[].baseDailyWage | String | **新增**。基础日薪快照(新人取新人档案值),字符串;0 或空为 null |
|
||
| staffList[].occupancyStatus | String | **新增**。`FREE` / `PARTIAL` / `FULL`;本团期未建或团期起止不全时为 null |
|
||
| staffList[].occupiedDays | Integer | **新增**。被占天数 |
|
||
| staffList[].freeRanges | String[] | **新增**。可派日期段 `yyyy-MM-dd~yyyy-MM-dd` |
|
||
| staffList[].occupancies | Object[] | **新增**。占用明细,按 `startDate` 升序 |
|
||
| staffList[].occupancies[].sourceType / sourceId | String | `GROUP_BATCH` + 运营团期 ID,或 `ORDER` + 订单 ID |
|
||
| staffList[].occupancies[].refNo / title / statusName | String | 团期号或订单号 / 团期名称或产品名 / 来源状态中文名 |
|
||
| staffList[].occupancies[].staffRole / staffRoleName | String | 他在那边的角色及中文名 |
|
||
| staffList[].occupancies[].startDate / endDate | String(yyyy-MM-dd) | 他在那边的服务起止 |
|
||
| staffList[].occupancies[].overlapStartDate / overlapEndDate | String(yyyy-MM-dd) | 与本团服务日期段重叠的起止 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
PUT /v3/admin/group-batch/2104455374549721090/staff/1005/replace
|
||
Authorization: Bearer <admin token>
|
||
Content-Type: application/json
|
||
|
||
{ "newStaffId": 1007 }
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测:原人刘大山(主报账人,服务日期 10-27 ~ 10-28,日薪 1000)换成白云飞(档案日薪 800)。等级、备注、服务日期随位置转给新人,日薪取新人档案:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"productBatchId": "2104455374549721090",
|
||
"groupBatchId": "2104455377657724930",
|
||
"oldStaffId": 1005,
|
||
"newStaffId": 1007,
|
||
"staffRole": "LEADER",
|
||
"reporterRank": "PRIMARY",
|
||
"primaryReporterTransferred": true,
|
||
"affectedOrderCount": 1,
|
||
"staffList": [
|
||
{
|
||
"id": "2104456292880023553",
|
||
"staffId": 1007,
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"staffName": "白云飞",
|
||
"staffPhone": "139****1007",
|
||
"avatarUrl": null,
|
||
"sortOrder": 1,
|
||
"remark": "负责额尔古纳段",
|
||
"reporterRank": "PRIMARY",
|
||
"reporterRankName": "主报账人",
|
||
"staffStatus": null,
|
||
"liveInfoDegraded": null,
|
||
"serviceStartDate": "2026-10-27",
|
||
"serviceEndDate": "2026-10-28",
|
||
"serviceDateCustom": true,
|
||
"baseDailyWage": "800.00",
|
||
"occupancyStatus": "FREE",
|
||
"occupiedDays": 0,
|
||
"freeRanges": ["2026-10-27~2026-10-28"],
|
||
"occupancies": []
|
||
}
|
||
]
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
写接口,无空数据形态;任何校验失败都不写入。新人档案日薪为 0 或空时,新行 `baseDailyWage` 为 null。
|
||
|
||
#### 错误响应
|
||
|
||
以下 582119 按源码文案模板拼出(示意,测试服未造「团期改期后旧日期越界再更换」的数据):
|
||
|
||
```json
|
||
{
|
||
"code": 582119,
|
||
"message": "白云飞 的服务日期(2026-10-25 至 2026-10-28)不合法:开始日期不能晚于结束日期,且须在团期日期(2026-10-26 至 2026-10-28)之内",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
| code | 触发条件 |
|
||
|---|---|
|
||
| `582119` | **新增**。原人的自定义服务日期已不在团期起止内(团期改期后没重新保存);文案里是**新人**的名字;不写入。先在保存弹窗把这个位置的日期改到团期内,再换人 |
|
||
| `100001` / `589508` / `589582` | 新旧相同 / 原人不在本团 / 新人已在本团(既有) |
|
||
| `582103` / `582118` / `582114` | 资源库取不到新人 / 新人已下架 / 新人类型不符合配置位(既有) |
|
||
| `589553` / `589598` | 未建团 / 团期已确认或已取消(既有) |
|
||
|
||
#### 业务边界
|
||
|
||
- 服务日期跟位置走:新人原样沿用原人的服务日期(包括「跟随团期」)。
|
||
- 日薪跟人走:取新人服务人员档案的基础日薪(D1),不沿用原人的日薪。
|
||
- 排序、备注、报账人等级转给新人(既有)。
|
||
|
||
### 4. 团期单人删除 `DELETE /v3/admin/group-batch/{productBatchId}/staff/{staffId}`
|
||
|
||
**VO**: `BatchStaffRemoveRespVO`
|
||
|
||
#### 使用场景
|
||
|
||
名册表格某一行点「删除」,只移除这一个人。本单只给响应的 `staffList[]` 加字段,删除行为不变。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| productBatchId | Path | Long | 是 | 产品侧排期 ID | 同名册接口(既有) |
|
||
| staffId | Path | Long | 是 | 须在本团名册中 | 要删除的人(既有) |
|
||
|
||
#### 出参 `Result<BatchStaffRemoveRespVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| productBatchId / groupBatchId | String | 回显 / 运营团期 ID(既有) |
|
||
| removedStaffId | Long | 被删除的人员 ID(既有) |
|
||
| removedStaffRole | String | 被删除人员的角色(既有) |
|
||
| primaryReporterRemoved | Boolean | 删的是否是主报账人(既有) |
|
||
| affectedOrderCount | Integer | 同步删除副本的活跃子订单数(既有) |
|
||
| staffList | Object[] | 删除后的整期名单(既有字段不变,`staffStatus`、`liveInfoDegraded` 为 null) |
|
||
| staffList[].serviceStartDate / serviceEndDate | String(yyyy-MM-dd) | **新增**。有效服务起止(没自定义 = 团期起止) |
|
||
| staffList[].serviceDateCustom | Boolean | **新增**。是否自定义过服务日期 |
|
||
| staffList[].baseDailyWage | String | **新增**。基础日薪快照,字符串;0 或空为 null |
|
||
| staffList[].occupancyStatus | String | **新增**。`FREE` / `PARTIAL` / `FULL`;本团期未建或团期起止不全时为 null |
|
||
| staffList[].occupiedDays | Integer | **新增**。被占天数 |
|
||
| staffList[].freeRanges | String[] | **新增**。可派日期段 `yyyy-MM-dd~yyyy-MM-dd` |
|
||
| staffList[].occupancies | Object[] | **新增**。占用明细,按 `startDate` 升序 |
|
||
| staffList[].occupancies[].sourceType / sourceId | String | `GROUP_BATCH` + 运营团期 ID,或 `ORDER` + 订单 ID |
|
||
| staffList[].occupancies[].refNo / title / statusName | String | 团期号或订单号 / 团期名称或产品名 / 来源状态中文名 |
|
||
| staffList[].occupancies[].staffRole / staffRoleName | String | 他在那边的角色及中文名 |
|
||
| staffList[].occupancies[].startDate / endDate | String(yyyy-MM-dd) | 他在那边的服务起止 |
|
||
| staffList[].occupancies[].overlapStartDate / overlapEndDate | String(yyyy-MM-dd) | 与本团服务日期段重叠的起止 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
DELETE /v3/admin/group-batch/2104455356057034754/staff/1009
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测节选(班期 11-16 ~ 11-18;`staffList` 只保留两行;金额按当前契约写成字符串):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"productBatchId": "2104455356057034754",
|
||
"groupBatchId": "2104455358355509249",
|
||
"removedStaffId": 1009,
|
||
"removedStaffRole": "LEADER",
|
||
"primaryReporterRemoved": false,
|
||
"affectedOrderCount": 1,
|
||
"staffList": [
|
||
{
|
||
"id": "2104456120838062081",
|
||
"staffId": 1005,
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"staffName": "刘大山",
|
||
"staffPhone": "138****1005",
|
||
"sortOrder": 1,
|
||
"remark": "负责草原段带队",
|
||
"reporterRank": "PRIMARY",
|
||
"reporterRankName": "主报账人",
|
||
"staffStatus": null,
|
||
"liveInfoDegraded": null,
|
||
"serviceStartDate": "2026-11-16",
|
||
"serviceEndDate": "2026-11-16",
|
||
"serviceDateCustom": true,
|
||
"baseDailyWage": "1000.00",
|
||
"occupancyStatus": "FREE",
|
||
"occupiedDays": 0,
|
||
"freeRanges": ["2026-11-16~2026-11-16"],
|
||
"occupancies": []
|
||
},
|
||
{
|
||
"id": "2104456120838062082",
|
||
"staffId": 1002,
|
||
"staffRole": "GUIDE",
|
||
"staffRoleName": "导游",
|
||
"staffName": "李雪梅",
|
||
"staffPhone": "138****1002",
|
||
"sortOrder": 2,
|
||
"remark": null,
|
||
"reporterRank": "NONE",
|
||
"reporterRankName": "非报账人",
|
||
"staffStatus": null,
|
||
"liveInfoDegraded": null,
|
||
"serviceStartDate": "2026-11-16",
|
||
"serviceEndDate": "2026-11-18",
|
||
"serviceDateCustom": false,
|
||
"baseDailyWage": "600.00",
|
||
"occupancyStatus": "PARTIAL",
|
||
"occupiedDays": 1,
|
||
"freeRanges": ["2026-11-16~2026-11-17"],
|
||
"occupancies": [
|
||
{
|
||
"sourceType": "GROUP_BATCH",
|
||
"sourceId": "2104455369311031298",
|
||
"refNo": "Q202611182104455365389361153",
|
||
"title": "11月18日海拉尔-额尔古纳3日团",
|
||
"statusName": "招募中",
|
||
"staffRole": "GUIDE",
|
||
"staffRoleName": "导游",
|
||
"startDate": "2026-11-18",
|
||
"endDate": "2026-11-20",
|
||
"overlapStartDate": "2026-11-18",
|
||
"overlapEndDate": "2026-11-18"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
删光后 `staffList` 为 `[]`(既有)。本团期未建或团期起止不全时,名单项占用四字段为 `null` / `0` / `[]` / `[]`。
|
||
|
||
#### 错误响应
|
||
|
||
错误码未改动。
|
||
|
||
```json
|
||
{
|
||
"code": 589508,
|
||
"message": "报账人不是该团期已派员工",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 删除行为、错误码与判权(`group-batch:manage`)都未改,只是响应 `staffList[]` 多了字段。
|
||
- 删掉的人在其他团的占用计算里立即消失(已删除的配置行不算占用)。
|
||
|
||
### 5. 团期人员候选分页 `GET /v3/admin/group-batch/{productBatchId}/staff/candidates/page`
|
||
|
||
**VO**: `PageResult<StaffCandidateRespVO>`
|
||
|
||
#### 使用场景
|
||
|
||
「配导游」「配摄影」选人弹窗的人员列表(带关键词搜索、分页)。本单起每行可展示等级、服务区域、擅长、基础日薪和占用标签,点占用标签看 `occupancies` 明细与 `freeRanges`。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| productBatchId | Path | Long | 是 | 产品侧排期 ID | 取 `detail.productBatchId`(既有) |
|
||
| role | Query | String | 是 | `GUIDE` / `PHOTOGRAPHER` | 配置位;导游位并收导游与领队(既有) |
|
||
| keyword | Query | String | 否 | ≤50 字 | 姓名包含;纯数字另按手机号尾号匹配(既有) |
|
||
| page | Query | Integer | 否 | 缺省 1 | 页码(既有) |
|
||
| pageSize | Query | Integer | 否 | 缺省 20,最大 100 | 每页条数(既有) |
|
||
|
||
#### 出参 `Result<PageResult<StaffCandidateRespVO>>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| total / page / pageSize | Integer | 分页信息(既有) |
|
||
| records | Object[] | 候选项(既有字段 `productBatchId`、`groupBatchId`、`staffId`、`staffName`、`staffPhone`、`staffType`、`staffTypeName`、`avatarUrl`、`assigned`、`assignedRole`、`assignedRoleName`、`reporterRank`、`reporterRankName` 不变) |
|
||
| records[].level | String | **新增**。导游等级:`初级` / `中级` / `高级` / `特级`,档案里认不出的写法原样返回;未填为 null |
|
||
| records[].serviceAreas | String[] | **新增**。服务区域;未填为 `[]`,恒非 null |
|
||
| records[].specialties | String[] | **新增**。擅长;未填为 `[]`,恒非 null |
|
||
| records[].baseDailyWage | String | **新增**。服务人员档案的基础日薪,字符串如 `"600.00"`,仅供参考;未填或为 0 时为 null;前端运算前 `Number()` |
|
||
| records[].occupancyStatus | String | **新增**。`FREE` / `PARTIAL` / `FULL`,按**本团出发日到结束日**比对;本团期未建(`groupBatchId` 为 null)或团期起止不全时为 null |
|
||
| records[].occupiedDays | Integer | **新增**。本团日期段内被占天数(两端都算);`occupancyStatus` 为 null 时为 0 |
|
||
| records[].freeRanges | String[] | **新增**。可派日期段 `yyyy-MM-dd~yyyy-MM-dd`,升序;全程占用或 `occupancyStatus` 为 null 时为 `[]` |
|
||
| records[].occupancies | Object[] | **新增**。占用明细,按 `startDate` 升序;空闲或 `occupancyStatus` 为 null 时为 `[]` |
|
||
| records[].occupancies[].sourceType | String | `GROUP_BATCH` 其他团期的人员配置 / `ORDER` 普通订单上定制师直派 |
|
||
| records[].occupancies[].sourceId | String | `GROUP_BATCH` 为运营团期 ID,`ORDER` 为订单 ID |
|
||
| records[].occupancies[].refNo | String | 团期号 / 订单号;源数据为空时为 null |
|
||
| records[].occupancies[].title | String | 团期名称(为空时取产品名)/ 订单的产品名;都为空时为 null |
|
||
| records[].occupancies[].statusName | String | 来源当前状态中文名,如「招募中」「待支付」 |
|
||
| records[].occupancies[].staffRole / staffRoleName | String | 他在那边的角色及中文名(跨角色也计入占用) |
|
||
| records[].occupancies[].startDate / endDate | String(yyyy-MM-dd) | 他在那边的服务起止:团期为他在那个团的有效服务日期(自定义日期先夹进那个团当前起止);订单为出发日到返回日(返回日为空按出发日当天) |
|
||
| records[].occupancies[].overlapStartDate / overlapEndDate | String(yyyy-MM-dd) | 与本团日期段重叠的起止,两端都算,恒在本团日期段内 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /v3/admin/group-batch/2104455359768993795/staff/candidates/page?role=GUIDE&page=1&pageSize=20
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测节选(班期 11-17 ~ 11-19,共 7 人,只保留三行:本团已选 → 空闲 → 部分占用;金额按当前契约写成字符串):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"productBatchId": "2104455359768993795",
|
||
"groupBatchId": "2104455363380285441",
|
||
"staffId": 1007,
|
||
"staffName": "白云飞",
|
||
"staffPhone": "139****1007",
|
||
"staffType": "LEADER",
|
||
"staffTypeName": "领队",
|
||
"avatarUrl": null,
|
||
"assigned": true,
|
||
"assignedRole": "LEADER",
|
||
"assignedRoleName": "领队",
|
||
"reporterRank": "NONE",
|
||
"reporterRankName": "非报账人",
|
||
"level": null,
|
||
"serviceAreas": ["内蒙古", "新疆"],
|
||
"specialties": ["户外探险", "亲子活动", "草原穿越"],
|
||
"baseDailyWage": "800.00",
|
||
"occupancyStatus": "FREE",
|
||
"occupiedDays": 0,
|
||
"freeRanges": ["2026-11-17~2026-11-19"],
|
||
"occupancies": []
|
||
},
|
||
{
|
||
"productBatchId": "2104455359768993795",
|
||
"groupBatchId": "2104455363380285441",
|
||
"staffId": 1005,
|
||
"staffName": "刘大山",
|
||
"staffPhone": "138****1005",
|
||
"staffType": "LEADER",
|
||
"staffTypeName": "领队",
|
||
"avatarUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/test/material/2026/03/26/45d9abebc569ca7b7ab13cac212ca38a.png",
|
||
"assigned": false,
|
||
"assignedRole": null,
|
||
"assignedRoleName": null,
|
||
"reporterRank": null,
|
||
"reporterRankName": null,
|
||
"level": null,
|
||
"serviceAreas": ["内蒙古", "新疆", "青海", "甘肃", "西藏"],
|
||
"specialties": ["户外探险", "高原旅行", "沙漠旅行", "自驾越野"],
|
||
"baseDailyWage": "1000.00",
|
||
"occupancyStatus": "FREE",
|
||
"occupiedDays": 0,
|
||
"freeRanges": ["2026-11-17~2026-11-19"],
|
||
"occupancies": []
|
||
},
|
||
{
|
||
"productBatchId": "2104455359768993795",
|
||
"groupBatchId": "2104455363380285441",
|
||
"staffId": 1002,
|
||
"staffName": "李雪梅",
|
||
"staffPhone": "138****1002",
|
||
"staffType": "GUIDE",
|
||
"staffTypeName": "导游",
|
||
"avatarUrl": null,
|
||
"assigned": false,
|
||
"assignedRole": null,
|
||
"assignedRoleName": null,
|
||
"reporterRank": null,
|
||
"reporterRankName": null,
|
||
"level": "中级",
|
||
"serviceAreas": ["云南", "四川", "贵州"],
|
||
"specialties": ["民俗风情", "美食体验", "自然风光"],
|
||
"baseDailyWage": "600.00",
|
||
"occupancyStatus": "PARTIAL",
|
||
"occupiedDays": 2,
|
||
"freeRanges": ["2026-11-19~2026-11-19"],
|
||
"occupancies": [
|
||
{
|
||
"sourceType": "GROUP_BATCH",
|
||
"sourceId": "2104455358355509249",
|
||
"refNo": "Q202611162104455356057034753",
|
||
"title": "11月16日海拉尔-额尔古纳3日团",
|
||
"statusName": "招募中",
|
||
"staffRole": "GUIDE",
|
||
"staffRoleName": "导游",
|
||
"startDate": "2026-11-16",
|
||
"endDate": "2026-11-18",
|
||
"overlapStartDate": "2026-11-17",
|
||
"overlapEndDate": "2026-11-18"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"total": 7,
|
||
"page": 1,
|
||
"pageSize": 20
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
本团期还没建(班期有、团期无)时,`groupBatchId` 为 null,占用四字段为空值(测试服班期 11-26 实测节选):
|
||
|
||
```json
|
||
{
|
||
"productBatchId": "2104455372507095042",
|
||
"groupBatchId": null,
|
||
"staffId": 1002,
|
||
"staffName": "李雪梅",
|
||
"level": "中级",
|
||
"baseDailyWage": "600.00",
|
||
"occupancyStatus": null,
|
||
"occupiedDays": 0,
|
||
"freeRanges": [],
|
||
"occupancies": []
|
||
}
|
||
```
|
||
|
||
- 页码越界:`records` 为 `[]`,`total` 为真实总数(既有)。
|
||
- 资源服务不可用:返回 582103(见下)。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{
|
||
"code": 582103,
|
||
"message": "员工信息查询失败,请稍后重试",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
| code | 触发条件 |
|
||
|---|---|
|
||
| `582103` | 资源服务查询候选失败(既有码,本单起候选分页经资源服务新的排序分页查询取数) |
|
||
| `582113` | `role` 不是 `GUIDE` / `PHOTOGRAPHER`(既有) |
|
||
| `589507` | 无团期查看权限(既有) |
|
||
| `400` | `keyword` 超 50 字(既有) |
|
||
|
||
#### 业务边界
|
||
|
||
- **全局排序**:本团本位已选(即 `assigned=true`)→ 空闲 → 部分占用 → 全程占用;同组内按等级从高到低(特级 → 高级 → 中级 → 初级 → 未填)→ 人员 `sortOrder` 升序 → `staffId` 升序。先按同一筛选条件(类型、关键词)取全体候选排好再切页,逐页翻完不重不漏,与第 6 个接口的顺序一致。
|
||
- 本团期未建时没有占用分组,只有「本团本位已选」排最前,其余人按等级 → `sortOrder` → `staffId` 排(改前只按 `sortOrder`、`staffId`)。
|
||
- 本团其他配置位上的人(例如在导游位看摄影师)不算占用(本团自己不算),`assigned=false`,照常用 `assignedRole` 提示「已在其他位」。
|
||
- 占用只提示不拦截;本单不提供「只看空闲」筛选参数(D9)。
|
||
- 保存仍以 `GET .../staff` 为已选名单来源,不能只凭当前页勾选拼保存请求(既有)。
|
||
|
||
### 6. 团期人员候选列表 `GET /v3/admin/group-batch/{productBatchId}/staff/candidates`
|
||
|
||
**VO**: `List<StaffCandidateRespVO>`
|
||
|
||
#### 使用场景
|
||
|
||
旧的全量候选接口(不分页)。条目结构、占用口径、排序规则与候选分页完全一致。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| productBatchId | Path | Long | 是 | 产品侧排期 ID | 取 `detail.productBatchId`(既有) |
|
||
| role | Query | String | 是 | `GUIDE` / `PHOTOGRAPHER` | 配置位;导游位并收导游与领队(既有) |
|
||
|
||
#### 出参 `Result<List<StaffCandidateRespVO>>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| 既有字段 | - | `productBatchId`、`groupBatchId`、`staffId`、`staffName`、`staffPhone`、`staffType`、`staffTypeName`、`avatarUrl`、`assigned`、`assignedRole`、`assignedRoleName`、`reporterRank`、`reporterRankName` 不变 |
|
||
| level | String | **新增**。导游等级:`初级` / `中级` / `高级` / `特级`,认不出的写法原样返回;未填为 null |
|
||
| serviceAreas | String[] | **新增**。服务区域;未填为 `[]` |
|
||
| specialties | String[] | **新增**。擅长;未填为 `[]` |
|
||
| baseDailyWage | String | **新增**。档案基础日薪,字符串,仅供参考;未填或为 0 时为 null |
|
||
| occupancyStatus | String | **新增**。`FREE` / `PARTIAL` / `FULL`,按本团出发日到结束日比对;本团期未建或团期起止不全时为 null |
|
||
| occupiedDays | Integer | **新增**。被占天数;`occupancyStatus` 为 null 时为 0 |
|
||
| freeRanges | String[] | **新增**。可派日期段 `yyyy-MM-dd~yyyy-MM-dd`;全程占用或 null 状态时为 `[]` |
|
||
| occupancies | Object[] | **新增**。占用明细,按 `startDate` 升序 |
|
||
| occupancies[].sourceType / sourceId | String | `GROUP_BATCH` + 运营团期 ID,或 `ORDER` + 订单 ID |
|
||
| occupancies[].refNo / title / statusName | String | 团期号或订单号 / 团期名称或产品名 / 来源状态中文名 |
|
||
| occupancies[].staffRole / staffRoleName | String | 他在那边的角色及中文名 |
|
||
| occupancies[].startDate / endDate | String(yyyy-MM-dd) | 他在那边的服务起止 |
|
||
| occupancies[].overlapStartDate / overlapEndDate | String(yyyy-MM-dd) | 与本团日期段重叠的起止 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /v3/admin/group-batch/2104455359768993795/staff/candidates?role=GUIDE
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测节选(班期 11-17 ~ 11-19;陈志远只有 11-18 被占,可派日期被切成两段;李雪梅被两个招募中的团占满整段):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": [
|
||
{
|
||
"productBatchId": "2104455359768993795",
|
||
"groupBatchId": "2104455363380285441",
|
||
"staffId": 1009,
|
||
"staffName": "陈志远",
|
||
"staffPhone": "139****1009",
|
||
"staffType": "LEADER",
|
||
"staffTypeName": "领队",
|
||
"avatarUrl": null,
|
||
"assigned": false,
|
||
"assignedRole": null,
|
||
"assignedRoleName": null,
|
||
"reporterRank": null,
|
||
"reporterRankName": null,
|
||
"level": null,
|
||
"serviceAreas": ["内蒙古", "黑龙江", "吉林"],
|
||
"specialties": ["户外探险", "高原旅行", "冬季活动"],
|
||
"baseDailyWage": null,
|
||
"occupancyStatus": "PARTIAL",
|
||
"occupiedDays": 1,
|
||
"freeRanges": ["2026-11-17~2026-11-17", "2026-11-19~2026-11-19"],
|
||
"occupancies": [
|
||
{
|
||
"sourceType": "GROUP_BATCH",
|
||
"sourceId": "2104455358355509249",
|
||
"refNo": "Q202611162104455356057034753",
|
||
"title": "11月16日海拉尔-额尔古纳3日团",
|
||
"statusName": "招募中",
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"startDate": "2026-11-18",
|
||
"endDate": "2026-11-18",
|
||
"overlapStartDate": "2026-11-18",
|
||
"overlapEndDate": "2026-11-18"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"productBatchId": "2104455359768993795",
|
||
"groupBatchId": "2104455363380285441",
|
||
"staffId": 1002,
|
||
"staffName": "李雪梅",
|
||
"staffPhone": "138****1002",
|
||
"staffType": "GUIDE",
|
||
"staffTypeName": "导游",
|
||
"avatarUrl": null,
|
||
"assigned": false,
|
||
"assignedRole": null,
|
||
"assignedRoleName": null,
|
||
"reporterRank": null,
|
||
"reporterRankName": null,
|
||
"level": "中级",
|
||
"serviceAreas": ["云南", "四川", "贵州"],
|
||
"specialties": ["民俗风情", "美食体验", "自然风光"],
|
||
"baseDailyWage": "600.00",
|
||
"occupancyStatus": "FULL",
|
||
"occupiedDays": 3,
|
||
"freeRanges": [],
|
||
"occupancies": [
|
||
{
|
||
"sourceType": "GROUP_BATCH",
|
||
"sourceId": "2104455358355509249",
|
||
"refNo": "Q202611162104455356057034753",
|
||
"title": "11月16日海拉尔-额尔古纳3日团",
|
||
"statusName": "招募中",
|
||
"staffRole": "GUIDE",
|
||
"staffRoleName": "导游",
|
||
"startDate": "2026-11-16",
|
||
"endDate": "2026-11-18",
|
||
"overlapStartDate": "2026-11-17",
|
||
"overlapEndDate": "2026-11-18"
|
||
},
|
||
{
|
||
"sourceType": "GROUP_BATCH",
|
||
"sourceId": "2104455369311031298",
|
||
"refNo": "Q202611182104455365389361153",
|
||
"title": "11月18日海拉尔-额尔古纳3日团",
|
||
"statusName": "招募中",
|
||
"staffRole": "GUIDE",
|
||
"staffRoleName": "导游",
|
||
"startDate": "2026-11-18",
|
||
"endDate": "2026-11-20",
|
||
"overlapStartDate": "2026-11-18",
|
||
"overlapEndDate": "2026-11-19"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
- 资源库没有可用人员:`data: []`(既有)。
|
||
- 本团期未建:`groupBatchId` 为 null,每人 `occupancyStatus=null`、`occupiedDays=0`、`freeRanges=[]`、`occupancies=[]`。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{
|
||
"code": 582113,
|
||
"message": "人员配置位不合法,请检查配置位标识",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
| code | 触发条件 |
|
||
|---|---|
|
||
| `582113` | `role` 不是 `GUIDE` / `PHOTOGRAPHER`(既有) |
|
||
| `582103` | 资源服务查询候选失败(既有) |
|
||
| `589507` | 无团期查看权限(既有) |
|
||
|
||
#### 业务边界
|
||
|
||
- 排序与候选分页同一规则:本团本位已选 → 空闲 → 部分占用 → 全程占用 → 等级从高到低 → `sortOrder` 升序 → `staffId` 升序。
|
||
- 同一来源(同一个团期或同一张订单)即使有多行也只出一条明细;`occupiedDays` 按实际被占的日子算,重叠部分只算一次。
|
||
- 占用只提示不拦截。
|
||
|
||
### 7. 配导游芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/guide`
|
||
|
||
**VO**: `GroupBatchChipDetailVO`
|
||
|
||
#### 使用场景
|
||
|
||
团期详情「配导游」页签、看板点导游芯片弹出的明细。本单起只看团期名册 `staffList`,不再有逐户人员表。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| groupBatchId | Path | Long | 是 | 运营团期 ID | 路由上的团期 ID(既有) |
|
||
|
||
#### 出参 `Result<GroupBatchChipDetailVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| batchId / groupBatchId | String | 团期 ID(`batchId` 已废弃,同值;既有) |
|
||
| chipLabel | String | 芯片中文名(既有) |
|
||
| aggregateStatus / aggregateStatusName | String | 整团聚合态及中文名(既有,口径不变,仍按户计) |
|
||
| totalCount / doneCount | Integer | 计入统计的户数 / 已完成户数(既有,口径不变) |
|
||
| staffList | Object[] | 本团导游位(导游 + 领队)已配置人员(既有,内容不变);元素字段 `staffId`、`staffRole`、`staffRoleName`、`staffName`、`staffPhone`、`reporterRank`、`reporterRankName`、`source`、`sourceName` |
|
||
| items | Object[] | **取值变化**:恒为 `[]`,不再逐户返回(改前每户一行并带 `items[].staffs`) |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /v3/admin/order/group-batch/2104455358355509249/chips/guide
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"batchId": "2104455358355509249",
|
||
"groupBatchId": "2104455358355509249",
|
||
"chipLabel": "配导游",
|
||
"aggregateStatus": "TODO",
|
||
"aggregateStatusName": "待开始",
|
||
"totalCount": 0,
|
||
"doneCount": 0,
|
||
"staffList": [
|
||
{
|
||
"staffId": "1005",
|
||
"staffRole": "LEADER",
|
||
"staffRoleName": "领队",
|
||
"staffName": "刘大山",
|
||
"staffPhone": "138****1005",
|
||
"reporterRank": "PRIMARY",
|
||
"reporterRankName": "主报账人",
|
||
"source": null,
|
||
"sourceName": null
|
||
},
|
||
{
|
||
"staffId": "1002",
|
||
"staffRole": "GUIDE",
|
||
"staffRoleName": "导游",
|
||
"staffName": "李雪梅",
|
||
"staffPhone": "138****1002",
|
||
"reporterRank": "NONE",
|
||
"reporterRankName": "非报账人",
|
||
"source": null,
|
||
"sourceName": null
|
||
}
|
||
],
|
||
"items": []
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
未配置导游位人员时 `staffList: []`、`items: []`(改前 `items` 会列出每户,本单起恒为 `[]`)。
|
||
|
||
#### 错误响应
|
||
|
||
错误码未改动。
|
||
|
||
```json
|
||
{
|
||
"code": 589500,
|
||
"message": "团期不存在",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 判权未改(`group-batch:view`,无权限 589507)。
|
||
- `staffList` 不带服务日期、日薪、占用;需要这些时调 `GET /v3/admin/group-batch/{productBatchId}/staff`。
|
||
- 芯片聚合态(`aggregateStatus`、`totalCount`、`doneCount`)仍按户计算,本单不改;改按团期名册计算的口径见 #8469。
|
||
- 配房、配车、合同、保险四个芯片完全不变。
|
||
|
||
### 8. 配摄影芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/photo`
|
||
|
||
**VO**: `GroupBatchChipDetailVO`
|
||
|
||
#### 使用场景
|
||
|
||
团期详情「配摄影」页签、看板点摄影芯片弹出的明细。本单起只看团期名册 `staffList`,不再有逐户人员表。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| groupBatchId | Path | Long | 是 | 运营团期 ID | 路由上的团期 ID(既有) |
|
||
|
||
#### 出参 `Result<GroupBatchChipDetailVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| batchId / groupBatchId | String | 团期 ID(`batchId` 已废弃,同值;既有) |
|
||
| chipLabel | String | 芯片中文名(既有) |
|
||
| aggregateStatus / aggregateStatusName | String | 整团聚合态及中文名(既有,口径不变,仍按户计) |
|
||
| totalCount / doneCount | Integer | 计入统计的户数 / 已完成户数(既有,口径不变) |
|
||
| staffList | Object[] | 本团摄影位已配置人员(既有,内容不变);元素字段 `staffId`、`staffRole`、`staffRoleName`、`staffName`、`staffPhone`、`reporterRank`、`reporterRankName`、`source`、`sourceName` |
|
||
| items | Object[] | **取值变化**:恒为 `[]`,不再逐户返回(改前每户一行并带 `items[].staffs`) |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /v3/admin/order/group-batch/2104455358355509249/chips/photo
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"batchId": "2104455358355509249",
|
||
"groupBatchId": "2104455358355509249",
|
||
"chipLabel": "配摄影",
|
||
"aggregateStatus": "TODO",
|
||
"aggregateStatusName": "待开始",
|
||
"totalCount": 0,
|
||
"doneCount": 0,
|
||
"staffList": [
|
||
{
|
||
"staffId": "1003",
|
||
"staffRole": "PHOTOGRAPHER",
|
||
"staffRoleName": "摄影",
|
||
"staffName": "王强",
|
||
"staffPhone": "138****1003",
|
||
"reporterRank": "NONE",
|
||
"reporterRankName": "非报账人",
|
||
"source": null,
|
||
"sourceName": null
|
||
}
|
||
],
|
||
"items": []
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
未配置摄影位人员时 `staffList: []`、`items: []`(改前 `items` 会列出每户,本单起恒为 `[]`)。
|
||
|
||
#### 错误响应
|
||
|
||
错误码未改动。
|
||
|
||
```json
|
||
{
|
||
"code": 589507,
|
||
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 判权未改(`group-batch:view`);团期不存在 589500(既有)。
|
||
- `staffList` 不带服务日期、日薪、占用;需要这些时调 `GET /v3/admin/group-batch/{productBatchId}/staff`。
|
||
- 芯片聚合态仍按户计算,本单不改;改按团期名册计算的口径见 #8469。
|
||
|
||
### 9. 新建服务人员 `POST /admin/staff`
|
||
|
||
**VO**: `StaffCreateRequest` → `StaffVO`
|
||
|
||
#### 使用场景
|
||
|
||
服务人员管理「新建」弹窗保存。本单起「基础日薪」输入框的值会保存(改前填了不保存)。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| name | Body | String | 是 | ≤100 字 | 姓名(既有) |
|
||
| staffType | Body | String | 是 | 人员类型字典 | 人员类型(既有) |
|
||
| basePrice | Body | Number | 否 | ≥0;最多 8 位整数、2 位小数 | **新增**。基础日薪(元/天);不传按 0 保存(= 没填) |
|
||
|
||
其余字段与改前一致。
|
||
|
||
#### 出参 `Result<StaffVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| basePrice | String | **新增**。基础日薪,按库值原样返回的字符串,如 `"650.00"`;没填为 `"0.00"`(不是 null)。回填数字输入框用 `Number(basePrice)` |
|
||
| 其余字段 | - | 与改前一致 |
|
||
|
||
#### 请求示例
|
||
|
||
```json
|
||
{
|
||
"name": "孟和巴雅尔",
|
||
"staffType": "LEADER",
|
||
"gender": 1,
|
||
"serviceAreas": ["内蒙古"],
|
||
"specialties": ["草原穿越"],
|
||
"basePrice": 650,
|
||
"description": "熟悉呼伦贝尔草原线路,常带亲子团"
|
||
}
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测节选(验收后已软删;金额按当前契约写成字符串):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"staffId": "2104454928988823553",
|
||
"name": "孟和巴雅尔",
|
||
"staffType": "LEADER",
|
||
"specialties": ["草原穿越"],
|
||
"serviceAreas": ["内蒙古"],
|
||
"basePrice": "650.00",
|
||
"sortOrder": 0,
|
||
"status": 0
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
写接口,无空数据形态。不传 `basePrice` 时按 0 保存,详情与列表返回 `"0.00"`。
|
||
|
||
#### 错误响应
|
||
|
||
与编辑接口同一组校验(测试服在编辑接口实测):
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "基础日薪不能为负数",
|
||
"data": null,
|
||
"traceId": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
| code | 触发条件 |
|
||
|---|---|
|
||
| `400` | `basePrice` 为负数(「基础日薪不能为负数」);超过 8 位整数或 2 位小数(「基础日薪最多8位整数、2位小数」) |
|
||
|
||
#### 业务边界
|
||
|
||
- 判权与审批上架流程未改。
|
||
- 校验失败不写入。
|
||
- 团期选人时取的就是这里保存的基础日薪(0 视为没填,团期侧显示 null)。
|
||
|
||
### 10. 编辑服务人员 `PUT /admin/staff/{staffId}`
|
||
|
||
**VO**: `StaffUpdateRequest` → `StaffVO`
|
||
|
||
#### 使用场景
|
||
|
||
服务人员管理「编辑」弹窗保存。弹窗打开时用详情接口回显 `Number(basePrice)`,保存时把数值传回。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| staffId | Path | Long | 是 | - | 人员 ID(既有) |
|
||
| basePrice | Body | Number | 否 | ≥0;最多 8 位整数、2 位小数 | **新增**。基础日薪(元/天);**不传不改**原值;传 0 = 清成没填 |
|
||
|
||
其余字段与改前一致(均为不传不改)。
|
||
|
||
#### 出参 `Result<StaffVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| basePrice | String | **新增**。保存后的基础日薪字符串,如 `"800.00"`;没填为 `"0.00"` |
|
||
| 其余字段 | - | 与改前一致 |
|
||
|
||
#### 请求示例
|
||
|
||
```json
|
||
{ "basePrice": 800 }
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测节选(金额按当前契约写成字符串):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"staffId": "1007",
|
||
"name": "白云飞",
|
||
"phone": "139****1007",
|
||
"staffType": "LEADER",
|
||
"basePrice": "800.00",
|
||
"sortOrder": 90,
|
||
"status": 1
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
写接口,无空数据形态。请求不带 `basePrice`(如 `{ "sortOrder": 90 }`)时原值不变,测试服实测保持 800。
|
||
|
||
#### 错误响应
|
||
|
||
测试服实测:
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "基础日薪最多8位整数、2位小数",
|
||
"data": null,
|
||
"traceId": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
| code | 触发条件 |
|
||
|---|---|
|
||
| `400` | `basePrice=-1` →「基础日薪不能为负数」;`basePrice=12.345` →「基础日薪最多8位整数、2位小数」;均不写入 |
|
||
|
||
#### 业务边界
|
||
|
||
- 不传不改:只提交部分字段的调用方不会把日薪清掉。
|
||
- 改了档案日薪后,已经选进团期的人日薪快照**不刷新**;之后新选、或更换进来的人才取新值(D1)。
|
||
- 判权未改。
|
||
|
||
### 11. 服务人员详情 `GET /admin/staff/{staffId}`
|
||
|
||
**VO**: `StaffVO`
|
||
|
||
#### 使用场景
|
||
|
||
服务人员详情页、编辑弹窗回显。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| staffId | Path | Long | 是 | - | 人员 ID(既有) |
|
||
|
||
#### 出参 `Result<StaffVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| basePrice | String | **新增**。基础日薪字符串,按库值原样返回,如 `"600.00"`;没填为 `"0.00"`(不是 null) |
|
||
| 其余字段 | - | 与改前一致 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /admin/staff/1007
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
测试服实测节选(1007 验收后已恢复为没填;金额为字符串):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"staffId": "1007",
|
||
"name": "白云飞",
|
||
"phone": "139****1007",
|
||
"staffType": "LEADER",
|
||
"guideLevel": null,
|
||
"serviceAreas": ["内蒙古", "新疆"],
|
||
"specialties": ["户外探险", "亲子活动", "草原穿越"],
|
||
"basePrice": "0.00",
|
||
"sortOrder": 90,
|
||
"status": 1
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
没填日薪的人 `basePrice` 为 `"0.00"`,前端按「未填」展示即可。
|
||
|
||
#### 错误响应
|
||
|
||
错误码未改动(人员不存在时 HTTP 200 + 业务码 404):
|
||
|
||
```json
|
||
{
|
||
"code": 404,
|
||
"message": "服务人员不存在",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 详情返回库里的原值(0 就是 `"0.00"`);团期侧把 0 视为没填、返回 null,两处口径不同是有意的。
|
||
- 判权未改。
|
||
|
||
### 12. 服务人员列表 `GET /admin/staff/list`
|
||
|
||
**VO**: `PageResult<StaffAdminListVO>`
|
||
|
||
#### 使用场景
|
||
|
||
服务人员管理列表页。本单起每条记录带 `basePrice`,列表可恢复「基础日薪」列。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| keyword | Query | String | 否 | - | 姓名 / 描述模糊匹配(既有) |
|
||
| staffType | Query | String | 否 | - | 人员类型筛选(既有) |
|
||
| status | Query | Integer | 否 | 0 / 1 | 下架 / 上架(既有) |
|
||
| page | Query | Integer | 否 | ≥1,缺省 1 | 页码(既有) |
|
||
| pageSize | Query | Integer | 否 | 1~100,缺省 20 | 每页条数(既有) |
|
||
|
||
#### 出参 `Result<PageResult<StaffAdminListVO>>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| records[].basePrice | String | **新增**。基础日薪字符串,按库值原样返回,如 `"1000.00"`;没填为 `"0.00"` |
|
||
| records[] 其余字段 | - | 与改前一致 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /admin/staff/list?staffType=LEADER&page=1&pageSize=20
|
||
Authorization: Bearer <admin token>
|
||
```
|
||
|
||
无请求体。
|
||
|
||
#### 响应示例
|
||
|
||
2026-09-28 测试服实测节选:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"staffId": "1005",
|
||
"name": "刘大山",
|
||
"staffType": "LEADER",
|
||
"phone": "138****1005",
|
||
"basePrice": "1000.00",
|
||
"sortOrder": 95,
|
||
"status": 1,
|
||
"supplierFullName": "陈巴尔虎旗天下草原旅游服务有限"
|
||
},
|
||
{
|
||
"staffId": "1007",
|
||
"name": "白云飞",
|
||
"staffType": "LEADER",
|
||
"phone": "139****1007",
|
||
"basePrice": "0.00",
|
||
"sortOrder": 90,
|
||
"status": 1
|
||
}
|
||
]
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
无匹配记录时 `records: []`(既有)。没填日薪的人 `basePrice` 为 `"0.00"`。
|
||
|
||
#### 错误响应
|
||
|
||
参数校验错误码未改动:
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "页码不能小于1",
|
||
"data": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 列表排序、筛选、判权都未改,只多了 `basePrice`。
|
||
- `basePrice` 是字符串,排序或求和前先 `Number()`。
|
||
|
||
---
|
||
|
||
## 四、契约约束与正确调用方式
|
||
|
||
### ✅ 正确 / ❌ 错误 payload 对照(保存团期人员配置)
|
||
|
||
| 场景 | payload(`staffList[]` 单项) | 结果 |
|
||
|------|---------|------|
|
||
| ✅ 前端现有写法,保留的人只传三项 | `{ "staffId": 1005, "staffRole": "LEADER", "sortOrder": 1 }` | 沿用原报账人等级、备注、服务日期、日薪 |
|
||
| ✅ 自定义服务日期 | `{ "staffId": 1008, "staffRole": "LEADER", "sortOrder": 2, "serviceStartDate": "2026-11-18", "serviceEndDate": "2026-11-18" }` | 落为自定义,`serviceDateCustom=true` |
|
||
| ✅ 改回跟随团期 | 传团期起止本身,如团期 11-17 ~ 11-19 时 `"serviceStartDate": "2026-11-17", "serviceEndDate": "2026-11-19"` | 按跟随团期处理,`serviceDateCustom=false` |
|
||
| ✅ 清空备注 | `{ ..., "remark": "" }` | 备注清空 |
|
||
| ⚠️ 想清空备注却传 null 或不传 | `{ ..., "remark": null }` | 保留下来的人**沿用原备注**(不会清空) |
|
||
| ⚠️ 想改回跟随团期却不传日期 | `{ "staffId": 1008, "staffRole": "LEADER" }` | 保留下来的人**沿用原自定义日期** |
|
||
| ❌ 开始晚于结束 | `"serviceStartDate": "2026-11-19", "serviceEndDate": "2026-11-18"` | 582119,整批不写入 |
|
||
| ❌ 越出团期 | 团期 11-17 ~ 11-19 时 `"serviceStartDate": "2026-11-16"` | 582119,整批不写入 |
|
||
| ➖ 带日薪 | `{ ..., "baseDailyWage": 9999 }` | 不报错,但被忽略;日薪取档案值 |
|
||
|
||
### 金额字段
|
||
|
||
- `baseDailyWage`(团期名册、候选)与 `basePrice`(服务人员管理详情、列表、新建与编辑响应)都是 JSON 字符串,如 `"600.00"`。展示可直接用;运算、比较、回填数字输入框前 `Number()`。
|
||
- 团期侧 `baseDailyWage` 为 null 表示「档案没填日薪」;服务人员管理侧 `basePrice` 为 `"0.00"` 表示同一件事。
|
||
- 服务人员新建 / 编辑的请求体里 `basePrice` 传数字即可(如 `800`)。
|
||
|
||
### 前端交接清单
|
||
|
||
1. **选人弹窗(候选分页 / 候选列表)**:每行展示等级 `level`、服务区域 `serviceAreas`、擅长 `specialties`、基础日薪 `baseDailyWage`(标「参考」),以及占用标签(`FREE` 空闲 / `PARTIAL` 部分占用 / `FULL` 全程占用)和被占天数 `occupiedDays`;`occupancyStatus` 为 null(团期未建)时不显示占用标签。列表顺序直接用接口顺序,不要在前端重排。
|
||
2. **占用明细弹层**:点占用标签弹出 `occupancies[]`(来源类型 `sourceType`、团期号或订单号 `refNo`、名称 `title`、状态 `statusName`、角色 `staffRoleName`、他那边的服务起止 `startDate`~`endDate`、与本团重叠的起止 `overlapStartDate`~`overlapEndDate`)和可派日期段 `freeRanges`。
|
||
3. **保存弹窗**:每个人可编辑服务开始 / 结束日期(不填 = 跟随团期),基础日薪只读展示。回显用名册的 `serviceStartDate` / `serviceEndDate` / `serviceDateCustom`;把自定义日期改回跟随团期时提交团期起止本身(不传会沿用原值);收到 582119 直接展示接口文案(带人名)。有占用不需要二次确认(D5)。
|
||
4. **已配置人员名册**:可加服务日期、基础日薪、占用标签三列(字段见接口 2)。
|
||
5. **服务人员管理**:编辑框回显用 `Number(row.basePrice)`(出参是字符串);列表恢复「基础日薪」列,`"0.00"` 按未填展示。
|
||
6. **团期详情导游 / 摄影页签、看板导 / 摄芯片弹层**:去掉逐户人员表(`items` 恒为 `[]`)及其「共 N 户计入」汇总行,只展示团期名册 `staffList`。
|
||
7. **本单不做**:「只看空闲」筛选(D9);导 / 摄芯片状态颜色口径另见 #8469,本单不改。
|
||
|
||
### 服务间内部接口(前端不可调)
|
||
|
||
资源服务的 `/internal/staff/...` 系列接口也随本单加了字段,并新增 `POST /internal/staff/page-available`(候选分页的全局排序由它完成)。这些接口不经网关,前端无需关注;候选分页在资源服务不可用时返回 582103。
|
||
|
||
---
|
||
|
||
## 五、数据库行为
|
||
|
||
| 前端动作 | 可观察到的存储结果 |
|
||
|----------|---------------------|
|
||
| 保存时服务日期不传 / 与团期起止相同 | 按「跟随团期」存,名册返回团期起止,`serviceDateCustom=false`,团期改期后跟着变 |
|
||
| 保存时服务日期自定义 | 原样保存,`serviceDateCustom=true`,团期改期后不变 |
|
||
| 保存 / 更换选人 | 基础日薪快照在选人那一刻从服务人员档案带出并保存;档案之后再改,快照不变 |
|
||
| 保存返回 582119 | 整批不写入,名册前后一致(测试服前后比对) |
|
||
| 服务人员新建 / 编辑带 `basePrice` | 档案基础日薪保存;编辑不传不改;新建不传为 0 |
|
||
|
||
- 存量团期人员配置:服务日期全部视为「跟随团期」,基础日薪快照为 null;下次保存这些人时会补取一次档案当前日薪。
|
||
- 查询接口只读。
|
||
|
||
---
|
||
|
||
## 六、边界行为
|
||
|
||
- **占用来源(D3 / D7)**:
|
||
- 计入:其他团期里这个人的有效配置(含招募中团期;在那个团当任何角色都算);普通订单(不属于任何团期)上定制师直接派的人(未取消的订单,任何订单状态都算)。
|
||
- 不计:本团自己;已取消的团期(含流团);出发日或结束日为空的团期;已删除的配置;团期同步到子订单的人员副本;车务派车的司机;已取消的订单;没有出发日的订单。
|
||
- **日期段**:候选接口用本团出发日到结束日;名册(及保存、更换、删除响应)用这个人在本团的有效服务日期,先夹进本团当前起止。其他团的自定义服务日期同样先夹进那个团当前起止,完全越界时按那个团整段算。订单用出发日到返回日,返回日为空按出发日一天。
|
||
- **两端都算(D4)**:首尾相接那一天算占用。测试服实测:本团 11-18 ~ 11-20,另一团 11-16 ~ 11-18,重叠 1 天(11-18)。
|
||
- **三档(D8)**:被占 0 天 → `FREE`;被占满整段 → `FULL`;其余 → `PARTIAL`。守恒:`FREE` ⇔ `occupiedDays=0` ⇔ `occupancies` 为空;`FULL` ⇔ `freeRanges` 为空;`occupiedDays` + 可派天数 = 日期段天数。
|
||
- **多段**:多条占用重叠部分只算一次;被占日子在中间时可派日期切成两段。
|
||
- **只提示不拦截(D5)**:有占用照样能保存。
|
||
- **未建团期**:候选能查、团期还没有是正常态,占用四字段为 `null` / `0` / `[]` / `[]`。
|
||
- **未登录**:网关拦截返回 401(既有)。
|
||
- **向后兼容**:团期侧全部为新增字段,旧前端不读也不报错;例外见六.6 的 `items` 与 `remark` 两处行为变化。
|
||
|
||
---
|
||
|
||
## 六.5、枚举 / 数据字典
|
||
|
||
### occupancyStatus(常量定义于 `com.hulalv.order.assignment.helper.StaffOccupancyCalculator`)
|
||
|
||
**所属字段**: `BatchStaffItemVO.occupancyStatus`、`StaffCandidateRespVO.occupancyStatus` | **类型**: `String`
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| `FREE` | 空闲 | 日期段内被占 0 天 |
|
||
| `PARTIAL` | 部分占用 | 被占天数大于 0 且小于日期段天数 |
|
||
| `FULL` | 全程占用 | 日期段每一天都被占 |
|
||
| `null` | - | 本团期未建或团期起止不全,算不出 |
|
||
|
||
### occupancies[].sourceType(常量定义于 `com.hulalv.order.assignment.helper.StaffOccupancyCalculator`)
|
||
|
||
**所属字段**: `StaffOccupancyItemVO.sourceType` | **类型**: `String`
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| `GROUP_BATCH` | 团期 | 其他团期的人员配置;`sourceId` 为运营团期 ID,`refNo` 为团期号 |
|
||
| `ORDER` | 订单 | 普通订单上定制师直派;`sourceId` 为订单 ID,`refNo` 为订单号 |
|
||
|
||
### level(`com.hulalv.resource.staff.constant.StaffGuideLevel`)
|
||
|
||
**所属字段**: `StaffCandidateRespVO.level` | **类型**: `String`
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| `特级` | 特级 | 排序最高 |
|
||
| `高级` | 高级 | - |
|
||
| `中级` | 中级 | - |
|
||
| `初级` | 初级 | 已知等级中排最后 |
|
||
| 其他原样值 / null | - | 档案写法认不出时原样返回;未填为 null;都排在已知等级之后 |
|
||
|
||
### occupancies[].statusName
|
||
|
||
**所属字段**: `StaffOccupancyItemVO.statusName` | **类型**: `String`(中文名,不是编码)
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| 团期来源 | 招募中 / 资源准备中 / 物料准备中 / 待出发 / 出行中 / 出行完毕 / 核单中 / 已结算 | 团期当前状态(已取消的团期不计入,不会出现) |
|
||
| 订单来源 | 待支付 / 定制中 / 待出行 / 出行中 / 已完成 | 订单当前状态(已取消的订单不计入,不会出现) |
|
||
|
||
---
|
||
|
||
## 六.6、修改前后对比
|
||
|
||
### 字段级对比
|
||
|
||
| 字段 | 改前 | 改后 |
|
||
|------|------|------|
|
||
| 名册 / 保存 / 更换 / 删除响应的人员项 | 无服务日期、日薪、占用 | 新增 `serviceStartDate`、`serviceEndDate`、`serviceDateCustom`、`baseDailyWage`、`occupancyStatus`、`occupiedDays`、`freeRanges`、`occupancies` |
|
||
| 保存请求 `staffList[]` | 无日期字段 | 新增可选 `serviceStartDate`、`serviceEndDate` |
|
||
| 候选项 | 只有姓名、手机、类型等 | 新增 `level`、`serviceAreas`、`specialties`、`baseDailyWage` 与四个占用字段 |
|
||
| 导 / 摄芯片 `items` | 每户一行,带 `items[].staffs` | 恒为 `[]` |
|
||
| 服务人员 `basePrice` | 请求传了不保存,响应不返回 | 可保存;详情、列表、新建与编辑响应返回字符串 |
|
||
|
||
### 行为级对比
|
||
|
||
| 行为 | 改前 | 改后 |
|
||
|------|------|------|
|
||
| 保存导游位(前端只传三项) | 主报账人被打回非报账人、备注被清空 | 沿用原等级、备注、服务日期、日薪 |
|
||
| 保存时 `remark` 不传 | 清空备注 | 保留下来的人沿用原备注;要清空传 `""` |
|
||
| 候选排序 | 资源库原顺序(`sortOrder`、`staffId`) | 本团本位已选 → 空闲 → 部分占用 → 全程占用 → 等级 → `sortOrder` → `staffId` |
|
||
| 服务日期不合法 | 无此校验 | 582119,整批不写入 |
|
||
| 更换人员 | 新人不带服务日期、日薪 | 新人沿用原人服务日期,日薪取新人档案 |
|
||
| 导 / 摄页签逐户表 | 每户显示分到的人 | 不再提供,只看团期名册 |
|
||
|
||
---
|
||
|
||
## 六.7、影响评估
|
||
|
||
- **是否破坏向后兼容**: 部分。团期侧与服务人员管理都是新增字段;有两处行为变化:①导 / 摄芯片 `items` 恒为 `[]`,旧页面的逐户人员表会变空;②保存时 `remark` 不传不再清空备注。候选顺序也变了(接口顺序即展示顺序)。
|
||
- **前端是否必须同步上线**: 否。新字段不读不会报错;逐户表变空只影响展示,按交接清单第 6 项去掉即可。
|
||
- **前端 workaround 清理点**: 如果前端为规避「保存后主报账人丢失」在保存后补调过设置报账人接口,可以删掉;导 / 摄页签里按 `items[].staffs` 渲染的「人员」列与「共 N 户计入」汇总行可以删掉。
|
||
|
||
---
|
||
|
||
## 七、不影响范围
|
||
|
||
- **仅影响**: 团期人员配置的保存 / 名册 / 更换 / 删除 / 两个候选接口,导 / 摄两个芯片明细,服务人员管理新建 / 编辑 / 详情 / 列表。
|
||
- **零影响**:
|
||
- 设置报账人等级 `PUT /v3/admin/group-batch/{productBatchId}/staff/{staffId}/reporter-rank`
|
||
- 配房、配车、合同、保险四个芯片明细与看板聚合
|
||
- 订单侧人员接口(`/v3/admin/order/{orderId}/staff`)与团期同步到子订单的人员副本
|
||
- 出团通知书里的人员默认值
|
||
- 核团费用(本单不用「日薪 × 服务天数」预填)
|
||
- 服务人员价格日历
|
||
|
||
---
|
||
|
||
## 八、测试环境已验证
|
||
|
||
- **环境**:TEST,`hl-resource-service` 与 `hl-order-service-v3` 均为 dev-v3 `623c932bd`(含 `bf65803b7` 与 `623c932bd` 两次合入;resource 14:28、order-v3 14:31 双实例滚动完成,先 resource 后 order-v3)。
|
||
- **方式**:经网关 `https://api.test.1814.love`,真实 admin token;每批取证前做构建身份探针(候选响应含 `occupancyStatus` 等新键),5 次全部命中。手机号均为接口脱敏值。
|
||
- **造数**:五个班期(A 11-16、B 11-17、C 11-18、D 11-26 未建团期、E 10-26)与两张普通订单;验收后配置清空、团期流团、订单取消,新建人员已软删,1007 基础日薪已恢复为 0。
|
||
|
||
| AC | 检验点 | 结果 | 证据 |
|
||
|----|--------|------|------|
|
||
| 1 | `basePrice` 编辑 800 后详情 / 列表都为 800;再次编辑不带 `basePrice` 仍 800;-1、12.345 返回 400 且库值不变;新建带 650 → 650 | ✅ | 会话证据 accept/AC-1.json |
|
||
| 3 | 候选带等级、服务区域、擅长、日薪;档案为 0 返回 null,1005 为 1000 | ✅ | accept/AC-3.json |
|
||
| 6 | 新选 1007 日薪 800、1008 为 null;请求夹 `baseDailyWage=9999` 不生效;档案改回 0 后再保存,已有 800 快照不刷新 | ✅ | accept/AC-6.json |
|
||
| 7 | 1005 设为主报账人、备注「负责草原段带队」,用前端现有请求体(只含 `staffId`/`staffRole`/`sortOrder`)重存导游位:仍为主报账人,备注、日薪、1009 的自定义日期都保留 | ✅ | accept/AC-7.json |
|
||
| 8 | 不传存为跟随团期且名册返回团期起止、`serviceDateCustom=false`;与团期起止相同同样跟随;自定义 → `true`;开始晚于结束 / 早于团期 / 晚于团期 → 582119,文案含「萨仁高娃」,名册前后一致 | ✅ | accept/AC-8.json |
|
||
| 9 | E 团 1005 → 1007:沿用 10-27 ~ 10-28,日薪 800,等级与备注随之转移 | ✅ | accept/AC-9.json |
|
||
| 10 | 产品侧把 C 改期到 11-19 后,团期变为 11-19 ~ 11-21,1002 名册日期随之变化 | ✅ | accept/AC-10.json |
|
||
| 11 | 名册与两个候选接口字段齐全,占用明细 11 个字段齐全;未建团期的班期 D 候选占用为 null / 0 / [] / [] | ✅ | accept/AC-11.json |
|
||
| 12 | 重叠 2 天、首尾相接 1 天、招募中算、本团不算、缩短日期后不算、删除后不算、流团后不算、多段合并、中间切两段、普通订单直派算、取消订单后不算、跨角色(订单上当摄影)算、团期副本不重复算 | ✅ | accept/AC-12.json |
|
||
| 13 | E 团派已被普通订单占用的 1005,保存成功,名册显示部分占用 | ✅ | accept/AC-13.json |
|
||
| 15 | A / B / C / E 四团每页 2 条翻完:本团已选 → 空闲 → 部分 → 全程 → 等级 → `sortOrder`,与全量接口一致,`total` 不变 | ✅ | accept/AC-15.json |
|
||
| 16 | A 团导游 / 摄影芯片 `items=[]`、`staffList` 有人;配房、配车芯片照常逐户返回 | ✅ | accept/AC-16.json |
|
||
| 18 | #8476 合入后复验:候选 `baseDailyWage` 为 `"600.00"` / `"1000.00"`;人员详情与列表 `basePrice` 为 `"600.00"` / `"0.00"`(字符串) | ✅ | accept/AC-18-wage-string.json |
|
||
|
||
说明:本文各响应示例取自 AC-6 ~ AC-16 的实测响应(取证时金额字段仍为数字),示例里的金额已按 AC-18 复验过的字符串形态书写,其余字段为原值。「司机行不算」在测试服造不出司机来源数据,由真库单测覆盖。
|
||
|
||
---
|
||
|
||
## 九、相关历史 PR
|
||
|
||
| PR | Issue | 说明 | 是否仍有效 |
|
||
|----|-------|------|------------|
|
||
| #7831 | #7827 | 团期人员候选分页与模糊搜索 | ✅ 有效(本单改了排序与条目字段) |
|
||
| #7856 | #7853 | 导 / 摄芯片带出 `staffList` 与逐户 `items[].staffs` | ⚠️ `staffList` 有效;逐户人员已被本单撤掉 |
|
||
| #8357 | #8354 | 名册实时姓名手机、单人删除 / 更换 | ✅ 有效(本单给响应加字段、更换沿用服务日期) |
|
||
| **#8475** | **#8468** | 本单主体 | ✅ 最新 |
|
||
| **#8476** | **#8468** | 金额字段改字符串输出 | ✅ 最新 |
|
||
|
||
---
|
||
|
||
## 十、相关文档
|
||
|
||
- 工单 #8468: https://git.1814.love/wx/HL/issues/8468
|
||
- 导 / 摄芯片状态改按团期名册计算:https://git.1814.love/wx/HL/issues/8469
|
||
- 团期人员配置二期改表:https://git.1814.love/wx/HL/issues/8258
|
||
|
||
---
|
||
|
||
## 关联 / 联系人
|
||
|
||
### 链接
|
||
|
||
- **Issue**: [#8468](https://git.1814.love/wx/HL/issues/8468)
|
||
- **PR**: [#8475](https://git.1814.love/wx/HL/pulls/8475)、[#8476](https://git.1814.love/wx/HL/pulls/8476)
|
||
- **Merge commit**: [bf65803b7](https://git.1814.love/wx/HL/commit/bf65803b7)、[623c932bd](https://git.1814.love/wx/HL/commit/623c932bd)
|
||
|
||
### 联系人
|
||
|
||
- **后端负责人**: @jw
|