Odoo | Module | 统计系统周期使用人数/当前在线人数

文内材料

GITHUB地址

前言介绍

Odoo作为开源ERP系统No.01,近年愈发的得到国内很多公司的关注。

虽然它的定位是中小型企业的ERP管理系统,但是在几年的Odoo开发实施过程中,有不足50人的小型企业,也有上万人的中大型企业。功能快速落地高度个性化扩展是它的核心特性,使用其他框架开发一个完整的页面可能需要1-2天,但在Odoo可能远超你的预期,在同等页面且不做翻译的前提下,成熟的Odoo开发工程师只需要 <0.5天的时间即可完成界面的主体开发(不包含各类赋值、处理逻辑)。

所以如果有ERP需求但是不想花费太多License费用的用户或者组织可以了解了解:Odoo

需求描述

返回正题,我们经常看见政府门户类网站或者一些访问量很大的公共网站,都会有一个当前在线人数的功能。

回到Odoo,原生并没有提供这样的数据统计方式或者功能,但是不要担心,毕竟Odoo是一个扩展十分方便的框架,我们可以通过现有的一些功能进行集成。

对于Odoo来说,有三种情况:

  1. 初次登录
  2. Session未过期,通过历史URL进入系统(无需登录)
  3. 网页打开但长时间未处理

源码阅读

  • 初次登录、Session未过期访问

    对于登录和已登录状态访问来说,如果验证成功会重定向回/web的route进行处理,并且最终会进入try内容,如果不发生错误,那么应该返回的是正常的网页内容+返回状态码200

    python 复制代码
    @http.route('/web', type='http', auth="none")
    def web_client(self, s_action=None, **kw):
        ensure_db()
        if not request.session.uid:
            return werkzeug.utils.redirect('/web/login', 303)
        if kw.get('redirect'):
            return werkzeug.utils.redirect(kw.get('redirect'), 303)
    
        request.uid = request.session.uid
        try:
            context = request.env['ir.http'].webclient_rendering_context()
            response = request.render('web.webclient_bootstrap', qcontext=context)
            response.headers['X-Frame-Options'] = 'DENY'
            return response
        except AccessError:
            return werkzeug.utils.redirect('/web/login?error=access')
  • 网页打开但长时间未处理

    初次登录、已登录访问可以通过web_client的扩展进行用户信息记录,但是如何检测用户还在使用网页,而不是使用完就关闭页面,也就是如何检测用户的在线情况:Longpolling

    我们可以通过新创建一个Module继承mail模块,以激活longpolling的定时轮询功能,轮询功能将定期的与服务器进行信息交互(交互方法如下),我们后续可以对其进行扩展:

    python 复制代码
    @route('/longpolling/poll', type="json", auth="public")
    def poll(self, channels, last, options=None):
        if options is None:
            options = {}
        if not dispatch:
            raise Exception("bus.Bus unavailable")
        if [c for c in channels if not isinstance(c, pycompat.string_types)]:
            raise Exception("bus.Bus only string channels are allowed.")
        if request.registry.in_test_mode():
            raise exceptions.UserError(_("bus.Bus not available in test mode"))
        return self._poll(request.db, channels, last, options)

集成操作

  • 操作内容
    1. 创建新模块,模块继承mail
    2. 集成登录controller、poll
    3. 提供用户访问信息记录表,必要时提供界面显示
  1. 创建新模块,继承mail

  2. 集成登录controller、poll

    python 复制代码
    # -*- coding: utf-8 -*-
    
    import odoo
    from odoo import http
    from odoo.http import request
    from odoo import exceptions, _
    from odoo.http import content_disposition, dispatch_rpc, request, \
        serialize_exception as _serialize_exception, route, Response
    from odoo.addons.bus.controllers.main import BusController
    from odoo.addons.web.controllers.main import Home
    
    
    class BusControllerInherit(BusController):
        # 存活检测 longpolling
        @route()
        def poll(self, channels, last, options=None):
            self.collection_current_users()
            res = super(BusControllerInherit, self).poll(channels, last, options)
            return res
        @staticmethod
        def collection_current_users():
            request_ip = request.httprequest.remote_addr
            request_db = request.httprequest.session.db
            request_user = request.httprequest.session.uid
            request_login = request.httprequest.session.login
    
            try:
                conn = odoo.sql_db.db_connect(request_db)
                with conn.cursor() as cr:
                    sql = """
                        insert into collection_user_info(request_ip, request_db, request_user, request_login, fast_login_time, latest_login_time)
                        values (%s, %s, %s, %s, now(), now())
                        on conflict (request_ip, request_db, request_user, request_login) do update set latest_login_time = now();
                    """
                    cr.execute(sql, (request_ip, request_db, request_user, request_login))
            except Exception as e:
                raise e
    
    class HomeInherit(Home):
        # 记录登录或者session存在时自动登录的情况
        @http.route()
        def web_client(self, s_action=None, **kw):
            res = super(HomeInherit, self).web_client(s_action, **kw)
            if isinstance(res, Response) and res.status_code == 200:
                BusControllerInherit.collection_current_users()
            return res
  3. 提供用户访问信息记录表,必要时提供界面显示

    具体代码不展示了,直接放图吧,因为局域网的关系,访问数据不是很多,大家可以自行下载模块安装测试 GITHUB工程地址

🎉如果对你有所帮助,可以点赞、关注、收藏起来,不然下次就找不到了🎉

【点赞】⭐️⭐️⭐️⭐️⭐️

【关注】⭐️⭐️⭐️⭐️⭐️

【收藏】⭐️⭐️⭐️⭐️⭐️

Thanks for watching.

--Kenny

相关推荐
odoo中国8 天前
Odoo 19 财务功能概述:财务模块中的定期存货计价(期末库存结转)
odoo·库存管理·财务管理·odoo19·库存计价·库存估值·期末库存结转
odoo中国10 天前
Odoo 19 库存功能实操:产品包装的设置与管理
odoo·仓库管理·odoo19·包装设置与管理
云草桑10 天前
Odoo 19.0 Docker Desktop快速部署 和Ubuntu24上安装1panel面板
运维·docker·容器·odoo
odoo中国15 天前
Odoo 19 采购功能:如何创建与管理产品类别,实现更智能的采购
odoo·odoo19·产品类别·采购类别·产品类别配置
Odoo老杨20 天前
成长型企业 ERP 系统选型:SAP 与 Odoo 免费开源 ERP 全面对比
sap·odoo·erp·中小企业数字化
linjun1863492 个月前
Odoo MTO 和智能MTO 完全解读:从源码到实战
odoo
云草桑2 个月前
15分钟快速了解 Odoo
数据库·python·docker·postgresql·.net·odoo
山上春2 个月前
Odoo 18 Web 客户端架构深度解析与 Navbar 差异化定制研究报告
odoo
山上春3 个月前
ONLYOFFICE Odoo 集成架构深度解析与实战手册(odoo文件预览方案)
架构·odoo
odoo中国3 个月前
如何在 Odoo 19 中创建日历视图
odoo·odoo19·odoo 视图开发·日历视图配置·alendar 标签使用·odoo 日程管理