// // 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) } }