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>
144 lines
4.8 KiB
Swift
144 lines
4.8 KiB
Swift
//
|
|
// ScenicSettlementViewControllers.swift
|
|
// suixinkan
|
|
//
|
|
// Created by Codex on 2026/6/26.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
/// 景区结算申请页。
|
|
final class ScenicSettlementViewController: ModuleTableViewController {
|
|
private let viewModel = ScenicSettlementViewModel()
|
|
private let amountField = UITextField()
|
|
private let remarkField = UITextField()
|
|
|
|
/// 视图加载完成后的 UI 初始化与数据绑定。
|
|
override func viewDidLoad() {
|
|
title = "景区结算"
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
title: "提交",
|
|
style: .done,
|
|
target: self,
|
|
action: #selector(submit)
|
|
)
|
|
super.viewDidLoad()
|
|
setupHeader()
|
|
wireViewModel(viewModel) { }
|
|
}
|
|
|
|
/// 初始化Header相关 UI 或状态。
|
|
private func setupHeader() {
|
|
amountField.placeholder = "结算金额"
|
|
amountField.borderStyle = .roundedRect
|
|
amountField.keyboardType = .decimalPad
|
|
remarkField.placeholder = "备注"
|
|
remarkField.borderStyle = .roundedRect
|
|
let stack = UIStackView(arrangedSubviews: [amountField, remarkField])
|
|
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
|
|
}
|
|
|
|
/// table行Count相关逻辑。
|
|
override func tableRowCount() -> Int {
|
|
viewModel.options.count
|
|
}
|
|
|
|
/// 配置Cell展示内容。
|
|
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
|
let option = viewModel.options[indexPath.row]
|
|
cell.configure(title: option.name, subtitle: option.selected ? "已选择" : nil)
|
|
cell.accessoryType = option.selected ? .checkmark : .none
|
|
}
|
|
|
|
/// didSelectTableRow 回调处理。
|
|
override func didSelectTableRow(at indexPath: IndexPath) {
|
|
viewModel.toggleScenic(id: viewModel.options[indexPath.row].id)
|
|
}
|
|
|
|
/// 刷新Content。
|
|
override func reloadContent() async {
|
|
await viewModel.load(
|
|
api: services.scenicPermissionAPI,
|
|
existingScenics: services.accountContext.scenicScopes
|
|
)
|
|
}
|
|
|
|
/// 提交。
|
|
@objc private func submit() {
|
|
viewModel.amountText = amountField.text ?? ""
|
|
viewModel.remarkText = remarkField.text ?? ""
|
|
Task {
|
|
let success = await viewModel.submit(api: services.scenicSettlementAPI)
|
|
if success {
|
|
services.toastCenter.show("提交成功")
|
|
navigationController?.popViewController(animated: true)
|
|
} else if let message = viewModel.message {
|
|
services.toastCenter.show(message)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ScenicSettlementViewModel: ViewModelBindable {}
|
|
|
|
/// 景区结算审核页。
|
|
final class ScenicSettlementReviewViewController: ModuleTableViewController {
|
|
private let viewModel = ScenicSettlementReviewViewModel()
|
|
|
|
/// 视图加载完成后的 UI 初始化与数据绑定。
|
|
override func viewDidLoad() {
|
|
title = "结算审核"
|
|
super.viewDidLoad()
|
|
wireViewModel(viewModel) { }
|
|
}
|
|
|
|
/// 返回列表 section 数量。
|
|
override func numberOfTableSections() -> Int { 2 }
|
|
|
|
/// 返回指定 section 行数。
|
|
override func tableRowCount(in section: Int) -> Int {
|
|
section == 0 ? viewModel.scenicApplications.count : viewModel.roleApplications.count
|
|
}
|
|
|
|
/// section 标题。
|
|
override func tableSectionTitle(for section: Int) -> String? {
|
|
section == 0 ? "景区申请" : "权限申请"
|
|
}
|
|
|
|
/// 提供自定义 Cell。
|
|
override func tableCell(for indexPath: IndexPath, row: ModuleTableRow, in tableView: UITableView) -> UITableViewCell {
|
|
let cell = tableView.dequeueReusableCell(
|
|
withIdentifier: TitleSubtitleTableViewCell.reuseIdentifier,
|
|
for: indexPath
|
|
) as! TitleSubtitleTableViewCell
|
|
if indexPath.section == 0 {
|
|
let item = viewModel.scenicApplications[indexPath.row]
|
|
cell.configure(
|
|
title: item.scenicName,
|
|
subtitle: viewModel.statusText(item.status),
|
|
detail: item.createdAt
|
|
)
|
|
} else {
|
|
let item = viewModel.roleApplications[indexPath.row]
|
|
cell.configure(
|
|
title: item.roleName,
|
|
subtitle: viewModel.statusText(item.status, fallback: item.statusLabel),
|
|
detail: item.createdAt
|
|
)
|
|
}
|
|
return cell
|
|
}
|
|
|
|
/// 刷新Content。
|
|
override func reloadContent() async {
|
|
await viewModel.load(api: services.scenicPermissionAPI)
|
|
}
|
|
}
|
|
|
|
extension ScenicSettlementReviewViewModel: ViewModelBindable {}
|