guomengjiao 1 месяц назад
Родитель
Сommit
5a7c45ca3a

+ 73 - 0
ruoyi-api/src/main/java/com/ruoyi/api/controller/shop/ApiSeckillActivityProductController.java

@@ -1,13 +1,26 @@
 package com.ruoyi.api.controller.shop;
 
 import com.ruoyi.api.controller.common.AbstractApiController;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.enums.FilePathSplicingType;
+import com.ruoyi.common.filepathsplicing.FilePathSplicing;
+import com.ruoyi.shop.marketing.seckill.domain.bo.SeckillActivityProductBo;
+import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityAppVO;
+import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityProductVo;
 import com.ruoyi.shop.marketing.seckill.service.ISeckillActivityProductService;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
 /**
  * 秒杀活动商品Controller
  *
@@ -23,5 +36,65 @@ public class ApiSeckillActivityProductController extends AbstractApiController {
 
     private final ISeckillActivityProductService iSeckillActivityProductService;
 
+    /**
+     * 查询该店铺中的正在秒杀的活动商品
+     */
+    @ApiOperation("查询该店铺中的正在秒杀的活动商品")
+    @GetMapping("/seckillingList")
+    @FilePathSplicing(type = FilePathSplicingType.RESPONSE)
+    public R<List<SeckillActivityProductVo>> seckillingList(SeckillActivityProductBo bo) {
+        return R.ok(iSeckillActivityProductService.seckillingApiList(bo));
+    }
+
+    /**
+     * 查询该店铺中的即将秒杀的活动商品
+     */
+    @ApiOperation("查询该店铺中的即将秒杀的活动商品")
+    @GetMapping("/willSeckill")
+    @FilePathSplicing(type = FilePathSplicingType.RESPONSE)
+    public R<List<SeckillActivityProductVo>> willSeckill(SeckillActivityProductBo bo) {
+        return R.ok(iSeckillActivityProductService.willSeckill(bo));
+    }
+
+    /**
+     * 查询商家某个秒杀活动商品列表
+     */
+    @ApiOperation("查询商家某个秒杀活动商品列表")
+    @GetMapping("/getSeckillGoodsList/{seckillId}")
+    @FilePathSplicing(type = FilePathSplicingType.RESPONSE)
+    public R<List<SeckillActivityProductVo>> getSeckillGoodsList(@PathVariable("seckillId") Long seckillId) {
+        return R.ok(iSeckillActivityProductService.getBySeckillId(seckillId));
+    }
+
+    /**
+     * 获取秒杀活动商品详细信息
+     */
+    @ApiOperation("获取秒杀活动商品详细信息")
+    @GetMapping("/info/{id}")
+    @FilePathSplicing(type = FilePathSplicingType.RESPONSE)
+    public R<SeckillActivityProductVo> getInfo(@ApiParam("主键")
+                                               @NotNull(message = "主键不能为空")
+                                               @PathVariable("id") Long id) {
+        return R.ok(iSeckillActivityProductService.getSeckillProductById(id, false));
+    }
+
+    /**
+     * APP -- 限时秒杀
+     */
+    @GetMapping("/flash-sale")
+    @ApiOperation("APP -- 限时秒杀")
+    @FilePathSplicing(type = FilePathSplicingType.RESPONSE)
+    public R<SeckillActivityAppVO> flashSale(SeckillActivityProductBo bo) {
+        return R.ok(iSeckillActivityProductService.flashSale(bo));
+    }
 
+    /**
+     * APP -- 根据开始时间查询限时秒杀
+     */
+    @GetMapping("/start-flash-sale")
+    @ApiOperation("APP -- 根据开始时间查询限时秒杀")
+    @FilePathSplicing(type = FilePathSplicingType.RESPONSE)
+    public R<SeckillActivityAppVO> startFlashSale(SeckillActivityProductBo bo) {
+        return R.ok(iSeckillActivityProductService.startFlashSale(bo));
+    }
 }

+ 8 - 0
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/domain/bo/SeckillActivityProductBo.java

