需要做的工作

  • 业务层

    • 查询某个用户关注的人,支持分页。
    • -查询某个用户的粉丝,支持分页。
  • 表现层
    • 处理“查询关注的人”、“查询粉丝”请求。
    • 编写“查询关注的人”、“查询粉丝”模板。

点击关注/粉丝数时,可以显示出关注/粉丝列表

FollowService.java中添加如下方法

// 查询某用户关注的“人”public List<Map<String, Object>> findFollowees(int userId, int offset, int limit) {//支持分页的条件String followeeKey = RedisKeyUtil.getFolloweeKey(userId, ENTITY_TYPE_USER);Set<Integer> targetIds = redisTemplate.opsForZSet().reverseRange(followeeKey, offset, offset + limit - 1);//默认时由小到大排序,但需求在于从大到小,于是倒叙,按范围查,if (targetIds == null) {return null;}List<Map<String, Object>> list = new ArrayList<>();//集合实例化for (Integer targetId : targetIds) {Map<String, Object> map = new HashMap<>();User user = userService.findUserById(targetId);//通过ID查询用户map.put("user", user);//关注的时间,把key,传入,看取那个id的分数Double score = redisTemplate.opsForZSet().score(followeeKey, targetId);map.put("followTime", new Date(score.longValue()));//小数转成long类型list.add(map);}return list;//查询某个用户所关注的人}// 查询某用户的粉丝//逻辑同上述方法类似public List<Map<String, Object>> findFollowers(int userId, int offset, int limit) {String followerKey = RedisKeyUtil.getFollowerKey(ENTITY_TYPE_USER, userId);//redis的range方法,返回的set是有序的,虽然JAVA jdk中的set是无序的,但它有自己的实现方法Set<Integer> targetIds = redisTemplate.opsForZSet().reverseRange(followerKey, offset, offset + limit - 1);if (targetIds == null) {return null;}List<Map<String, Object>> list = new ArrayList<>();for (Integer targetId : targetIds) {Map<String, Object> map = new HashMap<>();User user = userService.findUserById(targetId);map.put("user", user);Double score = redisTemplate.opsForZSet().score(followerKey, targetId);map.put("followTime", new Date(score.longValue()));list.add(map);}return list;}

处理表现层FollowController.java

//将某用户的id传入,因为是查询,所以请求方法是get@RequestMapping(path = "/followees/{userId}", method = RequestMethod.GET)public String getFollowees(@PathVariable("userId") int userId, Page page, Model model) {//Page支持分页,Model,传入模板User user = userService.findUserById(userId);// userService需要注入if (user == null) {//保证ID是正确的throw new RuntimeException("该用户不存在!");}model.addAttribute("user", user);//如果有用户,要将用户传给页面,因为前端页面也需要用到page.setLimit(5);page.setPath("/followees/" + userId);//查询一共有多少条数据;ENTITY_TYPE_USER:注意要实现接口CommunityConstantpage.setRows((int) followService.findFolloweeCount(userId, ENTITY_TYPE_USER));List<Map<String, Object>> userList = followService.findFollowees(userId, page.getOffset(), page.getLimit());if (userList != null) {for (Map<String, Object> map : userList) {User u = (User) map.get("user");map.put("hasFollowed", hasFollowed(u.getId()));//判断当前用户是否对该用户关注}}model.addAttribute("users", userList);return "/site/followee";//返回到模板处理}@RequestMapping(path = "/followers/{userId}", method = RequestMethod.GET)public String getFollowers(@PathVariable("userId") int userId, Page page, Model model) {User user = userService.findUserById(userId);if (user == null) {throw new RuntimeException("该用户不存在!");}model.addAttribute("user", user);page.setLimit(5);page.setPath("/followers/" + userId);page.setRows((int) followService.findFollowerCount(ENTITY_TYPE_USER, userId));List<Map<String, Object>> userList = followService.findFollowers(userId, page.getOffset(), page.getLimit());if (userList != null) {for (Map<String, Object> map : userList) {User u = (User) map.get("user");map.put("hasFollowed", hasFollowed(u.getId()));//判断用户是否是当前用户的粉丝}}model.addAttribute("users", userList);return "/site/follower";//返回到模板处理}private boolean hasFollowed(int userId) {//封装方法,判断当前用户对某人的关注状态if (hostHolder.getUser() == null) {//当前无用户登录return false;}return followService.hasFollowed(hostHolder.getUser().getId(), ENTITY_TYPE_USER, userId);}}

