将调度内核标识从 SimpleLite 全面重命名为 Simple3。
配置段/环境变量、Launcher、健康检查 API、OpenAPI 与前后端文案同步;兼容探测旧 SimpleLite 进程名。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,19 +12,17 @@ namespace MiGu.Server.Controllers;
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录请求体。
|
||||
/// 会话 N+1(启动反转):新增 <see cref="LaunchMode"/>。前端登录页让用户选 "WebOnly" / "DesktopAndWeb";
|
||||
/// MiGu.Server 据此拉起 SimpleLite 子进程并透传 <c>--display-mode=web|web+local</c>。
|
||||
/// 历史调用方不传该字段时默认 "DesktopAndWeb"(与之前 web+local 默认行为一致,向后兼容)。
|
||||
/// 登录请求体。可选 <see cref="LaunchMode"/>;Simple3 仅 Web 宿主,缺省/未知一律按 WebOnly。
|
||||
/// MiGu.Server 据此拉起子进程并透传 <c>--display-mode=web</c>。
|
||||
/// </summary>
|
||||
public record LoginRequest(string Username, string Password, string Scope, string? LaunchMode = null);
|
||||
public record LoginRequest(string Username, string Password, string? Scope = null, string? LaunchMode = null);
|
||||
|
||||
/// <summary>
|
||||
/// 登录响应。
|
||||
/// 会话 N+1 增量字段:
|
||||
/// <list type="bullet">
|
||||
/// <item><c>RunMode</c>:根据 SimpleLite 真实拉起结果回填(WebEnabled / WebOnly / Detached)。Detached 表示后端未能拉起 SimpleLite,前端可降级展示。</item>
|
||||
/// <item><c>LaunchStatus</c>:<see cref="SimpleLiteLauncher.LaunchResult.Status"/> 枚举字符串,前端用于精细化提示。</item>
|
||||
/// <item><c>RunMode</c>:根据 Simple3 真实拉起结果回填(WebEnabled / WebOnly / Detached)。Detached 表示后端未能拉起 Simple3,前端可降级展示。</item>
|
||||
/// <item><c>LaunchStatus</c>:<see cref="Simple3Launcher.LaunchResult.Status"/> 枚举字符串,前端用于精细化提示。</item>
|
||||
/// <item><c>LaunchWarning</c>:可空告警文本;非空时前端应该弹消息条告知用户。</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
@@ -51,17 +49,18 @@ public class AuthController : ControllerBase
|
||||
string Scope,
|
||||
string RunMode,
|
||||
EffectivePermissions EffectivePermissions,
|
||||
bool NeedsWizard = false);
|
||||
bool NeedsWizard = false,
|
||||
string? Token = null);
|
||||
|
||||
private const string CookieName = "simple.auth.token";
|
||||
|
||||
private readonly RbacStore _rbac;
|
||||
private readonly JwtIssuer _jwt;
|
||||
private readonly SimpleLiteLauncher _launcher;
|
||||
private readonly Simple3Launcher _launcher;
|
||||
private readonly ConfigStore _config;
|
||||
private readonly ILogger<AuthController> _log;
|
||||
|
||||
public AuthController(RbacStore rbac, JwtIssuer jwt, SimpleLiteLauncher launcher, ConfigStore config, ILogger<AuthController> log)
|
||||
public AuthController(RbacStore rbac, JwtIssuer jwt, Simple3Launcher launcher, ConfigStore config, ILogger<AuthController> log)
|
||||
{
|
||||
_rbac = rbac;
|
||||
_jwt = jwt;
|
||||
@@ -79,41 +78,40 @@ public class AuthController : ControllerBase
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(req.Username))
|
||||
return BadRequest(new { message = "用户名不能为空" });
|
||||
if (req.Scope is not ("Platform" or "RCSMonitor"))
|
||||
return BadRequest(new { message = "无效 scope" });
|
||||
|
||||
// 真密码校验:RbacStore.VerifyCredentials 对不存在 / 已禁用 / 密码错统一返回 null,防用户名枚举。
|
||||
var user = _rbac.VerifyCredentials(req.Username, req.Password);
|
||||
if (user == null)
|
||||
return Unauthorized(new { message = "用户名或密码错误,或账号已被停用" });
|
||||
|
||||
// scope 必须落在该账号「角色覆盖的 scope」集合内(admin 角色 scope=* 覆盖全部)。
|
||||
if (!_rbac.CanUseScope(user, req.Scope))
|
||||
return StatusCode(403, new { message = $"账号 {user.Username} 没有访问 {req.Scope} 的权限" });
|
||||
// 入口由账号角色决定,不再接受登录页挑选「管理端 / 运营端」。
|
||||
var scope = _rbac.ResolveLoginScope(user);
|
||||
if (scope == null)
|
||||
return StatusCode(403, new { message = $"账号 {user.Username} 没有任何可登录区域,请联系管理员分配角色" });
|
||||
|
||||
// 会话 N+1:按 LaunchMode 拉起 SimpleLite 子进程(线程池执行,避免占用请求线程)。
|
||||
// 会话 N+1:按 LaunchMode 拉起 Simple3 子进程(线程池执行,避免占用请求线程)。
|
||||
var launchMode = NormalizeLaunchMode(req.LaunchMode);
|
||||
SimpleLiteLauncher.LaunchResult? launchResult = null;
|
||||
Simple3Launcher.LaunchResult? launchResult = null;
|
||||
try
|
||||
{
|
||||
// M1:waitForReady=false —— 拉起 SimpleLite 后立即返回,不在登录请求里同步等端口
|
||||
// M1:waitForReady=false —— 拉起 Simple3 后立即返回,不在登录请求里同步等端口
|
||||
// 就绪(冷启动可能十几秒)。前端拿 LaunchStatus=Starting 即可,必要时轮询健康检查。
|
||||
launchResult = await Task.Run(() => _launcher.MaybeStart(launchMode, waitForReady: false));
|
||||
_log.LogInformation("SimpleLite launch result for user={User} launchMode={Mode}: Started={Started} Status={Status} Detail={Detail}",
|
||||
_log.LogInformation("Simple3 launch result for user={User} launchMode={Mode}: Started={Started} Status={Status} Detail={Detail}",
|
||||
user.Username, launchMode, launchResult.Value.Started, launchResult.Value.Status, launchResult.Value.Detail);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.LogError(ex, "SimpleLite launch threw for user={User} launchMode={Mode}", user.Username, launchMode);
|
||||
_log.LogError(ex, "Simple3 launch threw for user={User} launchMode={Mode}", user.Username, launchMode);
|
||||
}
|
||||
|
||||
var runMode = ResolveRunMode(launchResult, launchMode);
|
||||
|
||||
var (perm, roleNames, token) = BuildSession(user, req.Scope);
|
||||
var (perm, roleNames, token) = BuildSession(user, scope);
|
||||
SetAuthCookie(token);
|
||||
|
||||
var dto = new AuthUserDto(user.Id, user.Username, user.DisplayName, roleNames);
|
||||
return Ok(new LoginResponse(token, dto, req.Scope, runMode, perm,
|
||||
return Ok(new LoginResponse(token, dto, scope, runMode, perm,
|
||||
LaunchStatus: launchResult?.Status,
|
||||
LaunchWarning: launchResult?.Warning,
|
||||
NeedsWizard: NeedsWizard()));
|
||||
@@ -144,13 +142,20 @@ public class AuthController : ControllerBase
|
||||
if (user == null || !user.Enabled)
|
||||
return Unauthorized(new { message = "账号已失效或被停用" });
|
||||
|
||||
// 账号当前是否还允许这个 scope(管理员可能在此期间调整了角色)。
|
||||
if (!_rbac.CanUseScope(user, scope))
|
||||
return StatusCode(403, new { message = $"账号 {user.Username} 没有访问 {scope} 的权限" });
|
||||
var preferred = _rbac.ResolveLoginScope(user);
|
||||
if (preferred == null)
|
||||
return StatusCode(403, new { message = $"账号 {user.Username} 没有任何可登录区域,请联系管理员分配角色" });
|
||||
|
||||
var (perm, roleNames, token) = BuildSession(user, preferred);
|
||||
string? rotated = null;
|
||||
if (!string.Equals(preferred, scope, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
SetAuthCookie(token);
|
||||
rotated = token;
|
||||
}
|
||||
|
||||
var (perm, roleNames, _) = BuildSession(user, scope);
|
||||
var dto = new AuthUserDto(user.Id, user.Username, user.DisplayName, roleNames);
|
||||
return Ok(new MeResponse(dto, scope, InferRunMode(), perm, NeedsWizard()));
|
||||
return Ok(new MeResponse(dto, preferred, InferRunMode(), perm, NeedsWizard(), rotated));
|
||||
}
|
||||
|
||||
/// <summary>用同一身份切换 scope 并重发 token + perms。</summary>
|
||||
@@ -172,6 +177,11 @@ public class AuthController : ControllerBase
|
||||
if (!_rbac.CanUseScope(user, req.Scope))
|
||||
return StatusCode(403, new { message = $"账号 {user.Username} 没有访问 {req.Scope} 的权限" });
|
||||
|
||||
// 有管理权限的账号固定走管理入口,不再切到运营壳;请用运营权限账号登录查看运营页。
|
||||
var preferred = _rbac.ResolveLoginScope(user);
|
||||
if (preferred == PageCatalog.ScopePlatform && req.Scope == PageCatalog.ScopeMonitor)
|
||||
return StatusCode(403, new { message = "请使用运营权限账号查看运营页面" });
|
||||
|
||||
var (perm, roleNames, token) = BuildSession(user, req.Scope);
|
||||
SetAuthCookie(token);
|
||||
|
||||
@@ -200,22 +210,23 @@ public class AuthController : ControllerBase
|
||||
return (perm, roleNames, token);
|
||||
}
|
||||
|
||||
/// <summary>me / switchScope 不重启 SimpleLite,依据 Launcher 记录的 LastLaunchMode 反推 RunMode。</summary>
|
||||
/// <summary>me / switchScope 不重启 Simple3,依据 Launcher 记录的 LastLaunchMode 反推 RunMode。</summary>
|
||||
private string InferRunMode()
|
||||
{
|
||||
var last = _launcher.LastLaunchMode;
|
||||
if (string.IsNullOrEmpty(last)) return "Detached";
|
||||
if (last == SimpleLiteLauncher.ExternalReuseLaunchMode) return "WebEnabled";
|
||||
if (last == Simple3Launcher.ExternalReuseLaunchMode) return "WebOnly";
|
||||
return last.Contains("local", StringComparison.OrdinalIgnoreCase) ? "WebEnabled" : "WebOnly";
|
||||
}
|
||||
|
||||
/// <summary>根据 Launcher 真实结果决定 RunMode(避免 SimpleLite 没起却假装 WebEnabled)。</summary>
|
||||
private static string ResolveRunMode(SimpleLiteLauncher.LaunchResult? result, string launchMode)
|
||||
/// <summary>根据 Launcher 真实结果决定 RunMode(避免内核没起却假装已连接)。</summary>
|
||||
private static string ResolveRunMode(Simple3Launcher.LaunchResult? result, string launchMode)
|
||||
{
|
||||
if (result is not { Started: true })
|
||||
return "Detached";
|
||||
// Simple3 无本地端:复用既有实例也按 WebOnly 展示。
|
||||
if (result.Value.Status == "ReusingExisting")
|
||||
return "WebEnabled";
|
||||
return "WebOnly";
|
||||
if (!string.IsNullOrEmpty(result.Value.DisplayMode))
|
||||
{
|
||||
if (result.Value.DisplayMode.Equals("web", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -230,8 +241,9 @@ public class AuthController : ControllerBase
|
||||
{
|
||||
return raw?.Trim().ToLowerInvariant() switch
|
||||
{
|
||||
"webonly" or "web-only" or "web" => "WebOnly",
|
||||
_ => "DesktopAndWeb",
|
||||
"desktopandweb" or "web+local" or "weblocal" or "local" => "DesktopAndWeb",
|
||||
// Simple3 默认仅 Web;未传 / 未知也走 WebOnly
|
||||
_ => "WebOnly",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public sealed class FleetController : ControllerBase
|
||||
|
||||
/// <summary>
|
||||
/// CDM 搬运任务列表(读平台快照库 cdm_tasks)。在线时先即时同步一次拿最新,
|
||||
/// SimpleLite 关闭时回退最近快照,并通过 online/lastSyncAt 告知前端数据是否滞后。
|
||||
/// Simple3 关闭时回退最近快照,并通过 online/lastSyncAt 告知前端数据是否滞后。
|
||||
/// </summary>
|
||||
[HttpGet("tasks")]
|
||||
public async Task<ActionResult<object>> Tasks([FromQuery] int limit = 1000, CancellationToken ct = default)
|
||||
@@ -76,7 +76,7 @@ public sealed class FleetController : ControllerBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 车辆报警列表(读平台记录 vehicle_alarms)。含活跃 + 历史;SimpleLite 离线时回退最近记录,
|
||||
/// 车辆报警列表(读平台记录 vehicle_alarms)。含活跃 + 历史;Simple3 离线时回退最近记录,
|
||||
/// 通过 online/lastSyncAt 告知数据是否滞后。activeOnly=true 仅返回未恢复的报警。
|
||||
/// </summary>
|
||||
[HttpGet("alarms")]
|
||||
|
||||
@@ -9,9 +9,9 @@ namespace MiGu.Server.Controllers;
|
||||
public class HealthController : ControllerBase
|
||||
{
|
||||
private static readonly DateTimeOffset StartTime = DateTimeOffset.UtcNow;
|
||||
private readonly SimpleLiteLauncher _launcher;
|
||||
private readonly Simple3Launcher _launcher;
|
||||
|
||||
public HealthController(SimpleLiteLauncher launcher) => _launcher = launcher;
|
||||
public HealthController(Simple3Launcher launcher) => _launcher = launcher;
|
||||
|
||||
/// <summary>匿名存活探针:仅返回进程级状态,不暴露端口拓扑等部署细节。</summary>
|
||||
[HttpGet]
|
||||
@@ -26,28 +26,28 @@ public class HealthController : ControllerBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SimpleLite 拉起配置诊断:查看当前 ExecutablePath、解析结果、端口是否已有服务。
|
||||
/// 配置位置:<c>MiGu.Server/appsettings.json</c> → <c>SimpleLite</c> 节点。
|
||||
/// Simple3 拉起配置诊断:查看当前 ExecutablePath、解析结果、端口是否已有服务。
|
||||
/// 配置位置:<c>MiGu.Server/appsettings.json</c> → <c>Simple3</c> 节点。
|
||||
/// 含服务器本地路径等敏感信息,要求登录。
|
||||
/// </summary>
|
||||
[HttpGet("simplelite")]
|
||||
[HttpGet("simple3")]
|
||||
[Authorize]
|
||||
public IActionResult GetSimpleLiteDiagnostics() => Ok(_launcher.GetDiagnostics());
|
||||
public IActionResult GetSimple3Diagnostics() => Ok(_launcher.GetDiagnostics());
|
||||
|
||||
/// <summary>关闭本机全部 SimpleLite 进程。仅 Platform 管理端可调。</summary>
|
||||
[HttpPost("simplelite/stop")]
|
||||
/// <summary>关闭本机全部 Simple3 进程。仅 Platform 管理端可调。</summary>
|
||||
[HttpPost("simple3/stop")]
|
||||
[Authorize(Policy = "PlatformScope")]
|
||||
public IActionResult StopSimpleLite()
|
||||
public IActionResult StopSimple3()
|
||||
{
|
||||
var killed = _launcher.StopAll();
|
||||
var diag = _launcher.GetDiagnostics();
|
||||
return Ok(new { killed, diagnostics = diag });
|
||||
}
|
||||
|
||||
/// <summary>关闭并重新拉起 SimpleLite(不同步 DLL)。仅 Platform 管理端可调。</summary>
|
||||
[HttpPost("simplelite/restart")]
|
||||
/// <summary>关闭并重新拉起 Simple3(不同步 DLL)。仅 Platform 管理端可调。</summary>
|
||||
[HttpPost("simple3/restart")]
|
||||
[Authorize(Policy = "PlatformScope")]
|
||||
public IActionResult RestartSimpleLite([FromQuery] string launchMode = "webonly")
|
||||
public IActionResult RestartSimple3([FromQuery] string launchMode = "webonly")
|
||||
{
|
||||
var result = _launcher.Restart(launchMode);
|
||||
var diag = _launcher.GetDiagnostics();
|
||||
@@ -55,12 +55,12 @@ public class HealthController : ControllerBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭 SimpleLite、同步最新 DLL、重新拉起。用于「前往站点」API 缺失时一键更新。
|
||||
/// 会终止本机全部 SimpleLite 进程并重启,仅 Platform 管理端可调。
|
||||
/// 关闭 Simple3、同步最新 DLL、重新拉起。用于「前往站点」API 缺失时一键更新。
|
||||
/// 会终止本机全部 Simple3 进程并重启,仅 Platform 管理端可调。
|
||||
/// </summary>
|
||||
[HttpPost("simplelite/restart-for-update")]
|
||||
[HttpPost("simple3/restart-for-update")]
|
||||
[Authorize(Policy = "PlatformScope")]
|
||||
public IActionResult RestartSimpleLiteForUpdate([FromQuery] string launchMode = "webonly")
|
||||
public IActionResult RestartSimple3ForUpdate([FromQuery] string launchMode = "webonly")
|
||||
{
|
||||
var result = _launcher.RestartForUpdate(launchMode);
|
||||
var diag = _launcher.GetDiagnostics();
|
||||
|
||||
@@ -8,8 +8,8 @@ using MiGu.Server.Launcher;
|
||||
namespace MiGu.Server.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 读取 SimpleLite 地图固定目录下的 JSON 原文,供平台「地图管理」右侧预览。
|
||||
/// 先向 SimpleLite 拉取 maps 列表拿到 directory,再读本机同路径文件(与 SimpleLite 同机部署)。
|
||||
/// 读取 Simple3 地图固定目录下的 JSON 原文,供平台「地图管理」右侧预览。
|
||||
/// 先向 Simple3 拉取 maps 列表拿到 directory,再读本机同路径文件(与 Simple3 同机部署)。
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
@@ -18,13 +18,13 @@ public class MapsContentController : ControllerBase
|
||||
{
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly InternalTokenStore _internalToken;
|
||||
private readonly SimpleLiteOptions _sl;
|
||||
private readonly Simple3Options _sl;
|
||||
private readonly ILogger<MapsContentController> _log;
|
||||
|
||||
public MapsContentController(
|
||||
IHttpClientFactory httpFactory,
|
||||
InternalTokenStore internalToken,
|
||||
IOptions<SimpleLiteOptions> sl,
|
||||
IOptions<Simple3Options> sl,
|
||||
ILogger<MapsContentController> log)
|
||||
{
|
||||
_httpFactory = httpFactory;
|
||||
@@ -47,7 +47,7 @@ public class MapsContentController : ControllerBase
|
||||
{
|
||||
var directory = await FetchMapsDirectoryAsync(ct);
|
||||
if (string.IsNullOrWhiteSpace(directory))
|
||||
return StatusCode(503, new { message = "无法从 SimpleLite 获取地图目录" });
|
||||
return StatusCode(503, new { message = "无法从 Simple3 获取地图目录" });
|
||||
|
||||
var fileName = name.EndsWith(".json", StringComparison.OrdinalIgnoreCase) ? name : $"{name}.json";
|
||||
var fullPath = Path.GetFullPath(Path.Combine(directory, fileName));
|
||||
@@ -86,7 +86,7 @@ public class MapsContentController : ControllerBase
|
||||
using var resp = await client.SendAsync(msg, ct);
|
||||
var body = await resp.Content.ReadAsStringAsync(ct);
|
||||
if (!resp.IsSuccessStatusCode)
|
||||
throw new InvalidOperationException($"SimpleLite maps 列表返回 {(int)resp.StatusCode}");
|
||||
throw new InvalidOperationException($"Simple3 maps 列表返回 {(int)resp.StatusCode}");
|
||||
|
||||
using var doc = JsonDocument.Parse(body);
|
||||
var root = doc.RootElement;
|
||||
|
||||
@@ -4,8 +4,8 @@ using Microsoft.AspNetCore.Mvc;
|
||||
namespace MiGu.Server.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 投影 API 占位:真实落地时由 YARP 反代到 SimpleLite WebAPI 的 /api/projection/* 路径。
|
||||
/// 本地 Mock 数据仅用于无 SimpleLite 运行时的开发联调。
|
||||
/// 投影 API 占位:真实落地时由 YARP 反代到 Simple3 WebAPI 的 /api/projection/* 路径。
|
||||
/// 本地 Mock 数据仅用于无 Simple3 运行时的开发联调。
|
||||
///
|
||||
/// AR-4: 全 class 加 [Authorize] —— 任何登录用户都能读 mock 投影数据;未登录直接 401。
|
||||
/// </summary>
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace MiGu.Server.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 迷毂「数据中心」:把 scene.signal 的 Model JSON 以表格读写(PLC 握手 / 磁条交管)。
|
||||
/// 文件落在 SimpleLite 工作目录 <c>Config/Signal/*.json</c>,不依赖 SimpleLite 进程是否在跑。
|
||||
/// 文件落在 Simple3 工作目录 <c>Config/Signal/*.json</c>,不依赖 Simple3 进程是否在跑。
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize(Policy = "PlatformScope")]
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace MiGu.Server.Controllers;
|
||||
/// 数据持久化于 <c>platform.db</c> 的 <c>simple_fields</c> 表。
|
||||
///
|
||||
/// 对应前端「字段管理」页(<c>/admin/simple-fields</c>,页面 key <c>admin-simple-fields</c>)。
|
||||
/// 前端主流程为「刷新」读库、「默认」从 SimpleLite 拉取模板、「保存」走 <see cref="SaveBatch"/> 全量替换。
|
||||
/// 前端主流程为「刷新」读库、「默认」从 Simple3 拉取模板、「保存」走 <see cref="SaveBatch"/> 全量替换。
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace MiGu.Server.Controllers;
|
||||
/// </list>
|
||||
/// 说明:保存时即把选型固化为单一事实来源 <c>deployment</c> section,并同步联动 Launcher ——
|
||||
/// <see cref="SaveProfile"/> 调 <c>WriteActiveScenes</c> 写 <c>plugins/active-scenes.json</c> / 透传 <c>--scenes</c>,
|
||||
/// 驱动 SimpleLite 下次启动选择性加载选定的导航场景插件。
|
||||
/// 驱动 Simple3 下次启动选择性加载选定的导航场景插件。
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
@@ -25,10 +25,10 @@ namespace MiGu.Server.Controllers;
|
||||
public class WizardController : ControllerBase
|
||||
{
|
||||
private readonly ConfigStore _store;
|
||||
private readonly SimpleLiteLauncher _launcher;
|
||||
private readonly Simple3Launcher _launcher;
|
||||
private readonly ILogger<WizardController> _log;
|
||||
|
||||
public WizardController(ConfigStore store, SimpleLiteLauncher launcher, ILogger<WizardController> log)
|
||||
public WizardController(ConfigStore store, Simple3Launcher launcher, ILogger<WizardController> log)
|
||||
{
|
||||
_store = store;
|
||||
_launcher = launcher;
|
||||
@@ -81,7 +81,7 @@ public class WizardController : ControllerBase
|
||||
|
||||
_store.PutDeployment(profile);
|
||||
|
||||
// 平台 → 内核联动:把导航选型写入 SimpleLite 的 plugins/active-scenes.json(下次启动选择性加载;
|
||||
// 平台 → 内核联动:把导航选型写入 Simple3 的 plugins/active-scenes.json(下次启动选择性加载;
|
||||
// 已运行实例可由前端再调 POST /api/sl/projection/scenes/apply 触发增量 reload)。
|
||||
// scene.device(门/充电桩/按钮盒驱动)为各类项目通用能力,向导暂无独立选项,固定并入激活集合;
|
||||
// 选 SPS / Pack 时 ToLauncherSceneIds 会并入 scene.signal(PLC 握手)。
|
||||
@@ -107,7 +107,7 @@ public class WizardController : ControllerBase
|
||||
/// 统一对外投影:camelCase 字段 + 推导出的 activeSceneIds(导航选型 → 内核场景 id)+
|
||||
/// hiddenPages(被裁剪的菜单页)+ 可选的 activeScenesWrite(保存时写 active-scenes.json 的结果)。
|
||||
/// </summary>
|
||||
private static object Project(DeploymentProfile dp, SimpleLiteLauncher.ActiveScenesWriteResult? write = null) => new
|
||||
private static object Project(DeploymentProfile dp, Simple3Launcher.ActiveScenesWriteResult? write = null) => new
|
||||
{
|
||||
configured = dp.Configured,
|
||||
platformType = dp.PlatformType,
|
||||
|
||||
Reference in New Issue
Block a user