diff --git a/README.md b/README.md new file mode 100644 index 0000000..c16bf53 --- /dev/null +++ b/README.md @@ -0,0 +1,766 @@ +# 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** - 简洁、安全、现代化的博客系统