添加景区入驻申请流程并对齐 Android
This commit is contained in:
@ -6,58 +6,39 @@
|
||||
import SnapKit
|
||||
import UIKit
|
||||
|
||||
/// 订单来源选择 Bottom Sheet,对齐 Android `OrderSourcePicker` 弹层。
|
||||
/// 订单来源获客员选择 Bottom Sheet 首页,点击获客员后 push 带客单页。
|
||||
final class OrderSourcePickerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
|
||||
|
||||
private enum MenuLevel {
|
||||
case person
|
||||
case lead
|
||||
}
|
||||
|
||||
private let orderNumber: String
|
||||
private let viewModel: OrderListViewModel
|
||||
private let onPersonSelected: (OrderSourcePerson) -> Void
|
||||
private let referralOrder: BoundReferralOrderEntity?
|
||||
private let loadLeads: (OrderSourcePerson) async -> Void
|
||||
private let onLeadBound: (OrderSourceSelection) -> Void
|
||||
private let onCallPhone: (String) -> Void
|
||||
private let onPreviewImages: ([String], Int) -> Void
|
||||
|
||||
private var level: MenuLevel = .person
|
||||
private var pendingPerson: OrderSourcePerson?
|
||||
|
||||
private let headerStack = UIStackView()
|
||||
private let titleLabel = UILabel()
|
||||
private let subtitleLabel = UILabel()
|
||||
private let leadHeaderRow = UIStackView()
|
||||
private let backButton = UIButton(type: .system)
|
||||
private let leadTitleLabel = UILabel()
|
||||
private let leadPhoneButton = UIButton(type: .system)
|
||||
private let leadCallButton = UIButton(type: .system)
|
||||
private let tableView = UITableView(frame: .zero, style: .plain)
|
||||
private let loadingIndicator = UIActivityIndicatorView(style: .medium)
|
||||
private let emptyLabel = UILabel()
|
||||
|
||||
private var referralOrder: BoundReferralOrderEntity?
|
||||
|
||||
init(
|
||||
orderNumber: String,
|
||||
viewModel: OrderListViewModel,
|
||||
referralOrder: BoundReferralOrderEntity?,
|
||||
onPersonSelected: @escaping (OrderSourcePerson) -> Void,
|
||||
loadLeads: @escaping (OrderSourcePerson) async -> Void,
|
||||
onLeadBound: @escaping (OrderSourceSelection) -> Void,
|
||||
onCallPhone: @escaping (String) -> Void,
|
||||
onPreviewImages: @escaping ([String], Int) -> Void
|
||||
) {
|
||||
self.orderNumber = orderNumber
|
||||
self.viewModel = viewModel
|
||||
self.onPersonSelected = onPersonSelected
|
||||
self.referralOrder = referralOrder
|
||||
self.loadLeads = loadLeads
|
||||
self.onLeadBound = onLeadBound
|
||||
self.onCallPhone = onCallPhone
|
||||
self.onPreviewImages = onPreviewImages
|
||||
self.referralOrder = referralOrder
|
||||
self.pendingPerson = viewModel.orderSourceSelection(
|
||||
orderNumber: orderNumber,
|
||||
referralOrder: referralOrder
|
||||
)?.person
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@ -75,6 +56,8 @@ final class OrderSourcePickerViewController: UIViewController, UITableViewDataSo
|
||||
|
||||
func reloadFromViewModel() {
|
||||
applyViewModel()
|
||||
(navigationController?.topViewController as? OrderSourceLeadListViewController)?
|
||||
.reloadFromViewModel()
|
||||
}
|
||||
|
||||
private func setupUI() {
|
||||
@ -87,72 +70,37 @@ final class OrderSourcePickerViewController: UIViewController, UITableViewDataSo
|
||||
subtitleLabel.text = "选择人员后,再选择该人员创建的带客单"
|
||||
subtitleLabel.numberOfLines = 0
|
||||
|
||||
backButton.setImage(UIImage(systemName: "chevron.left"), for: .normal)
|
||||
backButton.tintColor = AppColor.text333
|
||||
backButton.addTarget(self, action: #selector(backTapped), for: .touchUpInside)
|
||||
|
||||
leadTitleLabel.font = .systemFont(ofSize: 18, weight: .bold)
|
||||
leadTitleLabel.textColor = AppColor.text333
|
||||
leadTitleLabel.numberOfLines = 2
|
||||
|
||||
leadPhoneButton.titleLabel?.font = .systemFont(ofSize: 13)
|
||||
leadPhoneButton.setTitleColor(AppColor.primary, for: .normal)
|
||||
leadPhoneButton.contentHorizontalAlignment = .leading
|
||||
leadPhoneButton.addTarget(self, action: #selector(leadPhoneTapped), for: .touchUpInside)
|
||||
|
||||
leadCallButton.backgroundColor = OrderTokens.phoneIconBackground
|
||||
leadCallButton.layer.cornerRadius = 16
|
||||
leadCallButton.tintColor = AppColor.primary
|
||||
leadCallButton.setImage(UIImage(systemName: "phone.fill"), for: .normal)
|
||||
leadCallButton.addTarget(self, action: #selector(leadPhoneTapped), for: .touchUpInside)
|
||||
|
||||
leadHeaderRow.axis = .horizontal
|
||||
leadHeaderRow.alignment = .top
|
||||
leadHeaderRow.spacing = 10
|
||||
leadHeaderRow.isHidden = true
|
||||
let leadTextStack = UIStackView(arrangedSubviews: [leadTitleLabel, leadPhoneButton])
|
||||
leadTextStack.axis = .vertical
|
||||
leadTextStack.spacing = 3
|
||||
leadHeaderRow.addArrangedSubview(backButton)
|
||||
leadHeaderRow.addArrangedSubview(leadTextStack)
|
||||
leadHeaderRow.addArrangedSubview(leadCallButton)
|
||||
|
||||
headerStack.axis = .vertical
|
||||
headerStack.spacing = 5
|
||||
headerStack.addArrangedSubview(titleLabel)
|
||||
headerStack.addArrangedSubview(subtitleLabel)
|
||||
headerStack.addArrangedSubview(leadHeaderRow)
|
||||
|
||||
tableView.separatorStyle = .none
|
||||
tableView.backgroundColor = .white
|
||||
tableView.dataSource = self
|
||||
tableView.delegate = self
|
||||
tableView.register(OrderSourcePersonCell.self, forCellReuseIdentifier: OrderSourcePersonCell.reuseIdentifier)
|
||||
tableView.register(OrderSourceLeadCell.self, forCellReuseIdentifier: OrderSourceLeadCell.reuseIdentifier)
|
||||
|
||||
loadingIndicator.hidesWhenStopped = true
|
||||
loadingIndicator.color = AppColor.primary
|
||||
|
||||
emptyLabel.font = .systemFont(ofSize: 14)
|
||||
emptyLabel.textColor = AppColor.text666
|
||||
emptyLabel.textAlignment = .center
|
||||
emptyLabel.numberOfLines = 0
|
||||
emptyLabel.text = "暂无合作获客员"
|
||||
|
||||
view.addSubview(headerStack)
|
||||
view.addSubview(titleLabel)
|
||||
view.addSubview(subtitleLabel)
|
||||
view.addSubview(tableView)
|
||||
view.addSubview(loadingIndicator)
|
||||
view.addSubview(emptyLabel)
|
||||
|
||||
headerStack.snp.makeConstraints { make in
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(view.safeAreaLayoutGuide).offset(AppSpacing.md)
|
||||
make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
|
||||
}
|
||||
backButton.snp.makeConstraints { make in
|
||||
make.width.height.equalTo(28)
|
||||
}
|
||||
leadCallButton.snp.makeConstraints { make in
|
||||
make.width.height.equalTo(32)
|
||||
subtitleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(5)
|
||||
make.leading.trailing.equalTo(titleLabel)
|
||||
}
|
||||
tableView.snp.makeConstraints { make in
|
||||
make.top.equalTo(headerStack.snp.bottom).offset(14)
|
||||
make.top.equalTo(subtitleLabel.snp.bottom).offset(14)
|
||||
make.leading.trailing.bottom.equalToSuperview()
|
||||
}
|
||||
loadingIndicator.snp.makeConstraints { make in
|
||||
@ -165,113 +113,54 @@ final class OrderSourcePickerViewController: UIViewController, UITableViewDataSo
|
||||
}
|
||||
|
||||
private func applyViewModel() {
|
||||
let currentSelection = viewModel.orderSourceSelection(
|
||||
orderNumber: orderNumber,
|
||||
referralOrder: referralOrder
|
||||
)
|
||||
titleLabel.isHidden = level == .lead
|
||||
subtitleLabel.isHidden = level == .lead
|
||||
leadHeaderRow.isHidden = level == .person
|
||||
|
||||
if level == .lead, let person = pendingPerson {
|
||||
leadTitleLabel.text = "\(person.name)创建的带客单"
|
||||
let phone = person.phone.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
leadPhoneButton.setTitle(phone, for: .normal)
|
||||
leadPhoneButton.isHidden = phone.isEmpty
|
||||
leadCallButton.isHidden = phone.isEmpty
|
||||
}
|
||||
|
||||
let isLoadingPeople = viewModel.isLoadingOrderSourcePeople && level == .person
|
||||
let isLoadingLeads = viewModel.loadingOrderSourceLeadsFor != nil && level == .lead
|
||||
if isLoadingPeople || isLoadingLeads {
|
||||
if viewModel.isLoadingOrderSourcePeople {
|
||||
loadingIndicator.startAnimating()
|
||||
tableView.isHidden = true
|
||||
emptyLabel.isHidden = true
|
||||
} else {
|
||||
loadingIndicator.stopAnimating()
|
||||
tableView.isHidden = false
|
||||
let isEmpty: Bool
|
||||
switch level {
|
||||
case .person:
|
||||
isEmpty = viewModel.orderSourcePeople.isEmpty
|
||||
case .lead:
|
||||
isEmpty = leadsForPendingPerson.isEmpty
|
||||
}
|
||||
let isEmpty = viewModel.orderSourcePeople.isEmpty
|
||||
emptyLabel.isHidden = !isEmpty
|
||||
emptyLabel.text = level == .person ? "暂无合作获客员" : "暂无可绑定带客单"
|
||||
tableView.reloadData()
|
||||
}
|
||||
_ = currentSelection
|
||||
}
|
||||
|
||||
private var leadsForPendingPerson: [OrderSourceLead] {
|
||||
guard let person = pendingPerson else { return [] }
|
||||
return viewModel.orderSourceLeads[person.key] ?? []
|
||||
}
|
||||
|
||||
@objc private func backTapped() {
|
||||
level = .person
|
||||
applyViewModel()
|
||||
}
|
||||
|
||||
@objc private func leadPhoneTapped() {
|
||||
guard let phone = pendingPerson?.phone.trimmingCharacters(in: .whitespacesAndNewlines), !phone.isEmpty else { return }
|
||||
onCallPhone(phone)
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
switch level {
|
||||
case .person:
|
||||
return viewModel.orderSourcePeople.count
|
||||
case .lead:
|
||||
return leadsForPendingPerson.count
|
||||
}
|
||||
viewModel.orderSourcePeople.count
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(
|
||||
withIdentifier: OrderSourcePersonCell.reuseIdentifier,
|
||||
for: indexPath
|
||||
) as! OrderSourcePersonCell
|
||||
let person = viewModel.orderSourcePeople[indexPath.row]
|
||||
let currentSelection = viewModel.orderSourceSelection(
|
||||
orderNumber: orderNumber,
|
||||
referralOrder: referralOrder
|
||||
)
|
||||
switch level {
|
||||
case .person:
|
||||
let cell = tableView.dequeueReusableCell(
|
||||
withIdentifier: OrderSourcePersonCell.reuseIdentifier,
|
||||
for: indexPath
|
||||
) as! OrderSourcePersonCell
|
||||
let person = viewModel.orderSourcePeople[indexPath.row]
|
||||
cell.configure(
|
||||
person: person,
|
||||
selected: currentSelection?.person.key == person.key
|
||||
)
|
||||
cell.onCallPhone = onCallPhone
|
||||
return cell
|
||||
case .lead:
|
||||
let cell = tableView.dequeueReusableCell(
|
||||
withIdentifier: OrderSourceLeadCell.reuseIdentifier,
|
||||
for: indexPath
|
||||
) as! OrderSourceLeadCell
|
||||
let lead = leadsForPendingPerson[indexPath.row]
|
||||
let selected = currentSelection?.person.key == pendingPerson?.key
|
||||
&& currentSelection?.lead.key == lead.key
|
||||
cell.configure(lead: lead, selected: selected)
|
||||
cell.onCallPhone = onCallPhone
|
||||
cell.onImageTap = onPreviewImages
|
||||
cell.onSelect = { [weak self] in
|
||||
guard let self, let person = self.pendingPerson else { return }
|
||||
let selection = OrderSourceSelection(person: person, lead: lead)
|
||||
self.onLeadBound(selection)
|
||||
}
|
||||
return cell
|
||||
}
|
||||
cell.configure(
|
||||
person: person,
|
||||
selected: currentSelection?.person.key == person.key
|
||||
)
|
||||
cell.onCallPhone = onCallPhone
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
guard level == .person else { return }
|
||||
let person = viewModel.orderSourcePeople[indexPath.row]
|
||||
pendingPerson = person
|
||||
level = .lead
|
||||
onPersonSelected(person)
|
||||
applyViewModel()
|
||||
let leadController = OrderSourceLeadListViewController(
|
||||
person: person,
|
||||
orderNumber: orderNumber,
|
||||
viewModel: viewModel,
|
||||
referralOrder: referralOrder,
|
||||
loadLeads: loadLeads,
|
||||
onLeadBound: onLeadBound,
|
||||
onCallPhone: onCallPhone,
|
||||
onPreviewImages: onPreviewImages
|
||||
)
|
||||
navigationController?.setNavigationBarHidden(false, animated: true)
|
||||
navigationController?.pushViewController(leadController, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user