完善实名认证、钱包与打卡点模块 UI 与业务逻辑。
对齐 Android 实名认证流程与审核页、钱包提现/积分兑换界面,优化打卡点列表与详情交互,并补充相关资源、主题 token 与单元测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -89,6 +89,7 @@ final class WalletViewModel {
|
||||
|
||||
private let staffIdProvider: () -> Int?
|
||||
private let calendar: Calendar
|
||||
private let nowProvider: () -> Date
|
||||
private var withdrawPage = 1
|
||||
private var withdrawCanLoadMore = true
|
||||
private var transactionPage = 1
|
||||
@ -101,10 +102,12 @@ final class WalletViewModel {
|
||||
staffIdProvider: @escaping () -> Int? = {
|
||||
Int(AppStore.shared.session.userId.trimmingCharacters(in: .whitespacesAndNewlines))
|
||||
},
|
||||
calendar: Calendar = Calendar(identifier: .gregorian)
|
||||
calendar: Calendar = Calendar(identifier: .gregorian),
|
||||
nowProvider: @escaping () -> Date = Date.init
|
||||
) {
|
||||
self.staffIdProvider = staffIdProvider
|
||||
self.calendar = calendar
|
||||
self.nowProvider = nowProvider
|
||||
}
|
||||
|
||||
/// 首次加载钱包首页全部首屏数据。
|
||||
@ -223,8 +226,11 @@ final class WalletViewModel {
|
||||
private func loadWithdraw(api: any WalletPageServing, refresh: Bool) async {
|
||||
if withdrawLoading && !refresh { return }
|
||||
let targetPage = refresh ? 1 : withdrawPage
|
||||
let previousPage = withdrawPage
|
||||
let previousCanLoadMore = withdrawCanLoadMore
|
||||
withdrawLoading = true
|
||||
withdrawRefreshing = refresh
|
||||
errorMessage = nil
|
||||
if refresh {
|
||||
withdrawCanLoadMore = true
|
||||
withdrawPage = 1
|
||||
@ -238,8 +244,8 @@ final class WalletViewModel {
|
||||
withdrawPage = response.item.isEmpty ? targetPage : targetPage + 1
|
||||
} catch {
|
||||
if refresh {
|
||||
withdrawRecords = []
|
||||
withdrawCanLoadMore = false
|
||||
withdrawPage = previousPage
|
||||
withdrawCanLoadMore = previousCanLoadMore
|
||||
}
|
||||
errorMessage = error.localizedDescription
|
||||
}
|
||||
@ -252,9 +258,12 @@ final class WalletViewModel {
|
||||
private func loadTransaction(api: any WalletPageServing, refresh: Bool) async {
|
||||
if transactionLoading && !refresh { return }
|
||||
let targetPage = refresh ? 1 : transactionPage
|
||||
let previousPage = transactionPage
|
||||
let previousCanLoadMore = transactionCanLoadMore
|
||||
let range = dateRange(for: filter)
|
||||
transactionLoading = true
|
||||
transactionRefreshing = refresh
|
||||
errorMessage = nil
|
||||
if refresh {
|
||||
transactionCanLoadMore = true
|
||||
transactionPage = 1
|
||||
@ -276,8 +285,8 @@ final class WalletViewModel {
|
||||
transactionPage = response.list.isEmpty ? targetPage : targetPage + 1
|
||||
} catch {
|
||||
if refresh {
|
||||
transactionGroups = []
|
||||
transactionCanLoadMore = false
|
||||
transactionPage = previousPage
|
||||
transactionCanLoadMore = previousCanLoadMore
|
||||
}
|
||||
errorMessage = error.localizedDescription
|
||||
}
|
||||
@ -287,7 +296,8 @@ final class WalletViewModel {
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
private func dateRange(for filter: WalletFilter, now: Date = Date()) -> (start: String, end: String) {
|
||||
private func dateRange(for filter: WalletFilter) -> (start: String, end: String) {
|
||||
let now = nowProvider()
|
||||
let end = calendar.startOfDay(for: now)
|
||||
let start = calendar.date(byAdding: .day, value: -filter.dayOffset, to: end) ?? end
|
||||
return (Self.dayFormatter.string(from: start), Self.dayFormatter.string(from: end))
|
||||
@ -367,7 +377,7 @@ final class WithdrawViewModel {
|
||||
|
||||
/// 更新短信验证码。
|
||||
func updateVerificationCode(_ value: String) {
|
||||
verificationCode = value.filter(\.isNumber)
|
||||
verificationCode = value
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
@ -416,14 +426,17 @@ final class WithdrawViewModel {
|
||||
|
||||
/// 表单是否可提交。
|
||||
var canSubmit: Bool {
|
||||
validationMessage == nil && !submitting
|
||||
withdrawInfo != nil &&
|
||||
!amount.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty &&
|
||||
!verificationCode.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty &&
|
||||
!submitting
|
||||
}
|
||||
|
||||
/// 表单校验提示。
|
||||
var validationMessage: String? {
|
||||
guard let withdrawInfo else { return "提现信息加载中" }
|
||||
guard !amount.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return "请输入提现金额" }
|
||||
guard let amountDecimal = Decimal(string: amount), amountDecimal > 0 else { return "请输入有效的金额" }
|
||||
guard let amountDecimal = Decimal(string: amount) else { return "请输入有效的金额" }
|
||||
let withdrawable = Decimal(string: withdrawInfo.amountWithdrawable) ?? 0
|
||||
if amountDecimal > withdrawable { return "金额不能大于可提现金额" }
|
||||
guard !verificationCode.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return "请输入验证码" }
|
||||
@ -495,6 +508,7 @@ final class PointsRedemptionViewModel {
|
||||
func refreshOverview(api: any WalletPageServing) async {
|
||||
guard let staffId = staffIdProvider(), staffId > 0 else { return }
|
||||
overviewLoading = true
|
||||
errorMessage = nil
|
||||
notifyStateChange()
|
||||
do {
|
||||
let response = try await api.pointOverview(staffId: staffId)
|
||||
@ -527,7 +541,7 @@ final class PointsRedemptionViewModel {
|
||||
return
|
||||
}
|
||||
let points = min(Int(digits) ?? 0, withdrawnPoints)
|
||||
pointsInput = points > 0 ? String(points) : ""
|
||||
pointsInput = String(points)
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
@ -566,8 +580,11 @@ final class PointsRedemptionViewModel {
|
||||
private func loadWithdrawList(api: any WalletPageServing, refresh: Bool) async {
|
||||
if withdrawLoading && !refresh { return }
|
||||
let targetPage = refresh ? 1 : withdrawPage
|
||||
let previousPage = withdrawPage
|
||||
let previousCanLoadMore = withdrawCanLoadMore
|
||||
withdrawLoading = true
|
||||
withdrawRefreshing = refresh
|
||||
errorMessage = nil
|
||||
if refresh {
|
||||
withdrawCanLoadMore = true
|
||||
withdrawPage = 1
|
||||
@ -581,8 +598,8 @@ final class PointsRedemptionViewModel {
|
||||
withdrawPage = response.list.isEmpty ? targetPage : targetPage + 1
|
||||
} catch {
|
||||
if refresh {
|
||||
withdrawRecords = []
|
||||
withdrawCanLoadMore = false
|
||||
withdrawPage = previousPage
|
||||
withdrawCanLoadMore = previousCanLoadMore
|
||||
}
|
||||
errorMessage = error.localizedDescription
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user