初始化代码 2022-02-11前 最新版本

This commit is contained in:
itheinjury@163.com
2022-02-11 19:30:50 +08:00
commit bf8f8d9382
1399 changed files with 165963 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
package cn.lili.event;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
/**
* 售后单改变状态
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface AfterSaleStatusChangeEvent {
/**
* 售后单改变
*
* @param afterSale 售后
*/
void afterSaleStatusChange(AfterSale afterSale);
}

View File

@@ -0,0 +1,18 @@
package cn.lili.event;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
/**
* 订单状态改变事件
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface GoodsCommentCompleteEvent {
/**
* 商品评价
* @param memberEvaluation 会员评价
*/
void goodsComment(MemberEvaluation memberEvaluation);
}

View File

@@ -0,0 +1,19 @@
package cn.lili.event;
import cn.lili.modules.member.entity.dos.Member;
/**
* 会员登录消息
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface MemberLoginEvent {
/**
* 会员登录
*
* @param member 会员
*/
void memberLogin(Member member);
}

View File

@@ -0,0 +1,19 @@
package cn.lili.event;
import cn.lili.modules.member.entity.dto.MemberPointMessage;
/**
* 会员积分改变消息
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface MemberPointChangeEvent {
/**
* 会员积分改变消息
*
* @param memberPointMessage 会员积分消息
*/
void memberPointChange(MemberPointMessage memberPointMessage);
}

View File

@@ -0,0 +1,19 @@
package cn.lili.event;
import cn.lili.modules.member.entity.dos.Member;
/**
* 会员注册消息
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface MemberRegisterEvent {
/**
* 会员注册
*
* @param member 会员
*/
void memberRegister(Member member);
}

View File

@@ -0,0 +1,19 @@
package cn.lili.event;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
/**
* 会员提现消息
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface MemberWithdrawalEvent {
/**
* 会员提现
*
* @param memberWithdrawalMessage 提现对象
*/
void memberWithdrawal(MemberWithdrawalMessage memberWithdrawalMessage);
}

View File

@@ -0,0 +1,18 @@
package cn.lili.event;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
/**
* 订单状态改变事件
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface OrderStatusChangeEvent {
/**
* 订单改变
* @param orderMessage 订单消息
*/
void orderChange(OrderMessage orderMessage);
}

View File

@@ -0,0 +1,20 @@
package cn.lili.event;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
/**
* 订单创建消息
*
* @author Chopper
* @since 2021/2/2 15:15
*/
public interface TradeEvent {
/**
* 订单创建
*
* @param tradeDTO 交易
*/
void orderCreate(TradeDTO tradeDTO);
}

View File

@@ -0,0 +1,85 @@
package cn.lili.event.impl;
import cn.hutool.core.date.DateTime;
import cn.lili.event.AfterSaleStatusChangeEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.distribution.entity.dos.DistributionOrder;
import cn.lili.modules.distribution.entity.enums.DistributionOrderStatusEnum;
import cn.lili.modules.distribution.mapper.DistributionOrderMapper;
import cn.lili.modules.distribution.service.DistributionOrderService;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 分销订单入库
*
* @author Chopper
* @since 2020-07-03 11:20
*/
@Slf4j
@Service
public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDayExecute, AfterSaleStatusChangeEvent {
/**
* 分销订单
*/
@Autowired
private DistributionOrderService distributionOrderService;
/**
* 分销订单持久层
*/
@Resource
private DistributionOrderMapper distributionOrderMapper;
@Override
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
//订单带校验/订单代发货,则记录分销信息
case TAKE:
case UNDELIVERED: {
//记录分销订单
distributionOrderService.calculationDistribution(orderMessage.getOrderSn());
break;
}
case CANCELLED: {
//修改分销订单状态
distributionOrderService.cancelOrder(orderMessage.getOrderSn());
break;
}
default: {
break;
}
}
}
@Override
public void execute() {
//计算分销提佣
distributionOrderMapper.rebate(DistributionOrderStatusEnum.WAIT_BILL.name(), new DateTime());
//修改分销订单状态
distributionOrderService.update(new LambdaUpdateWrapper<DistributionOrder>()
.eq(DistributionOrder::getDistributionOrderStatus, DistributionOrderStatusEnum.WAIT_BILL.name())
.le(DistributionOrder::getSettleCycle, new DateTime())
.set(DistributionOrder::getDistributionOrderStatus, DistributionOrderStatusEnum.WAIT_CASH.name()));
}
@Override
public void afterSaleStatusChange(AfterSale afterSale) {
if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {
distributionOrderService.refundOrder(afterSale.getSn());
}
}
}

View File

