84 行
3.5 KiB
Markdown
84 行
3.5 KiB
Markdown
# 【新增接口·管理后台】司机档案——车管一键批量续签(换季)
|
||
|
||
> 服务:hl-fleet-service(8087) | 分支:dev-v3 | PR:#3699 | 已部署测试服并实测通过(2026-06-11)
|
||
> 契约出处:FLEET API §3.7 | 前端触发位:司机档案列表页「批量续签」按钮(换季时用)
|
||
|
||
## ⚠️ 关键说明
|
||
|
||
1. **一键换季动作**:把指定司机(或全部在册 `season=active` 司机)批量转入续签流程——`active → pending` + 为每人生成续签 H5 邀请链接/二维码。**链接需车管手动转发给司机**(本期无自动推送)。
|
||
2. **非在册司机不报错**:`pending/archived/blacklist` 的司机自动跳过,进 `skipped[]` 给原因,不中断整批。
|
||
3. `renewSeasonLabel` 必填但**不落库**,仅入审计日志;`remark` 同理。
|
||
4. 防双击:同参数 3 秒内重复提交返「批量续签处理中,请勿重复提交」。
|
||
|
||
## 1. 新增端点
|
||
|
||
`POST /admin/fleet/drivers/batch-season-renew`
|
||
|
||
### 入参(body)
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| driverIds | string[] | 否 | 目标司机ID列表(雪花字符串);**缺省/空数组 = 对全部 season=active 司机全量换季**;含不存在的 ID 整批报 100001 |
|
||
| renewSeasonLabel | string | 是 | 续签目标赛季标识(如 `2027`);缺失返 400 |
|
||
| remark | string | 否 | 批量动作备注(入审计日志) |
|
||
|
||
### 请求示例
|
||
|
||
```bash
|
||
curl -k -X POST "https://api.test.1814.love:9443/admin/fleet/drivers/batch-season-renew" \
|
||
-H "Authorization: Bearer {token}" -H "Content-Type: application/json" \
|
||
-d '{"driverIds":["2065002428792492033"],"renewSeasonLabel":"2027","remark":"2027 赛季换季"}'
|
||
```
|
||
|
||
### 响应示例(测试服实测)
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"matchedCount": 1,
|
||
"transitionedCount": 1,
|
||
"inviteGeneratedCount": 1,
|
||
"invites": [
|
||
{
|
||
"driverId": "2065002428792492033",
|
||
"driverName": "张师傅",
|
||
"token": "e4dc8e393bc54224aeb97a346611cb58",
|
||
"url": "https://h5.hl-fleet.com/onboard?token=e4dc8e393bc54224aeb97a346611cb58",
|
||
"qrCodeUrl": "data:image/png;base64,iVBORw0KGgo...",
|
||
"expireAt": "2026-06-25T17:25:20"
|
||
}
|
||
],
|
||
"skipped": []
|
||
}
|
||
}
|
||
```
|
||
|
||
| 出参字段 | 说明 |
|
||
|---|---|
|
||
| matchedCount | 匹配司机数 |
|
||
| transitionedCount | 成功转入续签(active→pending)数 |
|
||
| inviteGeneratedCount | 生成续签邀请数(同事务恒等于 transitionedCount) |
|
||
| invites[] | 「待发列表」:driverId/driverName/token/url(H5 链接,`?token=` 参数)/qrCodeUrl(**二维码 Base64 DataURL,前端可直接 img src 渲染**)/expireAt(14 天有效) |
|
||
| skipped[] | 跳过明细:driverId + reason(如 `season=pending≠active(非在册,跳过)`) |
|
||
|
||
### 非 active 司机被跳过(实测)
|
||
|
||
```json
|
||
{ "matchedCount": 1, "transitionedCount": 0, "inviteGeneratedCount": 0, "invites": [],
|
||
"skipped": [ { "driverId": "2065002428792492033", "reason": "season=pending≠active(非在册,跳过)" } ] }
|
||
```
|
||
|
||
## 2. 错误码
|
||
|
||
| code | 触发场景 |
|
||
|---|---|
|
||
| 400 | renewSeasonLabel 缺失/空白(平台参数校验统一口径) |
|
||
| 100001 | driverIds 含不存在的司机 ID(消息列出缺失 ID,整批不执行) |
|
||
|
||
## 3. 联动效果(前端无需额外调用)
|
||
|
||
- 司机列表 §3.1 的 `season` 变 `pending`、`pendingInvitedAt` 有值(卡片可显示「续签链接已发送·{日期}」);
|
||
- 每位司机自动生成一条 mode=renew 的待审核记录(司机打开链接走 §4 续签 3 步流程,与单个生成链接 §4.1 完全同机制)。
|