当前位置: 首页 > news >正文

嘉兴app开发公司合肥网站优化

嘉兴app开发公司,合肥网站优化,怎么做外贸网站推广,饰品网站建设规划书用户点赞功能 如果用户只要点赞一次就对数据库中blog表中的liked字段的值加1就会导致一个用户无限点赞 PutMapping("/like/{id}") public Result likeBlog(PathVariable("id") Long id) {// 修改点赞数量,update tb_blog set liked liked 1 where id …

用户点赞功能

如果用户只要点赞一次就对数据库中blog表中的liked字段的值加1就会导致一个用户无限点赞

PutMapping("/like/{id}")
public Result likeBlog(@PathVariable("id") Long id) {// 修改点赞数量,update tb_blog set liked = liked + 1 where id = ?	blogService.update().setSql("liked = liked + 1").eq("id", id).update();return Result.ok();
}

需求: 同一个用户只能对同一篇笔记点赞一次再次点击则取消点赞,如果当前用户已经点赞则点赞按钮高亮显示

  • 增加isLike字段: 给Blog实体类中添加一个isLike字段,首页查询热门笔记或用户查看笔记详情内容时会根据isLike字段的属性值决定点赞按钮是否高亮显示
  • 点赞修改功能: 利用Redis中的set集合是否包含点赞用户的Id来判断用户是否点赞过,未点赞则点赞数+1,已点赞则点赞数-1
  • 查看笔记详情时根据id查询笔记: 判断当前登录用户是否点赞过,赋值给isLike字段决定点赞图标是否高亮显示
  • 访问首页时分页查询热门笔记: 判断当前登录用户是否点赞过,赋值给isLike字段决定点赞图标是否高亮显示

在这里插入图片描述

一人一赞

第一步: 给Blog实体类增加isLike字段,首页查询热门笔记或用户查看笔记详情内容时会根据isLike字段的属性值决定点赞按钮是否高亮显示

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_blog")
public class Blog implements Serializable {private static final long serialVersionUID = 1L;// isLike属性不属于Blog表中的字段@TableField(exist = false)private Boolean isLike;//..........
}

第二步: 编写控制器方法处理用户点赞的请求

@PutMapping("/like/{id}")
public Result likeBlog(@PathVariable("id") Long id) {return blogService.likeBlog(id);
}

第三步: 编写业务方法,以blog:liked:笔记Id作为Set集合的Key,集合中的元素就是点赞用户的Id

// 在RedisConstants类中声明一个常量作为Set集合的key,集合中包含了所有点赞的用户
public static final String BLOG_LIKED_KEY = "blog:liked:";
// 操作Redis,key和value要求是String类型
@Resource
private StringRedisTemplate stringRedisTemplate;@Override
public Result likeBlog(Long id) {//1. 获取当前登陆用户信息Long userId = UserHolder.getUser().getId();//2. 判断当前用户是否已经点赞//2.1如果用户未点赞则Blog表中like字段值加1,同时将点赞用户的Id加入set集合String key = BLOG_LIKED_KEY + id;Boolean isLiked = stringRedisTemplate.opsForSet().isMember(key, userId.toString());if (BooleanUtil.isFalse(isLiked)) {// update tb_blog set liked = liked + 1 where id = ?boolean success = update().setSql("liked = liked + 1").eq("id", id).update();// 更新成功将点赞用户Id加入set集合if (success) {stringRedisTemplate.opsForSet().add(key, userId.toString());}//2.2如果当前用户已点赞则取消点赞即like字段值减1,同时将点赞用户Id从set集合中移除}else {// update tb_blog set liked = liked - 1 where id = ?boolean success = update().setSql("liked = liked - 1").eq("id", id).update();if (success){// 更新成功则将点赞用户Id从set集合移除stringRedisTemplate.opsForSet().remove(key, userId.toString());}}return Result.ok();
}

修改查询笔记点赞高亮

访问首页时分页查询热门笔记: 判断当前登录用户是否点赞过,根据Blog实体类isLike属性的值决定点赞图标是否高亮显示

@Override
public Result queryHotBlog(Integer current) {// 根据点赞值降序分页查询笔记信息Page<Blog> page = query().orderByDesc("liked").page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 获取所有查询到的所有笔记数据List<Blog> records = page.getRecords();// 查询笔记中包含的用户昵称和头像以及是否点赞的信息records.forEach(blog -> {// 查询用户昵称和头像封装到Blog实体类当中queryBlogUser(blog);// 判断笔记是否被当前用户点赞isBlogLiked(blog);});return Result.ok(records);
}

查看笔记详情时根据id查询笔记: 判断当前登录用户是否点赞过,根据Blog实体类isLike属性的值决定点赞图标是否高亮显示

@Override
public Result queryBlogById(Integer id) {Blog blog = getById(id);if (blog == null) {return Result.fail("评价不存在或已被删除");}// 查询用户昵称和头像封装到Blog实体类当中queryBlogUser(blog);// 判断笔记是否被当前用户点赞isBlogLiked(blog);return Result.ok(blog);
}

由于查看用户信息判断笔记是否被当前用户点赞的业务逻辑比较通用,所以抽取成独立的方法

// 查看用户信息
private void queryBlogUser(Blog blog) {Long userId = blog.getUserId();User user = userService.getById(userId);blog.setName(user.getNickName());blog.setIcon(user.getIcon());
}// 判断用户是否已经点赞
private void isBlogLiked(Blog blog) {//1. 获取当前用户信息Long userId = UserHolder.getUser().getId();//2. 判断当前用户是否点赞String key = BLOG_LIKED_KEY + blog.getId();Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString());//3. 如果点赞了则将Blog类的isLike属性设置为trueblog.setIsLike(BooleanUtil.isTrue(isMember));
}

点赞排行榜

需求: 当我们点击探店笔记详情页面时,应该按点赞顺序展示点赞过的用户,比如显示最早点赞的TOP5形成点赞排行榜

在这里插入图片描述

因为Set集合不能对点赞的用户进行排序,所以我们需要使用SortedSet(Zset)集合存储点赞的用户Id,score属性的值是当前时间戳(默认按照从小到大排序)

在这里插入图片描述

第一步: ZSet没有判断元素是否存在的方法,是通过获取集合中元素的score属性的值来判断集合中是否有该元素

  • ZSCORE key e1: 获取集合元素的score属性值,若元素存在则返回对应score值,若不存在则返回null
@Override
public Result likeBlog(Long id) {//1. 获取当前登陆用户信息Long userId = UserHolder.getUser().getId();//2. 判断当前用户是否已经点赞//2.1如果用户未点赞则Blog表中like字段值加1,同时将点赞用户的Id加入set集合String key = BLOG_LIKED_KEY + id;// 尝试获取当前用户的score属性值Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());// 如果score为null则表示集合中没有该用户if (score == null) {// update tb_blog set liked = liked + 1 where id = ?boolean success = update().setSql("liked = liked + 1").eq("id", id).update();//更新成功则将点赞用户Id加入SortedSet集合,score属性的值就是当前的时间戳(默认按照从小到大排序)if (success) {stringRedisTemplate.opsForZSet().add(key, userId.toString(), System.currentTimeMillis());}//2.2如果当前用户已点赞则取消点赞即like字段值减1,同时将点赞用户Id从SortedSet集合中移除} else {// update tb_blog set liked = liked - 1 where id = ?boolean success = update().setSql("liked = liked - 1").eq("id", id).update();if (success) {//更新成功将点赞用户Id从SortedSet集合移除stringRedisTemplate.opsForZSet().remove(key, userId.toString());}}return Result.ok();
}

第二步: 判断用户是否点赞时如果用户没有登录就不需要判断用户是否点过赞了,因为用户没有登陆就获取不到userId此时会报空指针异常

private void isBlogLiked(Blog blog) {//1. 获取当前用户信息UserDTO userDTO = UserHolder.getUser();//2. 当用户未登录时就不判断用户是否点赞,直接return结束逻辑if (userDTO == null) {return;}//3. 判断当前用户是否点赞String key = BLOG_LIKED_KEY + blog.getId();Double score = stringRedisTemplate.opsForZSet().score(key, userDTO.getId().toString());// score不等于null返回true表示用户已经点过赞同时给Blog类的isLike属性赋值trueblog.setIsLike(score != null);
}

第三步: 显示点赞排行列表当浏览器发起GET请求blog/likes/4时服务器返回一个List集合包含top5点赞的用户信息

  • ZRANGE key start end: 获取指定范围的元素,SortedSet内的元素会自动排序(默认升序)
@GetMapping("/likes/{id}")
public Result queryBlogLikes(@PathVariable Integer id){return blogService.queryBlogLikes(id);
}
@Override
public Result queryBlogLikes(Integer id) {String key = BLOG_LIKED_KEY + id;// 查询SortedSet集合的前5个元素即用户的id(不包含元素的分数)Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);// 如果返回的set集合是空的即没人点赞,直接返回一个空的List集合if (top5 == null || top5.isEmpty()) {return Result.ok(Collections.emptyList());}// 将Set集合中String类型的用户id转变为Long类型的id然后收集到List集合中List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());//select * from tb_user where id in (ids[0],...) order by field(id, ids[0],...)String idsStr = StrUtil.join(",", ids);// 把ids集合拼成一个以","分隔的字符串List<UserDTO> userDTOS = userService.query().in("id", ids).last("order by field(id," + idsStr + ")").list().stream().map(user -> BeanUtil.copyProperties(user, UserDTO.class))// 将查询出来的用户隐私信息隐藏.collect(Collectors.toList());return Result.ok(userDTOS);
}

由于MySQL默认会对查询出来的所有结果按照id从小到大的方式排序,它并不会按照我们查询到的用户Id顺序去排序

  • order by field(排序字段,排序顺序) : 可以指定查询结果按照某个字段的排序方式

select * from tb_user where id in (ids[0], ids[1] ...): 这种方式并不会按照Set集合中Id的顺序对查询结果进行排序

List<UserDTO> userDTOS = userService.listByIds(ids).steram().map(user -> BeanUtil.copyProperties(user, UserDTO.class))// 将查询出来的用户隐私信息隐藏.collect(Collectors.toList());

select * from tb_user where id in (ids[0],...) order by field(id, ids[0],...): 指定查询结果按照我们指定的字段顺序排序

// 把ids集合拼成一个以","分隔的字符串
String idsStr = StrUtil.join(",", ids);
List<UserDTO> userDTOS = userService.query().in("id", ids).last("order by field(id," + idsStr + ")").list().stream().map(user -> BeanUtil.copyProperties(user, UserDTO.class))// 将查询出来的用户隐私信息隐藏.collect(Collectors.toList());
http://www.hrbkazy.com/news/51814.html

相关文章:

  • 做外贸面料的网站百度关键词指数查询工具
  • 网站建设与管理实验营销策划的八个步骤
  • proxy网站视频剪辑培训机构
  • 淘宝客导购网站长沙百度快照优化排名
  • 四网合一网站建设百度搜索量怎么查
  • 婚庆公司网站建设最好的免费建站网站
  • 北京营销型网站建设百度网站收录提交
  • 免费的好网站网络seo优化推广
  • 国家住房和城乡建设委员会网站良品铺子网络营销策划书
  • 礼服购物车网站模板百度指数热度榜
  • 网站怎么做图片按按钮跳转网站流量统计系统
  • 如何做有亮点的网站建设方案今日头条关键词工具
  • 做学校网站会下线吗优化大师使用心得
  • 有哪些网站做的比较好优化seo招聘
  • 自助wap建站陕西网站建设制作
  • 网站主办者和所有者区别aso关键词排名优化是什么
  • 发卡平台wordpress淘宝优化标题都是用什么软件
  • 建设银行信用卡在网站激活后如何设置密码排名第一的玉米品种
  • 无锡网站建设推广服务腾讯朋友圈广告代理
  • 北京火车站建站时间上海seo关键词优化
  • 网站建设培训个人如何把自己的网站推广出去
  • 国内永久免费crm系统网站推荐大全seo独立站优化
  • 如何自己做摄影网站哪个平台视频资源多
  • 查公司查企业用什么网站公司网站建设北京
  • 想自己做个网站怎么做常州网络推广seo
  • 香港服务器做盈利网站营销策划推广公司
  • 重庆万州网站建设广告咨询
  • 网站开发公司怎么接单子易观数据app排行
  • 做网站要服务器和什么网络推广的方法有多选题
  • 精准引流推广公司重庆网站页面优化