Commit fc432ba073485be7a292557dd8fe1bd492bfae90
1 parent
497ea2ee
优惠券:新人券使用 MQ 发放
Showing
10 changed files
with
132 additions
and
6 deletions
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java
| @@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; | @@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; | ||
| 12 | import org.apache.ibatis.annotations.Param; | 12 | import org.apache.ibatis.annotations.Param; |
| 13 | 13 | ||
| 14 | import java.time.LocalDateTime; | 14 | import java.time.LocalDateTime; |
| 15 | +import java.util.List; | ||
| 15 | import java.util.function.Consumer; | 16 | import java.util.function.Consumer; |
| 16 | 17 | ||
| 17 | /** | 18 | /** |
| @@ -48,4 +49,7 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { | @@ -48,4 +49,7 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { | ||
| 48 | 49 | ||
| 49 | void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount); | 50 | void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount); |
| 50 | 51 | ||
| 52 | + default List<CouponTemplateDO> selectListByTakeType(Integer takeType) { | ||
| 53 | + return selectList(CouponTemplateDO::getTakeType, takeType); | ||
| 54 | + } | ||
| 51 | } | 55 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.mq.consumer.coupon; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; | ||
| 4 | +import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage; | ||
| 5 | +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; | ||
| 6 | +import lombok.extern.slf4j.Slf4j; | ||
| 7 | +import org.springframework.stereotype.Component; | ||
| 8 | + | ||
| 9 | +import javax.annotation.Resource; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 针对 {@link RegisterCouponSendMessage} 的消费者 | ||
| 13 | + * | ||
| 14 | + * @author owen | ||
| 15 | + */ | ||
| 16 | +@Component | ||
| 17 | +@Slf4j | ||
| 18 | +public class RegisterCouponSendConsumer extends AbstractStreamMessageListener<RegisterCouponSendMessage> { | ||
| 19 | + | ||
| 20 | + @Resource | ||
| 21 | + private CouponService couponService; | ||
| 22 | + | ||
| 23 | + @Override | ||
| 24 | + public void onMessage(RegisterCouponSendMessage message) { | ||
| 25 | + log.info("[onMessage][消息内容({})]", message); | ||
| 26 | + couponService.takeCouponByRegister(message.getUserId()); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java
| @@ -119,12 +119,9 @@ public interface CouponService { | @@ -119,12 +119,9 @@ public interface CouponService { | ||
| 119 | /** | 119 | /** |
| 120 | * 【系统】给用户发送新人券 | 120 | * 【系统】给用户发送新人券 |
| 121 | * | 121 | * |
| 122 | - * @param templateId 优惠券模板编号 | ||
| 123 | - * @param userId 用户编号列表 | 122 | + * @param userId 用户编号 |
| 124 | */ | 123 | */ |
| 125 | - default void takeCouponByRegister(Long templateId, Long userId) { | ||
| 126 | - takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); | ||
| 127 | - } | 124 | + void takeCouponByRegister(Long userId); |
| 128 | 125 | ||
| 129 | /** | 126 | /** |
| 130 | * 获取会员领取指定优惠券的数量 | 127 | * 获取会员领取指定优惠券的数量 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
| @@ -40,7 +40,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | @@ -40,7 +40,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | ||
| 40 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; | 40 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; |
| 41 | import static java.util.Arrays.asList; | 41 | import static java.util.Arrays.asList; |
| 42 | 42 | ||
| 43 | -// TODO @疯狂:注册时,赠送用户优惠劵;为了解耦,可以考虑注册时发个 MQ 消息;然后营销这里监听后消费; | ||
| 44 | /** | 43 | /** |
| 45 | * 优惠劵 Service 实现类 | 44 | * 优惠劵 Service 实现类 |
| 46 | * | 45 | * |
| @@ -184,6 +183,14 @@ public class CouponServiceImpl implements CouponService { | @@ -184,6 +183,14 @@ public class CouponServiceImpl implements CouponService { | ||
| 184 | } | 183 | } |
| 185 | 184 | ||
| 186 | @Override | 185 | @Override |
| 186 | + public void takeCouponByRegister(Long userId) { | ||
| 187 | + List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateByTakeType(CouponTakeTypeEnum.REGISTER); | ||
| 188 | + for (CouponTemplateDO template : templates) { | ||
| 189 | + takeCoupon(template.getId(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + @Override | ||
| 187 | public List<CouponTakeCountBO> getTakeCountListByTemplateIds(Collection<Long> templateIds, Long userId) { | 194 | public List<CouponTakeCountBO> getTakeCountListByTemplateIds(Collection<Long> templateIds, Long userId) { |
| 188 | if (CollUtil.isEmpty(templateIds)) { | 195 | if (CollUtil.isEmpty(templateIds)) { |
| 189 | return ListUtil.empty(); | 196 | return ListUtil.empty(); |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java
| @@ -5,8 +5,10 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.Cou | @@ -5,8 +5,10 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.Cou | ||
| 5 | import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; | 5 | import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; |
| 6 | import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; | 6 | import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; |
| 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; | 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 8 | +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; | ||
| 8 | 9 | ||
| 9 | import javax.validation.Valid; | 10 | import javax.validation.Valid; |
| 11 | +import java.util.List; | ||
| 10 | 12 | ||
| 11 | /** | 13 | /** |
| 12 | * 优惠劵模板 Service 接口 | 14 | * 优惠劵模板 Service 接口 |
| @@ -69,4 +71,11 @@ public interface CouponTemplateService { | @@ -69,4 +71,11 @@ public interface CouponTemplateService { | ||
| 69 | */ | 71 | */ |
| 70 | void updateCouponTemplateTakeCount(Long id, int incrCount); | 72 | void updateCouponTemplateTakeCount(Long id, int incrCount); |
| 71 | 73 | ||
| 74 | + /** | ||
| 75 | + * 获得指定领取方式的优惠券模板 | ||
| 76 | + * | ||
| 77 | + * @param takeType 领取方式 | ||
| 78 | + * @return 优惠券模板列表 | ||
| 79 | + */ | ||
| 80 | + List<CouponTemplateDO> getCouponTemplateByTakeType(CouponTakeTypeEnum takeType); | ||
| 72 | } | 81 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java
| @@ -8,11 +8,14 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.Cou | @@ -8,11 +8,14 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.Cou | ||
| 8 | import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; | 8 | import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; |
| 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; | 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 10 | import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; | 10 | import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; |
| 11 | +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; | ||
| 11 | import org.springframework.stereotype.Service; | 12 | import org.springframework.stereotype.Service; |
| 12 | import org.springframework.validation.annotation.Validated; | 13 | import org.springframework.validation.annotation.Validated; |
| 13 | 14 | ||
| 14 | import javax.annotation.Resource; | 15 | import javax.annotation.Resource; |
| 15 | 16 | ||
| 17 | +import java.util.List; | ||
| 18 | + | ||
| 16 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 17 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; | 20 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; |
| 18 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL; | 21 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL; |
| @@ -93,4 +96,9 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { | @@ -93,4 +96,9 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { | ||
| 93 | couponTemplateMapper.updateTakeCount(id, incrCount); | 96 | couponTemplateMapper.updateTakeCount(id, incrCount); |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 99 | + @Override | ||
| 100 | + public List<CouponTemplateDO> getCouponTemplateByTakeType(CouponTakeTypeEnum takeType) { | ||
| 101 | + return couponTemplateMapper.selectListByTakeType(takeType.getValue()); | ||
| 102 | + } | ||
| 103 | + | ||
| 96 | } | 104 | } |
yudao-module-member/yudao-module-member-api/pom.xml
| @@ -22,6 +22,11 @@ | @@ -22,6 +22,11 @@ | ||
| 22 | <artifactId>yudao-common</artifactId> | 22 | <artifactId>yudao-common</artifactId> |
| 23 | </dependency> | 23 | </dependency> |
| 24 | 24 | ||
| 25 | + <dependency> | ||
| 26 | + <groupId>cn.iocoder.boot</groupId> | ||
| 27 | + <artifactId>yudao-spring-boot-starter-mq</artifactId> | ||
| 28 | + <scope>compile</scope> | ||
| 29 | + </dependency> | ||
| 25 | <!-- 参数校验 --> | 30 | <!-- 参数校验 --> |
| 26 | <dependency> | 31 | <dependency> |
| 27 | <groupId>org.springframework.boot</groupId> | 32 | <groupId>org.springframework.boot</groupId> |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.mq.message.user; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import lombok.EqualsAndHashCode; | ||
| 6 | + | ||
| 7 | +import javax.validation.constraints.NotNull; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 新人券发放消息 | ||
| 11 | + * | ||
| 12 | + * @author owen | ||
| 13 | + */ | ||
| 14 | +@Data | ||
| 15 | +@EqualsAndHashCode(callSuper = true) | ||
| 16 | +public class RegisterCouponSendMessage extends AbstractStreamMessage { | ||
| 17 | + | ||
| 18 | + /** | ||
| 19 | + * 用户编号 | ||
| 20 | + */ | ||
| 21 | + @NotNull(message = "用户编号不能为空") | ||
| 22 | + private Long userId; | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public String getStreamKey() { | ||
| 26 | + return "member.register-coupon.send"; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.mq.producer.user; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 4 | +import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage; | ||
| 5 | +import lombok.extern.slf4j.Slf4j; | ||
| 6 | +import org.springframework.stereotype.Component; | ||
| 7 | + | ||
| 8 | +import javax.annotation.Resource; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 新人券发放 Producer | ||
| 12 | + * | ||
| 13 | + * @author owen | ||
| 14 | + */ | ||
| 15 | +@Slf4j | ||
| 16 | +@Component | ||
| 17 | +public class RegisterCouponProducer { | ||
| 18 | + | ||
| 19 | + @Resource | ||
| 20 | + private RedisMQTemplate redisMQTemplate; | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 发送 {@link RegisterCouponSendMessage} 消息 | ||
| 24 | + * | ||
| 25 | + * @param userId 用户编号 | ||
| 26 | + */ | ||
| 27 | + public void sendMailSendMessage(Long userId) { | ||
| 28 | + redisMQTemplate.send(new RegisterCouponSendMessage().setUserId(userId)); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | +} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
| @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; | @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; | ||
| 18 | import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; | 18 | import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; |
| 19 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | 19 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; |
| 20 | import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; | 20 | import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; |
| 21 | +import cn.iocoder.yudao.module.member.mq.producer.user.RegisterCouponProducer; | ||
| 21 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 22 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 22 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; | 23 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; |
| 23 | import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; | 24 | import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; |
| @@ -58,6 +59,9 @@ public class MemberUserServiceImpl implements MemberUserService { | @@ -58,6 +59,9 @@ public class MemberUserServiceImpl implements MemberUserService { | ||
| 58 | @Resource | 59 | @Resource |
| 59 | private PasswordEncoder passwordEncoder; | 60 | private PasswordEncoder passwordEncoder; |
| 60 | 61 | ||
| 62 | + @Resource | ||
| 63 | + private RegisterCouponProducer registerCouponProducer; | ||
| 64 | + | ||
| 61 | @Override | 65 | @Override |
| 62 | public MemberUserDO getUserByMobile(String mobile) { | 66 | public MemberUserDO getUserByMobile(String mobile) { |
| 63 | return memberUserMapper.selectByMobile(mobile); | 67 | return memberUserMapper.selectByMobile(mobile); |
| @@ -89,6 +93,9 @@ public class MemberUserServiceImpl implements MemberUserService { | @@ -89,6 +93,9 @@ public class MemberUserServiceImpl implements MemberUserService { | ||
| 89 | user.setPassword(encodePassword(password)); // 加密密码 | 93 | user.setPassword(encodePassword(password)); // 加密密码 |
| 90 | user.setRegisterIp(registerIp); | 94 | user.setRegisterIp(registerIp); |
| 91 | memberUserMapper.insert(user); | 95 | memberUserMapper.insert(user); |
| 96 | + | ||
| 97 | + // 发送 MQ 消息,发放新人券 | ||
| 98 | + registerCouponProducer.sendMailSendMessage(user.getId()); | ||
| 92 | return user; | 99 | return user; |
| 93 | } | 100 | } |
| 94 | 101 |