Skip to content
AI 文档索引 ↗

行业场景事件建模示例 ​

以下电商、B2B 和内容场景展示事件命名、属性与触发时机的设计方法。示例是可映射的业务模板,不是 SDK 全局预置属性或后端固定合同;接入方需根据业务事件定义、隐私要求和权威数据来源确定最终事件。


一、电商与零售 ​

电商示例从浏览、加购、结算延伸到支付和退款。关联同一订单的事件可使用稳定的业务订单 ID;每条事件仍须有自己的 eventId,不要把不同事件复用成同一个事件 ID。支付和退款完成事件应由经过认证的业务服务端依据支付/退款结果产生,客户端点击只能记录意图或操作行为,不能代替账务事实。

text
[商品流/推荐位曝光] ──> [商品详情页浏览] ──> [加入购物车] ──> [发起提单结算] ──> [支付成功] ──> [退款成功]
 item_exposure           view_product          add_to_cart      initiate_checkout    order_paid       refund_issued

1. 事件模板与推荐属性 ​

事件名称业务阶段关键属性定义属性类型示例值
view_product浏览商品product_id
product_name
category_id
original_price
sale_price
string
string
string
number
number
"p_99023"
"无线降噪耳机 Pro"
"c_digital_audio"
899.00
699.00
add_to_cart加入购物车product_id
sku_id
quantity
cart_total_price
string
string
number
number
"p_99023"
"sku_black_01"
1
699.00
initiate_checkout发起提单结算checkout_id
cart_items_count
order_subtotal
string
number
number
"chk_20260908_001"
3
1498.00
order_paid支付成功order_id
transaction_id
amount
currency
string
string
number
string
"ord_88291039"
"cap_55091"
699.00
"CNY"
refund_issued退款成功refund_id
order_id
refund_amount
currency
string
string
number
string
"ref_3319"
"ord_88291039"
199.00
"CNY"

2. 模板语义与字段映射 ​

  • order_paid 表示业务后端已确认成功扣款/收款的金额;transaction_id 标识一次成功的支付交易。同一订单有多次独立成功扣款时,每次使用不同交易 ID。
  • refund_issued 表示一笔退款已成功完成;部分退款按每笔退款分别记录,refund_amount 使用该笔退款的正数金额,refund_id 唯一标识该退款。报表计算净收入时必须把退款按退款语义扣减,不能直接将两类正数相加。
  • 金额属性采用数值以支持分析计算,但本模板不是账务精度或对账合同。项目必须明确金额对应的币种、折扣/税费口径及精度;金额字段可以映射到客户已有名称(例如 pay_amount),SDK 不会自动重命名,也不会把这些字段加到全局预置属性。
  • currency 建议使用 ISO 4217 货币代码。SDK Tracking Plan 可校验字符串类型和长度,但不替代业务服务端的币种代码校验。
  • order_id、transaction_id、refund_id 应使用不含姓名、手机号、邮箱、卡号或访问令牌的业务标识。

接入前确认事件名、金额单位、精度和业务口径;使用本地 Tracking Plan 时,可据此配置客户端校验规则。

业务服务端应先对支付/退款通知做业务级去重,再创建事件。SDK 在传输重试时保持同一事件的 eventId,供接收端去重;它不会识别两个不同事件是否代表同一笔业务交易。

3. 客户端与服务端的职责、验证边界 ​

客户端可以记录 view_product、add_to_cart、initiate_checkout 或支付按钮点击等行为。支付成功、退款成功应由业务后端在确认状态后产生;若要求与订单数据库事务一致,应在同一事务写入业务记录和 Outbox 事件,再由 Relay 发送。参见 、Java、Go 和 服务端接入指南。

本地 Tracking Plan 只校验客户端事件,四种服务端 SDK 尚未集成该校验。服务端业务字段校验、幂等落库及收入报表应在实际部署环境中验证。 ​

二、 B2B 组织分析与服务端事实 ​

B2B 事件需要区分分析组织和授权租户。客户端 groupId 可用于分析组织维度;服务端 tenantId 如果用于租户隔离,应从服务端已认证的宿主上下文取得。它们不能因为示例值相同就被视为同一字段或信任边界。

text
[创建工作空间] ──> [邀请成员] ──> [使用核心功能] ──> [套餐变更]
 workspace_created   member_invited   feature_engaged   plan_changed

