简介这是一套面向计算机、数学及电子信息类专业本科生的毕业设计级高校普法系统开发资源聚焦Web全栈开发实践解决校园法治教育数字化落地需求。资源包含SSMSpringSpringMVCMyBatis后端与Vue.js前端协同开发的完整项目涵盖用户管理、普法内容展示、交互接口等核心模块并配套毕业论文、答辩PPT及可直接导入的MySQL数据库脚本显著降低毕设启动门槛。压缩包共927个文件以160个Java业务逻辑文件、57个Vue组件、167个JS交互脚本、61个HTML页面及55个CSS样式文件为主干辅以SQL建表语句、批处理部署脚本.bat和说明文档整体23.39MB结构清晰便于分层学习与调试。已有129人下载学习提供经严格调试的无Bug源码、开箱即用的运行环境配置及完整交付材料特别适合课程设计、期末大作业及毕业设计参考助力快速掌握前后端分离架构与实际项目工程化流程。1. 高校普法系统不是“做个网站交差”它得让法学院老师点头、学生愿意点开、教务处能查数据高校普法系统表面看是JavaSSMVue搭个前后端分离的Web应用但实际落地时90%的毕业设计翻车点不在技术栈本身而在于法律内容与业务流程的耦合深度——比如《宪法》知识模块必须支持“课堂扫码答题→自动批改→生成班级薄弱知识点热力图”《民法典》案例库得能按“校园贷/实习纠纷/恋爱财产分割”打标签并关联本地高校真实判例再比如普法活动报名不能只存个姓名电话得对接教务系统课表避免时间冲突还得给辅导员导出带学号学院参与时长的Excel。这个项目标题里藏着三个硬约束一是法律内容必须可审核、可追溯、可更新不是静态HTML塞进数据库二是角色权限必须细到“法学院管理员可编辑题库院系辅导员只能查看本院数据学生仅能答题和看报告”三是交付物必须闭环SQL脚本要能一键建库建表Vue前端打包后扔进Spring Boot静态资源目录就能跑PPT里每页截图都得对应真实功能界面论文里“系统测试”章节的用例得能复现。如果你正卡在“代码跑起来了但答辩被问‘这个系统怎么保证普法内容不 outdated’答不上来”或者“Vue页面能登录但SSM后端返回403说跨域失败”这篇笔记就是为你写的——不讲SSM原理只讲怎么把“高校普法”这个具体场景焊死在JavaVue的技术链路上。2. 搭建最小可运行骨架从零初始化SSM后端 Vue前端绕过所有“环境配置玄学”2.1 后端用Maven快速初始化SSM工程避开MyBatis-Plus版本踩坑高校普法系统对数据库操作要求不高增删改查为主但必须稳定。我一般不用MyBatis-Plus因为它的自动SQL生成在复杂联查如“统计各学院近3个月答题正确率TOP5题目”时容易翻车且毕业答辩时老师常问“你写的SQL在哪”。所以坚持手写Mapper XML用最保守的SSM组合Spring 5.3.32 Spring MVC 5.3.32 MyBatis 3.4.6 MySQL 8.0。Mavenpom.xml关键依赖如下dependencies !-- Spring核心 -- dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.3.32/version /dependency !-- Spring MVC -- dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId version5.3.32/version /dependency !-- MyBatis -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.4.6/version /dependency !-- MySQL驱动注意8.0要用mysql-connector-java 8.0.33 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency !-- JSON处理别用fastjson用jackson规避反序列化漏洞 -- dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version2.13.5/version /dependency /dependencies提示spring-webmvc必须显式声明否则Controller注解不生效MySQL驱动版本必须与MySQL服务端严格匹配8.0.33是目前最稳的实测8.0.32在Linux下偶发连接超时。2.2 前端Vue CLI 4.5.17 Element UI 2.15.14拒绝Vue 3和Composition API毕业设计系统稳定性压倒一切。Vue 3的setup()语法糖在答辩演示时容易因Node版本不一致报错而Element UI 2.x对IE11兼容性好很多高校机房还在用IE且组件API简单——比如el-table直接绑定data数组不用写v-for老师一眼看懂。初始化命令# 全局安装Vue CLI必须4.x5.x默认Vue 3 npm install -g vue/cli4.5.17 # 创建项目选Manually select features只勾选Babel、Router、CSS Pre-processors vue create campus-law-system cd campus-law-system # 安装Element UI2.x npm install element-ui2.15.14 # 安装axios别用fetchSSM后端习惯用application/json传参 npm install axios0.21.4在main.js中引入Element UIimport Vue from vue import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css import App from ./App.vue Vue.use(ElementUI) // 全局注册避免每个组件import new Vue({ render: h h(App), }).$mount(#app)2.3 前后端联调用Nginx代理解决跨域比Webpack devServer proxy更贴近生产开发时用vue-cli-service serve启动前端mvn tomcat7:run启动后端但跨域问题常让新手卡住。Webpack的devServer.proxy配置复杂且易失效尤其当后端接口带/api/v1/前缀时。我直接用Nginx做反向代理配置文件nginx.confserver { listen 8080; server_name localhost; # 前端静态资源 location / { root /path/to/campus-law-system/dist; # Vue build后的dist目录 try_files $uri $uri/ /index.html; } # 后端API代理SSM项目部署在Tomcat 8081 location /api/ { proxy_pass http://localhost:8081/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }参数说明proxy_pass末尾的/至关重要——它会把/api/user/list重写为http://localhost:8081/user/list去掉/api前缀若不加/则变成http://localhost:8081/api/user/list后端收不到请求。这是90%跨域失败的根源。3. 核心业务模块实现普法内容管理、在线答题、数据看板三块必须焊死的骨头3.1 普法内容管理用富文本编辑器存法律条文但必须隔离HTML执行风险高校普法内容不是纯文本需保留《刑法》第236条的条款编号、加粗重点词、插入司法解释PDF链接。但直接存HTML到数据库有XSS风险学生提交恶意脚本。解决方案前端用wangEditor轻量、无jQuery依赖后端入库前用Jsoup清洗。Vue组件中引入wangEditortemplate div div refeditorElem styleborder: 1px solid #ccc;/div /div /template script import E from wangeditor export default { mounted() { this.editor new E(this.$refs.editorElem) this.editor.config.uploadImgShowBase64 true // 图片转base64避免单独上传 this.editor.config.menus [ head, bold, italic, underline, link, list, quote, emoticon ] // 禁用code、table等高危菜单 this.editor.create() }, methods: { getContent() { return this.editor.txt.html() // 获取HTML字符串 } } } /scriptSSM后端接收时清洗HTMLimport org.jsoup.Jsoup; import org.jsoup.safety.Whitelist; Service public class ContentService { public String cleanHtml(String html) { // 只允许p、h1-h6、strong、em、ul、ol、li、a标签且a标签只保留href Whitelist whitelist Whitelist.basic() .addTags(p, h1, h2, h3, h4, h5, h6, br, hr) .addTags(strong, em, u, s, sup, sub) .addTags(ul, ol, li) .addTags(a) .addAttributes(a, href); return Jsoup.clean(html, whitelist); } }逻辑说明Whitelist.basic()是Jsoup内置安全白名单但默认允许script必须手动addTags()限定addAttributes(a, href)确保链接只能有href属性防onclickalert(1)注入。3.2 在线答题模块用Redis缓存题库答题状态避免MySQL锁表学生同时答题时若每次请求都查MySQL题库高并发下MySQL连接池会耗尽。方案题库数据题目、选项、答案启动时全量加载进Redis Hash结构答题状态当前题号、已答选项存Redis String过期时间设为30分钟。Redis数据结构设计题库Hashlaw:question:bank→fieldquestion_id, value{id:1,content:《宪法》第几条...,options:[A. ...,B. ...],answer:A}学生状态Stringlaw:answer:session:{student_id}→value{current:3,answers:[null,A,null,B]}SSM Service层代码Service public class ExamService { Autowired private RedisTemplateString, Object redisTemplate; // 加载题库到Redis系统启动时调用 PostConstruct public void loadQuestionBank() { ListQuestion questions questionMapper.selectAll(); MapString, String map new HashMap(); for (Question q : questions) { map.put(String.valueOf(q.getId()), JSON.toJSONString(q)); // 序列化为JSON字符串 } redisTemplate.opsForHash().putAll(law:question:bank, map); } // 获取题目从Redis读不查DB public Question getQuestion(int id) { Object obj redisTemplate.opsForHash() .get(law:question:bank, String.valueOf(id)); return JSON.parseObject((String) obj, Question.class); } // 保存答题状态 public void saveAnswerStatus(String studentId, AnswerStatus status) { String key law:answer:session: studentId; redisTemplate.opsForValue().set(key, JSON.toJSONString(status), Duration.ofMinutes(30)); } }参数说明Duration.ofMinutes(30)是Redis过期时间学生30分钟内未提交状态自动清除JSON.toJSONString()用FastJSON已在pom中引入序列化比Jackson快30%。3.3 数据看板用ECharts 4.9.0渲染但必须适配高校数据上报格式高校教务系统要求数据导出为Excel且字段名固定如“学院名称”“参与人数”“平均分”“及格率”。ECharts图表不能只画好看得能一键导出对应Excel。方案前端用ECharts画图后端提供/api/report/export接口返回标准Excel流。ECharts配置示例柱状图显示各学院参与率// Vue组件中 mounted() { this.chart this.$echarts.init(this.$refs.chartDom) this.chart.setOption({ tooltip: { trigger: axis }, xAxis: { type: category, data: this.collegeNames }, yAxis: { type: value }, series: [{ name: 参与率, type: bar, data: this.participationRates, itemStyle: { color: #409EFF } }] }) }, methods: { async fetchReportData() { const res await axios.get(/api/report/colleges) this.collegeNames res.data.map(i i.collegeName) this.participationRates res.data.map(i i.rate) } }后端Excel导出接口用Apache POI 4.1.2GetMapping(/export) public void exportCollegeReport(HttpServletResponse response) throws IOException { ListCollegeReport reports reportService.getCollegeReports(); // 创建Excel工作簿 XSSFWorkbook workbook new XSSFWorkbook(); XSSFSheet sheet workbook.createSheet(学院普法数据); // 表头 String[] headers {学院名称, 参与人数, 平均分, 及格率, 最高分}; XSSFRow headerRow sheet.createRow(0); for (int i 0; i headers.length; i) { headerRow.createCell(i).setCellValue(headers[i]); } // 数据行 int rowNum 1; for (CollegeReport r : reports) { XSSFRow row sheet.createRow(rowNum); row.createCell(0).setCellValue(r.getCollegeName()); row.createCell(1).setCellValue(r.getParticipateCount()); row.createCell(2).setCellValue(r.getAvgScore()); row.createCell(3).setCellValue(r.getPassRate() %); row.createCell(4).setCellValue(r.getMaxScore()); } // 写入响应流 response.setContentType(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet); response.setHeader(Content-Disposition, attachment; filenamecollege_report.xlsx); workbook.write(response.getOutputStream()); }逻辑说明response.setContentType指定Excel MIME类型Content-Disposition触发浏览器下载POI 4.1.2兼容Java 8避免高版本POI在Tomcat 7下报NoClassDefFoundError。4. 避坑指南SSMVue高校普法系统里那些让答辩挂科的致命细节4.1 现象Vue路由刷新后404F5页面空白原因Vue Router用history模式但Nginx未配置try_files回退到index.html导致/user/profile这类路径直接返回404。解决在Nginxlocation /块中添加try_files $uri $uri/ /index.html;确保所有前端路由由Vue Router接管。4.2 现象MySQL 8.0连接报Public Key Retrieval is not allowed原因MySQL 8.0默认开启SSL且驱动要求显式授权公钥检索但高校服务器常禁用SSL。解决JDBC URL追加参数?allowPublicKeyRetrievaltrueuseSSLfalse例如jdbc:mysql://localhost:3306/law_db?allowPublicKeyRetrievaltrueuseSSLfalseserverTimezoneAsia/Shanghai。4.3 现象Element UI表格分页后端返回total但前端不显示总页数原因el-pagination的total属性必须是Number类型若后端返回JSON中total:100字符串Vue不会自动转换。解决后端返回JSON时确保total是数字MyBatis映射用Integer而非String或前端接收后强制转换this.total parseInt(res.data.total)。4.4 现象富文本插入图片后SSM后端接收为data:image/png;base64,...但MySQL TEXT字段存不下原因base64图片编码后体积膨胀33%单张图超1MB时TEXT字段最大65535字节溢出。解决前端上传图片时用canvas压缩至宽度800px、质量0.7或后端接收到base64后用javax.imageio.ImageIO解码为BufferedImage再压缩存储为JPEG。4.5 现象答辩现场演示时Vue打包后CSS样式丢失按钮变灰色原因Vue CLI 4默认用mini-css-extract-plugin抽离CSS但若vue.config.js中css.extract设为falseCSS会打入JS bundle而SSM的web.xml未配置*.js的MIME类型Tomcat返回text/plain导致浏览器不解析。解决vue.config.js保持css.extract: true并在web.xml中添加mime-mapping extensioncss/extension mime-typetext/css/mime-type /mime-mapping mime-mapping extensionjs/extension mime-typeapplication/javascript/mime-type /mime-mapping5. 让答辩老师眼前一亮的三个实战技巧从“能跑”到“值得写进论文”5.1 把法律条文拆成可检索的知识点用Elasticsearch 7.10.2替代MySQL LIKE高校普法系统最大的痛点是“学生搜‘校园贷’找不到相关法条”。MySQL的LIKE %校园贷%效率低且无法分词。方案用Elasticsearch建立法律条文索引支持同义词扩展如“网贷”“分期乐”“趣店”都映射到“校园贷”。Elasticsearch索引mappinglaw_articles{ settings: { analysis: { analyzer: { law_analyzer: { type: custom, tokenizer: ik_max_word, filter: [synonym] } }, filter: { synonym: { type: synonym, synonyms: [校园贷,网贷,分期乐,趣店, 民法典,合同法,侵权责任法] } } } }, mappings: { properties: { title: { type: text, analyzer: law_analyzer }, content: { type: text, analyzer: law_analyzer }, article_number: { type: keyword } } } }Java客户端查询用RestHighLevelClientSearchRequest searchRequest new SearchRequest(law_articles); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.multiMatchQuery(校园贷, title, content)); sourceBuilder.from(0).size(10); searchRequest.source(sourceBuilder); SearchResponse response client.search(searchRequest, RequestOptions.DEFAULT); // 解析response.getHits().getHits()...价值点论文里可写“对比MySQL全文索引与ES的召回率测试1000条法条ES准确率提升42%”附上测试截图——这比“系统采用B/S架构”有力得多。5.2 给答题模块加“防作弊水印”用Canvas动态生成学生专属二维码防止学生用手机拍屏作弊可在答题页面右下角动态生成含学生ID的二维码水印每30秒刷新一次。Vue组件实现template div classexam-container canvas refwatermarkCanvas classwatermark/canvas slot/slot /div /template script import QRCode from qrcode export default { props: [studentId], mounted() { this.drawWatermark() this.timer setInterval(this.drawWatermark, 30000) }, beforeDestroy() { clearInterval(this.timer) }, methods: { async drawWatermark() { const canvas this.$refs.watermarkCanvas const ctx canvas.getContext(2d) canvas.width 200; canvas.height 200 // 生成含时间戳的二维码 const timestamp Date.now() const qrData ${this.studentId}_${timestamp} const qrImage await QRCode.toDataURL(qrData, { width: 150 }) // 绘制半透明水印 const img new Image() img.src qrImage img.onload () { ctx.globalAlpha 0.1 ctx.drawImage(img, 0, 0, 150, 150) ctx.globalAlpha 1 } } } } /script style scoped .watermark { position: fixed; bottom: 20px; right: 20px; z-index: 999; pointer-events: none; } /style血泪经验pointer-events: none确保水印不阻挡点击globalAlpha 0.1让水印淡到不影响阅读但拍照后清晰可辨——答辩时老师用手机扫一下就能验证真伪。5.3 SQL脚本里埋“数据校验断言”让答辩老师当场运行验证毕业设计SQL脚本常被质疑“数据是假的”。在init.sql末尾加入校验语句用MySQL 8.0的ASSERT或模拟断言-- 插入测试数据后校验关键表记录数 SELECT CASE WHEN (SELECT COUNT(*) FROM law_article) 127 THEN ✅ 法条表初始化成功共127条 ELSE ❌ 法条表数据异常请检查insert语句 END AS check_result; -- 校验管理员账号是否存在 SELECT CASE WHEN (SELECT COUNT(*) FROM sys_user WHERE username admin) 1 THEN ✅ 管理员账号已创建 ELSE ❌ 管理员账号缺失 END AS admin_check;技巧答辩时打开MySQL Workbench直接运行source /path/to/init.sql结果集第一行就显示✅或❌——比口头解释“我写了127条法条”直观100倍。这是我带过的毕业生里唯一一个让法学院老师主动鼓掌的细节。最后说一句高校普法系统不是炫技场它的价值在于让《宪法》第33条不再是一行铅字而是学生答题后弹出的“你答对了这正是公民基本权利的起点”。我坚持手写SQL、用Vue 2、拒绝过度封装就是因为——答辩台上老师要的不是你多会调API而是你能指着某行代码说“这里保证了法律内容的准确传递”。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
Android锁屏灭屏加载流程:双状态机与SystemUI时序调试 1. 先把"灭屏"和"锁屏"这两件事分开看安卓锁屏灭屏加载流程,很多开发者第一次接触时都会把它当成一条链路来理解,结果调试的时候越想越糊涂。真实情况是:灭屏是电源与显示子系统的状态迁移,锁屏是窗口管理与S… · 2026/11/12 0:30:34
一致性哈希算法原理与Go实现详解 1. 一致性哈希算法核心原理剖析 一致性哈希算法(Consistent Hashing)是分布式系统中解决数据分片与负载均衡问题的经典方案。与传统的哈希取模算法相比,它能在节点增减时最小化数据迁移量,保持系统稳定性。这个算法最早由MIT的Kar… · 2026/11/10 7:33:15
从零搭建语音工作台VoiceStudio:本地降噪、VAD与ASR全流程实战 1. 从零搭建一个语音工作台:VoiceStudio 到底在解决什么问题第一次看到 VoiceStudio 这个名字,我脑子里蹦出来的不是某个具体产品,而是一类需求:手头有一堆录音素材,想快速剪出干净的人声、统一音量、去掉杂音… · 2026/11/5 16:26:06
工地太忙根本没时间复习考试 电工证上岗证考试试题怎么报名全攻略 工地太忙根本没时间复习考试 电工证上岗证考试试题怎么报名全攻略 工地太忙根本没时间复习考试,这是很多一线施工人员的真实写照。你可能正忙着赶工期,连吃饭的时间都紧张,更别提抽出时间来准备电工证上岗证考试试题了。别担心,今天就带你从零开始,看看… · 2026/11/12 0:30:03
收电工证流程复审延期怎么办理 官方回应来了 收电工证流程复审延期怎么办理 官方回应来了 证书过期了不知道怎么复审延期,你不是一个人。最近,很多持证人反映, 收电工证流程… · 2026/11/12 0:30:03
漯河哪里可以办电工证保姆级教程:怕考不过白交培训费?这份攻略帮你搞定 漯河哪里可以办电工证保姆级教程:怕考不过白交培训费?这份攻略帮你搞定 怕考不过白交培训费?你不是一个人!在漯河,电工证已经成为很多建筑工人、电工从业者、维修人员的“刚需”。尤其是郑州金水区的在职建筑工人,经常需要接触高低压电气设备,没有电工… · 2026/11/12 0:30:03
q3是什么特种工证报考条件与考试时间 之前考的证在外省能不能转过来?Q3特种工证和电子证书全解析 之前考的证在外省能不能转过来?我刚接手一个鹤壁水利工程项目的工地,有位工人拿着河南考的Q3特种工证,说在本地项目上被要求重新考证,理由是证书系统显示“证书状态异常”。这事儿让我意识… · 2026/11/12 0:30:03
电工证归哪些部门审核值不值得考 上岗必备指南 电工证归哪些部门审核值不值得考 上岗必备指南 怕考不过白交培训费,尤其是电工证这种 上岗必备 的证书,很多人担心花了几千块培训费,结果考试不过,钱打水漂。别急,下面这些干货能帮你少走弯路。 电工证归哪些部门审核? 电工证归哪些部门审核… · 2026/11/12 0:29:03
电工证丢失还能补吗?千万别踩坑,丢了证等于失业 电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/11 12:18:07
电力电缆作业证直播报名入口与办理流程良心建议 电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/11 19:07:25
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/11 17:14:54
电工证设年审有效期多久官方回应来了,工地太忙根本没时间复习考试 电工证设年审有效期多久官方回应来了,工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是很多一线电工、焊工、高处作业人员的真实写照。尤其是像你这样刚毕业的鹤壁工程类毕业生,一边要找工作,一边要考证,时间紧张,复习效率低。但你可能不知… · 2026/11/12 0:00:56
新乡电工证实操怕挂科?电工作业动漫图+报考避坑全解析 新乡电工证实操怕挂科?电工作业动漫图+报考避坑全解析 实操考试心里没底怕挂科?你不是一个人。新乡的水利工程从业者,很多在报考电工证的时候都担心自己操作不熟练、考试不通过, 千万别踩坑 ,选对资料和方法真的能提高通过率。… · 2026/11/12 0:00:56
网电工证千万别踩坑:实操考试心里没底怕挂科怎么破? 网电工证千万别踩坑:实操考试心里没底怕挂科怎么破? 实操考试心里没底怕挂科,这是很多准备报考【网电工证】的学员最真实的感受。尤其是在高压电工、低压电工等工种上,操作环节的容错率极低,一旦失误就可能直接被判定不合格。很多人因为担心挂科而放弃考… · 2026/11/12 0:00:56
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 20:19:29
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 19:22:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/11 17:15:20