Просмотр исходного кода

生日积分定时任务

release_toaliyun_real
Burce 6 лет назад
Родитель
Сommit
c82d268e79
4 измененных файлов: 412 добавлений и 381 удалений
  1. +338
    -339
      mallinkSchedule/src/main/java/com/iformall/schedule/CouponSendSchedule.java
  2. +1
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxCreditHistoryServiceImpl.java
  3. +6
    -5
      mallinkService/src/main/java/com/iformall/service/impl/WxScoreRulesServiceImpl.java
  4. +67
    -37
      mallinkService/src/main/java/com/iformall/utils/CreditUtil.java

+ 338
- 339
mallinkSchedule/src/main/java/com/iformall/schedule/CouponSendSchedule.java Просмотреть файл

@@ -9,6 +9,7 @@ import com.iformall.enums.*;
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;
@@ -28,344 +29,342 @@ import java.util.stream.Collectors;
@Component
public class CouponSendSchedule {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
private WxMallMapper wxMallMapper;

@Autowired
private WxLevelConfigMapper WxLevelConfigMapper;

@Autowired
private WxLevelConfigService wxLevelConfigService;

@Autowired
private WxCUserBasicInfoMapper wxCUserBasicInfoMapper;

@Autowired
private WxCouponSendMapper wxCouponSendMapper;

@Autowired
private WxCouponActionLogMapper wxCouponActionLogMapper;

@Autowired
private WxOrderService wxOrderService;

@Autowired
private WxCouponActionLogService wxCouponActionLogService;

@Autowired
private WxCouponSendConfigMapper couponSendConfigMapper ;

@Autowired
private WxCouponSendService wxCouponSendService ;
@Autowired
private WxScoreRulesService wxScoreRulesService ;

@Autowired
private MqBaseProducer mqBaseProducer;



//@Scheduled(cron = "0 0 6 1 * ?") // 每月1号发放会员的权益券
@Scheduled(cron = "0 0 6 * * ?") // 测试每天6点发券
//@Scheduled(cron = "*/30 * * * * ?") // 测试30秒中一次
public void couponSendSchedule() {

List<WxMall> mallList = wxMallMapper.findList(new WxMall());

if (mallList.size()==0) {
logger.info("定时发券: No Mall info found");
return;
}

Date startTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.firstDayOfMonth())
.with(LocalTime.MIN)
.atZone(ZoneId.systemDefault())
.toInstant());
Date endTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.lastDayOfMonth())
.with(LocalTime.MAX)
.atZone(ZoneId.systemDefault())
.toInstant());
//查找所有couponSendConfig
Map<String, Integer> mallConfigMap = getAllCouponSendConfig(EnumCouponSendSendType.TIMED.getCode());
mallList.stream().forEach(mall-> {
//判断启用状态,状态为关闭时跳过不执行
if (isCouponSendDisable(mallConfigMap, mall)) {
logger.info("定时发券: {}发券状态关闭, 任务跳过不执行", mall.getName());
return;
}
WxLevelConfig wxLevelConfig = new WxLevelConfig();
wxLevelConfig.setTenantId(mall.getTenantId());
List<WxLevelConfig> levelConfigList = WxLevelConfigMapper.findList(wxLevelConfig);
levelConfigList = levelConfigList.stream()
.sorted(Comparator.comparing(WxLevelConfig::getPoints))
.collect(Collectors.toList());

for (int levelIndex = 0; levelIndex < levelConfigList.size(); levelIndex++) {
WxLevelConfig l = levelConfigList.get(levelIndex);
if (l.getCapability() == null)
continue;
Integer levelStartScore = l.getPoints();
Integer levelEndScore = levelIndex+1 < levelConfigList.size() ? levelConfigList.get(levelIndex+1).getPoints() : null;

JSONObject jo = null;
Long result = null;
try {
jo = JSONObject.parseObject(l.getCapability());
result = wxLevelConfigService.getCapabilitiesOfSendCarConpon(jo);
} catch (Exception e) {
logger.error("定时发券: 不能解析发券规则 levelId=" + l.getId() + e.getMessage());
continue;
}
Long sendCount = result;
if (sendCount > 0) {

WxCUserBasicInfoDto wxCUserBasicInfoDto = new WxCUserBasicInfoDto();
wxCUserBasicInfoDto.setTenantId(l.getTenantId());
wxCUserBasicInfoDto.setLevelStartScore(levelStartScore);
wxCUserBasicInfoDto.setLevelEndScore(levelEndScore);
List<WxCUserBasicInfo> wxCUserBasicInfoList = wxCUserBasicInfoMapper.findListByScore(wxCUserBasicInfoDto);

logger.info("定时发券:给LEVEL["+ l.getLevel() +
"]积分["+levelStartScore+"-"+levelEndScore+"]发券"+sendCount+"张");

wxCUserBasicInfoList.stream().forEach(cu->{

WxCouponSend wxCouponSend = new WxCouponSend();
wxCouponSend.setTenantId(l.getTenantId());
wxCouponSend.setSendType(EnumCouponSendSendType.TIMED.getCode());
wxCouponSend.setStatus(EnumCouponSendStatus.VALID.getCode());
List<WxCouponSendVo> couponSendList = wxCouponSendMapper.findListVo(wxCouponSend);
int remain = couponSendList.stream().map(cs->{
int count = cs.getRemainInventory();
logger.info("定时发券:给["+ cu.getNickName() +
"]券[" + cs.getTitle() + "]还剩" +
count +"张");
return count;
}).reduce(Integer::sum).get();

if (remain < sendCount){
logger.error("定时发券:库存不足["+ cu.getNickName() +"]应发"+sendCount+"张,总共剩"+ remain + "张");
return;
}

int sentCount = couponSendList.stream().map(cs->{
Map params = new HashMap<String, Object>();
params.put("tenantId", cs.getTenantId());
params.put("cUserId", cu.getId());
params.put("couponId", cs.getCouponId());
params.put("startTime", startTime);
params.put("endTime", endTime);
params.put("channelType", EnumCouponSendSendType.TIMED.getCode());
int count = wxCouponActionLogMapper.getCountByUserAndCouponAndDate(params);
logger.info("定时发券:已经给["+ cu.getNickName() +
"]券[" + cs.getTitle() + "] " +
count +"张");
return count;
}).reduce(Integer::sum).get();


logger.info("定时发券:给["+ cu.getNickName() +
"]总共已发送券" + sentCount + "张,还需发"+ (sendCount-sentCount) +"张");

for (int count = 0; count < sendCount - sentCount; count++) {
boolean sent = false;
for(int couponIndex = 0; couponIndex< couponSendList.size(); couponIndex++) {
WxCouponSendVo cs = couponSendList.get(couponIndex);
if (cs.getRemainInventory() <= 0)
continue;

// 发放免费券
try {
WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(),null);
wxCouponActionLogService.addOne(l.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId());
} catch (Exception e) {
logger.error("定时发券:发券失败 levelId=" + l.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage());
continue;
}

logger.info("定时发券:商场[" + mall.getName() +
"]会员等级[" + l.getLevel() +
"]发送券[" + cs.getTitle() +
"]给:" + cu.getNickName() +
" 电话-" + cu.getPhone() +
" id-" + cu.getId());
sent = true;
break;
}
if (!sent)
break;
}
});
}
}
});
}

