// // AppPermissionStore.swift // suixinkan // import Foundation /// 管理当前账号的角色权限、首页权限与可选景区缓存。 final class AppPermissionStore { private enum Key: String, CaseIterable { case legacyRoleId = "key_in_role_id" case rolePermissionList = "key_role_permission_list" case permissionItems = "key_in_permission" case roleScenicList = "key_current_role_scenic_list" } private let defaults: UserDefaults private let session: AppSessionStore /// 使用指定持久化容器和会话创建权限存储。 init(defaults: UserDefaults, session: AppSessionStore) { self.defaults = defaults self.session = session } /// 旧版 role_id,用于权限匹配兜底。 var legacyRoleId: Int { get { defaults.integer(forKey: scopedKey(.legacyRoleId)) } set { defaults.set(newValue, forKey: scopedKey(.legacyRoleId)) } } /// 保存完整 role-permission 列表。 func saveRolePermissionList(_ list: [RolePermissionResponse]) { save(list, for: .rolePermissionList) } /// 读取完整 role-permission 列表。 func rolePermissionList() -> [RolePermissionResponse] { load([RolePermissionResponse].self, for: .rolePermissionList) ?? [] } /// 保存当前角色扁平权限。 func savePermissionItems(_ items: [HomePermissionItem]) { save(items, for: .permissionItems) } /// 读取当前角色扁平权限。 func permissionItems() -> [HomePermissionItem] { load([HomePermissionItem].self, for: .permissionItems) ?? [] } /// 保存当前角色可选景区列表。 func saveRoleScenicList(_ scenicList: [ScenicInfo]) { save(scenicList, for: .roleScenicList) } /// 读取当前角色可选景区列表。 func roleScenicList() -> [ScenicInfo] { load([ScenicInfo].self, for: .roleScenicList) ?? [] } /// 在 role-permission 列表中匹配当前账号角色。 func matchRolePermissionItem(in list: [RolePermissionResponse]) -> RolePermissionResponse? { RolePermissionMatcher.match( in: list, roleCode: session.roleCode, roleName: session.roleName, legacyRoleId: legacyRoleId ) } /// 清除当前账号的全部权限缓存。 func clear() { Key.allCases.forEach { defaults.removeObject(forKey: scopedKey($0)) } } private func save(_ value: Value, for key: Key) { guard let data = try? JSONEncoder().encode(value) else { return } defaults.set(data, forKey: scopedKey(key)) } private func load(_ type: Value.Type, for key: Key) -> Value? { guard let data = defaults.data(forKey: scopedKey(key)) else { return nil } return try? JSONDecoder().decode(type, from: data) } private func scopedKey(_ key: Key) -> String { "\(session.accountCachePrefix)_\(key.rawValue)" } }