【业务功能篇97】微服务-springcloud-springboot-电商购物车模块-获取当前登录用户的购物车信息
购物车功能
一、购物车模块
1.创建cart服务
我们需要先创建一个cart的微服务,然后添加相关的依赖,设置配置,放开注解。
<dependencies><dependency><groupId>com.msb.mall</groupId><artifactId>mall-commons</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
然后属性文件中的配置
server.port=40000
spring.application.name=mall-cartspring.cloud.nacos.discovery.server-addr=192.168.56.100:8848
spring.thymeleaf.cache=false
然后再添加配置中心的配置:bootstrap.yml文件
spring.application.name=mall-cart
spring.cloud.nacos.config.server-addr=192.168.56.100:8848
放开注册中心的注解

2.Nginx配置
首先在windows中的host指定对应域名

拷贝对应的静态资源到Nginx的static/cart目录中

然后修改Nginx的配置文件

然后重启nginx服务
docker restart nginx
3.配置网关服务
Nginx接收了 cart.msb.com这个域名的访问,那么会把服务反向代理给网关服务,这时网关服务就需要把该请求路由到购物车服务中。我们需要修改网关服务的配置

最后调整下模板页面中的静态资源的路径就可以了

然后启动服务访问即可

二、购物车功能
1.购物车模式处理
讨论购物车中数据的存储方式。我们在购物车中可以有多见商品

然后对应的数据我们可以选择存储在Redis中,对应的数据存储结构我们要慎重的考虑,因为有多条记录,如果用List来存储
[{skuId:1,subTile:'华为',price:666},{skuId:1,subTile:'华为',price:666},{skuId:1,subTile:'华为',price:666}]
那么我们后面要对商品做添加删除和修改商品数量的时候就会比较麻烦,我们需要取出List中的整个数据,然后找到我们要操作的数据,然后把所有数据回写到Redis中,这种方式显然不可取,这时我们可以考虑hash的方式来存储:

