Advance UIKit rewrite with AMap integration and core UI modules.

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>
This commit is contained in:
2026-06-26 15:16:12 +08:00
parent 9edf993432
commit d99a5b1bf8
124 changed files with 5195 additions and 1536 deletions

View File

@ -13,6 +13,7 @@ struct WalletSummaryResponse: Decodable, Equatable {
let amountCurrentBalance: String
let amountWithdrawable: String
///
enum CodingKeys: String, CodingKey {
case amountTotal = "amount_total"
case amountCurrentBalance = "amount_current_balance"
@ -42,6 +43,7 @@ struct WalletEarningDetailResponse: Decodable, Equatable {
let total: Int
let list: [WalletEarningDetailGroup]
///
enum CodingKeys: String, CodingKey {
case totalAmount = "total_amount"
case totalPoints = "total_points"
@ -76,6 +78,7 @@ struct WalletEarningDetailGroup: Decodable, Equatable, Identifiable {
var id: String { date }
///
enum CodingKeys: String, CodingKey {
case date
case dayAmount = "day_amount"
@ -113,6 +116,7 @@ struct WalletEarningDetailItem: Decodable, Equatable, Identifiable {
let withdrawLabel: String?
let source: String?
///
enum CodingKeys: String, CodingKey {
case id
case amount
@ -168,6 +172,7 @@ struct WalletWithdrawListResponse: Decodable, Equatable {
let total: Int
let item: [WalletWithdrawRecord]
///
enum CodingKeys: String, CodingKey {
case total
case item
@ -197,6 +202,7 @@ struct WalletWithdrawRecord: Decodable, Equatable, Identifiable {
let auditTime: String?
let completedAt: String?
///
enum CodingKeys: String, CodingKey {
case id
case amount
@ -224,6 +230,7 @@ struct WalletWithdrawRecord: Decodable, Equatable, Identifiable {
struct BankCardInfoResponse: Decodable, Equatable {
let bankCard: WalletBankCardInfo?
///
enum CodingKeys: String, CodingKey {
case bankCard = "bank_card"
}
@ -244,6 +251,7 @@ struct WalletBankCardInfo: Decodable, Equatable, Identifiable {
let auditStatus: Int
let auditStatusLabel: String
///
enum CodingKeys: String, CodingKey {
case realName = "real_name"
case bankName = "bank_name"
@ -279,6 +287,7 @@ struct WalletBankCardInfo: Decodable, Equatable, Identifiable {
struct BankListResponse: Decodable, Equatable {
let banks: [String]
///
enum CodingKeys: String, CodingKey {
case banks
}
@ -296,6 +305,7 @@ struct AreaNode: Decodable, Equatable, Identifiable {
let name: String
let children: [AreaNode]
///
enum CodingKeys: String, CodingKey {
case id
case code
@ -324,6 +334,7 @@ struct WithdrawInfoResponse: Decodable, Equatable {
let bankCard: WithdrawBankCardInfo
let withdrawInfo: [String]
///
enum CodingKeys: String, CodingKey {
case amountWithdrawable = "amount_withdrawable"
case minWithdrawAmount = "min_withdraw_amount"
@ -353,6 +364,7 @@ struct WithdrawBankCardInfo: Decodable, Equatable {
let bankName: String
let cardNumber: String
///
enum CodingKeys: String, CodingKey {
case realName = "real_name"
case bankName = "bank_name"
@ -380,6 +392,7 @@ struct WithdrawApplyRequest: Encodable {
let amount: String
let smsCode: String
///
enum CodingKeys: String, CodingKey {
case amount
case smsCode = "sms_code"
@ -398,6 +411,7 @@ struct UpdateBankInfoRequest: Encodable, Equatable {
let cityCode: String
let smsVerifyCode: String
///
enum CodingKeys: String, CodingKey {
case realName = "real_name"
case cardNumber = "card_number"
@ -419,6 +433,7 @@ struct PointOverviewResponse: Decodable, Equatable {
let pendingPoints: Int
let time: String
///
enum CodingKeys: String, CodingKey {
case totalPoints = "total_points"
case availablePoints = "available_points"
@ -459,6 +474,7 @@ struct PointWithdrawListRequest: Encodable {
let page: Int
let pageSize: Int
///
enum CodingKeys: String, CodingKey {
case status
case page
@ -471,6 +487,7 @@ struct PointWithdrawListResponse: Decodable, Equatable {
let total: Int
let list: [PointWithdrawItem]
///
enum CodingKeys: String, CodingKey {
case total
case list
@ -498,6 +515,7 @@ struct PointWithdrawItem: Decodable, Equatable, Identifiable {
let status: Int
let createdAt: String
///
enum CodingKeys: String, CodingKey {
case id
case points

View File

@ -12,6 +12,7 @@ final class WalletViewController: ModuleTableViewController {
private let viewModel = WalletViewModel()
private let summaryLabel = UILabel()
/// UI
override func viewDidLoad() {
title = "我的钱包"
navigationItem.rightBarButtonItem = UIBarButtonItem(
@ -25,6 +26,7 @@ final class WalletViewController: ModuleTableViewController {
wireViewModel(viewModel) { [weak self] in self?.updateSummary() }
}
/// Header UI
private func setupHeader() {
summaryLabel.numberOfLines = 0
summaryLabel.font = .systemFont(ofSize: 14)
@ -34,6 +36,7 @@ final class WalletViewController: ModuleTableViewController {
tableView.tableHeaderView = summaryLabel
}
/// tableCount
override func tableRowCount() -> Int {
switch viewModel.selectedTab {
case .earnings:
@ -43,6 +46,7 @@ final class WalletViewController: ModuleTableViewController {
}
}
/// Cell
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
switch viewModel.selectedTab {
case .earnings:
@ -55,16 +59,19 @@ final class WalletViewController: ModuleTableViewController {
}
}
/// 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)
}
@ -78,6 +85,7 @@ final class WalletWithdrawViewController: ModuleTableViewController {
private let amountField = UITextField()
private let smsField = UITextField()
/// UI
override func viewDidLoad() {
title = "申请提现"
navigationItem.rightBarButtonItems = [
@ -100,21 +108,26 @@ final class WalletWithdrawViewController: ModuleTableViewController {
wireViewModel(viewModel) { }
}
/// tableCount
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 ?? ""