/**
* 生日券发放
*/
@Scheduled(cron = "0 0 14 30 * ?") // 测试每天6点发券
public void birthdayCouponSendSchedule() {
logger.info("生日发券: 任务开始");
List<WxMall> mallList = wxMallMapper.findList(new WxMall());
if (mallList.size() == 0) {
logger.info("生日发券: No Mall info found");
return;
}

Date startTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.firstDayOfYear())
.with(LocalTime.MIN)
.atZone(ZoneId.systemDefault())
.toInstant());
Date endTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.lastDayOfYear())
.with(LocalTime.MAX)
.atZone(ZoneId.systemDefault())
.toInstant());

//查找所有couponSendConfig
Map<String, Integer> mallConfigMap = getAllCouponSendConfig(EnumCouponSendSendType.BIRTHDAY.getCode());
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);
return;
}
//每人可以发送几张生日券
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
private WxMallMapper wxMallMapper;

@Autowired
private WxLevelConfigMapper WxLevelConfigMapper;

@Autowired
private WxLevelConfigService wxLevelConfigService;

@Autowired
private WxCUserBasicInfoMapper wxCUserBasicInfoMapper;

@Autowired
private WxCouponSendMapper wxCouponSendMapper;

@Autowired
private WxCouponActionLogMapper wxCouponActionLogMapper;

