Advance UIKit rewrite with AMap integration and core UI modules.

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>
This commit is contained in:
2026-06-26 15:16:12 +08:00
parent 9edf993432
commit d99a5b1bf8
124 changed files with 5195 additions and 1536 deletions

View File

@ -11,6 +11,7 @@ import UIKit
final class ProjectManagementViewController: ModuleTableViewController {
private let viewModel = ProjectManagementViewModel()
/// UI
override func viewDidLoad() {
title = "项目管理"
navigationItem.rightBarButtonItem = UIBarButtonItem(
@ -23,13 +24,16 @@ final class ProjectManagementViewController: ModuleTableViewController {
wireViewModel(viewModel) { }
}
/// tableCount
override func tableRowCount() -> Int { viewModel.items.count }
/// Cell
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
let item = viewModel.items[indexPath.row]
cell.configure(title: item.name, subtitle: item.statusName, detail: "¥\(item.price)")
}
/// didSelectTableRow
override func didSelectTableRow(at indexPath: IndexPath) {
let item = viewModel.items[indexPath.row]
navigationController?.pushViewController(
@ -38,10 +42,12 @@ final class ProjectManagementViewController: ModuleTableViewController {
)
}
/// Content
override func reloadContent() async {
await viewModel.reload(api: services.projectAPI, scenicId: services.currentScenicId)
}
///
@objc private func createProject() {
navigationController?.pushViewController(
ProjectEditorViewController(projectId: nil),
@ -56,19 +62,23 @@ extension ProjectManagementViewModel: ViewModelBindable {}
final class StoreProjectManagementViewController: ModuleTableViewController {
private let viewModel = StoreProjectManagementViewModel()
/// UI
override func viewDidLoad() {
title = "店铺项目"
super.viewDidLoad()
wireViewModel(viewModel) { }
}
/// tableCount
override func tableRowCount() -> Int { viewModel.filteredItems.count }
/// Cell
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
let item = viewModel.filteredItems[indexPath.row]
cell.configure(title: item.name, subtitle: item.typeName, detail: "¥\(item.price)")
}
/// didSelectTableRow
override func didSelectTableRow(at indexPath: IndexPath) {
let item = viewModel.filteredItems[indexPath.row]
navigationController?.pushViewController(
@ -77,6 +87,7 @@ final class StoreProjectManagementViewController: ModuleTableViewController {
)
}
/// Content
override func reloadContent() async {
await viewModel.reload(api: services.projectAPI, userId: services.userId)
}
@ -91,6 +102,7 @@ final class ProjectDetailViewController: ModuleTableViewController {
private let photographerViewModel = ProjectManagementViewModel()
private let storeViewModel = StoreProjectManagementViewModel()
///
init(projectId: Int, storeMode: Bool) {
self.projectId = projectId
self.storeMode = storeMode
@ -102,6 +114,7 @@ final class ProjectDetailViewController: ModuleTableViewController {
fatalError("init(coder:) has not been implemented")
}
/// UI
override func viewDidLoad() {
title = "项目详情"
super.viewDidLoad()
@ -116,10 +129,12 @@ final class ProjectDetailViewController: ModuleTableViewController {
storeMode ? storeViewModel.selectedDetail : photographerViewModel.selectedDetail
}
/// tableCount
override func tableRowCount() -> Int {
detail == nil ? 0 : 4
}
/// Cell
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
guard let detail else { return }
switch indexPath.row {
@ -130,6 +145,7 @@ final class ProjectDetailViewController: ModuleTableViewController {
}
}
/// Content
override func reloadContent() async {
if storeMode {
await storeViewModel.loadDetail(id: projectId, api: services.projectAPI)
@ -147,6 +163,7 @@ final class ProjectEditorViewController: ModuleTableViewController {
private let priceField = UITextField()
private let projectId: Int?
///
init(projectId: Int?) {
self.projectId = projectId
super.init(nibName: nil, bundle: nil)
@ -157,6 +174,7 @@ final class ProjectEditorViewController: ModuleTableViewController {
fatalError("init(coder:) has not been implemented")
}
/// UI
override func viewDidLoad() {
title = projectId == nil ? "新建项目" : "编辑项目"
navigationItem.rightBarButtonItem = UIBarButtonItem(
@ -170,6 +188,7 @@ final class ProjectEditorViewController: ModuleTableViewController {
wireViewModel(viewModel) { [weak self] in self?.fillFormIfNeeded() }
}
/// Header UI
private func setupHeader() {
nameField.placeholder = "项目名称"
nameField.borderStyle = .roundedRect
@ -187,8 +206,10 @@ final class ProjectEditorViewController: ModuleTableViewController {
tableView.tableHeaderView = stack
}
/// tableCount
override func tableRowCount() -> Int { 0 }
/// Content
override func reloadContent() async {
guard let projectId else { return }
if let detail = try? await services.projectAPI.projectDetail(id: projectId) {
@ -197,12 +218,14 @@ final class ProjectEditorViewController: ModuleTableViewController {
}
}
/// fill
private func fillFormIfNeeded() {
if nameField.text?.isEmpty != false { nameField.text = viewModel.name }
if descriptionField.text?.isEmpty != false { descriptionField.text = viewModel.descriptionText }
if priceField.text?.isEmpty != false { priceField.text = viewModel.price }
}
/// save
@objc private func save() {
viewModel.name = nameField.text ?? ""
viewModel.descriptionText = descriptionField.text ?? ""
@ -231,6 +254,7 @@ final class StoreProjectEditorViewController: ModuleTableViewController {
private let viewModel = StoreProjectEditorViewModel(mode: .create)
private let nameField = UITextField()
///
init(projectId: Int?) {
super.init(nibName: nil, bundle: nil)
}
@ -240,6 +264,7 @@ final class StoreProjectEditorViewController: ModuleTableViewController {
fatalError("init(coder:) has not been implemented")
}
/// UI
override func viewDidLoad() {
title = "店铺项目"
navigationItem.rightBarButtonItem = UIBarButtonItem(
@ -256,18 +281,22 @@ final class StoreProjectEditorViewController: ModuleTableViewController {
wireViewModel(viewModel) { }
}
/// tableCount
override func tableRowCount() -> Int { viewModel.scenicList.count }
/// Cell
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
let scenic = viewModel.scenicList[indexPath.row]
cell.configure(title: scenic.name, subtitle: viewModel.selectedScenicIds.contains(scenic.id) ? "已选择" : nil)
}
/// Content
override func reloadContent() async {
guard let userId = Int(services.userId ?? "") else { return }
await viewModel.loadScenicList(api: services.projectAPI, userId: userId)
}
/// save
@objc private func save() {
viewModel.name = nameField.text ?? ""
Task {