// // RolePermissionMatching.swift // suixinkan // // Created by Codex on 2026/6/29. // import Foundation /// 角色权限匹配工具,按 role_code 优先、legacy id、角色名顺序解析当前角色。 enum RolePermissionMatching { /// 解析当前 App 角色,用于快照迁移和 session 补全。 static func resolveRoleCode( roleCode: String?, roleId: Int?, roleName: String?, permissions: [RolePermissionResponse] = [] ) -> AppRoleCode? { if let code = AppRoleCode.fromCode(roleCode) { return code } if let legacyId = roleId, legacyId > 0, let code = AppRoleCode.fromLegacyRoleId(legacyId) { return code } if let code = AppRoleCode.fromRoleName(roleName) { return code } return inferFromPermissionList(roleId: roleId, roleName: roleName, permissions: permissions) } /// 在角色权限列表中匹配当前角色,优先 role_code。 static func match( in permissions: [RolePermissionResponse], roleCode: String?, roleId: Int?, roleName: String? ) -> RolePermissionResponse? { if let code = AppRoleCode.fromCode(roleCode) { if let matched = permissions.first(where: { AppRoleCode.fromCode($0.role.roleCode) == code }) { return matched } } if let roleId, roleId > 0, let matched = permissions.first(where: { $0.role.id == roleId }) { return matched } let trimmedName = roleName?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" if !trimmedName.isEmpty { if let matched = permissions.first(where: { item in let name = item.role.name.trimmingCharacters(in: .whitespacesAndNewlines) return !name.isEmpty && (name.contains(trimmedName) || trimmedName.contains(name)) }) { return matched } } return nil } /// 从权限列表推断角色 code。 private static func inferFromPermissionList( roleId: Int?, roleName: String?, permissions: [RolePermissionResponse] ) -> AppRoleCode? { guard !permissions.isEmpty else { return nil } if let roleId, roleId > 0, let item = permissions.first(where: { $0.role.id == roleId }) { return AppRoleCode.fromCode(item.role.roleCode) ?? AppRoleCode.fromRoleName(item.role.name) } let trimmedName = roleName?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" if !trimmedName.isEmpty, let item = permissions.first(where: { item in let name = item.role.name.trimmingCharacters(in: .whitespacesAndNewlines) return !name.isEmpty && (name.contains(trimmedName) || trimmedName.contains(name)) }) { return AppRoleCode.fromCode(item.role.roleCode) ?? AppRoleCode.fromRoleName(item.role.name) } return nil } }