package com.xiaopeng.account.util;
|
|
|
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSONObject;
|
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 com.xiaopeng.account.constant.I18nKeyConstant;
|
import com.xiaopeng.account.service.IXpAppUserCouponService;
|
import com.xiaopeng.account.service.impl.XpAppUserCouponServiceImpl;
|
import com.xiaopeng.api.dto.account.UcUserInfo;
|
import com.xiaopeng.api.dto.operation.SmsDto;
|
import com.xiaopeng.api.feignClient.account.UserResourcesClient;
|
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
|
import com.xiaopeng.api.feignClient.operation.SmsClient;
|
import com.xiaopeng.api.feignClient.operation.XpActicityClient;
|
import com.xiaopeng.api.feignClient.operation.XpCouponClient;
|
import com.xiaopeng.api.feignClient.order.XpOrderClient;
|
import com.xiaopeng.api.feignClient.pushMessage.SubscribeMessageClient;
|
import com.xiaopeng.api.feignClient.pushMessage.WebSocketMessageClient;
|
import com.xiaopeng.api.model.account.XpAppUserCoupon;
|
import com.xiaopeng.api.model.operation.XpActicityStrategy;
|
import com.xiaopeng.api.model.operation.XpActivity;
|
import com.xiaopeng.api.model.operation.XpCoupon;
|
import com.xiaopeng.api.vo.operation.SmsVo;
|
import com.xiaopeng.api.vo.pushMessage.SendCouponMessageVo;
|
import com.xiaopeng.api.vo.pushMessage.SendSubscribeMessageVo;
|
import com.xiaopeng.common.core.constant.Constants;
|
import com.xiaopeng.common.core.domain.R;
|
import com.xiaopeng.common.core.enums.MessageTemplateEnum;
|
import com.xiaopeng.common.core.exception.ServiceException;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.StringUtils;
|
|
import javax.annotation.Resource;
|
import java.time.LocalDateTime;
|
import java.time.ZoneOffset;
|
import java.time.format.DateTimeFormatter;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.stream.Collectors;
|
|
@Slf4j
|
@Component
|
public class UserCouponTask {
|
|
@Resource
|
private IXpAppUserCouponService xpAppUserCouponService;
|
|
@Resource
|
private XpActicityClient acticityClient;
|
|
@Resource
|
private SubscribeMessageClient subscribeMessageClient;
|
|
@Resource
|
private XpCouponClient xpCouponClient;
|
|
@Resource
|
private SmsClient smsClient;
|
|
@Value("${sms.appid}")
|
private String sms_appid;
|
|
@Resource
|
private UserResourcesClient userResourcesClient;
|
|
@Resource
|
private WebSocketMessageClient webSocketMessageClient;
|
|
private static final ThreadPoolExecutor RETRY_EXECUTOR = new ThreadPoolExecutor(
|
4,
|
16,
|
60L, TimeUnit.SECONDS,
|
new LinkedBlockingQueue<>(512),
|
new ThreadFactory() {
|
private final AtomicInteger counter = new AtomicInteger(0);
|
@Override
|
public Thread newThread(Runnable r) {
|
Thread t = new Thread(r, "route-push-retry-" + counter.incrementAndGet());
|
t.setDaemon(true);
|
return t;
|
}
|
},
|
new ThreadPoolExecutor.CallerRunsPolicy()
|
);
|
|
|
/**
|
* 定时任务发送优惠券通知
|
*/
|
@Scheduled(fixedDelay = 30000)
|
public void taskOrder() {
|
List<XpActivity> activityList = acticityClient.getAllEffectiveActivity().getData();
|
List<XpActivity> collect1 = activityList.stream().filter(xpActivity -> null != xpActivity.getWechatNotification() && xpActivity.getWechatNotification() == 1).collect(Collectors.toList());
|
pushWxCouponMessage(collect1);
|
List<XpActivity> collect2 = activityList.stream().filter(xpActivity -> null != xpActivity.getSmsNotification() && xpActivity.getSmsNotification() == 1).collect(Collectors.toList());
|
pushSmsCouponMessage(collect2);
|
List<XpActivity> collect3 = activityList.stream().filter(xpActivity -> null != xpActivity.getMiniProgramNotification() && xpActivity.getMiniProgramNotification() == 1).collect(Collectors.toList());
|
pushMiniProgramCouponMessage(collect3);
|
editUserCouponStatus();
|
}
|
|
|
/**
|
* 微信通知
|
*/
|
private void pushWxCouponMessage(List<XpActivity> activityList) {
|
log.info("开始执行优惠券微信提醒消息发送 {}", activityList.size());
|
for (XpActivity xpActivity : activityList) {
|
//微信通知活动开始提醒(0=否,1=是)
|
Integer wechatActicityStart = xpActivity.getWechatActicityStart();
|
if(null != wechatActicityStart && 1 == wechatActicityStart){
|
RETRY_EXECUTOR.execute(() -> {
|
//即将到期提前通知
|
Integer wechatActicityStartMinutes = xpActivity.getWechatActicityStartMinutes();
|
//获取满足微信通知的即将生效的优惠券
|
long time = LocalDateTime.now().plusMinutes(wechatActicityStartMinutes).toEpochSecond(ZoneOffset.of("+8"));
|
List<XpAppUserCoupon> list = xpAppUserCouponService.list(new LambdaUpdateWrapper<XpAppUserCoupon>()
|
.eq(XpAppUserCoupon::getActivityId, xpActivity.getId()).eq(XpAppUserCoupon::getStatus, 1)
|
.last(" and UNIX_TIMESTAMP(effective_time) >= " + time + " and " + time + "> UNIX_TIMESTAMP(effective_time) - 100"));
|
if(list.isEmpty()){
|
return;
|
}
|
log.info("开始执行生效前优惠券微信提醒消息发送");
|
for (XpAppUserCoupon xpAppUserCoupon : list) {
|
XpCoupon coupon = xpCouponClient.getCouponById(xpAppUserCoupon.getCouponId()).getData();
|
SendSubscribeMessageVo vo = new SendSubscribeMessageVo();
|
vo.setUserId(xpAppUserCoupon.getAppUserId());
|
vo.setTemplateId(MessageTemplateEnum.C.getTemplateId());
|
String json = MessageTemplateEnum.C.getRemarks();
|
json = json.replace("活动名称", xpAppUserCoupon.getCouponName());
|
json = json.replace("温馨提示", coupon.getCouponDescription());
|
vo.setJson(json);
|
R<?> r = subscribeMessageClient.sendSubscribeMessage(vo);
|
}
|
});
|
}
|
|
//微信通知即将过期提醒(0=否,1=是)
|
Integer wechatAboutExpireReminder = xpActivity.getWechatAboutExpireReminder();
|
if(null != wechatAboutExpireReminder && 1 == wechatAboutExpireReminder){
|
RETRY_EXECUTOR.execute(() -> {
|
//即将到期提前通知
|
Integer wechatAboutExpireDays = xpActivity.getWechatAboutExpireDays();
|
//微信通知即将过期天数
|
long time = LocalDateTime.now().plusDays(wechatAboutExpireDays).toEpochSecond(ZoneOffset.of("+8"));
|
List<XpAppUserCoupon> list = xpAppUserCouponService.list(new LambdaUpdateWrapper<XpAppUserCoupon>()
|
.eq(XpAppUserCoupon::getActivityId, xpActivity.getId()).eq(XpAppUserCoupon::getStatus, 1)
|
.last(" and UNIX_TIMESTAMP(expiration_time) >= " + time + " and " + time + "> UNIX_TIMESTAMP(expiration_time) - 100"));
|
if(list.isEmpty()){
|
return;
|
}
|
log.info("开始执行优惠券即将过期微信提醒消息发送");
|
for (XpAppUserCoupon xpAppUserCoupon : list) {
|
XpCoupon coupon = xpCouponClient.getCouponById(xpAppUserCoupon.getCouponId()).getData();
|
SendSubscribeMessageVo vo = new SendSubscribeMessageVo();
|
vo.setUserId(xpAppUserCoupon.getAppUserId());
|
vo.setTemplateId(MessageTemplateEnum.F.getTemplateId());
|
String json = MessageTemplateEnum.F.getRemarks();
|
json = json.replace("优惠券名称", xpAppUserCoupon.getCouponName());
|
json = json.replace("券过期时间", xpAppUserCoupon.getExpirationTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
|
json = json.replace("使用规则", coupon.getCouponDescription());
|
vo.setJson(json);
|
R<?> r = subscribeMessageClient.sendSubscribeMessage(vo);
|
}
|
});
|
}
|
}
|
}
|
|
|
/**
|
* 短信通知
|
* @param activityList
|
*/
|
private void pushSmsCouponMessage(List<XpActivity> activityList) {
|
log.info("开始执行优惠券短信提醒消息发送 {}", activityList.size());
|
aa: for (XpActivity xpActivity : activityList) {
|
Integer now = Integer.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmm")));
|
Integer smsAboutExpireReminder = xpActivity.getSmsAboutExpireReminder();
|
if(StringUtils.hasLength(xpActivity.getSmsStartBlockingTime())){
|
String[] smsStartBlockingTime = xpActivity.getSmsStartBlockingTime().split(",");
|
String[] smsEndBlockingTime = xpActivity.getSmsEndBlockingTime().split(",");
|
for (int i = 0; i < smsStartBlockingTime.length; i++) {
|
Integer start = Integer.valueOf(smsStartBlockingTime[i].replace(":", ""));
|
Integer end = Integer.valueOf(smsEndBlockingTime[i].replace(":", ""));
|
if(start <= now && now <= end){
|
log.info("当前时间在短信发送时间区间内,不发送短信");
|
continue aa;
|
}
|
}
|
}
|
|
|
//微信通知活动开始提醒(0=否,1=是)
|
Integer smsActicityStart = xpActivity.getSmsActicityStart();
|
if(null != smsActicityStart && 1 == smsActicityStart){
|
RETRY_EXECUTOR.execute(() -> {
|
//短信通知临近券生效前X分钟通知
|
Integer smsActicityStartMinutes = xpActivity.getSmsActicityStartMinutes();
|
//获取满足微信通知的即将生效的优惠券
|
long time = LocalDateTime.now().plusMinutes(smsActicityStartMinutes).toEpochSecond(ZoneOffset.of("+8"));
|
List<XpAppUserCoupon> list = xpAppUserCouponService.list(new LambdaUpdateWrapper<XpAppUserCoupon>()
|
.eq(XpAppUserCoupon::getActivityId, xpActivity.getId()).eq(XpAppUserCoupon::getStatus, 1)
|
.last(" and UNIX_TIMESTAMP(effective_time) >= " + time + " and " + time + "> UNIX_TIMESTAMP(effective_time) - 100"));
|
if(list.isEmpty()){
|
return;
|
}
|
log.info("开始执行生效前优惠券短信提醒消息发送");
|
for (XpAppUserCoupon xpAppUserCoupon : list) {
|
UcUserInfo ucUserInfo = userResourcesClient.getBaseUserByUid(xpAppUserCoupon.getAppUserId().toString());
|
if(null == ucUserInfo || !StringUtils.hasLength(ucUserInfo.getMobile())){
|
log.info("用户信息不存在,跳过");
|
continue;
|
}
|
XpCoupon coupon = xpCouponClient.getCouponById(xpAppUserCoupon.getCouponId()).getData();
|
SmsVo vo = new SmsVo();
|
vo.setAppId(sms_appid);
|
vo.setPushType(1);
|
vo.setReceivers(ucUserInfo.getMobile());
|
vo.setTemplateCode("RTActivityStartTpl");
|
vo.setAppPushConfigCode("RTActivityStartSms");
|
vo.setParams(new HashMap<>());
|
vo.getParams().put("name", xpAppUserCoupon.getCouponName());
|
SmsDto smsDto = smsClient.pushSms(vo);
|
if(null == smsDto || smsDto.getCode() != 200){
|
log.info("短信发送失败");
|
}
|
}
|
});
|
}
|
|
//短信通知即将过期提醒(0=否,1=是)
|
if(null != smsAboutExpireReminder && 1 == smsAboutExpireReminder){
|
RETRY_EXECUTOR.execute(() -> {
|
//即将到期提前通知
|
Integer smsAboutExpireDays = xpActivity.getSmsAboutExpireDays();
|
//微信通知即将过期天数
|
long time = LocalDateTime.now().plusDays(smsAboutExpireDays).toEpochSecond(ZoneOffset.of("+8"));
|
List<XpAppUserCoupon> list = xpAppUserCouponService.list(new LambdaUpdateWrapper<XpAppUserCoupon>()
|
.eq(XpAppUserCoupon::getActivityId, xpActivity.getId()).eq(XpAppUserCoupon::getStatus, 1)
|
.last(" and UNIX_TIMESTAMP(expiration_time) >= " + time + " and " + time + "> UNIX_TIMESTAMP(expiration_time) - 100"));
|
if(list.isEmpty()){
|
return;
|
}
|
log.info("开始执行优惠券即将过期短信提醒消息发送");
|
for (XpAppUserCoupon xpAppUserCoupon : list) {
|
UcUserInfo ucUserInfo = userResourcesClient.getBaseUserByUid(xpAppUserCoupon.getAppUserId().toString());
|
if(null == ucUserInfo || !StringUtils.hasLength(ucUserInfo.getMobile())){
|
log.info("用户信息不存在,跳过");
|
continue;
|
}
|
SmsVo vo = new SmsVo();
|
vo.setAppId(sms_appid);
|
vo.setPushType(1);
|
vo.setReceivers(ucUserInfo.getMobile());
|
vo.setTemplateCode("RTCouponExpireSoonTpl");
|
vo.setAppPushConfigCode("RTCouponExpireSoonSms");
|
vo.setParams(new HashMap<>());
|
vo.getParams().put("name", xpAppUserCoupon.getCouponName());
|
SmsDto smsDto = smsClient.pushSms(vo);
|
if(null == smsDto || smsDto.getCode() != 200){
|
log.info("短信发送失败");
|
}
|
}
|
});
|
}
|
}
|
|
|
}
|
|
|
/**
|
* 小程序通知
|
* @param activityList
|
*/
|
private void pushMiniProgramCouponMessage(List<XpActivity> activityList) {
|
log.info("开始执行优惠券小程序提醒消息发送 {}", activityList.size());
|
for (XpActivity xpActivity : activityList) {
|
//小程序弹窗券到账提醒(0=否,1=是)
|
Integer miniProgramReceivedReminder = xpActivity.getMiniProgramReceivedReminder();
|
String expireMinutesNotificationContent = xpActivity.getExpireMinutesNotificationContent();
|
if(null != miniProgramReceivedReminder && 1 == miniProgramReceivedReminder){
|
RETRY_EXECUTOR.execute(() -> {
|
//即将到期提前通知
|
Integer miniProgramAboutExpireMinutes = xpActivity.getMiniProgramAboutExpireMinutes();
|
//获取满足微信通知的即将生效的优惠券
|
long time = LocalDateTime.now().plusMinutes(miniProgramAboutExpireMinutes).toEpochSecond(ZoneOffset.of("+8"));
|
List<XpAppUserCoupon> list = xpAppUserCouponService.list(new LambdaUpdateWrapper<XpAppUserCoupon>()
|
.eq(XpAppUserCoupon::getActivityId, xpActivity.getId()).eq(XpAppUserCoupon::getStatus, 1)
|
.last(" and UNIX_TIMESTAMP(effective_time) >= " + time + " and " + time + "> UNIX_TIMESTAMP(effective_time) - 100"));
|
if(list.isEmpty()){
|
return;
|
}
|
log.info("开始执行生效前优惠券小程序提醒消息发送");
|
for (XpAppUserCoupon xpAppUserCoupon : list) {
|
SendCouponMessageVo vo = new SendCouponMessageVo();
|
vo.setAppUserId(xpAppUserCoupon.getAppUserId());
|
JSONObject message = new JSONObject();
|
message.put("type", "COUPON_MESSAGE");
|
message.put("content", expireMinutesNotificationContent);
|
message.put("timestamp", System.currentTimeMillis());
|
vo.setMessage(message.toString());
|
webSocketMessageClient.sendCouponMessage(vo);
|
}
|
});
|
}
|
|
//小程序弹窗即将过期提醒(0=否,1=是)
|
Integer miniProgramAboutExpireReminder = xpActivity.getMiniProgramAboutExpireReminder();
|
String expireDaysNotificationContent = xpActivity.getExpireDaysNotificationContent();
|
if(null != miniProgramAboutExpireReminder && 1 == miniProgramAboutExpireReminder){
|
RETRY_EXECUTOR.execute(() -> {
|
//即将到期提前通知
|
Integer aboutExpireDays = xpActivity.getAboutExpireDays();
|
//微信通知即将过期天数
|
long time = LocalDateTime.now().plusDays(aboutExpireDays).toEpochSecond(ZoneOffset.of("+8"));
|
List<XpAppUserCoupon> list = xpAppUserCouponService.list(new LambdaUpdateWrapper<XpAppUserCoupon>()
|
.eq(XpAppUserCoupon::getActivityId, xpActivity.getId()).eq(XpAppUserCoupon::getStatus, 1)
|
.last(" and UNIX_TIMESTAMP(expiration_time) >= " + time + " and " + time + "> UNIX_TIMESTAMP(expiration_time) - 100"));
|
if(list.isEmpty()){
|
return;
|
}
|
log.info("开始执行优惠券即将过期小程序提醒消息发送");
|
for (XpAppUserCoupon xpAppUserCoupon : list) {
|
SendCouponMessageVo vo = new SendCouponMessageVo();
|
vo.setAppUserId(xpAppUserCoupon.getAppUserId());
|
JSONObject message = new JSONObject();
|
message.put("type", "COUPON_MESSAGE");
|
message.put("content", expireDaysNotificationContent);
|
message.put("timestamp", System.currentTimeMillis());
|
vo.setMessage(message.toString());
|
webSocketMessageClient.sendCouponMessage(vo);
|
}
|
});
|
}
|
}
|
}
|
|
|
|
private void editUserCouponStatus(){
|
log.info("开始执行编辑用户优惠券状态");
|
RETRY_EXECUTOR.execute(() -> {
|
xpAppUserCouponService.update(new LambdaUpdateWrapper<XpAppUserCoupon>()
|
.set(XpAppUserCoupon::getStatus, 3)
|
.eq(XpAppUserCoupon::getStatus, 1)
|
.le(XpAppUserCoupon::getExpirationTime, LocalDateTime.now()));
|
});
|
}
|
}
|