# SimpleLite 面向咪咕平台数据 API 文档

> **版本**：与 SimpleLite 源码同步  
> **更新日期**：2026-06-18  
> **服务栈**：EmbedIO WebApi（非 ASP.NET Core）  
> **OpenAPI**：`Docs/openapi/simplelite-projection.json`（已在 MiGu.Server Swagger UI 中展示）

---

## 1. 架构与访问路径

SimpleLite 在进程内启动 HTTP 投影服务，默认监听 `http://127.0.0.1:8222`。咪咕平台后端 **MiGu.Server** 通过 YARP 反向代理将请求转发到 SimpleLite。

| 层级 | 前缀 | 说明 |
|------|------|------|
| 直连 SimpleLite | `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
    ▼
SimpleLite :8222  (/projection/*)
```

### 1.1 鉴权

| 场景 | 要求 |
|------|------|
| 经 MiGu.Server 访问 | 需登录 JWT（`Authorization: Bearer` 或 Cookie `simple.auth.token`）；YARP 自动注入 `X-Platform-Internal-Token` |
| 直连 SimpleLite | 本机回环（127.0.0.1 / ::1）默认放行；远程需携带与 MiGu.Server 共享的 `X-Platform-Internal-Token` |

Token 解析优先级（SimpleLite 侧）：

1. `simple.json` → `platform.internalToken`
2. 环境变量 `SIMPLELITE__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 + SimpleLite 全部 WebApi）
- SimpleLite 相关接口标签前缀为 `SimpleLite/`

---

## 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": "SimpleLite.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("SimpleLite")` 向 SimpleLite 开放。**插件在 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/`：

| 文件 | 对应 SimpleLite 前缀 |
|------|----------------------|
| `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/*` → SimpleLite |
| SimpleLite 投影 API | 8222 | `/projection/*` |
| SimpleLite webVRender | 8223 | `/vr/*`（3D 嵌入 UI，非数据 API） |

**健康检查**：`GET http://localhost:8080/api/health/simplelite`

**本地联调**：

```powershell
# 1. 启动 SimpleLite（或登录 MiGu.Server 后自动拉起）
# 2. 启动 MiGu.Server
# 3. 浏览器打开 http://localhost:8080/swagger
# 4. 授权 Bearer token 后测试 /api/sl/projection/cars
```