在profile.html中相关标签处做更改

在followee.html和follower.html里面改相应的逻辑

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="icon" href="https://static.nowcoder.com/images/logo_87_87.png"/><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous"><link rel="stylesheet" th:href="@{/css/global.css}" /><title>牛客网-关注</title>
</head>
<body><div class="nk-container"><!-- 头部 --><header class="bg-dark sticky-top" th:replace="index::header"><div class="container"><!-- 导航 --><nav class="navbar navbar-expand-lg navbar-dark"><!-- logo --><a class="navbar-brand" href="#"></a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><!-- 功能 --><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav mr-auto"><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link" href="../index.html">首页</a></li><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link position-relative" href="letter.html">消息<span class="badge badge-danger">12</span></a></li><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link" href="register.html">注册</a></li><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link" href="login.html">登录</a></li><li class="nav-item ml-3 btn-group-vertical dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><img src="http://images.nowcoder.com/head/1t.png" class="rounded-circle" style="width:30px;"/></a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item text-center" href="profile.html">个人主页</a><a class="dropdown-item text-center" href="setting.html">账号设置</a><a class="dropdown-item text-center" href="login.html">退出登录</a><div class="dropdown-divider"></div><span class="dropdown-item text-center text-secondary">nowcoder</span></div></li></ul><!-- 搜索 --><form class="form-inline my-2 my-lg-0" action="search.html"><input class="form-control mr-sm-2" type="search" aria-label="Search" /><button class="btn btn-outline-light my-2 my-sm-0" type="submit">搜索</button></form></div></nav></div></header><!-- 内容 --><div class="main"><div class="container"><div class="position-relative"><!-- 选项 --><ul class="nav nav-tabs mb-3"><li class="nav-item"><a class="nav-link position-relative active" th:href="@{|/followees/${user.id}|}"><i class="text-info" th:utext="${user.username}">Nowcoder</i> 关注的人</a></li><li class="nav-item"><a class="nav-link position-relative" th:href="@{|/followers/${user.id}|}">关注 <i class="text-info" th:utext="${user.username}">Nowcoder</i> 的人</a></li></ul><a th:href="@{|/user/profile/${user.id}|}" class="text-muted position-absolute rt-0">返回个人主页&gt;</a></div><!-- 关注列表 --><ul class="list-unstyled"><li class="media pb-3 pt-3 mb-3 border-bottom position-relative" th:each="map:${users}"><a th:href="@{|/user/profile/${map.user.id}|}"><img th:src="${map.user.headerUrl}" class="mr-4 rounded-circle user-header" alt="用户头像" ></a><div class="media-body"><h6 class="mt-0 mb-3"><span class="text-success" th:utext="${map.user.username}">落基山脉下的闲人</span><span class="float-right text-muted font-size-12">关注于 <i th:text="${#dates.format(map.followTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-28 14:13:25</i></span></h6><div><input type="hidden" id="entityId" th:value="${map.user.id}"><button type="button" th:class="|btn ${map.hasFollowed?'btn-secondary':'btn-info'} btn-sm float-right follow-btn|"th:if="${loginUser!=null && loginUser.id!=map.user.id}" th:text="${map.hasFollowed?'已关注':'关注TA'}">关注TA</button></div></div></li></ul><!-- 分页 --><nav class="mt-5" th:replace="index::pagination"><ul class="pagination justify-content-center"><li class="page-item"><a class="page-link" href="#">首页</a></li><li class="page-item disabled"><a class="page-link" href="#">上一页</a></li><li class="page-item active"><a class="page-link" href="#">1</a></li><li class="page-item"><a class="page-link" href="#">2</a></li><li class="page-item"><a class="page-link" href="#">3</a></li><li class="page-item"><a class="page-link" href="#">4</a></li><li class="page-item"><a class="page-link" href="#">5</a></li><li class="page-item"><a class="page-link" href="#">下一页</a></li><li class="page-item"><a class="page-link" href="#">末页</a></li></ul></nav></div></div><!-- 尾部 --><footer class="bg-dark"><div class="container"><div class="row"><!-- 二维码 --><div class="col-4 qrcode"><img src="https://uploadfiles.nowcoder.com/app/app_download.png" class="img-thumbnail" style="width:136px;" /></div><!-- 公司信息 --><div class="col-8 detail-info"><div class="row"><div class="col"><ul class="nav"><li class="nav-item"><a class="nav-link text-light" href="#">关于我们</a></li><li class="nav-item"><a class="nav-link text-light" href="#">加入我们</a></li><li class="nav-item"><a class="nav-link text-light" href="#">意见反馈</a></li><li class="nav-item"><a class="nav-link text-light" href="#">企业服务</a></li><li class="nav-item"><a class="nav-link text-light" href="#">联系我们</a></li><li class="nav-item"><a class="nav-link text-light" href="#">免责声明</a></li><li class="nav-item"><a class="nav-link text-light" href="#">友情链接</a></li></ul></div></div><div class="row"><div class="col"><ul class="nav btn-group-vertical company-info"><li class="nav-item text-white-50">公司地址:北京市朝阳区大屯路东金泉时代3-2708北京牛客科技有限公司</li><li class="nav-item text-white-50">联系方式:010-60728802(电话)&nbsp;&nbsp;&nbsp;&nbsp;admin@nowcoder.com</li><li class="nav-item text-white-50">牛客科技©2018 All rights reserved</li><li class="nav-item text-white-50">京ICP备14055008号-4 &nbsp;&nbsp;&nbsp;&nbsp;<img src="http://static.nowcoder.com/company/images/res/ghs.png" style="width:18px;" />京公网安备 11010502036488号</li></ul></div></div></div></div></div></footer></div><script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" crossorigin="anonymous"></script><script th:src="@{/js/global.js}"></script><script th:src="@{/js/profile.js}"></script>
</body>
</html>


<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="icon" href="https://static.nowcoder.com/images/logo_87_87.png"/><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous"><link rel="stylesheet" th:href="@{/css/global.css}" /><title>牛客网-关注</title>
</head>
<body><div class="nk-container"><!-- 头部 --><header class="bg-dark sticky-top" th:replace="index::header"><div class="container"><!-- 导航 --><nav class="navbar navbar-expand-lg navbar-dark"><!-- logo --><a class="navbar-brand" href="#"></a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><!-- 功能 --><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav mr-auto"><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link" href="../index.html">首页</a></li><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link position-relative" href="letter.html">消息<span class="badge badge-danger">12</span></a></li><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link" href="register.html">注册</a></li><li class="nav-item ml-3 btn-group-vertical"><a class="nav-link" href="login.html">登录</a></li><li class="nav-item ml-3 btn-group-vertical dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><img src="http://images.nowcoder.com/head/1t.png" class="rounded-circle" style="width:30px;"/></a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item text-center" href="profile.html">个人主页</a><a class="dropdown-item text-center" href="setting.html">账号设置</a><a class="dropdown-item text-center" href="login.html">退出登录</a><div class="dropdown-divider"></div><span class="dropdown-item text-center text-secondary">nowcoder</span></div></li></ul><!-- 搜索 --><form class="form-inline my-2 my-lg-0" action="search.html"><input class="form-control mr-sm-2" type="search" aria-label="Search" /><button class="btn btn-outline-light my-2 my-sm-0" type="submit">搜索</button></form></div></nav></div></header><!-- 内容 (选项)--><div class="main"><div class="container"><div class="position-relative"><!-- 选项 --><ul class="nav nav-tabs mb-3"><li class="nav-item"><a class="nav-link position-relative active" th:href="@{|/followees/${user.id}|}"><i class="text-info" th:utext="${user.username}">Nowcoder</i> 关注的人</a></li><li class="nav-item"><a class="nav-link position-relative" th:href="@{|/followers/${user.id}|}">关注 <i class="text-info" th:utext="${user.username}">Nowcoder</i> 的人</a></li></ul><a th:href="@{|/user/profile/${user.id}|}" class="text-muted position-absolute rt-0">返回个人主页&gt;</a></div><!-- 关注列表 (列表内容)--><ul class="list-unstyled"><li class="media pb-3 pt-3 mb-3 border-bottom position-relative" th:each="map:${users}"><a th:href="@{|/user/profile/${map.user.id}|}"><img th:src="${map.user.headerUrl}" class="mr-4 rounded-circle user-header" alt="用户头像" ></a><div class="media-body"><h6 class="mt-0 mb-3"><span class="text-success" th:utext="${map.user.username}">落基山脉下的闲人</span><span class="float-right text-muted font-size-12">关注于 <i th:text="${#dates.format(map.followTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-28 14:13:25</i></span></h6><div><input type="hidden" id="entityId" th:value="${map.user.id}"><button type="button" th:class="|btn ${map.hasFollowed?'btn-secondary':'btn-info'} btn-sm float-right follow-btn|"th:if="${loginUser!=null && loginUser.id!=map.user.id}" th:text="${map.hasFollowed?'已关注':'关注TA'}">关注TA</button></div></div></li></ul><!-- 分页 --><nav class="mt-5" th:replace="index::pagination"><ul class="pagination justify-content-center"><li class="page-item"><a class="page-link" href="#">首页</a></li><li class="page-item disabled"><a class="page-link" href="#">上一页</a></li><li class="page-item active"><a class="page-link" href="#">1</a></li><li class="page-item"><a class="page-link" href="#">2</a></li><li class="page-item"><a class="page-link" href="#">3</a></li><li class="page-item"><a class="page-link" href="#">4</a></li><li class="page-item"><a class="page-link" href="#">5</a></li><li class="page-item"><a class="page-link" href="#">下一页</a></li><li class="page-item"><a class="page-link" href="#">末页</a></li></ul></nav></div></div><!-- 尾部 --><footer class="bg-dark"><div class="container"><div class="row"><!-- 二维码 --><div class="col-4 qrcode"><img src="https://uploadfiles.nowcoder.com/app/app_download.png" class="img-thumbnail" style="width:136px;" /></div><!-- 公司信息 --><div class="col-8 detail-info"><div class="row"><div class="col"><ul class="nav"><li class="nav-item"><a class="nav-link text-light" href="#">关于我们</a></li><li class="nav-item"><a class="nav-link text-light" href="#">加入我们</a></li><li class="nav-item"><a class="nav-link text-light" href="#">意见反馈</a></li><li class="nav-item"><a class="nav-link text-light" href="#">企业服务</a></li><li class="nav-item"><a class="nav-link text-light" href="#">联系我们</a></li><li class="nav-item"><a class="nav-link text-light" href="#">免责声明</a></li><li class="nav-item"><a class="nav-link text-light" href="#">友情链接</a></li></ul></div></div><div class="row"><div class="col"><ul class="nav btn-group-vertical company-info"><li class="nav-item text-white-50">公司地址:北京市朝阳区大屯路东金泉时代3-2708北京牛客科技有限公司</li><li class="nav-item text-white-50">联系方式:010-60728802(电话)&nbsp;&nbsp;&nbsp;&nbsp;admin@nowcoder.com</li><li class="nav-item text-white-50">牛客科技©2018 All rights reserved</li><li class="nav-item text-white-50">京ICP备14055008号-4 &nbsp;&nbsp;&nbsp;&nbsp;<img src="http://static.nowcoder.com/company/images/res/ghs.png" style="width:18px;" />京公网安备 11010502036488号</li></ul></div></div></div></div></div></footer></div><script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" crossorigin="anonymous"></script><script th:src="@{/js/global.js}"></script><script th:src="@{/js/profile.js}"></script>
</body>
</html>

关键点

4-6:关注列表,粉丝列表相关推荐

  1. 4.3 关注、取消关注和关注、粉丝列表

    文章目录 设计Redis的key和Value 开发关注.取关的业务 开发Controller,接受关注取关请求 修改主页的js 增加获取关注,粉丝数量,是否关注的业务 主页的Controller 修改 ...

  2. 11、Redis实现关注、取消关注以及关注和粉丝列表

    实现关注.取消关注 value的数据类型时zset,有序集合,按照关注的时间排序 followee:userId:entityType -> zset(entityId,now) 某个用户关注的 ...

  3. Redis的应用实例:关注和粉丝的 实现

    前言: 我们知道,关注和粉丝已经成为很多信息流平台必备的功能,比如我们的csdn就有这一功能,但是随着关注人的增加,我们如果采用普通数据库的存储可能会满足不了用户的速度上的体验,如:MySQL数据存储 ...

  4. 使用JavaScript语言配合开发者工具获取B站关注或粉丝的详细信息

    使用JavaScript语言配合开发者工具获取B站关注或粉丝的详细信息 说明:需要在浏览器登录自己的B站账号,才能获取到自己关注或粉丝的完整的信息,否则以访客的身份只能获取到前五页用户的信息,而且会出 ...

  5. 【Redis的应用-关注和粉丝】

    Redis的应用实例:关注和粉丝的 实现 前言: 我们知道,关注和粉丝已经成为很多信息流平台必备的功能,比如我们的csdn就有这一功能,但是随着关注人的增加,我们如果采用普通数据库的存储可能会满足不了 ...

  6. python分析微博粉丝_新浪微博Python SDK笔记——获取粉丝列表或关注列表 | 学步园...

    上一节中创建了一个initclient包,封装了授权的过程,通过获取的myAPIClient对象可以直接调用API接口进行微博操作,上一节中就调用了发微博的接口发了一条新微博.这一节还是直接使用ini ...

  7. 4.6 关注列表、粉丝列表

    FollowService 倒序查询 //查询某用户关注的人public List<Map<String, Object>> findFollowees(int userId, ...

  8. TK协议软件、粉丝列表、评论、关注源码功能介绍

    Tk协议.账号管理 "is_star": false, "birthday": "1900-01-01", "shield_dig ...

  9. Python爬虫:微博粉丝列表

    前言 本来打算做一个关于微博粉丝列表的爬虫,可以统计一下某个微博账号的粉丝里面,僵尸粉(水军)的数量,大V数量. 结果写完爬虫才发现,现在微博只给人看粉丝列表的前5页.......哈哈,好吧.挺无奈的 ...

最新文章

  1. 工业3D打印:一场仍处在初级阶段的技术革命
  2. nagios中自己写的监控mysql主从复制的插件
  3. tensorflow 模型预训练后的参数restore finetuning
  4. Python判断 子集
  5. 新一代音视频技术架构驱动未来多媒体创新
  6. 【数据库系统】元数据
  7. 【API进阶之路】做OCR文字识别,谁说必须要有AI工程师?
  8. 后端开发常用框架文档及中文翻译
  9. mysql把字段拆成两个_MySQL数据库中,将一个字段的值分割成多条数据显示
  10. erp框架 saas_2020管理软件:分析saas系统与erp系统之间的区别
  11. 中科大 EPC课程 爬虫(最新,效果良好)
  12. 【Unity实战100例】Unity读取加载Gif动图的两种方式
  13. BFT类共识协议概览与分析实测
  14. linux公社_如何在Linux上搭建个人流媒体服务器
  15. 【LINUX】自己整理的干货,拿去看吧,不谢!!!。。。。。。。。。。。。
  16. 与QQ群中一屌人的聊天记录,颇有感触,贴出来,大家共勉一下哦
  17. 51单片机的指令系统(一)
  18. python中formatter的用法_Python pyplot.FuncFormatter方法代码示例
  19. 测试管理及项目测试流程
  20. 如何在LibreOffice中使用所有者和用户密码保护文档和PDF文件

热门文章

  1. 【工业互联网】一文读懂SAP Leonardo物联网平台
  2. uC/OS-III系统移植STM32F103C8
  3. 讲一个程序员如何副业月赚三万的真实故事
  4. WIN10中 提示“Win键已禁用”的解决方法
  5. Adobe软件试用下载
  6. Intel无线网卡蓝牙功能失效解决思路分享
  7. 对爱词霸(iciba)生词本功能的一些建议
  8. 迎风破局!Cocos 引擎荣获第六届金陀螺奖「年度优秀游戏服务商奖」
  9. spark driver HA
  10. swiper轮播图鼠标移入暂停有延时的问题