From 24f7f046f8854d63839ad52d0cff34ea45a0f449 Mon Sep 17 00:00:00 2001 From: gongzuming <gongzuming> Date: 星期二, 12 十一月 2024 13:10:17 +0800 Subject: [PATCH] 优化 --- src/main/java/com/mzl/flower/service/payment/OrderService.java | 760 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 684 insertions(+), 76 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..d8a9c9d 100644 --- a/src/main/java/com/mzl/flower/service/payment/OrderService.java +++ b/src/main/java/com/mzl/flower/service/payment/OrderService.java @@ -12,18 +12,26 @@ 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.comment.QueryFlowerCommentDTO; +import com.mzl.flower.dto.request.menber.MemberGrowthRecordDTO; import com.mzl.flower.dto.request.payment.*; +import com.mzl.flower.dto.response.comment.FlowerCommentVO; +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.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.Flower; 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,10 +45,16 @@ 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.comment.FlowerCommentService; +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; +import com.mzl.flower.utils.ExcelExportUtil; import com.mzl.flower.utils.UUIDGenerator; import com.wechat.pay.java.core.util.GsonUtil; import io.micrometer.core.instrument.util.StringUtils; @@ -48,17 +62,20 @@ 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; +import org.springframework.util.ObjectUtils; +import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.math.RoundingMode; +import java.net.URLEncoder; 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 @@ -131,47 +148,123 @@ @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; + + @Autowired + private FlowerCommentService flowerCommentService; + + 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); } } @@ -211,13 +304,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()); @@ -245,6 +343,8 @@ } public PreOrderDTO getPreOrderInfo(List<CartSaveDTO> flowers, Map<Long, PriceDTO> priceMap) { + String userId = SecurityUtils.getUserId(); + if (flowers == null || flowers.size() == 0) { throw new ValidationException("请选择商品"); } @@ -260,15 +360,37 @@ } 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); 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 +410,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 +421,7 @@ totalWeight += c.getWeight() * c.getNum(); totalAmount = totalAmount.add(c.getTotal()); + totalMemberAmount = totalMemberAmount.add(c.getTotalMember()); num += c.getNum(); } @@ -306,6 +432,7 @@ result.setFlowers(ls); result.setPacking(packing); result.setTotalAmount(totalAmount); + result.setTotalMemberAmount(totalMemberAmount); result.setTotalWeight(totalWeight); return result; @@ -326,7 +453,18 @@ } } - public Map commitOrder(OrderCommitDTO dto, PreOrderDTO p, Map<Long, PriceDTO> priceMap) { + public Map commitOrder(OrderCommitDTO dto, PreOrderDTO p, Map<Long, PriceDTO> priceMap) throws Exception { + 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()); @@ -339,7 +477,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) { @@ -348,21 +487,49 @@ deliveryName = d.getName(); } - 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.setMemberDiscountAmount(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();//使用优惠券之前的总价,使用商品价格 + CouponRecordDO coupon = useCouponRecord(order.getId(), totalAmount, dto.getCouponRecordId()); + log.info("用户优惠券: " + coupon); + if(coupon != null){ + order.setMemberCouponId(coupon.getId()); + order.setMemberCouponCode(coupon.getCouponCode()); + order.setMemberCouponName(coupon.getCouponName()); + 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); order.setCustomer(address.getName()); @@ -383,7 +550,12 @@ //商品列表处理 List<FlowerCartListDTO> flowers = p.getFlowers(); Map<Long, List<ParamItemDTO>> paramMap = new HashMap<>(); - for (FlowerCartListDTO f : flowers) { + final BigDecimal flowerAmount = order.getFlowerAmount();//订单商品总价 + 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()); @@ -408,8 +580,23 @@ 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());//非会员售价 + 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.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); @@ -421,9 +608,74 @@ 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 + * @param price + * @return + */ + private BigDecimal calculateCoupon(BigDecimal couponAmount, BigDecimal itemTotalAmount + , BigDecimal totalAmount, Integer num, BigDecimal price + , boolean isLastOne, BigDecimal usedCouponAmount){ + if(couponAmount == null || couponAmount.doubleValue() == 0){ + return new BigDecimal(0); + } + + if(couponAmount.compareTo(totalAmount) >= 0){ + 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 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)){ + //优惠券使用和验证,如果不符合使用条件需要抛出异常。需调用优惠券使用方法 + couponRecordService.useCoupon(couponRecordId, orderId, amount); + return couponRecordService.getCouponRecordById(couponRecordId); + } + + return null; } private String getOrderNo() { @@ -519,7 +771,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 +811,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); } @@ -595,19 +878,28 @@ 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<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(); 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); } @@ -701,6 +993,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) { Partner p = getCurrentPartner(); dto.setPartnerId(p.getId()); @@ -710,6 +1078,7 @@ public Page<OrderListDTO> selectCustomerOrderList(Page page, OrderQueryDTO dto) { dto.setCreateBy(SecurityUtils.getUserId()); + dto.setCustomerQuery(true); return selectOrderList(page, dto); } @@ -736,6 +1105,18 @@ boolean couldCheckRefund = StringUtils.isEmpty(transferId) && count == 0 && cc == 0; dto.setCouldCheckRefund(couldCheckRefund); + 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; } @@ -760,6 +1141,7 @@ new QueryWrapper<OrderItem>().eq("order_id", id)); Map<Long, String> stationMap = prepareStationMap(); + Map<String, FlowerCommentVO> commentMap=prepareCommentMap(id); List<OrderItemListDTO> result = new ArrayList<>(); for (OrderItem oi : ls) { @@ -768,18 +1150,43 @@ dto.setStationName(stationMap.get(oi.getStationId())); + // 评论 + final FlowerCommentVO flowerCommentVO = commentMap.get(oi.getId()); + copyCommentInfo(dto,flowerCommentVO); + result.add(dto); } return result; } - public void autoReceive() { + private Map<String, FlowerCommentVO> prepareCommentMap(String orderId) { + QueryFlowerCommentDTO queryFlowerCommentDTO = new QueryFlowerCommentDTO(); + queryFlowerCommentDTO.setOrderId(orderId); + final List<FlowerCommentVO> list = flowerCommentService.getList(queryFlowerCommentDTO); + if (list == null || list.isEmpty()) { + return Collections.emptyMap(); + } + // 将 List 转换为 Map,其中 key 为 FlowerCommentVO 的 id + return list.stream().collect(Collectors.toMap(FlowerCommentVO::getOrderItemId, item -> item)); + } + + + private void copyCommentInfo(OrderItemListDTO dto,FlowerCommentVO flowerCommentVO){ + if(null != dto && null!=flowerCommentVO){ + dto.setCommentGrade(flowerCommentVO.getCommentGrade()); + dto.setComment(flowerCommentVO.getComment()); + dto.setCommentImages(flowerCommentVO.getCommentImages()); + dto.setAnonymityFalg(flowerCommentVO.getAnonymityFalg()); + } + } + + 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 +1194,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 +1274,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 +1292,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) { @@ -1004,7 +1427,7 @@ return dto; } - public void processAbnormalOrder(String id) { + public void processAbnormalOrder(String id) throws Exception { Order o = orderMapper.selectById(id); String transferId = o.getTransferId(); if (StringUtils.isNotEmpty(transferId)) { @@ -1038,18 +1461,18 @@ deductAmount = deductAmount.add(a.getDeductAmount()); } + o.setTransferTime(LocalDateTime.now()); + o.update(SecurityUtils.getUserId()); + transferId = "NoNeedRefund"; if (deductAmount.doubleValue() > 0) { transferId = paymentV3Service.refundOrderSub(o, deductAmount); } o.setTransferId(transferId); - o.setTransferTime(LocalDateTime.now()); - o.update(SecurityUtils.getUserId()); orderMapper.updateById(o); - } - public void processLevelDown(OrderReduceDTO dto) { + public void processLevelDown(OrderReduceDTO dto) throws Exception { Order o = orderMapper.selectById(dto.getId()); String transferId = o.getTransferId(); if (StringUtils.isNotEmpty(transferId)) { @@ -1185,4 +1608,189 @@ order.update(SecurityUtils.getUserId()); orderMapper.updateById(order); } + + /** + * 获取用户最后收货时间 + * @param userId + * @return + */ + public LocalDateTime getUserLastOrderTime(String userId){ + 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(); + + } + + public void operationUpdate(OrderAddressUpdateDTO dto) { + if (StringUtils.isBlank(dto.getId())) { + throw new ValidationException("id不能为空"); + } + Order order = orderMapper.selectById(dto.getId()); + if (ObjectUtils.isEmpty(order)) { + throw new ValidationException("订单不存在"); + } + if (StringUtils.isBlank(dto.getCustomerAddress()) || StringUtils.isBlank(dto.getCustomerCity()) || StringUtils.isBlank(dto.getCustomerProvince()) || StringUtils.isBlank(dto.getCustomerRegion())) { + throw new ValidationException("地址信息不能为空"); + } + if (StringUtils.isBlank(dto.getCustomerTel())) { + throw new ValidationException("联系方式不能为空"); + } + BeanUtils.copyProperties(dto, order); + order.update(SecurityUtils.getUserId()); + orderMapper.updateById(order); + } + + private List<OrderListExportDTO> getOrderExportListBase(OrderQueryDTO dto) { + 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<OrderListExportDTO> ls = orderMapper.selectOrderExportList(dto); + return ls; + } + + public void exportOrderDetail(HttpServletResponse response, OrderQueryDTO dto) { + List<OrderListExportDTO> ls = getOrderExportListBase( dto); + String[] rowsName = new String[]{"序号","订单号", "用户账号", "收货人", "收货人电话", "收货地址", "订单金额" + , "底价", "订单状态", "下单时间", "合伙人", "库位", "特殊需求", "备注"}; + List<Object[]> dataList = new ArrayList<>(); + int sn = 1; + for (OrderListExportDTO o : ls) { + Object[] objs = new Object[rowsName.length]; + int a = 0; + objs[a++] = sn; + objs[a++] = o.getOrderNo(); + objs[a++] = o.getCreateName(); + objs[a++] = o.getCustomer(); + objs[a++] = o.getCustomerTel(); + objs[a++] = o.getCustomerAddress(); + objs[a++] = o.getTotalAmount(); + objs[a++] = o.getSupplierAmount(); + objs[a++] = o.getStatusBackendStr(); + objs[a++] = o.getCreateTime(); + objs[a++] = o.getPartnerName(); + objs[a++] = o.getWarehouseLocationCode(); + objs[a++] = o.getSpecialNeedsStr(); + objs[a++] = o.getRemarks(); + dataList.add(objs); + + sn++; + } + ExcelExportUtil excelExportUtil = new ExcelExportUtil("订单列表", rowsName, dataList, response); + try { + response.addHeader("filename", URLEncoder.encode("订单列表.xls", "UTF-8")); + response.addHeader("Access-Control-Expose-Headers", "filename"); + excelExportUtil.export(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + } + + public void exportPartnerOrderList(HttpServletResponse response, OrderQueryDTO dto) { + Partner p = getCurrentPartner(); + dto.setPartnerId(p.getId()); + exportOrderDetail(response, dto); + } + } -- Gitblit v1.9.3