@@ -138,5 +138,13 @@ public class SeckillActivityProductBo extends BaseEntity {
     @ApiModelProperty(value = "最大销售价", required = true)
     private BigDecimal maxSalePrice;
 
+    @ApiModelProperty(value = "查询最大条目数")
+    private Integer limit;
+
+    @ApiModelProperty(value = "开始时间")
+    private String startHour;
+
+    @ApiModelProperty(value = "结束时间")
+    private String endHour;
 
 }

+ 36 - 0
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/domain/vo/SeckillActivityAppVO.java

@@ -0,0 +1,36 @@
+package com.ruoyi.shop.marketing.seckill.domain.vo;
+
+import com.ruoyi.common.filepathsplicing.FilePathValue;
+import com.ruoyi.shop.enums.ActiveState;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * APP秒杀活动
+ *
+ * @author Mark
+ * @email sunlightcs@gmail.com
+ * @date 2020-11-23 17:30:11
+ */
+@Data
+public class SeckillActivityAppVO implements Serializable {
+
+    private String startHour;//当前时间场次
+
+    private Long nowTime;//当前时间毫秒值
+
+    private Long finishTime;//结束时间毫秒值
+    /**
+     * 活动状态
+     * 0:即将开始
+     * 1:正在抢购
+     * 2:已过期
+     */
+    private ActiveState activeState;//当前时间状态
+
+    @FilePathValue
+    private List<SeckillActivityProductVo> list;
+
+}

+ 2 - 1
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/exception/SeckillActivityProductExceptionEnum.java

@@ -19,7 +19,8 @@ public enum SeckillActivityProductExceptionEnum implements IIntegerEnum {
     ACTIVITY_PRICE_OUT_OF_RANGE(540007, "活动价格不在范围"),
     ACTIVITY_PRICE_LT_SALE_PRICE(540008, "活动价格需要小于原价"),
     SALE_EXCEPTION(540009, "可售数量与初始化销量之和不能小于已售数量"),
-    SECKILL_ACTIVITY_START(540010, "秒杀活动已开始,不能操作");
+    SECKILL_ACTIVITY_START(540010, "秒杀活动已开始,不能操作"),
+    INCORRECT_PARAMETER_PASSED_IN(540011, "传入参数有误");
 
     private Integer code;
 

+ 5 - 0
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/mapper/SeckillActivityProductMapper.java

@@ -7,6 +7,7 @@ import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityProductVo;
 import com.ruoyi.common.core.mapper.BaseMapperPlus;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -22,4 +23,8 @@ public interface SeckillActivityProductMapper extends BaseMapperPlus<SeckillActi
     SeckillActivityProductVo getSeckillProductById(Long id);
 
     List<SeckillActivityProductVo> seckillingList(@Param("businessId") Long businessId);
+
+    List<SeckillActivityProductVo> willSeckillList(@Param("businessId") Long businessId, @Param("startTime") Date startTime);
+
+    List<SeckillActivityProductVo> getNowAllSeckillProduct(@Param("bo") SeckillActivityProductBo bo);
 }

+ 11 - 0
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/service/ISeckillActivityProductService.java

@@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.PageQuery;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.shop.marketing.seckill.domain.SeckillActivityProduct;
 import com.ruoyi.shop.marketing.seckill.domain.bo.SeckillActivityProductBo;
+import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityAppVO;
 import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityProductVo;
 
 import java.util.Collection;
@@ -81,4 +82,14 @@ public interface ISeckillActivityProductService {
     List<SeckillActivityProductVo> seckillingList(Long businessId);
 
     void setSemaphore(SeckillActivityProductVo vo);
+
+    List<SeckillActivityProductVo> seckillingApiList(SeckillActivityProductBo bo);
+
+    List<SeckillActivityProductVo> willSeckill(SeckillActivityProductBo bo);
+
+    List<SeckillActivityProductVo> getBySeckillId(Long seckillId);
+
+    SeckillActivityAppVO flashSale(SeckillActivityProductBo bo);
+
+    SeckillActivityAppVO startFlashSale(SeckillActivityProductBo bo);
 }

+ 4 - 0
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/service/ISeckillActivityTimeItemService.java

