// // LocationReportHistoryViewModel.swift // suixinkan // import Foundation /// 位置上报历史 ViewModel,对齐 Android `LocationReportHistoryViewModel`。 final class LocationReportHistoryViewModel { private(set) var reportList: [LocationReportHistoryItem] = [] private(set) var selectedFilter: LocationReportFilterType = .all private(set) var isRefreshing = false private(set) var canLoadMore = false private(set) var startDate: Date? private(set) var endDate: Date? var onStateChange: (() -> Void)? var onShowMessage: ((String) -> Void)? private let appStore: AppStore private var currentPage = 1 private let pageSize = 10 private var isLoading = false init(appStore: AppStore = .shared) { self.appStore = appStore } var startDateText: String { formattedDate(startDate) } var endDateText: String { formattedDate(endDate) } var hasDateFilter: Bool { startDate != nil || endDate != nil } /// 加载历史上报列表。 func loadReportList(api: HomeAPI, refresh: Bool = false) async { guard !isLoading || refresh else { return } let staffId = appStore.userId.trimmingCharacters(in: .whitespacesAndNewlines) guard !staffId.isEmpty else { onShowMessage?("获取用户ID失败") return } if refresh { currentPage = 1 isRefreshing = true notifyStateChange() } isLoading = true defer { isLoading = false isRefreshing = false notifyStateChange() } do { let response = try await api.locationReportList( staffId: staffId, page: currentPage, pageSize: pageSize, type: selectedFilter.typeCode, startDate: apiDateString(startDate), endDate: apiDateString(endDate) ) if refresh || currentPage == 1 { reportList = response.list } else { reportList.append(contentsOf: response.list) } currentPage += 1 canLoadMore = reportList.count < response.total notifyStateChange() } catch is CancellationError { return } catch { onShowMessage?(error.localizedDescription) } } func selectFilter(_ filter: LocationReportFilterType, api: HomeAPI) async { selectedFilter = filter currentPage = 1 await loadReportList(api: api, refresh: true) } func setDateRange(start: Date?, end: Date?, api: HomeAPI) async { startDate = start endDate = end currentPage = 1 await loadReportList(api: api, refresh: true) } func clearDateRange(api: HomeAPI) async { startDate = nil endDate = nil currentPage = 1 await loadReportList(api: api, refresh: true) } func loadMoreIfNeeded(currentIndex: Int, api: HomeAPI) async { guard canLoadMore, !isLoading else { return } guard currentIndex >= reportList.count - 2 else { return } await loadReportList(api: api, refresh: false) } private func apiDateString(_ date: Date?) -> String? { guard let date else { return nil } let formatter = DateFormatter() formatter.locale = Locale(identifier: "zh_CN") formatter.dateFormat = "yyyy-MM-dd" return formatter.string(from: date) } private func formattedDate(_ date: Date?) -> String { guard let date else { return "请选择" } let formatter = DateFormatter() formatter.locale = Locale(identifier: "zh_CN") formatter.dateFormat = "yyyy-MM-dd" return formatter.string(from: date) } private func notifyStateChange() { onStateChange?() } }