@Autowired
private WxOrderService wxOrderService;

@Autowired
private WxCouponActionLogService wxCouponActionLogService;

@Autowired
private WxCouponSendConfigMapper couponSendConfigMapper;

@Autowired
private WxCouponSendService wxCouponSendService;
@Autowired
private WxScoreRulesService wxScoreRulesService;

@Autowired
private MqBaseProducer mqBaseProducer;


//@Scheduled(cron = "0 0 6 1 * ?") // 每月1号发放会员的权益券
@Scheduled(cron = "0 0 6 * * ?") // 测试每天6点发券
//@Scheduled(cron = "*/30 * * * * ?") // 测试30秒中一次
public void couponSendSchedule() {

List<WxMall> mallList = wxMallMapper.findList(new WxMall());

if (mallList.size() == 0) {
logger.info("定时发券: No Mall info found");
return;
}

Date startTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.firstDayOfMonth())
.with(LocalTime.MIN)
.atZone(ZoneId.systemDefault())
.toInstant());
Date endTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.lastDayOfMonth())
.with(LocalTime.MAX)
.atZone(ZoneId.systemDefault())
.toInstant());
//查找所有couponSendConfig
Map<String, Integer> mallConfigMap = getAllCouponSendConfig(EnumCouponSendSendType.TIMED.getCode());
mallList.stream().forEach(mall -> {
//判断启用状态,状态为关闭时跳过不执行
if (isCouponSendDisable(mallConfigMap, mall)) {
logger.info("定时发券: {}发券状态关闭, 任务跳过不执行", mall.getName());
return;
}
WxLevelConfig wxLevelConfig = new WxLevelConfig();
wxLevelConfig.setTenantId(mall.getTenantId());
List<WxLevelConfig> levelConfigList = WxLevelConfigMapper.findList(wxLevelConfig);
levelConfigList = levelConfigList.stream()
.sorted(Comparator.comparing(WxLevelConfig::getPoints))
.collect(Collectors.toList());

for (int levelIndex = 0; levelIndex < levelConfigList.size(); levelIndex++) {
WxLevelConfig l = levelConfigList.get(levelIndex);
if (l.getCapability() == null)
continue;
Integer levelStartScore = l.getPoints();
Integer levelEndScore = levelIndex + 1 < levelConfigList.size() ? levelConfigList.get(levelIndex + 1).getPoints() : null;

JSONObject jo = null;
Long result = null;
try {
jo = JSONObject.parseObject(l.getCapability());
result = wxLevelConfigService.getCapabilitiesOfSendCarConpon(jo);
} catch (Exception e) {
logger.error("定时发券: 不能解析发券规则 levelId=" + l.getId() + e.getMessage());
continue;
}
Long sendCount = result;
if (sendCount > 0) {

WxCUserBasicInfoDto wxCUserBasicInfoDto = new WxCUserBasicInfoDto();
wxCUserBasicInfoDto.setTenantId(l.getTenantId());
wxCUserBasicInfoDto.setLevelStartScore(levelStartScore);
wxCUserBasicInfoDto.setLevelEndScore(levelEndScore);
List<WxCUserBasicInfo> wxCUserBasicInfoList = wxCUserBasicInfoMapper.findListByScore(wxCUserBasicInfoDto);

logger.info("定时发券:给LEVEL[" + l.getLevel() +
"]积分[" + levelStartScore + "-" + levelEndScore + "]发券" + sendCount + "张");

wxCUserBasicInfoList.stream().forEach(cu -> {

WxCouponSend wxCouponSend = new WxCouponSend();
wxCouponSend.setTenantId(l.getTenantId());
wxCouponSend.setSendType(EnumCouponSendSendType.TIMED.getCode());
wxCouponSend.setStatus(EnumCouponSendStatus.VALID.getCode());
List<WxCouponSendVo> couponSendList = wxCouponSendMapper.findListVo(wxCouponSend);
int remain = couponSendList.stream().map(cs -> {
int count = cs.getRemainInventory();
logger.info("定时发券:给[" + cu.getNickName() +
"]券[" + cs.getTitle() + "]还剩" +
count + "张");
return count;
}).reduce(Integer::sum).get();

if (remain < sendCount) {
logger.error("定时发券:库存不足[" + cu.getNickName() + "]应发" + sendCount + "张,总共剩" + remain + "张");
return;
}

int sentCount = couponSendList.stream().map(cs -> {
Map params = new HashMap<String, Object>();
params.put("tenantId", cs.getTenantId());
params.put("cUserId", cu.getId());
params.put("couponId", cs.getCouponId());
params.put("startTime", startTime);
params.put("endTime", endTime);
params.put("channelType", EnumCouponSendSendType.TIMED.getCode());
int count = wxCouponActionLogMapper.getCountByUserAndCouponAndDate(params);
logger.info("定时发券:已经给[" + cu.getNickName() +
"]券[" + cs.getTitle() + "] " +
count + "张");
return count;
}).reduce(Integer::sum).get();


logger.info("定时发券:给[" + cu.getNickName() +
"]总共已发送券" + sentCount + "张,还需发" + (sendCount - sentCount) + "张");

for (int count = 0; count < sendCount - sentCount; count++) {
boolean sent = false;
for (int couponIndex = 0; couponIndex < couponSendList.size(); couponIndex++) {
WxCouponSendVo cs = couponSendList.get(couponIndex);
if (cs.getRemainInventory() <= 0)
continue;

// 发放免费券
try {
WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(), null);
wxCouponActionLogService.addOne(l.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId());
} catch (Exception e) {
logger.error("定时发券:发券失败 levelId=" + l.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage());
continue;
}

logger.info("定时发券:商场[" + mall.getName() +
"]会员等级[" + l.getLevel() +
"]发送券[" + cs.getTitle() +
"]给:" + cu.getNickName() +
" 电话-" + cu.getPhone() +
" id-" + cu.getId());
sent = true;
break;
}
if (!sent)
break;
}
});
}
}
});
}

