我的被窝 · 个人博客系统
一个属于自己的内容阵地,从 0 到 1 跑通 Web 全链路,实现纯个人风格前后台博客
一、项目背景
2022 年底,在大二学完动态网页 与数据库基础之后,我需要一个能"把所学全部串起来"的实战项目。"我的被窝"这个名字来源于我希望拥有一个属于自己的、温暖的小角落——一个可以记录生活、整理学习笔记、分享作品的内容阵地。
选博客系统作为全栈入门项目,是因为它足够"小而全":既有前台的内容展示,又有后台的数据管理;既要处理静态资源,又要处理动态接口;既涉及用户权限,又涉及富文本与评论交互,它能完整覆盖 Web 开发的全链路。
二、技术选型与架构设计
技术选型的核心原则是"够用、好学、能跑通"。作为第一个全栈项目,没有引入 React/Vue 这类前端框架,而是选择了服务端渲染(SSR)的传统栈,把注意力集中在理解 HTTP、模板与数据库上。
| 层级 | 技术 | 选型理由 |
|---|---|---|
| 后端框架 | Express | Node.js 最轻量 Web 框架,路由/中间件模型清晰,上手成本低,社区资源丰富 |
| 模板引擎 | art-template | 性能高、语法接近原生 HTML,支持 include 公共组件复用,适合 SSR 场景 |
| 数据库 | MongoDB | 文档型存储,文章/评论结构灵活无需建表,MongoDBCompass 操作直观 |
| 前端交互 | jQuery | DOM 操作与 AJAX 简洁,避免在框架学习上分散精力,聚焦业务逻辑 |
| UI 框架 | Bootstrap | 响应式栅格 + 现成组件(模态框、表单、分页),快速搭建美观后台 |
2.1 整体技术架构
2.2 前后台架构
系统分为前台(访客视角)与后台(管理员视角)两套独立的页面与路由,共用同一套数据库。前台专注内容呈现与互动,后台专注内容生产与管理。
| 端 | 页面/模块 | 核心职责 |
|---|---|---|
| 前台 | 首页文章列表 | 分页展示最新文章,封面图 + 摘要 + 标签 |
| 文章详情页 | 正文渲染、目录锚点跳转、评论区 | |
| 百宝箱 | 个人收藏的资源、工具、书单整理 | |
| 留言板 | 访客公开留言,无需登录即可提交 | |
| 作品集 | 展示个人设计/开发作品的卡片墙 | |
| 后台 | 用户管理 | 用户增删改查、角色分配(普通/管理员) |
| 文章管理 | 文章发布、编辑、删除、状态切换 | |
| 分页模块 | 通用分页组件,复用于列表与后台 |
2.3 数据库 ER 设计
数据库围绕"用户 - 文章 - 评论 - 留言"四类核心实体设计,用户与文章为一对多,文章与评论为一对多,留言板独立。
populate 联表取出评论及评论者昵称,避免前端二次请求。
三、核心功能实现
3.1 文章 CRUD
文章的增删改查是后台的核心。通过 Express 路由 + mongoose 模型完成数据操作,art-template 渲染后台列表与编辑页。
3.2 用户权限与登录拦截
用户分为普通用户(role=0)与管理员(role=1)两种角色。登录成功后将用户信息存入 session,通过中间件统一拦截未登录与权限不足的访问。
3.3 评论系统
文章详情页底部嵌入评论区,登录用户可提交评论。评论通过文章 ID 关联,提交后实时追加到评论列表,并显示评论者昵称与头像。
- 提交:POST
/comment/add,携带 articleId 与 content - 展示:查询文章时 populate 关联 comments,按时间倒序渲染
- 防刷:未登录跳转登录页;内容为空前端拦截,不发起请求
3.4 分页模块
分页是博客列表与后台管理的高频需求,封装为通用组件,传入当前页、总条数、每页条数即可渲染。
| 参数 | 含义 | 示例 |
|---|---|---|
| page | 当前页码(从 URL query 取) | 1 |
| size | 每页条数 | 5 |
| total | 总条数(countDocuments 取) | 23 |
| totalPage | 总页数(Math.ceil 计算) | 5 |
skip((page-1)*size).limit(size) 完成 MongoDB 分页查询;前端用 art-template 循环生成页码按钮,当前页高亮、首末页禁用上下页。
3.5 密码 MD5 加密
密码绝不能明文入库。使用 MD5 对密码进行单向散列,登录时对输入密码同样做 MD5 后与数据库比对。
四、设计风格
功能是骨架,视觉是皮肤。除了把功能跑通,我在视觉设计上也花了大量心思——希望这个博客不仅"能用",更要"充满个人色彩"。
4.1 莫兰迪黄配色
摒弃常见的纯白 + 蓝色科技风,选了低饱和度的莫兰迪黄作为主色,营造出"午后阳光洒在被窝上"的温暖感,呼应"我的被窝"这个项目名。
4.2 圆角毛玻璃风格
卡片大量使用 backdrop-filter: blur() 实现毛玻璃质感,配合 12-16px 的大圆角,整体柔和不刺眼。
4.3 个人原创 LOGO
没有用现成的图标库,而是手绘了一个专属 LOGO——一个蜷缩在被窝里的小形象,呼应"我的被窝"主题。LOGO 用在线条简洁的单色版与带渐变的彩色版两种场景,分别用于导航栏与首页大图。
五、项目复盘与反思
"我的被窝"是我第一个真正意义上独立完成、并部署上线的全栈项目,第一次完整地走完了"需求 → 设计 → 开发 → 部署"的整个流程。
5.1 最大的收获
- 建立 Web 全链路理解:从浏览器发请求 → Express 路由 → 控制器 → MongoDB数据库 → 模板渲染 → 浏览器展示,每一段都自己深刻实践。
- 理解前后台分离的本质:虽然用的是 SSR,但通过这个项目理解了"为什么后来要前后端分离"——SSR 在交互复杂时会很笨重。
- 建立工程化意识:学会了用中间件复用逻辑、用 public 目录管理静态资源、用 session 管理登录态、用分页组件复用 UI。
- "产品化"思维:不只是写代码、想配色、想 LOGO,还要想用户看到这个页面是什么感受、如何交互、如何优化用户体验——这开启了后来做产品的工作方式。
5.2 不足与改进方向
| 问题 | 当时方案 | 改进方向 |
|---|---|---|
| 密码加密 | MD5(可被彩虹表反查) | bcrypt 加盐哈希 |
| 登录态 | session 存内存(重启丢失) | Redis / JWT |
| 前端交互 | jQuery + SSR | 前后端分离 + Vue/React |
| 评论防刷 | 仅前端非空校验 | 限流 + 验证码 + 敏感词过滤 |
| 图片存储 | 本地 public 目录 | 对象存储 OSS + CDN |
回看技术架构的演进理解:当时选择MongoDB是因为"文档型无需建表、上手快",但也因此缺乏关系建模的训练;后续在水土保持系统项目中切换到MySQL+严谨的ER设计,补上了这一课。