第二十六章 仪表盘

篇别:第三篇 数据库与数据管理

本章学习目标

  • 能使用 ir.actions.client 挂载 OWL 客户端动作,搭建自定义 Dashboard
  • 理解 RPC(orm / rpc 服务) 在仪表盘中的典型用法与 权限边界
  • 了解 Odoo Spreadsheet模型数据 / 透视 的联动思路及限制。
  • 能设计 缓存、刷新策略,避免每次打开仪表盘都全量重算。

导读:从「列表」到「一屏总览」

业务用户每天打开多个菜单逐个点开,效率低。仪表盘KPI、图表、快捷入口 聚合在一个 客户端动作 页面中。实现上,后端仍通过 ORM 读数据;前端用 OWL 渲染卡片与图表。与 标准看板 不同:仪表盘往往 跨模型强定制,且常需要 定时刷新或短期缓存


26.1 Dashboard 开发

26.1.1 知识要点

  • ir.actions.clienttag 指向已在 registry 注册的 客户端动作组件(如 my_module.Dashboard);可选 params 传入初始配置。
  • 挂载位置:通过 菜单 action="..." 打开;也可由 其他动作 跳转(需熟悉 doAction 等前端 API)。
  • 数据加载:在组件 onWillStart / useService("orm") 中调用 search_readread_group;注意 大数据量 时应 limitdomain只取必要字段
  • 权限:ORM 调用使用 当前用户环境记录规则ACL 同样生效;勿在仪表盘里用 sudo() 扩大范围除非有 充分审计与控制
  • 缓存:可在 Service组件 state 中保存 上次拉取时间,例如 5 分钟内复用;或依赖 Bus 在业务写入后 失效缓存(进阶)。

26.1.2 案例

1)注册客户端动作组件(节选)

/** @odoo-module **/
import { registry } from "@web/core/registry";
import { Component, onWillStart, useState } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";

class LibraryDashboard extends Component {
    static template = "my_library.LibraryDashboard";
    static props = ["*"];

    setup() {
        this.orm = useService("orm");
        this.state = useState({ weekLoans: 0, loading: true });
        onWillStart(async () => {
            // 本周起始:建议用 luxon/dayjs 或后端 helper;此处用占位日期演示
            const start = "2026-01-01 00:00:00";
            const count = await this.orm.searchCount("library.loan", [
                ["create_date", ">=", start],
            ]);
            this.state.weekLoans = count;
            this.state.loading = false;
        });
    }
}

registry.category("actions").add("my_library_dashboard", LibraryDashboard);

2)XML 动作与菜单

<record id="action_library_dashboard" model="ir.actions.client">
    <field name="name">借阅仪表盘</field>
    <field name="tag">my_library_dashboard</field>
</record>

<menuitem id="menu_library_dashboard" name="仪表盘" parent="menu_library_root" action="action_library_dashboard"/>

3)QWeb 模板(示意):大数字卡片 + t-if="!state.loading" 展示 weekLoans

26.1.3 截图占位

图 26-1 自定义仪表盘:本周借阅 KPI

26.1.4 本节练习

  1. 实操:在仪表盘上展示 「本周新增借阅数」 大数字卡片(可用 search_count)。
  2. 简答:为何不建议在仪表盘 ORM 调用中随意 sudo()
  3. 判断:客户端动作中的数据请求 绕过 ir.rule。( )

参考答案提示:2. 易泄露跨公司/跨部门数据。3. 错,仍走当前用户(除非代码显式 sudo)。


26.2 Spreadsheet 集成(新增)

26.2.1 知识要点

  • 定位:Odoo Spreadsheet表格、公式、图表业务数据 结合;部分能力依赖 企业应用 或许可,实施前核对 版本说明
  • 数据源:可将 透视表、列表导出、专用数据连接器(以文档为准)作为数据源;公式能力 非完整 Excel,需 在文档中确认函数集
  • 权限:Spreadsheet 中看到的行仍受 ORM 权限 约束;共享链接 / 导出 可能带来 合规风险,需 组与记录规则 配套。
  • 与 Dashboard 关系:仪表盘可 嵌入链接 到 Spreadsheet;也可 分列菜单——仪表盘偏 实时 KPI,表格偏 分析员自助探索

26.2.2 案例

选型对比(简表)

维度 Spreadsheet 内分析 导出 Excel
实时性 可刷新数据源 静态文件
协作 Odoo 内共享 靠邮件/网盘
公式 受平台限制 Excel 全量

26.2.3 截图占位

图 26-2 Spreadsheet 中插入模型/透视数据

26.2.4 本节练习

  1. 简答:Spreadsheet 与 Pivot 视图导出 Excel协作与刷新 上各有什么优劣?
  2. 拓展:列出一种 不适合 放进 Spreadsheet 的 敏感字段类型 及处理方式。

参考答案提示:2. 如 薪资、密钥——应用 字段级权限独立报表服务


26.3 经典 Board 与多视图拼盘(补充)

26.3.1 知识要点

  • 旧式 board.board 模型可将 多个 ir.actions.act_window 子视图 拼在一屏;在 Odoo 19 中部分场景仍可见,但 新项目更推荐 OWL 客户端动作 以获得 统一技术栈与可测性
  • 若维护老模块:勿混用 两套仪表盘方案于同一菜单层级,避免用户困惑。

26.3.2 本节练习

  1. 简答:何时仍值得保留 board 而非重写 OWL?(例如:极短交付、零前端人力。)

本章综合练习

  1. 设计:仪表盘 缓存 5 分钟 的聚合策略:说明 缓存键(用户?公司?)、失效时机
  2. 权限:证明「仪表盘数据 仍受 记录规则约束」——举一个 domain 例子。
  3. 综合:同一 KPI「本月销售额」在 仪表盘卡片会计透视 中数值不一致时,列出 三条 排查方向(时区、状态筛选、多公司)。
  4. 实操:为仪表盘增加 手动刷新 按钮,清空缓存并重新 search_read

本章对应白皮书目录:第二十六章 仪表盘。