Browse Source

mall模块-限时折扣功能

zhangshuai 1 năm trước cách đây
mục cha
commit
04061b028c

+ 25 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java

@@ -1,11 +1,17 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.discount;
 
+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.discount.vo.*;
 import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
+import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
 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.dataobject.seckill.SeckillActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
 import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -17,8 +23,11 @@ import org.springframework.web.bind.annotation.*;
 import javax.annotation.Resource;
 import javax.validation.Valid;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 
 @Tag(name = "管理后台 - 限时折扣活动")
 @RestController
@@ -29,6 +38,9 @@ public class DiscountActivityController {
     @Resource
     private DiscountActivityService discountActivityService;
 
+    @Resource
+    private ProductSpuApi productSpuApi;
+
     @PostMapping("/create")
     @Operation(summary = "创建限时折扣活动")
     @PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')")
@@ -49,7 +61,7 @@ public class DiscountActivityController {
     @Parameter(name = "id", description = "编号", required = true)
     @PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')")
     public CommonResult<Boolean> closeRewardActivity(@RequestParam("id") Long id) {
-        discountActivityService.closeRewardActivity(id);
+        discountActivityService.closeDiscountActivity(id);
         return success(true);
     }
 
@@ -81,7 +93,18 @@ public class DiscountActivityController {
     @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')")
     public CommonResult<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) {
         PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO);
-        return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult));
+
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(PageResult.empty(pageResult.getTotal()));
+        }
+        // 拼接数据
+        List<DiscountProductDO> products = discountActivityService.getDiscountProductsByActivityId(
+                convertSet(pageResult.getList(), DiscountActivityDO::getId));
+
+        List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(
+                convertSet(products, DiscountProductDO::getSpuId));
+
+        return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products, spuList));
     }
 
 }

+ 22 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java

@@ -7,6 +7,7 @@ import lombok.ToString;
 
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "管理后台 - 限时折扣活动 Response VO")
 @Data
@@ -24,4 +25,25 @@ public class DiscountActivityRespVO extends DiscountActivityBaseVO {
     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
+
+    @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
+    private Long spuId;
+
+    @Schema(description = "限时折扣商品", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<DiscountActivityBaseVO.Product> products;
+
+
+    // ========== 商品字段 ==========
+
+    @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取
+            example = "618大促")
+    private String spuName;
+    @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 picUrl 读取
+            example = "https://www.iocoder.cn/xx.png")
+    private String picUrl;
+    @Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 marketPrice 读取
+            example = "50")
+    private Integer marketPrice;
+
+
 }

+ 51 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java

@@ -2,15 +2,22 @@ package cn.iocoder.yudao.module.promotion.convert.discount;
 
 import cn.hutool.core.util.ObjectUtil;
 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.api.discount.dto.DiscountProductRespDTO;
 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
 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.dataobject.seckill.SeckillProductDO;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 限时折扣活动 Convert
@@ -29,14 +36,57 @@ public interface DiscountActivityConvert {
     DiscountActivityRespVO convert(DiscountActivityDO bean);
 
     List<DiscountActivityRespVO> convertList(List<DiscountActivityDO> list);
+    List<DiscountActivityBaseVO.Product> convertList2(List<DiscountProductDO> list);
 
     List<DiscountProductRespDTO> convertList02(List<DiscountProductDO> list);
 
     PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page);
 
+    default PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page,
+                                                           List<DiscountProductDO> discountProductDOList,
+                                                           List<ProductSpuRespDTO> spuList) {
+        PageResult<DiscountActivityRespVO> pageResult = convertPage(page);
+
+        // 拼接商品
+        Map<Long, DiscountProductDO> discountActivityMap = CollectionUtils.convertMap(discountProductDOList, DiscountProductDO::getActivityId);
+        Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId);
+        pageResult.getList().forEach(item -> {
+            item.setProducts(convertList2(discountProductDOList));
+            item.setSpuId(discountActivityMap.get(item.getId())==null?null: discountActivityMap.get(item.getId()).getSpuId());
+            if (item.getSpuId() != null) {
+                MapUtils.findAndThen(spuMap, item.getSpuId(),
+                        spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()));
+            }
+
+        });
+        return pageResult;
+    }
+
     DiscountProductDO convert(DiscountActivityBaseVO.Product bean);
 
-    DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List<DiscountProductDO> products);
+    default DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List<DiscountProductDO> products){
+        if ( activity == null && products == null ) {
+            return null;
+        }
+
+        DiscountActivityDetailRespVO discountActivityDetailRespVO = new DiscountActivityDetailRespVO();
+
+        if ( activity != null ) {
+            discountActivityDetailRespVO.setName( activity.getName() );
+            discountActivityDetailRespVO.setStartTime( activity.getStartTime() );
+            discountActivityDetailRespVO.setEndTime( activity.getEndTime() );
+            discountActivityDetailRespVO.setRemark( activity.getRemark() );
+            discountActivityDetailRespVO.setId( activity.getId() );
+            discountActivityDetailRespVO.setStatus( activity.getStatus() );
+            discountActivityDetailRespVO.setCreateTime( activity.getCreateTime() );
+        }
+        if (!products.isEmpty()) {
+            discountActivityDetailRespVO.setSpuId(products.get(0).getSpuId());
+        }
+        discountActivityDetailRespVO.setProducts( convertList2( products ) );
+
+        return discountActivityDetailRespVO;
+    }
 
     // =========== 比较是否相等 ==========
     /**

+ 7 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.discount;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.Collection;
 import java.util.List;
@@ -23,4 +24,10 @@ public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> {
         return selectList(DiscountProductDO::getActivityId, activityId);
     }
 
+    default List<DiscountProductDO> selectListByActivityId(Collection<Long> activityIds) {
+        return selectList(DiscountProductDO::getActivityId, activityIds);
+    }
+
+
+    List<DiscountProductDO> getMatchDiscountProductList(@Param("skuIds") Collection<Long> skuIds);
 }

+ 9 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java

@@ -48,7 +48,7 @@ public interface DiscountActivityService {
      *
      * @param id 编号
      */
