// // PermissionApplyStatusViewController.swift // suixinkan // import SnapKit import UIKit /// 权限申请审核状态页,对齐 Android `PermissionApplyStatusScreen`。 final class PermissionApplyStatusViewController: BaseViewController { private let viewModel: PermissionApplyStatusViewModel private let homeAPI: HomeAPI private let scrollView = UIScrollView() private let contentStack = UIStackView() private let bannerView = PermissionApplyBannerView() private let loadingIndicator = UIActivityIndicatorView(style: .medium) init( applyCode: String, viewModel: PermissionApplyStatusViewModel? = nil, homeAPI: HomeAPI = NetworkServices.shared.homeAPI ) { self.viewModel = viewModel ?? PermissionApplyStatusViewModel(applyCode: applyCode) self.homeAPI = homeAPI 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 = 12 scrollView.addSubview(contentStack) view.addSubview(scrollView) view.addSubview(loadingIndicator) contentStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 16, right: 16)) make.width.equalTo(scrollView).offset(-32) } scrollView.snp.makeConstraints { make in make.edges.equalTo(view.safeAreaLayoutGuide) } loadingIndicator.snp.makeConstraints { make in make.center.equalToSuperview() } } override func bindActions() { viewModel.onStateChange = { [weak self] in Task { @MainActor in self?.applyViewModel() } } viewModel.onNavigateToEdit = { [weak self] pending in Task { @MainActor in self?.navigateToEdit(pending: pending) } } bannerView.onApplyNewScenic = { [weak self] in self?.navigationController?.pushViewController(ScenicApplicationViewController(), animated: true) } Task { await viewModel.loadPendingData(api: homeAPI) } } private func applyViewModel() { if viewModel.isLoading { loadingIndicator.startAnimating() scrollView.isHidden = true return } loadingIndicator.stopAnimating() scrollView.isHidden = false contentStack.arrangedSubviews.forEach { $0.removeFromSuperview() } contentStack.addArrangedSubview(bannerView) navigationItem.rightBarButtonItem = nil if let pending = viewModel.pendingData, pending.status == PermissionApplyPendingStatus.rejected { navigationItem.rightBarButtonItem = UIBarButtonItem( title: "去编辑", style: .plain, target: self, action: #selector(editTapped) ) navigationItem.rightBarButtonItem?.tintColor = AppColor.primary } guard let pending = viewModel.pendingData else { return } contentStack.addArrangedSubview(makeStatusCard(pending: pending)) contentStack.addArrangedSubview(makeSectionCard(title: "新增角色", chips: [pending.roleName])) if !pending.scenicList.isEmpty { contentStack.addArrangedSubview( makeSectionCard(title: "新增景区", chips: pending.scenicList.map(\.name)) ) } } private func makeStatusCard(pending: RoleApplyPendingResponse) -> UIView { let card = UIView() card.backgroundColor = AppColor.warningBackground card.layer.cornerRadius = 12 card.layer.borderWidth = 1 card.layer.borderColor = AppColor.warning.cgColor let statusLabel = UILabel() statusLabel.text = pending.statusLabel statusLabel.font = .systemFont(ofSize: 18, weight: .medium) statusLabel.textColor = AppColor.warning let stack = UIStackView() stack.axis = .vertical stack.spacing = 8 stack.addArrangedSubview(statusLabel) [ ("提交时间:", pending.createdAt), ("审核时间:", pending.auditedAt ?? "--"), ("审核人:", pending.auditedBy ?? "--"), ("审核备注:", pending.auditNote.isEmpty ? "--" : pending.auditNote), ].forEach { label, value in stack.addArrangedSubview(makeInfoRow(label: label, value: value)) } card.addSubview(stack) stack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(16) } return card } private func makeSectionCard(title: String, chips: [String]) -> UIView { let card = UIView() card.backgroundColor = .white card.layer.cornerRadius = 12 let titleLabel = UILabel() titleLabel.text = title titleLabel.font = .systemFont(ofSize: 16, weight: .medium) titleLabel.textColor = AppColor.textPrimary let chipStack = UIStackView() chipStack.axis = .horizontal chipStack.spacing = 8 chips.forEach { name in chipStack.addArrangedSubview(PermissionTagChip(title: name, showsRemove: false)) } card.addSubview(titleLabel) card.addSubview(chipStack) titleLabel.snp.makeConstraints { make in make.top.leading.trailing.equalToSuperview().inset(16) } chipStack.snp.makeConstraints { make in make.top.equalTo(titleLabel.snp.bottom).offset(12) make.leading.trailing.bottom.equalToSuperview().inset(16) } return card } private func makeInfoRow(label: String, value: String) -> UIView { let row = UIStackView() row.axis = .horizontal row.distribution = .equalSpacing let left = UILabel() left.text = label left.font = .systemFont(ofSize: 14) left.textColor = AppColor.textSecondary let right = UILabel() right.text = value.isEmpty ? "--" : value right.font = .systemFont(ofSize: 14) right.textColor = AppColor.textSecondary right.textAlignment = .right row.addArrangedSubview(left) row.addArrangedSubview(right) return row } @objc private func editTapped() { viewModel.navigateToEditIfRejected() } private func navigateToEdit(pending: RoleApplyPendingResponse) { var controllers = navigationController?.viewControllers ?? [] controllers.removeAll { $0 is PermissionApplyStatusViewController } let applyVC = PermissionApplyViewController(pendingData: pending) controllers.append(applyVC) navigationController?.setViewControllers(controllers, animated: true) } }