537 lines
11 KiB
Markdown
537 lines
11 KiB
Markdown
# 前端接入文档:新增平台 HTTP 接口
|
|
|
|
## 1. 背景
|
|
|
|
本次后端新增了一组 HTTP 接口,供前端在现有 WebSocket 交互之外,补充以下能力:
|
|
|
|
- 同步“当前关心的对象及其类型”
|
|
- 运行时修改部分碰撞检测相关参数
|
|
|
|
## 2. 通用约定
|
|
|
|
- 所有接口均为 `POST`
|
|
- 所有请求和响应均为 `application/json`
|
|
- 当前接口无鉴权、无 token、无签名校验
|
|
- 当前后端未补 CORS
|
|
- 如果前端是浏览器并且跨域访问,后续可能还需要后端补 CORS
|
|
- 配置修改仅在内存中生效
|
|
- 服务重启后恢复默认配置
|
|
- `VehicleRegistry` 是“增量更新”
|
|
- 本次未传入的历史对象不会被清空
|
|
|
|
建议前端统一配置接口基础地址,例如:
|
|
|
|
```ts
|
|
const API_BASE = 'http://<后端IP>:8080';
|
|
```
|
|
|
|
## 3. 接口一:对象注册同步
|
|
|
|
### 3.1 接口地址
|
|
|
|
```http
|
|
POST /api/VehicleRegistry
|
|
```
|
|
|
|
### 3.2 用途
|
|
|
|
前端将“当前关心的对象及其类型”增量同步给后端。
|
|
|
|
该接口会直接影响:
|
|
|
|
- 哪些对象参与碰撞检测
|
|
- 哪些车辆可能被系统下发控制命令
|
|
|
|
### 3.3 请求头
|
|
|
|
```http
|
|
Content-Type: application/json
|
|
```
|
|
|
|
### 3.4 请求体
|
|
|
|
```json
|
|
[
|
|
{ "vehicleID": "QN001", "vehicleType": "WUREN" },
|
|
{ "vehicleID": "TQ001", "vehicleType": "TEQIN" },
|
|
{ "vehicleID": "AC001", "vehicleType": "HANGKONG" }
|
|
]
|
|
```
|
|
|
|
### 3.5 字段说明
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|---|---|---|---|
|
|
| `vehicleID` | `string` | 是 | 对象唯一标识,不能为空 |
|
|
| `vehicleType` | `string` | 是 | 对象类型,只允许固定枚举值 |
|
|
|
|
### 3.6 `vehicleType` 可选值
|
|
|
|
- `WUREN`
|
|
- `TEQIN`
|
|
- `HANGKONG`
|
|
- `PUTONG`
|
|
- `JIUYUAN`
|
|
|
|
### 3.7 业务语义
|
|
|
|
#### `WUREN`
|
|
|
|
- 加入“可控车辆集合”
|
|
- 加入“受管车辆集合”
|
|
|
|
#### `TEQIN`
|
|
|
|
- 加入“受管车辆集合”
|
|
- 不属于“可控车辆集合”
|
|
|
|
#### `HANGKONG`
|
|
|
|
- 加入“已选中航空器集合”
|
|
- 用于参与航空器相关碰撞/安全区计算
|
|
|
|
#### `PUTONG`
|
|
|
|
- 仅记录类型
|
|
- 不进入可控/受管/已选航空器集合
|
|
|
|
#### `JIUYUAN`
|
|
|
|
- 仅记录类型
|
|
- 不进入可控/受管/已选航空器集合
|
|
|
|
### 3.8 成功响应
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"updatedAt": 1742280000000,
|
|
"updated": 3,
|
|
"controllableCount": 1,
|
|
"typesCount": {
|
|
"WUREN": 1,
|
|
"TEQIN": 1,
|
|
"HANGKONG": 1
|
|
},
|
|
"controllableVehicleIDs": ["QN001"]
|
|
}
|
|
```
|
|
|
|
### 3.9 响应字段说明
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|---|---|---|
|
|
| `status` | `string` | 固定为 `success` |
|
|
| `updatedAt` | `number` | 毫秒时间戳 |
|
|
| `updated` | `number` | 本次成功处理的条目数 |
|
|
| `controllableCount` | `number` | 当前系统内全部 `WUREN` 总数 |
|
|
| `typesCount` | `object` | 本次请求内各类型数量统计 |
|
|
| `controllableVehicleIDs` | `string[]` | 当前系统内全部可控车辆 ID 列表,即所有 `WUREN` |
|
|
|
|
### 3.10 错误响应示例
|
|
|
|
#### 请求体不是数组
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Body must be an array"
|
|
}
|
|
```
|
|
|
|
#### 参数非法
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Invalid request",
|
|
"errors": [
|
|
"item must be an object",
|
|
"missing vehicleID",
|
|
"missing vehicleType",
|
|
"vehicleID must be string",
|
|
"vehicleType must be string",
|
|
"vehicleID must be non-empty",
|
|
"invalid vehicleType=xxx"
|
|
]
|
|
}
|
|
```
|
|
|
|
#### 非法 JSON
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Invalid JSON",
|
|
"detail": "..."
|
|
}
|
|
```
|
|
|
|
### 3.11 前端调用示例
|
|
|
|
```ts
|
|
await fetch(`${API_BASE}/api/VehicleRegistry`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify([
|
|
{ vehicleID: 'QN001', vehicleType: 'WUREN' },
|
|
{ vehicleID: 'TQ001', vehicleType: 'TEQIN' },
|
|
{ vehicleID: 'AC001', vehicleType: 'HANGKONG' }
|
|
])
|
|
});
|
|
```
|
|
|
|
### 3.12 接入建议
|
|
|
|
- 页面首次拿到关注对象列表后调用一次
|
|
- 当前关注对象发生变化时再次调用
|
|
- 请求体必须是数组,即使只有一条数据也必须传数组
|
|
- 后端是“增量更新”,不要假设未传对象会被清空
|
|
|
|
## 4. 接口二:跑道区域航空器预警区半径
|
|
|
|
### 4.1 接口地址
|
|
|
|
```http
|
|
POST /config/runway/warning_zone_radius/aircraft
|
|
```
|
|
|
|
### 4.2 用途
|
|
|
|
前端运行时修改跑道区域的“航空器预警区半径”。
|
|
|
|
### 4.3 请求头
|
|
|
|
```http
|
|
Content-Type: application/json
|
|
```
|
|
|
|
### 4.4 请求体
|
|
|
|
```json
|
|
{ "value": 300 }
|
|
```
|
|
|
|
### 4.5 字段说明
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|---|---|---|---|
|
|
| `value` | `number` | 是 | 必须是大于 0 的有限数值 |
|
|
|
|
### 4.6 成功响应
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"area": "runway",
|
|
"field": "warning_zone_radius.aircraft",
|
|
"old": 200.0,
|
|
"new": 300.0
|
|
}
|
|
```
|
|
|
|
### 4.7 错误响应示例
|
|
|
|
#### 缺少字段
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Missing field: value"
|
|
}
|
|
```
|
|
|
|
#### 值非法
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Invalid value: must be a finite number greater than 0"
|
|
}
|
|
```
|
|
|
|
#### 非法 JSON
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Invalid JSON",
|
|
"detail": "..."
|
|
}
|
|
```
|
|
|
|
#### 字段类型错误
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Invalid field type",
|
|
"detail": "..."
|
|
}
|
|
```
|
|
|
|
### 4.8 前端调用示例
|
|
|
|
```ts
|
|
await fetch(`${API_BASE}/config/runway/warning_zone_radius/aircraft`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ value: 300 })
|
|
});
|
|
```
|
|
|
|
## 5. 接口三:跑道区域航空器告警区半径
|
|
|
|
### 5.1 接口地址
|
|
|
|
```http
|
|
POST /config/runway/alert_zone_radius/aircraft
|
|
```
|
|
|
|
### 5.2 用途
|
|
|
|
前端运行时修改跑道区域的“航空器告警区半径”。
|
|
|
|
### 5.3 请求体
|
|
|
|
```json
|
|
{ "value": 200 }
|
|
```
|
|
|
|
### 5.4 成功响应
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"area": "runway",
|
|
"field": "alert_zone_radius.aircraft",
|
|
"old": 150.0,
|
|
"new": 200.0
|
|
}
|
|
```
|
|
|
|
### 5.5 前端调用示例
|
|
|
|
```ts
|
|
await fetch(`${API_BASE}/config/runway/alert_zone_radius/aircraft`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ value: 200 })
|
|
});
|
|
```
|
|
|
|
### 5.6 说明
|
|
|
|
该接口的请求规则、错误规则与“预警区半径”接口一致,唯一差异是:
|
|
|
|
- 路径不同
|
|
- 成功响应中的 `field` 固定为 `alert_zone_radius.aircraft`
|
|
|
|
## 6. 接口四:冲突解除距离阈值
|
|
|
|
### 6.1 接口地址
|
|
|
|
```http
|
|
POST /config/collision/diverging_release_distance
|
|
```
|
|
|
|
### 6.2 用途
|
|
|
|
前端运行时修改“冲突解除距离阈值”。
|
|
|
|
### 6.3 请求体
|
|
|
|
```json
|
|
{ "value": 50 }
|
|
```
|
|
|
|
### 6.4 成功响应
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"area": "collision",
|
|
"field": "collision.diverging_release_distance",
|
|
"old": 40.0,
|
|
"new": 50.0
|
|
}
|
|
```
|
|
|
|
### 6.5 前端调用示例
|
|
|
|
```ts
|
|
await fetch(`${API_BASE}/config/collision/diverging_release_distance`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ value: 50 })
|
|
});
|
|
```
|
|
|
|
### 6.6 说明
|
|
|
|
该接口的请求规则、错误规则与前两个配置接口一致,唯一差异是:
|
|
|
|
- 路径不同
|
|
- 成功响应中的:
|
|
- `area` 固定为 `collision`
|
|
- `field` 固定为 `collision.diverging_release_distance`
|
|
|
|
## 7. 推荐前端封装
|
|
|
|
### 7.1 通用 POST JSON 请求
|
|
|
|
```ts
|
|
async function postJson<T>(url: string, body: unknown): Promise<T> {
|
|
const response = await fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(body)
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
throw data;
|
|
}
|
|
|
|
return data as T;
|
|
}
|
|
```
|
|
|
|
### 7.2 类型定义
|
|
|
|
```ts
|
|
type VehicleType = 'WUREN' | 'TEQIN' | 'HANGKONG' | 'PUTONG' | 'JIUYUAN';
|
|
|
|
interface VehicleRegistryItem {
|
|
vehicleID: string;
|
|
vehicleType: VehicleType;
|
|
}
|
|
|
|
interface VehicleRegistryResponse {
|
|
status: 'success';
|
|
updatedAt: number;
|
|
updated: number;
|
|
controllableCount: number;
|
|
typesCount: Record<string, number>;
|
|
controllableVehicleIDs: string[];
|
|
}
|
|
|
|
interface ConfigUpdateResponse {
|
|
status: 'success';
|
|
area: string;
|
|
field: string;
|
|
old: number;
|
|
new: number;
|
|
}
|
|
|
|
interface ErrorResponse {
|
|
status: 'error';
|
|
message: string;
|
|
detail?: string;
|
|
errors?: string[];
|
|
}
|
|
```
|
|
|
|
### 7.3 接口封装示例
|
|
|
|
```ts
|
|
export async function syncVehicleRegistry(items: VehicleRegistryItem[]) {
|
|
return postJson<VehicleRegistryResponse>(`${API_BASE}/api/VehicleRegistry`, items);
|
|
}
|
|
|
|
export async function updateRunwayWarningRadius(value: number) {
|
|
return postJson<ConfigUpdateResponse>(
|
|
`${API_BASE}/config/runway/warning_zone_radius/aircraft`,
|
|
{ value }
|
|
);
|
|
}
|
|
|
|
export async function updateRunwayAlertRadius(value: number) {
|
|
return postJson<ConfigUpdateResponse>(
|
|
`${API_BASE}/config/runway/alert_zone_radius/aircraft`,
|
|
{ value }
|
|
);
|
|
}
|
|
|
|
export async function updateDivergingReleaseDistance(value: number) {
|
|
return postJson<ConfigUpdateResponse>(
|
|
`${API_BASE}/config/collision/diverging_release_distance`,
|
|
{ value }
|
|
);
|
|
}
|
|
```
|
|
|
|
## 8. 前端联调注意事项
|
|
|
|
### 8.1 `VehicleRegistry`
|
|
|
|
- 请求体必须是数组
|
|
- `vehicleID` 不能为空字符串
|
|
- `vehicleType` 必须严格使用大写枚举值
|
|
- 该接口是“增量更新”,未传对象不会被后端自动删除
|
|
|
|
### 8.2 配置接口
|
|
|
|
- `value` 必须是 `number`
|
|
- 不要传字符串,例如 `"300"` 是错误的
|
|
- 必须大于 `0`
|
|
|
|
### 8.3 跨域问题
|
|
|
|
- 当前后端未配置 CORS
|
|
- 如果前端页面和后端接口不是同域同端口,浏览器可能拦截
|
|
- 如出现跨域报错,需要后端后续补 CORS 配置
|
|
|
|
### 8.4 生效方式
|
|
|
|
- 这 3 个配置接口修改后立即在当前服务进程内生效
|
|
- 服务重启后恢复默认值,不会持久化
|
|
|
|
## 9. 联调建议流程
|
|
|
|
### 9.1 第一步:先调对象注册接口
|
|
|
|
确认前端能成功将当前关注对象同步给后端。
|
|
|
|
### 9.2 第二步:再调配置接口
|
|
|
|
确认预警半径、告警半径、冲突解除距离可运行时修改。
|
|
|
|
### 9.3 第三步:观察业务联动
|
|
|
|
重点观察:
|
|
|
|
- 碰撞检测结果是否按新对象范围生效
|
|
- 跑道区域预警/告警范围是否按新阈值变化
|
|
- 冲突解除逻辑后续接入时是否读取当前运行时配置
|
|
|
|
## 10. 最小联调示例
|
|
|
|
```ts
|
|
async function initPlatformObjects() {
|
|
await syncVehicleRegistry([
|
|
{ vehicleID: 'QN001', vehicleType: 'WUREN' },
|
|
{ vehicleID: 'TQ001', vehicleType: 'TEQIN' },
|
|
{ vehicleID: 'AC001', vehicleType: 'HANGKONG' }
|
|
]);
|
|
}
|
|
|
|
async function updateRuntimeConfig() {
|
|
await updateRunwayWarningRadius(300);
|
|
await updateRunwayAlertRadius(200);
|
|
await updateDivergingReleaseDistance(50);
|
|
}
|
|
```
|
|
|
|
## 11. 接口清单汇总
|
|
|
|
| 接口 | 方法 | 用途 |
|
|
|---|---|---|
|
|
| `/api/VehicleRegistry` | `POST` | 同步当前关心对象及类型 |
|
|
| `/config/runway/warning_zone_radius/aircraft` | `POST` | 修改跑道区域航空器预警区半径 |
|
|
| `/config/runway/alert_zone_radius/aircraft` | `POST` | 修改跑道区域航空器告警区半径 |
|
|
| `/config/collision/diverging_release_distance` | `POST` | 修改冲突解除距离阈值 |
|