feat(market):新增缓存活动信息和查询缓存的活动信息的功能

This commit is contained in:
JIAN 2024-09-24 22:54:46 +08:00
parent b98ff8fdf3
commit cea88fc351
5 changed files with 142 additions and 11 deletions

View File

@ -0,0 +1,44 @@
package com.jzo2o.market.controller.consumer;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.market.enums.ActivityStatusEnum;
import com.jzo2o.market.model.dto.response.SeizeCouponInfoResDTO;
import com.jzo2o.market.service.IActivityService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* 用户端 - 活动管理控制器
* @author JIAN
*/
@Slf4j
@RestController("consumerActivityController")
@RequestMapping("/consumer/activity")
public class ActivityController {
@Resource
private IActivityService activityService;
/**
* 用户端查询缓存中的活动信息
* @param tabType 1 进行中 2 待生效
*/
@GetMapping("/list")
public List<SeizeCouponInfoResDTO> listActivity(@RequestParam Integer tabType) {
ActivityStatusEnum activityStatusEnum;
if (tabType == 1) {
activityStatusEnum = ActivityStatusEnum.DISTRIBUTING;
} else if (tabType == 2) {
activityStatusEnum = ActivityStatusEnum.NO_DISTRIBUTE;
} else {
throw new BadRequestException("请求的状态出错");
}
return activityService.getCachedActivity(activityStatusEnum);
}
}

View File

