资讯动态

若依集成积木报表与大屏:SSO鉴权与权限治理实战

发布时间:2026/10/14 10:23:18 来源:尧图企业网站定制
简介若依前后端分离版集成积木报表和大屏的完整工程包面向需要快速实现数据可视化报表与企业大屏展示的若依开发者适用于后台管理、数据分析、领导驾驶舱等场景。资源共643个文件压缩包仅3.11MB以274个java后端类、101个vue页面组件和80个js脚本为主力辅以xml配置、sql数据库脚本、yml环境配置及svg图标等完整覆盖若依框架与积木组件的对接链路。已有1626人学习下载。包内附带若依环境使用手册、bat启动脚本及前后端配置文件便于快速搭建运行环境并理解目录结构开发者可借助积木报表的拖拽式设计快速生成统计报表再用积木大屏将多组件组合成交互式看板同时参考java接口、vue页面与sql脚本完成业务数据接入和二开扩展。1. 集成积木报表与大屏前先看清若依的边界在哪里接手一个若依前后端分离版项目业务方第三天就丢过来一句话报表要能在线设计大屏要能拖拽配置并且都要挂在现有菜单里权限跟着部门走。听起来简单真正动手才发现若依是 Spring Security JWT 的鉴权体系积木报表自带一套登录逻辑积木大屏又依赖积木报表的认证状态三者揉在一起第一步就卡在「登录之后还是登录」的死循环里。这篇文章把我踩过的坑和最终跑通的集成路径完整拆开从依赖引入、鉴权打通、菜单嵌入到数据源对接每一步都有代码和参数说明最后还有一份排错清单适合已经跑通若依基础项目、正打算塞进报表与大屏的开发者。2. 后端集成把积木报表引擎真正挂到若依服务里2.1 依赖引入与冲突清理积木报表和积木大屏在若依项目里通常以 jar 包方式引入官方推荐的是jimu-report和jimu-big-screen两个模块但直接加到pom.xml里往往起不来报错多半集中在依赖冲突上。最常见的三个冲突点hutool的版本不一致、shiro与若依的spring-security共存冲突、mybatis拦截器被覆盖。我的做法是把若依原有的依赖排除掉让积木自己带的那份生效前提是版本不要盖住若依主流程。dependency groupIdorg.jeecgframework.jimureport/groupId artifactIdjimu-report-spring-boot-starter/artifactId version1.6.5/version exclusions exclusion groupIdcn.hutool/groupId artifactIdhutool-all/artifactId /exclusion exclusion groupIdorg.apache.shiro/groupId artifactIdshiro-core/artifactId /exclusion exclusion groupIdcom.baomidou/groupId artifactIdmybatis-plus-extension/artifactId /exclusion /exclusions /dependency这段配置排除了hutool-all是因为若依自带的 Hutool 版本较老积木报表内部用了较新的 API直接用会抛NoSuchMethodError排除shiro-core是因为若依用的是 Spring Security两个安全框架同时存在会出现过滤器链混乱报表请求被 Shiro 拦截后直接重定向排除mybatis-plus-extension是为了避免积木报表自带的数据库操作类影响若依的BaseMapper扩展。version参数按你实际拿到的包版本替换别照抄。2.2 安全配置把报表地址交给若依的鉴权上下文积木报表启动后默认会在jimuReport路径下暴露一批接口包括/jmreport/**的设计器页面、预览、导出以及/big-screen/**的大屏相关接口。如果不做任何配置这些接口直接被 Spring Security 拦住报表设计器打不开。但也不能简单地全部放行否则等于把所有报表数据裸奔在公网。我的方案是只放行静态资源与登录跳转路径其余走若依的 JWT 认证。security: ignore: whites: - /jmreport/desreport/dataSet/** # 数据集查询需要后端控制数据权限 - /jmreport/iframe/** # iframe 嵌入报表时使用的地址 - /big-screen/designer/** # 大屏设计器静态资源在若依的SecurityConfig里把这几个路径加入permitAll同时把/jmreport/**与/big-screen/**排除在 CSRF 防护之外。核心逻辑是设计器页面本身是静态 HTML可以匿名加载真正的数据查询与导出接口仍然放在 JWT 拦截范围内由后端校验用户身份与数据权限。2.3 单点登录用若依的 token 换取积木的在线凭证这是整个集成中最绕的一环。积木报表有自己独立的用户表和登录接口/jmreport/login如果用户在若依里登录了进入报表页面还要再输一次积木的账号密码体验很糟糕。更麻烦的是积木大屏内部也会校验自己的 session若依的 token 在里面是不认识的。我采用的方案做一个隐藏的登录转换接口在用户带若依 token 访问报表页面时后端拿若依当前的登录用户走积木的token认证接口把生成的积木 token 拼进报表地址里返回给前端。GetMapping(/report/sso) public AjaxResult reportSso(String jimuToken) { // 直接从请求头中读取若依的 Authorization String ruoYiToken SecurityUtils.getToken(); if (StringUtils.isBlank(ruoYiToken)) { return AjaxResult.error(未登录无法进入报表); } // 以服务端身份调用积木登录接口换取积木自己的 token HttpHeaders headers new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); JSONObject body new JSONObject(); body.put(username, ruoyi_admin); body.put(password, jimu_sso_secret); HttpEntityString entity new HttpEntity(body.toJSONString(), headers); ResponseEntityJSONObject response restTemplate.postForEntity( http://localhost:8080/jmreport/login, entity, JSONObject.class); String jimuToken response.getBody().getJSONObject(data).getString(token); // 返回拼接好的报表地址前端直接 iframe 加载 return AjaxResult.success(system/report/design?token jimuToken); }这段代码里最关键的是restTemplate.postForEntity的地址不能写死localhost否则集群环境下会出问题。username和password建议在配置中心里单独维护使用积木报表的管理员账号或者一个专供 SSO 使用的只读账号不要用若依业务用户去建映射因为若依的用户 id 和积木的用户 id 本来就是两个体系。登录成功后返回的jimuToken在积木的 Redis 里有一个有效期过期后需要重新换取这个过程对前端无感。3. 前端集成页面嵌入、token 传递与菜单配置3.1 菜单表里挂一个外部页面若依的前端菜单是走后端sys_menu表的想在菜单里点开一个积木报表页面最省事的方案是新增一条路由指向一个自定义的iframe容器组件而不是直接改若依的router/index.js。路径会变成用户点击菜单 → 加载 Vue 组件 → 组件内部通过postMessage或 URL 参数携带 token 给 iframe 中的积木页面。INSERT INTO sys_menu ( menu_name, parent_id, order_num, path, component, menu_type, perms, icon ) VALUES ( 报表中心, 0, 1, report-center, report/center/index, C, report:center:list, chart );component字段指向你提前放在src/views/report/center/index.vue里的组件path字段是前端路由路径最好与后端GetMapping的路径保持一致浏览器地址栏会好看一些。注意menu_type用C表示目录型菜单如果用F按钮类型点击会没有反应这是新手最容易忽略的点。3.2 iframe 里传 token拼接 URL 并防止浏览器拦截前端组件部分最直接的方式是在mounted生命周期里发起请求拿到第 2.3 节接口返回的报表地址再赋给 iframe 的src。template div classapp-report-container iframe v-ifreportUrl :srcreportUrl frameborder0 width100% height100% / /div /template script export default { data() { return { reportUrl: }; }, mounted() { // 调用若依统一封装的 request它会自动附带用户 token this.$http.get(/report/sso).then((res) { if (res.code 200) { this.reportUrl res.data; } }); } }; /scriptreportUrl是后端返回的完整地址包含jmreport的前缀和token参数。iframe 加载后积木前端会读取 URL 中的 token 自动完成登录态建立。这里有一个浏览器兼容问题如果token过期iframe 里的积木会跳转到自己的登录页而不是跳回若依的登录页所以要在积木的配置里把登录跳转地址指回若依的登录页面否则用户会觉得系统「卡死」了。3.3 大屏编辑器的特殊处理积木大屏与积木报表在路由上不一样大屏的编辑地址通常是/big-screen/view/{id}但它同样要 token。实际操作中我发现大屏的 iframe 加载比报表更快容易出现 token 还没写入就加载完的情况。解决方式是在 iframe 加载完成后用postMessage主动把 token 发送给积木页面。iframe.onload function() { iframe.contentWindow.postMessage({ type: jimu-auth, token: that.jimuToken }, *); };积木大屏的前端源码里已经监听了这个message事件收到后会写入自己的本地存储。*是postMessage的目标源生产环境建议改成具体的报表服务域名避免其他页面通过窗口对象把 fake token 注入进来。这个细节容易被忽略但它是大屏集成中最容易出现「偶发进不去」的根源之一。4. 报表数据源与大屏数据接口把业务数据喂给设计器4.1 数据源配置在积木后台建立数据源连接积木报表设计器在创建数据集时需要选择一个数据源这个数据源默认配置是写死在积木的jeecg数据库里的。我的做法是在积木的系统配置里新建一个数据源指向若依正在使用的主数据库这样设计报表时直接写 SQL 就能查到若依业务表的数据。数据源配置里有一个关键参数叫driver-class-name若依使用 MySQL 时填com.mysql.cj.jdbc.Driver使用 PostgreSQL 时填org.postgresql.Driver。连接池参数中initialSize建议设成 5maxActive设成 50如果直接沿用若依的Druid配置积木使用自己的连接池去访问同一个库Druid 的监控会出现两条链路排查问题时要分清是哪条链路报的错。4.2 大屏的 JSON 组件对接后端接口大屏设计器里的组件大部分是静态 JSON 数据但业务大屏需要实时数据。积木大屏提供了「数据接口」功能可以直接请求一个 URL。这个 URL 不能写localhost因为大屏预览时是浏览器发起的请求会存在跨域问题。解决办法是在若依后端写一个专用的大屏数据接口允许跨域并返回积木 JSON 组件需要的{code: 200, data: [...]}结构。GetMapping(/bigScreen/getOrderTrend) CrossOrigin public AjaxResult getOrderTrend() { ListMapString, Object list orderService.selectTrend7Days(); return AjaxResult.success(list); }积木大屏 JSON 组件的数据格式要求外层有codedata是数组。若依的AjaxResult.success返回结构正好是{code: 200, data: ...}但data在某些接口里是Map大屏组件识别不了需要保证data一定是数组类型。CrossOrigin注解在开发阶段很方便但生产环境建议把大屏域名配置到若依的CorsFilter的允许列表里或者干脆把预览地址做成同域反向代理避免全民可跨域。4.3 大屏动态刷新轮询与 websocket 的选择大屏的滚动数据、实时订单数量通常要求每几秒刷新一次。积木大屏本身有定时刷新配置直接在组件的「数据刷新」选项里填写秒数即可。但遇到需要与其他页面联动刷新的场景比如点击左侧图表后右侧数据跟随变化就得靠事件机制。我的做法是在大屏设计器里给图表组件配置一个「联动刷新」事件事件触发时调用一个自己写的若依接口接口返回最新数据后通过积木大屏的setData方法更新图表。这种方式比全局 websocket 简单很多因为在一个大屏页面里数据源的种类有限每个图表维持自己的定时器就够了没必要把整个页面全量重刷。5. 避坑排查集成中最常见的五个翻车现场5.1 报表设计器打不开一直循环到积木登录页现象点击菜单进入报表设计器浏览器地址变成/jmreport/login登录后跳回报表地址又跳回登录页。原因若依的 token 和二 积木的 token 是两套积木设计器页面没有拿到有效 token又因为配置里把跳转地址指回了自己造成无限循环。解决确认第 2.3 节的 SSO 接口中返回的jimuToken拼接正确检查积木报表配置中LOGIN_URL是否被改成了若依的地址。若改成若依地址积木登录页会跳转到若依但若依登录完成后的回调没有携带积木的 token要保证两边的回调地址成环闭合。5.2 报表导出 Excel 中文文件名乱码现象在积木报表设计器里点击导出浏览器下载的文件名变成一堆%E4%B8%AD%E6%96%87之类的编码。原因若依网关层或前端 Nginx 没有对Content-Disposition头里的中文做 URL 解码。积木报表导出时用URLEncoder.encode对文件名编码但前端拿到的是编码后的字符串没有decodeURIComponent。解决在前端请求封装里对响应头的Content-Disposition做一次decodeURIComponent。或者在 Nginx 的proxy_hide_header Content-Disposition后重新设置这个头部分版本的网关对*号支持有问题处理方式不唯一但确认编码链路是关键。5.3 报表数据集的 SQL 查不到若依的数据现象积木数据源连接成功但数据集预览返回空列表。原因积木的数据源连接数据库地址可能指向了它自带的jeecg库而不是若依的业务库。另外若依的框架表在生成时带上了tenant_id或dept_id的过滤条件积木数据源不知道要补上这些条件。解决在数据源配置里把jdbcUrl改成若依主库的地址同时如果若依开启了多租户要在每条数据集的 SQL 里手动加上租户过滤条件或者关闭若依的租户插件如果线上环境允许的话。5.4 大屏设计器能打开但预览时图表不加载现象设计器里拖拽组件正常点预览或者用小屏生成分享链接后图表区域一直转圈。原因大屏预览时所有数据请求都带上了积木的 token但有些组件配置了「跨域请求地址」为localhost。浏览器安全策略把请求拦住了或者后端接口拒绝了不带若依 token 的请求。解决把所有大屏数据接口统一成/bigScreen/**路径并在第 2.2 节的白名单里加入/bigScreen/**前提是这些接口自身做了权限控制。最保险的做法是在后端给大屏数据接口加一个内部的appId参数校验只有带着合法appId的请求才返回数据这个appId只存在大屏配置里不对外暴露。5.5 集成后若依原本的登录接口失效现象加上积木报表依赖后若依的/login接口报 500日志里出现ShiroFilter找不到类的错误。原因积木报表的 starter 里自动配置了 Shiro虽然排除了shiro-core但shiro-spring的自动装配还在。解决在启动类上增加SpringBootApplication(exclude {ShiroAutoConfiguration.class})。如果项目里用了spring.factories手动排除确认排除的类名与积木报表版本匹配不同版本的自动配置类路径有变化。6. 验证与进阶从单报表到多数据源看板的收尾习惯集成完成后我习惯用一套固定的验证顺序确认链路没断先用管理员账号登录若依打开报表中心检查设计器和预览是否正常再新建一个测试数据集跑通从 SQL 到图表的一条完整链路退出登录后清空浏览器缓存重新打开报表地址确认会跳回若依登录页而不是积木登录页最后用低权限账号测试一下数据权限是否生效——如果低权限账号能查到不该看的数据说明积木数据源绕过了若依的行级权限要回到第 4.1 节重新配置数据源。进阶的方向有两个一个是把积木报表的「数据权限」能力实际用起来在积木的报表设计器里设置数据源的时候可以绑定用户 token 里的部门参数做到按部门过滤数据另一个是把大屏嵌入到首页看板不做独立菜单而是作为若依首页的一个组件用定时器轮询刷新。两种做法都依赖我前面讲的 SSO 接口没有这个基础权限和 token 的打通就无从谈起。说实话集成积木报表这件事本身技术难度不高难的是两方面一是若依的 Spring Security 过滤链和积木的 Shiro 过滤链怎么共存二是两个系统的用户体系怎么不互相打架。第一个排掉了自动装配第二个靠隐藏的 SSO 接口解决。从那以后我每次接到类似的集成需求都会强制先走一遍「依赖排除清单 → 白名单路径 → SSO 换取 token → 低权限账号回归」这四步确认这几条站稳了再碰业务功能翻车率比以前少了一大半。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