当前位置: 首页 > news >正文

SpringBoot+React博客论坛系统 附带详细运行指导视频

文章目录

  • 一、项目演示
  • 二、项目介绍
  • 三、项目运行截图
  • 四、主要代码

一、项目演示

项目演示地址: 视频地址

二、项目介绍

项目描述:这是一个基于SpringBoot+React框架开发的博客论坛系统。首先,这是一个前后端分离的项目,文章编辑器支持Markdown语法,项目代码简洁规范,注释说明详细,易于理解和学习。其次,这项目功能丰富,具有一个博客论坛系统该有的所有功能。

项目功能:此项目分为两个角色:普通用户管理员普通用户有登录注册、浏览博客和问答信息、发表评论、问答发起者也能采纳评论、写文章、提问题、管理个人信息、关注他人等等功能。管理员除了拥有普通用户的所有功能,还有管理所有用户信息、管理所有文章信息、管理所有文章分类信息、管理所有文章标签信息、管理所有评论信息等等功能。

应用技术:SpringBoot + React + MySQL + MyBatis + Redis + Antd

运行环境:IntelliJ IDEA2019.3.5 + MySQL5.7(项目压缩包中自带) + Redis5.0.5(项目压缩包中自带) + JDK1.8 + Maven3.6.3(项目压缩包中自带)+ Node14.16.1(项目压缩包中自带)

三、项目运行截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、主要代码

1.前台编辑器页面代码:

 <div className={editorStyle.editor}><div className={editorStyle.title}><div className={editorStyle.back} onClick={() => backHome()}>返回首页</div><div style={{width: '80%', paddingTop: '0.5rem'}}><Input defaultValue={article.title} value={article.title} onChange={ e => setArticle({...article, title: e.target.value}) } ref={inputTitle} className={editorStyle.input} placeholder="请在这里输入文章标题"/></div></div><div className={editorStyle.content}><EditorContent onSave={() => saveArticle(6, 1)} ref={editor} preview={true} subfield={true}addImg={($file) => addImg($file)}value={article.contentMarkdown} onChange={handleChange}/></div><div className={editorStyle.footer}><div className={editorStyle.left}><div style={{width: '50%'}}><Select defaultValue={article.categoryId} value={article.categoryId} onChange={ e => setArticle({...article, categoryId: e}) }  style={{width: '100%'}} placeholder="请选择文章分类">{categoryList && categoryList.map((item, index) => {return (<Select.Option key={index} value={item.id}>{item.name}</Select.Option>)})}</Select></div><div style={{width: '50%', marginLeft: '1rem'}} ><ConfigProvider locale={zhCN}><Select mode="multiple" defaultValue={article.tagList} value={article.tagList} onChange={ e => {if(e.length > 3) {message.warning("最多选择3个标签哦!")} else {setArticle({...article, tagList: e});}} } style={{width: '100%'}} placeholder="请选择文章标签">{tagList && tagList.map((item, index) => {return (<Select.Option key={index} value={item.id}>{item.name}</Select.Option>)})}</Select></ConfigProvider></div></div><div className={editorStyle.center}><TextArea rows={1} defaultValue={article.summary} value={article.summary} onChange={ e => setArticle({...article, summary: e.target.value}) } placeholder="请输入文章摘要" /></div><div className={editorStyle.right}><div className={editorStyle.save} onClick={() => saveArticle(6, 1)}>保存草稿箱</div><div className={editorStyle.submit} onClick={() => saveArticle(1, 2)}>发布</div></div></div></div>

