Commit 408df683d8867330ca69adb09681f07653981b17

Authored by puhui999
1 parent af6016bb

秒杀活动: 完善 app 端获取活动分页、列表、详情接口

Showing 12 changed files with 217 additions and 101 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
... ... @@ -43,6 +43,16 @@ public class LocalDateTimeUtils {
43 43 return LocalDateTime.of(year, mouth, day, 0, 0, 0);
44 44 }
45 45  
  46 + /**
  47 + * 创建指定时间
  48 + *
  49 + * @param timeStr 时间字符串
  50 + * @return 指定时间
  51 + */
  52 + public static LocalDateTime buildTime(String timeStr) {
  53 + return LocalDateTime.of(LocalDate.now(), LocalTime.parse(timeStr));
  54 + }
  55 +
46 56 public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1,
47 57 int year2, int mouth2, int day2) {
48 58 return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)};
... ... @@ -63,6 +73,22 @@ public class LocalDateTimeUtils {
63 73 }
64 74  
65 75 /**
  76 + * 判断当前时间是否在该时间范围内
  77 + *
  78 + * @param startTime 开始时间
  79 + * @param endTime 结束时间
  80 + * @return 是否
  81 + */
  82 + public static boolean isBetween(String startTime, String endTime) {
  83 + if (startTime == null || endTime == null) {
  84 + return false;
  85 + }
  86 + LocalDate nowDate = LocalDate.now();
  87 + return LocalDateTimeUtil.isIn(LocalDateTime.now(), LocalDateTime.of(nowDate, LocalTime.parse(startTime)),
  88 + LocalDateTime.of(nowDate, LocalTime.parse(endTime)));
  89 + }
  90 +
  91 + /**
66 92 * 判断时间段是否重叠
67 93 *
68 94 * @param startTime1 开始 time1
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
... ... @@ -56,6 +56,7 @@ public interface ErrorCodeConstants {
56 56 ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除");
57 57 ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭");
58 58 ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "秒杀失败,原因秒杀库存不足");
  59 + ErrorCode SECKILL_ACTIVITY_FAIL_STATUS_CLOSED = new ErrorCode(1013008007, "秒杀活动已关闭");
59 60  
60 61 // ========== 秒杀时段 1013009000 ==========
61 62 ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在");
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
1 1 package cn.iocoder.yudao.module.promotion.controller.app.seckill;
2 2  
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  8 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  9 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
5 10 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
6 11 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
7 12 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
8 13 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
9   -import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
  14 +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
  15 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
  16 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
  17 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
  18 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
  19 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
10 20 import io.swagger.v3.oas.annotations.Operation;
11 21 import io.swagger.v3.oas.annotations.Parameter;
12 22 import io.swagger.v3.oas.annotations.tags.Tag;
  23 +import org.springframework.context.annotation.Lazy;
13 24 import org.springframework.validation.annotation.Validated;
14 25 import org.springframework.web.bind.annotation.GetMapping;
15 26 import org.springframework.web.bind.annotation.RequestMapping;
16 27 import org.springframework.web.bind.annotation.RequestParam;
17 28 import org.springframework.web.bind.annotation.RestController;
18 29  
19   -import java.time.LocalDateTime;
20   -import java.util.ArrayList;
  30 +import javax.annotation.Resource;
  31 +import java.util.Arrays;
21 32 import java.util.List;
22 33  
  34 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
23 35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  36 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst;
  38 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween;
  39 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_FAIL_STATUS_CLOSED;
24 40  
25 41 @Tag(name = "用户 App - 秒杀活动")
26 42 @RestController
27 43 @RequestMapping("/promotion/seckill-activity")
28 44 @Validated
29 45 public class AppSeckillActivityController {
  46 + @Resource
  47 + private SeckillActivityService activityService;
  48 + @Resource
  49 + @Lazy
  50 + private SeckillConfigService configService;
  51 +
  52 + @Resource
  53 + private ProductSpuApi spuApi;
30 54  
31 55 @GetMapping("/get-now")
32 56 @Operation(summary = "获得当前秒杀活动") // 提供给首页使用
33 57 // TODO 芋艿:需要增加 spring cache
34 58 public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() {
35   - AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();
36   - respVO.setConfig(new AppSeckillConfigRespVO().setId(10L).setStartTime("01:00").setEndTime("09:59"));
37   - List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
38   - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
39   - activity1.setId(1L);
40   - activity1.setName("618 大秒杀");
41   - activity1.setSpuId(2048L);
42   - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
43   - activity1.setMarketPrice(50);
44   - activity1.setSeckillPrice(100);
45   - activityList.add(activity1);
  59 + // 1、获取当前时间处在哪个秒杀阶段
  60 + List<SeckillConfigDO> configList = configService.getSeckillConfigList();
  61 + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(),
  62 + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime()));
  63 + // 1、1 时段不存在直接返回 null
  64 + if (filteredConfig == null) {
  65 + return success(null);
  66 + }
46 67  
47   - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
48   - activity2.setId(2L);
49   - activity2.setName("双十一大秒杀");
50   - activity2.setSpuId(4096L);
51   - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg");
52   - activity2.setMarketPrice(100);
53   - activity2.setSeckillPrice(200);
54   - activityList.add(activity2);
55   - respVO.setActivities(activityList);
56   - return success(respVO);
  68 + // 2、查询满足当前阶段的活动
  69 + List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIds(Arrays.asList(filteredConfig.getId()));
  70 + List<SeckillActivityDO> filteredList = filterList(activityList, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.ENABLE.getStatus()));
  71 + // 2、1 获取 spu 信息
  72 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(filteredList, SeckillActivityDO::getSpuId));
  73 + return success(SeckillActivityConvert.INSTANCE.convert(filteredConfig, filteredList, spuList));
57 74 }
58 75  
59 76 @GetMapping("/page")
60 77 @Operation(summary = "获得秒杀活动分页")
61   - // TODO @芋艿:分页参数
62 78 public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) {
63   - List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
64   - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
65   - activity1.setId(1L);
66   - activity1.setName("618 大秒杀");
67   - activity1.setSpuId(2048L);
68   - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
69   - activity1.setMarketPrice(50);
70   - activity1.setSeckillPrice(100);
71   - activity1.setUnitName("个");
72   - activity1.setStock(1);
73   - activity1.setTotalStock(2);
74   - activityList.add(activity1);
75   -
76   - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
77   - activity2.setId(2L);
78   - activity2.setName("双十一大秒杀");
79   - activity2.setSpuId(4096L);
80   - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg");
81   - activity2.setMarketPrice(100);
82   - activity2.setSeckillPrice(200);
83   - activity2.setUnitName("套");
84   - activity2.setStock(2);
85   - activity2.setTotalStock(3);
86   - activityList.add(activity2);
87   - return success(new PageResult<>(activityList, 100L));
  79 + // 1、查询满足当前阶段的活动
  80 + PageResult<SeckillActivityDO> pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO);
  81 + // 1、1 获取 spu 信息
  82 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(pageResult.getList(), SeckillActivityDO::getSpuId));
  83 + return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, spuList));
88 84 }
89 85  
90 86 @GetMapping("/get-detail")
91 87 @Operation(summary = "获得秒杀活动明细")
92 88 @Parameter(name = "id", description = "活动编号", required = true, example = "1024")
93 89 public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
  90 + // 1、获取当前时间处在哪个秒杀阶段
  91 + List<SeckillConfigDO> configList = configService.getSeckillConfigList();
  92 + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(),
  93 + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime()));
  94 + // 1、1 时段不存在直接返回 null
  95 + if (filteredConfig == null) {
  96 + return success(null);
  97 + }
  98 +
  99 + // 2、获取活动
  100 + SeckillActivityDO seckillActivity = activityService.getSeckillActivity(id);
  101 + if (seckillActivity == null) {
  102 + return success(null);
  103 + }
94 104 // TODO 芋艿:如果禁用的时候,需要抛出异常;
95   - AppSeckillActivityDetailRespVO obj = new AppSeckillActivityDetailRespVO();
96   - // 设置其属性的值
97   - obj.setId(id);
98   - obj.setName("晚九点限时秒杀");
99   - obj.setStatus(1);
100   - obj.setStartTime(LocalDateTime.of(2023, 6, 16, 0, 0, 0));
101   - obj.setEndTime(LocalDateTime.of(2023, 6, 20, 23, 59, 0));
102   - obj.setSpuId(633L);
103   - obj.setSingleLimitCount(2);
104   - obj.setTotalLimitCount(3);
105   - obj.setStock(100);
106   - obj.setTotalStock(200);
  105 + if (ObjectUtil.equal(seckillActivity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  106 + throw exception(SECKILL_ACTIVITY_FAIL_STATUS_CLOSED);
  107 + }
107 108  
108   - // 创建一个Product对象的列表
109   - List<AppSeckillActivityDetailRespVO.Product> productList = new ArrayList<>();
110   - // 创建三个新的Product对象并设置其属性的值
111   - AppSeckillActivityDetailRespVO.Product product1 = new AppSeckillActivityDetailRespVO.Product();
112   - product1.setSkuId(1L);
113   - product1.setSeckillPrice(100);
114   - product1.setStock(50);
115   - // 将第一个Product对象添加到列表中
116   - productList.add(product1);
117   - // 创建第二个Product对象并设置其属性的值
118   - AppSeckillActivityDetailRespVO.Product product2 = new AppSeckillActivityDetailRespVO.Product();
119   - product2.setSkuId(2L);
120   - product2.setSeckillPrice(200);
121   - product2.setStock(100);
122   - // 将第二个Product对象添加到列表中
123   - productList.add(product2);
124   - // 创建第三个Product对象并设置其属性的值
125   - AppSeckillActivityDetailRespVO.Product product3 = new AppSeckillActivityDetailRespVO.Product();
126   - product3.setSkuId(3L);
127   - product3.setSeckillPrice(300);
128   - product3.setStock(150);
129   - // 将第三个Product对象添加到列表中
130   - productList.add(product3);
131   - // 将Product列表设置为对象的属性值
132   - obj.setProducts(productList);
133   - return success(obj);
  109 + // 3、获取活动商品
  110 + List<SeckillProductDO> products = activityService.getSeckillProductListByActivityId(seckillActivity.getId());
  111 + return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, filteredConfig));
134 112 }
135 113  
136 114 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java
1 1 package cn.iocoder.yudao.module.promotion.controller.app.seckill;
2 2  
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 6 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
  7 +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
  9 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
5 10 import io.swagger.v3.oas.annotations.Operation;
6 11 import io.swagger.v3.oas.annotations.tags.Tag;
7 12 import org.springframework.validation.annotation.Validated;
... ... @@ -9,7 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping;
9 14 import org.springframework.web.bind.annotation.RequestMapping;
10 15 import org.springframework.web.bind.annotation.RestController;
11 16  
12   -import java.util.Arrays;
  17 +import javax.annotation.Resource;
  18 +import java.util.Collections;
13 19 import java.util.List;
14 20  
15 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
... ... @@ -19,18 +25,26 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
19 25 @RequestMapping("/promotion/seckill-config")
20 26 @Validated
21 27 public class AppSeckillConfigController {
  28 + @Resource
  29 + private SeckillConfigService configService;
22 30  
23 31 @GetMapping("/list")
24 32 @Operation(summary = "获得秒杀时间段列表")
25 33 public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() {
26   - return success(Arrays.asList(
27   - new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59")
28   - .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg",
29   - "https://static.iocoder.cn/mall/132.jpeg")),
30   - new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),
31   - new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"),
32   - new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59")
33   - ));
  34 + List<SeckillConfigDO> list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
  35 + if (CollectionUtil.isEmpty(list)) {
  36 + return success(Collections.emptyList());
  37 + }
  38 +
  39 + return success(SeckillConfigConvert.INSTANCE.convertList2(list));
  40 + //return success(Arrays.asList(
  41 + // new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59")
  42 + // .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg",
  43 + // "https://static.iocoder.cn/mall/132.jpeg")),
  44 + // new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),
  45 + // new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"),
  46 + // new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59")
  47 + //));
34 48 }
35 49  
36 50 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java
... ... @@ -19,7 +19,7 @@ public class AppSeckillActivityDetailRespVO {
19 19 @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
20 20 private Integer status;
21 21  
22   - // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈;
  22 + // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈;
23 23  
24 24 @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
25 25 private LocalDateTime startTime;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java
... ... @@ -31,7 +31,6 @@ public class AppSeckillActivityRespVO {
31 31 private Integer totalStock;
32 32  
33 33 @Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
34   - // 从秒杀商品里取最低价
35 34 private Integer seckillPrice;
36 35  
37 36 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
... ... @@ -3,15 +3,22 @@ package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
6 7 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  8 +import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
7 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
8 10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO;
9 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
10 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
11 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
12 14 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
  16 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
  17 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
  18 +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
13 19 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
14 20 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
  21 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
15 22 import org.mapstruct.Mapper;
16 23 import org.mapstruct.Mapping;
17 24 import org.mapstruct.Mappings;
... ... @@ -20,6 +27,10 @@ import org.mapstruct.factory.Mappers;
20 27 import java.util.List;
21 28 import java.util.Map;
22 29  
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
  32 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
  33 +
23 34 /**
24 35 * 秒杀活动 Convert
25 36 *
... ... @@ -79,4 +90,50 @@ public interface SeckillActivityConvert {
79 90  
80 91 List<SeckillProductRespVO> convertList2(List<SeckillProductDO> list);
81 92  
  93 + List<AppSeckillActivityRespVO> convertList3(List<SeckillActivityDO> activityList);
  94 +
  95 + default AppSeckillActivityNowRespVO convert(SeckillConfigDO filteredConfig, List<SeckillActivityDO> activityList, List<ProductSpuRespDTO> spuList) {
  96 + AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();
  97 + respVO.setConfig(SeckillConfigConvert.INSTANCE.convert1(filteredConfig));
  98 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  99 + respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> {
  100 + findAndThen(spuMap, item.getSpuId(), spu -> {
  101 + item.setPicUrl(spu.getPicUrl());
  102 + item.setMarketPrice(spu.getMarketPrice());
  103 + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
  104 + });
  105 + return item;
  106 + }));
  107 + return respVO;
  108 + }
  109 +
  110 + PageResult<AppSeckillActivityRespVO> convertPage1(PageResult<SeckillActivityDO> pageResult);
  111 +
  112 + default PageResult<AppSeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> pageResult, List<ProductSpuRespDTO> spuList) {
  113 + PageResult<AppSeckillActivityRespVO> result = convertPage1(pageResult);
  114 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  115 + List<AppSeckillActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
  116 + findAndThen(spuMap, item.getSpuId(), spu -> {
  117 + item.setPicUrl(spu.getPicUrl());
  118 + item.setMarketPrice(spu.getMarketPrice());
  119 + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
  120 + });
  121 + return item;
  122 + });
  123 + result.setList(list);
  124 + return result;
  125 + }
  126 +
  127 + AppSeckillActivityDetailRespVO convert2(SeckillActivityDO seckillActivity);
  128 +
  129 + List<AppSeckillActivityDetailRespVO.Product> convertList1(List<SeckillProductDO> products);
  130 +
  131 + default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List<SeckillProductDO> products, SeckillConfigDO filteredConfig) {
  132 + AppSeckillActivityDetailRespVO respVO = convert2(seckillActivity);
  133 + respVO.setProducts(convertList1(products));
  134 + respVO.setStartTime(buildTime(filteredConfig.getStartTime()));
  135 + respVO.setEndTime(buildTime(filteredConfig.getEndTime()));
  136 + return respVO;
  137 + }
  138 +
82 139 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java
... ... @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
5 5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO;
6 6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO;
7 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
8 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
9 10 import org.mapstruct.Mapper;
10 11 import org.mapstruct.factory.Mappers;
... ... @@ -33,4 +34,7 @@ public interface SeckillConfigConvert {
33 34  
34 35 PageResult<SeckillConfigRespVO> convertPage(PageResult<SeckillConfigDO> page);
35 36  
  37 + List<AppSeckillConfigRespVO> convertList2(List<SeckillConfigDO> list);
  38 +
  39 + AppSeckillConfigRespVO convert1(SeckillConfigDO filteredConfig);
36 40 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java
... ... @@ -87,7 +87,7 @@ public class SeckillActivityDO extends BaseDO {
87 87 */
88 88 private Integer singleLimitCount;
89 89 /**
90   - * 秒杀库存
  90 + * 秒杀库存(剩余库存秒杀时扣减)
91 91 */
92 92 private Integer stock;
93 93 /**
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
... ... @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
8 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
9 10 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
10 11 import org.apache.ibatis.annotations.Mapper;
... ... @@ -24,7 +25,7 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; {
24 25 .likeIfPresent(SeckillActivityDO::getName, reqVO.getName())
25 26 .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus())
26 27 .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime())
27   - .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ",time_ids) > 0")
  28 + .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ", config_ids) > 0")
28 29 .orderByDesc(SeckillActivityDO::getId));
29 30 }
30 31  
... ... @@ -48,4 +49,10 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; {
48 49 .setSql("totalStock = totalStock - " + count));
49 50 }
50 51  
  52 + default PageResult<SeckillActivityDO> selectPage(AppSeckillActivityPageReqVO pageReqVO, Integer status) {
  53 + return selectPage(pageReqVO, new LambdaQueryWrapperX<SeckillActivityDO>()
  54 + .eqIfPresent(SeckillActivityDO::getStatus, status)
  55 + .apply(ObjectUtil.isNotNull(pageReqVO.getConfigId()), "FIND_IN_SET(" + pageReqVO.getConfigId() + ",config_ids) > 0"));
  56 + }
  57 +
51 58 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
5 5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
6 6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
7 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
8 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
9 10  
... ... @@ -88,4 +89,20 @@ public interface SeckillActivityService {
88 89 */
89 90 List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds);
90 91  
  92 + /**
  93 + * 通过活动时段获取秒杀活动
  94 + *
  95 + * @param ids 时段配置编号
  96 + * @return 秒杀活动列表
  97 + */
  98 + List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids);
  99 +
  100 + /**
  101 + * 通过活动时段获取秒杀活动
  102 + *
  103 + * @param pageReqVO 请求
  104 + * @return 秒杀活动列表
  105 + */
  106 + PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO);
  107 +
91 108 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.service.seckill;
3 3 import cn.hutool.core.util.ObjectUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
7 8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
8 9 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
... ... @@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se
11 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
12 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
13 14 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
14 16 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
15 17 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
16 18 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
... ... @@ -264,4 +266,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
264 266 return seckillProductMapper.selectListByActivityId(activityIds);
265 267 }
266 268  
  269 + @Override
  270 + public List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids) {
  271 + return CollectionUtils.filterList(seckillActivityMapper.selectList(),
  272 + item -> CollectionUtils.anyMatch(item.getConfigIds(), ids::contains));
  273 + }
  274 +
  275 + @Override
  276 + public PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO) {
  277 + return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus());
  278 + }
  279 +
267 280 }
... ...