谷粒商城学习笔记(17.秒杀系统)

一、秒杀模块搭建

基本和之前的模块搭建一样配置就行

二、秒杀商品上架

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");
      })
    }
  });

4、测试

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值