// ============================================================================
// 【文件说明】AnalyticsCollectRequest.cs - 分析事件收集请求 DTO
// ============================================================================
// 这是前端上报访问事件的请求数据结构。
//
// 【什么是 DTO?】
// DTO = Data Transfer Object(数据传输对象)
// - 用于在 API 和前端之间传递数据
// - 不包含业务逻辑
// - 通常是简单的属性容器
//
// 【与 Java Spring Boot 的对比】
// Java 通常用 POJO 或 Record:
// public class AnalyticsCollectRequest {
// private String visitorId;
// private String sessionId;
// // getter/setter...
// }
//
// 或 Java 14+ Record:
// public record AnalyticsCollectRequest(
// String visitorId,
// String sessionId,
// ...
// ) {}
//
// C# 用普通类 + 自动属性,更简洁。
// ============================================================================
namespace Admin.NET.Plugin.HwPortal;
///
/// 分析事件收集请求。
///
/// 【业务场景】
/// 前端在以下时机上报事件:
/// - 页面加载完成:page_view
/// - 离开页面:page_leave(带停留时长)
/// - 提交搜索:search_submit(带关键词)
/// - 点击下载:download_click
/// - 提交联系表单:contact_submit
///
///
/// 【C# 语法知识点 - 自动属性】
/// public string VisitorId { get; set; }
///
/// 这是 C# 3.0 引入的"自动属性"语法:
/// - 编译器自动生成私有字段
/// - 不需要显式声明 getter/setter
/// - 等价于 Java 的 private field + public getter/setter
///
/// 对比 Java:
/// Java:
/// private String visitorId;
/// public String getVisitorId() { return visitorId; }
/// public void setVisitorId(String visitorId) { this.visitorId = visitorId; }
///
/// C# 一行代码完成同样功能。
///
///
public class AnalyticsCollectRequest
{
///
/// 访客 ID。
///
/// 【业务说明】
/// 由前端生成并存储在 Cookie 或 localStorage:
/// - 首次访问时生成 UUID
/// - 后续访问复用同一 ID
/// - 用于识别同一访客的多次访问
///
///
public string VisitorId { get; set; }
///
/// 会话 ID。
///
/// 【业务说明】
/// 每次访问生成新的会话 ID:
/// - 用于区分不同的访问会话
/// - 计算跳出率(单页会话占比)
///
///
public string SessionId { get; set; }
///
/// 事件类型。
///
/// 【允许值】
/// - page_view:页面浏览
/// - page_leave:离开页面
/// - search_submit:提交搜索
/// - download_click:点击下载
/// - contact_submit:提交联系表单
///
///
public string EventType { get; set; }
///
/// 页面路径。
///
/// 【示例】
/// /product/detail
/// /search?keyword=xxx
///
///
public string Path { get; set; }
///
/// 来源页面(Referrer)。
///
/// 【业务说明】
/// 用户从哪个页面跳转过来:
/// - 搜索引擎:https://www.google.com/search?q=xxx
/// - 外部网站:https://partner.com/link
/// - 直接访问:为空
///
///
public string Referrer { get; set; }
///
/// UTM 来源参数。
///
/// 【业务说明】
/// 用于营销追踪:
/// - utm_source:流量来源(如 google, baidu)
/// - utm_medium:营销媒介(如 cpc, email)
/// - utm_campaign:营销活动名称
///
///
public string UtmSource { get; set; }
///
/// UTM 媒介参数。
///
public string UtmMedium { get; set; }
///
/// UTM 活动参数。
///
public string UtmCampaign { get; set; }
///
/// 搜索关键词。
///
/// 【业务说明】
/// 仅 search_submit 事件需要此字段。
///
///
public string Keyword { get; set; }
///
/// User-Agent 字符串。
///
/// 【业务说明】
/// 前端可以上报自己的 UA,如果不传则使用请求头中的 UA。
///
///
public string Ua { get; set; }
///
/// 设备类型(前端上报)。
///
/// 【允许值】
/// - Mobile:手机
/// - Tablet:平板
/// - Desktop:桌面
///
///
public string Device { get; set; }
///
/// 浏览器名称(前端上报)。
///
public string Browser { get; set; }
///
/// 操作系统(前端上报)。
///
public string Os { get; set; }
///
/// 停留时长(毫秒)。
///
/// 【C# 语法知识点 - 可空值类型】
/// long? 是可空的长整型:
/// - 可以是 null(表示未提供)
/// - 可以是 long 值
///
/// 对比 Java:
/// Java 用 Long 包装类:
/// private Long stayMs; // 可以为 null
///
/// C# 的可空值类型是值类型,更高效。
///
///
/// 【业务说明】
/// 仅 page_leave 事件需要此字段。
///
///
public long? StayMs { get; set; }
///
/// 事件时间(Unix 毫秒时间戳)。
///
/// 【业务说明】
/// 前端上报事件发生的时间:
/// - 如果不传,使用服务器当前时间
/// - 用于处理网络延迟导致的时间偏差
///
///
public long? EventTime { get; set; }
}