黑马点评12-实现好友关注/取关功能,查看好友共同关注列表

好友关注

数据模型

数据库中的tb_follow记录博主与粉丝的关系

在这里插入图片描述

tb_follow表对应的实体类

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_follow")
public class Follow implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 用户id*/private Long userId;/*** 关联的用户id*/private Long followUserId;/*** 创建时间*/private LocalDateTime createTime;
}

是否关注/关注/取关

需求: 在探店图文的详情页面中,可以查看用户是否关注了笔记博主,用户也可以手动关注/取消关注发布笔记的作者

在这里插入图片描述

第一步: 在FollowController层中编写判断是否关注关注/取关的两个方法

@RestController
@RequestMapping("/follow")
public class FollowController {@Resourceprivate IFollowService followService;// 判断当前用户是否关注了笔记博主,参数是发布笔记的博主Id@GetMapping("/or/not/{id}")public Result isFollow(@PathVariable("id") Long followUserId) {return followService.isFollow(followUserId);}// 实现取关/关注,参数是发布笔记的博主Id以及是否关注(true表示关注,false表示取关)@PutMapping("/{id}/{isFollow}")public Result follow(@PathVariable("id") Long followUserId, @PathVariable("isFollow") Boolean isFellow) {return followService.follow(followUserId,isFellow);}
}