@ -1,19 +1,27 @@
package com.jzo2o.market.handler; package com.jzo2o.market.handler;
import com.jzo2o.common.expcetions.DBException; import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils; import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.JsonUtils;
import com.jzo2o.market.constants.RedisConstants;
import com.jzo2o.market.enums.ActivityStatusEnum; import com.jzo2o.market.enums.ActivityStatusEnum;
import com.jzo2o.market.enums.CouponStatusEnum; import com.jzo2o.market.enums.CouponStatusEnum;
import com.jzo2o.market.model.domain.Activity; import com.jzo2o.market.model.domain.Activity;
import com.jzo2o.market.model.domain.Coupon; import com.jzo2o.market.model.domain.Coupon;
import com.jzo2o.market.model.dto.response.SeizeCouponInfoResDTO;
import com.jzo2o.market.service.IActivityService; import com.jzo2o.market.service.IActivityService;
import com.jzo2o.market.service.ICouponService; import com.jzo2o.market.service.ICouponService;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -21,6 +29,7 @@ import java.util.stream.Collectors;
* XxlJob任务处理器 * XxlJob任务处理器
* @author JIAN * @author JIAN
*/ */
@Slf4j
@Component @Component
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class XxlJobHandler { public class XxlJobHandler {
@ -28,6 +37,8 @@ public class XxlJobHandler {
private IActivityService activityService; private IActivityService activityService;
@Resource @Resource
private ICouponService couponService; private ICouponService couponService;
@Resource
private RedisTemplate<String, Object> redisTemplate;
/** /**
* 自动修改活动状态(1分钟1次) * 自动修改活动状态(1分钟1次)
@ -37,6 +48,7 @@ public class XxlJobHandler {
@XxlJob("updateActivityStatus") @XxlJob("updateActivityStatus")
@Transactional @Transactional
public void updateActivityStatus() { public void updateActivityStatus() {
log.info("自动修改活动状态任务开始");
LocalDateTime nowTime = LocalDateTime.now(); LocalDateTime nowTime = LocalDateTime.now();
List<Activity> activityList = activityService.lambdaQuery() List<Activity> activityList = activityService.lambdaQuery()
.eq(Activity::getStatus, ActivityStatusEnum.NO_DISTRIBUTE) .eq(Activity::getStatus, ActivityStatusEnum.NO_DISTRIBUTE)
@ -76,6 +88,7 @@ public class XxlJobHandler {
@XxlJob("processExpireCoupon") @XxlJob("processExpireCoupon")
@Transactional @Transactional
public void processExpireCoupon() { public void processExpireCoupon() {
log.info("自动过期已领取优惠券任务开始");
List<Coupon> couponList = couponService.lambdaQuery() List<Coupon> couponList = couponService.lambdaQuery()
.eq(Coupon::getStatus, CouponStatusEnum.NO_USE) .eq(Coupon::getStatus, CouponStatusEnum.NO_USE)
// 不处理还没到有效期的优惠卷 // 不处理还没到有效期的优惠卷
@ -96,4 +109,36 @@ public class XxlJobHandler {
throw new DBException("更新优惠卷状态失败"); throw new DBException("更新优惠卷状态失败");
} }
} }
/**
* 自动预热(缓存)1个月内的活动
*/
@XxlJob("activityPreheat")
public void activityPreheat() {
log.info("自动预热1个月内的活动任务开始");
LocalDateTime nowTime = LocalDateTime.now();
// 获取近一个月未开始/已开始的活动
@SuppressWarnings("unchecked")
List<Activity> activityList = activityService.lambdaQuery()
.le(Activity::getDistributeStartTime, nowTime.plusDays(30))
.in(Activity::getStatus, Arrays.asList(ActivityStatusEnum.NO_DISTRIBUTE, ActivityStatusEnum.DISTRIBUTING))
.orderByAsc(Activity::getDistributeStartTime)
.list();
if (CollUtils.isEmpty(activityList)) {
activityList = new ArrayList<>();
}
List<SeizeCouponInfoResDTO> couponInfoList = activityList.stream()
.map(activity -> BeanUtils
.toBean(activity, SeizeCouponInfoResDTO.class)
.setRemainNum(activity.getStockNum()))
.collect(Collectors.toList());
String couponInfoListJsonStr = JsonUtils.toJsonStr(couponInfoList);
redisTemplate
.opsForValue()
.set(RedisConstants.RedisKey.ACTIVITY_CACHE_LIST, couponInfoListJsonStr);
}
} }

View File

@ -1,8 +1,10 @@
package com.jzo2o.market.model.dto.response; package com.jzo2o.market.model.dto.response;
import com.jzo2o.market.enums.ActivityStatusEnum;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -10,6 +12,7 @@ import java.time.LocalDateTime;
@Data @Data
@ApiModel("抢券列表信息") @ApiModel("抢券列表信息")
@Accessors(chain = true)
public class SeizeCouponInfoResDTO implements Serializable { public class SeizeCouponInfoResDTO implements Serializable {
@ApiModelProperty("活动id") @ApiModelProperty("活动id")
private Long id; private Long id;
@ -28,12 +31,9 @@ public class SeizeCouponInfoResDTO implements Serializable {
@ApiModelProperty("发放结束时间") @ApiModelProperty("发放结束时间")
private LocalDateTime distributeEndTime; private LocalDateTime distributeEndTime;
@ApiModelProperty("优惠券配置状态1待生效2进行中3已失效") @ApiModelProperty("优惠券配置状态1待生效2进行中3已失效")
private Integer status; private ActivityStatusEnum status;
@ApiModelProperty("优惠券剩余数量")
private Integer remainNum;
@ApiModelProperty("发放数量") @ApiModelProperty("发放数量")
private Integer totalNum; private Integer totalNum;
@ApiModelProperty("库存数量") @ApiModelProperty("优惠券剩余数量(库存数量)")
private Integer stockNum; private Integer remainNum;
} }

View File

@ -1,17 +1,20 @@
package com.jzo2o.market.service; package com.jzo2o.market.service;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.market.model.domain.Activity;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.market.enums.ActivityStatusEnum;
import com.jzo2o.market.model.domain.Activity;
import com.jzo2o.market.model.dto.request.ActivityPageQueryDTO; import com.jzo2o.market.model.dto.request.ActivityPageQueryDTO;
import com.jzo2o.market.model.dto.request.ActivitySaveReqDTO; import com.jzo2o.market.model.dto.request.ActivitySaveReqDTO;
import com.jzo2o.market.model.dto.response.ActivityInfoResDTO; import com.jzo2o.market.model.dto.response.ActivityInfoResDTO;
import com.jzo2o.market.model.dto.response.SeizeCouponInfoResDTO;
import java.util.List;
/** /**
* <p> * <p>
* 服务类 * 服务类
* </p> * </p>
*
* @author itcast * @author itcast
* @since 2023-09-16 * @since 2023-09-16
*/ */
@ -26,6 +29,12 @@ public interface IActivityService extends IService<Activity> {
*/ */
ActivityInfoResDTO getDetailById(Long id); ActivityInfoResDTO getDetailById(Long id);
/**
* 获取缓存的活动信息
* @param status 筛选的活动状态
*/
List<SeizeCouponInfoResDTO> getCachedActivity(ActivityStatusEnum status);
/** /**
* 新增/插入活动信息 * 新增/插入活动信息
*/ */

View File

@ -10,6 +10,9 @@ import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.expcetions.ForbiddenOperationException; import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult; import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils; import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.JsonUtils;
import com.jzo2o.market.constants.RedisConstants;
import com.jzo2o.market.enums.ActivityStatusEnum; import com.jzo2o.market.enums.ActivityStatusEnum;
import com.jzo2o.market.enums.CouponStatusEnum; import com.jzo2o.market.enums.CouponStatusEnum;
import com.jzo2o.market.enums.CouponTypeEnum; import com.jzo2o.market.enums.CouponTypeEnum;
@ -19,14 +22,19 @@ import com.jzo2o.market.model.domain.Coupon;
import com.jzo2o.market.model.dto.request.ActivityPageQueryDTO; import com.jzo2o.market.model.dto.request.ActivityPageQueryDTO;
import com.jzo2o.market.model.dto.request.ActivitySaveReqDTO; import com.jzo2o.market.model.dto.request.ActivitySaveReqDTO;
import com.jzo2o.market.model.dto.response.ActivityInfoResDTO; import com.jzo2o.market.model.dto.response.ActivityInfoResDTO;
import com.jzo2o.market.model.dto.response.SeizeCouponInfoResDTO;
import com.jzo2o.market.service.IActivityService; import com.jzo2o.market.service.IActivityService;
import com.jzo2o.market.service.ICouponService; import com.jzo2o.market.service.ICouponService;
import com.jzo2o.mysql.utils.PageUtils; import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* <p> * <p>
@ -39,6 +47,8 @@ import java.util.List;
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService { public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {
@Resource @Resource
private ICouponService couponService; private ICouponService couponService;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -79,6 +89,29 @@ public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> i
return activityInfoResDTO; return activityInfoResDTO;
} }
@Override
public List<SeizeCouponInfoResDTO> getCachedActivity(ActivityStatusEnum status) {
List<SeizeCouponInfoResDTO> couponInfoList = JsonUtils.toList((String) redisTemplate.opsForValue()
.get(RedisConstants.RedisKey.ACTIVITY_CACHE_LIST), SeizeCouponInfoResDTO.class);
if (CollUtils.isEmpty(couponInfoList)) {
return new ArrayList<>();
}
LocalDateTime nowTime = LocalDateTime.now();
return couponInfoList.stream()
.peek(coupon -> {
// 防止缓存中的状态出错
if (coupon.getDistributeEndTime().isBefore(nowTime)) {
coupon.setStatus(ActivityStatusEnum.LOSE_EFFICACY);
} else if (coupon.getDistributeStartTime().isBefore(nowTime)) {
coupon.setStatus(ActivityStatusEnum.DISTRIBUTING);
}
})
.filter(coupon -> coupon.getStatus() == status)
.collect(Collectors.toList());
}
@Override @Override
@Transactional @Transactional
public void saveOrUpdate(ActivitySaveReqDTO activitySaveReqDTO) { public void saveOrUpdate(ActivitySaveReqDTO activitySaveReqDTO) {