这样我们就可以一条一条来处理了,相比上面会更加的灵活。然后我们在后端服务中存储的结构为
Map<String,Map<String,CartItemVo>>
2.购物车VO
针对购物车的信息存储,我们创建两个对应的VO对象。
package com.msb.mall.vo;import java.math.BigDecimal;
import java.util.List;/*** 购物车中的商品信息*/
public class CartItem {// 商品的编号 SkuIdprivate Long skuId;// 商品的图片private String image;// 商品的标题private String title;// 是否选中private boolean check = true;// 商品的销售属性private List<String> skuAttr;// 商品的单价private BigDecimal price;// 购买的数量private Integer count;// 商品的总价private BigDecimal totalPrice;public Long getSkuId() {return skuId;}public void setSkuId(Long skuId) {this.skuId = skuId;}public String getImage() {return image;}public void setImage(String image) {this.image = image;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public boolean isCheck() {return check;}public void setCheck(boolean check) {this.check = check;}public List<String> getSkuAttr() {return skuAttr;}public void setSkuAttr(List<String> skuAttr) {this.skuAttr = skuAttr;}public BigDecimal getPrice() {return price;}public void setPrice(BigDecimal price) {this.price = price;}public Integer getCount() {return count;}public void setCount(Integer count) {this.count = count;}public BigDecimal getTotalPrice() {// 商品的总价 price * countreturn price.multiply(new BigDecimal(count));}}
Cart
package com.msb.mall.vo;import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;/*** 购物车*/
public class Cart {// 购物车中的商品种类private Integer countType;// 选中的商品数量private Integer checkCountNum;// 选中商品的总价private BigDecimal totalAmount;// 购物中存储的商品信息private List<CartItem> items;public Integer getCountType() {return items.size();}public Integer getCheckCountNum() {Integer count = 0;for (CartItem item : items) {if (item.isCheck()){count += item.getCount();}}return count;}public BigDecimal getTotalAmount() {BigDecimal amount = new BigDecimal(0);for (CartItem item : items) {if (item.isCheck()){amount = amount.add(item.getTotalPrice());}}return amount;}public List<CartItem> getItems() {return items;}public void setItems(List<CartItem> items) {this.items = items;}
}
3.认证信息
我们需要在购物车服务中根据当前登录用的用户信息去Redis中查询对应的购物车信息。首先我们需要导入Redis的相关依赖,同时我们要借助于前面讲解的SpringSession来共享认证的Session信息。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency>
添加属性文件信息
server.port=40000
spring.application.name=mall-cartspring.cloud.nacos.discovery.server-addr=192.168.56.100:8848
spring.thymeleaf.cache=falsespring.redis.host=192.168.56.100
spring.redis.port=6379
spring.thymeleaf.enabled=falsespring.session.store-type=redis
server.servlet.session.timeout=30m
spring.session.redis.namespace=spring:session
添加Cookie的配置信息
@Configuration
public class MySessionConfig {/*** 自定义Cookie的配置* @return*/@Beanpublic CookieSerializer cookieSerializer(){DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();cookieSerializer.setDomainName("msb.com"); // 设置session对应的一级域名cookieSerializer.setCookieName("msbsession");return cookieSerializer;}/*** 对存储在Redis中的数据指定序列化的方式* @return*/@Beanpublic RedisSerializer<Object> redisSerializer(){return new GenericJackson2JsonRedisSerializer();}
}
添加自定义的拦截器
/*** 我们自定义的拦截器:帮助我们获取当前登录的用户信息* 通过Session共享获取的*/
public class AuthInterceptor implements HandlerInterceptor {// 本地线程对象 Map<thread,Object>public static ThreadLocal<MemberVO> threadLocal = new ThreadLocal();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 通过HttpSession获取当前登录的用户信息HttpSession session = request.getSession();Object attribute = session.getAttribute(AuthConstant.AUTH_SESSION_REDIS);if(attribute != null){MemberVO memberVO = (MemberVO) attribute;threadLocal.set(memberVO);}return true;}
}
注册拦截器
@Configuration
public class MyWebInterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");}
}
然后登录后访问controller服务测试

4.页面跳转
从商品详情页面点击添加购物车完成添加购物车的逻辑。

5.添加购物车逻辑
具体完成添加购物车的逻辑,也service中我们获取到商品的SKUId和商品数量后,我们要实现的逻辑

具体核心代码
/*** 把商品添加到购物车中* @param skuId* @param num* @return*/@Overridepublic CartItem addCart(Long skuId, Integer num) throws Exception {BoundHashOperations<String, Object, Object> hashOperations = getCartKeyOperation();// 如果Redis存储在商品的信息,那么我们只需要修改商品的数量就可以了Object o = hashOperations.get(skuId.toString());if(o != null){// 说明已经存在了这个商品那么修改商品的数量即可String json = (String) o;CartItem item = JSON.parseObject(json, CartItem.class);item.setCount(item.getCount()+num);hashOperations.put(skuId.toString(),JSON.toJSONString(item));return item;}CartItem item = new CartItem();CompletableFuture future1 = CompletableFuture.runAsync(()->{// 1.远程调用获取 商品信息R r = productFeignService.info(skuId);String skuInfoJSON = (String) r.get("skuInfoJSON");SkuInfoVo vo = JSON.parseObject(skuInfoJSON,SkuInfoVo.class);item.setCheck(true);item.setCount(num);item.setPrice(vo.getPrice());item.setImage(vo.getSkuDefaultImg());item.setSkuId(skuId);item.setTitle(vo.getSkuTitle());},executor);CompletableFuture future2 = CompletableFuture.runAsync(()->{// 2.获取商品的销售属性List<String> skuSaleAttrs = productFeignService.getSkuSaleAttrs(skuId);item.setSkuAttr(skuSaleAttrs);},executor);CompletableFuture.allOf(future1,future2).get();// 3.把数据存储在Redis中String json = JSON.toJSONString(item);hashOperations.put(skuId.toString(),json);return item;}private BoundHashOperations<String, Object, Object> getCartKeyOperation() {// hash key: cart:1 skuId:cartItemMemberVO memberVO = AuthInterceptor.threadLocal.get();String cartKey = CartConstant.CART_PERFIX + memberVO.getId();BoundHashOperations<String, Object, Object> hashOperations = redisTemplate.boundHashOps(cartKey);return hashOperations;}
6.购物车主页
添加商品进入购物车后,我们可以点击结算进入购物车页面,那么我们需要在后台查询出所有的当前登录用户的购物车商品信息,然后在页面中展示


然后在页面中处理数据


相关文章:
【业务功能篇97】微服务-springcloud-springboot-电商购物车模块-获取当前登录用户的购物车信息
购物车功能 一、购物车模块 1.创建cart服务 我们需要先创建一个cart的微服务,然后添加相关的依赖,设置配置,放开注解。 <dependencies><dependency><groupId>com.msb.mall</groupId><artifactId>mall-commo…...
Shell常用的几个正则表达式:[:alnum:], [:alpha:], [:upper:], [:lower:], [:digit:] 认知
一:通配符命令简介: 匹配符合相关条件的符号,匹配文件名查找。 通配符类型: *:匹配任意长度的任意字符 ?:匹配任意单个字符 []:匹配指定范围内的任意单个字符 [^]:匹配指…...
简单的爬虫代码 爬(豆瓣电影)
路漫漫其修远兮,吾将上下而求索 这次写一个最简单的python爬虫代码,也是大多教程第一次爬取的,代码里面有个别的简单介绍,希望能加深您对python爬虫的理解。 本次爬取两个网页数据 一 爬取的网站 豆瓣电影 爬取网页中的&#…...
微服务之架构演变
随着互联网的发展,网站应用规模不断扩大,网站架构随之不断演变,演变历史大致分为单体应用架构-垂直应用架构-分布式架构-SOA架构-微服务架构-云原生架构 架构演变 单体应用架构 以前网站流量小,只需要一个应用就可以把所有功能…...
面试问题记录一 --- C++(Qt方向)
以下是我于2023年6~7月间换工作时遇到的面试题目,有需要的小伙伴可以参考下。约100个题目。 1 C和C++的区别 1) 文件区别:C源文件后缀 .c;C++源文件后缀 .cpp 2) 返回值: C默认返回int型;C++ 若无返回值,必须指定为void 3) 参数列表:C默认接收多个…...
使用词袋模型(BoW)测试提取图像的特征点和聚类中心
文章目录 环境配置代码测试 环境配置 (1) 导入opencv,参考链接 https://blog.csdn.net/Aer_7z/article/details/132612369(2) 安装numpy 激活虚拟环境的前提下,输入: pip install numpy(3) 安装sklearn 激活虚拟环境的前提下,输…...
利用vba处理Excel表格数据实现键值转化,适用于将编码转化成对应的文本
最近遇到了一个甲方需要提供系统登录的用户名单和对应的角色权限内容。无奈直接从数据库导出的数据对应的都是编码,没有转成中文,想着偷个懒能不能直接用Excel直接转,网上看了一下有修改单元格格式的,但需要编码是2到3个。多的就用…...
IntelliJ IDEA(Windows 版)的所有快捷键
🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥 大家好 本文参考了 IntelliJ IDEA 的官网,列举了IntelliJ IDEA(Windows 版)的所有快捷…...
文件上传漏洞全面渗透姿势
0x00 文件上传场景 (本文档只做技术交流) 文件上传的场景真的随处可见,不加防范小心,容易造成漏洞,造成信息泄露,甚至更为严重的灾难。 比如某博客网站评论编辑模块,右上角就有支持上传图片的功能,提交带…...
GreenPlum的gpfdist使用与原理流程分析
一、简介 GreenPlum 的数据导入功能作为对数据源的一种扩充,数据导入的方式有: 1、insert 该方式通过 sql 语句,把数据一条一条插入至表中。这种方式,不仅读取数据慢(一条一条读取),且数据需要…...
Spring AOP与静态代理/动态代理
文章目录 一、代理模式静态代理动态代理代理模式与AOP 二、Spring AOPSping AOP用来处理什么场景jdk 动态代理cglib 动态代理面试题:讲讲Spring AOP的原理与执行流程 总结 一、代理模式 代理模式是一种结构型设计模式,它允许对象提供替代品或占位符&…...
【LeetCode算法系列题解】第51~55题
CONTENTS LeetCode 51. N 皇后(困难)LeetCode 52. N 皇后 II(困难)LeetCode 53. 最大子序和(中等)LeetCode 54. 螺旋矩阵(中等)LeetCode 55. 跳跃游戏(中等) …...
驱动开发错误汇编
本博文将会不定期更新。以便记录我的驱动开发生涯中的一些点点滴滴的技术细节和琐事。 1. link阶段找不到导出函数 比如"LNK2019 无法解析的外部符号 _FltCreateCommunicationPort32"。 出现这种情况的原因是,驱动的编译环境忽略了所有的默认库&#x…...
知识图谱项目实践
目录 步骤 SpaCy Textacy——Text Analysis for Cybersecurity Networkx Dateparser 导入库 写出页面的名称 编辑 自然语言处理 词性标注 可能标记的完整列表 依存句法分析(Dependency Parsing,DEP) 可能的标签完整列表 实例理…...
stable diffusion实践操作-提示词-人物属性
系列文章目录 stable diffusion实践操作-提示词 文章目录 系列文章目录前言一、提示词汇总1.1 人物属性11.2 人物属性2 前言 本文主要收纳总结了提示词-人物属性。 一、提示词汇总 1.1 人物属性1 角色类型人物身材胸部头发-发型头发-发色[女仆][霊烏路空][大腿][乳房][呆毛…...
RabbitMQ的安装和配置
将RabbitMQ文件夹传到linux根目录 开启管理界面及配置...
WebRTC 日志
WebRTC 日志 flyfish WebRTC支持的日志等级 // // The meanings of the levels are: // LS_VERBOSE: This level is for data which we do not want to appear in the // normal debug log, but should appear in diagnostic logs. // LS_INFO: Chatty level used in de…...
【python爬虫】16.爬虫知识点总结复习
文章目录 前言爬虫总复习工具解析与提取(一)解析与提取(二)更厉害的请求存储更多的爬虫更强大的爬虫——框架给爬虫加上翅膀 爬虫进阶路线指引解析与提取 存储数据分析与可视化更多的爬虫更强大的爬虫——框架项目训练 反爬虫应对…...
Windows系统中Apache Http服务器简单使用
1 简介 Apache HTTP服务器是一个开源的、跨平台的Web服务器软件。它由Apache软件基金会开发和维护。Apache HTTP服务器可以在多种操作系统上运行,如Windows、Linux、Unix等,并且支持多种编程语言和技术,如PHP、Perl、Python、Java等。…...
Django ORM 框架中的表关系,你真的弄懂了吗?
Django ORM 框架中的表关系 为了说清楚问题,我们设计一个 crm 系统,包含五张表: 1.tb_student 学生表 2.tb_student_detail 学生详情表 3.tb_salesman 课程顾问表 4.tb_course 课程表 5.tb_entry 报名表 表关系和字段如下图:…...
收藏!AI时代,软件工程基本功才是你的核心竞争力
在AI coding时代,软件工程的基本功不仅没有过时,反而比以往任何时候都更加重要。AI是放大器,好的代码库能提升效率,而模糊混乱的代码库则会放大混乱。接口、边界、领域语言和测试等“老派”的基本功,是开发者手中杠杆率…...
【实战指南】用DistroAV构建企业级网络视频协作系统:从零到专业部署
【实战指南】用DistroAV构建企业级网络视频协作系统:从零到专业部署 【免费下载链接】obs-ndi DistroAV (formerly OBS-NDI): NDI integration for OBS Studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-ndi 你是否曾为传统视频制作中的复杂线缆连接…...
告别Python依赖!用SpringBoot+LangChain4j从零搭建企业级RAG知识库(附避坑指南)
告别Python依赖!用SpringBootLangChain4j从零搭建企业级RAG知识库(附避坑指南) 在AI技术快速落地的今天,检索增强生成(RAG)已成为企业知识管理的热门解决方案。然而,当大多数团队都在Python生态…...
给地球做CT时,那些‘捣乱’的波都是什么来头?聊聊地震勘探里的‘噪音’家族
给地球做CT时,那些‘捣乱’的波都是什么来头?聊聊地震勘探里的‘噪音’家族 想象一下医生用CT扫描人体时,如果患者不停移动或周围有手机干扰,图像就会出现模糊和伪影。地球物理学家用地震波给地球做"CT扫描"时…...
终极指南:10分钟将WinForms应用升级为现代化Material Design界面
终极指南:10分钟将WinForms应用升级为现代化Material Design界面 【免费下载链接】MaterialSkin Theming .NET WinForms, C# or VB.Net, to Googles Material Design Principles. 项目地址: https://gitcode.com/gh_mirrors/mat/MaterialSkin 你是否厌倦了传…...
华测RTK静态数据解算保姆级教程:从CHC Geomatics Office 2安装到平差报告导出
华测RTK静态数据解算全流程实战指南:从软件配置到精度优化 第一次接触华测RTK静态解算时,面对满屏的专业术语和复杂参数,不少同行都有过这样的困惑:为什么同样的数据,别人处理出来的结果总能一次性通过验收࿰…...
终极指南:如何用YOLOv8 AI自瞄系统快速提升游戏瞄准精度
终极指南:如何用YOLOv8 AI自瞄系统快速提升游戏瞄准精度 【免费下载链接】RookieAI_yolov8 基于yolov8实现的AI自瞄项目 AI self-aiming project based on yolov8 项目地址: https://gitcode.com/gh_mirrors/ro/RookieAI_yolov8 RookieAI_yolov8是一款基于YO…...
VSLAM与VIO技术解析:从3D建图到重定位的工程实践
1. 项目概述:从传感器融合到环境认知的跨越在机器人、自动驾驶和增强现实这些前沿领域,让机器“看见”并“理解”它所处的三维世界,是赋予其自主行动能力的基石。这背后,视觉SLAM(Simultaneous Localization and Mappi…...
【RK3588-AI-003】RK3588串口+SSH远程连接配置+文件互传实操
一、前言 很多刚入手RK3588开发板做AI部署、嵌入式开发的同学,都会遇到三大难题: ❌ 不知道怎么接线、看不懂串口打印日志,调试报错无从下手; ❌ 每次重启开发板IP都会变,频繁修改连接地址,开发极其麻烦&…...
VisualCppRedist AIO:一站式解决Windows C++运行库依赖问题
VisualCppRedist AIO:一站式解决Windows C运行库依赖问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist Visual C运行库是Windows系统中许多应用程序…...
