# BLOG_PROJECT **Repository Path**: testPan/blog_project ## Basic Information - **Project Name**: BLOG_PROJECT - **Description**: 博客实践自用 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-26 - **Last Updated**: 2025-11-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 现代化博客系统 一个基于 Vue3 + FastAPI 的现代化博客系统,支持前后端分离架构,提供完整的博客写作和管理体验。 ## ✨ 核心功能 ### 📝 文章管理系统 - **智能草稿箱**:支持草稿保存、编辑和发布,自动管理文章状态 - **Markdown编辑器**:支持实时预览、代码高亮、图片拖拽上传 - **文章发布**:一键发布,自动生成摘要和封面图片 - **文章编辑**:支持在线编辑已发布文章,保持版本控制 - **文章删除**:安全删除,支持权限验证 ### 🔐 用户认证系统 - **用户注册/登录**:JWT Token 认证,安全可靠 - **权限管理**:用户只能管理自己的文章和草稿 - **个人中心**:用户信息管理,文章统计 ### 🏷️ 内容组织 - **分类管理**:技术、生活、随笔等分类标签 - **标签系统**:灵活的标签管理,支持历史标签推荐 - **搜索功能**:全文搜索,支持标题和内容搜索 ### 💬 互动功能 - **评论系统**:支持文章评论和回复 - **点赞功能**:文章点赞统计 - **浏览统计**:文章浏览量统计 ### 🎨 用户体验 - **响应式设计**:完美适配桌面和移动设备 - **现代化UI**:基于 Element Plus 的美观界面 - **实时预览**:Markdown 编辑器实时预览功能 - **图片优化**:自动图片压缩和尺寸控制 ## 📋 草稿箱与文章管理详解 ### 草稿箱功能 草稿箱是本博客系统的核心功能之一,为用户提供了完整的文章创作和管理体验: #### 🔄 草稿生命周期 ``` 创建草稿 → 编辑草稿 → 发布文章 → 自动移除草稿 ↓ ↓ ↓ ↓ 保存为草稿 继续编辑 发布到首页 从草稿箱消失 ``` #### 📝 草稿箱特性 - **个人专属**:每个用户只能看到自己的草稿,确保隐私安全 - **实时同步**:草稿保存后立即在草稿箱中显示 - **自动管理**:文章发布后自动从草稿箱移除,无需手动删除 - **版本控制**:支持草稿的多次编辑和保存 - **快速访问**:通过个人下拉菜单快速进入草稿箱 #### 🎯 使用场景 1. **临时保存**:写了一半的文章可以先保存为草稿 2. **继续编辑**:下次登录后到草稿箱找到未完成的文章 3. **批量管理**:管理多个未完成的文章项目 4. **发布控制**:确认内容后再发布,避免误发布 #### 🔧 技术实现 - **前端状态管理**:通过 Pinia 管理草稿状态 - **后端权限控制**:API 层面确保用户只能访问自己的草稿 - **自动刷新机制**:发布后自动刷新草稿箱列表 - **页面监听**:使用 `onActivated` 监听页面激活,确保数据最新 ### 文章管理流程 #### 📖 文章状态 - **草稿状态** (`is_published: false`):保存在草稿箱,仅作者可见 - **已发布状态** (`is_published: true`):显示在首页,所有用户可见 #### 🔄 状态转换 - **草稿 → 已发布**:在编辑页面勾选"发布文章"并保存 - **已发布 → 草稿**:在编辑页面取消勾选"发布文章"并保存 - **自动清理**:发布后草稿自动从草稿箱移除 ## 技术栈 ### 前端 - **Vue 3 + TypeScript**:现代化前端框架 - **Element Plus**:企业级 UI 组件库 - **Vue Router**:单页面应用路由管理 - **Pinia**:Vue 3 官方状态管理库 - **@kangc/v-md-editor**:功能强大的 Markdown 编辑器 - **Axios**:HTTP 客户端,支持请求拦截器 - **Vite**:快速的前端构建工具 ### 后端 - **FastAPI + Python 3.9+**:高性能异步 Web 框架 - **SQLAlchemy**:Python SQL 工具包和 ORM - **SQLite/PostgreSQL**:关系型数据库 - **JWT**:JSON Web Token 认证 - **Uvicorn**:ASGI 服务器 - **Pydantic**:数据验证和序列化 - **Alembic**:数据库迁移工具 ### 部署 - **Docker + Docker Compose**:容器化部署 - **Nginx**:反向代理和静态文件服务 ## 项目结构 ``` blog_project/ ├── frontend/ # Vue3 前端项目 ├── backend/ # FastAPI 后端项目 ├── docker-compose.yml # Docker 编排文件 └── README.md ``` ## 快速开始 ### 使用 Docker (推荐) ```bash # 启动所有服务 docker-compose up -d # 查看服务状态 docker-compose ps # 停止服务 docker-compose down ``` ### 本地开发 #### 后端开发 ```bash cd backend pip install -r requirements.txt uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` #### 前端开发 ```bash cd frontend npm install npm run dev ``` ## 访问地址 - 前端: http://localhost:3000 - 后端API: http://localhost:8000 - API文档: http://localhost:8000/docs ### 本地运行后端(不使用 Docker) > 前置:确保本地已安装 Python 3.11+,并已启动 MySQL 容器(或可访问的 MySQL 实例)。 1. 启动(或确认)MySQL 容器在运行 ```bash cd /Users/pxy/PycharmProjects/blog_project docker compose up -d pan-mysql # 或使用 docker ps 确认 3306 已对外 ``` 本地 mysql docker-compose.yml ``` services: pan-mysql: image: mysql:8.0 platform: linux/arm64/v8 container_name: pan-mysql environment: MYSQL_ROOT_PASSWORD: wk1229 volumes: - mysql-data:/var/lib/mysql # 仅数据持久化 ports: - "3306:3306" volumes: mysql-data: ``` 本地登录mysql查看数据: mysql -h 127.0.0.1 -P 3306 -u root -p 远程mysql: ``` version: '3.8' services: pan-mysql: image: mysql:5.7 container_name: pan-mysql environment: MYSQL_ROOT_PASSWORD: wk1229 volumes: - ./mysql-data:/var/lib/mysql - ./mySqlDumpFile.sql:/docker-entrypoint-initdb.d/mySqlDumpFile.sql - ./sp_study.sql:/docker-entrypoint-initdb.d/sp_study.sql ports: - "3306:3306" networks: - shared-network networks: shared-network: driver: bridge ``` 2. 创建并激活虚拟环境 ```bash cd backend python3 -m venv venv source venv/bin/activate ``` 3. 安装依赖 ```bash pip install -r requirements.txt ``` 4.(可选)配置 .env 覆盖数据库连接(默认已连本机 127.0.0.1:3306/blog) ```bash cat > .env << 'EOF' DATABASE_URL=mysql+pymysql://root:wk1229@127.0.0.1:3306/blog EOF ``` 5. 启动后端(会自动建库/建表并插入默认分类:随笔、技术、生活、博客) ```bash uvicorn main:app --reload --host 0.0.0.0 --port 8000 ### 后台启动 nohup uvicorn main:app --reload --host 0.0.0.0 --port 8000 > uvicorn.log 2>&1 & ``` 6. 健康检查与接口文档 ```bash curl http://127.0.0.1:8000/health # 浏览器访问 http://127.0.0.1:8000/docs 查看 Swagger 文档 ## 验证本机正常启动 curl 'http://localhost:8000/api/posts/categories' ``` ## 快速启动 ### 使用 Colima + Docker(推荐) ```bash # 克隆项目 git clone cd blog_project # 方式1:完整 Docker 启动(需要网络连接) ./start-colima.sh # 方式2:简化启动(只启动数据库,手动启动前后端) ./start-colima-simple.sh # 方式3:本地开发模式(不依赖 Docker 镜像) ./start-local.sh ``` ### 使用传统 Docker ```bash # 启动所有服务 ./start.sh # 或者手动启动 docker-compose up -d ``` ### 本地开发 #### 后端开发 ```bash cd backend pip install -r requirements.txt uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` #### 前端开发 ```bash cd frontend npm install npm run dev ``` ## 项目结构 ``` blog_project/ ├── backend/ # FastAPI 后端 │ ├── models/ # 数据模型 │ ├── routers/ # API路由 │ ├── schemas/ # Pydantic模式 │ ├── utils/ # 工具函数 │ ├── alembic/ # 数据库迁移 │ ├── main.py # 应用入口 │ ├── database.py # 数据库配置 │ ├── config.py # 配置文件 │ └── requirements.txt # Python依赖 ├── frontend/ # Vue3 前端 │ ├── src/ │ │ ├── components/ # Vue组件 │ │ ├── views/ # 页面组件 │ │ ├── stores/ # Pinia状态管理 │ │ ├── router/ # 路由配置 │ │ ├── utils/ # 工具函数 │ │ └── types/ # TypeScript类型 │ ├── package.json # 前端依赖 │ └── vite.config.ts # Vite配置 ├── nginx/ # Nginx配置 ├── docker-compose.yml # Docker编排 └── start.sh # 启动脚本 ``` ## 开发计划 - [x] 项目架构设计 - [x] 后端API开发 - [x] 前端界面开发 - [x] 用户认证系统 - [x] 博客管理功能 - [x] Markdown编辑器集成 - [x] Docker环境配置 - [x] UI/UX优化 ### 前端代码编译& nginx配置 前端打包姿势,保证资源都从blog目录读取 ``` VITE_BASE_URL=/blog/ npm run build ``` niginx配置生效,必须 sudo docker-compose down & sudo docker-compose up -d nginx配置 ``` location /blog { alias /usr/share/nginx/html/blog-web; index index.html; try_files $uri $uri/ /blog/index.html; } ``` 前端代码放到nginx的html/blog-web目录下 ### 后端代码nginx配置&上传配置 服务端统一走/api 上传目录为nginx容器里面的 /usr/share/nginx/html/blog/uploads/,这个可以启动时映射到python项目中的uploads目录 ``` location /api { proxy_pass http://172.17.0.1:8000; # 关键!必须是 127.0.0.1:8001 proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always; if ($request_method = 'OPTIONS') { return 204; } } location /blog/uploads/ { alias /usr/share/nginx/html/blog/uploads/; # 注意末尾 "/" 必须带 expires 30d; add_header Cache-Control "public, immutable"; access_log off; # 可选,减少日志 } ``` ### 环境变量设置 由于服务端的上传目录和域名,都是可变的,所以我们通过环境变量定义 ``` ## vim ~/.bashrc, 添加如下 export SERVER_HOST=http://peter-pan.website export UPLOAD_PATH=blog/uploads/images 激活环境变量 source ~/.bashrc ```