若依集成积木报表与大屏:SSO鉴权与权限治理实战
简介若依前后端分离版集成积木报表和大屏的完整工程包面向需要快速实现数据可视化报表与企业大屏展示的若依开发者适用于后台管理、数据分析、领导驾驶舱等场景。资源共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 → 低权限账号回归」这四步确认这几条站稳了再碰业务功能翻车率比以前少了一大半。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

最长k可重区间集:最大费用流建模与实现详解

最长k可重区间集:最大费用流建模与实现详解

“最长k可重区间集问题”这名字第一次出现在《网络流24题》里时,我就被“最长”两个字骗了,以为又是一道区间贪心题。直到看到标准解法是最大费用最大流,才意识到这里的“最长”不是指最长区间,而是让选出的区间总长度最大&#x…

2026/10/15 15:30:19 阅读更多 →
React Native与鸿蒙跨平台开发实战:地址管理与登录确认

React Native与鸿蒙跨平台开发实战:地址管理与登录确认

1. 项目背景与核心需求 最近在开发一个电商类App时遇到了两个典型的交互场景需求:地址管理模块需要确保用户至少保留一个收货地址,而退出登录功能需要增加二次确认防止误操作。这两个需求看似简单,但在React Native与鸿蒙跨平台开发环境下实现…

2026/10/15 19:49:58 阅读更多 →
平面设计师简历为什么选.doc?格式解析与排版要点

平面设计师简历为什么选.doc?格式解析与排版要点

简介:一份平面设计师个人简历模板,面向平面设计、UI设计方向的求职者,也适合刚毕业或准备转岗的设计新人。模板以内置范文呈现完整简历结构,涵盖个人信息、教育背景、获奖荣誉、实习与工作经历、专业技能等模块,并列出…

2026/10/15 15:07:23 阅读更多 →

最新新闻

NDIS小端口驱动开发实战:从Miniport注册到NBL收发路径详解

NDIS小端口驱动开发实战:从Miniport注册到NBL收发路径详解

简介:这是一份面向Windows内核网络驱动开发者的NDIS 6.0小端口驱动实例源码,针对Realtek 8111/8168/8169/8110等PCI千兆以太网控制器编写。由于DDK中可参考的miniport示例仅有E100BEX,学习NDIS 6.0网卡驱动的资料相当稀缺,本资源正…

2026/10/15 20:55:56 阅读更多 →
档案管理信息系统核心设计:PostgreSQL+Django构建可审计闭环

档案管理信息系统核心设计:PostgreSQL+Django构建可审计闭环

简介:本资源是一套基于Delphi 6与SQL Server的档案管理信息系统(AMIS)完整开发源码包,面向高校计算机专业学生、桌面应用初学者及中小型单位信息化建设人员,解决传统档案手工管理效率低、检索难、权限模糊、版本混乱等…

2026/10/15 20:55:56 阅读更多 →
openai模型性能对比:用TaoToken统一Key跑通多模型基准测试

openai模型性能对比:用TaoToken统一Key跑通多模型基准测试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 20:55:56 阅读更多 →
C++算法实现工程手册:从数据结构选型到性能验证的避坑指南

C++算法实现工程手册:从数据结构选型到性能验证的避坑指南

简介:《Implementing Useful Algorithms in C》由Dmytro Kedyk撰写,面向具备一定C基础、希望深入掌握算法设计与工程实现的开发者与计算机专业学生。全书从算法正确性证明、渐进记法、机器模型等基础出发,延伸至随机化算法、数据类型选择、内…

2026/10/15 20:55:56 阅读更多 →
GPT、Kimi、DeepSeek 多模态能力实测:open design 设计任务中的公平对比与 TaoToken 统一接入

GPT、Kimi、DeepSeek 多模态能力实测:open design 设计任务中的公平对比与 TaoToken 统一接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 20:55:56 阅读更多 →
具身智能中的协同机理研究(107):双引擎并行实现毫秒级精确控制

具身智能中的协同机理研究(107):双引擎并行实现毫秒级精确控制

前沿技术探索:TVA智能体(简称TVA) TVA智能体(亦称“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统,也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习(DRL)、卷积神经网络(CNN)与因式分解算法(FRA),构成了具身智…

2026/10/15 20:54:55 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →