|
|
|
@@ -1,7 +1,6 @@ |
|
|
|
package com.iformall.schedule; |
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
|
import com.iformall.common.ErrorCode; |
|
|
|
import com.iformall.domain.dto.WxCUserBasicInfoDto; |
|
|
|
import com.iformall.domain.po.*; |
|
|
|
import com.iformall.domain.po.msg.WxMsgRecord; |
|
|
|
@@ -11,7 +10,6 @@ import com.iformall.mapper.*; |
|
|
|
import com.iformall.mq.MqBaseProducer; |
|
|
|
import com.iformall.service.*; |
|
|
|
import com.iformall.utils.CreditUtil; |
|
|
|
import com.iformall.utils.DateUtils; |
|
|
|
import org.apache.commons.collections.CollectionUtils; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
@@ -20,6 +18,8 @@ import org.springframework.scheduling.annotation.Scheduled; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.text.DateFormat; |
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
import java.time.LocalTime; |
|
|
|
import java.time.ZoneId; |
|
|
|
@@ -233,96 +233,92 @@ public class CouponSendSchedule { |
|
|
|
|
|
|
|
//查找所有couponSendConfig |
|
|
|
Map<String, Integer> mallConfigMap = getAllCouponSendConfig(EnumCouponSendSendType.BIRTHDAY.getCode()); |
|
|
|
DateFormat df = new SimpleDateFormat("MM-dd"); |
|
|
|
mallList.forEach(mall -> { |
|
|
|
//判断启用状态,状态为关闭时跳过不执行 |
|
|
|
if (isCouponSendDisable(mallConfigMap, mall)) { |
|
|
|
logger.info("生日发券: {} 发券状态关闭, 任务跳过不执行", mall.getName()); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
WxCUserBasicInfoDto wxCUserBasicInfoDto = new WxCUserBasicInfoDto(); |
|
|
|
wxCUserBasicInfoDto.setTenantId(mall.getTenantId()); |
|
|
|
List<WxCUserBasicInfo> wxCUserBasicInfoList = wxCUserBasicInfoMapper.findBirthdayList(wxCUserBasicInfoDto); |
|
|
|
if (CollectionUtils.isEmpty(wxCUserBasicInfoList)) { |
|
|
|
logger.info("生日发券: {} 用户列表为空 wxCUserBasicInfoList = {}, 任务跳过不执行", mall.getName(), wxCUserBasicInfoList); |
|
|
|
//查找生日券 |
|
|
|
WxCouponSend wxCouponSend = new WxCouponSend(); |
|
|
|
wxCouponSend.setTenantId(mall.getTenantId()); |
|
|
|
wxCouponSend.setSendType(EnumCouponSendSendType.BIRTHDAY.getCode()); |
|
|
|
wxCouponSend.setStatus(EnumCouponSendStatus.VALID.getCode()); |
|
|
|
List<WxCouponSendVo> couponSendList = wxCouponSendMapper.findListVo(wxCouponSend); |
|
|
|
if (CollectionUtils.isEmpty(couponSendList)) { |
|
|
|
logger.info("生日发券: 会员生日券投放列表为空 couponSendList = {}, 任务跳过不执行", couponSendList); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
int birthdayScale = CreditUtil.getBirthdayScoreScale(mall.getTenantId(), wxScoreRulesService); |
|
|
|
WxCouponSend birthdayConfig = wxCouponSendService.getConfig(EnumCouponSendSendType.BIRTHDAY.getCode(), mall.getTenantId()); |
|
|
|
String conditions = birthdayConfig.getConditions(); |
|
|
|
JSONObject configJo = null; |
|
|
|
try { |
|
|
|
configJo = JSONObject.parseObject(conditions); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("生日发券: 解析conditions异常: {}", e.getMessage()); |
|
|
|
} |
|
|
|
if (Objects.isNull(conditions) || Objects.isNull(configJo)) { |
|
|
|
logger.info("生日发券: 会员生日券配置解析异常 conditions = {}, 任务跳过不执行", conditions); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
//每人可以发送几张生日券 |
|
|
|
// final int sendCount = 1; |
|
|
|
wxCUserBasicInfoList.forEach(cu -> { |
|
|
|
WxCouponSend wxCouponSend = new WxCouponSend(); |
|
|
|
wxCouponSend.setTenantId(cu.getTenantId()); |
|
|
|
wxCouponSend.setSendType(EnumCouponSendSendType.BIRTHDAY.getCode()); |
|
|
|
wxCouponSend.setStatus(EnumCouponSendStatus.VALID.getCode()); |
|
|
|
List<WxCouponSendVo> couponSendList = wxCouponSendMapper.findListVo(wxCouponSend); |
|
|
|
if (CollectionUtils.isEmpty(couponSendList)) { |
|
|
|
logger.info("生日发券: 会员生日券投放列表为空 couponSendList = {}, 任务跳过不执行", couponSendList); |
|
|
|
return; |
|
|
|
} |
|
|
|
boolean couponSent = false; |
|
|
|
for (WxCouponSendVo cs : couponSendList) { |
|
|
|
String conditions = cs.getConditions(); |
|
|
|
JSONObject configJo = null; |
|
|
|
try { |
|
|
|
configJo = JSONObject.parseObject(conditions); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("生日发券: 解析conditions异常: {}", e.getMessage()); |
|
|
|
} |
|
|
|
if (Objects.isNull(conditions) || Objects.isNull(configJo)) { |
|
|
|
logger.info("生日发券: 会员生日券配置解析异常 conditions = {}, 任务跳过不执行", conditions); |
|
|
|
return; |
|
|
|
} |
|
|
|
//默认生日当天发送 |
|
|
|
int beforeDays = 0; |
|
|
|
if (configJo.containsKey(WxCouponSend.KEY_BEFOREDAYS)) { |
|
|
|
beforeDays = configJo.getIntValue(WxCouponSend.KEY_BEFOREDAYS); |
|
|
|
} |
|
|
|
|
|
|
|
//默认生日当天发送 |
|
|
|
int beforeDays = 0; |
|
|
|
if (configJo.containsKey(WxCouponSend.KEY_BEFOREDAYS)) { |
|
|
|
beforeDays = configJo.getIntValue(WxCouponSend.KEY_BEFOREDAYS); |
|
|
|
} |
|
|
|
//提前n天发送生日券,不满足跳过不执行,没有发送的进行补发 |
|
|
|
int diffBithday = DateUtils.birthdaysBetween(cu.getBirthdate()); |
|
|
|
if (diffBithday < 0 && Math.abs(diffBithday) > beforeDays || diffBithday > beforeDays) { |
|
|
|
logger.info("生日发券: [会员={},生日={}不满足提前{}天发券]", cu.getNickName(), cu.getBirthdate(), beforeDays); |
|
|
|
return; |
|
|
|
} |
|
|
|
//未来 ${beforeDays}天时间 |
|
|
|
Calendar today = Calendar.getInstance(); |
|
|
|
Date begin = today.getTime(); |
|
|
|
today.add(Calendar.DAY_OF_YEAR, beforeDays); |
|
|
|
Date end = today.getTime(); |
|
|
|
|
|
|
|
//boolean couponLimit = pushLimitService.checkCoupon(cu.getTenantId(), cu.getId(), cs.getCouponId()); |
|
|
|
//if (!couponLimit) { |
|
|
|
// logger.info("生日发券: {}", ErrorCode.PUSH_LIMIT_UP_TO_COUPONLIMIT.getMessage()); |
|
|
|
// continue; |
|
|
|
//} |
|
|
|
|
|
|
|
Calendar now = Calendar.getInstance() ; |
|
|
|
now.set(Calendar.HOUR, now.get(Calendar.HOUR) - 2) ; |
|
|
|
Map<String, Object> params = new HashMap<>(); |
|
|
|
params.put("tenantId", cs.getTenantId()); |
|
|
|
params.put("cUserId", cu.getId()); |
|
|
|
params.put("couponId", null); |
|
|
|
params.put("startTime", startTime); |
|
|
|
params.put("endTime", now.getTime()); |
|
|
|
params.put("channelType", EnumCouponSendSendType.BIRTHDAY.getCode()); |
|
|
|
int count = wxCouponActionLogMapper.getCountByUserAndCouponAndDate(params); |
|
|
|
//判断之前是否发送过会员生日券 |
|
|
|
if (count > 0) { |
|
|
|
logger.info("生日发券: 已经给会员{}发送过生日券, 本次不再发送", cu.getNickName()); |
|
|
|
return; |
|
|
|
} |
|
|
|
List<WxCUserBasicInfo> wxCUserBasicInfoList = wxCUserBasicInfoMapper.findBirthdayList(mall.getTenantId(), df.format(begin.getTime()), df.format(end.getTime())); |
|
|
|
if (CollectionUtils.isEmpty(wxCUserBasicInfoList)) { |
|
|
|
logger.info("生日发券: {} 满足发券的用户列表为空 wxCUserBasicInfoList = {}, 任务跳过不执行", mall.getName(), wxCUserBasicInfoList); |
|
|
|
return; |
|
|
|
} |
|
|
|
//过滤掉已经发送过生日券的用户 |
|
|
|
List<WxCUserBasicInfo> newUserList = wxCUserBasicInfoList.stream().filter(wxCUserBasicInfo -> { |
|
|
|
Calendar now = Calendar.getInstance(); |
|
|
|
//本次之前的20分钟 |
|
|
|
now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) - 30); |
|
|
|
Map<String, Object> params = new HashMap<>(); |
|
|
|
params.put("tenantId", wxCUserBasicInfo.getTenantId()); |
|
|
|
params.put("cUserId", wxCUserBasicInfo.getId()); |
|
|
|
params.put("couponId", null); |
|
|
|
params.put("startTime", startTime); |
|
|
|
params.put("endTime", now.getTime()); |
|
|
|
params.put("channelType", EnumCouponSendSendType.BIRTHDAY.getCode()); |
|
|
|
int count = wxCouponActionLogMapper.getCountByUserAndCouponAndDate(params); |
|
|
|
//判断之前是否发送过会员生日券 |
|
|
|
if (count > 0) { |
|
|
|
logger.info("生日发券: 已经给会员{}发送过生日券, 本次不再发送", wxCUserBasicInfo.getNickName()); |
|
|
|
return false; |
|
|
|
} else { |
|
|
|
return true; |
|
|
|
} |
|
|
|
}).collect(Collectors.toList()); |
|
|
|
|
|
|
|
if (cs.getRemainInventory() <= 0) { |
|
|
|
logger.info("生日发券: [title={},id={}]卡券库存不足!", cs.getTitle(), cs.getCouponId()); |
|
|
|
continue; |
|
|
|
} |
|
|
|
// 发放免费券 |
|
|
|
List<WxCUserBasicInfo> couponSendedUsers = new ArrayList<>(); |
|
|
|
for (WxCouponSendVo cs : couponSendList) { |
|
|
|
if (cs.getRemainInventory() <= 0) { |
|
|
|
logger.info("生日发券: [title={},id={}]卡券库存不足!", cs.getTitle(), cs.getCouponId()); |
|
|
|
continue; |
|
|
|
} |
|
|
|
for (WxCUserBasicInfo cu : newUserList) { |
|
|
|
// 发放生日券 |
|
|
|
try { |
|
|
|
WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(), null); |
|
|
|
wxCouponActionLogService.addOne(cu.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId()); |
|
|
|
couponSendedUsers.add(cu); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("定时发券:发券失败 levelId=" + cu.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage()); |
|
|
|
continue; |
|
|
|
} |
|
|
|
couponSent = true; |
|
|
|
logger.info("定时发券:商场[" + mall.getName() + |
|
|
|
"]会员生日[" + cu.getBirthdate().toInstant() + |
|
|
|
"]发送券[" + cs.getTitle() + |
|
|
|
@@ -330,25 +326,28 @@ public class CouponSendSchedule { |
|
|
|
" 电话-" + cu.getPhone() + |
|
|
|
" id-" + cu.getId()); |
|
|
|
} |
|
|
|
if (couponSent) { |
|
|
|
// 记录积分倍率日期 |
|
|
|
try { |
|
|
|
WxCUserBasicInfo toUpdate = new WxCUserBasicInfo(); |
|
|
|
toUpdate.setId(cu.getId()); |
|
|
|
toUpdate.setScoreDate(cu.getBirthdate()); |
|
|
|
wxCUserBasicInfoMapper.updateByPrimaryKeySelective(toUpdate); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("定时发券:记录积分倍率日期失败 {}", e.getMessage()); |
|
|
|
} |
|
|
|
//短信限制 |
|
|
|
boolean couponLimit = pushLimitService.checkMsg(cu.getTenantId()); |
|
|
|
if (couponLimit) { |
|
|
|
sendSMS(cu, mall, birthdayScale); |
|
|
|
} else { |
|
|
|
logger.info("生日发券: {}", ErrorCode.PUSH_LIMIT_NOT_INRANG.getMessage()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int birthdayScale = CreditUtil.getBirthdayScoreScale(mall.getTenantId(), wxScoreRulesService); |
|
|
|
for (WxCUserBasicInfo cu : couponSendedUsers) { |
|
|
|
// 记录积分倍率日期 |
|
|
|
try { |
|
|
|
WxCUserBasicInfo toUpdate = new WxCUserBasicInfo(); |
|
|
|
toUpdate.setId(cu.getId()); |
|
|
|
toUpdate.setScoreDate(cu.getBirthdate()); |
|
|
|
wxCUserBasicInfoMapper.updateByPrimaryKeySelective(toUpdate); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("定时发券:记录积分倍率日期失败 {}", e.getMessage()); |
|
|
|
continue; |
|
|
|
} |
|
|
|
}); |
|
|
|
//短信限制 |
|
|
|
//boolean couponLimit = pushLimitService.checkMsg(cu.getTenantId()); |
|
|
|
//if (couponLimit) { |
|
|
|
sendSMS(cu, mall, birthdayScale); |
|
|
|
//} else { |
|
|
|
// logger.info("生日发券: {}", ErrorCode.PUSH_LIMIT_NOT_INRANG.getMessage()); |
|
|
|
//} |
|
|
|
} |
|
|
|
}); |
|
|
|
logger.info("生日发券: 任务结束"); |
|
|
|
} |
|
|
|
|