@@ -0,0 +1,240 @@
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.entity.enums.GoodsTypeEnum;
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.OrderTagsEnum;
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;
import java.util.stream.Collectors;
/**
* 订单状态处理类
*
* @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().isEmpty())
|| (cartVO.getGiftPoint() != null && cartVO.getGiftPoint() > 0)
|| (cartVO.getGiftCouponList() != null && !cartVO.getGiftCouponList().isEmpty())) {
cache.put(CachePrefix.ORDER.getPrefix() + cartVO.getSn(), JSONUtil.toJsonStr(cartVO));
}
}
);
}
@Override
public void orderChange(OrderMessage orderMessage) {
//如果订单已支付
if (orderMessage.getNewStatus().equals(OrderStatusEnum.PAID)) {
log.debug("满减活动,订单状态操作 {}", CachePrefix.ORDER.getPrefix() + orderMessage.getOrderSn());
renderGift(JSONUtil.toBean(cache.getString(CachePrefix.ORDER.getPrefix() + orderMessage.getOrderSn()), CartVO.class), 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().isEmpty()) {
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().isEmpty()) {
generatorGiftOrder(cartVO.getGiftList(), order);
}
} catch (Exception e) {
log.error("订单赠送赠品异常", e);
}
}
/**
* 生成赠品订单
*
* @param skuIds 赠品sku信息
* @param originOrder 赠品原订单信息
*/
private void generatorGiftOrder(List<String> skuIds, Order originOrder) {
//获取赠品列表
List<GoodsSku> goodsSkus = goodsSkuService.getGoodsSkuByIdFromCache(skuIds);
//赠品判定
if (goodsSkus == null || goodsSkus.isEmpty()) {
log.error("赠品不存在:{}", skuIds);
return;
}
//赠品分类,分为实体商品/虚拟商品/电子卡券
List<GoodsSku> physicalSkus = goodsSkus.stream().filter(goodsSku -> goodsSku.getGoodsType().equals(GoodsTypeEnum.PHYSICAL_GOODS.name())).collect(Collectors.toList());
List<GoodsSku> virtualSkus = goodsSkus.stream().filter(goodsSku -> goodsSku.getGoodsType().equals(GoodsTypeEnum.VIRTUAL_GOODS.name())).collect(Collectors.toList());
List<GoodsSku> eCouponSkus = goodsSkus.stream().filter(goodsSku -> goodsSku.getGoodsType().equals(GoodsTypeEnum.E_COUPON.name())).collect(Collectors.toList());
//如果赠品不为空,则生成对应的赠品订单
if (!physicalSkus.isEmpty()) {
giftOrderHandler(physicalSkus, originOrder, OrderTypeEnum.NORMAL);
}
if (!virtualSkus.isEmpty()) {
giftOrderHandler(virtualSkus, originOrder, OrderTypeEnum.VIRTUAL);
}
if (!eCouponSkus.isEmpty()) {
giftOrderHandler(eCouponSkus, originOrder, OrderTypeEnum.E_COUPON);
}
}
/**
* 赠品订单处理
*
* @param skuList 赠品列表
* @param originOrder 原始订单
* @param orderTypeEnum 订单类型
*/
private void giftOrderHandler(List<GoodsSku> skuList, Order originOrder, OrderTypeEnum orderTypeEnum) {
//初始化订单对象/订单日志/自订单
Order order = new Order();
List<OrderItem> orderItems = new ArrayList<>();
List<OrderLog> orderLogs = new ArrayList<>();
//初始化价格详情
PriceDetailDTO priceDetailDTO = new PriceDetailDTO();
//复制通用属性
BeanUtil.copyProperties(originOrder, order, "id");
BeanUtil.copyProperties(priceDetailDTO, order, "id");
//生成订单参数
order.setSn(SnowFlake.createStr("G"));
order.setOrderPromotionType(OrderPromotionTypeEnum.GIFT.name());
order.setOrderStatus(OrderStatusEnum.UNPAID.name());
order.setPayStatus(PayStatusEnum.PAID.name());
order.setOrderType(orderTypeEnum.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 (GoodsSku goodsSku : skuList) {
OrderItem orderItem = new OrderItem();
BeanUtil.copyProperties(goodsSku, 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(goodsSku.getThumbnail());
orderItem.setGoodsName(goodsSku.getGoodsName());
orderItem.setSkuId(goodsSku.getId());
orderItem.setCategoryId(goodsSku.getCategoryPath().substring(
goodsSku.getCategoryPath().lastIndexOf(",") + 1
));
orderItem.setGoodsPrice(goodsSku.getPrice());
orderItem.setPriceDetailDTO(priceDetailDTO);
orderItems.add(orderItem);
}
//保存订单
orderService.save(order);
orderItemService.saveBatch(orderItems);
orderLogService.saveBatch(orderLogs);
//发送订单已付款消息PS:不在这里处理逻辑是因为期望加交给消费者统一处理库存等等问题)
OrderMessage orderMessage = new OrderMessage();
orderMessage.setOrderSn(order.getSn());
orderMessage.setPaymentMethod(order.getPaymentMethod());
orderMessage.setNewStatus(OrderStatusEnum.PAID);
String destination = rocketmqCustomProperties.getOrderTopic() + ":" + OrderTagsEnum.STATUS_CHANGE.name();
//发送订单变更mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(orderMessage), RocketmqSendCallbackBuilder.commonCallback());
}
}

View File

@@ -0,0 +1,30 @@
package cn.lili.event.impl;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 商品SKU变化
*
* @author Chopper
* @since 2020-07-03 11:20
*/
@Service
public class GoodsSkuExecute implements GoodsCommentCompleteEvent {
/**
* 商品
*/
@Autowired
private GoodsSkuService goodsSkuService;
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
goodsSkuService.updateGoodsSkuCommentNum(memberEvaluation.getSkuId());
}
}

View File

@@ -0,0 +1,25 @@
package cn.lili.event.impl;
import cn.lili.event.MemberLoginEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员自身业务
*
* @author Chopper
* @version v1.0
* 2022-01-11 11:08
*/
@Service
public class MemberExecute implements MemberLoginEvent {
@Autowired
private MemberService memberService;
@Override
public void memberLogin(Member member) {
memberService.updateMemberLoginTime(member.getId());
}
}

