当前位置: 首页 > 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);}

相关文章:

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

文章目录一、项目演示二、项目介绍三、项目运行截图四、主要代码一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootReact框架开发的博客论坛系统。首先&#xff0c;这是一个前后端分离的项目&#xff0c;文章编辑器…...

C++ primer 之 extern

C primer 之 extern什么是声明什么是定义两者有什么区别ertern的作用什么是声明 就是使得名字为程序所知&#xff0c;一个文件如果想使用别处定义的名字就必须包含对那个名字的声明。 什么是定义 负责创建与名字关联的实体。 两者有什么区别 变量声明和声明都规定了变量的…...

Linux 练习二 (VIM编辑器 + GCC编译器 + GDB调试)

文章目录VIM命令思维导图GCC编译器1、GCC编译文件练习2、静态库动态库制作练习将此函数编译成动态库将此函数编译成静态库GCC优化选项 -OnGDB调试命令练习练习一&#xff1a;编写一个程序&#xff0c;通过gdb调试&#xff0c;使用到gdb的b&#xff0c;n&#xff0c;s&#xff0…...

python3 连接数据库 mysql PyMysql

python3PyMysql PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库 &#xff0c; 遵循 Python 数据库 API v2.0 规范 。 PyMySQL 安装 pip install PyMySQLPyMySQL 连接数据库 import pymysql pymysql.Connect(hostlocalhost,port 3306,user root,password **…...

昇腾AI新技能,还能预防猪生病?

国药集团动物保健股份有限公司&#xff08;简称“国药动保”&#xff09;是专业从事动物保健产品研发、生产和销售的国家高新技术企业&#xff0c;是国内少数几家具备新产品原创能力的动物保健企业。其中&#xff0c;猪圆环病毒灭活疫苗等市场份额位居行业前列。 “猪圆环病毒…...

模板方法模式(Template Method)

模式结构图 说明 基本方法是模板方法的组成部分。基本方法分为一下三种&#xff1a; 抽象方法 由抽象类声明&#xff0c;由其具体子类实现。C中就是纯虚函数。 具体方法 由抽象类或具体类声明并实现&#xff0c;子类可以进行覆盖也可以继承。C中是虚函数。 钩子方法 由抽象类…...

C C++ typedef的使用

一、为基本数据类型起别名 typedef int myint; myint x 5; "myint"是"int"的别名&#xff0c;可以使用"myint"来代替"int"声明变量&#xff0c;这个很好理解&#xff0c;但是也很少有人这么用吧。 二、为结构体起别名 …...

Laravel框架03:DB类操作数据库

Laravel框架03&#xff1a;DB类操作数据库一、概述二、数据表的创建与配置三、增删改操作1. 增加信息2. 修改数据3. 删除数据四、查询操作1. 取出基本数据2. 取出单行数据3. 获取一个字段的值4. 获取多个字段的值5. 排序6. 分页五、执行任意的SQL语句一、概述 按照MVC的架构&a…...

数据结构期末复习总结(前章)

作者的话 作为一名计算机类的学生&#xff0c;我深知数据结构的重要性。在期末复习前&#xff0c;我希望通过这篇博客给大家一些复习建议。希望能帮助大家夯实数据结构的基础知识&#xff0c;并能够更好地掌握数据结构和算法的应用。 一、绪论 数据&#xff1a;信息的载体&am…...

设计环形队列

文章目录1.思路分析1.1队列空满分析1.2出队分析2.循环队列设计1.思路分析 1.1队列空满分析 首先我们假设一个长度为4的环形队列 队头front 队尾rear 当队列为空时 frontrear 当队列满时 frontrear 所以我们无法判断队列是满的或者空的 因此我们多加入一个空间使队列长度为5&am…...

面向对象之-接口鉴权

1 需求 1.1 需求背景 为了保证接口调用的安全性&#xff0c;我们希望设计实现一个接口调用鉴权功能&#xff0c;只有经过认证之后的系统才能调用我们的接口&#xff0c;没有认证过的系统调用我们的接口会被拒绝。 2 需求分析 2.1 基础分析 对于如何做鉴权这样一个问题&…...

Python 多进程多线程线程池进程池协程

目录 一、线程与进程很简单的介绍 1.1 线程与进程的区别 二、多进程Process 2.1 多进程与多线程的区别 2.2 多进程为啥要使用队列 2.3 控制进程运行顺序 2.3.1 join &#xff0c; 2.3.1 daemon 守护进程 2.4 进程id 2.5 进程 存活状态is_alive() 2.5 实现自定义多…...

【自然语言处理】基于句子嵌入的文本摘要算法实现

