diff --git a/blog/hexo.sh b/blog/hexo/hexo.sh similarity index 100% rename from blog/hexo.sh rename to blog/hexo/hexo.sh diff --git a/blog/创建博客.md b/blog/hexo/创建博客.md similarity index 100% rename from blog/创建博客.md rename to blog/hexo/创建博客.md diff --git a/blog/部署博客.md b/blog/hexo/部署博客.md similarity index 100% rename from blog/部署博客.md rename to blog/hexo/部署博客.md diff --git a/blog/配置博客.md b/blog/hexo/配置博客.md similarity index 100% rename from blog/配置博客.md rename to blog/hexo/配置博客.md diff --git a/blog/博客/01 博客系统需求文档.md b/blog/博客/01 博客系统需求文档.md new file mode 100644 index 00000000..37b5994e --- /dev/null +++ b/blog/博客/01 博客系统需求文档.md @@ -0,0 +1,88 @@ +## 1 需求说明 + + +### 1.1 需求背景 + +工作已经快两年了,自己已经成为了半个技术人了。有很多很多东西想要想要整理一下分享出来,并不是期待能有多少人关注自己,而是希望自己有一天能够回忆起自己对于这份工作的热爱,不止是money。 + +另一方面,在大厂拧螺丝几乎让自己没有任何机会从头到尾搭建一个完善的工程,作为一个普通的后端工程师,在一个庞大的企业架构里,只能负责一小部分。这一次,也是为了自己能够从想要搭建一个自己的博客开始,能够实践一些最前沿的技术,例如Java23、SpringBoot3、Vue3等。 + + +### 1.2 需求目标 + +搭建一套前后端分离的博客系统。 + +为了能够全面掌控自己的数据,自己的笔记都是一Markdown形式存在的,通过github进行托管。由于各种各样的笔记软件数据安全性存在问题、无法提供长久的支持,很可能过几天就倒闭了,而且其对书写方式的要求也各种各样,并能满足自己的爱好。所以选择了这种最朴素数据记录方式,如果有任何展示的需求,就可以基于Markdown的语法转换、渲染成各种自己喜欢的格式。 + + + +### 1.3 技术选型 + +当前主要有两套技术方案,一种是纯前端的静态博客,其主要有以下部分组成。 +* 内容数据:博客内容,可以使Markdown或者其他内容撰写的文章,是展示的核心内容,一般以文件的方式存储在硬盘上。 +* 元数据:描述内容的数据,方便用来管理和显示。例如目录和标签,如果是新添加的博客可以按照不同博客的元数据系统展示博客内容。但如果是旧的文章迁移到新的博客系统中,就需要通过特定的脚本或者人工补充的方式将元数据添加到博客系统当中。 +* 主题框架:展示内容的模板。模板规定了前端的风格,包括展示的格式、布局等,是不同博客系统核心的最大差异的部分。 +* 渲染工具:将内容数据、元数据、主题框架结合起来生成前端脚本。往往是一个一次性运行的脚本,其生成的结果一般是纯静态的前端工程,可以直接在网页上显示。 + +其代表的工具主要有Hexo、vuepress等。 + +另一种是前后端分离的博客系统,其主要有以下部分组成。 +* 内容数据:博客内容。可以使各种格式,一般内容会与元数据都存储在数据库中,方便检索和管理。 +* 后端模块:基于数据库实现内容的增删改查,启动服务器提供Rest接口。 +* 前端模块:通过Rest接口访问后端获取数据,在前端获取数据。或者直接获取后端渲染好的数据进行展示。 + +每个语言都有其代表的前端工具和后端工具。后端工具主要包括:java-springboot、nodejs-express、go-gin、python-django等。前端主要包括页面模板(adminlte、antd、element)和数据渲染工具(vue、react) + + +纯静态博客与有后端的博客最大的不同就是渲染的时机。纯静态博客的渲染是在部署的时候完成渲染,生成可以直接通过路径访问的完整的HTML页面,一般可以托管在githubpages这样的无后端系统中,最大的弊端是无法在运行是动态修改数据,只能通过重试部署的方式在Server再次渲染(或者增量渲染),但由于所有页面都是生成好的,其加载速度也非常快。有后端的博客系统可以在用户请求的时候,采取传统MVC方式在后端完成动态的渲染,生成HTML页面返回给前端,也可以采取前后端的分离的方案,后端值负责维护数据,在ClientSide完成页面的渲染,有后端的系统也会更加灵活,用户可以与博客系统进行数据交互,例如实现聊天室、评论功能等。 + + +综合以上的调研结果,主要选择当前最先进的技术体系,一方面为了分享,另一方面为了实践,选择上主要贴合自己的技术栈。 + +后端 +- 数据库:MySQL +- Web框架:Java23 + SpringBoot3 +- 数据管理:vscode + GitHub + Markdown + +前端 +- Vue + Element + AdminLTE + + +### 1.4 需求分析 +主要的模块可以分为一下模块。 +不需要多用户管理。只需要生成的静态用户信息。可以放一个JSON配置文件,系统的启动的时候去加载。 + +文章同步功能P0:文章的编辑通过vscode/markdown/github三件套实现,不需要博客系统本身具有撰写文章的能力,只需要能根据原始数据生成文章的数据。 +* 设置自动同步和定时扫描任务,从原始数据扫描文章,加载到MySQL数据库中,能够自动对比文章的不同,实现增量数据的处理,能够清理已经过期的文章。 + + +文章管理功能P0.博客系统的核心功能,用来组织文章相关的数据,实现文章列表、详情的展示、文章元数据的展示、文章不同方式的索引。 +* 查询搜索功能:基于多个条件索引文章,创建时间、修改时间、目录、标签、文章内容关键字、是否隐藏进行动态查询分页。 +* 查看详情功能:显示文章的详情页内容、统计数据等。 +* 分类管理功能:以列表的形式展示文章的目录。 +* 标签管理功能:能够自动生成文章的标签。能够以标签云的形式展示文章的标签。 +* 数据统计功能。博客系统内部,业务相关的统计数据。每篇文章的浏览量、博客系统的访问量等。 + + +文章评论功能P1 +* 创建评论功能:能够回复文章或指定的评论。 +* 删除评论功能:同一个用户可以删除自己评论。 +* 博客留言功能:用户可以在留言板上留言。 + + +用户管理功能P1,前端需要对某些管理员的功能进行隐藏和展示,后端需要对管理员的功能进行进行鉴权。 +* 用户登录功能。任何人访问博客都可以建立真实账户或者匿名用户,用于留言板和系统评论功能。 +* 权限校验功能。设置不同的API和对应的权限。管理员账户需要一些魔法和特殊能力。例如查看文章 +* 个人资料管理。自动生成匿名用户并且能够识别是否是同一个匿名用户访问、添加关联邮箱、繁琐创建完整用户。用户可以创建、编辑和管理自己的个人资料,包括头像、昵称、密码等。 + + +后台管理功能P2。实现对文章元数据的修改。 +* 文章隐藏功能。能够查看隐藏文章,并设置文章隐藏功能,对质量较低、还没有完善的草稿进行隐藏。(管理员) +* 文章置顶功能。能够显示置顶的文章。能够置顶一篇文章(管理员)。 +* 系统监控功能。后台数据分析功能 + +自动部署能力P2。 +* 系统部署:工程打包成docker镜像,方便系统快速迁移。 +* 数据变更:通过github触发自动部署流水线。 + + diff --git a/blog/博客/02 博客系统设计文档.md b/blog/博客/02 博客系统设计文档.md new file mode 100644 index 00000000..9a406ef3 --- /dev/null +++ b/blog/博客/02 博客系统设计文档.md @@ -0,0 +1,142 @@ + +## 1 架构设计 + +### 架构和技术说明 + + + +本项目主要架构包括三部分 +1. 数据层。通过vscode和markdown创建的笔记内容数据,存储在github上。需要对笔记内容进行重构,以适应多种形式的输出。 +2. 业务层。提供博客系统的业务数据访问。 + 1. Sync模块从github同步数据,存储到本地数据库中对数据进行分析和处理,通过只能算法生成博客的元数据,包括tag、description等,对数据内容进行筛选(根据配置)和完整性校验,可以通过定时任务和Github的流水线触发数据的增量处理任务。 + 2. User模块提供了用户的登录认证、权限校验功能,允许用户匿名访问系统也允许用户创建一个简单的账户,区分匿名用户、普通用户、管理用户的权限区别。 + 3. Article模块提供文章的多级索引,包括目录、tag、日期、关键字等方便用户快速找到自己感兴趣的文章,也方便自己回顾阅读,同时提供了一些基础的交互能力和数据统计能力,包括点赞、评论、访问量。整个系统通过标准Rest接口对外提供访问。 +3. 渲染层。通过vue前端框架和element组件库,快速构建前端页面,提供交互能力。访问后端的Rest接口进行渲染。 + + +## 2 模型设计 + +### 2.1 对象设计 +文章的对象模型主要包括以下五个:文章、分类、标签、评论、用户。 + + + +### 2.2 逻辑设计 +在逻辑设计的时候应该遵循以下原则 +1. 不允许使用外键 +2. 尽量减少连表操作。连表操作会大大增加数据管理的难度。 + +文章与用户关系:在博文中记录的应该是用户名,这样前端直接根据用户名称进行查询,就可以找到对应的文章。而不是传递用户id。 + +文章与目录:文章与目录是一对多的关系。可以直接在文章中存储目录的id。不同目录下可能存在同名的子目录。所以目录名称的唯一键应该是 父目录+子目录。 + +文章与标签:文章与标签是多对多的关系。不需要建立关联关系表,直接将标签以逗号分割的形式添加到文章里即可。多选可以使用 Like or的方法直接进行查询。标签的名称是唯一键,主要用来显示标签云,不用每次都统计标签的数量 + +文章与评论:文章与评论是一对多关系。不需要建立关联关系。评论中存储文章id的外键。评论之间可以相互回复,parent_id标识其上一级评论,如果parent_id为零,表示直接回复当篇文章。 + + + + + + +### 2.3 物理设计 + +```sql + +--【1】创建 blog数据库 +CREATE DATABASE blog SET utf8mb4 COLLATE utf8mb4_unicode_ci; + + +--【2】创建用户表 user +CREATE TABLE `user` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', + `user_name` varchar(32) NOT NULL COMMENT '用户名', + `password` varchar(64) DEFAULT NULL COMMENT '用户密码', + `nickname` varchar(32) DEFAULT NULL COMMENT '用户名', + `email` varchar(64) DEFAULT NULL COMMENT '用户邮箱', + `role` tinyint DEFAULT 0 COMMENT '注册时间0表示普通用户1表示管理员2表示匿名用户', + `photo` varchar(256) DEFAULT NULL COMMENT '用户头像', + `uuid` varchar(32) DEFAULT NULL COMMENT '唯一标识', + `ip` varchar(20) NOT NULL COMMENT '用户IP', + PRIMARY KEY (`id`), + KEY `user_name` (`user_name`), + KEY `email` (`email`) +); + + +--【3】创建分类表 \category + +CREATE TABLE `category` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '目录ID', + `name` varchar(100) NOT NULL COMMENT '标签名称', + `parent` bigint NOT NULL DEFAULT '0' COMMENT '目录ID,0表示顶层目录', + `description` text DEFAULT NULL COMMENT '目录下README.MD文件的内容', + PRIMARY KEY (`id`), + UNITUQ KEY `path`(`parent`,`name`) +)COMMENT='分类表'; + + + +--【4】创建分类表 tag + +CREATE TABLE `tag` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `name` varchar(32) DEFAULT '' COMMENT '标签名称', + `count` int DEFAULT '0' COMMENT '权重数量', + `description` varchar(256) DEFAULT NULL COMMENT '评论数量', + PRIMARY KEY (`id`), + UNIQUE KEY `name`(`name`) +) COMMENT='标签表'; + + + + +--【5】创建文章表 article +CREATE TABLE `article` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '博文ID', + `user_id` bigint NOT NULL COMMENT '发表用户ID', + `category_id` bigint NOT NULL COMMENT '目录ID', + `title` varchar(128) NOT NULL COMMENT '博文标题', + `content` longtext NOT NULL COMMENT '博文内容', + `description` text NOT NULL COMMENT '博文简介', + `love` int NOT NULL DEFAULT 0 COMMENT '喜欢量', + `view` int NOT NULL DEFAULT 0 COMMENT '浏览量', + `order` int NOT NULL DEFAULT 0 COMMENT '评论总数', + `state` tinyint NOT NULL DEFAULT 0 COMMENT '状态0标识正常,1表示草稿或隐藏', + `path` varchar(256) NOT NULL COMMENT '文章相对路径', + `cover` varchar(256) DEFAULT NULL COMMENT '文章封面图片路径', + PRIMARY KEY (`article_id`), + KEY `user_id` (`user_id`), + KEY `category_id`(`category_id`) +) COMMENT='文章表'; + +--【6】创建文章标签表 tag +CREATE TABLE `article_tag` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `article_id` bigint NOT NULL COMMENT '文章id', + `tag_id` bigint NOT NULL COMMENT '标签id', + PRIMARY KEY (`id`), + UNIQUE KEY `article_tag_id`(`article_id`,`tag_id`) +) COMMENT='文章标签表'; + + +--【7】创建评论表 comment +CREATE TABLE `comment` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `user_id` bigint NOT NULL COMMENT '创建者id', + `article_id` bigint NOT NULL COMMENT '文章id', + `parent_id` bigint NOT NULL DEFAULT 0 COMMENT '父评论ID' + `content` varchar(256) DEFAULT '' COMMENT '评论内容', + PRIMARY KEY (`id`) +)COMMENT='评论表'; + + +--【8】忽略外键约束 +-- ALTER TABLE blog_article ADD CONSTRAINT FK_ARTICLE_TAGID FOREIGN KEY(tag_id) REFERENCES blog_tag(id); +-- ALTER TABLE blog_article ADD CONSTRAINT FK_ARTICLE_USERID FOREIGN KEY(user_id) REFERENCES blog_auth(id); + +-- ALTER TABLE blog_comment ADD CONSTRAINT FK_COMMENT_USERID FOREIGN KEY(user_id) REFERENCES blog_tag(id); +-- ALTER TABLE blog_comment ADD CONSTRAINT FK_COMMENT_ARTICLEID FOREIGN KEY(article_id) REFERENCES blog_article(id); + +``` + diff --git a/blog/博客/03 博客系统详细设计.md b/blog/博客/03 博客系统详细设计.md new file mode 100644 index 00000000..5c708972 --- /dev/null +++ b/blog/博客/03 博客系统详细设计.md @@ -0,0 +1,31 @@ +# 功能模块设计 + +## 1 文章同步功能 + +### 数据同步 + +### 构建目录 + +### 构建文章 + +### 构建标签 + +### 保存数据 + + +## 2 文章管理功能 + + + +## 3 评论管理功能 + + +## 4 用户管理功能 + + +## 5 后台管理功能 + + + +## 6 自动部署功能 + diff --git a/blog/博客/draw/ER.drawio.svg b/blog/博客/draw/ER.drawio.svg new file mode 100644 index 00000000..9f499618 --- /dev/null +++ b/blog/博客/draw/ER.drawio.svg @@ -0,0 +1,740 @@ + + + + + + + + + + + + + + + + + + + + + + + + 用户 + + + + + + 用户 + + + + + + + + + + + id + + + + + + id + + + + + + + + + + + 昵称 + + + + + + 昵称 + + + + + + + + + + + 邮箱 + + + + + + 邮箱 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 博文 + + + + + + 博文 + + + + + + + + + + + + + + 分类/栏目 + + + + + + 分类/栏目 + + + + + + + + + + + + + + 标签 + + + + + + 标签 + + + + + + + + + + + 密码 + + + + + + 密码 + + + + + + + + + + + 头像 + + + + + + 头像 + + + + + + + + + + + 创建时间 + + + + + + 创建时间 + + + + + + + + + + + 更新时间 + + + + + + 更新时间 + + + + + + + + + + + 用户IP + + + + + + 用户IP + + + + + + + + + + + 标题 + + + + + + 标题 + + + + + + + + + + + 内容 + + + + + + 内容 + + + + + + + + + + + 点赞量 + + + + + + 点赞量 + + + + + + + + + + + 浏览量 + + + + + + 浏览量 + + + + + + + + + + + 优先级 + + + + + + 优先级 + + + + + + + + + + + 全路径 + + + + + + 全路径 + + + + + + + + + + + + 发表 + + + + + + 发表 + + + + + + + + + + + + + + 评论 + + + + + + 评论 + + + + + + + + + + + + 设置 + + + + + + 设置 + + + + + + + + + + + + 设置 + + + + + + 设置 + + + + + + + + + + + + 关联 + + + + + + 关联 + + + + + + + + + + + + 发表 + + + + + + 发表 + + + + + + + + + + + + 公共属性 + + + + + + 公共属性 + + + + + + + + + + + 评论内容 + + + + + + 评论内容 + + + + + + + + + + + + 父评论 + + + + + + 父评论 + + + + + + + + + + + 分类名称 + + + + + + 分类名称 + + + + + + + + + + + 父分类 + + + + + + 父分类 + + + + + + + + + + + 分类描述 + + + + + + 分类描述 + + + + + + + + + + + 名称 + + + + + + 名称 + + + + + + + + + + + 描述 + + + + + + 描述 + + + + + + + + + + + 权重 + + + + + + 权重 + + + + + + + + + + + 点赞量 + + + + + + 点赞量 + + + + + + + + + + + UUID + + + + + + UUID + + + + + + + + + + + 角色 + + + + + + 角色 + + + + + + + + + + + 状态 + + + + + + 状态 + + + + + + + + + + + 封面 + + + + + + 封面 + + + + + + + + + + + + 简介 + + + + + + 简介 + + + + + + + + + + + 用户名 + + + + + + 用户名 + + + + + + + + + Text is not SVG - cannot display + + + + \ No newline at end of file diff --git a/blog/博客/draw/arch.drawio.svg b/blog/博客/draw/arch.drawio.svg new file mode 100644 index 00000000..a0ce7193 --- /dev/null +++ b/blog/博客/draw/arch.drawio.svg @@ -0,0 +1,227 @@ + + + + + + + + + + + + + Github + + + + + + Github + + + + + + + + + + + + + + + Vscode + + + + + + Vscode + + + + + + + + + + + Markdown + + + + + + Markdown + + + + + + + + + + + + + Sync + + + + + + Sync + + + + + + + + + + + Rest Interface + + + + + + Rest Interface + + + + + + + + + + + User + + + + + + User + + + + + + + + + + + Article + + + + + + Article + + + + + + + + + + + + + VUE(Data + Template Render) + + + + + + VUE(Data + Template Render) + + + + + + + + + + + 文章 + + + + + + 文章 + + + + + + + + + + + 用户 + + + + + + 用户 + + + + + + + + + + + 分类 + + + + + + 分类 + + + + + + + + + + + 标签 + + + + + + 标签 + + + + + + + + + Text is not SVG - cannot display + + + + \ No newline at end of file diff --git a/blog/博客/draw/logic.drawio.svg b/blog/博客/draw/logic.drawio.svg new file mode 100644 index 00000000..d252b386 --- /dev/null +++ b/blog/博客/draw/logic.drawio.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user + + + + + id:bigint + + + + + username:varchar(32) + + + + + passworld:varchar(64) + + + + + nickname:varchar(32) + + + + + email:varchar(64) + + + + + role:unsigned tinyint + + + + + photo:varchar(256) + + + + + UUID:varchar(128) + + + + + ip:varchar(32) + + + + + + + + article + + + + + id:bigint + + + + + user_id:bigint + + + + + category_id:bigint + + + + + title:varchar(128) + + + + + content:longtext + + + + + description:varchar(256) + + + + + love:int + + + + + view:int + + + + + order:int + + + + + state:tinyint + + + + + path:varchar(256) + + + + + cover:varchar(256) + + + + + + + + tag + + + + + id:bigint + + + + + name:varchar(32) + + + + + count:int + + + + + description:varchar(256) + + + + + + + + category + + + + + id:bigint + + + + + name:varchar(32) + + + + + parent:bigint + + + + + description:varchar(256) + + + + + + + + comment + + + + + id:bigint + + + + + article_id:bigint(128) + + + + + content:text + + + + + parent:bigint + + + + + description:varchar(256) + + + + + + + + + + article_tag + + + + + id:bigint + + + + + article_id:bigint + + + + + tag_id:bigint + + + + + + + + + + + + \ No newline at end of file