View File

@@ -0,0 +1,102 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.entity.enums.PointTypeEnum;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.ExperienceSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 会员经验值
*
* @author Bulbasaur
* @since 2021/5/16 11:16 下午
*/
//@Service
public class MemberExperienceExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent {
/**
* 配置
*/
@Autowired
private SettingService settingService;
/**
* 会员
*/
@Autowired
private MemberService memberService;
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 会员注册赠送经验值
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberPoint(Long.valueOf(experienceSetting.getRegister().longValue()), PointTypeEnum.INCREASE.name(), member.getId(), "会员注册,赠送经验值" + experienceSetting.getRegister());
}
/**
* 商品评价赠送经验值
*
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberPoint(Long.valueOf(experienceSetting.getComment().longValue()), PointTypeEnum.INCREASE.name(), memberEvaluation.getMemberId(), "会员评价,赠送经验值" + experienceSetting.getComment());
}
/**
* 完成订单赠送经验值
*
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
if (orderMessage.getNewStatus().equals(OrderStatusEnum.COMPLETED)) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//计算赠送经验值数量
Double point = CurrencyUtil.mul(experienceSetting.getMoney(), order.getFlowPrice(), 0);
//赠送会员经验值
memberService.updateMemberPoint(point.longValue(), PointTypeEnum.INCREASE.name(), order.getMemberId(), "会员下单,赠送经验值" + point + "");
}
}
/**
* 获取经验值设置
*
* @return 经验值设置
*/
private ExperienceSetting getExperienceSetting() {
Setting setting = settingService.get(SettingEnum.EXPERIENCE_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), ExperienceSetting.class);
}
}

View File

@@ -0,0 +1,156 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.event.AfterSaleStatusChangeEvent;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.entity.enums.PointTypeEnum;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.PointSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员积分
*
* @author Bulbasaur
* @since 2020-07-03 11:20
*/
@Service
public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent, AfterSaleStatusChangeEvent {
/**
* 配置
*/
@Autowired
private SettingService settingService;
/**
* 会员
*/
@Autowired
private MemberService memberService;
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 会员注册赠送积分
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取积分设置
PointSetting pointSetting = getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(pointSetting.getRegister().longValue(), PointTypeEnum.INCREASE.name(), member.getId(), "会员注册,赠送积分" + pointSetting.getRegister() + "");
}
/**
* 会员评价赠送积分
*
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取积分设置
PointSetting pointSetting = getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(pointSetting.getComment().longValue(), PointTypeEnum.INCREASE.name(), memberEvaluation.getMemberId(), "会员评价,赠送积分" + pointSetting.getComment() + "");
}
/**
* 非积分订单订单完成后赠送积分
*
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
case CANCELLED: {
Order order = orderService.getBySn(orderMessage.getOrderSn());
Long point = order.getPriceDetailDTO().getPayPoint();
if (point <= 0) {
return;
}
//如果未付款,则不去要退回相关代码执行
if (order.getPayStatus().equals(PayStatusEnum.UNPAID.name())) {
return;
}
String content = "订单取消,积分返还:" + point + "";
//赠送会员积分
memberService.updateMemberPoint(point, PointTypeEnum.INCREASE.name(), order.getMemberId(), content);
break;
}
case COMPLETED: {
Order order = orderService.getBySn(orderMessage.getOrderSn());
//如果是积分订单 则直接返回
if (StringUtils.isNotEmpty(order.getOrderPromotionType())
&& order.getOrderPromotionType().equals(OrderPromotionTypeEnum.POINTS.name())) {
return;
}
//获取积分设置
PointSetting pointSetting = getPointSetting();
if (pointSetting.getConsumer() == 0) {
return;
}
//计算赠送积分数量
Double point = CurrencyUtil.mul(pointSetting.getConsumer(), order.getFlowPrice(), 0);
//赠送会员积分
memberService.updateMemberPoint(point.longValue(), PointTypeEnum.INCREASE.name(), order.getMemberId(), "会员下单,赠送积分" + point + "");
break;
}
default:
break;
}
}
/**
* 提交售后后扣除积分
*
* @param afterSale 售后
*/
@Override
public void afterSaleStatusChange(AfterSale afterSale) {
if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {
//获取积分设置
PointSetting pointSetting = getPointSetting();
//计算扣除积分数量
Double point = CurrencyUtil.mul(pointSetting.getMoney(), afterSale.getActualRefundPrice(), 0);
//扣除会员积分
memberService.updateMemberPoint(point.longValue(), PointTypeEnum.REDUCE.name(), afterSale.getMemberId(), "会员退款,回退积分" + point + "");
}
}
/**
* 获取积分设置
*
* @return 积分设置
*/
private PointSetting getPointSetting() {
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
}
}

View File

@@ -0,0 +1,27 @@
package cn.lili.event.impl;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.wallet.service.MemberWalletService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员钱包创建
*
* @author Chopper
* @since 2020-07-03 11:20
*/
@Service
public class MemberWalletExecute implements MemberRegisterEvent {
@Autowired
private MemberWalletService memberWalletService;
@Override
public void memberRegister(Member member) {
// 有些情况下会同时创建一个member_id的两条数据
// memberWalletService.save(member.getId(),member.getUsername());
}
}

View File

