Files
suixinkan_uikit/suixinkan/Features/Profile/ViewModels/AccountSwitchViewModel.swift
汉秋 005cac3f78 Implement profile tab with Android-aligned flows and OSS upload.
Add personal info page, account switch, real-name auth, withdrawal settings, session cache extensions, AlibabaCloudOSS SPM, and unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 16:01:05 +08:00

78 lines
2.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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: "账号信息异常,请重新选择账号"
}
}
}