217 lines
7.7 KiB
Swift
217 lines
7.7 KiB
Swift
//
|
|
// ScenicPermissionViewControllers.swift
|
|
// suixinkan
|
|
//
|
|
// Created by Codex on 2026/6/26.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
/// 景区选择页。
|
|
final class ScenicSelectionViewController: ModuleTableViewController {
|
|
private let viewModel = ScenicSelectionViewModel()
|
|
private let searchBar = UISearchBar()
|
|
|
|
override func viewDidLoad() {
|
|
title = "选择景区"
|
|
super.viewDidLoad()
|
|
setupSearchBar()
|
|
wireViewModel(viewModel) { }
|
|
}
|
|
|
|
private func setupSearchBar() {
|
|
searchBar.placeholder = "搜索景区"
|
|
searchBar.delegate = self
|
|
searchBar.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 56)
|
|
tableView.tableHeaderView = searchBar
|
|
}
|
|
|
|
override func tableRowCount() -> Int {
|
|
viewModel.filteredItems.count
|
|
}
|
|
|
|
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
|
let item = viewModel.filteredItems[indexPath.row]
|
|
cell.configure(title: item.name, subtitle: item.address, detail: item.distanceText)
|
|
}
|
|
|
|
override func didSelectTableRow(at indexPath: IndexPath) {
|
|
let item = viewModel.filteredItems[indexPath.row]
|
|
viewModel.select(
|
|
scenicId: item.id,
|
|
accountContext: services.accountContext,
|
|
permissionContext: services.permissionContext,
|
|
snapshotStore: AccountSnapshotStore()
|
|
)
|
|
navigationController?.popViewController(animated: true)
|
|
}
|
|
|
|
override func reloadContent() async {
|
|
viewModel.reload(from: services.accountContext)
|
|
}
|
|
}
|
|
|
|
extension ScenicSelectionViewModel: ViewModelBindable {}
|
|
|
|
extension ScenicSelectionViewController: UISearchBarDelegate {
|
|
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
|
|
viewModel.searchQuery = searchText
|
|
}
|
|
}
|
|
|
|
/// 权限申请页。
|
|
final class PermissionApplyViewController: ModuleTableViewController {
|
|
private let viewModel = PermissionApplyViewModel()
|
|
|
|
override func viewDidLoad() {
|
|
title = "权限申请"
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
title: "提交",
|
|
style: .done,
|
|
target: self,
|
|
action: #selector(submit)
|
|
)
|
|
super.viewDidLoad()
|
|
wireViewModel(viewModel) { }
|
|
}
|
|
|
|
override func numberOfSections(in tableView: UITableView) -> Int { 2 }
|
|
|
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
section == 0 ? viewModel.roleOptions.count : viewModel.scenicOptions.count
|
|
}
|
|
|
|
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
|
section == 0 ? "选择角色" : "选择景区"
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
let cell = tableView.dequeueReusableCell(
|
|
withIdentifier: TitleSubtitleTableViewCell.reuseIdentifier,
|
|
for: indexPath
|
|
) as! TitleSubtitleTableViewCell
|
|
if indexPath.section == 0 {
|
|
let role = viewModel.roleOptions[indexPath.row]
|
|
cell.configure(title: role.name, subtitle: role.notes)
|
|
cell.accessoryType = viewModel.selectedRoleId == role.id ? .checkmark : .none
|
|
} else {
|
|
let scenic = viewModel.scenicOptions[indexPath.row]
|
|
cell.configure(title: scenic.name, subtitle: scenic.disabled ? "已有权限" : nil)
|
|
cell.accessoryType = scenic.selected ? .checkmark : .none
|
|
}
|
|
return cell
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
tableView.deselectRow(at: indexPath, animated: true)
|
|
if indexPath.section == 0 {
|
|
viewModel.selectRole(id: viewModel.roleOptions[indexPath.row].id)
|
|
Task { await viewModel.loadScenicListIfNeeded(api: services.scenicPermissionAPI, force: true) }
|
|
} else {
|
|
viewModel.toggleScenic(id: viewModel.scenicOptions[indexPath.row].id)
|
|
}
|
|
}
|
|
|
|
override func reloadContent() async {
|
|
viewModel.bootstrap(rolePermissions: services.permissionContext.rolePermissions)
|
|
if viewModel.selectedRoleId != nil {
|
|
await viewModel.loadScenicListIfNeeded(api: services.scenicPermissionAPI, force: true)
|
|
}
|
|
}
|
|
|
|
@objc private func submit() {
|
|
Task {
|
|
await viewModel.submit(api: services.scenicPermissionAPI)
|
|
if viewModel.message == "提交成功,等待审核" {
|
|
services.toastCenter.show(viewModel.message ?? "提交成功")
|
|
navigationController?.popViewController(animated: true)
|
|
} else if let message = viewModel.message {
|
|
services.toastCenter.show(message)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension PermissionApplyViewModel: ViewModelBindable {}
|
|
|
|
/// 权限申请状态页。
|
|
final class PermissionApplyStatusViewController: ModuleTableViewController {
|
|
private let viewModel = PermissionApplyStatusViewModel()
|
|
|
|
override func viewDidLoad() {
|
|
title = "申请状态"
|
|
super.viewDidLoad()
|
|
viewModel.onChange = { [weak self] in self?.reloadTable() }
|
|
}
|
|
|
|
override func tableRowCount() -> Int {
|
|
viewModel.pending == nil ? 0 : 4
|
|
}
|
|
|
|
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
|
guard let pending = viewModel.pending else { return }
|
|
switch indexPath.row {
|
|
case 0: cell.configure(title: "申请编号", subtitle: pending.code)
|
|
case 1: cell.configure(title: "角色", subtitle: pending.roleName)
|
|
case 2: cell.configure(title: "状态", subtitle: pending.statusLabel)
|
|
default: cell.configure(title: "申请时间", subtitle: pending.createdAt)
|
|
}
|
|
}
|
|
|
|
override func reloadContent() async {
|
|
await viewModel.load(api: services.scenicPermissionAPI, applyCode: nil)
|
|
}
|
|
}
|
|
|
|
/// 景区申请页。
|
|
final class ScenicApplicationViewController: ModuleTableViewController {
|
|
private let viewModel = ScenicApplicationViewModel()
|
|
private let nameField = UITextField()
|
|
|
|
override func viewDidLoad() {
|
|
title = "景区申请"
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
title: "提交",
|
|
style: .done,
|
|
target: self,
|
|
action: #selector(submit)
|
|
)
|
|
super.viewDidLoad()
|
|
nameField.placeholder = "景区名称"
|
|
nameField.borderStyle = .roundedRect
|
|
nameField.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 52)
|
|
tableView.tableHeaderView = nameField
|
|
wireViewModel(viewModel) { [weak self] in
|
|
if self?.nameField.text?.isEmpty != false {
|
|
self?.nameField.text = self?.viewModel.scenicName
|
|
}
|
|
}
|
|
}
|
|
|
|
override func tableRowCount() -> Int { 3 }
|
|
|
|
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
|
switch indexPath.row {
|
|
case 0: cell.configure(title: "省份", subtitle: viewModel.selectedProvince)
|
|
case 1: cell.configure(title: "城市", subtitle: viewModel.selectedCity)
|
|
default: cell.configure(title: "合作类型", subtitle: viewModel.coopType == 1 ? "自营" : "合作")
|
|
}
|
|
}
|
|
|
|
override func reloadContent() async {
|
|
await viewModel.loadInitial(api: services.scenicPermissionAPI)
|
|
}
|
|
|
|
@objc private func submit() {
|
|
viewModel.scenicName = nameField.text ?? ""
|
|
Task {
|
|
await viewModel.submit(api: services.scenicPermissionAPI, uploader: services.ossUploadService)
|
|
if let message = viewModel.message {
|
|
services.toastCenter.show(message)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ScenicApplicationViewModel: ViewModelBindable {}
|