完善实名认证、钱包与打卡点模块 UI 与业务逻辑。

对齐 Android 实名认证流程与审核页、钱包提现/积分兑换界面,优化打卡点列表与详情交互,并补充相关资源、主题 token 与单元测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-13 16:28:10 +08:00
co-authored by Cursor
parent 07b2b9d459
commit 5138c1c11a
63 changed files with 3101 additions and 745 deletions
@@ -29,11 +29,13 @@ final class PunchPointListViewModel {
var onStateChange: (() -> Void)?
var onShowMessage: ((String) -> Void)?
var onShowQRCode: ((String) -> Void)?
var onBeginDeleteAnimation: ((Int64) -> Void)?
private var currentPage = 1
private var totalCount = 0
private let pageSize = 10
private let currentScenicIdProvider: () -> Int
private var pendingDeleteIDs = Set<Int64>()
/// 初始化打卡点列表 ViewModel。
init(currentScenicIdProvider: @escaping () -> Int = { AppStore.shared.session.currentScenicId }) {
@@ -81,12 +83,11 @@ final class PunchPointListViewModel {
/// 删除打卡点。
func delete(item: PunchPointItem, api: any PunchPointAPIProtocol) async {
guard !pendingDeleteIDs.contains(item.id) else { return }
do {
try await api.delete(id: item.id)
items.removeAll { $0.id == item.id }
totalCount = max(0, totalCount - 1)
canLoadMore = items.count < totalCount
notifyStateChange()
pendingDeleteIDs.insert(item.id)
onBeginDeleteAnimation?(item.id)
} catch is CancellationError {
return
} catch {
@@ -94,6 +95,15 @@ final class PunchPointListViewModel {
}
}
/// 删除动画完成后,从列表数据中正式移除条目。
func completeDeleteAnimation(id: Int64) {
guard pendingDeleteIDs.remove(id) != nil else { return }
items.removeAll { $0.id == id }
totalCount = max(0, totalCount - 1)
canLoadMore = items.count < totalCount
notifyStateChange()
}
private func load(reset: Bool, showLoading: Bool, api: any PunchPointAPIProtocol) async {
if reset {
currentPage = 1