先说结论
Odoo 的在线课程体系,真正难的不是“上传内容”,而是怎么把课程入口管对。
从 /home/ubuntu/odoo-temp/addons/website_slides/models/slide_channel.py 和 slide_channel_partner.py 来看,一门课程至少有三道门:
- 门一:这门课对谁可见
- 门二:看见的人能不能加入
- 门三:加入之后,是否还要满足前置课程条件
所以 slide.channel 真正解决的问题不是:
如何发布课程页面。
而是:
如何把公开展示、成员访问、邀请制与学习路径约束收进同一套课程对象。
第一层:为什么 visibility 不等于“是否发布”
很多人会把课程是否可见,简单理解为一个 published 开关。
但 slide.channel 里明显分了几层:
website_publishedvisibility:public / connected / membersis_visible
这表示官方在区分两件事:
- 课程有没有对网站公开发布
- 当前访问者在身份上有没有资格看见它
is_visible 的计算会综合:
- 课程是 public
- 或当前用户已经是成员
- 或用户不是游客,且课程允许 connected 用户查看
这说明课程曝光不是单一开关,而是发布状态 + 访问者身份 的合取判断。
这很重要,因为很多培训内容并不是“上网站就给所有人看”。有些课程适合当公开营销入口,有些只适合登录后查看,有些则只对成员开放。
第二层:为什么 members 可见性会强制绑定 invite
源码中有一个很有代表性的约束:
CHECK(visibility != 'members' OR enroll = 'invite')
翻成大白话就是:
- 如果课程只给成员看
- 那入课方式就必须是邀请制
这是一条非常产品化的规则。
因为如果你允许一门“只有成员能看”的课程却又开放自由报名,就会出现语义冲突:
- 页面上别人先看不见
- 但又希望他主动加入
- 加入入口和可见性彼此打架
Odoo 直接在数据层把这种混搭禁掉,相当于给课程策略加了护栏。
这比把复杂性留给运营自己记规则稳得多。
第三层:为什么课程成员状态不是简单 enrolled / not enrolled
slide.channel.partner 里有四种很关键的 member_status:
invitedjoinedongoingcompleted
这说明课程成员关系不是一个布尔值,而是一条有过程的状态链。
特别是 invited 这个状态很有意思。
它表示:
- 这个人和课程已经有关系
- 但还不算真正进入学习过程
- 他可能只有一个邀请链接,还没点击加入
这也解释了为什么很多统计口径要排除 invited,只把真正开始参与的人算进课程成员与完成率。
换句话说,Odoo 不是把“收到邀请”和“开始学习”混在一起,而是把它们拆开处理。
第四层:邀请链接为什么不是随便拼个 URL
slide.channel.partner 会基于 partner 与 channel 计算 invitation_link,其核心是一个 HMAC 风格的 invite_hash。
这表示邀请链接不是一个公开课程链接后面随手带个 id,而是带签名校验的成员入口。
它的价值在于:
- 邀请制课程可以精确定位到某个成员
- 前台可以识别“这个人是被邀请来的”
- 运营不用额外发账号,也能先把成员关系建起来
对企业培训来说,这很实用。因为很多时候企业想要的是:
- 先指定要学的人
- 再通过邮件把入口发给他们
- 最后追踪谁加入、谁进行中、谁完成
而不是把课程扔到网站上自助报名。
第五层:为什么前置课程不是装饰字段
slide.channel 里有:
prerequisite_channel_idsprerequisite_of_channel_idsprerequisite_user_has_completed
这说明前置课程不是内容推荐,而是访问闸门的一部分。
也就是说,官方承认课程体系里存在“学习路径”这件事。
它不是让用户自己猜下一门该学什么,而是允许课程之间形成显式依赖:
- 先学基础课
- 再进进阶课
- 当前用户是否完成前置要求,会影响能否顺利进入后续课程
这对文档式课程和岗位培训尤其有价值。因为现实里的培训从来不是一堆平铺资源,而是有顺序、有门槛的。
第六层:为什么 partner_has_new_content 和成员状态能一起工作
即使一门课程已经加入,Odoo 也没有把成员关系当成静态事实。
partner_has_new_content 这类计算说明,成员进入课程后,系统还在继续判断:
- 有没有新内容发布
- 当前成员需不需要被提醒
- 学习进度是否要继续推进
这和前面几轮我们写过的完成度、下一课推荐是互补的。
如果说完成度解决的是“已经在学的人下一步去哪”,那么可见性、邀请制和前置课程解决的就是:
谁能开始学,以及何时有资格开始学。
最容易误解的三个点
误区一:课程发布了,所有人都能看见
不是。发布状态还要叠加 visibility 与当前访问者身份。
误区二:成员关系就是加进课程名单
不是。邀请、加入、进行中、完成是不同状态。
误区三:前置课程只是推荐路径
也不是。它本质上是访问和学习路径的闸门。
实战上怎么落地最稳
建议这样设计课程体系:
- 先区分公开营销课、登录可见课、成员专属课
- 成员专属课一律按邀请制思路设计,不要和公开自助报名混用
- 企业培训先建立成员关系,再发邀请链接,统计口径会更清楚
- 有明确学习阶段的课程,尽量启用 prerequisite,而不是只靠文案提示“建议先学这个”
- 课程运营报表里,把 invited 和真正学习中的成员分开看
最后总结
Odoo eLearning 的课程对象,本质上不是“内容容器”,而是一个带访问策略的学习入口。
它把 发布状态、可见性、邀请制成员关系与前置课程依赖 串成了完整闸门。理解这一点,你就不会把在线课程系统误用成一个只能堆课件的文件夹。
DISCUSSION
评论区