满减优惠问题相关处理,秒杀商品打开页面异常问题处理

This commit is contained in:
Chopper 2021-08-25 20:58:09 +08:00
parent d4911d1a32
commit a971066909
21 changed files with 615 additions and 237 deletions

View File

@ -0,0 +1,202 @@
package cn.lili.event.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.SnowFlake;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.event.TradeEvent;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.member.entity.enums.PointTypeEnum;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.enums.*;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.dos.OrderLog;
import cn.lili.modules.order.trade.service.OrderLogService;
import cn.lili.modules.promotion.service.MemberCouponService;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.MqOrderTagsEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 订单状态处理类
*
* @author Chopper
* @since 2020-07-03 11:20
**/
@Slf4j
@Service
public class FullDiscountExecute implements TradeEvent, OrderStatusChangeEvent {
@Autowired
private Cache cache;
@Autowired
private MemberService memberService;
@Autowired
private OrderService orderService;
@Autowired
private OrderItemService orderItemService;
@Autowired
private OrderLogService orderLogService;
@Autowired
private MemberCouponService memberCouponService;
@Autowired
private GoodsSkuService goodsSkuService;
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Override
public void orderCreate(TradeDTO tradeDTO) {
tradeDTO.getCartList().forEach(
cartVO -> {
//有满减优惠则记录信息
if (cartVO.getGiftList() != null && cartVO.getGiftList().size() > 0
&& cartVO.getGiftPoint() != null && cartVO.getGiftPoint() > 0
&& cartVO.getGiftCouponList() != null && cartVO.getGiftCouponList().size() > 0) {
cache.put(CachePrefix.ORDER.getPrefix() + cartVO.getSn(), cartVO);
}
}
);
}
@Override
public void orderChange(OrderMessage orderMessage) {
System.out.println(CachePrefix.ORDER.getPrefix() + orderMessage.getOrderSn());
if (orderMessage.getNewStatus().equals(OrderStatusEnum.PAID)) {
renderGift((CartVO) cache.get(CachePrefix.ORDER.getPrefix() + orderMessage.getOrderSn()), orderMessage);
}
}
/**
* 渲染优惠券信息
*/
private void renderGift(CartVO cartVO, OrderMessage orderMessage) {
//没有优惠信息则跳过
if (cartVO == null) {
return;
}
Order order = orderService.getBySn(orderMessage.getOrderSn());
//赠送积分判定
try {
if (cartVO.getGiftPoint() != null && cartVO.getGiftPoint() > 0) {
memberService.updateMemberPoint(cartVO.getGiftPoint().longValue(), PointTypeEnum.INCREASE.name(),
order.getMemberId(), "订单满优惠赠送积分" + cartVO.getGiftPoint());
}
} catch (Exception e) {
log.error("订单赠送积分异常", e);
}
try {
//优惠券判定
if (cartVO.getGiftCouponList() != null && cartVO.getGiftCouponList().size() > 0) {
cartVO.getGiftCouponList().forEach(couponId -> {
memberCouponService.receiveCoupon(couponId, order.getMemberId(), order.getMemberName());
});
}
} catch (Exception e) {
log.error("订单赠送优惠券异常", e);
}
try {
//赠品潘迪ing
if (cartVO.getGiftList() != null && cartVO.getGiftList().size() > 0) {
generatorGiftOrder(cartVO.getGiftList(), cartVO, order);
}
} catch (Exception e) {
log.error("订单赠送赠品异常", e);
}
}
/**
* 生成赠品订单
*
* @param skuIds 赠品sku信息
* @param cartVO 购物车信息
* @param originOrder 赠品原订单信息
*/
private void generatorGiftOrder(List<String> skuIds, CartVO cartVO, Order originOrder) {
List<OrderItem> orderItems = new ArrayList<>();
List<OrderLog> orderLogs = new ArrayList<>();
Order order = new Order();
PriceDetailDTO priceDetailDTO = new PriceDetailDTO();
BeanUtil.copyProperties(originOrder, order, "id");
BeanUtil.copyProperties(priceDetailDTO, order, "id");
order.setSn(SnowFlake.createStr("G"));
order.setOrderType(OrderPromotionTypeEnum.GIFT.name());
order.setOrderStatus(OrderStatusEnum.UNPAID.name());
order.setPayStatus(PayStatusEnum.UNPAID.name());
order.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name());
order.setNeedReceipt(false);
order.setPriceDetailDTO(priceDetailDTO);
order.setClientType(originOrder.getClientType());
String message = "赠品订单[" + order.getSn() + "]创建";
orderLogs.add(new OrderLog(order.getSn(), originOrder.getMemberId(), UserEnums.MEMBER.name(), originOrder.getMemberName(), message));
for (String skuId : skuIds) {
GoodsSku goodsSkuByIdFromCache = goodsSkuService.getGoodsSkuByIdFromCache(skuId);
OrderItem orderItem = new OrderItem();
BeanUtil.copyProperties(goodsSkuByIdFromCache, orderItem, "id");
BeanUtil.copyProperties(priceDetailDTO, orderItem, "id");
orderItem.setAfterSaleStatus(OrderItemAfterSaleStatusEnum.NEW.name());
orderItem.setCommentStatus(CommentStatusEnum.NEW.name());
orderItem.setComplainStatus(OrderComplaintStatusEnum.NEW.name());
orderItem.setNum(1);
orderItem.setOrderSn(order.getSn());
orderItem.setImage(goodsSkuByIdFromCache.getThumbnail());
orderItem.setGoodsName(goodsSkuByIdFromCache.getGoodsName());
orderItem.setSkuId(goodsSkuByIdFromCache.getId());
orderItem.setCategoryId(goodsSkuByIdFromCache.getCategoryPath().substring(
goodsSkuByIdFromCache.getCategoryPath().lastIndexOf(",") + 1
));
orderItem.setGoodsPrice(goodsSkuByIdFromCache.getPrice());
orderItem.setPriceDetailDTO(priceDetailDTO);
orderItems.add(orderItem);
}
orderService.save(order);
orderItemService.saveBatch(orderItems);
orderLogService.saveBatch(orderLogs);
//发送订单已付款消息
OrderMessage orderMessage = new OrderMessage();
orderMessage.setOrderSn(order.getSn());
orderMessage.setPaymentMethod(order.getPaymentMethod());
orderMessage.setNewStatus(OrderStatusEnum.PAID);
String destination = rocketmqCustomProperties.getOrderTopic() + ":" + MqOrderTagsEnum.STATUS_CHANGE.name();
//发送订单变更mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(orderMessage), RocketmqSendCallbackBuilder.commonCallback());
}
}

