4-3:点赞功能
创始人
2024-03-07 13:55:39
0

点赞

点赞

  • 支持对帖子、评论点赞。
  • 第1次点赞,第2次取消点赞。
    首页点赞数量
  • 统计帖子的点赞数量。
    详情页点赞数量
  • 统计点赞数量。
  • 显示点赞状态。

Redis缓存用于点赞功能,可以提高性能。(面向Key编程)

1.建立RedisKeyUtil.java

package com.nowcoder.community.util;public class RedisKeyUtil {private static final String SPLIT = ":";private static final String PREFIX_ENTITY_LIKE = "like:entity";// 生成某个实体的赞// like:entity:entityType:entityId -> set(userId),用id集合表示赞,不用整数,防止后面需求发生变化,集合中装载UserId,public static String getEntityLikeKey(int entityType, int entityId) {return PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;//拼的结果}}
  1. 开发业务组件LikeService.java
package com.nowcoder.community.service;import com.nowcoder.community.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;@Service
public class LikeService {@Autowiredprivate RedisTemplate redisTemplate;//注入Redis模板// 点赞public void like(int userId, int entityType, int entityId) {String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);boolean isMember = redisTemplate.opsForSet().isMember(entityLikeKey, userId);if (isMember) {//判断用户是否点过赞,用户id在集合中,就是点过赞。redisTemplate.opsForSet().remove(entityLikeKey, userId);} else {redisTemplate.opsForSet().add(entityLikeKey, userId);}}// 查询某实体被点赞的数量public long findEntityLikeCount(int entityType, int entityId) {String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);return redisTemplate.opsForSet().size(entityLikeKey);}// 查询某人对某实体的点赞状态public int findEntityLikeStatus(int userId, int entityType, int entityId) {String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);return redisTemplate.opsForSet().isMember(entityLikeKey, userId) ? 1 : 0;//返回整数,可以表现更多的状态,如踩等。1:点赞,0:没有点赞}
}

3. 表现层

异步请求,整个页面不刷新,更新点赞数就行

package com.nowcoder.community.controller;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.HashMap;
import java.util.Map;@Controller
public class LikeController {@Autowiredprivate LikeService likeService;@Autowiredprivate HostHolder hostHolder;@RequestMapping(path = "/like", method = RequestMethod.POST)//处理异步请求的方法@ResponseBodypublic String like(int entityType, int entityId) {User user = hostHolder.getUser();// 点赞likeService.like(user.getId(), entityType, entityId);// 数量long likeCount = likeService.findEntityLikeCount(entityType, entityId);// 状态int likeStatus = likeService.findEntityLikeStatus(user.getId(), entityType, entityId);// 返回的结果:统一传递给页面Map map = new HashMap<>();map.put("likeCount", likeCount);map.put("likeStatus", likeStatus);return CommunityUtil.getJSONString(0, null, map);//返回Json格式的数据:正确返回0,提示,并将数据返回给页面}}

4.discuss-detail

点赞是在帖子详情页面进行的,也就是说要在该处,进行修改


在这里插入图片描述
依赖的JS文件

function like(btn, entityType, entityId) {$.post(//POST请求,将点赞key拼接CONTEXT_PATH + "/like",{"entityType":entityType,"entityId":entityId},function(data) {//转存服务器返回的数据data = $.parseJSON(data);if(data.code == 0) {//判断请求是否成功$(btn).children("i").text(data.likeCount);//获取btn节点的子节点,改变它的内容。$(btn).children("b").text(data.likeStatus==1?'已赞':"赞");//赞成功了显示“已赞”。} else {alert(data.msg);//失败传出提示}});
}

5. 重启服务器,判断一下结果

在这里插入图片描述
在这里插入图片描述
注意变量要有“$”符号

5首页显示的点赞的数量要一致

在 HomeController.java中,将likeService注入
方法修改如下:

public String getIndexPage(Model model, Page page) {// 方法调用钱,SpringMVC会自动实例化Model和Page,并将Page注入Model.// 所以,在thymeleaf中可以直接访问Page对象中的数据.page.setRows(discussPostService.findDiscussPostRows(0));page.setPath("/index");List list = discussPostService.findDiscussPosts(0, page.getOffset(), page.getLimit());List> discussPosts = new ArrayList<>();if (list != null) {for (DiscussPost post : list) {Map map = new HashMap<>();map.put("post", post);User user = userService.findUserById(post.getUserId());map.put("user", user);long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, post.getId());map.put("likeCount", likeCount);discussPosts.add(map);}}model.addAttribute("discussPosts", discussPosts);return "/index";}

在index.html中找到首页显示赞的地方:

寒江雪 发布于 2019-04-15 15:32:18
  • 11
  • |
  • 回帖 7

5帖子详情页面显示的点赞的数量和状态也要一致

DiscussPostController.java中将likeService注入,在方法内部进行处理

 public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {// 帖子DiscussPost post = discussPostService.findDiscussPostById(discussPostId);model.addAttribute("post", post);// 作者User user = userService.findUserById(post.getUserId());model.addAttribute("user", user);// 点赞数量long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeCount", likeCount);//将状态传到页面// 点赞状态int likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);//判断用户是否登录,没登录也可以看model.addAttribute("likeStatus", likeStatus);......

完整:

public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {// 帖子DiscussPost post = discussPostService.findDiscussPostById(discussPostId);model.addAttribute("post", post);// 作者User user = userService.findUserById(post.getUserId());model.addAttribute("user", user);// 点赞数量long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeCount", likeCount);// 点赞状态int likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeStatus", likeStatus);// 评论分页信息page.setLimit(5);page.setPath("/discuss/detail/" + discussPostId);page.setRows(post.getCommentCount());// 评论: 给帖子的评论// 回复: 给评论的评论// 评论列表List commentList = commentService.findCommentsByEntity(ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());// 评论VO列表List> commentVoList = new ArrayList<>();if (commentList != null) {for (Comment comment : commentList) {// 评论VOMap commentVo = new HashMap<>();// 评论commentVo.put("comment", comment);// 作者commentVo.put("user", userService.findUserById(comment.getUserId()));// 点赞数量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, comment.getId());//评论的点赞状态,数量commentVo.put("likeCount", likeCount);// 点赞状态likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("likeStatus", likeStatus);//装到VO中// 回复列表List replyList = commentService.findCommentsByEntity(ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);// 回复VO列表List> replyVoList = new ArrayList<>();if (replyList != null) {for (Comment reply : replyList) {Map replyVo = new HashMap<>();// 回复replyVo.put("reply", reply);// 作者 replyVo.put("user", userService.findUserById(reply.getUserId()));// 回复目标User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());replyVo.put("target", target);// 点赞数量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, reply.getId());replyVo.put("likeCount", likeCount);// 点赞状态likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, reply.getId());//回复的处理也是类似的。replyVo.put("likeStatus", likeStatus);replyVoList.add(replyVo);}}commentVo.put("replys", replyVoList);// 回复数量int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("replyCount", replyCount);commentVoList.add(commentVo);}}model.addAttribute("comments", commentVoList);return "/site/discuss-detail";}}

6:帖子详情页面也要更改

在这里插入图片描述
另外两个位置处理方式相似
在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...