diff --git a/backend/api/api使用说明.md b/backend/api/api使用说明.md new file mode 100644 index 0000000..be5868a --- /dev/null +++ b/backend/api/api使用说明.md @@ -0,0 +1,322 @@ +# SmartEDT 后端 API 使用说明(Web 前端) + +本文档面向 Web 前端调用方,按当前后端代码实现汇总接口清单、鉴权方式、请求/响应示例与常见错误。 + +## 1. 基本约定 + +- 服务地址:`http://:5000` +- JSON 请求: + - Header:`Content-Type: application/json` + - Body:UTF-8 JSON +- 鉴权: + - 需要登录的接口统一使用 Header:`Authorization: Bearer ` +- 返回错误: + - `401`:未登录 / token 缺失或无效 + - `403`:无权限(当前多数管理接口仅允许管理员 `role_id=admin`) + - `404`:资源不存在 + - `409`:资源冲突(例如唯一键冲突、系统已初始化) + +## 2. 鉴权(Auth) + +### 2.1 首次初始化(创建首个管理员) + +仅当系统还没有任何用户时可调用;成功后返回 token 与用户信息。 + +- `POST /api/auth/bootstrap` + +请求: +```json +{ + "username": "admin", + "password": "Admin123!", + "display_name": "系统管理员" +} +``` + +响应: +```json +{ + "token": { + "access_token": "v1....", + "token_type": "bearer", + "expires_in": 3600 + }, + "user": { + "user_id": "user_...", + "username": "admin", + "display_name": "系统管理员", + "role_id": "admin", + "role_name": "系统管理员", + "is_active": true, + "last_login_at": null, + "created_at": "2026-01-01T00:00:00+00:00", + "updated_at": "2026-01-01T00:00:00+00:00", + "extra": null + } +} +``` + +### 2.2 登录获取 token + +- `POST /api/auth/login` + +请求: +```json +{ + "username": "admin", + "password": "Admin123!" +} +``` + +响应:同 `bootstrap`(`token + user`)。 + +### 2.3 获取当前登录用户 + +- `GET /api/auth/me` +- Header:`Authorization: Bearer ` + +响应: +```json +{ + "user": { + "user_id": "user_...", + "username": "admin", + "display_name": "系统管理员", + "role_id": "admin", + "role_name": "系统管理员", + "is_active": true, + "last_login_at": "2026-01-01T00:00:00+00:00", + "created_at": "2026-01-01T00:00:00+00:00", + "updated_at": "2026-01-01T00:00:00+00:00", + "extra": null + } +} +``` + +### 2.4 前端请求封装(示例) + +```js +async function apiFetch(path, { token, method = "GET", body } = {}) { + const headers = { "Content-Type": "application/json" }; + if (token) headers.Authorization = `Bearer ${token}`; + const res = await fetch(`http://127.0.0.1:5000${path}`, { + method, + headers, + body: body ? JSON.stringify(body) : undefined, + }); + if (!res.ok) throw new Error(await res.text()); + return await res.json(); +} +``` + +## 3. 用户管理(仅管理员) + +### 3.1 用户列表 +- `GET /api/users` + +### 3.2 用户详情 +- `GET /api/users/{user_id}` + +### 3.3 创建用户 +- `POST /api/users` + +请求: +```json +{ + "username": "teacher01", + "display_name": "李老师", + "password": "123456", + "role_id": "teacher", + "is_active": true, + "extra": {} +} +``` + +### 3.4 更新用户 +- `PATCH /api/users/{user_id}` + +请求(示例:变更角色): +```json +{ + "role_id": "auditor" +} +``` + +### 3.5 禁用用户(软删除) +- `DELETE /api/users/{user_id}` + +### 3.6 重置密码 +- `PUT /api/users/{user_id}/password` + +请求: +```json +{ + "new_password": "NewPass123!" +} +``` + +## 4. 角色/权限管理(仅管理员) + +### 4.1 角色 +- `GET /api/roles` +- `GET /api/roles/{role_id}` +- `POST /api/roles` +- `PATCH /api/roles/{role_id}` +- `DELETE /api/roles/{role_id}`(禁用) + +创建角色请求示例: +```json +{ + "role_id": "trainer", + "role_name": "教练", + "role_desc": "训练教练角色", + "is_active": true, + "extra": {} +} +``` + +### 4.2 权限点 + +- `GET /api/permissions` +- `POST /api/permissions` +- `DELETE /api/permissions/{perm_code}` + +创建权限点请求示例: +```json +{ + "perm_code": "report:export", + "perm_name": "报表导出", + "perm_group": "report", + "perm_desc": "允许导出报表" +} +``` + +### 4.3 给角色配置权限点 + +- `GET /api/roles/{role_id}/permissions` +- `PUT /api/roles/{role_id}/permissions`(覆盖设置) + +请求示例: +```json +{ + "perm_codes": ["report:export", "report:view"] +} +``` + +## 5. 仿真控制(基础接口) + +### 5.1 查询设备状态(示例) +- `GET /api/devices` + +### 5.2 启动仿真 +- `POST /api/simulation/start` + +请求示例: +```json +{ + "scenario": "紧急制动测试", + "weather": "sunny", + "time_period": "day", + "max_speed_kmh": 120, + "duration_minutes": 10, + "driver": "张三", + "extra": {} +} +``` + +响应: +```json +{ "simulation_id": "SIM20260101120000ABCD" } +``` + +说明: +- 当前后端会在数据库中创建一条仿真任务记录,并启动本地 mock 设备采样。 +- 若已启用 Unity Socket,启动/停止会自动下发 `Command(action=start/stop)`。 + +### 5.3 停止仿真 +- `POST /api/simulation/{simulation_id}/stop` + +响应: +```json +{ "simulation_id": "SIM...", "status": "stopped" } +``` + +## 6. Unity 数据交互(仅管理员) + +该模块用于将 `InitConfig` 与 `Command` 通过 Socket 转发给 Unity 程序(同时在数据库记录)。 + +### 6.1 发送 InitConfig(主控 → Unity) + +- `POST /api/unity/initconfig` + +请求: +```json +{ + "payload": { + "msgType": "init", + "timestamp": 1737388800000, + "session": { + "sessionId": "sess_20250120_143000_001", + "taskId": "task_brake_001", + "taskName": "紧急制动测试", + "createTime": "2025-01-20 14:30:00", + "syncTimestamp": 1737388800000 + }, + "driver": { "driverId": "D20250001", "name": "张三" }, + "vehicle": { "vehicleId": "V003", "model": "改装教学车A型" }, + "scene": { "sceneId": "scene_03", "sceneName": "城市道路" } + } +} +``` + +响应: +```json +{ "simulation_id": "task_brake_001" } +``` + +说明: +- 后端会把 `payload` 存入 `sim_tasks.init_config`,并记录 `init_sent_at`。 +- `simulation_id` 当前等于 `payload.session.taskId`(若该值长度不合规则会自动生成)。 + +### 6.2 发送 Command(主控 → Unity) + +- `POST /api/unity/command` + +请求示例: +```json +{ + "payload": { + "msgType": "command", + "action": "start", + "mode": { "type": "realtime" } + } +} +``` + +响应: +```json +{ "ok": true } +``` + +说明: +- 如果请求体未传 `timestamp/seqId`,后端会自动补齐。 + +## 7. 文件下载 + +- `GET /files/{file_path}` + +说明: +- `file_path` 必须是相对路径,后端会做目录穿越校验。 + +## 8. WebSocket(服务端推送) + +- 地址:`ws://:5000/ws` +- 当前实现:无需鉴权;连接建立后服务端会主动广播各类事件。 + +常见消息类型(`message.type`): +- `server.metrics`:服务器监控指标 +- `simulation.status`:仿真状态变化(running/stopped) +- `vehicle.signal`:车辆信号数据(采样 + 广播) +- `simulation.init_config`:调用 `/api/unity/initconfig` 后的广播回显 +- `simulation.command`:调用 `/api/unity/command` 后的广播回显 +