- AnalyticsRouteObserver:didPush/didReplace/didPop 集中捕获,页面零侵入 - AnalyticsPageName 枚举:pageName 编译期锁死(字典 v2 九个初始值 + 客户端现存 create/pet_archive/services/post_detail),字典外路由不上报 - PageViewTracker:page_viewed 单一上报出口,维护 referrer 链(栈底/冷启动首页为 null)与去重(Tab 重复点选) - 三类非路由曝光手动补点:主壳 Tab 切换(IndexedStack)、认证状态机切页(AnimatedSwitcher)、回栈到无名根路由(resolveRootPage) - 既有 Navigator.push 挂 RouteSettings.name:login_page(register)、main_shell_page(post_detail);fade_route 签名扩展可选 settings - M2 健康档案页面(pet_list/pet_detail/pet_form/record_form/record_detail)先留枚举定义,待功能落地接线 测试新增 8 例(analytics_route_observer_test):push 上报/push 两页 referrer 链正确 + pop 补报/根路由 resolveRootPage 补报/枚举外不报/dialog 不报/Tab 去重/referrer 连贯/reportTab。 验收对照(06 号报告 §5.2 六条):1✓ observer 注册、2✓ pageName 枚举含 pet_form、3✓ referrer 链、4✓ 字典外不报、5✓ 单测 push/pop/referrer、6✓ M1 存量四页接全。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:patbond_flutter/analytics/analytics_page_name.dart';
|
||||
import 'package:patbond_flutter/analytics/page_view_tracker.dart';
|
||||
|
||||
/// 集中式 page_viewed 路由埋点(03 号评估 §3.2:NavigatorObserver 派生,
|
||||
/// 页面零侵入;06 号报告 §5.2 验收 1/4)。
|
||||
///
|
||||
/// 只统计 [PageRoute](bottom sheet / dialog 是 PopupRoute,不计曝光);
|
||||
/// 路由名不在 [AnalyticsPageName] 枚举内不上报(后端会整条 rejected,
|
||||
/// 不白白消耗队列)。didPop 补报「回退后重新曝光的前一页」;弹回到
|
||||
/// 无名根路由(认证状态机的 AnimatedSwitcher 宿主)时经 [resolveRootPage]
|
||||
/// 解析当前根部页面。
|
||||
class AnalyticsRouteObserver extends NavigatorObserver {
|
||||
AnalyticsRouteObserver({required this.tracker, this.resolveRootPage});
|
||||
|
||||
final PageViewTracker tracker;
|
||||
|
||||
/// 根路由(无 RouteSettings.name)当前展示页的解析器,由 app.dart
|
||||
/// 按认证状态与主壳当前 Tab 提供;返回 null 则不补报。
|
||||
final AnalyticsPageName? Function()? resolveRootPage;
|
||||
|
||||
void _reportRoute(Route<dynamic>? route) {
|
||||
if (route is! PageRoute) return;
|
||||
final page = AnalyticsPageName.fromRouteName(route.settings.name);
|
||||
if (page != null) tracker.report(page);
|
||||
}
|
||||
|
||||
@override
|
||||
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
|
||||
_reportRoute(route);
|
||||
}
|
||||
|
||||
@override
|
||||
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
|
||||
_reportRoute(newRoute);
|
||||
}
|
||||
|
||||
@override
|
||||
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
|
||||
if (previousRoute is! PageRoute) return;
|
||||
final page = AnalyticsPageName.fromRouteName(previousRoute.settings.name);
|
||||
if (page != null) {
|
||||
tracker.report(page);
|
||||
} else if (previousRoute.isFirst) {
|
||||
final rootPage = resolveRootPage?.call();
|
||||
if (rootPage != null) tracker.report(rootPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user