先说结论
在 Odoo 的 website_crm 里,访客不是和 CRM 完全隔离的两套世界。
源码做了三件很关键的事:
- 在线索上挂
visitor_ids; - 通过 SQL 聚合算
visitor_page_count; - 在线索 merge 时,把各自关联的访客一起并到主记录。
所以 CRM 看到的“客户行为”,并不只来自销售手工填写,也可能来自站点侧的浏览轨迹。
一、visitor_ids 说明 visitor 本来就被当成销售线索线索索引
website_crm.models.crm_lead 直接给 crm.lead 加了 visitor_ids 多对多字段。
这意味着设计上它不是“以后也许能关联”,而是:
网站访客本来就是 CRM 线索证据链的一部分。
一个 lead 可以对应多个 visitor,反过来 visitor 也可能和多条商业互动有关。对实施来说,这比单纯在 lead 上存一个 landing_page 文本要强得多。
二、为什么 page view 要用 SQL 聚合,而不是 ORM 循环数
_compute_visitor_page_count() 明确:
- flush 关系表;
- 连接
crm_lead_website_visitor_rel、website_visitor、website_track; - 按 lead 直接 count。
这说明 Odoo 认为这个统计会比较高频,也可能涉及不少数据量,所以不用一条条 visitor 去数页面,而是直接做聚合。
业务含义也很实在:
- 你看到的 page view 不是销售自报;
- 它来自访客轨迹汇总;
- 一条线索背后若有多个 visitor,也会被合并计数。
三、为什么 merge 线索时还要把 visitor 一起迁过去
_merge_get_fields_specific() 对 visitor_ids 做了专门覆盖:
- 不是选主记录的 visitor;
- 而是把所有 lead 的 visitor ids 全量并过去。
这件事非常重要。
否则重复线索一合并,站点行为历史就会被拆断:
- 旧访客只挂在被删掉的壳子上;
- 主记录看起来像“什么都没看过”;
- 后续页面兴趣判断失真。
Odoo 这里的选择是对的:
商业对象要收敛,行为证据不能丢。
四、这套设计最适合解决什么问题
它特别适合回答三类问题:
- 这条线索是不是只是留了联系方式,但根本没浏览内容;
- 这个客户在提交表单前后到底看了多少页面;
- 重复线索合并后,历史浏览兴趣有没有保留下来。
换句话说,visitor 链路不是替代 CRM 主数据,而是给销售提供“温度感”。
五、最容易误解的边界
1. visitor_page_count 不是唯一访客数
它是页面浏览数,不是 UV。
2. 不是所有浏览轨迹都自动等于可销售信号
看得多,不代表意向高;看得少,也不代表价值低。
3. merge 后 visitor 变多,不是重复计算 bug
有时只是因为多条重复 lead 各自挂了不同 visitor,如今被正确汇总到主记录。
六、排错顺序
如果你发现某些线索看不到浏览足迹,先查:
- 是否真的建立了
visitor_ids关联; - 页面轨迹是否在
website_track里; - 是否是 merge 后看错了主记录;
- 是否把 page view 当成访客数理解错了。
一句话记忆
Odoo CRM 里的网站浏览足迹不是展示层彩蛋,而是通过 visitor 关联、页面聚合和 merge 保留机制接进销售线索链路的。
DISCUSSION
评论区