@@ -0,0 +1,238 @@
package cn.lili.event.impl;
import cn.lili.event.*;
import cn.lili.modules.member.entity.dto.MemberPointMessage;
import cn.lili.modules.member.entity.enums.PointTypeEnum;
import cn.lili.modules.message.entity.dto.NoticeMessageDTO;
import cn.lili.modules.message.entity.enums.NoticeMessageNodeEnum;
import cn.lili.modules.message.entity.enums.NoticeMessageParameterEnum;
import cn.lili.modules.message.service.NoticeMessageService;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.enums.MemberWithdrawalDestinationEnum;
import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* 通知类消息实现
*
* @author Chopper
* @since 2020-07-03 11:20
**/
@Service
public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent, AfterSaleStatusChangeEvent, MemberPointChangeEvent, MemberWithdrawalEvent {
@Autowired
private NoticeMessageService noticeMessageService;
@Autowired
private OrderService orderService;
@Override
public void orderCreate(TradeDTO tradeDTO) {
//订单创建发送订单创建站内信息
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(tradeDTO.getMemberId());
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.ORDER_CREATE_SUCCESS);
Map<String, String> params = new HashMap<>(2);
params.put("goods", tradeDTO.getSkuList().get(0).getGoodsSku().getGoodsName());
noticeMessageDTO.setParameter(params);
//保存站内信
noticeMessageService.noticeMessage(noticeMessageDTO);
}
@Override
public void orderChange(OrderMessage orderMessage) {
//查询订单信息
OrderDetailVO orderDetailVO = orderService.queryDetail(orderMessage.getOrderSn());
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
//如果订单状态不为空
if (orderDetailVO != null) {
Map<String, String> params = new HashMap<>(2);
switch (orderMessage.getNewStatus()) {
//如果订单新的状态为已取消 则发送取消订单站内信
case CANCELLED:
params.put(NoticeMessageParameterEnum.CANCEL_REASON.getType(), orderDetailVO.getOrder().getCancelReason());
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.ORDER_CANCEL_SUCCESS);
break;
//如果订单新的状态为已经支付,则发送支付成功站内信
case PAID:
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.ORDER_PAY_SUCCESS);
break;
//如果订单新的状态为已发货,则发送已发货站内信
case DELIVERED:
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.ORDER_DELIVER);
break;
//如果订单新的状态为已完成,则发送已完成站内信
case COMPLETED:
//订单完成消息
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.ORDER_COMPLETE);
//订单完成也可以进行评价,所以要有评价消息
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.ORDER_EVALUATION);
break;
//如果是拼团订单,发送拼团成功消息
case UNDELIVERED:
if (OrderPromotionTypeEnum.PINTUAN.name().equals(orderDetailVO.getOrder().getOrderPromotionType())) {
//拼团成功消息
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.PINTUAN_SUCCESS);
}
break;
default:
break;
}
noticeMessageDTO.setMemberId(orderDetailVO.getOrder().getMemberId());
//添加站内信参数
params.put(NoticeMessageParameterEnum.GOODS.getType(), orderDetailVO.getOrderItems().get(0).getGoodsName());
noticeMessageDTO.setParameter(params);
//如果有消息,则发送消息
if (noticeMessageDTO.getNoticeMessageNodeEnum() != null) {
//保存站内信
noticeMessageService.noticeMessage(noticeMessageDTO);
}
}
}
@Override
public void afterSaleStatusChange(AfterSale afterSale) {
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(afterSale.getMemberId());
Map<String, String> params = new HashMap<>(2);
params.put("goods", afterSale.getGoodsName());
params.put("refuse", afterSale.getAuditRemark());
noticeMessageDTO.setParameter(params);
//如果售后单是申请中 则发送申请中站内信
if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.APPLY.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.AFTER_SALE_CREATE_SUCCESS);
}
//售后审核同意切退货站内信通知
else if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.PASS.name()) && afterSale.getServiceType().equals(AfterSaleTypeEnum.RETURN_GOODS.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.RETURN_GOODS_PASS);
}
//售后审核拒绝且退货站内信通知
else if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.REFUSE.name()) && afterSale.getServiceType().equals(AfterSaleTypeEnum.RETURN_GOODS.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.RETURN_GOODS_REFUSE);
}
//售后审核同意切退款站内信通知
else if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.PASS.name()) && afterSale.getServiceType().equals(AfterSaleTypeEnum.RETURN_MONEY.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.RETURN_MONEY_PASS);
}
//售后审核拒绝且退款站内信通知
else if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.REFUSE.name()) && afterSale.getServiceType().equals(AfterSaleTypeEnum.RETURN_MONEY.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.RETURN_MONEY_REFUSE);
}
//售后商家确认收货站内信通知
else if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.SELLER_CONFIRM.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.AFTER_SALE_ROG_PASS);
}
//退货物品拒收站内信通知
else if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.SELLER_TERMINATION.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.AFTER_SALE_ROG_REFUSE);
}
//售后完成通知
else if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.AFTER_SALE_COMPLETE);
}
//保存站内信
if (noticeMessageDTO.getNoticeMessageNodeEnum() != null) {
noticeMessageService.noticeMessage(noticeMessageDTO);
}
}
@Override
public void memberPointChange(MemberPointMessage memberPointMessage) {
if (memberPointMessage == null) {
return;
}
//组织站内信参数
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(memberPointMessage.getMemberId());
Map<String, String> params = new HashMap<>(2);
if (memberPointMessage.getType().equals(PointTypeEnum.INCREASE.name())) {
params.put("expenditure_points", "0");
params.put("income_points", memberPointMessage.getPoint().toString());
} else {
params.put("expenditure_points", memberPointMessage.getPoint().toString());
params.put("income_points", "0");
}
noticeMessageDTO.setParameter(params);
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.POINT_CHANGE);
//发送站内通知信息
noticeMessageService.noticeMessage(noticeMessageDTO);
}
@Override
public void memberWithdrawal(MemberWithdrawalMessage memberWithdrawalMessage) {
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(memberWithdrawalMessage.getMemberId());
//如果提现状态为申请则发送申请提现站内消息
if (memberWithdrawalMessage.getStatus().equals(WithdrawStatusEnum.APPLY.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_CREATE);
Map<String, String> params = new HashMap<>(2);
params.put("price", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
//发送提现申请成功消息
noticeMessageService.noticeMessage(noticeMessageDTO);
}
//如果提现状态为通过则发送审核通过站内消息
if (memberWithdrawalMessage.getStatus().equals(WithdrawStatusEnum.VIA_AUDITING.name())) {
//如果提现到余额
if (memberWithdrawalMessage.getDestination().equals(MemberWithdrawalDestinationEnum.WALLET.name())) {
//组织参数
Map<String, String> params = new HashMap<>(2);
params.put("income", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_SUCCESS);
//发送提现成功消息
noticeMessageService.noticeMessage(noticeMessageDTO);
params.put("income", memberWithdrawalMessage.getPrice().toString());
params.put("expenditure", "0");
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_CHANGE);
noticeMessageDTO.setParameter(params);
//发送余额变动消息
noticeMessageService.noticeMessage(noticeMessageDTO);
}
//如果提现到微信
if (memberWithdrawalMessage.getDestination().equals(MemberWithdrawalDestinationEnum.WECHAT.name())) {
Map<String, String> params = new HashMap<>(2);
params.put("income", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_WEICHAT_SUCCESS);
//发送提现成功消息
noticeMessageService.noticeMessage(noticeMessageDTO);
params.put("income", "0");
params.put("expenditure", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_CHANGE);
noticeMessageDTO.setParameter(params);
//发送余额变动消息
noticeMessageService.noticeMessage(noticeMessageDTO);
}
}
//如果提现状态为拒绝则发送审核拒绝站内消息
if (memberWithdrawalMessage.getStatus().equals(WithdrawStatusEnum.FAIL_AUDITING.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_ERROR);
Map<String, String> params = new HashMap<>(2);
params.put("price", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
//发送提现申请成功消息
noticeMessageService.noticeMessage(noticeMessageDTO);
}
}
}

