初始化代码 2022-02-11前 最新版本
This commit is contained in:
20
consumer/src/main/java/cn/lili/ConsumerApplication.java
Normal file
20
consumer/src/main/java/cn/lili/ConsumerApplication.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package cn.lili;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* 消费者
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2020/11/16 10:03 下午
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class ConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("es.set.netty.runtime.available.processors", "false");
|
||||
SpringApplication.run(ConsumerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
19
consumer/src/main/java/cn/lili/event/MemberLoginEvent.java
Normal file
19
consumer/src/main/java/cn/lili/event/MemberLoginEvent.java
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
20
consumer/src/main/java/cn/lili/event/TradeEvent.java
Normal file
20
consumer/src/main/java/cn/lili/event/TradeEvent.java
Normal 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);
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
25
consumer/src/main/java/cn/lili/event/impl/MemberExecute.java
Normal file
25
consumer/src/main/java/cn/lili/event/impl/MemberExecute.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
34
consumer/src/main/java/cn/lili/init/SensitiveWordsInit.java
Normal file
34
consumer/src/main/java/cn/lili/init/SensitiveWordsInit.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package cn.lili.init;
|
||||
|
||||
import cn.lili.modules.system.service.SensitiveWordsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* SensitiveWordsInit
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2021-11-29 11:38
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SensitiveWordsInit implements ApplicationRunner {
|
||||
|
||||
@Autowired
|
||||
private SensitiveWordsService sensitiveWordsService;
|
||||
|
||||
/**
|
||||
* consumer 启动时,实时更新一下过滤词
|
||||
*
|
||||
* @param args 启动参数
|
||||
*/
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
sensitiveWordsService.resetCache();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package cn.lili.listener;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.event.AfterSaleStatusChangeEvent;
|
||||
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
|
||||
import cn.lili.rocketmq.tags.AfterSaleTagsEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 售后通知
|
||||
*
|
||||
* @author paulG
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RocketMQMessageListener(topic = "${lili.data.rocketmq.after-sale-topic}", consumerGroup = "${lili.data.rocketmq.after-sale-group}")
|
||||
public class AfterSaleMessageListener implements RocketMQListener<MessageExt> {
|
||||
|
||||
/**
|
||||
* 售后订单状态
|
||||
*/
|
||||
@Autowired
|
||||
private List<AfterSaleStatusChangeEvent> afterSaleStatusChangeEvents;
|
||||
|
||||
@Override
|
||||
public void onMessage(MessageExt messageExt) {
|
||||
if (AfterSaleTagsEnum.valueOf(messageExt.getTags()) == AfterSaleTagsEnum.AFTER_SALE_STATUS_CHANGE) {
|
||||
for (AfterSaleStatusChangeEvent afterSaleStatusChangeEvent : afterSaleStatusChangeEvents) {
|
||||
try {
|
||||
AfterSale afterSale = JSONUtil.toBean(new String(messageExt.getBody()), AfterSale.class);
|
||||
afterSaleStatusChangeEvent.afterSaleStatusChange(afterSale);
|
||||
} catch (Exception e) {
|
||||
log.error("售后{},在{}业务中,状态修改事件执行异常",
|
||||
new String(messageExt.getBody()),
|
||||
afterSaleStatusChangeEvent.getClass().getName(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
package cn.lili.listener;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ClassLoaderUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.event.GoodsCommentCompleteEvent;
|
||||
import cn.lili.modules.distribution.entity.dos.DistributionGoods;
|
||||
import cn.lili.modules.distribution.entity.dto.DistributionGoodsSearchParams;
|
||||
import cn.lili.modules.distribution.service.DistributionGoodsService;
|
||||
import cn.lili.modules.distribution.service.DistributionSelectedGoodsService;
|
||||
import cn.lili.modules.goods.entity.dos.*;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
|
||||
import cn.lili.modules.goods.service.*;
|
||||
import cn.lili.modules.member.entity.dos.FootPrint;
|
||||
import cn.lili.modules.member.entity.dos.MemberEvaluation;
|
||||
import cn.lili.modules.member.service.FootprintService;
|
||||
import cn.lili.modules.member.service.GoodsCollectionService;
|
||||
import cn.lili.modules.promotion.entity.dos.BasePromotions;
|
||||
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
|
||||
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
|
||||
import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
|
||||
import cn.lili.modules.promotion.service.PromotionGoodsService;
|
||||
import cn.lili.modules.promotion.service.PromotionService;
|
||||
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
|
||||
import cn.lili.modules.search.service.EsGoodsIndexService;
|
||||
import cn.lili.modules.store.service.StoreService;
|
||||
import cn.lili.rocketmq.tags.GoodsTagsEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 商品消息
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2020/12/9
|
||||
**/
|
||||
@Component
|
||||
@Slf4j
|
||||
@RocketMQMessageListener(topic = "${lili.data.rocketmq.goods-topic}", consumerGroup = "${lili.data.rocketmq.goods-group}")
|
||||
public class GoodsMessageListener implements RocketMQListener<MessageExt> {
|
||||
|
||||
/**
|
||||
* ES商品
|
||||
*/
|
||||
@Autowired
|
||||
private EsGoodsIndexService goodsIndexService;
|
||||
/**
|
||||
* 店铺
|
||||
*/
|
||||
@Autowired
|
||||
private StoreService storeService;
|
||||
/**
|
||||
* 商品
|
||||
*/
|
||||
@Autowired
|
||||
private GoodsService goodsService;
|
||||
/**
|
||||
* 商品Sku
|
||||
*/
|
||||
@Autowired
|
||||
private GoodsSkuService goodsSkuService;
|
||||
/**
|
||||
* 用户足迹
|
||||
*/
|
||||
@Autowired
|
||||
private FootprintService footprintService;
|
||||
/**
|
||||
* 商品收藏
|
||||
*/
|
||||
@Autowired
|
||||
private GoodsCollectionService goodsCollectionService;
|
||||
/**
|
||||
* 商品评价
|
||||
*/
|
||||
@Autowired
|
||||
private List<GoodsCommentCompleteEvent> goodsCommentCompleteEvents;
|
||||
/**
|
||||
* 分销商品
|
||||
*/
|
||||
@Autowired
|
||||
private DistributionGoodsService distributionGoodsService;
|
||||
/**
|
||||
* 分销员-商品关联表
|
||||
*/
|
||||
@Autowired
|
||||
private DistributionSelectedGoodsService distributionSelectedGoodsService;
|
||||
/**
|
||||
* 分类
|
||||
*/
|
||||
@Autowired
|
||||
private CategoryService categoryService;
|
||||
/**
|
||||
* 品牌
|
||||
*/
|
||||
@Autowired
|
||||
private BrandService brandService;
|
||||
/**
|
||||
* 店铺商品分类
|
||||
*/
|
||||
@Autowired
|
||||
private StoreGoodsLabelService storeGoodsLabelService;
|
||||
|
||||
@Autowired
|
||||
private PromotionService promotionService;
|
||||
|
||||
@Autowired
|
||||
private PromotionGoodsService promotionGoodsService;
|
||||
|
||||
@Override
|
||||
public void onMessage(MessageExt messageExt) {
|
||||
|
||||
switch (GoodsTagsEnum.valueOf(messageExt.getTags())) {
|
||||
//查看商品
|
||||
case VIEW_GOODS:
|
||||
FootPrint footPrint = JSONUtil.toBean(new String(messageExt.getBody()), FootPrint.class);
|
||||
footprintService.saveFootprint(footPrint);
|
||||
break;
|
||||
//生成索引
|
||||
case GENERATOR_GOODS_INDEX:
|
||||
try {
|
||||
String goodsId = new String(messageExt.getBody());
|
||||
log.info("生成索引: {}", goodsId);
|
||||
Goods goods = this.goodsService.getById(goodsId);
|
||||
updateGoodsIndex(goods);
|
||||
} catch (Exception e) {
|
||||
log.error("生成商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
|
||||
}
|
||||
break;
|
||||
case UPDATE_GOODS_INDEX_PROMOTIONS:
|
||||
this.updateGoodsIndexPromotions(new String(messageExt.getBody()));
|
||||
break;
|
||||
case DELETE_GOODS_INDEX_PROMOTIONS:
|
||||
BasePromotions promotions = JSONUtil.toBean(new String(messageExt.getBody()), BasePromotions.class);
|
||||
if (CharSequenceUtil.isNotEmpty(promotions.getScopeId())) {
|
||||
this.goodsIndexService.deleteEsGoodsPromotionByPromotionId(Arrays.asList(promotions.getScopeId().split(",")), promotions.getId());
|
||||
} else {
|
||||
this.goodsIndexService.deleteEsGoodsPromotionByPromotionId(null, promotions.getId());
|
||||
}
|
||||
break;
|
||||
case UPDATE_GOODS_INDEX:
|
||||
try {
|
||||
String goodsIdsJsonStr = new String(messageExt.getBody());
|
||||
GoodsSearchParams searchParams = new GoodsSearchParams();
|
||||
searchParams.setId(ArrayUtil.join(JSONUtil.toList(goodsIdsJsonStr, String.class).toArray(), ","));
|
||||
List<Goods> goodsList = goodsService.queryListByParams(searchParams);
|
||||
this.updateGoodsIndex(goodsList);
|
||||
} catch (Exception e) {
|
||||
log.error("更新商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
|
||||
}
|
||||
break;
|
||||
case UPDATE_GOODS_INDEX_FIELD:
|
||||
try {
|
||||
String updateIndexFieldsJsonStr = new String(messageExt.getBody());
|
||||
JSONObject updateIndexFields = JSONUtil.parseObj(updateIndexFieldsJsonStr);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> queryFields = updateIndexFields.get("queryFields", Map.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> updateFields = updateIndexFields.get("updateFields", Map.class);
|
||||
goodsIndexService.updateIndex(queryFields, updateFields);
|
||||
} catch (Exception e) {
|
||||
log.error("更新商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
|
||||
}
|
||||
break;
|
||||
case RESET_GOODS_INDEX:
|
||||
try {
|
||||
String goodsIdsJsonStr = new String(messageExt.getBody());
|
||||
List<EsGoodsIndex> goodsIndices = JSONUtil.toList(goodsIdsJsonStr, EsGoodsIndex.class);
|
||||
goodsIndexService.updateBulkIndex(goodsIndices);
|
||||
} catch (Exception e) {
|
||||
log.error("重置商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
|
||||
}
|
||||
break;
|
||||
//审核商品
|
||||
case GOODS_AUDIT:
|
||||
Goods goods = JSONUtil.toBean(new String(messageExt.getBody()), Goods.class);
|
||||
updateGoodsNum(goods);
|
||||
updateGoodsIndex(goods);
|
||||
break;
|
||||
//删除商品
|
||||
case GOODS_DELETE:
|
||||
try {
|
||||
String goodsIdsJsonStr = new String(messageExt.getBody());
|
||||
for (String goodsId : JSONUtil.toList(goodsIdsJsonStr, String.class)) {
|
||||
Goods goodsById = this.goodsService.getById(goodsId);
|
||||
if (goodsById != null) {
|
||||
this.deleteGoods(goodsById);
|
||||
this.updateGoodsNum(goodsById);
|
||||
List<String> skuIdsByGoodsId = this.goodsSkuService.getSkuIdsByGoodsId(goodsId);
|
||||
if (skuIdsByGoodsId != null && !skuIdsByGoodsId.isEmpty()) {
|
||||
this.goodsIndexService.deleteIndexByIds(skuIdsByGoodsId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("删除商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
|
||||
}
|
||||
break;
|
||||
//规格删除
|
||||
case SKU_DELETE:
|
||||
String message = new String(messageExt.getBody());
|
||||
List<String> skuIds = JSONUtil.toList(message, String.class);
|
||||
goodsCollectionService.deleteSkuCollection(skuIds);
|
||||
break;
|
||||
//商品评价
|
||||
case GOODS_COMMENT_COMPLETE:
|
||||
MemberEvaluation memberEvaluation = JSONUtil.toBean(new String(messageExt.getBody()), MemberEvaluation.class);
|
||||
for (GoodsCommentCompleteEvent goodsCommentCompleteEvent : goodsCommentCompleteEvents) {
|
||||
try {
|
||||
goodsCommentCompleteEvent.goodsComment(memberEvaluation);
|
||||
} catch (Exception e) {
|
||||
log.error("评价{},在{}业务中,状态修改事件执行异常",
|
||||
new String(messageExt.getBody()),
|
||||
goodsCommentCompleteEvent.getClass().getName(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//购买商品完成
|
||||
case BUY_GOODS_COMPLETE:
|
||||
this.goodsBuyComplete(messageExt);
|
||||
break;
|
||||
default:
|
||||
log.error("商品执行异常:{}", new String(messageExt.getBody()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateGoodsIndexPromotions(String promotionsJsonStr) {
|
||||
try {
|
||||
log.info("更新商品索引促销信息: {}", promotionsJsonStr);
|
||||
JSONObject jsonObject = JSONUtil.parseObj(promotionsJsonStr);
|
||||
BasePromotions promotions = (BasePromotions) jsonObject.get("promotions",
|
||||
ClassLoaderUtil.loadClass(jsonObject.get("promotionsType").toString()));
|
||||
String esPromotionKey = jsonObject.get("esPromotionKey").toString();
|
||||
if (PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(promotions.getScopeType())) {
|
||||
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
|
||||
searchParams.setPromotionId(promotions.getId());
|
||||
List<PromotionGoods> promotionGoodsList = this.promotionGoodsService.listFindAll(searchParams);
|
||||
List<String> skuIds = promotionGoodsList.stream().map(PromotionGoods::getSkuId).collect(Collectors.toList());
|
||||
this.goodsIndexService.deleteEsGoodsPromotionByPromotionId(skuIds, promotions.getId());
|
||||
this.goodsIndexService.updateEsGoodsIndexByList(promotionGoodsList, promotions, esPromotionKey);
|
||||
} else if (PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name().equals(promotions.getScopeType())) {
|
||||
GoodsSearchParams searchParams = new GoodsSearchParams();
|
||||
searchParams.setCategoryPath(promotions.getScopeId());
|
||||
List<GoodsSku> goodsSkuByList = this.goodsSkuService.getGoodsSkuByList(searchParams);
|
||||
List<String> skuIds = goodsSkuByList.stream().map(GoodsSku::getId).collect(Collectors.toList());
|
||||
this.goodsIndexService.deleteEsGoodsPromotionByPromotionId(skuIds, promotions.getId());
|
||||
this.goodsIndexService.updateEsGoodsIndexPromotions(skuIds, promotions, esPromotionKey);
|
||||
} else if (PromotionsScopeTypeEnum.ALL.name().equals(promotions.getScopeType())) {
|
||||
this.goodsIndexService.updateEsGoodsIndexAllByList(promotions, esPromotionKey);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("生成商品索引促销信息执行异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品索引
|
||||
*
|
||||
* @param goodsList 商品列表消息
|
||||
*/
|
||||
private void updateGoodsIndex(List<Goods> goodsList) {
|
||||
List<EsGoodsIndex> goodsIndices = new ArrayList<>();
|
||||
for (Goods goods : goodsList) {
|
||||
//如果商品通过审核&&并且已上架
|
||||
GoodsSearchParams searchParams = new GoodsSearchParams();
|
||||
searchParams.setGoodsId(goods.getId());
|
||||
searchParams.setGeQuantity(0);
|
||||
List<GoodsSku> goodsSkuList = this.goodsSkuService.getGoodsSkuByList(searchParams);
|
||||
if (goods.getAuthFlag().equals(GoodsAuthEnum.PASS.name())
|
||||
&& goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())
|
||||
&& Boolean.FALSE.equals(goods.getDeleteFlag())) {
|
||||
goodsSkuList.forEach(goodsSku -> {
|
||||
EsGoodsIndex goodsIndex = this.settingUpGoodsIndexData(goods, goodsSku);
|
||||
goodsIndices.add(goodsIndex);
|
||||
});
|
||||
}
|
||||
//如果商品状态值不支持es搜索,那么将商品信息做下架处理
|
||||
else {
|
||||
for (GoodsSku goodsSku : goodsSkuList) {
|
||||
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
|
||||
if (esGoodsOld != null) {
|
||||
goodsIndexService.deleteIndexById(goodsSku.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
goodsIndexService.updateBulkIndex(goodsIndices);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品索引
|
||||
*
|
||||
* @param goods 商品消息
|
||||
*/
|
||||
private void updateGoodsIndex(Goods goods) {
|
||||
//如果商品通过审核&&并且已上架
|
||||
GoodsSearchParams searchParams = new GoodsSearchParams();
|
||||
searchParams.setGoodsId(goods.getId());
|
||||
List<GoodsSku> goodsSkuList = this.goodsSkuService.getGoodsSkuByList(searchParams);
|
||||
log.info("goods:{}", goods);
|
||||
log.info("goodsSkuList:{}", goodsSkuList);
|
||||
if (goods.getAuthFlag().equals(GoodsAuthEnum.PASS.name())
|
||||
&& goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())
|
||||
&& Boolean.FALSE.equals(goods.getDeleteFlag())) {
|
||||
this.generatorGoodsIndex(goods, goodsSkuList);
|
||||
}
|
||||
//如果商品状态值不支持es搜索,那么将商品信息做下架处理
|
||||
else {
|
||||
for (GoodsSku goodsSku : goodsSkuList) {
|
||||
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
|
||||
if (esGoodsOld != null) {
|
||||
goodsIndexService.deleteIndexById(goodsSku.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成商品索引
|
||||
*
|
||||
* @param goods 商品信息
|
||||
* @param goodsSkuList 商品sku信息
|
||||
*/
|
||||
private void generatorGoodsIndex(Goods goods, List<GoodsSku> goodsSkuList) {
|
||||
int skuSource = 100;
|
||||
for (GoodsSku goodsSku : goodsSkuList) {
|
||||
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
|
||||
EsGoodsIndex goodsIndex = this.settingUpGoodsIndexData(goods, goodsSku);
|
||||
goodsIndex.setSkuSource(skuSource--);
|
||||
log.info("goodsSku:{}", goodsSku);
|
||||
log.info("esGoodsOld:{}", esGoodsOld);
|
||||
//如果商品库存不为0,并且es中有数据
|
||||
if (goodsSku.getQuantity() > 0 && esGoodsOld == null) {
|
||||
log.info("生成商品索引 {}", goodsIndex);
|
||||
this.goodsIndexService.addIndex(goodsIndex);
|
||||
} else if (goodsSku.getQuantity() > 0 && esGoodsOld != null) {
|
||||
goodsIndexService.updateIndex(goodsIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EsGoodsIndex settingUpGoodsIndexData(Goods goods, GoodsSku goodsSku) {
|
||||
EsGoodsIndex goodsIndex = new EsGoodsIndex(goodsSku);
|
||||
if (goods.getParams() != null && !goods.getParams().isEmpty()) {
|
||||
List<GoodsParamsDTO> goodsParamDTOS = JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class);
|
||||
goodsIndex = new EsGoodsIndex(goodsSku, goodsParamDTOS);
|
||||
}
|
||||
goodsIndex.setAuthFlag(goods.getAuthFlag());
|
||||
goodsIndex.setMarketEnable(goods.getMarketEnable());
|
||||
this.settingUpGoodsIndexOtherParam(goodsIndex);
|
||||
return goodsIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置商品索引的其他参数(非商品自带)
|
||||
*
|
||||
* @param goodsIndex 商品索引信息
|
||||
*/
|
||||
private void settingUpGoodsIndexOtherParam(EsGoodsIndex goodsIndex) {
|
||||
List<Category> categories = categoryService.listByIdsOrderByLevel(Arrays.asList(goodsIndex.getCategoryPath().split(",")));
|
||||
if (!categories.isEmpty()) {
|
||||
goodsIndex.setCategoryNamePath(ArrayUtil.join(categories.stream().map(Category::getName).toArray(), ","));
|
||||
}
|
||||
Brand brand = brandService.getById(goodsIndex.getBrandId());
|
||||
if (brand != null) {
|
||||
goodsIndex.setBrandName(brand.getName());
|
||||
goodsIndex.setBrandUrl(brand.getLogo());
|
||||
}
|
||||
if (goodsIndex.getStoreCategoryPath() != null && CharSequenceUtil.isNotEmpty(goodsIndex.getStoreCategoryPath())) {
|
||||
List<StoreGoodsLabel> storeGoodsLabels = storeGoodsLabelService.listByStoreIds(Arrays.asList(goodsIndex.getStoreCategoryPath().split(",")));
|
||||
if (!storeGoodsLabels.isEmpty()) {
|
||||
goodsIndex.setStoreCategoryNamePath(ArrayUtil.join(storeGoodsLabels.stream().map(StoreGoodsLabel::getLabelName).toArray(), ","));
|
||||
}
|
||||
}
|
||||
|
||||
if (goodsIndex.getPromotionMap() == null || goodsIndex.getPromotionMap().isEmpty()) {
|
||||
Map<String, Object> goodsCurrentPromotionMap = promotionService.getGoodsSkuPromotionMap(goodsIndex.getStoreId(), goodsIndex.getId());
|
||||
goodsIndex.setPromotionMapJson(JSONUtil.toJsonStr(goodsCurrentPromotionMap));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
* 1.更新店铺的商品数量
|
||||
* 2.删除分销员-分销商品绑定关系
|
||||
* 3.删除分销商品
|
||||
*
|
||||
* @param goods 消息
|
||||
*/
|
||||
private void deleteGoods(Goods goods) {
|
||||
|
||||
DistributionGoodsSearchParams searchParams = new DistributionGoodsSearchParams();
|
||||
searchParams.setGoodsId(goods.getId());
|
||||
//删除获取分销商品
|
||||
DistributionGoods distributionGoods = distributionGoodsService.getDistributionGoods(searchParams);
|
||||
|
||||
if (distributionGoods != null) {
|
||||
|
||||
//删除分销商品绑定关系
|
||||
distributionSelectedGoodsService.deleteByDistributionGoodsId(distributionGoods.getId());
|
||||
|
||||
//删除分销商品
|
||||
distributionGoodsService.removeById(distributionGoods.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品数量
|
||||
*
|
||||
* @param goods 信息体
|
||||
*/
|
||||
private void updateGoodsNum(Goods goods) {
|
||||
try {
|
||||
//更新店铺商品数量
|
||||
assert goods != null;
|
||||
storeService.updateStoreGoodsNum(goods.getStoreId());
|
||||
} catch (Exception e) {
|
||||
log.error("修改商品数量错误");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品购买完成
|
||||
* 1.更新商品购买数量
|
||||
* 2.更新SKU购买数量
|
||||
* 3.更新索引购买数量
|
||||
*
|
||||
* @param messageExt 信息体
|
||||
*/
|
||||
private void goodsBuyComplete(MessageExt messageExt) {
|
||||
String goodsCompleteMessageStr = new String(messageExt.getBody());
|
||||
List<GoodsCompleteMessage> goodsCompleteMessageList = JSONUtil.toList(JSONUtil.parseArray(goodsCompleteMessageStr), GoodsCompleteMessage.class);
|
||||
for (GoodsCompleteMessage goodsCompleteMessage : goodsCompleteMessageList) {
|
||||
Goods goods = goodsService.getById(goodsCompleteMessage.getGoodsId());
|
||||
if (goods != null) {
|
||||
//更新商品购买数量
|
||||
if (goods.getBuyCount() == null) {
|
||||
goods.setBuyCount(0);
|
||||
}
|
||||
int buyCount = goods.getBuyCount() + goodsCompleteMessage.getBuyNum();
|
||||
this.goodsService.updateGoodsBuyCount(goodsCompleteMessage.getGoodsId(), buyCount);
|
||||
} else {
|
||||
log.error("商品Id为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
|
||||
}
|
||||
GoodsSku goodsSku = goodsSkuService.getById(goodsCompleteMessage.getSkuId());
|
||||
if (goodsSku != null) {
|
||||
//更新商品购买数量
|
||||
if (goodsSku.getBuyCount() == null) {
|
||||
goodsSku.setBuyCount(0);
|
||||
}
|
||||
int buyCount = goodsSku.getBuyCount() + goodsCompleteMessage.getBuyNum();
|
||||
goodsSku.setBuyCount(buyCount);
|
||||
goodsSkuService.update(goodsSku);
|
||||
|
||||
this.goodsIndexService.updateIndex(
|
||||
MapUtil.builder(new HashMap<String, Object>()).put("id", goodsCompleteMessage.getSkuId()).build(),
|
||||
MapUtil.builder(new HashMap<String, Object>()).put("buyCount", buyCount).build());
|
||||
|
||||
} else {
|
||||
log.error("商品SkuId为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package cn.lili.listener;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.event.MemberLoginEvent;
|
||||
import cn.lili.event.MemberPointChangeEvent;
|
||||
import cn.lili.event.MemberRegisterEvent;
|
||||
import cn.lili.event.MemberWithdrawalEvent;
|
||||
import cn.lili.modules.member.entity.dos.Member;
|
||||
import cn.lili.modules.member.entity.dos.MemberSign;
|
||||
import cn.lili.modules.member.entity.dto.MemberPointMessage;
|
||||
import cn.lili.modules.member.service.MemberSignService;
|
||||
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
|
||||
import cn.lili.rocketmq.tags.MemberTagsEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会员消息
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2020/12/9
|
||||
**/
|
||||
@Component
|
||||
@Slf4j
|
||||
@RocketMQMessageListener(topic = "${lili.data.rocketmq.member-topic}", consumerGroup = "${lili.data.rocketmq.member-group}")
|
||||
public class MemberMessageListener implements RocketMQListener<MessageExt> {
|
||||
|
||||
/**
|
||||
* 会员签到
|
||||
*/
|
||||
@Autowired
|
||||
private MemberSignService memberSignService;
|
||||
/**
|
||||
* 会员积分变化
|
||||
*/
|
||||
@Autowired
|
||||
private List<MemberPointChangeEvent> memberPointChangeEvents;
|
||||
/**
|
||||
* 会员提现
|
||||
*/
|
||||
@Autowired
|
||||
private List<MemberWithdrawalEvent> memberWithdrawalEvents;
|
||||
/**
|
||||
* 会员注册
|
||||
*/
|
||||
@Autowired
|
||||
private List<MemberRegisterEvent> memberSignEvents;
|
||||
|
||||
/**
|
||||
* 会员注册
|
||||
*/
|
||||
@Autowired
|
||||
private List<MemberLoginEvent> memberLoginEvents;
|
||||
|
||||
|
||||
@Override
|
||||
public void onMessage(MessageExt messageExt) {
|
||||
switch (MemberTagsEnum.valueOf(messageExt.getTags())) {
|
||||
//会员注册
|
||||
case MEMBER_REGISTER:
|
||||
for (MemberRegisterEvent memberRegisterEvent : memberSignEvents) {
|
||||
try {
|
||||
Member member = JSONUtil.toBean(new String(messageExt.getBody()), Member.class);
|
||||
memberRegisterEvent.memberRegister(member);
|
||||
} catch (Exception e) {
|
||||
log.error("会员{},在{}业务中,状态修改事件执行异常",
|
||||
new String(messageExt.getBody()),
|
||||
memberRegisterEvent.getClass().getName(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MEMBER_LOGIN:
|
||||
|
||||
for (MemberLoginEvent memberLoginEvent : memberLoginEvents) {
|
||||
try {
|
||||
Member member = JSONUtil.toBean(new String(messageExt.getBody()), Member.class);
|
||||
memberLoginEvent.memberLogin(member);
|
||||
} catch (Exception e) {
|
||||
log.error("会员{},在{}业务中,状态修改事件执行异常",
|
||||
new String(messageExt.getBody()),
|
||||
memberLoginEvent.getClass().getName(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//会员签到
|
||||
case MEMBER_SING:
|
||||
MemberSign memberSign = JSONUtil.toBean(new String(messageExt.getBody()), MemberSign.class);
|
||||
memberSignService.memberSignSendPoint(memberSign.getMemberId(), memberSign.getSignDay());
|
||||
break;
|
||||
//会员积分变动
|
||||
case MEMBER_POINT_CHANGE:
|
||||
for (MemberPointChangeEvent memberPointChangeEvent : memberPointChangeEvents) {
|
||||
try {
|
||||
MemberPointMessage memberPointMessage = JSONUtil.toBean(new String(messageExt.getBody()), MemberPointMessage.class);
|
||||
memberPointChangeEvent.memberPointChange(memberPointMessage);
|
||||
} catch (Exception e) {
|
||||
log.error("会员{},在{}业务中,状态修改事件执行异常",
|
||||
new String(messageExt.getBody()),
|
||||
memberPointChangeEvent.getClass().getName(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//会员提现
|
||||
case MEMBER_WITHDRAWAL:
|
||||
for (MemberWithdrawalEvent memberWithdrawalEvent : memberWithdrawalEvents) {
|
||||
try {
|
||||
MemberWithdrawalMessage memberWithdrawalMessage = JSONUtil.toBean(new String(messageExt.getBody()), MemberWithdrawalMessage.class);
|
||||
memberWithdrawalEvent.memberWithdrawal(memberWithdrawalMessage);
|
||||
} catch (Exception e) {
|
||||
log.error("会员{},在{}业务中,提现事件执行异常",
|
||||
new String(messageExt.getBody()),
|
||||
memberWithdrawalEvent.getClass().getName(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.lili.listener;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.modules.message.entity.dto.NoticeMessageDTO;
|
||||
import cn.lili.modules.message.service.NoticeMessageService;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 站内信通知
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2020/12/9
|
||||
*/
|
||||
@Component
|
||||
@RocketMQMessageListener(topic = "${lili.data.rocketmq.notice-topic}", consumerGroup = "${lili.data.rocketmq.notice-group}")
|
||||
public class NoticeMessageListener implements RocketMQListener<MessageExt> {
|
||||
|
||||
/**
|
||||
* 站内信
|
||||
*/
|
||||
@Autowired
|
||||
private NoticeMessageService noticeMessageService;
|
||||
|
||||
@Override
|
||||
public void onMessage(MessageExt messageExt) {
|
||||
NoticeMessageDTO noticeMessageDTO = JSONUtil.toBean(new String(messageExt.getBody()), NoticeMessageDTO.class);
|
||||
noticeMessageService.noticeMessage(noticeMessageDTO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package cn.lili.listener;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.common.enums.SwitchEnum;
|
||||
import cn.lili.common.vo.PageVO;
|
||||
import cn.lili.modules.member.entity.vo.MemberSearchVO;
|
||||
import cn.lili.modules.member.entity.vo.MemberVO;
|
||||
import cn.lili.modules.member.service.MemberService;
|
||||
import cn.lili.modules.message.entity.dos.MemberMessage;
|
||||
import cn.lili.modules.message.entity.dos.Message;
|
||||
import cn.lili.modules.message.entity.dos.StoreMessage;
|
||||
import cn.lili.modules.message.entity.enums.MessageSendClient;
|
||||
import cn.lili.modules.message.entity.enums.MessageStatusEnum;
|
||||
import cn.lili.modules.message.entity.enums.RangeEnum;
|
||||
import cn.lili.modules.message.service.MemberMessageService;
|
||||
import cn.lili.modules.message.service.StoreMessageService;
|
||||
import cn.lili.modules.sms.SmsUtil;
|
||||
import cn.lili.modules.sms.entity.dto.SmsReachDTO;
|
||||
import cn.lili.modules.store.entity.dos.Store;
|
||||
import cn.lili.modules.store.service.StoreService;
|
||||
import cn.lili.rocketmq.tags.OtherTagsEnum;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息发送
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2020/12/9
|
||||
*/
|
||||
@Component
|
||||
@RocketMQMessageListener(topic = "${lili.data.rocketmq.notice-send-topic}", consumerGroup = "${lili.data.rocketmq.notice-send-group}")
|
||||
public class NoticeSendMessageListener implements RocketMQListener<MessageExt> {
|
||||
|
||||
/**
|
||||
* 短信
|
||||
*/
|
||||
@Autowired
|
||||
private SmsUtil smsUtil;
|
||||
/**
|
||||
* 店铺消息
|
||||
*/
|
||||
@Autowired
|
||||
private StoreMessageService storeMessageService;
|
||||
/**
|
||||
* 会员消息
|
||||
*/
|
||||
@Autowired
|
||||
private MemberMessageService memberMessageService;
|
||||
/**
|
||||
* 店铺
|
||||
*/
|
||||
@Autowired
|
||||
private StoreService storeService;
|
||||
/**
|
||||
* 会员
|
||||
*/
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
@Override
|
||||
public void onMessage(MessageExt messageExt) {
|
||||
switch (OtherTagsEnum.valueOf(messageExt.getTags())) {
|
||||
case SMS:
|
||||
String smsJsonStr = new String(messageExt.getBody());
|
||||
SmsReachDTO smsReachDTO = JSONUtil.toBean(smsJsonStr, SmsReachDTO.class);
|
||||
//发送全部会员
|
||||
if (smsReachDTO.getSmsRange().equals(RangeEnum.ALL.name())) {
|
||||
//获取所有会员的手机号
|
||||
List<String> list = memberService.getAllMemberMobile();
|
||||
smsUtil.sendBatchSms(smsReachDTO.getSignName(), list, smsReachDTO.getMessageCode());
|
||||
//判断为发送部分用户
|
||||
} else {
|
||||
smsUtil.sendBatchSms(smsReachDTO.getSignName(), smsReachDTO.getMobile(), smsReachDTO.getMessageCode());
|
||||
}
|
||||
break;
|
||||
//管理员发送站内信
|
||||
case MESSAGE:
|
||||
Message message = JSONUtil.toBean(new String(messageExt.getBody()), Message.class);
|
||||
// 管理端发送给商家的站内信
|
||||
if (message.getMessageClient().equals(MessageSendClient.STORE.name().toLowerCase())) {
|
||||
saveStoreMessage(message);
|
||||
} else {
|
||||
//管理员发送给会员的站内信
|
||||
saveMemberMessage(message);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存店铺消息
|
||||
*
|
||||
* @param message 消息
|
||||
*/
|
||||
private void saveStoreMessage(Message message) {
|
||||
List<StoreMessage> list = new ArrayList<>();
|
||||
//发送全部商家情况
|
||||
if ("ALL".equals(message.getMessageRange())) {
|
||||
List<Store> storeList = storeService.list(new QueryWrapper<Store>().eq("store_disable", "OPEN"));
|
||||
storeList.forEach(item -> {
|
||||
StoreMessage storeMessage = new StoreMessage();
|
||||
storeMessage.setMessageId(message.getId());
|
||||
storeMessage.setStoreName(item.getStoreName());
|
||||
storeMessage.setStoreId(item.getId());
|
||||
storeMessage.setStatus(MessageStatusEnum.UN_READY.name());
|
||||
storeMessage.setTitle(message.getTitle());
|
||||
storeMessage.setContent(message.getContent());
|
||||
list.add(storeMessage);
|
||||
});
|
||||
} else {
|
||||
//发送给指定商家情况
|
||||
int i = 0;
|
||||
for (String str : message.getUserIds()) {
|
||||
StoreMessage storeMessage = new StoreMessage();
|
||||
storeMessage.setMessageId(message.getId());
|
||||
storeMessage.setStoreId(str);
|
||||
storeMessage.setStoreName(message.getUserNames()[i]);
|
||||
storeMessage.setStatus(MessageStatusEnum.UN_READY.name());
|
||||
storeMessage.setTitle(message.getTitle());
|
||||
storeMessage.setContent(message.getContent());
|
||||
list.add(storeMessage);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
//执行保存
|
||||
storeMessageService.save(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存会员消息
|
||||
*
|
||||
* @param message 消息
|
||||
*/
|
||||
private void saveMemberMessage(Message message) {
|
||||
List<MemberMessage> list = new ArrayList<>();
|
||||
//如果是给所有会员发送消息
|
||||
if ("ALL".equals(message.getMessageRange())) {
|
||||
//查询所有会员总数,因为会员总数比较大 如果一次性查出来会占用数据库资源,所以要分页查询
|
||||
MemberSearchVO memberSearchVO = new MemberSearchVO();
|
||||
memberSearchVO.setDisabled(SwitchEnum.OPEN.name());
|
||||
long memberNum = memberService.getMemberNum(memberSearchVO);
|
||||
//构建分页查询参数
|
||||
//100条查一次
|
||||
int pageSize = 100;
|
||||
int pageCount;
|
||||
pageCount = (int) (memberNum / pageSize);
|
||||
pageCount = memberNum % pageSize > 0 ? pageCount + 1 : pageCount;
|
||||
for (int i = 1; i <= pageCount; i++) {
|
||||
PageVO pageVO = new PageVO();
|
||||
pageVO.setPageSize(pageSize);
|
||||
pageVO.setPageNumber(i);
|
||||
IPage<MemberVO> page = memberService.getMemberPage(memberSearchVO, pageVO);
|
||||
//循环要保存的信息
|
||||
page.getRecords().forEach(item -> {
|
||||
MemberMessage memberMessage = new MemberMessage();
|
||||
memberMessage.setContent(message.getContent());
|
||||
memberMessage.setTitle(message.getTitle());
|
||||
memberMessage.setMessageId(message.getId());
|
||||
memberMessage.setMemberId(item.getId());
|
||||
memberMessage.setMemberName(item.getUsername());
|
||||
memberMessage.setStatus(MessageStatusEnum.UN_READY.name());
|
||||
list.add(memberMessage);
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
//如果是给指定会员发送消息
|
||||
int i = 0;
|
||||
for (String str : message.getUserIds()) {
|
||||
MemberMessage memberMessage = new MemberMessage();
|
||||
memberMessage.setMessageId(message.getId());
|
||||
memberMessage.setMemberId(str);
|
||||
memberMessage.setMemberName(message.getUserNames()[i]);
|
||||
memberMessage.setStatus(MessageStatusEnum.UN_READY.name());
|
||||
memberMessage.setTitle(message.getTitle());
|
||||
memberMessage.setContent(message.getContent());
|
||||
list.add(memberMessage);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
//执行保存
|
||||
memberMessageService.save(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package cn.lili.listener;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.cache.Cache;
|
||||
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.rocketmq.tags.OrderTagsEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单消息
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2020/12/9
|
||||
**/
|
||||
@Component
|
||||
@Slf4j
|
||||
@RocketMQMessageListener(topic = "${lili.data.rocketmq.order-topic}", consumerGroup = "${lili.data.rocketmq.order-group}")
|
||||
public class OrderMessageListener implements RocketMQListener<MessageExt> {
|
||||
|
||||
/**
|
||||
* 交易
|
||||
*/
|
||||
@Autowired
|
||||
private List<TradeEvent> tradeEvent;
|
||||
/**
|
||||
* 订单状态
|
||||
*/
|
||||
@Autowired
|
||||
private List<OrderStatusChangeEvent> orderStatusChangeEvents;
|
||||
/**
|
||||
* 缓存
|
||||
*/
|
||||
@Autowired
|
||||
private Cache<Object> cache;
|
||||
|
||||
@Override
|
||||
public void onMessage(MessageExt messageExt) {
|
||||
try {
|
||||
this.orderStatusEvent(messageExt);
|
||||
} catch (Exception e) {
|
||||
log.error("订单状态变更事件调用异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单状态变更
|
||||
* @param messageExt
|
||||
*/
|
||||
public void orderStatusEvent(MessageExt messageExt) {
|
||||
|
||||
switch (OrderTagsEnum.valueOf(messageExt.getTags())) {
|
||||
//订单创建
|
||||
case ORDER_CREATE:
|
||||
String key = new String(messageExt.getBody());
|
||||
TradeDTO tradeDTO = JSONUtil.toBean(cache.getString(key), TradeDTO.class);
|
||||
boolean result = true;
|
||||
for (TradeEvent event : tradeEvent) {
|
||||
try {
|
||||
event.orderCreate(tradeDTO);
|
||||
} catch (Exception e) {
|
||||
log.error("交易{}入库,在{}业务中,状态修改事件执行异常",
|
||||
tradeDTO.getSn(),
|
||||
event.getClass().getName(),
|
||||
e);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
//如所有步骤顺利完成
|
||||
if (Boolean.TRUE.equals(result)) {
|
||||
//清除记录信息的trade cache key
|
||||
cache.remove(key);
|
||||
}
|
||||
break;
|
||||
//订单状态变更
|
||||
case STATUS_CHANGE:
|
||||
for (OrderStatusChangeEvent orderStatusChangeEvent : orderStatusChangeEvents) {
|
||||
try {
|
||||
OrderMessage orderMessage = JSONUtil.toBean(new String(messageExt.getBody()), OrderMessage.class);
|
||||
orderStatusChangeEvent.orderChange(orderMessage);
|
||||
} catch (Exception e) {
|
||||
log.error("订单{},在{}业务中,状态修改事件执行异常",
|
||||
new String(messageExt.getBody()),
|
||||
orderStatusChangeEvent.getClass().getName(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
104
consumer/src/main/java/cn/lili/timetask/TimedTaskJobHandler.java
Normal file
104
consumer/src/main/java/cn/lili/timetask/TimedTaskJobHandler.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package cn.lili.timetask;
|
||||
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import cn.lili.timetask.handler.EveryHourExecute;
|
||||
import cn.lili.timetask.handler.EveryMinuteExecute;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 定时器任务
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2020-12-24 11:51
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class TimedTaskJobHandler {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<EveryMinuteExecute> everyMinuteExecutes;
|
||||
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<EveryHourExecute> everyHourExecutes;
|
||||
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<EveryDayExecute> everyDayExecutes;
|
||||
|
||||
/**
|
||||
* 每分钟任务
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@XxlJob("everyMinuteExecute")
|
||||
public ReturnT<String> everyMinuteExecute(String param) {
|
||||
log.info("每分钟任务执行");
|
||||
if (everyMinuteExecutes == null || everyMinuteExecutes.size() == 0) {
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < everyMinuteExecutes.size(); i++) {
|
||||
try {
|
||||
everyMinuteExecutes.get(i).execute();
|
||||
} catch (Exception e) {
|
||||
log.error("每分钟任务异常", e);
|
||||
}
|
||||
}
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每小时任务
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@XxlJob("everyHourExecuteJobHandler")
|
||||
public ReturnT<String> everyHourExecuteJobHandler(String param) {
|
||||
log.info("每小时任务执行");
|
||||
if (everyHourExecutes == null || everyHourExecutes.size() == 0) {
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < everyHourExecutes.size(); i++) {
|
||||
try {
|
||||
everyHourExecutes.get(i).execute();
|
||||
} catch (Exception e) {
|
||||
log.error("每分钟任务异常", e);
|
||||
}
|
||||
}
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每日任务
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@XxlJob("everyDayExecuteJobHandler")
|
||||
public ReturnT<String> everyDayExecuteJobHandler(String param) {
|
||||
|
||||
log.info("每日任务执行");
|
||||
if (everyDayExecutes == null || everyDayExecutes.size() == 0) {
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < everyDayExecutes.size(); i++) {
|
||||
try {
|
||||
everyDayExecutes.get(i).execute();
|
||||
} catch (Exception e) {
|
||||
log.error("每分钟任务异常", e);
|
||||
}
|
||||
}
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.lili.timetask.config;
|
||||
|
||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* xxl-job config
|
||||
*
|
||||
* @author xuxueli 2017-04-28
|
||||
*/
|
||||
@Configuration
|
||||
public class XxlJobConfig {
|
||||
private final Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
|
||||
|
||||
@Value("${xxl.job.admin.addresses:}")
|
||||
private String adminAddresses;
|
||||
|
||||
@Value("${xxl.job.accessToken:}")
|
||||
private String accessToken;
|
||||
|
||||
@Value("${xxl.job.executor.appname}")
|
||||
private String appname;
|
||||
|
||||
@Value("${xxl.job.executor.address}")
|
||||
private String address;
|
||||
|
||||
@Value("${xxl.job.executor.ip}")
|
||||
private String ip;
|
||||
|
||||
@Value("${xxl.job.executor.port}")
|
||||
private int port;
|
||||
|
||||
@Value("${xxl.job.executor.logpath}")
|
||||
private String logPath;
|
||||
|
||||
@Value("${xxl.job.executor.logretentiondays}")
|
||||
private int logRetentionDays;
|
||||
|
||||
|
||||
@Bean
|
||||
public XxlJobSpringExecutor xxlJobExecutor() {
|
||||
logger.info(">>>>>>>>>>> xxl-job config init.");
|
||||
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
||||
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
|
||||
xxlJobSpringExecutor.setAppname(appname);
|
||||
xxlJobSpringExecutor.setAddress(address);
|
||||
xxlJobSpringExecutor.setIp(ip);
|
||||
xxlJobSpringExecutor.setPort(port);
|
||||
xxlJobSpringExecutor.setAccessToken(accessToken);
|
||||
xxlJobSpringExecutor.setLogPath(logPath);
|
||||
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
|
||||
|
||||
return xxlJobSpringExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
|
||||
*
|
||||
* 1、引入依赖:
|
||||
* <dependency>
|
||||
* <groupId>org.springframework.cloud</groupId>
|
||||
* <artifactId>spring-cloud-commons</artifactId>
|
||||
* <version>${version}</version>
|
||||
* </dependency>
|
||||
*
|
||||
* 2、配置文件,或者容器启动变量
|
||||
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
|
||||
*
|
||||
* 3、获取IP
|
||||
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.lili.timetask.handler;
|
||||
|
||||
/**
|
||||
* 每日任务
|
||||
* 每日凌晨1点执行
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2020/12/24 11:52
|
||||
*/
|
||||
public interface EveryDayExecute {
|
||||
|
||||
/**
|
||||
* 执行每日任务
|
||||
*/
|
||||
void execute();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.lili.timetask.handler;
|
||||
|
||||
/**
|
||||
* 每小时任务
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2020/12/24 11:52
|
||||
*/
|
||||
public interface EveryHourExecute {
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*/
|
||||
void execute();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.lili.timetask.handler;
|
||||
|
||||
/**
|
||||
* 每分钟任务
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2020/12/24 11:52
|
||||
*/
|
||||
public interface EveryMinuteExecute {
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*/
|
||||
void execute();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package cn.lili.timetask.handler.impl.bill;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.lili.modules.store.entity.dto.StoreSettlementDay;
|
||||
import cn.lili.modules.store.service.BillService;
|
||||
import cn.lili.modules.store.service.StoreDetailService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 店铺结算执行
|
||||
*
|
||||
* @author Bulbasaur
|
||||
* @since 2021/2/18 3:45 下午
|
||||
*/
|
||||
@Component
|
||||
public class BillExecute implements EveryDayExecute {
|
||||
|
||||
/**
|
||||
* 结算单
|
||||
*/
|
||||
@Autowired
|
||||
private BillService billService;
|
||||
/**
|
||||
* 店铺详情
|
||||
*/
|
||||
@Autowired
|
||||
private StoreDetailService storeDetailService;
|
||||
|
||||
/**
|
||||
* 1.查询今日待结算的商家
|
||||
* 2.查询商家上次结算日期,生成本次结算单
|
||||
* 3.记录商家结算日
|
||||
*/
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
//获取当前天数
|
||||
int day = DateUtil.date().dayOfMonth();
|
||||
|
||||
//获取待结算商家列表
|
||||
List<StoreSettlementDay> storeList = storeDetailService.getSettlementStore(day);
|
||||
|
||||
//获取当前时间
|
||||
DateTime endTime = DateUtil.date();
|
||||
//批量商家结算
|
||||
for (StoreSettlementDay storeSettlementDay : storeList) {
|
||||
|
||||
//生成结算单
|
||||
billService.createBill(storeSettlementDay.getStoreId(), storeSettlementDay.getSettlementDay(), endTime);
|
||||
|
||||
//修改店铺结算时间
|
||||
storeDetailService.updateSettlementDay(storeSettlementDay.getStoreId(), endTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.lili.timetask.handler.impl.broadcast;
|
||||
|
||||
import cn.lili.modules.goods.service.CommodityService;
|
||||
import cn.lili.timetask.handler.EveryHourExecute;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 小程序直播状态获取
|
||||
*
|
||||
* @author Bulbasaur
|
||||
* @since 2021/5/20 2:52 下午
|
||||
*/
|
||||
@Component
|
||||
public class BroadcastExecute implements EveryHourExecute {
|
||||
|
||||
@Autowired
|
||||
private CommodityService commodityService;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
//同步直播商品状态
|
||||
commodityService.getGoodsWareHouse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.lili.timetask.handler.impl.coupon;
|
||||
|
||||
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
|
||||
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
|
||||
import cn.lili.modules.promotion.service.MemberCouponService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 优惠券状态监测
|
||||
*
|
||||
* @author Bulbasaur
|
||||
* @since 2021/5/24 10:08 上午
|
||||
*/
|
||||
@Component
|
||||
public class CouponExecute implements EveryDayExecute {
|
||||
|
||||
/**
|
||||
* 过期常量,过期后或者使用后一定时间内,删除无效的优惠券,物理删除
|
||||
*/
|
||||
static final int EXPIRATION_DAY = 3;
|
||||
|
||||
@Autowired
|
||||
private MemberCouponService memberCouponService;
|
||||
|
||||
/**
|
||||
* 检测优惠券的使用时间,超期未使用则失效
|
||||
* 此方法用于领取*天后失效优惠券使用
|
||||
*/
|
||||
@Override
|
||||
public void execute() {
|
||||
//将过期优惠券变更为过期状体
|
||||
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
|
||||
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
|
||||
.le(MemberCoupon::getEndTime, new Date())
|
||||
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
|
||||
this.memberCouponService.update(updateWrapper);
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - EXPIRATION_DAY);
|
||||
Date removeTime = calendar.getTime();
|
||||
//删除过期/已使用的优惠券
|
||||
LambdaUpdateWrapper<MemberCoupon> deleteWrapper = new LambdaUpdateWrapper<MemberCoupon>()
|
||||
//如果结束时间小于 当前时间增加指定删除日期,则删除
|
||||
.le(MemberCoupon::getEndTime, removeTime);
|
||||
this.memberCouponService.remove(deleteWrapper);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cn.lili.timetask.handler.impl.goods;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.lili.modules.goods.mapper.GoodsMapper;
|
||||
import cn.lili.modules.member.entity.dos.MemberEvaluation;
|
||||
import cn.lili.modules.member.mapper.MemberEvaluationMapper;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品定时器
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2021/3/18 3:23 下午
|
||||
*/
|
||||
@Component
|
||||
public class GoodsExecute implements EveryDayExecute {
|
||||
/**
|
||||
* 会员评价
|
||||
*/
|
||||
@Resource
|
||||
private MemberEvaluationMapper memberEvaluationMapper;
|
||||
/**
|
||||
* 商品
|
||||
*/
|
||||
@Resource
|
||||
private GoodsMapper goodsMapper;
|
||||
|
||||
/**
|
||||
* 查询已上架的商品的评价数量并赋值
|
||||
*/
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
//查询上次统计到本次的评价数量
|
||||
List<Map<String, Object>> list = memberEvaluationMapper.memberEvaluationNum(
|
||||
new QueryWrapper<MemberEvaluation>()
|
||||
.between("create_time", DateUtil.yesterday(), new DateTime()));
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
goodsMapper.addGoodsCommentNum(Convert.toInt(map.get("num").toString()), map.get("goods_id").toString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.lili.timetask.handler.impl.hotwords;
|
||||
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.cache.CachePrefix;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2021/3/11
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class HotWordsEveryDayTaskExecute implements EveryDayExecute {
|
||||
|
||||
@Autowired
|
||||
private Cache cache;
|
||||
|
||||
/**
|
||||
* 执行每日任务
|
||||
*/
|
||||
@Override
|
||||
public void execute() {
|
||||
//移除昨日的热搜词
|
||||
cache.remove(CachePrefix.HOT_WORD.getPrefix());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package cn.lili.timetask.handler.impl.order;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.modules.order.order.entity.dos.Order;
|
||||
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.OrderSetting;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import cn.lili.timetask.handler.EveryMinuteExecute;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 订单自动取消(每分钟执行)
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2021/3/11
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CancelOrderTaskExecute implements EveryMinuteExecute {
|
||||
/**
|
||||
* 订单
|
||||
*/
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
@Autowired
|
||||
private SettingService settingService;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
|
||||
OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
|
||||
if (orderSetting != null && orderSetting.getAutoCancel() != null) {
|
||||
//订单自动取消时间 = 当前时间 - 自动取消时间分钟数
|
||||
DateTime cancelTime = DateUtil.offsetMinute(DateUtil.date(), -orderSetting.getAutoCancel());
|
||||
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.UNPAID.name());
|
||||
//订单创建时间 <= 订单自动取消时间
|
||||
queryWrapper.le(Order::getCreateTime, cancelTime);
|
||||
List<Order> list = orderService.list(queryWrapper);
|
||||
List<String> cancelSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
|
||||
for (String sn : cancelSnList) {
|
||||
orderService.systemCancel(sn, "超时未支付自动取消");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package cn.lili.timetask.handler.impl.order;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.member.entity.dto.MemberEvaluationDTO;
|
||||
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
|
||||
import cn.lili.modules.member.service.MemberEvaluationService;
|
||||
import cn.lili.modules.order.aftersale.service.AfterSaleService;
|
||||
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.enums.CommentStatusEnum;
|
||||
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.mapper.OrderItemMapper;
|
||||
import cn.lili.modules.order.order.service.OrderItemService;
|
||||
import cn.lili.modules.order.order.service.OrderService;
|
||||
import cn.lili.modules.system.entity.dos.Setting;
|
||||
import cn.lili.modules.system.entity.dto.OrderSetting;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2021/3/11
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
|
||||
public class OrderEveryDayTaskExecute implements EveryDayExecute {
|
||||
|
||||
/**
|
||||
* 订单
|
||||
*/
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
/**
|
||||
* 订单货物
|
||||
*/
|
||||
@Autowired
|
||||
private OrderItemService orderItemService;
|
||||
@Resource
|
||||
private OrderItemMapper orderItemMapper;
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
@Autowired
|
||||
private SettingService settingService;
|
||||
/**
|
||||
* 会员评价
|
||||
*/
|
||||
@Autowired
|
||||
private MemberEvaluationService memberEvaluationService;
|
||||
|
||||
@Autowired
|
||||
private AfterSaleService afterSaleService;
|
||||
|
||||
/**
|
||||
* 执行每日任务
|
||||
*/
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
|
||||
//订单设置
|
||||
OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
|
||||
if (orderSetting == null) {
|
||||
throw new ServiceException(ResultCode.ORDER_SETTING_ERROR);
|
||||
}
|
||||
|
||||
//自动确认收货
|
||||
completedOrder(orderSetting);
|
||||
//自动好评
|
||||
memberEvaluation(orderSetting);
|
||||
//关闭允许售后申请
|
||||
closeAfterSale(orderSetting);
|
||||
//关闭允许投诉
|
||||
closeComplaint(orderSetting);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动确认收获,订单完成
|
||||
*
|
||||
* @param orderSetting 订单设置
|
||||
*/
|
||||
private void completedOrder(OrderSetting orderSetting) {
|
||||
|
||||
|
||||
//订单自动收货时间 = 当前时间 - 自动收货时间天数
|
||||
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoReceive());
|
||||
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.DELIVERED.name());
|
||||
|
||||
//订单发货时间 >= 订单自动收货时间
|
||||
queryWrapper.le(Order::getLogisticsTime, receiveTime);
|
||||
List<Order> list = orderService.list(queryWrapper);
|
||||
|
||||
//判断是否有符合条件的订单,进行订单完成处理
|
||||
if (!list.isEmpty()) {
|
||||
List<String> receiveSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
|
||||
for (String orderSn : receiveSnList) {
|
||||
orderService.systemComplete(orderSn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动好评
|
||||
*
|
||||
* @param orderSetting 订单设置
|
||||
*/
|
||||
private void memberEvaluation(OrderSetting orderSetting) {
|
||||
//订单自动收货时间 = 当前时间 - 自动收货时间天数
|
||||
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
|
||||
|
||||
//订单完成时间 <= 订单自动好评时间
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
queryWrapper.le("o.complete_time", receiveTime);
|
||||
queryWrapper.eq("oi.comment_status", CommentStatusEnum.UNFINISHED.name());
|
||||
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
|
||||
|
||||
//判断是否有符合条件的订单,进行自动评价处理
|
||||
if (!orderItems.isEmpty()) {
|
||||
for (OrderItem orderItem : orderItems) {
|
||||
MemberEvaluationDTO memberEvaluationDTO = new MemberEvaluationDTO();
|
||||
memberEvaluationDTO.setOrderItemSn(orderItem.getSn());
|
||||
memberEvaluationDTO.setContent("系统默认好评");
|
||||
memberEvaluationDTO.setGoodsId(orderItem.getGoodsId());
|
||||
memberEvaluationDTO.setSkuId(orderItem.getSkuId());
|
||||
memberEvaluationDTO.setGrade(EvaluationGradeEnum.GOOD.name());
|
||||
memberEvaluationDTO.setDeliveryScore(5);
|
||||
memberEvaluationDTO.setDescriptionScore(5);
|
||||
memberEvaluationDTO.setServiceScore(5);
|
||||
|
||||
memberEvaluationService.addMemberEvaluation(memberEvaluationDTO, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 关闭允许售后申请
|
||||
*
|
||||
* @param orderSetting 订单设置
|
||||
*/
|
||||
private void closeAfterSale(OrderSetting orderSetting) {
|
||||
|
||||
//订单关闭售后申请时间 = 当前时间 - 自动关闭售后申请天数
|
||||
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
|
||||
|
||||
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
queryWrapper.le("o.complete_time", receiveTime);
|
||||
queryWrapper.eq("oi.after_sale_status", OrderItemAfterSaleStatusEnum.NOT_APPLIED.name());
|
||||
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
|
||||
|
||||
//判断是否有符合条件的订单,关闭允许售后申请处理
|
||||
if (!orderItems.isEmpty()) {
|
||||
|
||||
//获取订单货物ID
|
||||
List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
|
||||
|
||||
//修改订单售后状态
|
||||
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
|
||||
.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
|
||||
.in(OrderItem::getId, orderItemIdList);
|
||||
orderItemService.update(lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭允许交易投诉
|
||||
*
|
||||
* @param orderSetting 订单设置
|
||||
*/
|
||||
private void closeComplaint(OrderSetting orderSetting) {
|
||||
|
||||
//订单关闭交易投诉申请时间 = 当前时间 - 自动关闭交易投诉申请天数
|
||||
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getCloseComplaint());
|
||||
|
||||
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
queryWrapper.le("o.complete_time", receiveTime);
|
||||
queryWrapper.eq("oi.complain_status", OrderComplaintStatusEnum.NO_APPLY.name());
|
||||
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
|
||||
|
||||
//判断是否有符合条件的订单,关闭允许售后申请处理
|
||||
if (!orderItems.isEmpty()) {
|
||||
|
||||
//获取订单货物ID
|
||||
List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
|
||||
|
||||
//修改订单投诉状态
|
||||
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
|
||||
.set(OrderItem::getComplainStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
|
||||
.in(OrderItem::getId, orderItemIdList);
|
||||
orderItemService.update(lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package cn.lili.timetask.handler.impl.order;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
|
||||
import cn.lili.modules.system.entity.dos.Setting;
|
||||
import cn.lili.modules.system.entity.dto.OrderSetting;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import cn.lili.modules.wallet.entity.dos.Recharge;
|
||||
import cn.lili.modules.wallet.service.RechargeService;
|
||||
import cn.lili.timetask.handler.EveryMinuteExecute;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 充值订单自动取消(每分钟执行)
|
||||
*
|
||||
* @author zhuhai
|
||||
* @since 2021/3/11
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RechargeOrderTaskExecute implements EveryMinuteExecute {
|
||||
/**
|
||||
* 充值
|
||||
*/
|
||||
@Autowired
|
||||
private RechargeService rechargeService;
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
@Autowired
|
||||
private SettingService settingService;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
|
||||
OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
|
||||
if (orderSetting != null && orderSetting.getAutoCancel() != null) {
|
||||
//充值订单自动取消时间 = 当前时间 - 自动取消时间分钟数
|
||||
DateTime cancelTime = DateUtil.offsetMinute(DateUtil.date(), -orderSetting.getAutoCancel());
|
||||
LambdaQueryWrapper<Recharge> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Recharge::getPayStatus, PayStatusEnum.UNPAID.name());
|
||||
//充值订单创建时间 <= 订单自动取消时间
|
||||
queryWrapper.le(Recharge::getCreateTime, cancelTime);
|
||||
List<Recharge> list = rechargeService.list(queryWrapper);
|
||||
List<String> cancelSnList = list.stream().map(Recharge::getRechargeSn).collect(Collectors.toList());
|
||||
for (String sn : cancelSnList) {
|
||||
rechargeService.rechargeOrderCancel(sn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package cn.lili.timetask.handler.impl.promotion;
|
||||
|
||||
import cn.lili.modules.promotion.entity.dos.Seckill;
|
||||
import cn.lili.modules.promotion.service.SeckillService;
|
||||
import cn.lili.modules.search.service.EsGoodsIndexService;
|
||||
import cn.lili.modules.system.entity.dos.Setting;
|
||||
import cn.lili.modules.system.entity.dto.SeckillSetting;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 促销活动每日定时器
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2021/3/18 3:23 下午
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PromotionEverydayExecute implements EveryDayExecute {
|
||||
|
||||
/**
|
||||
* ES商品索引
|
||||
*/
|
||||
@Autowired
|
||||
private EsGoodsIndexService esGoodsIndexService;
|
||||
/**
|
||||
* 系统设置
|
||||
*/
|
||||
@Autowired
|
||||
private SettingService settingService;
|
||||
/**
|
||||
* 秒杀活动
|
||||
*/
|
||||
@Autowired
|
||||
private SeckillService seckillService;
|
||||
|
||||
/**
|
||||
* 将已过期的促销活动置为结束
|
||||
*/
|
||||
@Override
|
||||
public void execute() {
|
||||
//清除所以商品索引的无效促销活动
|
||||
this.esGoodsIndexService.cleanInvalidPromotion();
|
||||
//定时创建活动
|
||||
addSeckill();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加秒杀活动
|
||||
* 从系统设置中获取秒杀活动的配置
|
||||
* 添加30天后的秒杀活动
|
||||
*/
|
||||
private void addSeckill() {
|
||||
Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
|
||||
SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
|
||||
for (int i = 1; i <= SeckillService.PRE_CREATION; i++) {
|
||||
Seckill seckill = new Seckill(i, seckillSetting.getHours(), seckillSetting.getSeckillRule());
|
||||
seckillService.savePromotions(seckill);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package cn.lili.timetask.handler.impl.statistics;
|
||||
|
||||
import cn.lili.modules.statistics.entity.dos.MemberStatisticsData;
|
||||
import cn.lili.modules.statistics.service.MemberStatisticsService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 会员数据统计
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2021-03-02 14:56
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MemberStatisticsExecute implements EveryDayExecute {
|
||||
|
||||
/**
|
||||
* 会员统计
|
||||
*/
|
||||
@Autowired
|
||||
private MemberStatisticsService memberStatisticsService;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
try {
|
||||
//统计的时间(开始。结束时间)
|
||||
Date startTime, endTime;
|
||||
//初始值
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 1);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
endTime = calendar.getTime();
|
||||
//-1天,即为开始时间
|
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
|
||||
startTime = calendar.getTime();
|
||||
MemberStatisticsData memberStatisticsData = new MemberStatisticsData();
|
||||
memberStatisticsData.setMemberCount(memberStatisticsService.memberCount(endTime));
|
||||
memberStatisticsData.setCreateDate(startTime);
|
||||
memberStatisticsData.setActiveQuantity(memberStatisticsService.activeQuantity(startTime));
|
||||
memberStatisticsData.setNewlyAdded(memberStatisticsService.newlyAdded(startTime, endTime));
|
||||
memberStatisticsService.save(memberStatisticsData);
|
||||
} catch (Exception e) {
|
||||
log.error("每日会员统计功能异常:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package cn.lili.timetask.handler.impl.statistics;
|
||||
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.cache.CachePrefix;
|
||||
import cn.lili.common.security.enums.UserEnums;
|
||||
import cn.lili.common.properties.StatisticsProperties;
|
||||
import cn.lili.modules.statistics.entity.vo.OnlineMemberVO;
|
||||
import cn.lili.timetask.handler.EveryHourExecute;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 实时在线人数统计
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2021-02-21 09:47
|
||||
*/
|
||||
@Component
|
||||
public class OnlineMemberStatistics implements EveryHourExecute {
|
||||
|
||||
/**
|
||||
* 缓存
|
||||
*/
|
||||
@Autowired
|
||||
private Cache<List<OnlineMemberVO>> cache;
|
||||
/**
|
||||
* 统计小时
|
||||
*/
|
||||
@Autowired
|
||||
private StatisticsProperties statisticsProperties;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
|
||||
List<OnlineMemberVO> onlineMemberVOS = cache.get(CachePrefix.ONLINE_MEMBER.getPrefix());
|
||||
|
||||
if (onlineMemberVOS == null) {
|
||||
onlineMemberVOS = new ArrayList<>();
|
||||
}
|
||||
|
||||
//过滤 有效统计时间
|
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - statisticsProperties.getOnlineMember());
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
Calendar finalCalendar = calendar;
|
||||
onlineMemberVOS = onlineMemberVOS.stream()
|
||||
.filter(onlineMemberVO -> onlineMemberVO.getDate().after(finalCalendar.getTime()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
//计入新数据
|
||||
calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
onlineMemberVOS.add(new OnlineMemberVO(calendar.getTime(), cache.keys(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + "*").size()));
|
||||
|
||||
//写入缓存
|
||||
cache.put(CachePrefix.ONLINE_MEMBER.getPrefix(), onlineMemberVOS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 手动设置某一时间,活跃人数
|
||||
*
|
||||
* @param time 时间
|
||||
* @param num 人数
|
||||
*/
|
||||
public void execute(Date time, Integer num) {
|
||||
|
||||
List<OnlineMemberVO> onlineMemberVOS = cache.get(CachePrefix.ONLINE_MEMBER.getPrefix());
|
||||
|
||||
if (onlineMemberVOS == null) {
|
||||
onlineMemberVOS = new ArrayList<>();
|
||||
}
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(time);
|
||||
//过滤 有效统计时间
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 48);
|
||||
|
||||
onlineMemberVOS = onlineMemberVOS.stream()
|
||||
.filter(onlineMemberVO -> onlineMemberVO.getDate().after(calendar.getTime()))
|
||||
.collect(Collectors.toList());
|
||||
onlineMemberVOS.add(new OnlineMemberVO(time, num));
|
||||
|
||||
//写入缓存
|
||||
cache.put(CachePrefix.ONLINE_MEMBER.getPrefix(), onlineMemberVOS);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.lili.timetask.handler.impl.storerating;
|
||||
|
||||
import cn.lili.common.enums.SwitchEnum;
|
||||
import cn.lili.modules.member.entity.dos.MemberEvaluation;
|
||||
import cn.lili.modules.member.entity.vo.StoreRatingVO;
|
||||
import cn.lili.modules.member.mapper.MemberEvaluationMapper;
|
||||
import cn.lili.modules.store.entity.dos.Store;
|
||||
import cn.lili.modules.store.entity.enums.StoreStatusEnum;
|
||||
import cn.lili.modules.store.service.StoreService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 店铺评分
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2021/3/15 5:30 下午
|
||||
*/
|
||||
@Component
|
||||
public class StoreRatingExecute implements EveryDayExecute {
|
||||
/**
|
||||
* 店铺
|
||||
*/
|
||||
@Autowired
|
||||
private StoreService storeService;
|
||||
/**
|
||||
* 会员评价
|
||||
*/
|
||||
@Resource
|
||||
private MemberEvaluationMapper memberEvaluationMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
//获取所有开启的店铺
|
||||
List<Store> storeList = storeService.list(new LambdaQueryWrapper<Store>().eq(Store::getStoreDisable, StoreStatusEnum.OPEN.name()));
|
||||
for (Store store : storeList) {
|
||||
//店铺所有开启的评价
|
||||
LambdaQueryWrapper<MemberEvaluation> lambdaQueryWrapper = Wrappers.lambdaQuery();
|
||||
lambdaQueryWrapper.eq(MemberEvaluation::getStoreId, store.getId());
|
||||
lambdaQueryWrapper.eq(MemberEvaluation::getStatus, SwitchEnum.OPEN.name());
|
||||
StoreRatingVO storeRatingVO = memberEvaluationMapper.getStoreRatingVO(lambdaQueryWrapper);
|
||||
|
||||
if (storeRatingVO != null) {
|
||||
//保存评分
|
||||
LambdaUpdateWrapper<Store> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
|
||||
lambdaUpdateWrapper.eq(Store::getId, store.getId());
|
||||
lambdaUpdateWrapper.set(Store::getDescriptionScore, storeRatingVO.getDescriptionScore());
|
||||
lambdaUpdateWrapper.set(Store::getDeliveryScore, storeRatingVO.getDeliveryScore());
|
||||
lambdaUpdateWrapper.set(Store::getServiceScore, storeRatingVO.getServiceScore());
|
||||
storeService.update(lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
package cn.lili.timetask.handler.impl.view;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.cache.CachePrefix;
|
||||
import cn.lili.common.utils.BeanUtil;
|
||||
import cn.lili.modules.statistics.entity.dos.PlatformViewData;
|
||||
import cn.lili.modules.statistics.service.PlatformViewService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 统计 入库
|
||||
*
|
||||
* @author Chopper
|
||||
* @since 2021-01-15 18:20
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PageViewStatisticsExecute implements EveryDayExecute {
|
||||
/**
|
||||
* 缓存
|
||||
*/
|
||||
@Autowired
|
||||
private Cache cache;
|
||||
/**
|
||||
* 平台PV统计
|
||||
*/
|
||||
@Autowired
|
||||
private PlatformViewService platformViewService;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
//1、缓存keys 模糊匹配
|
||||
//2、过滤今日的数据,即今天只能统计今日以前的数据
|
||||
//4对key value 分别代表平台PV、平台UV、店铺PV、店铺UV
|
||||
List<String> pvKeys = filterKeys(cache.keys(CachePrefix.PV.getPrefix() + "*"));
|
||||
List<Integer> pvValues = cache.multiGet(pvKeys);
|
||||
|
||||
List<String> storePVKeys = filterKeys(cache.keys(CachePrefix.STORE_PV.getPrefix() + "*"));
|
||||
List<Integer> storePvValues = cache.multiGet(storePVKeys);
|
||||
|
||||
//备份UV数据,这里赋值之后,会被删除
|
||||
List<String> uvKeys = new ArrayList<>();
|
||||
List<String> storeUvKeys = new ArrayList<>();
|
||||
|
||||
log.debug("开始统计平台数据,PV共计【{}】条", pvKeys.size());
|
||||
log.debug("开始统计店铺数据,PV共计【{}】条", storePvValues.size());
|
||||
|
||||
//定义要统计的数据
|
||||
List<PlatformViewData> platformViewDataList = new ArrayList<>();
|
||||
|
||||
//PV 统计
|
||||
if (pvKeys.size() > 0) {
|
||||
for (int i = 0; i < pvKeys.size(); i++) {
|
||||
String key = pvKeys.get(i);
|
||||
PageViewStatistics pageViewStatistics = new PageViewStatistics(key);
|
||||
PlatformViewData platformPVData = new PlatformViewData();
|
||||
BeanUtil.copyProperties(pageViewStatistics, platformPVData);
|
||||
platformPVData.setPvNum(pvValues.get(i).longValue());
|
||||
//根据pvkey 获取 uvkey
|
||||
String uvKey = getUvKey(key);
|
||||
uvKeys.add(uvKey);
|
||||
platformPVData.setUvNum(cache.counter(uvKey));
|
||||
platformPVData.setStoreId("-1");
|
||||
platformViewDataList.add(platformPVData);
|
||||
}
|
||||
batchSave(pvKeys, uvKeys, platformViewDataList);
|
||||
}
|
||||
//店铺 PV 统计
|
||||
if (storePVKeys.size() > 0) {
|
||||
platformViewDataList = new ArrayList<>();
|
||||
for (int i = 0; i < storePVKeys.size(); i++) {
|
||||
String key = storePVKeys.get(i);
|
||||
PageViewStatistics pageViewStatistics = new PageViewStatistics(key);
|
||||
PlatformViewData storePVData = new PlatformViewData();
|
||||
BeanUtil.copyProperties(pageViewStatistics, storePVData);
|
||||
storePVData.setPvNum(storePvValues.get(i).longValue());
|
||||
//根据pvkey 获取 uvkey
|
||||
String uvKey = getUvKey(key);
|
||||
uvKeys.add(uvKey);
|
||||
storePVData.setUvNum(cache.counter(uvKey));
|
||||
platformViewDataList.add(storePVData);
|
||||
}
|
||||
batchSave(storePVKeys, storeUvKeys, platformViewDataList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据缓存的PVkey 获取对应的UVkey
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
private String getUvKey(String key) {
|
||||
if (StringUtils.isNotEmpty(key)) {
|
||||
|
||||
key = key.replace(CachePrefix.PV.getPrefix(), CachePrefix.UV.getPrefix());
|
||||
key = key.replace(CachePrefix.STORE_PV.getPrefix(), CachePrefix.STORE_UV.getPrefix());
|
||||
return key;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存数据&&清除保存数据的缓存
|
||||
*
|
||||
* @param pvKeys PV key
|
||||
* @param uvKeys UV key
|
||||
* @param platformViewData DOS
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
void batchSave(List<String> pvKeys, List<String> uvKeys, List<PlatformViewData> platformViewData) {
|
||||
log.debug("批量保存流量数据,共计【{}】条", platformViewData.size());
|
||||
platformViewService.saveBatch(platformViewData);
|
||||
//批量删除缓存key
|
||||
cache.multiDel(pvKeys);
|
||||
cache.multiDel(uvKeys);
|
||||
log.debug("流量数据保存完成");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 过滤缓存key
|
||||
*
|
||||
* @param keys 缓存key集合
|
||||
*/
|
||||
private static List<String> filterKeys(List<String> keys) {
|
||||
|
||||
//只统计一天前的数据
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.HOUR_OF_DAY, -24);
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String key : keys) {
|
||||
PageViewStatistics temp = new PageViewStatistics(key);
|
||||
//如果需要统计,则将key写入集合
|
||||
if (temp.getDate().before(calendar.getTime())) {
|
||||
result.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据缓存key 获取其中需要的参数,年月日,以及店铺信息
|
||||
*/
|
||||
@Data
|
||||
class PageViewStatistics {
|
||||
/**
|
||||
* 年 、 月 、 日 、 店铺id
|
||||
*/
|
||||
private Date date;
|
||||
private String storeId;
|
||||
|
||||
public PageViewStatistics(String str) {
|
||||
//将字符串解析成需要的对象
|
||||
str = str.substring(str.indexOf("}") + 2);
|
||||
String[] dateStr = str.split("-");
|
||||
Integer year = Convert.toInt(dateStr[0]);
|
||||
Integer month = Convert.toInt(dateStr[1]);
|
||||
Integer day;
|
||||
//是否有店铺id
|
||||
if (dateStr.length > 3) {
|
||||
day = Convert.toInt(dateStr[2]);
|
||||
this.storeId = dateStr[3];
|
||||
} else {
|
||||
day = Convert.toInt(dateStr[2]);
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
calendar.set(Calendar.MONTH, month - 1);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, day);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
this.date = calendar.getTime();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package cn.lili.trigger;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.common.utils.ThreadPoolUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.data.redis.core.DefaultTypedTuple;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 延时队列工厂
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2020/11/7
|
||||
**/
|
||||
@Slf4j
|
||||
public abstract class AbstractDelayQueueListen implements ApplicationRunner {
|
||||
|
||||
@Autowired
|
||||
private Cache cache;
|
||||
|
||||
|
||||
/**
|
||||
* 延时队列机器开始运作
|
||||
*/
|
||||
private void startDelayQueueMachine() {
|
||||
log.info("延时队列机器{}开始运作", setDelayQueueName());
|
||||
|
||||
//监听redis队列
|
||||
while (true) {
|
||||
try {
|
||||
//获取当前时间的时间戳
|
||||
long now = System.currentTimeMillis() / 1000;
|
||||
//获取当前时间前需要执行的任务列表
|
||||
Set<DefaultTypedTuple> tuples = cache.zRangeByScore(setDelayQueueName(), 0, now);
|
||||
|
||||
//如果任务不为空
|
||||
if (!CollectionUtils.isEmpty(tuples)) {
|
||||
log.info("执行任务:{}", JSONUtil.toJsonStr(tuples));
|
||||
|
||||
for (DefaultTypedTuple tuple : tuples) {
|
||||
String jobId = (String) tuple.getValue();
|
||||
//移除缓存,如果移除成功则表示当前线程处理了延时任务,则执行延时任务
|
||||
Long num = cache.zRemove(setDelayQueueName(), jobId);
|
||||
//如果移除成功, 则执行
|
||||
if (num > 0) {
|
||||
ThreadPoolUtil.execute(() -> invoke(jobId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理延时任务发生异常,异常原因为{}", e.getMessage(), e);
|
||||
} finally {
|
||||
//间隔一秒钟搞一次
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(5L);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 最终执行的任务方法
|
||||
*
|
||||
* @param jobId 任务id
|
||||
*/
|
||||
public abstract void invoke(String jobId);
|
||||
|
||||
|
||||
/**
|
||||
* 要实现延时队列的名字
|
||||
* @return 促销延时队列名称
|
||||
*/
|
||||
public abstract String setDelayQueueName();
|
||||
|
||||
|
||||
/**
|
||||
* 监听队列
|
||||
*/
|
||||
public void init() {
|
||||
ThreadPoolUtil.getPool().execute(this::startDelayQueueMachine);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.lili.trigger;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.trigger.model.TimeTriggerMsg;
|
||||
import cn.lili.trigger.util.DelayQueueTools;
|
||||
import cn.lili.common.utils.SpringContextUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 事件触发消费者
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2020/11/17 7:19 下午
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
@RocketMQMessageListener(topic = "${lili.data.rocketmq.promotion-topic}", consumerGroup = "${lili.data.rocketmq.promotion-group}")
|
||||
public class TimeTriggerConsumer implements RocketMQListener<TimeTriggerMsg> {
|
||||
@Autowired
|
||||
private Cache<Integer> cache;
|
||||
|
||||
@Override
|
||||
public void onMessage(TimeTriggerMsg timeTriggerMsg) {
|
||||
try {
|
||||
String key = DelayQueueTools.generateKey(timeTriggerMsg.getTriggerExecutor(), timeTriggerMsg.getTriggerTime(), timeTriggerMsg.getUniqueKey());
|
||||
|
||||
if (cache.get(key) == null) {
|
||||
log.info("执行器执行被取消:{} | 任务标识:{}", timeTriggerMsg.getTriggerExecutor(), timeTriggerMsg.getUniqueKey());
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("执行器执行:" + timeTriggerMsg.getTriggerExecutor());
|
||||
log.info("执行器参数:" + JSONUtil.toJsonStr(timeTriggerMsg.getParam()));
|
||||
|
||||
cache.remove(key);
|
||||
|
||||
TimeTriggerExecutor executor = (TimeTriggerExecutor) SpringContextUtil.getBean(timeTriggerMsg.getTriggerExecutor());
|
||||
executor.execute(timeTriggerMsg.getParam());
|
||||
} catch (Exception e) {
|
||||
log.error("mq延时任务异常", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.lili.trigger;
|
||||
|
||||
/**
|
||||
* 延时任务执行器接口
|
||||
*
|
||||
* @author Chopper
|
||||
*/
|
||||
public interface TimeTriggerExecutor {
|
||||
|
||||
|
||||
/**
|
||||
* 执行任务
|
||||
*
|
||||
* @param object 任务参数
|
||||
*/
|
||||
void execute(Object object);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.lili.trigger.executor;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.modules.goods.service.StudioService;
|
||||
import cn.lili.trigger.TimeTriggerExecutor;
|
||||
import cn.lili.trigger.message.BroadcastMessage;
|
||||
import cn.lili.trigger.model.TimeExecuteConstant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 直播间事件触发
|
||||
*
|
||||
* @author Bulbasaur
|
||||
* @since 2021/6/1 5:02 下午
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(TimeExecuteConstant.BROADCAST_EXECUTOR)
|
||||
public class BroadcastTimeTriggerExecutor implements TimeTriggerExecutor {
|
||||
|
||||
|
||||
@Autowired
|
||||
private StudioService studioService;
|
||||
|
||||
@Override
|
||||
public void execute(Object object) {
|
||||
//直播间订单消息
|
||||
BroadcastMessage broadcastMessage = JSONUtil.toBean(JSONUtil.parseObj(object), BroadcastMessage.class);
|
||||
if (broadcastMessage != null && broadcastMessage.getStudioId() != null) {
|
||||
log.info("直播间消费:{}", broadcastMessage);
|
||||
//修改直播间状态
|
||||
studioService.updateStudioStatus(broadcastMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.lili.trigger.executor;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.modules.order.order.service.OrderService;
|
||||
import cn.lili.modules.promotion.entity.dos.Pintuan;
|
||||
import cn.lili.trigger.TimeTriggerExecutor;
|
||||
import cn.lili.trigger.message.PintuanOrderMessage;
|
||||
import cn.lili.trigger.model.TimeExecuteConstant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 促销事件触发
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v4.1
|
||||
* @since 2020/11/17 7:20 下午
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(TimeExecuteConstant.PROMOTION_EXECUTOR)
|
||||
public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
|
||||
/**
|
||||
* 订单
|
||||
*/
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(Object object) {
|
||||
//拼团订单消息
|
||||
PintuanOrderMessage pintuanOrderMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PintuanOrderMessage.class);
|
||||
if (pintuanOrderMessage != null && pintuanOrderMessage.getPintuanId() != null) {
|
||||
log.info("拼团订单信息消费:{}", pintuanOrderMessage);
|
||||
//拼团订单自动处理
|
||||
orderService.agglomeratePintuanOrder(pintuanOrderMessage.getPintuanId(), pintuanOrderMessage.getOrderSn());
|
||||
}
|
||||
Pintuan pintuan = JSONUtil.toBean(JSONUtil.parseObj(object), Pintuan.class);
|
||||
if (pintuan != null && pintuan.getId() != null) {
|
||||
this.orderService.checkFictitiousOrder(pintuan.getId(), pintuan.getRequiredNum(), pintuan.getFictitious());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.lili.trigger.listen;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.trigger.AbstractDelayQueueListen;
|
||||
import cn.lili.trigger.enums.DelayQueueEnums;
|
||||
import cn.lili.trigger.interfaces.TimeTrigger;
|
||||
import cn.lili.trigger.model.TimeTriggerMsg;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* PromotionTimeTriggerListen
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2021-06-11 10:47
|
||||
*/
|
||||
@Component
|
||||
public class PromotionDelayQueueListen extends AbstractDelayQueueListen {
|
||||
|
||||
@Autowired
|
||||
private TimeTrigger timeTrigger;
|
||||
|
||||
@Override
|
||||
public void invoke(String jobId) {
|
||||
timeTrigger.execute(JSONUtil.toBean(jobId, TimeTriggerMsg.class));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String setDelayQueueName() {
|
||||
return DelayQueueEnums.PROMOTION.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user