Files
suixinkan_ios_new/suixinkan/Features/Main/Main.md

55 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Main 模块业务逻辑
## 模块职责
Main 模块负责登录后的主界面 Tab 容器,以及当前尚未迁移页面的占位入口。
主界面由 `MainTabsView` 承载:
- 使用系统 `TabView` 展示登录后的底部导航。
- 底部按顺序展示首页、订单、扫码、数据、我的五个入口。
- 扫码入口只负责打开扫码页,不属于 `AppTab`,也不持有独立业务导航栈。
- 每个 Tab 内部都包裹独立的 `NavigationStack`,并通过 `TabNavigationStackHost` 复用同一套导航构建逻辑。
- 每个 Tab 的导航路径由 `AppRouter` 单独保存。
- 订单 Tab 角标由 `MainTabBadgeViewModel` 提供,数量为 0 或获取失败时不显示。
## Tab 结构
当前 Tab 来自 `AppTab`
- `home`:首页
- `orders`:订单
- `statistics`:数据
- `profile`:我的
`HomeRootView` 已接入真实的 `HomeView``OrdersRootView` 已按角色接入 `StoreOrderListView``StoreAdminOrderListView``StatisticsRootView` 已接入真实的 `StatisticsView``ProfileRootView` 已接入真实的 `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只是主界面的全局动作入口。
- 真实业务页面接入后,应同步补充该模块文档和单元测试。