View File

@@ -0,0 +1,55 @@
package cn.lili.event.impl;
import cn.hutool.json.JSONUtil;
import cn.lili.common.utils.BeanUtil;
import cn.lili.event.TradeEvent;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dos.Receipt;
import cn.lili.modules.order.order.entity.vo.OrderVO;
import cn.lili.modules.order.order.entity.vo.ReceiptVO;
import cn.lili.modules.order.order.service.ReceiptService;
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
**/
@Service
public class OrderCreateReceiptExecute implements TradeEvent {
@Autowired
private ReceiptService receiptService;
@Override
public void orderCreate(TradeDTO tradeDTO) {
//根据交易sn查询订单信息
List<OrderVO> orderList = tradeDTO.getOrderVO();
//获取发票信息
ReceiptVO receiptVO = tradeDTO.getReceiptVO();
//如果需要获取发票则保存发票信息
if (Boolean.TRUE.equals(tradeDTO.getNeedReceipt()) && !orderList.isEmpty()) {
List<Receipt> receipts = new ArrayList<>();
for (OrderVO orderVO : orderList) {
Receipt receipt = new Receipt();
BeanUtil.copyProperties(receiptVO, receipt);
receipt.setMemberId(orderVO.getMemberId());
receipt.setMemberName(orderVO.getMemberName());
receipt.setStoreId(orderVO.getStoreId());
receipt.setStoreName(orderVO.getStoreName());
receipt.setOrderSn(orderVO.getSn());
receipt.setReceiptDetail(JSONUtil.toJsonStr(orderVO.getOrderItems()));
receipt.setReceiptPrice(orderVO.getFlowPrice());
receipt.setReceiptStatus(0);
receipts.add(receipt);
}
//保存发票
receiptService.saveBatch(receipts);
}
}
}

View File

@@ -0,0 +1,31 @@
package cn.lili.event.impl;
import cn.lili.event.TradeEvent;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.service.TradeService;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 订单状态处理类
*
* @author Chopper
* @since 2020-07-03 11:20
**/
@Service
public class OrderStatusHandlerExecute implements TradeEvent {
@Autowired
private TradeService tradeService;
@Override
public void orderCreate(TradeDTO tradeDTO) {
//如果订单需要支付金额为0则将订单步入到下一个流程
if (tradeDTO.getPriceDetailDTO().getFlowPrice() <= 0) {
tradeService.payTrade(tradeDTO.getSn(), PaymentMethodEnum.BANK_TRANSFER.name(), "-1");
}
}
}

View File

