16购物车(redis)

1添加到购物车

1.1 接口说明

在这里插入图片描述
参数

post:
productId
selected: true

返回结果:
在这里插入图片描述

1.2 将商品的不变的属性存在redis当中

商品存在redis,不是商品的所有属性都存在redis当中,例如商品的价格就随时在变化,如果存在redis中,会造成数据的不准确性,所以对商品的某些不变的属性进行存储。
新建一个新的对象,存不变的属性

1.2.1 新增对象

@Data
public class Cart {
    
    

	private Integer productId;

	private Integer quantity;

	private Boolean productSelected;

	public Cart() {
    
    
	}

	public Cart(Integer productId, Integer quantity, Boolean productSelected) {
    
    
		this.productId = productId;
		this.quantity = quantity;
		this.productSelected = productSelected;
	}
}

1.2.2存在redis中

在这里插入图片描述

list带来的麻烦就是得遍历每一个对象,然后在更改数量,所以我们用hash存,小key是productID,value是对象
在这里插入图片描述
数量的改变:
先从redis中读出来数据,如果有就加一,没有就新增记录
在这里插入图片描述

1.3总的代码:

1.3.1添加入参对象

public class CartAddForm {
    
    

	@NotNull
	private Integer productId;

	private Boolean selected = true;
}

