Ruoyi-Vue 3.8.7集成积木报表JmReport和积木大屏JimuBI

news2025/2/22 4:58:03

Ruoyi-Vue 3.8.7集成积木报表JmReport和积木大屏JimuBI

一、版本

RuoYi-Vue版本:v3.8.7

JMreport报表版本: v1.9.4

JimuBI大屏版本:V1.9.4

二、数据库

积木数据库sql

下载后,使用数据库管理工具执行sql脚本,将需要的一些表导入进去。

三、Pom中引入积木报表最新依赖

打开ruoyi-admin下的pom.xml引入最新依赖

        <!-- 积木报表 -->
        <dependency>
            <groupId>org.jeecgframework.jimureport</groupId>
            <artifactId>jimureport-spring-boot-starter</artifactId>
            <version>1.9.4</version>
        </dependency>
        <!--积木BI大屏-->
        <dependency>
            <groupId>org.jeecgframework.jimureport</groupId>
            <artifactId>jimubi-spring-boot-starter</artifactId>
            <version>1.9.4</version>
        </dependency>

四、RuoYiApplication添加积木报表扫描文件

打开ruoyi-admin模块中的RuoYiApplication文件

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class },scanBasePackages = {"org.jeecg","com.ruoyi"})

五、配置序列化白名单

打开ruoyi-common模块中Constants文件,修改161行

public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi", "org.jeecg.modules.drag" };

六、SecurityConfig拦截排除

在ruoyi-framework模块中,打开SecurityConfig文件

  1. 添加代码

    .antMatchers("/jmreport/**","/drag/**","/jimubi/**").anonymous()
    
  2. 禁用Https响应

    // 禁用HTTP响应标头
    .headers().frameOptions().disable();
    

    Snipaste_2025-02-20_13-39-46

七、后端创建Controller文件

在ruoyi-admin模块中,创建src/main/java/com/ruoyi/web/controller/tool/reportController.java文件。这个controller目的向前端返回积木的前半部分地址,在前端拼接上后关部分地址。

Snipaste_2025-02-20_13-42-18

代码如下:

package com.ruoyi.web.controller.tool;
 
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.utils.ip.IpUtils;
import org.springframework.core.env.Environment;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
 
@Anonymous
@RestController
@RequestMapping("/tool/jm")
public class ReportController {
 
    @Autowired
    Environment environment;
 
    //报表设计
    @PreAuthorize("@ss.hasPermi('tool:report:list')")
    @GetMapping(value = "/reportList")
    public String ReportList(){
        return "http://" + IpUtils.getHostIp() + ":" + environment.getProperty("server.port") + "/jmreport/list";
    }
 
    //报表查看
    @GetMapping(value = "/reportView")
    public String ReportView(){
        return "http://" + IpUtils.getHostIp() + ":" + environment.getProperty("server.port") + "/jmreport/view";
    }
 
    //报表查看
    @GetMapping(value = "/biList")
    public String bi(){
        return "http://" + IpUtils.getHostIp() + ":" + environment.getProperty("server.port") + "/drag/list";
    }
 
    //报表查看
    @GetMapping(value = "/biView")
    public String biView(){
        return "http://" + IpUtils.getHostIp() + ":" + environment.getProperty("server.port") + "/drag/share/view";
    }
}

