feat(market):新增持久化Redis抢卷信息的功能
This commit is contained in:
parent
136715846c
commit
31b5b7c8f2
@ -0,0 +1,28 @@
|
||||
package com.jzo2o.market.config;
|
||||
|
||||
import com.jzo2o.redis.properties.RedisSyncProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 线程池配置
|
||||
* @author JIAN
|
||||
*/
|
||||
@Configuration
|
||||
public class TreadPoolConfiguration {
|
||||
@Bean("syncThreadPool")
|
||||
public ThreadPoolExecutor threadPoolExecutor(RedisSyncProperties redisSyncProperties) {
|
||||
return new ThreadPoolExecutor(
|
||||
1,
|
||||
redisSyncProperties.getQueueNum(),
|
||||
120,
|
||||
TimeUnit.SECONDS,
|
||||
new SynchronousQueue<>(),
|
||||
new ThreadPoolExecutor.DiscardPolicy()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.jzo2o.market.handler;
|
||||
|
||||
import com.jzo2o.common.expcetions.CommonException;
|
||||
import com.jzo2o.market.service.ICouponService;
|
||||
import com.jzo2o.redis.handler.SyncProcessHandler;
|
||||
import com.jzo2o.redis.model.SyncMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jzo2o.market.constants.RedisConstants.RedisKey.COUPON_SEIZE_SYNC_QUEUE_NAME;
|
||||
|
||||
/**
|
||||
* 抢卷同步队列同步处理器
|
||||
* @author JIAN
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(COUPON_SEIZE_SYNC_QUEUE_NAME)
|
||||
public class SeizeCouponSyncProcessHandler implements SyncProcessHandler<Object> {
|
||||
@Resource
|
||||
private ICouponService couponService;
|
||||
|
||||
@Override
|
||||
public void batchProcess(List<SyncMessage<Object>> multiData) {
|
||||
throw new CommonException("不支持批量处理");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void singleProcess(SyncMessage<Object> singleData) {
|
||||
long userId = Long.parseLong(singleData.getKey());
|
||||
long activityId = Long.parseLong(singleData.getValue().toString());
|
||||
|
||||
log.info("同步优惠卷信息, 活动id: {}, 用户id: {}", activityId, userId);
|
||||
couponService.syncCouponRecord(activityId, userId);
|
||||
}
|
||||
}
|
||||
@ -2,14 +2,20 @@ package com.jzo2o.market.handler;
|
||||
|
||||
import com.jzo2o.market.service.IActivityService;
|
||||
import com.jzo2o.market.service.ICouponService;
|
||||
import com.jzo2o.redis.sync.SyncManager;
|
||||
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.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import static com.jzo2o.market.constants.RedisConstants.RedisKey.COUPON_SEIZE_SYNC_QUEUE_NAME;
|
||||
import static com.jzo2o.redis.constants.RedisSyncQueueConstants.MODE_SINGLE;
|
||||
import static com.jzo2o.redis.constants.RedisSyncQueueConstants.STORAGE_TYPE_HASH;
|
||||
|
||||
/**
|
||||
* XxlJob任务处理器
|
||||
* @author JIAN
|
||||
@ -22,8 +28,10 @@ public class XxlJobHandler {
|
||||
private IActivityService activityService;
|
||||
@Resource
|
||||
private ICouponService couponService;
|
||||
@Resource(name = "syncThreadPool")
|
||||
private ThreadPoolExecutor syncThreadPool;
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
private SyncManager syncManager;
|
||||
|
||||
/**
|
||||
* 自动修改活动状态(1分钟1次)
|
||||
@ -57,4 +65,13 @@ public class XxlJobHandler {
|
||||
activityService.cacheComingActivity();
|
||||
log.info("自动预热1个月内的活动任务完成");
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动从Redis同步抢卷结果到数据库
|
||||
*/
|
||||
@XxlJob("seizeCouponSyncJob")
|
||||
public void seizeCouponSyncJob() {
|
||||
log.info("自动从Redis同步抢卷结果到数据库任务开始");
|
||||
syncManager.start(COUPON_SEIZE_SYNC_QUEUE_NAME, STORAGE_TYPE_HASH, MODE_SINGLE, syncThreadPool);
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.jzo2o.market.enums.CouponTypeEnum;
|
||||
import com.jzo2o.market.enums.CouponStatusEnum;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
@ -20,6 +21,7 @@ import java.time.LocalDateTime;
|
||||
* @since 2023-09-16
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class Coupon implements Serializable {
|
||||
@ -29,7 +31,7 @@ public class Coupon implements Serializable {
|
||||
/**
|
||||
* 优惠券id
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.NONE)
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.jzo2o.market.model.dto.response;
|
||||
|
||||
import com.jzo2o.market.enums.CouponStatusEnum;
|
||||
import com.jzo2o.market.enums.CouponTypeEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ -25,7 +26,7 @@ public class CouponSimpleInfoResDTO implements Serializable {
|
||||
private Long activityId;
|
||||
|
||||
@ApiModelProperty(value = "使用类型,1:满减,2:折扣", required = true)
|
||||
private Integer type;
|
||||
private CouponTypeEnum type;
|
||||
|
||||
@ApiModelProperty(value = "折扣")
|
||||
private Integer discountRate;
|
||||
|
||||
@ -12,9 +12,8 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author itcast
|
||||
* @since 2023-09-16
|
||||
*/
|
||||
@ -33,4 +32,9 @@ public interface ICouponService extends IService<Coupon> {
|
||||
* 更新过期优惠卷的状态为失效中
|
||||
*/
|
||||
void invalidExpiredCoupon();
|
||||
|
||||
/**
|
||||
* 同步优惠卷数据到数据库中
|
||||
*/
|
||||
void syncCouponRecord(long activityId, long userId);
|
||||
}
|
||||
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.jzo2o.api.customer.CommonUserApi;
|
||||
import com.jzo2o.api.customer.dto.response.CommonUserResDTO;
|
||||
import com.jzo2o.common.expcetions.BadRequestException;
|
||||
import com.jzo2o.common.expcetions.DBException;
|
||||
import com.jzo2o.common.model.PageResult;
|
||||
@ -13,6 +14,7 @@ import com.jzo2o.common.utils.BeanUtils;
|
||||
import com.jzo2o.common.utils.CollUtils;
|
||||
import com.jzo2o.market.enums.CouponStatusEnum;
|
||||
import com.jzo2o.market.mapper.CouponMapper;
|
||||
import com.jzo2o.market.model.domain.Activity;
|
||||
import com.jzo2o.market.model.domain.Coupon;
|
||||
import com.jzo2o.market.model.dto.request.CouponPageQueryDTO;
|
||||
import com.jzo2o.market.model.dto.response.CouponPageInfoResDTO;
|
||||
@ -21,9 +23,7 @@ import com.jzo2o.market.service.IActivityService;
|
||||
import com.jzo2o.market.service.ICouponService;
|
||||
import com.jzo2o.mvc.utils.UserContext;
|
||||
import com.jzo2o.mysql.utils.PageUtils;
|
||||
import com.jzo2o.redis.properties.RedisSyncProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -43,10 +43,6 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
@Slf4j
|
||||
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements ICouponService {
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Resource
|
||||
private RedisSyncProperties redisSyncProperties;
|
||||
@Resource
|
||||
private CommonUserApi commonUserApi;
|
||||
@Resource
|
||||
@ -110,4 +106,35 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
|
||||
throw new DBException("更新优惠卷状态失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void syncCouponRecord(long activityId, long userId) {
|
||||
Activity activity = activityService.getById(activityId);
|
||||
CommonUserResDTO user = commonUserApi.findById(userId);
|
||||
|
||||
if (!this.save(Coupon.builder()
|
||||
.userId(userId)
|
||||
.userName(user.getNickname())
|
||||
.userPhone(user.getPhone())
|
||||
.activityId(activityId)
|
||||
.name(activity.getName())
|
||||
.type(activity.getType())
|
||||
.amountCondition(activity.getAmountCondition())
|
||||
.discountRate(activity.getDiscountRate())
|
||||
.discountAmount(activity.getDiscountAmount())
|
||||
.validityTime(LocalDateTime.now().plusDays(activity.getValidityDays()))
|
||||
.status(CouponStatusEnum.NO_USE)
|
||||
.build())) {
|
||||
throw new DBException("插入优惠卷表失败");
|
||||
}
|
||||
|
||||
if (!activityService.lambdaUpdate()
|
||||
.setSql("stock_num = stock_num - 1")
|
||||
.eq(Activity::getId, activityId)
|
||||
.gt(Activity::getStockNum, 0)
|
||||
.update()) {
|
||||
throw new DBException("更新活动库存失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user