新增门店订单与核销管理列表,对齐 Android 订单能力并完善账号级缓存。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-29 14:46:10 +08:00
parent c4de3d17d0
commit 08492df6ce
51 changed files with 3668 additions and 102 deletions

View File

@ -0,0 +1,141 @@
//
// WriteOffListViewModel.swift
// suixinkan
//
// Created by Codex on 2026/6/29.
//
import Foundation
import Combine
@MainActor
/// ViewModel Android WriteOffListViewModel
final class WriteOffListViewModel: ObservableObject {
@Published var searchPhone = ""
@Published var selectedStatus = 0
@Published var filterStartDate: Date?
@Published var filterEndDate: Date?
@Published private(set) var orders: [WriteOffOrderItem] = []
@Published private(set) var loading = false
@Published private(set) var loadingMore = false
@Published private(set) var isVerifying = false
@Published private(set) var total = 0
@Published private(set) var page = 1
@Published private(set) var hasMore = false
private let pageSize = 20
///
var normalizedPhone: String? {
let text = searchPhone.trimmingCharacters(in: .whitespacesAndNewlines)
return text.isEmpty ? nil : text
}
///
func reload(api: OrderServing, scenicId: Int?, storeId: Int? = nil, showLoading: Bool = true) async throws {
guard let scenicId else {
orders = []
total = 0
page = 1
hasMore = false
return
}
if showLoading { loading = true }
defer { if showLoading { loading = false } }
let result = try await api.writeOffList(
scenicId: scenicId,
storeId: storeId,
page: 1,
pageSize: pageSize,
orderStatus: orderStatusQuery,
orderVerifyStatus: verifyStatusQuery,
startTime: OrderDateRangeFormatter.queryValue(from: filterStartDate),
endTime: OrderDateRangeFormatter.queryValue(from: filterEndDate),
userPhone: normalizedPhone
)
orders = result.list
total = result.total
page = 1
hasMore = orders.count < result.total && !result.list.isEmpty
}
///
func loadMore(api: OrderServing, scenicId: Int?, storeId: Int? = nil) async throws {
guard !loadingMore, hasMore, let scenicId else { return }
loadingMore = true
defer { loadingMore = false }
let nextPage = page + 1
let result = try await api.writeOffList(
scenicId: scenicId,
storeId: storeId,
page: nextPage,
pageSize: pageSize,
orderStatus: orderStatusQuery,
orderVerifyStatus: verifyStatusQuery,
startTime: OrderDateRangeFormatter.queryValue(from: filterStartDate),
endTime: OrderDateRangeFormatter.queryValue(from: filterEndDate),
userPhone: normalizedPhone
)
orders.append(contentsOf: result.list)
total = result.total
page = nextPage
hasMore = orders.count < result.total && !result.list.isEmpty
}
///
func verify(api: OrderServing, scenicId: Int, storeId: Int? = nil, orderNumber: String) async throws {
guard !isVerifying else { return }
isVerifying = true
defer { isVerifying = false }
try await api.writeOff(orderNumber: orderNumber)
try await reload(api: api, scenicId: scenicId, storeId: storeId, showLoading: false)
}
///
func matchedWriteOffOrder(for rawCode: String) -> (orderNumber: String, matched: WriteOffOrderItem?)? {
guard let orderNumber = OrderNumberParser.parse(rawCode) else { return nil }
let matched = orders.first {
$0.orderNumber.caseInsensitiveCompare(orderNumber) == .orderedSame
}
return (matched?.orderNumber ?? orderNumber, matched)
}
///
func writeOffOrder(matching orderNumber: String) -> WriteOffOrderItem? {
orders.first { $0.orderNumber.caseInsensitiveCompare(orderNumber) == .orderedSame }
}
///
func canVerify(_ item: WriteOffOrderItem) -> Bool {
let status = displayVerificationStatus(for: item)
return !status.contains("已核销") && !status.contains("已退款") && !status.contains("已完成")
}
///
func displayVerificationStatus(for item: WriteOffOrderItem) -> String {
let text = item.orderVerificationStatus.trimmingCharacters(in: .whitespacesAndNewlines)
return text.isEmpty ? "待核销" : text
}
private var orderStatusQuery: Int? {
switch selectedStatus {
case 18, 30:
return selectedStatus
default:
return nil
}
}
private var verifyStatusQuery: Int? {
switch selectedStatus {
case 1, 2:
return selectedStatus
default:
return nil
}
}
}