# API v2 Agent 接口文档

本文档面向 AI Agent 及外部自动化调用方，描述 `/api/v2/ai/` 前缀下的所有接口。

## 基本约定

- Base URL: `/api/v2/ai`
- 认证：所有接口使用固定 API Key，通过 `Authorization` 请求头直接传入（无 `Bearer` 前缀）
- 多商户隔离：每个接口均需传入 `merchant_id` 查询参数，后端以此确定数据范围

### 认证方式

```
Authorization: <AGENT_ACCESS_KEY>
```

`AGENT_ACCESS_KEY` 由后端部署时通过同名环境变量配置。未配置时所有请求均返回 `401`。

---

## 数据结构

### TransportVehicle

```json
{
  "id": 1,
  "merchant_id": 10,
  "name": "大卡车",
  "license_plate": "粤A12345",
  "material_capacities": [
    {"id": 1, "material_name": "坯布", "capacity": 500},
    {"id": 2, "material_name": "成品", "capacity": 300}
  ],
  "created_at": "2026-04-01T08:00:00+08:00",
  "updated_at": "2026-04-01T08:00:00+08:00"
}
```

### Shipment（出货单）

```json
{
  "id": 100,
  "merchant_id": 10,
  "customer": 5,
  "customer_name": "客户A",
  "shipment_date": "2026-04-14",
  "address": "广州市天河区",
  "contact_name": "张三",
  "contact_phone": "13800000000",
  "area": "华东",
  "remark": "备注",
  "status": "pending",
  "status_display": "待出货",
  "external_id": null,
  "geo_coordinates": {"lat": 23.1291, "lng": 113.2644},
  "delivery_id": null,
  "delivery": null,
  "sales_items": [
    {
      "id": 201,
      "name": "销售品甲",
      "quantity": "50.00",
      "unit": 1,
      "unit_display": "件",
      "position": "A-01",
      "remark": "",
      "printing_job_id": 88,
      "printing_job_width": "150cm"
    },
    {
      "id": 202,
      "name": "销售品乙",
      "quantity": "10.00",
      "unit": 1,
      "unit_display": "件",
      "position": "",
      "remark": "",
      "printing_job_id": null,
      "printing_job_width": null
    }
  ],
  "created_at": "2026-04-14T10:00:00+08:00",
  "updated_at": "2026-04-14T10:00:00+08:00"
}
```

---

## 运输车辆列表

- URL: `/api/v2/ai/transport-vehicles/`
- Method: `GET`

查询参数：

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `merchant_id` | int | 是 | 商户 ID |
| `limit` | int | 否 | 分页每页数量（默认由服务端决定） |
| `offset` | int | 否 | 分页偏移量 |

响应为分页结构，`results` 中每条为 `TransportVehicle`，包含该车辆的所有物料容量。

说明：

- `material_capacities` 表示该车辆对不同物料的最大装载量（单位：条）
- 只返回 `merchant_id` 对应商户的车辆
- `VehicleType`（旧版车辆类型字典）和 `VehicleTransportRecord`（旧版司机车次记录）是已废弃的模型，不在此接口返回

## 运输车辆详情

- URL: `/api/v2/ai/transport-vehicles/<license_plate>/`
- Method: `GET`

路径参数：

| 参数 | 说明 |
|------|------|
| `license_plate` | 车牌号码（URL 编码，如 `粤A12345` → `%E7%B2%A4A12345`） |

查询参数：

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `merchant_id` | int | 是 | 商户 ID |

说明：

- 同一商户内 `license_plate` 唯一（数据库 `unique_together: merchant + license_plate`），因此 `merchant_id + license_plate` 可精确定位一辆车
- 不同商户可能存在相同车牌号，`merchant_id` 参数是必须的
- 车辆不存在时返回 `404`

成功响应：`TransportVehicle`

---

## 未出货出货单列表

- URL: `/api/v2/ai/shipments/unshipped/`
- Method: `GET`

查询参数：

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `merchant_id` | int | 是 | 商户 ID |
| `area` | string | 是 | 地区筛选（精确匹配） |
| `limit` | int | 否 | 分页每页数量 |
| `offset` | int | 否 | 分页偏移量 |

说明：

- "未出货"定义：`delivery` 为空，即尚未关联送货单
- `delivery_id` 始终返回送货单ID；未关联时为 `null`
- 结果按 `created_at` 降序排列
- 只返回 `merchant_id` 对应商户的数据
- `sales_items` 包含该出货单的所有销售品（软删除的条目自动排除）
- `sales_items[].printing_job_width`：对应 `PrintingJob → PrintingOrder.width`；若无关联印染任务则为 `null`

响应为分页结构，`results` 中每条为 `Shipment`。
