Files
suixinkan_uikit/suixinkan/Features/Auth/AuthSessionHelper.swift

124 lines
5.0 KiB
Swift

//
// 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.session.saveToken(token)
AppStore.shared.session.lastLoginUsername = username
AppStore.shared.session.privacyAgreementAccepted = privacyAgreementAccepted
applyAccountSession(from: selectedAccount, in: response)
if privacyAgreementAccepted {
AMapBootstrap.configureIfNeeded()
UmengBootstrap.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.session.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.session.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.session.userId = String(user.businessUserId)
AppStore.shared.session.accountType = .scenicUser
AppStore.shared.session.accountDisplayName = firstNonEmpty(
user.scenicName, user.nickname, user.realName
)
AppStore.shared.session.userName = firstNonEmpty(user.nickname, user.realName)
AppStore.shared.session.realName = user.realName
AppStore.shared.session.phone = user.phone
AppStore.shared.session.currentScenicId = user.scenicId
AppStore.shared.session.currentScenicName = user.scenicName
AppStore.shared.session.currentStoreId = 0
if !user.appRoleCode.isEmpty {
AppStore.shared.session.roleCode = user.appRoleCode
}
if !user.appRoleName.isEmpty {
AppStore.shared.session.roleName = user.appRoleName
}
}
private static func applyStoreUser(_ user: V9StoreUser) {
AppStore.shared.session.userId = String(user.businessUserId)
AppStore.shared.session.accountType = .storeUser
AppStore.shared.session.accountDisplayName = firstNonEmpty(
user.storeName, user.scenicName, user.realName
)
AppStore.shared.session.userName = user.realName
AppStore.shared.session.realName = user.realName
AppStore.shared.session.phone = user.phone
AppStore.shared.session.avatar = user.avatar
AppStore.shared.session.currentScenicId = user.scenicId
AppStore.shared.session.currentScenicName = user.scenicName
AppStore.shared.session.currentStoreId = user.storeId
if !user.appRoleCode.isEmpty {
AppStore.shared.session.roleCode = user.appRoleCode
}
if !user.appRoleName.isEmpty {
AppStore.shared.session.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 } ?? ""
}
}