Skip to content

Commit 3569f58

Browse files
committed
refactor:优化文章结构展示
1 parent 04417d0 commit 3569f58

2 files changed

Lines changed: 228 additions & 5 deletions

File tree

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# OpenBlog —— 从零搭建的个人博客全栈实践
2+
3+
> 一个面向个人博客场景的现代化全栈项目,基于 Spring Boot 3 + Vue 3 构建,已上线运行于 [wecode.xin](https://www.wecode.xin/)
4+
5+
---
6+
7+
## 写在前面
8+
9+
作为一名开发者,我一直想拥有一个属于自己的博客空间——不只是为了写文章,更是为了亲手打造一个完整的、现代化的 Web 应用。于是,**OpenBlog** 诞生了。
10+
11+
这是一个从后端到前端、从数据库到缓存、从 SEO 到运维部署,全链路自研的个人博客系统。目前项目已开源在 GitHub([yyyCode/OpenBlog](https://github.com/yyyCode/OpenBlog.git)),线上站点 [wecode.xin](https://www.wecode.xin/) 稳定运行中。
12+
13+
本文将全面介绍 OpenBlog 的技术架构、功能设计与实现细节,希望能给同样想搭建个人博客的开发者一些参考。
14+
15+
---
16+
17+
## 项目概览
18+
19+
OpenBlog 定位为**面向个人博客场景的全栈项目**,覆盖了博客系统的完整功能链路:
20+
21+
| 模块 | 功能说明 |
22+
|------|----------|
23+
| 账号系统 | 注册、登录、JWT 双 Token 鉴权(Access + Refresh)、用户资料管理 |
24+
| 文章系统 | Markdown 撰写、草稿/发布/定时发布、导入/导出、全文搜索 |
25+
| 评论系统 | 文章评论、回复嵌套、删除管理 |
26+
| 互动系统 | 点赞、收藏、关注,完整的用户互动链路 |
27+
| 媒体管理 | 图片上传(支持粘贴/拖拽)、缩略图生成、媒体库浏览、一键插入 |
28+
| SEO 优化 | 爬虫动态 SSR、Open Graph / JSON-LD 结构化数据、sitemap.xml 自动生成、百度站长推送 |
29+
| 站点配置 | 后台可视化配置站点标题、描述、版权等全局信息 |
30+
| 管理后台 | 文章管理、用户管理、评论审核、反馈处理、附件管理、更新日志等 |
31+
| 个性化 | Live2D 看板娘、飞书风格主题、亮暗主题切换 |
32+
33+
---
34+
35+
## 技术栈一览
36+
37+
### 后端
38+
39+
| 技术 | 版本 | 用途 |
40+
|------|------|------|
41+
| Java | **17** | 运行环境 |
42+
| Spring Boot | **3.5.x** | 核心框架(Web、Security、Validation、Data JPA) |
43+
| MyBatis-Plus | **3.5.x** | ORM 增强(与 JPA 并存,按场景选用) |
44+
| MySQL | **8.0** | 关系型数据库,含 FULLTEXT 全文索引 |
45+
| Redis || 两级缓存、计数器去重、限流器 |
46+
| JWT (jjwt) | **0.12.x** | 无状态鉴权 |
47+
| MinIO || 对象存储(图片等二进制资源,可选本地文件系统) |
48+
| flexmark | **0.64.x** | 服务端 Markdown → HTML 预渲染 |
49+
| Thymeleaf || SEO 爬虫页面服务端渲染模板引擎 |
50+
| Thumbnailator || 图片缩略图生成 |
51+
| Caffeine || 本地缓存 |
52+
53+
### 前端
54+
55+
| 技术 | 版本 | 用途 |
56+
|------|------|------|
57+
| Vue | **3.5.x** | 前端框架 |
58+
| Vue Router | **4.x** | 前端路由 |
59+
| Vite | **8.x** | 构建工具 |
60+
| marked | **17.x** | Markdown 渲染(前端回退) |
61+
| DOMPurify | **3.x** | HTML 消毒,防止 XSS |
62+
| oh-my-live2d | **0.19.x** | Live2D 看板娘组件 |
63+
64+
### 自定义框架模块
65+
66+
项目拆分为多模块 Maven 工程,其中两个自研框架模块值得单独说明:
67+
68+
- **OpenBlog-framework-redis**:对 Redis 操作的统一封装,提供 `RedisOps` 接口(内置容错)、`RedisKeys` 统一 Key 管理、滑动窗口限流器等基础设施。业务模块不直接依赖 `StringRedisTemplate`
69+
- **OpenBlog-framework-elasticsearch**:预留的 Elasticsearch 集成模块,为后续搜索能力升级做准备。
70+
71+
---
72+
73+
## 架构设计亮点
74+
75+
### 1. 文章存储:元数据与正文分离
76+
77+
传统博客系统往往将文章标题、摘要、正文全部塞在一张表里。OpenBlog 采用了**分表存储**策略:
78+
79+
```
80+
┌─────────────────┐ ┌──────────────────────┐
81+
│ articles │ 1:1 │ article_bodies │
82+
│─────────────────│ │──────────────────────│
83+
│ id │────────→│ article_id │
84+
│ title │ │ content_markdown │ (MEDIUMTEXT)
85+
│ summary │ │ content_html │ (MEDIUMTEXT)
86+
│ status │ └──────────────────────┘
87+
│ category_id │
88+
│ author_id │
89+
│ view_count │
90+
│ like_count │
91+
│ ... │
92+
└─────────────────┘
93+
```
94+
95+
**设计收益:**
96+
- 列表查询只检索元数据表,不拖出正文大字段,查询更轻量
97+
- 正文独立做 FULLTEXT 全文索引,搜索更高效
98+
- 服务端发布时用 flexmark **预渲染** Markdown 为 HTML,前端直接展示,避免每次客户端解析
99+
100+
### 2. 缓存架构:两级缓存 + 版本号失效
101+
102+
已发布文章的读取链路使用 Redis 做两级缓存:
103+
104+
| 缓存层级 | TTL | 策略 |
105+
|----------|-----|------|
106+
| 文章正文缓存 | 30 分钟 | Cache-Aside:查无则回源 MySQL 并回写 |
107+
| 文章列表缓存 | 5 分钟 | **版本号机制**:写操作递增全局版本号,旧缓存自然过期 |
108+
109+
```
110+
读取流程:Redis → 命中返回 → 未命中查 MySQL → 回写 Redis
111+
写入流程:更新 MySQL → 删除/失效 Redis → 下次读取自动重建
112+
```
113+
114+
**版本号机制的巧妙之处**:文章列表缓存 Key 中携带 `v{version}`,发布/删除文章时只需 `INCR version`,旧版本缓存无需逐个清理,自然淘汰。
115+
116+
**故障降级**`RedisOps` 所有方法内置 try-catch,Redis 不可用时自动回退到数据库,不影响正常业务。
117+
118+
### 3. SEO 架构:动态 SSR 方案
119+
120+
SPA(单页应用)对搜索引擎不友好是个老问题。OpenBlog 没有采用 Nuxt.js 等重量级 SSR 框架,而是实现了一套**轻量级动态 SSR**
121+
122+
```
123+
爬虫请求 → Nginx(User-Agent 检测)
124+
├── 爬虫:转发到后端 SEO 控制器 → Thymeleaf 渲染 → 完整 HTML
125+
└── 普通用户:直接返回 Vue SPA
126+
```
127+
128+
配合以下组件形成完整 SEO 闭环:
129+
130+
- **Open Graph / Twitter Card**:文章详情页注入社交分享元标签
131+
- **JSON-LD 结构化数据**:帮助搜索引擎理解页面内容
132+
- **sitemap.xml**:自动生成,包含所有已发布文章 URL
133+
- **百度站长推送**:文章发布时异步调用百度 API,加速收录
134+
135+
### 4. 媒体管理:粘贴即上传
136+
137+
文章编辑器做了细致的产品体验打磨:
138+
139+
- 在编辑区 **Ctrl+V 粘贴截图****拖拽图片**,自动上传并插入 Markdown 图片语法
140+
- 工具栏「插入图片」按钮支持直接选文件
141+
- 「媒体库」弹窗浏览已上传图片,点击缩略图一键插入
142+
- 上传自动生成缩略图,全屏预览、一键复制 URL
143+
144+
---
145+
146+
## 项目结构一览
147+
148+
```
149+
OpenBlog/
150+
├── OpenBlog-framework-redis/ # Redis 框架封装(自研模块)
151+
├── OpenBlog-framework-elasticsearch/ # ES 集成预留(自研模块)
152+
├── OpenBlog-business/ # 业务主模块
153+
│ └── src/main/
154+
│ ├── java/com/yqz/openblog/
155+
│ │ ├── article/ # 文章:实体、服务、缓存、导入导出
156+
│ │ ├── category/ # 文章分类
157+
│ │ ├── changelog/ # 更新日志
158+
│ │ ├── comment/ # 评论系统
159+
│ │ ├── interaction/ # 互动(点赞/收藏/关注)
160+
│ │ ├── media/ # 媒体管理(MinIO/本地+缩略图)
161+
│ │ ├── user/ # 用户认证与 JWT
162+
│ │ ├── seo/ # SEO:SSR渲染、sitemap、百度推送
163+
│ │ ├── site/ # 站点全局配置
164+
│ │ ├── controller/ # REST 控制器
165+
│ │ └── config/ # Spring Security 等配置
166+
│ └── resources/
167+
│ ├── templates/seo/ # Thymeleaf SEO 模板
168+
│ └── sql/ # 数据库脚本
169+
├── vue/ # Vue 3 前端
170+
│ └── src/
171+
│ ├── api/ # HTTP 请求封装
172+
│ ├── views/ # 页面组件(含管理后台全套页面)
173+
│ ├── components/ # 通用组件(Live2D、评论、文章卡片等)
174+
│ └── layouts/ # 布局组件(公开页+控制台双布局)
175+
├── docs/ # 设计文档与规划
176+
└── pom.xml # 根 POM
177+
```
178+
179+
---
180+
181+
## 线上体验
182+
183+
OpenBlog 已部署上线,欢迎访问体验:
184+
185+
**线上地址:[https://www.wecode.xin/](https://www.wecode.xin/)**
186+
187+
你可以在这里:
188+
- 浏览已发布的文章,体验 Markdown 渲染效果
189+
- 感受飞书风格主题与亮暗模式切换
190+
- 查看 SEO 优化效果(右键查看源码,体验服务端渲染的结构化数据)
191+
- 与右下角 Live2D 看板娘互动
192+
193+
---
194+
195+
## 开源与贡献
196+
197+
项目完全开源,采用 Maven 多模块 + Vue 3 单页应用的经典前后端分离架构,适合作为个人博客搭建的参考实现,也适合 Java/Vue 开发者学习全栈项目实践。
198+
199+
**GitHub 仓库:[https://github.com/yyyCode/OpenBlog](https://github.com/yyyCode/OpenBlog.git)**
200+
201+
### 本地运行
202+
203+
```bash
204+
# 1. 准备 MySQL 8 数据库与 Redis
205+
206+
# 2. 启动后端(默认端口 8082)
207+
./mvnw spring-boot:run
208+
209+
# 3. 启动前端
210+
cd vue && npm install && npm run dev
211+
```
212+
213+
详细配置说明请参考仓库 [README](https://github.com/yyyCode/OpenBlog)
214+
215+
---
216+
217+
## 写在最后
218+
219+
OpenBlog 是我个人在博客系统领域的一次完整实践,从最初的文章发布,到后续逐步加入缓存优化、SEO 支持、媒体管理、管理后台、站点配置等能力,迭代过程中踩了不少坑,也学到了很多。
220+
221+
技术选型上,没有盲目追新,而是选用了 Spring Boot + Vue 这套成熟稳定的组合,把精力集中在**架构设计的合理性****产品体验的打磨**上——比如文章分表存储降低查询开销、版本号机制优雅处理缓存失效、粘贴即上传降低写作摩擦、动态 SSR 兼顾 SEO 与开发体验。
222+
223+
如果你也在搭建个人博客,或者想学习 Spring Boot 3 + Vue 3 的全栈项目实践,希望 OpenBlog 能给你带来一些启发。欢迎 Star、提 Issue、交流讨论!
224+
225+
---
226+
227+
*2026 年 7 月 · Spring Boot / Vue 3 / 全栈 / 个人博客 / 开源*

vue/src/assets/blog.css

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,11 +1284,7 @@ body {
12841284
display: flex;
12851285
flex-direction: column;
12861286
gap: 4px;
1287-
padding-left: 14px;
1288-
}
1289-
1290-
.article-tree-group-body .article-tree-group-body {
1291-
padding-left: 12px;
1287+
padding-left: 18px;
12921288
}
12931289

12941290
.article-tree-leaf {

0 commit comments

Comments
 (0)