初始提交

This commit is contained in:
2026-06-22 11:28:01 +08:00
commit 0a0d4fbd79
84 changed files with 8899 additions and 0 deletions

View File

@ -0,0 +1,83 @@
//
// PermissionContext.swift
// suixinkan
//
// Created by Codex on 2026/6/22.
//
import Foundation
import Observation
@MainActor
@Observable
/// URI
final class PermissionContext {
private(set) var rolePermissions: [RolePermissionResponse] = []
private(set) var permissionURIs: Set<String> = []
var currentRole: RoleInfo?
/// ID
func replaceRolePermissions(_ rolePermissions: [RolePermissionResponse], currentRoleId: Int? = nil) {
self.rolePermissions = rolePermissions
currentRole = currentRoleId.flatMap { id in
rolePermissions.first { $0.role.id == id }?.role
} ?? currentRole.flatMap { role in
rolePermissions.first { $0.role.id == role.id }?.role
} ?? rolePermissions.first?.role
permissionURIs = Set(Self.flattenPermissions(currentRole?.permission ?? []))
}
///
func selectRole(id roleId: Int, accountContext: AccountContext) {
guard let rolePermission = rolePermissions.first(where: { $0.role.id == roleId }) else { return }
currentRole = rolePermission.role
permissionURIs = Set(Self.flattenPermissions(rolePermission.role.permission))
let scenicScopes = Self.uniqueScenicScopes(from: rolePermission.scenic)
accountContext.replaceScopes(
scenic: scenicScopes,
stores: accountContext.storeScopes,
currentScenicId: accountContext.currentScenic?.id,
currentStoreId: accountContext.currentStore?.id
)
}
/// URI
func canAccess(_ uri: String) -> Bool {
permissionURIs.contains(uri.trimmingCharacters(in: .whitespacesAndNewlines))
}
///
func currentRoleScenicScopes() -> [BusinessScope] {
guard let currentRole else { return [] }
guard let rolePermission = rolePermissions.first(where: { $0.role.id == currentRole.id }) else {
return []
}
return Self.uniqueScenicScopes(from: rolePermission.scenic)
}
/// 退
func reset() {
rolePermissions = []
permissionURIs = []
currentRole = nil
}
/// URI
private static func flattenPermissions(_ permissions: [PermissionItem]) -> [String] {
permissions.flatMap { item -> [String] in
let current = item.uri.trimmingCharacters(in: .whitespacesAndNewlines)
let children = flattenPermissions(item.children)
return current.isEmpty ? children : [current] + children
}
}
///
private static func uniqueScenicScopes(from scenics: [ScenicInfo]) -> [BusinessScope] {
var seen = Set<Int>()
return scenics.compactMap { scenic in
guard seen.insert(scenic.id).inserted else { return nil }
return BusinessScope(id: scenic.id, name: scenic.name, kind: .scenic)
}
}
}