Commit 6ef94ade6a5d0ea850e67975d43b0c233797b881
1 parent
52848d63
完善订单和活动 review 提到的问题
Showing
27 changed files
with
248 additions
and
186 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
| ... | ... | @@ -43,17 +43,6 @@ 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 | - // TODO @puhui999:这个方法的实现,和 LocalDateTimeUtil.parse() 的差异点是啥呀 | |
| 54 | - return LocalDateTime.of(LocalDate.now(), LocalTime.parse(timeStr)); | |
| 55 | - } | |
| 56 | - | |
| 57 | 46 | public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, |
| 58 | 47 | int year2, int mouth2, int day2) { |
| 59 | 48 | return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; | ... | ... |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java
| ... | ... | @@ -7,14 +7,13 @@ package cn.iocoder.yudao.module.promotion.api.seckill; |
| 7 | 7 | */ |
| 8 | 8 | public interface SeckillActivityApi { |
| 9 | 9 | |
| 10 | - // TODO @puhui999:activityId 改成 id 好点哈; | |
| 11 | 10 | /** |
| 12 | 11 | * 更新秒杀库存 |
| 13 | 12 | * |
| 14 | - * @param activityId 活动编号 | |
| 13 | + * @param id 活动编号 | |
| 15 | 14 | * @param skuId sku 编号 |
| 16 | 15 | * @param count 数量 |
| 17 | 16 | */ |
| 18 | - void updateSeckillStock(Long activityId, Long skuId, Integer count); | |
| 17 | + void updateSeckillStock(Long id, Long skuId, Integer count); | |
| 19 | 18 | |
| 20 | 19 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java
| ... | ... | @@ -17,8 +17,8 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { |
| 17 | 17 | private SeckillActivityService activityService; |
| 18 | 18 | |
| 19 | 19 | @Override |
| 20 | - public void updateSeckillStock(Long activityId, Long skuId, Integer count) { | |
| 21 | - activityService.updateSeckillStock(activityId, skuId, count); | |
| 20 | + public void updateSeckillStock(Long id, Long skuId, Integer count) { | |
| 21 | + activityService.updateSeckillStock(id, skuId, count); | |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | 24 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainActivityController.java
| ... | ... | @@ -23,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController; |
| 23 | 23 | import javax.annotation.Resource; |
| 24 | 24 | import java.util.List; |
| 25 | 25 | |
| 26 | +import static cn.hutool.core.util.ObjectUtil.defaultIfNull; | |
| 26 | 27 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 27 | 28 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| 28 | 29 | |
| ... | ... | @@ -39,7 +40,7 @@ public class AppBargainActivityController { |
| 39 | 40 | @GetMapping("/page") |
| 40 | 41 | @Operation(summary = "获得砍价活动分页") |
| 41 | 42 | public CommonResult<PageResult<AppBargainActivityRespVO>> getBargainActivityPage(PageParam pageReqVO) { |
| 42 | - PageResult<BargainActivityDO> result = bargainActivityService.getBargainActivityPageForApp(pageReqVO); | |
| 43 | + PageResult<BargainActivityDO> result = bargainActivityService.getBargainActivityPage(pageReqVO); | |
| 43 | 44 | if (CollUtil.isEmpty(result.getList())) { |
| 44 | 45 | return success(PageResult.empty(result.getTotal())); |
| 45 | 46 | } |
| ... | ... | @@ -54,7 +55,7 @@ public class AppBargainActivityController { |
| 54 | 55 | @Parameter(name = "count", description = "需要展示的数量", example = "6") |
| 55 | 56 | public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList( |
| 56 | 57 | @RequestParam(name = "count", defaultValue = "6") Integer count) { |
| 57 | - List<BargainActivityDO> list = bargainActivityService.getBargainActivityListForApp(count); | |
| 58 | + List<BargainActivityDO> list = bargainActivityService.getBargainActivityListByCount(defaultIfNull(count, 6)); | |
| 58 | 59 | if (CollUtil.isEmpty(list)) { |
| 59 | 60 | return success(BargainActivityConvert.INSTANCE.convertAppList(list)); |
| 60 | 61 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java
| ... | ... | @@ -27,6 +27,7 @@ import javax.annotation.Resource; |
| 27 | 27 | import java.util.Arrays; |
| 28 | 28 | import java.util.List; |
| 29 | 29 | |
| 30 | +import static cn.hutool.core.util.ObjectUtil.defaultIfNull; | |
| 30 | 31 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 31 | 32 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 32 | 33 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| ... | ... | @@ -49,7 +50,7 @@ public class AppCombinationActivityController { |
| 49 | 50 | @Parameter(name = "count", description = "需要展示的数量", example = "6") |
| 50 | 51 | public CommonResult<List<AppCombinationActivityRespVO>> getCombinationActivityList( |
| 51 | 52 | @RequestParam(name = "count", defaultValue = "6") Integer count) { |
| 52 | - List<CombinationActivityDO> list = activityService.getCombinationActivityAppList(count); | |
| 53 | + List<CombinationActivityDO> list = activityService.getCombinationActivityListByCount(defaultIfNull(count, 6)); | |
| 53 | 54 | if (CollUtil.isEmpty(list)) { |
| 54 | 55 | return success(CombinationActivityConvert.INSTANCE.convertAppList(list)); |
| 55 | 56 | } |
| ... | ... | @@ -62,7 +63,7 @@ public class AppCombinationActivityController { |
| 62 | 63 | @GetMapping("/page") |
| 63 | 64 | @Operation(summary = "获得拼团活动分页") |
| 64 | 65 | public CommonResult<PageResult<AppCombinationActivityRespVO>> getCombinationActivityPage(PageParam pageParam) { |
| 65 | - PageResult<CombinationActivityDO> result = activityService.getCombinationActivityAppPage(pageParam); | |
| 66 | + PageResult<CombinationActivityDO> result = activityService.getCombinationActivityPage(pageParam); | |
| 66 | 67 | if (CollUtil.isEmpty(result.getList())) { |
| 67 | 68 | return success(PageResult.empty(result.getTotal())); |
| 68 | 69 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
| ... | ... | @@ -27,13 +27,11 @@ import org.springframework.web.bind.annotation.RequestParam; |
| 27 | 27 | import org.springframework.web.bind.annotation.RestController; |
| 28 | 28 | |
| 29 | 29 | import javax.annotation.Resource; |
| 30 | -import java.util.Arrays; | |
| 31 | 30 | import java.util.List; |
| 32 | 31 | |
| 33 | 32 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 34 | 33 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 35 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | |
| 36 | -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween; | |
| 34 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 37 | 35 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_APP_STATUS_CLOSED; |
| 38 | 36 | |
| 39 | 37 | @Tag(name = "用户 App - 秒杀活动") |
| ... | ... | @@ -54,22 +52,17 @@ public class AppSeckillActivityController { |
| 54 | 52 | @Operation(summary = "获得当前秒杀活动", description = "获取当前正在进行的活动,提供给首页使用") |
| 55 | 53 | public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() { |
| 56 | 54 | // 1. 获取当前时间处在哪个秒杀阶段 |
| 57 | - // TODO @puhui999:可以考虑在 service 写个方法;这样 controller 不用关注过多逻辑 | |
| 58 | - List<SeckillConfigDO> configList = configService.getSeckillConfigList(); | |
| 59 | - SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), | |
| 60 | - CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); | |
| 61 | - if (filteredConfig == null) { // 时段不存在直接返回 null | |
| 55 | + SeckillConfigDO configList = configService.getSeckillConfigListByStatusOnCurrentTime(CommonStatusEnum.ENABLE.getStatus()); | |
| 56 | + if (configList == null) { // 时段不存在直接返回 null | |
| 62 | 57 | return success(null); |
| 63 | 58 | } |
| 64 | 59 | |
| 65 | 60 | // 2. 查询满足当前阶段的活动 |
| 66 | - // TODO @puhui999:最好直接返回开启的;不多查询数据 | |
| 67 | - List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIds(Arrays.asList(filteredConfig.getId())); | |
| 68 | - List<SeckillActivityDO> filteredList = filterList(activityList, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.ENABLE.getStatus())); | |
| 61 | + List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIdAndStatus(configList.getId(), CommonStatusEnum.ENABLE.getStatus()); | |
| 69 | 62 | // 3 获取 spu 信息 |
| 70 | - List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(filteredList, SeckillActivityDO::getSpuId)); | |
| 63 | + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(activityList, SeckillActivityDO::getSpuId)); | |
| 71 | 64 | // TODO 芋艿:需要增加 spring cache |
| 72 | - return success(SeckillActivityConvert.INSTANCE.convert(filteredConfig, filteredList, spuList)); | |
| 65 | + return success(SeckillActivityConvert.INSTANCE.convert(configList, activityList, spuList)); | |
| 73 | 66 | } |
| 74 | 67 | |
| 75 | 68 | @GetMapping("/page") |
| ... | ... | @@ -87,12 +80,9 @@ public class AppSeckillActivityController { |
| 87 | 80 | @Operation(summary = "获得秒杀活动明细") |
| 88 | 81 | @Parameter(name = "id", description = "活动编号", required = true, example = "1024") |
| 89 | 82 | public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) { |
| 90 | - // 1、获取当前时间处在哪个秒杀阶段 | |
| 91 | - // TODO puhui999:这里,和 58 行是雷同的 | |
| 92 | - List<SeckillConfigDO> configList = configService.getSeckillConfigList(); | |
| 93 | - SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), | |
| 94 | - CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); | |
| 95 | - if (filteredConfig == null) { // 时段不存在直接返回 null | |
| 83 | + // 1. 获取当前时间处在哪个秒杀阶段 | |
| 84 | + SeckillConfigDO configList = configService.getSeckillConfigListByStatusOnCurrentTime(CommonStatusEnum.ENABLE.getStatus()); | |
| 85 | + if (configList == null) { // 时段不存在直接返回 null | |
| 96 | 86 | return success(null); |
| 97 | 87 | } |
| 98 | 88 | |
| ... | ... | @@ -107,7 +97,7 @@ public class AppSeckillActivityController { |
| 107 | 97 | |
| 108 | 98 | // 3. 拼接数据 |
| 109 | 99 | List<SeckillProductDO> products = activityService.getSeckillProductListByActivityId(seckillActivity.getId()); |
| 110 | - return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, filteredConfig)); | |
| 100 | + return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, configList)); | |
| 111 | 101 | } |
| 112 | 102 | |
| 113 | 103 | } | ... | ... |
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 | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | 5 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; |
| 7 | 6 | import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; |
| 8 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; | |
| 9 | 7 | import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService; |
| 10 | 8 | import io.swagger.v3.oas.annotations.Operation; |
| 11 | 9 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -15,7 +13,6 @@ import org.springframework.web.bind.annotation.RequestMapping; |
| 15 | 13 | import org.springframework.web.bind.annotation.RestController; |
| 16 | 14 | |
| 17 | 15 | import javax.annotation.Resource; |
| 18 | -import java.util.Collections; | |
| 19 | 16 | import java.util.List; |
| 20 | 17 | |
| 21 | 18 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| ... | ... | @@ -31,13 +28,7 @@ public class AppSeckillConfigController { |
| 31 | 28 | @GetMapping("/list") |
| 32 | 29 | @Operation(summary = "获得秒杀时间段列表") |
| 33 | 30 | public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() { |
| 34 | - List<SeckillConfigDO> list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 35 | - // TODO @puhui999:如果这种,不用判空也问题不大; | |
| 36 | - if (CollectionUtil.isEmpty(list)) { | |
| 37 | - return success(Collections.emptyList()); | |
| 38 | - } | |
| 39 | - | |
| 40 | - return success(SeckillConfigConvert.INSTANCE.convertList2(list)); | |
| 31 | + return success(SeckillConfigConvert.INSTANCE.convertList2(configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus()))); | |
| 41 | 32 | } |
| 42 | 33 | |
| 43 | 34 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java
| ... | ... | @@ -46,9 +46,7 @@ public interface BargainActivityConvert { |
| 46 | 46 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); |
| 47 | 47 | List<BargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { |
| 48 | 48 | findAndThen(spuMap, item.getSpuId(), spu -> { |
| 49 | - // TODO @puhui999:这里可以使用链式哈 | |
| 50 | - item.setPicUrl(spu.getPicUrl()); | |
| 51 | - item.setSpuName(spu.getName()); | |
| 49 | + item.setPicUrl(spu.getPicUrl()).setSpuName(spu.getName()); | |
| 52 | 50 | }); |
| 53 | 51 | return item; |
| 54 | 52 | }); |
| ... | ... | @@ -76,9 +74,7 @@ public interface BargainActivityConvert { |
| 76 | 74 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); |
| 77 | 75 | List<AppBargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { |
| 78 | 76 | findAndThen(spuMap, item.getSpuId(), spu -> { |
| 79 | - // TODO @puhui999:这里可以使用链式哈 | |
| 80 | - item.setPicUrl(spu.getPicUrl()); | |
| 81 | - item.setMarketPrice(spu.getMarketPrice()); | |
| 77 | + item.setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()); | |
| 82 | 78 | }); |
| 83 | 79 | return item; |
| 84 | 80 | }); |
| ... | ... | @@ -93,9 +89,7 @@ public interface BargainActivityConvert { |
| 93 | 89 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); |
| 94 | 90 | return CollectionUtils.convertList(activityList, item -> { |
| 95 | 91 | findAndThen(spuMap, item.getSpuId(), spu -> { |
| 96 | - // TODO @puhui999:这里可以使用链式哈 | |
| 97 | - item.setPicUrl(spu.getPicUrl()); | |
| 98 | - item.setMarketPrice(spu.getMarketPrice()); | |
| 92 | + item.setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()); | |
| 99 | 93 | }); |
| 100 | 94 | return item; |
| 101 | 95 | }); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
| ... | ... | @@ -62,8 +62,7 @@ public interface CombinationActivityConvert { |
| 62 | 62 | PageResult<CombinationActivityRespVO> pageResult = convertPage(page); |
| 63 | 63 | pageResult.getList().forEach(item -> { |
| 64 | 64 | MapUtils.findAndThen(spuMap, item.getSpuId(), spu -> { |
| 65 | - item.setSpuName(spu.getName()); | |
| 66 | - item.setPicUrl(spu.getPicUrl()); | |
| 65 | + item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()); | |
| 67 | 66 | }); |
| 68 | 67 | item.setProducts(convertList2(productList)); |
| 69 | 68 | }); |
| ... | ... | @@ -100,16 +99,15 @@ public interface CombinationActivityConvert { |
| 100 | 99 | default CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO, |
| 101 | 100 | CombinationActivityDO activity, MemberUserRespDTO user, |
| 102 | 101 | ProductSpuRespDTO spu, ProductSkuRespDTO sku) { |
| 103 | - // TODO @puhui999:搞成链式的 set;这样会更规整一点; | |
| 104 | - CombinationRecordDO record = convert(reqDTO); | |
| 105 | - record.setVirtualGroup(false); | |
| 106 | - record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration())); | |
| 107 | - record.setUserSize(activity.getUserSize()); | |
| 108 | - record.setNickname(user.getNickname()); | |
| 109 | - record.setAvatar(user.getAvatar()); | |
| 110 | - record.setSpuName(spu.getName()); | |
| 111 | - record.setPicUrl(sku.getPicUrl()); | |
| 112 | - return record; | |
| 102 | + // TODO @puhui999:订单付款后需要设置开始时间和结束时间; | |
| 103 | + return convert(reqDTO) | |
| 104 | + .setVirtualGroup(false) | |
| 105 | + .setExpireTime(activity.getStartTime().plusHours(activity.getLimitDuration())) | |
| 106 | + .setUserSize(activity.getUserSize()) | |
| 107 | + .setNickname(user.getNickname()) | |
| 108 | + .setAvatar(user.getAvatar()) | |
| 109 | + .setSpuName(spu.getName()) | |
| 110 | + .setPicUrl(sku.getPicUrl()); | |
| 113 | 111 | } |
| 114 | 112 | |
| 115 | 113 | List<CombinationRecordRespDTO> convert(List<CombinationRecordDO> bean); |
| ... | ... | @@ -121,8 +119,7 @@ public interface CombinationActivityConvert { |
| 121 | 119 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); |
| 122 | 120 | return CollectionUtils.convertList(activityList, item -> { |
| 123 | 121 | findAndThen(spuMap, item.getSpuId(), spu -> { |
| 124 | - item.setPicUrl(spu.getPicUrl()); | |
| 125 | - item.setMarketPrice(spu.getMarketPrice()); | |
| 122 | + item.setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()); | |
| 126 | 123 | }); |
| 127 | 124 | return item; |
| 128 | 125 | }); |
| ... | ... | @@ -135,8 +132,7 @@ public interface CombinationActivityConvert { |
| 135 | 132 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); |
| 136 | 133 | List<AppCombinationActivityRespVO> list = CollectionUtils.convertList(appPage.getList(), item -> { |
| 137 | 134 | findAndThen(spuMap, item.getSpuId(), spu -> { |
| 138 | - item.setPicUrl(spu.getPicUrl()); | |
| 139 | - item.setMarketPrice(spu.getMarketPrice()); | |
| 135 | + item.setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()); | |
| 140 | 136 | }); |
| 141 | 137 | return item; |
| 142 | 138 | }); |
| ... | ... | @@ -149,9 +145,7 @@ public interface CombinationActivityConvert { |
| 149 | 145 | List<AppCombinationActivityDetailRespVO.Product> convertList1(List<CombinationProductDO> products); |
| 150 | 146 | |
| 151 | 147 | default AppCombinationActivityDetailRespVO convert3(CombinationActivityDO combinationActivity, List<CombinationProductDO> products) { |
| 152 | - AppCombinationActivityDetailRespVO detailRespVO = convert2(combinationActivity); | |
| 153 | - detailRespVO.setProducts(convertList1(products)); | |
| 154 | - return detailRespVO; | |
| 148 | + return convert2(combinationActivity).setProducts(convertList1(products)); | |
| 155 | 149 | } |
| 156 | 150 | |
| 157 | 151 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.date.LocalDateTimeUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| ... | ... | @@ -29,7 +30,6 @@ import java.util.Map; |
| 29 | 30 | |
| 30 | 31 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| 31 | 32 | import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; |
| 32 | -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; | |
| 33 | 33 | |
| 34 | 34 | /** |
| 35 | 35 | * 秒杀活动 Convert |
| ... | ... | @@ -98,10 +98,9 @@ public interface SeckillActivityConvert { |
| 98 | 98 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); |
| 99 | 99 | respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> { |
| 100 | 100 | findAndThen(spuMap, item.getSpuId(), spu -> { |
| 101 | - // TODO @puhui999:可以尝试链式 set 哈; | |
| 102 | - item.setPicUrl(spu.getPicUrl()); | |
| 103 | - item.setMarketPrice(spu.getMarketPrice()); | |
| 104 | - item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); | |
| 101 | + item.setPicUrl(spu.getPicUrl()) | |
| 102 | + .setMarketPrice(spu.getMarketPrice()) | |
| 103 | + .setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); | |
| 105 | 104 | }); |
| 106 | 105 | return item; |
| 107 | 106 | })); |
| ... | ... | @@ -115,10 +114,9 @@ public interface SeckillActivityConvert { |
| 115 | 114 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); |
| 116 | 115 | List<AppSeckillActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { |
| 117 | 116 | findAndThen(spuMap, item.getSpuId(), spu -> { |
| 118 | - // TODO @puhui999:可以尝试链式 set 哈; | |
| 119 | - item.setPicUrl(spu.getPicUrl()); | |
| 120 | - item.setMarketPrice(spu.getMarketPrice()); | |
| 121 | - item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); | |
| 117 | + item.setPicUrl(spu.getPicUrl()) | |
| 118 | + .setMarketPrice(spu.getMarketPrice()) | |
| 119 | + .setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); | |
| 122 | 120 | }); |
| 123 | 121 | return item; |
| 124 | 122 | }); |
| ... | ... | @@ -131,12 +129,12 @@ public interface SeckillActivityConvert { |
| 131 | 129 | List<AppSeckillActivityDetailRespVO.Product> convertList1(List<SeckillProductDO> products); |
| 132 | 130 | |
| 133 | 131 | default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List<SeckillProductDO> products, SeckillConfigDO filteredConfig) { |
| 134 | - AppSeckillActivityDetailRespVO respVO = convert2(seckillActivity); | |
| 135 | - respVO.setProducts(convertList1(products)); | |
| 136 | - // TODO @puhui999:可以尝试链式 set 哈; | |
| 137 | - respVO.setStartTime(buildTime(filteredConfig.getStartTime())); | |
| 138 | - respVO.setEndTime(buildTime(filteredConfig.getEndTime())); | |
| 139 | - return respVO; | |
| 132 | + return convert2(seckillActivity) | |
| 133 | + .setProducts(convertList1(products)) | |
| 134 | + .setStartTime(LocalDateTimeUtil.parse(LocalDateTimeUtil.format(seckillActivity.getStartTime(), "yyyy-MM-dd") + " " + filteredConfig.getStartTime(), | |
| 135 | + "yyyy-MM-dd HH:mm:ss")) // 活动开始日期和时段结合 | |
| 136 | + .setEndTime(LocalDateTimeUtil.parse(LocalDateTimeUtil.format(seckillActivity.getEndTime(), "yyyy-MM-dd") + " " + filteredConfig.getEndTime(), | |
| 137 | + "yyyy-MM-dd HH:mm:ss")); // 活动结束日期和时段结合 | |
| 140 | 138 | } |
| 141 | 139 | |
| 142 | 140 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
| ... | ... | @@ -45,11 +45,34 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> { |
| 45 | 45 | .setSql("stock = stock - " + count)); |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | - default PageResult<BargainActivityDO> selectAppPage(PageParam pageReqVO, Integer status, LocalDateTime now) { | |
| 48 | + /** | |
| 49 | + * 查询处在 now 日期时间且是 status 状态的活动分页 | |
| 50 | + * | |
| 51 | + * @param pageReqVO 分页参数 | |
| 52 | + * @param status 状态 | |
| 53 | + * @param now 当前日期时间 | |
| 54 | + * @return 活动分页 | |
| 55 | + */ | |
| 56 | + default PageResult<BargainActivityDO> selectPage(PageParam pageReqVO, Integer status, LocalDateTime now) { | |
| 49 | 57 | return selectPage(pageReqVO, new LambdaQueryWrapperX<BargainActivityDO>() |
| 50 | 58 | .eq(BargainActivityDO::getStatus, status) |
| 51 | 59 | .le(BargainActivityDO::getStartTime, now) |
| 52 | 60 | .ge(BargainActivityDO::getEndTime, now)); |
| 53 | 61 | } |
| 54 | 62 | |
| 63 | + /** | |
| 64 | + * 查询处在 now 日期时间且是 status 状态的活动分页 | |
| 65 | + * | |
| 66 | + * @param status 状态 | |
| 67 | + * @param now 当前日期时间 | |
| 68 | + * @return 活动分页 | |
| 69 | + */ | |
| 70 | + default List<BargainActivityDO> selectList(Integer count, Integer status, LocalDateTime now) { | |
| 71 | + return selectList(new LambdaQueryWrapperX<BargainActivityDO>() | |
| 72 | + .eq(BargainActivityDO::getStatus, status) | |
| 73 | + .le(BargainActivityDO::getStartTime, now) | |
| 74 | + .ge(BargainActivityDO::getEndTime, now) | |
| 75 | + .apply("LIMIT " + count)); | |
| 76 | + } | |
| 77 | + | |
| 55 | 78 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java
| ... | ... | @@ -29,9 +29,29 @@ public interface CombinationActivityMapper extends BaseMapperX<CombinationActivi |
| 29 | 29 | return selectList(CombinationActivityDO::getStatus, status); |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | - default PageResult<CombinationActivityDO> selectAppPage(PageParam pageParam, Integer status) { | |
| 32 | + /** | |
| 33 | + * 查询 status 状态的活动分页 | |
| 34 | + * | |
| 35 | + * @param pageParam 分页参数 | |
| 36 | + * @param status 状态 | |
| 37 | + * @return 活动分页 | |
| 38 | + */ | |
| 39 | + default PageResult<CombinationActivityDO> selectPage(PageParam pageParam, Integer status) { | |
| 33 | 40 | return selectPage(pageParam, new LambdaQueryWrapperX<CombinationActivityDO>() |
| 34 | 41 | .eq(CombinationActivityDO::getStatus, status)); |
| 35 | 42 | } |
| 36 | 43 | |
| 44 | + /** | |
| 45 | + * 查询 status 状态的活动分页 | |
| 46 | + * | |
| 47 | + * @param status 状态 | |
| 48 | + * @param count 限制条数 | |
| 49 | + * @return 活动分页 | |
| 50 | + */ | |
| 51 | + default List<CombinationActivityDO> selectList(Integer status, Integer count) { | |
| 52 | + return selectList(new LambdaQueryWrapperX<CombinationActivityDO>() | |
| 53 | + .eq(CombinationActivityDO::getStatus, status) | |
| 54 | + .apply("LIMIT " + count)); | |
| 55 | + } | |
| 56 | + | |
| 37 | 57 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java
| ... | ... | @@ -63,22 +63,20 @@ public interface BargainActivityService { |
| 63 | 63 | */ |
| 64 | 64 | PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO); |
| 65 | 65 | |
| 66 | - // TODO @puhui999:这里可以改成进行中的活动;尽量避免专门为 app 定制,或者类似的名字哈;mapper 那也是 | |
| 67 | - | |
| 68 | 66 | /** |
| 69 | - * 获取 APP 端活动分页数据 | |
| 67 | + * 获取正在进行的活动分页数据 | |
| 70 | 68 | * |
| 71 | 69 | * @param pageReqVO 分页请求 |
| 72 | 70 | * @return 砍价活动分页 |
| 73 | 71 | */ |
| 74 | - PageResult<BargainActivityDO> getBargainActivityPageForApp(PageParam pageReqVO); | |
| 72 | + PageResult<BargainActivityDO> getBargainActivityPage(PageParam pageReqVO); | |
| 75 | 73 | |
| 76 | 74 | /** |
| 77 | - * 获取 APP 端活动展示数据 | |
| 75 | + * 获取正在进行的活动分页数据 | |
| 78 | 76 | * |
| 79 | 77 | * @param count 需要的数量 |
| 80 | 78 | * @return 砍价活动分页 |
| 81 | 79 | */ |
| 82 | - List<BargainActivityDO> getBargainActivityListForApp(Integer count); | |
| 80 | + List<BargainActivityDO> getBargainActivityListByCount(Integer count); | |
| 83 | 81 | |
| 84 | 82 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
| ... | ... | @@ -142,21 +142,14 @@ public class BargainActivityServiceImpl implements BargainActivityService { |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | @Override |
| 145 | - public PageResult<BargainActivityDO> getBargainActivityPageForApp(PageParam pageReqVO) { | |
| 145 | + public PageResult<BargainActivityDO> getBargainActivityPage(PageParam pageReqVO) { | |
| 146 | 146 | // 只查询进行中,且在时间范围内的 |
| 147 | - return bargainActivityMapper.selectAppPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); | |
| 147 | + return bargainActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); | |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | @Override |
| 151 | - public List<BargainActivityDO> getBargainActivityListForApp(Integer count) { | |
| 152 | - // TODO @puhui999:这种 default count 的逻辑,可以放到 controller 哈;然后可以使用 ObjectUtils.default 方法 | |
| 153 | - if (count == null) { | |
| 154 | - count = 6; | |
| 155 | - } | |
| 156 | - // TODO @puhui999:这种不要用 page;会浪费一次 count; | |
| 157 | - PageResult<BargainActivityDO> result = bargainActivityMapper.selectAppPage(new PageParam().setPageSize(count), | |
| 158 | - CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); | |
| 159 | - return result.getList(); | |
| 151 | + public List<BargainActivityDO> getBargainActivityListByCount(Integer count) { | |
| 152 | + return bargainActivityMapper.selectList(count, CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); | |
| 160 | 153 | } |
| 161 | 154 | |
| 162 | 155 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
| ... | ... | @@ -85,19 +85,19 @@ public interface CombinationActivityService { |
| 85 | 85 | void validateCombination(Long activityId, Long userId, Long skuId, Integer count); |
| 86 | 86 | |
| 87 | 87 | /** |
| 88 | - * 获取 APP 端活动展示数据 | |
| 88 | + * 获取正在进行的活动分页数据 | |
| 89 | 89 | * |
| 90 | 90 | * @param count 需要的数量 |
| 91 | - * @return 活动列表 | |
| 91 | + * @return 拼团活动分页 | |
| 92 | 92 | */ |
| 93 | - List<CombinationActivityDO> getCombinationActivityAppList(Integer count); | |
| 93 | + List<CombinationActivityDO> getCombinationActivityListByCount(Integer count); | |
| 94 | 94 | |
| 95 | 95 | /** |
| 96 | - * 获取 APP 端活动分页数据 | |
| 96 | + * 获取正在进行的活动分页数据 | |
| 97 | 97 | * |
| 98 | - * @param pageParam 分页参数 | |
| 99 | - * @return 活动分页数据 | |
| 98 | + * @param pageParam 分页请求 | |
| 99 | + * @return 拼团活动分页 | |
| 100 | 100 | */ |
| 101 | - PageResult<CombinationActivityDO> getCombinationActivityAppPage(PageParam pageParam); | |
| 101 | + PageResult<CombinationActivityDO> getCombinationActivityPage(PageParam pageParam); | |
| 102 | 102 | |
| 103 | 103 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
| ... | ... | @@ -224,8 +224,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic |
| 224 | 224 | throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE); |
| 225 | 225 | } |
| 226 | 226 | // 1.3 校验是否超出单次限购数量 |
| 227 | - // TODO puhui999:count > activity.getSingleLimitCount() 会更好理解点; | |
| 228 | - if (activity.getSingleLimitCount() < count) { | |
| 227 | + if (count > activity.getSingleLimitCount()) { | |
| 229 | 228 | throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); |
| 230 | 229 | } |
| 231 | 230 | |
| ... | ... | @@ -247,19 +246,13 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic |
| 247 | 246 | } |
| 248 | 247 | |
| 249 | 248 | @Override |
| 250 | - public List<CombinationActivityDO> getCombinationActivityAppList(Integer count) { | |
| 251 | - if (count == null) { | |
| 252 | - count = 6; | |
| 253 | - } | |
| 254 | - | |
| 255 | - PageResult<CombinationActivityDO> result = combinationActivityMapper.selectAppPage(new PageParam().setPageSize(count), | |
| 256 | - CommonStatusEnum.ENABLE.getStatus()); | |
| 257 | - return result.getList(); | |
| 249 | + public List<CombinationActivityDO> getCombinationActivityListByCount(Integer count) { | |
| 250 | + return combinationActivityMapper.selectList(CommonStatusEnum.ENABLE.getStatus(), count); | |
| 258 | 251 | } |
| 259 | 252 | |
| 260 | 253 | @Override |
| 261 | - public PageResult<CombinationActivityDO> getCombinationActivityAppPage(PageParam pageParam) { | |
| 262 | - return combinationActivityMapper.selectAppPage(pageParam, CommonStatusEnum.ENABLE.getStatus()); | |
| 254 | + public PageResult<CombinationActivityDO> getCombinationActivityPage(PageParam pageParam) { | |
| 255 | + return combinationActivityMapper.selectPage(pageParam, CommonStatusEnum.ENABLE.getStatus()); | |
| 263 | 256 | } |
| 264 | 257 | |
| 265 | 258 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
| ... | ... | @@ -37,11 +37,11 @@ public interface SeckillActivityService { |
| 37 | 37 | /** |
| 38 | 38 | * 更新秒杀库存 |
| 39 | 39 | * |
| 40 | - * @param activityId 活动编号 | |
| 40 | + * @param id 活动编号 | |
| 41 | 41 | * @param skuId sku 编号 |
| 42 | 42 | * @param count 数量 |
| 43 | 43 | */ |
| 44 | - void updateSeckillStock(Long activityId, Long skuId, Integer count); | |
| 44 | + void updateSeckillStock(Long id, Long skuId, Integer count); | |
| 45 | 45 | |
| 46 | 46 | /** |
| 47 | 47 | * 关闭秒杀活动 |
| ... | ... | @@ -98,6 +98,15 @@ public interface SeckillActivityService { |
| 98 | 98 | List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids); |
| 99 | 99 | |
| 100 | 100 | /** |
| 101 | + * 通过活动时段编号获取指定 status 的秒杀活动 | |
| 102 | + * | |
| 103 | + * @param configId 时段配置编号 | |
| 104 | + * @param status 状态 | |
| 105 | + * @return 秒杀活动列表 | |
| 106 | + */ | |
| 107 | + List<SeckillActivityDO> getSeckillActivityListByConfigIdAndStatus(Long configId, Integer status); | |
| 108 | + | |
| 109 | + /** | |
| 101 | 110 | * 通过活动时段获取秒杀活动 |
| 102 | 111 | * |
| 103 | 112 | * @param pageReqVO 请求 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
| ... | ... | @@ -3,7 +3,6 @@ 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; | |
| 7 | 6 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 8 | 7 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 9 | 8 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| ... | ... | @@ -31,6 +30,7 @@ import java.util.Map; |
| 31 | 30 | import static cn.hutool.core.collection.CollUtil.isNotEmpty; |
| 32 | 31 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 33 | 32 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 33 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween; | |
| 34 | 34 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; |
| 35 | 35 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; |
| 36 | 36 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; |
| ... | ... | @@ -148,16 +148,16 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { |
| 148 | 148 | |
| 149 | 149 | @Override |
| 150 | 150 | @Transactional(rollbackFor = Exception.class) |
| 151 | - public void updateSeckillStock(Long activityId, Long skuId, Integer count) { | |
| 151 | + public void updateSeckillStock(Long id, Long skuId, Integer count) { | |
| 152 | 152 | // 1、校验秒杀活动是否存在 |
| 153 | - SeckillActivityDO seckillActivity = getSeckillActivity(activityId); | |
| 153 | + SeckillActivityDO seckillActivity = getSeckillActivity(id); | |
| 154 | 154 | // 1.1、校验库存是否充足 |
| 155 | 155 | if (seckillActivity.getTotalStock() < count) { |
| 156 | 156 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | // 2、获取活动商品 |
| 160 | - List<SeckillProductDO> products = getSeckillProductListByActivityId(activityId); | |
| 160 | + List<SeckillProductDO> products = getSeckillProductListByActivityId(id); | |
| 161 | 161 | // 2.1、过滤出购买的商品 |
| 162 | 162 | SeckillProductDO product = findFirst(products, item -> ObjectUtil.equal(skuId, item.getSkuId())); |
| 163 | 163 | // 2.2、检查活动商品库存是否充足 |
| ... | ... | @@ -268,8 +268,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { |
| 268 | 268 | |
| 269 | 269 | @Override |
| 270 | 270 | public List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids) { |
| 271 | - return CollectionUtils.filterList(seckillActivityMapper.selectList(), | |
| 272 | - item -> CollectionUtils.anyMatch(item.getConfigIds(), ids::contains)); | |
| 271 | + return filterList(seckillActivityMapper.selectList(), | |
| 272 | + item -> anyMatch(item.getConfigIds(), ids::contains)); | |
| 273 | + } | |
| 274 | + | |
| 275 | + @Override | |
| 276 | + public List<SeckillActivityDO> getSeckillActivityListByConfigIdAndStatus(Long configId, Integer status) { | |
| 277 | + return filterList(seckillActivityMapper.selectList(SeckillActivityDO::getStatus, status), | |
| 278 | + item -> anyMatch(item.getConfigIds(), id -> ObjectUtil.equal(id, configId)) // 校验时段 | |
| 279 | + && isBetween(item.getStartTime(), item.getEndTime())); // 追加当前日期是否处在活动日期之间的校验条件 | |
| 273 | 280 | } |
| 274 | 281 | |
| 275 | 282 | @Override | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigService.java
| ... | ... | @@ -54,6 +54,7 @@ public interface SeckillConfigService { |
| 54 | 54 | */ |
| 55 | 55 | List<SeckillConfigDO> getSeckillConfigList(); |
| 56 | 56 | |
| 57 | + | |
| 57 | 58 | /** |
| 58 | 59 | * 校验秒杀时段是否存在 |
| 59 | 60 | * |
| ... | ... | @@ -85,4 +86,12 @@ public interface SeckillConfigService { |
| 85 | 86 | */ |
| 86 | 87 | void updateSeckillConfigStatus(Long id, Integer status); |
| 87 | 88 | |
| 89 | + /** | |
| 90 | + * 获取当前日期时间处于的秒杀时段且状态为 status | |
| 91 | + * | |
| 92 | + * @param status 状态 | |
| 93 | + * @return 时段 | |
| 94 | + */ | |
| 95 | + SeckillConfigDO getSeckillConfigListByStatusOnCurrentTime(Integer status); | |
| 96 | + | |
| 88 | 97 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigServiceImpl.java
| ... | ... | @@ -20,6 +20,8 @@ import java.util.Collection; |
| 20 | 20 | import java.util.List; |
| 21 | 21 | |
| 22 | 22 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 23 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst; | |
| 24 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween; | |
| 23 | 25 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; |
| 24 | 26 | |
| 25 | 27 | /** |
| ... | ... | @@ -68,6 +70,12 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { |
| 68 | 70 | } |
| 69 | 71 | |
| 70 | 72 | @Override |
| 73 | + public SeckillConfigDO getSeckillConfigListByStatusOnCurrentTime(Integer status) { | |
| 74 | + return findFirst(seckillConfigMapper.selectList(SeckillConfigDO::getStatus, status), | |
| 75 | + config -> isBetween(config.getStartTime(), config.getEndTime())); | |
| 76 | + } | |
| 77 | + | |
| 78 | + @Override | |
| 71 | 79 | public void deleteSeckillConfig(Long id) { |
| 72 | 80 | // 校验存在 |
| 73 | 81 | validateSeckillConfigExists(id); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
| ... | ... | @@ -12,7 +12,7 @@ import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; |
| 12 | 12 | import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; |
| 13 | 13 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 14 | 14 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 15 | -import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 15 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespVO; | |
| 16 | 16 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService; |
| 17 | 17 | import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; |
| 18 | 18 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; |
| ... | ... | @@ -87,13 +87,13 @@ public class TradeAfterSaleController { |
| 87 | 87 | // 拼接数据 |
| 88 | 88 | MemberUserRespDTO user = memberUserApi.getUser(afterSale.getUserId()); |
| 89 | 89 | // 获取售后日志 |
| 90 | - List<TradeAfterSaleLogRespDTO> logs = afterSaleLogService.getLog(afterSale.getId()); | |
| 90 | + List<TradeAfterSaleLogRespVO> logs = afterSaleLogService.getLog(afterSale.getId()); | |
| 91 | 91 | // TODO 方便测试看效果,review 后移除 |
| 92 | 92 | if (logs == null) { |
| 93 | 93 | logs = new ArrayList<>(); |
| 94 | 94 | } |
| 95 | 95 | for (int i = 1; i <= 6; i++) { |
| 96 | - TradeAfterSaleLogRespDTO respVO = new TradeAfterSaleLogRespDTO(); | |
| 96 | + TradeAfterSaleLogRespVO respVO = new TradeAfterSaleLogRespVO(); | |
| 97 | 97 | respVO.setId((long) i); |
| 98 | 98 | respVO.setUserId((long) i); |
| 99 | 99 | respVO.setUserType(i % 2 == 0 ? 2 : 1); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java
| ... | ... | @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; |
| 6 | 6 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; |
| 7 | 7 | import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDetailRespVO; |
| 8 | 8 | import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; |
| 9 | -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO; | |
| 10 | 9 | import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; |
| 11 | 10 | import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; |
| 12 | 11 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderBaseVO; |
| ... | ... | @@ -16,7 +15,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; |
| 16 | 15 | import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; |
| 17 | 16 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 18 | 17 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 19 | -import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 18 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespVO; | |
| 20 | 19 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 21 | 20 | import org.mapstruct.Mapper; |
| 22 | 21 | import org.mapstruct.Mapping; |
| ... | ... | @@ -68,10 +67,10 @@ public interface TradeAfterSaleConvert { |
| 68 | 67 | |
| 69 | 68 | PageResult<AppTradeAfterSaleRespVO> convertPage02(PageResult<TradeAfterSaleDO> page); |
| 70 | 69 | |
| 71 | - List<TradeAfterSaleLogRespDTO> convertList(List<TradeAfterSaleLogDO> list); | |
| 70 | + List<TradeAfterSaleLogRespVO> convertList(List<TradeAfterSaleLogDO> list); | |
| 72 | 71 | |
| 73 | 72 | default TradeAfterSaleDetailRespVO convert(TradeAfterSaleDO afterSale, TradeOrderDO order, List<TradeOrderItemDO> orderItems, |
| 74 | - MemberUserRespDTO user, List<TradeAfterSaleLogRespDTO> logs) { | |
| 73 | + MemberUserRespDTO user, List<TradeAfterSaleLogRespVO> logs) { | |
| 75 | 74 | TradeAfterSaleDetailRespVO respVO = convert(afterSale, orderItems); |
| 76 | 75 | // 处理用户信息 |
| 77 | 76 | respVO.setUser(convert(user)); |
| ... | ... | @@ -81,7 +80,8 @@ public interface TradeAfterSaleConvert { |
| 81 | 80 | respVO.setLogs(convertList1(logs)); |
| 82 | 81 | return respVO; |
| 83 | 82 | } |
| 84 | - List<TradeAfterSaleLogRespVO> convertList1(List<TradeAfterSaleLogRespDTO> list); | |
| 83 | + | |
| 84 | + List<cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO> convertList1(List<TradeAfterSaleLogRespVO> list); | |
| 85 | 85 | @Mapping(target = "id", source = "afterSale.id") |
| 86 | 86 | TradeAfterSaleDetailRespVO convert(TradeAfterSaleDO afterSale, List<TradeOrderItemDO> orderItems); |
| 87 | 87 | TradeOrderBaseVO convert(TradeOrderDO order); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/dto/TradeAfterSaleLogRespDTO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/dto/TradeAfterSaleLogRespVO.java
| ... | ... | @@ -8,7 +8,6 @@ import lombok.NoArgsConstructor; |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | 9 | import java.time.LocalDateTime; |
| 10 | 10 | |
| 11 | -// TODO @puhui999:这个是不是应该搞成 vo 啊? | |
| 12 | 11 | /** |
| 13 | 12 | * 贸易售后日志详情 DTO |
| 14 | 13 | * |
| ... | ... | @@ -17,7 +16,7 @@ import java.time.LocalDateTime; |
| 17 | 16 | @Data |
| 18 | 17 | @NoArgsConstructor |
| 19 | 18 | @AllArgsConstructor |
| 20 | -public class TradeAfterSaleLogRespDTO { | |
| 19 | +public class TradeAfterSaleLogRespVO { | |
| 21 | 20 | |
| 22 | 21 | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20669") |
| 23 | 22 | private Long id; | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/service/AfterSaleLogService.java
| ... | ... | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service; |
| 2 | 2 | |
| 3 | 3 | |
| 4 | 4 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO; |
| 5 | -import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 5 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespVO; | |
| 6 | 6 | |
| 7 | 7 | import java.util.List; |
| 8 | 8 | |
| ... | ... | @@ -29,6 +29,6 @@ public interface AfterSaleLogService { |
| 29 | 29 | * @param afterSaleId 售后编号 |
| 30 | 30 | * @return 售后日志 |
| 31 | 31 | */ |
| 32 | - List<TradeAfterSaleLogRespDTO> getLog(Long afterSaleId); | |
| 32 | + List<TradeAfterSaleLogRespVO> getLog(Long afterSaleId); | |
| 33 | 33 | |
| 34 | 34 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
| ... | ... | @@ -26,7 +26,7 @@ import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; |
| 26 | 26 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; |
| 27 | 27 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; |
| 28 | 28 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO; |
| 29 | -import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 29 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespVO; | |
| 30 | 30 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService; |
| 31 | 31 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 32 | 32 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; |
| ... | ... | @@ -450,7 +450,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa |
| 450 | 450 | } |
| 451 | 451 | |
| 452 | 452 | @Override |
| 453 | - public List<TradeAfterSaleLogRespDTO> getLog(Long afterSaleId) { | |
| 453 | + public List<TradeAfterSaleLogRespVO> getLog(Long afterSaleId) { | |
| 454 | 454 | // TODO 不熟悉流程先这么滴 |
| 455 | 455 | List<TradeAfterSaleLogDO> saleLogDOs = tradeAfterSaleLogMapper.selectList(TradeAfterSaleLogDO::getAfterSaleId, afterSaleId); |
| 456 | 456 | return TradeAfterSaleConvert.INSTANCE.convertList(saleLogDOs); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| ... | ... | @@ -553,41 +553,49 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 553 | 553 | tradeOrderMapper.updateById(update); |
| 554 | 554 | // TODO @芋艿:改价时,赠送的积分,要不要做改动??? |
| 555 | 555 | |
| 556 | - // TODO @puhui999:应该是按照 payPrice 分配;并且要考虑取余问题;payPrice 也要考虑,item 里的 | |
| 557 | - // TODO:先按 adjustPrice 实现,没明白 payPrice 怎么搞哈哈哈 | |
| 558 | - // TODO @puhui999:就是对比新老 adjustPrice 的差值,然后计算补充的 adjustPrice 最终值;另外,可以不用区分 items.size 是不是 > 1 哈;应该是一致的逻辑;分摊的逻辑,有点类似 dividePrice 方法噢; | |
| 559 | 556 | // 5、更新 TradeOrderItem |
| 560 | - if (items.size() > 1) { | |
| 561 | - // TradeOrderItemDO 需要做 adjustPrice 的分摊 | |
| 562 | - int price = reqVO.getAdjustPrice() / items.size(); | |
| 563 | - int remainderPrice = reqVO.getAdjustPrice() % items.size(); | |
| 564 | - List<TradeOrderItemDO> orders = new ArrayList<>(); | |
| 565 | - for (int i = 0; i < items.size(); i++) { | |
| 566 | - // 把平摊后剩余的金额加到第一个订单项 | |
| 567 | - if (remainderPrice != 0 && i == 0) { | |
| 568 | - orders.add(convertOrderItemPrice(items.get(i), price + remainderPrice)); | |
| 569 | - } | |
| 570 | - orders.add(convertOrderItemPrice(items.get(i), price)); | |
| 571 | - } | |
| 572 | - tradeOrderItemMapper.updateBatch(orders); | |
| 573 | - } else { | |
| 574 | - TradeOrderItemDO orderItem = items.get(0); | |
| 575 | - TradeOrderItemDO updateItem = convertOrderItemPrice(orderItem, reqVO.getAdjustPrice()); | |
| 576 | - tradeOrderItemMapper.updateById(updateItem); | |
| 557 | + // TradeOrderItemDO 需要做 adjustPrice 的分摊 | |
| 558 | + List<Integer> dividePrices = dividePrice(items, orderPayPrice); | |
| 559 | + List<TradeOrderItemDO> updateItems = new ArrayList<>(); | |
| 560 | + for (int i = 0; i < items.size(); i++) { | |
| 561 | + TradeOrderItemDO item = items.get(i); | |
| 562 | + Integer adjustPrice = item.getPrice() - dividePrices.get(i); // 计算调整的金额 | |
| 563 | + updateItems.add(new TradeOrderItemDO().setId(item.getId()).setAdjustPrice(adjustPrice) | |
| 564 | + .setPayPrice(item.getPayPrice() - adjustPrice)); | |
| 577 | 565 | } |
| 566 | + tradeOrderItemMapper.updateBatch(updateItems); | |
| 567 | + | |
| 578 | 568 | |
| 579 | 569 | // 6、更新支付订单 |
| 580 | 570 | payOrderApi.updatePayOrderPrice(order.getPayOrderId(), update.getPayPrice()); |
| 581 | 571 | } |
| 582 | 572 | |
| 583 | - private TradeOrderItemDO convertOrderItemPrice(TradeOrderItemDO orderItem, Integer price) { | |
| 584 | - TradeOrderItemDO newOrderItem = new TradeOrderItemDO(); | |
| 585 | - newOrderItem.setId(orderItem.getId()); | |
| 586 | - newOrderItem.setAdjustPrice(price); | |
| 587 | - int payPrice = orderItem.getAdjustPrice() != null ? (orderItem.getPayPrice() - orderItem.getAdjustPrice()) | |
| 588 | - + price : orderItem.getPayPrice() + price; | |
| 589 | - newOrderItem.setPayPrice(payPrice); | |
| 590 | - return newOrderItem; | |
| 573 | + /** | |
| 574 | + * 计算订单调价价格分摊 | |
| 575 | + * | |
| 576 | + * @param items 订单项 | |
| 577 | + * @param orderPayPrice 订单支付金额 | |
| 578 | + * @return 分摊金额数组,和传入的 orderItems 一一对应 | |
| 579 | + */ | |
| 580 | + private List<Integer> dividePrice(List<TradeOrderItemDO> items, Integer orderPayPrice) { | |
| 581 | + Integer total = getSumValue(items, TradeOrderItemDO::getPrice, Integer::sum); | |
| 582 | + assert total != null; | |
| 583 | + // 遍历每一个,进行分摊 | |
| 584 | + List<Integer> prices = new ArrayList<>(items.size()); | |
| 585 | + int remainPrice = orderPayPrice; | |
| 586 | + for (int i = 0; i < items.size(); i++) { | |
| 587 | + TradeOrderItemDO orderItem = items.get(i); | |
| 588 | + int partPrice; | |
| 589 | + if (i < items.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 | |
| 590 | + partPrice = (int) (orderPayPrice * (1.0D * orderItem.getPayPrice() / total)); | |
| 591 | + remainPrice -= partPrice; | |
| 592 | + } else { | |
| 593 | + partPrice = remainPrice; | |
| 594 | + } | |
| 595 | + Assert.isTrue(partPrice >= 0, "分摊金额必须大于等于 0"); | |
| 596 | + prices.add(partPrice); | |
| 597 | + } | |
| 598 | + return prices; | |
| 591 | 599 | } |
| 592 | 600 | |
| 593 | 601 | @Override | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeBeforeOrderCreateReqBO.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.order.bo; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | |
| 3 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 5 | import lombok.Data; |
| 5 | 6 | |
| ... | ... | @@ -14,36 +15,73 @@ import javax.validation.constraints.NotNull; |
| 14 | 15 | @Data |
| 15 | 16 | public class TradeBeforeOrderCreateReqBO { |
| 16 | 17 | |
| 17 | - // TODO @puhui999:注释也写下哈;bo 还是写注释噢 | |
| 18 | - | |
| 18 | + /** | |
| 19 | + * 订单类型 | |
| 20 | + * | |
| 21 | + * 枚举 {@link TradeOrderTypeEnum} | |
| 22 | + */ | |
| 19 | 23 | @NotNull(message = "订单类型不能为空") |
| 20 | 24 | private Integer orderType; |
| 21 | 25 | |
| 26 | + /** | |
| 27 | + * 用户编号 | |
| 28 | + * | |
| 29 | + * 关联 MemberUserDO 的 id 编号 | |
| 30 | + */ | |
| 31 | + @NotNull(message = "用户编号不能为空") | |
| 32 | + private Long userId; | |
| 33 | + | |
| 22 | 34 | // ========== 秒杀活动相关字段 ========== |
| 23 | 35 | |
| 36 | + /** | |
| 37 | + * | |
| 38 | + */ | |
| 24 | 39 | @Schema(description = "秒杀活动编号", example = "1024") |
| 25 | 40 | private Long seckillActivityId; |
| 26 | 41 | |
| 27 | 42 | // ========== 拼团活动相关字段 ========== |
| 28 | 43 | |
| 44 | + /** | |
| 45 | + * 拼团活动编号 | |
| 46 | + */ | |
| 29 | 47 | @Schema(description = "拼团活动编号", example = "1024") |
| 30 | 48 | private Long combinationActivityId; |
| 31 | 49 | |
| 50 | + /** | |
| 51 | + * 拼团团长编号 | |
| 52 | + */ | |
| 32 | 53 | @Schema(description = "拼团团长编号", example = "2048") |
| 33 | 54 | private Long combinationHeadId; |
| 34 | 55 | |
| 56 | + // ========== 砍价活动相关字段 ========== | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * 砍价活动编号 | |
| 60 | + */ | |
| 35 | 61 | @Schema(description = "砍价活动编号", example = "123") |
| 36 | 62 | private Long bargainActivityId; |
| 37 | 63 | |
| 64 | + // ========== 活动购买商品相关字段 ========== | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * 商品 SPU 编号 | |
| 68 | + * | |
| 69 | + * 关联 ProductSkuDO 的 spuId 编号 | |
| 70 | + */ | |
| 38 | 71 | @NotNull(message = "SPU 编号不能为空") |
| 39 | 72 | private Long spuId; |
| 40 | 73 | |
| 74 | + /** | |
| 75 | + * 商品 SKU 编号 | |
| 76 | + * | |
| 77 | + * 关联 ProductSkuDO 的 id 编号 | |
| 78 | + */ | |
| 41 | 79 | @NotNull(message = "SKU 编号活动商品不能为空") |
| 42 | 80 | private Long skuId; |
| 43 | 81 | |
| 44 | - @NotNull(message = "用户编号不能为空") | |
| 45 | - private Long userId; | |
| 46 | - | |
| 82 | + /** | |
| 83 | + * 购买的商品数量 | |
| 84 | + */ | |
| 47 | 85 | @NotNull(message = "购买数量不能为空") |
| 48 | 86 | private Integer count; |
| 49 | 87 | ... | ... |