Files
suixinkan_uikit/suixinkan/Features/CooperationOrder/ViewModels/CooperationOrderListViewModel.swift
汉秋 2bea05b1d9 Add scenic selection and cooperation order flows aligned with Android.
Upgrade scenic picker with search, location sorting, permission apply/status, and blocking home dialog; add cooperation order module and order source picker improvements with unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:48:43 +08:00

130 lines
3.7 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.

//
// CooperationOrderListViewModel.swift
// suixinkan
//
import Foundation
/// ViewModel Android `CooperationOrderListViewModel`
final class CooperationOrderListViewModel {
private(set) var selectedTab = 0
private(set) var searchText = ""
private(set) var leads: [ReferralLeadEntity] = []
private(set) var orders: [AcquisitionOrderEntity] = []
private(set) var isRefreshing = false
private(set) var isLoadingMore = false
private(set) var canLoadMore = false
var onStateChange: (() -> Void)?
var onShowMessage: ((String) -> Void)?
private let pageSize = 10
private var leadsPage = 1
private var ordersPage = 1
private var leadsTotal = 0
private var ordersTotal = 0
func onTabSelected(_ index: Int) {
guard selectedTab != index else { return }
selectedTab = index
notifyStateChange()
}
func onSearchTextChange(_ text: String) {
searchText = text
notifyStateChange()
}
func refreshCurrentTab(api: OrderAPI) async {
if selectedTab == 0 {
await refreshLeads(api: api)
} else {
await refreshAcquisitionOrders(api: api)
}
}
func refreshLeads(api: OrderAPI) async {
leadsPage = 1
isRefreshing = true
isLoadingMore = false
notifyStateChange()
await loadLeads(api: api)
}
func refreshAcquisitionOrders(api: OrderAPI) async {
ordersPage = 1
isRefreshing = true
isLoadingMore = false
notifyStateChange()
await loadAcquisitionOrders(api: api)
}
func loadMore(api: OrderAPI) async {
guard !isRefreshing, !isLoadingMore, canLoadMore else { return }
isLoadingMore = true
notifyStateChange()
if selectedTab == 0 {
leadsPage += 1
await loadLeads(api: api)
} else {
ordersPage += 1
await loadAcquisitionOrders(api: api)
}
}
func shouldLoadMore(at index: Int) -> Bool {
guard canLoadMore, !isRefreshing, !isLoadingMore else { return false }
let count = selectedTab == 0 ? leads.count : orders.count
return index >= max(0, count - 3)
}
private func loadLeads(api: OrderAPI) async {
do {
let response = try await api.referralLeads(
page: String(leadsPage),
pageSize: String(pageSize)
)
leadsTotal = response.total
if leadsPage == 1 {
leads = response.list
} else {
leads.append(contentsOf: response.list)
}
canLoadMore = leads.count < leadsTotal
} catch {
onShowMessage?(error.localizedDescription)
}
isRefreshing = false
isLoadingMore = false
notifyStateChange()
}
private func loadAcquisitionOrders(api: OrderAPI) async {
let keyword = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
do {
let response = try await api.acquisitionOrders(
keyword: keyword.isEmpty ? nil : keyword,
page: String(ordersPage),
pageSize: String(pageSize)
)
ordersTotal = response.total
if ordersPage == 1 {
orders = response.list
} else {
orders.append(contentsOf: response.list)
}
canLoadMore = orders.count < ordersTotal
} catch {
onShowMessage?(error.localizedDescription)
}
isRefreshing = false
isLoadingMore = false
notifyStateChange()
}
private func notifyStateChange() {
onStateChange?()
}
}