From e425e5d101e1d48e40674a2a801efb8dd060e8a5 Mon Sep 17 00:00:00 2001 From: gongzuming <gongzuming> Date: 星期五, 20 九月 2024 13:44:35 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master-v2' --- src/main/java/com/mzl/flower/service/payment/OrderService.java | 306 +++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 262 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/mzl/flower/service/payment/OrderService.java b/src/main/java/com/mzl/flower/service/payment/OrderService.java index ca0a23a..681a6fd 100644 --- a/src/main/java/com/mzl/flower/service/payment/OrderService.java +++ b/src/main/java/com/mzl/flower/service/payment/OrderService.java @@ -16,6 +16,7 @@ import com.mzl.flower.dto.request.payment.*; import com.mzl.flower.dto.response.flower.FlowerCartListDTO; import com.mzl.flower.dto.response.flower.FlowerCartListWrapDTO; +import com.mzl.flower.dto.response.flower.FlowerDTO; import com.mzl.flower.dto.response.flower.ParamItemDTO; import com.mzl.flower.dto.response.partner.PartnerOrderDTO; import com.mzl.flower.dto.response.payment.*; @@ -25,6 +26,7 @@ import com.mzl.flower.entity.coupon.CouponRecordDO; import com.mzl.flower.entity.customer.Address; import com.mzl.flower.entity.customer.Customer; +import com.mzl.flower.entity.flower.Flower; import com.mzl.flower.entity.flower.FlowerSupplierSaleNum; import com.mzl.flower.entity.menber.Member; import com.mzl.flower.entity.partner.Partner; @@ -40,9 +42,11 @@ import com.mzl.flower.mapper.system.UserWechatMapper; import com.mzl.flower.mapper.warehouse.WarehouseLocationMapper; import com.mzl.flower.service.BaseService; +import com.mzl.flower.service.coupon.CouponRecordService; import com.mzl.flower.service.flower.FlowerService; import com.mzl.flower.service.menber.MemberGrowthRecordService; import com.mzl.flower.service.point.CustomerPointService; +import com.mzl.flower.service.point.PointGoodsService; import com.mzl.flower.service.system.CodeService; import com.mzl.flower.service.system.WeChatService; import com.mzl.flower.service.transport.TransportService; @@ -147,47 +151,110 @@ @Autowired private CustomerPointService customerPointService; + @Autowired + private PointGoodsService pointGoodsService; + + @Autowired + private RedisLockService lockService; + + @Autowired + private CouponRecordService couponRecordService; + + public void changeFlower2Cart(CartSaveDTO dto) { String userId = SecurityUtils.getUserId(); - Cart c = cartMapper.selectOne(new QueryWrapper<Cart>() - .eq("create_by", userId).eq("flower_id", dto.getId())); - if (c == null) { - if (dto.getNum() <= 0) { - throw new ValidationException("数量不能小于等于0,请刷新页面重试"); - } - c = new Cart(); - c.setFlowerId(dto.getId()); - c.setNum(dto.getNum()); - c.create(userId); + String key = userId + "_" + dto.getId(); + boolean lock = lockService.getObjectLock(RedisLockService.LOCK_KEY_CART_, key); + if(!lock){ + return; + } - cartMapper.insert(c); - } else { - c.setNum(c.getNum() + dto.getNum()); - c.update(userId); - if (c.getNum() <= 0) { - cartMapper.deleteById(c.getId()); + try { + Cart c = cartMapper.selectOne(new QueryWrapper<Cart>() + .eq("create_by", userId).eq("flower_id", dto.getId())); + if (c == null) { + if (dto.getNum() <= 0) { + throw new ValidationException("数量不能小于等于0,请刷新页面重试"); + } + c = new Cart(); + c.setFlowerId(dto.getId()); + c.setNum(dto.getNum()); + c.create(userId); + + // 限购 1.首先查看购物车中的数量是否已经超过限售数量 + final FlowerDTO flowerDetail = flowerService.getFlowerDetail(c.getFlowerId()); + if(null!=c.getNum() && null!=flowerDetail.getLimited() + && c.getNum().compareTo(flowerDetail.getLimited())>0){ + throw new ValidationException("数量不能超过限售数量!"); + } + + // 限购 2.查看已结单的订单的当前花朵已经购买的数量,加当前购物车的加入的数量是否超过限购的数量,查看当前5点前到昨天五点前 + Integer completeNumToday=getFlowerCompleteNumToday(userId,c.getFlowerId()); + Integer tmp=completeNumToday+c.getNum(); + if(null!=tmp && null!=flowerDetail.getLimited() + && tmp.compareTo(flowerDetail.getLimited())>0){ + throw new ValidationException("当天的订单的花数量加上购物车的数量不能超过限售数量!"); + } + + cartMapper.insert(c); } else { - cartMapper.updateById(c); + // 查看是否已经超过当前商品的限购数量 + final FlowerDTO flowerDetail = flowerService.getFlowerDetail(c.getFlowerId()); + c.setNum((c.getNum()==null?0:c.getNum()) + dto.getNum()); + + // 限购 1.首先查看购物车中的数量是否已经超过限售数量 + if(null!=c.getNum() && null!=flowerDetail.getLimited() + && c.getNum().compareTo(flowerDetail.getLimited())>0){ + throw new ValidationException("数量不能超过限售数量!"); + } + + // 限购 2.查看已结单的订单的当前花朵已经购买的数量,加当前购物车的加入的数量是否超过限购的数量,查看当前5点前到昨天五点前 + Integer completeNumToday=getFlowerCompleteNumToday(userId,c.getFlowerId()); + Integer tmp=completeNumToday+c.getNum(); + if(null!=tmp && null!=flowerDetail.getLimited() + && tmp.compareTo(flowerDetail.getLimited())>0){ + throw new ValidationException("当天的订单的花数量加上购物车的数量不能超过限售数量!"); + } + + c.update(userId); + if (c.getNum() <= 0) { + cartMapper.deleteById(c.getId()); + } else { + cartMapper.updateById(c); + } } + } finally { + lockService.releaseObjectLock(RedisLockService.LOCK_KEY_CART_, key); } } public void saveFlower2Cart(CartSaveDTO dto) { String userId = SecurityUtils.getUserId(); - Cart c = cartMapper.selectOne(new QueryWrapper<Cart>() - .eq("create_by", userId).eq("flower_id", dto.getId())); - if (c == null) { - c = new Cart(); - c.setFlowerId(dto.getId()); - c.setNum(dto.getNum()); - c.create(userId); - cartMapper.insert(c); - } else { - c.setNum(dto.getNum()); - c.update(userId); + String key = userId + "_" + dto.getId(); + boolean lock = lockService.getObjectLock(RedisLockService.LOCK_KEY_CART_, key); + if(!lock){ + return; + } - cartMapper.updateById(c); + try { + Cart c = cartMapper.selectOne(new QueryWrapper<Cart>() + .eq("create_by", userId).eq("flower_id", dto.getId())); + if (c == null) { + c = new Cart(); + c.setFlowerId(dto.getId()); + c.setNum(dto.getNum()); + c.create(userId); + + cartMapper.insert(c); + } else { + c.setNum(dto.getNum()); + c.update(userId); + + cartMapper.updateById(c); + } + } finally { + lockService.releaseObjectLock(RedisLockService.LOCK_KEY_CART_, key); } } @@ -266,6 +333,8 @@ } public PreOrderDTO getPreOrderInfo(List<CartSaveDTO> flowers, Map<Long, PriceDTO> priceMap) { + String userId = SecurityUtils.getUserId(); + if (flowers == null || flowers.size() == 0) { throw new ValidationException("请选择商品"); } @@ -281,6 +350,18 @@ } idNumMap.put(id, num); } + + // 限购数量校验 鲜花数量校验 + flowers.forEach(cartSaveDTO -> { + // 限购数量 鲜花数量校验 + Integer completeNumToday=getFlowerCompleteNumToday(userId,cartSaveDTO.getId()); + Integer tmp=completeNumToday+cartSaveDTO.getNum(); + Flower flower=flowerMapper.selectById(cartSaveDTO.getId()); + if(null!=flower.getLimited() && tmp.compareTo(flower.getLimited())>0){ + throw new ValidationException("商品:'"+flower.getName()+"' 昨天17:00到今天17:00 超过限售数量:"+flower.getLimited()+"!"); + } + }); + PreOrderDTO result = new PreOrderDTO(); List<FlowerCartListDTO> ls = flowerMapper.selectFlowerOrderList(ids); @@ -363,6 +444,17 @@ } public Map commitOrder(OrderCommitDTO dto, PreOrderDTO p, Map<Long, PriceDTO> priceMap) { + String userId = SecurityUtils.getUserId(); + p.getFlowers().forEach(flower -> { + // 限购数量 鲜花数量校验 + Integer completeNumToday=getFlowerCompleteNumToday(userId,flower.getId()); + Integer tmp=completeNumToday+flower.getNum(); + if(null!=tmp && null!=flower.getLimited() + && tmp.compareTo(flower.getLimited())>0){ + throw new ValidationException("商品:'"+flower.getName()+"' 昨天17:00到今天17:00 超过限售数量:"+flower.getLimited()+"!"); + } + }); + WxMaJscode2SessionResult session = null; try { session = weChatService.getWxMaSessionInfo(dto.getWxcode()); @@ -385,7 +477,7 @@ deliveryName = d.getName(); } - String userId = SecurityUtils.getUserId(); + Order order = new Order(); order.setId(UUIDGenerator.getUUID()); @@ -410,8 +502,9 @@ order.setTransportFee(transportFee); order.setDeliveryName(deliveryName); - BigDecimal totalAmount = order.getFlowerAmount().add(p.getPacking()).add(transportFee);//使用优惠券之前的总价 + BigDecimal totalAmount = order.getFlowerAmount();//使用优惠券之前的总价,使用商品价格 CouponRecordDO coupon = useCouponRecord(order.getId(), totalAmount, dto.getCouponRecordId()); + log.info("用户优惠券: " + coupon); if(coupon != null){ order.setMemberCouponId(coupon.getId()); order.setMemberCouponCode(coupon.getCouponCode()); @@ -419,6 +512,13 @@ order.setMemberCouponAmount(coupon.getCouponDiscountValue()); totalAmount = totalAmount.subtract(order.getMemberCouponAmount());//满足条件需要减去优惠券金额 + } + if(totalAmount.doubleValue() < 0){//假如扣除优惠券后金额小于0,则按0计算 + totalAmount = new BigDecimal(0); + } + totalAmount = totalAmount.add(p.getPacking()).add(transportFee); + if(totalAmount.doubleValue() <= 0){//假如总价小于等于0,则支付0.01元 + totalAmount = new BigDecimal(0.01); } order.setTotalAmount(totalAmount); @@ -441,8 +541,11 @@ List<FlowerCartListDTO> flowers = p.getFlowers(); Map<Long, List<ParamItemDTO>> paramMap = new HashMap<>(); final BigDecimal flowerAmount = order.getFlowerAmount();//订单商品总价 - final BigDecimal memberCouponAmount = order.getMemberCouponAmount();//使用优惠券面值 - for (FlowerCartListDTO f : flowers) { + final BigDecimal memberCouponAmount = getAmount(order.getMemberCouponAmount());//使用优惠券面值 + BigDecimal usedCouponAmount = new BigDecimal(0); + for (int i = 0; i < flowers.size(); i++) { + FlowerCartListDTO f = flowers.get(i); + OrderItem t = new OrderItem(); t.setId(UUIDGenerator.getUUID()); t.setOrderId(order.getId()); @@ -471,9 +574,19 @@ t.setTotal(f.getTotalMember());//使用会员总价 t.setOriginalPrice(pp.getPrice());//非会员售价 - BigDecimal couponAmount = calculateCoupon(memberCouponAmount, t.getTotal(), flowerAmount, t.getNum()); + boolean isLastOne = i == (flowers.size() - 1); + BigDecimal couponAmount = calculateCoupon(memberCouponAmount, t.getTotal() + , flowerAmount, t.getNum(), t.getPrice(), isLastOne, usedCouponAmount); t.setCouponAmount(couponAmount);//每扎平摊的优惠券面值 - t.setRealPrice(t.getPrice().subtract(couponAmount));//退款时使用的真实成交价 + t.setRealPrice(t.getPrice().subtract(couponAmount));//退款时使用的真实成交单价 + + t.setCouponAmountTotal(couponAmount.multiply(BigDecimal.valueOf(t.getNum()))); + if(isLastOne){ + t.setCouponAmountTotal(memberCouponAmount.subtract(usedCouponAmount)); + } else { + usedCouponAmount = usedCouponAmount.add(t.getCouponAmountTotal()); + } + t.setRealTotal(t.getTotal().subtract(t.getCouponAmountTotal())); t.create(userId); orderItemMapper.insert(t); @@ -503,7 +616,12 @@ } private void usePointGoods(String orderId, List<Long> goodsRecordIdList){ - //TODO 使用积分商品兑换券 + //使用积分商品兑换券 + if(goodsRecordIdList != null && goodsRecordIdList.size() > 0){ + for(Long grId : goodsRecordIdList){ + pointGoodsService.useExchangeGoods(grId, orderId); + } + } } /** @@ -513,21 +631,38 @@ * @param itemTotalAmount * @param totalAmount * @param num + * @param price * @return */ private BigDecimal calculateCoupon(BigDecimal couponAmount, BigDecimal itemTotalAmount - , BigDecimal totalAmount, Integer num){ - if(couponAmount == null){ + , BigDecimal totalAmount, Integer num, BigDecimal price + , boolean isLastOne, BigDecimal usedCouponAmount){ + if(couponAmount == null || couponAmount.doubleValue() == 0){ return new BigDecimal(0); } - BigDecimal radio = itemTotalAmount.divide(totalAmount, 2, RoundingMode.HALF_UP);//计算该商品总价在订单中的占比 + + if(couponAmount.doubleValue() >= totalAmount.doubleValue()){ + return price; + } + if(isLastOne){//最后的商品使用优惠券剩下的面值 + BigDecimal subCoupon = couponAmount.subtract(usedCouponAmount);//占有的优惠券面值 + return subCoupon.divide(BigDecimal.valueOf(num), 2, RoundingMode.HALF_UP); + } + + /*BigDecimal radio = itemTotalAmount.divide(totalAmount, 2, RoundingMode.HALF_UP);//计算该商品总价在订单中的占比 BigDecimal subCoupon = couponAmount.multiply(radio);//占有的优惠券面值 - return subCoupon.divide(BigDecimal.valueOf(num), 2, RoundingMode.HALF_UP); + return subCoupon.divide(BigDecimal.valueOf(num), 2, RoundingMode.HALF_UP);*/ + + //不能分步计算,分步计算会有精度问题 + return couponAmount.multiply(itemTotalAmount).divide(totalAmount.multiply(BigDecimal.valueOf(num)), 2, RoundingMode.HALF_UP); } private CouponRecordDO useCouponRecord(String orderId, BigDecimal amount, String couponRecordId){ + log.info("使用用户优惠券id: " + couponRecordId + "; 订单id: " + orderId); if(StringUtils.isNotEmpty(couponRecordId)){ - //TODO 优惠券使用和验证,如果不符合使用条件需要抛出异常。需调用优惠券使用方法 + //优惠券使用和验证,如果不符合使用条件需要抛出异常。需调用优惠券使用方法 + couponRecordService.useCoupon(couponRecordId, orderId, amount); + return couponRecordService.getCouponRecordById(couponRecordId); } return null; @@ -738,10 +873,9 @@ orderIds.add(o.getId()); } - List<OrderItem> itemList = orderItemMapper.selectList( - new QueryWrapper<OrderItem>().in("order_id", orderIds)); + List<OrderItemListDTO> itemList = orderItemMapper.getOrderItems(orderIds); Map<String, List<OrderItemListDTO>> map = new HashMap<>(); - for (OrderItem oi : itemList) { + for (OrderItemListDTO oi : itemList) { String orderId = oi.getOrderId(); List<OrderItemListDTO> ll = map.computeIfAbsent(orderId, k -> new ArrayList<>()); OrderItemListDTO d = new OrderItemListDTO(); @@ -837,6 +971,82 @@ } return ls; + } + + public List<OrderCheckLocationListDTO> selectOrderCheckLocationList(OrderQueryDTO dto) { + dto.setIdList(splitParam(dto.getIds())); + dto.setStartDate(parseLocalDateTime(dto.getStartDateStr(), true)); + dto.setEndDate(parseLocalDateTime(dto.getEndDateStr(), false)); + + dto.setCreateStartDate(parseLocalDateTime(dto.getCreateStartDateStr(), 17, 0, 0, -1)); + dto.setCreateEndDate(parseLocalDateTime(dto.getCreateEndDateStr(), 17, 0, 0, 0)); + + List<OrderCheckListDTO> ls = orderMapper.selectOrderCheckList(dto); + + List<OrderCheckLocationListDTO> result = new ArrayList<>(); + + if (ls != null && ls.size() > 0) { + List<String> orderIds = new ArrayList<>(); + Map<Long, OrderCheckLocationListDTO> rMap = new HashMap<>(); + Map<String, OrderCheckListDTO> orderMap = new HashMap<>(); + for (OrderCheckListDTO c : ls) { + orderIds.add(c.getId()); + + orderMap.put(c.getId(), c); + + Long locationId = c.getWarehouseLocationId(); + OrderCheckLocationListDTO llc = rMap.get(locationId); + if(llc == null){ + llc = new OrderCheckLocationListDTO(); + BeanUtils.copyProperties(c, llc); + llc.setTotalAmount(new BigDecimal(0)); + + rMap.put(locationId, llc); + result.add(llc); + } + + BigDecimal t = llc.getTotalAmount(); + if(t == null){ + t = new BigDecimal(0); + } + t = t.add(c.getTotalAmount()); + llc.setTotalAmount(t); + } + + Map<Long, String> stationMap = prepareStationMap(); + + List<OrderItem> itemList = orderItemMapper.selectList(new QueryWrapper<OrderItem>() + .in("order_id", orderIds)); + Map<String, List<OrderItemLocationListDTO>> map = new HashMap<>(); + + for (OrderItem oi : itemList) { + String orderId = oi.getOrderId(); + List<OrderItemLocationListDTO> ll = map.computeIfAbsent(orderId, k -> new ArrayList<>()); + OrderItemLocationListDTO d = new OrderItemLocationListDTO(); + BeanUtils.copyProperties(oi, d); + d.setStationName(stationMap.get(oi.getStationId())); + + OrderCheckListDTO c = orderMap.get(oi.getOrderId()); + d.setOrderNo(c.getOrderNo()); + d.setOrderId(c.getId()); + + ll.add(d); + } + + for (OrderCheckListDTO c : ls) { + String orderId = c.getId(); + Long locationId = c.getWarehouseLocationId(); + OrderCheckLocationListDTO r = rMap.get(locationId); + List<OrderItemLocationListDTO> items = r.getItems(); + if(items == null){ + items = new ArrayList<>(); + r.setItems(items); + } + items.addAll(map.get(orderId)); + } + } + + return result; } public Page<OrderListDTO> selectPartnerOrderList(Page page, OrderQueryDTO dto) { @@ -949,6 +1159,9 @@ if(checkList != null && checkList.size() > 0){ for(OrderItemCheck c : checkList){ + if(Constants.CHECK_TYPE.replace.name().equals(c.getType())){ + continue; + } totalAmount = totalAmount.subtract(getAmount(c.getDeductAmount())); } } @@ -1349,4 +1562,9 @@ Order o = orderMapper.getUserLastOrder(userId); return o.getReceiveTime(); } + + public Integer getFlowerCompleteNumToday(String userId,Long flowerId){ + Integer completeNum= orderMapper.getFlowerCompleteNumToday(userId,flowerId); + return completeNum; + } } -- Gitblit v1.9.3