很多人看到 HR Gantt,会以为它只是在通用 Gantt 上多放了个员工头像。但企业版 hr_gantt 的改动更有意思:它既改了行头表达,又改了时间 pill 在周/月尺度下的显示语义。
一、它不是另起炉灶,而是基于通用 GanttRenderer 做定向覆盖
hr_gantt_view.js 直接把 Renderer 换成 HrGanttRenderer,说明 HR Gantt 的策略不是重写整套 Gantt,而是在通用能力上加人力场景特化。这种做法很 Odoo:尽量复用基础视图,只覆盖真正与业务有关的部分。
二、员工头像不是装饰,而是行语义增强
processRow() 会在按 employee_id 分组、且存在 resId 时,构造 rowsWithAvatar,把 relation 特判成 hr.employee.public 或其他模型。XML 模板里则在 row header 处优先渲染 Avatar。
这意味着头像不是简单多塞一个图片标签,而是把“这一行代表哪种员工实体”先在 renderer 层算好,再交给模板做呈现。
三、真正有价值的改动在 getPill()
getPill() 的 override 处理了一个很细但很人类化的问题:当班次在周/月视图中正好跨两个半天时,默认柱块可能会看起来像占满整天。源码通过 11:00~14:00 这个午休判断,把 pill 适当向上午或下午偏移,避免上午班/下午班被误读为全天班。
这是一种非常典型的“业务语义修正前端几何”的做法:
- 时间轴几何上看,它跨了两个半格;
- 排班语义上看,它其实只是上午或下午班;
- renderer 需要主动把这种语义差异修正出来。
四、新手误区
1. 以为 HR Gantt 只是多一个 avatar 组件
源码里最重要的改动其实是 pill 位置修正,而不是头像。
2. 以为 Gantt 视图的柱块显示只由原始开始结束时间决定
在特定业务场景里,renderer 还会加入额外的人类语义判断。
3. 以为行头模板替换很简单
它依赖 renderer 先准备好 rowsWithAvatar 这类派生状态。
五、实战注意事项
- 做 HR 视图定制时,优先扩 renderer,不要急着魔改基础 Gantt;
- 周/月尺度下的视觉误导最容易出事故,测试要覆盖半天班次;
- 员工模型若有 public/private 差异,头像 relation 处理别偷懒;
- 如果要继续扩班次视觉语义,最好沿着
getPill()这一层做,而不是事后改 CSS 硬修。
结语
HR Gantt 真正体现的,不是“界面更漂亮”,而是把排班业务语义精确地注入通用 Gantt 渲染器里。理解了这一层,就会知道企业版前端很多价值都藏在这种小而关键的 renderer override 里。
DISCUSSION
评论区