基于句子嵌入的文本摘要算法实现人们在理解了文本的含义后&#xff0c;很容易用自己的话对文本进行总结。但在数据过多、缺乏人力和时间的情况下&#xff0c;自动文本摘要则显得至关重要。一般使用自动文本摘要的原因包括&#xff1a; 减少阅读时间根据摘要&#xff0c;选择自…...

fiddler抓包

一、工具介绍Fiddler是一个通过代理的方式来进行抓包工具&#xff0c;运行时会在本地建立一个代理服务&#xff0c;默认地址&#xff1a;127.0.0.1:8888。Fiddler开启之后&#xff0c;配置本机代理&#xff0c;再打开IE浏览器&#xff0c;IE的PROXY会自动变成127.0.0.1:8888&am…...

【Linux】网络套接字编程

前言 在掌握一定的网络基础&#xff0c;我们便可以先从代码入手&#xff0c;利用UDP协议/TCP协议进行编写套接字程序&#xff0c;明白网络中服务器端与客户端之间如何进行连接并且通信的。 目录 一、了解源目的IP、端口、网络字节序、套接字 端口号&#xff1a; 套接字&…...

break与continue关键字

1.概述 不知道大家有没有这样一种感受哈&#xff0c;有的时候容易混淆break语句和continue语句的用法&#xff0c;总是模棱两可&#xff0c;不敢确定自己是否使用正确了。正好&#xff0c;我们本篇的重点就是break和continue关键字的用法。 2.使用场景 Java中为啥会诞生break…...

kafka使用入门案例与踩坑记录

每次用到kafka时都会出现各种奇怪的问题&#xff0c;综合实践&#xff0c;下面汇总下主要操作步骤&#xff1a; Docker镜像形式启动 zookeeper启动 docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeperkafka启动 docker run --name kafka01 -p 9092:909…...

系统启动太慢,调优后我直呼Nice

问题背景最近在负责一个订单系统的业务研发&#xff0c;本来不是件困难的事。但是服务的启动时间很慢&#xff0c;慢的令人发指。单次启动的时间约在10多分钟左右&#xff0c;基本一次迭代、开发&#xff0c;大部分的时间都花在了启动项目上。忍无可忍的我&#xff0c;终于决定…...

java知识点

文章目录异常写法JVM加载反射访问private调用方法动态代理注解元数据&#xff1a;TargetRetention元注解泛型编写泛型擦拭法局限通配符无限定通配符(<?>)集合重写方法和实现类IO流字节与字符转换同步和异步可以设置编码的类Print*类Files时间与日期时区一种二种三种异常…...

文件的打开关闭和顺序读写

目录 一、文件的打开与关闭 &#xff08;一&#xff09;文件指针 &#xff08;二&#xff09; 文件的打开和关闭 二、文件的顺序读写 &#xff08;一&#xff09;fputc 1. 介绍 2. 举例 &#xff08;二&#xff09;fgetc 1. 介绍 2. 举例1 3. 举例2 &#xff08;三&…...

(十八)操作系统-进程互斥的软件实现方法

文章目录一、知识总览二、单标志法三、双标志先检查法四、双标志后检查法五、Peterson算法六、总结一、知识总览 二、单标志法 算法思想&#xff1a;两个进程在访问临界区后&#xff0c;会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进…...

2023年三月份图形化一级打卡试题

活动时间 从2023年3月1日至3月21日&#xff0c;每天一道编程题。 本次打卡的规则如下&#xff1a; 小朋友每天利用10~15分钟做一道编程题&#xff0c;遇到问题就来群内讨论&#xff0c;我来给大家答疑。 小朋友做完题目后&#xff0c;截图到朋友圈打卡并把打卡的截图发到活动群…...

linux 防火墙管理-firewalld

什么是Firewalld 当前很多linux系统中都默认使用 firewalld&#xff08;Dynamic Firewall Manager of Linux systems&#xff0c;Linux系统的动态防火墙管理器&#xff09;服务作为防火墙配置管理工具。 “firewalld”是firewall daemon。它提供了一个动态管理的防火墙&#x…...

2023年最新大厂开发面试题(滴滴,华为,京东,腾讯,头条)

2023年最新大厂开发面试题&#xff01;&#xff01;&#xff01; 滴滴篇 B树、B-树的区别? 数据库隔离级别&#xff0c;幻读和不可重复读的区别&#xff1f; 有 hell, well, hello, world 等字符串组&#xff0c;现在问能否拼接成 helloworld&#xff0c;代码实现。 快排算…...

2023年三月份图形化三级打卡试题

