将 MiGu.Server 相关忽略规则迁移至 backends/MiGu.Server,并新增对 .tmp-build* 和 /.cursor/rules 的忽略,优化敏感数据与临时文件的管理。
75 lines
3.9 KiB
C#
75 lines
3.9 KiB
C#
namespace MiGu.Server.Configs;
|
|
|
|
/// <summary>
|
|
/// 配置向导「可选项目录」与「选型 → 平台能力」映射的单一事实来源。
|
|
///
|
|
/// <para>前端向导从 <c>GET /api/wizard/options</c> 拿到这些可选项渲染勾选框;后端
|
|
/// <see cref="ModuleToPages"/> 在「按选型裁剪菜单」时把模块
|
|
/// 映射为 PageCatalog 的可见页 id。集中定义,避免前后端各写一份导致漂移。</para>
|
|
/// </summary>
|
|
public static class DeploymentCatalog
|
|
{
|
|
/// <summary>一个可勾选项。<see cref="Id"/> 是稳定机器标识,<see cref="Group"/> 用于前端分组展示。</summary>
|
|
public record Option(string Id, string Name, string Group, string Description);
|
|
|
|
/// <summary>导航方式(多选,一等维度)。id 与 <see cref="DeploymentProfile.NavKindToSceneId"/> 的 key 对齐。</summary>
|
|
public static readonly IReadOnlyList<Option> NavigationKinds = new[]
|
|
{
|
|
new Option("magnetic", "磁导航", "navigation", "磁条循迹 + 地标 / RFID 定位"),
|
|
new Option("qrcode", "二维码导航", "navigation", "二维码地标 + 码值地图"),
|
|
new Option("laser", "激光导航", "navigation", "反光板 / SLAM + 激光避障"),
|
|
};
|
|
|
|
/// <summary>功能模块(多选)。暂定保留 WMS / PTL 两项,后续按需扩展(参考 RIOT 的 WMS/WCS/MES/APS 分层)。</summary>
|
|
public static readonly IReadOnlyList<Option> Modules = new[]
|
|
{
|
|
new Option("wms", "WMS 仓储管理", "module", "库位 / 库存 / 出入库管理"),
|
|
new Option("ptl", "PTL 拣选系统", "module", "Pick-to-Light 亮灯拣选与播种"),
|
|
};
|
|
|
|
/// <summary>功能模块 → PageCatalog 页面 Key 列表的映射。PTL 暂无专属配置页,未纳入映射(选中不影响菜单)。</summary>
|
|
public static readonly IReadOnlyDictionary<string, string[]> ModuleToPages =
|
|
new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
["wms"] = new[] { "admin-config-location" },
|
|
};
|
|
|
|
/// <summary>所有「可被选型控制」的页面 Key(Module → 页 映射值的并集)。</summary>
|
|
public static IReadOnlyCollection<string> TailorablePages()
|
|
{
|
|
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
foreach (var v in ModuleToPages.Values) foreach (var p in v) set.Add(p);
|
|
return set;
|
|
}
|
|
|
|
/// <summary>当前部署画像下被「点亮」的可裁剪页(已启用 Module 映射到的页)。</summary>
|
|
public static IReadOnlyCollection<string> EnabledPages(DeploymentProfile dp)
|
|
{
|
|
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
if (dp == null) return set;
|
|
foreach (var m in dp.Modules ?? new List<string>())
|
|
if (ModuleToPages.TryGetValue(m, out var ps)) foreach (var p in ps) set.Add(p);
|
|
return set;
|
|
}
|
|
|
|
/// <summary>当前部署画像下应隐藏的页(可裁剪但未被点亮)。向导未完成(Configured=false)则不隐藏任何页。</summary>
|
|
public static IReadOnlyCollection<string> HiddenPages(DeploymentProfile dp)
|
|
{
|
|
if (dp == null || !dp.Configured) return Array.Empty<string>();
|
|
var enabled = EnabledPages(dp);
|
|
return TailorablePages().Where(p => !enabled.Contains(p)).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 从 RBAC 计算出的可见页集合中移除「被部署画像隐藏」的页 —— 这是「按选型裁剪菜单」的核心。
|
|
/// 不在任何映射中的页不受影响;向导未完成时原样返回(避免首登空菜单)。
|
|
/// </summary>
|
|
public static List<string> FilterPagesByDeployment(IEnumerable<string> pages, DeploymentProfile dp)
|
|
{
|
|
var input = (pages ?? Enumerable.Empty<string>()).ToList();
|
|
if (dp == null || !dp.Configured) return input;
|
|
var hidden = new HashSet<string>(HiddenPages(dp), StringComparer.OrdinalIgnoreCase);
|
|
return input.Where(p => !hidden.Contains(p)).ToList();
|
|
}
|
|
}
|