Files
suixinkan_ios_new/suixinkan/App/State/AccountContext.swift
汉秋 b61bf0d070 新增景区权限模块,集成 AMap CocoaPods 并支持模拟器
将景区选择与权限申请流程接入首页路由,集成高德 SDK 用于真机构建,并通过 Podfile post_install 钩子保证 arm64 模拟器可编译。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 10:15:26 +08:00

150 lines
4.5 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.

//
// AccountContext.swift
// suixinkan
//
// Created by Codex on 2026/6/18.
//
import Observation
///
struct AccountProfile: Codable, Equatable {
var userId: String
var displayName: String
var phone: String?
var avatarURL: String?
}
///
struct BusinessScope: Codable, Equatable, Identifiable {
///
enum Kind: Codable, Equatable {
case scenic
case store
}
var id: Int
var name: String
var kind: Kind
var parentScenicId: Int?
var status: Int?
var address: String?
var latitude: Double?
var longitude: Double?
var coverURLString: String?
/// parentScenicId
init(
id: Int,
name: String,
kind: Kind,
parentScenicId: Int? = nil,
status: Int? = nil,
address: String? = nil,
latitude: Double? = nil,
longitude: Double? = nil,
coverURLString: String? = nil
) {
self.id = id
self.name = name
self.kind = kind
self.parentScenicId = parentScenicId
self.status = status
self.address = address
self.latitude = latitude
self.longitude = longitude
self.coverURLString = coverURLString
}
}
@MainActor
@Observable
/// /
final class AccountContext {
private(set) var profile: AccountProfile?
private(set) var scenicScopes: [BusinessScope] = []
private(set) var storeScopes: [BusinessScope] = []
var currentScenic: BusinessScope?
var currentStore: BusinessScope?
///
func applyLogin(profile: AccountProfile? = nil) {
self.profile = profile
}
///
func replaceProfile(_ profile: AccountProfile?) {
self.profile = profile
}
///
func replaceScopes(
scenic: [BusinessScope],
stores: [BusinessScope],
currentScenicId: Int? = nil,
currentStoreId: Int? = nil
) {
scenicScopes = scenic
storeScopes = stores
currentScenic = currentScenicId.flatMap { id in
scenic.first { $0.id == id }
} ?? currentScenic.flatMap { current in
scenic.first { $0.id == current.id }
} ?? scenic.first
currentStore = resolvedStore(
in: stores,
currentScenic: currentScenic,
preferredStoreId: currentStoreId ?? currentStore?.id
)
}
///
func selectScenic(id scenicId: Int) {
guard let scenic = scenicScopes.first(where: { $0.id == scenicId }) else { return }
currentScenic = scenic
currentStore = resolvedStore(
in: storeScopes,
currentScenic: scenic,
preferredStoreId: currentStore?.id
)
}
///
func selectStore(id storeId: Int) {
guard let store = storeScopes.first(where: { $0.id == storeId }) else { return }
currentStore = store
if let scenicId = store.parentScenicId,
currentScenic?.id != scenicId,
let scenic = scenicScopes.first(where: { $0.id == scenicId }) {
currentScenic = scenic
}
}
/// 退
func reset() {
profile = nil
scenicScopes = []
storeScopes = []
currentScenic = nil
currentStore = nil
}
/// ID
private func resolvedStore(
in stores: [BusinessScope],
currentScenic: BusinessScope?,
preferredStoreId: Int?
) -> BusinessScope? {
let scenicId = currentScenic?.id
let storesForScenic = stores.filter { store in
guard let scenicId else { return true }
return store.parentScenicId == nil || store.parentScenicId == scenicId
}
if let preferredStoreId,
let store = storesForScenic.first(where: { $0.id == preferredStoreId }) {
return store
}
return storesForScenic.first
}
}