八、前端文件(Vue2)创建

  1. 创建src/api/tool/jimu.js文件,代码如下:

    import request from '@/utils/request'
    
    
    export function getReportUrl() {
      return request({
        url: '/tool/jm/reportList',
        method: 'get'
      })
    }
    export function getReportViewUrl() {
      return request({
        url: '/tool/jm/reportView',
        method: 'get'
      })
    }
    export function getBiUrl() {
      return request({
        url: '/tool/jm/biList',
        method: 'get'
      })
    }
    export function getBiViewUrl() {
      return request({
        url: '/tool/jm/biView',
        method: 'get'
      })
    }
    
  2. 创建src/views/tool/report/reportList.vue文件

    <template>
      <!-- 组件名按照 Vue 2 习惯一般首字母大写,当然小写也能用 -->
      <IFrame :src="url" />
    </template>
    
    <script>
    // 导入获取 token 的工具函数
    import { getToken } from '@/utils/auth';
    // 导入获取报表 URL 的 API 函数
    import { getReportUrl } from '@/api/tool/jimu';
    // 导入自定义的 IFrame 组件
    import IFrame from "@/components/iFrame/index.vue";
    
    export default {
      // 组件名称
      name: 'ReportDesign',
      // 注册子组件
      components: {
        IFrame
      },
      // 定义组件的数据
      data() {
        return {
          // 初始化 url 为空字符串
          url: ''
        };
      },
      // 生命周期钩子,在实例创建完成后立即调用
      created() {
        this.init();
      },
      // 定义组件的方法
      methods: {
        init() {
          getReportUrl()
            .then((res) => {
              // 将获取到的 URL 拼接上 token 并赋值给 data 中的 url
              this.url = res + "?token=Bearer " + getToken();
            })
            .catch((error) => {
              // 处理接口调用失败的情况
              console.error('获取报表 URL 失败:', error);
              // 你可以在这里添加更多错误处理逻辑,比如显示错误提示给用户
            });
        }
      }
    };
    </script>
    
  3. 创建src/views/tool/report/reportView.vue文件

    <template>
      <!-- 按照 Vue 组件命名规范,建议组件名首字母大写 -->
      <IFrame :src="url" />
    </template>
    
    <script>
    // 导入获取 token 的工具函数
    import { getToken } from '@/utils/auth';
    // 导入获取报表视图 URL 的 API 函数
    import { getReportViewUrl } from '@/api/tool/jimu';
    // 导入自定义的 IFrame 组件
    import IFrame from "@/components/iFrame/index.vue";
    
    export default {
      // 组件名称
      name: 'ReportView',
      // 注册子组件
      components: {
        IFrame
      },
      // 定义组件的数据
      data() {
        return {
          // 初始化 url 为空字符串
          url: ''
        };
      },
      // 生命周期钩子,在实例创建完成后立即调用
      created() {
        this.init();
      },
      // 定义组件的方法
      methods: {
        init() {
          getReportViewUrl()
            .then((res) => {
              // 从路由路径中提取 reportId
              const reportId = this.$route.path.substring(this.$route.path.lastIndexOf("/") + 1);
              // 拼接 URL、reportId 和 token 并赋值给 url
              this.url = res + "/" + reportId + "?token=Bearer " + getToken();
            })
            .catch((error) => {
              // 处理接口调用失败的情况
              console.error('获取报表视图 URL 失败:', error);
              // 可以添加更多错误处理逻辑,如显示错误提示信息给用户
            });
        }
      }
    };
    </script>
    
  4. 创建src/views/tool/report/biList.vue文件

    <template>
      <i-frame :src="url" />
    </template>
    
    <script>
    import { getToken } from '@/utils/auth';
    import { getBiUrl } from '@/api/tool/jimu';
    import IFrame from "@/components/iFrame/index.vue";
    
    export default {
      name: 'ReportDesign',
      components: {
        IFrame
      },
      data() {
        return {
          url: ''
        };
      },
      created() {
        this.init();
      },
      methods: {
        init() {
          getBiUrl()
            .then(res => {
              this.url = res + "?token=Bearer " + getToken();
            })
            .catch(error => {
              console.error('获取 BI URL 失败:', error);
              // 可以添加更详细的错误处理逻辑,如显示错误提示信息
            });
        }
      }
    };
    </script>
    
    1. 创建src/views/tool/report/biView.vue文件
    <template>
      <!-- 建议使用大写开头的组件名,遵循 Vue 组件命名规范 -->
      <IFrame :src="url" />
    </template>
    
    <script>
    // 导入获取 token 的工具函数
    import { getToken } from '@/utils/auth';
    // 导入获取 BI 视图 URL 的 API 函数
    import { getBiViewUrl } from '@/api/tool/jimu';
    // 导入自定义的 IFrame 组件
    import IFrame from "@/components/iFrame/index.vue";
    
    export default {
      // 组件名称
      name: 'ReportView',
      // 注册子组件
      components: {
        IFrame
      },
      // 定义组件的数据
      data() {
        return {
          // 初始化 url 为空字符串
          url: ''
        };
      },
      // 生命周期钩子,在实例创建完成后立即调用
      created() {
        this.init();
      },
      // 定义组件的方法
      methods: {
        init() {
          getBiViewUrl()
            .then((res) => {
              // 从路由路径中提取 reportId
              const reportId = this.$route.path.substring(this.$route.path.lastIndexOf("/") + 1);
              // 将获取到的 URL 拼接上 reportId 和 token 并赋值给 data 中的 url
              this.url = res + "/" + reportId + "?token=Bearer " + getToken();
            })
            .catch((error) => {
              // 处理接口调用失败的情况
              console.error('获取 BI 视图 URL 失败:', error);
              // 可以在这里添加更多错误处理逻辑,例如显示错误提示给用户
            });
        }
      }
    };
    </script>
    

