Co-Authored-By: Claude Code <noreply@anthropic.com>
18 KiB
客户行为采集平台 · 设计文档
- 日期:2026-09-15
- 状态:已确认
- 关联文档:
docs/客户行为数据采集平台完整项目实施方案.docx、docs/客户行为数据采集平台方案实施报告.docx(需求基线,本设计在其基础上按实际约束裁剪落地);docs/客户画像与销售转化实施方案.md(M4+ 路线图,本平台即其"跨天轨迹底座")
1. 项目目标
构建一个第一方客户行为数据采集平台:网站引入自研 JS SDK,采集访客行为轨迹与环境信息,写入独立后台数据库;后台基于 Art Design Pro 构建管理控制台,提供访客/客户的跨天行为时间线、来源归因、有效停留统计和客户档案管理。
核心业务问题:"这个客户从哪来、看过什么、哪天来过、每次停多久、在哪儿流失、什么时候变成了线索"。
2. 已确认的决策
| 维度 | 决策 |
|---|---|
| 形态 | 通用 JS SDK(网站引入)+ 独立后台 |
| 后端 | Python · Django + DRF |
| 数据库 | MySQL 8(复用 1Panel 现有容器),事件表按月分区 |
| 前端 | Art Design Pro(Vue3 + TypeScript + Element Plus + Pinia + ECharts) |
| 部署 | 阿里云 ECS · 1Panel · Docker Compose(Nginx 静态 + 反代 Django) |
| 规模策略 | 先小后大;单组织多站点,表结构带 site_id 留多站点扩展位 |
| 实时性 | 准实时(事件分钟内可见,最近 5 分钟活跃作为"在线"口径) |
| 客户识别 | 表单提交(询盘/留言)为主;邮件专属链接识别(M2);登录绑定(P2) |
| 缓存 | M1 不引入 Redis;M2 起可选(限流/缓存加固) |
2.1 与原方案文档的差异
| 原文档建议 | 本设计 | 理由 |
|---|---|---|
| Node.js 后端 | Django + DRF | 团队技术选型 |
| PostgreSQL | MySQL 8 | 现有 1Panel 环境;JSON 类型 + 按月分区满足当前量级 |
| React/Next.js 后台 | Art Design Pro | 指定模板,自带权限/菜单/主题体系 |
| 多租户 SaaS 就绪 | 单组织多站点 | 先自用,不为 SaaS 付复杂度 |
| Redis 起步必备 | M2 可选 | 先小后大 |
明确砍掉/推迟(首期不做):多租户组织管理、ClickHouse、同意管理平台(CMP)、Webhook、会话回放、浏览器指纹身份追踪、营销自动化、机器学习评分。
保留的治理底线(不可裁剪):敏感字段黑名单双重拦截、确定性合并原则、数据保留期限与清理、客户删除流程、隐私告知。
3. 系统架构
┌─────────────────────────────────────────────┐
│ 网站浏览器 │
│ JS SDK(自研 ≤15KB gzip,异步加载,不阻塞页面) │
└──────────────────┬──────────────────────────┘
│ HTTPS 批量 JSON 上报
▼
┌─────────────────────────────────────────────┐
│ 阿里云 ECS · 1Panel · Docker │
│ Nginx │
│ ├─ 静态:Art Design Pro 打包产物 │
│ └─ /api/* ──► Django + DRF │
│ ├─ 采集接口(公开、域名白名单、限流)│
│ ├─ 管理接口(JWT 登录) │
│ └─ 后台任务(会话化/聚合/清理) │
│ │ │
│ ▼ │
│ MySQL 8(events 按月分区) │
└─────────────────────────────────────────────┘
- 开发期:Vite 代理解决跨域;部署期同域无跨域问题。
- 响应格式适配 Art Design Pro 的
{code, data, message}约定。 - 升级路径:事件量到瓶颈时把采集接口拆为独立 FastAPI 服务,SDK 协议不变。
4. JS SDK 设计
4.1 接入方式(两行)
<script>
window.ctk = window.ctk || function(){(ctk.q = ctk.q || []).push(arguments)};
ctk('init', { siteId: 'site_xxx', endpoint: 'https://track.example.com' });
</script>
<script async src="https://track.example.com/sdk/v1.js"></script>
4.2 身份模型
visitor_id:加密安全随机数,存 localStorage(第一方存储,不用 Cookie+localStorage 双恢复对抗用户清除)。session_id:30 分钟无活动切新会话;跨天访问 = 新会话、同一 visitor。会话权威在 SDK;服务端按同一 30 分钟规则做兜底校验(超长/跨天异常时切分修正),不产生第二套会话口径。- 首次落地时保存首触来源(referrer + UTM + 落地页)到访客档案;每次会话各自记录来源。
4.3 事件清单
| 事件 | 优先级 | 字段要点 |
|---|---|---|
page_view |
P0 | path、title、referrer、UTM;SPA 路由变化触发(P1) |
page_stay |
P0 | active_ms 有效停留:页面可见 + 有鼠标/键盘/滚动活动才累计;visibilitychange 停止;sendBeacon 兜底上报 |
scroll_depth |
P1 | 25/50/75/100% 四档 |
click |
P1 | 可配置范围(按钮/导航/外链/下载),data-track-id 优先标识 |
form_start / form_submit |
P1 | 表单标识、字段名清单、成功/失败;字段值白名单制(白名单在后台按站点配置,SDK init 可覆盖) |
copy / download / print |
P1 | 意图事件:复制了邮箱/电话、下载报价单 PDF、打印页面 |
rage_click / dead_click |
P2 | 反复点无反应区域 |
first_interaction |
P1 | 进页面后首次互动耗时 |
form_field_drop |
P1 | 表单在哪个字段放弃、是否粘贴、是否自动填充 |
identify_hit |
P1 | 邮件专属链接 token 命中(见 5.3) |
sdk_loaded |
P0 | 诊断事件:SDK 版本、初始化耗时 |
4.4 环境信息(首次访问携带)
设备类型、OS + 版本、浏览器 + 版本、屏幕分辨率、语言、时区、触屏、CPU 核心数、设备内存(可选开)、Client Hints(设备型号)、网络类型/下行/RTT(navigator.connection)、页面性能(Navigation Timing)。
4.5 传输可靠性
- 内存队列 → 批量发送(10 条或 15 秒触发);页面隐藏
sendBeacon,需自定义头时fetch keepalive。 - 每事件 UUID
event_id,服务端按site_id + event_id幂等去重。 - 失败指数退避重试(上限 3 次);4xx 不重试;离线队列超限按最旧丢弃并记本地丢弃计数。
- 客户端时间仅作排序参考,服务端另存
received_at并标记时钟偏差。 - SDK 全部逻辑 try/catch 包裹,任何异常不影响宿主网站。
4.6 隐私与安全红线(SDK 端)
- 不采集:password/hidden/file/autocomplete 敏感字段值、验证码、银行卡、身份证。
- URL 清洗:含邮箱/手机号/令牌类查询参数在入库前删除或哈希。
- 不做:键盘逐键记录、剪贴板读取、摄像头/麦克风、浏览器指纹身份追踪(弱指纹仅用于爬虫识别,不参与身份关联)。
- 免费文本默认不采集,需逐项白名单。
5. 身份识别与客户合并
5.1 身份层级
visitor_id(匿名浏览器)
└─ session_id(每次访问)
└─ events
contact(客户档案)── identity 关联表 ── visitor_id / 邮箱哈希 / 手机号哈希
5.2 表单识别(M2 主路径)
匿名访客逛了 3 天 → 第 4 天提交询盘表单
→ 白名单字段值(姓名/邮箱/电话)创建客户档案
→ 同邮箱/手机号已存在则归并,不建重复档案
→ 该 visitor_id 全部历史轨迹自动归入客户名下
→ 后续访问持续追加到同一档案
- 表单字段值浏览器端采集(询盘线索场景够用 + 垃圾过滤:粘贴检测/Honeypot/频率)。
- 订单、支付、注册成功等业务事实必须走服务端签名 API(P2),浏览器事件不作事实依据。
5.3 邮件专属链接识别(M2)
开发信/WhatsApp/社媒发 https://site/?ctk_token=<专属token> 链接;对方点开即触发 identify_hit,立即把匿名轨迹归到对应客户档案——比等表单提交更早识别。
5.4 合并规则
- 只做确定性合并:邮箱/手机号/token/user_id。IP、城市、设备相似绝不自动合并,仅作线索提示。
- 手动认领:后台把匿名访客轨迹认领给客户,支持解除;操作记审计。
- 多个 visitor_id 绑定同一邮箱 → 汇入同一 contact(跨设备视图)。
- 每次 merge/认领/解除记录操作者、时间、规则版本。
6. 来源归因(四层)
- 自动 referrer:提取来路域名(google.com / 合作伙伴站 / 微信内置浏览器 / 直接访问)。
- UTM 参数:utm_source / medium / campaign / term / content,外投链接统一带参。
- 首触 + 会话来源:访客/客户档案永久记录首触来源;每次会话各自记录(时间线可见"第 N 次访问来自 X")。
- 渠道规则映射 + 手动标记:后台配置
域名 → 渠道名规则表(google.com → 自然搜索等);支持手动改/手动标(线下展会、referrer 丢失场景)。
已知边界:referrer 被剥(部分隐私工具/HTTPS→HTTP/微信)记为"直接访问";要 100% 可靠归因用 UTM 链接。
7. 匿名访客可采集信息全景
| 类别 | 内容 |
|---|---|
| 身份标识 | visitor_id、session_id、新/回访、访问次数、首末次访问、活跃天数 |
| 行为轨迹 | 页面浏览及路径、每页有效停留、滚动深度、点击、表单行为(开始/放弃字段/提交)、意图事件(复制/下载/打印) |
| 来源 | referrer 域名、UTM、落地页、部分搜索词 |
| 设备环境 | 设备类型、OS/浏览器及版本、分辨率、语言、时区、触屏、硬件(可选)、Client Hints、网络质量、页面性能 |
| 网络地理(服务端) | IP(保留期限见 9.2)、国家/省/市(ip2region 离线库)、运营商、爬虫识别 |
| 跨站关联 | 自有域名间经站间跳转传 token 串联(M3,首方合法做法);或经客户识别后归并到同一档案 |
拿不到(诚实边界):匿名阶段真实身份(姓名/邮箱/电话);跨设备同一人(直到提交表单/登录/token 命中);清存储/无痕后重新开始(不对抗)。
8. 管理控制台(Art Design Pro 页面)
| # | 页面 | 优先级 | 内容 |
|---|---|---|---|
| C1 | 登录/权限 | P0 | JWT;管理员/普通成员两角色起步(复用模板权限体系) |
| C2 | 总览 Dashboard | P0 | 今日/7日/30日 PV、UV、会话数、新访客比;最近 5 分钟活跃(准实时在线);趋势图 |
| C3 | 访客列表(匿名) | P0 | 访客 ID、首末次访问、会话数、来源、位置、设备 |
| C4 | 访客/会话详情 | P0 | 单访客跨天时间线 + 单会话页面路径(M1 验收核心) |
| C5 | 站点管理 | P0 | 站点 CRUD、site_id 签发、域名白名单 |
| C6 | 客户列表 | P1 | 姓名/邮箱/手机号脱敏、首末次访问、访问次数、总停留、最近来源、标签筛选、搜索 |
| C7 | 客户详情 | P1 | 跨天时间线(日期分组)+ 会话列表 + 设备/地理位置 + 首触来源 + 标签备注 |
| C8 | 事件调试流 | P1 | 原始事件流(含拒绝原因、时延),开发调试用 |
| C9 | 标签/备注 | P1 | 客户打标签、跟进备注 |
| C10 | 渠道规则 | P1 | 域名→渠道映射配置 |
| C11 | 专属链接生成 | P1 | 给客户/活动生成带 token 的识别链接 |
| C12 | 数据导出 | P2 | 客户列表/时间线 CSV |
| C13 | 事件字典 | P2 | 事件 schema 登记 |
客户时间线样式(原样采用文档 8.2):
09-01 10:20 首次访问产品 A 页面 来源 Google Ads
09-01 10:24 查看价格页 有效停留 2 分 18 秒
09-02 16:10 再次访问案例页面
09-02 16:15 询盘提交成功 身份识别为 customer@example.com
9. 数据治理
9.1 敏感字段黑名单
SDK 端 + 服务端双重拦截:password/验证码/银行卡/身份证等永不入库;服务端对 properties 做体积/数量/长度/深度校验,未知字段拒绝或隔离并记原因。
9.2 数据保留(默认值,站点可配)
| 数据 | 保留期 |
|---|---|
| 原始事件(events 分区) | 180 天,分区清理 |
| 原始 IP | 180 天,到期后台任务截断(IPv4 → /24,IPv6 → /64 前缀);地理/运营商解析结果长期保留 |
| 客户档案、标签、备注 | 长期(直至客户删除) |
| 审计日志 | 1 年 |
9.3 客户删除
删除客户档案 + 关联事件(标记删除 + 异步物理清理),记录审计;导出留档。
9.4 隐私告知
提供隐私政策/Cookie 告知文案模板;SDK 预留 consent 开关接口(同意管理模式 P2 完善化);第三方脚本不可绕过同意状态。
10. 数据库核心表(MySQL 8)
| 表 | 要点 |
|---|---|
site |
站点、site_id、域名白名单、采样配置 |
visitor |
visitor_id、首触来源、首次/最近访问、环境摘要 |
session |
session_id、visitor、开始/结束、来源、落地页、会话时长 |
events(按月分区) |
event_id(site 内唯一幂等键)、visitor、session、contact(可空)、event_type、occurred_at、received_at、path、properties JSON |
contact |
客户档案:姓名、邮箱(规范化+加盐哈希列)、电话(同)、公司(可由邮箱域名推导,预留 account 关联,M4+ 客户画像阶段扩展 Account/Person 体系)、标签、备注、负责人 |
identity_map |
visitor_id / 邮箱哈希 / 电话哈希 / token ↔ contact 关联 + 合并审计字段 |
track_token |
专属链接 token ↔ contact |
daily_stats / session_rollup |
聚合派生表(日指标、会话摘要),避免报表扫 events |
admin_user / audit_log |
后台账号、审计 |
索引原则:时间线 (site_id, visitor_id/contact_id, occurred_at DESC);会话 (site_id, visitor_id, started_at DESC);高频筛选字段独立列,长尾属性进 JSON。
11. API 概览
| 接口 | 说明 |
|---|---|
POST /api/collect/batch |
浏览器批量上报:校验站点状态/域名白名单/体积/限流/幂等去重/黑名单 → 入库 |
POST /api/collect/identify |
token 命中识别(M2) |
管理接口 /api/admin/* |
JWT;站点、访客、客户、事件调试、标签、渠道规则、导出、Dashboard 聚合 |
采集接口返回最小响应(成功/失败 + 稳定错误码),不向匿名调用方泄露配置或客户数据。site_id 是公开标识,只用于归属,不赋予任何读取权限。
12. 非功能需求
- SDK 体积 ≤ 15KB(gzip),初始化不阻塞首屏;加载失败对网站零影响。
- 采集接口:日均 10 万事件内单 Django 实例 + MySQL 从容承载;监控接受率、去重率、拒绝原因分布。
- 准实时:事件从发生到后台可见 ≤ 60 秒(列表刷新即得,无长连接)。
- 部署:1Panel Docker Compose(Nginx + Django + gunicorn + 复用 MySQL 容器);.env 管理密钥;数据库迁移向前兼容。
- 备份:MySQL 自动备份 + 恢复演练(复用 1Panel 能力)。
13. 里程碑
M1 · 最小闭环(端到端技术验证)
- SDK:接入两行代码、visitor/session 身份、page_view、page_stay、批量传输、幂等去重、UTM/referrer 首触记录、环境信息、sdk_loaded 诊断事件。
- 后端:采集 API(域名白名单/限流/黑名单校验)、核心表、会话化与日聚合任务。
- 后台:C1 登录权限、C2 总览、C3 访客列表、C4 访客/会话详情、C5 站点管理。
- 验收:一个真实网站接入,后台能看到"某访客今天看了 3 页、每页停多久、昨天来过、首触来源是 Google"。
M2 · 完整产品(客户识别 + 完整后台)
- SDK:click、scroll、SPA 路由、表单事件(含字段放弃/粘贴/自动填充)、意图事件(复制/下载/打印)、first_interaction、URL 清洗、track/identify/reset API。
- 身份:表单→客户档案创建与归并、邮箱/手机号去重、邮件专属链接识别、手动认领/解除、合并审计。
- 后台:C6 客户列表、C7 客户详情、C8 事件调试流、C9 标签备注、C10 渠道规则、C11 专属链接生成。
- 治理:IP 保留期任务、客户删除流程、隐私告知模板。
- 验收:询盘表单提交后客户档案自动生成并归并全部历史轨迹;专属链接点开即识别。
M3 · 增强与扩展
- rage/dead click、远程配置(采样/开关,ETag)、npm 包发布。
- 登录绑定
identify(user_id)(含服务端签名令牌机制)、同意管理模式完善(consent 分目的开关)。 - 服务端签名事件 API(订单/注册事实)、WordPress 连接器插件(注入 SDK + CF7/WPForms 钩子)。
- IP 企业反查(Leadfeeder 式 B2B 线索提示,可选付费库,只提示不自动合并)、邮箱后缀→公司名补全。
- 跨自有域名访客串联(站间跳转传 token)。
- 数据导出、事件字典、Redis 限流加固、(独立评估)会话回放。
- 上线门禁:跨境/隐私合规专项确认(按原方案文档第十二章执行)。
M4+ · 客户画像与销售转化(独立立项,见 docs/客户画像与销售转化实施方案.md)
不在本设计范围内。本平台为其提供的数据基础保障:
- 原始事件全量保存 path/title/properties——画像评分规则可基于历史数据回放重算;
- contact 模型对齐其 Person 概念,预留 account 关联;
- 站内搜索词、下载/复制/打印等意图事件、表单字段级数据从 M2 起持续积累,正是其 Intent/Engagement 评分的原料。
14. 风险与开放项
| 项 | 状态 |
|---|---|
| 表单字段值浏览器端先行、签名机制 P2 | 已决策 |
| 原始 IP 默认保留 180 天后截断(站点可配) | 已决策(默认值) |
| 微信内置浏览器 referrer 常缺失 | 已知边界,用 UTM 专属链接兜底 |
| 主要访客区域与跨境合规 | 上线前按原方案文档第十章做一次专项确认 |
| 事件量超预期 | 升级路径已定:FastAPI 采集拆分 → 分区细化 → 聚合下沉 |