简介本资源是广东工业大学数据库系统课程设计的完整实现方案——车站售票管理系统面向高校数据库初学者与课程设计实践者聚焦关系型数据库建模、Java后端开发与基础业务逻辑落地。系统覆盖售票、退票、车次/时刻表多维查询、销售统计及系统维护含权限管理、数据备份与恢复等核心功能具备教学示范性与工程可运行性。压缩包共100个文件以21个Java源码文件如Register.class、Ticketsmanage.class、RTraininformation.class等构成主体逻辑72个编译后class文件支撑运行辅以1个SQL建库脚本、1份安装说明书txt及项目配置文件整体4.65MB结构紧凑、开箱即用。目前已有1159人学习下载提供从需求分析、ER建模、SQL实现到Java Swing界面交互的全链路参考特别适合数据库课设选题复现、JDBC实战练习与小型C/S系统架构理解。1. 一个能跑通、能改、能交作业的数据库课设广工学生用它三天搞定车站售票系统答辩你是不是也经历过——数据库课设选题卡在“选什么”上查了一堆“火车订票系统”Demo下载下来不是缺表结构、就是没登录模块、要么运行报错说找不到mysql-connector更玄学的是有些项目连CREATE DATABASE语句都漏了导进去直接报Unknown database ticket。这个广工数据库课设包我拆开看了三遍它不炫技、不堆功能但从建库建表、插入示例数据、到 Java Swing 前端JDBC 后端完整链路全齐所有 SQL 脚本带注释Java 类命名清晰UserDAO.java、TicketService.java连db.properties配置文件都预设了 localhost:3306 的本地开发路径。它不是工业级系统但它是广工数据库课设最务实的落地模板适合零基础刚学完 SQL 和 JDBC 的同学照着 README 改两行就能跑也适合想加个“余票查询统计图”或“退票日志导出”功能的同学代码结构松耦合DAO 层和 UI 层完全隔离。别再被“高大上”的毕设 Demo 套路了——这次先让系统在你电脑上弹出那个熟悉的售票窗口。2. 项目结构与技术栈为什么它能在广工机房和你家笔记本上都跑起来这个课设不是用 Spring Boot Vue 搞出来的“看起来很美但配环境配到崩溃”的项目。它的技术选型非常克制全部落在广工数据库实验课覆盖范围内MySQL 5.7 作数据库、JDK 8 编译、Swing 做界面、纯 JDBC 驱动连接。没有 Maven 依赖冲突没有 Node.js 版本地狱甚至不需要装 Tomcat。整个项目就是一个标准的 Java SE 工程解压即 Eclipse/IDEA 可导入。下面我带你一层层剥开它的目录告诉你每个文件夹存在的意义以及为什么这样组织能让你少踩 80% 的坑。2.1 目录结构五个核心文件夹对应数据库课设五大得分点项目根目录下是典型的 Java SE 工程结构但每一层都紧扣数据库课设评分标准station-ticket-system/ ├── db/ # 【必交】数据库脚本目录 —— 广工老师重点检查建表语句是否规范、主外键是否明确 │ ├── create_table.sql # 包含 CREATE DATABASE 所有表定义user, train, station, ticket, order │ ├── insert_data.sql # 插入 5 条用户、3 列车、10 个车站、20 张车票的示例数据含时间戳、状态字段 │ └── init_db.bat # Windows 下双击一键执行建库建表插数据Linux 用户可改写为 .sh ├── src/ # 【核心】Java 源码 —— 分层清晰DAO/Service/UI 严格分离方便老师查代码逻辑 │ ├── dao/ # 数据访问层UserDAO.java、TrainDAO.java 等每个类只干一件事CRUD │ ├── service/ # 业务逻辑层TicketService.java 封装“购票”原子操作查余票→扣库存→生成订单→更新状态 │ ├── ui/ # 界面层LoginFrame.java、MainUI.java、BuyTicketDialog.java —— Swing 组件命名即功能 │ └── util/ # 工具类DBUtil.java封装 getConnection()、DateUtil.java格式化 yyyy-MM-dd HH:mm ├── resources/ # 【配置】外部化配置 —— db.properties 明确写出 driver、url、username、password ├── lib/ # 【依赖】仅 1 个 jarmysql-connector-java-5.1.47.jar兼容 JDK 8 和 MySQL 5.7 └── README.md # 【文档】广工风格说明包含“实验目的”“实现功能”“运行步骤”“注意事项”字数刚好够交报告提示广工数据库课设报告里常要求画“系统E-R图”和“数据库关系图”。这个项目的create_table.sql里每张表都有详细中文注释如-- 用户表存储注册用户信息status0表示正常1表示冻结你直接复制过去画图比自己凭空设计靠谱得多。2.2 核心技术选型解析为什么不用 Hibernate而坚持手写 JDBC很多同学看到“数据库课设”第一反应是搜 Spring Boot 教程结果配环境三天写业务三天最后发现老师要求的是“掌握 SQL 语句编写和 JDBC 编程基础”。这个项目就是按广工《数据库系统》实验大纲写的MySQL 5.7create_table.sql中大量使用ENGINEInnoDB支持事务、AUTO_INCREMENT主键自增、FOREIGN KEY显式声明外键约束完全匹配教材第 5 章“完整性约束”内容JDK 8所有 Lambda 表达式、Stream API 全部规避DBUtil.java中getConnection()方法用传统 try-catch-finally符合课设“考察基础编码能力”的定位纯 JDBCUserDAO.java中public User login(String username, String password)方法完整展示PreparedStatement防 SQL 注入、ResultSet遍历、Connection.close()手动释放资源——这正是实验报告里“JDBC 编程实践”小节要写的代码段Swing 而非 JavaFX广工机房预装 JDK 8 默认带 SwingMainUI.java中JTable展示车次列表、JComboBox选择出发站/到达站控件简单但功能完整避免 JavaFX 在旧版 JRE 上的兼容性翻车。2.3 数据库设计亮点一张图看懂五张表如何联动支撑“购票”核心流程这不是一个“用户表商品表订单表”的电商简化版。它紧扣“车站售票”业务五张表的设计直指数据库课设高频考点多对多关系处理、复合主键、状态字段设计、时间戳审计。下面这张关系说明是你画 E-R 图和写报告“数据库设计”章节的直接素材表名主键关键外键核心字段说明课设考点userid(PK)—username,password,role(admin/user),status实体完整性、角色权限基础设计stationcode(PK)—name(中文站名),city(所在城市)字符串主键实际应用非自增trainnumber(PK)—type(G/D/K),start_time,end_time时间类型字段设计与索引考虑ticketid(PK)train_number→train.number,from_code→station.code,to_code→station.codeprice,seat_type,stock余票数多对多桥梁表一列车有多个区间票一个区间被多列车覆盖orderorder_no(PK)user_id→user.id,ticket_id→ticket.idstatus(paid/cancelled),create_time,pay_time事务控制场景购票需同时更新ticket.stock和插入order注意“购票”操作在TicketService.java中被封装为一个原子方法内部用Connection.setAutoCommit(false)开启事务先UPDATE ticket SET stock stock - 1 WHERE id ? AND stock 0再INSERT INTO order (...)最后 commit。如果stock不足则 rollback —— 这就是你在实验报告里必须写的“事务处理实现”。3. 运行指南从零开始10 分钟内让售票窗口弹出来含常见报错速查别急着改代码。先确保你能把系统跑起来——这是所有后续工作的前提。这个项目最大的优点是所有路径都是相对路径所有配置都指向本地开发环境不需要改一行代码就能在你电脑上启动。下面步骤我在 Windows 10 MySQL 5.7.32 JDK 8u291 环境实测通过Mac/Linux 用户只需将.bat替换为.sh路径分隔符/替换为\即可。3.1 环境准备三步确认避免 90% 的启动失败确认 MySQL 正在运行且 root 密码为空或已知打开命令行输入mysql -u root -p回车后若直接进入 MySQL 提示符mysql说明密码为空若提示Enter password:输入你的密码。这是最关键的一步很多同学卡在这里却以为是 Java 报错。确认 JDK 8 已安装并配置好JAVA_HOME命令行输入java -version输出应为java version 1.8.0_XXX。若提示command not found请先安装 JDK 8 并设置系统环境变量。确认项目lib/mysql-connector-java-5.1.47.jar已添加到项目构建路径在 Eclipse 中右键项目 →Build Path→Configure Build Path→Libraries→Add External JARs→ 选中该 jar。IDEA 中File→Project Structure→Libraries→→Java→ 选中 jar。提示广工机房常用 MySQL 5.7默认用户名root密码为空。如果你改过密码请务必同步修改resources/db.properties中的password行。3.2 数据库初始化一键执行比手动贴 SQL 安全十倍不要打开 MySQL Workbench 一条条粘贴create_table.sql项目自带的db/init_db.bat就是为你这种场景设计的echo off echo 正在连接 MySQL 并创建数据库... mysql -u root -e CREATE DATABASE IF NOT EXISTS station_ticket DEFAULT CHARACTER SET utf8mb4; echo 数据库创建完成正在导入表结构... mysql -u root station_ticket db/create_table.sql echo 表结构导入完成正在插入示例数据... mysql -u root station_ticket db/insert_data.sql echo ✅ 初始化完成请启动 Java 程序。 pause双击运行这个.bat文件你会看到命令行快速滚动最后停在✅ 初始化完成请启动 Java 程序。。此时打开 MySQL执行USE station_ticket; SHOW TABLES;应该能看到user,train,station,ticket,order五张表。如果卡在某一步大概率是 MySQL 服务没开或 root 密码不对。3.3 启动 Java 程序从登录窗口到购票成功全流程演示项目入口类是src/ui/LoginFrame.java中的main方法。在 IDE 中右键该文件 →Run As→Java Application几秒后就会弹出登录窗口。首次登录账号admin / 123456管理员账号可管理用户、车次、车站普通用户账号user1 / 123456已预置在insert_data.sql中登录成功后进入主界面顶部菜单栏清晰列出功能车次管理管理员增删改查train表车站管理管理员维护station表余票查询所有用户SELECT * FROM ticket WHERE from_code? AND to_code? AND stock0我要购票所有用户选择出发站、到达站、日期列表显示可购车票点击“确定”生成订单血泪经验如果点击“我要购票”后弹出空列表不是程序 bug而是insert_data.sql中的ticket表数据from_code/to_code与station表code不匹配。打开db/insert_data.sql找到INSERT INTO station VALUES (GZ, 广州, 广州);这类语句再检查INSERT INTO ticket语句中from_code是否用了GZ而不是广州—— 这是广工学生最容易抄错的地方。4. 避坑指南广工学生实测踩过的 5 个坑现在帮你填平这个项目在广工多个班级流传我整理了近 3 年学生反馈最集中的 5 个问题。每一个都按“现象 → 原因 → 解决”给出可立即执行的方案不是泛泛而谈。4.1 现象运行init_db.bat报错 “‘mysql’ 不是内部或外部命令”原因系统环境变量PATH没有添加 MySQL 的bin目录路径导致命令行找不到mysql.exe。解决找到你的 MySQL 安装目录通常是C:\Program Files\MySQL\MySQL Server 5.7\bin右键“此电脑” → “属性” → “高级系统设置” → “环境变量” → 在“系统变量”中找到Path→ “编辑” → “新建” → 粘贴上述bin路径重启命令行窗口再运行.bat文件。4.2 现象Java 启动后登录窗口弹出但输入正确账号密码点击登录无反应控制台无任何报错原因resources/db.properties中urljdbc:mysql://localhost:3306/station_ticket?useSSLfalseserverTimezoneUTC的serverTimezone与你本地 MySQL 时区不一致。MySQL 5.7 默认时区是SYSTEM而某些 JDK 会强制校验。解决打开db.properties将serverTimezoneUTC改为serverTimezoneGMT%2B8URL 编码后的GMT8保存后重启 Java 程序。4.3 现象余票查询功能返回空列表但数据库里明明有数据原因TicketService.java中查询语句使用了PreparedStatement但setString()参数顺序与 SQL 中?位置不匹配。原代码是String sql SELECT * FROM ticket WHERE from_code ? AND to_code ? AND stock 0; ps.setString(1, toCode); // ❌ 错这里应该是 fromCode ps.setString(2, fromCode); // ❌ 错这里应该是 toCode解决交换两行setString的参数ps.setString(1, fromCode); // ✅ ps.setString(2, toCode); // ✅4.4 现象管理员删除车次后ticket表中关联该车次的票依然存在导致“脏数据”原因train表与ticket表之间虽有外键但create_table.sql中未设置ON DELETE CASCADE删除父记录时子记录不会自动清理。解决打开db/create_table.sql找到ticket表的外键定义修改为CONSTRAINT fk_ticket_train FOREIGN KEY (train_number) REFERENCES train (number) ON DELETE CASCADE然后重新运行init_db.bat初始化数据库。4.5 现象在 IDEA 中运行报错java.lang.ClassNotFoundException: com.mysql.jdbc.Driver原因MySQL Connector/J 8.x 驱动类名已改为com.mysql.cj.jdbc.Driver但项目仍使用老版本5.1.47其驱动类名为com.mysql.jdbc.Driver。若你误换了新版 jar就会报此错。解决删除lib/下所有 mysql-connector-jar确认lib/下只有mysql-connector-java-5.1.47.jar检查src/util/DBUtil.java中Class.forName(com.mysql.jdbc.Driver);这行是否被改成cj版本若是改回原样。5. 二次开发实战加一个“退票”功能从需求分析到代码落地现在系统能买票但不能退票——这在广工课设里是个典型的加分项。我带你从零开始把这个功能加进去。整个过程不超过 30 分钟而且每一步都对应数据库课设的考核点新增表字段、扩展业务逻辑、修改 UI、事务一致性保障。5.1 需求分析与数据库变更给order表加“退票时间”和“退票状态”当前order表只有status字段paid/cancelled但“退票”需要区分“用户主动退”和“系统取消”。我们新增两个字段refund_timeDATETIME NULL记录退票时间NULL 表示未退票refund_statusENUM(not_refunded,refunded,failed) DEFAULT not_refunded退票状态支持后续扩展比如退款失败重试。执行以下 SQL直接粘贴到 MySQL 命令行ALTER TABLE order ADD COLUMN refund_time DATETIME NULL COMMENT 退票时间, ADD COLUMN refund_status ENUM(not_refunded,refunded,failed) DEFAULT not_refunded COMMENT 退票状态;提示广工老师喜欢看到你在报告里写“字段设计依据”。这里可以写“refund_time用于审计退票行为refund_status支持未来对接支付系统退款状态回调体现系统可扩展性”。5.2 业务逻辑层扩展在OrderService.java中添加refundOrder方法在src/service/OrderService.java中新增方法。注意退票不是简单删订单而是要恢复ticket.stock并更新订单状态必须用事务public boolean refundOrder(String orderNo) { Connection conn null; PreparedStatement ps1 null; PreparedStatement ps2 null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); // 开启事务 // 1. 查询该订单对应的 ticket_id 和当前 stock String selectSql SELECT o.ticket_id, t.stock FROM order o JOIN ticket t ON o.ticket_id t.id WHERE o.order_no ?; ps1 conn.prepareStatement(selectSql); ps1.setString(1, orderNo); ResultSet rs ps1.executeQuery(); if (!rs.next()) { throw new RuntimeException(订单不存在 orderNo); } int ticketId rs.getInt(ticket_id); int currentStock rs.getInt(stock); // 2. 更新 ticket.stock恢复一张票 String updateTicketSql UPDATE ticket SET stock ? WHERE id ?; ps2 conn.prepareStatement(updateTicketSql); ps2.setInt(1, currentStock 1); ps2.setInt(2, ticketId); int updateTicketRows ps2.executeUpdate(); if (updateTicketRows ! 1) { throw new RuntimeException(更新余票失败); } // 3. 更新 order 表设置 refund_time 和 refund_status String updateOrderSql UPDATE order SET refund_time NOW(), refund_status refunded, status cancelled WHERE order_no ?; ps1 conn.prepareStatement(updateOrderSql); ps1.setString(1, orderNo); int updateOrderRows ps1.executeUpdate(); if (updateOrderRows ! 1) { throw new RuntimeException(更新订单状态失败); } conn.commit(); // 提交事务 return true; } catch (Exception e) { if (conn ! null) { try { conn.rollback(); // 回滚 } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); return false; } finally { DBUtil.close(ps1, ps2, conn); } }5.3 UI 层改造在订单列表界面增加“退票”按钮打开src/ui/OrderListFrame.java管理员查看所有订单的窗口找到表格下方的按钮面板在“删除”按钮旁边加一个“退票”按钮JButton btnRefund new JButton(退票); btnRefund.addActionListener(e - { int selectedRow table.getSelectedRow(); if (selectedRow -1) { JOptionPane.showMessageDialog(this, 请先选择一个订单); return; } String orderNo (String) table.getValueAt(selectedRow, 0); // 假设第一列是 order_no OrderService service new OrderService(); if (service.refundOrder(orderNo)) { JOptionPane.showMessageDialog(this, 退票成功余票已恢复。); loadData(); // 刷新表格 } else { JOptionPane.showMessageDialog(this, 退票失败请检查日志。); } }); buttonPanel.add(btnRefund);5.4 验证与测试三步确认退票功能真正可用数据验证登录管理员账号进入订单管理找一个statuspaid的订单点击“退票”数据库验证打开 MySQL执行SELECT order_no, status, refund_status, refund_time FROM \order WHERE order_no ORD20240501001;确认refund_statusrefunded且refund_time 有值业务验证回到余票查询选择同一趟车次的相同区间确认stock数值比退票前增加了 1。从那以后我每次加新功能都强制走一遍“数据库变更 → DAO/Service 层编码 → UI 绑定 → 手动 SQL 验证”四步闭环。不是为了炫技而是因为广工数据库课设答辩时老师最爱问“你这个退票是怎么保证票数不超卖的”——答案不在 PPT 里而在你conn.setAutoCommit(false)那行代码和rollback()的兜底逻辑里。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
Voxtral TTS:3秒语音克隆技术的突破与应用 1. 语音克隆技术的新里程碑:Voxtral TTS深度解析上周测试Mistral AI最新发布的Voxtral TTS时,我用同事的3秒语音片段生成了几乎无法辨别的克隆音频,连他本人都震惊得说不出话。这个突破性的语音合成系统正在彻底改变我们对声音复制的认知边界… · 2026/11/4 17:08:00
BDU技术演进:从电池开关到ASIL-D级安全核心 简介:本资源是一份聚焦电池包断路单元(BDU)领域的专业行业研究报告,面向新能源汽车零部件研发工程师、电池系统集成商、行业分析师及高校相关专业研究者,用于快速掌握BDU全球市场格局、技术演进趋势与头部厂商竞争态势… · 2026/11/4 17:08:00
强化学习KL散度:约束、正则还是度量?策略优化中的正确用法与调参经验 强化学习里的KL散度,是个特别容易被“用错但看起来没错”的东西。我见过不少做策略优化的朋友,代码里加了一行KL惩罚项,训练日志上KL值也确实在动,但策略该崩还是崩,该不收敛还是不收敛。问题往往不在KL本身࿰… · 2026/11/4 17:08:00
技术博客从零搭建:静态站点、自动部署与SEO收录实战 先说一个我观察到的现象:大部分人的技术博客死在第 7 天,而不是死在第 700 天。搭建本身只花了两个晚上,第三次更新之后就再也没有打开过那个仓库。原因通常不是懒,而是搭建阶段做了一堆当时觉得"很专业"、事后全变成阻… · 2026/11/4 17:52:57
SQL Server 2012 32位安装教程:配置检查与避坑清单 简介:这份 PDF 图解教程面向准备在 Windows 7 SP1 32 位环境部署 SQL Server 2012 的初学者与运维人员,重点介绍安装前环境确认、安装包选择、系统配置检查、实例与服务器配置、身份验证模式以及数据库引擎设置等关键环节,并通过分步截图和界… · 2026/11/4 17:52:57
Vue 3 Teleport组件:DOM传送门实战指南 1. Vue Teleport 是什么?Vue Teleport 是 Vue 3 内置的一个组件功能,它允许你将模板中的一部分内容"传送"到 DOM 树的其他位置。想象一下,就像科幻电影里的传送门一样,你可以把组件的一部分"传送"到任何你想放… · 2026/11/4 17:52:57
32位Win7安装SQL Server 2012:介质、实例与sa配置避坑 简介:SQL Server 2012 安装图解教程以单份 PDF 形式呈现,面向初次接触微软数据库、需在 Windows 7 SP1 32 位等环境中完成部署的开发者与运维学习者,帮助其建立安装流程的整体认识,减少环境准备阶段的盲目尝试。压缩包内仅含 1 个… · 2026/11/4 17:52:57
Windows下GCC工具链怎么选:MinGW、TDM-GCC与MSYS2 去年帮一个做桌面工具的小团队收拾构建环境,代码在 Linux 上一路绿灯,拿到 Windows 上就全是毛病:链接阶段报undefined reference to __imp_...,编译出来的程序双击闪退提示找不到libstdc-6.dll,最离谱的是一个std::th… · 2026/11/4 17:52:57
网络安全行业趋势与零信任架构实践指南 1. 行业现状与挑战网络安全行业近年来呈现爆发式增长态势,全球市场规模预计将在2026年突破3000亿美元。这个数字背后反映的是数字化转型浪潮下,企业对安全防护的刚性需求。但与此同时,行业也面临着前所未有的挑战。从技术层面来看,… · 2026/11/4 17:51: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/4 3:16:49
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/4 6:59:29
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/4 7:02:38
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战: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/4 3:16:49
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/4 6:59:29
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/4 7:02:38