diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java index feca25411..6eb33d27d 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java @@ -43,6 +43,16 @@ public class LocalDateTimeUtils { return LocalDateTime.of(year, mouth, day, 0, 0, 0); } + /** + * 创建指定时间 + * + * @param timeStr 时间字符串 + * @return 指定时间 + */ + public static LocalDateTime buildTime(String timeStr) { + return LocalDateTime.of(LocalDate.now(), LocalTime.parse(timeStr)); + } + public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, int year2, int mouth2, int day2) { return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; @@ -62,6 +72,22 @@ public class LocalDateTimeUtils { return LocalDateTimeUtil.isIn(LocalDateTime.now(), startTime, endTime); } + /** + * 判断当前时间是否在该时间范围内 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 是否 + */ + public static boolean isBetween(String startTime, String endTime) { + if (startTime == null || endTime == null) { + return false; + } + LocalDate nowDate = LocalDate.now(); + return LocalDateTimeUtil.isIn(LocalDateTime.now(), LocalDateTime.of(nowDate, LocalTime.parse(startTime)), + LocalDateTime.of(nowDate, LocalTime.parse(endTime))); + } + /** * 判断时间段是否重叠 * diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index 4fc58004a..c39fbb316 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/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 { ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "秒杀失败,原因秒杀库存不足"); + ErrorCode SECKILL_ACTIVITY_FAIL_STATUS_CLOSED = new ErrorCode(1013008007, "秒杀活动已关闭"); // ========== 秒杀时段 1013009000 ========== ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在"); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java index 098dfca67..8037c36cb 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java @@ -1,136 +1,114 @@ package cn.iocoder.yudao.module.promotion.controller.app.seckill; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO; import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO; import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO; -import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.context.annotation.Lazy; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.time.LocalDateTime; -import java.util.ArrayList; +import javax.annotation.Resource; +import java.util.Arrays; import java.util.List; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_FAIL_STATUS_CLOSED; @Tag(name = "用户 App - 秒杀活动") @RestController @RequestMapping("/promotion/seckill-activity") @Validated public class AppSeckillActivityController { + @Resource + private SeckillActivityService activityService; + @Resource + @Lazy + private SeckillConfigService configService; + + @Resource + private ProductSpuApi spuApi; @GetMapping("/get-now") @Operation(summary = "获得当前秒杀活动") // 提供给首页使用 // TODO 芋艿:需要增加 spring cache public CommonResult getNowSeckillActivity() { - AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO(); - respVO.setConfig(new AppSeckillConfigRespVO().setId(10L).setStartTime("01:00").setEndTime("09:59")); - List activityList = new ArrayList<>(); - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO(); - activity1.setId(1L); - activity1.setName("618 大秒杀"); - activity1.setSpuId(2048L); - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); - activity1.setMarketPrice(50); - activity1.setSeckillPrice(100); - activityList.add(activity1); + // 1、获取当前时间处在哪个秒杀阶段 + List configList = configService.getSeckillConfigList(); + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); + // 1、1 时段不存在直接返回 null + if (filteredConfig == null) { + return success(null); + } - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO(); - activity2.setId(2L); - activity2.setName("双十一大秒杀"); - activity2.setSpuId(4096L); - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); - activity2.setMarketPrice(100); - activity2.setSeckillPrice(200); - activityList.add(activity2); - respVO.setActivities(activityList); - return success(respVO); + // 2、查询满足当前阶段的活动 + List activityList = activityService.getSeckillActivityListByConfigIds(Arrays.asList(filteredConfig.getId())); + List filteredList = filterList(activityList, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.ENABLE.getStatus())); + // 2、1 获取 spu 信息 + List spuList = spuApi.getSpuList(CollectionUtils.convertList(filteredList, SeckillActivityDO::getSpuId)); + return success(SeckillActivityConvert.INSTANCE.convert(filteredConfig, filteredList, spuList)); } @GetMapping("/page") @Operation(summary = "获得秒杀活动分页") - // TODO @芋艿:分页参数 public CommonResult> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) { - List activityList = new ArrayList<>(); - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO(); - activity1.setId(1L); - activity1.setName("618 大秒杀"); - activity1.setSpuId(2048L); - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); - activity1.setMarketPrice(50); - activity1.setSeckillPrice(100); - activity1.setUnitName("个"); - activity1.setStock(1); - activity1.setTotalStock(2); - activityList.add(activity1); - - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO(); - activity2.setId(2L); - activity2.setName("双十一大秒杀"); - activity2.setSpuId(4096L); - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); - activity2.setMarketPrice(100); - activity2.setSeckillPrice(200); - activity2.setUnitName("套"); - activity2.setStock(2); - activity2.setTotalStock(3); - activityList.add(activity2); - return success(new PageResult<>(activityList, 100L)); + // 1、查询满足当前阶段的活动 + PageResult pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO); + // 1、1 获取 spu 信息 + List spuList = spuApi.getSpuList(CollectionUtils.convertList(pageResult.getList(), SeckillActivityDO::getSpuId)); + return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, spuList)); } @GetMapping("/get-detail") @Operation(summary = "获得秒杀活动明细") @Parameter(name = "id", description = "活动编号", required = true, example = "1024") public CommonResult getSeckillActivity(@RequestParam("id") Long id) { - // TODO 芋艿:如果禁用的时候,需要抛出异常; - AppSeckillActivityDetailRespVO obj = new AppSeckillActivityDetailRespVO(); - // 设置其属性的值 - obj.setId(id); - obj.setName("晚九点限时秒杀"); - obj.setStatus(1); - obj.setStartTime(LocalDateTime.of(2023, 6, 16, 0, 0, 0)); - obj.setEndTime(LocalDateTime.of(2023, 6, 20, 23, 59, 0)); - obj.setSpuId(633L); - obj.setSingleLimitCount(2); - obj.setTotalLimitCount(3); - obj.setStock(100); - obj.setTotalStock(200); + // 1、获取当前时间处在哪个秒杀阶段 + List configList = configService.getSeckillConfigList(); + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); + // 1、1 时段不存在直接返回 null + if (filteredConfig == null) { + return success(null); + } - // 创建一个Product对象的列表 - List productList = new ArrayList<>(); - // 创建三个新的Product对象并设置其属性的值 - AppSeckillActivityDetailRespVO.Product product1 = new AppSeckillActivityDetailRespVO.Product(); - product1.setSkuId(1L); - product1.setSeckillPrice(100); - product1.setStock(50); - // 将第一个Product对象添加到列表中 - productList.add(product1); - // 创建第二个Product对象并设置其属性的值 - AppSeckillActivityDetailRespVO.Product product2 = new AppSeckillActivityDetailRespVO.Product(); - product2.setSkuId(2L); - product2.setSeckillPrice(200); - product2.setStock(100); - // 将第二个Product对象添加到列表中 - productList.add(product2); - // 创建第三个Product对象并设置其属性的值 - AppSeckillActivityDetailRespVO.Product product3 = new AppSeckillActivityDetailRespVO.Product(); - product3.setSkuId(3L); - product3.setSeckillPrice(300); - product3.setStock(150); - // 将第三个Product对象添加到列表中 - productList.add(product3); - // 将Product列表设置为对象的属性值 - obj.setProducts(productList); - return success(obj); + // 2、获取活动 + SeckillActivityDO seckillActivity = activityService.getSeckillActivity(id); + if (seckillActivity == null) { + return success(null); + } + // TODO 芋艿:如果禁用的时候,需要抛出异常; + if (ObjectUtil.equal(seckillActivity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { + throw exception(SECKILL_ACTIVITY_FAIL_STATUS_CLOSED); + } + + // 3、获取活动商品 + List products = activityService.getSeckillProductListByActivityId(seckillActivity.getId()); + return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, filteredConfig)); } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java index d59a365b9..d55e9ee47 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java @@ -1,7 +1,12 @@ package cn.iocoder.yudao.module.promotion.controller.app.seckill; +import cn.hutool.core.collection.CollectionUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; @@ -9,7 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.Arrays; +import javax.annotation.Resource; +import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -19,18 +25,26 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @RequestMapping("/promotion/seckill-config") @Validated public class AppSeckillConfigController { + @Resource + private SeckillConfigService configService; @GetMapping("/list") @Operation(summary = "获得秒杀时间段列表") public CommonResult> getSeckillConfigList() { - return success(Arrays.asList( - new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59") - .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg", - "https://static.iocoder.cn/mall/132.jpeg")), - new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"), - new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"), - new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59") - )); + List list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus()); + if (CollectionUtil.isEmpty(list)) { + return success(Collections.emptyList()); + } + + return success(SeckillConfigConvert.INSTANCE.convertList2(list)); + //return success(Arrays.asList( + // new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59") + // .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg", + // "https://static.iocoder.cn/mall/132.jpeg")), + // new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"), + // new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"), + // new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59") + //)); } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java index 46fa4fbbd..799b2f8db 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java +++ b/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 { @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer status; - // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈; + // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈; @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime startTime; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java index 2797f9a1b..42f5a5ff4 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java +++ b/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 { private Integer totalStock; @Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - // 从秒杀商品里取最低价 private Integer seckillPrice; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java index 9714a1f33..fcdcb7dd0 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java +++ b/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; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.enums.DictTypeConstants; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @@ -20,6 +27,10 @@ import org.mapstruct.factory.Mappers; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; + /** * 秒杀活动 Convert * @@ -79,4 +90,50 @@ public interface SeckillActivityConvert { List convertList2(List list); + List convertList3(List activityList); + + default AppSeckillActivityNowRespVO convert(SeckillConfigDO filteredConfig, List activityList, List spuList) { + AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO(); + respVO.setConfig(SeckillConfigConvert.INSTANCE.convert1(filteredConfig)); + Map spuMap = convertMap(spuList, ProductSpuRespDTO::getId); + respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> { + findAndThen(spuMap, item.getSpuId(), spu -> { + item.setPicUrl(spu.getPicUrl()); + item.setMarketPrice(spu.getMarketPrice()); + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); + }); + return item; + })); + return respVO; + } + + PageResult convertPage1(PageResult pageResult); + + default PageResult convertPage(PageResult pageResult, List spuList) { + PageResult result = convertPage1(pageResult); + Map spuMap = convertMap(spuList, ProductSpuRespDTO::getId); + List list = CollectionUtils.convertList(result.getList(), item -> { + findAndThen(spuMap, item.getSpuId(), spu -> { + item.setPicUrl(spu.getPicUrl()); + item.setMarketPrice(spu.getMarketPrice()); + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); + }); + return item; + }); + result.setList(list); + return result; + } + + AppSeckillActivityDetailRespVO convert2(SeckillActivityDO seckillActivity); + + List convertList1(List products); + + default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List products, SeckillConfigDO filteredConfig) { + AppSeckillActivityDetailRespVO respVO = convert2(seckillActivity); + respVO.setProducts(convertList1(products)); + respVO.setStartTime(buildTime(filteredConfig.getStartTime())); + respVO.setEndTime(buildTime(filteredConfig.getEndTime())); + return respVO; + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java index b1e827019..077a39793 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java +++ b/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 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -33,4 +34,7 @@ public interface SeckillConfigConvert { PageResult convertPage(PageResult page); + List convertList2(List list); + + AppSeckillConfigRespVO convert1(SeckillConfigDO filteredConfig); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java index a8c7eb265..7fd39bec9 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java +++ b/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 { */ private Integer singleLimitCount; /** - * 秒杀库存 + * 秒杀库存(剩余库存秒杀时扣减) */ private Integer stock; /** diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java index 79eca4aa0..d7b90c118 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java +++ b/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; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -24,7 +25,7 @@ public interface SeckillActivityMapper extends BaseMapperX { .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime()) - .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ",time_ids) > 0") + .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ", config_ids) > 0") .orderByDesc(SeckillActivityDO::getId)); } @@ -48,4 +49,10 @@ public interface SeckillActivityMapper extends BaseMapperX { .setSql("totalStock = totalStock - " + count)); } + default PageResult selectPage(AppSeckillActivityPageReqVO pageReqVO, Integer status) { + return selectPage(pageReqVO, new LambdaQueryWrapperX() + .eqIfPresent(SeckillActivityDO::getStatus, status) + .apply(ObjectUtil.isNotNull(pageReqVO.getConfigId()), "FIND_IN_SET(" + pageReqVO.getConfigId() + ",config_ids) > 0")); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java index 6ed4f3f87..2be81ccb9 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java +++ b/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; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; @@ -88,4 +89,20 @@ public interface SeckillActivityService { */ List getSeckillProductListByActivityId(Collection activityIds); + /** + * 通过活动时段获取秒杀活动 + * + * @param ids 时段配置编号 + * @return 秒杀活动列表 + */ + List getSeckillActivityListByConfigIds(Collection ids); + + /** + * 通过活动时段获取秒杀活动 + * + * @param pageReqVO 请求 + * @return 秒杀活动列表 + */ + PageResult getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java index 43f595dbf..10891e071 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java +++ b/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; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 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 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; @@ -264,4 +266,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { return seckillProductMapper.selectListByActivityId(activityIds); } + @Override + public List getSeckillActivityListByConfigIds(Collection ids) { + return CollectionUtils.filterList(seckillActivityMapper.selectList(), + item -> CollectionUtils.anyMatch(item.getConfigIds(), ids::contains)); + } + + @Override + public PageResult getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO) { + return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus()); + } + }