Commit 408df683d8867330ca69adb09681f07653981b17
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
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
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<SeckillActivityDO> { |
| 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<SeckillActivityDO> { |
| 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 | } | ... | ... |