Files
hgmj_android/analytics_sdk/lib/entity/page_click_event.dart
T
2026-10-08 11:37:25 +07:00

285 lines
9.1 KiB
Dart

import 'package:analytics_sdk/manager/page_name_manager.dart';
import 'package:analytics_sdk/const/event_type.dart';
import 'package:analytics_sdk/manager/page_click_auto_fields.dart';
import 'package:analytics_sdk/manager/sdk_context.dart';
/// 应用页面点击日志 (自动)
class PageClickEvent {
final String event = EventType.pageClick.event;
late final String eventId;
final String pageKey;
/// 页面名称:首页, 我的, 视频页
final String pageName;
/// 点击位置坐标x轴
final int clickPageX;
/// 点击位置坐标y轴
final int clickPageY;
/// SDK 标准化点击相对当前页面根容器可视区域左上角的 X 坐标。
final int clickViewportX;
/// SDK 标准化点击相对当前页面根容器可视区域左上角的 Y 坐标。
final int clickViewportY;
/// 点击相对当前页面主内容完整区域左上角的 X 坐标。
final int clickDocumentX;
/// 点击相对当前页面主内容完整区域左上角的 Y 坐标。
final int clickDocumentY;
/// 点击位置横坐标百分比(0-100)
final int clickXPercent;
/// 点击位置纵坐标百分比(0-100)
final int clickYPercent;
/// 屏幕宽度(像素)
final int screenWidth;
/// 屏幕高度(像素)
final int screenHeight;
/// 点击时当前页面根容器可交互可视区域宽度。
final int viewportWidth;
/// 点击时当前页面根容器可交互可视区域高度。
final int viewportHeight;
/// 点击时当前页面主内容容器完整宽度。
final int pageWidth;
/// 点击时当前页面主内容容器完整高度。
final int pageHeight;
/// 点击时当前页面主内容容器纵向滚动偏移。
final int scrollTop;
/// 点击时当前页面主内容容器横向滚动偏移。
final int scrollLeft;
/// 推荐引擎的trace_id,有多个推荐列表时用英文逗号分隔,未接推荐引擎传空字符串
final String recommendTraceId;
late final Map<String, dynamic> _commonFields;
PageClickEvent({
required String pageKey,
required this.pageName,
required this.clickPageX,
required this.clickPageY,
required this.clickXPercent,
required this.clickYPercent,
required this.screenWidth,
required this.screenHeight,
int? clickViewportX,
int? clickViewportY,
int? clickDocumentX,
int? clickDocumentY,
int? viewportWidth,
int? viewportHeight,
int? pageWidth,
int? pageHeight,
int? scrollTop,
int? scrollLeft,
this.recommendTraceId = '',
}) : pageKey = PageNameMapper.normalizeKey(pageKey),
clickViewportX = _coordinateOrFallback(clickViewportX, clickPageX),
clickViewportY = _coordinateOrFallback(clickViewportY, clickPageY),
viewportWidth = _dimensionOrFallback(viewportWidth, screenWidth),
viewportHeight = _dimensionOrFallback(viewportHeight, screenHeight),
clickDocumentX = _hasInvalidHorizontalDocumentMetrics(
pageWidth: pageWidth,
viewportWidth: viewportWidth,
screenWidth: screenWidth,
scrollLeft: scrollLeft,
)
? -1
: _unknownable(clickDocumentX),
clickDocumentY = _unknownable(clickDocumentY),
pageWidth = _hasInvalidHorizontalDocumentMetrics(
pageWidth: pageWidth,
viewportWidth: viewportWidth,
screenWidth: screenWidth,
scrollLeft: scrollLeft,
)
? -1
: _unknownable(pageWidth),
pageHeight = _unknownable(pageHeight),
scrollTop = _unknownable(scrollTop),
scrollLeft = _hasInvalidHorizontalDocumentMetrics(
pageWidth: pageWidth,
viewportWidth: viewportWidth,
screenWidth: screenWidth,
scrollLeft: scrollLeft,
)
? -1
: _unknownable(scrollLeft) {
_commonFields = SdkContext.generateCommonFields(event);
eventId = SdkContext.generateEventIdFromCommonFields(_commonFields, [
this.pageKey,
pageName,
clickPageX.toString(),
clickPageY.toString(),
this.clickViewportX.toString(),
this.clickViewportY.toString(),
this.clickDocumentX.toString(),
this.clickDocumentY.toString(),
clickXPercent.toString(),
clickYPercent.toString(),
screenWidth.toString(),
screenHeight.toString(),
this.viewportWidth.toString(),
this.viewportHeight.toString(),
this.pageWidth.toString(),
this.pageHeight.toString(),
this.scrollTop.toString(),
this.scrollLeft.toString(),
recommendTraceId,
]);
}
Map<String, dynamic> toJson() {
Map<String, dynamic> payload = {
'page_key': pageKey,
'page_name': pageName,
'click_page_x': clickPageX,
'click_page_y': clickPageY,
'click_viewport_x': clickViewportX,
'click_viewport_y': clickViewportY,
'click_document_x': clickDocumentX,
'click_document_y': clickDocumentY,
'click_x_percent': clickXPercent,
'click_y_percent': clickYPercent,
'screen_width': screenWidth,
'screen_height': screenHeight,
'viewport_width': viewportWidth,
'viewport_height': viewportHeight,
'page_width': pageWidth,
'page_height': pageHeight,
'scroll_top': scrollTop,
'scroll_left': scrollLeft,
'recommend_trace_id': recommendTraceId,
};
return {
..._commonFields,
'event_id': eventId,
"payload": payload,
};
}
factory PageClickEvent.fromJson(Map<String, dynamic> json) {
return PageClickEvent(
pageKey: json['page_key'] as String,
pageName: json['page_name'] as String,
clickPageX: json['click_page_x'] as int,
clickPageY: json['click_page_y'] as int,
clickXPercent: json['click_x_percent'] as int,
clickYPercent: json['click_y_percent'] as int,
screenWidth: json['screen_width'] as int,
screenHeight: json['screen_height'] as int,
clickViewportX: json['click_viewport_x'] as int?,
clickViewportY: json['click_viewport_y'] as int?,
clickDocumentX: json['click_document_x'] as int?,
clickDocumentY: json['click_document_y'] as int?,
viewportWidth: json['viewport_width'] as int?,
viewportHeight: json['viewport_height'] as int?,
pageWidth: json['page_width'] as int?,
pageHeight: json['page_height'] as int?,
scrollTop: json['scroll_top'] as int?,
scrollLeft: json['scroll_left'] as int?,
recommendTraceId: json['recommend_trace_id'] as String? ?? '',
);
}
static PageClickEvent fromViewport({
required String pageKey,
required String pageName,
required int clickPageX,
required int clickPageY,
required int clickViewportX,
required int clickViewportY,
required int viewportWidth,
required int viewportHeight,
int? clickDocumentX,
int? clickDocumentY,
int? pageWidth,
int? pageHeight,
int? scrollTop,
int? scrollLeft,
String recommendTraceId = '',
}) {
final documentMetrics = currentClickDocumentMetrics(
clickViewportX: clickViewportX,
clickViewportY: clickViewportY,
);
final clickXPercent = viewportWidth > 0
? (clickViewportX / viewportWidth * 100).round().clamp(0, 100)
: 0;
final clickYPercent = viewportHeight > 0
? (clickViewportY / viewportHeight * 100).round().clamp(0, 100)
: 0;
return PageClickEvent(
pageKey: pageKey,
pageName: pageName,
clickPageX: clickPageX,
clickPageY: clickPageY,
clickXPercent: clickXPercent,
clickYPercent: clickYPercent,
screenWidth: viewportWidth,
screenHeight: viewportHeight,
clickViewportX: clickViewportX,
clickViewportY: clickViewportY,
clickDocumentX: clickDocumentX ?? documentMetrics.clickDocumentX,
clickDocumentY: clickDocumentY ?? documentMetrics.clickDocumentY,
viewportWidth: viewportWidth,
viewportHeight: viewportHeight,
pageWidth: pageWidth ?? documentMetrics.pageWidth,
pageHeight: pageHeight ?? documentMetrics.pageHeight,
scrollTop: scrollTop ?? documentMetrics.scrollTop,
scrollLeft: scrollLeft ?? documentMetrics.scrollLeft,
recommendTraceId: recommendTraceId,
);
}
static int _coordinateOrFallback(int? value, int fallback) {
final resolved = value ?? fallback;
return resolved < 0 ? -1 : resolved;
}
static int _dimensionOrFallback(int? value, int fallback) {
final resolved = value ?? fallback;
return resolved < 0 ? -1 : resolved;
}
static int _unknownable(int? value) {
if (value == null || value < 0) return -1;
return value;
}
static bool _hasInvalidHorizontalDocumentMetrics({
required int? pageWidth,
required int? viewportWidth,
required int screenWidth,
required int? scrollLeft,
}) {
final resolvedPageWidth = _unknownable(pageWidth);
final resolvedViewportWidth =
_dimensionOrFallback(viewportWidth, screenWidth);
final resolvedScrollLeft = _unknownable(scrollLeft);
if (resolvedPageWidth < 0 ||
resolvedViewportWidth < 0 ||
resolvedScrollLeft <= 0) {
return false;
}
final maxScrollLeft = resolvedPageWidth - resolvedViewportWidth;
return maxScrollLeft < 0 || resolvedScrollLeft > maxScrollLeft;
}
}