using MiGu.Server.Auth; namespace MiGu.Server.Dashboard; /// /// Dashboard 快捷入口 key 白名单。key 与前端 quickEntries.ts 对齐; /// 用于 RBAC 校验(用户须有权访问对应页面)。 /// public sealed record ShortcutDef(string Key, string PageKey, string Scope); public static class DashboardShortcutCatalog { /// 旧版快捷 key(别名)→ 菜单 key。保存时归一化,避免与菜单项重复。 private static readonly Dictionary LegacyKeyAliases = new(StringComparer.OrdinalIgnoreCase) { ["platform-config"] = "admin-map-editor", ["mission"] = "admin-task-templates", ["cars"] = "admin-cars", ["auth"] = "admin-config-system-center", ["system"] = "admin-config-system-center", ["ops"] = "admin-config-ops-center", ["tasks"] = "admin-config-strategy", }; private static readonly ShortcutDef[] PlatformShortcuts = [ new("admin-dashboard", "admin-dashboard", PageCatalog.ScopePlatform), new("admin-map-monitor", "admin-map-monitor", PageCatalog.ScopePlatform), new("admin-maps", "admin-maps", PageCatalog.ScopePlatform), new("admin-map-editor", "admin-map-editor", PageCatalog.ScopePlatform), new("admin-project-properties", "admin-project-properties", PageCatalog.ScopePlatform), new("admin-tracks", "admin-tracks", PageCatalog.ScopePlatform), new("admin-cars", "admin-cars", PageCatalog.ScopePlatform), new("admin-processes", "admin-processes", PageCatalog.ScopePlatform), new("admin-scripts", "admin-scripts", PageCatalog.ScopePlatform), new("admin-task-templates", "admin-task-templates", PageCatalog.ScopePlatform), new("admin-simple-fields", "admin-simple-fields", PageCatalog.ScopePlatform), new("admin-config-strategy", "admin-config-strategy", PageCatalog.ScopePlatform), new("admin-vehicle-hub", "admin-vehicle-hub", PageCatalog.ScopePlatform), new("admin-config-facility", "admin-config-facility", PageCatalog.ScopePlatform), new("admin-config-business", "admin-config-business", PageCatalog.ScopePlatform), new("admin-config-ops-center", "admin-config-ops-center", PageCatalog.ScopePlatform), new("admin-config-system-center", "admin-config-system-center", PageCatalog.ScopePlatform), ]; private static readonly ShortcutDef[] MonitorShortcuts = [ new("monitor-dashboard", "monitor-dashboard", PageCatalog.ScopeMonitor), new("monitor-vehicle-hub", "monitor-vehicle-hub", PageCatalog.ScopeMonitor), new("monitor-map", "monitor-map", PageCatalog.ScopeMonitor), new("monitor-ops", "monitor-ops", PageCatalog.ScopeMonitor), new("monitor-notes", "monitor-notes", PageCatalog.ScopeMonitor), ]; private static readonly Dictionary ByKey = PlatformShortcuts.Concat(MonitorShortcuts) .ToDictionary(s => s.Key, s => s, StringComparer.OrdinalIgnoreCase); public static readonly int MaxKeysPerUser = 16; /// Platform 域固定保留、不可删除的快捷入口。 public static readonly IReadOnlyList MandatoryPlatformKeys = [ "admin-maps", "admin-map-editor", "admin-cars", "admin-map-monitor", "admin-vehicle-hub", "admin-task-templates" ]; public static readonly IReadOnlyList DefaultPlatformKeys = [ "admin-maps", "admin-map-editor", "admin-cars", "admin-map-monitor", "admin-vehicle-hub", "admin-task-templates", "admin-config-system-center", "admin-config-ops-center", "admin-config-strategy" ]; public static readonly IReadOnlyList DefaultMonitorKeys = ["monitor-vehicle-hub", "monitor-map", "monitor-ops"]; private static readonly HashSet ExcludedKeys = new(StringComparer.OrdinalIgnoreCase) { "admin-dashboard", "monitor-dashboard" }; public static bool IsValidKey(string key) => !ExcludedKeys.Contains(key) && ByKey.ContainsKey(key); public static ShortcutDef? TryGet(string key) => ByKey.TryGetValue(key, out var def) ? def : null; public static IReadOnlyList DefaultKeysForScope(string scope) => string.Equals(scope, PageCatalog.ScopeMonitor, StringComparison.OrdinalIgnoreCase) ? DefaultMonitorKeys : DefaultPlatformKeys; public static bool KeyMatchesScope(string key, string scope) { var def = TryGet(key); return def != null && string.Equals(def.Scope, scope, StringComparison.OrdinalIgnoreCase); } public static string PageKeyFor(string key) => TryGet(NormalizeKey(key))?.PageKey ?? NormalizeKey(key); public static string NormalizeKey(string key) => LegacyKeyAliases.TryGetValue(key.Trim(), out var canon) ? canon : key.Trim(); public static bool IsMandatoryKey(string key, string scope) => string.Equals(scope, PageCatalog.ScopePlatform, StringComparison.OrdinalIgnoreCase) && MandatoryPlatformKeys.Contains(NormalizeKey(key), StringComparer.OrdinalIgnoreCase); }