285 lines
9.1 KiB
Dart
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;
|
|
}
|
|
}
|