package cn.lili.modules.promotion.tools; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.enums.ResultCode; import cn.lili.common.exception.ServiceException; import cn.lili.modules.promotion.entity.dos.BasePromotions; import cn.lili.modules.promotion.entity.dos.PromotionGoods; import cn.lili.modules.promotion.entity.enums.PromotionsStatusEnum; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; /** * 优惠活动通用验证类 * * @author paulG * @since 2020/8/18 **/ @Slf4j public class PromotionTools { public static final String START_TIME_COLUMN = "start_time"; public static final String END_TIME_COLUMN = "end_time"; public static final String PLATFORM_ID = "0"; public static final String PLATFORM_NAME = "platform"; private PromotionTools() { throw new IllegalStateException("Utility class"); } /** * 参数验证 * 1、活动起始时间必须大于当前时间 * 2、验证活动开始时间是否大于活动结束时间 * * @param startTime 活动开始时间 * @param endTime 活动结束时间 */ public static void checkPromotionTime(Date startTime, Date endTime) { if (startTime == null) { throw new ServiceException(ResultCode.PROMOTION_TIME_NOT_EXIST); } DateTime now = DateUtil.date(); //如果活动起始时间小于现在时间 // if (now.after(startTime)) { // throw new ServiceException(ResultCode.PROMOTION_START_TIME_ERROR); // } //如果活动结束时间小于现在时间 if (endTime != null && now.after(endTime)) { throw new ServiceException(ResultCode.PROMOTION_END_TIME_ERROR); } //开始时间不能大于结束时间 if (endTime != null && startTime.after(endTime)) { throw new ServiceException(ResultCode.PROMOTION_TIME_ERROR); } } /** * 组装检查促销活动时间 query wrapper * * @param startTime 开始时间 * @param endTime 结束时间 * @param typeEnum 促销类型 * @param storeId 店铺id * @param activityId 排除的促销活动id * @return mybatis plus query wrapper对象 */ public static QueryWrapper checkActiveTime(Date startTime, Date endTime, PromotionTypeEnum typeEnum, String storeId, String activityId) { QueryWrapper queryWrapper = new QueryWrapper<>(); if (PromotionTypeEnum.SECKILL != typeEnum) { queryWrapper.nested(i -> { //新活动起始时间 大于 之前活动的起始时间 小于 之前活动的截止时间 i.nested(i2 -> i2.le(START_TIME_COLUMN, startTime).ge(END_TIME_COLUMN, startTime)); //新活动结束时间 大于 之前活动的起始时间 小于 之前活动的截止时间 i.or(i1 -> i1.le(START_TIME_COLUMN, endTime).ge(END_TIME_COLUMN, endTime)); }); } else { queryWrapper.ge(START_TIME_COLUMN, DateUtil.beginOfDay(startTime)).le(END_TIME_COLUMN, DateUtil.endOfDay(endTime)); } if (storeId != null) { queryWrapper.eq("store_id", storeId); } if (activityId != null) { queryWrapper.ne("id", activityId); } queryWrapper.and(i -> i.or(queryPromotionStatus(PromotionsStatusEnum.NEW)).or(queryPromotionStatus(PromotionsStatusEnum.START))); queryWrapper.eq("delete_flag", false); return queryWrapper; } /** * 检查商品是否重复参加同类型活动 * * @param exceptType 排除的促销活动类型(可同时参加的活动类型) * @param skuIds 商品skuId * @param activityId 当前活动id * @return mybatis plus query wrapper对象 */ public static QueryWrapper checkSkuDuplicate(List exceptType, List skuIds, String activityId) { QueryWrapper queryWrapper = new QueryWrapper<>(); if (skuIds != null && !skuIds.isEmpty()) { queryWrapper.in("sku_id", skuIds); } if (CharSequenceUtil.isNotEmpty(activityId)) { queryWrapper.ne("id", activityId); } queryWrapper.and(i -> i.or(PromotionTools.queryPromotionStatus(PromotionsStatusEnum.START)).or(PromotionTools.queryPromotionStatus(PromotionsStatusEnum.NEW))); if (exceptType != null) { queryWrapper.notIn(!exceptType.isEmpty(), "promotion_type", exceptType.stream().map(PromotionTypeEnum::name).collect(Collectors.toList())); } queryWrapper.eq("delete_flag", false); return queryWrapper; } public static Consumer> queryPromotionStatus(PromotionsStatusEnum promotionsStatusEnum) { switch (promotionsStatusEnum) { case NEW: return (QueryWrapper t) -> t.nested(i -> i.gt(START_TIME_COLUMN, new Date()).gt(END_TIME_COLUMN, new Date())); case START: return (QueryWrapper t) -> t.nested(i -> i.le(START_TIME_COLUMN, new Date()).ge(END_TIME_COLUMN, new Date())); case END: return (QueryWrapper t) -> t.nested(i -> i.lt(START_TIME_COLUMN, new Date()).lt(END_TIME_COLUMN, new Date())); case CLOSE: return (QueryWrapper t) -> t.nested(i -> i.isNull(START_TIME_COLUMN).isNull(END_TIME_COLUMN)); default: return null; } } /** * 促销商品入库前填充 * * @param originList 原促销商品列表 * @param promotion 促销信息 * @return 促销商品列表 */ public static List promotionGoodsInit(List originList, BasePromotions promotion, PromotionTypeEnum promotionTypeEnum) { if (originList != null) { //本次促销商品入库 for (PromotionGoods promotionGoods : originList) { promotionGoods.setPromotionId(promotion.getId()); if (CharSequenceUtil.isEmpty(promotionGoods.getStoreId())) { promotionGoods.setStoreId(promotion.getStoreId()); } if (CharSequenceUtil.isEmpty(promotionGoods.getStoreName())) { promotionGoods.setStoreName(promotion.getStoreName()); } promotionGoods.setTitle(promotion.getPromotionName()); // 如果是秒杀活动保留原时间 if (promotionGoods.getStartTime() == null || !PromotionTypeEnum.SECKILL.equals(promotionTypeEnum)) { promotionGoods.setStartTime(promotion.getStartTime()); } if (promotionGoods.getStartTime() == null || !PromotionTypeEnum.SECKILL.equals(promotionTypeEnum)) { promotionGoods.setEndTime(promotion.getEndTime()); } promotionGoods.setPromotionType(promotionTypeEnum.name()); promotionGoods.setNum(0); promotionGoods.setDeleteFlag(promotion.getDeleteFlag()); } } return originList; } public static int nextHour(String[] totalHours, Integer timeline) { int nextHour = 23; int[] hoursSored = Arrays.stream(totalHours).mapToInt(Integer::parseInt).toArray(); Arrays.sort(hoursSored); for (int i : hoursSored) { if (timeline < i) { nextHour = i; break; } } return nextHour; } /** * 过滤无效促销活动 * * @param map 促销活动map * @return 过滤后的促销活动map */ public static Map filterInvalidPromotionsMap(Map map) { if (CollUtil.isEmpty(map)) { return new HashMap<>(); } try { //移除无效促销活动 return map.entrySet().stream().filter(Objects::nonNull).filter(i -> { try { if (JSONUtil.isTypeJSON(JSONUtil.toJsonStr(i.getValue()))) { JSONObject promotionsObj = JSONUtil.parseObj(i.getValue()); BasePromotions basePromotions = promotionsObj.toBean(BasePromotions.class); if (basePromotions != null && basePromotions.getStartTime() != null && basePromotions.getEndTime() != null) { return basePromotions.getStartTime().getTime() <= System.currentTimeMillis() && basePromotions.getEndTime().getTime() >= System.currentTimeMillis(); } } else { return false; } } catch (Exception ee) { log.debug("转换异常促销活动信息:{}", i); return false; } return i.getValue() != null; }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> newValue)); } catch (Exception e) { log.error("过滤无效促销活动出现异常。异常促销信息:{},异常信息 ", map, e); return new HashMap<>(); } } /** * 是否为需要检查的促销活动类型(用于判定部分类型的商品不能参与活动的条件) * 内容为不需要检查的促销活动类型 * * @param key 促销key * @return 当前促销key是否存在 */ public static boolean isPromotionsTypeNeedsToChecked(String key) { return !CharSequenceUtil.containsAny(key, PromotionTypeEnum.COUPON.name(), PromotionTypeEnum.FULL_DISCOUNT.name()); } }