@@ -85,4 +85,8 @@ public interface ISeckillActivityTimeItemService {
     void saveBatch(List<SeckillActivityTimeItem> list);
 
     boolean removeBySeckillId(Long seckillId);
+
+    SeckillActivityTimeItem seckillingTime(Long businessId);
+
+    SeckillActivityTimeItem currentTimeOneSeckill(String startTime, Long businessId);
 }

+ 106 - 1
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/service/impl/SeckillActivityProductServiceImpl.java

@@ -14,27 +14,35 @@ import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.MathUtils;
 import com.ruoyi.common.utils.redis.RedisUtils;
 import com.ruoyi.common.utils.redis.SemaphoreTool;
+import com.ruoyi.shop.enums.ActiveState;
 import com.ruoyi.shop.enums.PriceType;
 import com.ruoyi.shop.marketing.seckill.domain.SeckillActivityProduct;
+import com.ruoyi.shop.marketing.seckill.domain.SeckillActivityTimeItem;
 import com.ruoyi.shop.marketing.seckill.domain.bo.SeckillActivityProductBo;
+import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityAppVO;
 import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityProductVo;
 import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityVo;
 import com.ruoyi.shop.marketing.seckill.exception.SeckillActivityProductExceptionEnum;
 import com.ruoyi.shop.marketing.seckill.mapper.SeckillActivityProductMapper;
 import com.ruoyi.shop.marketing.seckill.service.ISeckillActivityProductService;
 import com.ruoyi.shop.marketing.seckill.service.ISeckillActivityService;
+import com.ruoyi.shop.marketing.seckill.service.ISeckillActivityTimeItemService;
 import com.ruoyi.shop.product.domain.Product;
 import com.ruoyi.shop.product.domain.bo.ProductSkuSetBo;
 import com.ruoyi.shop.product.service.IProductService;
 import com.ruoyi.shop.product.service.IProductSkuSetService;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 秒杀活动商品Service业务层处理
@@ -49,6 +57,7 @@ public class SeckillActivityProductServiceImpl implements ISeckillActivityProduc
     private final SeckillActivityProductMapper baseMapper;
     private final IProductService productService;
     private final SemaphoreTool semaphoreTool;
+    private final ISeckillActivityTimeItemService seckillActivityTimeItemService;
     @Lazy
     @Resource
     private ISeckillActivityService seckillActivityService;
@@ -319,4 +328,100 @@ public class SeckillActivityProductServiceImpl implements ISeckillActivityProduc
         }
     }
 
