Files
lixi 6fef0db009
CI / flutter-gates (push) Successful in 1m3s
新增:page_viewed 集中式路由埋点(NavigatorObserver)
- 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>
2026-09-07 14:50:04 +08:00

39 lines
1.4 KiB
Dart
Raw Permalink 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.
import 'package:patbond_flutter/analytics/analytics_page_name.dart';
/// trackEvent 形状的回调(生产传 `AnalyticsService.trackEvent`,测试传录制桩)。
typedef TrackEventFn =
Future<void> Function(String eventName, [Map<String, dynamic>? props]);
/// page_viewed 上报的单一出口:维护 referrer 链与去重。
///
/// 路由事件(AnalyticsRouteObserver)、主壳 Tab 切换、认证状态机切页
/// 三类曝光都经此上报,referrer(前一页 pageName)才能跨机制连贯;
/// 栈底/冷启动首页 referrer 为 null06 §5.2 验收 3)。
class PageViewTracker {
PageViewTracker(this._track);
final TrackEventFn _track;
String? _lastPageName;
AnalyticsPageName? _currentTab;
/// 主壳当前 Tab(供回栈补报解析根路由曝光页)。
AnalyticsPageName? get currentTab => _currentTab;
/// 上报一次页面曝光;与上一条相同的页面去重(Tab 重复点选等)。
void report(AnalyticsPageName page) {
if (page.pageName == _lastPageName) return;
final referrer = _lastPageName;
_lastPageName = page.pageName;
final props = <String, dynamic>{'pageName': page.pageName};
if (referrer != null) props['referrer'] = referrer;
_track('page_viewed', props);
}
/// 主壳 Tab 曝光:记录当前 Tab 后上报(IndexedStack 无路由事件,手动补点)。
void reportTab(AnalyticsPageName page) {
_currentTab = page;
report(page);
}
}