第二步: 在FellowServiceImp中来编写具体的业务逻辑

  • 判断当前用户是否关注了笔记博主: 将请求参数携带的发布笔记的博主Id和当前登陆的用户Id作为条件去数据库中查询是否有对应的记录
  • 关注和取消关注: 请求参数中的true(关注)/fasle(取关),关注是将用户和博主的关联信息保存到数据库,取关即将他们的关联信息从数据库移除,避免堆积数据
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {@Overridepublic Result isFollow(Long followUserId) {// 获取当前登录的用户IdLong userId = UserHolder.getUser().getId();LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();// 查询tb_follow表判断当前用户是否关注了该笔记的博主queryWrapper.eq(Follow::getUserId, userId).eq(Follow::getFollowUserId, followUserId);// 没必要查询出具体数据,只需要判断数据存不存在即可//select count(*) from tb_follow where user_id = ? and follow_user_id = ?int count = this.count(queryWrapper);return Result.ok(count > 0);}@Overridepublic Result follow(Long followUserId, Boolean isFellow) {// 获取当前登录的用户IdLong userId = UserHolder.getUser().getId();// 判断用户是要关注还是取关,true表示关注,false表示取关if (isFellow) {// 关注则将用户和笔记博主的关联信息保存到数据库Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);save(follow);} else {// 取关则将用户和博主的关联信息从数据库中移除,避免数据库中堆积大量数据//delete from tb_follow where user_id = ? and follow_user_id = ?LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Follow::getUserId, userId).eq(Follow::getFollowUserId, followUserId);remove(queryWrapper);}return Result.ok();}
}

共同关注

需求:当我们点击博主用户头像时进入到详情页,可以查看到博主发布的笔记以及用户和博主的好友共同关注列表

在这里插入图片描述

第一步: 在UserController中编写查询博主信息的方法

@GetMapping("/{id}")
public Result queryUserById(@PathVariable("id") Long userId) {// 查询详情User user = userService.getById(userId);if (user == null) {// 查不到返回空return Result.ok();}// 查到则转为userDTO对象UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);// 返回查询到的数据return Result.ok(userDTO);
}

第二步: 在BlogController中编写分页查询博主发布的所有笔记的方法

// 根据博主id查询博主的探店笔记
@GetMapping("/of/user")
public Result queryBlogByUserId(@RequestParam(value = "current", defaultValue = "1") Integer current, @RequestParam("id") Long id) {LambdaQueryWrapper<Blog> queryWrapper = new LambdaQueryWrapper<>();// 根据博主id查询用户信息queryWrapper.eq(Blog::getUserId, id);Page<Blog> pageInfo = new Page<>(current, SystemConstants.MAX_PAGE_SIZE);blogService.page(pageInfo, queryWrapper);// 获取查询到的所有用户信息List<Blog> records = pageInfo.getRecords();return Result.ok(records);
}// 根据博主id查询博主的探店笔记
@GetMapping("/of/user")
public Result queryBlogByUserId(@RequestParam(value = "current", defaultValue = "1") Integer current,@RequestParam("id") Long id) {// 根据博主id查询用户信息Page<Blog> page = blogService.query().eq("user_id", id).page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 获取查询到的所有用户信息List<Blog> records = page.getRecords();return Result.ok(records);
}

第三步: 修改关注/取关的逻辑,以follows:userId作为Set集合的Key,存放当前用户关注的所有博主Id

  • 关注/取关: 将关注的博主Id放到当前登陆用户关注的Set集合中,取关就是将关注的博主Id从当前登陆用户的Set集合中移除
  • 共同关注:通过SINTER key1 key2查询登陆用户的Set集合和其关注博主的Set集合中元素的交集
@Resource
private StringRedisTemplate stringRedisTemplate;
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {@Overridepublic Result follow(Long followUserId, Boolean isFellow) {// 获取当前登录的用户IdLong userId = UserHolder.getUser().getId();String key = "follows:" + userId;// 判断用户是要关注还是取关,true表示关注,false表示取关if (isFellow) {// 关注则将用户和笔记博主的关联信息保存到数据库Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);boolean iSsuccess = save(follow);// 如果更新成功则将关联信息也写入Redis,key是当前的用户id,value就是关注的博主idif (iSsuccess) {stringRedisTemplate.opsForSet().add(key, followUserId.toString());}} else {// 取关则将用户和博主的关联信息从数据库中移除,避免数据库中堆积大量数据//delete from tb_follow where user_id = ? and follow_user_id = ?LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Follow::getUserId, userId).eq(Follow::getFollowUserId, followUserId);boolean iSsuccess = remove(queryWrapper);// 如果取关成功则将关联的博主Id从当前登陆用户的set集合中移除if (iSsuccess){stringRedisTemplate.opsForSet().remove(key,followUserId.toString());}}return Result.ok();} 
}

第四步: 编写控制器方法,查看登陆用户和其关注博主的好友共同关注列表

@GetMapping("/common/{id}")
public Result followCommons(@PathVariable Long id){return followService.followCommons(id);
}
@Resource
private IUserService userService;
@Override
public Result followCommons(Long id) {// 获取当前登陆用户的idLong userId = UserHolder.getUser().getId();// // 获取当前登陆对应的set集合的keyString key1 = "follows:" + userId;// 获取当前登陆用户关注博主所对应的set集合的keyString key2 = "follows:" + id;// 对当前登陆用户和其关注博主的Set集合取交集Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key1, key2);// 无交集就返回个空的List集合if (intersect == null || intersect.isEmpty()) {return Result.ok(Collections.emptyList());}// 将String类型的用户id转化为Long类型的用户id然后使用List集合收集List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());// 根据ids集合中的用户id去数据库中查询登陆用户和博主共同关注的用户信息并封装成UserDto对象,最后存入List集合中返回List<UserDTO> userDTOS = userService.listByIds(ids).stream().map(user ->BeanUtil.copyProperties(user, UserDTO.class)).collect(Collectors.toList());return Result.ok(userDTOS);
}

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

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

相关文章

嵌入式系统在工业自动化中的应用

嵌入式系统在工业自动化中的应用非常广泛&#xff0c;它们通过集成控制和实时响应能力&#xff0c;实现了生产线的自动化、智能化和高效化。以下将详细介绍嵌入式系统在工业自动化中的几个重要应用领域&#xff0c;并提供一些示例代码。 1. PLC&#xff08;可编程逻辑控制器&a…

Web服务器(go net/http) 处理Get、Post请求

大家好 我是寸铁&#x1f44a; 总结了一篇Go Web服务器(go net/http) 处理Get、Post请求的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 go http请求如何编写简单的函数去拿到前端的请求(Get和Post) 服务器(后端)接收到请求后&#xff0c;又是怎么处理请求&#xff0c…

【网络奇缘】- 计算机网络|分层结构|ISO模型

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络分层结构 OSI参考模型 OSI模型起源 失败原因: OSI模型组成 协议的作用 &#x1f4dd;全文…

4.常见面试题--操作系统

特点&#xff1a;并发性、共享性、虚拟性、异步性。 Windows 和 Linux 内核差异 对于内核的架构⼀般有这三种类型&#xff1a; ● 宏内核&#xff0c;包含多个模块&#xff0c;整个内核像⼀个完整的程序&#xff1b; ● 微内核&#xff0c;有⼀个最⼩版本的内核&#xff0…

Python----类对象和实例对象

目录 一.类和类的实例 二.类属性和实例属性 三.私有属性和公有属性 四.静态方法和类方法 五.__init__方法&#xff0c;__new__方法和__del__方法&#xff1a; 六.私有方法和公有方法 七.方法的重载 八.方法的继承 九.方法的重写 十.对象的特殊方法 十一.对象的引用&a…

EPT-Net:用于3D医学图像分割的边缘感知转换器

EPT-Net: Edge Perception Transformer for 3D Medical Image Segmentation EPT-Net&#xff1a;用于3D医学图像分割的边缘感知转换器背景贡献实验方法Dual Positional Transformer&#xff08;双位置Transformer&#xff09;Learnable Patch EmbeddingVoxel Spacial Positiona…

HBuilderX前端软件社区+Thinkphp后端源码

HBuilderX前端软件社区thinkphp后端源码&#xff0c;搭建好后台在前端找到 util 这个文件把两个js文件上面的填上自己的域名&#xff0c;登录HBuilderX账号没有账号就注册账号然后上传文件即可。打包选择发行 可以打包app或h5等等 后端设置运行目录为public(重要)&#xff0c;…

解决LocalDateTime传输前端为时间的数组

问题出现如下&#xff1a; 问题出现原因&#xff1a; 默认序列化情况下会使用SerializationFeature.WRITE_DATES_AS_TIMESTAMPS。使用这个解析时就会打印出数组。 解决方法&#xff1a; 我在全文搜索处理方法总结如下&#xff1a; 1.前端自定义函数来书写 ,cols: [[ //表头{…

ESP32之避障

ESP32之避障 图片 程序 int Led27;//定义LED 接口 int buttonpin4; //定义光遮断传感器接口 int val;//定义数字变量val void setup() { pinMode(Led,OUTPUT);//定义LED 为输出接口 pinMode(buttonpin,INPUT);//定义避障传感器为输出接口 } void loop() {Serial.begin(9600);…

探讨工业元宇宙和数字孪生的关系

就在各类技术专家还在试图设想元宇宙虚拟世界将为企业和消费者带来什么时&#xff0c;工业元宇宙虚拟世界已经在改变人们设计、制造以及与各行业物理实体互动的方式。尽管元宇宙的定义比比皆是&#xff0c;工业元宇宙将如何发展还有待观察&#xff0c;但数字孪生越来越多地被视…

【Unity】 UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用

1. 什么是PhysicsRaycaster组件&#xff1f; PhysicsRaycaster是Unity UGUI中的一个组件&#xff0c;用于在UI元素上进行物理射线检测。它可以检测鼠标或触摸事件是否发生在UI元素上&#xff0c;并将事件传递给相应的UI元素。 2. PhysicsRaycaster的工作原理 PhysicsRaycast…

不做机器视觉工程师,转行,转岗的建议与想法

正所谓外行看热闹&#xff0c;内行看门道。提前咨询前辈们&#xff0c;多问问&#xff0c;多看看。要做就做&#xff0c;一定要提前做好防范。 无论你是要转行或者是转岗&#xff0c;看你有没有本钱和试错成本 有些人&#xff0c;家庭好&#xff0c;可以一直去试错和从头再来。…