问答平台(4),点赞

点赞

1
2
3
- 支持对帖子、评论点赞。
- 第1次点赞,第2次取消点赞。
- 点赞功能需要考虑性能的问题:点赞数据存到 Redis 里会提升性能。

首页点赞数量

1
- 统计帖子的点赞数量。

详情页点赞数量

1
2
- 统计点赞数量。
- 显示点赞状态。

工具类

  • RedisKeyUtil:新增
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class RedisKeyUtil {

    private static final String SPLIT = ":";
    private static final String PREFIX_ENTITY_LIKE = "like:entity";

    // 某个实体的赞
    // like:entity:entityType:entityId -> set(userId)
    public static String getEntityLikeKey(int entityType, int entityId) {
    return PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;
    }
    }

业务层

  • LikeService:新增
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    @Service
    public class LikeService {

    @Autowired
    private RedisTemplate redisTemplate;

    // 点赞
    public void like(int userId, int entityType, int entityId) {
    String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
    boolean isMember = operations.opsForSet().isMember(entityLikeKey, userId);

    if (isMember) {
    operations.opsForSet().remove(entityLikeKey, userId);
    } else {
    operations.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;
    }
    }

表现层

  • LikeController:新增
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    @Controller
    public class LikeController implements CommunityConstant {

    @Autowired
    private LikeService likeService;

    @Autowired
    private HostHolder hostHolder;

    @RequestMapping(path = "/like", method = RequestMethod.POST)
    @ResponseBody
    public 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<String, Object> map = new HashMap<>();
    map.put("likeCount", likeCount);
    map.put("likeStatus", likeStatus);

    return CommunityUtil.getJSONString(0, null, map);
    }
    }
  • 实现首页的点赞数量的显示
    1
    2
    3
    // HomeController -> getIndexPage(): 加入查找点赞数量的逻辑
    long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, post.getId());
    map.put("likeCount", likeCount);
  • 实现帖子详情页(帖子、评论、回复)的点赞数量和点赞状态的显示
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // DiscussPostController -> getDiscussPost(): 加入如下逻辑

    // 点赞数量
    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);

    // 评论VO列表
    // 点赞数量
    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列表
    // 点赞数量
    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);

页面

  • discuss-detail.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!-- 内容 -->
    <!-- 作者 -->
    <li class="d-inline ml-2">
    <a href="javascript:;" th:onclick="|like(this,1,${post.id});|" class="text-primary">
    <b th:text="${likeStatus==1?'已赞':'赞'}"></b> <i th:text="${likeCount}">11</i>
    </a>
    </li>
    <!-- 回帖列表 -->
    <li class="d-inline ml-2">
    <a href="javascript:;" th:onclick="|like(this,2,${cvo.comment.id});|" class="text-primary">
    <b th:text="${cvo.likeStatus==1?'已赞':'赞'}"></b> (<i th:text="${cvo.likeCount}">1</i>)
    </a>
    </li>
    <!-- 回复列表 -->
    <li class="d-inline ml-2">
    <a href="javascript:;" th:onclick="|like(this,2,${rvo.reply.id});|" class="text-primary">
    <b th:text="${rvo.likeStatus==1?'已赞':'赞'}"></b> (<i th:text="${rvo.likeCount}">1</i>)
    </a>
    </li>
  • discuss.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function like(btn, entityType, entityId) {
    $.post(
    CONTEXT_PATH + "/like",
    {"entityType": entityType, "entityId": entityId},
    function (data) {
    data = $.parseJSON(data);
    if (data.code == 0) {
    $(btn).children("i").text(data.likeCount);
    $(btn).children("b").text(data.likeStatus == 1 ? '已赞' : '赞');
    } else {
    alert(data.msg);
    }
    }
    );
    }
  • index.html
    1
    2
    3
    4
    5
    6
    <!-- 帖子列表 -->
    <ul class="d-inline float-right">
    <li class="d-inline ml-2"><span th:text="${map.likeCount}">11</span></li>
    <li class="d-inline ml-2">|</li>
    <li class="d-inline ml-2">回帖 <span th:text="${map.post.commentCount}">7</span></li>
    </ul>

参考资料


问答平台(4),点赞
https://lcf163.github.io/2020/05/24/问答平台(4),点赞/
作者
乘风的小站
发布于
2020年5月24日
许可协议