+    @Override
+    public List<SeckillActivityProductVo> seckillingApiList(SeckillActivityProductBo bo) {
+        //正在秒杀的活动商品
+        List<SeckillActivityProductVo> seckillActivityProductVos = baseMapper.seckillingList(bo.getBusinessId());
+        seckillActivityProductVos.forEach(SeckillActivityProductVo::loadDiscount);
+        return seckillActivityProductVos;
+    }
+
+    @Override
+    public List<SeckillActivityProductVo> willSeckill(SeckillActivityProductBo bo) {
+        //查询当前正在秒杀的活动
+        SeckillActivityTimeItem timeItem = seckillActivityTimeItemService.seckillingTime(bo.getBusinessId());
+        //取出开始时间,用于查询下一场活动
+        Date startTime = new Date();
+        if (timeItem != null) {
+            startTime = timeItem.getStartTime();
+        }
+        List<SeckillActivityProductVo> list = baseMapper.willSeckillList(bo.getBusinessId(), startTime);
+        list.forEach(SeckillActivityProductVo::loadDiscount);
+        return list;
+    }
+
+    @Override
+    public List<SeckillActivityProductVo> getBySeckillId(Long seckillId) {
+        List<SeckillActivityProductVo> seckillActivityProductVos = baseMapper.selectVoList(new LambdaQueryWrapper<SeckillActivityProduct>()
+            .eq(SeckillActivityProduct::getSeckillId, seckillId)
+            .orderByAsc(SeckillActivityProduct::getCreateTime)
+        );
+        seckillActivityProductVos.forEach(v -> {
+            //设置秒杀活动商品sku
+            v.loadProductSkuSetList();
+        });
+        return seckillActivityProductVos;
+    }
+
+    @Override
+    public SeckillActivityAppVO flashSale(SeckillActivityProductBo bo) {
+        SeckillActivityAppVO vo = new SeckillActivityAppVO();
+        //秒杀活动结束时间戳
+        SeckillActivityTimeItem timeItem = seckillActivityTimeItemService.seckillingTime(bo.getBusinessId());
+        if (timeItem != null) {
+            //开始时间场次
+            String startHour = timeItem.getStartHour();
+            vo.setStartHour(startHour.split(":")[0]);
+            //结束时间
+            vo.setFinishTime(timeItem.getEndTime().getTime());
+            //当前时间段所有秒杀活动商品
+            vo.setList(baseMapper.getNowAllSeckillProduct(bo));
+        }
+        return vo;
+    }
+
+    @Override
+    public SeckillActivityAppVO startFlashSale(SeckillActivityProductBo bo) {
+        SeckillActivityAppVO vo = new SeckillActivityAppVO();
+        String startHour = bo.getStartHour();
+        String endHour = bo.getEndHour();
+        Long businessId = bo.getBusinessId();
+        if (StringUtils.isBlank(startHour) || StringUtils.isBlank(endHour)) {
+            throw new ServiceException(SeckillActivityProductExceptionEnum.INCORRECT_PARAMETER_PASSED_IN);
+        }
+        //活动开始时间
+        String startTime = DateCustomUtils.dateToString(new Date()) + " " + startHour;
+        //活动结束时间
+        String endTime = DateCustomUtils.dateToString(new Date()) + " " + endHour;
+        long nowTime = System.currentTimeMillis();
+        long startTimestamp = DateUtils.stringToDate(startTime).getTime();
+        long endTimestamp = DateUtils.stringToDate(endTime).getTime();
+        vo.setStartHour(startHour);
+        //当前时间
+        vo.setNowTime(nowTime);
+        //结束时间
+        vo.setFinishTime(endTimestamp);
+        //设置活动状态 -- 计算当前时间的活动状态
+        if (nowTime < startTimestamp) {
+            //即将开始
+            vo.setActiveState(ActiveState.NOT_START);
+        } else if (nowTime > endTimestamp) {
+            //已过期
+            vo.setActiveState(ActiveState.FINISHED);
+        } else {
+            //正在抢购
+            vo.setActiveState(ActiveState.UNDERWAY);
+        }
+        //查询当前开始时间段的活动
+        SeckillActivityTimeItem timeItem = seckillActivityTimeItemService.currentTimeOneSeckill(startTime, businessId);
+        if (timeItem != null) {
+            //查询秒杀活动
+            seckillActivityService.loadById(timeItem.getSeckillId(), true);
+            //当前场次所有的活动商品
+//            IPage<SeckillActivityGoodsVO> page = this.baseMapper.startFlashSalePage(new Query<SeckillActivityGoodsVO>().getPage(params), startTime, shopId);
+//            vo.setPage(new PageUtils(page));
+        }
+        return vo;
+    }
+
 }

+ 35 - 10
ruoyi-shop/src/main/java/com/ruoyi/shop/marketing/seckill/service/impl/SeckillActivityTimeItemServiceImpl.java

@@ -2,28 +2,31 @@ package com.ruoyi.shop.marketing.seckill.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.domain.PageQuery;
+import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.BeanCopyUtils;
 import com.ruoyi.common.utils.DateCustomUtils;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.core.domain.PageQuery;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.shop.enums.Week;
 import com.ruoyi.shop.marketing.seckill.domain.SeckillActivity;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
+import com.ruoyi.shop.marketing.seckill.domain.SeckillActivityTimeItem;
 import com.ruoyi.shop.marketing.seckill.domain.bo.SeckillActivityTimeItemBo;
 import com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityTimeItemVo;
-import com.ruoyi.shop.marketing.seckill.domain.SeckillActivityTimeItem;
+import com.ruoyi.shop.marketing.seckill.exception.SeckillActivityTimeItemExceptionEnum;
 import com.ruoyi.shop.marketing.seckill.mapper.SeckillActivityTimeItemMapper;
 import com.ruoyi.shop.marketing.seckill.service.ISeckillActivityTimeItemService;
