新增磁导航内部交管和信号交互界面

This commit is contained in:
ykkokluo
2026-08-24 16:16:58 +08:00
parent 125372b157
commit 134c7480b3
21 changed files with 1188 additions and 16 deletions
@@ -0,0 +1,112 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiGu.Server.Configs;
using MiGu.Server.Signal;
namespace MiGu.Server.Controllers;
/// <summary>
/// 迷毂「数据中心」:把 scene.signal 的 Model JSON 以表格读写(PLC 握手 / 磁条交管)。
/// 文件落在 SimpleLite 工作目录 <c>Config/Signal/*.json</c>,不依赖 SimpleLite 进程是否在跑。
/// </summary>
[ApiController]
[Authorize(Policy = "PlatformScope")]
[Route("api/signal-data")]
public sealed class SignalDataController : ControllerBase
{
private readonly SignalDataStore _store;
private readonly ConfigStore _config;
public SignalDataController(SignalDataStore store, ConfigStore config)
{
_store = store;
_config = config;
}
[HttpGet]
public IActionResult List([FromQuery] bool summary = false)
{
var enabled = SignalEnabled();
var tables = summary
? _store.GetTables().Select(ProjectSummary).ToList()
: _store.GetTables().Select(ProjectTable).ToList();
return Ok(new
{
signalEnabled = enabled,
workingDirectory = _store.ResolveWorkingDirectory(),
tables
});
}
[HttpGet("{id}")]
public IActionResult Get(string id)
{
var table = _store.Find(id);
if (table == null)
return NotFound(new { message = $"未知数据表:{id}" });
return Ok(ProjectTable(table));
}
[HttpPut("{id}")]
public IActionResult Save(string id, [FromBody] JsonElement body)
{
var table = _store.Find(id);
if (table == null)
return NotFound(new { message = $"未知数据表:{id}" });
if (!body.TryGetProperty("rows", out var rowsEl) || rowsEl.ValueKind != JsonValueKind.Array)
return BadRequest(new { message = "请求体需要 rows 数组" });
JsonArray rows;
try
{
rows = JsonNode.Parse(rowsEl.GetRawText()) as JsonArray ?? new JsonArray();
}
catch (Exception ex)
{
return BadRequest(new { message = $"rows 不是合法 JSON 数组:{ex.Message}" });
}
try
{
_store.SaveRows(table, rows);
}
catch (Exception ex)
{
return StatusCode(500, new { message = $"保存失败:{ex.Message}" });
}
return Ok(ProjectTable(table));
}
private object ProjectSummary(SignalTableDef table) => new
{
id = table.Id,
title = table.Title,
category = table.Category,
fileName = table.FileName
};
private object ProjectTable(SignalTableDef table)
{
var (path, error) = _store.ResolveFile(table, createDir: false);
var exists = path != null && System.IO.File.Exists(path);
return new
{
id = table.Id,
title = table.Title,
category = table.Category,
fileName = table.FileName,
exists,
error,
columns = table.Columns,
rows = _store.LoadRows(table)
};
}
private bool SignalEnabled() =>
_config.GetDeployment().ToLauncherSceneIds()
.Contains(DeploymentProfile.SignalSceneId, StringComparer.OrdinalIgnoreCase);
}
+3 -4
View File
@@ -84,9 +84,8 @@ public class WizardController : ControllerBase
// 平台 → 内核联动:把导航选型写入 SimpleLite 的 plugins/active-scenes.json(下次启动选择性加载;
// 已运行实例可由前端再调 POST /api/sl/projection/scenes/apply 触发增量 reload)。
// scene.device(门/充电桩/按钮盒驱动)为各类项目通用能力,向导暂无独立选项,固定并入激活集合;
// scene.vda5050 等协议插件保持按需(不在集合则不加载)。基座 StandardScene.dll 由内核按
// 清单 requiresCore 自动 alwaysLoad,无需在此声明。
var sceneIds = profile.ToActiveSceneIds().Concat(new[] { "scene.device" }).Distinct().ToList();
// 磁导航选型时 ToLauncherSceneIds 会并入 scene.signalPLC 握手 + 磁条交管)。
var sceneIds = profile.ToLauncherSceneIds();
var write = _launcher.WriteActiveScenes(sceneIds, alwaysLoad: null, source: "deployment-profile");
_log.LogInformation("部署向导已保存 by={User} nav=[{Nav}] scenes=[{Scenes}] activeScenesWritten={Ok}",
@@ -116,7 +115,7 @@ public class WizardController : ControllerBase
navigationKinds = dp.NavigationKinds,
scenarios = dp.Scenarios,
updatedBy = dp.UpdatedBy,
activeSceneIds = dp.ToActiveSceneIds(),
activeSceneIds = dp.ToLauncherSceneIds(),
hiddenPages = DeploymentCatalog.HiddenPages(dp),
activeScenesWrite = write == null ? null : new
{