Introduce configurable custom TabBar with order badge, central scanner routing to verification orders, and update the migration checklist for recently completed modules. Co-authored-by: Cursor <cursoragent@cursor.com>
3.6 KiB
3.6 KiB
Main 模块业务逻辑
模块职责
Main 模块负责登录后的主界面 Tab 容器,以及当前尚未迁移页面的占位入口。
主界面由 MainTabsView 承载:
- 根据
MainTabBarConfiguration.activeStyle选择自定义 TabBar 或系统TabView。 - 默认使用自定义 TabBar;如需切回系统实现,将配置改为
.system。 - 自定义和系统两套外壳都展示首页、订单、数据、我的四个 Tab。
- 每个 Tab 内部都包裹独立的
NavigationStack,并通过TabNavigationStackHost复用同一套导航构建逻辑。 - 每个 Tab 的导航路径由
AppRouter单独保存。
Tab 结构
当前 Tab 来自 AppTab:
home:首页orders:订单statistics:数据profile:我的
HomeRootView 已接入真实的 HomeView,OrdersRootView 已接入真实的 OrdersView,StatisticsRootView 已接入真实的 StatisticsView,ProfileRootView 已接入真实的 ProfileView。
导航流程
MainTabsView从 Environment 读取AppRouter。MainTabsView根据MainTabBarConfiguration.activeStyle选择CustomMainTabsView或SystemMainTabsView。- 两套外壳都使用
appRouter.selectedTab作为选中状态。 - 每个 Tab 通过
TabNavigationStackHost创建自己的NavigationStack(path:)。 - 路径绑定来自
appRouter.binding(for:)。 - Tab 内页面需要进入尚未迁移的子页面时,通过当前 Tab 注入的
RouterPathpush 一个AppRoute.placeholder。 navigationDestination根据AppRoute展示详情页。- 子页面展示时读取
AppRoute.hidesTabBarWhenPushed,默认隐藏底部 TabBar。
自定义 TabBar
自定义 TabBar 由 CustomMainTabsView 和 CustomMainTabBar 组成:
CustomMainTabsView负责保留已访问 Tab 页面、刷新订单角标、展示扫码页。CustomTabNavigationStackHost会把CustomMainTabBar拼在每个 Tab 的根页面内容下方。CustomMainTabBar只负责展示 UI,不直接读取账号、订单 API 或业务上下文。MainTabBadgeViewModel通过OrdersAPI.writeOffList获取待核销数量,失败时静默清空角标。- 中间扫码按钮使用订单模块已有的
OrderScannerPage。 - 扫码成功后调用
AppRouter.routeToOrderVerification(scannedCode:),订单页再通过consumePendingOrderScanCode()一次性消费结果。 - 自定义 TabBar 只属于 Tab 根页面内容;当前 Tab 的导航栈 push 到二级页面后,目标页面不包含 TabBar,也不会保留底部占位高度。
- 承载根页面和
CustomMainTabBar的容器需要忽略键盘底部安全区,避免订单搜索框等输入控件唤起键盘时把自定义 TabBar 顶起。
系统 TabView 外壳由 SystemMainTabsView 保留。系统模式不显示中间扫码按钮,但订单页内部的扫码核销入口仍然可用。
后续迁移规则
迁移新页面时:
- 优先替换对应 Tab 的 RootView。
- 保持每个 Tab 自己的
NavigationStack。 - 跨 Tab 跳转通过
AppRouter.select切换 Tab。 - 需要从首页或全局入口进入订单核销时,优先使用
AppRouter.selectOrders(entry:)或AppRouter.routeToOrderVerification(scannedCode:)。 - Tab 内跳转通过当前 Tab 的
RouterPath.navigate或扩展后的AppRoute处理。 - 普通业务子页面默认隐藏 TabBar;只有确有产品需求时,才在
AppRoute策略中单独放开。 - 不要把业务状态塞进自定义 TabBar 组件;TabBar 只接收绑定、文案和动作回调。
- 真实业务页面接入后,应同步补充该模块文档和单元测试。