Skip to content

zhansan379/my_blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

博客系统设计方案

markdown编辑页面 image 管理端 image 用户端 image

一、功能列表

1. 前台功能(用户端)

模块 功能点 说明
文章展示 文章列表 分页展示所有已发布文章
文章详情 查看单篇文章完整内容
分类筛选 按分类筛选文章
标签筛选 按标签筛选文章
搜索文章 关键词搜索文章标题/内容
用户交互 用户注册/登录 邮箱注册、JWT认证
评论功能 发表/回复评论(需登录)
点赞收藏 文章点赞、收藏(需登录)
个人中心 查看我的文章、收藏、评论

2. 后台功能(管理端)

模块 功能点 说明
仪表盘 数据统计 文章数、评论数、访问量统计
文章管理 文章CRUD 创建、编辑、删除、发布文章
分类管理 增删改查文章分类
标签管理 增删改查文章标签
评论管理 评论审核 审核/回复/删除评论
用户管理 用户列表 查看/禁用/启用用户
角色权限 管理员/普通用户权限控制
系统设置 站点配置 站点名称、Logo、SEO设置

二、数据库SQL设计

-- 用户表
CREATE TABLE `users` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `username` VARCHAR(50) NOT NULL UNIQUE,
  `email` VARCHAR(100) NOT NULL UNIQUE,
  `password_hash` VARCHAR(255) NOT NULL,
  `avatar` VARCHAR(255) DEFAULT '/default-avatar.png',
  `bio` TEXT,
  `role` ENUM('user', 'admin') DEFAULT 'user',
  `is_active` BOOLEAN DEFAULT TRUE,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 分类表
CREATE TABLE `categories` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(50) NOT NULL UNIQUE,
  `slug` VARCHAR(50) NOT NULL UNIQUE,
  `description` TEXT,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 标签表
CREATE TABLE `tags` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(30) NOT NULL UNIQUE,
  `slug` VARCHAR(30) NOT NULL UNIQUE,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 文章表
CREATE TABLE `posts` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `title` VARCHAR(200) NOT NULL,
  `slug` VARCHAR(200) NOT NULL UNIQUE,
  `content` LONGTEXT NOT NULL,
  `excerpt` TEXT,
  `featured_image` VARCHAR(255),
  `status` ENUM('draft', 'published', 'private') DEFAULT 'draft',
  `view_count` INT DEFAULT 0,
  `like_count` INT DEFAULT 0,
  `category_id` INT,
  `author_id` INT NOT NULL,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `published_at` TIMESTAMP NULL,
  FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE SET NULL,
  FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
  INDEX `idx_status_published` (`status`, `published_at`),
  INDEX `idx_category` (`category_id`)
);

-- 文章标签关联表
CREATE TABLE `post_tags` (
  `post_id` INT NOT NULL,
  `tag_id` INT NOT NULL,
  PRIMARY KEY (`post_id`, `tag_id`),
  FOREIGN KEY (`post_id`) REFERENCES `posts`(`id`) ON DELETE CASCADE,
  FOREIGN KEY (`tag_id`) REFERENCES `tags`(`id`) ON DELETE CASCADE
);

-- 评论表
CREATE TABLE `comments` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `content` TEXT NOT NULL,
  `post_id` INT NOT NULL,
  `user_id` INT,
  `parent_id` INT DEFAULT NULL,
  `status` ENUM('pending', 'approved', 'spam') DEFAULT 'pending',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (`post_id`) REFERENCES `posts`(`id`) ON DELETE CASCADE,
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
  FOREIGN KEY (`parent_id`) REFERENCES `comments`(`id`) ON DELETE CASCADE,
  INDEX `idx_post_status` (`post_id`, `status`)
);

-- 收藏表
CREATE TABLE `favorites` (
  `user_id` INT NOT NULL,
  `post_id` INT NOT NULL,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`user_id`, `post_id`),
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
  FOREIGN KEY (`post_id`) REFERENCES `posts`(`id`) ON DELETE CASCADE
);