九、后台创建菜单

  1. 创建积木报表首页导航菜单,如果你是按第七步中的文件名创建的前端文件,请按下图创建导航菜单,否则,根据实际的组件修改。权限字符,可以自定义。

Snipaste_2025-02-20_13-50-40

  1. 创建Bi报表

Snipaste_2025-02-20_13-51-00

十、创建报表或大屏

在此以创建报表为例

1、预览创建好的积木报表,在地址栏中,找到报表的ID号,如下图中的

引用图片1

2、在ruoyi系统中创建导航菜单

1)路由地址中,要加入报表的ID号

2)组件路径,填写用于显示报表的组件。可以查看第七步 创建src/views/tool/report/reportView.vue文件

3)权限字符中,也加入了报表ID号,用于权限控制

引用图片2

十一、问题

集成后,登录ruoyi系统提示如下错误:

No qualifying bean of type 'org.springframework.context.MessageSource' available: expected single matching bean but found 2: messageSource,jmMessageSource

解决方法:
找到src/main/java/com/ruoyi/common/utils/MessageUtils.java

修改获取bean为通过名字获取项目指定bean

MessageSource messageSource = SpringUtils.getBean("messageSource");

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亲测可用,IDEA中使用满血版DeepSeek R1!支持深度思考!免费!免配置!

作者&#xff1a;程序员 Hollis 之前介绍过在IDEA中使用DeepSeek的方案&#xff0c;但是很多人表示还是用的不够爽&#xff0c;比如用CodeChat的方案&#xff0c;只支持V3版本&#xff0c;不支持带推理的R1。想要配置R1的话有特别的麻烦。 那么&#xff0c;今天&#xff0c;给…

jvm中各个参数的理解

MEMORY - MANAGERS 定义 MEMORY - MANAGERS即内存管理器&#xff0c;它是操作系统或软件系统中负责管理计算机内存资源的组件。从本质上来说&#xff0c;它是一种软件机制&#xff0c;旨在协调计算机系统中内存的分配、使用和回收等操作&#xff0c;确保系统能够高效、稳定地…

【队列】循环队列(Circular Queue)详解

文章目录 一、循环队列简介二、循环队列的判空和判满三、循环队列的实现leetcode 622. 设计循环队列 一、循环队列简介 在实际开发中&#xff0c;队列是一种常用的数据结构&#xff0c;而循环队列&#xff08;Circular Queue&#xff09;则一般是一种基于数组实现的队列&#x…

DeepSeek掀起推理服务器新风暴,AI应用迎来变革转折点?

AI 浪潮下&#xff0c;推理服务器崭露头角 在科技飞速发展的当下&#xff0c;AI 是耀眼明星&#xff0c;席卷各行业&#xff0c;深刻改变生活与工作模式&#xff0c;从语音助手到医疗诊断、金融风险预测&#xff0c;AI 无处不在。其发展分数据收集整理、模型训练、推理应用三个…

Vue 项目中逐步引入 TypeScript 的类型检查

在现有的 Vue 项目中逐步引入 TypeScript 的类型检查 本文源于一道面试题&#xff1a;注&#xff1a;两种问法一个意思哈&#xff01;&#xff01; 问题一&#xff1a;“ 老项目Js写的&#xff0c;如何轻量方式享受 ts 类型&#xff1f;” 问题二&#xff1a;“如何 在现有的 …

Git企业开发

Git&#xff08;版本控制器&#xff09; 在我们对于文档进行操作的时候&#xff0c;很多时候可能会出现多个文档&#xff0c;对这些文档进行多个版本的保存和记录就变成必要的。通俗的讲&#xff0c;就是记录每次的修改和记录版本迭代的管理系统。目前最主流的版本控制器就是G…

DeepSeek预测25考研分数线

25考研分数马上要出了。 目前&#xff0c;多所大学已经陆续给出了分数查分时间&#xff0c;综合往年情况来看&#xff0c;每年的查分时间一般集中在2月底。 等待出成绩的日子&#xff0c;学子们的心情是万分焦急&#xff0c;小编用最近爆火的“活人感”十足的DeepSeek帮大家预…

基于springboot校园健康系统的设计与实现(源码+文档)

大家好我是风歌&#xff0c;今天要和大家聊的是一款基于springboot的园健康系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于springboot校园健康系统的设计与实现的主要使用者管理员具有最高的权限&#xff0c;通…

【YOLOv8】损失函数

