Files

3.1 KiB
Raw Permalink Blame History

Main 模块业务逻辑

模块职责

Main 模块负责登录后的主界面 Tab 容器,以及当前尚未迁移页面的占位入口。

主界面由 MainTabsView 承载:

  • 使用系统 TabView 展示登录后的底部导航。
  • 底部按顺序展示首页、订单、扫码、数据、我的五个入口。
  • 扫码入口只负责打开扫码页,不属于 AppTab,也不持有独立业务导航栈。
  • 每个 Tab 内部都包裹独立的 NavigationStack,并通过 TabNavigationStackHost 复用同一套导航构建逻辑。
  • 每个 Tab 的导航路径由 AppRouter 单独保存。
  • 订单 Tab 角标由 MainTabBadgeViewModel 提供,数量为 0 或获取失败时不显示。

Tab 结构

当前 Tab 来自 AppTab

  • home:首页
  • orders:订单
  • statistics:数据
  • profile:我的

HomeRootView 已接入真实的 HomeViewOrdersRootView 已按角色接入 StoreOrderListViewStoreAdminOrderListViewStatisticsRootView 已接入真实的 StatisticsViewProfileRootView 已接入真实的 ProfileView

导航流程

  1. MainTabsView 从 Environment 读取 AppRouter
  2. TabView 使用内部 MainTabSelection 作为选择值,普通 Tab 映射到 AppTab,扫码映射到 .scanner
  3. 普通 Tab 切换时调用 AppRouter.select(_:) 更新当前业务 Tab。
  4. 每个普通 Tab 通过 TabNavigationStackHost 创建自己的 NavigationStack(path:)
  5. 导航栈宿主直接观察当前 Tab 对应的 RouterPath,并把 $router.path 绑定给 NavigationStack
  6. Tab 内页面需要进入子页面时,通过当前 Tab 注入的 RouterPath push 对应 AppRoute
  7. navigationDestination 根据 AppRoute 展示详情页。
  8. 子页面展示时读取 AppRoute.hidesTabBarWhenPushed,默认隐藏底部 TabBar。

扫码入口

扫码入口是系统 TabView 中的中间入口,只显示 qrcode.viewfinder 图标,并通过无障碍标签标记为“扫码核销”。

点击扫码入口时,MainTabsView 拦截 .scanner 选择并展示订单模块已有的 OrderScannerPage,不会修改 AppRouter.selectedTab。因此用户关闭扫码页后,仍停留在打开扫码前的 Tab。

扫码成功后调用 AppRouter.routeToOrderVerification(scannedCode:),订单页再通过 consumePendingOrderScanCode() 一次性消费结果。扫码失败时关闭扫码页并展示错误提示。

后续迁移规则

迁移新页面时:

  • 优先替换对应 Tab 的 RootView。
  • 保持每个 Tab 自己的 NavigationStack
  • 跨 Tab 跳转通过 AppRouter.select 切换 Tab。
  • 需要从首页或全局入口进入订单核销时,优先使用 AppRouter.selectOrders(entry:)AppRouter.routeToOrderVerification(scannedCode:)
  • Tab 内跳转通过当前 Tab 的 RouterPath.navigate 或扩展后的 AppRoute 处理。
  • 普通业务子页面默认隐藏 TabBar只有确有产品需求时才在 AppRoute 策略中单独放开。
  • 不要把扫码入口加入 AppTab;它不是业务 Tab只是主界面的全局动作入口。
  • 真实业务页面接入后,应同步补充该模块文档和单元测试。