客户案例

Odoo 客户案例页为什么不是“摆一排 Logo”这么简单:行业筛选、国家聚合与公开展示边界讲透

很多人把 Odoo 的 Customers 页面理解成静态客户 Logo 墙,但 website_customer 实际把已发布客户、行业与国家聚合、标签筛选、地图能力和详情页访问边界组织成了一个可检索案例目录。

网站
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 网站里的 Customers 页面,不是“后台勾几个客户,然后前台摆一排 Logo”这么简单。

website_customer 真正构建的是一个公开案例目录,它同时处理:

  • 哪些客户允许公开展示;
  • 如何按行业、国家、标签进行筛选;
  • 列表页怎样统计各筛选分组数量;
  • 有没有 Google Maps 地图视图;
  • 详情页该如何在 slug 与公开边界内安全访问。

所以这个模块更像一个轻量版的“客户案例库”,而不是纯装修组件。


一、为什么 Customers 页面从一开始就不是随便公开联系人

controller 里的基础 domain 很明确:

  • website_published = True
  • assigned_partner_id != False

这两个条件合起来很重要。

第一层说明:

  • 不是所有联系人都能上官网,必须显式发布。

第二层说明:

  • 只有被视作“客户案例 / 客户引用对象”的伙伴,才应该出现在目录里;
  • 普通联系人、供应商、内部地址记录,并不会自动挤进前台。

也就是说,Odoo 在产品层面已经把“CRM/联系人数据库”和“公开客户案例库”划了一道线。


二、为什么列表筛选按行业和国家做聚合,而不是前端死写选项

customers() 里会先基于当前搜索 domain 做两次 _read_group()

  • 一次按 industry_id
  • 一次按 country_id

然后把统计结果转换成前台可渲染的筛选数据。

这代表一个很务实的思路:

筛选项应该从当前真实可展示的数据里长出来。

好处有三个:

  1. 没有客户的行业不会硬占位置;
  2. 搜索后筛选计数仍然可信;
  3. 前台不需要维护一套和数据库可能脱节的静态选项。

所以这不是“多加几个下拉框”的事,而是案例目录的可维护性设计。


三、为什么 country 命中过空时要自动回退到 All Countries

源码里有个细节很容易被忽略:

  • 如果当前 country 路由存在;
  • 但在现有结果里这个国家已经没有客户;
  • 系统会把 fallback_all_countries = True,并把当前国家置空。

这个体验非常像成熟目录站,而不是死板后台页。

因为现实里常会发生:

  • 某客户取消公开;
  • 案例被下线;
  • 搜索词变化导致该国家下没有结果。

如果系统强行留在一个空国家筛选里,用户会以为网站坏了。

Odoo 的处理更聪明:

  • 路由可以保留;
  • 但结果层面回退到“所有国家”;
  • 同时告诉前台这是一次 fallback。

四、为什么标签不是联系人标签,而是“网站标签”

res.partner 在这里扩展的是:

  • website_tag_ids

而不是直接拿 CRM 里所有伙伴标签来复用。

同时 res.partner.tag 在这个模块里被定义成:

  • 可发布;
  • 带颜色 class;
  • 专门用于网站筛选客户案例。

这说明 Odoo 非常清楚后台业务标签和前台公开分类不是一回事。

如果直接把内部标签全端出去,前台会很快变成:

  • 含义不统一;
  • 运营不可控;
  • 甚至暴露内部管理语义。

所以它专门给客户案例页留了一套网站标签体系。


五、为什么 Customers 还要兼容地图能力

controller 继承的是 website_google_map.controllers.main.GoogleMap

并且 _get_gmap_domains() 会在 dom == "website_customer.customers" 时,改写成客户案例页面自己的 domain。

这说明 Odoo 把客户案例目录理解成可以同时存在两种浏览方式:

  • 文本列表 / 卡片浏览;
  • 地理分布浏览。

对于做国际客户展示、区域覆盖证明、线下服务能力说明的公司来说,这比普通 logo 墙有说服力得多。

也就是说,Customers 页面并不只是内容展示,而是销售可信度的一个证明入口。


六、为什么详情页访问还要校验 slug 和公开状态

/customers/<partner_id> 这条路由不是 semantic route,而是手动 unslug 再检查。

流程大致是:

  1. 先从 slug 里解出 partner id;
  2. sudo() 读取伙伴;
  3. 检查记录是否存在且 website_published=True
  4. 如果 slug 不规范,则 302 重定向到正确 slug;
  5. 否则渲染详情页;
  6. 任一条件不满足就 not_found()

这说明 Odoo 很重视案例详情页的两个基础问题:

  • URL 标准化;
  • 非公开记录不能被随便捞出来。

对于官网案例页来说,这一点非常必要。


七、实施时最容易误解的地方

1. 以为 Customers 只是展示组件,不是内容目录

不对。源码明显在做分组、搜索、分页和地图支持。

2. 以为联系人只要存在就能上站

不对。必须同时满足公开发布与客户归属条件。

3. 以为标签可以直接复用后台联系人标签

不对。网站公开标签和内部业务标签最好分开。

4. 以为空国家筛选结果就该硬显示 0 条

不对。更好的体验是回退到 All Countries。


最后总结

Odoo 的 website_customer 真正做的是:

  • 把可公开的客户案例从联系人数据库里挑出来;
  • 组织成带国家、行业、标签与地图能力的目录;
  • 让列表页和详情页都遵守公开展示边界;
  • 用更可检索、更可信的方式替代简单 Logo 墙。

所以它更像:

一个为销售可信度服务的官网客户案例目录系统。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。