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>
111 lines
3.1 KiB
Swift
111 lines
3.1 KiB
Swift
//
|
||
// NavigationRouter.swift
|
||
// suixinkan
|
||
//
|
||
// Created by Codex on 2026/6/18.
|
||
//
|
||
|
||
import Foundation
|
||
|
||
/// 应用内可导航目标,承载各 Tab 内部的路由目的地。
|
||
enum AppRoute: Hashable {
|
||
case placeholder(title: String)
|
||
case home(HomeRoute)
|
||
case profile(ProfileRoute)
|
||
case orders(OrdersRoute)
|
||
|
||
/// 返回该路由通过 push 后是否隐藏底部 TabBar。
|
||
var hidesTabBarWhenPushed: Bool {
|
||
true
|
||
}
|
||
}
|
||
|
||
@MainActor
|
||
/// 单个导航栈的路径容器,用于保存某个 Tab 的导航历史。
|
||
final class RouterPath {
|
||
var onChange: (() -> Void)?
|
||
var path: [AppRoute] = [] { didSet { onChange?() } }
|
||
|
||
/// 将指定路由压入当前 Tab 的导航栈。
|
||
func navigate(to route: AppRoute) {
|
||
path.append(route)
|
||
}
|
||
|
||
/// 从当前 Tab 的导航栈弹出最后一级路由。
|
||
func navigateBack() {
|
||
guard !path.isEmpty else { return }
|
||
path.removeLast()
|
||
}
|
||
|
||
/// 清空当前 Tab 的导航栈。
|
||
func reset() {
|
||
path = []
|
||
}
|
||
}
|
||
|
||
@MainActor
|
||
/// 主导航状态中心,管理当前 Tab 和每个 Tab 独立的导航路径。
|
||
final class AppRouter {
|
||
var onChange: (() -> Void)?
|
||
var selectedTab: AppTab = .home { didSet { onChange?() } }
|
||
var selectedOrdersEntry: OrdersEntry = .storeOrders { didSet { onChange?() } }
|
||
private(set) var pendingOrderScanCode: String? { didSet { onChange?() } }
|
||
|
||
private let routers: [AppTab: RouterPath]
|
||
|
||
/// 初始化实例。
|
||
init() {
|
||
var builtRouters: [AppTab: RouterPath] = [:]
|
||
for tab in AppTab.allCases {
|
||
builtRouters[tab] = RouterPath()
|
||
}
|
||
routers = builtRouters
|
||
routers.values.forEach { router in
|
||
router.onChange = { [weak self] in
|
||
self?.onChange?()
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 获取指定 Tab 对应的路由路径容器。
|
||
func router(for tab: AppTab) -> RouterPath {
|
||
guard let router = routers[tab] else {
|
||
assertionFailure("Missing router path for tab: \(tab)")
|
||
return RouterPath()
|
||
}
|
||
return router
|
||
}
|
||
|
||
/// 切换到指定主 Tab。
|
||
func select(_ tab: AppTab) {
|
||
selectedTab = tab
|
||
}
|
||
|
||
/// 切换到订单 Tab,并指定订单内部子入口。
|
||
func selectOrders(entry: OrdersEntry) {
|
||
selectedOrdersEntry = entry
|
||
selectedTab = .orders
|
||
}
|
||
|
||
/// 切换到核销订单入口,并暂存全局扫码结果等待订单页消费。
|
||
func routeToOrderVerification(scannedCode: String) {
|
||
pendingOrderScanCode = scannedCode
|
||
selectOrders(entry: .verificationOrders)
|
||
}
|
||
|
||
/// 读取并清空待处理的全局扫码结果,确保同一次扫码只被处理一次。
|
||
func consumePendingOrderScanCode() -> String? {
|
||
let code = pendingOrderScanCode
|
||
pendingOrderScanCode = nil
|
||
return code
|
||
}
|
||
|
||
/// 重置主 Tab 选择和所有 Tab 的导航历史。
|
||
func reset() {
|
||
selectedTab = .home
|
||
selectedOrdersEntry = .storeOrders
|
||
pendingOrderScanCode = nil
|
||
routers.values.forEach { $0.reset() }
|
||
}
|
||
}
|