@@ -0,0 +1,84 @@
package cn.lili.event.impl;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.SpringContextUtil;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.kit.Payment;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 支付
*
* @author Chopper
* @since 2021-03-13 16:58
*/
@Slf4j
@Service
public class PaymentExecute implements OrderStatusChangeEvent {
/**
* 订单
*/
@Autowired
private OrderService orderService;
@Override
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
case CANCELLED:
Order order = orderService.getBySn(orderMessage.getOrderSn());
//如果未付款,则不去要退回相关代码执行
if (order.getPayStatus().equals(PayStatusEnum.UNPAID.name())) {
return;
}
PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(order.getPaymentMethod());
//进行退款操作
switch (paymentMethodEnum) {
case WALLET:
case ALIPAY:
case WECHAT:
//获取支付方式
Payment payment =
(Payment) SpringContextUtil.getBean(paymentMethodEnum.getPlugin());
RefundLog refundLog = RefundLog.builder()
.isRefund(false)
.totalAmount(order.getFlowPrice())
.payPrice(order.getFlowPrice())
.memberId(order.getMemberId())
.paymentName(order.getPaymentMethod())
.afterSaleNo("订单取消")
.orderSn(order.getSn())
.paymentReceivableNo(order.getReceivableNo())
.outOrderNo("AF" + SnowFlake.getIdStr())
.outOrderNo("AF" + SnowFlake.getIdStr())
.refundReason("订单取消")
.build();
payment.cancel(refundLog);
break;
case BANK_TRANSFER:
break;
default:
log.error("订单支付执行异常,订单编号:{}", orderMessage.getOrderSn());
break;
}
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,41 @@
package cn.lili.event.impl;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionsStatusEnum;
import cn.lili.modules.promotion.service.CouponActivityService;
import cn.lili.modules.promotion.tools.PromotionTools;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 注册赠券活动
*
* @author Bulbasaur
* @since 2021/5/24 10:48 上午
*/
@Component
public class RegisteredCouponActivityExecute implements MemberRegisterEvent {
@Autowired
private CouponActivityService couponActivityService;
/**
* 获取进行中的注册赠券的优惠券活动
* 发送注册赠券
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
List<CouponActivity> couponActivities = couponActivityService.list(new QueryWrapper<CouponActivity>()
.eq("coupon_activity_type", CouponActivityTypeEnum.REGISTERED.name())
.and(PromotionTools.queryPromotionStatus(PromotionsStatusEnum.START)));
couponActivityService.registered(couponActivities, member);
}
}

View File

@@ -0,0 +1,372 @@
package cn.lili.event.impl;
import cn.hutool.core.convert.Convert;
import cn.lili.cache.Cache;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.service.GoodsSkuService;
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.enums.PayStatusEnum;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.promotion.entity.dos.KanjiaActivity;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.KanjiaActivityGoodsDTO;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.entity.vos.PointsGoodsVO;
import cn.lili.modules.promotion.service.KanjiaActivityGoodsService;
import cn.lili.modules.promotion.service.KanjiaActivityService;
import cn.lili.modules.promotion.service.PointsGoodsService;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
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 StockUpdateExecute implements OrderStatusChangeEvent {
/**
* 出库失败消息
*/
static String outOfStockMessage = "库存不足,出库失败";
/**
* Redis
*/
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private DefaultRedisScript<Boolean> quantityScript;
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 规格商品
*/
@Autowired
private GoodsSkuService goodsSkuService;
/**
* 促销商品
*/
@Autowired
private PromotionGoodsService promotionGoodsService;
/**
* 缓存
*/
@Autowired
private Cache cache;
@Autowired
private KanjiaActivityService kanjiaActivityService;
@Autowired
private KanjiaActivityGoodsService kanjiaActivityGoodsService;
@Autowired
private PointsGoodsService pointsGoodsService;
@Override
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
case PAID: {
//获取订单详情
OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn());
//库存key 和 扣减数量
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
for (OrderItem orderItem : order.getOrderItems()) {
keys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
int i = -orderItem.getNum();
values.add(Integer.toString(i));
setPromotionStock(keys, values, orderItem);
}
List<Integer> stocks = cache.multiGet(keys);
//如果缓存中不存在存在等量的库存值,则重新写入缓存,防止缓存击穿导致无法下单
checkStocks(stocks, order);
//库存扣除结果
Boolean skuResult = stringRedisTemplate.execute(quantityScript, keys, values.toArray());
//如果库存扣减都成功,则记录成交订单
if (Boolean.TRUE.equals(skuResult)) {
log.info("库存扣减成功,参数为{};{}", keys, values);
//库存确认之后对结构处理
orderService.afterOrderConfirm(orderMessage.getOrderSn());
//成功之后,同步库存
synchroDB(order);
} else {
log.info("库存扣件失败变更缓存key{} 变更缓存value{}", keys, values);
//失败之后取消订单
this.errorOrder(orderMessage.getOrderSn());
}
break;
}
case CANCELLED: {
//获取订单详情
OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn());
//判定是否已支付 并且 非库存不足导致库存回滚 则需要考虑订单库存返还业务
if (order.getOrder().getPayStatus().equals(PayStatusEnum.PAID.name())
&& !order.getOrder().getCancelReason().equals(outOfStockMessage)) {
//库存key 和 还原数量
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
//返还商品库存,促销库存不与返还,不然前台展示层有展示逻辑错误
for (OrderItem orderItem : order.getOrderItems()) {
keys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
int i = orderItem.getNum();
values.add(Integer.toString(i));
}
//批量脚本执行库存回退
Boolean skuResult = stringRedisTemplate.execute(quantityScript, keys, values.toArray());
//返还失败,则记录日志
if (Boolean.FALSE.equals(skuResult)) {
log.error("库存回退异常keys{},回复库存值为: {}", keys, values);
}
rollbackOrderStock(order);
}
break;
}
default:
break;
}
}
/**
* 校验库存是否有效
*
* @param stocks
*/
private void checkStocks(List<Integer> stocks, OrderDetailVO order) {
if (order.getOrderItems().size() == stocks.size()) {
return;
}
initSkuCache(order.getOrderItems());
initPromotionCache(order.getOrderItems());
}
/**
* 缓存中sku库存值不存在时将不存在的信息重新写入一边
*
* @param orderItems
*/
private void initSkuCache(List<OrderItem> orderItems) {
orderItems.forEach(orderItem -> {
//如果不存在
if (!cache.hasKey(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()))) {
//内部会自动写入,这里不需要进行二次处理
goodsSkuService.getStock(orderItem.getSkuId());
}
});
}
/**
* 初始化促销商品缓存
*
* @param orderItems
*/
private void initPromotionCache(List<OrderItem> orderItems) {
//如果促销类型需要库存判定,则做对应处理
orderItems.forEach(orderItem -> {
if (orderItem.getPromotionType() != null) {
//如果此促销有库存概念,则计入
if (PromotionTypeEnum.haveStock(orderItem.getPromotionType())) {
PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType());
String cacheKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId());
switch (promotionTypeEnum) {
case KANJIA:
cache.put(cacheKey, kanjiaActivityGoodsService.getKanjiaGoodsBySkuId(orderItem.getSkuId()).getStock());
return;
case POINTS_GOODS:
cache.put(cacheKey, pointsGoodsService.getPointsGoodsDetailBySkuId(orderItem.getSkuId()).getActiveStock());
return;
case SECKILL:
case PINTUAN:
cache.put(cacheKey, promotionGoodsService.getPromotionGoodsStock(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId()));
return;
default:
break;
}
}
}
});
}
/**
* 订单出库失败
*
* @param orderSn 失败入库订单信息
*/
private void errorOrder(String orderSn) {
orderService.systemCancel(orderSn, outOfStockMessage);
}
/**
* 写入需要更改促销库存的商品
*
* @param keys 缓存key值
* @param values 缓存value值
* @param sku 购物车信息
*/
private void setPromotionStock(List<String> keys, List<String> values, OrderItem sku) {
if (sku.getPromotionType() != null) {
//如果此促销有库存概念,则计入
if (!PromotionTypeEnum.haveStock(sku.getPromotionType())) {
return;
}
PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(sku.getPromotionType());
keys.add(PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, sku.getPromotionId(), sku.getSkuId()));
int i = -sku.getNum();
values.add(Integer.toString(i));
}
}
/**
* 同步库存和促销库存
* <p>
* 需修改DB商品库存、Sku商品库存、活动商品库存
* 1.获取需要修改的Sku列表、活动商品列表
* 2.写入sku商品库存批量修改
* 3.写入促销商品的卖出数量、剩余数量,批量修改
* 4.调用方法修改商品库存
*
* @param order 订单
*/
private void synchroDB(OrderDetailVO order) {
//sku商品
List<GoodsSku> goodsSkus = new ArrayList<>();
//促销商品
List<PromotionGoods> promotionGoods = new ArrayList<>();
//sku库存key 集合
List<String> skuKeys = new ArrayList<>();
//促销库存key 集合
List<String> promotionKey = new ArrayList<>();
//循环订单
for (OrderItem orderItem : order.getOrderItems()) {
skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
GoodsSku goodsSku = new GoodsSku();
goodsSku.setId(orderItem.getSkuId());
goodsSku.setGoodsId(orderItem.getGoodsId());
//如果有促销信息
if (null != orderItem.getPromotionType() && null != orderItem.getPromotionId() && PromotionTypeEnum.haveStock(orderItem.getPromotionType())) {
//如果促销有库存信息
PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType());
//修改砍价商品库存
if (promotionTypeEnum.equals(PromotionTypeEnum.KANJIA)) {
KanjiaActivity kanjiaActivity = kanjiaActivityService.getById(orderItem.getPromotionId());
KanjiaActivityGoodsDTO kanjiaActivityGoodsDTO = kanjiaActivityGoodsService.getKanjiaGoodsDetail(kanjiaActivity.getKanjiaActivityGoodsId());
Integer stock = Integer.parseInt(cache.get(PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId())).toString());
kanjiaActivityGoodsDTO.setStock(stock);
kanjiaActivityGoodsService.updateById(kanjiaActivityGoodsDTO);
//修改积分商品库存
} else if (promotionTypeEnum.equals(PromotionTypeEnum.POINTS_GOODS)) {
PointsGoodsVO pointsGoodsVO = pointsGoodsService.getPointsGoodsDetail(orderItem.getPromotionId());
Integer stock = Integer.parseInt(cache.get(PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId())).toString());
pointsGoodsVO.setActiveStock(stock);
pointsGoodsService.updateById(pointsGoodsVO);
} else {
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
searchParams.setPromotionType(promotionTypeEnum.name());
searchParams.setPromotionId(orderItem.getPromotionId());
searchParams.setSkuId(orderItem.getSkuId());
PromotionGoods pGoods = promotionGoodsService.getPromotionsGoods(searchParams);
//记录需要更新的促销库存信息
promotionKey.add(
PromotionGoodsService.getPromotionGoodsStockCacheKey(
promotionTypeEnum,
orderItem.getPromotionId(), orderItem.getSkuId())
);
if (pGoods != null) {
promotionGoods.add(pGoods);
}
}
}
goodsSkus.add(goodsSku);
}
//批量获取商品库存
List skuStocks = cache.multiGet(skuKeys);
//循环写入商品库存
for (int i = 0; i < skuStocks.size(); i++) {
goodsSkus.get(i).setQuantity(Convert.toInt(skuStocks.get(i).toString()));
}
//批量修改商品库存
goodsSkuService.updateBatchById(goodsSkus);
//促销库存处理
if (!promotionKey.isEmpty()) {
List promotionStocks = cache.multiGet(promotionKey);
for (int i = 0; i < promotionKey.size(); i++) {
promotionGoods.get(i).setQuantity(Convert.toInt(promotionStocks.get(i).toString()));
Integer num = promotionGoods.get(i).getNum();
promotionGoods.get(i).setNum((num != null ? num : 0) + order.getOrder().getGoodsNum());
}
promotionGoodsService.updateBatchById(promotionGoods);
}
//商品库存包含sku库存集合批量更新商品库存相关
goodsSkuService.updateGoodsStuck(goodsSkus);
log.info("订单确认,库存同步:商品信息--{};促销信息---{}", goodsSkus, promotionGoods);
}
/**
* 恢复商品库存
*
* @param order 订单
*/
private void rollbackOrderStock(OrderDetailVO order) {
//sku商品
List<GoodsSku> goodsSkus = new ArrayList<>();
//sku库存key 集合
List<String> skuKeys = new ArrayList<>();
//循环订单
for (OrderItem orderItem : order.getOrderItems()) {
skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
GoodsSku goodsSku = new GoodsSku();
goodsSku.setId(orderItem.getSkuId());
goodsSkus.add(goodsSku);
}
//批量获取商品库存
List skuStocks = cache.multiGet(skuKeys);
//循环写入商品SKU库存
for (int i = 0; i < skuStocks.size(); i++) {
goodsSkus.get(i).setQuantity(Convert.toInt(skuStocks.get(i).toString()));
}
log.info("订单取消,库存还原:{}", goodsSkus);
//批量修改商品库存
goodsSkuService.updateBatchById(goodsSkus);
goodsSkuService.updateGoodsStuck(goodsSkus);
}
}

