day12-13
169 购物车业务介绍
添加购物车
1.购物车业务介绍
存储用户预想购买的商品
订单模块的入口
2.购物车功能
登录时: userId
添加: hset key field value;
查询: hvals key;
合并购物车:
未登录购物车+登录购物车数据合并
删除未登录购物车
hget key field
hset key field value
删除:
修改:
未登录时:userTemp
添加:
查询:
删除:
修改:
3.数据是如何存储的?
mysql -----
redis -----
cookie 因为它有数据大小限制
可以使用mysql+redis ----组合存储
双写!
考虑数据同步!
canal maxwell mq 延迟双删 多线程!
使用redis该使用哪种数据类型:
hash
hset key field value
key = userId 谁的购物车
field = skuId
value= vartInfo
note
1. 购物车业务分析
添加:
登录:
userId
未登录:
userTempId ---> 起到的作用,主要是组成缓存的key,记录这个客户端添加的商品都有哪些!
查看:
删除:
修改:
重点:
1. 完成购物车业务
a. 添加购物车 hget key field; hset key field value;
登录:1
未登录:111
同一个业务逻辑!
b. 查看购物车 hvals key
登录:1
未登录:111
同一个业务逻辑!
合并:
登录:
26 1 1
27 1 1
28 1 0
29 1 0
未登录:
26 1 1
27 1 0
28 1 1
29 1 0
30 1 1
合并: 合并完成之后,从哪里获取的数据! 登录的购物车了;
26 2 1
27 2 1
28 2 1
29 2 0
30 1 1
合并条件:
skuId 相同! skuNum=相加但是不能超过200; 合并选中的商品!
skuId 不同! skuNum=但是不能超过200; 设置临时用户Id 为登录用户Id!
可以计算 cartPrice 与 skuPrice; 友好信息提示!
修改:
修改选中状态:
删除:
测试购物车:
移动到收藏:
user:userId:cart
user:userId:start
必须要登录: userId skuId redis hash
送货到哪里,可以调用一个前端组件!
可以通过第三方调用--库存系统!--- 校验是否有足够的库存!-- 减少超卖!
商品详情---购物车---登录!
2. 讲订单业务
1. 记录用户真正要购买的商品!
2. 将商品变现的过程!
3. 对接库存系统校验库存数量!
4. 后续对接支付系统---支付宝!
a. 显示订单结算页!
添加购物车业务
构建购物车模块
建module —>service-cart
添加依赖
<dependencies>
<dependency>
<groupId>com.atguigu.gmall</groupId>
<artifactId>service-product-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.atguigu.gmall</groupId>
<artifactId>service-product-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
添加yaml或者properties
spring.application.name=service-cart
spring.profiles.active=dev
spring.cloud.nacos.discovery.server-addr=47.92.110.102:8848
spring.cloud.nacos.config.server-addr=47.92.110.102:8848
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml
创建启动类(排除数据库连接)
package com.atguigu.gmall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class CartApp {
public static void main(String[] args) {
SpringApplication.run(CartApp.class, args);
}
}
添加购物车功能参数分析,由此得出api接口
通过url中的参数,你可以得出有skuId,skuNum,userId
创建api接口,返回Result
/api/cart/addToCart/{skuId}/{skuNum}
controller
流程:
url参数:通过skuId,skuNum,
1.还得从请求头中获取userId
2.对获取的userId进行判空操作,
3.如果为空,应该从请求头中获得临时userId
4.调用服务层方法,返回ok
/**
* 添加购物车
* @param skuId
* @param skuNum
* @param request
* @return
*/
@GetMapping("/addToCart/{skuId}/{skuNum}")
public Result addToCart(@PathVariable Long skuId,
@PathVariable Integer skuNum,
HttpServletRequest request){
// 从请求头中获取数据
String userId = AuthContextHolder.getUserId(request);
// 判断userId 为空
if (StringUtils.isEmpty(userId)){
// 获取临时用户Id
userId = AuthContextHolder.getUserTempId(request);
}
// 调用服务层方法
this.cartService.addToCart(skuId,skuNum,userId);
// 默认返回
return Result.ok();
}
service
这里该怎么实现:
1.组成key->(user:userId:cart)去redis中查找,返回cartInfo,
2.判空(看看这个用户有没有cartInfo),
if
2.1如果有数据,取出商品数量+新加入购物车的数量,这里需要对加起来的数据进行判断,超过200就固定200,买的数量不能超过200,没超过就按加起来的算,
2.2然后修改cartInfoExist中数量为最新的,
2.3再重新设置选中状态为1,(这里就直接设置了,也可以判断下是否修改)
2.4设置最新修改时间,
2.5再设置下cartInfo中sku价格为最新的价格,调用productFeignClient.getSkuPrice(skuId)
else
3.如果没有数据就是第一次加入购物车:
3.1新创建一个cartInfo
3.2通过productFeignClient.getSkuInfo(skuId)获取skuInfo信息
将skuInfo中信息赋值给cartInfo
cartInfo中包括
skuId,
skuNum(不能超过200),
userId,
加入购入车时候的价格,
商品现在的价格,
cart中product的imageUrl,
skuName,
创建时间,
更新时间
4.最后将cartInfoExist存入redis
redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfoExist);
@Override
public void addToCart(Long skuId, Integer skuNum, String userId) {
// 组成购物车的key = user:userId:cart
String cartKey = getCartKey(userId);
// 判断当前购物车中是否有该商品 hget key field;
CartInfo cartInfoExist = (CartInfo) this.redisTemplate.opsForHash().get(cartKey, skuId.toString());
if (null != cartInfoExist){
// 有这个商品!
Integer number = cartInfoExist.getSkuNum()+skuNum>200?200:cartInfoExist.getSkuNum()+skuNum;
cartInfoExist.setSkuNum(number);
// 设置为选中状态
cartInfoExist.setIsChecked(1);
// if (cartInfoExist.getIsChecked().intValue()==0) {
// cartInfoExist.setIsChecked(1);
// }
cartInfoExist.setUpdateTime(new Date());
cartInfoExist.setSkuPrice(this.productFeignClient.getSkuPrice(skuId));
// 需要将这个数据保存到缓存 hset key field value;
// this.redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfoExist);
} else {
// 第一次添加该商品.
cartInfoExist = new CartInfo();
// 通过skuId 获取商品基本信息
SkuInfo skuInfo = this.productFeignClient.getSkuInfo(skuId);
// 赋值信息
cartInfoExist.setSkuId(skuId);
// 防止用户修改url地址中的skuNum
cartInfoExist.setSkuNum(skuNum>200?200:skuNum);
cartInfoExist.setUserId(userId);
cartInfoExist.setCartPrice(skuInfo.getPrice());
cartInfoExist.setSkuPrice(this.productFeignClient.getSkuPrice(skuId));
cartInfoExist.setImgUrl(skuInfo.getSkuDefaultImg());
cartInfoExist.setSkuName(skuInfo.getSkuName());
cartInfoExist.setCreateTime(new Date());
cartInfoExist.setUpdateTime(new Date());
}
// 需要将这个数据保存到缓存 hset key field value;
this.redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfoExist);
// 写过期的话:1年 ---> 获取每个用户的购买力度! userId ---> totalAmount 总金额
// 1个月:70w 2年 淘宝 40w if()else if() else if(){}else{1个月} --- 工厂模式
}
添加购物车控制器
/**
* 添加购物车控制器
* @param request
* @return
*/
@GetMapping("addCart.html")
public String addCart(HttpServletRequest request){
// 存储skuInfo;
SkuInfo skuInfo = productFeignClient.getSkuInfo(Long.parseLong(request.getParameter("skuId")));
request.setAttribute("skuInfo",skuInfo);
// 存储购买数量.
request.setAttribute("skuNum",request.getParameter("skuNum"));
// 返回添加成功页面
return "cart/addCart";
}
查看购物车列表
商品详情页的加入购物车
window.location.href = ‘http://cart.gmall.com/addCart.html?skuId=’ + this.skuId + ‘&skuNum=’ + this.skuNum
@GetMapping("addCart.html")
public String addCart(HttpServletRequest request){
// 存储skuInfo;
SkuInfo skuInfo = productFeignClient.getSkuInfo(Long.parseLong(request.getParameter("skuId")));
request.setAttribute("skuInfo",skuInfo);
// 存储购买数量.
request.setAttribute("skuNum",request.getParameter("skuNum"));
// 返回添加成功页面
return "cart/addCart";
}
@GetMapping(“cart.html”)
public String cartList(){
// 返回购物车列表页面
return “cart/index”;
}
url: this.api_name + ‘/addToCart/’ + skuId + ‘/’ + skuNum,
gmall-web/src/main/resources/templates/item/item.html
加入购物车url:
cart.addToCart(this.skuId, this.skuNum).then(response => {
window.location.href = 'http://cart.gmall.com/addCart.html?skuId=' + this.skuId + '&skuNum=' + this.skuNum
})
进入控制器gmall-web/src/main/java/com/atguigu/gmall/web/controller/CartController.java
@GetMapping("addCart.html")
public String addCart(HttpServletRequest request){
// 存储skuInfo;
SkuInfo skuInfo = productFeignClient.getSkuInfo(Long.parseLong(request.getParameter("skuId")));
request.setAttribute("skuInfo",skuInfo);
// 存储购买数量.
request.setAttribute("skuNum",request.getParameter("skuNum"));
// 返回添加成功页面
return "cart/addCart";
}
跳转到gmall-web/src/main/resources/templates/cart/addCart.html
去购物车结算
<a href="/cart.html" class="sui-btn btn-xlarge btn-danger " target="_blank">去购物车结算 > </a>
进入控制器:com.atguigu.gmall.web.controller.CartController#cartList
@GetMapping("cart.html")
public String cartList(){
// 返回购物车列表页面
return "cart/index";
}
异步渲染购物车中数据
addToCart(skuId, skuNum=1) {
cart.addToCart(skuId, skuNum).then(response => {
this.init()
})
},
// 添加购物车
addToCart(skuId, skuNum) {
return request({
url: this.api_name + '/addToCart/' + skuId + '/' + skuNum,
method: 'get'
})
},
查看购物车列表
// 我的购物车
cartList() {
return request({
url: this.api_name + '/cartList',
method: 'get'
})
},
异步请求url:http:xxxx/api/cart/cartList
接口文档:获取购物车列表
接口名称: cartList
请求方法: GET
请求路径: /api/cart/cartList
描述: 用于获取用户的购物车列表。
请求参数
无请求参数。
请求示例
GET api/cart/cartList
controller
这种方法是简单实现:
@GetMapping("/cartList")
public Result cartList(HttpServletRequest request){
// 从请求头中获取数据
String userId = AuthContextHolder.getUserId(request);
// 获取临时用户Id
String userTempId = AuthContextHolder.getUserTempId(request);
// 调用服务层方法
List<CartInfo> cartInfoList = this.cartService.cartList(userId,userTempId);
return Result.ok(cartInfoList);
}
service
现在是购物车合并功能,
针对这个功能,
参数userId,userTempId,
三种情况:
1.只存在userTempId,userId=null
2.只存在userId,userTempId= null
3.同时存在
步骤:
这是1.只存在userTempId,userId=null这种情况
1.先声明一个List空对象来准备存储购物车集合
2.先判断userTempId是否为空if (!StringUtils.isEmpty(userTempId))
2.1不为空进来,获取userTempId的购物车key
2.2获取购物车,从redis中根据key取list,这里用到了hash数据类型,对应的redisTemplate API是
this.redisTemplate.opsForHash().values(cartKey);
3.判断userId是否为空,如果为空就是没有登录if (StringUtils.isEmpty(userId))
3.1此时只有userTempId,判断未登录id对应的购物车列表是否为空
3.1.1如果userTempId的cartList不是空,就进行按照修改时间排序,新加入购物车的排在最前面
cartInfoNoLoginList.sort((cart1,cart2)-> DateUtil.truncatedCompareTo(cart2.getUpdateTime(),cart1.getUpdateTime(), Calendar.SECOND));
这个语句调用了自己写的时间比较工具
4.返回未登录的用户对应的购物车列表,这里直接return
return cartInfoNoLoginList;
这是2.只存在userId,userTempId= null这种情况
1.声明一个集合来存储登录购物车
2.根据userId来获取登录用户的购物车key
3.根据key从redisTemplate中获取集合
这个地方使用到了一个特殊的api,redisTemplate.boundHashOps(cartKey);
// boundHashOps() 也可以操作 opsForHash()
// BoundHashOperations<H, HK, HV> hset key field value
这是3.存在userId,userTempId= null这种情况,这种情况包含在存在userId的时候
4.接下来有可能合并,加入if判断
if (!CollectionUtils.isEmpty(cartInfoNoLoginList)){
如果这里未登录用户id对应的购物车列表是空,就不进行合并,如果未登录用户购物车有数据,就一定要合并,
4.1合并,怎么合并,将未登录用户userTempId的临时购物车列表合并到userId的购物车,具体怎么实现?
4.2循环遍历未登录用户购物车集合for (CartInfo cartInfoNoLogin : cartInfoNoLoginList)
下面是未登录用户购物车和登录用户购物车中有相同skuId的商品
4.3// 判断登录对象中是否包含未登录的skuId,这个方法hasKey返回boolean
if (boundHashOperations.hasKey(cartInfoNoLogin.getSkuId().toString()))
4.3.1登录购物车信息种包含未登录购物车skuId
4.3.2通过boundHashOperations.get(cartInfoNoLogin.getSkuId().toString());拿到cartInfoLogin对象
4.3.3将cartInfoLogin对象中的num数量和cartInfoNoLogin对象中的num数量相加并且判断是否大于200,大于就设置成200,小于就相加后的数量,算是设置上限
4.3.4修改cartInfoLogin对象中的数量
4.3.5修改cartInfoLogin对象中的修改时间
4.3.6如果没有登录的用户的购物车中的商品有选中,合并之后也选中,
if (cartInfoNoLogin.getIsChecked().intValue()==1){
cartInfoLogin.setIsChecked(1);
}
4.3.7这里可以加入比价功能,如果加入购物车时候的价格,和合并购物车时候的架构不一致,可以算出他们的差值,加入比价功能
3.4.8写回缓存
boundHashOperations.put(cartInfoNoLogin.getSkuId().toString(),cartInfoLogin);
下面是未登录用户购物车和登录用户购物车中有不相同skuId的商品
4.4.对于登录用户购物车中没有未登录用户购物车中的skuId,直接将没有的全部添加到登录用户购物车中,相当与新增
4.4.1将登录用户userId先设置到未登录用户cartInfoNoLogin中
4.4.2对未登录用户的购物车设置数量,不能超过200
4.4.3对未登录用户的购物车设置创建时间
4.4.4对未登录用户的购物车设置更新时间
4.4.5设置不选中,将没有的商品放入缓存中,boundHashOperations.put(cartInfoNoLogin.getSkuId().toString(),cartInfoNoLogin);
4.5这里直接衔接4.2
删除未登录购物车集合数据:
redisTemplate.delete(this.getCartKey(userTempId));
5.没有userTempId的情况,
5.1走到这里的时候// 表示既有合并之后,也有没有合并只有登录的业务!
cartInfoLoginList = boundHashOperations.values();
5.2判断上面的对象是否空对象
5.2.1空就直接返回空对象
6.查看购物车的时候再进行对更新时间排序
7.返回cartInfoLoginList;
public List<CartInfo> cartList(String userId, String userTempId) {
List<CartInfo> cartInfoNoLoginList = new ArrayList<>();
// 判断
if (!StringUtils.isEmpty(userTempId)){
// 获取临时购物车key
String cartKey = this.getCartKey(userTempId);
// 获取购物车集合
cartInfoNoLoginList = this.redisTemplate.opsForHash().values(cartKey);
}
// 如果要是没有登录,则返回并排序.
if (StringUtils.isEmpty(userId)){
if (!CollectionUtils.isEmpty(cartInfoNoLoginList)){
// 安装修改时间进行排序。
cartInfoNoLoginList.sort((cart1,cart2)-> DateUtil.truncatedCompareTo(cart2.getUpdateTime(),cart1.getUpdateTime(), Calendar.SECOND));
}
// 返回集合
return cartInfoNoLoginList;
}
// 至少有userId
// 声明一个集合来存储登录购物车
List<CartInfo> cartInfoLoginList = new ArrayList<>();
// 获取登录购物车key
String cartKey = this.getCartKey(userId);
// boundHashOps() 也可以操作 opsForHash()
// BoundHashOperations<H, HK, HV> hset key field value
BoundHashOperations<String,String,CartInfo> boundHashOperations = this.redisTemplate.boundHashOps(cartKey);
// cartInfoLoginList = this.redisTemplate.opsForHash().values(cartKey);
// 有可能会发生合并.
if (!CollectionUtils.isEmpty(cartInfoNoLoginList)){
// 一定要合并了. 合并购物车的条件 skuId 必须要相同.
// 循环遍历未登录购物车集合
for (CartInfo cartInfoNoLogin : cartInfoNoLoginList) {
// 判断登录对象中是否包含未登录的skuId 26 27 28
if (boundHashOperations.hasKey(cartInfoNoLogin.getSkuId().toString())){
// 说明skuId 相同 未登录添加到登录中
CartInfo cartInfoLogin = boundHashOperations.get(cartInfoNoLogin.getSkuId().toString());
Integer number = cartInfoLogin.getSkuNum()+cartInfoNoLogin.getSkuNum()>200?200:cartInfoLogin.getSkuNum()+cartInfoNoLogin.getSkuNum();
cartInfoLogin.setSkuNum(number);
// 设置一下修改时间
cartInfoLogin.setUpdateTime(new Date());
// 选中问题:合并选中的,还是选中与不选中都 合并呢 ?
if (cartInfoNoLogin.getIsChecked().intValue()==1){
cartInfoLogin.setIsChecked(1);
}
// if (cartInfoLogin.getCartPrice().compareTo(cartInfoLogin.getSkuPrice())!=0) {
// // 计算价格:变化金额
// cartInfoLogin.getCartPrice().subtract(cartInfoLogin.getSkuPrice()).abs();
// }
// 价格暂时以数据库为准.
// 写回缓存.
boundHashOperations.put(cartInfoNoLogin.getSkuId().toString(),cartInfoLogin);
} else {
// 不相同 29
// 相当于新增。
// if (cartInfoNoLogin.getIsChecked().intValue()==1){
// cartInfoNoLogin.setUserId(userId);
// cartInfoNoLogin.setCreateTime(new Date());
// cartInfoNoLogin.setUpdateTime(new Date());
// // 选中不选中?
// boundHashOperations.put(cartInfoNoLogin.getSkuId().toString(),cartInfoNoLogin);
// }
cartInfoNoLogin.setUserId(userId);
// 限制购买数量。
cartInfoNoLogin.setSkuNum(cartInfoNoLogin.getSkuNum()>200?200:cartInfoNoLogin.getSkuNum());
cartInfoNoLogin.setCreateTime(new Date());
cartInfoNoLogin.setUpdateTime(new Date());
// 选中不选中?
boundHashOperations.put(cartInfoNoLogin.getSkuId().toString(),cartInfoNoLogin);
}
}
// 删除未登录购物车集合数据:
this.redisTemplate.delete(this.getCartKey(userTempId));
}
// 表示既有合并之后,也有没有合并只有登录的业务!
cartInfoLoginList = boundHashOperations.values();
if (CollectionUtils.isEmpty(cartInfoLoginList)){
// 返回空对象即可
return new ArrayList<CartInfo>();
}
// 查看购物车的时候,需要按照更新时间进行排序.
cartInfoLoginList.sort((cart1,cart2)-> DateUtil.truncatedCompareTo(cart2.getUpdateTime(),cart1.getUpdateTime(), Calendar.SECOND));
// 返回登录数据
return cartInfoLoginList;
}
购物车选中状态(单选)
单选修改功能:
分析api
url:/api/cart/checkCart/{skuId}/{isChecked}
前端请求
checkCart(skuId, isChecked) {
return request({
url: this.api_name + '/checkCart/' + skuId + '/' + isChecked,
method: 'get'
})
},
com.atguigu.gmall.cart.controller.CartApiController#checkCart
控制器中接口方法实现
接口文档:修改购物车商品选中状态(单选)
接口名称: checkCart
请求方法: GET
请求路径: /api/cart/checkCart/{skuId}/{isChecked}
描述: 用于修改购物车中商品的选中状态。
请求参数
参数名称 | 描述 | 示例值 |
---|---|---|
skuId | 商品的唯一标识符(路径参数) | 12345 |
isChecked | 商品的选中状态(路径参数) | 1 (选中), 0 (未选中) |
请求示例
GET /api/cart/checkCart/12345/1
controller
@GetMapping("/checkCart/{skuId}/{isChecked}")
public Result checkCart(@PathVariable Long skuId,
@PathVariable Integer isChecked,
HttpServletRequest request){
// 获取用户Id
String userId = AuthContextHolder.getUserId(request);
// 判断是否有用户Id
if (StringUtils.isEmpty(userId)){
userId = AuthContextHolder.getUserTempId(request);
}
// 调用service
this.cartService.checkCart(skuId,isChecked,userId);
// 返回
return Result.ok();
}
service实现
public void checkCart(Long skuId, Integer isChecked, String userId) {
1.先通过userId组成redis中的key
2.通过key来查找这个key对一个的hash对象,再通过skuId来查找对应的cartInfo
CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(cartKey, skuId.toString());
3.判断返回对象是否空
3.1不为空,修改选中状态cartInfo.setIsChecked(isChecked);
3.2考虑是否保存修改时间
4.写回缓存,hset key field value
redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfo);
购物车选中状态(全选)
接口文档:全选/取消全选购物车商品
接口名称: allCheckCart
请求方法: GET
请求路径: /api/cart/allCheckCart/{isChecked}
描述: 用于全选或取消全选购物车中的所有商品。
请求参数
参数名称 | 参数类型 | 是否必填 | 描述 | 示例值 |
---|---|---|---|---|
isChecked | Integer | 是 | 全选状态(路径参数) | 1 (全选), 0 (取消全选) |
请求示例
GET /api/cart/allCheckCart/1
controller
@GetMapping("/allCheckCart/{isChecked}")
public Result allCheckCart(@PathVariable Integer isChecked,
HttpServletRequest request){
service
public void allCheckCart(Integer isChecked, String userId) {
1.通过userId组成redis中的key
2.拿key去redis中取该key下所有cartInfo对象,
List cartInfoList = this.redisTemplate.opsForHash().values(cartKey);
3.对cartInfoList进行判空
3.1将集合中的cartInfo中的选中属性都赋值成1,使用stream
Map<String, CartInfo> map = cartInfoList.stream().map(cartInfo -> {
cartInfo.setIsChecked(isChecked);
return cartInfo;
}).collect(Collectors.toMap(cartInfo -> cartInfo.getSkuId().toString(), cartInfo -> cartInfo));
4.将数据放入缓存redisTemplate.opsForHash().putAll(cartKey,map);
删除购物车中指定的商品
接口文档:删除购物车中的商品
接口名称: deleteCart
请求方法: GET
请求路径: /api/cart/deleteCart/{skuId}
描述: 用于删除购物车中的指定商品。
请求参数
参数名称 | 参数类型 | 是否必填 | 描述 | 示例值 |
---|---|---|---|---|
skuId | Long | 是 | 商品的唯一标识符(路径参数) | 12345 |
请求示例
GET /api/cart/deleteCart/12345
controller
@DeleteMapping("deleteCart/{skuId}")
public Result deleteCart(@PathVariable Long skuId,
HttpServletRequest request){
service
1.通过userId组成redis中的key
2.使用redisTemplate操作redis中的hash
// hdel key field;
this.redisTemplate.opsForHash().delete(this.getCartKey(userId),skuId.toString());
清空购物车中所有商品
接口文档:清空购物车
接口名称: clearCart
请求方法: GET
请求路径: /api/cart/clearCart
描述: 用于清空用户的购物车。
请求参数
无请求参数。
请求示例
GET /api/cart/clearCart
controller
@GetMapping("clearCart")
public Result clearCart(HttpServletRequest request){
service
1.通过userId组成redis中的key
2.使用redisTemplate操作redis中的hash,这次删除的是userId下的全部数据
// del key
this.redisTemplate.delete(this.getCartKey(userId));