Files
suixinkan_ios_uikit/suixinkan_ios/Features/Payment/ViewControllers/PaymentCollectionViewController.swift
汉秋 24a7339b68 Refactor AppServices into grouped bundles and document DI conventions.
Centralize dependency wiring with Session/Context/Network/UI/Runtime bundles, unify leaf ViewControllers on appServices, and add a test initializer with AppServicesTests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 15:24:25 +08:00

86 lines
3.1 KiB
Swift

//
// PaymentCollectionViewController.swift
// suixinkan
//
// Created by Codex on 2026/6/26.
//
import SnapKit
import UIKit
///
final class PaymentCollectionViewController: UIViewController {
private let viewModel = PaymentCollectionViewModel()
private let qrImageView = UIImageView()
private let statusLabel = UILabel()
private let amountField = UITextField()
private let remarkField = UITextField()
private let activityIndicator = UIActivityIndicatorView(style: .large)
/// UI
override func viewDidLoad() {
super.viewDidLoad()
title = "收款"
view.backgroundColor = UIColor(hex: 0xF5F7FA)
setupUI()
viewModel.onChange = { [weak self] in self?.render() }
Task { await viewModel.loadPayCode(api: appServices.paymentAPI, scenicId: appServices.currentScenicId) }
}
/// UI UI
private func setupUI() {
qrImageView.contentMode = .scaleAspectFit
statusLabel.numberOfLines = 0
statusLabel.textAlignment = .center
statusLabel.textColor = AppDesign.textSecondary
amountField.placeholder = "动态金额"
amountField.borderStyle = .roundedRect
amountField.keyboardType = .decimalPad
remarkField.placeholder = "备注"
remarkField.borderStyle = .roundedRect
let stack = UIStackView(arrangedSubviews: [qrImageView, statusLabel, amountField, remarkField])
stack.axis = .vertical
stack.spacing = 12
view.addSubview(stack)
view.addSubview(activityIndicator)
stack.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide).offset(24)
make.leading.trailing.equalToSuperview().inset(24)
}
qrImageView.snp.makeConstraints { $0.height.equalTo(240) }
activityIndicator.snp.makeConstraints { $0.center.equalTo(qrImageView) }
navigationItem.rightBarButtonItems = [
UIBarButtonItem(title: "生成", style: .plain, target: self, action: #selector(applyAmount)),
UIBarButtonItem(title: "轮询", style: .plain, target: self, action: #selector(togglePolling))
]
}
/// render
private func render() {
qrImageView.image = viewModel.qrImage
statusLabel.text = viewModel.errorMessage ?? String(describing: viewModel.status)
if viewModel.isLoading { activityIndicator.startAnimating() } else { activityIndicator.stopAnimating() }
}
/// apply
@objc private func applyAmount() {
viewModel.amountText = amountField.text ?? ""
viewModel.remarkText = remarkField.text ?? ""
_ = viewModel.applyDynamicAmount()
}
/// togglePolling
@objc private func togglePolling() {
Task {
await viewModel.pollUntilPaymentDetected(
api: appServices.paymentAPI,
scenicId: appServices.currentScenicId
)
}
}
}
extension PaymentCollectionViewModel: ViewModelBindable {}