-import com.ruoyi.shop.marketing.seckill.exception.SeckillActivityTimeItemExceptionEnum;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 秒杀活动日期时间Service业务层处理
@@ -212,4 +215,26 @@ public class SeckillActivityTimeItemServiceImpl implements ISeckillActivityTimeI
         return baseMapper.delete(new LambdaQueryWrapper<SeckillActivityTimeItem>().eq(SeckillActivityTimeItem::getSeckillId, seckillId)) > 0;
     }
 
+    @Override
+    public SeckillActivityTimeItem seckillingTime(Long businessId) {
+        Date date = new Date();
+        return baseMapper.selectOne(
+            new LambdaQueryWrapper<SeckillActivityTimeItem>()
+                .eq(businessId != null, SeckillActivityTimeItem::getBusinessId, businessId)
+                .le(SeckillActivityTimeItem::getStartTime, date)
+                .ge(SeckillActivityTimeItem::getEndTime, date)
+                .last("limit 1")
+        );
+    }
+
+    @Override
+    public SeckillActivityTimeItem currentTimeOneSeckill(String startTime, Long businessId) {
+        return this.baseMapper.selectOne(
+            new LambdaQueryWrapper<SeckillActivityTimeItem>()
+                .eq(businessId != null, SeckillActivityTimeItem::getBusinessId, businessId)
+                .eq(SeckillActivityTimeItem::getStartTime, startTime)
+                .last("limit 1")
+        );
+    }
+
 }

+ 32 - 1
ruoyi-shop/src/main/resources/mapper/marketing/seckill/SeckillActivityProductMapper.xml

@@ -67,7 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT OUTER JOIN tb_product tp ON sap.product_id=tp.product_id
         LEFT OUTER JOIN tb_seckill_activity sa ON sap.seckill_id=sa.id
         LEFT OUTER JOIN tb_seckill_activity_time_item sati ON sati.seckill_id=sap.seckill_id
-        WHERE tp.shelved_status = 1 and tp.audit_status = 10 AND sap.residue_stock_total > 0
+        WHERE sap.residue_stock_total > 0 and sa.discard = 0
         <if test="businessId != null and businessId != ''">
             AND sa.business_id = #{businessId}
         </if>
@@ -75,5 +75,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ORDER BY sap.sort ASC,sap.update_time DESC
     </select>
 
+    <select id="willSeckillList"
+            resultType="com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityProductVo">
+        SELECT
+            sap.*,tp.title,tp.cover_image,sa.start_time,sa.end_time,sa.start_hour,sa.end_hour
+        FROM tb_seckill_activity_product sap
+                 LEFT OUTER JOIN tb_seckill_activity sa ON sap.seckill_id=sa.id
+                 LEFT OUTER JOIN tb_product tp ON sap.product_id=tp.product_id
+        WHERE sa.business_id = #{businessId} and sa.discard = 0
+          AND sap.seckill_id=(SELECT seckill_id  FROM  tb_seckill_activity_time_item where start_time>#{startTime}   ORDER BY start_time limit 1)
+        ORDER BY sap.sort,sap.update_time ASC
+    </select>
+
+    <select id="getNowAllSeckillProduct"
+            resultType="com.ruoyi.shop.marketing.seckill.domain.vo.SeckillActivityProductVo">
+        SELECT
+        sap.id,sap.min_price,sap.max_price,sa.start_time,sa.end_time,sa.start_hour,sa.end_hour,tp.title,tp.cover
+        FROM tb_seckill_activity_product sap
+        LEFT OUTER JOIN tb_seckill_activity sa ON sap.seckill_id=sa.id
+        LEFT OUTER JOIN tb_product tp ON sap.product_id=tp.product_id
+        WHERE sa.discard = 0 and sap.seckill_id in (
+            SELECT DISTINCT(seckill_id) FROM `tb_seckill_activity_time_item`
+                WHERE NOW() &gt;= start_time AND NOW() &lt; end_time
+            <if test="bo.businessId != null">
+                AND business_id = #{bo.businessId}
+            </if>
+        )
+        ORDER BY sap.create_time DESC
+        <if test ="bo.limit!=null and bo.limit>0">
+            limit #{bo.limit}
+        </if>
+    </select>
 
 </mapper>