namespace MiGu.Server.Configs;
///
/// 部署画像 —— 登录后「配置向导」的结果,对应 ConfigStore 的 deployment section
/// (持久化于 data/config-deployment.json)。
///
/// 它是「按选型裁剪」的单一事实来源:
///
/// - =false 时,登录返回 NeedsWizard=true,前端跳转配置向导;
/// - 经 映射为 SimpleLite 场景 id,
/// 由 Launcher 写入 plugins/active-scenes.json / 透传 --scenes,驱动内核「选择性加载」导航场景插件;
/// - 驱动平台菜单与能力裁剪(PageCatalog 可见页)。
///
///
/// 向导是否已完成。false = 登录后强制进入配置向导。
/// 平台主定位(仅用于 UI 标题/默认值),如 standard / wcs / wms-wcs / custom。
/// 启用的功能模块(多选),暂定 wms / ptl。
/// 导航方式(多选,一等维度),取值 magnetic / qrcode / laser,与 SimpleCore.NavKind 对齐。
/// 选用的业务场景模板 id(来自 ScenarioTemplateConfig),如 tpl-sps / tpl-pack。
/// 最近一次保存向导的用户名(审计用)。
public record DeploymentProfile(
bool Configured,
string PlatformType,
List Modules,
List NavigationKinds,
List Scenarios,
string UpdatedBy)
{
public static DeploymentProfile Default() => new(
Configured: false,
PlatformType: "standard",
Modules: new List(),
NavigationKinds: new List(),
Scenarios: new List(),
UpdatedBy: "");
///
/// 导航方式 → SimpleLite 场景 id 映射。与 *.scene.json.id、SimpleCore.Navigation.NavKind
/// 以及内核 active-scenes.json.activeScenes 一致;这是平台与内核之间「导航选型」的契约约定。
/// 两平台制(StandardScene 拆分落地):磁导航 → scene.mag;
/// 二维码与激光共用融合平台 scene.qrlidar(激光坐标导航 + 二维码按轨道逐段触发,可融合可单用)。
///
public static readonly IReadOnlyDictionary NavKindToSceneId =
new Dictionary(StringComparer.OrdinalIgnoreCase)
{
["magnetic"] = "scene.mag",
["qrcode"] = "scene.qrlidar",
["laser"] = "scene.qrlidar",
};
///
/// 把已选 映射为 SimpleLite 激活场景 id 列表(去重、忽略未知项、保持选择顺序)。
/// 供 Launcher 写 active-scenes.json / 拼 --scenes 参数使用。
///
public IReadOnlyList ToActiveSceneIds()
{
var result = new List();
if (NavigationKinds == null) return result;
foreach (var k in NavigationKinds)
{
if (string.IsNullOrWhiteSpace(k)) continue;
if (NavKindToSceneId.TryGetValue(k.Trim(), out var sceneId) && !result.Contains(sceneId))
result.Add(sceneId);
}
return result;
}
/// 信号交互场景 id(PLC 握手 + 磁条交管)。
public const string SignalSceneId = "scene.signal";
/// 设备驱动场景 id(门/充电桩等,各类项目通用)。
public const string DeviceSceneId = "scene.device";
/// 是否选了磁导航。
public bool UsesMagnetic() =>
NavigationKinds?.Any(k => string.Equals(k, "magnetic", StringComparison.OrdinalIgnoreCase)) == true;
///
/// 写入 active-scenes.json 的完整场景集合:导航插件 + 磁导航时并入 scene.signal + scene.device。
///
public IReadOnlyList ToLauncherSceneIds()
{
var result = ToActiveSceneIds().ToList();
if (UsesMagnetic() && !result.Contains(SignalSceneId, StringComparer.OrdinalIgnoreCase))
result.Add(SignalSceneId);
if (!result.Contains(DeviceSceneId, StringComparer.OrdinalIgnoreCase))
result.Add(DeviceSceneId);
return result;
}
}