351 行
15 KiB
Markdown
351 行
15 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "8561"
|
||
title: "派单矩阵三个入口补年份区间校验,新增错误码 605076"
|
||
consumer: "admin"
|
||
author: "wx(GIT)"
|
||
change_type: "修改接口"
|
||
backend_status: "deployed"
|
||
gateway_status: "verified"
|
||
frontend_status: "not_required"
|
||
frontend_owner: ""
|
||
frontend_ref: ""
|
||
target_release: ""
|
||
verified_at: ""
|
||
status_note: "PR #8565 合并 dev-v3(ad3c6e4305);hl-fleet-service dev-v3 分支部署测试网关 @ 9c7ac9382 并实测:grid/month-counts/unassigned-orders 三入口越界年份(1800/9999/1990)均返回 605076,区间内年份(含 2020/2100 两端边界,已在 grid 入口实测)行为不变。"
|
||
updated_at: "2026-09-30"
|
||
base: "dev-v3"
|
||
---
|
||
|
||
# hl-fleet-service: 派单矩阵三个入口补年份区间校验,新增错误码 605076
|
||
|
||
> **存放目录**: `changelogs-v2/2026-09/`
|
||
> **服务**: hl-fleet-service (端口 8087)
|
||
> **PR**: #8565
|
||
> **Issue**: #8561
|
||
> **日期**: 2026-09-30
|
||
> **影响范围**: 管理后台派单矩阵三个查询入口(grid / month-counts / unassigned-orders)的年份校验
|
||
|
||
---
|
||
|
||
## ⚠️ 关键变化
|
||
|
||
- 派单矩阵三个查询入口(`grid`/`month-counts`/`unassigned-orders`)此前只校月份是否在 1-12,**不校年份**——`year=1800`、`year=9999` 这类明显异常值会被当成合法年份继续查询。现在统一在 Service 层加了年份区间校验 `[2020, 2100]`,越界抛**新增错误码 605076**。
|
||
- 605076 的错误文案是 `年份超出范围(仅支持 2020-2100 年)`(`AssignmentErrorCode.MATRIX_YEAR_OUT_OF_RANGE`,文案里的年份区间已按当前常量渲染为 2020/2100)。
|
||
- 校验顺序是**先年后月**:`year` 越界时直接抛 605076,不会先看 `month`。
|
||
- 区间内年份(含边界 2020、2100)行为完全不变,仍按原逻辑正常查询并返回 200。
|
||
- 三入口的 `year` 字段本身仍是**必填**(`@NotNull`),缺失依旧是既有的参数校验码 `100001`,本次未改动这一路径。
|
||
|
||
---
|
||
|
||
## 二、变更接口清单
|
||
|
||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||
|---|------|------|------|----------|------|
|
||
| 1 | 矩阵主数据 | GET | `/admin/fleet/matrix/grid` | 校验补充 | 新增年份区间校验,越界返 605076 |
|
||
| 2 | 矩阵年度月度统计 | GET | `/admin/fleet/matrix/month-counts` | 校验补充 | 新增年份区间校验,越界返 605076 |
|
||
| 3 | 矩阵未派订单清单 | GET | `/admin/fleet/matrix/unassigned-orders` | 校验补充 | 新增年份区间校验,越界返 605076 |
|
||
|
||
---
|
||
|
||
## 三、接口详情
|
||
|
||
### 1. 矩阵主数据 `GET /admin/fleet/matrix/grid`
|
||
|
||
**VO**: `MatrixGridReqVO` → `MatrixGridRespVO`
|
||
|
||
#### 使用场景
|
||
|
||
车务打开派单矩阵页查看某年某月逐日车辆占用/待派情况时调用。本次改动只影响 `year` 越界场景的响应,区间内查询字段结构与既有行为未变。
|
||
|
||
#### 入参字段表
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| year | Query | Integer | ✅ | 🔴 新增:2020-2100(越界返 605076) | 年份 |
|
||
| month | Query | Integer | ✅ | 1-12(越界返 605010) | 月份 |
|
||
| season | Query | String | - | active/pending/archived/blacklist | 司机赛季筛选,默认 active |
|
||
| fleetTeamIds | Query | Long[] | - | - | 车队 ID 多选,空=全部 |
|
||
| fleets | Query | String[] | - | 已废弃,仅客户端迁移兼容 | 旧版车队稳定编码多选 |
|
||
| typeKeys | Query | String[] | - | 规范小写,空=全部 | 车型大类多选 |
|
||
| status | Query | String | - | all/unassigned/assigned | 兼容矩阵筛选 |
|
||
| statuses | Query | String[] | - | 非空时优先于 status | 有效状态精确筛选 |
|
||
|
||
#### 出参字段表
|
||
|
||
响应结构本次未改动,以下仅列出与本次校验相关、已实测确认的顶层字段:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| year | Integer | 年份(回显) |
|
||
| month | Integer | 月份(回显) |
|
||
| daysInMonth | Integer | 该月天数 |
|
||
| vehicles | List | 车辆逐日占用数据 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /admin/fleet/matrix/grid?year=2020&month=6&season=active
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
区间下边界(year=2020)实测:
|
||
|
||
```json
|
||
{"code":200,"message":"成功","data":{"year":2020,"month":6,"daysInMonth":30},"traceId":null,"success":true}
|
||
```
|
||
|
||
区间上边界(year=2100)实测:
|
||
|
||
```json
|
||
{"code":200,"message":"成功","data":{"year":2100,"month":6},"traceId":null,"success":true}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
区间内查询若当月无任何车辆/派车数据,`vehicles` 为空数组,属正常业务结果,不是错误;本次改动不影响此形态。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{"code":605076,"message":"年份超出范围(仅支持 2020-2100 年)","data":null,"traceId":null,"success":false}
|
||
```
|
||
|
||
(实测 `year=1800` 与 `year=9999` 均返回上述响应体,仅请求参数不同。)
|
||
|
||
#### 业务边界
|
||
|
||
- `year` 越界(不在 [2020, 2100])→ 605076,`month` 是否越界不影响判定结果(先年后月)。
|
||
- `year` 合法、`month` 越界(如 13)→ 仍按既有 605010 路径处理,本次未改动。
|
||
- `year`/`month` 缺失仍是既有的 100001(参数非法),未受本次改动影响。
|
||
|
||
### 2. 矩阵年度月度统计 `GET /admin/fleet/matrix/month-counts`
|
||
|
||
**VO**: `MatrixMonthCountsReqVO` → `MatrixMonthCountsRespVO`
|
||
|
||
#### 使用场景
|
||
|
||
车务查看某年 12 个月各状态计数概览时调用(矩阵页顶部年度视图)。本次改动只影响 `year` 越界场景。
|
||
|
||
#### 入参字段表
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| year | Query | Integer | ✅ | 🔴 新增:2020-2100(越界返 605076) | 年份 |
|
||
| season | Query | String | - | active/pending/archived/blacklist | 司机赛季筛选,默认 active |
|
||
| fleetTeamIds | Query | Long[] | - | - | 车队 ID 多选,空=全部 |
|
||
| typeKeys | Query | String[] | - | 规范小写,空=全部 | 车型大类多选 |
|
||
|
||
注:本端点没有 `month` 入参,年份越界统一走 605076,不会把调用方指去改一个不存在的字段。
|
||
|
||
#### 出参字段表
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| year | Integer | 年份(回显) |
|
||
| months | List | 12 个月各状态计数 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /admin/fleet/matrix/month-counts?year=2026&season=active
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
```json
|
||
{"code":200,"message":"成功","data":{"year":2026},"traceId":null,"success":true}
|
||
```
|
||
|
||
(实测该年 12 个月 `statusCounts` 均为 0,字段结构本次未改动,示例只截取顶层字段。)
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
区间内年份若全年无任何数据,`months` 中每个月的计数均为 0,属正常业务结果;本次改动不影响此形态。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{"code":605076,"message":"年份超出范围(仅支持 2020-2100 年)","data":null,"traceId":null,"success":false}
|
||
```
|
||
|
||
(实测 `year=1800` 返回上述响应体。)
|
||
|
||
#### 业务边界
|
||
|
||
- `year` 越界(不在 [2020, 2100])→ 605076。
|
||
- `year` 缺失仍是既有的 100001(参数非法),未受本次改动影响。
|
||
|
||
### 3. 矩阵未派订单清单 `GET /admin/fleet/matrix/unassigned-orders`
|
||
|
||
**VO**: `MatrixUnassignedReqVO` → `List<MatrixUnassignedOrderVO>`
|
||
|
||
#### 使用场景
|
||
|
||
车务查看某年某月未派车订单清单(含虚拟待派条目)时调用。本次改动只影响 `year` 越界场景;`month` 越界的同构收敛见工单 #8571 的 changelog。
|
||
|
||
#### 入参字段表
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| year | Query | Integer | ✅ | 🔴 新增:2020-2100(越界返 605076),本次前摘掉了原 `@Min(1970)/@Max(9999)` | 年份 |
|
||
| month | Query | Integer | ✅ | 1-12(越界返 605010,见 #8571) | 月份 |
|
||
| typeKeys | Query | String[] | - | 规范小写,空=全部 | 车型大类多选 |
|
||
|
||
#### 出参字段表
|
||
|
||
响应结构本次未改动。
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| virtualPending | Boolean | 是否虚拟待派条目(库里无对应行,由 order-v3 当前需求投射) |
|
||
| headcountLabel | String | 人数展示文案 |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
GET /admin/fleet/matrix/unassigned-orders?year=1990&month=6&season=active
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
```json
|
||
{"code":200,"message":"成功","data":[],"traceId":null,"success":true}
|
||
```
|
||
|
||
(对照:`year=2026&month=6`(区间内)实测返回上述形态,`data` 为空数组属正常业务结果,与越界错误可区分。)
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
区间内年份若当月无未派订单,`data` 为空数组,属正常业务结果,与越界返回的错误响应(`success:false`)可明确区分。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{"code":605076,"message":"年份超出范围(仅支持 2020-2100 年)","data":null,"traceId":null,"success":false}
|
||
```
|
||
|
||
(实测 `year=1990` 返回上述响应体;本次改动前该场景返回的是框架码 100001,见"六.6、修改前后对比"。)
|
||
|
||
#### 业务边界
|
||
|
||
- 🔴 **契约收窄**:本端点 `year` 原有的校验区间是 `[1970, 9999]`(`@Min/@Max` 注解),本次收窄为 `[2020, 2100]` 且改走业务码 605076。`year=1990` 这类此前能通过框架校验、现在会被拒绝的取值,前端如果曾经允许用户选择这类年份,需要同步收紧可选范围。
|
||
- `year` 越界 → 605076;`month` 越界 → 605010(#8571),二者不互相覆盖,先年后月。
|
||
- `year`/`month` 缺失仍是既有的 100001(`@NotNull` 保留,未随本次摘除区间注解一并摘掉)。
|
||
|
||
---
|
||
|
||
## 四、契约约束与正确调用方式
|
||
|
||
> 本节只写后端接受/拒绝 payload 的规则,不写 UI 渲染建议。
|
||
|
||
### ✅ 正确 / ❌ 错误 payload 对照
|
||
|
||
| 场景 | payload / 响应 |
|
||
|------|-----------------|
|
||
| ✅ `year` 在 [2020, 2100] 区间内(含边界) | 三入口均正常返回 `code=200` |
|
||
| ❌ `year` 不在 [2020, 2100] 区间(如 1800/1990/9999) | 三入口均返回 `code=605076` |
|
||
| ❌ 继续沿用 `unassigned-orders` 此前 `[1970, 9999]` 的可选年份范围 | `year=1990` 等取值现在会被 605076 拒绝,不再是 100001 |
|
||
| ❌ 把 605076 当作可重试错误自动重试 | 605076 是入参永久性非法,重试同一 `year` 不会成功,需要用户重新选择年份 |
|
||
|
||
### 切换状态时的必要动作
|
||
|
||
前端拦到 `code=605076` 时应提示"年份超出范围,仅支持 2020-2100 年"类文案,并将年份选择控件的可选范围收紧到该区间,不要自动重试。
|
||
|
||
---
|
||
|
||
## 五、数据库行为
|
||
|
||
本次涉及的三个接口均为只读查询,无任何数据库写操作。改动只在 Service 层新增一段入参校验逻辑,不涉及任何表结构或存量数据变化。
|
||
|
||
---
|
||
|
||
## 六、边界行为
|
||
|
||
- `year` 不在 [2020, 2100] → 605076(三入口统一,本次新增)
|
||
- `year` 缺失 → 100001(既有行为,未改动)
|
||
- `year` 合法、`month` 越界 → 605010(grid 既有行为;unassigned-orders 同构收敛见 #8571)
|
||
- `year`/`month` 均合法 → 按既有逻辑正常查询,字段结构未变
|
||
|
||
---
|
||
|
||
## 六.5、枚举 / 数据字典
|
||
|
||
### 矩阵年份越界错误码(`AssignmentErrorCode.MATRIX_YEAR_OUT_OF_RANGE`)
|
||
|
||
**所属字段**: 无(HTTP 响应顶层 `code`) | **类型**: `Integer`
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| `605076` | 年份超出范围(仅支持 2020-2100 年) | 🔴 本次新增;三个矩阵查询入口的 `year` 不在 [2020, 2100] 时统一返回;入参永久性非法,不应自动重试 |
|
||
|
||
## 六.6、修改前后对比
|
||
|
||
### 字段级对比
|
||
|
||
本次无请求/响应字段新增或删除;`unassigned-orders` 的 `year` 字段摘掉了 `@Min(1970)/@Max(9999)` 注解(见入参字段表标注),字段本身仍是必填 `Integer`。
|
||
|
||
### 行为级对比
|
||
|
||
| 场景 | 改前 | 改后 |
|
||
|------|------|------|
|
||
| grid / month-counts,`year` 越界(不在 [2020,2100],如 1800/9999) | 未校验,当作合法年份继续查询 | 返回 `code=605076`(新增拦截) |
|
||
| unassigned-orders,`year` 不在 [2020, 2100](含此前 `@Min(1970)/@Max(9999)` 认为合法的 [1970,2019]∪[2101,9999] 区间) | 该子区间内视为合法继续查询,落在 [1970,9999] 之外才返回框架码 100001 | 统一返回业务码 605076,不再区分是否曾落在 [1970,9999] 内 |
|
||
| 三入口,`year` 在 [2020, 2100] | 正常返回 200 | 不变,仍正常返回 200 |
|
||
|
||
## 六.7、影响评估
|
||
|
||
- **是否破坏向后兼容**: 是(仅 `unassigned-orders`)——`year` 的可接受范围从 `[1970, 9999]` 收窄到 `[2020, 2100]`,且越界时的错误码从 100001 变为 605076;`grid`/`month-counts` 此前对越界年份没有任何拦截,本次是新增拦截而非收窄既有契约。
|
||
- **前端是否必须同步上线**: 是——年份选择控件若允许超出 `[2020, 2100]` 的取值,现在会收到新的 605076 错误码,前端需要新增该码的处理分支(提示文案 + 阻断当前查询),并建议同步收紧可选年份范围以减少用户触发该错误的机会。
|
||
- **前端 workaround 清理点**: 若此前为"年份异常导致矩阵页面空白/报错"写过特殊兼容逻辑,可以确认不再需要,因为现在有明确的 605076 信号可用。
|
||
|
||
---
|
||
|
||
## 七、不影响范围
|
||
|
||
- **仅影响**: 派单矩阵三个查询入口(`grid`/`month-counts`/`unassigned-orders`)在 `year` 入参越界时的响应。
|
||
- **零影响**:
|
||
- 三入口在 `year` 合法时的成功路径字段结构
|
||
- `month` 越界的既有校验 605010(`unassigned-orders` 的同构收敛见 #8571 单独的 changelog)
|
||
- `season`/`fleetTeamIds`/`typeKeys`/`status`/`statuses` 等其余入参的校验逻辑
|
||
- `day-orders` 等矩阵模块下其余未涉及本次改动的端点
|
||
|
||
---
|
||
|
||
## 八、测试环境已验证
|
||
|
||
服务:`hl-fleet-service`,dev-v3 分支部署测试网关 @ `9c7ac9382`(含 #8561 所在提交),测试网关 `https://api.test.1814.love`:
|
||
|
||
```
|
||
✓ GET grid?year=1800&month=6 → code=605076, message="年份超出范围(仅支持 2020-2100 年)"
|
||
✓ GET grid?year=9999&month=6 → code=605076
|
||
✓ GET month-counts?year=1800 → code=605076
|
||
✓ GET unassigned-orders?year=1990&month=6 → code=605076(此前为 100001,见六.6)
|
||
✓ GET grid?year=2020&month=6(下边界)→ code=200,正常返回
|
||
✓ GET grid?year=2100&month=6(上边界)→ code=200,正常返回
|
||
✓ GET month-counts?year=2026(区间中段)→ code=200,正常返回
|
||
✓ GET unassigned-orders?year=2026&month=6(区间中段)→ code=200, data=[]
|
||
```
|
||
|
||
注:2020/2100 两端边界值仅在 `grid` 入口做了直接边界实测;`month-counts`/`unassigned-orders` 在区间中段(year=2026)验证了正常放行。三入口共用同一段 `requireValidYearMonth` 校验逻辑(`MatrixService.java`),边界判定不因入口而异,越界拦截已在三入口分别实测(见上)。
|
||
|
||
---
|
||
|
||
## 十、相关文档
|
||
|
||
- 关联 Issue: [wx/HL#8561](https://git.1814.love/wx/HL/issues/8561)
|
||
- 关联 PR: [wx/HL#8565](https://git.1814.love/wx/HL/pulls/8565)
|
||
|
||
## 关联 / 联系人
|
||
|
||
### 链接
|
||
|
||
- **Issue**: [#8561](https://git.1814.love/wx/HL/issues/8561)
|
||
- **PR**: [#8565](https://git.1814.love/wx/HL/pulls/8565)
|
||
- **Merge commit**: [ad3c6e4305](https://git.1814.love/wx/HL/commit/ad3c6e4305)
|
||
|
||
### 联系人
|
||
|
||
- **后端负责人**: @wx
|