19.购物车
1.添加购物车
@Override
public CartItemVo addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
//拿到要操作的购物车信息
BoundHashOperations<String, Object, Object> cartOps = getCartOps();
//判断Redis是否有该商品的信息
String productRedisValue = (String) cartOps.get(skuId.toString());
//如果没有就添加数据
if (StringUtils.isEmpty(productRedisValue)) {
//2、添加新的商品到购物车(redis)
CartItemVo cartItemVo = new CartItemVo();
//开启第一个异步任务
CompletableFuture<Void> getSkuInfoFuture = CompletableFuture.runAsync(() -> {
//1、远程查询当前要添加商品的信息
R productSkuInfo = productFeignService.getInfo(skuId);
SkuInfoVo skuInfo = productSkuInfo.getData("skuInfo", new TypeReference<SkuInfoVo>() {
});
//数据赋值操作
cartItemVo.setSkuId(skuInfo.getSkuId());
cartItemVo.setTitle(skuInfo.getSkuTitle());
cartItemVo.setImage(skuInfo.getSkuDefaultImg());
cartItemVo.setPrice(skuInfo.getPrice());
cartItemVo.setCount(num);
}, executor);
//开启第二个异步任务
CompletableFuture<Void> getSkuAttrValuesFuture = CompletableFuture.runAsync(() -> {
//2、远程查询skuAttrValues组合信息
List<String> skuSaleAttrValues = productFeignService.getSkuSaleAttrValues(skuId);
cartItemVo.setSkuAttrValues(skuSaleAttrValues);
}, executor);
//等待所有的异步任务全部完成
CompletableFuture.allOf(getSkuInfoFuture, getSkuAttrValuesFuture).get();
String cartItemJson = JSON.toJSONString(cartItemVo);
cartOps.put(skuId.toString(), cartItemJson);
return cartItemVo;
} else {
//购物车有此商品,修改数量即可
CartItemVo cartItemVo = JSON.parseObject(productRedisValue, CartItemVo.class);
cartItemVo.setCount(cartItemVo.getCount() + num);
//修改redis的数据
String cartItemJson = JSON.toJSONString(cartItemVo);
cartOps.put(skuId.toString(), cartItemJson);
return cartItemVo;
}
}
/**
* 获取到我们要操作的购物车
*
* @return
*/
private BoundHashOperations<String, Object, Object> getCartOps() {
//先得到当前用户信息
UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
String cartKey = "";
if (userInfoTo.getUserId() != null) {
//gulimall:cart:1
cartKey = CART_PREFIX + userInfoTo.getUserId();
} else {
cartKey = CART_PREFIX + userInfoTo.getUserKey();
}
//绑定指定的key操作Redis
return redisTemplate.boundHashOps(cartKey);
}
2.获取购物车某个购物项
@Override
public CartItemVo getCartItem(Long skuId) {
//拿到要操作的购物车信息
BoundHashOperations<String, Object, Object> cartOps = getCartOps();
String redisValue = (String) cartOps.get(skuId.toString());
return JSON.parseObject(redisValue, CartItemVo.class);
}
3.获取用户登录或者未登录购物车里所有的数据
@Override
public CartVo getCart() throws ExecutionException, InterruptedException {
CartVo cartVo = new CartVo();
UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
if (userInfoTo.getUserId() != null) {
//1、登录
String cartKey = CART_PREFIX + userInfoTo.getUserId();
//临时购物车的键
String temptCartKey = CART_PREFIX + userInfoTo.getUserKey();
//2、如果临时购物车的数据还未进行合并
List<CartItemVo> tempCartItems = getCartItems(temptCartKey);
if (tempCartItems != null) {
//临时购物车有数据需要进行合并操作
for (CartItemVo item : tempCartItems) {
addToCart(item.getSkuId(), item.getCount());
}
//清除临时购物车的数据
clearCartInfo(temptCartKey);
}
//3、获取登录后的购物车数据【包含合并过来的临时购物车的数据和登录后购物车的数据】
List<CartItemVo> cartItems = getCartItems(cartKey);
cartVo.setItems(cartItems);
} else {
//没登录
String cartKey = CART_PREFIX + userInfoTo.getUserKey();
//获取临时购物车里面的所有购物项
List<CartItemVo> cartItems = getCartItems(cartKey);
cartVo.setItems(cartItems);
}
return cartVo;
}
4.获取购物车里面的数据
private List<CartItemVo> getCartItems(String cartKey) {
//获取购物车里面的所有商品
BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(cartKey);
List<Object> values = operations.values();
if (values != null && values.size() > 0) {
return values.stream().map((obj) -> {
String str = (String) obj;
return JSON.parseObject(str, CartItemVo.class);
}).collect(Collectors.toList());
}
return null;
}
5.勾选购物项
@Override
public void checkItem(Long skuId, Integer check) {
//查询购物车里面的商品
CartItemVo cartItem = getCartItem(skuId);
//修改商品状态
cartItem.setCheck(check == 1);
//序列化存入redis中
String redisValue = JSON.toJSONString(cartItem);
BoundHashOperations<String, Object, Object> cartOps = getCartOps();
cartOps.put(skuId.toString(), redisValue);
}
6.修改购物项数量
@Override
public void changeItemCount(Long skuId, Integer num) {
//查询购物车里面的商品
CartItemVo cartItem = getCartItem(skuId);
cartItem.setCount(num);
BoundHashOperations<String, Object, Object> cartOps = getCartOps();
//序列化存入redis中
String redisValue = JSON.toJSONString(cartItem);
cartOps.put(skuId.toString(), redisValue);
}
7.删除购物项
@Override
public void deleteIdCartInfo(Integer skuId) {
BoundHashOperations<String, Object, Object> cartOps = getCartOps();
cartOps.delete(skuId.toString());
}
8.获取、合并购物车
@Override
public List<CartItemVo> getUserCartItems() {
List<CartItemVo> cartItemVoList = new ArrayList<>();
//获取当前用户登录的信息
UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
//如果用户未登录直接返回null
if (userInfoTo.getUserId() == null) {
return null;
} else {
//获取购物车项
String cartKey = CART_PREFIX + userInfoTo.getUserId();
//获取所有的
List<CartItemVo> cartItems = getCartItems(cartKey);
if (cartItems == null) {
throw new CartExceptionHandler();
}
//筛选出选中的
cartItemVoList = cartItems.stream()
.filter(CartItemVo::getCheck)
.peek(item -> {
//更新为最新的价格(查询数据库)
BigDecimal price = productFeignService.getPrice(item.getSkuId());
item.setPrice(price);
}).collect(Collectors.toList());
}
return cartItemVoList;
}