// // AuthSessionHelper.swift // suixinkan // import Foundation /// 登录会话辅助工具,负责写入本地 Token、账号上下文并广播登录成功通知。 enum AuthSessionHelper { /// 完成登录,保存 Token、账号上下文与用户偏好,并通知 SceneDelegate 切换根页面。 static func completeLogin( with response: V9AuthResponse, username: String, privacyAgreementAccepted: Bool, selectedAccount: AccountSwitchAccount ) { let token = response.token.trimmingCharacters(in: .whitespacesAndNewlines) guard !token.isEmpty else { return } AppStore.shared.saveToken(token) AppStore.shared.lastLoginUsername = username AppStore.shared.privacyAgreementAccepted = privacyAgreementAccepted applyAccountSession(from: selectedAccount, in: response) if privacyAgreementAccepted { AMapBootstrap.configureIfNeeded() } NotificationCenter.default.post(name: NotificationName.userDidLogin, object: nil) } /// 账号切换完成后更新会话,不触发根页面重建。 static func applyAccountSwitch( with response: V9AuthResponse, account: AccountSwitchAccount ) { let token = response.token.trimmingCharacters(in: .whitespacesAndNewlines) guard !token.isEmpty else { return } AppStore.shared.saveToken(token) applyAccountSession(from: account, in: response) NotificationCenter.default.post(name: NotificationName.accountDidSwitch, object: nil) } /// 将 v9 响应中的角色与账号展示信息写入 AppStore。 static func applyAccountSession(from account: AccountSwitchAccount, in response: V9AuthResponse) { AppStore.shared.applyAccount(account) if let scenicUser = response.scenicUsers.first(where: { matches($0, account: account) }) { applyScenicUser(scenicUser) return } if let storeUser = response.storeUsers.first(where: { matches($0, account: account) }) { applyStoreUser(storeUser) } } /// 从 v9 响应中解析当前账号实体,优先 `isCurrent`。 static func resolveCurrentAccount(from response: V9AuthResponse) -> AccountSwitchAccount? { let accounts = response.accounts.filter { $0.businessUserId > 0 } if let current = accounts.first(where: \.isCurrent) { return current } return accounts.first } private static func applyScenicUser(_ user: V9ScenicUser) { AppStore.shared.userId = String(user.businessUserId) AppStore.shared.accountType = V9ScenicUser.accountTypeValue AppStore.shared.accountDisplayName = firstNonEmpty( user.scenicName, user.nickname, user.realName, user.username ) AppStore.shared.userName = firstNonEmpty(user.nickname, user.username, user.realName) AppStore.shared.realName = firstNonEmpty(user.realName, user.nickname, user.username) AppStore.shared.phone = user.phone AppStore.shared.currentScenicId = user.scenicId AppStore.shared.currentScenicName = user.scenicName AppStore.shared.currentStoreId = 0 if !user.appRoleCode.isEmpty { AppStore.shared.roleCode = user.appRoleCode } if !user.appRoleName.isEmpty { AppStore.shared.roleName = user.appRoleName } } private static func applyStoreUser(_ user: V9StoreUser) { AppStore.shared.userId = String(user.businessUserId) AppStore.shared.accountType = V9StoreUser.accountTypeValue AppStore.shared.accountDisplayName = firstNonEmpty( user.storeName, user.scenicName, user.realName, user.userName, user.username ) AppStore.shared.userName = firstNonEmpty(user.userName, user.username, user.realName) AppStore.shared.realName = firstNonEmpty(user.realName, user.userName, user.username) AppStore.shared.phone = user.phone AppStore.shared.avatar = user.avatar AppStore.shared.currentScenicId = user.scenicId AppStore.shared.currentScenicName = user.scenicName AppStore.shared.currentStoreId = user.storeId if !user.appRoleCode.isEmpty { AppStore.shared.roleCode = user.appRoleCode } if !user.appRoleName.isEmpty { AppStore.shared.roleName = user.appRoleName } } private static func matches(_ user: V9ScenicUser, account: AccountSwitchAccount) -> Bool { user.businessUserId == account.businessUserId || account.id == "\(V9ScenicUser.accountTypeValue)_\(user.businessUserId)" } private static func matches(_ user: V9StoreUser, account: AccountSwitchAccount) -> Bool { user.businessUserId == account.businessUserId || account.id == "\(V9StoreUser.accountTypeValue)_\(user.businessUserId)" } private static func firstNonEmpty(_ values: String...) -> String { values.first { !$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } ?? "" } }