目录
一、秒杀模块搭建
基本和之前的模块搭建一样配置就行
二、秒杀商品上架
1、远程服务查询秒杀商品时间-【优惠卷模块】
1.远程调用coupon服务查询时间
com.atguigu.gulimall.seckill.feign.CouponFeignService
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
@GetMapping("/coupon/seckillsession/lates3DaySession")
R getLates3DaySession();
}
2.商品服务controller类
coupon商品服务
com.atguigu.gulimall.coupon.controller.SeckillSessionController
@GetMapping("/lates3DaySession")
public R getLates3DaySession(){
List<SeckillSessionEntity> sessions = seckillSessionService.getLates3DaySession();
return R.ok().setData(sessions);
}
3.coupon服务查询根据时间相应商品实现类
com.atguigu.gulimall.coupon.service.impl.SeckillSessionServiceImpl
startTime sendTime将查出的时间进行格式化,对时间日期进行处理
private String startTime(){
LocalDate now = LocalDate.now();
LocalTime min = LocalTime.MIN;
LocalDateTime start = LocalDateTime.of(now, min);
String format = start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
return format;
}
private String endTime(){
LocalDate now = LocalDate.now();
LocalDate localDate = now.plusDays(2);
LocalDateTime of = LocalDateTime.of(localDate, LocalTime.MAX);
String format = of.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
return format;
}
设计getLate3Day查出时间内,相应的活动信息。以及活动绑定的商品
@Override
public List<SeckillSessionEntity> getLates3DaySession() {
//
List<SeckillSessionEntity> list = this.list(new QueryWrapper<SeckillSessionEntity>().between("start_time", startTime(), endTime()));
//活动关联的相关商品
if(list != null ){
List<SeckillSessionEntity> collect = list.stream().map(session -> {
Long id = session.getId();
List<SeckillSkuRelationEntity> relationEntities = seckillSkuRelationService.list(new QueryWrapper<SeckillSkuRelationEntity>().eq("promotion_session_id", id));
session.setRelationSkus(relationEntities);
return session;
}).collect(Collectors.toList());
return collect;
}
return null;
}
2、商品上架功能
1.调用商品服务远程模块查询sku信息【商品模块】
com.atguigu.gulimall.seckill.feign.ProductFeignService
@FeignClient("gulimall-product")
public interface ProductFeignService {
@RequestMapping("/product/skuinfo/info/{skuId}")
R getSkuInfo(@PathVariable("skuId") Long skuId);
}
2.controller类秒杀商品上架
3.秒杀商品上架实现类
com.atguigu.gulimall.seckill.service.impl.SeckillServiceImpl
@Service
public class SeckillServiceImpl implements SeckillService {
@Autowired
CouponFeignService couponFeignService;
@Autowired
StringRedisTemplate redisTemplate;
@Autowired
ProductFeignService productFeignService;
@Autowired
RedissonClient redissonClient;
private final String SESSIONS_CACHE_PREFIX = "seckill:sessions";
private final String SKUKILL_CACHE_PREFIX = "seckill:skus";
private final String SKU_STOCK_SEMAPHORE = "seckill:stock:";
public void uploadSeckillSkuLatest3Days(){
//扫描最近三天需要参与秒杀的活动
R session = couponFeignService.getLates3DaySession();
if(session.getCode() == 0){
//上架商品
List<SeckillSessionsWithSkus> sessionData = session.getData(new TypeReference<List<SeckillSessionsWithSkus>>(){});
//缓存到redis
//1.缓冲活动信息
saveSessionInfos(sessionData);
//2.缓存活动的关联信息
saveSessionSkuInfos(sessionData);
}
}
private void saveSessionInfos(List<SeckillSessionsWithSkus> sessions){
sessions.stream().forEach(session ->{
Long startTime = session.getStartTime().getTime();
Long endTime = session.getEndTime().getTime();
String key = SESSIONS_CACHE_PREFIX + startTime+"_"+endTime;
Boolean hasKey = redisTemplate.hasKey(key);
if(!hasKey){
List<String> collect = session.getRelationSkus().stream().map(item-> item.getPromotionSessionId()+"_"+item.getSkuId().toString()).collect(Collectors.toList());
//缓存活动信息
redisTemplate.opsForList().leftPushAll(key,collect);
}
});
}
private void saveSessionSkuInfos(List<SeckillSessionsWithSkus> sessions){
sessions.stream().forEach(session -> {
BoundHashOperations<String, Object, Object> ops = redisTemplate.boundHashOps(SKUKILL_CACHE_PREFIX);
session.getRelationSkus().stream().forEach(seckillSkuVo -> {
String token = UUID.randomUUID().toString().replace("-","");
if(!ops.hasKey(seckillSkuVo.getPromotionSessionId().toString()+"_"+seckillSkuVo.getSkuId().toString())){
//缓存商品
SecKillSkuRedisTo redisTo = new SecKillSkuRedisTo();
//1.sku的基本数据
R skuInfo = productFeignService.getSkuInfo(seckillSkuVo.getSkuId());
if(skuInfo.getCode() == 0){
SkuInfoVo info = skuInfo.getData("skuInfo", new TypeReference<SkuInfoVo>(){});
redisTo.setSkuInfo(info);
}
//2.sku的秒杀信息
BeanUtils.copyProperties(seckillSkuVo, redisTo);
//3.设置当前商品的秒杀信息
redisTo.setStartTime(session.getStartTime().getTime());
redisTo.setEndTime(session.getEndTime().getTime());
//4.随机码
redisTo.setRandomCode(token);
String jsonString = JSON.toJSONString(redisTo);
ops.put(seckillSkuVo.getPromotionSessionId().toString()+"_"+seckillSkuVo.getSkuId().toString(), jsonString);
//如果当前的这个场次的库存信息以及上架就不需要上架
//5.使用库存作为分布式的信号量 限流
RSemaphore semaphore = redissonClient.getSemaphore(SKU_STOCK_SEMAPHORE + token);
semaphore.trySetPermits(seckillSkuVo.getSeckillCount());
}
});
});
}
}
3、前端页面修改
<div class="section_second_list">
<div class="swiper-container swiper_section_second_list_left">
<div class="swiper-wrapper">
<div class="swiper-slide">
<ul id="seckillSkuContent">
</ul>
$.get("http://seckill.yjlmall.com/currentSeckillSkus",function (resp){
if(resp.data.length > 0){
resp.data.forEach(function (item) {
$("<li></li>")
.append($("<img style='width: 130px;height: 130px' src='"+item.skuInfo.skuInfo.skuDefaultImg+"'/>"))
.append($("<p>"+item.skuInfo.skuTitle+"</p>"))
.append($("<span>"+item.seckillPrice+"</span>"))
.append($("<s>"+item.skuInfo.price+"</s>"))
.appendTo("#seckillSkuContent");
})
}
});