-    void closeRewardActivity(Long id);
+    void closeDiscountActivity(Long id);
 
     /**
      * 删除限时折扣活动
@@ -81,4 +81,12 @@ public interface DiscountActivityService {
      */
     List<DiscountProductDO> getDiscountProductsByActivityId(Long activityId);
 
+    /**
+     * 获得活动编号,对应对应的商品列表
+     *
+     * @param activityIds 活动编号
+     * @return 活动的商品列表
+     */
+    List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds);
+
 }

+ 21 - 11
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java

@@ -2,6 +2,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.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
@@ -20,6 +21,7 @@ import org.springframework.validation.annotation.Validated;
 import javax.annotation.Resource;
 import java.util.Collection;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -41,8 +43,9 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
 
     @Override
     public List<DiscountProductDO> getMatchDiscountProductList(Collection<Long> skuIds) {
-        // TODO 芋艿:开启、满足 skuId、日期内
-        return null;
+        //  芋艿:开启、满足 skuId、日期内
+        List<DiscountProductDO> matchDiscountProductList = discountProductMapper.getMatchDiscountProductList(skuIds);
+        return matchDiscountProductList;
     }
 
     @Override
@@ -66,7 +69,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
     public void updateDiscountActivity(DiscountActivityUpdateReqVO updateReqVO) {
         // 校验存在
         DiscountActivityDO discountActivity = validateDiscountActivityExists(updateReqVO.getId());
-        if (discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢
+        if (discountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能修改噢
             throw exception(DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
         }
         // 校验商品是否冲突
@@ -99,7 +102,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
         }
     }
 
-    // TODO 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。
+    // 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。
     /**
      * 校验商品是否冲突
      *
@@ -111,27 +114,30 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
             return;
         }
         // 查询商品参加的活动
-        List<DiscountProductDO> discountActivityProductList = null;
+
+        List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id);
+        List<Long> skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
+        List<DiscountProductDO> matchDiscountProductList = getMatchDiscountProductList(skuIds);
 //                getRewardProductListBySkuIds(
 //                convertSet(products, DiscountActivityBaseVO.Product::getSkuId),
 //                asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()));
         if (id != null) { // 排除自己这个活动
-            discountActivityProductList.removeIf(product -> id.equals(product.getActivityId()));
+            matchDiscountProductList.removeIf(product -> id.equals(product.getActivityId()));
         }
         // 如果非空,则说明冲突
-        if (CollUtil.isNotEmpty(discountActivityProductList)) {
+        if (CollUtil.isNotEmpty(matchDiscountProductList)) {
             throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS);
         }
     }
 
     @Override
-    public void closeRewardActivity(Long id) {
+    public void closeDiscountActivity(Long id) {
         // 校验存在
         DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id);
-        if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢
+        if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
             throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
         }
-        if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢
+        if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
             throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END);
         }
 
@@ -144,7 +150,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
     public void deleteDiscountActivity(Long id) {
         // 校验存在
         DiscountActivityDO discountActivity = validateDiscountActivityExists(id);
-        if (!discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢
+        if (!discountActivity.getStatus().equals(CommonStatusEnum.ENABLE.getStatus())) { // 未关闭的活动,不能删除噢
             throw exception(DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED);
         }
 
@@ -175,4 +181,8 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
         return discountProductMapper.selectListByActivityId(activityId);
     }
 
+    @Override
+    public List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds) {
+        return discountProductMapper.selectList("activity_id", activityIds);
+    }
 }

+ 24 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/discount/DiscountProductMapper.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper">
+
+
+    <select id="getMatchDiscountProductList"   resultType="cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO">
+        SELECT pdp.*
+        FROM promotion_discount_product pdp
+        LEFT JOIN promotion_discount_activity pda
+        ON pdp.activity_id = pda.id
+        <where>
+            <if test="skuIds != null and skuIds.size > 0">
+                AND pdp.sku_id in
+                <foreach collection="skuIds" item="skuId" index="index" open="(" close=")" separator=",">
+                    #{skuId}
+                </foreach>
+            </if>
+            AND pda.start_time &lt;= CURRENT_TIME AND pda.end_time &gt;= CURRENT_TIME
+            AND pda.`status` = 20
+            AND pda.deleted != 1
+        </where>
+    </select>
+
+</mapper>