Files
suixinkan_uikit/suixinkan/DataStore/AppPermissionStore.swift
lujiuyinandCursor c083f1d4b3 升级 AppStore 缓存 Key 并在覆盖安装时强制重新登录。
统一账号作用域 Key 对齐 Android,新增缓存 schema 迁移清理旧数据,并同步更新相关模块与单元测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 09:35:55 +08:00

101 lines
3.3 KiB
Swift

//
// 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 {
guard let key = scopedKey(.legacyRoleId) else { return 0 }
return defaults.integer(forKey: key)
}
set {
guard let key = scopedKey(.legacyRoleId) else { return }
defaults.set(newValue, forKey: key)
}
}
/// 保存完整 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(accountScope: String) {
guard !accountScope.isEmpty else { return }
Key.allCases.forEach { defaults.removeObject(forKey: "\(accountScope)_\($0.rawValue)") }
}
private func save<Value: Encodable>(_ value: Value, for key: Key) {
guard let scopedKey = scopedKey(key),
let data = try? JSONEncoder().encode(value) else { return }
defaults.set(data, forKey: scopedKey)
}
private func load<Value: Decodable>(_ type: Value.Type, for key: Key) -> Value? {
guard let scopedKey = scopedKey(key),
let data = defaults.data(forKey: scopedKey) else { return nil }
return try? JSONDecoder().decode(type, from: data)
}
private func scopedKey(_ key: Key) -> String? {
session.accountScopedKey(key.rawValue)
}
}