View File

@ -45,6 +45,19 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt messageExt) {
try {
this.orderStatusEvent(messageExt);
} catch (Exception e) {
log.error("订单状态变更事件调用异常", e);
}
}
/**
* 订单状态变更
* @param messageExt
*/
public void orderStatusEvent(MessageExt messageExt) {
switch (MqOrderTagsEnum.valueOf(messageExt.getTags())) {
//订单创建
case ORDER_CREATE:
@ -86,5 +99,4 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
break;
}
}
}

View File

@ -468,7 +468,11 @@ public enum CachePrefix {
/**
* 店铺分类
*/
STORE_CATEGORY;
STORE_CATEGORY,
/**
* 订单暂时缓存
*/
ORDER;
public static String removePrefix(String str) {

View File

@ -17,7 +17,7 @@ public enum ResultCode {
/**
* 失败返回码
*/
ERROR(400, "服务器繁忙,请稍后重试"),
ERROR(400, "业务异常,请核对问题后进行重试"),
/**
* 失败返回码
@ -296,7 +296,7 @@ public enum ResultCode {
FULL_DISCOUNT_NOT_EXIST_ERROR(43004, "当前要操作的满优惠活动不存在!"),
FULL_DISCOUNT_WAY_ERROR(43005, "请选择一种优惠方式!"),
FULL_DISCOUNT_GIFT_ERROR(43006, "请选择赠品!"),
FULL_DISCOUNT_COUPON_TIME_ERROR(43007, "赠送的优惠券有效时间必须大于活动时间"),
FULL_DISCOUNT_COUPON_TIME_ERROR(43007, "赠送的优惠券有效时间必须在活动时间之内"),
FULL_DISCOUNT_MONEY_ERROR(43008, "请填写满减金额"),
FULL_DISCOUNT_MONEY_GREATER_THAN_MINUS(43009, "满减金额不能大于优惠门槛"),
FULL_RATE_NUM_ERROR(43010, "请填写打折数值"),

View File

@ -159,6 +159,23 @@ public class StringUtils extends StrUtil {
Matcher m = p.matcher(str);
return m.replaceAll("").trim();
}
/**
* double 转价格字符串
*
* @return
*/
public static String toFen(Double doubleValue) {
String str = doubleValue.toString();
if (!str.contains(".")) {
str = str + ".00";
} else if (str.substring(str.indexOf(".")).length() == 2) {
str = str + "0";
}
return str;
}
}

View File

@ -9,6 +9,8 @@ import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.entity.vo.PriceDetailVO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.vos.MemberCouponVO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -88,6 +90,15 @@ public class TradeDTO implements Serializable {
*/
private Map<String, MemberCouponDTO> storeCoupons;
/**
* 可用优惠券列表
*/
private List<MemberCoupon> canUseCoupons;
/**
* 无法使用优惠券无法使用的原因
*/
private List<MemberCouponVO> cantUseCoupons;
/**
* 收货地址
@ -120,13 +131,16 @@ public class TradeDTO implements Serializable {
private List<OrderVO> orderVO;
public TradeDTO(CartTypeEnum cartTypeEnum) {
this.cartTypeEnum = cartTypeEnum;
this.skuList = new ArrayList<>();
this.cartList = new ArrayList<>();
this.skuPromotionDetail = new HashMap<>();
this.storeCoupons = new HashMap<>();
this.storeCoupons = new HashMap<>();
this.priceDetailDTO = new PriceDetailDTO();
this.cartTypeEnum = cartTypeEnum;
this.cantUseCoupons = new ArrayList<>();
this.canUseCoupons = new ArrayList<>();
this.needReceipt = false;
}

View File

@ -23,23 +23,6 @@ import java.util.stream.Collectors;
@Service
public class CartPriceRender implements CartRenderStep {
/**
* 商品分类
*/
@Autowired
private CategoryService categoryService;
/**
* 积分商品
*/
@Autowired
private PointsGoodsService pointsGoodsService;
/**
* 砍价商品
*/
@Autowired
private KanjiaActivityGoodsService kanjiaActivityGoodsService;
@Override
public RenderStepEnums step() {
return RenderStepEnums.CART_PRICE;

View File

@ -2,6 +2,7 @@ package cn.lili.modules.order.cart.render.impl;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.order.cart.entity.dto.MemberCouponDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.RenderStepEnums;
@ -10,11 +11,16 @@ import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.order.cart.render.util.PromotionPriceUtil;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.enums.CouponScopeTypeEnum;
import cn.lili.modules.promotion.entity.enums.CouponTypeEnum;
import cn.lili.modules.promotion.entity.vos.MemberCouponVO;
import cn.lili.modules.promotion.service.MemberCouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 购物促销信息渲染实现
@ -33,12 +39,136 @@ public class CouponRender implements CartRenderStep {
@Autowired
private PromotionPriceUtil promotionPriceUtil;
@Autowired
private MemberCouponService memberCouponService;
@Override
public void render(TradeDTO tradeDTO) {
//优惠券列表
renderCouponRule(tradeDTO);
//主要渲染各个优惠的价格
this.renderCoupon(tradeDTO);
}
/**
* 渲染优惠券规则
*/
private void renderCouponRule(TradeDTO tradeDTO) {
List<MemberCoupon> memberCouponList = memberCouponService.getMemberCoupons();
memberCouponList.forEach(memberCoupon -> {
available(tradeDTO, memberCoupon);
});
}
/**
* 判定优惠券是否可用
*
* @param tradeDTO
* @param memberCoupon
*/
private void available(TradeDTO tradeDTO, MemberCoupon memberCoupon) {
if (memberCoupon == null) {
return;
}
List<CartSkuVO> filterSku = filterSkuVo(tradeDTO.getSkuList(), memberCoupon);
if (filterSku == null || filterSku.size() == 0) {
tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon,
"购物车中没有满足优惠券使用范围的优惠券"));
return;
}
List<PriceDetailDTO> priceDetailDTOS =
filterSku.stream().map(CartSkuVO::getPriceDetailDTO).collect(Collectors.toList());
PriceDetailDTO totalPrice = new PriceDetailDTO();
totalPrice.accumulationPriceDTO(priceDetailDTOS);
//满足条件判定
if (totalPrice.getGoodsPrice() >= memberCoupon.getConsumeThreshold()) {
tradeDTO.getCanUseCoupons().add(memberCoupon);
} else {
tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon,
"优惠券使用门槛不足,还差" +
StringUtils.toFen(CurrencyUtil.sub(memberCoupon.getConsumeThreshold(), totalPrice.getGoodsPrice())) +
""));
}
}
/**
* 过滤购物车商品信息按照优惠券的适用范围过滤
*
* @param cartSkuVOS
* @param memberCoupon
* @return
*/
private List<CartSkuVO> filterSkuVo(List<CartSkuVO> cartSkuVOS, MemberCoupon memberCoupon) {
List<CartSkuVO> filterSku;
//平台店铺过滤
if (memberCoupon.getIsPlatform()) {
filterSku = cartSkuVOS;
} else {
filterSku = cartSkuVOS.stream().filter(cartSkuVO -> {
return cartSkuVO.getStoreId().equals(memberCoupon.getStoreId());
}).collect(Collectors.toList());
}
if (filterSku == null || filterSku.size() == 0) {
return null;
}
//优惠券类型判定
switch (CouponScopeTypeEnum.valueOf(memberCoupon.getScopeType())) {
case ALL:
return filterSku;
case PORTION_GOODS:
//按照商品过滤
filterSku = filterSku.stream().filter(cartSkuVO -> {
return memberCoupon.getScopeId().indexOf(cartSkuVO.getGoodsSku().getId()) > 0;
}).collect(Collectors.toList());
break;
case PORTION_SHOP_CATEGORY:
//按照店铺分类过滤
filterSku = filterSku.stream().filter(cartSkuVO -> {
if (StringUtils.isNotEmpty(cartSkuVO.getGoodsSku().getStoreCategoryPath())) {
//获取店铺分类
String[] storeCategoryPath = cartSkuVO.getGoodsSku().getStoreCategoryPath().split(",");
for (String category : storeCategoryPath) {
//店铺分类只要有一项吻合即可返回true
if (memberCoupon.getScopeId().indexOf(category) > 0) {
return true;
}
}
return false;
} else {
return false;
}
}).collect(Collectors.toList());
break;
case PORTION_GOODS_CATEGORY:
//按照店铺分类过滤
filterSku = filterSku.stream().filter(cartSkuVO -> {
//平台分类获取
String[] categoryPath = cartSkuVO.getGoodsSku().getCategoryPath().split(",");
//平台三级分类
String categoryId = categoryPath[categoryPath.length - 1];
if (memberCoupon.getScopeId().indexOf(categoryId) > 0) {
return true;
}
return false;
}).collect(Collectors.toList());
break;
default:
return null;
}
return filterSku;
}
/**
* 渲染优惠券
*

View File

@ -9,6 +9,7 @@ import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.order.cart.render.util.PromotionPriceUtil;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.service.FullDiscountService;
import org.springframework.beans.factory.annotation.Autowired;
@ -79,6 +80,11 @@ public class FullDiscountRender implements CartRenderStep {
if (fullDiscount.getIsFullMinus()) {
promotionPriceUtil.recountPrice(tradeDTO, skuPriceDetail, fullDiscount.getFullMinus(), PromotionTypeEnum.FULL_DISCOUNT);
}
//打折
else if (fullDiscount.getIsFullRate()) {
this.renderFullRate(cart, skuPriceDetail, CurrencyUtil.div(fullDiscount.getFullRate(), 10));
}
//渲染满优惠
renderFullMinus(cart);
}
}
@ -89,6 +95,35 @@ public class FullDiscountRender implements CartRenderStep {
}
/**
* 渲染满折
*
* @param cart
* @param skuPriceDetail
*/
private void renderFullRate(CartVO cart, Map<String, Double> skuPriceDetail, Double rate) {
List<CartSkuVO> cartSkuVOS = cart.getSkuList().stream().filter(cartSkuVO -> {
return skuPriceDetail.containsKey(cartSkuVO.getGoodsSku().getId());
}).collect(Collectors.toList());
// 循环计算扣减金额
cartSkuVOS.forEach(cartSkuVO -> {
PriceDetailDTO priceDetailDTO = cartSkuVO.getPriceDetailDTO();
//优惠金额=旧的优惠金额+商品金额*商品折扣比例
priceDetailDTO.setDiscountPrice(
CurrencyUtil.add(priceDetailDTO.getDiscountPrice(),
CurrencyUtil.mul(priceDetailDTO.getGoodsPrice(),
CurrencyUtil.sub(1, rate)
)
)
);
});
}
/**
* 获取参与满优惠的商品id
*
@ -153,8 +188,6 @@ public class FullDiscountRender implements CartRenderStep {
* @return 是否满足满优惠
*/
private boolean isFull(Double price, CartVO cart) {
if (cart.getFullDiscount().getFullMoney() <= price) {
cart.setPromotionNotice("正在参与满优惠活动(" + cart.getFullDiscount().getPromotionName() + "" + cart.getFullDiscount().notice());
return true;

View File

@ -2,16 +2,9 @@ package cn.lili.modules.order.cart.render.util;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.promotion.service.KanjiaActivityGoodsService;
import cn.lili.modules.promotion.service.PointsGoodsService;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import cn.lili.modules.promotion.service.SeckillApplyService;
import cn.lili.modules.search.service.EsGoodsSearchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
@ -28,38 +21,6 @@ import java.util.Map;
@Slf4j
public class PromotionPriceUtil {
/**
* ES商品
*/
@Autowired
private EsGoodsSearchService goodsSearchService;
/**
* 秒杀活动申请
*/
@Autowired
private SeckillApplyService seckillApplyService;
/**
* 促销商品
*/
@Autowired
private PromotionGoodsService promotionGoodsService;
/**
* 规格商品
*/
@Autowired
private GoodsSkuService goodsSkuService;
/**
* 积分商品
*/
@Autowired
private PointsGoodsService pointsGoodsService;
/**
* 积分商品
*/
@Autowired
private KanjiaActivityGoodsService kanjiaActivityGoodsService;
/**
* 重新计算购物车价格
*
@ -160,67 +121,6 @@ public class PromotionPriceUtil {
}
// /**
// * 计算积分商品
// * 积分商品的购买金额是0
// * 1.根据SkuId去查询积分商品Mongo
// * 2.计算积分商品的优惠信息
// *
// * @param tradeSkuList 交易商品促销金额列表
// * @return 计算结果
// */
// private List<GoodsSkuPromotionPriceDTO> pointGoodsPromotion(List<PromotionPriceParamDTO> tradeSkuList) {
// List<GoodsSkuPromotionPriceDTO> priceDTOList = new ArrayList<>();
// //获取积分商品SkuId
// String skuId = tradeSkuList.get(0).getSkuId();
// //获取积分商品VO
// PointsGoodsVO pointsGoodsVO = pointsGoodsService.getPointsGoodsVOByMongo(skuId);
// //参与计算的缓存中的商品SKU列表
// GoodsSku goodsSku = pointsGoodsVO.getGoodsSku();
// //获取商品促销金额
// GoodsSkuPromotionPriceDTO goodsSkuPromotionPrice = new GoodsSkuPromotionPriceDTO(goodsSku, tradeSkuList.get(0).getNum());
// //计算商品原价=原价*数量
// goodsSkuPromotionPrice.setTotalOriginalPrice(CurrencyUtil.mul(goodsSkuPromotionPrice.getOriginalPrice(), goodsSkuPromotionPrice.getNumber()));
// //计算商品积分数量=兑换积分*数量
// goodsSkuPromotionPrice.setTotalPoints(pointsGoodsVO.getPoints() * Convert.toLong(goodsSkuPromotionPrice.getNumber()));
// //优惠金额=商品原价*数量
// goodsSkuPromotionPrice.setTotalDiscountPrice(CurrencyUtil.mul(goodsSkuPromotionPrice.getOriginalPrice(), goodsSkuPromotionPrice.getNumber()));
// //购买价格=积分商品价格为 0
// goodsSkuPromotionPrice.setTotalFinalePrice(0.0);
// priceDTOList.add(goodsSkuPromotionPrice);
// return priceDTOList;
// }
//
// /**
// * 计算砍价商品
// * 砍价商品只能购买一件
// * 1.根据SkuId去查询积分商品Mongo
// * 2.计算积分商品的优惠信息
// *
// * @param tradeSkuList 交易商品促销金额列表
// * @return 计算结果
// */
// private List<GoodsSkuPromotionPriceDTO> kanjiaPromotion(List<PromotionPriceParamDTO> tradeSkuList) {
// List<GoodsSkuPromotionPriceDTO> priceDTOList = new ArrayList<>();
// //获取积分商品SkuId
// String skuId = tradeSkuList.get(0).getSkuId();
// //获取积分商品VO
// KanjiaActivityGoodsDTO kanjiaActivityGoodsDTO = kanjiaActivityGoodsService.getKanJiaGoodsBySku(skuId);
//
// //参与计算的缓存中的商品SKU列表
// GoodsSku goodsSku = kanjiaActivityGoodsDTO.getGoodsSku();
// GoodsSkuPromotionPriceDTO goodsSkuPromotionPrice = new GoodsSkuPromotionPriceDTO(goodsSku, tradeSkuList.get(0).getNum());
// //优惠金额=商品原价-购买价格
// goodsSkuPromotionPrice.setTotalDiscountPrice(CurrencyUtil.sub(goodsSkuPromotionPrice.getOriginalPrice(), kanjiaActivityGoodsDTO.getPurchasePrice()));
// //购买价格=砍价成交金额
// goodsSkuPromotionPrice.setTotalFinalePrice(kanjiaActivityGoodsDTO.getPurchasePrice());
// //原价
// goodsSkuPromotionPrice.setTotalOriginalPrice(goodsSkuPromotionPrice.getOriginalPrice());
// priceDTOList.add(goodsSkuPromotionPrice);
// return priceDTOList;
// }
/**
* 检查活动有效时间
*

View File

@ -8,37 +8,25 @@ import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
import cn.lili.trigger.util.DelayQueueTools;
import cn.lili.trigger.enums.DelayTypeEnums;
import cn.lili.trigger.message.PintuanOrderMessage;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import cn.lili.rocketmq.tags.MqOrderTagsEnum;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.trigger.interfaces.TimeTrigger;
import cn.lili.trigger.model.TimeExecuteConstant;
import cn.lili.trigger.model.TimeTriggerMsg;
import cn.lili.modules.system.utils.OperationalJudgment;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.member.entity.dto.MemberAddressDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.order.aop.OrderLogPoint;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dos.Receipt;
import cn.lili.modules.order.order.entity.dto.*;
import cn.lili.modules.order.order.entity.dto.OrderBatchDeliverDTO;
import cn.lili.modules.order.order.entity.dto.OrderExportDTO;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
import cn.lili.modules.order.order.entity.enums.*;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
@ -56,9 +44,21 @@ import cn.lili.modules.promotion.entity.dos.Pintuan;
import cn.lili.modules.promotion.service.PintuanService;
import cn.lili.modules.statistics.model.dto.StatisticsQueryParam;
import cn.lili.modules.statistics.util.StatisticsDateUtil;
import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.modules.system.entity.vo.Traces;
import cn.lili.modules.system.service.LogisticsService;
import cn.lili.modules.system.utils.OperationalJudgment;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import cn.lili.rocketmq.tags.MqOrderTagsEnum;
import cn.lili.trigger.enums.DelayTypeEnums;
import cn.lili.trigger.interfaces.TimeTrigger;
import cn.lili.trigger.message.PintuanOrderMessage;
import cn.lili.trigger.model.TimeExecuteConstant;
import cn.lili.trigger.model.TimeTriggerMsg;
import cn.lili.trigger.util.DelayQueueTools;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@ -77,7 +77,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 子订单业务层实现
@ -185,8 +187,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
orderItemService.saveBatch(orderItems);
//批量记录订单操作日志
orderLogService.saveBatch(orderLogs);
//赠品根据店铺单独生成订单
this.generatorGiftOrder(tradeDTO);
}
@Override
@ -733,79 +733,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
}
/**
* 生成赠品订单
*
* @param tradeDTO 生成订单所需参数
*/
private void generatorGiftOrder(TradeDTO tradeDTO) {
List<Order> orders = new ArrayList<>(tradeDTO.getCartList().size());
List<OrderItem> orderItems = new ArrayList<>();
List<OrderLog> orderLogs = new ArrayList<>();
for (CartVO cartVO : tradeDTO.getCartList()) {
if (cartVO.getGiftList() != null && !cartVO.getGiftList().isEmpty()) {
Order order = new Order();
PriceDetailDTO priceDetailDTO = new PriceDetailDTO();
BeanUtil.copyProperties(cartVO, order, "id");
BeanUtil.copyProperties(priceDetailDTO, order, "id");
order.setSn(SnowFlake.createStr("G"));
order.setTradeSn(tradeDTO.getSn());
order.setOrderType(OrderPromotionTypeEnum.GIFT.name());
order.setOrderStatus(OrderStatusEnum.UNPAID.name());
order.setPayStatus(PayStatusEnum.UNPAID.name());
order.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name());
order.setMemberId(tradeDTO.getMemberId());
order.setMemberName(tradeDTO.getMemberName());
order.setNeedReceipt(false);
order.setPriceDetailDTO(priceDetailDTO);
order.setClientType(tradeDTO.getClientType());
if (tradeDTO.getMemberAddress() != null) {
order.setConsigneeAddressIdPath(tradeDTO.getMemberAddress().getConsigneeAddressIdPath());
order.setConsigneeAddressPath(tradeDTO.getMemberAddress().getConsigneeAddressPath());
order.setConsigneeDetail(tradeDTO.getMemberAddress().getDetail());
order.setConsigneeMobile(tradeDTO.getMemberAddress().getMobile());
order.setConsigneeName(tradeDTO.getMemberAddress().getName());
}
orders.add(order);
String message = "赠品订单[" + order.getSn() + "]创建";
orderLogs.add(new OrderLog(order.getSn(), UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getRole().getRole(), UserContext.getCurrentUser().getUsername(), message));
for (String giftGoodsId : cartVO.getGiftList()) {
GoodsSku goodsSkuByIdFromCache = goodsSkuService.getGoodsSkuByIdFromCache(giftGoodsId);
OrderItem orderItem = new OrderItem();
BeanUtil.copyProperties(goodsSkuByIdFromCache, orderItem, "id");
BeanUtil.copyProperties(priceDetailDTO, orderItem, "id");
orderItem.setAfterSaleStatus(OrderItemAfterSaleStatusEnum.NEW.name());
orderItem.setCommentStatus(CommentStatusEnum.NEW.name());
orderItem.setComplainStatus(OrderComplaintStatusEnum.NEW.name());
orderItem.setNum(cartVO.getGoodsNum());
orderItem.setOrderSn(order.getSn());
orderItem.setTradeSn(tradeDTO.getSn());
orderItem.setImage(goodsSkuByIdFromCache.getThumbnail());
orderItem.setGoodsName(goodsSkuByIdFromCache.getGoodsName());
orderItem.setSkuId(goodsSkuByIdFromCache.getId());
orderItem.setCategoryId(goodsSkuByIdFromCache.getCategoryPath().substring(
goodsSkuByIdFromCache.getCategoryPath().lastIndexOf(",") + 1
));
orderItem.setGoodsPrice(goodsSkuByIdFromCache.getPrice());
orderItem.setPriceDetailDTO(priceDetailDTO);
orderItems.add(orderItem);
}
}
}
if (!orders.isEmpty()) {
this.saveBatch(orders);
orderItemService.saveBatch(orderItems);
orderLogService.saveBatch(orderLogs);
for (Order order : orders) {
OrderMessage orderMessage = new OrderMessage();
orderMessage.setOrderSn(order.getSn());
orderMessage.setPaymentMethod(PaymentMethodEnum.BANK_TRANSFER.name());
orderMessage.setNewStatus(OrderStatusEnum.PAID);
this.sendUpdateStatusMessage(orderMessage);
}
}
}
/**
* 检查交易信息

View File

@ -72,4 +72,46 @@ public class FullDiscount extends BasePromotion {
@ApiModelProperty(value = "活动说明")
private String description;
public Boolean getIsFullMinus() {
if (isFullMinus == null) {
return false;
}
return isFullMinus;
}
public Boolean getIsFullRate() {
if (isFullRate == null) {
return false;
}
return isFullRate;
}
public Boolean getIsPoint() {
if (isPoint == null) {
return false;
}
return isPoint;
}
public Boolean getIsFreeFreight() {
if (isFreeFreight == null) {
return false;
}
return isFreeFreight;
}
public Boolean getIsGift() {
if (isGift == null) {
return false;
}
return isGift;
}
public Boolean getIsCoupon() {
if (isCoupon == null) {
return false;
}
return isCoupon;
}
}

View File

@ -0,0 +1,29 @@
package cn.lili.modules.promotion.entity.vos;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* MemberCouponVO
*
* @author Chopper
* @version v1.0
* 2021-08-24 14:30
*/
@Data
public class MemberCouponVO extends MemberCoupon {
@ApiModelProperty(value = "无法使用原因")
private String reason;
public MemberCouponVO(MemberCoupon memberCoupon, String reason) {
BeanUtil.copyProperties(memberCoupon, this);
this.reason = reason;
}
public MemberCouponVO(){
}
}

View File

@ -44,6 +44,13 @@ public interface MemberCouponService extends IService<MemberCoupon> {
*/
IPage<MemberCoupon> getMemberCoupons(CouponSearchParams param, PageVO pageVo);
/**
* 获取会员所有优惠券
*
* @return 会员优惠券列表
*/
List<MemberCoupon> getMemberCoupons();
/**
* 获取会员优惠券列表
*

View File

@ -122,6 +122,16 @@ public interface PromotionGoodsService extends IService<PromotionGoods> {
*/
Integer getPromotionGoodsStock(PromotionTypeEnum typeEnum, String promotionId, String skuId);
/**
* 批量获取促销活动商品库存
*
* @param typeEnum 促销商品类型
* @param promotionId 促销活动id
* @param skuId 批量商品skuId
* @return 促销活动商品库存
*/
List<Integer> getPromotionGoodsStock(PromotionTypeEnum typeEnum, String promotionId, List<String> skuId);
/**
* 根据条件获取促销活动商品详情
*
@ -132,6 +142,16 @@ public interface PromotionGoodsService extends IService<PromotionGoods> {
*/
PromotionGoods getPromotionGoods(PromotionTypeEnum typeEnum, String promotionId, String skuId);
/**
* 批量获取促销商品信息
*
* @param typeEnum 促销类型
* @param promotionId 促销活动id
* @param skuId 商品skuId
* @return 促销活动商品详情
*/
List<PromotionGoods> getPromotionGoods(PromotionTypeEnum typeEnum, String promotionId, List<String> skuId);
/**
* 更新促销活动商品库存
*

View File

@ -264,7 +264,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
*/
@Override
public void receiveCoupon(String couponId, Integer receiveNum) {
CouponVO couponVO = checkStatus(couponId);
CouponVO couponVO = this.mongoTemplate.findById(couponId, CouponVO.class);
couponVO.setReceivedNum(couponVO.getReceivedNum() + receiveNum);
LambdaUpdateWrapper<Coupon> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Coupon::getId, couponId);
@ -401,7 +401,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
LambdaQueryWrapper<FullDiscount> queryWrapper = new LambdaQueryWrapper<FullDiscount>().eq(FullDiscount::getIsCoupon, true).eq(FullDiscount::getCouponId, id);
FullDiscount fullDiscount = fullDiscountService.getOne(queryWrapper);
if (fullDiscount != null) {
throw new ServiceException("当前优惠券参与了促销活动 " + fullDiscount.getTitle() + " 不能进行编辑删除操作");
throw new ServiceException("当前优惠券参与了促销活动" + fullDiscount.getPromotionName() + "不能进行编辑删除操作");
}
return coupon;
}

View File

@ -273,10 +273,14 @@ public class FullDiscountServiceImpl extends ServiceImpl<FullDiscountMapper, Ful
if (noGiftSelected) {
throw new ServiceException(ResultCode.FULL_DISCOUNT_GIFT_ERROR);
}
}else{
fullDiscountVO.setGiftId(null);
}
//如果优惠方式是赠优惠券
if (Boolean.TRUE.equals(fullDiscountVO.getIsCoupon())) {
this.checkCoupon(fullDiscountVO.getCouponId(), fullDiscountVO.getEndTime().getTime());
}else{
fullDiscountVO.setCouponId(null);
}
//如果优惠方式是折扣
if (Boolean.TRUE.equals(fullDiscountVO.getIsFullRate())) {
@ -316,9 +320,6 @@ public class FullDiscountServiceImpl extends ServiceImpl<FullDiscountMapper, Ful
throw new ServiceException(ResultCode.COUPON_NOT_EXIST);
}
Coupon coupon = this.couponService.getById(couponId);
if (coupon.getEndTime().getTime() < endTime) {
throw new ServiceException(ResultCode.FULL_DISCOUNT_COUPON_TIME_ERROR);
}
}
/**

View File

@ -86,6 +86,13 @@ public class MemberCouponServiceImpl extends ServiceImpl<MemberCouponMapper, Mem
return this.page(PageUtil.initPage(pageVo), queryWrapper);
}
@Override
public List<MemberCoupon> getMemberCoupons() {
QueryWrapper<MemberCoupon> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("member_id", UserContext.getCurrentUser().getId());
return this.list(queryWrapper);
}
/**
* 获取会员优惠券列表
*

View File

@ -273,18 +273,45 @@ public class PromotionGoodsServiceImpl extends ServiceImpl<PromotionGoodsMapper,
String promotionStockKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(typeEnum, promotionId, skuId);
String promotionGoodsStock = stringRedisTemplate.opsForValue().get(promotionStockKey);
PromotionGoods promotionGoods = this.getPromotionGoods(typeEnum, promotionId, skuId);
if (promotionGoods == null) {
throw new ServiceException(ResultCode.PROMOTION_GOODS_NOT_EXIT);
}
if (promotionGoodsStock != null && CharSequenceUtil.isNotEmpty(promotionGoodsStock) && promotionGoods.getQuantity().equals(Convert.toInt(promotionGoodsStock))) {
//库存如果不为空则直接返回
if (promotionGoodsStock != null && CharSequenceUtil.isNotEmpty(promotionGoodsStock)) {
return Convert.toInt(promotionGoodsStock);
} else {
}
//如果为空
else {
//获取促销商品如果不存在促销商品则返回0
PromotionGoods promotionGoods = this.getPromotionGoods(typeEnum, promotionId, skuId);
if (promotionGoods == null) {
return 0;
}
//否则写入新的促销商品库存
stringRedisTemplate.opsForValue().set(promotionStockKey, promotionGoods.getQuantity().toString());
return promotionGoods.getQuantity();
}
}
@Override
public List<Integer> getPromotionGoodsStock(PromotionTypeEnum typeEnum, String promotionId, List<String> skuId) {
//获取促销商品如果不存在促销商品则返回0
List<PromotionGoods> promotionGoods = this.getPromotionGoods(typeEnum, promotionId, skuId);
//接收数据
List<Integer> result = new ArrayList<>(skuId.size());
for (String sid : skuId) {
Integer stock = null;
for (PromotionGoods pg : promotionGoods) {
if (sid.equals(pg.getSkuId())) {
stock = pg.getQuantity();
}
}
//如果促销商品不存在给一个默认值
if (stock == null) {
stock = 0;
}
result.add(stock);
}
return result;
}
/**
* 根据条件获取促销活动商品详情
*
@ -300,6 +327,22 @@ public class PromotionGoodsServiceImpl extends ServiceImpl<PromotionGoodsMapper,
return this.getOne(queryWrapper);
}
/**
* 根据条件获取促销活动商品详情
*
* @param typeEnum 促销类型
* @param promotionId 促销活动id
* @param skuId 商品skuId
* @return 促销活动商品详情
*/
@Override
public List<PromotionGoods> getPromotionGoods(PromotionTypeEnum typeEnum, String promotionId, List<String> skuId) {
LambdaQueryWrapper<PromotionGoods> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(PromotionGoods::getPromotionType, typeEnum.name()).eq(PromotionGoods::getPromotionId, promotionId)
.in(PromotionGoods::getSkuId, skuId);
return this.list(queryWrapper);
}
/**
* 更新促销活动商品库存
*

View File

@ -135,17 +135,21 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
seckillApplyPage.setCurrent(pageVo.getMongoPageNumber());
seckillApplyPage.setSize(pageVo.getPageSize());
List<SeckillApply> seckillApplyList = seckillVO.getSeckillApplyList() != null ? seckillVO.getSeckillApplyList() : new ArrayList<>();
for (SeckillApply seckillApply : seckillApplyList) {
if (CharSequenceUtil.isNotEmpty(queryParam.getStoreId()) && !seckillApply.getStoreId().equals(queryParam.getStoreId())) {
seckillApplyList.remove(seckillApply);
}
try {
Integer goodsStock = promotionGoodsService.getPromotionGoodsStock(PromotionTypeEnum.SECKILL, seckillApply.getSeckillId(), seckillApply.getSkuId());
seckillApply.setQuantity(goodsStock);
} catch (Exception e) {
log.error("获取促销商品促销失败!", e);
// 如果查询参数店铺id不为空则表示是店铺在查询信息那么这里要对店铺的请求做过滤处理把其他店铺的信息进行移除
seckillApplyList.removeIf(seckillApply -> CharSequenceUtil.isNotEmpty(queryParam.getStoreId()) && !seckillApply.getStoreId().equals(queryParam.getStoreId()));
//获取skuid
List<String> skuIds = seckillApplyList.stream()
.map(SeckillApply::getSkuId).collect(Collectors.toList());
//循环获取 店铺/全平台 参与的促销商品库存进行填充
if (skuIds.size() > 0) {
List<Integer> skuStock = promotionGoodsService.getPromotionGoodsStock(PromotionTypeEnum.SECKILL, seckillVO.getId(), skuIds);
for (int i = 0; i < skuIds.size(); i++) {
seckillApplyList.get(i).setQuantity(skuStock.get(i));
}
}
seckillApplyPage.setTotal(seckillApplyList.size());
List<SeckillApply> page = CollUtil.page(pageVo.getMongoPageNumber(), pageVo.getPageSize(), seckillApplyList);
seckillApplyPage.setRecords(page);

View File

@ -22,6 +22,9 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
AuthUser authUser = UserContext.getCurrentUser();
if (authUser != null) {
this.setFieldValByName("createBy", authUser.getUsername(), metaObject);
}else{
this.setFieldValByName("createBy", "SYSTEM", metaObject);
}
this.setFieldValByName("createTime", new Date(), metaObject);
//有值则写入