/**
* 生日券发放
*/
@Scheduled(cron = "0 0 14 30 * ?") // 测试每天6点发券
public void birthdayCouponSendSchedule() {
logger.info("生日发券: 任务开始");
List<WxMall> mallList = wxMallMapper.findList(new WxMall());
if (mallList.size() == 0) {
logger.info("生日发券: No Mall info found");
return;
}

Date startTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.firstDayOfYear())
.with(LocalTime.MIN)
.atZone(ZoneId.systemDefault())
.toInstant());
Date endTime = Date.from(LocalDateTime.now()
.with(TemporalAdjusters.lastDayOfYear())
.with(LocalTime.MAX)
.atZone(ZoneId.systemDefault())
.toInstant());

//查找所有couponSendConfig
Map<String, Integer> mallConfigMap = getAllCouponSendConfig(EnumCouponSendSendType.BIRTHDAY.getCode());
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);
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 sent = 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);
}
Map<String, Object> params = new HashMap<>();
params.put("tenantId", cs.getTenantId());
params.put("cUserId", cu.getId());
params.put("couponId", cs.getCouponId());
params.put("startTime", startTime);
params.put("endTime", endTime);
params.put("channelType", EnumCouponSendSendType.BIRTHDAY.getCode());
int count = wxCouponActionLogMapper.getCountByUserAndCouponAndDate(params);
logger.info("生日发券:已经给[" + cu.getNickName() +
"]券[" + cs.getTitle() + "] " +
count + "张");
if (count > 0) {
logger.info("生日发券: 会员{}已经发送过生日券, 本次不再发送", cu.getNickName());
continue;
}
//提前n天发送生日券,不满足跳过不执行,没有发送的进行补发
if (DateUtils.birthdaysBetween(cu.getBirthdate()) <= beforeDays) {
logger.info("生日发券: [会员={},生日={}不满足提前{}天发券]", cu.getNickName(), cu.getBirthdate(),beforeDays);
continue;
}
if (cs.getRemainInventory() <= 0) {
logger.info("生日发券: [title={},id={}]卡券库存不足!", cs.getTitle(), cs.getCouponId());
continue;
}
// 发放免费券
try {
WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(),null);
wxCouponActionLogService.addOne(cu.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId());
} catch (Exception e) {
logger.error("定时发券:发券失败 levelId=" + cu.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage());
continue;
}
sent = true ;
logger.info("定时发券:商场[" + mall.getName() +
"]会员生日[" + cu.getBirthdate().toInstant() +
"]发送券[" + cs.getTitle() +
"]给:" + cu.getNickName() +
" 电话-" + cu.getPhone() +
" id-" + cu.getId());
}
if (sent) {
sendSMS(cu, mall);
// 记录积分倍率日期
try {
cu.setScoreDate(cu.getBirthdate());
wxCUserBasicInfoMapper.updateByPrimaryKeySelective(cu);
} catch (Exception e) {
logger.error("定时发券:记录积分倍率日期失败 {}", e.getMessage());
}
}
});
});
logger.info("生日发券: 任务结束");
}

