From 0a3a6825d5186ed252545ad1bea99b5157e416be Mon Sep 17 00:00:00 2001 From: owen Date: Tue, 26 Sep 2023 20:44:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E5=96=84APP=E4=BC=98=E6=83=A0=E5=88=B8=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 6 +- .../dto/RewardActivityMatchRespDTO.java | 2 +- .../common/PromotionProductScopeEnum.java | 6 +- .../vo/template/CouponTemplatePageReqVO.java | 9 +- .../admin/reward/vo/RewardActivityBaseVO.java | 2 +- .../coupon/AppCouponTemplateController.java | 123 +++++++----------- .../coupon/vo/coupon/AppCouponMatchReqVO.java | 6 +- .../template/AppCouponTemplatePageReqVO.java | 10 +- .../convert/coupon/CouponTemplateConvert.java | 21 +++ .../dataobject/reward/RewardActivityDO.java | 2 +- .../dal/mysql/coupon/CouponMapper.java | 11 ++ .../mysql/coupon/CouponTemplateMapper.java | 3 + .../service/coupon/CouponService.java | 31 ++++- .../service/coupon/CouponServiceImpl.java | 13 +- .../service/coupon/bo/CouponTakeCountBO.java | 20 +++ .../brokerage/BrokerageRecordMapper.java | 5 +- .../brokerage/BrokerageWithdrawMapper.java | 5 +- 17 files changed, 169 insertions(+), 106 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 443be2c2c7..ef0da9f0a5 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -1188,8 +1188,8 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1166, 2, '折扣', '2', 'promotion_discount_type', 0, 'primary', '', '优惠类型 - 折扣', '1', '2022-11-01 12:46:51', '1', '2022-11-01 12:50:08', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1167, 1, '固定日期', '1', 'promotion_coupon_template_validity_type', 0, 'default', '', '优惠劵模板的有限期类型 - 固定日期', '1', '2022-11-02 00:07:34', '1', '2022-11-04 00:07:49', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1168, 2, '领取之后', '2', 'promotion_coupon_template_validity_type', 0, 'default', '', '优惠劵模板的有限期类型 - 领取之后', '1', '2022-11-02 00:07:54', '1', '2022-11-04 00:07:52', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1169, 1, '通用卷', '1', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 全部商品参与', '1', '2022-11-02 00:28:22', '1', '2023-09-01 23:42:49', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1170, 2, '商品卷', '2', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 指定商品参与', '1', '2022-11-02 00:28:34', '1', '2023-09-01 23:42:54', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1169, 1, '通用券', '1', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 全部商品参与', '1', '2022-11-02 00:28:22', '1', '2023-09-01 23:42:49', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1170, 2, '商品券', '2', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 指定商品参与', '1', '2022-11-02 00:28:34', '1', '2023-09-01 23:42:54', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1171, 1, '已领取', '1', 'promotion_coupon_status', 0, 'primary', '', '优惠劵的状态 - 已领取', '1', '2022-11-04 00:15:08', '1', '2022-11-04 19:16:04', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1172, 2, '已使用', '2', 'promotion_coupon_status', 0, 'success', '', '优惠劵的状态 - 已使用', '1', '2022-11-04 00:15:21', '1', '2022-11-04 19:16:08', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1173, 3, '已过期', '3', 'promotion_coupon_status', 0, 'info', '', '优惠劵的状态 - 已过期', '1', '2022-11-04 00:15:43', '1', '2022-11-04 19:16:12', b'0'); @@ -1284,7 +1284,7 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1355, 5, '抽奖奖励', '5', 'member_experience_biz_type', 0, '', '', NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1356, 1, '快递发货', '1', 'trade_delivery_type', 0, '', '', '', '1', '2023-08-23 00:04:55', '1', '2023-08-23 00:04:55', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1357, 2, '用户自提', '2', 'trade_delivery_type', 0, '', '', '', '1', '2023-08-23 00:05:05', '1', '2023-08-23 00:05:05', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1358, 3, '品类卷', '3', 'promotion_product_scope', 0, 'default', '', '', '1', '2023-09-01 23:43:07', '1', '2023-09-01 23:43:07', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1358, 3, '品类券', '3', 'promotion_product_scope', 0, 'default', '', '', '1', '2023-09-01 23:43:07', '1', '2023-09-01 23:43:07', b'0'); COMMIT; -- ---------------------------- diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java index 19f46a49ae..6ae71a1d9e 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java @@ -68,7 +68,7 @@ public class RewardActivityMatchRespDTO { */ private List couponIds; /** - * 赠送的优惠卷数量的数组 + * 赠送的优惠券数量的数组 */ private List couponCounts; diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java index 6ae9f9f468..882dc4aee7 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java @@ -15,9 +15,9 @@ import java.util.Arrays; @AllArgsConstructor public enum PromotionProductScopeEnum implements IntArrayValuable { - ALL(1, "通用卷"), // 全部商品 - SPU(2, "商品卷"), // 指定商品 - CATEGORY(3, "品类卷"), // 指定商品 + ALL(1, "通用券"), // 全部商品 + SPU(2, "商品券"), // 指定商品 + CATEGORY(3, "品类券"), // 指定品类 ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray(); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java index abc7134e1d..551d076ea0 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -33,8 +34,14 @@ public class CouponTemplatePageReqVO extends PageParam { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @Schema(description = "可以领取的类型", example = "[1,2, 3]") + @Schema(description = "可以领取的类型", example = "[1, 2, 3]") @InEnum(value = CouponTakeTypeEnum.class, message = "可以领取的类型,必须是 {value}") private List canTakeTypes; + @Schema(description = "商品范围", example = "1") + @InEnum(value = PromotionProductScopeEnum.class, message = "商品范围,必须是 {value}") + private Integer productScope; + + @Schema(description = "商品范围编号", example = "1") + private Long productScopeValue; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java index 3cb3109f3e..030a31a5da 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java @@ -84,7 +84,7 @@ public class RewardActivityBaseVO { @Schema(description = "赠送的优惠劵编号的数组", example = "1,2,3") private List couponIds; - @Schema(description = "赠送的优惠卷数量的数组", example = "1,2,3") + @Schema(description = "赠送的优惠券数量的数组", example = "1,2,3") private List couponCounts; @AssertTrue(message = "优惠劵和数量必须一一对应") diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java index c4d81de2c8..be2c53559c 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java @@ -1,27 +1,31 @@ package cn.iocoder.yudao.module.promotion.controller.app.coupon; +import cn.hutool.core.util.ObjUtil; 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.app.coupon.vo.template.AppCouponTemplatePageReqVO; import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template.AppCouponTemplateRespVO; +import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; +import java.util.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; @Tag(name = "用户 App - 优惠劵模板") @RestController @@ -31,84 +35,45 @@ public class AppCouponTemplateController { @Resource private CouponTemplateService couponTemplateService; + @Resource + private CouponService couponService; - // TODO 芋艿:待实现 - @GetMapping("/list") - @Operation(summary = "获得优惠劵模版列表") - @Parameters({ - @Parameter(name = "spuId", description = "商品 SPU 编号"), // 目前主要给商品详情使用 - @Parameter(name = "useType", description = "使用类型"), - @Parameter(name = "count", description = "数量", required = true) - }) - public CommonResult> getCouponTemplateList(@RequestParam(value = "spuId", required = false) Long spuId, - @RequestParam(value = "useType", required = false) Integer useType, - @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { - List list = new ArrayList<>(); - Random random = new Random(); - for (int i = 0; i < 10; i++) { - AppCouponTemplateRespVO vo = new AppCouponTemplateRespVO(); - vo.setId(i + 1L); - vo.setName("优惠劵" + (i + 1)); - vo.setTakeLimitCount(random.nextInt(10) + 1); - vo.setUsePrice(random.nextInt(100) * 100); - vo.setValidityType(random.nextInt(2) + 1); - if (vo.getValidityType() == 1) { - vo.setValidStartTime(LocalDateTime.now().plusDays(random.nextInt(10))); - vo.setValidEndTime(LocalDateTime.now().plusDays(random.nextInt(20) + 10)); - } else { - vo.setFixedStartTerm(random.nextInt(10)); - vo.setFixedEndTerm(random.nextInt(10) + vo.getFixedStartTerm() + 1); - } - vo.setDiscountType(random.nextInt(2) + 1); - if (vo.getDiscountType() == 1) { - vo.setDiscountPercent(null); - vo.setDiscountPrice(random.nextInt(50) * 100); - vo.setDiscountLimitPrice(null); - } else { - vo.setDiscountPercent(random.nextInt(90) + 10); - vo.setDiscountPrice(null); - vo.setDiscountLimitPrice(random.nextInt(200) * 100); - } - vo.setTakeStatus(random.nextBoolean()); - list.add(vo); - } - return success(list); - } + @Resource + private ProductSpuApi productSpuApi; - // TODO 芋艿:待实现;和 getCouponTemplateList 类似 @GetMapping("/page") @Operation(summary = "获得优惠劵模版分页") public CommonResult> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) { - List list = new ArrayList<>(); - Random random = new Random(); - for (int i = 0; i < 10; i++) { - AppCouponTemplateRespVO vo = new AppCouponTemplateRespVO(); - vo.setId(i + 1L); - vo.setName("优惠劵" + (i + 1)); - vo.setTakeLimitCount(random.nextInt(10) + 1); - vo.setUsePrice(random.nextInt(100) * 100); - vo.setValidityType(random.nextInt(2) + 1); - if (vo.getValidityType() == 1) { - vo.setValidStartTime(LocalDateTime.now().plusDays(random.nextInt(10))); - vo.setValidEndTime(LocalDateTime.now().plusDays(random.nextInt(20) + 10)); - } else { - vo.setFixedStartTerm(random.nextInt(10)); - vo.setFixedEndTerm(random.nextInt(10) + vo.getFixedStartTerm() + 1); - } - vo.setDiscountType(random.nextInt(2) + 1); - if (vo.getDiscountType() == 1) { - vo.setDiscountPercent(null); - vo.setDiscountPrice(random.nextInt(50) * 100); - vo.setDiscountLimitPrice(null); - } else { - vo.setDiscountPercent(random.nextInt(90) + 10); - vo.setDiscountPrice(null); - vo.setDiscountLimitPrice(random.nextInt(200) * 100); - } - vo.setTakeStatus(random.nextBoolean()); - list.add(vo); + // 1.1 处理查询条件:商品范围编号 + Long productScopeValue = getaProductScopeValue(pageReqVO); + // 1.2 处理查询条件:领取方式=直接领取 + List canTakeTypes = Collections.singletonList(CouponTakeTypeEnum.USER.getValue()); + // 2. 分页查询 + PageResult pageResult = couponTemplateService.getCouponTemplatePage( + CouponTemplateConvert.INSTANCE.convert(pageReqVO, canTakeTypes, pageReqVO.getProductScope(), productScopeValue)); + // 3.1 领取数量 + Map couponTakeCountMap = new HashMap<>(0); + Long userId = getLoginUserId(); + if (userId != null) { + List templateIds = convertList(pageResult.getList(), CouponTemplateDO::getId, + t -> ObjUtil.notEqual(t.getTakeLimitCount(), -1)); // 只查有设置“每人限领个数”的 + couponTakeCountMap = couponService.getTakeCountMapByTemplateIds(templateIds, userId); } - return success(new PageResult<>(list, 20L)); + // 3.2 拼接返回 + return success(CouponTemplateConvert.INSTANCE.convertAppPage(pageResult, couponTakeCountMap)); + } + + private Long getaProductScopeValue(AppCouponTemplatePageReqVO pageReqVO) { + Long productScopeValue = pageReqVO.getSpuId(); + if (pageReqVO.getProductScope() == null || Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.ALL.getScope())) { + // 通用券:清除商品范围 + productScopeValue = null; + } else if (Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.CATEGORY.getScope()) && pageReqVO.getSpuId() != null) { + // 品类券:查询商品的品类 + productScopeValue = Optional.ofNullable(productSpuApi.getSpu(pageReqVO.getSpuId())) + .map(ProductSpuRespDTO::getCategoryId).orElse(null); + } + return productScopeValue; } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchReqVO.java index 633644ea36..9d36e3a4e8 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchReqVO.java @@ -15,15 +15,15 @@ public class AppCouponMatchReqVO { @NotNull(message = "商品金额不能为空") private Integer price; - @Schema(description = "商品 SPU 编号的数组", required = true, example = "[1, 2]") + @Schema(description = "商品 SPU 编号的数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]") @NotEmpty(message = "商品 SPU 编号不能为空") private List spuIds; - @Schema(description = "商品 SKU 编号的数组", required = true, example = "[1, 2]") + @Schema(description = "商品 SKU 编号的数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]") @NotEmpty(message = "商品 SKU 编号不能为空") private List skuIds; - @Schema(description = "分类编号的数组", required = true, example = "[10, 20]") + @Schema(description = "分类编号的数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[10, 20]") @NotEmpty(message = "分类编号不能为空") private List categoryIds; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java index 6eda32167e..48f2dc9045 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,8 +14,10 @@ import lombok.ToString; @ToString(callSuper = true) public class AppCouponTemplatePageReqVO extends PageParam { - @Schema(description = "使用类型", example = "1") - // TODO 芋艿:这里要限制下枚举的使用 - private Integer useType; + @Schema(description = "商品范围", example = "1") + @InEnum(value = PromotionProductScopeEnum.class, message = "商品范围,必须是 {value}") + private Integer productScope; + @Schema(description = "商品标号", example = "1") + private Long spuId; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java index 22d78f46fd..b6d3bed9b5 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java @@ -26,4 +26,25 @@ public interface CouponTemplateConvert { PageResult convertPage(PageResult page); + CouponTemplatePageReqVO convert(AppCouponTemplatePageReqVO pageReqVO, List canTakeTypes, Integer productScope, Long productScopeValue); + + PageResult convertAppPage(PageResult pageResult); + + default PageResult convertAppPage(PageResult pageResult, Map couponTakeCountMap) { + PageResult result = convertAppPage(pageResult); + if (MapUtil.isEmpty(couponTakeCountMap)) { + return result; + } + + for (AppCouponTemplateRespVO vo : result.getList()) { + // 每人领取数量无限制 + if (vo.getTakeLimitCount() == -1) { + vo.setTakeStatus(false); + continue; + } + // 检查已领取数量是否超过限领数量 + vo.setTakeStatus(MapUtil.getInt(couponTakeCountMap, vo.getId(), 0) >= vo.getTakeLimitCount()); + } + return result; + } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java index 9d417d75fc..a066d2f26e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java @@ -110,7 +110,7 @@ public class RewardActivityDO extends BaseDO { */ private List couponIds; /** - * 赠送的优惠卷数量的数组 + * 赠送的优惠券数量的数组 */ private List couponCounts; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java index ddf90691c4..f79f23c21b 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; +import cn.hutool.core.bean.BeanUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.github.yulichang.toolkit.MPJWrappers; import org.apache.ibatis.annotations.Mapper; import java.util.Collection; @@ -62,4 +65,12 @@ public interface CouponMapper extends BaseMapperX { ); } + default List selectCountByUserIdAndTemplateIdIn(Long userId, Collection templateIds) { + return BeanUtil.copyToList(selectMaps(MPJWrappers.lambdaJoin(CouponDO.class) + .select(CouponDO::getTemplateId) + .selectCount(CouponDO::getId, CouponTakeCountBO::getCount) + .eq(CouponDO::getUserId, userId) + .in(CouponDO::getTemplateId, templateIds) + .groupBy(CouponDO::getTemplateId)), CouponTakeCountBO.class); + } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java index c95513e184..3c575c4d42 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java @@ -39,6 +39,9 @@ public interface CouponTemplateMapper extends BaseMapperX { .eqIfPresent(CouponTemplateDO::getStatus, reqVO.getStatus()) .eqIfPresent(CouponTemplateDO::getDiscountType, reqVO.getDiscountType()) .betweenIfPresent(CouponTemplateDO::getCreateTime, reqVO.getCreateTime()) + .eqIfPresent(CouponTemplateDO::getProductScope, reqVO.getProductScope()) + .and(reqVO.getProductScopeValue() != null, w -> w.apply("FIND_IN_SET({0}, product_scope_values)", + reqVO.getProductScopeValue())) .and(canTakeConsumer != null, canTakeConsumer) .orderByDesc(CouponTemplateDO::getId)); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java index cf22fe2b3a..b3569a34be 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java @@ -5,10 +5,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; +import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Set; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + /** * 优惠劵 Service 接口 * @@ -18,11 +23,11 @@ public interface CouponService { /** * 校验优惠劵,包括状态、有限期 - * + *

* 1. 如果校验通过,则返回优惠劵信息 * 2. 如果校验不通过,则直接抛出业务异常 * - * @param id 优惠劵编号 + * @param id 优惠劵编号 * @param userId 用户编号 * @return 优惠劵信息 */ @@ -31,9 +36,8 @@ public interface CouponService { /** * 校验优惠劵,包括状态、有限期 * - * @see #validCoupon(Long, Long) 逻辑相同,只是入参不同 - * * @param coupon 优惠劵 + * @see #validCoupon(Long, Long) 逻辑相同,只是入参不同 */ void validCoupon(CouponDO coupon); @@ -124,4 +128,23 @@ public interface CouponService { takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); } + /** + * 统计会员领取优惠券的数量 + * + * @param templateIds 优惠券模板编号列表 + * @param userId 用户编号 + * @return 领取优惠券的数量 + */ + default Map getTakeCountMapByTemplateIds(Collection templateIds, Long userId) { + return convertMap(getTakeCountListByTemplateIds(templateIds, userId), CouponTakeCountBO::getTemplateId, CouponTakeCountBO::getCount); + } + + /** + * 统计会员领取优惠券的数量 + * + * @param templateIds 优惠券模板编号列表 + * @param userId 用户编号 + * @return 领取优惠券的数量 + */ + List getTakeCountListByTemplateIds(Collection templateIds, Long userId); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java index f4b56260c0..ab96fd14f6 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.coupon; import cn.hutool.core.collection.CollStreamUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -18,12 +19,14 @@ import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponMapper; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; +import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO; 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 java.util.Map; import java.util.Set; @@ -175,6 +178,14 @@ public class CouponServiceImpl implements CouponService { couponTemplateService.updateCouponTemplateTakeCount(templateId, userIds.size()); } + @Override + public List getTakeCountListByTemplateIds(Collection templateIds, Long userId) { + if (CollUtil.isEmpty(templateIds)) { + return ListUtil.empty(); + } + return couponMapper.selectCountByUserIdAndTemplateIdIn(userId, templateIds); + } + /** * 校验优惠券是否可以领取 * @@ -211,7 +222,7 @@ public class CouponServiceImpl implements CouponService { /** * 过滤掉达到领取上线的用户 * - * @param userIds 用户编号数组 + * @param userIds 用户编号数组 * @param couponTemplate 优惠劵模版 */ private void removeTakeLimitUser(Set userIds, CouponTemplateDO couponTemplate) { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java new file mode 100644 index 0000000000..18928067de --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.promotion.service.coupon.bo; + +import lombok.Data; + +/** + * 优惠券领取数量 BO + * + * @author owen + */ +@Data +public class CouponTakeCountBO { + /** + * 优惠劵模板编号 + */ + private Long templateId; + /** + * 领取数量 + */ + private Integer count; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java index 95c160515f..b4b606b5a0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.github.yulichang.toolkit.LambdaUtils; import com.github.yulichang.toolkit.MPJWrappers; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -62,7 +61,7 @@ public interface BrokerageRecordMapper extends BaseMapperX { Integer status) { List> list = selectMaps(MPJWrappers.lambdaJoin(BrokerageRecordDO.class) .select(BrokerageRecordDO::getUserId) - .selectCount(BrokerageRecordDO::getId, LambdaUtils.getName(UserBrokerageSummaryBO::getCount)) + .selectCount(BrokerageRecordDO::getId, UserBrokerageSummaryBO::getCount) .selectSum(BrokerageRecordDO::getPrice) .in(BrokerageRecordDO::getUserId, userIds) .eq(BrokerageRecordDO::getBizId, bizType) @@ -71,7 +70,7 @@ public interface BrokerageRecordMapper extends BaseMapperX { return BeanUtil.copyToList(list, UserBrokerageSummaryBO.class); // return selectJoinList(UserBrokerageSummaryBO.class, MPJWrappers.lambdaJoin(BrokerageRecordDO.class) // .select(BrokerageRecordDO::getUserId) -// .selectCount(BrokerageRecordDO::getId, LambdaUtils.getName(UserBrokerageSummaryBO::getCount)) +// .selectCount(BrokerageRecordDO::getId, UserBrokerageSummaryBO::getCount) // .selectSum(BrokerageRecordDO::getPrice) // .in(BrokerageRecordDO::getUserId, userIds) // .eq(BrokerageRecordDO::getBizId, bizType) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java index 5a950a4cbd..4bbf427e97 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java @@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.Brok import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserWithdrawSummaryBO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.github.yulichang.toolkit.LambdaUtils; import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.ibatis.annotations.Mapper; @@ -45,7 +44,7 @@ public interface BrokerageWithdrawMapper extends BaseMapperX selectCountAndSumPriceByUserIdAndStatus(Collection userIds, Integer status) { List> list = selectMaps(new MPJLambdaWrapper() .select(BrokerageWithdrawDO::getUserId) - .selectCount(BrokerageWithdrawDO::getId, LambdaUtils.getName(UserWithdrawSummaryBO::getCount)) + .selectCount(BrokerageWithdrawDO::getId, UserWithdrawSummaryBO::getCount) .selectSum(BrokerageWithdrawDO::getPrice) .in(BrokerageWithdrawDO::getUserId, userIds) .eq(BrokerageWithdrawDO::getStatus, status) @@ -54,7 +53,7 @@ public interface BrokerageWithdrawMapper extends BaseMapperX() // .select(BrokerageWithdrawDO::getUserId) -// .selectCount(BrokerageWithdrawDO::getId, LambdaUtils.getName(UserWithdrawSummaryBO::getCount)) +// .selectCount(BrokerageWithdrawDO::getId, UserWithdrawSummaryBO::getCount) // .selectSum(BrokerageWithdrawDO::getPrice) // .in(BrokerageWithdrawDO::getUserId, userIds) // .eq(BrokerageWithdrawDO::getStatus, status)