- YARP: map-edit/ai-config 全方法、reflection 写方法挂 PlatformScope, reflection/selection 单独放行(运营端 3D 高亮),堵住运营账号直达地图编辑/反射调用 - goto-site 探测改用不存在的 car/-1(消除健康检查真实派车风险)并加 60s 缓存 - Config PUT 按 scope 收紧:RCSMonitor 仅可写 ops 节;wizard 写操作与 simplelite/restart-for-update 限 PlatformScope;/api/health 去除虚假端口表 - 修复 wms 模块菜单裁剪失效(admin-config-location → admin-config-facility) - vrHost 默认 location.hostname:8223(新增 utils/vrender.ts),远程访问 3D 视口可用 - /status 页改接真实 /api/health* 诊断;uploadAsset 移除矛盾 multipart 头; mapsApi.merge 对齐 save 的 409 冲突处理;JWT 验签参数改启动期 DI 一次性配置 - 清理死代码:ProjectionController、DataTablePro、useClipboard、CadToolbarView、 AppShell 未用导入;lint 脚本替换为 typecheck;日志窗口 List 改 Queue
78 lines
4.1 KiB
C#
78 lines
4.1 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 暂无专属配置页,未纳入映射(选中不影响菜单)。
|
|
/// 注意:Key 必须是 PageCatalog 当前有效 Key(不能用 LegacyKeyAliases 里的旧名,否则裁剪悄然失效)。
|
|
/// </summary>
|
|
public static readonly IReadOnlyDictionary<string, string[]> ModuleToPages =
|
|
new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
["wms"] = new[] { "admin-config-facility" },
|
|
};
|
|
|
|
/// <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();
|
|
}
|
|
}
|