Redis 購物車 - 刪除商品與更新購買數量

Leon_Jinhai_Sun發表於2020-10-08
@ApiOperation(value = "從購物車中刪除商品", notes = "從購物車中刪除商品", httpMethod = "POST")
@PostMapping("/del")
public JSONResult del(
		@RequestParam String userId,
		@RequestParam String itemSpecId,
		HttpServletRequest request,
		HttpServletResponse response
) {

	if (StringUtils.isBlank(userId) || StringUtils.isBlank(itemSpecId)) {
		return JSONResult.errorMsg("引數不能為空");
	}

	// 使用者在頁面刪除購物車中的商品資料,如果此時使用者已經登入,則需要同步刪除redis購物車中的商品
	String shopcartJson = redisOperator.get(FOODIE_SHOPCART + ":" + userId);
	if (StringUtils.isNotBlank(shopcartJson)) {
		// redis中已經有購物車了
		List<ShopcartBO> shopcartList = JsonUtils.jsonToList(shopcartJson, ShopcartBO.class);
		// 判斷購物車中是否存在已有商品,如果有的話則刪除
		for (ShopcartBO sc: shopcartList) {
			String tmpSpecId = sc.getSpecId();
			if (tmpSpecId.equals(itemSpecId)) {
				shopcartList.remove(sc);
				break;
			}
		}
		// 覆蓋現有redis中的購物車
		redisOperator.set(FOODIE_SHOPCART + ":" + userId, JsonUtils.objectToJson(shopcartList));
	}

	return JSONResult.ok();
}
@ApiOperation(value = "使用者下單", notes = "使用者下單", httpMethod = "POST")
@PostMapping("/create")
public JSONResult create(
		@RequestBody SubmitOrderBO submitOrderBO,
		HttpServletRequest request,
		HttpServletResponse response) {

	if (submitOrderBO.getPayMethod() != PayMethod.WEIXIN.type
		&& submitOrderBO.getPayMethod() != PayMethod.ALIPAY.type ) {
		return JSONResult.errorMsg("支付方式不支援!");
	}

//        System.out.println(submitOrderBO.toString());

	String shopcartJson = redisOperator.get(FOODIE_SHOPCART + ":" + submitOrderBO.getUserId());
	if (StringUtils.isBlank(shopcartJson)) {
		return JSONResult.errorMsg("購物資料不正確");
	}

	List<ShopcartBO> shopcartList = JsonUtils.jsonToList(shopcartJson, ShopcartBO.class);

	// 1. 建立訂單
	OrderVO orderVO = orderService.createOrder(shopcartList, submitOrderBO);
	String orderId = orderVO.getOrderId();

	// 2. 建立訂單以後,移除購物車中已結算(已提交)的商品
	/**
	 * 1001
	 * 2002 -> 使用者購買
	 * 3003 -> 使用者購買
	 * 4004
	 */
	// 清理覆蓋現有的redis彙總的購物資料
	shopcartList.removeAll(orderVO.getToBeRemovedShopcatdList());
	redisOperator.set(FOODIE_SHOPCART + ":" + submitOrderBO.getUserId(), JsonUtils.objectToJson(shopcartList));
	// 整合redis之後,完善購物車中的已結算商品清除,並且同步到前端的cookie
	CookieUtils.setCookie(request, response, FOODIE_SHOPCART, JsonUtils.objectToJson(shopcartList), true);

	// 3. 向支付中心傳送當前訂單,用於儲存支付中心的訂單資料
	MerchantOrdersVO merchantOrdersVO = orderVO.getMerchantOrdersVO();
	merchantOrdersVO.setReturnUrl(payReturnUrl);

	// 為了方便測試購買,所以所有的支付金額都統一改為1分錢
	merchantOrdersVO.setAmount(1);

	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_JSON);
	headers.add("UserId","");
	headers.add("password","");

	HttpEntity<MerchantOrdersVO> entity =
			new HttpEntity<>(merchantOrdersVO, headers);

	ResponseEntity<JSONResult> responseEntity =
			restTemplate.postForEntity(paymentUrl,
										entity,
										JSONResult.class);
	JSONResult paymentResult = responseEntity.getBody();
	if (paymentResult.getStatus() != 200) {
		logger.error("傳送錯誤:{}", paymentResult.getMsg());
		return JSONResult.errorMsg("支付中心訂單建立失敗,請聯絡管理員!");
	}

	return JSONResult.ok(orderId);
}
/**
 * 用於建立訂單相關資訊
 * @param submitOrderBO
 */