-- 点赞表
CREATE TABLE `likes` (
  `user_id` INT NOT NULL,
  `post_id` INT NOT NULL,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`user_id`, `post_id`),
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
  FOREIGN KEY (`post_id`) REFERENCES `posts`(`id`) ON DELETE CASCADE
);

三、接口数据设计(RESTful API)

1. 认证接口

// POST /api/auth/register
Request:
{
  "username": "johndoe",
  "email": "john@example.com",
  "password": "Password123!"
}

Response:
{
  "code": 200,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": 1,
      "username": "johndoe",
      "email": "john@example.com",
      "role": "user"
    }
  }
}

2. 文章接口

// GET /api/posts?page=1&limit=10&category=tech
Response:
{
  "code": 200,
  "data": {
    "total": 100,
    "page": 1,
    "limit": 10,
    "items": [
      {
        "id": 1,
        "title": "Vue3 组合式API详解",
        "slug": "vue3-composition-api",
        "excerpt": "本文深入讲解Vue3的组合式API...",
        "featured_image": "/images/vue3.jpg",
        "view_count": 1500,
        "like_count": 89,
        "category": { "id": 1, "name": "前端" },
        "tags": [{ "id": 1, "name": "Vue" }],
        "author": { "id": 1, "username": "admin", "avatar": "/avatar.jpg" },
        "created_at": "2024-01-15T08:30:00Z"
      }
    ]
  }
}

// POST /api/posts (Admin)
Request:
{
  "title": "新文章标题",
  "content": "Markdown格式内容...",
  "category_id": 1,
  "tag_ids": [1, 2],
  "status": "published",
  "featured_image": "/uploads/image.jpg"
}

3. 评论接口

// POST /api/posts/1/comments
Request:
{
  "content": "这篇文章写得非常好!",
  "parent_id": null
}

Response:
{
  "code": 200,
  "data": {
    "id": 101,
    "content": "这篇文章写得非常好!",
    "user": { "username": "johndoe", "avatar": "/avatar.jpg" },
    "created_at": "2024-01-16T10:30:00Z"
  }
}

4. 后台管理接口

// GET /api/admin/stats
Response:
{
  "code": 200,
  "data": {
    "posts_count": 156,
    "comments_count": 892,
    "users_count": 345,
    "views_today": 1234,
    "popular_posts": [
      { "id": 1, "title": "热门文章1", "views": 5000 }
    ]
  }
}

四、系统生成建议

技术栈推荐

层级 技术方案
前端 Vue3 + Pinia + Element Plus + Markdown编辑器
后端 Java Spring Boot
数据库 MySQL 8.0
部署 Docker + Nginx

五、已识别安全问题(需持续修复)

高优先级

  1. JWT 仅在功能描述中出现,缺少刷新令牌、吊销策略、密钥轮换策略。
  2. 权限模型粗粒度,需持续防御水平越权与垂直越权。
  3. 文章与评论内容存在富文本输入面,需严格输出转义与白名单过滤,防止存储型 XSS。
  4. 登录/注册/评论/点赞等接口需限流与风控,防止撞库和刷接口。

中优先级

  1. 密码策略需明确(强度校验、哈希成本参数、重置流程)。
  2. 输入边界需统一(分页上限、字段长度、排序白名单、非法参数兜底)。
  3. 关键操作需审计日志(登录失败、权限变更、内容删除、评论审核)。

低优先级

  1. 安全响应头(CSP、X-Frame-Options 等)和上传安全策略尚未纳入本轮。
  2. 高级 RBAC、设备管理、异常行为检测等属于后续增强项。

六、本轮MVP实现范围(已落地)

后端

  1. 用户注册/登录(JWT)
  2. 文章列表与详情(分页、关键词、分类、标签筛选)
  3. 评论发布与展示
  4. 点赞/收藏(幂等处理)
  5. 简版管理端接口:文章 CRUD、分类 CRUD、基础统计
  6. MyBatis + 手工 SQL 建表脚本(schema.sql、data.sql)

前端

  1. Vue3 + Element Plus + Pinia + Vue Router + Axios
  2. 页面:首页、文章详情、登录注册、管理仪表盘、文章管理、分类管理
  3. 响应式适配:移动端/平板/桌面断点布局

