先说结论
很多人理解 Odoo 的 @提及时,会把它当成“在评论里插入一个高亮名字”。
这只看到了表层。
从官方源码看,提及真正涉及的是一整条通知链:
- 谁可以被提及
- 前端候选人怎么出来
- 提及对象怎样拿到安全 token
- 被提及的人怎样变成
partner_ids直接收件人 - 作者自己要不要被提醒
- followers 与 direct recipients 到底怎么分工
一句话说:
Odoo 的 @提及不是富文本装饰,而是把某个人显式拉进本次消息通知范围的机制。
源码从哪里看
这篇最值得一起看的有两块:
候选人与 token
addons/mail/models/res_partner.py
这里能看到:
get_mention_suggestions()_get_mention_token()_search_mention_suggestions()
通知分发
addons/mail/models/mail_thread.py
这里能看到:
partner_ids在通知里的作用notify_author_mention- followers 与显式收件人的边界
如果只看编辑器 UI,你会觉得 @提及很轻;如果把这两段源码连起来看,就会知道它其实是通知系统的一部分。
第一步:不是所有人都一样进入提及候选
在 res_partner.py 里,get_mention_suggestions() 最终会调用 _search_mention_suggestions()。
它的排序策略很有意思:
- 优先内部用户
- 再看一般用户
- 最后扩展到普通联系人
而且匹配条件不是只看名字,也会看邮箱。
这说明 Odoo 设计提及时,优先考虑的是:
协同里最常被提及的,往往是系统里的真实工作用户,而不是任意联系人。
这跟纯社交产品不一样,更像办公协作工具的优先级。
第二步:为什么还要有 mention_token
源码里 _get_mention_token() 会给 partner 生成一个带作用域的 token,scope 是 mail.message_mention。
这说明前端里出现的“可提及对象”并不是裸露的 partner id,而是带有限权语义的引用。
这背后其实有两个好处:
1. 前端可以安全地表达“这个对象可被提及”
不是把一切内部主键都直接暴露出来。
2. 提及动作可以和权限边界挂钩
也就是:
- 不是你知道某个 ID 就能随便拼接提及
- 系统要明确认可这个对象处在可提及范围内
对企业系统来说,这比“插个 @name 文本”严谨得多。
第三步:提及和 partner_ids 是什么关系
读 mail_thread.py 时,最值得注意的一点是:
通知阶段会区分:
- followers
partner_ids这类显式收件人
注释写得非常明确:
notify_author_mention允许作者在 direct recipients 中也收到通知notify_skip_followers时,消息更像 user notification,只依赖显式 recipients
换句话说:
提及最重要的后果,不是文本里多了一个 @,而是消息有了更明确的 direct recipients。
这也是为什么很多业务人员的直觉是:
- 我被 @ 了,那这次消息应该更“点对点”地到我这里
官方实现正是朝这个方向设计的。
followers 和 direct recipients 到底有什么区别
这两者很容易被混淆。
followers
更像:
- 你长期关注这条业务记录
- 以后相关消息大概率也会持续收到
direct recipients / partner_ids
更像:
- 这一次消息明确点名发给你
- 它有更强的即时性和针对性
所以在 Odoo 的协同里:
- follower 是“订阅关系”
- mention 更接近“本次消息的显式收件关系”
这就是为什么你不能只靠 follower 来理解 @提及。
为什么源码专门有 notify_author_mention
这是一个很容易被忽略、但很说明问题的细节。
通常系统不会给作者自己发通知,否则会产生大量自我提醒噪音。
但 mail_thread.py 又留了一个例外:
- 如果作者本人也出现在 direct recipients 里
- 并且
notify_author_mention开启 - 那就允许作者收到通知
这反映出一个很务实的设计选择:
默认不提醒作者,但当作者是被显式点名的收件人时,可以破例。
为什么需要这个例外?
因为现实协同里确实有这种场景:
- 机器人或自动流程代某人发消息
- 当前用户既是作者语义上的发起者,也是这条消息必须被提醒的人
- 或者某些内部提醒需要作者自己也看到通知链落地情况
所以这不是多余开关,而是对复杂协同语义的保留。
为什么说 @提及不是“自动关注”的替代品
很多实现会把“提及某人”直接做成“把某人加为 follower”。
但官方思路并不是这样简单粗暴。
因为两者语义不一样:
提及
强调:
- 本次消息你要看
- 这是一次显式点名
关注
强调:
- 这个记录以后你持续处在消息链里
如果把两者混成一件事,就会出现两个问题:
- 只是临时点名,却被永久订阅
- 或者明明应该长期跟进,却只收到一次提醒
所以更好的理解是:
提及是本次消息级别的显式收件,关注是记录级别的持续订阅。
这套设计对办公协同有什么价值
1. 能把“群里说一下”升级成“明确点名谁处理”
这让沟通责任更清楚。
2. 能让提醒精度高于单纯 follower 广播
不是所有关注者都需要每次都被强提醒。
3. 能保留作者不自扰的默认体验
但又允许在必要时精确打破这个规则。
4. 能把候选人筛选和权限安全绑在一起
这比一个普通富文本 @ 功能成熟得多。
做相关定制时最容易踩的坑
1. 只做前端高亮,不接通知链
结果用户以为自己“@到了”,其实没有真正被纳入收件范围。
2. 把提及和 follower 强绑定
结果一次性沟通被错误地变成长期订阅。
3. 忽略作者通知例外
一些自动化或代理发送场景下,提醒行为会和官方语义不一致。
4. 候选人搜索不区分内部用户优先级
办公产品的提及体验会变得很乱。
一句话记忆法
Odoo 的 @提及,本质上是把某个人显式放进这次消息的 direct recipients,而不只是把名字高亮出来。
理解这一句,就能分清 mention、followers 和通知分发之间真正的边界。
DISCUSSION
评论区