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

    @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的定时轮询功能,轮询功能将定期的与服务器进行信息交互(交互方法如下),我们后续可以对其进行扩展:

    @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

    # -*- 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/298821.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

即时设计:设计流程图,让您的设计稿更具条理和逻辑

流程图小助手 在设计工作中,流程图是一种重要的工具,它可以帮助设计师清晰地展示设计思路和流程,提升设计的条理性和逻辑性。今天,我们要向您推荐一款强大的设计工具,它可以帮助您轻松为设计稿设计流程图,让…

c#调试程序一次启动两个工程(多个工程)

概述 c# - Visual Studio : debug multiple projects at the same time? 以在解决方案中设置多个启动项目(右键单击解决方案,转到设置启动项目,选择多个启动项目),并为包含在解决方案(无、开始、不调试就开始)。如果您将多个项目设置为开始…

IDEA TODO

今天记录一个 IDEA 工具的小技巧, TODO。比如下班前有一个小功能没完善好,此时可以在响应代码上加上 TODO 注解, //密码比对 // TODO 后期需要进行md5加密,然后再进行比对 password DigestUtils.md5DigestAsHex(password.getByt…

Jenkins修改全局maven配置后不生效解决办法、以及任务读取不同的settings.xml文件配置

一、修改Global Tool Configuration的maven配置不生效 说明:搭建好jenkins后,修改了全局的settings.xml,导致读取settings一直是之前配置的。 解决办法一 Jenkins在创建工作任务时,会读取当前配置文件内容,固定在这…

【Leetcode】230. 二叉搜索树中第K小的元素

一、题目 1、题目描述 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。 示例1: 输入:root = [3,1,4,null,2], k = 1 输出:1示例2: 输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3提示: 树中…

关于CNN卷积神经网络与Conv2D标准卷积的重要概念

温故而知新,可以为师矣! 一、参考资料 深入解读卷积网络的工作原理(附实现代码) 深入解读反卷积网络(附实现代码) Wavelet U-net进行微光图像处理 卷积知识点 CNN网络的设计论:NAS vs Handcra…

【数据库】视图索引执行计划多表查询面试题

文章目录 一、视图1.1 概念1.2 视图与数据表的区别1.3 优点1.4 语法1.5 实例 二、索引2.1 什么是索引2.2.为什么要使用索引2.3 优缺点2.4 何时不使用索引2.5 索引何时失效2.6 索引分类2.6.1.普通索引2.6.2.唯一索引2.6.3.主键索引2.6.4.组合索引2.6.5.全文索引 三、执行计划3.1…

【leetcode】字符串中的第一个唯一字符

题目描述 给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。 用例 示例 1: 输入: s “leetcode” 输出: 0 示例 2: 输入: s “loveleetcode” 输出: 2 示例 3: 输入: s “aabb”…

【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax类图

【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax概述 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax快速入门 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax类图 【大数据进阶第三阶段之Datax学习笔记】使用…

FineBI:简介

1 介绍 FineBI 是帆软软件有限公司推出的一款商业智能(Business Intelligence)产品。 FineBI 是定位于自助大数据分析的 BI 工具,能够帮助企业的业务人员和数据分析师,开展以问题导向的探索式分析。 2 现阶段数据分析弊端 现阶…

系列七、Typora安装 配置

一、安装 1.1、下载安装包 我分享的链接: 链接:https://pan.baidu.com/s/1K5DjV_xhCH5WGiiEHlNQVQ?pwdyyds 提取码:yyds 1.2、安装 无脑下一步,下一步即可。 二、Typora中设置插入的图片左对齐 2.1、背景 往Typora中插入图…

开启Android学习之旅-4-Android集成FontAwesome

FontAwesome 是一个非常标准、统一风格的图标库。产品经理在原型中应用了很多图标都是FontAwesome。正常流程是 UI 需要再手工绘制或在 iconfont 或 iconpark 网站挨个找,如果在 Android 直接使用不是省了一步(注意版权问题,使用免费版&#…

echart图表

首先我们要知道ECharts是什么,它是怎么用的? ECharts是一个使用JavaScript实现的开源可视化库,它涵盖各行业图表,满足各种需求。它提供了丰富的图表类型和交互能力,使用户能够通过国简单的配置生成各种各样的图表,包括…

解决“SQLServer 添加数据库,报Error 5118“错误

当将把一个SQLServer的数据库文件*.MDF和日志文件*.LDF,从电脑A拷贝到电脑B,然后在电脑B上,使用Microsoft SQL Server Management Studio添加该*.MDF文件,有时报"Error 5118"错误,如图(1)所示: 图…

Kettle Local引擎使用记录(基于Kettle web版数据集成开源工具data-integration源码)

Kettle Web 📚第一章 前言📚第二章 demo源码📗pom.xml引入Kettle引擎核心文件📗java源码📕 controller📕 service📕 其它📕 maven settings.xml 📗测试📕 测试…

Vercel自动部署实战:零基础实操指南

🌟🌌 欢迎来到知识与创意的殿堂 — 远见阁小民的世界!🚀 🌟🧭 在这里,我们一起探索技术的奥秘,一起在知识的海洋中遨游。 🌟🧭 在这里,每个错误都…

Spring Boot实现数据加密脱敏:注解 + 反射 + AOP

文章目录 1. 引言2. 数据加密和脱敏的需求3. Spring Boot项目初始化4. 敏感数据加密注解设计5. 实现加密和脱敏的工具类6. 实体类和加密脱敏注解的使用7. 利用AOP实现加密和脱敏8. 完善AOP切面9. 测试10. 拓展功能与未来展望10.1 加密算法的选择10.2 动态注解配置 11. 总结 &am…

数据结构:树详解

创建二叉树 给出了完整的先序遍历序列,子树为空用’#’表示,所以这样我们在通过先序遍历序列创建二叉树时我们直到先序遍历序列是先进行根结点,然后左子树最后右子树的顺序进行遍历的,所以对于完整的先序遍历序列我们可以直到先序…

SCADE—产品级安全关键系统的MBD开发套件

产品概述 随着新能源三电、智能驾驶等新技术的应用,汽车中衍生出很多安全关键零部件,如BMS、VCU、MCU、ADAS等,相应的软件在汽车中的比重越来越大,并且安全性、可靠性要求也越来越高。ANSYS主要针对安全关键零部件的嵌入式产品级软…

【Redis】非关系型数据库之Redis的介绍及安装配置

目录 前言 一、关系型数据库与非关系型数据库 1.1关系型数据库 1.2非关系型数据库 1.3两者的区别 1.4非关系型数据库产生的背景 1.5总结 二、Redis介绍 2.1Redis是什么 2.2Redis的优点 2.3Redis的使用场景 2.4那些数据适合放在缓存中 2.5Redis为什么那么快&#xf…