博主介绍:✌全网粉丝3W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战✌
博主作品:《微服务实战》专栏是本人的实战经验总结,《Spring家族及微服务系列》专注Spring、SpringMVC、SpringBoot、SpringCloud系列、Nacos等源码解读、热门面试题、架构设计等。除此之外还有不少文章等你来细细品味,更多惊喜等着你哦
开源项目:点击这里克隆或者下载
文末关注公众号获取联系精彩专栏推荐订阅 不然下次找不到哟
✨【微服务】Nacos为什么丢弃短连接(http)而选择拥抱长连接(gRPC)
目录
一、前言
1.导言
1.1编写目的
1.2项目范围
1.3参考资料
2.项目介绍
2.1项目背景
2.2项目目标
二、系统设计
1、系统运行环境
2、系统架构设计
三、功能需求简介
1、系统角色分析
1.1、游客
1.2、会员
1.3管理员
2、用例分析与设计
2.1、管理员
2.2、博主
2.3、游客编辑
四、功能截图
1、管理员
1.1、文章管理
1.2、消息管理
1.3、用户管理
1.4、权限管理
1.5、系统管理
1.6、相册管理
1.7、说说管理
2、博主
2.1、首页
2.2、点击测试文章进来
五、实现代码
1、文章控制器
2、服务接口
3、实现类
六、获取源码
一、前言
该文档描述了个人博客网站的功能和性能的要求,将作为对该项目在概要设计阶段的设计输入。
本文档的预期读者包括:
1.设计开发人员
2.项日管理人员
3.测试人员
4.用户
该文档的月的是解决整个项月系统中“做仁么”的问题。对于开发技术在这里并没有涉及,而+要是通过建立模型的方式来描述用户的需求为,客户、用户,开发方等不同参与方提供一个交流的平台。
[1]《软件工程导论第6版》 张海潘等清华大学出版社
[2]《软件项目管理案例教程第3版》韩万江等,机械工业出版社
博客是使用特定的软件,在网络上出版、发表和张贴个人文章的人,或者是一种通常由个人管理、不定期张贴新的文章的网站。博客上的文章通常以网页形式出现,并根据张贴时间,以倒序排列。博客是继MSN、BBS、ICQ之后出现的第4种网络交流方式,现已受到大家的欢迎,是网络时代的个人“读者文摘”,是以超级链接为入口的网络日记,它代表着新的生活、工作和学习方式。许多博客专注在特定的课题上提供评论或新闻,其他则被作为个人性的日记。一个典型的博客结合了文字、图像、其他博客或网站的链接及其它与主题相关的媒体,能够让读者以互动的方式留下意见,是许多博客的重要要素。大部分的博客内容以文字为主,但仍有一些博客专注在艺术、摄影、视频、音乐、播客等各种主题
开发一个具有开放体系结构的、易扩充的、易维护的、具有良好人机交互界面的个人博客网站,为网络用户提供进行在线交流的网络平台。
通过个人博客网站可以结交更多的朋友,表达更多的想法,它随时可以发布文章。
二、系统设计
开发系统:Windows10左右
架构模式:MVC/前后端分离
JDK版本:Java JDK1.8
开发工具:IDEA
数据库版本: mysql5.7
数据库可视化工具: SQL yog或Navicat for MySQL
服务器:SpringBoot自带 apache tomcat
主要技术:Java、SpringBoot2、MyBatis-plus、SpringSecurity、MySQL、RabbitMQ、ES、Html、Vue、Elementui等,建造者模式、策略模式等
三、功能需求简介
角色是指与系统产生交互的外部用户或者外部系统。本系统的使用角色主要有游客、会员、管理员三种。以下是详细介绍
游客是第一次进入网站,但未进行注册,进行部分功能试用,在具体的功能实现上,可以分为以下几个部分:
1.1.1.搜索和浏览他人的博客
游客不须登录系统就可以实现查看日志照片以及博客主的资料信息。
1.1.2.用户注册
游客将个人的信息存储到博客网站的数据库中,以成为本博客的正式用户。
通过计算机网络将前台与后台的数据库相连,系统用户将从前台得到的信息进行处理,实现文章管理,信息管理,个人相册管理,评论,留言等子系统。
1.2.1.博客管理
注册用户员对网站中自己的文章进行删除,更新等操作。
1.2.2.信息管理
发布,更改个人资料信息。
1.2.3.个人相册管理
对博客相册中的图片进行上传,更新,删除操作。
1.2.4.好友管理
添加或删除好友。
1.2.5.评论
对于他人给自己的不恰当评论予以删除。
1.2.6.留言
对他人给自己的留言进行回复或删除。
1.3.1.用户管理
对已注册的用户进行管理。
1.3.2.评论、留言管理
对已注册的用户发表的评论和留言进行管理。
1.3.3.相册管理
对已注册用户上传的照片进行审核,严禁上传不和谐的照片。
1.3.4.博客管理
对用户已发表的博文进行管理,规范其内容,屏蔽掉一些不健康或反动的言论。
分析现有情况及问题,将个人博客系统划分为三个功能用例:游客用例、用户用例、管理员用例。
在个人博客系统中,管理员要让每个博客申请个人博客账号,并让博客设置个人密码,账户内存储每个博客的个人信息。有账号的博客用员可以通过管理员浏览好友动态、写博文、分享博文等。每个博客浏览的范围、期限不同,可通过互联网或登录个人博客网站查询个人信息和其他情况。
登录个人博客主页时,先输入博客的账号和密码,系统验证该帐号的有效性,无效则提示其原因,有效则显示博客的主页信息,供管理员人工核对。然后可以进行浏览动态,添加应用等一些功能。
1系统总体用例
四、功能截图
登录界面:
首页:
1)发布文章
2)文章列表
3)分类管理
4)标签管理
1)评论管理
2)留言管理
1)用户列表
2)在线用户
1)角色管理
2)接口管理
3)菜单管理
1)友链管理
1)相册列表
1)发布说说
2)说说列表
博主也有很多功能界面,这里就不一一举出了。
可以播放音乐,试听结合
五、实现代码
@Api(tags = "文章模块")
@RestController
public class ArticleController {
@Autowired
private ArticleService articleService;
@Autowired
private UploadStrategyContext uploadStrategyContext;
@Autowired
private ArticleImportStrategyContext articleImportStrategyContext;
/**
* 查看文章归档
*
* @return {@link Result} 文章归档列表
*/
@ApiOperation(value = "查看文章归档")
@GetMapping("/articles/archives")
public Result> listArchives() {
return Result.ok(articleService.listArchives());
}
/**
* 查看首页文章
*
* @return {@link Result} 首页文章列表
*/
@ApiOperation(value = "查看首页文章")
@GetMapping("/articles")
public Result> listArticles() {
return Result.ok(articleService.listArticles());
}
/**
* 查看后台文章
*
* @param conditionVO 条件
* @return {@link Result} 后台文章列表
*/
@ApiOperation(value = "查看后台文章")
@GetMapping("/admin/articles")
public Result> listArticleBacks(ConditionVO conditionVO) {
return Result.ok(articleService.listArticleBacks(conditionVO));
}
/**
* 添加或修改文章
*
* @param articleVO 文章信息
* @return {@link Result<>}
*/
@OptLog(optType = SAVE_OR_UPDATE)
@ApiOperation(value = "添加或修改文章")
@PostMapping("/admin/articles")
public Result> saveOrUpdateArticle(@Valid @RequestBody ArticleVO articleVO) {
articleService.saveOrUpdateArticle(articleVO);
return Result.ok();
}
/**
* 修改文章置顶状态
*
* @param articleTopVO 文章置顶信息
* @return {@link Result<>}
*/
@OptLog(optType = UPDATE)
@ApiOperation(value = "修改文章置顶")
@PutMapping("/admin/articles/top")
public Result> updateArticleTop(@Valid @RequestBody ArticleTopVO articleTopVO) {
articleService.updateArticleTop(articleTopVO);
return Result.ok();
}
/**
* 恢复或删除文章
*
* @param deleteVO 逻辑删除信息
* @return {@link Result<>}
*/
@OptLog(optType = UPDATE)
@ApiOperation(value = "恢复或删除文章")
@PutMapping("/admin/articles")
public Result> updateArticleDelete(@Valid @RequestBody DeleteVO deleteVO) {
articleService.updateArticleDelete(deleteVO);
return Result.ok();
}
/**
* 上传文章图片
*
* @param file 文件
* @return {@link Result} 文章图片地址
*/
@ApiOperation(value = "上传文章图片")
@ApiImplicitParam(name = "file", value = "文章图片", required = true, dataType = "MultipartFile")
@PostMapping("/admin/articles/images")
public Result saveArticleImages(MultipartFile file) {
return Result.ok(uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.ARTICLE.getPath()));
}
/**
* 删除文章
*
* @param articleIdList 文章id列表
* @return {@link Result<>}
*/
@OptLog(optType = REMOVE)
@ApiOperation(value = "物理删除文章")
@DeleteMapping("/admin/articles")
public Result> deleteArticles(@RequestBody List articleIdList) {
articleService.deleteArticles(articleIdList);
return Result.ok();
}
/**
* 根据id查看后台文章
*
* @param articleId 文章id
* @return {@link Result} 后台文章
*/
@ApiOperation(value = "根据id查看后台文章")
@ApiImplicitParam(name = "articleId", value = "文章id", required = true, dataType = "Integer")
@GetMapping("/admin/articles/{articleId}")
public Result getArticleBackById(@PathVariable("articleId") Integer articleId) {
return Result.ok(articleService.getArticleBackById(articleId));
}
/**
* 根据id查看文章
*
* @param articleId 文章id
* @return {@link Result} 文章信息
*/
@ApiOperation(value = "根据id查看文章")
@ApiImplicitParam(name = "articleId", value = "文章id", required = true, dataType = "Integer")
@GetMapping("/articles/{articleId}")
public Result getArticleById(@PathVariable("articleId") Integer articleId) {
return Result.ok(articleService.getArticleById(articleId));
}
/**
* 根据条件查询文章
*
* @param condition 条件
* @return {@link Result} 文章列表
*/
@ApiOperation(value = "根据条件查询文章")
@GetMapping("/articles/condition")
public Result listArticlesByCondition(ConditionVO condition) {
return Result.ok(articleService.listArticlesByCondition(condition));
}
/**
* 搜索文章
*
* @param condition 条件
* @return {@link Result} 文章列表
*/
@ApiOperation(value = "搜索文章")
@GetMapping("/articles/search")
public Result> listArticlesBySearch(ConditionVO condition) {
return Result.ok(articleService.listArticlesBySearch(condition));
}
/**
* 点赞文章
*
* @param articleId 文章id
* @return {@link Result<>}
*/
@ApiOperation(value = "点赞文章")
@ApiImplicitParam(name = "articleId", value = "文章id", required = true, dataType = "Integer")
@PostMapping("/articles/{articleId}/like")
public Result> saveArticleLike(@PathVariable("articleId") Integer articleId) {
articleService.saveArticleLike(articleId);
return Result.ok();
}
/**
* 导出文章
*
* @param articleIdList 文章id列表
* @return {@link List} 文件url列表
*/
@ApiOperation(value = "导出文章")
@ApiImplicitParam(name = "articleIdList", value = "文章id", required = true, dataType = "List")
@PostMapping("/admin/articles/export")
public Result> exportArticles(@RequestBody List articleIdList) {
return Result.ok(articleService.exportArticles(articleIdList));
}
/**
* 导入文章
*
* @param file 文件
* @param type 文章类型
* @return {@link Result<>}
*/
@ApiOperation(value = "导入文章")
@PostMapping("/admin/articles/import")
public Result> importArticles(MultipartFile file, @RequestParam(required = false) String type) {
articleImportStrategyContext.importArticles(file, type);
return Result.ok();
}
}
public interface ArticleService extends IService {
/**
* 查询文章归档
*
* @return 文章归档
*/
PageResult listArchives();
/**
* 查询后台文章
*
* @param condition 条件
* @return 文章列表
*/
PageResult listArticleBacks(ConditionVO condition);
/**
* 查询首页文章
*
* @return 文章列表
*/
List listArticles();
/**
* 根据条件查询文章列表
*
* @param condition 条件
* @return 文章列表
*/
ArticlePreviewListDTO listArticlesByCondition(ConditionVO condition);
/**
* 搜索文章
*
* @param condition 条件
* @return 文章列表
*/
List listArticlesBySearch(ConditionVO condition);
/**
* 根据id查看后台文章
*
* @param articleId 文章id
* @return 文章列表
*/
ArticleVO getArticleBackById(Integer articleId);
/**
* 根据id查看文章
*
* @param articleId 文章id
* @return {@link ArticleDTO} 文章信息
*/
ArticleDTO getArticleById(Integer articleId);
/**
* 点赞文章
*
* @param articleId 文章id
*/
void saveArticleLike(Integer articleId);
/**
* 添加或修改文章
*
* @param articleVO 文章信息
*/
void saveOrUpdateArticle(ArticleVO articleVO);
/**
* 修改文章置顶
*
* @param articleTopVO 文章置顶信息
*/
void updateArticleTop(ArticleTopVO articleTopVO);
/**
* 删除或恢复文章
*
* @param deleteVO 逻辑删除对象
*/
void updateArticleDelete(DeleteVO deleteVO);
/**
* 物理删除文章
*
* @param articleIdList 文章id集合
*/
void deleteArticles(List articleIdList);
/**
* 导出文章
*
* @param articleIdList 文章id列表
* @return {@link List}<{@link String}> 文件地址
*/
List exportArticles(List articleIdList);
}
@Service
@Slf4j
public class ArticleServiceImpl extends ServiceImpl implements ArticleService {
@Autowired
private ArticleDao articleDao;
@Autowired
private CategoryDao categoryDao;
@Autowired
private TagDao tagDao;
@Autowired
private TagService tagService;
@Autowired
private ArticleTagDao articleTagDao;
@Autowired
private SearchStrategyContext searchStrategyContext;
@Autowired
private HttpSession session;
@Autowired
private RedisService redisService;
@Autowired
private ArticleTagService articleTagService;
@Autowired
private BlogInfoService blogInfoService;
@Autowired
private UploadStrategyContext uploadStrategyContext;
@Override
public PageResult listArchives() {
Page page = new Page<>(PageUtils.getCurrent(), PageUtils.getSize());
// 获取分页数据
Page articlePage = articleDao.selectPage(page, new LambdaQueryWrapper()
.select(Article::getId, Article::getArticleTitle, Article::getCreateTime).orderByDesc(Article::getCreateTime)
.eq(Article::getIsDelete, FALSE)
.eq(Article::getStatus, PUBLIC.getStatus()));
List archiveDTOList = BeanCopyUtils.copyList(articlePage.getRecords(), ArchiveDTO.class);
return new PageResult<>(archiveDTOList, (int) articlePage.getTotal());
}
@Override
public PageResult listArticleBacks(ConditionVO condition) {
// 查询文章总量
Integer count = articleDao.countArticleBacks(condition);
if (count == 0) {
return new PageResult<>();
}
// 查询后台文章
List articleBackDTOList = articleDao.listArticleBacks(PageUtils.getLimitCurrent(), PageUtils.getSize(), condition);
// 查询文章点赞量和浏览量
Map
六、获取源码
大家点赞、收藏、关注、评论啦 、关注下方公众号获取联系方式