---
schema: "hl-changelog/v2"
ticket: "5459"
title: "用车需求提交/修改接口补定制师归属校验（越权修复）"
consumer: "admin"
change_type: "修改接口"
author: "wx(GIT)"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
updated_at: "2026-08-04"
base: "dev-v3"
---

# 订单: 用车需求提交/修改接口补定制师归属校验（#5459 越权修复）

> **服务**: hl-order-service-v3
> **PR**: #5471
> **Issue**: #5459
> **日期**: 2026-08-04
> **影响范围**: 管理后台用车需求提交/修改（定制师弹窗）

---

## ⚠️ 关键变化（行为修复，契约新增错误码）

`PUT /v3/admin/order/:id/vehicle-requirement`（提交/修改/调整用车需求）此前无角色/归属校验，车务角色可越权修改任意订单需求。现补操作人守卫，与同模块加急接口（`/vehicle-requirement/:requirementId/urgent`）校验口径一致：

- **超管（SUPER_ADMIN）**：放行。
- **其余角色**：必须是该订单归属定制师（订单 `consultant_id` == 当前登录 adminId），否则返回 **582094**，请求不落库。

## 变更接口

| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 提交/修改/调整用车需求 | PUT | `/v3/admin/order/:id/vehicle-requirement` | 行为变更 | 增加操作人归属校验，非本单定制师/非超管返回 582094 |

## 二、接口详情

### 1. 提交/修改/调整用车需求 `PUT /v3/admin/order/:id/vehicle-requirement`

**使用场景**：定制师在订单详情提交/修改/调整用车需求（无 active=INIT_SUBMIT / PENDING=PENDING_EDIT / DONE=DONE_ADJUST 三分支自动判断）。

**请求头**：`Authorization: Bearer <token>`（角色来自登录态，无新增字段）

**入参**（无变化）：

| 字段 | 位置 | 类型 | 必填 | 说明 |
|------|------|------|------|------|
| `fleet[]` | Body | Array | ✅ | 车型需求列表 |
| `fleet[].vehicleType` | Body | String | ✅ | 车型大类 key（如 suv/mpv） |
| `fleet[].seats` | Body | Integer | ✅ | 座位数 |
| `fleet[].count` | Body | Integer | ✅ | 辆数 |
| `specialTags[]` | Body | Array | - | 特殊标签 |
| `remark` | Body | String | - | 备注 |

**出参**：`Result<VehicleRequirementRespVO>`（branchTaken/version/... 结构无变化）

**错误码（新增）**：

| 错误码 | 场景 |
|--------|------|
| `582094` | **新增**：操作人非该订单定制师且非超管（如车务角色调用） |
| `582083` | 需求状态不允许此操作 |
| `582022` | 车型座位数选项非法 |

**典型成功示例**（定制师本人）：

```http
PUT /v3/admin/order/2084280429287817218/vehicle-requirement
Authorization: Bearer <wx token>
Content-Type: application/json

{
  "fleet": [
    {
      "vehicleType": "suv",
      "seats": 5,
      "count": 1
    }
  ],
  "specialTags": [],
  "remark": "定制师本人提交"
}
```

响应（成功）：`code=200`，data 含 `branchTaken=INIT_SUBMIT`、`version=1`。

**越权拒绝示例**（车务角色调用他人订单）：

```http
PUT /v3/admin/order/2084466629751558146/vehicle-requirement
Authorization: Bearer <admin(VEHICLE_MANAGER) token>
Content-Type: application/json

{
  "fleet": [
    {
      "vehicleType": "suv",
      "seats": 5,
      "count": 1
    }
  ],
  "specialTags": [],
  "remark": "越权尝试"
}
```

响应（拒绝）：`code=582094`「仅该订单定制师或超管可提交/修改用车需求」，data=null。

## 三、契约约束

| 场景 | 后端行为 |
|------|----------|
| 车务（VEHICLE_MANAGER）调用任意订单 | 582094 拒绝，不落库（修复前返回 200 并成功修改需求） |
| 定制师本人（订单归属 consultantId 匹配） | 正常提交/修改 |
| 超管（SUPER_ADMIN） | 放行，不校验归属 |
| 校验口径 | 与 `POST /v3/admin/order/vehicle-requirement/:requirementId/urgent`（582084）完全一致 |

## 前端注意事项

- 管理后台车务端不展示/不调用此接口，前端**无需改动**；若存在车务侧直达该接口的旧逻辑，请清理。
- 定制师弹窗调用该接口的既有逻辑不受影响。

## 验证证据

- 定向单测 3 例：车务角色拒绝（582094 不落库）/ 定制师本人正常 / 超管放行。
- 模块全量 `mvn -pl hl-order-service-v3 -am test`：7414 tests 0 failures 0 errors（BUILD SUCCESS）。
- TEST 网关实测：admin（VEHICLE_MANAGER）对 wx 订单调用返回 582094 且需求未被修改；wx（CUSTOMIZER）本人调用返回 200 成功（INIT_SUBMIT v1）。超管路径由单测覆盖（TEST 环境无超管账号）。

## 关联/联系人

- 后端负责人: @wx
- 关联 Issue: [wx/HL#5459](https://git.1814.love:8443/wx/HL/issues/5459)
- 关联 PR: [wx/HL#5471](https://git.1814.love:8443/wx/HL/pulls/5471)