private Map<String, Integer> getAllCouponSendConfig(Integer sendType) {
WxCouponSendConfig queryConfig = new WxCouponSendConfig();
queryConfig.setSendType(sendType);
List<WxCouponSendConfig> couponSendConfigList = couponSendConfigMapper.findList(queryConfig);
return CollectionUtils.isNotEmpty(couponSendConfigList) ?
couponSendConfigList.stream().collect(Collectors.toMap(WxCouponSendConfig::getTenantId, WxCouponSendConfig::getValue)) : null;
}

private boolean isCouponSendDisable(Map<String, Integer> mallConfigMap, WxMall mall) {
if (mallConfigMap != null && Objects.nonNull(mallConfigMap.get(mall.getTenantId()))) {
Integer disable = mallConfigMap.get(mall.getTenantId());
return Objects.equals(disable, EnumEnableType.Disable.getCode());
}
return false;
}

private void sendSMS(WxCUserBasicInfo cUserBasicInfo, WxMall mall) {
WxMsgRecord wxMsgRecord = new WxMsgRecord();
wxMsgRecord.setMsgType(EnumMsgRecordType.SMS.getCode());
wxMsgRecord.setReceiver(cUserBasicInfo.getPhone());
wxMsgRecord.setTenantId(cUserBasicInfo.getTenantId());
Map<String, String> dynamicContentMap = new HashMap<>();
WxScoreRules rules = wxScoreRulesService.getScoreRules(cUserBasicInfo.getTenantId());
if (Objects.nonNull(rules) && Objects.nonNull(rules.getScale())) {
int birthdayScale = rules.getScale();
if (birthdayScale > WxScoreRules.DEFAULT_SCALE) {
float creditScale = new BigDecimal(birthdayScale).divide(new BigDecimal(WxScoreRules.DEFAULT_SCALE)).floatValue();
dynamicContentMap.put("creditScale", String.valueOf(creditScale));
wxMsgRecord.setModelType(EnumMsgModel.COUPON_BIRTHDAY_OPENED.getCode());
}
} else {
//没有配置积分规则
wxMsgRecord.setModelType(EnumMsgModel.COUPON_BIRTHDAY_OPENED_NO.getCode());
}
dynamicContentMap.put("userName", Objects.isNull(cUserBasicInfo.getNickName()) ? "" : cUserBasicInfo.getNickName());
dynamicContentMap.put("mallName", mall.getName());
wxMsgRecord.setDynamicContentMap(dynamicContentMap);
mqBaseProducer.sendMessage(wxMsgRecord, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}
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 sent = 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);
}
Map<String, Object> params = new HashMap<>();
params.put("tenantId", cs.getTenantId());
params.put("cUserId", cu.getId());
params.put("couponId", cs.getCouponId());
params.put("startTime", startTime);
params.put("endTime", endTime);
params.put("channelType", EnumCouponSendSendType.BIRTHDAY.getCode());
int count = wxCouponActionLogMapper.getCountByUserAndCouponAndDate(params);
logger.info("生日发券:已经给[" + cu.getNickName() +
"]券[" + cs.getTitle() + "] " +
count + "张");
if (count > 0) {
logger.info("生日发券: 会员{}已经发送过生日券, 本次不再发送", cu.getNickName());
continue;
}
//提前n天发送生日券,不满足跳过不执行,没有发送的进行补发
int diffBithday = DateUtils.birthdaysBetween(cu.getBirthdate());
if (diffBithday < 0 || diffBithday > beforeDays) {
logger.info("生日发券: [会员={},生日={}不满足提前{}天发券]", cu.getNickName(), cu.getBirthdate(), beforeDays);
continue;
}
if (cs.getRemainInventory() <= 0) {
logger.info("生日发券: [title={},id={}]卡券库存不足!", cs.getTitle(), cs.getCouponId());
continue;
}
// 发放免费券
try {
WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(), null);
wxCouponActionLogService.addOne(cu.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId());
} catch (Exception e) {
logger.error("定时发券:发券失败 levelId=" + cu.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage());
continue;
}
sent = true;
logger.info("定时发券:商场[" + mall.getName() +
"]会员生日[" + cu.getBirthdate().toInstant() +
"]发送券[" + cs.getTitle() +
"]给:" + cu.getNickName() +
" 电话-" + cu.getPhone() +
" id-" + cu.getId());
}
if (sent) {
sendSMS(cu, mall);
// 记录积分倍率日期
try {
cu.setScoreDate(cu.getBirthdate());
wxCUserBasicInfoMapper.updateByPrimaryKeySelective(cu);
} catch (Exception e) {
logger.error("定时发券:记录积分倍率日期失败 {}", e.getMessage());
}
}
});
});
logger.info("生日发券: 任务结束");
}