View File

@@ -0,0 +1,70 @@
package cn.lili.event.impl;
import cn.hutool.core.util.RandomUtil;
import cn.lili.event.OrderStatusChangeEvent;
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.enums.OrderComplaintStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 虚拟商品
*
* @author Bulbasaur
* @since 2021/5/29 9:17 上午
*/
@Component
public class VerificationOrderExecute implements OrderStatusChangeEvent {
@Autowired
private OrderService orderService;
@Autowired
private OrderItemService orderItemService;
@Override
public void orderChange(OrderMessage orderMessage) {
//订单状态为待核验,添加订单添加核验码
if (orderMessage.getNewStatus().equals(OrderStatusEnum.TAKE)) {
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//获取随机数,判定是否存在
String code = getCode(order.getStoreId());
//设置订单验证码
orderService.update(new LambdaUpdateWrapper<Order>()
.set(Order::getVerificationCode, code)
.eq(Order::getSn, orderMessage.getOrderSn()));
//修改虚拟订单货物可以进行售后、投诉
orderItemService.update(new LambdaUpdateWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderMessage.getOrderSn())
.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.NOT_APPLIED)
.set(OrderItem::getCommentStatus, OrderComplaintStatusEnum.NO_APPLY));
}
}
/**
* 获取随机数
* 判断当前店铺下是否使用验证码,如果已使用则重新获取
*
* @param storeId 店铺ID
* @return
*/
private String getCode(String storeId) {
//获取八位验证码
String code = Long.toString(RandomUtil.randomLong(10000000, 99999999));
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<Order>()
.eq(Order::getVerificationCode, code)
.eq(Order::getStoreId, storeId);
if (orderService.getOne(lambdaQueryWrapper) == null) {
return code;
} else {
return this.getCode(storeId);
}
}
}

View File

@@ -0,0 +1,57 @@
package cn.lili.event.impl;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.event.TradeEvent;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.vo.OrderVO;
import cn.lili.modules.wechat.util.WechatMessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 微信消息执行器
*
* @author Chopper
* @version v1.0
* 2021-04-19 14:25
*/
@Slf4j
@Service
public class WechatMessageExecute implements OrderStatusChangeEvent, TradeEvent {
@Autowired
private WechatMessageUtil wechatMessageUtil;
@Override
public void orderCreate(TradeDTO tradeDTO) {
for (OrderVO orderVO : tradeDTO.getOrderVO()) {
try {
wechatMessageUtil.sendWechatMessage(orderVO.getSn());
} catch (Exception e) {
log.error("微信消息发送失败:" + orderVO.getSn(), e);
}
}
}
@Override
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
case PAID:
case UNDELIVERED:
case DELIVERED:
case COMPLETED:
try {
wechatMessageUtil.sendWechatMessage(orderMessage.getOrderSn());
} catch (Exception e) {
log.error("微信消息发送失败", e);
}
break;
default:
break;
}
}
}