2.后端查询文章列表代码:

    /*** 分页获取文章数据* @param pageDTO* @return*/@Overridepublic ResponseDTO<PageDTO<ArticleDTO>> getArticleList(PageDTO<ArticleDTO> pageDTO) {ArticleExample articleExample = new ArticleExample();// 不知道当前页多少,默认为第一页if(pageDTO.getPage() == null){pageDTO.setPage(1);}// 不知道每页多少条记录,默认为每页5条记录if(pageDTO.getSize() == null){pageDTO.setSize(5);}ArticleExample.Criteria c1 = articleExample.createCriteria();if(pageDTO.getParam() != null) {ArticleDTO articleDTO = pageDTO.getParam();if(!CommonUtil.isEmpty(articleDTO.getCategoryId()) && !"0".equals(articleDTO.getCategoryId())) {c1.andCategoryIdEqualTo(articleDTO.getCategoryId());}if(!CommonUtil.isEmpty(articleDTO.getTitle())) {c1.andTitleLike("%" + articleDTO.getTitle() + "%");}if(articleDTO.getType() != null && articleDTO.getType() != 0) {c1.andTypeEqualTo(articleDTO.getType());}if(articleDTO.getState() != null && articleDTO.getState() != 0) {c1.andStateEqualTo(articleDTO.getState());}if(articleDTO.getState() == null) {List<Integer> stateList = new ArrayList<>();stateList.add(ArticleStateEnum.WAIT.getCode());stateList.add(ArticleStateEnum.DRAFT.getCode());stateList.add(ArticleStateEnum.FAIL.getCode());c1.andStateNotIn(stateList);}if(!CommonUtil.isEmpty(articleDTO.getUserId())&& !ArticleQueryTypeEnum.LIKE.getCode().equals(articleDTO.getQueryType())&& !ArticleQueryTypeEnum.COLLECT.getCode().equals(articleDTO.getQueryType())) {c1.andUserIdEqualTo(articleDTO.getUserId());}if(ArticleQueryTypeEnum.BLOG.getCode().equals(articleDTO.getQueryType())) {c1.andTypeEqualTo(ArticleTypeEnum.BLOG.getCode());}if(ArticleQueryTypeEnum.FORUM.getCode().equals(articleDTO.getQueryType())) {c1.andTypeEqualTo(ArticleTypeEnum.FORUM.getCode());}if(ArticleQueryTypeEnum.LIKE.getCode().equals(articleDTO.getQueryType())) {LikeExample likeExample = new LikeExample();likeExample.createCriteria().andUserIdEqualTo(articleDTO.getUserId());List<Like> likeList = likeMapper.selectByExample(likeExample);List<String> articleIdList = likeList.stream().map(Like::getArticleId).collect(Collectors.toList());if(articleIdList.size() == 0) {articleIdList.add("-1");}c1.andIdIn(articleIdList);}if(ArticleQueryTypeEnum.COLLECT.getCode().equals(articleDTO.getQueryType())) {CollectExample collectExample = new CollectExample();collectExample.createCriteria().andUserIdEqualTo(articleDTO.getUserId());List<Collect> collectList = collectMapper.selectByExample(collectExample);List<String> articleIdList = collectList.stream().map(Collect::getArticleId).collect(Collectors.toList());if(articleIdList.size() == 0) {articleIdList.add("-1");}c1.andIdIn(articleIdList);}}articleExample.setOrderByClause("top desc, essence desc, official desc, create_time desc");PageHelper.startPage(pageDTO.getPage(), pageDTO.getSize());// 分页查出文章数据List<Article> articleList = articleMapper.selectByExample(articleExample);PageInfo<Article> pageInfo = new PageInfo<>(articleList);// 获取数据的总数pageDTO.setTotal(pageInfo.getTotal());// 讲domain类型数据  转成 DTO类型数据List<ArticleDTO> articleDTOList = CopyUtil.copyList(articleList, ArticleDTO.class);for(ArticleDTO articleDTO : articleDTOList) {// 获取文章所属用户信息User user = userMapper.selectByPrimaryKey(articleDTO.getUserId());articleDTO.setUserDTO(CopyUtil.copy(user, UserDTO.class));// 获取文章所属标签信息TagItemExample tagItemExample = new TagItemExample();tagItemExample.createCriteria().andArticleIdEqualTo(articleDTO.getId());List<TagItem> tagItemList = tagItemMapper.selectByExample(tagItemExample);List<String> tagIdList = tagItemList.stream().map(TagItem::getTagId).collect(Collectors.toList());List<Tag> tagList;if(tagIdList.size() == 0) {tagList = new ArrayList<>();} else {TagExample tagExample = new TagExample();tagExample.createCriteria().andIdIn(tagIdList);tagList = tagMapper.selectByExample(tagExample);}articleDTO.setTagDTOList(CopyUtil.copyList(tagList, TagDTO.class));// 获取文章所属分类信息Category category = categoryMapper.selectByPrimaryKey(articleDTO.getCategoryId());if(category == null) {articleDTO.setCategoryDTO(CopyUtil.copy(new Category(), CategoryDTO.class));} else {articleDTO.setCategoryDTO(CopyUtil.copy(category, CategoryDTO.class));}}pageDTO.setList(articleDTOList);return ResponseDTO.success(pageDTO);}
http://www.lryc.cn/news/21473.html

相关文章:

  • C++ primer 之 extern
  • Linux 练习二 (VIM编辑器 + GCC编译器 + GDB调试)
  • python3 连接数据库 mysql PyMysql
  • 昇腾AI新技能,还能预防猪生病?
  • 模板方法模式(Template Method)
  • C C++ typedef的使用
  • Laravel框架03:DB类操作数据库
  • 数据结构期末复习总结(前章)
  • 设计环形队列
  • 面向对象之-接口鉴权
  • Python 多进程多线程线程池进程池协程
  • 【自然语言处理】基于句子嵌入的文本摘要算法实现
  • fiddler抓包
  • 【Linux】网络套接字编程
  • break与continue关键字
  • kafka使用入门案例与踩坑记录
  • 系统启动太慢,调优后我直呼Nice
  • java知识点
  • 文件的打开关闭和顺序读写
  • (十八)操作系统-进程互斥的软件实现方法
  • 2023年三月份图形化一级打卡试题
  • linux 防火墙管理-firewalld
  • 2023年最新大厂开发面试题(滴滴,华为,京东,腾讯,头条)
  • 2023年三月份图形化三级打卡试题
  • 蓝桥杯算法模板
  • python之并发编程
  • Vue.js自定义事件的使用(实现父子之间的通信)
  • 第12天-商品维护(发布商品、商品管理、SPU管理)
  • 动态分区分配计算
  • 【云原生】k8s的pod基本概念