本轮未实现(后续迭代)

  1. 邮件激活、刷新令牌与多端会话管理
  2. 复杂 RBAC 权限矩阵
  3. 全文检索(ElasticSearch)
  4. 对象存储上传与图片审核
  5. 高级风控与告警系统

my_blog 安装配置指南

环境要求

依赖 版本 说明
JDK 17+ 后端运行环境
Node.js 20.19+ / 22.12+ 前端运行环境
MySQL 8.0+ 数据库
Redis 7.x+ 缓存
RustFS - S3 兼容对象存储(可选)

前置安装

1. 安装 MySQL

创建数据库:

CREATE DATABASE my_blog DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

2. 安装 Redis

启动 Redis(默认端口 6379),无需额外配置。Spring Boot 自动连接 localhost:6379

3. 安装 RustFS(可选)

项目使用 RustFS 作为文件存储服务。如不需要文件上传功能可暂时跳过。

后端配置

1. 数据库配置

编辑 my_blog/src/main/resources/application.properties,修改数据库连接信息:

spring.datasource.url=jdbc:mysql://localhost:3306/my_blog?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=你的数据库密码

2. JWT 密钥

将 JWT 密钥替换为一个随机字符串(至少 256 位):

jwt.secret=替换为你自己的长随机密钥

可以使用以下命令生成:

# Linux / Mac
openssl rand -base64 64

# Windows PowerShell
[Convert]::ToBase64String((1..64 | ForEach-Object { Get-Random -Maximum 256 }))

3. 文件存储配置(可选)

storage.provider=rustfs
storage.uploadUrl=http://127.0.0.1:9000/api/upload
storage.endpoint=http://127.0.0.1:9000
storage.bucket=my-bolg-bucket
storage.baseUrl=http://127.0.0.1:9000
storage.access-key-id=rustfsadmin
storage.secret-access-key=rustfsadmin

4. 启动后端

项目启动时会自动执行 schema.sqldata.sql 建表并插入初始化数据。

cd my_blog
./mvnw spring-boot:run

后端运行在 http://localhost:8080

前端配置

1. 安装依赖

cd my_blog/frontend/my_blog_frontend
npm install

2. 配置代理

前端开发时通过 Vite 代理转发 API 请求到后端。如需修改,编辑 vite.config.js

export default defineConfig({
  server: {
    proxy: {
      '/api': 'http://localhost:8080'
    }
  }
  // ...
})

3. 启动前端

npm run dev

前端开发服务器运行在 http://localhost:5173

目录结构

project/
├── INSTALL.md                    # 本文件
└── my_blog/
    ├── pom.xml                   # Maven 配置
    ├── src/main/
    │   ├── java/com/fun/my_blog/
    │   │   ├── config/           # 配置类
    │   │   ├── controller/       # 控制器
    │   │   ├── domain/           # 实体类
    │   │   ├── dto/              # 数据传输对象
    │   │   ├── mapper/           # MyBatis Mapper
    │   │   ├── security/         # Spring Security + JWT
    │   │   └── service/          # 业务层
    │   └── resources/
    │       ├── application.properties
    │       ├── schema.sql        # 数据库建表
    │       └── data.sql          # 初始数据
    └── frontend/
        └── my_blog_frontend/     # Vue 3 前端项目
            └── src/

默认端口

服务 端口
后端 API 8080
前端 Dev Server 5173
MySQL 3306
Redis 6379
RustFS 9000

常见问题

Q: 启动报错 "Access denied for user"

检查 application.properties 中的数据库用户名和密码是否正确。

Q: 启动报错 "Unknown database 'my_blog'"

需要先在 MySQL 中创建数据库:CREATE DATABASE my_blog;

Q: 前端请求 API 报 CORS 错误

确认 app.cors.allowed-origins 配置的前端地址与实际一致。

Q: 文件上传失败

确保 RustFS 服务已启动,且 storage.* 配置与 RustFS 实例匹配。如暂时不需要文件上传,可忽略该错误。

About

个人极简博客,有蕾姆看板娘,文章管理,评论收藏等功能

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors