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;
import com.jzo2o.common.expcetions.DBException;
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.CouponStatusEnum;
import com.jzo2o.market.model.domain.Activity;
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.ICouponService;
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.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -21,6 +29,7 @@ import java.util.stream.Collectors;
* XxlJob任务处理器
* @author JIAN
*/
@Slf4j
@Component
@SuppressWarnings("unused")
public class XxlJobHandler {
@ -28,6 +37,8 @@ public class XxlJobHandler {
private IActivityService activityService;
@Resource
private ICouponService couponService;
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 自动修改活动状态(1分钟1次)
@ -37,6 +48,7 @@ public class XxlJobHandler {
@XxlJob("updateActivityStatus")
@Transactional
public void updateActivityStatus() {
log.info("自动修改活动状态任务开始");
LocalDateTime nowTime = LocalDateTime.now();
List<Activity> activityList = activityService.lambdaQuery()
.eq(Activity::getStatus, ActivityStatusEnum.NO_DISTRIBUTE)
@ -76,6 +88,7 @@ public class XxlJobHandler {
@XxlJob("processExpireCoupon")
@Transactional
public void processExpireCoupon() {
log.info("自动过期已领取优惠券任务开始");
List<Coupon> couponList = couponService.lambdaQuery()
.eq(Coupon::getStatus, CouponStatusEnum.NO_USE)
// 不处理还没到有效期的优惠卷
@ -96,4 +109,36 @@ public class XxlJobHandler {
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;
import com.jzo2o.market.enums.ActivityStatusEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
@ -10,6 +12,7 @@ import java.time.LocalDateTime;
@Data
@ApiModel("抢券列表信息")
@Accessors(chain = true)
public class SeizeCouponInfoResDTO implements Serializable {
@ApiModelProperty("活动id")
private Long id;
@ -28,12 +31,9 @@ public class SeizeCouponInfoResDTO implements Serializable {
@ApiModelProperty("发放结束时间")
private LocalDateTime distributeEndTime;
@ApiModelProperty("优惠券配置状态1待生效2进行中3已失效")
private Integer status;
@ApiModelProperty("优惠券剩余数量")
private Integer remainNum;
private ActivityStatusEnum status;
@ApiModelProperty("发放数量")
private Integer totalNum;
@ApiModelProperty("库存数量")
private Integer stockNum;
}
@ApiModelProperty("优惠券剩余数量(库存数量)")
private Integer remainNum;
}

View File

@ -1,17 +1,20 @@
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.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.ActivitySaveReqDTO;
import com.jzo2o.market.model.dto.response.ActivityInfoResDTO;
import com.jzo2o.market.model.dto.response.SeizeCouponInfoResDTO;
import java.util.List;
/**
* <p>
* 服务类
* 服务类
* </p>
*
* @author itcast
* @since 2023-09-16
*/
@ -26,6 +29,12 @@ public interface IActivityService extends IService<Activity> {
*/
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.model.PageResult;
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.CouponStatusEnum;
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.ActivitySaveReqDTO;
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.ICouponService;
import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
@ -39,6 +47,8 @@ import java.util.List;
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {
@Resource
private ICouponService couponService;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
@SuppressWarnings("unchecked")
@ -79,6 +89,29 @@ public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> i
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
@Transactional
public void saveOrUpdate(ActivitySaveReqDTO activitySaveReqDTO) {