1.3.2代码:

	@PostMapping("/carts")
	public ResponseVo<CartVo> add(@Valid @RequestBody CartAddForm cartAddForm,
								  HttpSession session) {
    
    
		User user = (User) session.getAttribute(MallConst.CURRENT_USER);
		return cartService.add(user.getId(), cartAddForm);
@Override
	public ResponseVo<CartVo> add(Integer uid, CartAddForm form) {
    
    
		Integer quantity = 1;

		Product product = productMapper.selectByPrimaryKey(form.getProductId());

		//商品是否存在
		if (product == null) {
    
    
			return ResponseVo.error(ResponseEnum.PRODUCT_NOT_EXIST);
		}

		//商品是否正常在售
		if (!product.getStatus().equals(ProductStatusEnum.ON_SALE.getCode())) {
    
    
			return ResponseVo.error(ResponseEnum.PRODUCT_OFF_SALE_OR_DELETE);
		}

		//商品库存是否充足
		if (product.getStock() <= 0) {
    
    
			return ResponseVo.error(ResponseEnum.PROODUCT_STOCK_ERROR);
		}

		//写入到redis1 先从redis中读出来数据,如果有就加一,没有就新增)
		//key: cart_1
		HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
		String redisKey  = String.format(CART_REDIS_KEY_TEMPLATE, uid);

		Cart cart;
		String value = opsForHash.get(redisKey, String.valueOf(product.getId()));
		if (StringUtils.isEmpty(value)) {
    
    
			//没有该商品, 新增
			cart = new Cart(product.getId(), quantity, form.getSelected());
		}else {
    
    
			//已经有了,数量+1
			cart = gson.fromJson(value, Cart.class);
			cart.setQuantity(cart.getQuantity() + quantity);
		}

		opsForHash.put(redisKey,
				String.valueOf(product.getId()),
				gson.toJson(cart));

		return list(uid);
	}

2 查询购物车

2.1 分析

在这里插入图片描述
计算总价:

//计算总价(只计算选中的)
				if (cart.getProductSelected()) {
    
    
					cartTotalPrice = cartTotalPrice.add(cartProductVo.getProductTotalPrice());
				}

2.2总代码:

	@GetMapping("/carts")
	public ResponseVo<CartVo> list(HttpSession session) {
    
    
		User user = (User) session.getAttribute(MallConst.CURRENT_USER);
		return cartService.list(user.getId());
	}
public ResponseVo<CartVo> list(Integer uid) {
    
    
		HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
		String redisKey  = String.format(CART_REDIS_KEY_TEMPLATE, uid);
		Map<String, String> entries = opsForHash.entries(redisKey);

		boolean selectAll = true;
		Integer cartTotalQuantity = 0;
		BigDecimal cartTotalPrice = BigDecimal.ZERO;
		CartVo cartVo = new CartVo();
		List<CartProductVo> cartProductVoList = new ArrayList<>();
		for (Map.Entry<String, String> entry : entries.entrySet()) {
    
    
			Integer productId = Integer.valueOf(entry.getKey());
			Cart cart = gson.fromJson(entry.getValue(), Cart.class);

			//TODO 需要优化,使用mysql里的in
			Product product = productMapper.selectByPrimaryKey(productId);
			if (product != null) {
    
    
				CartProductVo cartProductVo = new CartProductVo(productId,
						cart.getQuantity(),
						product.getName(),
						product.getSubtitle(),
						product.getMainImage(),
						product.getPrice(),
						product.getStatus(),
						product.getPrice().multiply(BigDecimal.valueOf(cart.getQuantity())),
						product.getStock(),
						cart.getProductSelected()
				);
				cartProductVoList.add(cartProductVo);

				if (!cart.getProductSelected()) {
    
    
					selectAll = false;
				}

				//计算总价(只计算选中的)
				if (cart.getProductSelected()) {
    
    
					cartTotalPrice = cartTotalPrice.add(cartProductVo.getProductTotalPrice());
				}
			}

			cartTotalQuantity += cart.getQuantity();
		}

		//有一个没有选中,就不叫全选
		cartVo.setSelectedAll(selectAll);
		cartVo.setCartTotalQuantity(cartTotalQuantity);
		cartVo.setCartTotalPrice(cartTotalPrice);
		cartVo.setCartProductVoList(cartProductVoList);
		return ResponseVo.success(cartVo);
	}

3 更新购物车

3.1 接口说明:

** PUT /carts/{
    
    productId}
quantity //非必填
selected: true //非必填
{
    
    
    "status": 0,
    "data": {
    
    
        "cartProductVoList": [
            {
    
    
                "productId": 1,
                "quantity": 12,
                "productName": "iphone7",
                "productSubtitle": "双十一促销",
                "productMainImage": "mainimage.jpg",
                "productPrice": 7199.22,
                "productStatus": 1,
                "productTotalPrice": 86390.64,
                "productStock": 86,
                "productSelected": true
            },
            {
    
    
                "productId": 2,
                "quantity": 1,
                "productName": "oppo R8",
                "productSubtitle": "oppo促销进行中",
                "productMainImage": "mainimage.jpg",
                "productPrice": 2999.11,
                "productStatus": 1,
                "productTotalPrice": 2999.11,
                "productStock": 86,
                "productSelected": true,
            }
        ],
        "selectedAll": true,
        "cartTotalPrice": 89389.75,
        "cartTotalQuantity": 13
 

3.2 代码

3.2.1 添加入参对象

@Data
public class CartUpdateForm {
    
    

	private Integer quantity;

	private Boolean selected;
}

3.2.1 代码:

@PutMapping("/carts/{productId}")
	public ResponseVo<CartVo> update(@PathVariable Integer productId,
									 @Valid @RequestBody CartUpdateForm form,
									 HttpSession session) {
    
    
		User user = (User) session.getAttribute(MallConst.CURRENT_USER);
		return cartService.update(user.getId(), productId, form);
	}

主要修改【数量】和【选择不选择】两个

public ResponseVo<CartVo> update(Integer uid, Integer productId, CartUpdateForm form) {
    
    
		HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
		String redisKey  = String.format(CART_REDIS_KEY_TEMPLATE, uid);

		String value = opsForHash.get(redisKey, String.valueOf(productId));
		if (StringUtils.isEmpty(value)) {
    
    
			//没有该商品, 报错
			return ResponseVo.error(ResponseEnum.CART_PRODUCT_NOT_EXIST);
		}

		//已经有了,修改内容
		Cart cart = gson.fromJson(value, Cart.class);
		if (form.getQuantity() != null
				&& form.getQuantity() >= 0) {
    
    
			cart.setQuantity(form.getQuantity());
		}
		if (form.getSelected() != null) {
    
    
			cart.setProductSelected(form.getSelected());
		}

		opsForHash.put(redisKey, String.valueOf(productId), gson.toJson(cart));
		return list(uid);
	}

4删除购物车

4.1 接口说明

** DELETE /carts/{
    
    productId}
productId
{
    
    
    "status": 0,
    "data": {
    
    
        "cartProductVoList": [
            {
    
    
                "productId": 2,
                "quantity": 1,
                "productName": "oppo R8",
                "productSubtitle": "oppo促销进行中",
                "productMainImage": "mainimage.jpg",
                "productPrice": 2999.11,
                "productStatus": 1,
                "productTotalPrice": 2999.11,
                "productStock": 86,
                "productSelected": true
            }
        ],
        "selectedAll": true,
        "cartTotalPrice": 2999.11,
        "cartTotalQuantity": 1
    }
}

4.2代码

	@DeleteMapping("/carts/{productId}")
	public ResponseVo<CartVo> delete(@PathVariable Integer productId,
									 HttpSession session) {
    
    
		User user = (User) session.getAttribute(MallConst.CURRENT_USER);
		return cartService.delete(user.getId(), productId);
	}
@Override
	public ResponseVo<CartVo> delete(Integer uid, Integer productId) {
    
    
		HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
		String redisKey  = String.format(CART_REDIS_KEY_TEMPLATE, uid);

		String value = opsForHash.get(redisKey, String.valueOf(productId));
		if (StringUtils.isEmpty(value)) {
    
    
			//没有该商品, 报错
			return ResponseVo.error(ResponseEnum.CART_PRODUCT_NOT_EXIST);
		}

		opsForHash.delete(redisKey, String.valueOf(productId));
		return list(uid);
	}

5全选=

5.1 接口说明

** PUT /carts/selectAll

返回

同接口 获取购物车列表

5.2代码


	@Override
	public ResponseVo<CartVo> selectAll(Integer uid) {
    
    
		HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
		String redisKey  = String.format(CART_REDIS_KEY_TEMPLATE, uid);

		for (Cart cart : listForCart(uid)) {
    
    
			cart.setProductSelected(true);
			opsForHash.put(redisKey,
					String.valueOf(cart.getProductId()),
					gson.toJson(cart));
		}

		return list(uid);
	}

	private List<Cart> listForCart(Integer uid) {
    
    
		HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
		String redisKey  = String.format(CART_REDIS_KEY_TEMPLATE, uid);
		Map<String, String> entries = opsForHash.entries(redisKey);

		List<Cart> cartList = new ArrayList<>();
		for (Map.Entry<String, String> entry : entries.entrySet()) {
    
    
			cartList.add(gson.fromJson(entry.getValue(), Cart.class));
		}

		return cartList;
	}

6全不选=

6.1 接口说明

** PUT /carts/unSelectAll

返回

同接口 获取购物车列表

6.2代码

@Override
	public ResponseVo<CartVo> unSelectAll(Integer uid) {
    
    

		for (Cart cart : listForCart(uid)) {
    
    
			cart.setProductSelected(false);
			opsForHash.put(redisKey,
					String.valueOf(cart.getProductId()),
					gson.toJson(cart));
		}

		return list(uid);
	}
private List<Cart> listForCart(Integer uid) {
    
    
		HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
		String redisKey  = String.format(CART_REDIS_KEY_TEMPLATE, uid);
		Map<String, String> entries = opsForHash.entries(redisKey);

		List<Cart> cartList = new ArrayList<>();
		for (Map.Entry<String, String> entry : entries.entrySet()) {
    
    
			cartList.add(gson.fromJson(entry.getValue(), Cart.class));
		}

		return cartList;
	}

7#### 7.获取购物中所有商品数量总和

** GET /carts/products/sum

无参数,需要登录状态

response:

{
“status”: 0,
“data”: 2
}

	@Override
	public ResponseVo<Integer> sum(Integer uid) {
    
    
		Integer sum = listForCart(uid).stream()
				.map(Cart::getQuantity)
				.reduce(0, Integer::sum);
		return ResponseVo.success(sum);
	}

猜你喜欢

转载自blog.csdn.net/Insist___/article/details/109157659