public OrderVO createOrder(List<ShopcartBO> shopcartList, SubmitOrderBO submitOrderBO);
@Transactional(propagation = Propagation.REQUIRED)
@Override
public OrderVO createOrder(List<ShopcartBO> shopcartList, SubmitOrderBO submitOrderBO) {

	String userId = submitOrderBO.getUserId();
	String addressId = submitOrderBO.getAddressId();
	String itemSpecIds = submitOrderBO.getItemSpecIds();
	Integer payMethod = submitOrderBO.getPayMethod();
	String leftMsg = submitOrderBO.getLeftMsg();
	// 包郵費用設定為0
	Integer postAmount = 0;

	String orderId = sid.nextShort();

	UserAddress address = addressService.queryUserAddres(userId, addressId);

	// 1. 新訂單資料儲存
	Orders newOrder = new Orders();
	newOrder.setId(orderId);
	newOrder.setUserId(userId);

	newOrder.setReceiverName(address.getReceiver());
	newOrder.setReceiverMobile(address.getMobile());
	newOrder.setReceiverAddress(address.getProvince() + " "
								+ address.getCity() + " "
								+ address.getDistrict() + " "
								+ address.getDetail());

//        newOrder.setTotalAmount();
//        newOrder.setRealPayAmount();
	newOrder.setPostAmount(postAmount);

	newOrder.setPayMethod(payMethod);
	newOrder.setLeftMsg(leftMsg);

	newOrder.setIsComment(YesOrNo.NO.type);
	newOrder.setIsDelete(YesOrNo.NO.type);
	newOrder.setCreatedTime(new Date());
	newOrder.setUpdatedTime(new Date());


	// 2. 迴圈根據itemSpecIds儲存訂單商品資訊表
	String itemSpecIdArr[] = itemSpecIds.split(",");
	Integer totalAmount = 0;    // 商品原價累計
	Integer realPayAmount = 0;  // 優惠後的實際支付價格累計
	List<ShopcartBO> toBeRemovedShopcatdList = new ArrayList<>();
	for (String itemSpecId : itemSpecIdArr) {
		ShopcartBO cartItem = getBuyCountsFromShopcart(shopcartList, itemSpecId);
		// 整合redis後,商品購買的數量重新從redis的購物車中獲取
		int buyCounts = cartItem.getBuyCounts();
		toBeRemovedShopcatdList.add(cartItem);

		// 2.1 根據規格id,查詢規格的具體資訊,主要獲取價格
		ItemsSpec itemSpec = itemService.queryItemSpecById(itemSpecId);
		totalAmount += itemSpec.getPriceNormal() * buyCounts;
		realPayAmount += itemSpec.getPriceDiscount() * buyCounts;

		// 2.2 根據商品id,獲得商品資訊以及商品圖片
		String itemId = itemSpec.getItemId();
		Items item = itemService.queryItemById(itemId);
		String imgUrl = itemService.queryItemMainImgById(itemId);

		// 2.3 迴圈儲存子訂單資料到資料庫
		String subOrderId = sid.nextShort();
		OrderItems subOrderItem = new OrderItems();
		subOrderItem.setId(subOrderId);
		subOrderItem.setOrderId(orderId);
		subOrderItem.setItemId(itemId);
		subOrderItem.setItemName(item.getItemName());
		subOrderItem.setItemImg(imgUrl);
		subOrderItem.setBuyCounts(buyCounts);
		subOrderItem.setItemSpecId(itemSpecId);
		subOrderItem.setItemSpecName(itemSpec.getName());
		subOrderItem.setPrice(itemSpec.getPriceDiscount());
		orderItemsMapper.insert(subOrderItem);

		// 2.4 在使用者提交訂單以後,規格表中需要扣除庫存
		itemService.decreaseItemSpecStock(itemSpecId, buyCounts);
	}

	newOrder.setTotalAmount(totalAmount);
	newOrder.setRealPayAmount(realPayAmount);
	ordersMapper.insert(newOrder);

	// 3. 儲存訂單狀態表
	OrderStatus waitPayOrderStatus = new OrderStatus();
	waitPayOrderStatus.setOrderId(orderId);
	waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
	waitPayOrderStatus.setCreatedTime(new Date());
	orderStatusMapper.insert(waitPayOrderStatus);

	// 4. 構建商戶訂單,用於傳給支付中心
	MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
	merchantOrdersVO.setMerchantOrderId(orderId);
	merchantOrdersVO.setMerchantUserId(userId);
	merchantOrdersVO.setAmount(realPayAmount + postAmount);
	merchantOrdersVO.setPayMethod(payMethod);

	// 5. 構建自定義訂單vo
	OrderVO orderVO = new OrderVO();
	orderVO.setOrderId(orderId);
	orderVO.setMerchantOrdersVO(merchantOrdersVO);
	orderVO.setToBeRemovedShopcatdList(toBeRemovedShopcatdList);

	return orderVO;
}
/**
 * 從redis中的購物車裡獲取商品,目的:counts
 * @param shopcartList
 * @param specId
 * @return
 */
private ShopcartBO getBuyCountsFromShopcart(List<ShopcartBO> shopcartList, String specId) {
	for (ShopcartBO cart : shopcartList) {
		if (cart.getSpecId().equals(specId)) {
			return cart;
		}
	}
	return null;
}

 

相關文章