private Map<String, Integer> getAllCouponSendConfig(Integer sendType) {
WxCouponSendConfig queryConfig = new WxCouponSendConfig();
queryConfig.setSendType(sendType);
List<WxCouponSendConfig> couponSendConfigList = couponSendConfigMapper.findList(queryConfig);
return CollectionUtils.isNotEmpty(couponSendConfigList) ?
couponSendConfigList.stream().collect(Collectors.toMap(WxCouponSendConfig::getTenantId, WxCouponSendConfig::getValue)) : null;
}

private boolean isCouponSendDisable(Map<String, Integer> mallConfigMap, WxMall mall) {
if (mallConfigMap != null && Objects.nonNull(mallConfigMap.get(mall.getTenantId()))) {
Integer disable = mallConfigMap.get(mall.getTenantId());
return Objects.equals(disable, EnumEnableType.Disable.getCode());
}
return false;
}

private void sendSMS(WxCUserBasicInfo cUserBasicInfo, WxMall mall) {
WxMsgRecord wxMsgRecord = new WxMsgRecord();
wxMsgRecord.setMsgType(EnumMsgRecordType.SMS.getCode());
wxMsgRecord.setReceiver(cUserBasicInfo.getPhone());
wxMsgRecord.setTenantId(cUserBasicInfo.getTenantId());
Map<String, String> dynamicContentMap = new HashMap<>();

int birthdayScale = CreditUtil.getScoreScale(cUserBasicInfo.getTenantId(), wxScoreRulesService);
if (birthdayScale > WxScoreRules.DEFAULT_SCALE) {
float creditScale = new BigDecimal(birthdayScale).divide(new BigDecimal(WxScoreRules.DEFAULT_SCALE)).floatValue();
dynamicContentMap.put("creditScale", String.valueOf(creditScale));
wxMsgRecord.setModelType(EnumMsgModel.COUPON_BIRTHDAY_OPENED.getCode());
} else {
//没有配置积分规则
wxMsgRecord.setModelType(EnumMsgModel.COUPON_BIRTHDAY_OPENED_NO.getCode());
}
dynamicContentMap.put("userName", Objects.isNull(cUserBasicInfo.getNickName()) ? "" : cUserBasicInfo.getNickName());
dynamicContentMap.put("mallName", mall.getName());
wxMsgRecord.setDynamicContentMap(dynamicContentMap);
mqBaseProducer.sendMessage(wxMsgRecord, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}
}

