# 基于springboot+thymeleaf实现的多法人博客系统
# 一、项目简介
Hexo Boot 是基于 Spring Boot + MySQL 开发的一套开源的博客系统。前身是 [ml-blog](https://github.com/moonlightL/ml-blog) 博客系统,在此基础上演变和扩展而来。
# 二、扩展功能
除了继承 [ml-blog](https://github.com/moonlightL/ml-blog) 中的功能(文章、分类、标签、全局参数)外,Hexo Boot 还扩展了一下功能
- **评论、留言功能**:轻松查看网友的评论与留言,及时互动,同时还附带表情功能,丰富回复内容
- **友链功能**:与网友互换主页,友好分享
- **主题功能**:支持前端页面主题动态变换以及在线编辑源码,让页面色彩丰富起来,同时支持自定义主题
- **黑名单功能**:设置 ip 黑名单,防御网络小人恶意攻击系统
- **附件功能**:支持本地、七牛云、OSS 3种附件管理
- **备份功能**:支持自动和手动备份SQL数据,防患数据丢失
- **音乐播放**:支持音乐配置管理以及在线播放,切换页面不中断
- **动态**:发表个人心情(支持图片、视频和 emoji 表情)、名人名言等简短信息
- **默认主题特色**:支持 CDN 配置
- **图片延迟加载**
- **图片灯箱**
- **夜间模式**
- **音乐播放**
- **打赏功能**
- **点赞功能**
- **评论功能**(支持两种:默认和Twikoo)
- **文章布局**(支持两种:卡片和列表)
- **实现 pjax**
# 三、预览效果
## 3.1 后台管理预览图











## 3.2 前端预览图(默认主题)

# 四、项目设计
## 4.1 数据库设计
### 4.1.1 表结构
**用户表**

**访客表**

**主题表**

**标签表**

**操作日志表**

**文件表**

**分类表**

**系统设计表**

**评论表**

**友情链接表**

**留言表**

**消息表**

**封面表**

**文章表**

**文章评论表**

### 4.1.2 E-R图

## 4.2 系统设计
```java
/**
* 列表页
* @param resultMap
* @return
*/
@RequestMapping("listUI.html")
public String listUI(Map<String, Object> resultMap) {
List<Category> categoryList = this.categoryService.findAll(true);
resultMap.put("categoryList", categoryList);
return this.render("listUI", resultMap);
}
/**
* 新增页
* @param resultMap
* @return
*/
@RequestMapping("addUI.html")
public String addUI(Map<String, Object> resultMap) {
List<Category> categoryList = this.categoryService.findAll(true);
resultMap.put("categoryList", categoryList);
return this.render("addUI", resultMap);
}
/**
* 编辑页
* @param resultMap
* @return
*/
@RequestMapping("editUI/{id}.html")
public String editUI(@PathVariable Integer id, Map<String, Object> resultMap) {
Post post = this.postService.findById(id);
resultMap.put("vo", post);
List<Category> categoryList = this.categoryService.findAll(true);
resultMap.put("categoryList", categoryList);
PostTask postTask = this.postTaskService.getPostTask(post.getId());
resultMap.put("jobTime", postTask != null ? postTask.getJobTime() : "");
return this.render("editUI", resultMap);
}
/**
* 导入页
* @param resultMap
* @return
*/
@RequestMapping("importUI.html")
public String importUI(Map<String, Object> resultMap) {
return this.render("importUI", resultMap);
}
/**
* 新增文章
* @param request
* @return
*/
@RequestMapping("add.json")
@ResponseBody
@OperateLog(value = "新增文章", actionType = ActionEnum.ADMIN_ADD)
public Result add(@Validated(BaseRequest.Save.class) PostRequest request) {
Post post = request.toDoModel();
this.postService.savePost(post);
return Result.success();
}
/**
* 编辑文章
* @param request
* @return
*/
@RequestMapping("edit.json")
@ResponseBody
@OperateLog(value = "编辑文章", actionType = ActionEnum.ADMIN_EDIT)
public Result edit(@Validated(BaseRequest.Update.class) PostRequest request) {
Post post = request.toDoModel();
this.postService.editPost(post);
return Result.success();
}
/**
* 导入文章
* @param path
* @return
*/
@RequestMapping("importPosts.json")
@ResponseBody
@OperateLog(value = "导入文章", actionType = ActionEnum.ADMIN_ADD)
public Result importPosts(@RequestParam String path, @RequestParam String type) {
if ("md".equals(type)) {
this.postService.importPostsByMd(path);
} else if ("json".equals(type)) {
this.postService.importPostsByJson(path);
}
return Result.success();
}
/**
* 修改开关
* @param request
* @return
*/
@RequestMapping("updateSwitch.json")
@ResponseBody
@OperateLog(value = "修改文章状态", actionType = ActionEnum.ADMIN_EDIT)
public Result updateState