package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 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.template.CouponTemplatePageReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; import java.time.LocalDateTime; import java.util.List; import java.util.function.Consumer; /** * 优惠劵模板 Mapper * * @author 芋道源码 */ @Mapper public interface CouponTemplateMapper extends BaseMapperX { default PageResult selectPage(CouponTemplatePageReqVO reqVO) { // 构建可领取的查询条件 Consumer> canTakeConsumer = buildCanTakeQueryConsumer(reqVO.getCanTakeTypes()); // 执行分页查询 return selectPage(reqVO, new LambdaQueryWrapperX() .likeIfPresent(CouponTemplateDO::getName, reqVO.getName()) .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)); } default int updateTakeCount(Long id, Integer incrCount) { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() .eq(CouponTemplateDO::getId, id) .setSql("take_count = take_count + " + incrCount); // 增加已领取的数量(incrCount 为正数),需要考虑发放数量 totalCount 的限制 if (incrCount > 0) { updateWrapper.and(i -> i.apply("take_count < total_count") .or().eq(CouponTemplateDO::getTotalCount, CouponTemplateDO.TOTAL_COUNT_MAX)); } return update(updateWrapper); } default List selectListByTakeType(Integer takeType) { return selectList(CouponTemplateDO::getTakeType, takeType, CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()); } default List selectList(List canTakeTypes, Integer productScope, Long productScopeValue, Integer count) { // 构建可领取的查询条件 Consumer> canTakeConsumer = buildCanTakeQueryConsumer(canTakeTypes); return selectList(new LambdaQueryWrapperX() .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> buildCanTakeQueryConsumer(List canTakeTypes) { Consumer> canTakeConsumer = null; if (CollUtil.isNotEmpty(canTakeTypes)) { canTakeConsumer = w -> w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的 .in(CouponTemplateDO::getTakeType, canTakeTypes) // 2. 领取方式一致 .and(ww -> ww.gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now()) // 3.1 未过期 .or().eq(CouponTemplateDO::getValidityType, CouponTemplateValidityTypeEnum.TERM.getType())) // 3.2 领取之后 .apply(" (take_count < total_count OR total_count = " + CouponTemplateDO.TOTAL_COUNT_MAX + ")"); // 4. 剩余数量大于 0,或者无限领取 } return canTakeConsumer; } }