这些事件名和字段只是可映射模板,需按企业自己的产品指标和 Tracking Plan 确认。客户端事件可记录成员邀请操作、功能使用等行为;套餐、席位、支付或退款等已完成的业务事实,应由确认该事实的业务服务端产生。

1. 客户端组织分析示例 ​

客户端通过 group(groupId, traits) 设置分析组织:

ts
await analytics.identify('user-123');
await analytics.group('org-456', { plan: 'enterprise' });
analytics.track('feature_engaged', {
  module_name: 'advanced_analytics',
  action_type: 'export_csv',
});

groupId 是宿主显式提供的分析上下文;traits 随 $group 事件发送,不会自动并入每个后续事件。客户端可上报的组织或租户属性不能作为后端授权依据。

2. 服务端权威业务事件 ​

支付、退款、订阅和席位变化应在业务服务确认状态后从服务端发出。服务端 SDK 的 ServerIdentity 支持显式 tenantId,宿主应从已认证的业务上下文填充它;SDK 不替代认证、权限校验、业务去重或事务 Outbox。金额口径、币种、退款表示及 ARR 定义必须由业务、财务和数仓共同确认,不作为 SDK 的全局预置属性。具体边界见 B2B 组织属性与服务端租户边界 和服务端事件接入合同。


三、内容社区与流媒体 ​

内容产品可记录阅读、播放进度和互动,用于分析内容消费深度与参与度。

text
[信息流曝光] ──> [进入正文/播放页] ──> [消费进度打卡] ──> [社交点赞/评论/分享]
 feed_exposure      view_content            content_progress    social_interaction

1. 事件模板与推荐属性 ​

事件名称业务阶段关键属性定义属性类型说明
content_exposure内容瀑布流曝光content_id
content_type
position_index
rec_algorithm_id
string
string
number
string
用于推荐算法负样本与曝光未点击率分析
view_content打开内容详情content_id
category_id
author_id
publish_time
string
string
string
string
开始消费图文或视频
content_progress阅读/播放进度content_id
progress_percent
playback_position_s
string
number
number
可按项目定义的进度节点触发;播放位置不是累计观看时长
social_interaction社交互动content_id
interaction_type
target_user_id
string
string
string
interaction_type: "like", "comment", "share_timeline"

2. 按进度节点记录事件 ​

ts
// 假设 analytics 已初始化。每次播放创建一个 reporter,同一次播放每个节点最多记录一次。
function createProgressReporter(contentId: string) {
  const reported = new Set<number>();
  const checkpoints = [25, 50, 75, 100];

  return (currentTime: number, duration: number) => {
    if (!Number.isFinite(currentTime) || !Number.isFinite(duration) || duration <= 0) return;
    const position = Math.min(100, Math.max(0, (currentTime / duration) * 100));

    for (const checkpoint of checkpoints) {
      if (position >= checkpoint && !reported.has(checkpoint)) {
        reported.add(checkpoint);
        analytics.track('content_progress', {
          content_id: contentId,
          progress_percent: checkpoint,
          playback_position_s: Math.round(currentTime),
        });
      }
    }
  };
}

const reportProgress = createProgressReporter('content_10029');
video.addEventListener('timeupdate', () => reportProgress(video.currentTime, video.duration));
swift
// 在持有 sdk 和 hasTrackedCompletion 的 UIScrollViewDelegate 中使用。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let maxOffset = scrollView.contentSize.height - scrollView.bounds.height
    guard maxOffset > 0 else { return }
    let progress = Int((scrollView.contentOffset.y / maxOffset) * 100)

    if progress >= 100 && !hasTrackedCompletion {
        hasTrackedCompletion = true
        sdk.track("content_progress", properties: [
            "content_id": .string("art_10029"),
            "progress_percent": .number(100)
        ])
    }
}

四、字段治理建议 ​

  1. 高频进度回调应按项目定义的里程碑去重记录,避免把每次 UI 回调都变成事件。选择哪些节点取决于业务分析目标。
  2. 不发送密码、访问令牌、完整支付凭据或无关个人信息。哈希不等于匿名化;不要把哈希当作通用脱敏方式。确需关联用户时,由业务和数据治理团队确定允许的标识、用途和留存规则。
  3. 为自定义属性选定团队约定的命名风格并保持一致。SDK 接受自定义字段名,不会强制转换为 snake_case;接收端映射规则需单独确认。
  4. 金额字段使用什么单位、精度和币种由项目定义,并确保每条金额记录带有可解释的币种信息。SDK 不会统一换算或改写金额。