From 544597d6e2e53f6db9588b0754d80e90b648662d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 5 Nov 2022 19:57:50 +0800 Subject: [PATCH] =?UTF-8?q?promotion=EF=BC=9A=E5=AE=8C=E5=96=84=E9=99=90?= =?UTF-8?q?=E6=97=B6=E6=8A=98=E6=89=A3=EF=BC=8C=E8=A1=A5=E5=85=85=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../discount/DiscountActivityConvert.java | 4 ++ .../mysql/discount/DiscountProductMapper.java | 4 ++ .../discount/DiscountActivityServiceImpl.java | 32 ++++++++- .../DiscountActivityServiceImplTest.java | 71 +++++++++++++++++-- 4 files changed, 105 insertions(+), 6 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java index 982b91e90..6708199e0 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.convert.discount; 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.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityRespVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; @@ -46,4 +47,7 @@ public interface DiscountActivityConvert { return detail; }); } + + DiscountProductDO convert(DiscountActivityBaseVO.Product bean); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java index deca21741..646b60707 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java @@ -19,4 +19,8 @@ public interface DiscountProductMapper extends BaseMapperX { return selectList(DiscountProductDO::getSkuId, skuIds); } + default List selectListByActivityId(Long activityId) { + return selectList(DiscountProductDO::getActivityId, activityId); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java index 076caff5d..5504ac25d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.promotion.service.discount; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; @@ -22,6 +23,7 @@ import javax.annotation.Resource; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; import static java.util.Arrays.asList; @@ -54,10 +56,14 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { // 校验商品是否冲突 validateDiscountActivityProductConflicts(null, createReqVO.getProducts()); - // 插入 + // 插入活动 DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO) .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); discountActivityMapper.insert(discountActivity); + // 插入商品 + List discountProducts = convertList(createReqVO.getProducts(), + product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(discountActivity.getId())); + discountProductMapper.insertBatch(discountProducts); // 返回 return discountActivity.getId(); } @@ -72,12 +78,34 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { // 校验商品是否冲突 validateDiscountActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); - // 更新 + // 更新活动 DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO) .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); discountActivityMapper.updateById(updateObj); + // 更新商品 + updateDiscountProduct(updateReqVO); } + private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) { + List dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId()); + // 计算要删除的记录 + List deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId, + discountProductDO -> updateReqVO.getProducts().stream() + .noneMatch(product -> product.getSkuId().equals(discountProductDO.getSkuId()) + && product.getDiscountPrice().equals(discountProductDO.getDiscountPrice()))); + if (CollUtil.isNotEmpty(deleteIds)) { + discountProductMapper.deleteBatchIds(deleteIds); + } + // 计算新增的记录 + List newDiscountProducts = convertList(updateReqVO.getProducts(), + product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId())); + newDiscountProducts.removeIf(product -> dbDiscountProducts.stream().anyMatch( + dbProduct -> dbProduct.getSkuId().equals(product.getSkuId()) + && dbProduct.getDiscountPrice().equals(product.getDiscountPrice()))); // 如果匹配到,说明是更新的 + if (CollectionUtil.isNotEmpty(newDiscountProducts)) { + discountProductMapper.insertBatch(newDiscountProducts); + } + } /** * 校验商品是否冲突 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java index e3190b49b..6d482bde0 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java @@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.promotion.service.discount; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; @@ -14,6 +17,7 @@ import org.springframework.context.annotation.Import; import javax.annotation.Resource; import java.time.Duration; import java.util.Date; +import java.util.List; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime; @@ -23,6 +27,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServic import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.DISCOUNT_ACTIVITY_NOT_EXISTS; +import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.*; /** @@ -38,6 +43,8 @@ public class DiscountActivityServiceImplTest extends BaseDbUnitTest { @Resource private DiscountActivityMapper discountActivityMapper; + @Resource + private DiscountProductMapper discountProductMapper; @Test public void testCreateDiscountActivity_success() { @@ -45,32 +52,87 @@ public class DiscountActivityServiceImplTest extends BaseDbUnitTest { DiscountActivityCreateReqVO reqVO = randomPojo(DiscountActivityCreateReqVO.class, o -> { // 用于触发进行中的状态 o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); + // 设置商品 + o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L).setDiscountPrice(3), + new DiscountActivityBaseVO.Product().setSpuId(10L).setSkuId(20L).setDiscountPrice(30))); }); // 调用 Long discountActivityId = discountActivityService.createDiscountActivity(reqVO); // 断言 assertNotNull(discountActivityId); - // 校验记录的属性是否正确 + // 校验活动 DiscountActivityDO discountActivity = discountActivityMapper.selectById(discountActivityId); assertPojoEquals(reqVO, discountActivity); + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); + // 校验商品 + List discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); + assertEquals(discountProducts.size(), reqVO.getProducts().size()); + for (int i = 0; i < reqVO.getProducts().size(); i++) { + DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); + DiscountProductDO discountProduct = discountProducts.get(i); + assertEquals(discountProduct.getActivityId(), discountActivity.getId()); + assertEquals(discountProduct.getSpuId(), product.getSpuId()); + assertEquals(discountProduct.getSkuId(), product.getSkuId()); + assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); + } } @Test public void testUpdateDiscountActivity_success() { - // mock 数据 + // mock 数据(商品) DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class); discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 + // mock 数据(活动) + DiscountProductDO dbDiscountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) + .setSpuId(1L).setSkuId(2L)); + DiscountProductDO dbDiscountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) + .setSpuId(10L).setSkuId(20L)); + discountProductMapper.insert(dbDiscountProduct01); + discountProductMapper.insert(dbDiscountProduct02); // 准备参数 DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class, o -> { o.setId(dbDiscountActivity.getId()); // 设置更新的 ID + // 用于触发进行中的状态 + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); + // 设置商品 + o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L).setDiscountPrice(3), + new DiscountActivityBaseVO.Product().setSpuId(100L).setSkuId(200L).setDiscountPrice(30))); }); // 调用 discountActivityService.updateDiscountActivity(reqVO); - // 校验是否更新正确 + // 校验活动 DiscountActivityDO discountActivity = discountActivityMapper.selectById(reqVO.getId()); // 获取最新的 assertPojoEquals(reqVO, discountActivity); + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); + // 校验商品 + List discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); + assertEquals(discountProducts.size(), reqVO.getProducts().size()); + for (int i = 0; i < reqVO.getProducts().size(); i++) { + DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); + DiscountProductDO discountProduct = discountProducts.get(i); + assertEquals(discountProduct.getActivityId(), discountActivity.getId()); + assertEquals(discountProduct.getSpuId(), product.getSpuId()); + assertEquals(discountProduct.getSkuId(), product.getSkuId()); + assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); + } + } + + @Test + public void testCloseDiscountActivity() { + // mock 数据 + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, + o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); + discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbDiscountActivity.getId(); + + // 调用 + discountActivityService.closeRewardActivity(id); + // 校验状态 + DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); } @Test @@ -85,7 +147,8 @@ public class DiscountActivityServiceImplTest extends BaseDbUnitTest { @Test public void testDeleteDiscountActivity_success() { // mock 数据 - DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class); + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, + o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus())); discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbDiscountActivity.getId();