Files
suixinkan_uikit/suixinkan/Features/ScenicQueue/ViewModels/ScenicQueueSettingChangeLogViewModel.swift
2026-07-07 15:32:25 +08:00

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.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.scenicQueuePunchSpotId)
do {
let data = try await api.settingChangeLog(
scenicId: Int64(appStore.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?()
}
}