JavaWeb_LeadNews_Day9-Redis实现用户行为
JavaWeb_LeadNews_Day9-Redis实现用户行为
- 网关配置
- 点赞
- 阅读
- 不喜欢
- 关注
- 收藏
- 文章详情-行为数据回显
- 来源
- Gitee
网关配置
nacos: leadnews-app-gateway
# 用户行为微服务
- id: leadnews-behavioruri: lb://leadnews-behaviorpredicates:- Path=/behavior/**filters:- StripPrefix= 1
nacos: leadnews-behavior
在配置文件中去除数据源自动配置
spring:# redis配置redis:host: localhost# password: port: 6379autoconfigure:exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
点赞
- 当前登录的用户点击了”赞“,就要保存当前行为数据
- 可以取消点赞
public ResponseResult likesBehavior(LikesBehaviorDto dto) {// 1. 检查参数if(dto == null || dto.getArticleId() == null || checkParam(dto)){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}// 2. 是否登录ApUser user = AppThreadLocalUtil.getUser();if(user == null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}// 3. 点赞, 保存数据if(dto.getOperation() == 0){// 点赞Object obj = cacheService.hGet(BehaviorConstants.LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString());if(obj != null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "已点赞");}// 保存当前keylog.info("保存当前key:{} ,{}, {}", BehaviorConstants.LIKE_BEHAVIOR+dto.getArticleId(), user.getId(), dto);cacheService.hPut(BehaviorConstants.LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString(), JSON.toJSONString(dto));}else{// 取消点赞// 删除当前keylog.info("删除当前key:{}, {}", BehaviorConstants.LIKE_BEHAVIOR+dto.getArticleId(), user.getId());cacheService.hDelete(BehaviorConstants.LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString());}return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}private boolean checkParam(LikesBehaviorDto dto) {if(dto.getType() > 2 || dto.getType() < 0 || dto.getOperation() > 1 || dto.getOperation() < 0){return true;}return false;
}
阅读
- 当用户查看了某一篇文章,需要记录当前用户查看的次数
public ResponseResult readBehavior(ReadBehaviorDto dto) {// 1. 检查次数if(dto == null || dto.getArticleId() == null || dto.getCount() == null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}// 2. 是否登录ApUser user = AppThreadLocalUtil.getUser();if(user == null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}// 3. 阅读, 保存数据// 3.1 更新阅读次数String readBehaviorJson = (String) cacheService.hGet(BehaviorConstants.READ_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString());if(StringUtils.isNotBlank(readBehaviorJson)){ReadBehaviorDto readBehaviorDto = JSON.parseObject(readBehaviorJson, ReadBehaviorDto.class);dto.setCount(readBehaviorDto.getCount()+dto.getCount());}// 3.2 保存数据// 保存当前keylog.info("保存当前key:{} {} {}", BehaviorConstants.READ_BEHAVIOR+dto.getArticleId(), user.getId(), dto);cacheService.hPut(BehaviorConstants.READ_BEHAVIOR+dto.getArticleId().toString(), user.getId().toString(), JSON.toJSONString(dto));return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
不喜欢
用户点击了不喜欢, 就不再给当前用户推荐这一类型的文章信息
public ResponseResult unLikesBehavior(UnLikesBehaviorDto dto) {// 1. 检查次数if(dto == null || dto.getArticleId() == null || dto.getType() > 1 || dto.getType() < 0){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}// 2. 是否登录ApUser user = AppThreadLocalUtil.getUser();if(user == null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}// 3. 不喜欢文章, 保存数据if(dto.getType() == 0){// 不喜欢Object o = cacheService.hGet(BehaviorConstants.UN_LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString());if(o != null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "已经不喜欢");}log.info("保存当前key:{} ,{}, {}", BehaviorConstants.UN_LIKE_BEHAVIOR+dto.getArticleId(), user.getId(), dto);cacheService.hPut(BehaviorConstants.UN_LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString(), JSON.toJSONString(dto));}else{// 取消不喜欢log.info("删除当前key:{}, {}", BehaviorConstants.UN_LIKE_BEHAVIOR+dto.getArticleId(), user.getId());cacheService.hDelete(BehaviorConstants.UN_LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString());}return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
关注
- 当前登录后的用户可以关注作者,也可以取消关注作者
- 从用户的角度出发:一个用户可以关注其他多个作者 —— 我的关注
- 从作者的角度出发:一个用户(同是作者)也可以拥有很多个粉丝 —— 我的粉丝
public ResponseResult userFollow(UserRelationDto dto) {// 1. 检查参数if(dto == null || checkParam(dto)){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}// 2. 是否登录ApUser user = AppThreadLocalUtil.getUser();if(user == null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}// 3. 关注, 保存数据if(dto.getOperation() == 0){// 关注// 将作者写入我的关注中cacheService.zAdd(BehaviorConstants.APUSER_FOLLOW_RELATION+user.getId(), dto.getAuthorId().toString(), System.currentTimeMillis());// 将我写入作者的粉丝中cacheService.zAdd(BehaviorConstants.APUSER_FANS_RELATION+dto.getAuthorId(), user.getId().toString(), System.currentTimeMillis());}else{// 取消关注cacheService.zRemove(BehaviorConstants.APUSER_FOLLOW_RELATION+user.getId(), dto.getAuthorId().toString());cacheService.zRemove(BehaviorConstants.APUSER_FANS_RELATION+dto.getAuthorId(), user.getId().toString());}return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}private boolean checkParam(UserRelationDto dto) {if(dto.getArticleId() == null || dto.getAuthorId() == null){return true;}if(dto.getOperation() > 1 || dto.getOperation() < 0){return true;}return false;
}
收藏
- 记录当前登录人收藏的文章
public ResponseResult collectionBehavior(CollectionBehaviorDto dto) {// 1. 检查参数if(dto == null || checkParam(dto)){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}// 2. 是否登录ApUser user = AppThreadLocalUtil.getUser();if(user == null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}// 3. 文章收藏, 数据保存if(dto.getOperation() == 0){// 收藏// 判断是否已经收藏String collectionJson = (String) cacheService.hGet(BehaviorConstants.COLLECTION_BEHAVIOR + dto.getEntryId(), user.getId().toString());if(StringUtils.isNotBlank(collectionJson)){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "已收藏");}log.info("文章收藏,保存key:{},{},{}",BehaviorConstants.COLLECTION_BEHAVIOR + user.getId(),dto.getEntryId().toString(), JSON.toJSONString(dto));cacheService.hPut(BehaviorConstants.COLLECTION_BEHAVIOR + user.getId(),dto.getEntryId().toString(), JSON.toJSONString(dto));}else{// 取消收藏log.info("文章收藏,删除key:{},{},{}",BehaviorConstants.COLLECTION_BEHAVIOR + user.getId(),dto.getEntryId().toString());cacheService.hDelete(BehaviorConstants.COLLECTION_BEHAVIOR + user.getId(),dto.getEntryId().toString());}return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
文章详情-行为数据回显
展示文章的关系,app端用户必须登录,判断当前用户是否已经关注该文章的作者、是否收藏了此文章、是否点赞了文章、是否不喜欢该文章等
public ResponseResult loadArticleBehavior(ArticleInfoDto dto) {// 1. 检查数据if(dto == null || dto.getArticleId() == null || dto.getAuthorId() == null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}// 2. 是否登录ApUser user = AppThreadLocalUtil.getUser();if(user == null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}// 3. 回显数据Map<String, Boolean> map = new HashMap<>();Boolean islike = false, isunlike = false, iscollection = false, isfollow = false;// 3.1 是否点赞String likeJson = (String) cacheService.hGet(BehaviorConstants.LIKE_BEHAVIOR + dto.getArticleId(), user.getId().toString());if(likeJson != null){islike = true;}// 3.2 是否不喜欢String unLikeJson = (String) cacheService.hGet(BehaviorConstants.UN_LIKE_BEHAVIOR + dto.getArticleId(), user.getId().toString());if(unLikeJson != null){isunlike = true;}// 3.3 是否收藏String collectiontJson = (String) cacheService.hGet(BehaviorConstants.COLLECTION_BEHAVIOR + user.getId(), dto.getArticleId().toString());if(collectiontJson != null){iscollection = true;}// 3.4 是否关注Double score = cacheService.zScore(BehaviorConstants.APUSER_FOLLOW_RELATION + user.getId(), dto.getAuthorId().toString());if(score != null){isfollow = true;}map.put("islike", islike);map.put("isunlike", isunlike);map.put("iscollection", iscollection);map.put("isfollow", isfollow);return ResponseResult.okResult(map);
}
来源
黑马程序员. 黑马头条
Gitee
https://gitee.com/yu-ba-ba-ba/leadnews
相关文章:
JavaWeb_LeadNews_Day9-Redis实现用户行为
JavaWeb_LeadNews_Day9-Redis实现用户行为 网关配置点赞阅读不喜欢关注收藏文章详情-行为数据回显来源Gitee 网关配置 nacos: leadnews-app-gateway # 用户行为微服务 - id: leadnews-behavioruri: lb://leadnews-behaviorpredicates:- Path/behavior/**filters:- StripPrefi…...
IntelliJ IDEA2021.3.1 使用 MybatisCodeHelperPro插件
一、 下载 下载破解后的 MybatisCodeHelperPro 的 V3.2.2版本 V3.2.2-CSDN 或者 V3.2.2-Gitee 二、 应用 将下载下来的Zip文件 放到电脑上的某个位置 (最好放在Idea 管理插件的 plugins 下) 然后自从搜索 Idea如何从磁盘中应用插件 三、激活 由于已经破解过了 但是还是需要激活…...
el-date-picker 等 点击无反应不回显问题解决
如上图,编辑回显正常,但是时间控件在拖动过程中时间不会跟随改变。 解决办法: <el-date-picker input"onInput()" ...><el-input input"onInput()" ...>js中onInput() {this.$forceUpdate();},...
Ansible学习笔记12
playbook: playbook(剧本):是ansible用于配置、部署和管理被控节点的剧本,用于Ansible操作的编排。 使用的是yaml格式,(saltstack、elk、docker、docker-compose、k8s都会使用到yaml格式。&am…...
sqlmap中文文档
这是 sqlmap -hh的翻译,后续可能会对参数进行详细的示例 sqlmap 普通选项 -h, --help # 显示基本帮助信息并退出 -hh # 详细帮助信息 --versino # 版本 -v # 日志详细级别 0-60:只显示python错误以及严重的信息。1:同时显示基本信…...
【C++模拟实现】vector的模拟实现
【C模拟实现】vector的模拟实现 目录 【C模拟实现】vector的模拟实现vector模拟实现的标准代码vector模拟实现中的要点insert和erase会涉及到迭代器失效的问题vector深度剖析关于模版template< class InputIterator >使用memcpy拷贝问题 作者:爱写代码的刚子 …...
go学习part21(3)redis连接池
连接池 1.介绍 每次使用数据就就建立链接再关闭可以,但是如果有大量客户端频繁请求连接,大量创建连接和关闭会非常耗费资源。 所以就建立一个连接池,里面存放几个不关闭的连接,谁要用就分配给谁。 说明:通过Golang 对 Redis操…...
乐理-笔记
乐理笔记整理 1、前言2、认识钢琴键盘及音名3、升降号、还原号4、如何区分同一音名的不同键?5、各类音符时值的关系6、歌曲拍号7、拍号的强弱规律8、歌曲速度(BPM)9、附点音符10、三连音12、唱名与简谱数字13、自然大调(白键&…...
java八股文面试[数据库]——B树和B+树的区别
B树是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(logn)的时间复杂度进行查找、顺序读取、插入和删除等操作。 1、B树的特性 B树中允许一个结点中包含多个key,可以是3个、4个、5个甚至更多,并不确定,需要看具体的实…...
2、Nginx 安装
文章目录 2、Nginx 安装2.1 官网下载2.2 安装 nginx2.2.1 第一步2.2.2 第二步2.2.3 第三步,安装 nginx2.2.4 第四步,修改防火漆规则 【尚硅谷】尚硅谷Nginx教程由浅入深 志不强者智不达;言不信者行不果。 2、Nginx 安装 2.1 官网下载 nginx…...
最适合 AI 的 Python Web 框架
迷途小书童的 Note 读完需要 4分钟 速读仅需 2 分钟 1 简介 本文将介绍 Gradio 库,它是 Python 的一个 web 框架,可以帮助我们快速构建交互式 AI 应用。我们将了解 Gradio 的应用场景、基本原理、功能介绍,并通过一个代码示例来演示如何使用 …...
算法通关村第十八关——回溯
回溯很大感觉就是多重递归,在递归的题目中,例如斐波那契数列,只需要考虑当前情况以及他的子情况。而在回溯中,要进行很多次递归,并且要对条件进行处理。 LeetCode257:给你一个二叉树的根节点root,按任意顺序ÿ…...
使用kafka还在依赖Zookeeper,kraft模式了解下
Kafka的Kraft模式 概述 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer,以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器…...
【100天精通Python】Day52:Python 数据分析_Numpy入门基础与数组操作
目录 1 NumPy 基础概述 1.1 NumPy的主要特点和功能 1.2 NumPy 安装和导入 2 Numpy 数组 2.1 创建NumPy数组 2.2 数组的形状和维度 2.3 数组的数据类型 2.4 访问和修改数组元素 3 数组操作 3.1 数组运算 3.2 数学函数 3.3 统计函数 4 数组形状操作 4.1 重塑数组形…...
Day01-Java基础语法
目录 1. 人机交互 1.1 什么是cmd? 1.2 如何打开CMD窗口? 1.3 常用CMD命令 1.4 CMD练习 1.5 环境变量 2. Java概述 1.1 Java是什么? 1.2下载和安装 1.2.1 下载 1.2.2 安装 1.2.3 JDK的安装目录介绍 1.3 HelloWorld小案例 2.3.1 …...
代码随想录二刷day06
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣242. 有效的字母异位词二、力扣349. 两个数组的交集三、力扣202. 快乐数四、力扣1两数之和 前言 一、力扣242. 有效的字母异位词 class Solution {pub…...
可扩展的Blender插件开发汇总
成熟的 Blender 3D 插件是令人惊奇的事情。作为 Python 和 Blender 的新手,我经常发现自己被社区中的人们创造的强大的东西弄得目瞪口呆。坦率地说,其中一些包看起来有点神奇,当自我怀疑或冒名顶替综合症的唠叨声音被打破时,很容易想到“如果有人能做出可以做xxx的东西就好…...
2023_Spark_实验二:IDEA安装及配置
一、下载安装包 链接:百度网盘 请输入提取码 所在文件夹:大数据必备工具--》开发工具(前端后端)--》后端 下载文件名称:ideaIU-2019.2.3.exe (喜欢新版本也可安装新版本,新旧版本会存在部分差异) IDEA …...
小赢科技,寻找金融科技核心价
如果说金融是经济的晴雨表,是通过改善供给质量以提高经济质量的切入口,那么金融科技公司,就是这一切行动的推手。上半年,社会经济活跃程度提高背后,金融科技公司既是奉献者,也是受益者。 8月29日࿰…...
NAT与代理服务器
1.DNS Domain Name System 是一整套从域名映射到IP的系统(把域名转化为IP地址) 2.域名简介 3.周鸿祎 傅盛 4.ICMP协议 用来网络故障排查原因 草图理解“位置” ping ICMP 是绕过TCP UDP传输协议的,没有端口号 traceroute 5.NAT技术 N…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
