diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java new file mode 100644 index 000000000..16ff03c44 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.api.bargain; + +import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO; +import org.springframework.stereotype.Service; + +/** + * 砍价活动 API 实现类 TODO @puhui999 + * + * @author HUIHUI + */ +@Service +public class BargainRecordApiImpl implements BargainRecordApi { + + @Override + public void createRecord(BargainRecordCreateReqDTO reqDTO) { + + } + + @Override + public boolean validateRecordSuccess(Long userId, Long orderId) { + return false; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java index 5f7e50a03..a6d131b94 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java @@ -4,12 +4,12 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.admin.bargain.vo.activity.BargainActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -20,8 +20,6 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.Collections; -import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -40,7 +38,7 @@ public class BargainActivityController { @PostMapping("/create") @Operation(summary = "创建砍价活动") @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:create')") - public CommonResult createBargainActivity(@Valid @RequestBody BargainActivityCreateReqVO createReqVO) { + public CommonResult createBargainActivity(@Valid @RequestBody BargainActivityBaseVO createReqVO) { return success(activityService.createBargainActivity(createReqVO)); } @@ -79,14 +77,6 @@ public class BargainActivityController { if (CollUtil.isEmpty(pageResult.getList())) { return success(PageResult.empty(pageResult.getTotal())); } - - // 拼接数据 -// List products = activityService.getBargainProductsByActivityIds( -// convertSet(pageResult.getList(), BargainActivityDO::getId)); - List products = Collections.emptyList(); - List spus = productSpuApi.getSpuList( - convertSet(pageResult.getList(), BargainActivityDO::getSpuId)); - return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, products, spus)); return success(BargainActivityConvert.INSTANCE.convertPage(activityService.getBargainActivityPage(pageVO))); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java index 290f2ab4e..d3ef255f9 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.promotion.convert.bargain; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; @@ -20,7 +20,7 @@ public interface BargainActivityConvert { BargainActivityConvert INSTANCE = Mappers.getMapper(BargainActivityConvert.class); - BargainActivityDO convert(BargainActivityCreateReqVO bean); + BargainActivityDO convert(BargainActivityBaseVO bean); BargainActivityDO convert(BargainActivityUpdateReqVO bean); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java index 7977d8fa9..0eb511474 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activit import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; @@ -73,7 +72,7 @@ public interface CombinationActivityConvert { @Mapping(target = "activityId", source = "activity.id"), @Mapping(target = "spuId", source = "activity.spuId"), @Mapping(target = "skuId", source = "product.skuId"), - @Mapping(target = "activePrice", source = "product.activePrice"), + @Mapping(target = "combinationPrice", source = "product.combinationPrice"), @Mapping(target = "activityStartTime", source = "activity.startTime"), @Mapping(target = "activityEndTime", source = "activity.endTime") }) @@ -83,7 +82,7 @@ public interface CombinationActivityConvert { return CollectionUtils.convertList(products, item -> convert(activity, item).setActivityStatus(activity.getStatus())); } - default List convertList(List updateProductVOs, + default List convertList(List updateProductVOs, List products, CombinationActivityDO activity) { Map productMap = convertMap(products, CombinationProductDO::getSkuId, CombinationProductDO::getId); return CollectionUtils.convertList(updateProductVOs, updateProductVO -> convert(activity, updateProductVO) 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 43b114bde..96ca1ef8c 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 @@ -2,6 +2,7 @@ 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.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO; @@ -40,11 +41,14 @@ public interface SeckillActivityConvert { PageResult convertPage(PageResult page); default PageResult convertPage(PageResult page, List seckillProducts, List spuList) { - Map spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId, c -> c); + Map spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId); PageResult pageResult = convertPage(page); pageResult.getList().forEach(item -> { - item.setSpuName(spuMap.get(item.getSpuId()).getName()); - item.setPicUrl(spuMap.get(item.getSpuId()).getPicUrl()); + MapUtils.findAndThen(spuMap, item.getSpuId(), spu -> { + item.setSpuName(spu.getName()); + item.setPicUrl(spu.getPicUrl()); + }); + item.setProducts(convertList2(seckillProducts)); }); return pageResult; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java index 1c49155a8..e7a1240cb 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.promotion.service.bargain; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; @@ -21,7 +21,7 @@ public interface BargainActivityService { * @param createReqVO 创建信息 * @return 编号 */ - Long createBargainActivity(@Valid BargainActivityCreateReqVO createReqVO); + Long createBargainActivity(@Valid BargainActivityBaseVO createReqVO); /** * 更新砍价活动 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java index 96d9d32b1..51551e6e0 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java @@ -10,7 +10,7 @@ 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; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert; @@ -37,7 +37,8 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; */ @Service @Validated -public class BargainServiceImpl implements BargainActivityService, BargainRecordService { +public class BargainActivityServiceImpl implements BargainActivityService { + @Resource private BargainActivityMapper bargainActivityMapper; @@ -57,7 +58,7 @@ public class BargainServiceImpl implements BargainActivityService, BargainRecord @Override @Transactional(rollbackFor = Exception.class) - public Long createBargainActivity(BargainActivityCreateReqVO createReqVO) { + public Long createBargainActivity(BargainActivityBaseVO createReqVO) { // 校验商品 SPU 是否存在是否参加的别的活动 validateBargainConflict(createReqVO.getSpuId(), null); // 获取所选 spu下的所有 sku diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java index fda991a72..dc5ab1ef9 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.bargain; /** - * 商品活动记录 service + * 砍价记录 service 接口 * * @author HUIHUI */ diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java new file mode 100644 index 000000000..78780c97b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.promotion.service.bargain; + +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +/** + * 砍价记录 Service 实现类 + * + * @author HUIHUI + */ +@Service +@Validated +public class BargainRecordServiceImpl implements BargainRecordService { +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java index efbc0d1d0..4e2f85e27 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java @@ -14,11 +14,11 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.time.LocalDateTime; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_RECORD_USER_FULL; // TODO 芋艿:等拼团记录做完,完整 review 下 /** @@ -37,6 +37,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { private CombinationRecordMapper recordMapper; @Override + @Transactional(rollbackFor = Exception.class) public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) { // 校验拼团是否存在 CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId()); @@ -80,6 +81,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { } @Override + @Transactional(rollbackFor = Exception.class) public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) { // 1.1 校验拼团活动 CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(reqDTO.getActivityId()); @@ -88,9 +90,19 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { if (recordDO != null) { throw exception(COMBINATION_RECORD_EXISTS); } - // 1.3 父拼团是否存在,是否已经满了 + // 1.3 校验用户是否参加了其它拼团 + List recordDOList = recordMapper.selectListByUserIdAndStatus(reqDTO.getUserId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus()); + if (CollUtil.isNotEmpty(recordDOList)) { + throw exception(COMBINATION_RECORD_FAILED_HAVE_JOINED); + } + // 1.4 校验当前活动是否过期 + if (LocalDateTime.now().isAfter(activity.getEndTime())) { + throw exception(COMBINATION_RECORD_FAILED_TIME_END); + } + // 1.5 父拼团是否存在,是否已经满了 if (reqDTO.getHeadId() != null) { - CombinationRecordDO recordDO1 = recordMapper.selectRecordByHeadId(reqDTO.getHeadId(), reqDTO.getActivityId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus()); + // 查询进行中的父拼团 + CombinationRecordDO recordDO1 = recordMapper.selectOneByHeadId(reqDTO.getHeadId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus()); if (recordDO1 == null) { throw exception(COMBINATION_RECORD_HEAD_NOT_EXISTS); } @@ -99,7 +111,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { throw exception(COMBINATION_RECORD_USER_FULL); } } - // TODO @puhui999:应该还有一些校验,后续补噶;例如说,一个团,自己已经参与进去了,不能再参与进去; // 2. 创建拼团记录 CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO); @@ -115,6 +126,25 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { return validateCombinationRecord(userId, orderId); } + @Override + public List getRecordListByUserIdAndActivityId(Long userId, Long activityId) { + return recordMapper.selectListByUserIdAndActivityId(userId, activityId); + } + + @Override + public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) { + // 1.1 校验拼团活动 + CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(activityId); + // 校验是否达到限购总限购标准 + if ((sumCount + count) > activity.getTotalLimitCount()) { + throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED); + } + // 单次购买是否达到限购标准 + if (count > activity.getSingleLimitCount()) { + throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); + } + } + /** * APP 端获取开团记录 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationServiceImpl.java deleted file mode 100644 index 1b6ffd69f..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationServiceImpl.java +++ /dev/null @@ -1,319 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.combination; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.CollectionUtil; -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; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationActivityMapper; -import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationProductMapper; -import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper; -import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuAllExists; - -/** - * 拼团活动 Service 实现类 - * - * @author HUIHUI - */ -@Service -@Validated -public class CombinationServiceImpl implements CombinationActivityService, CombinationRecordService { - - @Resource - private CombinationActivityMapper combinationActivityMapper; - @Resource - private CombinationRecordMapper recordMapper; - @Resource - private CombinationProductMapper combinationProductMapper; - @Resource - private ProductSpuApi productSpuApi; - @Resource - private ProductSkuApi productSkuApi; - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) { - // 校验商品 SPU 是否存在是否参加的别的活动 - validateProductCombinationConflict(createReqVO.getSpuId(), null); - // 获取所选 spu下的所有 sku - List skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId())); - // 校验商品 sku 是否存在 - validateProductSkuAllExists(skus, createReqVO.getProducts(), CombinationProductCreateReqVO::getSkuId); - - // 插入拼团活动 - CombinationActivityDO activityDO = CombinationActivityConvert.INSTANCE.convert(createReqVO); - // TODO 营销相关属性初始化 拼团成功更新相关属性 - activityDO.setTotalNum(0); - activityDO.setSuccessNum(0); - activityDO.setOrderUserCount(0); - activityDO.setVirtualGroup(0); - activityDO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - combinationActivityMapper.insert(activityDO); - // 插入商品 - List productDOs = CombinationActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activityDO); - combinationProductMapper.insertBatch(productDOs); - // 返回 - return activityDO.getId(); - } - - private void validateProductCombinationConflict(Long spuId, Long activityId) { - // 校验商品 spu 是否存在 - List spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId)); - if (CollUtil.isEmpty(spuList)) { - throw exception(SPU_NOT_EXISTS); - } - // 查询所有开启的拼团活动 - List activityDOs = combinationActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); - // 更新时排除自己 - if (activityId != null) { - activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId)); - } - // 过滤出所有 spuIds 有交集的活动 - List doList = CollectionUtils.convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getId(), spuId)); - if (CollUtil.isNotEmpty(doList)) { - throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateCombinationActivity(CombinationActivityUpdateReqVO updateReqVO) { - // 校验存在 - CombinationActivityDO activityDO = validateCombinationActivityExists(updateReqVO.getId()); - // 校验状态 - if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { - throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE); - } - // 校验商品冲突 - validateProductCombinationConflict(updateReqVO.getSpuId(), updateReqVO.getId()); - // 获取所选 spu下的所有 sku - List skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId())); - // 校验商品 sku 是否存在 - validateProductSkuAllExists(skus, updateReqVO.getProducts(), CombinationProductUpdateReqVO::getSkuId); - - // 更新 - CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO); - combinationActivityMapper.updateById(updateObj); - // 更新商品 - updateCombinationProduct(updateObj, updateReqVO.getProducts()); - } - - /** - * 更新拼团商品 - * - * @param activity 拼团活动 - * @param products 该活动的最新商品配置 - */ - private void updateCombinationProduct(CombinationActivityDO activity, List products) { - // 第一步,对比新老数据,获得添加、修改、删除的列表 - List newList = CombinationActivityConvert.INSTANCE.convertList(products, activity); - List oldList = combinationProductMapper.selectListByActivityIds(CollUtil.newArrayList(activity.getId())); - List> diffList = CollectionUtils.diffList(oldList, newList, (oldVal, newVal) -> { - boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId()); - if (same) { - newVal.setId(oldVal.getId()); - } - return same; - }); - - // 第二步,批量添加、修改、删除 - if (CollUtil.isNotEmpty(diffList.get(0))) { - combinationProductMapper.insertBatch(diffList.get(0)); - } - if (CollUtil.isNotEmpty(diffList.get(1))) { - combinationProductMapper.updateBatch(diffList.get(1)); - } - if (CollUtil.isNotEmpty(diffList.get(2))) { - combinationProductMapper.deleteBatchIds(CollectionUtils.convertList(diffList.get(2), CombinationProductDO::getId)); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void deleteCombinationActivity(Long id) { - // 校验存在 - CombinationActivityDO activityDO = validateCombinationActivityExists(id); - // 校验状态 - if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { - throw exception(COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END); - } - - // 删除 - combinationActivityMapper.deleteById(id); - } - - private CombinationActivityDO validateCombinationActivityExists(Long id) { - CombinationActivityDO activityDO = combinationActivityMapper.selectById(id); - if (activityDO == null) { - throw exception(COMBINATION_ACTIVITY_NOT_EXISTS); - } - return activityDO; - } - - @Override - public CombinationActivityDO getCombinationActivity(Long id) { - return validateCombinationActivityExists(id); - } - - @Override - public List getCombinationActivityList(Collection ids) { - return combinationActivityMapper.selectBatchIds(ids); - } - - @Override - public PageResult getCombinationActivityPage(CombinationActivityPageReqVO pageReqVO) { - return combinationActivityMapper.selectPage(pageReqVO); - } - - @Override - public List getCombinationProductsByActivityIds(Collection ids) { - return combinationProductMapper.selectListByActivityIds(ids); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) { - // 校验拼团是否存在 - CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId()); - - // 更新状态 - recordDO.setStatus(reqDTO.getStatus()); - recordMapper.updateById(recordDO); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) { - CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId()); - // 更新状态 - recordDO.setStatus(reqDTO.getStatus()); - // 更新开始时间 - recordDO.setStartTime(reqDTO.getStartTime()); - recordMapper.updateById(recordDO); - - // 更新拼团参入人数 - List recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), reqDTO.getStatus()); - if (CollUtil.isNotEmpty(recordDOs)) { - recordDOs.forEach(item -> { - item.setUserCount(recordDOs.size()); - // 校验拼团是否满足要求 - if (ObjectUtil.equal(recordDOs.size(), recordDO.getUserSize())) { - item.setStatus(CombinationRecordStatusEnum.SUCCESS.getStatus()); - } - }); - } - recordMapper.updateBatch(recordDOs); - } - - private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) { - // 校验拼团是否存在 - CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(userId, orderId); - if (recordDO == null) { - throw exception(COMBINATION_RECORD_NOT_EXISTS); - } - return recordDO; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) { - // 1.1 校验拼团活动 - CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId()); - // 1.2 需要校验下,他当前是不是已经参加了该拼团; - CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(reqDTO.getUserId(), reqDTO.getOrderId()); - if (recordDO != null) { - throw exception(COMBINATION_RECORD_EXISTS); - } - // 1.3 校验用户是否参加了其它拼团 - List recordDOList = recordMapper.selectListByUserIdAndStatus(reqDTO.getUserId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus()); - if (CollUtil.isNotEmpty(recordDOList)) { - throw exception(COMBINATION_RECORD_FAILED_HAVE_JOINED); - } - // 1.4 校验当前活动是否过期 - if (LocalDateTime.now().isAfter(activity.getEndTime())) { - throw exception(COMBINATION_RECORD_FAILED_TIME_END); - } - // 1.5 父拼团是否存在,是否已经满了 - if (reqDTO.getHeadId() != null) { - // 查询进行中的父拼团 - CombinationRecordDO recordDO1 = recordMapper.selectOneByHeadId(reqDTO.getHeadId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus()); - if (recordDO1 == null) { - throw exception(COMBINATION_RECORD_HEAD_NOT_EXISTS); - } - // 校验拼团是否满足要求 - if (ObjectUtil.equal(recordDO1.getUserCount(), recordDO1.getUserSize())) { - throw exception(COMBINATION_RECORD_USER_FULL); - } - } - - // 2. 创建拼团记录 - CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO); - record.setVirtualGroup(false); - // TODO @puhui999:过期时间,应该是 Date 哈; - record.setExpireTime(activity.getLimitDuration()); - record.setUserSize(activity.getUserSize()); - recordMapper.insert(record); - } - - @Override - public CombinationRecordDO getCombinationRecord(Long userId, Long orderId) { - return validateCombinationRecord(userId, orderId); - } - - /** - * APP 端获取开团记录 - * - * @return 开团记录 - */ - public List getRecordListByStatus(Integer status) { - return recordMapper.selectListByStatus(status); - } - - public List getRecordListByUserIdAndActivityId(Long userId, Long activityId) { - return recordMapper.selectListByUserIdAndActivityId(userId, activityId); - } - - @Override - public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) { - // 1.1 校验拼团活动 - CombinationActivityDO activity = validateCombinationActivityExists(activityId); - // 校验是否达到限购总限购标准 - if ((sumCount + count) > activity.getTotalLimitCount()) { - throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED); - } - // 单次购买是否达到限购标准 - if (count > activity.getSingleLimitCount()) { - throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); - } - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java index 81ce84dd4..86d58d747 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java @@ -23,15 +23,15 @@ import static org.junit.jupiter.api.Assertions.*; // TODO 芋艿:等完成后,在补全单测 /** - * {@link CombinationServiceImpl} 的单元测试类 + * {@link CombinationActivityServiceImpl} 的单元测试类 * * @author HUIHUI */ -@Import(CombinationServiceImpl.class) +@Import(CombinationActivityServiceImpl.class) public class CombinationActivityServiceImplTest extends BaseDbUnitTest { @Resource - private CombinationServiceImpl combinationActivityService; + private CombinationActivityServiceImpl combinationActivityService; @Resource private CombinationActivityMapper combinationActivityMapper; @@ -111,8 +111,8 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest { o.setStartTime(null); o.setEndTime(null); o.setUserSize(null); - o.setTotalNum(null); - o.setSuccessNum(null); + o.setTotalCount(null); + o.setSuccessCount(null); o.setOrderUserCount(null); o.setVirtualGroup(null); o.setStatus(null); @@ -135,9 +135,9 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest { // 测试 userSize 不匹配 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setUserSize(null))); // 测试 totalNum 不匹配 - combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalNum(null))); + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalCount(null))); // 测试 successNum 不匹配 - combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSuccessNum(null))); + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSuccessCount(null))); // 测试 orderUserCount 不匹配 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setOrderUserCount(null))); // 测试 virtualGroup 不匹配 @@ -173,8 +173,8 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest { o.setStartTime(null); o.setEndTime(null); o.setUserSize(null); - o.setTotalNum(null); - o.setSuccessNum(null); + o.setTotalCount(null); + o.setSuccessCount(null); o.setOrderUserCount(null); o.setVirtualGroup(null); o.setStatus(null); @@ -197,9 +197,9 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest { // 测试 userSize 不匹配 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setUserSize(null))); // 测试 totalNum 不匹配 - combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalNum(null))); + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalCount(null))); // 测试 successNum 不匹配 - combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSuccessNum(null))); + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSuccessCount(null))); // 测试 orderUserCount 不匹配 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setOrderUserCount(null))); // 测试 virtualGroup 不匹配