Initial commit: suixinkan_ios UIKit rewrite project.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -0,0 +1,77 @@
|
||||
//
|
||||
// AccountSwitchViewModel.swift
|
||||
// suixinkan
|
||||
//
|
||||
// Created by Codex on 2026/6/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@MainActor
|
||||
/// 账号切换 ViewModel,管理可切换账号列表、选择状态和提交状态。
|
||||
final class AccountSwitchViewModel {
|
||||
var onChange: (() -> Void)?
|
||||
private(set) var accounts: [AccountSwitchAccount] = [] { didSet { onChange?() } }
|
||||
var selectedAccountId: String? { didSet { onChange?() } }
|
||||
private(set) var loading = false { didSet { onChange?() } }
|
||||
private(set) var switching = false { didSet { onChange?() } }
|
||||
private var didLoad = false
|
||||
|
||||
/// 当前选中的账号。
|
||||
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
|
||||
defer { loading = false }
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/// 选择指定账号。
|
||||
func select(_ account: AccountSwitchAccount) {
|
||||
selectedAccountId = account.id
|
||||
}
|
||||
|
||||
/// 提交账号切换,调用 set-user 换取正式 token。
|
||||
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
|
||||
defer { switching = false }
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// 账号切换错误实体,表示重复提交或账号数据异常。
|
||||
enum AccountSwitchError: LocalizedError, Equatable {
|
||||
case submitting
|
||||
case invalidAccount
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .submitting:
|
||||
"账号正在切换,请稍候"
|
||||
case .invalidAccount:
|
||||
"账号信息异常,请重新选择账号"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user