# Jog System - 博客系统 [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4.5-brightgreen)](https://spring.io/projects/spring-boot) [![Vue](https://img.shields.io/badge/Vue.js-3.x-brightgreen)](https://vuejs.org/) [![Java](https://img.shields.io/badge/Java-17-orange)](https://openjdk.org/) [![License](https://img.shields.io/badge/License-MIT-blue)](LICENSE) 一个基于 Spring Boot 3 + Vue 3 构建的现代化博客系统,支持文章发布、评论互动、用户管理等功能。 --- ## 目录 - [项目概述](#项目概述) - [核心功能](#核心功能) - [技术栈](#技术栈) - [项目结构](#项目结构) - [环境要求](#环境要求) - [快速开始](#快速开始) - [配置说明](#配置说明) - [API 接口文档](#api-接口文档) - [数据库设计](#数据库设计) - [开发指南](#开发指南) - [常见问题](#常见问题) - [贡献指南](#贡献指南) - [许可证](#许可证) --- ## 项目概述 Jog System 是一个功能完善的博客内容管理系统,采用前后端分离架构,后端使用 Spring Boot 3 构建 RESTful API,前端使用 Vue 3 + Element Plus 构建现代化用户界面。系统支持管理员对平台进行统一管控,注册用户可发布博客、互动评论,访客可浏览公开内容。 ### 项目特点 - **现代化技术栈**:基于 Spring Boot 3.4 和 Vue 3 构建 - **安全可靠**:集成 Spring Security + JWT 无状态认证 - **多模块架构**:Maven 多模块设计,职责清晰 - **数据库迁移**:使用 Flyway 管理数据库版本 - **API 文档**:集成 SpringDoc OpenAPI,自动生成接口文档 - **限流防护**:支持接口限流,防止恶意请求 - **XSS 防护**:内置 XSS 过滤器,保障内容安全 --- ## 核心功能 ### 用户管理 | 功能 | 描述 | |:---|:---| | 管理员登录 | 支持用户名/手机号+密码登录,验证码机制,防暴力破解 | | 用户注册 | 邮箱+密码注册,邮箱验证,密码强度校验 | | 用户登录 | 支持多端登录(最多3个活跃会话),记住我功能 | | 会话管理 | JWT Token 认证,Token 自动刷新 | ### 博客功能 | 功能 | 描述 | |:---|:---| | 文章发布 | 富文本编辑器,支持图片上传、视频嵌入 | | 草稿保存 | 手动保存 + 自动保存(每30秒) | | 文章可见性 | 公开、私密、仅粉丝可见 | | 分类与标签 | 一篇文章必须绑定1个分类,最多5个标签 | | 文章列表 | 支持排序、筛选、全文检索、分页 | | 浏览量统计 | 自动统计文章浏览量(去重) | ### 评论功能 | 功能 | 描述 | |:---|:---| | 多级评论 | 支持楼中楼回复,最多嵌套3级 | | 评论审核 | 可配置是否需要管理员审核 | | 违规处理 | 管理员可删除或屏蔽违规评论 | | 回复通知 | 评论被回复时发送站内通知 | ### 系统管理 | 功能 | 描述 | |:---|:---| | 用户管理 | 查看用户列表,重置用户密码 | | 文章管理 | 管理所有文章,删除违规内容 | | 评论管理 | 审核评论,处理违规内容 | | 分类管理 | 创建、编辑、删除分类 | | 标签管理 | 创建、删除标签 | --- ## 技术栈 ### 后端技术 | 技术 | 版本 | 说明 | |:---|:---|:---| | Spring Boot | 3.4.5 | 核心框架 | | Spring Security | - | 安全框架 | | JWT (jjwt) | 0.12.6 | Token 认证 | | MyBatis-Plus | 3.5.9 | ORM 框架 | | MySQL | 8.0+ | 关系型数据库 | | Redis | 7.2.x | 缓存数据库 | | Flyway | - | 数据库迁移 | | SpringDoc OpenAPI | 2.8.6 | API 文档 | | Hutool | 5.8.34 | 工具类库 | | Jsoup | 1.18.1 | HTML 解析(XSS 过滤) | ### 前端技术 | 技术 | 版本 | 说明 | |:---|:---|:---| | Vue.js | 3.5.x | 前端框架 | | Vite | 6.0.x | 构建工具 | | Element Plus | 2.9.x | UI 组件库 | | Pinia | 2.3.x | 状态管理 | | Vue Router | 4.5.x | 路由管理 | | Axios | 1.7.x | HTTP 客户端 | | Tiptap | 2.11.x | 富文本编辑器 | --- ## 项目结构 ``` jog-system/ ├── pom.xml # 父 POM,管理依赖版本 ├── doc/ # 项目文档 │ ├── jog-system-requirements.md # 需求规格说明书 │ └── jog-system-technical-design.md # 技术设计说明书 │ ├── jog-common/ # 公共模块 │ ├── pom.xml │ └── src/main/java/fun/nojava/common/ │ ├── annotation/ # 自定义注解(如 @RateLimit) │ ├── constant/ # 常量定义 │ ├── enums/ # 枚举定义 │ ├── exception/ # 统一异常处理 │ ├── model/ # 公共模型(ApiResult, PageResult) │ └── util/ # 工具类 │ ├── jog-framework/ # 框架核心模块 │ ├── pom.xml │ └── src/main/java/fun/nojava/framework/ │ ├── aspect/ # AOP 切面(日志、限流) │ ├── config/ # 配置类(Security, Web, JWT) │ ├── filter/ # 过滤器(XSS 过滤) │ ├── handler/ # 全局异常处理 │ ├── security/ # 安全相关(JWT 认证) │ └── util/ # 框架工具类 │ ├── jog-module-system/ # 系统管理模块 │ ├── pom.xml │ └── src/main/java/fun/nojava/module/system/ │ ├── controller/ # 控制器 │ │ ├── admin/ # 后台管理接口 │ │ └── app/ # 前台用户接口 │ ├── service/ # 业务服务 │ ├── mapper/ # 数据访问 │ ├── entity/ # 实体类 │ └── dto/ # 数据传输对象 │ ├── jog-module-blog/ # 博客内容模块 │ ├── pom.xml │ └── src/main/java/fun/nojava/module/blog/ │ ├── controller/ │ ├── service/ │ ├── mapper/ │ ├── entity/ │ └── dto/ │ ├── jog-module-comment/ # 评论模块 │ ├── pom.xml │ └── src/main/java/fun/nojava/module/comment/ │ ├── controller/ │ ├── service/ │ ├── mapper/ │ ├── entity/ │ └── dto/ │ ├── jog-admin/ # 后台管理启动模块 │ ├── pom.xml │ └── src/main/ │ ├── java/fun/nojava/admin/ # 启动类 │ └── resources/ │ ├── application.yml # 应用配置 │ └── db/migration/ # Flyway 迁移脚本 │ ├── V1__init_schema.sql # 数据库表结构 │ └── V2__init_data.sql # 初始化数据 │ └── jog-frontend/ # 前端工程 ├── package.json ├── vite.config.js ├── index.html └── src/ ├── api/ # API 接口封装 ├── layouts/ # 布局组件 ├── router/ # 路由配置 ├── stores/ # Pinia 状态管理 ├── utils/ # 工具函数 └── views/ # 页面组件 ├── admin/ # 后台管理页面 └── app/ # 前台用户页面 ``` ### 模块依赖关系 ``` jog-admin (启动入口) ├── jog-module-system │ └── jog-framework │ └── jog-common ├── jog-module-blog │ └── jog-module-system └── jog-module-comment └── jog-module-blog ``` --- ## 环境要求 ### 开发环境 | 软件 | 版本要求 | |:---|:---| | JDK | 17 或更高 | | Maven | 3.9+ | | Node.js | 18.x 或更高 | | MySQL | 8.0+ | | Redis | 7.2.x | ### 推荐开发工具 - **后端**:IntelliJ IDEA(推荐)或 Eclipse - **前端**:VS Code 或 WebStorm - **数据库**:MySQL Workbench 或 Navicat - **API 测试**:Postman 或 Apifox --- ## 快速开始 ### 1. 克隆项目 ```bash git clone https://github.com/your-username/jog-system.git cd jog-system ``` ### 2. 数据库配置 创建 MySQL 数据库: ```sql CREATE DATABASE jog_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` ### 3. 修改配置文件 编辑 `jog-admin/src/main/resources/application.yml`: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/jog_db?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: your_username password: your_password data: redis: host: localhost port: 6379 ``` ### 4. 安装前端依赖 ```bash cd jog-frontend npm install ``` ### 5. 启动后端服务 ```bash cd .. mvn clean install -DskipTests cd jog-admin mvn spring-boot:run ``` 或者直接运行主类 `fun.nojava.admin.JogAdminApplication`。 ### 6. 启动前端开发服务器 ```bash cd jog-frontend npm run dev ``` 前端开发服务器将在 `http://localhost:5173` 启动。 ### 7. 访问应用 - **前端页面**:http://localhost:5173 - **后端 API**:http://localhost:8080 - **Swagger 文档**:http://localhost:8080/swagger-ui.html ### 8. 默认管理员账号 | 用户名 | 密码 | 角色 | |:---|:---|:---| | admin | Admin@123 | 管理员 | --- ## 配置说明 ### 应用配置 (application.yml) ```yaml server: port: 8080 # 服务端口 spring: application: name: jog-system # 应用名称 datasource: # 数据源配置 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/jog_db username: root password: root data: redis: # Redis 配置 host: localhost port: 6379 database: 0 flyway: # Flyway 配置 enabled: true locations: classpath:db/migration mail: # 邮件配置 host: smtp.example.com port: 587 username: noreply@example.com password: your-mail-password jwt: # JWT 配置 secret: YourSuperSecretKeyForJwtTokenGenerationMustBeAtLeast256BitsLongForHS256Algorithm access-token-expire: 7200 # Access Token 有效期(秒) refresh-token-expire: 86400 # Refresh Token 有效期(秒) refresh-token-expire-remember: 1209600 # 记住我时的有效期 mybatis-plus: # MyBatis-Plus 配置 mapper-locations: classpath*:/mapper/**/*.xml configuration: map-underscore-to-camel-case: true global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 springdoc: # Swagger 配置 api-docs: enabled: true path: /v3/api-docs swagger-ui: enabled: true path: /swagger-ui.html ``` ### 前端配置 (vite.config.js) ```javascript export default defineConfig({ server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, }, }, }, build: { outDir: '../jog-admin/src/main/resources/static', emptyOutDir: true, }, }) ``` --- ## API 接口文档 ### 接口分类 系统 API 按照访问权限分为三类: | 前缀 | 权限 | 说明 | |:---|:---|:---| | `/api/public/**` | 无需认证 | 公开接口 | | `/api/app/**` | 需要用户登录 | 用户接口 | | `/api/admin/**` | 需要管理员权限 | 管理接口 | ### 认证接口 | 方法 | 路径 | 说明 | |:---|:---|:---| | POST | /api/public/admin/login | 管理员登录 | | POST | /api/public/user/login | 用户登录 | | POST | /api/public/user/register | 用户注册 | | POST | /api/public/refresh-token | 刷新 Token | | GET | /api/public/captcha | 获取验证码 | ### 文章接口 | 方法 | 路径 | 说明 | |:---|:---|:---| | GET | /api/public/article/list | 获取公开文章列表 | | GET | /api/public/article/{id} | 获取文章详情 | | POST | /api/app/article | 创建文章 | | PUT | /api/app/article/{id} | 更新文章 | | DELETE | /api/app/article/{id} | 删除文章 | | GET | /api/app/article/mine | 获取我的文章 | | POST | /api/app/article/{id}/like | 点赞/取消点赞 | ### 评论接口 | 方法 | 路径 | 说明 | |:---|:---|:---| | GET | /api/public/comment/list | 获取评论列表 | | POST | /api/app/comment | 发表评论 | | DELETE | /api/app/comment/{id} | 删除评论 | ### 管理接口 | 方法 | 路径 | 说明 | |:---|:---|:---| | GET | /api/admin/user/list | 获取用户列表 | | GET | /api/admin/article/list | 获取所有文章 | | DELETE | /api/admin/article/{id} | 删除文章 | | GET | /api/admin/comment/list | 获取所有评论 | | PUT | /api/admin/comment/{id}/audit | 审核评论 | ### 统一响应格式 ```json { "code": 200, "message": "success", "data": { ... }, "timestamp": 1715923200000 } ``` ### 错误码说明 | 错误码 | 说明 | |:---|:---| | 200 | 成功 | | 400 | 请求参数错误 | | 401 | 未认证/Token 过期 | | 403 | 无权限 | | 404 | 资源不存在 | | 429 | 请求过于频繁 | | 500 | 服务器内部错误 | --- ## 数据库设计 ### 核心表结构 #### 用户表 (sys_user) | 字段 | 类型 | 说明 | |:---|:---|:---| | id | BIGINT | 主键 | | username | VARCHAR(50) | 用户名 | | email | VARCHAR(100) | 邮箱(唯一) | | password | VARCHAR(255) | 密码(BCrypt 加密) | | user_type | TINYINT | 用户类型:0管理员 1普通用户 | | status | TINYINT | 状态:0正常 1锁定 | | email_verified | TINYINT | 邮箱是否验证 | #### 文章表 (blog_article) | 字段 | 类型 | 说明 | |:---|:---|:---| | id | BIGINT | 主键 | | user_id | BIGINT | 作者ID | | category_id | BIGINT | 分类ID | | title | VARCHAR(200) | 标题 | | content | LONGTEXT | 内容 | | status | TINYINT | 状态:0草稿 1已发布 2回收站 | | visibility | TINYINT | 可见性:0公开 1私密 2仅粉丝 | | view_count | INT | 浏览量 | #### 评论表 (blog_comment) | 字段 | 类型 | 说明 | |:---|:---|:---| | id | BIGINT | 主键 | | article_id | BIGINT | 文章ID | | user_id | BIGINT | 评论者ID | | parent_id | BIGINT | 父评论ID | | content | VARCHAR(1000) | 评论内容 | | level | TINYINT | 评论层级(最多3级) | | status | TINYINT | 状态:0待审核 1已通过 2已屏蔽 | ### 数据库迁移 系统使用 Flyway 管理数据库版本,迁移脚本位于: ``` jog-admin/src/main/resources/db/migration/ ├── V1__init_schema.sql # 表结构初始化 └── V2__init_data.sql # 初始数据 ``` --- ## 开发指南 ### 后端开发 #### 1. 创建新的业务模块 ```xml fun.nojava jog-system 1.0.0 jog-module-xxx ``` #### 2. Controller 示例 ```java @RestController @RequestMapping("/api/app/article") @RequiredArgsConstructor public class ArticleController { private final ArticleService articleService; @PostMapping @Operation(summary = "创建文章") public ApiResult create(@Valid @RequestBody ArticleCreateDTO dto) { return ApiResult.success(articleService.create(dto)); } } ``` #### 3. Service 示例 ```java @Service @RequiredArgsConstructor public class ArticleServiceImpl implements ArticleService { private final ArticleMapper articleMapper; @Override @Transactional public Long create(ArticleCreateDTO dto) { Article article = new Article(); BeanUtils.copyProperties(dto, article); articleMapper.insert(article); return article.getId(); } } ``` ### 前端开发 #### 1. 创建新页面 ```vue ``` #### 2. 添加路由 ```javascript // router/index.js { path: '/new-page', name: 'NewPage', component: () => import('@/views/NewPage.vue'), meta: { title: '新页面', requiresAuth: true }, } ``` #### 3. API 调用 ```javascript // api/example.js import request from '@/utils/request' export function getData(params) { return request.get('/api/app/example', { params }) } export function createData(data) { return request.post('/api/app/example', data) } ``` ### 构建部署 #### 开发环境 ```bash # 后端 mvn spring-boot:run # 前端 cd jog-frontend npm run dev ``` #### 生产环境 ```bash # 构建前端(自动输出到 jog-admin/src/main/resources/static) cd jog-frontend npm run build # 打包后端(包含前端静态资源) cd .. mvn clean package -DskipTests # 运行 java -jar jog-admin/target/jog-admin.jar ``` --- ## 常见问题 ### Q1: 启动时报数据库连接错误? **A**: 检查以下几点: 1. MySQL 服务是否启动 2. 数据库 `jog_db` 是否已创建 3. `application.yml` 中的数据库配置是否正确 4. MySQL 用户是否有足够的权限 ### Q2: Flyway 迁移失败? **A**: 可能原因: 1. 数据库已存在数据,与迁移脚本冲突 2. 解决方法:清空数据库后重新启动,或设置 `spring.flyway.baseline-on-migrate=true` ### Q3: JWT Token 无效? **A**: 检查: 1. Token 是否过期 2. JWT secret 配置是否一致 3. 请求头是否正确携带 `Authorization: Bearer ` ### Q4: 前端代理不生效? **A**: 确保: 1. `vite.config.js` 中代理配置正确 2. 后端服务已启动在 8080 端口 3. 使用 `/api` 前缀访问后端接口 ### Q5: Redis 连接失败? **A**: 检查: 1. Redis 服务是否启动 2. `application.yml` 中 Redis 配置是否正确 3. 端口是否被占用 --- ## 贡献指南 欢迎贡献代码!请遵循以下步骤: ### 1. Fork 项目 点击右上角 Fork 按钮,将项目 Fork 到你的账户。 ### 2. 克隆仓库 ```bash git clone https://github.com/your-username/jog-system.git cd jog-system ``` ### 3. 创建分支 ```bash git checkout -b feature/your-feature-name ``` ### 4. 提交代码 ```bash git add . git commit -m "feat: 添加新功能" ``` ### 提交信息规范 | 前缀 | 说明 | |:---|:---| | feat | 新功能 | | fix | 修复 Bug | | docs | 文档更新 | | style | 代码格式调整 | | refactor | 重构 | | test | 测试相关 | | chore | 构建/工具相关 | ### 5. 推送分支 ```bash git push origin feature/your-feature-name ``` ### 6. 创建 Pull Request 在 GitHub 上创建 Pull Request,描述你的修改内容。 --- ## 许可证 本项目采用 [MIT](LICENSE) 许可证。 --- ## 联系方式 如有问题或建议,欢迎提交 Issue 或 Pull Request。 --- **Jog System** - 简洁、安全、现代化的博客系统