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

相关推荐
云草桑8 天前
15分钟快速了解 Odoo
数据库·python·docker·postgresql·.net·odoo
山上春11 天前
Odoo 18 Web 客户端架构深度解析与 Navbar 差异化定制研究报告
odoo
山上春18 天前
ONLYOFFICE Odoo 集成架构深度解析与实战手册(odoo文件预览方案)
架构·odoo
odoo中国22 天前
如何在 Odoo 19 中创建日历视图
odoo·odoo19·odoo 视图开发·日历视图配置·alendar 标签使用·odoo 日程管理
odoo中国1 个月前
如何在 Odoo 19 中加载演示数据
xml·csv·odoo·odoo 19·odoo 演示数据加载
odoo中国1 个月前
Odoo 19 模块结构概述
开发语言·python·module·odoo·核心组件·py文件按
odoo中国1 个月前
如何在 Odoo 中从 XML 文件调用函数
xml·odoo·odoo开发·调用函数
odoo中国1 个月前
Odoo 19 中的基础视图有哪些?
odoo·odoo19·基础视图
曲幽1 个月前
Flask登录验证实战:从零构建一个基础的账号密码登录系统
python·flask·web·session·username·login
李怀瑾2 个月前
在Odoo18中实现多选下拉框搜索功能
odoo