博客系统架构与设计

2026年6月23日 blogTech 24 分钟阅读 7 次阅读
📖 文章摘要

详细的技术架构文档:系统设计、请求流程、数据库表结构、API 接口、前端页面路由、样式体系、目录结构。

Blog 项目架构与开发部署文档

blog.vue2.xyz — 个人博客系统
技术栈:Nuxt.js 3 (SSR) + FastAPI + SQLite
文档日期:2026-06-23


1. 项目概况

个人博客系统,支持文章发布、标签分类、评论审核、全文搜索、RSS 订阅、后台管理、临时网盘等功能。部署在韩国首尔服务器(<服务器IP>),与 MyChat 项目同机共存。


2. 技术栈

层级 技术 说明
前端框架 Nuxt.js 3 (SSR) Vue 3 全栈框架,服务端渲染支持 SEO
样式 Tailwind CSS 响应式设计,参考 MapleBlog 毛玻璃质感
后端框架 FastAPI (Python) 类型安全,自动 Swagger 文档
数据库 SQLite + SQLAlchemy 单用户博客零运维成本
WSGI 服务器 Gunicorn + Uvicorn 生产级 Python Web 服务
反向代理 Nginx HTTPS 卸载、静态文件直出、请求分发
进程管理 systemd blog-api、blog-web 各一个 service
认证 JWT (python-jose) 无状态 token,7 天有效期

3. 系统架构

请求流程

