Initial commit
This commit is contained in:
60
suixinkan/App/State/ScenicSpotContext.swift
Normal file
60
suixinkan/App/State/ScenicSpotContext.swift
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// ScenicSpotContext.swift
|
||||
// suixinkan
|
||||
//
|
||||
// Created by Codex on 2026/6/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
|
||||
/// 景点加载阶段实体,表示当前景区景点列表的加载状态。
|
||||
enum ScenicSpotLoadState: Equatable {
|
||||
case idle
|
||||
case loading
|
||||
case loaded
|
||||
case failed(String)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Observable
|
||||
/// 景点上下文状态中心,保存当前景区下的景点或打卡点列表。
|
||||
final class ScenicSpotContext {
|
||||
private(set) var scenicId: Int?
|
||||
private(set) var spots: [ScenicSpotItem] = []
|
||||
private(set) var loadState: ScenicSpotLoadState = .idle
|
||||
|
||||
/// 按景区 ID 重新加载景点列表,失败只影响景点模块本身。
|
||||
func reload(scenicId: Int?, api: AccountContextServing) async {
|
||||
guard let scenicId else {
|
||||
reset()
|
||||
return
|
||||
}
|
||||
|
||||
if self.scenicId != scenicId {
|
||||
spots = []
|
||||
}
|
||||
self.scenicId = scenicId
|
||||
loadState = .loading
|
||||
|
||||
do {
|
||||
let response = try await api.scenicSpotListAll(scenicId: scenicId)
|
||||
guard !Task.isCancelled else { return }
|
||||
spots = response.list
|
||||
loadState = .loaded
|
||||
} catch is CancellationError {
|
||||
loadState = .idle
|
||||
} catch {
|
||||
guard !Task.isCancelled else { return }
|
||||
spots = []
|
||||
loadState = .failed(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
/// 清空景点上下文,通常在退出登录或没有当前景区时调用。
|
||||
func reset() {
|
||||
scenicId = nil
|
||||
spots = []
|
||||
loadState = .idle
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user