活动时间 从2023年3月1日至3月21日&#xff0c;每天一道编程题。 本次打卡的规则如下&#xff1a; 小朋友每天利用10~15分钟做一道编程题&#xff0c;遇到问题就来群内讨论&#xff0c;我来给大家答疑。 小朋友做完题目后&#xff0c;截图到朋友圈打卡并把打卡的截图发到活动群…...

蓝桥杯算法模板

模拟散列表拉链法import java.io.*; import java.util.*; public class a1 {static int n;static int N100003;static int[] hnew int[N];static int[] enew int[N];static int[] nenew int[N]; static int idx; static void insert(int x){int k(x%NN)%N;e[idx]x;ne[idx]h[k];…...

python之并发编程

一、并发编程之多进程 1.multiprocessing模块介绍 python中的多线程无法利用多核优势&#xff0c;如果想要充分地使用多核CPU的资源&#xff08;os.cpu_count()查看&#xff09;&#xff0c;在python中大部分情况需要使用多进程。Python提供了multiprocessing。 multiprocess…...

Vue.js自定义事件的使用(实现父子之间的通信)

vue v-model修饰符&#xff1a;.lazy、.number、.trim $attrs数据的透传&#xff0c;在组件&#xff08;这个是写在App.vue中&#xff09;,数据就透传到student组件中&#xff0c;在template中可以直接使用{{$attrs.students}}获取数据 通过defineProps定义的属性在attrs中就…...

第12天-商品维护(发布商品、商品管理、SPU管理)

1.发布商品流程 发布商品分为5个步骤&#xff1a; 基本信息规格参数销售属性SKU信息保存完成 2.发布商品-基本信息 2.1.会员等级-会员服务 2.1.1.会员服务-网关配置 在网关增加会员服务的路由配置 - id: member_routeuri: lb://gmall-memberpredicates:- Path/api/member/…...

动态分区分配计算

动态分区分配 内存连续分配管理分为&#xff1a; 单一连续分配固定分区分配动态分区分配&#xff08;本篇所讲&#xff09; 首次适应算法&#xff08;First Fit&#xff0c;FF&#xff09; 该算法又称最先适应算法&#xff0c;要求空闲分区按照首地址递增的顺序排列。 优点…...

企业建网站报价/百度推广关键词技巧定价

中关村在线消息&#xff1a;华为今日发布了2019年上半年业绩&#xff1a;上半年销售收入4013亿元&#xff0c;同比增长23.2%。其中消费者业务2208亿元&#xff0c;占比55%。华为今年上半年智能手机发货量(含荣耀)达到1.18亿台&#xff0c;同比增长24%。华为董事长梁华表示&…...

商城移动端网站开发/东莞网站推广大全

引子 今年开始&#xff0c;我在翻译一本大部头的&#xff0c;比较经典的的Python进阶书籍。 有空就翻译几页。这本书不仅是教你很多进阶的Python的语法&#xff0c;更重要的是讲解很多设计方法和设计思想。 这些方法和思想&#xff0c;一点点叠加起来&#xff0c;就会让你从…...

长春市网站制作/百度电脑版

描述 给一包含大写字母和整数(从 0 到 9)的字符串, 试写一函数返回有序的字母以及数字和. 样例 - 样例 1:输入 : str "AC2BEW3" 输出 : "ABCEW5" 说明 : 字母按字母表的顺序排列, 接着是整数的和(2 和 3)。解析 首先看了一下Java和Python的提交 Java…...

wordpress 主题 保存/人工智能培训班收费标准

树的遍历 Description 给定某二叉树的前序序列和中序序列&#xff0c;输出该二叉树的后序序列。&#xff08;输入的前序遍历和中序遍历的结果中都不含重复的数字&#xff09; 第一行是n 接下来一行有n个数表示前序序列 最后一行是中序序列 对于30%的数据&#xff0c;n<20…...

四川高速公路建设集团网站/电商网站订烟

springspringMVCMybatis整合_XML配置示例 1.概述 springspringMVCMybatis整合 XML配置方式 1.1 测试环境说明 名称版本备注操作系统windows 10 专业版 1809_X64 JDKjdk1.8.0_121 WIN_X64 数据库mysql5.7 WIN_X64 web服务器Tomcat8.5 WIN_X64 2.入门示例 2.1示例流程简述 第…...

自己做电商网站吗/短视频代运营合作方案

问题出于安全原因&#xff0c;默认参数很严格&#xff0c;禁止root用户直接使用ssh登陆比如先用非root的帐户&#xff0c;登陆到ssh后&#xff0c;su成为root解决方案如果想直接用root登陆&#xff0c;则修改如下配置文件&#xff1a;vi /etc/ssh/sshd_config找到其中的如下一行…...