Files
suixinkan_ios_uikit/suixinkan_ios/Features/Payment/ViewControllers/PaymentCollectionViewController.swift
2026-06-26 14:33:31 +08:00

82 lines
2.9 KiB
Swift

//
// PaymentCollectionViewController.swift
// suixinkan
//
// Created by Codex on 2026/6/26.
//
import SnapKit
import UIKit
///
final class PaymentCollectionViewController: UIViewController {
private let services = AppServices.shared
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)
override func viewDidLoad() {
super.viewDidLoad()
title = "收款"
view.backgroundColor = UIColor(hex: 0xF5F7FA)
setupUI()
viewModel.onChange = { [weak self] in self?.render() }
Task { await viewModel.loadPayCode(api: services.paymentAPI, scenicId: services.currentScenicId) }
}
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))
]
}
private func render() {
qrImageView.image = viewModel.qrImage
statusLabel.text = viewModel.errorMessage ?? String(describing: viewModel.status)
if viewModel.isLoading { activityIndicator.startAnimating() } else { activityIndicator.stopAnimating() }
}
@objc private func applyAmount() {
viewModel.amountText = amountField.text ?? ""
viewModel.remarkText = remarkField.text ?? ""
_ = viewModel.applyDynamicAmount()
}
@objc private func togglePolling() {
Task {
await viewModel.pollUntilPaymentDetected(
api: services.paymentAPI,
scenicId: services.currentScenicId
)
}
}
}
extension PaymentCollectionViewModel: ViewModelBindable {}