SpringBoot毕业生就业去向登记管理系统:毕设源码与二次开发指南
简介这份资源是面向计算机专业毕业生与Java初学者的一套完整就业去向登记管理系统源码可直接作为毕业设计或课程设计参考。系统基于SpringBoot框架开发覆盖需求分析、总体设计、详细设计与功能测试全流程包含功能结构、数据结构及安全设计等环节并配有数据库文件与配置说明下载后按说明即可运行。压缩包共296个文件约9.9MB其中66个Java源文件承载核心业务逻辑161个svg与13个png、3个jpg构成前端图标与界面素材另有14个js、8个vm模板、9个xml及yml、properties等配置以及sql数据库脚本和bat、cmd启动脚本结构清晰便于二次开发。目前已有570人学习下载适合需要完整赛题方案、模块实现代码与排错思路的读者参考借鉴。1. 从一份毕设源码说起就业去向登记到底在管什么每年三四月高校就业办的老师最头疼的不是催学生交三方协议而是手里那堆格式各异的去向表——有人填了单位名称却漏了统一社会信用代码有人把灵活就业写成签约就业还有人提交后偷偷改了两遍。等数据汇总到省里平台字段对不上、逻辑校验报错返工就是一周起步。这份「springboot毕业生就业去向登记管理系统」要解决的正是这个场景把纸质表格和散落的 Excel 变成一个有状态流转、有权限隔离、有统计口径的 Web 系统。它适合两类人——正在找毕设题目的计算机专业学生以及需要一套可二次开发的就业数据采集底座的开发者。技术栈是 SpringBoot MyBatis-Plus MySQL Thymeleaf 的经典组合没有微服务那些花哨东西跑起来不费劲改起来也看得懂。2. 环境搭建与数据库设计把「去向」拆成可校验的字段2.1 技术选型为什么是 SpringBoot 单体而不是前后端分离拿到源码包先别急着导入 IDE得想清楚这套东西的定位。就业去向登记系统的核心诉求是「快速上线、方便部署、维护简单」很多高校的就业办并没有专职运维你给他一个需要 Nginx 反代 Node 构建 跨域配置的前后端分离项目光是部署就能劝退。SpringBoot 单体 Thymeleaf 模板的方案打成一个 jar 包丢到服务器上java -jar就能跑数据库用 MySQL 5.7 或 8.0 都兼容这对毕设答辩和实际交付都友好。另一个原因是权限模型。就业系统涉及学生、导师、院系管理员、就业办四级角色用 Spring Security 做 URL 级拦截比在 Vue 路由里做守卫更直接后端一拦前端根本拿不到数据安全边界清晰。源码里用的是 Spring Security JWT 的混合模式登录后发 token后续请求走过滤器校验这套逻辑在单体里写起来不绕。2.2 数据库表结构三张核心表撑起整个流转就业去向登记的数据模型不复杂但字段设计有讲究。我一般会先看sql目录下的建表脚本重点盯三张表student_info学生基础信息、employment_record去向记录、audit_log审核日志。下面是从源码里提炼的建表逻辑我加了注释说明每个字段为什么这么设。-- 学生信息表学号做主键避免用自增 ID 导致数据迁移时对不上 CREATE TABLE student_info ( student_no varchar(20) NOT NULL COMMENT 学号业务主键, name varchar(50) NOT NULL COMMENT 姓名, college varchar(100) DEFAULT NULL COMMENT 院系, major varchar(100) DEFAULT NULL COMMENT 专业, class_name varchar(50) DEFAULT NULL COMMENT 班级, phone varchar(20) DEFAULT NULL COMMENT 联系电话, status tinyint DEFAULT 1 COMMENT 1-在读 2-已毕业 3-休学, PRIMARY KEY (student_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT学生基础信息; -- 去向记录表一个学生可以有多条记录升学、签约、违约重签 CREATE TABLE employment_record ( id bigint NOT NULL AUTO_INCREMENT, student_no varchar(20) NOT NULL, record_type tinyint NOT NULL COMMENT 1-签约就业 2-升学 3-灵活就业 4-待就业, company_name varchar(200) DEFAULT NULL COMMENT 单位名称, credit_code varchar(18) DEFAULT NULL COMMENT 统一社会信用代码18位校验, position varchar(100) DEFAULT NULL COMMENT 岗位, salary_range varchar(50) DEFAULT NULL COMMENT 薪资区间, work_city varchar(50) DEFAULT NULL COMMENT 工作城市, submit_time datetime DEFAULT CURRENT_TIMESTAMP, audit_status tinyint DEFAULT 0 COMMENT 0-待审 1-通过 2-驳回, audit_remark varchar(500) DEFAULT NULL COMMENT 审核意见, PRIMARY KEY (id), KEY idx_student_no (student_no), KEY idx_audit_status (audit_status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT就业去向记录; -- 审核日志表谁在什么时候改了哪条记录留痕用 CREATE TABLE audit_log ( id bigint NOT NULL AUTO_INCREMENT, record_id bigint NOT NULL, operator varchar(50) NOT NULL COMMENT 操作人工号, action varchar(20) NOT NULL COMMENT submit/approve/reject, remark varchar(500) DEFAULT NULL, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_record_id (record_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT审核操作日志;这里有个容易翻车的点credit_code字段设了 18 位但很多学生填的时候会带空格或者小写字母入库前必须做 trim 和转大写否则统计时同一个单位会被算成两个。源码里在 Service 层做了StringUtils.trim和toUpperCase这个细节值得留意。2.3 配置文件与启动参数改对数据库连接就能跑导入项目后第一件事是改application.yml。源码默认用的是localhost:3306/employment_db用户名密码是root/123456实际部署肯定要改。下面是我一般会调整的几个参数spring: datasource: url: jdbc:mysql://127.0.0.1:3306/employment_db?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/Shanghai username: your_username password: your_password driver-class-name: com.mysql.cj.jdbc.Driver thymeleaf: cache: false # 开发阶段关缓存改页面不用重启 server: port: 8080 servlet: context-path: /employmentserverTimezone必须设成Asia/Shanghai不然提交时间会差 8 小时审核日志的时间线就乱了。context-path设了之后所有接口都要带前缀前端模板里的链接也要同步改这个在源码里已经处理好了但如果你要改路径记得全局搜一遍。启动命令就一句mvn spring-boot:run或者打成 jar 后java -jar employment-system.jar。首次启动会自动执行schema.sql建表但数据初始化脚本data.sql里只有管理员账号学生数据得自己导或者手动加。3. 核心功能实现从提交去向到审核通过的全链路3.1 学生提交去向表单校验与防重复提交学生端的核心操作是填去向。源码里用 Thymeleaf 渲染表单后端用Valid做参数校验。下面这段是 Controller 里的提交逻辑我加了注释说明每个校验点的作用PostMapping(/record/submit) public String submitRecord(Valid EmploymentRecord record, BindingResult result, HttpSession session, RedirectAttributes attrs) { // 1. 基础字段校验NotBlank 等注解在实体类上 if (result.hasErrors()) { attrs.addFlashAttribute(error, result.getFieldError().getDefaultMessage()); return redirect:/record/form; } // 2. 统一社会信用代码格式校验18位数字大写字母 if (record.getCreditCode() ! null !record.getCreditCode().matches(^[0-9A-Z]{18}$)) { attrs.addFlashAttribute(error, 统一社会信用代码格式不正确); return redirect:/record/form; } // 3. 防重复提交同一学生同一类型只能有一条待审或通过记录 Long count recordMapper.selectCount(new LambdaQueryWrapperEmploymentRecord() .eq(EmploymentRecord::getStudentNo, record.getStudentNo()) .eq(EmploymentRecord::getRecordType, record.getRecordType()) .in(EmploymentRecord::getAuditStatus, 0, 1)); if (count 0) { attrs.addFlashAttribute(error, 您已有同类去向记录在审核中或已通过请勿重复提交); return redirect:/record/form; } record.setAuditStatus(0); // 待审核 recordMapper.insert(record); // 4. 写审核日志 auditLogService.log(record.getId(), record.getStudentNo(), submit, 学生提交); return redirect:/record/list; }这段逻辑里最容易被忽略的是第 3 步的防重复提交。很多毕设源码只做了前端按钮置灰后端不拦学生用 Postman 或者刷新页面就能塞进去两条一样的记录审核老师看到两条待审直接懵。加上这个查询后数据库层面就干净了。参数说明recordType是枚举值1 到 4 分别对应签约、升学、灵活、待就业auditStatus初始为 0审核通过后变 1驳回变 2。驳回后学生可以修改再提交这时候要允许同一类型存在多条记录所以防重复的查询条件里只查了状态 0 和 1。3.2 管理员审核状态机与批量操作审核端的功能比学生端复杂因为涉及状态流转和批量处理。源码里用了一个简单的状态机待审(0) → 通过(1) 或 驳回(2)驳回后学生修改重新提交状态回到 0。下面这段是审核接口的实现PostMapping(/admin/audit) PreAuthorize(hasRole(ADMIN)) // Spring Security 角色拦截 public String audit(RequestParam Long recordId, RequestParam Integer action, // 1-通过 2-驳回 RequestParam(required false) String remark, HttpSession session) { EmploymentRecord record recordMapper.selectById(recordId); if (record null || record.getAuditStatus() ! 0) { return redirect:/admin/list?errorinvalid; } // 驳回必须填意见通过可以不填 if (action 2 (remark null || remark.trim().isEmpty())) { return redirect:/admin/list?errorremark_required; } record.setAuditStatus(action 1 ? 1 : 2); record.setAuditRemark(remark); recordMapper.updateById(record); // 记录操作日志操作人从 session 里取 String operator (String) session.getAttribute(username); auditLogService.log(recordId, operator, action 1 ? approve : reject, remark); return redirect:/admin/list; }PreAuthorize注解依赖 Spring Security 的配置类源码里在SecurityConfig中开启了EnableGlobalMethodSecurity(prePostEnabled true)否则这个注解不生效。这是个常见坑注解写了但没开开关权限拦截形同虚设。批量操作在源码里是通过前端复选框 后端接收ListLong ids实现的逻辑和单条审核一样只是循环处理。注意批量驳回时每条都要填意见源码里简化成统一填一个意见实际用的时候可以改成逐条弹窗。3.3 统计报表按院系和专业聚合的 SQL 写法就业办最关心的功能是统计。源码里用 MyBatis-Plus 的QueryWrapper配合groupBy实现按院系聚合下面这条 SQL 是核心SELECT s.college AS college, COUNT(DISTINCT s.student_no) AS total, SUM(CASE WHEN e.record_type 1 THEN 1 ELSE 0 END) AS signed, SUM(CASE WHEN e.record_type 2 THEN 1 ELSE 0 END) AS further_study, SUM(CASE WHEN e.record_type 3 THEN 1 ELSE 0 END) AS flexible, SUM(CASE WHEN e.record_type 4 THEN 1 ELSE 0 END) AS unemployed FROM student_info s LEFT JOIN employment_record e ON s.student_no e.student_no AND e.audit_status 1 WHERE s.status 2 -- 只统计已毕业学生 GROUP BY s.college ORDER BY total DESC;这里用LEFT JOIN而不是INNER JOIN是为了把没有提交去向的学生也算进总数否则就业率分母会偏小。audit_status 1的条件放在 JOIN 里而不是 WHERE 里也是同样的道理——如果放 WHERE未提交的学生会被过滤掉。统计结果在 Thymeleaf 里用表格渲染源码没有用 ECharts 之类的图表库就是纯 HTML 表格。如果你要加图表可以在后端把数据转成 JSON 返回前端引一个轻量图表库但注意别引入太重的依赖毕设答辩时加载慢会尴尬。4. 避坑与排查部署和运行时的五个血泪教训4.1 中文乱码从数据库到页面的三层排查现象学生姓名显示成问号或者提交后入库变成乱码。原因MySQL 建库时字符集不是utf8mb4或者 JDBC URL 里没加characterEncodingutf8mb4再或者 Thymeleaf 页面没声明 UTF-8。解决三步走——先SHOW CREATE DATABASE employment_db;确认字符集是utf8mb4不是就ALTER DATABASE改再检查application.yml里的 URL 参数最后在 HTML 的head里加meta charsetUTF-8。三层都对了才不会乱。4.2 时间差 8 小时serverTimezone 必须显式指定现象提交记录的时间比实际时间早 8 小时审核日志的时间线对不上。原因MySQL 驱动默认用 UTC 时区而国内服务器是东八区。解决JDBC URL 里加serverTimezoneAsia/Shanghai。注意是Asia/Shanghai不是GMT8后者在部分驱动版本里会报错。改完重启应用新数据就正常了旧数据得手动UPDATE修正。4.3 权限注解不生效忘了开 EnableGlobalMethodSecurity现象PreAuthorize(hasRole(ADMIN))写了但普通学生账号也能调审核接口。原因Spring Security 默认不处理方法级注解需要在配置类上加EnableGlobalMethodSecurity(prePostEnabled true)。解决找到SecurityConfig类加上这个注解。另外注意hasRole(ADMIN)里的角色名要带ROLE_前缀的存储格式数据库里存的权限字段如果是ADMINSpring Security 会自动补前缀但如果你用的是hasAuthority就得写全。4.4 打包后 Thymeleaf 页面 404模板路径大小写问题现象IDE 里跑正常打成 jar 后访问页面报 404。原因Linux 服务器文件系统区分大小写Windows 不区分。源码里 Controller 返回record/List但实际文件名是list.htmlWindows 下能找到Linux 下就 404。解决全局搜 Controller 里的返回值确保和templates目录下的文件名大小写完全一致。这个坑在毕设答辩时如果用的是 Windows 服务器可能遇不到但部署到云服务器上必翻车。4.5 统计数字对不上LEFT JOIN 的条件位置写错现象就业率算出来偏高因为未提交去向的学生没被算进分母。原因把e.audit_status 1写在了 WHERE 子句里导致 LEFT JOIN 退化成 INNER JOIN。解决把条件移到 ON 子句里如第 3.3 节的 SQL 所示。另外COUNT(DISTINCT s.student_no)里的 DISTINCT 不能省因为一个学生可能有多条已通过的记录比如先签约后升学不去重会重复计数。5. 二次开发与验证三个能直接落地的扩展点5.1 加一个「去向变更申请」功能现有系统里学生提交后如果发现填错了只能等管理员驳回再改。实际场景中更常见的是学生主动申请变更。扩展思路是加一张change_request表记录原记录 ID、变更原因、新数据走独立的审核流。核心代码是在原employment_record上加一个is_locked字段变更申请通过后解锁原记录并插入新记录。这个功能在毕设答辩时是个不错的加分项因为它体现了对业务状态的理解而不只是增删改查。5.2 用定时任务做数据导出就业办经常需要把数据导成 Excel 报给上级。源码里没有导出功能可以用 EasyExcel 加一个定时任务每周一凌晨把已审核通过的数据生成 Excel 存到指定目录。关键配置是Scheduled(cron 0 0 1 ? * MON)注意 cron 表达式里周几的字段Spring 里 1 代表周一和 Linux crontab 的 0 代表周日不一样这个玄学坑我踩过不止一次。5.3 验证清单部署后必做的五项检查检查项操作预期结果数据库连接启动日志搜HikariPool无Connection refused字符集插入一条中文姓名页面显示正常无问号权限拦截用学生账号调/admin/audit返回 403 或跳转登录时间字段提交一条记录看submit_time与当前时间差不超过 1 分钟统计口径手动加一个未提交学生总数加 1就业率分母变大这五项走完基本能确认系统跑在正轨上。从那以后我每次拿到类似的毕设源码都先跑一遍这个清单再动代码省得改了半天发现是环境问题。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Spring Boot 3.x API密钥认证与密钥轮换实战指南

Spring Boot 3.x API密钥认证与密钥轮换实战指南

“你的服务对接了十几个下游调用方,大家约定好每次请求头里带一个 API Key,服务端校验通过才放行。密钥用了一年,安全团队突然要求立即轮换,你改配置、重启、发通知,结果重启期间服务不可用,调用方新旧密钥…

2026/10/13 7:38:09 阅读更多 →
链表分解:从内存布局到指针偏移的底层实践

链表分解:从内存布局到指针偏移的底层实践

1. 项目概述:这不是“拆链子”,而是把链表“掰开揉碎”讲清楚 “链表的分解”这五个字,乍看像一道算法题的标题,但实际在一线教学、代码评审和系统调试中,它代表一种极其关键的底层思维训练——不是单纯地写个反转或删…

2026/10/13 7:37:09 阅读更多 →
Python网络协议编辑器与分析器:从抓包到构造的全链路实现

Python网络协议编辑器与分析器:从抓包到构造的全链路实现

简介:计算机网络课程设计作品,包含网络协议编辑器与网络协议分析器,采用Python编程实现,面向计算机专业本科生、网络编程爱好者及需要完成类似课设的开发者。资源内包括两个主要Python脚本:packet_sender.py用于创建、…

2026/10/13 7:37:09 阅读更多 →

最新新闻

阿里云ECS IPv6配置全链路排障指南

阿里云ECS IPv6配置全链路排障指南

1. 为什么现在还值得花时间配通ECS的IPv6——不是赶时髦,是绕不开的现实需求 “阿里云ECS开启IPv6支持”这个标题看起来像一份过时的操作指南。毕竟IPv6喊了十几年,很多人印象里还是“实验室技术”“过渡方案”“等运营商推”。但去年底我帮某高校做一套…

2026/10/13 8:19:36 阅读更多 →
JDK编译报错“不支持发行版本6”:根因分析与Maven配置修复指南

JDK编译报错“不支持发行版本6”:根因分析与Maven配置修复指南

最近帮一位同事收拾旧项目,报错很典型:本地装的是JDK 11,代码从仓库拉下来,在IDE里一点编译,控制台直接打出java: 错误: 不支持发行版本 6。第一反应是Maven没配置好,又怀疑依赖版本冲突,折腾了…

2026/10/13 8:19:36 阅读更多 →
LLM代理成为一等优化手段:算子优化范式从手写汇编到代理驱动的转变

LLM代理成为一等优化手段:算子优化范式从手写汇编到代理驱动的转变

1. 从"手写汇编"到"代理驱动":算子优化范式正在发生什么变化2026年过半,如果你还在用纯手工的方式去调一个LLM推理场景下的算子kernel,大概率会在效率上吃大亏。这不是危言耸听,而是我这半年在几个实际项目里…

2026/10/13 8:19:36 阅读更多 →
开源可自托管代码评审工作流:从流程负担到质量抓手的工程实践

开源可自托管代码评审工作流:从流程负担到质量抓手的工程实践

代码评审这件事,做得好是团队效率的放大器,做得不好就是每天下班前的一场互相折磨。我在一线写了十几年代码,见过太多评审流于形式的团队——评论里全是“LGTM”,合入之后bug频发;也有评审严格到让人不敢提PR的团队&am…

2026/10/13 8:19:36 阅读更多 →
鸿蒙校园通开发实战:分布式数据同步与后台任务调度避坑指南

鸿蒙校园通开发实战:分布式数据同步与后台任务调度避坑指南

简介:这份资源是面向鸿蒙应用开发初学者与在校学生的实战项目源码包,以华为HarmonyOS为技术底座,围绕校园生活场景构建了一款功能完整的「校园通」软件。项目覆盖课程表管理、食堂菜谱、图书馆查询、校园导航、景点导览、号码百事通、校区平面…

2026/10/13 8:19:36 阅读更多 →
JMeter If Controller深度解析:逻辑调度与条件控制最佳实践

JMeter If Controller深度解析:逻辑调度与条件控制最佳实践

1. 项目概述:If Controller不是“条件开关”,而是JMeter里最被低估的逻辑调度中枢 如果你在用Jmeter做接口压测时,还只是把所有请求堆在同一个线程组里、靠“固定定时器”硬控节奏,或者一遇到“登录成功才跑下单”“状态为process…

2026/10/13 8:18:35 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →