Merge branch 'feature/mall_product' of https://gitee.com/CrazyWorld/ruoyi-vue-pro into feature/mall_product

# Conflicts:
#	yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
This commit is contained in:
YunaiV
2023-10-01 22:00:31 +08:00
89 changed files with 1651 additions and 570 deletions

View File

@@ -1,6 +1,5 @@
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.framework.common.util.object.ObjectUtils;
@@ -25,11 +24,9 @@ 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.*;
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 - 优惠劵模板")
@@ -46,7 +43,6 @@ public class AppCouponTemplateController {
@Resource
private ProductSpuApi productSpuApi;
// TODO 疯狂:这里应该还有个 list 接口哈;获得优惠劵模版列表,用于首页、商品页的优惠劵
@GetMapping("/list")
@Operation(summary = "获得优惠劵模版列表")
@Parameters({
@@ -56,46 +52,28 @@ public class AppCouponTemplateController {
})
public CommonResult<List<AppCouponTemplateRespVO>> getCouponTemplateList(
@RequestParam(value = "spuId", required = false) Long spuId,
@RequestParam(value = "useType", required = false) Integer useType,
@RequestParam(value = "productScope", required = false) Integer productScope,
@RequestParam(value = "count", required = false, defaultValue = "10") Integer count) {
List<AppCouponTemplateRespVO> 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);
}
// TODO @疯狂:是否已领取,要不在 TemplateService 搞个 static 方法,让它基于 countMap 这种去计算,这样好点?
vo.setTakeStatus(random.nextBoolean());
list.add(vo);
}
return success(list);
// 1.1 处理查询条件:商品范围编号
Long productScopeValue = getProductScopeValue(productScope, spuId);
// 1.2 处理查询条件:领取方式 = 直接领取
List<Integer> canTakeTypes = Collections.singletonList(CouponTakeTypeEnum.USER.getValue());
// 2. 查询
List<CouponTemplateDO> list = couponTemplateService.getCouponTemplateList(canTakeTypes, productScope,
productScopeValue, count);
// 3.1 领取数量
Map<Long, Boolean> canCanTakeMap = couponService.getUserCanCanTakeMap(getLoginUserId(), list);
// 3.2 拼接返回
return success(CouponTemplateConvert.INSTANCE.convertAppList(list, canCanTakeMap));
}
@GetMapping("/page")
@Operation(summary = "获得优惠劵模版分页")
public CommonResult<PageResult<AppCouponTemplateRespVO>> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) {
// 1.1 处理查询条件:商品范围编号
Long productScopeValue = getProductScopeValue(pageReqVO);
Long productScopeValue = getProductScopeValue(pageReqVO.getProductScope(), pageReqVO.getSpuId());
// 1.2 处理查询条件:领取方式 = 直接领取
List<Integer> canTakeTypes = Collections.singletonList(CouponTakeTypeEnum.USER.getValue());
@@ -104,35 +82,30 @@ public class AppCouponTemplateController {
CouponTemplateConvert.INSTANCE.convert(pageReqVO, canTakeTypes, pageReqVO.getProductScope(), productScopeValue));
// 3.1 领取数量
Map<Long, Integer> couponTakeCountMap = new HashMap<>(0);
Long userId = getLoginUserId();
if (userId != null) {
List<Long> templateIds = convertList(pageResult.getList(), CouponTemplateDO::getId,
t -> ObjUtil.notEqual(t.getTakeLimitCount(), -1)); // 只查有设置“每人限领个数”的
couponTakeCountMap = couponService.getTakeCountMapByTemplateIds(templateIds, userId);
}
Map<Long, Boolean> canCanTakeMap = couponService.getUserCanCanTakeMap(getLoginUserId(), pageResult.getList());
// 3.2 拼接返回
return success(CouponTemplateConvert.INSTANCE.convertAppPage(pageResult, couponTakeCountMap));
return success(CouponTemplateConvert.INSTANCE.convertAppPage(pageResult, canCanTakeMap));
}
/**
* 获得分页查询的商品范围
* 获得商品的使用范围编号
*
* @param pageReqVO 分页查询
* @return 商品范围
* @param productScope 商品范围
* @param spuId 商品 SPU 编号
* @return 商品范围编号
*/
private Long getProductScopeValue(AppCouponTemplatePageReqVO pageReqVO) {
// 通用券:清除商品范围
if (pageReqVO.getProductScope() == null || ObjectUtils.equalsAny(pageReqVO.getProductScope(), PromotionProductScopeEnum.ALL.getScope(), null)) {
private Long getProductScopeValue(Integer productScope, Long spuId) {
// 通用券:没有商品范围
if (productScope == null || ObjectUtils.equalsAny(productScope, PromotionProductScopeEnum.ALL.getScope(), null)) {
return null;
}
// 品类券:查询商品的品类
if (Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.CATEGORY.getScope()) && pageReqVO.getSpuId() != null) {
return Optional.ofNullable(productSpuApi.getSpu(pageReqVO.getSpuId()))
// 品类券:查询商品的品类编号
if (Objects.equals(productScope, PromotionProductScopeEnum.CATEGORY.getScope()) && spuId != null) {
return Optional.ofNullable(productSpuApi.getSpu(spuId))
.map(ProductSpuRespDTO::getCategoryId).orElse(null);
}
// 商品卷:直接返回
return pageReqVO.getSpuId();
return spuId;
}
}

View File

@@ -55,7 +55,7 @@ public class AppCouponTemplateRespVO {
// ========== 用户相关字段 ==========
@Schema(description = "是否领取", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
private Boolean takeStatus;
@Schema(description = "是否可以领取", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
private Boolean canTake;
}

View File

@@ -37,21 +37,25 @@ public interface CouponTemplateConvert {
PageResult<AppCouponTemplateRespVO> convertAppPage(PageResult<CouponTemplateDO> pageResult);
default PageResult<AppCouponTemplateRespVO> convertAppPage(PageResult<CouponTemplateDO> pageResult, Map<Long, Integer> couponTakeCountMap) {
List<AppCouponTemplateRespVO> convertAppList(List<CouponTemplateDO> list);
default PageResult<AppCouponTemplateRespVO> convertAppPage(PageResult<CouponTemplateDO> pageResult, Map<Long, Boolean> userCanTakeMap) {
PageResult<AppCouponTemplateRespVO> result = convertAppPage(pageResult);
if (MapUtil.isEmpty(couponTakeCountMap)) {
return result;
}
for (AppCouponTemplateRespVO template : result.getList()) {
// 每人领取数量无限制
if (template.getTakeLimitCount() == -1) {
template.setTakeStatus(false);
continue;
}
// 检查已领取数量是否超过限领数量
template.setTakeStatus(MapUtil.getInt(couponTakeCountMap, template.getId(), 0) >= template.getTakeLimitCount());
}
copyTo(result.getList(), userCanTakeMap);
return result;
}
default List<AppCouponTemplateRespVO> convertAppList(List<CouponTemplateDO> list, Map<Long, Boolean> userCanTakeMap) {
List<AppCouponTemplateRespVO> result = convertAppList(list);
copyTo(result, userCanTakeMap);
return result;
}
default void copyTo(List<AppCouponTemplateRespVO> list, Map<Long, Boolean> userCanTakeMap) {
for (AppCouponTemplateRespVO template : list) {
// 检查已领取数量是否超过限领数量
template.setCanTake(MapUtil.getBool(userCanTakeMap, template.getId(), false));
}
}
}

View File

@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.coupon;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
@@ -8,7 +8,6 @@ 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.enums.common.PromotionProductScopeEnum;
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;
@@ -16,9 +15,12 @@ import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 优惠劵 Mapper
*
@@ -70,14 +72,16 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
);
}
// TODO @疯狂:这个是不是搞个 Map 就可以呀?
default List<CouponTakeCountBO> selectCountByUserIdAndTemplateIdIn(Long userId, Collection<Long> templateIds) {
return BeanUtil.copyToList(selectMaps(MPJWrappers.lambdaJoin(CouponDO.class)
.select(CouponDO::getTemplateId)
.selectCount(CouponDO::getId, CouponTakeCountBO::getCount)
default Map<Long, Integer> selectCountByUserIdAndTemplateIdIn(Long userId, Collection<Long> templateIds) {
String templateIdAlias = "templateId";
String countAlias = "count";
List<Map<String, Object>> list = selectMaps(MPJWrappers.lambdaJoin(CouponDO.class)
.selectAs(CouponDO::getTemplateId, templateIdAlias)
.selectCount(CouponDO::getId, countAlias)
.eq(CouponDO::getUserId, userId)
.in(CouponDO::getTemplateId, templateIds)
.groupBy(CouponDO::getTemplateId)), CouponTakeCountBO.class);
.groupBy(CouponDO::getTemplateId));
return convertMap(list, map -> MapUtil.getLong(map, templateIdAlias), map -> MapUtil.getInt(map, countAlias));
}
default List<CouponDO> selectListByUserIdAndStatusAndUsePriceLeAndProductScope(

View File

@@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
import java.util.function.Consumer;
/**
@@ -23,16 +24,8 @@ import java.util.function.Consumer;
public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> {
default PageResult<CouponTemplateDO> selectPage(CouponTemplatePageReqVO reqVO) {
// 构建可领取的查询条件, 好啰嗦 ( ╯-_-)╯┴—┴
Consumer<LambdaQueryWrapper<CouponTemplateDO>> canTakeConsumer = null;
if (CollUtil.isNotEmpty(reqVO.getCanTakeTypes())) {
canTakeConsumer = w ->
w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的
.in(CouponTemplateDO::getTakeType, reqVO.getCanTakeTypes()) // 2. 领取方式一致
.and(ww -> ww.isNull(CouponTemplateDO::getValidEndTime) // 3. 未过期
.or().gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now()))
.apply(" take_count < total_count "); // 4. 剩余数量大于 0
}
// 构建可领取的查询条件
Consumer<LambdaQueryWrapper<CouponTemplateDO>> canTakeConsumer = buildCanTakeQueryConsumer(reqVO.getCanTakeTypes());
// 执行分页查询
return selectPage(reqVO, new LambdaQueryWrapperX<CouponTemplateDO>()
.likeIfPresent(CouponTemplateDO::getName, reqVO.getName())
@@ -48,4 +41,33 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> {
void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount);
default List<CouponTemplateDO> selectListByTakeType(Integer takeType) {
return selectList(CouponTemplateDO::getTakeType, takeType);
}
default List<CouponTemplateDO> selectList(List<Integer> canTakeTypes, Integer productScope, Long productScopeValue, Integer count) {
// 构建可领取的查询条件
Consumer<LambdaQueryWrapper<CouponTemplateDO>> canTakeConsumer = buildCanTakeQueryConsumer(canTakeTypes);
return selectList(new LambdaQueryWrapperX<CouponTemplateDO>()
.eqIfPresent(CouponTemplateDO::getProductScope, productScope)
.and(productScopeValue != null, w -> w.apply("FIND_IN_SET({0}, product_scope_values)",
productScopeValue))
.and(canTakeConsumer != null, canTakeConsumer)
.last(" LIMIT " + count)
.orderByDesc(CouponTemplateDO::getId));
}
static Consumer<LambdaQueryWrapper<CouponTemplateDO>> buildCanTakeQueryConsumer(List<Integer> canTakeTypes) {
Consumer<LambdaQueryWrapper<CouponTemplateDO>> canTakeConsumer = null;
if (CollUtil.isNotEmpty(canTakeTypes)) {
canTakeConsumer = w ->
w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的
.in(CouponTemplateDO::getTakeType, canTakeTypes) // 2. 领取方式一致
.and(ww -> ww.isNull(CouponTemplateDO::getValidEndTime) // 3. 未过期
.or().gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now()))
.apply(" take_count < total_count "); // 4. 剩余数量大于 0
}
return canTakeConsumer;
}
}

View File

@@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.promotion.mq.consumer.coupon;
import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage;
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 针对 {@link RegisterCouponSendMessage} 的消费者
*
* @author owen
*/
@Component
@Slf4j
public class RegisterCouponSendConsumer extends AbstractStreamMessageListener<RegisterCouponSendMessage> {
@Resource
private CouponService couponService;
@Override
public void onMessage(RegisterCouponSendMessage message) {
log.info("[onMessage][消息内容({})]", message);
couponService.takeCouponByRegister(message.getUserId());
}
}

View File

@@ -1,17 +1,16 @@
package cn.iocoder.yudao.module.promotion.service.coupon;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
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.controller.app.coupon.vo.coupon.AppCouponMatchReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO;
import java.util.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 优惠劵 Service 接口
*
@@ -119,12 +118,9 @@ public interface CouponService {
/**
* 【系统】给用户发送新人券
*
* @param templateId 优惠券模板编号
* @param userId 用户编号列表
* @param userId 用户编号
*/
default void takeCouponByRegister(Long templateId, Long userId) {
takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER);
}
void takeCouponByRegister(Long userId);
/**
* 获取会员领取指定优惠券的数量
@@ -134,11 +130,8 @@ public interface CouponService {
* @return 领取优惠券的数量
*/
default Integer getTakeCount(Long templateId, Long userId) {
return CollUtil.emptyIfNull(getTakeCountListByTemplateIds(Collections.singleton(templateId), userId))
.stream()
.findFirst()
.map(CouponTakeCountBO::getCount)
.orElse(0);
Map<Long, Integer> map = getTakeCountMapByTemplateIds(Collections.singleton(templateId), userId);
return MapUtil.getInt(map, templateId, 0);
}
/**
@@ -148,19 +141,7 @@ public interface CouponService {
* @param userId 用户编号
* @return 领取优惠券的数量
*/
default Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId) {
return convertMap(getTakeCountListByTemplateIds(templateIds, userId),
CouponTakeCountBO::getTemplateId, CouponTakeCountBO::getCount);
}
/**
* 统计会员领取优惠券的数量
*
* @param templateIds 优惠券模板编号列表
* @param userId 用户编号
* @return 领取优惠券的数量
*/
List<CouponTakeCountBO> getTakeCountListByTemplateIds(Collection<Long> templateIds, Long userId);
Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId);
/**
* 获取用户匹配的优惠券列表
@@ -178,4 +159,13 @@ public interface CouponService {
*/
int expireCoupon();
/**
* 获取用户是否可以领取优惠券
*
* @param userId 用户编号
* @param templates 优惠券列表
* @return 是否可以领取
*/
Map<Long, Boolean> getUserCanCanTakeMap(Long userId, List<CouponTemplateDO> templates);
}

View File

@@ -2,7 +2,6 @@ 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;
@@ -21,7 +20,6 @@ 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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -29,18 +27,14 @@ 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;
import java.util.*;
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;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
import static java.util.Arrays.asList;
// TODO @疯狂:注册时,赠送用户优惠劵;为了解耦,可以考虑注册时发个 MQ 消息;然后营销这里监听后消费;
/**
* 优惠劵 Service 实现类
*
@@ -184,9 +178,17 @@ public class CouponServiceImpl implements CouponService {
}
@Override
public List<CouponTakeCountBO> getTakeCountListByTemplateIds(Collection<Long> templateIds, Long userId) {
public void takeCouponByRegister(Long userId) {
List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateByTakeType(CouponTakeTypeEnum.REGISTER);
for (CouponTemplateDO template : templates) {
takeCoupon(template.getId(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER);
}
}
@Override
public Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId) {
if (CollUtil.isEmpty(templateIds)) {
return ListUtil.empty();
return Collections.emptyMap();
}
return couponMapper.selectCountByUserIdAndTemplateIdIn(userId, templateIds);
}
@@ -222,6 +224,29 @@ public class CouponServiceImpl implements CouponService {
return count;
}
@Override
public Map<Long, Boolean> getUserCanCanTakeMap(Long userId, List<CouponTemplateDO> templates) {
Map<Long, Boolean> userCanTakeMap = convertMap(templates, CouponTemplateDO::getId, templateId -> true);
// 未登录时,都显示可以领取
if (userId == null) {
return userCanTakeMap;
}
// 过滤领取数量无限制的
Set<Long> templateIds = convertSet(templates, CouponTemplateDO::getId, template -> template.getTakeLimitCount() != -1);
// 检查用户领取的数量是否超过限制
if (CollUtil.isNotEmpty(templateIds)) {
Map<Long, Integer> couponTakeCountMap = this.getTakeCountMapByTemplateIds(templateIds, userId);
for (CouponTemplateDO template : templates) {
Integer takeCount = couponTakeCountMap.get(template.getId());
userCanTakeMap.put(template.getId(), takeCount == null || takeCount < template.getTakeLimitCount());
}
}
return userCanTakeMap;
}
/**
* 过期单个优惠劵
*

View File

@@ -5,8 +5,10 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.Cou
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
import javax.validation.Valid;
import java.util.List;
/**
* 优惠劵模板 Service 接口
@@ -69,4 +71,24 @@ public interface CouponTemplateService {
*/
void updateCouponTemplateTakeCount(Long id, int incrCount);
/**
* 获得指定领取方式的优惠券模板
*
* @param takeType 领取方式
* @return 优惠券模板列表
*/
List<CouponTemplateDO> getCouponTemplateByTakeType(CouponTakeTypeEnum takeType);
/**
* 获得优惠券模板列表
*
* @param canTakeTypes 可领取的类型列表
* @param productScope 商品使用范围类型
* @param productScopeValue 商品使用范围编号
* @param count 查询数量
* @return 优惠券模板列表
*/
List<CouponTemplateDO> getCouponTemplateList(List<Integer> canTakeTypes, Integer productScope,
Long productScopeValue, Integer count);
}

View File

@@ -2,16 +2,22 @@ package cn.iocoder.yudao.module.promotion.service.coupon;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.api.category.ProductCategoryApi;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO;
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.dal.mysql.coupon.CouponTemplateMapper;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS;
@@ -29,9 +35,15 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
@Resource
private CouponTemplateMapper couponTemplateMapper;
// TODO @疯狂:新增/修改时,需要校验对应的商品、分类是否存在
@Resource
private ProductCategoryApi productCategoryApi;
@Resource
private ProductSpuApi productSpuApi;
@Override
public Long createCouponTemplate(CouponTemplateCreateReqVO createReqVO) {
// 校验商品范围
validateProductScope(createReqVO.getProductScope(), createReqVO.getProductScopeValues());
// 插入
CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO)
.setStatus(CommonStatusEnum.ENABLE.getStatus());
@@ -48,6 +60,8 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
if (updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) {
throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount());
}
// 校验商品范围
validateProductScope(updateReqVO.getProductScope(), updateReqVO.getProductScopeValues());
// 更新
CouponTemplateDO updateObj = CouponTemplateConvert.INSTANCE.convert(updateReqVO);
@@ -78,6 +92,14 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
return couponTemplate;
}
private void validateProductScope(Integer productScope, List<Long> productScopeValues) {
if (Objects.equals(PromotionProductScopeEnum.SPU.getScope(), productScope)) {
productSpuApi.validateSpuList(productScopeValues);
} else if (Objects.equals(PromotionProductScopeEnum.CATEGORY.getScope(), productScope)) {
productCategoryApi.validateCategoryList(productScopeValues);
}
}
@Override
public CouponTemplateDO getCouponTemplate(Long id) {
return couponTemplateMapper.selectById(id);
@@ -93,4 +115,15 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
couponTemplateMapper.updateTakeCount(id, incrCount);
}
@Override
public List<CouponTemplateDO> getCouponTemplateByTakeType(CouponTakeTypeEnum takeType) {
return couponTemplateMapper.selectListByTakeType(takeType.getValue());
}
@Override
public List<CouponTemplateDO> getCouponTemplateList(List<Integer> canTakeTypes, Integer productScope,
Long productScopeValue, Integer count) {
return couponTemplateMapper.selectList(canTakeTypes, productScope, productScopeValue, count);
}
}

View File

@@ -1,22 +0,0 @@
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;
}