将会话、权限、位置、收款与排队存储拆分为独立模块,同步更新各 ViewModel 与单元测试,并补充素材管理 UI 与个人空间设置交互。 Co-authored-by: Cursor <cursoragent@cursor.com>
82 lines
2.4 KiB
Swift
82 lines
2.4 KiB
Swift
//
|
|
// ScenicQueueSettingChangeLogViewModel.swift
|
|
// suixinkan
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// 排队设置配置日志 ViewModel。
|
|
final class ScenicQueueSettingChangeLogViewModel {
|
|
private enum Constants {
|
|
static let pageSize = 20
|
|
}
|
|
|
|
private(set) var items: [ScenicQueueSettingChangeLogItem] = []
|
|
private(set) var isRefreshing = false
|
|
private(set) var isLoadingMore = false
|
|
private(set) var canLoadMore = false
|
|
|
|
var onStateChange: (() -> Void)?
|
|
var onShowMessage: ((String) -> Void)?
|
|
|
|
private let appStore: AppStore
|
|
private var total = 0
|
|
private var lastLoadedPage = 0
|
|
|
|
init(appStore: AppStore = .shared) {
|
|
self.appStore = appStore
|
|
}
|
|
|
|
/// 刷新配置日志。
|
|
func refresh(api: ScenicQueueAPIProtocol) async {
|
|
await load(api: api, page: 1, append: false)
|
|
}
|
|
|
|
/// 加载更多配置日志。
|
|
func loadMore(api: ScenicQueueAPIProtocol) async {
|
|
guard canLoadMore, !isRefreshing, !isLoadingMore else { return }
|
|
await load(api: api, page: lastLoadedPage + 1, append: true)
|
|
}
|
|
|
|
private func load(api: ScenicQueueAPIProtocol, page: Int, append: Bool) async {
|
|
guard appStore.session.currentScenicId > 0 else {
|
|
onShowMessage?("请先选择景区")
|
|
return
|
|
}
|
|
if append {
|
|
isLoadingMore = true
|
|
} else {
|
|
isRefreshing = true
|
|
}
|
|
notifyStateChange()
|
|
defer {
|
|
if append { isLoadingMore = false } else { isRefreshing = false }
|
|
notifyStateChange()
|
|
}
|
|
let spotId = Int64(appStore.scenicQueue.punchSpotId)
|
|
do {
|
|
let data = try await api.settingChangeLog(
|
|
scenicId: Int64(appStore.session.currentScenicId),
|
|
scenicSpotId: spotId,
|
|
page: page,
|
|
pageSize: Constants.pageSize
|
|
)
|
|
if append {
|
|
let seen = Set(items.map(\.id))
|
|
items += data.list.filter { !seen.contains($0.id) }
|
|
} else {
|
|
items = data.list
|
|
}
|
|
total = max(0, data.total)
|
|
lastLoadedPage = max(1, data.page)
|
|
canLoadMore = items.count < total && !data.list.isEmpty
|
|
} catch {
|
|
onShowMessage?(error.localizedDescription)
|
|
}
|
|
}
|
|
|
|
private func notifyStateChange() {
|
|
onStateChange?()
|
|
}
|
|
}
|