学习视频&#xff1a; yolov8 | 损失函数 之 5、类别损失_哔哩哔哩_bilibili yolov8 | 损失函数 之 6、定位损失 CIoU DFL_哔哩哔哩_bilibili 2.13、yolov8损失函数_哔哩哔哩_bilibili YOLOv8 的损失函数由类别损失和定位损失构成 类别损失&#xff1a;BCE Loss 定位损失…

【Linux】【网络】Libevent 内部实现简略版

【Linux】【网络】Libevent 内部实现简略版 1 event_base结构–>相当于Reactor 在使用libevent之前&#xff0c;就必须先创建这个结构。 以epoll为例&#xff1a; 1.1evbase void* evbase-->epollop结构体&#xff08;以epoll为例&#xff09; libevent通过一个void…

计算机网络抄手 运输层

一、运输层协议概述 1. 进程之间的通信 从通信和信息处理的角度看&#xff0c;运输层向它上面的应用层提供通信服务&#xff0c;它属于面向通信部分的最高层&#xff0c;同时也是用户功能中的最低层。当网络边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时&…

MATLAB图像处理:图像分割方法

图像分割将图像划分为具有特定意义的子区域&#xff0c;是目标检测、医学影像分析、自动驾驶等领域的核心预处理步骤。本文讲解阈值分割、边缘检测、区域生长、聚类分割、基于图的方法等经典与前沿技术&#xff0c;提供MATLAB代码实现。 目录 1. 图像分割基础 2. 经典分割方…

【VSCode】MicroPython环境配置

【VSCode】MicroPython环境配置 RT-Thread MicroPython 插件安装MicroPython 库文件配置结束语 RT-Thread MicroPython 插件安装 在 VSCode 拓展中搜索 “RT-Thread MicroPython” 并安装&#xff0c;详细配置步骤&#xff08;修改 VSCode 默认终端、MicroPython 代码补全&…

【python】网页批量转PDF

安装wkhtmltopdf 网站&#xff1a;wkhtmltopdf wkhtmltopdf http://www.baidu.com/ D:website1.pdf 安装pdfkit库 pip install pdfkit 批量转换代码 import os import pdfkit path_wkthmltopdf rE:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe config pdfkit.configu…

基于Flask的租房信息可视化系统的设计与实现

【Flask】基于Flask的租房信息可视化系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网的快速发展&#xff0c;租房市场日益繁荣&#xff0c;信息量急剧增加&#xff…

Scrapy安装,创建Scrapy项目,启动Scrapy爬虫

Scrapy安装&#xff0c;创建Scrapy项目&#xff0c;启动Scrapy爬虫 1. 安装 Python2. 安装 Scrapy3. 验证安装4. 创建 Scrapy 项目5. 启动爬虫5.1 示例 总结 Scrapy 的安装方式比较简单&#xff0c;下面是基于 Python 环境的安装流程&#xff1a; 1. 安装 Python 首先&#x…

C++项目:高并发内存池_上

目录 1. 项目介绍 2. 内存池概念 2.1 池化技术 2.2 内存池和内存碎片 2.3 细看malloc 3. 定长内存池的实现 ObjectPool.hpp 4. 高并发内存池框架 5. thread cache测试 5.1 thread cache框架 5.2 ConcurrentAlloc.hpp 6. central cache测试 6.1 central cache框架 …

手机控制电脑远程关机

远程看看软件兼容iOS和Android设备&#xff0c;该软件除了能通过电脑远程关闭另一台电脑外&#xff0c;您还可以通过它在手机上远程关闭公司的电脑。您可以按照以下步骤进行操作以实现电脑远程关机&#xff1a; 步骤1.在手机应用商店搜索“远程看看”进行软件安装&#xff0c;…

IO模型与NIO基础--NIO网络传输选择器--字符编码

放进NIO体系进行网络编程的工作流程&#xff1a; Selector的创建 通过调用Selector.open()方法创建一个Selector&#xff0c;如下&#xff1a; Selector selector Selector.open(); 向Selector注册通道 通过Channel.register()方法来实现&#xff0c; 注意&#xff1a;Chan…

【亚马逊开发者账号02】终审问题SA+review_Pre-review+Doc.xlsx

1.终审问题 你好感谢您在此过程中的回复和协作。所有想要构建具有受限 SP-API 角色的公开可用应用程序的开发人员都必须与我们的解决方案架构师团队一起完成架构审核。 这将需要详细说明应用程序的数据流、个人身份信息 &#xff08;PII&#xff09; 的数据保护控制&#xff0…