Integrate高德 SDK with simulator-safe build flags, add map views for operating area and punch points, refactor main tabs and key feature screens to UIKit with Diffable lists, and document Swift concurrency defaults in AGENTS.md. Co-authored-by: Cursor <cursoragent@cursor.com>
146 lines
5.2 KiB
Swift
146 lines
5.2 KiB
Swift
//
|
|
// WalletViewControllers.swift
|
|
// suixinkan
|
|
//
|
|
// Created by Codex on 2026/6/26.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
/// 钱包首页。
|
|
final class WalletViewController: ModuleTableViewController {
|
|
private let viewModel = WalletViewModel()
|
|
private let summaryLabel = UILabel()
|
|
|
|
/// 视图加载完成后的 UI 初始化与数据绑定。
|
|
override func viewDidLoad() {
|
|
title = "我的钱包"
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
title: "提现",
|
|
style: .plain,
|
|
target: self,
|
|
action: #selector(openWithdraw)
|
|
)
|
|
super.viewDidLoad()
|
|
setupHeader()
|
|
wireViewModel(viewModel) { [weak self] in self?.updateSummary() }
|
|
}
|
|
|
|
/// 初始化Header相关 UI 或状态。
|
|
private func setupHeader() {
|
|
summaryLabel.numberOfLines = 0
|
|
summaryLabel.font = .systemFont(ofSize: 14)
|
|
summaryLabel.textAlignment = .center
|
|
summaryLabel.textColor = AppDesign.textSecondary
|
|
summaryLabel.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 72)
|
|
tableView.tableHeaderView = summaryLabel
|
|
}
|
|
|
|
/// table行Count相关逻辑。
|
|
override func tableRowCount() -> Int {
|
|
switch viewModel.selectedTab {
|
|
case .earnings:
|
|
return viewModel.earningsGroups.flatMap(\.items).count
|
|
case .withdraws:
|
|
return viewModel.withdrawRecords.count
|
|
}
|
|
}
|
|
|
|
/// 配置Cell展示内容。
|
|
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
|
switch viewModel.selectedTab {
|
|
case .earnings:
|
|
let items = viewModel.earningsGroups.flatMap(\.items)
|
|
let item = items[indexPath.row]
|
|
cell.configure(title: item.typeLabel, subtitle: item.amount, detail: item.createdAt)
|
|
case .withdraws:
|
|
let record = viewModel.withdrawRecords[indexPath.row]
|
|
cell.configure(title: "¥\(record.amount)", subtitle: record.statusLabel, detail: record.createdAt)
|
|
}
|
|
}
|
|
|
|
/// 刷新Content。
|
|
override func reloadContent() async {
|
|
await viewModel.loadInitial(api: services.walletAPI, staffId: services.staffId)
|
|
updateSummary()
|
|
}
|
|
|
|
/// 更新Summary状态。
|
|
private func updateSummary() {
|
|
summaryLabel.text = "\(viewModel.withdrawableText) · \(viewModel.totalAmountText)"
|
|
navigationItem.rightBarButtonItem?.title = viewModel.selectedTab == .earnings ? "提现记录" : "收益明细"
|
|
}
|
|
|
|
/// openWithdraw相关逻辑。
|
|
@objc private func openWithdraw() {
|
|
navigationController?.pushViewController(WalletWithdrawViewController(), animated: true)
|
|
}
|
|
}
|
|
|
|
extension WalletViewModel: ViewModelBindable {}
|
|
|
|
/// 钱包提现页。
|
|
final class WalletWithdrawViewController: ModuleTableViewController {
|
|
private let viewModel = WithdrawApplyViewModel()
|
|
private let amountField = UITextField()
|
|
private let smsField = UITextField()
|
|
|
|
/// 视图加载完成后的 UI 初始化与数据绑定。
|
|
override func viewDidLoad() {
|
|
title = "申请提现"
|
|
navigationItem.rightBarButtonItems = [
|
|
UIBarButtonItem(title: "提交", style: .done, target: self, action: #selector(submit)),
|
|
UIBarButtonItem(title: "验证码", style: .plain, target: self, action: #selector(sendSms))
|
|
]
|
|
super.viewDidLoad()
|
|
amountField.placeholder = "提现金额"
|
|
amountField.borderStyle = .roundedRect
|
|
amountField.keyboardType = .decimalPad
|
|
smsField.placeholder = "短信验证码"
|
|
smsField.borderStyle = .roundedRect
|
|
let stack = UIStackView(arrangedSubviews: [amountField, smsField])
|
|
stack.axis = .vertical
|
|
stack.spacing = 8
|
|
stack.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 96)
|
|
stack.layoutMargins = UIEdgeInsets(top: 12, left: 16, bottom: 12, right: 16)
|
|
stack.isLayoutMarginsRelativeArrangement = true
|
|
tableView.tableHeaderView = stack
|
|
wireViewModel(viewModel) { }
|
|
}
|
|
|
|
/// table行Count相关逻辑。
|
|
override func tableRowCount() -> Int { 1 }
|
|
|
|
/// 配置Cell展示内容。
|
|
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
|
let amount = viewModel.info?.amountWithdrawable ?? "0"
|
|
cell.configure(title: "可提现", subtitle: "¥ \(amount)")
|
|
}
|
|
|
|
/// 刷新Content。
|
|
override func reloadContent() async {
|
|
await viewModel.load(api: services.walletAPI)
|
|
}
|
|
|
|
/// sendSms相关逻辑。
|
|
@objc private func sendSms() {
|
|
Task { await viewModel.sendSms(api: services.walletAPI) }
|
|
}
|
|
|
|
/// 提交。
|
|
@objc private func submit() {
|
|
viewModel.amountText = amountField.text ?? ""
|
|
viewModel.smsCode = smsField.text ?? ""
|
|
Task {
|
|
if await viewModel.submit(api: services.walletAPI) {
|
|
services.toastCenter.show("提现申请已提交")
|
|
navigationController?.popViewController(animated: true)
|
|
} else if let message = viewModel.errorMessage {
|
|
services.toastCenter.show(message)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension WithdrawApplyViewModel: ViewModelBindable {}
|