mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-14 10:11:53 +08:00
code review:优惠劵逻辑
This commit is contained in:
@@ -44,4 +44,5 @@ public class CouponTemplatePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "商品范围编号", example = "1")
|
||||
private Long productScopeValue;
|
||||
|
||||
}
|
||||
|
@@ -41,13 +41,15 @@ public class AppCouponController {
|
||||
@Operation(summary = "领取优惠劵")
|
||||
@Parameter(name = "templateId", description = "优惠券模板编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> takeCoupon(@Valid @RequestBody AppCouponTakeReqVO reqVO) {
|
||||
Long userId = getLoginUserId();
|
||||
// 领取
|
||||
Long userId = getLoginUserId();
|
||||
couponService.takeCoupon(reqVO.getTemplateId(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.USER);
|
||||
|
||||
// 检查是否可以继续领取
|
||||
CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(reqVO.getTemplateId());
|
||||
boolean canTakeAgain = true;
|
||||
if (couponTemplate.getTakeLimitCount() != null && couponTemplate.getTakeLimitCount() > 0) {
|
||||
// TODO @疯狂:要不要搞个 getTakeCount 方法?
|
||||
Integer takeCount = MapUtil.getInt(couponService.getTakeCountMapByTemplateIds(
|
||||
Collections.singleton(reqVO.getTemplateId()), userId), reqVO.getTemplateId(), 0);
|
||||
canTakeAgain = takeCount < couponTemplate.getTakeLimitCount();
|
||||
@@ -58,7 +60,7 @@ public class AppCouponController {
|
||||
@GetMapping("/match-list")
|
||||
@Operation(summary = "获得匹配指定商品的优惠劵列表")
|
||||
public CommonResult<List<AppCouponMatchRespVO>> getMatchCouponList(AppCouponMatchReqVO matchReqVO) {
|
||||
// todo: 优惠金额倒序
|
||||
// todo: 优化:优惠金额倒序
|
||||
return success(CouponConvert.INSTANCE.convertList(couponService.getMatchCouponList(getLoginUserId(), matchReqVO)));
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@ 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;
|
||||
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;
|
||||
@@ -45,12 +46,14 @@ public class AppCouponTemplateController {
|
||||
@Operation(summary = "获得优惠劵模版分页")
|
||||
public CommonResult<PageResult<AppCouponTemplateRespVO>> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) {
|
||||
// 1.1 处理查询条件:商品范围编号
|
||||
Long productScopeValue = getaProductScopeValue(pageReqVO);
|
||||
// 1.2 处理查询条件:领取方式=直接领取
|
||||
Long productScopeValue = getProductScopeValue(pageReqVO);
|
||||
// 1.2 处理查询条件:领取方式 = 直接领取
|
||||
List<Integer> canTakeTypes = Collections.singletonList(CouponTakeTypeEnum.USER.getValue());
|
||||
|
||||
// 2. 分页查询
|
||||
PageResult<CouponTemplateDO> pageResult = couponTemplateService.getCouponTemplatePage(
|
||||
CouponTemplateConvert.INSTANCE.convert(pageReqVO, canTakeTypes, pageReqVO.getProductScope(), productScopeValue));
|
||||
|
||||
// 3.1 领取数量
|
||||
Map<Long, Integer> couponTakeCountMap = new HashMap<>(0);
|
||||
Long userId = getLoginUserId();
|
||||
@@ -63,17 +66,24 @@ public class AppCouponTemplateController {
|
||||
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()))
|
||||
/**
|
||||
* 获得分页查询的商品范围
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 商品范围
|
||||
*/
|
||||
private Long getProductScopeValue(AppCouponTemplatePageReqVO pageReqVO) {
|
||||
// 通用券:清除商品范围
|
||||
if (pageReqVO.getProductScope() == null || ObjectUtils.equalsAny(pageReqVO.getProductScope(), PromotionProductScopeEnum.ALL.getScope(), null)) {
|
||||
return null;
|
||||
}
|
||||
// 品类券:查询商品的品类
|
||||
if (Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.CATEGORY.getScope()) && pageReqVO.getSpuId() != null) {
|
||||
return Optional.ofNullable(productSpuApi.getSpu(pageReqVO.getSpuId()))
|
||||
.map(ProductSpuRespDTO::getCategoryId).orElse(null);
|
||||
}
|
||||
return productScopeValue;
|
||||
// 商品卷:直接返回
|
||||
return pageReqVO.getSpuId();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -20,4 +20,5 @@ public class AppCouponTemplatePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "商品标号", example = "1")
|
||||
private Long spuId;
|
||||
|
||||
}
|
||||
|
@@ -61,4 +61,5 @@ public interface CouponConvert {
|
||||
PageResult<AppCouponRespVO> convertAppPage(PageResult<CouponDO> pageResult);
|
||||
|
||||
List<AppCouponMatchRespVO> convertList(List<CouponDO> list);
|
||||
|
||||
}
|
||||
|
@@ -42,16 +42,16 @@ public interface CouponTemplateConvert {
|
||||
if (MapUtil.isEmpty(couponTakeCountMap)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (AppCouponTemplateRespVO vo : result.getList()) {
|
||||
for (AppCouponTemplateRespVO template : result.getList()) {
|
||||
// 每人领取数量无限制
|
||||
if (vo.getTakeLimitCount() == -1) {
|
||||
vo.setTakeStatus(false);
|
||||
if (template.getTakeLimitCount() == -1) {
|
||||
template.setTakeStatus(false);
|
||||
continue;
|
||||
}
|
||||
// 检查已领取数量是否超过限领数量
|
||||
vo.setTakeStatus(MapUtil.getInt(couponTakeCountMap, vo.getId(), 0) >= vo.getTakeLimitCount());
|
||||
template.setTakeStatus(MapUtil.getInt(couponTakeCountMap, template.getId(), 0) >= template.getTakeLimitCount());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -70,6 +70,7 @@ 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)
|
||||
@@ -81,18 +82,17 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
|
||||
|
||||
default List<CouponDO> selectListByUserIdAndStatusAndUsePriceLeAndProductScope(
|
||||
Long userId, Integer status, Integer usePrice, List<Long> spuIds, List<Long> categoryIds) {
|
||||
|
||||
Function<List<Long>, String> productScopeValuesFindInSetFunc = ids -> ids.stream()
|
||||
.map(id -> StrUtil.format("FIND_IN_SET({}, product_scope_values) ", id))
|
||||
.collect(Collectors.joining(" OR "));
|
||||
return selectList(new LambdaQueryWrapperX<CouponDO>()
|
||||
.eq(CouponDO::getUserId, userId)
|
||||
.eq(CouponDO::getStatus, status)
|
||||
.le(CouponDO::getUsePrice, usePrice)
|
||||
.and(w -> w.eq(CouponDO::getProductScope, PromotionProductScopeEnum.ALL.getScope())
|
||||
.or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.SPU.getScope())
|
||||
.le(CouponDO::getUsePrice, usePrice) // 价格小于等于,满足价格使用条件
|
||||
.and(w -> w.eq(CouponDO::getProductScope, PromotionProductScopeEnum.ALL.getScope()) // 商品范围一:全部
|
||||
.or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.SPU.getScope()) // 商品范围二:满足指定商品
|
||||
.apply(productScopeValuesFindInSetFunc.apply(spuIds)))
|
||||
.or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.CATEGORY.getScope())
|
||||
.or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.CATEGORY.getScope()) // 商品范围三:满足指定分类
|
||||
.apply(productScopeValuesFindInSetFunc.apply(categoryIds)))));
|
||||
}
|
||||
|
||||
@@ -102,4 +102,5 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
|
||||
.le(CouponDO::getValidEndTime, validEndTime)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -137,7 +137,8 @@ public interface CouponService {
|
||||
* @return 领取优惠券的数量
|
||||
*/
|
||||
default Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId) {
|
||||
return convertMap(getTakeCountListByTemplateIds(templateIds, userId), CouponTakeCountBO::getTemplateId, CouponTakeCountBO::getCount);
|
||||
return convertMap(getTakeCountListByTemplateIds(templateIds, userId),
|
||||
CouponTakeCountBO::getTemplateId, CouponTakeCountBO::getCount);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -222,13 +222,12 @@ public class CouponServiceImpl implements CouponService {
|
||||
|
||||
private boolean expireCoupon(CouponDO coupon) {
|
||||
// 更新记录状态
|
||||
CouponDO updateObj = new CouponDO().setStatus(CouponStatusEnum.EXPIRE.getStatus());
|
||||
int updateRows = couponMapper.updateByIdAndStatus(coupon.getId(), CouponStatusEnum.UNUSED.getStatus(), updateObj);
|
||||
int updateRows = couponMapper.updateByIdAndStatus(coupon.getId(), CouponStatusEnum.UNUSED.getStatus(),
|
||||
new CouponDO().setStatus(CouponStatusEnum.EXPIRE.getStatus()));
|
||||
if (updateRows == 0) {
|
||||
log.error("[expireCoupon][coupon({}) 更新为已过期失败]", coupon.getId());
|
||||
return false;
|
||||
}
|
||||
|
||||
log.info("[expireCoupon][coupon({}) 更新为已过期成功]", coupon.getId());
|
||||
return true;
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import lombok.Data;
|
||||
*/
|
||||
@Data
|
||||
public class CouponTakeCountBO {
|
||||
|
||||
/**
|
||||
* 优惠劵模板编号
|
||||
*/
|
||||
@@ -17,4 +18,5 @@ public class CouponTakeCountBO {
|
||||
* 领取数量
|
||||
*/
|
||||
private Integer count;
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user