+ 1
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxCreditHistoryServiceImpl.java Просмотреть файл

@@ -217,6 +217,7 @@ public class WxCreditHistoryServiceImpl implements WxCreditHistoryService {
int creditChangeNumOrigin = creditIncrement(record);
int creditChangeNum = creditChangeNumOrigin ;
if (record.getCreditType().equals(EnumScoreType.CONSUMPTION.getCode()) || record.getCreditType().equals(EnumScoreType.SPEND_CREDIT.getCode())) {
//等级积分配置
int birthdayScale = wxLevelConfigMapper.getScale(wxCUser.getTenantId(), wxCUser.getScore()) ;
creditChangeNum = CreditUtil.calUserCredit(creditChangeNumOrigin, wxCUser, birthdayScale, wxCUserBasicInfo, wxScoreRulesService);
}


+ 6
- 5
mallinkService/src/main/java/com/iformall/service/impl/WxScoreRulesServiceImpl.java Просмотреть файл

@@ -67,11 +67,12 @@ public class WxScoreRulesServiceImpl implements WxScoreRulesService {

} else {
// 如果成长值规则不存在,启用默认值
final IdWorker idWorker = IdWorker.get();
scoreRules.setId(idWorker.nextId());
scoreRules.setRules(WxScoreRules.getScoreDefaultRules());

wxScoreRulesMapper.insertSelective(scoreRules);
this.saveOrUpdate(scoreRules);
//final IdWorker idWorker = IdWorker.get();
//scoreRules.setId(idWorker.nextId());
//scoreRules.setRules(WxScoreRules.getScoreDefaultRules());
//
//wxScoreRulesMapper.insertSelective(scoreRules);
}
// 插入缓存
scoreRulesRedisTemplate.opsForValue().set(key, scoreRules);


+ 67
- 37
mallinkService/src/main/java/com/iformall/utils/CreditUtil.java Просмотреть файл

@@ -14,44 +14,74 @@ import java.util.Objects;
@Slf4j
public class CreditUtil {

/**
* 计算用户积分
*
* @return
*/
public static int calUserCredit(int creditOrigin, WxCUser wxCUser, Integer scaleFromDb, WxCUserBasicInfo wxCUserBasicInfo, WxScoreRulesService wxScoreRulesService) {
if (Objects.isNull(wxCUser) || Objects.isNull(wxCUserBasicInfo)) {
return 0;
}
// 获取等级积分倍率:默认为1.0,
int levelScale = WxLevelConfig.DEFAULT_SCALE;
Integer score = wxCUser.getScore();
if (Objects.nonNull(score)) {
if (Objects.nonNull(scaleFromDb)) {
levelScale = scaleFromDb;
}
}
/**
* 计算用户积分
*
* @param creditOrigin 原始积分
* @param wxCUser C端用户信息
* @param scaleFromDb 等级倍率
* @param wxCUserBasicInfo C端用户信息
* @param wxScoreRulesService
* @return
*/
public static int calUserCredit(int creditOrigin, WxCUser wxCUser, Integer scaleFromDb, WxCUserBasicInfo wxCUserBasicInfo, WxScoreRulesService wxScoreRulesService) {
if (Objects.isNull(wxCUser) || Objects.isNull(wxCUserBasicInfo)) {
return 0;
}
// 获取等级积分倍率:默认为1.0,
int levelScale = calLevelScale(wxCUser, scaleFromDb);

// 获取生日积分倍率:
int birthdayScale = calBirthdayScale(wxCUserBasicInfo, wxScoreRulesService);

int creditNew = new BigDecimal(creditOrigin)
.multiply(new BigDecimal(levelScale))
.multiply(new BigDecimal(birthdayScale))
.divide(new BigDecimal(WxScoreRules.DEFAULT_SCALE))
.divide(new BigDecimal(WxLevelConfig.DEFAULT_SCALE)
, BigDecimal.ROUND_HALF_UP).intValue();
log.info("积分倍率计算, 用户:{},成长值:{},等级积分倍率:{},生日积分倍率:{},原积分:{},新积分:{}", wxCUser.getId(), wxCUser.getScore(), levelScale, birthdayScale, creditOrigin, creditNew);
return creditNew;
}

// 获取生日积分倍率:
public static int calLevelScale(WxCUser wxCUser, Integer scaleFromDb) {
int levelScale = WxLevelConfig.DEFAULT_SCALE;
Integer score = wxCUser.getScore();
//积分不为空时进行计算
if (Objects.nonNull(score)) {
//等级积分配置存在时进行计算
if (Objects.nonNull(scaleFromDb)) {
levelScale = scaleFromDb;
} else {
log.info("积分倍率计算:等级积分倍率配置=null");
}
}
log.info("积分倍率计算:会员等级积分倍率配置={}", levelScale);
return levelScale;
}

public static int calBirthdayScale(WxCUserBasicInfo wxCUserBasicInfo, WxScoreRulesService wxScoreRulesService) {
int birthdayScale = WxScoreRules.DEFAULT_SCALE;
//判断是否生日当天,一年一天有效
if (Objects.nonNull(wxCUserBasicInfo.getScoreDate()) && DateUtils.birthdaysBetween(wxCUserBasicInfo.getScoreDate()) == 0) {
birthdayScale = getScoreScale(wxCUserBasicInfo.getTenantId(), wxScoreRulesService);
} else {
log.info("积分倍率计算:未设置生日或生日条件未匹配={}", wxCUserBasicInfo.getScoreDate());
}
return birthdayScale;
}

public static int getScoreScale(String tenantId, WxScoreRulesService wxScoreRulesService) {
int birthdayScale = WxScoreRules.DEFAULT_SCALE;
//判断是否生日当天,一年一天有效
if (Objects.nonNull(wxCUserBasicInfo.getScoreDate()) && DateUtils.birthdaysBetween(wxCUserBasicInfo.getScoreDate()) == 0) {
WxScoreRules rules = wxScoreRulesService.getCreditRules(wxCUser.getTenantId());
if (Objects.nonNull(rules) && Objects.nonNull(rules.getScale())) {
birthdayScale = rules.getScale();
} else {
log.info("会员生日券倍率配置:null");
//没有配置积分规则
}
WxScoreRules rules = wxScoreRulesService.getCreditRules(tenantId);
if (Objects.nonNull(rules) && Objects.nonNull(rules.getScale())) {
//规则存使用积分倍率
birthdayScale = rules.getScale();
} else {
//没有配置积分规则
log.info("积分倍率计算:会员生日积分倍率配置=null");
}

int creditNew = new BigDecimal(creditOrigin)
.multiply(new BigDecimal(levelScale))
.multiply(new BigDecimal(birthdayScale))
.divide(new BigDecimal(WxScoreRules.DEFAULT_SCALE))
.divide(new BigDecimal(WxLevelConfig.DEFAULT_SCALE)
, BigDecimal.ROUND_HALF_UP).intValue();
log.info("积分倍率, 用户:{},成长值:{},等级积分倍率:{},生日积分倍率:{},原积分:{},新积分:{}", wxCUser.getId(), wxCUser.getScore(), levelScale, birthdayScale, creditOrigin, creditNew);
return creditNew;
}
log.info("会员生日积分倍率配置:{}", birthdayScale);
return birthdayScale ;
}
}

Загрузка…
Отмена
Сохранить