Files
Migu2.0/PLATFORM_V3_CHANGES.md
T
黄兆尉andCursor 3686abdc78 将调度内核标识从 SimpleLite 全面重命名为 Simple3。
配置段/环境变量、Launcher、健康检查 API、OpenAPI 与前后端文案同步;兼容探测旧 SimpleLite 进程名。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-26 17:46:52 +08:00

12 KiB
Raw Blame History

平台 v3 重构 — 阶段 0~6 实际改动

范围:把 Simple3 WebTerminal 由"全功能浮动 Panel"模式收敛到"纯 3D Canvas",所有 UI 改由 Vue 平台前端 (frontends/apps/simple-platform-vue) 接管;同时补齐反射 / 编辑 / 监控 / 编排 4 大业务面板与撤销栈、AI 生图、报警 SSE 等关键能力。

基线:上一份方案见 ARCHITECTURE.md v2/v3 章节;后续以本文件为准。

编译验证

  • dotnet build Simple3/Simple3.csproj —— 0 警告 0 错误
  • dotnet build MiGu.Server/MiGu.Server.csproj —— 0 警告 0 错误
  • build-platform-frontend.bat —— vite build 46.5s,无 vue-tsc / ts 错误,robocopy /MIR 已同步 MiGu.Server/wwwroot
  • SimpleComposer (WinForms) 在 v3 之外,不在本次构建目标里
  • HttpClientHelper 提升 LangVersion=latest 修通

阶段 0:后端 Simple3 平台化(已完成)

新增文件

