From 444caa3bc3712f29f0b589c47e803b65835d68bb Mon Sep 17 00:00:00 2001 From: Burce Date: Thu, 15 Aug 2019 19:12:03 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E7=94=9F=E6=97=A5=E7=A7=AF=E5=88=86?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iformall/schedule/CouponSendSchedule.java | 205 +++++++++++++++++- .../com/iformall/domain/po/WxCouponSend.java | 6 +- .../service/impl/WxCouponSendServiceImpl.java | 54 ++--- 3 files changed, 227 insertions(+), 38 deletions(-) diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/CouponSendSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/CouponSendSchedule.java index f3bbbc16e..0cbdf6f8d 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/CouponSendSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/CouponSendSchedule.java @@ -1,21 +1,20 @@ package com.iformall.schedule; +import com.alibaba.fastjson.JSONArray; 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.vo.WxCouponSendVo; import com.iformall.enums.EnumCouponSendSendType; import com.iformall.enums.EnumCouponSendStatus; -import com.iformall.exception.MallinkException; import com.iformall.mapper.*; -import com.iformall.service.WxCouponActionLogService; -import com.iformall.service.WxCouponSendService; -import com.iformall.service.WxLevelConfigService; -import com.iformall.service.WxOrderService; -import io.swagger.models.auth.In; +import com.iformall.service.*; +import com.iformall.utils.DateUtils; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -56,6 +55,12 @@ public class CouponSendSchedule { @Autowired private WxCouponActionLogService wxCouponActionLogService; + @Autowired + private WxCouponSendConfigMapper couponSendConfigMapper ; + + @Autowired + private WxCouponMapper wxCouponMapper ; + //@Scheduled(cron = "0 0 6 1 * ?") // 每月1号发放会员的权益券 @Scheduled(cron = "0 0 6 * * ?") // 测试每天6点发券 @@ -79,9 +84,14 @@ public class CouponSendSchedule { .with(LocalTime.MAX) .atZone(ZoneId.systemDefault()) .toInstant()); - + //查找所有couponSendConfig + Map mallConfigMap = getAllCouponSendConfig(); mallList.stream().forEach(mall-> { - + //判断启用状态,状态为关闭时跳过不执行 + if (isCouponSendDisable(mallConfigMap, mall)) { + logger.info("定时发券: {}发券状态关闭,任务跳过不执行", mall.getName()); + return; + } WxLevelConfig wxLevelConfig = new WxLevelConfig(); wxLevelConfig.setTenantId(mall.getTenantId()); List levelConfigList = WxLevelConfigMapper.findList(wxLevelConfig); @@ -189,4 +199,181 @@ public class CouponSendSchedule { } }); } + + /** + * 生日券发放 + */ + @Scheduled(cron = "0 0 4 * * ?") // 测试每天6点发券 + public void birthdayCouponSendSchedule() { + logger.info("生日发券任务开始"); + List 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 mallConfigMap = getAllCouponSendConfig(); + mallList.forEach(mall -> { + //判断启用状态,状态为关闭时跳过不执行 + if (isCouponSendDisable(mallConfigMap, mall)) { + logger.info("生日发券: {} 发券状态关闭, 任务跳过不执行", mall.getName()); + return; + } + + WxCUserBasicInfoDto wxCUserBasicInfoDto = new WxCUserBasicInfoDto(); + wxCUserBasicInfoDto.setTenantId(mall.getTenantId()); + List wxCUserBasicInfoList = wxCUserBasicInfoMapper.findBirthdayList(wxCUserBasicInfoDto); + if (CollectionUtils.isEmpty(wxCUserBasicInfoList)) { + logger.info("生日发券: 用户列表为空 wxCUserBasicInfoList = {}, 任务跳过不执行",wxCUserBasicInfoList); + return; + } + //每人可以发送几张生日券 + final int sendCount = 2; + wxCUserBasicInfoList.forEach(cu -> { + WxCouponSend wxCouponSend = new WxCouponSend(); + wxCouponSend.setTenantId(cu.getTenantId()); + wxCouponSend.setSendType(EnumCouponSendSendType.BIRTHDAY.getCode()); + wxCouponSend.setStatus(EnumCouponSendStatus.VALID.getCode()); + List couponSendList = wxCouponSendMapper.findListVo(wxCouponSend); + if(CollectionUtils.isEmpty(couponSendList)) { + logger.info("生日发券: 会员生日券配置列表为空 couponSendList = {}, 任务跳过不执行", couponSendList); + return; + } + int beforeDays; + //获取生日券列表 + List newCouponSendList = new ArrayList<>() ; + for(WxCouponSendVo wxCouponSendVo:couponSendList) { + JSONObject conditions = JSONObject.parseObject(wxCouponSendVo.getConditions()); + JSONArray couponIdArr = conditions.getJSONArray(WxCouponSend.KEY_COUPONIDS); + if (Objects.isNull(couponIdArr) || couponIdArr.isEmpty()) { + logger.info("生日发券: 会员生日券列表为空 couponIdArr = {}", couponIdArr); + continue; + } + List couponIds = couponIdArr.toJavaList(Long.class); + if (CollectionUtils.isEmpty(couponIds)) { + logger.error("生日发券: 转换错误 couponIds ={}", couponIds); + continue; + } + + List wxCouponList = wxCouponMapper.selectByIds(StringUtils.join(couponIds, ",")); + if (CollectionUtils.isEmpty(wxCouponList)) { + logger.error("生日发券: 转换错误 wxCouponList ={}", wxCouponList); + } + //添加卡列表 + wxCouponList.forEach(wxCoupon -> { + WxCouponSendVo vo = new WxCouponSendVo(); + BeanUtils.copyProperties(wxCouponSendVo, vo); + vo.setRemainInventory(wxCoupon.getRemainInventory()); + vo.setUseLimitQuantity(wxCoupon.getUseLimitQuantity()); + vo.setInventory(wxCoupon.getInventory()); + vo.setValidStartDate(wxCoupon.getValidStartDate()); + vo.setValidEndDate(wxCoupon.getValidEndDate()); + vo.setTitle(wxCoupon.getTitle()); + newCouponSendList.add(vo); + }); + } + + if (CollectionUtils.isEmpty(newCouponSendList)) { + logger.error("生日发券: 会员生日券列表为空 newCouponSendList ={}, 任务跳过不执行", newCouponSendList); + return; + } + + int remain = newCouponSendList.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<>(); + 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 + "张"); + return count; + }).reduce(Integer::sum).orElse(0); + + + 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); + JSONObject condititions = JSONObject.parseObject(cs.getConditions()) ; + beforeDays = condititions.getIntValue(WxCouponSend.KEY_BEFOREDAYS); + //提前n天发送生日券,不满足跳过不执行 + if(DateUtils.daysBetween(cu.getBirthdate(), new Date()) == beforeDays) { + continue; + } + if (cs.getRemainInventory() <= 0) + continue; + // 发放免费券 + try { + WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId()); + 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; + } + + logger.info("定时发券:商场[" + mall.getName() + + "]会员生日[" + cu.getBirthdate().toInstant() + + "]发送券[" + cs.getTitle() + + "]给:" + cu.getNickName() + + " 电话-" + cu.getPhone() + + " id-" + cu.getId()); + sent = true; + break; + } + if (!sent) + break; + } + }); + }); + logger.info("生日发券任务结束"); + } + + private Map getAllCouponSendConfig() { + WxCouponSendConfig queryConfig = new WxCouponSendConfig(); + queryConfig.setSendType(EnumCouponSendSendType.TIMED.getCode()); + List couponSendConfigList = couponSendConfigMapper.findList(queryConfig); + Map mallConfigMap = CollectionUtils.isNotEmpty(couponSendConfigList) ? + couponSendConfigList.stream().collect(Collectors.toMap(WxCouponSendConfig::getTenantId, WxCouponSendConfig::getValue)) : null; + return mallConfigMap; + } + + private boolean isCouponSendDisable(Map mallConfigMap, WxMall mall) { + if (mallConfigMap != null && Objects.nonNull(mallConfigMap.get(mall.getTenantId()))) { + Integer disable = mallConfigMap.get(mall.getTenantId()); + return disable == 1; + } + return false; + } } \ No newline at end of file diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxCouponSend.java b/mallinkService/src/main/java/com/iformall/domain/po/WxCouponSend.java index 04730bb92..3c85c7ef5 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxCouponSend.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxCouponSend.java @@ -15,13 +15,15 @@ import java.util.List; @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class WxCouponSend extends BaseEntity { + public static final String KEY_COUPONIDS = "couponIds" ; + public static final String KEY_BEFOREDAYS = "beforeDays" ; @Id protected Long id; @Transient protected List ids; - @io.swagger.annotations.ApiModelProperty(value="租户ID",name="tenantId") + @io.swagger.annotations.ApiModelProperty(value="租户ID",name="tenantId" ,required = true) private String tenantId; @io.swagger.annotations.ApiModelProperty(value="卡券id",name="couponId") private Long couponId; @@ -30,7 +32,7 @@ public class WxCouponSend extends BaseEntity { private String title; @io.swagger.annotations.ApiModelProperty(value="发券方式(1.主动领取,2.停车发券,3.核销发券)",name="sendType") private Integer sendType; - @io.swagger.annotations.ApiModelProperty(value="发券条件",name="condition") + @io.swagger.annotations.ApiModelProperty(value="发券条件",name="condition",required = true) private String conditions; @io.swagger.annotations.ApiModelProperty(value="0:有效 1:无效",name="status") private Integer status; diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponSendServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponSendServiceImpl.java index 9a10309ea..0c342a68d 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponSendServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponSendServiceImpl.java @@ -95,33 +95,33 @@ public class WxCouponSendServiceImpl implements WxCouponSendService { if (!Objects.equals(record.getSendType(), EnumCouponSendSendType.BIRTHDAY.getCode())) { return record ; } - //会员生日券 - JSONObject conditions = JSONObject.parseObject(record.getConditions()); - Long couponId = record.getCouponId(); - if (Objects.nonNull(couponId)) { - JSONArray couponIds; - if (Objects.isNull(record.getId())) { - //添加新卡券 - couponIds = new JSONArray(); - couponIds.add(couponId); - } else { - //更新卡券列表 - WxCouponSend couponSend = wxCouponSendMapper.selectByPrimaryKey(record.getId()); - JSONObject couponSendJo = JSONObject.parseObject(couponSend.getConditions()); - couponIds = couponSendJo.getJSONArray("couponIds"); - if (Objects.isNull(couponIds)) { - couponIds = new JSONArray(); - couponIds.add(couponId); - } else { - //添加新卡券 - if (!couponIds.contains(couponId)) { - couponIds.add(couponId); - } - } - } - conditions.put("couponIds", couponIds); - } - record.setConditions(conditions.toJSONString()); +// //会员生日券 +// JSONObject conditions = JSONObject.parseObject(record.getConditions()); +// Long couponId = record.getCouponId(); +// if (Objects.nonNull(couponId)) { +// JSONArray couponIds; +// if (Objects.isNull(record.getId())) { +// //添加新卡券 +// couponIds = new JSONArray(); +// couponIds.add(couponId); +// } else { +// //更新卡券列表 +// WxCouponSend couponSend = wxCouponSendMapper.selectByPrimaryKey(record.getId()); +// JSONObject couponSendJo = JSONObject.parseObject(couponSend.getConditions()); +// couponIds = couponSendJo.getJSONArray(WxCouponSend.KEY_COUPONIDS); +// if (Objects.isNull(couponIds)) { +// couponIds = new JSONArray(); +// couponIds.add(couponId); +// } else { +// //添加新卡券 +// if (!couponIds.contains(couponId)) { +// couponIds.add(couponId); +// } +// } +// } +// conditions.put(WxCouponSend.KEY_COUPONIDS, couponIds); +// } +// record.setConditions(conditions.toJSONString()); return record; } From 42b1aade0d3c67a58e9146837c2caf67a7ad679e Mon Sep 17 00:00:00 2001 From: Burce Date: Fri, 16 Aug 2019 10:12:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BC=9A=E5=91=98?= =?UTF-8?q?=E7=94=9F=E6=97=A5=E7=A7=AF=E5=88=86=E5=80=8D=E7=8E=87=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/iformall/utils/CreditUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/utils/CreditUtil.java b/mallinkService/src/main/java/com/iformall/utils/CreditUtil.java index db2db5024..af35d0a4b 100644 --- a/mallinkService/src/main/java/com/iformall/utils/CreditUtil.java +++ b/mallinkService/src/main/java/com/iformall/utils/CreditUtil.java @@ -38,8 +38,8 @@ public class CreditUtil { } // 获取生日积分倍率: int birthdayScale = WxScoreRules.DEFAULT_SCALE; - //生日当天 - if (Objects.nonNull(wxCUserBasicInfo.getBirthdate()) || DateUtils.daysBetween(new Date(), wxCUserBasicInfo.getBirthdate()) == 0) { + //判断是否生日当天 + if (Objects.nonNull(wxCUserBasicInfo.getBirthdate()) && DateUtils.daysBetween(new Date(), wxCUserBasicInfo.getBirthdate()) == 0) { WxScoreRules rules = wxScoreRulesService.getScoreRules(wxCUser.getTenantId()); if (Objects.nonNull(rules) && Objects.nonNull(rules.getScale())) { birthdayScale = rules.getScale();