From af63efdfd4b82e1efa995992768c2f283fa6d98f Mon Sep 17 00:00:00 2001 From: Cui Zhi Feng <7426394+wuxixiaocui@user.noreply.gitee.com> Date: 星期三, 04 九月 2024 15:43:04 +0800 Subject: [PATCH] 优惠券使用 --- src/main/java/com/mzl/flower/service/payment/OrderService.java | 328 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 267 insertions(+), 61 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 44149e3..71d5a97 100644 --- a/src/main/java/com/mzl/flower/service/payment/OrderService.java +++ b/src/main/java/com/mzl/flower/service/payment/OrderService.java @@ -12,6 +12,7 @@ import com.mzl.flower.config.security.SecurityUtils; import com.mzl.flower.constant.Constants; import com.mzl.flower.dto.PriceDTO; +import com.mzl.flower.dto.request.menber.MemberGrowthRecordDTO; import com.mzl.flower.dto.request.payment.*; import com.mzl.flower.dto.response.flower.FlowerCartListDTO; import com.mzl.flower.dto.response.flower.FlowerCartListWrapDTO; @@ -21,9 +22,11 @@ import com.mzl.flower.dto.response.system.CodeValueDTO; import com.mzl.flower.dto.response.transport.TransportOrderDTO; import com.mzl.flower.dto.response.warehouse.WarehouseLocationDTO; +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.FlowerSupplierSaleNum; +import com.mzl.flower.entity.menber.Member; import com.mzl.flower.entity.partner.Partner; import com.mzl.flower.entity.payment.*; import com.mzl.flower.entity.supplier.Station; @@ -37,7 +40,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; @@ -48,6 +55,7 @@ import me.chanjar.weixin.common.error.WxErrorException; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -131,47 +139,87 @@ @Autowired private OrderItemCheckMapper orderItemCheckMapper; + @Autowired + private OrderPointGoodsMapper pointGoodsMapper; + + @Autowired + @Lazy + private MemberGrowthRecordService memberGrowthRecordService; + + @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); + + cartMapper.insert(c); } else { - cartMapper.updateById(c); + c.setNum(c.getNum() + dto.getNum()); + 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); } } @@ -211,13 +259,18 @@ if (ls != null && ls.size() > 0) { Customer customer = getCurrentCustomer(); Long partnerId = customer.getPartnerId(); + Long levelId = customer.getLevelId(); + Member member = getMember(levelId); Map<Long, FlowerCartListWrapDTO> map = new HashMap<>(); for (FlowerCartListDTO c : ls) { BigDecimal price = getFinalPrice(partnerId, c.getCategory() , c.getId(), c.getPrice(), c.getLevel()); c.setPrice(price); + c.setPriceMember(calculateMemberPrice(price, member)); + c.setTotal(price.multiply(new BigDecimal(c.getNum()))); + c.setTotalMember(c.getPriceMember().multiply(new BigDecimal(c.getNum()))); if (c.getSales() != null && c.getRealSales() != null) { c.setSales(c.getSales() + c.getRealSales()); @@ -265,10 +318,20 @@ List<FlowerCartListDTO> ls = flowerMapper.selectFlowerOrderList(ids); Customer customer = getCurrentCustomer(); Long partnerId = customer.getPartnerId(); + Long levelId = customer.getLevelId(); + Member member = getMember(levelId); + if (member != null) { + result.setMemberId(levelId); + result.setMemberName(member.getName()); + result.setMemberDiscountType(member.getDiscountType()); + result.setMemberDiscountRatio(member.getDiscountRatio()); + result.setMemberDiscountAmount(member.getDiscountAmount()); + } double totalWeight = 0D; int num = 0; BigDecimal totalAmount = new BigDecimal(0); + BigDecimal totalMemberAmount = new BigDecimal(0); for (FlowerCartListDTO c : ls) { if (!Constants.FLOWER_STATUS.UP.name().equals(c.getStatus())) { throw new ValidationException("商品" + c.getName() + "已下架,请重新提交"); @@ -288,7 +351,10 @@ , c.getId(), c.getPrice(), c.getLevel()); BigDecimal price = priceDTO.getPrice(); c.setPrice(price); + c.setPriceMember(calculateMemberPrice(price, member)); + c.setTotal(price.multiply(new BigDecimal(c.getNum()))); + c.setTotalMember(c.getPriceMember().multiply(new BigDecimal(c.getNum())));//使用会员价计算总价 if (priceMap != null) { priceMap.put(c.getId(), priceDTO); @@ -296,6 +362,7 @@ totalWeight += c.getWeight() * c.getNum(); totalAmount = totalAmount.add(c.getTotal()); + totalMemberAmount = totalMemberAmount.add(c.getTotalMember()); num += c.getNum(); } @@ -306,6 +373,7 @@ result.setFlowers(ls); result.setPacking(packing); result.setTotalAmount(totalAmount); + result.setTotalMemberAmount(totalMemberAmount); result.setTotalWeight(totalWeight); return result; @@ -339,7 +407,8 @@ } Address address = addressMapper.selectById(dto.getAddressId()); - List<TransportOrderDTO> tLs = transportService.getPreOrderTransportList(address, p.getTotalWeight(), dto.getTransportId()); + List<TransportOrderDTO> tLs = transportService.getPreOrderTransportList(address + , p.getTotalWeight(), dto.getTransportId()); BigDecimal transportFee = new BigDecimal(0); String deliveryName = ""; if (tLs != null && tLs.size() > 0) { @@ -351,18 +420,38 @@ String userId = SecurityUtils.getUserId(); Order order = new Order(); order.setId(UUIDGenerator.getUUID()); + + final List<Long> goodsRecordIdList = dto.getGoodsRecordIdList(); + usePointGoods(order.getId(), goodsRecordIdList);//使用积分商品兑换券 + order.create(userId); order.setRemarks(dto.getRemarks()); order.setSpecialNeeds(dto.getSpecialNeeds()); order.setStatusBackend(Constants.ORDER_STATUS_BACKEND.PENDING.name()); order.setStatus(Constants.ORDER_STATUS.PENDING.name()); - order.setFlowerAmount(p.getTotalAmount()); + //设置下单时的会员信息 + order.setMemberId(p.getMemberId()); + order.setMemberName(p.getMemberName()); + order.setMemberDiscountType(p.getMemberDiscountType()); + order.setMemberDiscountRatio(p.getMemberDiscountRatio()); + order.setMemberCouponAmount(p.getMemberDiscountAmount()); + + order.setFlowerAmount(p.getTotalMemberAmount());//使用会员价总价 order.setPackingFee(p.getPacking()); order.setTransportFee(transportFee); order.setDeliveryName(deliveryName); - BigDecimal totalAmount = order.getFlowerAmount().add(p.getPacking()).add(transportFee); + BigDecimal totalAmount = order.getFlowerAmount().add(p.getPacking()).add(transportFee);//使用优惠券之前的总价 + CouponRecordDO coupon = useCouponRecord(order.getId(), totalAmount, dto.getCouponRecordId()); + if(coupon != null){ + order.setMemberCouponId(coupon.getId()); + order.setMemberCouponCode(coupon.getCouponCode()); + order.setMemberCouponName(coupon.getCouponName()); + order.setMemberCouponAmount(coupon.getCouponDiscountValue()); + + totalAmount = totalAmount.subtract(order.getMemberCouponAmount());//满足条件需要减去优惠券金额 + } order.setTotalAmount(totalAmount); order.setCustomer(address.getName()); @@ -383,6 +472,8 @@ //商品列表处理 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) { OrderItem t = new OrderItem(); t.setId(UUIDGenerator.getUUID()); @@ -408,8 +499,13 @@ t.setMarkupOne(pp.getFirstFee()); t.setMarkupTwo(pp.getSecondFee()); t.setMarkupPartner(pp.getPartnerFee()); - t.setPrice(pp.getPrice()); - t.setTotal(f.getTotal()); + t.setPrice(f.getPriceMember());//使用会员单价 + t.setTotal(f.getTotalMember());//使用会员总价 + + t.setOriginalPrice(pp.getPrice());//非会员售价 + BigDecimal couponAmount = calculateCoupon(memberCouponAmount, t.getTotal(), flowerAmount, t.getNum()); + t.setCouponAmount(couponAmount);//每扎平摊的优惠券面值 + t.setRealPrice(t.getPrice().subtract(couponAmount));//退款时使用的真实成交价 t.create(userId); orderItemMapper.insert(t); @@ -421,9 +517,59 @@ order.setPayOpenid(openId); orderMapper.insert(order); + //处理积分商品兑换券 + if(goodsRecordIdList != null && goodsRecordIdList.size() > 0){ + for(Long goodsRecordId : goodsRecordIdList){ + OrderPointGoods g = new OrderPointGoods(); + g.setId(UUIDGenerator.getUUID()); + g.setOrderId(order.getId()); + g.setGoodsRecordId(goodsRecordId); + g.create(userId); + pointGoodsMapper.insert(g); + } + } + Map map = paymentV3Service.wxPrepay(order); map.put("_testV2OrderId", order.getId()); return map; + } + + private void usePointGoods(String orderId, List<Long> goodsRecordIdList){ + //使用积分商品兑换券 + if(goodsRecordIdList != null && goodsRecordIdList.size() > 0){ + for(Long grId : goodsRecordIdList){ + pointGoodsService.useExchangeGoods(grId, orderId); + } + } + } + + /** + * 计算订单中每种商品每扎平摊的优惠券面值,保留2位小数 + * + * @param couponAmount + * @param itemTotalAmount + * @param totalAmount + * @param num + * @return + */ + private BigDecimal calculateCoupon(BigDecimal couponAmount, BigDecimal itemTotalAmount + , BigDecimal totalAmount, Integer num){ + if(couponAmount == null){ + return new BigDecimal(0); + } + BigDecimal radio = itemTotalAmount.divide(totalAmount, 2, RoundingMode.HALF_UP);//计算该商品总价在订单中的占比 + BigDecimal subCoupon = couponAmount.multiply(radio);//占有的优惠券面值 + return subCoupon.divide(BigDecimal.valueOf(num), 2, RoundingMode.HALF_UP); + } + + private CouponRecordDO useCouponRecord(String orderId, BigDecimal amount, String couponRecordId){ + if(StringUtils.isNotEmpty(couponRecordId)){ + //优惠券使用和验证,如果不符合使用条件需要抛出异常。需调用优惠券使用方法 + couponRecordService.useCoupon(couponRecordId, orderId, amount); + return couponRecordService.getCouponRecordById(couponRecordId); + } + + return null; } private String getOrderNo() { @@ -519,7 +665,27 @@ * 合伙人订单定时发货 */ public void setPartnerOrderSend() { - orderMapper.setPartnerOrderReceive(); + List<Order> orders = orderMapper.getPartnerOrderReceive(); + if(orders == null || orders.size() == 0){ + return; + } + for (Order o : orders) { + //set status_backend = 'RECEIVE', status = 'RECEIVE' + o.setStatusBackend("RECEIVE"); + o.setStatus("RECEIVE"); + //发送微信发货请求 + JSONObject jsonObject = sendWxDeliveryGood(o); + if (jsonObject != null && (int) jsonObject.get("errcode") == 0) { + o.setWxDeliveryGood(true); + o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); + } else { + o.setWxDeliveryGood(false); + o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); + } + + orderMapper.updateById(o); + } + //orderMapper.setPartnerOrderReceive(); } /** @@ -539,6 +705,17 @@ o.setStatus(Constants.ORDER_STATUS.RECEIVE.name()); o.setStatusBackend(Constants.ORDER_STATUS_BACKEND.RECEIVE.name()); o.update(SecurityUtils.getUserId()); + + //发送微信发货请求 + JSONObject jsonObject = sendWxDeliveryGood(o); + if (jsonObject != null && (int) jsonObject.get("errcode") == 0) { + o.setWxDeliveryGood(true); + o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); + } else { + o.setWxDeliveryGood(false); + o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); + } + orderMapper.updateById(o); } @@ -736,6 +913,9 @@ boolean couldCheckRefund = StringUtils.isEmpty(transferId) && count == 0 && cc == 0; dto.setCouldCheckRefund(couldCheckRefund); + List<OrderPointGoodsListDTO> pointGoodsList = orderMapper.getPointGoodsList(id); + dto.setPointGoodsList(pointGoodsList); + return dto; } @@ -774,12 +954,12 @@ return result; } - public void autoReceive() { + public List<Order> autoReceive() { int days = -5; //5天前的订单自动收货 LocalDateTime endTime = LocalDateTime.now().plusDays(days); List<Order> ls = orderMapper.getOrderForAutoReceive(endTime); if (ls == null || ls.size() == 0) { - return; + return ls; } for (Order o : ls) { @@ -787,20 +967,45 @@ o.setStatusBackend(Constants.ORDER_STATUS_BACKEND.EVALUATE.name()); o.setReceiveTime(LocalDateTime.now()); o.update("sys"); - - - //发送微信发货请求 - JSONObject jsonObject = sendWxDeliveryGood(o); - if (jsonObject != null && (int) jsonObject.get("errcode") == 0) { - o.setWxDeliveryGood(true); - o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); - } else { - o.setWxDeliveryGood(false); - o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); - } orderMapper.updateById(o); - } + + return ls; + } + + public void processAfterReceive(Order o){ + String status = o.getStatus(); + if(!Constants.ORDER_STATUS.EVALUATE.name().equals(status)){ + log.warn("订单未确认收货,无法处理积分和成长值"); + return; + } + + BigDecimal totalAmount = o.getTotalAmount(); + List<OrderItemCheck> checkList = orderItemCheckMapper.selectList(new QueryWrapper<OrderItemCheck>() + .eq("order_id", o.getId()) + .eq("audit_status", Constants.CHECK_AUDIT_STATUS.AGREED.name()) + ); + + 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())); + } + } + + //成长值计算 + MemberGrowthRecordDTO mDto = new MemberGrowthRecordDTO(); + mDto.setTotalAmount(totalAmount); + mDto.setUserId(o.getCreateBy()); + mDto.setSource(Constants.GROWTH_SOURCE.consume.name()); + mDto.setType(Constants.GROWTH_TYPE.add.name()); + mDto.setRemarks("订单: " + o.getOrderNo()); + memberGrowthRecordService.saveMemberGrowthRecord(mDto); + + //积分计算 + customerPointService.consumptionPoint(totalAmount, o.getOrderNo(), o.getCreateBy()); } public JSONObject sendWxDeliveryGood(Order o) { @@ -842,7 +1047,7 @@ } } - public void confirmOrderReceive(String id) { + public Order confirmOrderReceive(String id) { Order o = orderMapper.selectById(id); String userId = SecurityUtils.getUserId(); if (!userId.equals(o.getCreateBy())) { @@ -860,18 +1065,9 @@ o.setStatusBackend(Constants.ORDER_STATUS_BACKEND.EVALUATE.name()); o.setReceiveTime(LocalDateTime.now()); o.update(userId); - - //发送微信发货请求 - JSONObject jsonObject = sendWxDeliveryGood(o); - if (jsonObject != null && (int) jsonObject.get("errcode") == 0) { - o.setWxDeliveryGood(true); - o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); - } else { - o.setWxDeliveryGood(false); - o.setWxDeliveryMsg(GsonUtil.toJson(jsonObject)); - } - orderMapper.updateById(o); + + return o; } public Integer getMyOrderStatusCount(String status) { @@ -1185,4 +1381,14 @@ order.update(SecurityUtils.getUserId()); orderMapper.updateById(order); } + + /** + * 获取用户最后收货时间 + * @param userId + * @return + */ + public LocalDateTime getUserLastOrderTime(String userId){ + Order o = orderMapper.getUserLastOrder(userId); + return o.getReceiveTime(); + } } -- Gitblit v1.9.3