|  |  | 
 |  |  | 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.coupon.CouponRecordVO; | 
 |  |  | 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.*; | 
 |  |  | 
 |  |  | 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; | 
 |  |  | 
 |  |  | import org.springframework.context.annotation.Lazy; | 
 |  |  | import org.springframework.stereotype.Service; | 
 |  |  | import org.springframework.transaction.annotation.Transactional; | 
 |  |  | import org.springframework.util.ObjectUtils; | 
 |  |  |  | 
 |  |  | import java.math.BigDecimal; | 
 |  |  | import java.math.RoundingMode; | 
 |  |  | import java.time.LocalDate; | 
 |  |  | import java.time.LocalDateTime; | 
 |  |  | import java.util.ArrayList; | 
 |  |  | import java.util.HashMap; | 
 |  |  | import java.util.List; | 
 |  |  | import java.util.Map; | 
 |  |  | import java.time.LocalTime; | 
 |  |  | import java.util.*; | 
 |  |  | import java.util.stream.Collectors; | 
 |  |  |  | 
 |  |  | @Service | 
 |  |  | @Transactional | 
 |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private CouponRecordService couponRecordService; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     public void changeFlower2Cart(CartSaveDTO dto) { | 
 |  |  |         String userId = SecurityUtils.getUserId(); | 
 |  |  |         String key = userId + "_" + 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 { | 
 |  |  |                 // 查看是否已经超过当前商品的限购数量 | 
 |  |  |                 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()); | 
 |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public PreOrderDTO getPreOrderInfo(List<CartSaveDTO> flowers, Map<Long, PriceDTO> priceMap) { | 
 |  |  |         String userId = SecurityUtils.getUserId(); | 
 |  |  |  | 
 |  |  |         if (flowers == null || flowers.size() == 0) { | 
 |  |  |             throw new ValidationException("请选择商品"); | 
 |  |  |         } | 
 |  |  | 
 |  |  |             } | 
 |  |  |             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); | 
 |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     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()); | 
 |  |  | 
 |  |  |             deliveryName = d.getName(); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         String userId = SecurityUtils.getUserId(); | 
 |  |  |  | 
 |  |  |         Order order = new Order(); | 
 |  |  |         order.setId(UUIDGenerator.getUUID()); | 
 |  |  |  | 
 |  |  | 
 |  |  |         List<FlowerCartListDTO> flowers = p.getFlowers(); | 
 |  |  |         Map<Long, List<ParamItemDTO>> paramMap = new HashMap<>(); | 
 |  |  |         final BigDecimal flowerAmount = order.getFlowerAmount();//订单商品总价 | 
 |  |  |         final BigDecimal memberCouponAmount = order.getMemberCouponAmount();//使用优惠券面值 | 
 |  |  |         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()); | 
 |  |  | 
 |  |  |             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));//退款时使用的真实成交单价 | 
 |  |  |  | 
 |  |  |             usedCouponAmount = usedCouponAmount.add(couponAmount.multiply(BigDecimal.valueOf(t.getNum()))); | 
 |  |  |             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); | 
 |  |  | 
 |  |  |     private BigDecimal calculateCoupon(BigDecimal couponAmount, BigDecimal itemTotalAmount | 
 |  |  |             , BigDecimal totalAmount, Integer num, BigDecimal price | 
 |  |  |             , boolean isLastOne, BigDecimal usedCouponAmount){ | 
 |  |  |         if(couponAmount == null){ | 
 |  |  |         if(couponAmount == null || couponAmount.doubleValue() == 0){ | 
 |  |  |             return new BigDecimal(0); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  | 
 |  |  |             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 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){ | 
 |  |  | 
 |  |  |         List<OrderListDTO> ls = getOrderListBase(page, dto); | 
 |  |  |         if (ls != null && ls.size() > 0) { | 
 |  |  |             List<String> orderIds = new ArrayList<>(); | 
 |  |  |             Map<String, OrderListDTO> orderMap = new HashMap<>(); | 
 |  |  |             for (OrderListDTO o : ls) { | 
 |  |  |                 o.setCouldRefund(couldRefund(o.getStatusBackend(), o.getPaymentTime())); | 
 |  |  |                 orderIds.add(o.getId()); | 
 |  |  |                 orderMap.put(o.getId(), o); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             List<OrderItemListDTO> itemList = orderItemMapper.getOrderItems(orderIds); | 
 |  |  | 
 |  |  |                 List<OrderItemListDTO> ll = map.computeIfAbsent(orderId, k -> new ArrayList<>()); | 
 |  |  |                 OrderItemListDTO d = new OrderItemListDTO(); | 
 |  |  |                 BeanUtils.copyProperties(oi, d); | 
 |  |  |  | 
 |  |  |                 OrderListDTO o = orderMap.get(orderId); | 
 |  |  |                 if(dto.isCustomerQuery() && o != null && StringUtils.isEmpty(o.getTransferId())){ | 
 |  |  |                     d.setReduceNum(0); | 
 |  |  |                     d.setLackNum(0); | 
 |  |  |                     d.setReplaceNum(0); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 ll.add(d); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  | 
 |  |  |                 if(llc == null){ | 
 |  |  |                     llc = new OrderCheckLocationListDTO(); | 
 |  |  |                     BeanUtils.copyProperties(c, llc); | 
 |  |  |                     rMap.put(locationId, llc); | 
 |  |  |                     llc.setTotalAmount(new BigDecimal(0)); | 
 |  |  |  | 
 |  |  |                     rMap.put(locationId, llc); | 
 |  |  |                     result.add(llc); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  | 
 |  |  |  | 
 |  |  |     public Page<OrderListDTO> selectCustomerOrderList(Page page, OrderQueryDTO dto) { | 
 |  |  |         dto.setCreateBy(SecurityUtils.getUserId()); | 
 |  |  |         dto.setCustomerQuery(true); | 
 |  |  |  | 
 |  |  |         return selectOrderList(page, dto); | 
 |  |  |     } | 
 |  |  | 
 |  |  |  | 
 |  |  |         List<OrderPointGoodsListDTO> pointGoodsList = orderMapper.getPointGoodsList(id); | 
 |  |  |         dto.setPointGoodsList(pointGoodsList); | 
 |  |  |  | 
 |  |  |         //判断优惠券ID是否为空 用户优惠券id | 
 |  |  |         if(StringUtils.isNotBlank(o.getMemberCouponId())){ | 
 |  |  |             CouponRecordVO couponRecordVO = couponRecordService.getCouponRecordById(o.getMemberCouponId()); | 
 |  |  |             if(!ObjectUtils.isEmpty(couponRecordVO)){ | 
 |  |  |                 dto.setCouponDiscountType(couponRecordVO.getCouponDiscountType()); | 
 |  |  |                 dto.setMinOrderAmount("满"+couponRecordVO.getMinOrderAmount()); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         return dto; | 
 |  |  |     } | 
 |  |  | 
 |  |  |         Order o = orderMapper.getUserLastOrder(userId); | 
 |  |  |         return o.getReceiveTime(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public Integer getFlowerCompleteNumToday(String userId,Long flowerId){ | 
 |  |  |  | 
 |  |  |         int completeNum = 0; | 
 |  |  |         // 获取当前时间 | 
 |  |  |         LocalDateTime now = LocalDateTime.now(); | 
 |  |  |         // 构造今天的17:00 | 
 |  |  |         LocalDateTime todayAtFivePM = LocalDateTime.of(LocalDate.now(), LocalTime.of(17, 0)); | 
 |  |  |         // 定义时间区间的开始和结束时间 | 
 |  |  |         LocalDateTime startTime; | 
 |  |  |         LocalDateTime endTime; | 
 |  |  |  | 
 |  |  |         if (now.isAfter(todayAtFivePM)) { | 
 |  |  |             // 当前时间大于今天的17:00,取今天17:00到明天17:00的区间 | 
 |  |  |             startTime = todayAtFivePM; | 
 |  |  |             endTime = todayAtFivePM.plusDays(1);  // 明天的17:00 | 
 |  |  |         } else { | 
 |  |  |             // 当前时间小于今天的17:00,取昨天17:00到今天17:00的区间 | 
 |  |  |             startTime = todayAtFivePM.minusDays(1);  // 昨天的17:00 | 
 |  |  |             endTime = todayAtFivePM;  // 今天的17:00 | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 调用Mapper方法,传递开始时间和结束时间 | 
 |  |  |         completeNum = orderMapper.getFlowerCompleteNumWithinTimeRange(userId, flowerId, startTime, endTime); | 
 |  |  |  | 
 |  |  |         return completeNum; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Transactional | 
 |  |  |     public String copyOrder(String id) { | 
 |  |  |         List<OrderItem> ls = orderItemMapper.selectList( | 
 |  |  |                 new QueryWrapper<OrderItem>().eq("order_id", id)); | 
 |  |  |         StringBuilder sb=new StringBuilder(); | 
 |  |  |         ls.stream().forEach(orderItem -> { | 
 |  |  |             Cart cart = null; | 
 |  |  |             final Long flowerId = orderItem.getFlowerId(); | 
 |  |  |             final Integer num = orderItem.getNum(); | 
 |  |  |             final String userId=orderItem.getCreateBy(); | 
 |  |  |             // 查看当前的花是否已经下架 | 
 |  |  |             Flower flower = flowerMapper.selectById(flowerId); | 
 |  |  |             // 查看当前的花的限购 | 
 |  |  |             final Integer limited = flower.getLimited(); | 
 |  |  |  | 
 |  |  |             // 查看当前购物车里面是否已经存在当前花 | 
 |  |  |             cart = cartMapper.selectOne(new QueryWrapper<Cart>() | 
 |  |  |                     .eq("create_by", orderItem.getCreateBy()).eq("flower_id",flowerId)); | 
 |  |  |  | 
 |  |  |             if(null==cart){ | 
 |  |  |                 cart = new Cart(); | 
 |  |  |                 cart.setFlowerId(flowerId); | 
 |  |  |                 cart.setNum(0); | 
 |  |  |                 cart.create(orderItem.getCreateBy()); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             if (!flower.getStatus().equals(Constants.FLOWER_STATUS.UP.name())) { | 
 |  |  |                 sb.append(flower.getName() + "已下架"); | 
 |  |  |             }else if(flower.getStatus().equals(Constants.FLOWER_STATUS.UP.name())){ | 
 |  |  |                 // 未下架库存逻辑控制 | 
 |  |  |                 Integer tmpNum=cart.getNum()+num; | 
 |  |  |                 //查看当前的库存 | 
 |  |  |                 if (null!=flower.getStock() && flower.getStock() > 0 && flower.getStock().compareTo(tmpNum) >= 0) { | 
 |  |  |                     // 库存充足 | 
 |  |  |                     cart.setNum(tmpNum); | 
 |  |  |                 } else if (null!=flower.getStock() && flower.getStock() > 0 && flower.getStock().compareTo(tmpNum) < 0) { | 
 |  |  |                     // 库存不足,剩多少给多少 | 
 |  |  |                     cart.setNum(flower.getStock()); | 
 |  |  |                     sb.append(flower.getName() + "购物车的总数超过库存,已调整成库存数!"); | 
 |  |  |                 }else { | 
 |  |  |                     sb.append(flower.getName() + "已无库存"); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 // 限购控制,如果当前的购物车的数量大于限购的话,则需要控制 | 
 |  |  |                 if(null!=limited && limited>0){ | 
 |  |  |                     Integer buyedNum= getFlowerCompleteNumToday(userId,flowerId); | 
 |  |  |                     Integer todayNum=cart.getNum()+buyedNum; | 
 |  |  |                     // | 
 |  |  |                     if(todayNum>limited){ | 
 |  |  |                         cart.setNum(limited-buyedNum<=0?0:limited-buyedNum); | 
 |  |  |                         sb.append(flower.getName() + "购物车的总数超过限购,已调整成未限购数!"); | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             if(null!=cart){ | 
 |  |  |                 // 插入购物车 | 
 |  |  |                 if(null!=cart.getId()){ | 
 |  |  |                     // 新增 | 
 |  |  |                     cartMapper.updateById(cart); | 
 |  |  |                 }else{ | 
 |  |  |                    // 更新 | 
 |  |  |                     cartMapper.insert(cart); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |         }); | 
 |  |  |  | 
 |  |  |         return sb.toString(); | 
 |  |  |  | 
 |  |  |     } | 
 |  |  | } |