From 98ca7cc7d469f1d477760314bbf67a33ac12ffb5 Mon Sep 17 00:00:00 2001 From: wx <2636507191@qq.com> Date: Fri, 23 Oct 2026 12:45:01 +0800 Subject: [PATCH] =?UTF-8?q?changelog(9209):=20=E5=8D=95=E5=9B=A2=E6=8E=92?= =?UTF-8?q?=E8=BD=A6=E9=A1=B9=E4=B8=8A=E9=99=90=204000->500=EF=BC=88?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=A5=E5=8F=A3/=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=90=8E=E5=8F=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...’车项上限由4000收紧到500-修改接口-管理后台.md | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 changelogs-v2/2026-10/23_9209_单团排车项上限由4000收紧到500-修改接口-管理后台.md diff --git a/changelogs-v2/2026-10/23_9209_单团排车项上限由4000收紧到500-修改接口-管理后台.md b/changelogs-v2/2026-10/23_9209_单团排车项上限由4000收紧到500-修改接口-管理后台.md new file mode 100644 index 00000000..4e9ffc5e --- /dev/null +++ b/changelogs-v2/2026-10/23_9209_单团排车项上限由4000收紧到500-修改接口-管理后台.md @@ -0,0 +1,201 @@ +--- +schema: "hl-changelog/v2" +ticket: "9209" +title: "单团排车项上限由 4000 收紧到 500:超过 500 项在提交阶段即被拒,文案改为「请减少配车项后重新提交」" +consumer: "admin" +author: "chewu5(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 #9218,squash 5f1d456c4),已部署测试服(deploy-backend hl-fleet-service --branch dev-v3,11:47:04):deploy-status 显示 dev-v3 / 5f1d456c4 / 0/N / ok;双实例 8087、8187 health 均 200,部署日志 Started 之后 ERROR 0。契约变化只有一处上限:POST /admin/fleet/assignments/batch 的 dailyPlan 由最多 4000 项收紧到 500 项(@Size(max=500)),501 项起返回 400 + 可执行文案;入参字段名/类型、出参结构、其余错误码均未变。确认侧上限 500 与 #9193 的计数守卫原样保留,常量统一到 FleetLimits.MAX_DISPATCH_ITEMS_PER_GROUP。hl-ui 不改也不会错;若前端曾按 4000 做本地上限,建议同步到 500,免得用户填到 501~4000 项才在提交时被拒。" +updated_at: "2026-10-23" +base: "dev-v3" +--- +# hl-fleet-service: 单团排车项上限由 4000 收紧到 500 + +> **服务**: hl-fleet-service(管理后台) +> **PR**: #9218(已合入 dev-v3,合并提交 5f1d456c4) +> **Issue**: #9209 +> **日期**: 2026-10-23 +> **影响范围**: 管理后台「车务最终实派方案」批量提交(`dailyPlan` 项数上限) + +--- + +## ⚠️ 关键变化 + +🟢 `POST /admin/fleet/assignments/batch` 的 `dailyPlan` 上限:**4000 项 → 500 项**。 + +🟢 超过上限的拒绝文案改为可执行提示: + +```text +单次逐日派车配置不能超过500项,请减少配车项后重新提交 +``` + +🔴 请求体字段名/类型、响应结构、错误码集合都没变;500 项整仍然成功提交,501 项起才被拒。 + +--- + +## 一、背景 + +确认侧(`POST /admin/fleet/group-dispatch/batches/{groupBatchId}/confirm`)自 #9179 起单团只允许 500 行存活配车行,而提交侧 `batchCreate` 的 `dailyPlan` 一直允许 4000 项(该数值来自 #5292,无容量依据)。两者不一致的结果是:**501~4000 项的团能建得成、却永远确认不了**——25 天 × 21 车的常规团就是 525 项,直接命中。 + +wx 2026-10-23 拍板:500 够用,提交侧收紧到 500。本单同时把「500」这个数字收敛到唯一出处 `FleetLimits.MAX_DISPATCH_ITEMS_PER_GROUP`:提交侧的 Bean Validation 注解与确认侧的行数守卫引用同一个常量,避免将来改一处漏一处。 + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 车务最终实派方案原子提交 | POST | `/admin/fleet/assignments/batch` | 入参上限收紧 + 文案 | `dailyPlan` 最多 500 项(原 4000);其余字段与出参不变 | + +## 三、接口详情 + +### 1. 车务最终实派方案原子提交 `POST /admin/fleet/assignments/batch` + +**VO**: `BatchCreateAssignmentReqVO` / `Result` + +#### 使用场景 + +管理后台在团期 / 订单的车务配车页点「提交最终方案」时调用:一次提交该需求在完整日期窗内的逐日配车清单(服务日期 × 车辆 × 司机),服务端原子落库并回写订单。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| orderId | Body | Long | ✅ | - | 订单 ID | +| requirementId | Body | Long | ✅ | - | 当前生效用车需求 ID | +| kind | Body | String | 否 | TRAVEL / TRANSFER | 需求类别,不传按 TRAVEL | +| startDate / endDate | Body | Date | ✅ | - | 用车起止日期 | +| requestId | Body | String | ✅ | ≤ 64 字符 | 批次级幂等标识 | +| **dailyPlan** | Body | Array | ✅ | **≤ 500 项(原 4000)** | 按行程日的完整配车列表,逐项为 服务日期×车辆×司机;同一服务日允许多条 | +| 其余字段 | Body | - | 否 | - | 与改动前一致(headcount / pickupAt / dropoffAt / sendItinerarySms 等) | + +#### 出参 `Result` + +结构与字段名均未变: + +| 字段 | 类型 | 说明 | +|------|------|------| +| assignments | Array | 本次提交落库的配车行列表 | +| finalPlanPublished | Boolean | 最终方案是否已发布 | +| finalPlanNotPublishedReason | String | 未发布时的第一个原因;发布时为 null | +| pickupDropoffGate | Object | 接送机第③步门禁信息 | +| failedFleetItemIndex | Integer | 失败的配车项下标(仅失败时) | +| dailyDifferences | Array | 整批 diff 明细(按日) | +| fleetItemIndex | Integer | 当前处理到的配车项下标 | +| assignment | Object | 单行写入结果(`AssignmentWriteRespVO`) | + +#### 请求示例 + +```json +{ + "orderId": "2112275846201069569", + "requirementId": "2112275846201070000", + "startDate": "2026-10-25", + "endDate": "2026-10-30", + "requestId": "batch-20261023-0001", + "dailyPlan": [ + { "serviceDate": "2026-10-25", "vehicleId": "2112275846201088001", "driverId": "2112275846201099001" } + ] +} +``` + +#### 响应示例 + +```json +{ "code": 200, "message": "成功", "data": { "finalPlanPublished": true, "finalPlanNotPublishedReason": null }, "success": true } +``` + +#### 空数据 / 降级响应 + +`dailyPlan` 为空或缺失不属于降级场景:`@NotNull` 直接拒绝,返回 400「逐日派车计划不能为空」。 + +#### 错误响应 + +超过 500 项时(HTTP 200 + 业务码,网关统一语义): + +```json +{ "code": 400, "message": "单次逐日派车配置不能超过500项,请减少配车项后重新提交", "data": null, "success": false } +``` + +其余错误码(605062 服务日期越窗、605912 派车快照缺车型等)语义与文案均未变。 + +#### 业务边界 + +- `dailyPlan` 恰好 500 项:**成功**,与改动前一样走完整提交流程。 +- `dailyPlan` 501 项起:`@Size` 拒绝,**零写入**,不产生配车行、不触发订单回写。 +- 确认侧上限仍是 500 行存活配车行(#9179 / #9193),且 #9193 的「先计数拒绝、不读明细」守卫原样保留;提交侧与确认侧现在共用同一常量。 +- 本单不动读取路径、不动表结构、不订正存量数据。 + +## 四、契约约束与正确调用方式 + +| 场景 | 调用 | +|------|------| +| ✅ 单团 ≤ 500 项 | 正常提交 | +| ❌ 501~4000 项 | 会被 400 拒绝;应按提示减少配车项后重新提交,不要重试同一请求 | +| ❌ 把 400 当成可重试的并发错误 | 不是并发错误,重试不会改变项数 | + +前端若做提交前校验,上限请用 **500**;已经按 4000 做本地上限的页面在 501~4000 项时会拿到上述 400 与文案(功能不会错,只是提示出现在提交时刻)。 + +## 五、数据库行为 + +无表结构变更、无 Flyway、无数据订正。仅提交侧入参校验收紧。 + +## 六、边界行为 + +- 边界严格按 `> 500`:500 成功、501 拒绝,两侧都有单元用例(`BatchCreateAssignmentReqVOTest#validate_dailyPlanAtLimit_passes` / `#validate_dailyPlanOverLimit_violatesSize`)。 +- 校验发生在 Controller 入参绑定阶段(`@Valid`),早于任何业务写入与锁获取。 +- 确认侧文案:「拆团」措辞已清理,现为「请减少配车项后重试」(该动作没有接口,不该出现在提示里)。 + +## 六.6、修改前后对比 + +### 行为级对比 + +| 场景 | 改前 | 改后 | +|------|------|------| +| dailyPlan = 500 项 | 成功 | 成功(不变) | +| dailyPlan = 501 项 | 成功提交(随后永远确认不了) | 400 拒绝,零写入 | +| dailyPlan = 1000 / 4000 项 | 成功提交(死团) | 400 拒绝 | +| 确认侧 > 500 存活行 | 602010(#9193:先计数拒绝) | 不变 | + +### 字段级对比 + +无字段变化:字段名、类型、必填性、枚举、错误码数值均未改;只有 `dailyPlan` 的 `@Size(max)` 由 4000 变为 500,以及超限文案改为可执行提示。 + +## 六.7、影响评估 + +- **是否破坏向后兼容**: 是「收紧」而非「破坏」——合法调用(≤ 500 项)行为与出参完全不变;原本能提交的 501~4000 项现在被提前拒绝,而这批数据原本也无法确认(确认侧上限 500)。 +- **前端是否必须同步上线**: 否。前端不做任何改动也能正常提交 ≤ 500 项;若前端自己按 4000 做本地上限,建议同步到 500(只是把提示提前到用户编辑时)。 +- **前端 workaround 清理点**: 若有页面按 4000 做客户端条数校验,把常量改为 500。 +- **存量数据**: 测试服 > 500 行的团 0 个,无需订正;生产如有存量死团,应另单处置(本单不做数据订正)。 + +## 七、不影响范围 + +- 其它 `hl-fleet-service` 接口:`PickupDropoffConfigReqVO` 的 4000 上限属接送机配置,写的是另一张表、不参与 `fleet_group_dispatch`,本单未改。 +- 确认侧守卫逻辑(#9193)零改动。 +- `hl-mini` / `about-h5` 不消费 `/admin/fleet/**`。 + +## 八、测试环境已验证 + +| 项 | 读数 | +|---|---| +| 部署 | `deploy-backend hl-fleet-service --branch dev-v3` 11:47:04;deploy-status:dev-v3 / 5f1d456c4 / 0/N / ok | +| 双实例 | 8087、8187 `is UP`,`/actuator/health` 均 200 | +| 部署日志 | 两实例 `Started` 之后 ` ERROR ` 计数均 0 | +| 定向测试 | `BatchCreateAssignmentReqVOTest` 13 / `AssignmentControllerTest` 49 / `GroupDispatchConfirmTest` 32 / `FleetRedLineArchTest` 31+2,SUM tests=127 failures=0 errors=0 skipped=0 | +| 编译 | 清 classes 后重新编译:Compiling 1195 main + 532 test,EXIT=0 | +| 存量数据只读核对 | 测试服 `fleet_group_dispatch` 存活行:>500 行的团 0 个(最多 7 行,4 团共 23 行)⇒ 无死团需要处置 | + +## 十、相关文档 + +- `docs/fleet-workbench/1-2接口文档.md`(提交接口的 dailyPlan 上限说明如与本条不一致,以本条为准) +- 上游单:#9179(确认侧 500 行上限)、#9193(先计数再拒绝)、#5292(4000 的来源,已判定无依据) + +## 关联 / 联系人 + +- 后端:车务5(本单实现与验证) +- 工单:wx/HL#9209;PR:wx/HL#9218 \ No newline at end of file