SpringBoot实现文章点赞功能

news2024/11/20 18:34:12

提示:今日是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.coloradmin.cn/o/1881636.html

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

相关文章

动态系统开发方法(DSDM): 基于RAD的全面指导与管理

目录 前言1. 动态系统开发方法概述1.1 DSDM的起源与背景1.2 DSDM的核心理念 2. DSDM的关键原则2.1 用户主动参与2.2 频繁交付2.3 时间盒管理2.4 高效的合作 3. DSDM的主要阶段3.1 可行性研究阶段3.2 业务研究阶段3.3 原型开发阶段3.4 设计与构建阶段3.5 部署阶段3.6 维护与支持…

MicroBin好用的粘贴板工具

有时候你可能想从一台电脑上粘贴文本到另一台电脑上&#xff0c;或者是你想要分享一张图片或者是一些文件&#xff0c;某些设备上登陆qq和微信有不太方便&#xff0c;那么就可以使用MicroBin&#xff0c;它不但可以实现跨设备复制粘贴的功能&#xff0c;还支持文件上传等功能 …

基于改进滑模、经典滑模、最优滑模控制的永磁同步电机调速系统MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 针对永磁同步电机调速系统的响应性能和抗干扰能力问题&#xff0c;本文做了四个仿真&#xff0c;分别为&#xff1a;永磁同步电机的PID控制调速系统、基于传统滑模控制的永磁同步电机的调速系统、最…

Windows 系统 Solr 8.11.3 安装详细教程(最新)

Windows 系统 Solr 8.11.3 安装详细教程 说明什么是Solr下载与解压如何启动启动命令&#xff1a;浏览器中打开dashboard其他命令查看关闭命令 说明 本次只是简单安装&#xff0c;为了在项目中使用&#xff0c;如果在公开服务器中安装需要更改开放端口&#xff0c;配置权限等。 …

echarts 图例有数值但是柱子不显示问题

如图所示在做echarts图表时发现柱状图有数值&#xff0c;但是柱子没展示&#xff0c;后来发现这个没展示的数值是最小值和左侧y轴的最小值保持持平了&#xff0c;所以没有展示出来。 将下图中设置y轴最小值为0就可以了 yAxis: [{type: value,name: 产出,min: 0max: dataMax,ax…

使用Visual Studio Code记笔记

因为学习需要&#xff0c;记笔记是很有必要的&#xff0c;平常发CSDN&#xff08;都让CSDN是很棒的哈&#xff09;&#xff0c;后来使用VS Code的时候发现了很多插件&#xff0c;觉得做笔记还是相对不错的&#xff0c;主要用到的还是Markdown 主要设计的插件包括&#xff1a; …

为用户转出并处理MODIS NDVI数据案例过程记述,希望对大家有用!

最近为用户转出和处理了一次MODIS NDVI数据&#xff0c;我将过程做了个总结供大家参考&#xff01;希望能帮助到一些下载和处理数据的朋友! 使用工具为三个&#xff1a;地图资源工具 和 GIS数据转换器-栅格&#xff0c;qgis。 1.选择【数据下载功能】&#xff0c;然后选择MO…

【C++】相机标定源码笔记- 立体视觉相机的校准和图像矫正类

类主要用于双目相机的标定和矫正。它包含了读取和保存相机模型、计算标定参数以及矫正图像的功能。通过这些功能&#xff0c;可以实现双目相机的标定和矫正&#xff0c;从而提高双目相机的精度和稳定性。 公有函数&#xff1a; 构造函数、带参构造函数、析构函数、读取双目相机…

java基于ssm+jsp 房屋租赁系统

1 管理员登录 管理员输入个人的用户名、密码登录系统&#xff0c;这时候系统的数据库就会在进行查找相关的信息&#xff0c;如果我们输入的用户名、密码不正确&#xff0c;数据库就会提示出错误的信息提示&#xff0c;同时会提示管理员重新输入自己的用户名、密码&#xff0c;…

Allegro如何画2D弧形线?

Allegro如何画2D弧形线? 在用Allegro进行PCB设计时,画弧形线的主要是在对PCB进行邮票孔拼板的时候。 具体操作方法如下: 1、选择菜单栏Add 选择3pt Arc(3pt 圆弧) Add的下拉菜单的各项功能作用如下图

influxdb时序数据库使用

influxdb时序数据库使用 influxdb时序数据库使用免费influxdb申请云无服务器Telegraf安装influxdb安装mac安装Redhat && Centos安装docker安装Kubernetes安装windows安装 influx 网页使用influx CLI 安装influx命令行界面influx配置项权限认证配置管理 API 令牌InfluxD…

http.cookiejar.LoadError: Cookies file must be Netscape formatted,not JSON.解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

解析桥式整流电路

下面这个桥式整流电路出场率很高&#xff0c;看着一定眼熟。 事实证明&#xff0c;强行灌输的东西总是难以下咽。记得读书那会&#xff0c;第一次看到这个电路时被吓到了&#xff0c;以至于直到这门课结束了也没搞清楚。 本文就来分析一下此电路中电流的走向&#xff0c;进而理…

1、什么是SSD?

概念 SSD&#xff08;Solid State Drive&#xff09;固态硬盘&#xff0c;是以闪存为介质的存储设备&#xff1b;这里突出的重点是闪存。 闪存&#xff0c;也就是常说的flash&#xff0c;分为NOR 和 NAND&#xff1b; NOR的地址线和数据线分开&#xff0c;所以NOR芯片可以像…

Mojo — 适用于所有人工智能开发人员的编程语言

Mojo语言是一个由人工智能公司Modular推出的全新编程语言&#xff0c;专为AI开发者设计。Mojo的语法与Python相似&#xff0c;但结合了Python的易用性和C语言的高性能&#xff0c;旨在解锁AI硬件的可编程性和AI模型的可扩展性。 Modular这个公司则是一个非常年轻的新生AI创业公…

Spark SQL 的总体工作流程

Spark SQL 是 Apache Spark 的一个模块,它提供了处理结构化和半结构化数据的能力。通过 Spark SQL,用户可以使用 SQL 语言或 DataFrame API 来执行数据查询和分析。这个模块允许开发者将 SQL 查询与 Spark 的数据处理能力结合起来,实现高效、优化的数据处理。下面是 Spark S…

【CT】LeetCode手撕—19. 删除链表的倒数第 N 个结点

题目 原题连接&#xff1a;19. 删除链表的倒数第 N 个结点 1- 思路 模式识别&#xff1a;删除倒数第 n 个结点 ——> 定义 dummyHead 并用双指针实现删除逻辑 2- 实现 ⭐19. 删除链表的倒数第 N 个结点——题解思路 class Solution {public ListNode removeNthFromEnd(Li…

选项类型组件支持动态默认值功能

06/26 主要更新模块概览 动态默认 批量设置 应用设置 表单组件 01 表单管理 1.1 【表单组件】-选项类型组件新增动态默认值功能 说明&#xff1a; 原选项类型默认值只支持固定默认值&#xff0c;且关联其他表单数据无法设置默认值&#xff0c;现增加…

体验升级:扫描全能王智能高清滤镜2.0全面测评

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

U盘数据恢复实战指南:原因、方案与预防措施

一、引言&#xff1a;U盘数据恢复概述 在数字化时代&#xff0c;U盘作为一种便携式存储设备&#xff0c;广泛应用于个人和企业中。然而&#xff0c;由于各种原因&#xff0c;U盘数据丢失的问题时有发生。U盘数据恢复技术便是在这种情况下应运而生&#xff0c;它帮助用户在数据…