添加景区选择与合作订单流程并对齐 Android

This commit is contained in:
2026-07-07 10:48:43 +08:00
parent ef1d3b4af5
commit c4057537d2
50 changed files with 5603 additions and 191 deletions

View File

@ -0,0 +1,196 @@
//
// BindAcquirerViewController.swift
// suixinkan
//
import SnapKit
import UIKit
/// / Android `BindAcquirerScreen`
final class BindAcquirerViewController: BaseViewController {
var onBindSuccess: (() -> Void)?
private let saleUserId: Int
private let viewModel = BindAcquirerViewModel()
private let orderAPI = NetworkServices.shared.orderAPI
private let scrollView = UIScrollView()
private let contentStack = UIStackView()
private let headerCard = UIView()
private let headerIcon = UIImageView()
private let headerTitleLabel = UILabel()
private let infoCard = UIView()
private let salerRow = CooperationInfoRowView(label: "获客员")
private let phoneRow = CooperationInfoRowView(label: "手机号")
private let commissionField = UITextField()
private let acceptButton = AppButton(title: "接受邀请")
private let loadingIndicator = UIActivityIndicatorView(style: .large)
private let bottomBar = UIView()
init(saleUserId: Int) {
self.saleUserId = saleUserId
super.init(nibName: nil, bundle: nil)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setupNavigationBar() {
title = "接受邀请"
}
override func setupUI() {
contentStack.axis = .vertical
contentStack.spacing = AppSpacing.sm
headerCard.backgroundColor = AppColor.primary
headerCard.layer.cornerRadius = AppRadius.md
headerIcon.image = UIImage(systemName: "person.fill")
headerIcon.tintColor = .white
headerTitleLabel.text = "邀请信息"
headerTitleLabel.font = .systemFont(ofSize: 16, weight: .bold)
headerTitleLabel.textColor = .white
infoCard.backgroundColor = .white
infoCard.layer.cornerRadius = AppRadius.md
commissionField.placeholder = "请输入分账比例0-100"
commissionField.keyboardType = .numberPad
commissionField.borderStyle = .roundedRect
commissionField.font = .systemFont(ofSize: 15)
bottomBar.backgroundColor = .white
acceptButton.addTarget(self, action: #selector(acceptTapped), for: .touchUpInside)
loadingIndicator.hidesWhenStopped = true
loadingIndicator.color = AppColor.primary
view.addSubview(scrollView)
view.addSubview(bottomBar)
scrollView.addSubview(contentStack)
bottomBar.addSubview(acceptButton)
scrollView.addSubview(loadingIndicator)
contentStack.addArrangedSubview(headerCard)
contentStack.addArrangedSubview(infoCard)
headerCard.addSubview(headerIcon)
headerCard.addSubview(headerTitleLabel)
let infoStack = UIStackView(arrangedSubviews: [salerRow, phoneRow, commissionField])
infoStack.axis = .vertical
infoStack.spacing = AppSpacing.sm
infoCard.addSubview(infoStack)
infoStack.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(AppSpacing.md)
}
headerIcon.snp.makeConstraints { make in
make.leading.equalToSuperview().offset(AppSpacing.md)
make.centerY.equalToSuperview()
make.size.equalTo(24)
}
headerTitleLabel.snp.makeConstraints { make in
make.leading.equalTo(headerIcon.snp.trailing).offset(AppSpacing.sm)
make.trailing.equalToSuperview().inset(AppSpacing.md)
make.top.bottom.equalToSuperview().inset(AppSpacing.md)
}
headerCard.snp.makeConstraints { make in
make.height.greaterThanOrEqualTo(56)
}
commissionField.snp.makeConstraints { make in
make.height.equalTo(44)
}
}
override func setupConstraints() {
bottomBar.snp.makeConstraints { make in
make.leading.trailing.bottom.equalToSuperview()
}
acceptButton.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(AppSpacing.md)
}
scrollView.snp.makeConstraints { make in
make.top.leading.trailing.equalTo(view.safeAreaLayoutGuide)
make.bottom.equalTo(bottomBar.snp.top)
}
contentStack.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(AppSpacing.md)
make.width.equalTo(scrollView.snp.width).offset(-AppSpacing.md * 2)
}
loadingIndicator.snp.makeConstraints { make in
make.center.equalTo(scrollView)
}
}
override func bindActions() {
viewModel.onStateChange = { [weak self] in
Task { @MainActor in self?.applyViewModel() }
}
viewModel.onShowMessage = { [weak self] message in
Task { @MainActor in self?.showToast(message) }
}
viewModel.onBindSuccess = { [weak self] in
Task { @MainActor in
if let callback = self?.onBindSuccess {
callback()
} else {
self?.navigationController?.popViewController(animated: true)
}
}
}
viewModel.onShouldPop = { [weak self] in
Task { @MainActor in self?.navigationController?.popViewController(animated: true) }
}
commissionField.addTarget(self, action: #selector(commissionChanged), for: .editingChanged)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard CooperationOrderFeature.hasPermission(in: AppStore.shared.permissionItems()) else {
showToast("暂无合作订单权限")
navigationController?.popViewController(animated: false)
return
}
}
override func viewDidLoad() {
super.viewDidLoad()
viewModel.initSaleUserId(saleUserId)
Task { await viewModel.loadInviteInfo(api: orderAPI) }
}
@objc private func commissionChanged() {
viewModel.updateCommissionRateDraft(commissionField.text ?? "")
}
@objc private func acceptTapped() {
Task { await viewModel.acceptBind(api: orderAPI) }
}
private func applyViewModel() {
if viewModel.isLoading, viewModel.inviteInfo == nil {
loadingIndicator.startAnimating()
contentStack.isHidden = true
bottomBar.isHidden = true
return
}
loadingIndicator.stopAnimating()
contentStack.isHidden = false
bottomBar.isHidden = false
if let info = viewModel.inviteInfo {
title = info.title.isEmpty ? "接受邀请" : info.title
salerRow.setValue(info.salerName.isEmpty ? "" : info.salerName)
phoneRow.setValue(info.salerPhone.isEmpty ? "" : info.salerPhone)
}
commissionField.text = viewModel.commissionRateDraft
commissionField.isEnabled = !viewModel.isAlreadyBound
acceptButton.isEnabled = !viewModel.isAlreadyBound
acceptButton.setTitle(viewModel.isAlreadyBound ? "已绑定获客员" : "接受邀请", for: .normal)
}
}