SpringBoot实现文章点赞功能

提示:今日是2024年的6月30日,未来的你看到这篇文章,希望你依旧快乐

文章目录


前言

首先在这里前缀部分我就不做要求了,比如说登录信息什么的


数据库表格

这里实现点赞功能,主要是围绕论坛项目完成的

user_info代表用户信息表

forum_article代表着文章信息表

user_message代表着点赞或者评论点赞发送信息表

like_record代表着用户点赞表

 user_info用户信息表

 

 forum_article文章信息表

 

 user_message点赞评论信息发送表

 

 

 like_record点赞信息表

 

 

 表格准备完毕

代码实现

Controller层

 

/*** 实现文章点赞功能。* 通过请求映射 "/doLike",该方法处理用户对文章的点赞操作。* 使用@GlobalInterceptor注解,表明该方法受全局拦截器影响,会检查参数有效性及用户登录状态。** @param session 用户会话对象,用于获取会话中的用户信息。* @param articleId 需要点赞的文章ID,通过@VerifyParam注解确保其为非空,保证操作的有效性。* @return 返回操作成功的响应对象。*/@RequestMapping("/doLike")@GlobalInterceptor(checkParams = true, checkLogin = true)public ResponseVO likeArticle(HttpSession session, @VerifyParam(required = true) String articleId) {// 从会话中获取用户信息SessionWebUserDto sessionWebUserDto = getUserInfoFromSession(session);// 调用点赞服务,记录用户的点赞行为likeRecordService.doLike(articleId, sessionWebUserDto.getUserId(), sessionWebUserDto.getNickName(), OperRecordOpTypeEnum.ARTICLE_LIKE);// 返回操作成功的响应return getSuccessResponseVO(null);}
//枚举package com.easybbs.entity.enums;public enum OperRecordOpTypeEnum {ARTICLE_LIKE(0, "文章点赞"),COMMENT_LIKE(1, "评论点赞");private Integer type;private String desc;OperRecordOpTypeEnum(Integer type, String desc) {this.type = type;this.desc = desc;}public Integer getType() {return type;}public String getDesc() {return desc;}}

至于这里的参数校验和登录校验我就不作详细解释了,相信未来的你也一定可以看懂

 Service接口层

//点赞void doLike(String objectId, String userId, String nickName, OperRecordOpTypeEnum opTypeEnum);

 Service接口实现层

/*** 用户点赞操作。* 实现对文章或评论的点赞功能,并记录用户的点赞行为。* @param objectId 点赞对象的ID,可以是文章ID或评论ID。* @param userId 点赞用户的ID。* @param nickName 点赞用户的昵称。* @param opTypeEnum 点赞操作的类型,区分是文章点赞还是评论点赞。* @throws BusinessException 如果文章不存在,则抛出业务异常。*/@Override@Transactional(rollbackFor = Exception.class)public void doLike(String objectId, String userId, String nickName, OperRecordOpTypeEnum opTypeEnum) {// 创建用户消息对象,用于记录点赞行为。UserMessage userMessage = new UserMessage();userMessage.setCreateTime(new Date());// 根据点赞类型执行不同的操作。switch (opTypeEnum){case ARTICLE_LIKE:// 根据文章ID查询文章信息,如果文章不存在,则抛出异常。ForumArticle forumArticle = forumArticleMapper.selectByArticleId(objectId);if(forumArticle == null){throw new BusinessException("文章不存在");}// 执行文章点赞逻辑。articleLike(objectId,forumArticle,userId,opTypeEnum);// 设置用户消息的相关信息,如文章ID、文章标题等。userMessage.setArticleId(objectId);userMessage.setArticleTitle(forumArticle.getTitle());userMessage.setMessageType(MessageTypeEnum.ARTICLE_LIKE.getType());userMessage.setCommentId(Constants.ZERO);userMessage.setReceivedUserId(forumArticle.getUserId());break;case COMMENT_LIKE:// 评论点赞的逻辑实现。break;}// 设置用户消息的发送者信息。userMessage.setSendUserId(userId);userMessage.setSendNickName(nickName);userMessage.setStatus(MessageStatusEnum.NO_READ.getStatus());// 判断是否为给自己的点赞,若是,则不记录点赞消息。// 判断是否已经点赞if(!userId.equals(userMessage.getReceivedUserId())){// 根据文章ID、评论ID、发送者ID和消息类型查询是否已存在相同的点赞记录。UserMessage dbInfo = userMessageMapper.selectByArticleIdAndCommentIdAndSendUserIdAndMessageType(userMessage.getArticleId(),userMessage.getCommentId(),userMessage.getSendUserId(),userMessage.getMessageType());// 如果不存在相同的点赞记录,则插入新的点赞消息。if(dbInfo == null ){userMessageMapper.insert(userMessage);}}}/*** 用户对文章进行点赞或取消点赞操作。** @param objId 对象ID,即文章的唯一标识。* @param forumArticle 文章对象,用于获取文章的作者信息。* @param userId 用户ID,执行点赞操作的用户。* @param opTypeEnum 操作类型枚举,表示点赞或取消点赞。* @return 返回点赞记录,如果用户之前点赞过,则返回非空;否则返回空。*/public LikeRecord articleLike(String objId, ForumArticle forumArticle, String userId, OperRecordOpTypeEnum opTypeEnum) {// 根据对象ID、用户ID和操作类型查询点赞记录,判断用户是否已经点赞过。LikeRecord record = this.likeRecordMapper.selectByObjectIdAndUserIdAndOpType(objId, userId, opTypeEnum.getType());if (record != null) {// 如果用户之前点赞过,则取消点赞。this.likeRecordMapper.deleteByObjectIdAndUserIdAndOpType(objId, userId, opTypeEnum.getType());// 更新文章的点赞数,减少1。forumArticleMapper.updateArticleCount(UpdateArticleCountTypeEnum.GOOD_COUNT.getType(), -1, objId);} else {// 如果用户未点赞,则创建新的点赞记录。LikeRecord likeRecord = new LikeRecord();likeRecord.setObjectId(objId);likeRecord.setUserId(userId);likeRecord.setOpType(opTypeEnum.getType());likeRecord.setCreateTime(new Date());// 设置点赞记录的作者用户ID为文章的作者用户ID。likeRecord.setAuthorUserId(forumArticle.getUserId());// 插入新的点赞记录。this.likeRecordMapper.insert(likeRecord);// 更新文章的点赞数,增加1。forumArticleMapper.updateArticleCount(UpdateArticleCountTypeEnum.GOOD_COUNT.getType(), 1, objId);}// 返回点赞记录,无论是否新点赞或取消点赞。return record;}

Mapper层

<!-- 根据PrimaryKey获取对象--><select id="selectByArticleId" resultMap="base_result_map" >select <include refid="base_column_list" />,content,markdown_content from forum_article where article_id=#{articleId}</select><!-- 根据PrimaryKey获取对象--><select id="selectByArticleIdAndCommentIdAndSendUserIdAndMessageType" resultMap="base_result_map" >select <include refid="base_column_list" /> from user_message where article_id=#{articleId} and comment_id=#{commentId} and send_user_id=#{sendUserId} and message_type=#{messageType}</select><!-- 根据ObjectIdAndUserIdAndOpType删除--><delete id="deleteByObjectIdAndUserIdAndOpType">delete from like_record where object_id=#{objectId} and user_id=#{userId} and op_type=#{opType}</delete><!-- 根据PrimaryKey获取对象--><select id="selectByObjectIdAndUserIdAndOpType" resultMap="base_result_map" >select <include refid="base_column_list" /> from like_record where object_id=#{objectId} and user_id=#{userId} and op_type=#{opType}</select>

 总结

当然上面只是一些代码的展示,但其实主要的是思路,那接下来我就说明一下我实现的思路

文章点赞功能,首先文章点赞传到Controller层的时候,肯定需要把文章id传送过去,在Controller接受到文章id之后,再从登录信息里面传递出来用户的id,用户的名称,是文章点赞还是评论点赞呢,传递过去之后,创建发送消息的对象,根据点赞类型进行分开,如果是文章点赞的话,首先根据用户id,文章id,点赞类型去查找点赞的记录表,如果说找到了的话,取消点赞,实际上也就是删除点赞信息,删除一条点赞信息表里面的语句,如果说没有点赞的话,创建一个点赞对象,点赞的人是这个用户,名称是这个用户,点赞的文章是文章id,点赞的类型是文章点赞,还需要额外设置点赞是给哪一个用户点赞,肯定是根据文章信息找到发送文章的人,然后插入新的点赞记录,更改文章的点赞数,如果说取消点赞也需要更改文章点赞类型,

点赞完成之后去继续完善用户发送信息表,比如说设置文章id,文章标题,文章点赞类型,接收人用户id是谁,发送人用户id是谁,发送人名字是谁,发送的是未读状态,

接下来首先需要判断不是自己给自己点赞,自己给自己点赞是肯定不会发送消息的,如果说根据文章id,评论的id发送者id,点赞类型查找如果说没有查找到的话,添加一条记录消息,总不能每次点赞完成之后都发送一次消息吧,发送的肯定是一次消息,大概逻辑就是这样

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/864014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SprongBoot3整合Knife4j

大家好&#xff0c;我是晓凡。 写在前面 在上一篇文章&#xff0c;我们详细介绍了SpringBoot3 怎么整合SpringDoc实现在线接口文档。但是&#xff0c;有不少小伙伴 都觉得接口界面太丑了。有没有什么更美观一点的UI界面呢&#xff1f; 当然是有的了&#xff0c;毕竟这是一…

抖音直播自动点赞脚本:让点赞变得简单

抖音直播自动点赞脚本&#xff1a;让点赞变得简单 简介 点赞是社交媒体上表达喜爱的一种方式&#xff0c;尤其在抖音这样的平台上&#xff0c;点赞不仅能够增加主播的人气&#xff0c;还能鼓励他们创作更多优质内容。然而&#xff0c;手动点赞往往既耗时又费力。为了解决这个…

云服务出现故障这样处理

无法连接云服务器 服务器远程无法连接时&#xff0c;可通过7ECloud控制台进行连接。 常见故障现象 1、ping不通 2、ping丢包 3、部分端口telnet不通 4、全部端口telnet不通 5、广告、弹窗植入 6、域名无法访问IP访问正常 常见故障原因 1、云服务器过期、关机或者EIP被…

深度学习基准模型Transformer

深度学习基准模型Transformer 深度学习基准模型Transformer&#xff0c;最初由Vaswani等人在2017年的论文《Attention is All You Need》中提出&#xff0c;是自然语言处理&#xff08;NLP&#xff09;领域的一个里程碑式模型。它在许多序列到序列&#xff08;seq2seq&#xf…

恭喜了!全体前端彻底狂欢吧!这个好消息来得太及时!

在这个快速变化的科技时代&#xff0c;作为独立开发者&#xff0c;你是否常常被繁琐的开发任务压得喘不过气&#xff1f;前端开发要操心后端的各种服务搭建和接口开发&#xff0c;这些琐碎而耗时的工作常常让人头大。但现在&#xff0c;你可以松一口气了&#xff0c;因为MemFir…

【ARM-Linux篇】项目:智能家居

一、项目概述 •项目功能 通过语音控制客厅灯、卧室灯、风扇、人脸识别开门等,可以进行火灾险情监测,可以并且实现Sockect发送指令远程控制各类家电等 •项目描述 全志H616通过串口连接各模块硬件,检测语音的识别结果,分析语音识别的结果来对家电设备进行控制。摄像头拍…

视频上面怎样编辑文字?4种视频编辑文字方法分享

视频已成为我们日常生活中不可或缺的一部分。无论是社交分享、商业宣传还是个人记录&#xff0c;视频都以其直观、生动的特点吸引着观众的眼球。然而&#xff0c;一个优质的视频&#xff0c;除了画面和音效&#xff0c;文字编辑也是提升观看体验的关键。那么&#xff0c;如何在…

Webpack: 并行构建

概述 受限于 Node.js 的单线程架构&#xff0c;原生 Webpack 对所有资源文件做的所有解析、转译、合并操作本质上都是在同一个线程内串行执行&#xff0c;CPU 利用率极低&#xff0c;因此&#xff0c;理所当然地&#xff0c;社区出现了一些以多进程方式运行 Webpack&#xff0…

Redis学习——Redisson 分布式锁集成及其简单使用

文章目录 引言1. Redisson概述1.1 Redisson的基本概念1.2 Redisson的主要功能1.3 Redisson的优点 2. 开发环境3. Redisson的安装与配置3.1 添加依赖3.2 配置Redisson 4. 使用Redisson4.1 可重入锁4.1.1 可重入锁的概念4.1.2 可重入锁的实现原理4.1.3 简单使用锁的获取和释放 4.…

在线疫苗预约小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;工作人员管理&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;疫苗管理&#xff0c;论坛管理&#xff0c;公告管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;公告&#xff0c;疫苗&…

【FreeRTOS】空闲任务

目录 空闲任务及其钩子函数介绍使用钩子函数的前提 实际操作任务如何退出&#xff1f;IDLE函数 空闲任务及其钩子函数 介绍 空闲任务(Idle任务)的作用之一&#xff1a;释放被删除的任务的内存。 除了上述目的之外&#xff0c;为什么必须要有空闲任务? 这是一个良好的程序&…

Linux基础 - DHCP 动态管理主机地址

目录 零. 简介 一. 部署 dhcpd 二. 提高安全性 零. 简介 DHCP&#xff08;Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff09;是一种网络协议&#xff0c;用于动态地为主机分配 IP 地址、子网掩码、默认网关、DNS 服务器等网络配置信息。 其主要…

鸿蒙 HarmonyOs 动画效果 快速入门

一、理论 1.1 animation属性 名称参数类型必填描述durationnumber否设置动画时长&#xff0c;默认值&#xff1a;1000&#xff0c;单位&#xff1a;毫秒temponumber否动画播放速度。数值越大&#xff0c;速度越快&#xff0c;默认为1curvestring | Curve否 设置动画曲线。 默…

C语言--vs使用调试技巧

1.什么是bug? 1.产品说明书中规定要做的事情&#xff0c;而软件没有实现。 2.产品说明书中规定不要做的事情&#xff0c;而软件确实现了。 3.产品说明书中没有提到过的事情&#xff0c;而软件确实现了。 4.产品说明书中没有提到但是必须要做的事情&#xff0c;软件确没有实…

vue3中使用弹幕组件vue-danmaku

1、最开始使用的是vue3-marquee&#xff0c;后面发现一直有一个bug无法解决&#xff0c;就是鼠标hover到第一个弹幕上字体就会变粗&#xff0c;已经提了issue给作者&#xff0c;但是目前还未答复&#xff0c;所以就换了方案。 地址如下&#xff1a; https://github.com/megasa…

stable-diffusion-webui-colab搭建SadTalker由图生成视频人

在这里选择一个stable-diffusion-webui-colab ​​​​​​​​​GitHub - camenduru/stable-diffusion-webui-colab: stable diffusion webui colab 这里我选择是&#xff1a; https://colab.research.google.com/github/camenduru/stable-diffusion-webui-colab/blob/main…

【Python时序预测系列】基于LSTM实现多输入多输出单步预测(案例+源码)

这是我的第312篇原创文章。 一、引言 单站点多变量输入多变量输出单步预测问题----基于LSTM实现。 多输入就是输入多个特征变量 多输出就是同时预测出多个标签的结果 单步就是利用过去N天预测未来1天的结果 二、实现过程 2.1 读取数据集 dfpd.read_csv("data.csv&qu…

CSS-实例-div 水平居中 垂直靠上

1 需求 2 语法 3 示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>表格水平居中、垂直靠上示例…

AI 上车的一些随想

​最近一直在做AI大模型上车的战略企划工作&#xff0c;听了好多供应商的宣讲&#xff0c;自己也查阅了大量书籍、资料。信息输入呈现爆炸性增长&#xff0c;受限于专业知识水平&#xff0c;仅能在应用层面上有所思考。纯个人观点&#xff0c;仅供参考。 车自古以来都是移动工…