Integrate高德 SDK with simulator-safe build flags, add map views for operating area and punch points, refactor main tabs and key feature screens to UIKit with Diffable lists, and document Swift concurrency defaults in AGENTS.md. Co-authored-by: Cursor <cursoragent@cursor.com>
121 lines
3.8 KiB
Swift
121 lines
3.8 KiB
Swift
//
|
|
// PilotCertificationViewController.swift
|
|
// suixinkan
|
|
//
|
|
// Created by Codex on 2026/6/26.
|
|
//
|
|
|
|
import SnapKit
|
|
import UIKit
|
|
|
|
/// 飞手认证页。
|
|
final class PilotCertificationViewController: ModuleTableViewController {
|
|
private let viewModel = PilotCertificationViewModel()
|
|
private let statusLabel = UILabel()
|
|
|
|
/// 视图加载完成后的 UI 初始化与数据绑定。
|
|
override func viewDidLoad() {
|
|
title = "飞手认证"
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
title: "提交",
|
|
style: .done,
|
|
target: self,
|
|
action: #selector(submit)
|
|
)
|
|
super.viewDidLoad()
|
|
setupHeader()
|
|
wireViewModel(viewModel) { [weak self] in self?.updateHeader() }
|
|
}
|
|
|
|
/// 初始化Header相关 UI 或状态。
|
|
private func setupHeader() {
|
|
statusLabel.numberOfLines = 0
|
|
statusLabel.font = .systemFont(ofSize: 14)
|
|
statusLabel.textColor = AppDesign.textSecondary
|
|
statusLabel.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 80)
|
|
tableView.tableHeaderView = statusLabel
|
|
}
|
|
|
|
/// 返回列表 section 数量。
|
|
override func numberOfTableSections() -> Int { 2 }
|
|
|
|
/// 返回指定 section 行数。
|
|
override func tableRowCount(in section: Int) -> Int {
|
|
section == 0 ? formRows.count : 1
|
|
}
|
|
|
|
/// section 标题。
|
|
override func tableSectionTitle(for section: Int) -> String? {
|
|
section == 0 ? "认证信息" : "操作"
|
|
}
|
|
|
|
/// 提供自定义 Cell。
|
|
override func tableCell(for indexPath: IndexPath, row: ModuleTableRow, in tableView: UITableView) -> UITableViewCell {
|
|
let cell = tableView.dequeueReusableCell(
|
|
withIdentifier: TitleSubtitleTableViewCell.reuseIdentifier,
|
|
for: indexPath
|
|
) as! TitleSubtitleTableViewCell
|
|
if indexPath.section == 0 {
|
|
let row = formRows[indexPath.row]
|
|
cell.configure(title: row.title, subtitle: row.value)
|
|
} else {
|
|
cell.configure(title: "发送验证码", subtitle: viewModel.phone)
|
|
}
|
|
return cell
|
|
}
|
|
|
|
/// 处理行选中。
|
|
override func didSelectTableRow(at indexPath: IndexPath) {
|
|
if indexPath.section == 1 {
|
|
Task {
|
|
do {
|
|
try await viewModel.sendCode(api: services.pilotCertificationAPI)
|
|
showToast("验证码已发送")
|
|
} catch {
|
|
showToast(error.localizedDescription)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 刷新Content。
|
|
override func reloadContent() async {
|
|
await viewModel.load(api: services.pilotCertificationAPI, realNameAPI: services.profileAPI)
|
|
updateHeader()
|
|
}
|
|
|
|
/// 提交。
|
|
@objc private func submit() {
|
|
Task {
|
|
do {
|
|
try await viewModel.submit(
|
|
api: services.pilotCertificationAPI,
|
|
uploader: services.ossUploadService,
|
|
scenicId: services.currentScenicId
|
|
)
|
|
services.toastCenter.show("提交成功")
|
|
} catch {
|
|
services.toastCenter.show(error.localizedDescription)
|
|
}
|
|
}
|
|
}
|
|
|
|
private var formRows: [(title: String, value: String)] {
|
|
[
|
|
("姓名", viewModel.name),
|
|
("证件号", viewModel.certNo),
|
|
("手机号", viewModel.phone),
|
|
("无人机型号", viewModel.droneModel),
|
|
("序列号", viewModel.droneSerialNo)
|
|
]
|
|
}
|
|
|
|
/// 更新Header状态。
|
|
private func updateHeader() {
|
|
let status = viewModel.auditStatusText
|
|
statusLabel.text = "状态:\(status)\n\(viewModel.statusMessage ?? "")"
|
|
}
|
|
}
|
|
|
|
extension PilotCertificationViewModel: ViewModelBindable {}
|