配置段/环境变量、Launcher、健康检查 API、OpenAPI 与前后端文案同步;兼容探测旧 SimpleLite 进程名。 Co-authored-by: Cursor <cursoragent@cursor.com>
497 lines
17 KiB
Markdown
497 lines
17 KiB
Markdown
# Simple3 面向咪咕平台数据 API 文档
|
||
|
||
> **版本**:与 Simple3 源码同步
|
||
> **更新日期**:2026-06-18
|
||
> **服务栈**:EmbedIO WebApi(非 ASP.NET Core)
|
||
> **OpenAPI**:`Docs/openapi/simple3-projection.json`(已在 MiGu.Server Swagger UI 中展示)
|
||
|
||
---
|
||
|
||
## 1. 架构与访问路径
|
||
|
||
Simple3 在进程内启动 HTTP 投影服务,默认监听 `http://127.0.0.1:8222`。咪咕平台后端 **MiGu.Server** 通过 YARP 反向代理将请求转发到 Simple3。
|
||
|
||
| 层级 | 前缀 | 说明 |
|
||
|------|------|------|
|
||
| 直连 Simple3 | `http://127.0.0.1:8222/projection/...` | 开发调试、本机回环 |
|
||
| 经 MiGu.Server | `http://{host}:8080/api/sl/projection/...` | 平台前端/运维正式入口 |
|
||
|
||
```
|
||
浏览器 / Vue SPA
|
||
│ Authorization: Bearer {JWT}
|
||
▼
|
||
MiGu.Server :8080 (/api/sl/*)
|
||
│ 追加 X-Platform-Internal-Token
|
||
▼
|
||
Simple3 :8222 (/projection/*)
|
||
```
|
||
|
||
### 1.1 鉴权
|
||
|
||
| 场景 | 要求 |
|
||
|------|------|
|
||
| 经 MiGu.Server 访问 | 需登录 JWT(`Authorization: Bearer` 或 Cookie `simple.auth.token`);YARP 自动注入 `X-Platform-Internal-Token` |
|
||
| 直连 Simple3 | 本机回环(127.0.0.1 / ::1)默认放行;远程需携带与 MiGu.Server 共享的 `X-Platform-Internal-Token` |
|
||
|
||
Token 解析优先级(Simple3 侧):
|
||
|
||
1. `simple.json` → `platform.internalToken`
|
||
2. 环境变量 `SIMPLE3__PLATFORM__INTERNALTOKEN`
|
||
3. `Platform.Server/data/.internal-token` 或 `MiGu.Server/data/.internal-token`
|
||
|
||
### 1.2 通用响应格式
|
||
|
||
**投影快照类**(`ProjectionWebApiController`)直接返回 JSON 数组或对象,无统一信封。
|
||
|
||
**反射 / 地图编辑 / 工具栏 / 诊断 / AI 配置类** 使用统一信封:
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"code": 200,
|
||
"data": { },
|
||
"message": "Success"
|
||
}
|
||
```
|
||
|
||
失败时 `success=false`,`code` 为 HTTP 语义码(400/500 等),`message` 为错误说明。
|
||
|
||
### 1.3 Swagger 查看
|
||
|
||
开发环境下启动 MiGu.Server 后访问:
|
||
|
||
- **统一文档**:`http://localhost:8080/swagger`(含 MiGu.Server 自有 API + Simple3 全部 WebApi)
|
||
- Simple3 相关接口标签前缀为 `Simple3/`
|
||
|
||
---
|
||
|
||
## 2. 实时数据流(SSE)
|
||
|
||
| 方法 | 路径(MiGu.Server) | 说明 |
|
||
|------|---------------------|------|
|
||
| GET | `/api/sl/projection/stream` | Server-Sent Events 实时推送 |
|
||
|
||
**Content-Type**:`text/event-stream`
|
||
|
||
**事件类型**:
|
||
|
||
| event | 说明 |
|
||
|-------|------|
|
||
| `snapshot-tick` | 连接建立时立即推送当前快照 |
|
||
| `car-state` | 车辆状态增量 |
|
||
| `mission-status` | 任务状态增量 |
|
||
| `selection-detail` | 选中对象详情变更 |
|
||
| `heartbeat` | 保活(约 15s) |
|
||
|
||
地图编辑写操作完成后也会通过此通道广播增量,供多 Tab / 3D 视口同步。
|
||
|
||
---
|
||
|
||
## 3. 投影快照 API
|
||
|
||
**前缀**:`/api/sl/projection`
|
||
**控制器**:`ProjectionWebApiController.cs`
|
||
**用途**:运营监控、工作台列表、选中详情、配送单管理
|
||
|
||
### 3.1 只读快照
|
||
|
||
| 方法 | 路径 | 说明 | 查询参数 |
|
||
|------|------|------|----------|
|
||
| GET | `/cars` | 全部车辆快照 | — |
|
||
| GET | `/missions` | 全部任务快照 | — |
|
||
| GET | `/sites` | 全部站点 | — |
|
||
| GET | `/tracks` | 全部路径 | — |
|
||
| GET | `/deliveries` | 配送单列表 | `includeFinished`(默认 true)、`includeAborted`(默认 true) |
|
||
| GET | `/fleet/health` | 车队健康探测 | — |
|
||
| GET | `/workbench/{nav}` | 工作台分页列表 | `nav` ∈ map / car / process / scene / script |
|
||
| GET | `/selection/detail` | 选中对象详情面板 | `objectKind`/`kind`、`objectId`/`id`、`tab`(默认 properties) |
|
||
|
||
**车辆字段示例**(`GET /cars`):
|
||
|
||
```json
|
||
{
|
||
"id": "C01",
|
||
"name": "AGV-1",
|
||
"typeName": "Simple3.RCS.CarTypes.Car",
|
||
"rawId": 1,
|
||
"x": 1200.5,
|
||
"y": 800.0,
|
||
"theta": 1.57,
|
||
"batterySoc": 0.85,
|
||
"state": "running",
|
||
"lastUpdate": "2026-06-09T08:00:00.0000000Z",
|
||
"group": "main",
|
||
"address": "tcp://192.168.1.10:5000",
|
||
"ip": "192.168.1.10",
|
||
"onboardUrl": "http://192.168.1.10:8080",
|
||
"lstatus": "运行中"
|
||
}
|
||
```
|
||
|
||
**车辆 state 枚举**:`idle` / `running` / `paused` / `charging` / `fault` / `offline`(由 `lstatus` 中文/英文子串映射)
|
||
|
||
**任务 status 枚举**:`queued` / `running` / `paused` / `completed` / `cancelled` / `failed`
|
||
|
||
### 3.2 配送单操作
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/deliveries/{deliveryId}/cancel` | 取消配送单 |
|
||
| POST | `/deliveries/{deliveryId}/resend` | 重发配送单 |
|
||
| POST | `/deliveries/{deliveryId}/force-complete` | 强制完成 |
|
||
|
||
成功返回 `{ "success": true, "deliveryId": N }`,失败 HTTP 400。
|
||
|
||
---
|
||
|
||
## 4. 反射式通用 API
|
||
|
||
**前缀**:`/api/sl/projection/reflection`
|
||
**控制器**:`ReflectionApiController.cs`
|
||
**用途**:工作台动态渲染、字段读写、方法执行、插件管理、项目/应用配置
|
||
|
||
### 4.1 元数据与列表
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/kinds` | 顶级分类 KPI(map/car/process/scene/script)及 subKinds |
|
||
| GET | `/assemblies` | 已加载用户程序集列表 |
|
||
| GET | `/objects/{kind}` | 对象列表;`scene` 为 site+track+special 合成 |
|
||
| GET | `/types/{kind}` | 可实例化的 .NET 类型列表 |
|
||
| GET | `/methods/{kind}/{id}` | 单对象可执行方法表 |
|
||
| GET | `/methods-by-type/{kind}` | 按类型聚合的方法表 |
|
||
| GET | `/status/{kind}/{id}` | 对象运行状态键值 |
|
||
| GET | `/fields/{kind}/{id}` | 用户字段 + 成员字段 |
|
||
| GET | `/bundle/{kind}/{id}` | 对象 + 字段 + 方法 + 状态聚合包 |
|
||
|
||
**kind 取值**:`map` / `car` / `mission` / `site` / `track` / `special` / `scene`(合成)/ `script` / `process`
|
||
|
||
### 4.2 字段读写
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/fields/{kind}/{id}/{field}` | 写入字段(body: `{ "value": "..." }`) |
|
||
| DELETE | `/fields/{kind}/{id}/{field}` | 删除用户自定义字段 |
|
||
|
||
### 4.3 选中态
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/selection` | 当前选中对象 |
|
||
| POST | `/selection` | 设置选中(body: `{ "kind", "id" }`) |
|
||
| POST | `/selection/clear` | 清除选中 |
|
||
|
||
### 4.4 对象 CRUD
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/objects/{kind}` | 创建对象(body 依 kind 类型) |
|
||
| DELETE | `/objects/{kind}/{id}` | 删除对象 |
|
||
|
||
### 4.5 方法执行
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET / POST | `/execute/{kind}/{id}/{method}` | 调用 `[MethodMember]` 装饰的方法;POST body 为参数 JSON 数组 |
|
||
| POST | `/car/{id}/goto-site` | 车辆前往站点(body: `{ "siteId": N }`) |
|
||
| POST | `/car/{id}/gotosite` | 同上(别名路由) |
|
||
|
||
### 4.6 脚本
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/scripts/{id}/source` | 脚本源码 |
|
||
| GET | `/scripts/{id}/exception-status` | 脚本异常状态 |
|
||
|
||
### 4.7 插件管理
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/plugins` | 已加载插件列表 |
|
||
| POST | `/plugins/reload` | 重新扫描并增量加载 |
|
||
| POST | `/plugins/{name}/unload` | 卸载指定插件(需重启才彻底移除) |
|
||
|
||
### 4.8 项目 / 应用 / 监控配置
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/project/fields` | 项目级字段 |
|
||
| POST | `/project/fields/{field}` | 写入项目字段 |
|
||
| POST | `/project/save` | 保存项目到磁盘 |
|
||
| GET | `/app-config/fields` | 应用配置字段 |
|
||
| POST | `/app-config/fields/{field}` | 写入应用配置字段 |
|
||
| POST | `/app-config/save` | 保存应用配置 |
|
||
| GET / POST | `/monitor-config` | 监控端配置读写 |
|
||
|
||
### 4.9 视口与车辆样式
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET / PATCH | `/viewport-style` | 3D 视口样式 |
|
||
| GET | `/car-style/types` | 车辆类型样式列表 |
|
||
| GET | `/car-types/coder-fields` | 所有插件车型的 Coder Fields 字段袋定义(Site/Track/Plan/Car) |
|
||
| GET / POST / DELETE | `/car-style/{typeFullName}` | 单类型样式 CRUD |
|
||
| GET / POST | `/car-style/alarm-colors` | 告警颜色配置 |
|
||
| POST | `/car-style/save` | 持久化样式到磁盘 |
|
||
|
||
### 4.10 车型 Coder Fields
|
||
|
||
**路径**:`GET /api/sl/projection/reflection/car-types/coder-fields`
|
||
|
||
返回所有已加载插件中带 `[CarType]` 的车型,及其脚本 Coder 使用的 **SiteFields / TrackFields / PlanFields / CarFields** 字段袋定义。字段来源:
|
||
|
||
- 车型类上的 `[TemplateTrackCoderSettings]` / `[TemplateSiteCoderSettings]`
|
||
- `[ProgramTrackCoderSettings]` 关联的 `ITrackCoder`(如 `CommonTemplateTrackCoder`、`MagneticTrackCoder`)
|
||
|
||
**响应示例**(`ReflectionEnvelope` 信封):
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"code": 200,
|
||
"message": "Success",
|
||
"data": [
|
||
{
|
||
"typeName": "StandardScene.CarTypes.Kiva",
|
||
"shortName": "Kiva",
|
||
"label": "Kiva",
|
||
"assemblyName": "StandardScene.QrLidar",
|
||
"siteFields": {
|
||
"typeName": "StandardScene.CarTypes.KivaSiteFields",
|
||
"shortName": "KivaSiteFields",
|
||
"assemblyName": "StandardScene.Core",
|
||
"baseTypeName": "StandardScene.CarTypes.BasicSiteFields",
|
||
"fields": [
|
||
{ "name": "Shelf", "typeName": "System.String", "defaultValue": "" },
|
||
{ "name": "FetchSpeed", "typeName": "System.Single", "defaultValue": 0 }
|
||
]
|
||
},
|
||
"trackFields": { "typeName": "StandardScene.CarTypes.KivaTrackFields", "fields": [] },
|
||
"planFields": { "typeName": "StandardScene.CarTypes.KivaPlanFields", "fields": [] },
|
||
"carFields": null
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**说明**:
|
||
|
||
| 字段 | 含义 |
|
||
|------|------|
|
||
| `siteFields` / `trackFields` / `planFields` / `carFields` | 该车型对应类别的字段袋;未注册时为 `null` |
|
||
| `fields[].name` | 字段名(对应 `site.fields` / `track.fields` 字典键) |
|
||
| `fields[].typeName` | .NET 字段类型全名 |
|
||
| `fields[].defaultValue` | 字段袋类声明时的默认值 |
|
||
|
||
同一车型若多个 Coder 引用不同 Fields 类型,接口会合并后取**最派生、字段最全**的类型(如 Kiva 取 `KivaTrackFields` 而非 `BasicTrackFields`)。返回的 `fields` 数组**包含继承链上全部 public 字段**(例如 `KivaTrackFields` 会同时包含 `BasicTrackFields` 的 `IOArea`、`Speed` 等基类字段)。
|
||
|
||
> **实现说明**:Fields 类在插件程序集中多为 `internal`;插件已通过 `InternalsVisibleTo("Simple3")` 向 Simple3 开放。**插件在 collectible ALC 中加载时**,SimpleCore 特性类型与宿主不一致,须通过 `CustomAttributeData` 读取 Coder 上的 `siteFields`/`trackFields` 等 metadata(不能依赖 `GetCustomAttributes(typeof(TemplateTrackCoderSettings))`)。`StandardScene.dll` 内 Fields 由 `CoderFieldsMetadata.Describe` 在 Core 程序集内反射导出。
|
||
|
||
---
|
||
|
||
## 5. 地图编辑 API
|
||
|
||
**前缀**:`/api/sl/projection/map-edit`
|
||
**控制器**:`MapEditApiController.cs`
|
||
**用途**:平台地图设计器(创建/删除图元、拾取、工程/地图管理、AI 生图、录制回放)
|
||
|
||
### 5.1 对象操作
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/objects/{kind}` | 创建图元;kind ∈ site/track/bezier/arc/nurbs/image/text/model |
|
||
| DELETE | `/objects/{kind}/{id}` | 删除图元 |
|
||
| POST | `/objects/batch` | 批量创建/更新/删除 |
|
||
| POST | `/objects/{kind}/{id}/fields/copy-to` | 字段复制到另一对象 |
|
||
| POST | `/objects/track/{id}/sample-sites` | 路径自动采样站点 |
|
||
| POST | `/pick` | 拾取会话(canvas 点击返回坐标与命中对象) |
|
||
|
||
### 5.2 仪表盘与资产
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/dashboard/summary` | 地图编辑 KPI 聚合 |
|
||
| POST | `/assets/upload` | 上传图片/模型资产 |
|
||
|
||
### 5.3 工程管理
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/project/current` | 当前打开的工程信息 |
|
||
| POST | `/project/save` | 保存工程 |
|
||
| POST | `/project/load` | 加载工程 |
|
||
| GET | `/project/browse` | 浏览工程目录 |
|
||
| POST | `/project/native-pick-open` | 原生文件对话框打开 |
|
||
| POST | `/project/native-pick-save` | 原生文件对话框保存 |
|
||
|
||
### 5.4 地图管理
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/maps` | 地图列表 |
|
||
| GET | `/maps/scene-task-status` | 场景任务状态 |
|
||
| POST | `/maps/save` | 保存当前地图 |
|
||
| POST | `/maps/open` | 打开地图 |
|
||
| POST | `/maps/use` | 切换使用地图 |
|
||
| POST | `/maps/rename` | 重命名地图 |
|
||
| DELETE | `/maps/{rawName}` | 删除地图 |
|
||
| POST | `/maps/merge` | 合并地图 |
|
||
|
||
### 5.5 视图 / 图层 / AI / 录制
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET / POST | `/view-filter` | 视图过滤器 |
|
||
| GET | `/layers` | 图层列表 |
|
||
| POST | `/layers/visible` | 设置图层可见性 |
|
||
| POST | `/ai/map-generate` | AI 自然语言生成地图元素 |
|
||
| GET | `/recording/status` | 录制状态 |
|
||
| POST | `/recording/start` | 开始录制 |
|
||
| POST | `/recording/stop` | 停止录制 |
|
||
| GET | `/recordings` | 录像文件列表 |
|
||
| POST | `/recordings/delete` | 删除录像 |
|
||
| POST | `/playback/start` | 开始回放 |
|
||
| POST | `/playback/stop` | 停止回放 |
|
||
|
||
---
|
||
|
||
## 6. 工作区工具栏 API
|
||
|
||
**前缀**:`/api/sl/projection/toolbar`
|
||
**控制器**:`WorkspaceToolbarApiController.cs`
|
||
**用途**:Embed/CanvasOnly iframe 底栏(对齐、选择、显示、图层、录制、相机)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/state` | 聚合读取全部工具栏状态 |
|
||
| POST | `/align` | 对齐吸附开关(sites/cars/tracks) |
|
||
| POST | `/select` | 选择过滤(tracks/cars/decor/sites) |
|
||
| POST | `/display` | 显示内容(labels/primitives/cars) |
|
||
| POST | `/layer` | 图层可见性 |
|
||
| POST | `/recording/start` | 开始录制 |
|
||
| POST | `/recording/stop` | 停止录制 |
|
||
| POST | `/recording/rename` | 重命名录像 |
|
||
| DELETE | `/recording/{fileName}` | 删除录像 |
|
||
| POST | `/playback/start` | 开始回放 |
|
||
| POST | `/playback/stop` | 停止回放 |
|
||
| POST | `/view/toggle` | 切换视图模式 |
|
||
| POST | `/camera/follow` | 相机跟随车辆 |
|
||
| POST | `/camera/locate` | 相机定位到坐标/对象 |
|
||
|
||
---
|
||
|
||
## 7. 场景插件 API(配置向导)
|
||
|
||
**前缀**:`/api/sl/projection/scenes`
|
||
**控制器**:`SceneApiController.cs`
|
||
**用途**:咪咕平台「配置向导」选择性加载导航场景插件
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/available` | plugins 目录下全部场景清单 |
|
||
| GET | `/active` | 当前激活集合及已加载画像 |
|
||
| POST | `/apply` | 写入 `active-scenes.json` 并增量 reload |
|
||
|
||
**POST /apply 请求体**:
|
||
|
||
```json
|
||
{
|
||
"activeScenes": ["scene-id-1", "scene-id-2"],
|
||
"alwaysLoad": ["common-plugin"],
|
||
"source": "wizard"
|
||
}
|
||
```
|
||
|
||
与 MiGu.Server `WizardController` 写配置后调用本接口联动。
|
||
|
||
---
|
||
|
||
## 8. 实时诊断 API
|
||
|
||
**前缀**:`/api/sl/projection/diagnosis`
|
||
**控制器**:`DiagnosisApiController.cs`
|
||
**用途**:平台「日志管理 → 实时诊断」只读查看内核 Diagnosis 内存态
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/all` | 全部诊断条目(合订标签 + 滚动记录) |
|
||
|
||
**响应 data 结构**:
|
||
|
||
```json
|
||
{
|
||
"serverTime": "2026-06-09T16:00:00.000",
|
||
"total": 42,
|
||
"taggedCount": 5,
|
||
"untaggedCount": 37,
|
||
"items": [
|
||
{ "index": 0, "time": "...", "tag": "Traffic", "tagged": true, "content": "..." }
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 9. AI 服务配置 API
|
||
|
||
**前缀**:`/api/sl/projection/ai-config`
|
||
**控制器**:`AiConfigController.cs`
|
||
**用途**:平台「系统配置 → AI 服务」表单读写
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/` | 读取配置(apiKey 脱敏为 `***last4`) |
|
||
| POST | `/` | 保存配置(脱敏占位符不覆盖原密钥) |
|
||
|
||
**配置字段**:`endpoint`、`apiKey`、`model`、`systemPrompt`、`temperature`、`maxTokens`、`timeoutSec`
|
||
|
||
---
|
||
|
||
## 10. 已下线接口
|
||
|
||
**前缀**:`/api/sl/projection/persistence/*`
|
||
**状态**:已在 `ProjectionWebHost` 中取消挂载,调用返回 **404**
|
||
|
||
| 原路径 | 说明 |
|
||
|--------|------|
|
||
| POST `/export-json` | 导出 JSON |
|
||
| POST `/import-json` | 导入 JSON |
|
||
| POST `/reload-from-db` | 从 DB 重载 |
|
||
| POST `/resume-missions` | 恢复任务 |
|
||
| GET `/status` | 持久化状态 |
|
||
| GET / PATCH `/scene-meta` | 场景元数据 |
|
||
|
||
---
|
||
|
||
## 11. 前端 API 胶水对照
|
||
|
||
咪咕 Vue 前端封装位于 `Migu2.0/frontends/apps/simple-platform-vue/src/api/`:
|
||
|
||
| 文件 | 对应 Simple3 前缀 |
|
||
|------|----------------------|
|
||
| `reflection.ts` | `/api/sl/projection/reflection` |
|
||
| `mapEdit.ts` | `/api/sl/projection/map-edit` |
|
||
| `workspaceToolbar.ts` | `/api/sl/projection/toolbar` |
|
||
| `logs.ts` | `/api/sl/projection/diagnosis` |
|
||
|
||
---
|
||
|
||
## 12. 端口与部署速查
|
||
|
||
| 服务 | 默认端口 | 路径 |
|
||
|------|----------|------|
|
||
| MiGu.Server | 8080 | `/api/sl/*` → Simple3 |
|
||
| Simple3 投影 API | 8222 | `/projection/*` |
|
||
| Simple3 webVRender | 8223 | `/vr/*`(3D 嵌入 UI,非数据 API) |
|
||
|
||
**健康检查**:`GET http://localhost:8080/api/health/simple3`
|
||
|
||
**本地联调**:
|
||
|
||
```powershell
|
||
# 1. 启动 Simple3(或登录 MiGu.Server 后自动拉起)
|
||
# 2. 启动 MiGu.Server
|
||
# 3. 浏览器打开 http://localhost:8080/swagger
|
||
# 4. 授权 Bearer token 后测试 /api/sl/projection/cars
|
||
```
|