很多企业第一次看招聘平台集成,会以为这只是“把职位描述推送出去”。但 enterprise/hr_recruitment_integration_base/models/hr_job.py 与 hr_job_post.py 明确表明:Odoo 真正在管理的是一个持续存在的 job post 业务对象,而不是一次性的 API 调用。
一、发布入口是 wizard,不是直接调用平台 API
hr_job.py 的 action_post_job() 只是打开 hr.recruitment.post.job.wizard。这说明官方设计思路是:职位本身是内部对象,真正对外发布前还要补平台、申请方式、开始/结束日期、外显内容等参数。
因此,“发布职位”这件事被拆成了两层:
hr.job负责企业自己的招聘岗位;hr.job.post负责这个岗位在外部平台上的一次发布活动。
这层拆分很值钱,因为一个岗位完全可能同时投多个平台,甚至在不同平台上使用不同联络方式。
二、job post 代表的是一段 campaign 生命周期
hr_job_post.py 的 action_post_now() 会写入 campaign_start_date 并调用 _start_new_campaign();action_stop_campaign() 则写入 campaign_end_date 再调用 _stop_finished_campaign()。而 _start_new_campaign() / _stop_finished_campaign() 都是批量找待启动、待结束的 post,再通过 wizard 或 _delete_post() 处理。
这意味着外部招聘发布并不是“同步一次就完成”,而是有开始、持续、结束三个阶段。平台帖子是否在线、是否过期、是否该删除,系统都当成长期状态来管。
三、更新不是覆盖写,而是重新走发布 wizard
action_update_job_post() 会新建一个 post wizard,把当前 post 的平台、日期、内容、联系方式、API 数据一并塞进去,再调用 post_wizard.action_post_job()。这说明“更新岗位帖子”的本质不是直接改数据库字段,而是重新执行一次发布链路。
这么设计有两个好处:
- 更新逻辑与首次发布共享同一套校验和平台适配层;
- 每次更新都能留下明确痕迹,而不是悄悄把一条历史发布改掉。
四、日志不是锦上添花,而是跨平台排错的关键证据
create() 创建 post 后立刻 _log_post_modifications();日志里会记录平台、岗位、状态、状态消息、申请方式、联络点、起止日期等信息。企业在多平台招聘时最怕一句话:“我们记得好像发过。”而 message_post() 正是在把这种模糊记忆变成可追踪证据。
一旦某个平台返回状态异常,或者岗位内容被人修改过,chatter 日志就是 HR 与管理员排查的第一现场。
五、实战注意事项
- 把岗位和岗位发布分开管理:岗位是内部主数据,发布是外部 campaign。
- 定义好 apply vector:
_contact_point_to_vector()说明邮箱、链接等联系方式会影响平台侧行为,不要混着填。 - 给发布设置结束日期:否则帖子会长期悬挂,影响候选人体验和品牌可信度。
- 保留日志,不要只看平台结果:Odoo 里的 post chatter 往往比第三方平台后台更容易回溯完整上下文。
新手误区
- 误以为一个岗位只对应一个外部帖子。
- 误以为更新帖子就是改一段 HTML。
- 误以为结束招聘只要在外部平台手工下线。
- 误以为日志只是通知信息,不是正式运维证据。
主要源码参考
enterprise/hr_recruitment_integration_base/models/hr_job.pyenterprise/hr_recruitment_integration_base/models/hr_job_post.py
DISCUSSION
评论区