189 lines
6.6 KiB
Swift
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 {}
|