简介这份资源是面向Java Web初学者与课程实践者的个人博客系统完整源码基于SSH2SpringStruts2Hibernate3与Oracle数据库开发可用于毕业设计参考、框架整合练习或二次开发。系统功能覆盖首页展示、日志评论、用户登录与后台管理四大模块支持分类下日志的发布、编辑、删除、分页浏览及评论显示登录环节含随机验证码校验后台提供日志的增删改查与分页管理结构较为完整。压缩包为rar格式共159个文件、约1.51MB以gif界面素材、java源码、xml配置、class编译文件与jsp页面为主另含jar依赖、tld标签库、js脚本及properties配置便于对照学习分层设计与框架配置。目前已有1166人学习下载适合希望理解SSH2整合流程、掌握Oracle持久化与MVC分层实现的读者参考借鉴。1. 从一份博客源码说起为什么我建议你先跑通再谈二次开发去年帮一个朋友接手他的技术博客站点跑在某台快到期的小机器上数据库三天两头出问题后台编辑器还停留在十年前那种纯文本框。他丢给我一个压缩包说这是当年找人写的博客系统源码让我看看能不能救。我解压之后发现这套东西其实结构挺完整前台展示、后台管理、文章发布、分类标签、评论、归档该有的都有只是没人维护了。这件事让我意识到一个很现实的问题——很多人下载博客系统源码第一反应是打开编辑器从头读读了两小时就放弃了。正确的顺序应该是先把它跑起来看到页面能打开、能发文章、能评论再去拆它的路由和模型。这篇笔记就按这个顺序来先讲清这套博客系统能干什么、技术栈长什么样再带你把它在本机跑通最后落到二次开发时真正会改的那几个地方。关键词博客系统、博客源码说的就是这类自建站点项目适合想拥有独立写作空间、又不想被平台规则绑住的开发者。2. 项目定位与技术栈一套典型的前后端分离博客系统2.1 这套源码解决的是什么问题从功能面看这是一套完整的个人博客系统核心能力可以拆成四块。第一块是内容管理包括文章的增删改查、草稿与发布状态切换、Markdown 正文存储、封面图上传。第二块是组织维度文章可以挂分类也可以打多个标签前台按分类和标签做聚合页。第三块是读者侧交互文章详情页、评论提交与审核、按时间归档、全文搜索。第四块是后台登录鉴权、文章列表分页、站点基础配置站点名、副标题、备案信息位、社交链接。这四块基本覆盖了一个个人博客从写作到被阅读的完整闭环。它不适合做多人协作的内容平台也不适合做电商或社区定位就是单人维护、内容为主的轻量站点。判断一套博客源码值不值得用我一般看三点文章正文是不是以 Markdown 原文存储而不是存渲染后的 HTML评论有没有审核开关后台有没有做登录态校验。这三点决定了你后面改起来是顺手还是遭罪。2.2 技术栈拆解前端、后端、数据库各是什么角色这类博客系统源码常见的技术组合是「前端框架 后端 API 关系型数据库」的前后端分离结构。前端负责页面渲染和路由后端只吐 JSON数据库存文章和评论。下面这张表是我按这套源码的实际结构整理的你拿到压缩包后可以对照着确认层次常见技术选型在这套系统里的职责前端框架Vue 或 React 单页应用首页列表、文章详情、归档、后台管理界面前端路由vue-router / react-router前台页面切换、后台菜单跳转HTTP 客户端axios / fetch 封装统一请求拦截、携带登录 token后端框架Node.jsExpress/Koa或 PythonFlask/FastAPI提供 REST 接口、处理业务逻辑数据库MySQL 或 SQLite存文章、分类、标签、评论、用户鉴权JWT 或 Session后台登录态校验静态资源本地 uploads 目录或对象存储封面图、头像需要说明的是具体是 Vue 还是 React、是 Express 还是 Flask要以你手上这份源码的 package.json 或 requirements.txt 为准。我见过不少下载来的博客源码前端用 Vue2、后端用 Express这种组合在 2020 年前后特别常见跑起来不难但依赖版本要留意后面避坑章节会专门讲。2.3 目录结构先认清哪几个文件夹是核心解压之后不要急着看文件先看目录层级。一套典型的前后端分离博客源码根目录下通常是这样分的blog-system/ ├── client/ # 前端工程 │ ├── src/ │ │ ├── views/ # 页面级组件首页、文章详情、归档、后台 │ │ ├── components/ # 复用组件文章卡片、评论列表、分页器 │ │ ├── router/ # 前端路由表 │ │ ├── api/ # 接口请求封装按模块拆分 │ │ └── store/ # 全局状态登录用户、站点配置 │ └── package.json ├── server/ # 后端工程 │ ├── routes/ # 路由层article、category、comment、auth │ ├── controllers/ # 业务逻辑层 │ ├── models/ # 数据模型与数据库操作 │ ├── middleware/ # 鉴权、错误处理、日志 │ ├── uploads/ # 上传的图片落盘目录 │ └── app.js # 服务入口 ├── sql/ # 建表脚本与初始数据 └── README.md认清三个位置就够了server/routes决定有哪些接口server/models决定数据怎么存client/src/views决定页面长什么样。二次开发 80% 的改动都落在这三处。我一般会先把sql/里的建表脚本打开看一遍表结构清楚了后面读代码就顺了。3. 把项目跑起来环境准备、依赖安装与数据库初始化3.1 环境准备版本对齐比装最新版更重要跑这类老项目最容易翻车的地方不是代码是环境版本。前端如果是 Vue2 时代的工程Node 版本建议控制在 16 或 18用 Node 20 以上经常会在装依赖时报一堆 peer dependency 冲突。后端如果是 Python先看requirements.txt里有没有钉版本号有就按它来没有就用 3.8 到 3.10 之间的版本太新的解释器容易遇到某些包不兼容。我一般的做法是先确认三件事Node 版本、包管理器、数据库是否已启动。命令如下# 确认 Node 与 npm 版本老项目建议 Node 16/18 node -v npm -v # 如果项目里有 .nvmrc直接按它切换 cat .nvmrc # 确认数据库服务在跑以 MySQL 为例 mysql --version参数说明node -v看的是运行时版本npm -v看的是包管理器版本两者不匹配时优先降 Node。如果源码里带了package-lock.json就用npm ci而不是npm install前者严格按锁文件装能避免依赖漂移。这一步看着琐碎但它是后面所有步骤的地基。3.2 数据库初始化建库、导表、改连接配置数据库是这类项目跑不起来的头号原因。sql/目录下通常有一个init.sql或schema.sql里面是建表语句和少量初始数据比如默认管理员账号、默认分类。导入顺序是先建库、再导表# 登录 MySQL 并创建数据库字符集用 utf8mb4 以支持 emoji mysql -u root -p -e CREATE DATABASE blog_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 导入建表脚本 mysql -u root -p blog_db sql/init.sql # 确认表已建好 mysql -u root -p blog_db -e SHOW TABLES;导完之后要改后端的数据连接配置。这类配置一般放在server/config/db.js或.env文件里字段通常是 host、port、user、password、database 五项。常见做法是把这些抽到.env代码里用process.env.DB_HOST读取这样本地和线上不用改代码。如果你拿到的源码是硬编码在文件里的建议顺手改成环境变量后面部署会省很多事。提示导入脚本前先看一眼文件开头有没有CREATE DATABASE和USE语句。有的话直接整文件导入即可没有的话必须先手动建库否则会报「No database selected」。3.3 启动前后端两个终端、两个端口前后端分离项目要起两个进程。后端一般监听 3000 或 5000前端开发服务器监听 8080 或 5173。启动顺序建议先后端再前端因为前端启动时如果配了接口代理后端没起来会在控制台刷一堆连接失败。# 终端一启动后端 cd server npm install # 或 pip install -r requirements.txt npm run dev # 常见脚本名dev / start # 终端二启动前端 cd client npm install npm run serve # Vue CLI 项目Vite 项目是 npm run dev启动后打开浏览器访问前端地址能看到首页列表就说明链路通了。如果首页空白但控制台没报错多半是接口返回了空数组去数据库确认文章表里有没有数据。如果控制台报跨域检查前端vue.config.js或vite.config.js里的 proxy 配置把/api代理到后端端口。这一步跑通整个项目就算活了。3.4 后台登录与第一篇测试文章前台能打开只是第一步真正验证系统完整性要看后台能不能发文。访问/admin或/login路径进入后台用init.sql里的默认账号登录常见是 admin / 123456具体以脚本为准。登录成功后先改密码再发一篇测试文章正文里写一段 Markdown保存后回前台看渲染效果。// 前端 api/article.js 里常见的发文请求封装 import request from /utils/request // 创建文章title 标题content 为 Markdown 原文categoryId 分类tags 标签数组 export function createArticle(data) { return request({ url: /api/article, method: post, data }) }这段代码说明发文走的是 POST/api/article请求体里带标题、正文、分类和标签。如果保存成功但前台看不到先查文章状态字段是不是「草稿」再查列表接口有没有按发布时间倒序过滤。这两个点是最常见的「发了但没显示」的原因。4. 核心模块拆解文章、评论、鉴权三条主链路4.1 文章模块从建表到列表接口的完整链路文章是整个系统的核心表。一套合格的博客源码文章表至少要有这些字段主键 id、标题 title、正文 content存 Markdown 原文、摘要 excerpt、封面 cover、分类 category_id、状态 status0 草稿 / 1 发布、浏览量 views、创建时间 created_at、更新时间 updated_at。标签因为是多对多通常单独建一张标签表和一张关联表。后端列表接口的典型实现是先查总数再分页查数据两个查询放在一起返回前端才能渲染分页器// server/controllers/article.js // 文章列表支持按分类、标签、关键词筛选分页返回 async function listArticles(req, res) { const page parseInt(req.query.page) || 1 const size parseInt(req.query.size) || 10 const offset (page - 1) * size const { categoryId, keyword } req.query // 动态拼 where 条件避免 SQL 注入用占位符 let where WHERE status 1 const params [] if (categoryId) { where AND category_id ? params.push(categoryId) } if (keyword) { where AND title LIKE ? params.push(%${keyword}%) } const total await db.queryOne(SELECT COUNT(*) AS c FROM article ${where}, params) const rows await db.query( SELECT id, title, excerpt, cover, views, created_at FROM article ${where} ORDER BY created_at DESC LIMIT ? OFFSET ?, [...params, size, offset] ) res.json({ code: 0, data: { list: rows, total: total.c, page, size } }) }逻辑说明先算 offset再拼 where 条件所有用户输入都用?占位符传参这是防注入的基本功。返回结构统一成{ code, data }前端拦截器按 code 判断成功与否。参数上page和size决定分页categoryId和keyword是可选的筛选条件。这里有个细节值得注意列表查询只 select 了摘要字段没有把 content 一起查出来因为正文可能很长列表页用不上这是性能上的常见做法。4.2 评论模块审核开关与防刷是重点评论模块看着简单实际是博客系统里最容易出问题的地方。合格的实现要有三层提交时校验文章是否存在、内容长度是否合规入库时默认状态为待审核展示时只查已审核通过的评论。很多下载来的源码为了演示方便把审核开关去掉了直接提交即显示这种上线后很快会被灌垃圾评论。// server/controllers/comment.js // 提交评论默认待审核status0 async function addComment(req, res) { const { articleId, nickname, email, content } req.body if (!content || content.length 500) { return res.json({ code: 1, msg: 评论内容需在 1-500 字之间 }) } const article await db.queryOne(SELECT id FROM article WHERE id ? AND status 1, [articleId]) if (!article) { return res.json({ code: 1, msg: 文章不存在 }) } await db.query( INSERT INTO comment (article_id, nickname, email, content, status, created_at) VALUES (?, ?, ?, ?, 0, NOW()), [articleId, nickname, email, content] ) res.json({ code: 0, msg: 评论已提交审核后展示 }) }逻辑说明先做长度校验再确认文章存在且已发布最后以status 0入库。参数里 nickname 和 email 是读者填的content 是正文。前台查询评论时一定要带WHERE status 1否则待审核的评论会直接暴露。防刷方面常见做法是按 IP 做频率限制比如同一 IP 一分钟内最多提交三条这个可以在中间件层加不必写进业务代码。4.3 鉴权链路JWT 从登录到接口校验后台所有写操作都必须过鉴权。这套源码常见的是 JWT 方案登录接口校验账号密码通过后签发 token前端存起来之后每个请求在 header 里带上Authorization: Bearer xxx后端中间件解析 token 并挂到req.user上。// server/middleware/auth.js const jwt require(jsonwebtoken) // 鉴权中间件校验请求头里的 token function auth(req, res, next) { const header req.headers.authorization || const token header.startsWith(Bearer ) ? header.slice(7) : if (!token) { return res.status(401).json({ code: 401, msg: 未登录 }) } try { // SECRET 从环境变量读取不要硬编码 req.user jwt.verify(token, process.env.JWT_SECRET) next() } catch (e) { return res.status(401).json({ code: 401, msg: 登录已过期 }) } }逻辑说明先从 header 里截出 token没有就直接 401有则用密钥验签失败也返回 401。参数上JWT_SECRET必须放环境变量硬编码在代码里等于把钥匙挂在门上。这个中间件挂在后台路由组上比如router.post(/article, auth, createArticle)前台公开接口不挂。改密码或强制下线时JWT 方案没法主动失效单个 token常见做法是缩短过期时间或者维护一个黑名单这一点在二次开发时要心里有数。5. 避坑与排查跑不起来时先看这几处5.1 依赖装不上Node 版本与锁文件冲突现象npm install报一堆ERESOLVE或 peer dependency 错误装到一半退出。原因通常是项目基于老版本 Node 和旧依赖树新版 npm 对 peer 依赖校验更严。解决办法有两个一是降 Node 到 16/18二是用npm install --legacy-peer-deps跳过严格校验。如果项目带了package-lock.json优先npm ci它按锁文件装不会重新解析依赖树。我一般先试npm ci失败再降版本最后才用 legacy 参数因为跳过校验可能装出不兼容的组合。5.2 页面空白接口地址与代理没对上现象前端能启动浏览器打开一片空白控制台报 404 或跨域。原因多半是前端请求的 baseURL 和后端实际端口不一致或者开发代理没配。解决打开client/src/utils/request.js看 baseURL再对照后端app.js里的监听端口如果是跨域在vue.config.js的devServer.proxy里把/api指到后端地址。改完要重启前端开发服务器代理配置不热更新。5.3 图片上传失败目录权限与静态托管现象后台选图上传报 500或者上传成功但前台图片裂开。原因一是server/uploads目录不存在或没有写权限二是后端没有把 uploads 目录托管成静态资源。解决手动建目录并给写权限再在app.js里加app.use(/uploads, express.static(uploads))。如果部署在容器里还要确认目录是挂载出来的否则重启后图片全丢。5.4 中文乱码字符集没统一现象文章标题或评论里的中文变成问号或乱码。原因通常是数据库、表、连接三处字符集不一致。解决建库时用utf8mb4建表也指定utf8mb4后端连接配置里加charset: utf8mb4。三处都对齐才不会出问题。这个坑我踩过不止一次尤其是从别人那拿来的 sql 脚本开头没写字符集导入后就埋了雷。5.5 后台能登录但接口 401token 没带上现象登录成功跳转后台后每个请求都返回 401。原因一般是前端请求拦截器没把 token 塞进 header或者存储的 key 和后端读取的不一致。解决检查request.js的请求拦截器确认从 localStorage 取 token 后拼成Bearer xxx再确认后端中间件截取的前缀一致。两边对不上token 等于没带。6. 二次开发从改一个字段到加一个新模块的实操思路二次开发最忌讳一上来就大改。我的习惯是先做一次「最小改动验证」挑一个字段从数据库改到前端展示完整走一遍链路确认自己理解了数据是怎么流的。比如给文章加一个「置顶」功能改动点其实很清晰文章表加is_top字段列表接口的排序改成ORDER BY is_top DESC, created_at DESC后台表单加一个开关前台卡片加一个置顶标识。这四步走完你就摸清了这套系统的改法。具体到代码排序这一处是核心-- 文章表增加置顶字段默认 0 ALTER TABLE article ADD COLUMN is_top TINYINT NOT NULL DEFAULT 0 COMMENT 是否置顶; -- 列表查询改为置顶优先再按时间倒序 SELECT id, title, excerpt, cover, views, is_top, created_at FROM article WHERE status 1 ORDER BY is_top DESC, created_at DESC LIMIT ? OFFSET ?;改完 SQL 要同步改三处后端列表接口的 select 字段和 order by、后台编辑页的表单字段、前台卡片的渲染逻辑。少改一处就会出现「后台能设置但前台不生效」的情况。这类联动改动我一般会列一个清单改完逐项打勾比凭记忆靠谱。再往上一层是加新模块比如「友链」页面。思路是照抄现有模块的结构建friend_link表写routes/friendLink.js和对应 controller前端加一个views/FriendLink.vue和路由。照抄的好处是风格统一、鉴权中间件直接复用不用重新设计。加模块时唯一要注意的是路由注册顺序后台鉴权路由要挂在 auth 中间件之后公开路由挂在之前挂错了要么后台接口裸奔要么前台接口被拦。验证改动是否生效我有一套固定动作先看数据库字段有没有写进去再看接口返回的 JSON 对不对最后看页面渲染。三层都过才算改完。只看页面很容易被缓存骗过去尤其是前端打包后的静态资源浏览器缓存没清会看到旧版本白白排查半天。还有一个容易被忽略的点是配置外置。这套源码里如果有硬编码的站点名、分页大小、上传大小限制二次开发时顺手抽到配置文件或环境变量里。我吃过亏一个分页大小写死在三个文件里后来要改成 20漏改一处前台和后台分页对不上排查了半小时才发现是同一个数字。从那以后我每次动这类常量都先全局搜一遍再改改完再搜一遍确认没有漏网。希望这些经验能帮到你少走点弯路。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
LabVIEW软件授权管理:时间锁死与序列号验证技术详解 1. 项目背景与需求解析在工业自动化领域,LabVIEW作为图形化编程的标杆工具,被广泛应用于测试测量、设备控制等场景。但软件交付后的授权管理一直是开发者面临的痛点——尤其当遇到恶意拖欠尾款的客户时,传统授权方式往往束手无策。这个模块正… · 2026/11/7 5:12:26
拓扑排序算法详解:从课程表问题到工程实践 ## 1. 问题背景与需求解析这道题来自LeetCode第210题"课程表II",属于经典的拓扑排序应用场景。我在实际面试中至少遇到过5次不同公司对该问题的变体考察,它完美检验了开发者对图论基础算法的掌握程度。题目要求我们模拟大学课程选修系统&#… · 2026/11/6 4:00:24
Clonezilla Live磁盘克隆实战:U盘启动、镜像还原与批量部署避坑 简介:面向服务器运维人员、系统管理员及有整机迁移与灾难恢复需求的用户,这份资源提供开源克隆工具再生龙(Clonezilla Live)2.7.0-10 的 AMD64 镜像,适用于 64 位计算机的磁盘与分区备份、系统克隆和数据保护ÿ… · 2026/11/6 4:00:24
江西通用电工证千万别踩坑,这些坑你真的避开了吗 江西通用电工证千万别踩坑,这些坑你真的避开了吗 不知道去哪报名怕被中介坑?江西通用电工证千万别踩坑,别让不靠谱的机构耽误你的时间和钱。现在很多人在办理江西通用电工证时,总是在网上被各种信息误导,甚至被中介坑得一塌糊涂。下面我从江西本地实际操… · 2026/11/8 0:55:41
工地太忙根本没时间复习考试,钢丝钳电工作业作用和多少钱全讲透 工地太忙根本没时间复习考试,钢丝钳电工作业作用和多少钱全讲透 你是不是也这样?工地天天赶工期,白天巡检,晚上盯进度,哪还有时间复习考试?特种作业操作证这事,拖着拖着就忘了。特别是像钢丝钳电工作业这种,看似简单,实则讲究,操作不当,分分钟出问… · 2026/11/8 0:55:41
北京地区电工证考试在哪考?实操考试心里没底怕挂科怎么办 北京地区电工证考试在哪考?实操考试心里没底怕挂科怎么办 实操考试心里没底怕挂科,这是很多人在准备【北京地区电工证考试】时最真实的感受。尤其是对于第一次报考或需要复审的学员,面对复杂的流程、严格的考试要求,心理压力很大。而“在哪考”这个问题,… · 2026/11/8 0:55:41
特种工包过多少钱官方报名入口怎么找不被坑 特种工包过多少钱官方报名入口怎么找不被坑 你是不是也遇到过这种情况?找培训机构报名特种工考试,结果花了大价钱,结果考试还是没过,连报名流程都搞不清楚?别急,这正是很多人在报考【特种工包过多少钱】时最担心的问题。今天就从濮阳一位学员的真实经历… · 2026/11/8 0:55:41
社会人电工证怎么考郑州报考避坑指南 社会人电工证怎么考郑州报考避坑指南 之前考的证在外省能不能转过来?这个问题我天天在郑州金水区的项目现场听到。别急,今天就带你搞清楚【社会人电工证怎么考】,还有郑州本地报考的避坑指南,帮你少走弯路。 一、社会人电工证到底值不值得考?… · 2026/11/8 0:55:41
办理溧阳金梧路电工证需要什么材料 电工证实操考试怕挂科?听过来,真实经历告诉你怎么稳过 实操考试心里没底怕挂科?别慌,我也是从零开始考过溧阳金梧路电工证的,今天就把我的真实经历和备考心得一五一十告诉你,帮你少走弯路,稳稳拿下证书。 一、电工证到底考什么?先搞清楚范围… · 2026/11/8 0:54:40
电工证丢失还能补吗?千万别踩坑,丢了证等于失业 电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/8 0:00:20
电力电缆作业证直播报名入口与办理流程良心建议 电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/8 0:00:20
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/8 0:00:20
电工证丢失还能补吗?千万别踩坑,丢了证等于失业 电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/8 0:00:20
电力电缆作业证直播报名入口与办理流程良心建议 电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/8 0:00:20
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/8 0:00:20
双极步进电机控制实战: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/7 11:25:08
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/7 12:02:18
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/6 10:29:23