// // AccountSwitchViewModel.swift // suixinkan // import Foundation /// 账号切换 ViewModel,管理可切换账号列表、选择状态和提交状态。 final class AccountSwitchViewModel { private(set) var accounts: [AccountSwitchAccount] = [] private(set) var selectedAccountId: String? private(set) var loading = false private(set) var switching = false private var didLoad = false var onStateChange: (() -> Void)? var selectedAccount: AccountSwitchAccount? { accounts.first { $0.id == selectedAccountId } } func load(api: ProfileAPI, force: Bool = false, currentAccountId: String? = nil) async throws { guard force || !didLoad else { return } didLoad = true loading = true notifyStateChange() defer { loading = false notifyStateChange() } let response = try await api.switchableAccounts() accounts = response.accounts.filter { $0.businessUserId > 0 } selectedAccountId = accounts.first(where: { $0.isCurrent || isCurrent($0, currentAccountId: currentAccountId) })?.id ?? accounts.first?.id notifyStateChange() } func select(_ account: AccountSwitchAccount) { selectedAccountId = account.id notifyStateChange() } func switchAccount(_ account: AccountSwitchAccount, api: AuthAPI) async throws -> V9AuthResponse { guard !switching else { throw AccountSwitchError.submitting } guard account.businessUserId > 0 else { throw AccountSwitchError.invalidAccount } switching = true notifyStateChange() defer { switching = false notifyStateChange() } return try await api.setUser(account.toSetUserRequest()) } func isCurrent(_ account: AccountSwitchAccount, currentAccountId: String?) -> Bool { guard let currentAccountId else { return false } return account.id == currentAccountId || String(account.businessUserId) == currentAccountId } private func notifyStateChange() { onStateChange?() } } enum AccountSwitchError: LocalizedError, Equatable { case submitting case invalidAccount var errorDescription: String? { switch self { case .submitting: "账号正在切换,请稍候" case .invalidAccount: "账号信息异常,请重新选择账号" } } }