文件
hl-api-changelog/changelogs-v2/2026-10/23_9193_团期确认超限改为先计数拒绝-修改接口-管理后台.md
T
2026-10-23 11:29:15 +08:00

211 行
8.8 KiB
Markdown
原始文件 Blame 文件历史

此文件含有不可见的 Unicode 字符
此文件含有人类无法区分的不可见的 Unicode 字符,但可以由计算机进行不同的处理。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
---
schema: "hl-changelog/v2"
ticket: "9193"
title: "团期确认超限改为先计数拒绝:602010 触发时机提前、文案改为整团重配并警示解除"
consumer: "admin"
author: "chewu2(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "已合并 dev-v3(PR #9214,squash b50acf55e),已部署测试服 task 67120fc5,双实例 8187/8087 均 is UP(各 7s),health 均 200,部署日志 ERROR 0;ha_r1_vm 经网关 GET /admin/fleet/dispatch-groups/page 返回 HTTP 200 / code 200(39 团)。接口入参/出参结构零变化,仅 602010 的触发时机与文案变化:超限团不再先做全量 FOR UPDATE 读取。hl-ui 无需改代码。"
updated_at: "2026-10-23"
base: "dev-v3"
---
# hl-fleet-service: 团期确认超限改为先计数拒绝
> **服务**: hl-fleet-service(管理后台)
> **PR**: #9214(已合入 dev-v3,合并提交 b50acf55e)
> **Issue**: #9193
> **日期**: 2026-10-23
> **影响范围**: 管理后台团期确认(超限存量团的 602010 触发时机与文案)
---
## ⚠️ 关键变化
🟢 团级确认在存活配车行超过 500 时,改为**先计数、再拒绝**:不再先把全量存活行 `FOR UPDATE` 读进内存。
🟢 `602010` 的触发时机提前,文案改为:
```text
单团存活配车行 N 超过单次确认上限 500,本次确认已拒绝且未读取明细。请联系管理员,用整团重配把排车项降到 500 以内——注意重配是整团全量覆盖,未在新计划中列出的排车项会被解除。
```
🔴 接口路径、请求体、响应体结构、错误码数值均未变。前端不需要改字段或解析逻辑;若页面直接展示 `message`,会自动显示新文案。
---
## 一、背景
#9179 给团级确认加了 500 行上限,但守卫在 `selectAliveByGroupBatchForUpdate` 之后:超限团仍要先全量锁定读,再被拒绝。#9193 修读取侧:先计数守卫、再决定是否读明细。
超限存量的现实来源:一是 #9179 上线前的历史数据;二是 `batchCreate` 允许 4000 项而确认侧只允许 500 项(独立缺陷,另单处理)。
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 团期确认 | POST | `/admin/fleet/group-dispatch/batches/{groupBatchId}/confirm` | 错误码触发时机 + 文案 | 超限时先计数拒绝,不读明细;入参/出参结构不变 |
## 三、接口详情
### 1. 团期确认 `POST /admin/fleet/group-dispatch/batches/{groupBatchId}/confirm`
**VO**: `GroupDispatchConfirmReqVO` / `Result<GroupDispatchConfirmRespVO>`
#### 使用场景
管理后台团期配车页点击「确认配车」时调用。服务端锁定团期、校验覆盖率与资源可派性,并把本团「已派车」行推进为「已确认」。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | ✅ | - | 团期主订单 ID |
| requirementId | Body | Long | 否 | - | 需求 ID;不传则取当前有效需求 |
| requirementVersion | Body | Integer | 否 | - | 需求版本,用于并发校验 |
| remark | Body | String | 否 | 长度上限见 VO | 确认备注 |
#### 出参 `Result<GroupDispatchConfirmRespVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| groupBatchId | Long | 团期主订单 ID |
| confirmedCount | Integer | 本次确认行数 |
| alreadyConfirmedCount | Integer | 原本已确认行数 |
| requirementId / requirementVersion | Long / Integer | 本次使用的需求与版本 |
| planVersion | Long | 配车计划版本 |
| requirementAdvanceIntent | String | 需求推进意图 |
| coverage | Object | 覆盖率明细 |
| legacyGroupRowCount | Integer | 旧团行数 |
| specWarnings | Array | 规格告警 |
#### 请求示例
```json
{ "requirementId": 2112275846201069569, "requirementVersion": 3, "remark": "确认配车" }
```
#### 响应示例
```json
{ "code": 200, "message": "成功", "data": { "groupBatchId": 2112275846201069569, "confirmedCount": 12 }, "success": true }
```
#### 空数据 / 降级响应
本接口无空数据降级:无法确认时返回业务错误码,不返回部分成功。
#### 错误响应
```json
{
"code": 602010,
"message": "单团存活配车行 2000 超过单次确认上限 500,本次确认已拒绝且未读取明细。请联系管理员,用整团重配把排车项降到 500 以内——注意重配是整团全量覆盖,未在新计划中列出的排车项会被解除。",
"success": false,
"data": null
}
```
#### 业务边界
- 存活行 ≤ 500:正常确认;恰好 500 行成功。
- 存活行 > 500:先计数拒绝,不读明细;返回 602010。
- 并发窗口:计数与全量锁定读之间若有人插行,读后二次复核仍会按 602010 拒绝。
- 鉴权、错误码 602005/602006/602007/602008/602009 等原有语义不变。
## 四、契约约束与正确调用方式
### ✅ 正确 / ❌ 错误调用对照
| 场景 | 调用 |
|------|------|
| ✅ 存活行 ≤ 500 | 正常 POST,按原逻辑确认 |
| ❌ 存活行 > 500 仍反复重试 | 每次都会 602010;应先整团重配降到 500 行以内 |
| ❌ 把 602010 当成可重试的并发错误 | 不是并发错误;重试不会改变存活行数 |
### 超限后的必要动作
由管理员执行一次请求项 ≤ 500 的整团重配(`POST /admin/fleet/group-dispatch/batches/{groupBatchId}/reconfigure`),把存活行压回 500 以内。**重配是整团全量覆盖**:未在新计划中列出的排车项会被解除,不是增量补充。
## 五、数据库行为
无表结构变更、无 Flyway。确认成功时仍按原逻辑把 `fleet_group_dispatch.status` 从 `ASSIGNED` CAS 为 `CONFIRMED`;超限拒绝时零写入。
## 六、边界行为
- 未登录 / 无车务权限 → 网关或权限守卫拒绝(403),与本次改动无关。
- 团期不存在 → 原错误码。
- 存活行恰好 500 → 成功(判据是 `> 500` 才拒)。
- 存活行 501 → 602010,且不执行全量明细读取。
- 存量 2000/5000 → 只读 1 行计数,明细零读取;实测全量读耗时 140/168ms(远小于 30s 租约)。
## 六.6、修改前后对比
### 行为级对比
| 场景 | 改前 | 改后 |
|------|------|------|
| 存活行 ≤ 500 | 正常确认 | 正常确认(不变) |
| 存活行 = 501 | 先全量 FOR UPDATE 读取,再 602010 拒绝 | 先计数,直接 602010 拒绝,不读明细 |
| 存活行 = 2000/5000 | 读取成本随存量线性增长 | 只读 1 行计数,明细零读取 |
### 字段级对比
无字段变化。
## 六.7、影响评估
- **是否破坏向后兼容**: 否。请求/响应结构、错误码数值均未变;只有 602010 的触发时机提前、文案变化。
- **前端是否必须同步上线**: 否。前端无需改代码;若自定义了 602010 提示语,建议同步为新文案。
- **前端 workaround 清理点**: 无。
## 七、不影响范围
- **仅影响**: 管理后台团期确认的 602010 触发时机与文案。
- **零影响**:
- 团期重配 `reconfigure` 的请求/响应结构与 500 项上限(未改)。
- 团期分享确认 `share/confirm`(走独立事务路径,未改)。
- 配车计划查询、覆盖率查询、派车工作台读取。
- 数据库表结构与 Flyway。
- 网关路由 `/admin/fleet/**`。
## 八、测试环境已验证
**环境**: TEST **验证时间**: 2026-10-23 11:08~11:10
**构建身份**: hl-fleet-service `dev-v3 @ b50acf55e`,部署 task `67120fc5`;双实例 `8187/8087 is UP after 7s`;部署状态回读 `dev-v3 b50acf55e 0/N ok`。
```text
POST https://api.test.1814.love/admin/auth/login (ha_r1_vm) → HTTP 200 / code 200
GET https://api.test.1814.love/admin/fleet/dispatch-groups/page?pageNo=1&pageSize=1 → HTTP 200 / code 200 / total=39
GET http://127.0.0.1:8087/actuator/health → 200
GET http://127.0.0.1:8187/actuator/health → 200
部署窗口 ERROR 计数: 8087=0 / 8187=0
```
真库用例:JDBC 预置存活 2000 行的团,确认被 602010 拒绝且 `selectAliveByGroupBatchForUpdate` 零调用;500 行成功、501 行拒绝;2000/5000 行全量读耗时 140/168ms。
## 十、相关文档
- 关联 Issue: [wx/HL#9193](https://git.1814.love/wx/HL/issues/9193)
- 关联 PR: [wx/HL#9214](https://git.1814.love/wx/HL/pulls/9214)
- 前置工单: [wx/HL#9179](https://git.1814.love/wx/HL/issues/9179)
## 关联 / 联系人
### 链接
- **Issue**: [#9193](https://git.1814.love/wx/HL/issues/9193)
- **PR**: [#9214](https://git.1814.love/wx/HL/pulls/9214)
- **Merge commit**: [b50acf55e](https://git.1814.love/wx/HL/commit/b50acf55ecdb08b2c28f20cfeaf5344e16cafd53)
### 联系人
- **后端负责人**: @chewu2