优惠券活动发送/触发

This commit is contained in:
lifenlong
2021-05-24 11:09:21 +08:00
parent 8924981556
commit 777226dc95
11 changed files with 389 additions and 100 deletions

View File

@@ -81,4 +81,14 @@ public class Coupon extends BasePromotion {
@ApiModelProperty(value = "消费门槛")
private Double consumeThreshold;
/**
* @see cn.lili.modules.promotion.entity.enums.CouponRangeDayEnum
*
*/
@ApiModelProperty(value = "时间范围类型")
private String rangeDayType;
@ApiModelProperty(value = "有效期")
private Integer effectiveDays;
}

View File

@@ -1,6 +1,7 @@
package cn.lili.modules.promotion.entity.dos;
import cn.lili.modules.promotion.entity.dto.BasePromotion;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -23,6 +24,12 @@ import javax.validation.constraints.NotNull;
@ApiModel(value = "优惠券活动实体类")
public class CouponActivity extends BasePromotion {
/**
* @see CouponActivityTypeEnum
* @author Bulbasaur
* @date: 2021/5/24 10:28 上午
*
*/
@NotNull(message = "优惠券活动类型不能为空")
@ApiModelProperty(value = "优惠券活动类型")
private String couponActivityType;

View File

@@ -0,0 +1,27 @@
package cn.lili.modules.promotion.entity.enums;
/**
* 优惠券时间范围枚举
*
* @author Bulbasaur
* @date: 2021/5/24 8:31 上午
*/
public enum CouponRangeDayEnum {
/**
* 枚举
*/
FIXEDTIME("固定时间"), DYNAMICTIME("动态时间");
private final String description;
CouponRangeDayEnum(String str) {
this.description = str;
}
public String description() {
return description;
}
}

View File

@@ -11,7 +11,13 @@ public enum PromotionTypeEnum {
/**
* 促销枚举
*/
PINTUAN("拼团"), SECKILL("秒杀"), COUPON("优惠券"), FULL_DISCOUNT("满减"), POINTS_GOODS("积分商品");
PINTUAN("拼团"),
SECKILL("秒杀"),
COUPON("优惠券"),
FULL_DISCOUNT("满减"),
POINTS_GOODS("积分商品"),
COUPON_ACTIVITY("优惠券活动")
;
/**
* 拼团秒杀拥有独立库存,如果其他促销也有独立库存涉及库存扣减的,请添加在下方

View File

@@ -1,7 +1,9 @@
package cn.lili.modules.promotion.service;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.dto.CouponActivityDTO;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.entity.vos.CouponActivityVO;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -46,17 +48,16 @@ public interface CouponActivityService extends IService<CouponActivity> {
/**
* 注册赠券
*
* @param couponActivityIds 优惠券活动ID
* @param memberId
* @param couponActivityList 优惠券活动
* @param member 会员
*/
void registered(List<String> couponActivityIds, String memberId);
void registered(List<CouponActivity> couponActivityList, Member member);
//编辑优惠券活动
//删除优惠券活动
//关闭优惠券活动
boolean updateCouponActivityStatus(String id, PromotionStatusEnum promotionStatus);
//开启优惠券活动
//查看优惠券活动

View File

@@ -10,6 +10,7 @@ import cn.lili.modules.promotion.entity.dos.CouponActivityItem;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dto.CouponActivityDTO;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.entity.vos.CouponActivityVO;
import cn.lili.modules.promotion.mapper.CouponActivityMapper;
import cn.lili.modules.promotion.service.CouponActivityItemService;
@@ -53,7 +54,6 @@ public class CouponActivityServiceImpl extends ServiceImpl<CouponActivityMapper,
this.save(couponActivityDTO);
//添加优惠券活动优惠券
this.addCouponActivityItems(couponActivityDTO);
//发送促销活动开始的延时任务
return couponActivityDTO;
}
@@ -68,7 +68,6 @@ public class CouponActivityServiceImpl extends ServiceImpl<CouponActivityMapper,
.eq(CouponActivityItem::getActivityId,couponActivityDTO.getId()));
//重新添加优惠券活动关联优惠券
this.addCouponActivityItems(couponActivityDTO);
//更新促销活动的延时任务
return couponActivityDTO;
}
@@ -92,15 +91,13 @@ public class CouponActivityServiceImpl extends ServiceImpl<CouponActivityMapper,
}
@Override
public void registered(List<String> couponActivityIds, String memberId) {
for (String couponActivityId : couponActivityIds) {
//获取优惠券
CouponActivity couponActivity = this.getById(couponActivityId);
public void registered(List<CouponActivity> couponActivityList, Member member) {
for (CouponActivity couponActivity : couponActivityList) {
//获取会员信息
List<Map<String, Object>> memberList = new ArrayList<>();
Map<String, Object> map = new HashMap<>();
map.put("id", memberId);
map.put("nick_name", memberService.getById(memberId).getNickName());
map.put("id", member.getId());
map.put("nick_name", member.getNickName());
memberList.add(map);
//优惠优惠券活动的优惠券列表
@@ -111,6 +108,13 @@ public class CouponActivityServiceImpl extends ServiceImpl<CouponActivityMapper,
}
}
@Override
public boolean updateCouponActivityStatus(String id, PromotionStatusEnum promotionStatus) {
CouponActivity couponActivity=this.getById(id);
couponActivity.setPromotionStatus(promotionStatus.name());
return this.updateById(couponActivity);
}
/**
* 发送优惠券
*

View File

@@ -9,10 +9,7 @@ import cn.lili.common.utils.DateUtil;
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
import cn.lili.modules.promotion.entity.dos.*;
import cn.lili.modules.promotion.entity.enums.*;
import cn.lili.modules.promotion.entity.vos.CouponVO;
import cn.lili.modules.promotion.entity.vos.PintuanVO;
import cn.lili.modules.promotion.entity.vos.PointsGoodsVO;
import cn.lili.modules.promotion.entity.vos.SeckillVO;
import cn.lili.modules.promotion.entity.vos.*;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
@@ -63,6 +60,9 @@ public class PromotionServiceImpl implements PromotionService {
//积分商品
@Autowired
private PointsGoodsService pointsGoodsService;
//优惠券活动
@Autowired
private CouponActivityService couponActivityService;
//ES商品
@Autowired
private EsGoodsIndexService goodsIndexService;
@@ -84,61 +84,11 @@ public class PromotionServiceImpl implements PromotionService {
break;
//秒杀
case SECKILL:
SeckillVO seckill = this.mongoTemplate.findById(promotionMessage.getPromotionId(), SeckillVO.class);
if (seckill == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
break;
}
seckill.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.seckillService.update(promotionMessage.updateWrapper());
for (SeckillApply seckillApply : seckill.getSeckillApplyList()) {
if (seckillApply.getPromotionApplyStatus().equals(PromotionApplyStatusEnum.PASS.name())) {
// 下一个时间,默认为当天结束时间
int nextHour = 23;
String[] split = seckill.getHours().split(",");
int[] hoursSored = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
// 排序时间段
Arrays.sort(hoursSored);
for (int i : hoursSored) {
// 如果当前时间段大于排序后的时间段的某个,当前时间段的下个时间段即为排序后的时间段的某个
if (seckillApply.getTimeLine() < i) {
nextHour = i;
break;
}
}
Seckill seckill1 = JSONUtil.toBean(JSONUtil.toJsonStr(seckill), Seckill.class);
String format = cn.hutool.core.date.DateUtil.format(seckill.getStartTime(), DateUtil.STANDARD_DATE_FORMAT);
DateTime parseStartTime = cn.hutool.core.date.DateUtil.parse((format + " " + seckillApply.getTimeLine()), "yyyy-MM-dd HH");
DateTime parseEndTime = cn.hutool.core.date.DateUtil.parse((format + " " + nextHour), "yyyy-MM-dd HH");
// 如果是当天最后的时间段则设置到当天结束时间的59分59秒
if (nextHour == seckillApply.getTimeLine()) {
parseEndTime = cn.hutool.core.date.DateUtil.parse((format + " " + nextHour + ":59:59"), DateUtil.STANDARD_FORMAT);
}
seckill1.setStartTime(parseStartTime);
// 当时商品的限时抢购活动结束时间为下个时间段的开始
seckill1.setEndTime(parseEndTime);
this.goodsIndexService.updateEsGoodsIndex(seckillApply.getSkuId(), seckill1, promotionTypeEnum.name() + "-" + seckillApply.getTimeLine(), seckillApply.getPrice());
}
}
this.mongoTemplate.save(seckill);
result = this.updateSeckill(promotionMessage, esPromotionKey, promotionTypeEnum);
break;
//拼团
case PINTUAN:
PintuanVO pintuanVO = this.mongoTemplate.findById(promotionMessage.getPromotionId(), PintuanVO.class);
if (pintuanVO == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
break;
}
pintuanVO.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.pintuanService.update(promotionMessage.updateWrapper());
this.promotionGoodsService.updateBatchById(pintuanVO.getPromotionGoodsList());
List<PromotionGoods> promotionGoodsList = pintuanVO.getPromotionGoodsList();
// 更新促销商品索引
for (PromotionGoods promotionGoods : promotionGoodsList) {
Pintuan pintuan1 = JSONUtil.toBean(JSONUtil.toJsonStr(pintuanVO), Pintuan.class);
this.goodsIndexService.updateEsGoodsIndex(promotionGoods.getSkuId(), pintuan1, esPromotionKey, promotionGoods.getPrice());
}
this.mongoTemplate.save(pintuanVO);
result = this.updatePintuan(promotionMessage, esPromotionKey, promotionTypeEnum);
break;
//优惠券
case COUPON:
@@ -146,16 +96,11 @@ public class PromotionServiceImpl implements PromotionService {
break;
//积分商品
case POINTS_GOODS:
PointsGoodsVO pointsGoodsVO = this.mongoTemplate.findById(promotionMessage.getPromotionId(), PointsGoodsVO.class);
if (pointsGoodsVO == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
break;
}
pointsGoodsVO.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.pointsGoodsService.update(promotionMessage.updateWrapper());
PointsGoods pointsGoods = JSONUtil.toBean(JSONUtil.toJsonStr(pointsGoodsVO), PointsGoods.class);
this.goodsIndexService.updateEsGoodsIndex(pointsGoodsVO.getSkuId(), pointsGoods, esPromotionKey, null);
this.mongoTemplate.save(pointsGoodsVO);
result = this.updatePointsGoods(promotionMessage, esPromotionKey, promotionTypeEnum);
break;
//优惠券活动
case COUPON_ACTIVITY:
result = this.updateCouponActivity(promotionMessage, promotionTypeEnum);
break;
default:
break;
@@ -285,6 +230,13 @@ public class PromotionServiceImpl implements PromotionService {
return promotionMap;
}
/**
* 修改满额活动状态
* @param promotionMessage 信息队列传输促销信息实体
* @param esPromotionKey es Key
* @param promotionTypeEnum 促销分类枚举
* @return 修改结果
*/
private boolean updateFullDiscount(PromotionMessage promotionMessage, String esPromotionKey, PromotionTypeEnum promotionTypeEnum) {
boolean result;
//从mongo中获取促销备份
@@ -315,19 +267,31 @@ public class PromotionServiceImpl implements PromotionService {
return result;
}
/**
* 修改优惠券状态
* @param promotionMessage 信息队列传输促销信息实体
* @param esPromotionKey es Key
* @param promotionTypeEnum 促销分类枚举
* @return 修改结果
*/
private boolean updateCoupon(PromotionMessage promotionMessage, String esPromotionKey, PromotionTypeEnum promotionTypeEnum) {
boolean result;
//从mongo中获取优惠券信息
CouponVO couponVO = this.mongoTemplate.findById(promotionMessage.getPromotionId(), CouponVO.class);
if (couponVO == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
return false;
}
//修改优惠券
couponVO.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.couponService.update(promotionMessage.updateWrapper());
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>().eq(MemberCoupon::getCouponId, couponVO.getId()).set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
this.memberCouponService.update(updateWrapper);
//优惠券活动结束,会员已领取的优惠券状态修改为:已过期
if(couponVO.getPromotionStatus().equals(PromotionStatusEnum.END)){
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
.eq(MemberCoupon::getCouponId, couponVO.getId())
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
this.memberCouponService.update(updateWrapper);
}
// clone一个活动信息用于存放与索引中
CouponVO clone = ObjectUtil.clone(couponVO);
clone.setPromotionGoodsList(null);
@@ -343,11 +307,127 @@ public class PromotionServiceImpl implements PromotionService {
return result;
}
/**
* 修改拼团状态
* @param promotionMessage 信息队列传输促销信息实体
* @param esPromotionKey es Key
* @param promotionTypeEnum 促销分类枚举
* @return 修改结果
*/
private boolean updatePintuan(PromotionMessage promotionMessage, String esPromotionKey, PromotionTypeEnum promotionTypeEnum){
boolean result;
PintuanVO pintuanVO = this.mongoTemplate.findById(promotionMessage.getPromotionId(), PintuanVO.class);
if (pintuanVO == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
return false;
}
pintuanVO.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.pintuanService.update(promotionMessage.updateWrapper());
this.promotionGoodsService.updateBatchById(pintuanVO.getPromotionGoodsList());
List<PromotionGoods> promotionGoodsList = pintuanVO.getPromotionGoodsList();
// 更新促销商品索引
for (PromotionGoods promotionGoods : promotionGoodsList) {
Pintuan pintuan1 = JSONUtil.toBean(JSONUtil.toJsonStr(pintuanVO), Pintuan.class);
this.goodsIndexService.updateEsGoodsIndex(promotionGoods.getSkuId(), pintuan1, esPromotionKey, promotionGoods.getPrice());
}
this.mongoTemplate.save(pintuanVO);
return result;
}
/**
* 修改秒杀状态
* @param promotionMessage 信息队列传输促销信息实体
* @param esPromotionKey es Key
* @param promotionTypeEnum 促销分类枚举
* @return 修改结果
*/
private boolean updateSeckill(PromotionMessage promotionMessage, String esPromotionKey, PromotionTypeEnum promotionTypeEnum){
boolean result;
SeckillVO seckill = this.mongoTemplate.findById(promotionMessage.getPromotionId(), SeckillVO.class);
if (seckill == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
return false;
}
seckill.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.seckillService.update(promotionMessage.updateWrapper());
for (SeckillApply seckillApply : seckill.getSeckillApplyList()) {
if (seckillApply.getPromotionApplyStatus().equals(PromotionApplyStatusEnum.PASS.name())) {
// 下一个时间,默认为当天结束时间
int nextHour = 23;
String[] split = seckill.getHours().split(",");
int[] hoursSored = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
// 排序时间段
Arrays.sort(hoursSored);
for (int i : hoursSored) {
// 如果当前时间段大于排序后的时间段的某个,当前时间段的下个时间段即为排序后的时间段的某个
if (seckillApply.getTimeLine() < i) {
nextHour = i;
break;
}
}
Seckill seckill1 = JSONUtil.toBean(JSONUtil.toJsonStr(seckill), Seckill.class);
String format = cn.hutool.core.date.DateUtil.format(seckill.getStartTime(), DateUtil.STANDARD_DATE_FORMAT);
DateTime parseStartTime = cn.hutool.core.date.DateUtil.parse((format + " " + seckillApply.getTimeLine()), "yyyy-MM-dd HH");
DateTime parseEndTime = cn.hutool.core.date.DateUtil.parse((format + " " + nextHour), "yyyy-MM-dd HH");
// 如果是当天最后的时间段则设置到当天结束时间的59分59秒
if (nextHour == seckillApply.getTimeLine()) {
parseEndTime = cn.hutool.core.date.DateUtil.parse((format + " " + nextHour + ":59:59"), DateUtil.STANDARD_FORMAT);
}
seckill1.setStartTime(parseStartTime);
// 当时商品的限时抢购活动结束时间为下个时间段的开始
seckill1.setEndTime(parseEndTime);
this.goodsIndexService.updateEsGoodsIndex(seckillApply.getSkuId(), seckill1, promotionTypeEnum.name() + "-" + seckillApply.getTimeLine(), seckillApply.getPrice());
}
}
return result;
}
/**
* 修改积分商品状态
* @param promotionMessage 信息队列传输促销信息实体
* @param esPromotionKey es Key
* @param promotionTypeEnum 促销分类枚举
* @return 修改结果
*/
private boolean updatePointsGoods(PromotionMessage promotionMessage, String esPromotionKey, PromotionTypeEnum promotionTypeEnum){
boolean result;
PointsGoodsVO pointsGoodsVO = this.mongoTemplate.findById(promotionMessage.getPromotionId(), PointsGoodsVO.class);
if (pointsGoodsVO == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
return false;
}
pointsGoodsVO.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.pointsGoodsService.update(promotionMessage.updateWrapper());
PointsGoods pointsGoods = JSONUtil.toBean(JSONUtil.toJsonStr(pointsGoodsVO), PointsGoods.class);
this.goodsIndexService.updateEsGoodsIndex(pointsGoodsVO.getSkuId(), pointsGoods, esPromotionKey, null);
this.mongoTemplate.save(pointsGoodsVO);
return result;
}
/**
* 修改优惠券活动状态
* @param promotionMessage 信息队列传输促销信息实体
* @param promotionTypeEnum 促销分类枚举
* @return 修改结果
*/
private boolean updateCouponActivity(PromotionMessage promotionMessage, PromotionTypeEnum promotionTypeEnum){
boolean result;
CouponActivityVO couponActivityVO = this.mongoTemplate.findById(promotionMessage.getPromotionId(), CouponActivityVO.class);
if (couponActivityVO == null) {
this.throwPromotionException(promotionTypeEnum, promotionMessage.getPromotionId(), promotionMessage.getPromotionStatus());
return false;
}
couponActivityVO.setPromotionStatus(promotionMessage.getPromotionStatus());
result = this.couponActivityService.update(promotionMessage.updateWrapper());
this.mongoTemplate.save(couponActivityVO);
return result;
}
/**
* 更新促销商品信息
*
* @param promotionId
* @param promotionStatus
* @param promotionId 促销活动ID
* @param promotionStatus 活动状态
*/
private void updatePromotionGoods(String promotionId, String promotionStatus) {
LambdaUpdateWrapper<PromotionGoods> updateWrapper = new LambdaUpdateWrapper<>();