Files
Jog/README.md
2026-05-17 16:08:37 +08:00

767 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
<!-- pom.xml -->
<project>
<parent>
<groupId>fun.nojava</groupId>
<artifactId>jog-system</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>jog-module-xxx</artifactId>
</project>
```
#### 2. Controller 示例
```java
@RestController
@RequestMapping("/api/app/article")
@RequiredArgsConstructor
public class ArticleController {
private final ArticleService articleService;
@PostMapping
@Operation(summary = "创建文章")
public ApiResult<Long> 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
<template>
<div class="page-container">
<!-- 页面内容 -->
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const data = ref([])
onMounted(() => {
fetchData()
})
async function fetchData() {
// 获取数据
}
</script>
```
#### 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 <token>`
### 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** - 简洁、安全、现代化的博客系统