Files
suixinkan_ios_uikit/suixinkan_ios/Features/Tasks/ViewControllers/TaskViewControllers.swift
2026-06-26 14:33:31 +08:00

189 lines
6.6 KiB
Swift

//
// TaskViewControllers.swift
// suixinkan
//
// Created by Codex on 2026/6/26.
//
import UIKit
///
final class TaskManagementViewController: ModuleTableViewController {
private let viewModel = TaskManagementViewModel()
override func viewDidLoad() {
title = "任务管理"
navigationItem.rightBarButtonItem = UIBarButtonItem(
title: "发布",
style: .plain,
target: self,
action: #selector(createTask)
)
super.viewDidLoad()
wireViewModel(viewModel) { }
}
override func tableRowCount() -> Int {
viewModel.tasks.count
}
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
let task = viewModel.tasks[indexPath.row]
cell.configure(title: task.name, subtitle: task.statusName, detail: task.createdAt)
}
override func didSelectTableRow(at indexPath: IndexPath) {
let task = viewModel.tasks[indexPath.row]
navigationController?.pushViewController(
TaskDetailViewController(taskId: task.id, summary: task),
animated: true
)
}
override func reloadContent() async {
try? await viewModel.reload(api: services.taskAPI, scenicId: services.currentScenicId)
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard indexPath.row >= viewModel.tasks.count - 2 else { return }
Task { try? await viewModel.loadMore(api: services.taskAPI, scenicId: services.currentScenicId) }
}
@objc private func createTask() {
navigationController?.pushViewController(TaskCreateViewController(), animated: true)
}
}
extension TaskManagementViewModel: ViewModelBindable {}
///
final class TaskDetailViewController: ModuleTableViewController {
private let taskId: Int
private let summary: PhotographerTaskItem?
private let viewModel = TaskDetailViewModel()
init(taskId: Int, summary: PhotographerTaskItem?) {
self.taskId = taskId
self.summary = summary
super.init(nibName: nil, bundle: nil)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
title = summary?.name ?? "任务详情"
super.viewDidLoad()
wireViewModel(viewModel) { [weak self] in
self?.title = self?.viewModel.detail?.name ?? self?.summary?.name ?? "任务详情"
}
}
override func tableRowCount() -> Int {
guard let detail = viewModel.detail else { return summary == nil ? 0 : 4 }
return 6
}
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
if let detail = viewModel.detail {
switch indexPath.row {
case 0: cell.configure(title: "任务名称", subtitle: detail.name)
case 1: cell.configure(title: "状态", subtitle: detail.taskStatusLabel)
case 2: cell.configure(title: "订单号", subtitle: detail.order?.orderNumber ?? "--")
case 3: cell.configure(title: "备注", subtitle: detail.photogRemark)
case 4: cell.configure(title: "创建时间", subtitle: detail.createdAt)
default: cell.configure(title: "附件", subtitle: "\(detail.taskResult.count)")
}
} else if let summary {
switch indexPath.row {
case 0: cell.configure(title: "任务名称", subtitle: summary.name)
case 1: cell.configure(title: "状态", subtitle: summary.statusName)
case 2: cell.configure(title: "订单号", subtitle: summary.orderNumber)
default: cell.configure(title: "创建时间", subtitle: summary.createdAt)
}
}
}
override func reloadContent() async {
await viewModel.load(api: services.taskAPI, taskId: taskId)
}
}
extension TaskDetailViewModel: ViewModelBindable {}
///
final class TaskCreateViewController: ModuleTableViewController {
private let viewModel = TaskCreateViewModel()
private let nameField = UITextField()
private let remarkField = UITextField()
override func viewDidLoad() {
title = "发布任务"
navigationItem.rightBarButtonItem = UIBarButtonItem(
title: "提交",
style: .done,
target: self,
action: #selector(submit)
)
super.viewDidLoad()
setupHeader()
wireViewModel(viewModel) { }
}
private func setupHeader() {
nameField.placeholder = "任务名称"
nameField.borderStyle = .roundedRect
remarkField.placeholder = "备注"
remarkField.borderStyle = .roundedRect
let stack = UIStackView(arrangedSubviews: [nameField, remarkField])
stack.axis = .vertical
stack.spacing = 8
stack.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 96)
stack.layoutMargins = UIEdgeInsets(top: 12, left: 16, bottom: 12, right: 16)
stack.isLayoutMarginsRelativeArrangement = true
tableView.tableHeaderView = stack
}
override func tableRowCount() -> Int {
viewModel.availableOrders.count
}
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
let order = viewModel.availableOrders[indexPath.row]
let selected = viewModel.selectedOrder?.orderNumber == order.orderNumber
cell.configure(title: order.orderNumber, subtitle: order.projectName, detail: selected ? "已选择" : nil)
cell.accessoryType = selected ? .checkmark : .none
}
override func didSelectTableRow(at indexPath: IndexPath) {
viewModel.selectedOrder = viewModel.availableOrders[indexPath.row]
}
override func reloadContent() async {
await viewModel.loadAvailableOrders(api: services.taskAPI, scenicId: services.currentScenicId)
}
@objc private func submit() {
viewModel.taskName = nameField.text ?? ""
viewModel.remark = remarkField.text ?? ""
Task {
do {
let success = try await viewModel.submit(
api: services.taskAPI,
uploadService: services.ossUploadService,
scenicId: services.currentScenicId
)
if success {
navigationController?.popViewController(animated: true)
}
} catch {
services.toastCenter.show(error.localizedDescription)
}
}
}
}
extension TaskCreateViewModel: ViewModelBindable {}