// // HomeViewModel.swift // suixinkan // // Created by Codex on 2026/6/22. // import Foundation @MainActor /// 首页 ViewModel,根据当前角色权限构建首页菜单列表。 final class HomeViewModel { var onChange: (() -> Void)? private(set) var menuItems: [HomeMenuItem] = [] { didSet { onChange?() } } /// 菜单排序权重,与旧工程和 Android 端保持一致。 private let preferredOrder: [String] = [ "space_settings", "album_list", "album_trailer", "wallet", "cloud_management", "cloud_storage_transit", "asset_management", "material_upload", "task_management", "schedule_management", "system_settings", "message_center", "checkin_points", "sample_management", "sample_upload", "live_stream_management", "scenicselection", "scenicapplication", "permission_apply", "permission_apply_status", "scenic_settlement", "scenic_settlement_review", "verification_order", "live_album", "pm", "location_report", "registration_invitation", "store", "fly", "pilot_cert", "task_management_editor", "deposit_order_detail", "deposit_order", "pm_manager", "pilot_controller", "/scenic-queue", "queue_management", "operating-area", "/scenic-order-manage", "photographer_orders" ] /// 从角色权限树扁平化出菜单项,按固定顺序排序并按 URI 别名去重。 func buildMenus(from permissions: [RolePermissionResponse], currentRoleId: Int?) { let source: RolePermissionResponse? if let currentRoleId { source = permissions.first { $0.role.id == currentRoleId } } else { source = permissions.first } guard let source else { menuItems = [] return } let permissionItems = flatten(source.role.permission) var seen = Set() var deduplicated: [PermissionItem] = [] for item in permissionItems where !item.uri.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { if seen.insert(HomeMenuRouter.menuAliasKey(for: item.uri)).inserted { deduplicated.append(item) } } let preferredIndexMap = Dictionary(uniqueKeysWithValues: preferredOrder.enumerated().map { ($1, $0) }) let sortedItems = deduplicated.sorted { lhs, rhs in let lhsRank = preferredIndexMap[lhs.uri] ?? Int.max let rhsRank = preferredIndexMap[rhs.uri] ?? Int.max if lhsRank != rhsRank { return lhsRank < rhsRank } let lhsIndex = deduplicated.firstIndex(where: { $0.id == lhs.id }) ?? Int.max let rhsIndex = deduplicated.firstIndex(where: { $0.id == rhs.id }) ?? Int.max return lhsIndex < rhsIndex } menuItems = sortedItems.map { item in HomeMenuItem( title: item.name.isEmpty ? HomeMenuRouter.title(for: item.uri) : item.name, uri: item.uri, iconSrc: item.iconSrc ) } } /// 返回指定 URI 的展示标题。 func title(for uri: String) -> String { HomeMenuRouter.title(for: uri) } /// 递归展开权限树。 private func flatten(_ items: [PermissionItem]) -> [PermissionItem] { items.flatMap { item in [item] + flatten(item.children) } } }