用户 → blog.vue2.xyz:443
           ↓
        Nginx (SSL 终止)
       /        |        \
      /api/*   /_nuxt/*   /(其他页面)
      |        |          |
   FastAPI   Nuxt SSR    Nuxt SSR
   :8001      :3000       :3000
      |        |             |
    SQLite   静态资源     FastAPI (SSR 时拉数据)
  1. 用户访问 https://blog.vue2.xyz/
  2. Nginx 443 端口接收,SSL 终止
  3. Nginx 路径分发:
    • /api/* → 反向代理到 FastAPI (127.0.0.1:8001)
    • /_nuxt/* → 反向代理到 Nuxt SSR (127.0.0.1:3000) 的构建资源
    • /uploads/* → Nginx 直出静态文件(缓存 3 天)
    • 其余路径 → Nuxt.js SSR (127.0.0.1:3000)
  4. Nuxt SSR 阶段,需要数据的页面(如文章详情)内部请求 FastAPI API
  5. FastAPI 操作 SQLite 数据库,返回 JSON
  6. Nuxt 将数据嵌入完整 HTML,返回给浏览器/爬虫

端口映射

服务 端口 绑定地址 说明
Nginx 443/80 0.0.0.0 HTTPS/HTTP,对外公开
FastAPI 8001 127.0.0.1 仅 Nginx 访问
Nuxt SSR 3000 127.0.0.1 仅 Nginx 访问
SSH 2894 0.0.0.0 非默认端口

4. 数据库设计

4.1 Article(文章)

字段 类型 说明
id INT PK 自增主键
title VARCHAR 文章标题
slug VARCHAR UNIQUE URL 标识
content_md TEXT Markdown 原文
content_html TEXT 缓存渲染后的 HTML
summary VARCHAR 摘要
cover_image VARCHAR 封面图 URL
category_id INT FK 所属分类
is_published BOOL 是否发布
is_top BOOL 是否置顶
allow_comment BOOL 允许评论
meta JSON 扩展信息
created_at DATETIME 创建时间
updated_at DATETIME 更新时间
published_at DATETIME 发布时间

4.2 Category(分类)

字段 类型 说明
id INT PK 自增主键
name VARCHAR 名称
slug VARCHAR URL 标识
description TEXT 描述
type VARCHAR 默认 'blog'

4.3 Tag(标签)

字段 类型 说明
id INT PK 自增主键
name VARCHAR 名称
slug VARCHAR URL 标识
type VARCHAR 默认 'blog'

4.4 Comment(评论)

字段 类型 说明
id INT PK 自增主键
article_id INT FK 所属文章
parent_id INT FK 父评论(楼中楼预留)
author VARCHAR 昵称
email VARCHAR 邮箱
content TEXT 评论内容
is_approved BOOL 审核通过
is_pinned BOOL 置顶
created_at DATETIME 创建时间

4.5 Admin(管理员)

字段 类型 说明
id INT PK 自增主键
username VARCHAR 用户名
password_hash VARCHAR 密码哈希(SHA256)
nickname VARCHAR 显示名
avatar VARCHAR 头像 URL

4.6 SiteSetting(站点配置 key-value)

常用 key 说明
site_name 站点名称
author_name 作者名
author_avatar 头像 base64 或 URL
author_tags 技能标签 JSON 数组
social_links 社交链接 JSON 数组
background_url 背景图 URL
github_url / email 旧版社交链接

4.7 Share(网盘文件)

字段 类型 说明
id INT PK 自增主键
file_name VARCHAR 原始文件名
file_path VARCHAR 服务器路径
file_size INT 字节数
password_hash VARCHAR 下载密码 SHA256
password_plain VARCHAR 下载密码明文
download_limit INT 下载限制(0=不限)
download_count INT 已下载次数
expire_at DATETIME 过期时间
created_at DATETIME 创建时间

4.8 DownloadLog(下载记录)

字段 类型 说明
id INT PK 自增主键
share_id INT FK 所属文件
downloaded_at DATETIME 下载时间

5. API 接口

公开接口

GET    /api/articles             文章列表(分页,支持 ?page=&size=&category=&tag=)
GET    /api/articles/{slug}      文章详情
GET    /api/categories           分类列表
GET    /api/tags                 标签列表
GET    /api/search?q=xxx         全文搜索
POST   /api/comments             提交评论
GET    /api/comments/{id}        评论列表
GET    /api/feed/rss             RSS 订阅
GET    /api/site                 站点信息(名称、头像、背景图等)
GET    /api/sitemap.xml          SEO sitemap

网盘接口

POST   /api/pan/upload                   上传(需管理员密码验证)
POST   /api/pan/{id}/verify              验证下载密码,返回临时 token
GET    /api/pan/{id}/download            下载文件(需 token,5min 有效)
GET    /api/pan                          文件列表(需 JWT)
GET    /api/pan/{id}/logs                下载记录(需 JWT)
DELETE /api/pan/{id}                     删除文件(需 JWT)

管理接口(需 JWT)

POST   /api/auth/login                   登录
POST   /api/auth/change-password         修改密码
POST   /api/admin/articles               创建文章
PUT    /api/admin/articles/{id}          编辑文章
DELETE /api/admin/articles/{id}          删除
GET    /api/admin/articles               列表(支持 ?q= 标题搜索)
PATCH  /api/admin/articles/{id}/publish  发布/下架
POST   /api/admin/categories             新增分类
DELETE /api/admin/categories/{id}        删除
POST   /api/admin/tags                   新增标签
DELETE /api/admin/tags/{id}              删除
GET    /api/admin/comments               评论列表
POST   /api/admin/comments/{id}/approve  审核通过
DELETE /api/admin/comments/{id}          删除
POST   /api/admin/upload                 上传图片(压缩 + quality 优化)
PUT    /api/admin/site                   更新站点配置

安全机制

  • JWT 7 天有效期,存 cookie
  • API 401 自动清除 cookie 跳转登录页
  • 评论默认不显示,需后台审核通过
  • 网盘双重验证:密码 → token(5min 窗口)→ 文件下载
  • 密码 SHA256 存储
  • 上传图片缩放 + quality 压缩

6. 前端页面

pages/
├── index.vue            首页(个人名片 + 文章瀑布流)
├── p/[slug].vue         文章详情(TOC + 分享 + 目录锚点)
├── categories.vue       分类列表
├── c/[slug].vue         分类文章列表(分页)
├── tags.vue             标签云
├── t/[slug].vue         标签文章列表(分页)
├── search.vue           搜索
├── about.vue            关于页
├── pan/
│   ├── index.vue        网盘上传(需管理员密码)
│   └── [id].vue         网盘下载(需密码验证)
└── admin/
    ├── login.vue        登录
    ├── index.vue        文章管理(搜索 + 列表)
    ├── edit/[id].vue    编辑器(分栏实时预览)
    ├── comments.vue     评论审核
    ├── pan.vue          网盘管理
    ├── settings.vue     站点设置(含修改密码)
    ├── categories.vue   分类管理
    └── tags.vue         标签管理

核心组件

组件 作用
AppHeader.vue 导航栏(桌面完整 + 移动端折叠菜单)
BackButton.vue 粘性返回按钮,根据路由名称显示对应标签
GlassCard.vue 毛玻璃卡片容器
BackToTop.vue 滚动 300px 后显示返回顶部按钮
ArticleCard.vue 文章摘要卡片(整张可点击)
ArticleMeta.vue 文章元信息(日期、阅读量、标签)
ContentRenderer.vue Markdown 转 HTML 渲染
TagBadge.vue 标签徽章(循环配色)
CommentSection.vue 评论区
SearchBar.vue 搜索输入框
ThemeToggle.vue 主题切换(亮/暗/跟随系统)
Pagination.vue 分页导航(7 页截断模式)

7. 样式体系

毛玻璃(Glassmorphism)

类名 blur 背景 用途
.glass 20px 18% 白 导航栏、主卡片
.glass-t 10px 10% 白 侧边栏、二级面板
.glass-l 5px 5% 白 标签、小元素
.glass-bare 8px 15% 白 浮动层
  • 双 inset 高光 + 弹性缓动曲线 cubic-bezier(0.175, 0.885, 0.32, 2.2)
  • SVG 液态玻璃滤镜(#glass-distortion):feTurbulence + feDisplacementMap
  • 渐变背景 #1a1a2e → #0d0d14,支持自定义背景图覆盖
  • 文章卡片渐入动画(stagger-fade-in),hover 悬停效果
  • 标签循环配色:6 种低饱和颜色轮换(blue/emerald/violet/amber/rose/cyan),20% 不透明度

8. 目录结构

<项目路径>\
├── frontend/
│   ├── pages/              # 14 个页面
│   │   ├── pan/            # 网盘页面
│   │   └── admin/          # 后台管理
│   ├── components/
│   │   ├── base/           # 通用组件(AppHeader, BackButton 等)
│   │   ├── blog/           # 博客组件(ArticleCard, CommentSection 等)
│   │   ├── search/         # 搜索组件
│   │   └── admin/          # 后台组件
│   ├── composables/        # useApi, useAuth
│   ├── layouts/            # default.vue, admin.vue
│   ├── middleware/         # auth.ts 路由守卫
│   ├── assets/css/         # main.css(毛玻璃 + 组件样式)
│   ├── public/             # robots.txt 等静态文件
│   └── nuxt.config.ts
├── backend/
│   ├── main.py             # FastAPI 入口 + CORS + 路由注册
│   ├── config.py           # 配置(DB、JWT、上传路径)
│   ├── database.py         # SQLAlchemy 引擎 + 会话管理
│   ├── models.py           # 8 个 ORM 模型
│   ├── schemas.py          # Pydantic 请求/响应模型
│   ├── auth.py             # JWT 认证工具
│   ├── routers/
│   │   ├── articles.py     # 公开文章接口
│   │   ├── categories.py   # 公开分类接口
│   │   ├── tags.py         # 公开标签接口
│   │   ├── comments.py     # 公开评论接口
│   │   ├── search.py       # 搜索接口
│   │   ├── feed.py         # RSS 订阅
│   │   ├── site.py         # 站点信息
│   │   ├── pan.py          # 网盘
│   │   ├── sitemap.py      # SEO
│   │   └── admin/          # 后台管理接口
│   ├── utils/markdown.py   # Markdown 渲染工具
│   └── requirements.txt
├── data/                   # 运行时数据(不提交 git)
│   ├── blog.db             # SQLite 数据库
│   ├── uploads/            # 上传的图片
│   └── pan/                # 网盘文件
├── deploy/
│   ├── deploy.py           # 一键部署工具
│   ├── sync-db.py          # 数据库同步(旧版,建议用 deploy.py)
│   ├── blog-api.service    # systemd 后端服务配置
│   ├── blog-web.service    # systemd 前端 SSR 服务配置
│   └── nginx-blog.conf     # Nginx 站点配置
├── docs/
│   └── architecture.md     # 本文档
├── start.bat               # 本地一键启动前后端
└── README.md

9. 本地开发

环境需求

  • Python 3.11+
  • Node.js 20+
  • npm

方式一:一键启动

双击 start.bat,同时启动后端(:8001)和前端(:3000)。

方式二:分别启动

后端:

cd <项目路径>\backend
source venv/Scripts/activate
uvicorn main:app --reload --host 0.0.0.0 --port 8001

前端:

cd <项目路径>\frontend
npm install
npm run dev

访问 http://localhost:3000,后台 http://localhost:3000/admin

注意: 本地开发通过 Vite proxy 转接 /api/uploads 到后端 8001 端口,无需 Nginx。

首次运行初始化

# 后端依赖
cd <项目路径>\backend
python -m venv venv
pip install -r requirements.txt

# 前端依赖
cd <项目路径>\frontend
npm install

10. 部署

详见 deploy.md — 包含服务器信息、首次部署、日常更新、数据库同步、服务器维护等完整流程。

快速部署

cd <项目路径>
python deploy/deploy.py

菜单选项:

  • 1 - 完整部署:构建前端 → 打包前后端 → SCP 上传 → 服务器解压重启
  • 2 - 数据库同步:下载(服务器→本地)/ 上传(本地→服务器)

11. 功能清单

前台

功能 说明
个人名片 毛玻璃卡片 + 头像 + 技能标签 + 社交图标
技能标签 后台可编辑,前台循环配色
社交图标 10+ 平台,后台管理增删
文章卡片 渐入动画 + 标签 + 蓝色边框悬停效果
文章目录 自动提取 h2-h4,锚点跳转带偏移补偿
返回顶部 滚动 300px 后出现
粘性返回按钮 根据路由显示对应上下文标签
毛玻璃质感 SVG 液态滤镜 + 双 inset 高光
页面动画 淡入 + 上移入场
分页导航 7 页截断模式(1 ... n-1 n n+1 ... last)
SEO Nuxt SSR + robots.txt + sitemap.xml
临时网盘 上传/密码验证/token 下载

后台

功能 说明
文章搜索 标题模糊搜索 + 防抖
Markdown 编辑器 分栏实时预览
文章状态 草稿 / 已发布 / 置顶
移动端适配 汉堡菜单 + 卡片式布局
评论审核 待审核 → 通过/删除
修改密码 需原密码验证
退出登录 清除 token + 跳转
401 自动跳转 全局 axios 拦截器
图片上传 gif/jpg/png/webp,自动缩放 + quality 优化
站点配置 名称/头像/背景图/技能标签/社交链接
网盘管理 查看文件/下载记录/复制链接/删除

12. 踩坑记录

  1. bcrypt 版本:passlib 1.7.4 与 bcrypt 5.x 不兼容,需 pip install bcrypt==4.0.1
  2. Node.js 版本:Nuxt 3.13+ 需要 Node.js ≥ v20,Ubuntu apt 上的 v18 不够,需从 nodesource 安装
  3. SQLAlchemy cascade:自引用 Comment.replies 的 cascade="all, delete-orphan" 会报错,去掉即可
  4. 相对导入from . import models 在 uvicorn main:app 模式下失败,需用绝对导入 import models
  5. Windows 路径:SQLite URL 需要 .as_posix() 转正斜杠
  6. 平台绑定依赖:npm install 在 Windows 上产生的 native binding,服务器上需 rm -rf node_modules package-lock.json 后重新 install
  7. Pydantic v2:NULL 值字段(如 summary=None)会被严格模式拒绝,schema 定义需设 = "" 默认值
  8. Nginx body 大小:默认 1MB,上传图片需在 server 块加 client_max_body_size 20m
  9. useAsyncData 分页:需要 { watch: [page] } 才能响应 query 变化重新 fetch
  10. CSS animation-fill-mode:stagger 动画中的 transform 会覆盖 hover transform,两种效果不要混在同一个属性上
  11. Windows 文件锁:SQLite 被本地 dev server 占用时不能 os.remove,改用 shutil.copy2 覆盖写入
  12. scp 路径格式:Git Bash 下用 MSYS2 路径(/d/Projects/...)或 cmd 格式(D:/...),不要混用

13. 后续规划

  • 评论楼中楼(Comment.parent_id 已预留)
  • 封面图管理(Article.cover_image 已预留,但编辑器未支持)
  • Docker 化部署
  • 数据库自动备份脚本
  • 日志轮转配置
  • 站点统计(PV/UV)
最后更新:2026年6月29日CC BY-NC-SA 4.0

评论

暂无评论,来写第一条吧

© 2026 My Blog. Built with Nuxt.js + FastAPI.