New file |
| | |
| | | package com.matrix.system.shopXcx.api.service; |
| | | |
| | | import com.matrix.system.common.init.UserCacheManager; |
| | | import com.matrix.core.exception.GlobleException; |
| | | import com.matrix.core.tools.LogUtil; |
| | | import com.matrix.system.common.dao.BusParameterSettingsDao; |
| | | import com.matrix.system.shopXcx.api.pojo.OrderCouponGroup; |
| | | import com.matrix.system.shopXcx.api.pojo.OrderItemDto; |
| | | import com.matrix.system.shopXcx.bean.ShopCoupon; |
| | | import com.matrix.system.shopXcx.bean.ShopShoppingCart; |
| | | import com.matrix.system.shopXcx.dao.ShopProductDao; |
| | | import com.matrix.system.shopXcx.dao.ShopShoppingCartDao; |
| | | import com.matrix.system.shopXcx.dao.ShopSkuDao; |
| | | import org.apache.commons.collections.CollectionUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 购物车前台展示对象 |
| | | */ |
| | | @Service |
| | | public class OrderCouponGroupService { |
| | | @Autowired |
| | | private ShopShoppingCartDao shoppingCartDao; |
| | | @Autowired |
| | | private UserCacheManager userCacheManager; |
| | | |
| | | @Autowired |
| | | WxShopCouponService shopCouponService; |
| | | |
| | | @Autowired |
| | | BusParameterSettingsDao busParameterSettingsDao; |
| | | |
| | | @Autowired |
| | | ShopProductDao shopProductDao; |
| | | |
| | | @Autowired |
| | | ShopSkuDao shopSkuDao; |
| | | |
| | | /** |
| | | * 初始化OrderCouponElement |
| | | * @param skuId |
| | | * @param count |
| | | * @param payType |
| | | * @return |
| | | */ |
| | | public OrderItemDto buildOrderCouponElement(OrderItemDto orderItemDto){ |
| | | orderItemDto.setShopSku(shopSkuDao.selectById(orderItemDto.getSkuId())); |
| | | orderItemDto.setShopProduct(shopProductDao.selectById(orderItemDto.getProductId())); |
| | | return orderItemDto; |
| | | } |
| | | |
| | | /** |
| | | * 计算用户的产品可以参与的店铺优惠活动分组 |
| | | */ |
| | | public List<OrderCouponGroup> buildOrderCouponGroupList(List<OrderItemDto> list) { |
| | | |
| | | //定义购物车优惠分组 |
| | | List<OrderCouponGroup> orderCouponGroupList = new ArrayList<>(); |
| | | // 1表示没有优惠的默认分组 |
| | | OrderCouponGroup def = new OrderCouponGroup(); |
| | | def.setSatisfactionCoupon(true); |
| | | def.setMsg("商城"); |
| | | def.setOrderItemDtos(new ArrayList<>()); |
| | | // 组合默认分组 |
| | | orderCouponGroupList.add(def); |
| | | |
| | | // 记录所有优惠券,一个优惠券(活动)表示一组 |
| | | Map<Integer, ShopCoupon> shopCouponMap = new HashMap<>(); |
| | | |
| | | //查询购物车中的产品匹配上的所有优惠活动 |
| | | for (OrderItemDto orderItemDto : list) { |
| | | |
| | | if(orderItemDto.getPayType()== ShopShoppingCart.CAR_TYPE_SCORE){ |
| | | // 积分兑换产品不参加优惠 |
| | | def.getOrderItemDtos().add(orderItemDto); |
| | | }else{ |
| | | List<ShopCoupon> shopCouponList = shopCouponService.getHdListByProductId(orderItemDto.getProductId()); |
| | | if (CollectionUtils.isNotEmpty(shopCouponList)) { |
| | | // 把所有的优惠券和购物车条目先关联一下,后续可以计算优惠升级的情况 |
| | | orderItemDto.setShopCoupons(shopCouponList); |
| | | for (ShopCoupon shopCoupon : shopCouponList) { |
| | | shopCouponMap.put(shopCoupon.getId(), shopCoupon); |
| | | } |
| | | } else { |
| | | // 该产品没有参加优惠券 |
| | | def.getOrderItemDtos().add(orderItemDto); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | //计算没有优惠组的价格 |
| | | countPrice(def); |
| | | |
| | | |
| | | /* |
| | | * 计算优惠券分组 1、获取到所有的优惠券,从最高满减开始,找寻合适的产品,找到后加入对应的购物车组 |
| | | * 2、计算组内价格 |
| | | */ |
| | | Set<Integer> keys = shopCouponMap.keySet(); |
| | | List<ShopCoupon> allShopCoupons = new ArrayList<>(); |
| | | for (Integer key : keys) { |
| | | allShopCoupons.add(shopCouponMap.get(key)); |
| | | } |
| | | |
| | | //根据优惠力度排序,优惠力度大的先参与计算 |
| | | Collections.sort(allShopCoupons, new Comparator() { |
| | | @Override |
| | | public int compare(Object o1, Object o2) { |
| | | ShopCoupon e1 = (ShopCoupon) o1; |
| | | ShopCoupon e2 = (ShopCoupon) o2; |
| | | return e2.getMinAmount().compareTo(e1.getMinAmount()); |
| | | } |
| | | }); |
| | | |
| | | |
| | | // 进行购物车和优惠券的匹配,匹配成功的加入到优惠组中, |
| | | for (int i = 0; i < allShopCoupons.size(); i++) { |
| | | ShopCoupon shopCoupon = allShopCoupons.get(i); |
| | | OrderCouponGroup shopCarVo = new OrderCouponGroup(); |
| | | shopCarVo.setCoupon(shopCoupon); |
| | | shopCarVo.setOrderItemDtos(new ArrayList<>()); |
| | | orderCouponGroupList.add(i, shopCarVo); |
| | | |
| | | // 获取所有购物车条目 |
| | | for (OrderItemDto orderItemDto : list) { |
| | | // 如果匹配到的产品已经出现在其他优惠组中,则需要判断是否移除之前的组 |
| | | boolean needRemove = false; |
| | | |
| | | // 判断当前购物车条目是否已经在合适的组里了 |
| | | if (isInGroupAndSatisfaction(orderItemDto, orderCouponGroupList)) { |
| | | continue; |
| | | |
| | | } else if (isInGroupNotSatisfaction(orderItemDto, orderCouponGroupList)) { |
| | | needRemove = true; |
| | | } |
| | | |
| | | List<ShopCoupon> cartCouons = orderItemDto.getShopCoupons(); |
| | | if (cartCouons != null) { |
| | | // 获取每个购物车条目满足的优惠 |
| | | for (ShopCoupon cartCouon : cartCouons) { |
| | | if (cartCouon.getId().equals(shopCoupon.getId())) { |
| | | //匹配成功,加入本组 |
| | | LogUtil.debug("购物车" + orderItemDto.getProductId() + "和优惠券" + cartCouon.getCName() + "匹配"); |
| | | if (needRemove) { |
| | | removeNotSatisfaction(orderItemDto, orderCouponGroupList); |
| | | } |
| | | shopCarVo.getOrderItemDtos().add(orderItemDto); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | // 计算本组优惠券是否已经满足优惠条件 |
| | | countPrice(shopCarVo); |
| | | } |
| | | |
| | | |
| | | // 因为有些优惠中可能没有产品,所以要去除cartList中没有产品的分组 |
| | | List<OrderCouponGroup> cartListCopy = new ArrayList<>(); |
| | | for (OrderCouponGroup orderCouponGroup : orderCouponGroupList) { |
| | | if (CollectionUtils.isNotEmpty(orderCouponGroup.getOrderItemDtos())) { |
| | | cartListCopy.add(orderCouponGroup); |
| | | } |
| | | } |
| | | return cartListCopy; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 购车条目在组中并且组是否已经满足优惠的 |
| | | * |
| | | * @param cartList |
| | | * @return |
| | | */ |
| | | private boolean isInGroupAndSatisfaction(OrderItemDto orderItemDto, List<OrderCouponGroup> cartList) { |
| | | boolean result = false; |
| | | for (OrderCouponGroup cartVo : cartList) { |
| | | if (cartVo.isSatisfactionCoupon() && cartVo.getOrderItemDtos().contains(orderItemDto)) { |
| | | result = true; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 购物车条目在组中,但是组中产品没有达到优惠条件 |
| | | * @param cartList |
| | | * @return |
| | | */ |
| | | private boolean isInGroupNotSatisfaction(OrderItemDto orderItemDto, List<OrderCouponGroup> cartList) { |
| | | boolean result = false; |
| | | for (OrderCouponGroup cartVo : cartList) { |
| | | if (!cartVo.isSatisfactionCoupon() && cartVo.getOrderItemDtos().contains(orderItemDto)) { |
| | | result = true; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 删除购物车条目所在分组中的引用 |
| | | * |
| | | * @param cartList |
| | | */ |
| | | private void removeNotSatisfaction(OrderItemDto orderItemDto, List<OrderCouponGroup> cartList) { |
| | | for (OrderCouponGroup cartVo : cartList) { |
| | | if (cartVo.getOrderItemDtos().remove(orderItemDto)) { |
| | | LogUtil.debug("删除购物车所在组" + cartVo.getCoupon().getCName() + "," + orderItemDto.getProductId()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 计算购物车价格和优惠信息 |
| | | * |
| | | * @author JIANGYOUYAO |
| | | * @email 935090232@qq.com |
| | | * @date 2019年8月27日 |
| | | */ |
| | | private void countPrice(OrderCouponGroup orderCouponGroup) { |
| | | List<OrderItemDto> orderItemDtoList = orderCouponGroup.getOrderItemDtos(); |
| | | // 计算总价 |
| | | BigDecimal sum = BigDecimal.ZERO; |
| | | //抵扣总积分 |
| | | BigDecimal scoreSum = BigDecimal.ZERO; |
| | | |
| | | for (OrderItemDto orderCouponElement : orderItemDtoList) { |
| | | if(ShopShoppingCart.CAR_TYPE_MICRO==orderCouponElement.getPayType()){ |
| | | //直接购买 |
| | | sum = sum.add(orderCouponElement.getShopSku().getPrice().multiply(BigDecimal.valueOf(orderCouponElement.getCount()))); |
| | | |
| | | }else if(ShopShoppingCart.CAR_TYPE_SCORE==orderCouponElement.getPayType()){ |
| | | //积分兑换 |
| | | sum = sum.add(orderCouponElement.getShopSku().getScorePrice().multiply(BigDecimal.valueOf(orderCouponElement.getCount()))); |
| | | scoreSum = scoreSum.add(new BigDecimal(orderCouponElement.getShopSku().getScoreCount() * orderCouponElement.getCount())); |
| | | }else{ |
| | | throw new GlobleException("参数错误"); |
| | | } |
| | | } |
| | | |
| | | if (orderCouponGroup.getCoupon() != null) { |
| | | // 存在优惠券 |
| | | if (sum.compareTo(orderCouponGroup.getCoupon().getMinAmount()) >= 0) { |
| | | //标记为合理分组 |
| | | orderCouponGroup.setSatisfactionCoupon(true); |
| | | if (sum.compareTo(orderCouponGroup.getCoupon().getMinAmount()) >= 0) { |
| | | orderCouponGroup.setSubtotal(sum.subtract(orderCouponGroup.getCoupon().getOffsetAmount())); |
| | | orderCouponGroup.setSrcPrice(sum); |
| | | orderCouponGroup.setCouponPrice(orderCouponGroup.getCoupon().getOffsetAmount()); |
| | | orderCouponGroup.setMsg(orderCouponGroup.getCoupon().getCName() + ",已优惠" |
| | | + orderCouponGroup.getCoupon().getOffsetAmount().stripTrailingZeros().toPlainString() + "元"); |
| | | } |
| | | } |
| | | if (sum.compareTo(orderCouponGroup.getCoupon().getMinAmount()) < 0) { |
| | | orderCouponGroup.setSatisfactionCoupon(false); |
| | | orderCouponGroup.setSubtotal(sum); |
| | | orderCouponGroup.setSrcPrice(sum); |
| | | orderCouponGroup.setMsg(orderCouponGroup.getCoupon().getCName()); |
| | | if (sum.doubleValue() > 0) { |
| | | orderCouponGroup.setMsg(orderCouponGroup.getCoupon().getCName() + ",再买" |
| | | + (orderCouponGroup.getCoupon().getMinAmount().subtract(sum)).stripTrailingZeros() |
| | | .toPlainString() |
| | | + "元立减" + orderCouponGroup.getCoupon().getOffsetAmount().stripTrailingZeros().toPlainString() |
| | | + "元"); |
| | | } |
| | | } |
| | | } else { |
| | | orderCouponGroup.setSubtotal(sum); |
| | | orderCouponGroup.setSrcPrice(sum); |
| | | orderCouponGroup.setSatisfactionCoupon(true); |
| | | } |
| | | orderCouponGroup.setScorePay(scoreSum); |
| | | } |
| | | |
| | | } |