fix: 定时精准发送优惠券被立即发送问题处理。自动领取优惠券时会触发精准发券全平台会员

This commit is contained in:
Chopper711 2023-10-13 15:35:47 +08:00
parent 23182106b9
commit d1c6988d0f
8 changed files with 120 additions and 12 deletions

View File

@ -0,0 +1,31 @@
package cn.lili.trigger.executor;
import cn.hutool.json.JSONUtil;
import cn.lili.modules.promotion.service.CouponActivityService;
import cn.lili.trigger.TimeTriggerExecutor;
import cn.lili.trigger.message.CouponActivityMessage;
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.COUPON_ACTIVITY_EXECUTOR)
public class CouponActivityTriggerExecutor implements TimeTriggerExecutor {
@Autowired
private CouponActivityService couponActivityService;
@Override
public void execute(Object object) {
CouponActivityMessage couponActivityMessage = JSONUtil.toBean(JSONUtil.parseObj(object), CouponActivityMessage.class);
couponActivityService.specifyCoupon(couponActivityMessage.getCouponActivityId());
}
}

View File

@ -24,6 +24,9 @@ public enum CouponFrequencyEnum {
}
public static boolean exist(String name) {
if (name == null) {
return false;
}
try {
CouponFrequencyEnum.valueOf(name);
} catch (IllegalArgumentException e) {

View File

@ -32,6 +32,13 @@ public interface CouponActivityService extends AbstractPromotionsService<CouponA
*/
void specify(CouponActivity couponActivity);
/**
* 精准发券
*
* @param couponActivityId 精准发券活动ID
*/
void specifyCoupon(String couponActivityId);
/**
* 用户优惠券活动触发
*

View File

@ -7,6 +7,7 @@ import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.AuthUser;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.promotion.entity.dos.Coupon;
@ -21,6 +22,12 @@ import cn.lili.modules.promotion.entity.vos.CouponActivityVO;
import cn.lili.modules.promotion.mapper.CouponActivityMapper;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.promotion.tools.PromotionTools;
import cn.lili.trigger.enums.DelayTypeEnums;
import cn.lili.trigger.interfaces.TimeTrigger;
import cn.lili.trigger.message.CouponActivityMessage;
import cn.lili.trigger.model.TimeExecuteConstant;
import cn.lili.trigger.model.TimeTriggerMsg;
import cn.lili.trigger.util.DelayQueueTools;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import groovy.util.logging.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -60,6 +67,16 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
@Autowired
private Cache<List<CouponActivityVO>> cache;
/**
* 延时任务
*/
@Autowired
private TimeTrigger timeTrigger;
/**
* RocketMQ
*/
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
@Override
public CouponActivityVO getCouponActivityVO(String couponActivityId) {
@ -67,9 +84,31 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
return new CouponActivityVO(couponActivity, couponActivityItemService.getCouponActivityItemListVO(couponActivityId));
}
@Override
public void specify(CouponActivity couponActivity) {
//如果开始时间为空则表示活动关闭
if (couponActivity.getStartTime() == null) {
return;
}
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.COUPON_ACTIVITY_EXECUTOR,
couponActivity.getStartTime().getTime(),
CouponActivityMessage.builder().couponActivityId(couponActivity.getId()).build(),
DelayQueueTools.wrapperUniqueKey(DelayTypeEnums.COUPON_ACTIVITY, couponActivity.getId()),
rocketmqCustomProperties.getPromotionTopic());
//发送促销活动开始的延时任务
timeTrigger.addDelay(timeTriggerMsg);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void specify(CouponActivity couponActivity) {
public void specifyCoupon(String couponActivityId) {
//获取优惠券活动
CouponActivity couponActivity = this.getById(couponActivityId);
//获取活动优惠券发送范围
List<Map<String, Object>> member = this.getMemberList(couponActivity);
@ -92,7 +131,6 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
sendCoupon(memberList, couponActivityItems);
}
}
}
/**
@ -119,8 +157,6 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
*/
@Override
public void checkPromotions(CouponActivity couponActivity) {
super.checkPromotions(couponActivity);
if (couponActivity instanceof CouponActivityDTO) {
CouponActivityDTO couponActivityDTO = (CouponActivityDTO) couponActivity;
//指定会员判定
@ -170,6 +206,7 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
// 精准发券 则立即发放
case SPECIFY:
this.specify(couponActivity);
this.resetCache(couponActivity.getCouponActivityType());
break;
//其他活动则是缓存模块根据缓存中的优惠券活动信息来确认发放优惠券测略
case INVITE_NEW:
@ -259,7 +296,7 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
* @return
*/
private List<CouponActivityVO> ongoingActivities(List<CouponActivityVO> activityVOS) {
if (activityVOS == null || activityVOS.size() == 0) {
if (activityVOS == null || activityVOS.isEmpty()) {
return new ArrayList<>();
}
return activityVOS.stream().filter(item -> {

View File

@ -1,19 +1,17 @@
package cn.lili.modules.promotion.serviceimpl;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.DateUtil;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.dos.MemberCouponSign;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.CouponFrequencyEnum;
import cn.lili.modules.promotion.entity.vos.CouponActivityVO;
import cn.lili.modules.promotion.mapper.MemberCouponSignMapper;
import cn.lili.modules.promotion.service.MemberCouponSignService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@ -33,15 +31,11 @@ import java.util.List;
public class MemberCouponSignServiceImpl extends ServiceImpl<MemberCouponSignMapper, MemberCouponSign> implements MemberCouponSignService {
@Autowired
private Cache cache;
@Override
public void clean() {
LambdaQueryWrapper<MemberCouponSign> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.lt(MemberCouponSign::getInvalidTime, DateUtil.getCurrentDayStartTime());
this.baseMapper.delete(queryWrapper);
cache.remove(CachePrefix.MEMBER_COUPON_SIGN.getPrefix());
}
@Override
@ -115,6 +109,9 @@ public class MemberCouponSignServiceImpl extends ServiceImpl<MemberCouponSignMap
throw new ServiceException();
}
} else if (activity.getCouponActivityType().equals(CouponActivityTypeEnum.SPECIFY.name())) {
//精准发券 则标记失效时间为活动结束时间 防止同一个活动同一周期被多次领取
return activity.getEndTime();
} else {
throw new ServiceException();
}

View File

@ -16,6 +16,10 @@ public enum DelayTypeEnums {
* 拼团订单
*/
PINTUAN_ORDER("拼团订单"),
/**
* 订单
*/
COUPON_ACTIVITY("优惠券活动"),
/**
* 直播

View File

@ -0,0 +1,25 @@
package cn.lili.trigger.message;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 信息队列传输促销信息实体
*
* @author paulG
* @date 2020/10/30
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class CouponActivityMessage {
/**
* 促销id
*/
private String couponActivityId;
}

View File

@ -18,4 +18,8 @@ public interface TimeExecuteConstant {
*/
public static final String BROADCAST_EXECUTOR = "broadcastTimeTriggerExecutor";
/**
* 促销延迟加载执行器
*/
public static final String COUPON_ACTIVITY_EXECUTOR = "couponActivityExecutor";
}