文件 作用
Simple3/Web/MapEditApiController.cs 写操作 8 路 APIcreate/delete/batch/copy-to/pick/dashboard/upload/ai-generate;阶段 6 又补:project/saveproject/loadproject/currentsample-sites-along-track
Simple3/Web/ReflectionApiController.cs 只读 + execute APIlistKinds / listObjects / methods-by-type / setField / getBundle / selection 等
Simple3/Web/ReflectionApiDtos.cs 反射 API DTO + 统一信封 ReflectionEnvelope<T>
Simple3/Web/AiCompletionService.cs OpenAI Function Calling 调用 + map-generate 工具桥(真实 LLM,不再桩)
Simple3/Web/AiConfigController.cs AI 服务配置(endpoint/apiKey/model/system prompt/temperature/maxTokens/timeout)读写
Simple3/Web/AlarmStreamService.cs 1s 周期 diff car.status.enums.AlarmInfo(语义与 E:\Work\FRLD\StandardScene\Forklift.csCommons.GetCarStatus(this, "AlarmInfo") 等价),变化时通过 SSE alarm 事件推送 raise/update/clear
Simple3/Web/ProjectionStreamModule.cs 平台 SSE 总线,对外广播 object-created / object-deleted / object-patched / object-batch-changed / alarm / pick-result / project-saved / project-loaded
Simple3/Web/PluginAssemblyScan.cs 反射扫描 plugins/*.dll,把 MethodMember 标注的方法 + Car/Mission/CarProgram/Site/Track 子类型暴露给反射 API

修改文件

文件 关键改动
Simple3/Startup.cs EntryPoint 第一步 EnsureImguiIniFromEmbedded();启动 AlarmStreamService、ProjectionStreamModule、AiConfig 加载
Simple3/UI/SimpleUI.cs CreateRemotePanelSetForTerminal 检测 CanvasOnly 旗标:不创建 Workbench / Toolbar / BottomBar / CAD / Welcome;保留 SelectionAction、SceneInput、SceneDrawable、2DMapView
Simple3/Workspace/WorkspaceWebUiContext.cs 增加 IsCanvasOnly(terminal) 旗标 + /declareCanvasOnly 注册器(与 /declareEmbedUi 互斥)
Simple3/Web/ProjectionWebHost.cs /declareCanvasOnly 路由注册
Simple3/Web/ProjectionWebApiController.cs 现有 projection API 上挂 selection-detail SSE hook
Simple3/UI/ComposerDockPanel.cs CanvasOnly 时 PrepareWelcomePanel 返回空
Simple3/Props/UIHelpers.cs 增加 UI_Image / UI_Text / UI_Model PropType。UI_Model 用于 CycleGUI 装饰物挂模型(obj/glb/gltf/cyclemodel

关键 API 路径

POST  /projection/map-edit/objects/{kind}          # site|track|bezier|arc|nurbs|image|text|model
DELETE /projection/map-edit/objects/{kind}/{id}
POST  /projection/map-edit/objects/batch           # create/delete/patch 混合
POST  /projection/map-edit/objects/{kind}/{id}/fields/copy-to
POST  /projection/map-edit/pick                    # 拾取会话
GET   /projection/map-edit/dashboard/summary       # KPI 聚合
POST  /projection/map-edit/assets/upload           # 图片/模型 base64
POST  /projection/map-edit/ai/map-generate         # 真实 LLM 生图

# 阶段 6 新增(本会话)
POST  /projection/map-edit/project/save            # body: { path?: string }
POST  /projection/map-edit/project/load            # body: { path: string }
GET   /projection/map-edit/project/current
POST  /projection/map-edit/objects/track/{id}/sample-sites
                                                   # body: { spacingMm, includeEndpoints?, layer? }

GET   /projection/ai-config                        # 读 AI 服务配置
POST  /projection/ai-config                        # 写 AI 服务配置

GET   /projection/reflection/kinds | objects/{kind} | methods/{kind}/{id} | ...
SSE   /projection/stream                            # 所有 SSE 事件

阶段 1MapEditorView 四栏壳(已完成)

frontends/apps/simple-platform-vue/src/views/admin/MapEditorView.vue 完整重写为:

┌─────────────────────────────────────────────────────┐
│ EditTopBar:项目 / 文件 / 编辑 / 视图 / 图层 / 对齐吸附 │
│             + 撤销/重做 + AI 生图 + 保存            │
├──────┬─────────────────────────┬───────────────────┤
│ Edit │   Workspace3D           │ EditPropertyPanel │
│ Tool │  (canvas-only iframe)   │ 对象/类型默认/图层 │
│ Rail │                         │                   │
├──────┴─────────────────────────┴───────────────────┤
│ EditStatusBar:选中 / 鼠标坐标 / 工具 / 吸附 / undo │
└─────────────────────────────────────────────────────┘

新增组件

  • components/map-editor/EditTopBar.vue —— 6 个 dropdown 菜单(项目/文件/编辑/视图/图层/对齐吸附)+ 撤销重做按钮 + AI 生图入口 + 保存
  • components/map-editor/EditToolRail.vue —— 6 组 CAD 工具按钮 + 吸附组(网格/对象/端点/中点 + 网格步长)
  • components/map-editor/EditPropertyPanel.vue —— 3 Tab(对象 / 类型默认 / 图层),自动反射出 getFields,每行可改可保存;多选时统一字段写入;不一致字段显示「-」;执行 reflectionApi.execute 调任何 MethodMember
  • components/map-editor/EditStatusBar.vue —— 状态栏
  • components/map-editor/AiGenerateDialog.vue —— AI 生图对话框

反射 API 接入

  • api/mapEdit.ts —— MapEditApiController 全 8+4 路 API 胶水(本会话补的 4 个:projectSave / projectLoad / projectCurrent / sampleSitesAlongTrack
  • api/reflection.ts —— ReflectionApiController 全套胶水(含 MOCK 离线 fallback

阶段 2:对齐 / 批量生成 / 复制字段 / 类型默认 / 图层(已完成)

  • composables/useAlignment.ts —— 11 种对齐模式:left/right/top/bottom/centerH/centerV/center/distributeH/distributeV/toFirst/toLast
  • composables/useBatchGenerate.ts —— 横向/纵向/矩阵/环形 4 种批量生成器,输出 BatchOp[]
  • composables/useClipboard.ts —— 对象/字段剪贴板
  • transform.copyFields 工具:MapEditorView runCopyFields 读取多选(第 1 个为源,其余目标),prompt 字段名列表,调 mapEditApi.copyFieldsTo;撤销时用前置 patch 回滚
  • 类型默认 Tab:站点/路径默认 layer/前缀/颜色/线宽,存 localStorage mapEditor.defaults
  • 图层 Tab:图层名列表 + 可见 / 可选 / 颜色,本地状态

阶段 3:AI 生图 + 状态栏 + 项目保存/加载(已完成)

  • AiGenerateDialog 通过 mapEditApi.aiMapGenerate 真实调用 LLM,后端走 AiCompletionService.GenerateMapAsync:用 OpenAI Function Calling 让 LLM 直接调 create_site / create_track / batch_create 等"工具",落地到 SimpleLib
  • 入口:EditTopBar 「AI 生图」按钮 → 弹对话框,参数:prompt / mode (sites/tracks/sites+tracks/full) / bounds / referenceImageBase64 / layer / constraints
  • 项目保存/加载:EditTopBar「保存」/「另存为」/「加载项目」→ prompt 输入路径 → 调 mapEditApi.projectSave/Load → 服务端走 SimpleProject.ToFile / FromFile;最近路径缓存到 localStorage mapEditor.lastProjectPath

阶段 4MapMonitor 浮动报警卡 + KPI + 实时列表(已完成)

frontends/apps/simple-platform-vue/src/views/admin/MapMonitorView.vue 改动:

  • 删除原 AlarmTicker.vue 底部滚动条
  • 新增 components/map-monitor/FloatingAlarmStack.vue + FloatingAlarmCard.vue,可拖动 / 可吸边 / 可堆叠
  • 报警来源走 useMapEditStream.onAlarm(订阅 SSE 的 alarm 事件,由 AlarmStreamService 1s diff 推送)
  • KPI 3 卡:在线车辆 / 运行中任务 / 排队任务
  • 实时列表:左侧 Workspace3D + 右侧 VehicleMonitorPanel + SelectionDetailPanel
  • 「定位」按钮通过 reflectionApi.setSelection('car', id) 让 Simple3 3D 高亮该车(视觉上等效 flyTo)

阶段 5OrchestrationView 设计与编排(已完成)

views/admin/OrchestrationView.vue 5-Tab 壳:

Tab 来源
车辆 复用现有 CarPanelView
进程 复用现有 MissionEditorView
脚本 components/orchestration/ReflectionKindTable.vuekind=script):动态列表 + 反射 method 执行
任务流 ReflectionKindTablekind=mission, extraFilter='taskflow'
触发器 ReflectionKindTablekind=mission, extraFilter='trigger'

Tab 状态缓存到 sessionStorage。

阶段 6:联调 / 撤销栈做实 / 文档(已完成)

撤销栈做实

composables/useHistory.ts 提供 run/undo/redo/composite,每个命令 apply/revert 双向。本次把 MapEditorView 里所有占位 revert 改成真实回滚:

命令 原 revert 现 revert
runCreateSite delete 创建的 id (未变)
handleTrackPick 创建路径 delete 创建的 id (未变)
deleteSelection ⚠️ 仅本地撤销 getBundle 抓快照 → batch.create 重建(id 重排)
onSetField 字段修改 ⚠️ 不回滚 getBundle 抓原值 → setField 回去
applyAlignment (已用 patch 反向恢复) (未变)
applyBatchAsCommand (已用 delete 反向移除) (未变)
runAlongPathSampling(新增) —— delete 所有采样产生的 site id
runCopyFields(新增) —— patch 反向把 targets 字段值恢复

沿路径采样

  • 后端:POST /projection/map-edit/objects/track/{id}/sample-sites { spacingMm, includeEndpoints?, layer? } —— 当前在 siteA → siteB 之间欧式直线均分(贝塞尔/弧的真实参数化采样留待后续 Track 子类 PR)
  • 前端:选中 1+ 条 track,工具栏「沿路径」→ prompt 间距和端点开关 → 调后端,撤销可回退

编译相关清理

  • Simple3/Recording/(之前的录制/回放实验目录)误用 Simple3.Rendering namespace、Car 找不到、Start(string, out) 默认参数顺序等 3 个错误 → 修
  • Simple3/Props/UISite.csSimple3.Props namespace 下 Workspace.AddProp 被解析成 Simple3.Workspace.AddProp → 改为全限定 CycleGUI.Workspace.AddProp
  • Simple3/Workspace/WorkspaceBottomBar.csusing Simple3.Workspace; → 补
  • HttpClientHelper.csproj LangVersion 7.3 → latest

已知 TODO(不阻塞 v3 上线)

  1. 贝塞尔/弧/Nurbs 路径的真实参数化采样(当前直线均分)
  2. 撤销栈跨 Tab / 跨 session 共享(当前仅 MapEditor 视图局部)
  3. Workspace3D 真正的 postMessage 'workspace.flyTo' 双向桥(当前用 setSelection 代替)
  4. 复制字段 UI 支持类型化字段挑选器(当前 prompt 输入字段名)
  5. AI 生图 OAuth/键持久化加密(当前明文存 config)
  6. Recording 录制/回放模块未完工(PlaybackController 已修通编译,UI 已挂底栏,但实际录制/回放业务逻辑需要后续单独 PR 完成)

启动方式

# 1. 后端 buildSimple3 + MiGu.Server
dotnet build Simple3\Simple3.csproj
dotnet build MiGu.Server\MiGu.Server.csproj

# 2. 前端打包并同步到 wwwroot
.\build-platform-frontend.bat

# 3. 启动平台 + Simple3
dotnet run --project MiGu.Server  # 监听 0.0.0.0:8080
# Simple3 端口 8222/8223 由 Simple3 自己启动

# 4. 访问
http://127.0.0.1:8080/admin/map-editor      # 地图编辑(v3 四栏壳)
http://127.0.0.1:8080/admin/map-monitor     # 地图监控(驾驶舱 + 浮动报警)
http://127.0.0.1:8080/admin/orchestration   # 设计与编排(5 Tab