Files
suixinkan_uikit/suixinkan/DataStore/AppSessionStore.swift
汉秋 005349f8e6 模块化 AppStore 并完善素材管理与个人空间设置。
将会话、权限、位置、收款与排队存储拆分为独立模块,同步更新各 ViewModel 与单元测试,并补充素材管理 UI 与个人空间设置交互。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 11:01:08 +08:00

234 lines
7.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.

//
// AppSessionStore.swift
// suixinkan
//
import Foundation
///
enum AppAccountType: Equatable, Sendable {
case scenicUser
case storeUser
case unknown(String)
///
init(rawValue: String) {
switch rawValue {
case "scenic_user": self = .scenicUser
case "store_user": self = .storeUser
default: self = .unknown(rawValue)
}
}
///
var rawValue: String {
switch self {
case .scenicUser: "scenic_user"
case .storeUser: "store_user"
case let .unknown(value): value
}
}
}
///
final class AppSessionStore {
private enum Key: String {
case token = "key_in_token"
case lastLoginUsername = "key_last_login_username"
case privacyAgreementAccepted = "key_privacy_agreement_accepted"
case userId = "key_in_user_id"
case userName = "key_in_user_name"
case realName = "key_in_real_name"
case avatar = "key_in_avatar"
case phone = "key_in_phone"
case accountType = "key_in_account_type"
case accountDisplayName = "key_in_account_display_name"
case roleCode = "key_in_role_code"
case roleName = "key_in_role_name"
case currentScenicId = "key_in_current_scenic_id"
case currentScenicName = "key_in_current_scenic_name"
case currentStoreId = "key_in_current_store_id"
}
private let defaults: UserDefaults
/// 使 UserDefaults
init(defaults: UserDefaults) {
self.defaults = defaults
}
/// Token
var token: String {
get { string(for: .token) }
set { defaults.set(newValue, forKey: Key.token.rawValue) }
}
///
var lastLoginUsername: String? {
get { defaults.string(forKey: Key.lastLoginUsername.rawValue) }
set {
if let newValue {
defaults.set(newValue, forKey: Key.lastLoginUsername.rawValue)
} else {
defaults.removeObject(forKey: Key.lastLoginUsername.rawValue)
}
}
}
///
var privacyAgreementAccepted: Bool {
get { defaults.bool(forKey: Key.privacyAgreementAccepted.rawValue) }
set { defaults.set(newValue, forKey: Key.privacyAgreementAccepted.rawValue) }
}
/// ID
var userId: String {
get { string(for: .userId) }
set { defaults.set(newValue, forKey: Key.userId.rawValue) }
}
///
var userName: String {
get { string(for: .userName) }
set { defaults.set(newValue, forKey: Key.userName.rawValue) }
}
///
var realName: String {
get { string(for: .realName) }
set { defaults.set(newValue, forKey: Key.realName.rawValue) }
}
///
var avatar: String {
get { string(for: .avatar) }
set { defaults.set(newValue, forKey: Key.avatar.rawValue) }
}
///
var phone: String {
get { string(for: .phone) }
set { defaults.set(newValue, forKey: Key.phone.rawValue) }
}
///
var accountType: AppAccountType {
get { AppAccountType(rawValue: string(for: .accountType)) }
set { defaults.set(newValue.rawValue, forKey: Key.accountType.rawValue) }
}
///
var accountDisplayName: String {
get { string(for: .accountDisplayName) }
set { defaults.set(newValue, forKey: Key.accountDisplayName.rawValue) }
}
///
var roleCode: String {
get { string(for: .roleCode) }
set { defaults.set(newValue, forKey: Key.roleCode.rawValue) }
}
///
var roleName: String {
get { string(for: .roleName) }
set { defaults.set(newValue, forKey: Key.roleName.rawValue) }
}
/// ID0
var currentScenicId: Int {
get { Int(string(for: .currentScenicId)) ?? 0 }
set { defaults.set(newValue > 0 ? String(newValue) : "", forKey: Key.currentScenicId.rawValue) }
}
///
var currentScenicName: String {
get { string(for: .currentScenicName) }
set { defaults.set(newValue, forKey: Key.currentScenicName.rawValue) }
}
/// ID0
var currentStoreId: Int {
get { defaults.integer(forKey: Key.currentStoreId.rawValue) }
set { defaults.set(newValue, forKey: Key.currentStoreId.rawValue) }
}
/// Android `getAccountCachePrefix`
var accountCachePrefix: String {
let uid = userId.trimmingCharacters(in: .whitespacesAndNewlines)
let type = accountType.rawValue.trimmingCharacters(in: .whitespacesAndNewlines)
if uid.isEmpty { return "guest" }
if type.isEmpty { return uid }
return "\(uid)_\(type)"
}
///
var currentAppRole: AppRoleCode? {
AppRoleCode.fromCode(roleCode) ?? AppRoleCode.fromRoleName(roleName)
}
///
var isPhotographerRole: Bool {
if let role = currentAppRole {
return role.isPhotographer
}
return roleName.trimmingCharacters(in: .whitespacesAndNewlines) == "摄影师"
}
/// Token
var isLoggedIn: Bool {
!token.isEmpty
}
/// Token
func saveToken(_ token: String) {
self.token = token
}
///
func applyAccount(_ account: AccountSwitchAccount) {
userId = String(account.businessUserId)
accountType = AppAccountType(rawValue: account.accountType)
accountDisplayName = account.title
userName = account.subtitle
phone = account.phone
if !account.avatar.isEmpty {
avatar = account.avatar
}
currentScenicName = account.scenicName
currentScenicId = account.scenicId ?? 0
currentStoreId = account.storeId ?? 0
}
///
func applyUserInfo(_ info: UserInfoResponse) {
if !info.nickname.isEmpty { userName = info.nickname }
if !info.realName.isEmpty { realName = info.realName }
if !info.avatar.isEmpty { avatar = info.avatar }
if !info.phone.isEmpty { phone = info.phone }
if !info.roleName.isEmpty, roleName.isEmpty { roleName = info.roleName }
}
///
func clearAuthenticatedSession() {
token = ""
userId = ""
userName = ""
realName = ""
avatar = ""
phone = ""
accountType = .unknown("")
accountDisplayName = ""
roleCode = ""
roleName = ""
currentScenicId = 0
currentScenicName = ""
currentStoreId = 0
}
private func string(for key: Key) -> String {
defaults.string(forKey: key.rawValue) ?? ""
}
}