diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/UserCreateConsumer.java similarity index 65% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/UserCreateConsumer.java index 5ad9751ec..5876a4daf 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/UserCreateConsumer.java @@ -1,7 +1,7 @@ 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.mq.message.coupon.UserCreateMessage; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -9,19 +9,19 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; /** - * 针对 {@link RegisterCouponSendMessage} 的消费者 + * 针对 {@link UserCreateMessage} 的消费者 * * @author owen */ @Component @Slf4j -public class RegisterCouponSendConsumer extends AbstractStreamMessageListener { +public class UserCreateConsumer extends AbstractStreamMessageListener { @Resource private CouponService couponService; @Override - public void onMessage(RegisterCouponSendMessage message) { + public void onMessage(UserCreateMessage message) { log.info("[onMessage][消息内容({})]", message); couponService.takeCouponByRegister(message.getUserId()); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java new file mode 100644 index 000000000..da48e99c8 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.promotion.mq.message.coupon; + +import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotNull; + +/** + * 会员用户创建消息 + * + * @author owen + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class UserCreateMessage extends AbstractStreamMessage { + + /** + * 用户编号 + */ + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Override + public String getStreamKey() { + return "member.create.send"; + } + +} 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 8d65fab7e..bed4d25a3 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 @@ -178,7 +178,7 @@ public class CouponServiceImpl implements CouponService { } @Override - // TODO @疯狂:搞个事务; + @Transactional(rollbackFor = Exception.class) public void takeCouponByRegister(Long userId) { List templates = couponTemplateService.getCouponTemplateListByTakeType(CouponTakeTypeEnum.REGISTER); for (CouponTemplateDO template : templates) { diff --git a/yudao-module-member/yudao-module-member-api/pom.xml b/yudao-module-member/yudao-module-member-api/pom.xml index e79dde21c..1f60cd0fc 100644 --- a/yudao-module-member/yudao-module-member-api/pom.xml +++ b/yudao-module-member/yudao-module-member-api/pom.xml @@ -22,13 +22,6 @@ yudao-common - - - cn.iocoder.boot - yudao-spring-boot-starter-mq - compile - - org.springframework.boot diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java index 928f76dc8..e499f72f7 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java @@ -38,11 +38,9 @@ public interface ErrorCodeConstants { //========== 签到配置 1-004-009-000 ========== ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1_004_009_000, "签到天数规则不存在"); ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1_004_009_001, "签到天数规则已存在"); - // TODO @疯狂:这个可以用 validator 去做;通过在 BaseVO 里,增加一个 @AssertTrue 注解的方式 - ErrorCode SIGN_IN_CONFIG_AWARD_EMPTY = new ErrorCode(1_004_009_002, "签到奖励积分和经验不能同时为空"); //========== 签到配置 1-004-010-000 ========== - ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1_004_010_000,"今日已签到,请勿重复签到"); + ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1_004_010_000, "今日已签到,请勿重复签到"); //========== 用户等级 1-004-011-000 ========== ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1_004_011_000, "用户等级不存在"); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java index e83c487cf..2ddeeb9be 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java @@ -1,10 +1,13 @@ package cn.iocoder.yudao.module.member.controller.admin.signin.vo.config; +import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; +import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotNull; import javax.validation.constraints.PositiveOrZero; @@ -34,4 +37,9 @@ public class MemberSignInConfigBaseVO { @InEnum(CommonStatusEnum.class) private Integer status; + @AssertTrue(message = "签到奖励积分和经验不能同时为空") + @JsonIgnore + public boolean isConfigAward() { + return ObjUtil.notEqual(point, 0) || ObjUtil.notEqual(experience, 0); + } } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/UserCreateMessage.java similarity index 76% rename from yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/UserCreateMessage.java index 5d9641a9e..509527b09 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/UserCreateMessage.java @@ -7,13 +7,13 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; /** - * 新人券发放消息 + * 会员用户创建消息 * * @author owen */ @Data @EqualsAndHashCode(callSuper = true) -public class RegisterCouponSendMessage extends AbstractStreamMessage { +public class UserCreateMessage extends AbstractStreamMessage { /** * 用户编号 @@ -23,7 +23,7 @@ public class RegisterCouponSendMessage extends AbstractStreamMessage { @Override public String getStreamKey() { - return "member.register-coupon.send"; + return "member.create.send"; } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java deleted file mode 100644 index 25b495b73..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.member.mq.producer.user; - -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; -import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; - -// TODO @疯狂:发 UserCreateMessage;解耦,然后优惠劵监听到,去发卷; -/** - * 新人券发放 Producer - * - * @author owen - */ -@Slf4j -@Component -public class RegisterCouponProducer { - - @Resource - private RedisMQTemplate redisMQTemplate; - - /** - * 发送 {@link RegisterCouponSendMessage} 消息 - * - * @param userId 用户编号 - */ - public void sendMailSendMessage(Long userId) { - redisMQTemplate.send(new RegisterCouponSendMessage().setUserId(userId)); - } - -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/UserCreateProducer.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/UserCreateProducer.java new file mode 100644 index 000000000..6337b9f00 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/UserCreateProducer.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.member.mq.producer.user; + +import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; +import cn.iocoder.yudao.module.member.mq.message.user.UserCreateMessage; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 会员用户创建 Producer + * + * @author owen + */ +@Slf4j +@Component +public class UserCreateProducer { + + @Resource + private RedisMQTemplate redisMQTemplate; + + /** + * 发送 {@link UserCreateMessage} 消息 + * + * @param userId 用户编号 + */ + public void sendUserCreateMessage(Long userId) { + redisMQTemplate.send(new UserCreateMessage().setUserId(userId)); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java index 1687ed404..4e2b04c63 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java @@ -11,10 +11,10 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Comparator; 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.member.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_EXISTS; +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_NOT_EXISTS; /** * 签到规则 Service 实现类 @@ -30,8 +30,6 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @Override public Long createSignInConfig(MemberSignInConfigCreateReqVO createReqVO) { - // 校验奖励积分、奖励经验 - validatePointAndExperience(createReqVO.getPoint(), createReqVO.getExperience()); // 判断是否重复插入签到天数 validateSignInConfigDayDuplicate(createReqVO.getDay(), null); @@ -44,8 +42,6 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @Override public void updateSignInConfig(MemberSignInConfigUpdateReqVO updateReqVO) { - // 校验奖励积分、奖励经验 - validatePointAndExperience(updateReqVO.getPoint(), updateReqVO.getExperience()); // 校验存在 validateSignInConfigExists(updateReqVO.getId()); // 判断是否重复插入签到天数 @@ -88,13 +84,6 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService } } - private void validatePointAndExperience(Integer point, Integer experience) { - // 奖励积分、经验 至少要配置一个,否则没有意义 - if (Objects.equals(point, 0) && Objects.equals(experience, 0)) { - throw exception(SIGN_IN_CONFIG_AWARD_EMPTY); - } - } - @Override public MemberSignInConfigDO getSignInConfig(Long id) { return memberSignInConfigMapper.selectById(id); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java index 1c7d30abc..ee1bdf1b6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.service.user; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -18,7 +19,7 @@ import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; -import cn.iocoder.yudao.module.member.mq.producer.user.RegisterCouponProducer; +import cn.iocoder.yudao.module.member.mq.producer.user.UserCreateProducer; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; @@ -27,6 +28,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; import javax.validation.Valid; @@ -60,7 +62,10 @@ public class MemberUserServiceImpl implements MemberUserService { private PasswordEncoder passwordEncoder; @Resource - private RegisterCouponProducer registerCouponProducer; + private UserCreateProducer registerCouponProducer; + + @Resource + private TransactionTemplate transactionTemplate; @Override public MemberUserDO getUserByMobile(String mobile) { @@ -92,11 +97,13 @@ public class MemberUserServiceImpl implements MemberUserService { user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 user.setPassword(encodePassword(password)); // 加密密码 user.setRegisterIp(registerIp); - memberUserMapper.insert(user); - // 发送 MQ 消息,发放新人券 - // TODO @疯狂:事务结束后,在发送 MQ 消息;避免出现消息已经发了,事务没提交,或者回滚了 - registerCouponProducer.sendMailSendMessage(user.getId()); + Boolean success = transactionTemplate.execute(status -> memberUserMapper.insert(user) > 0); + if (BooleanUtil.isTrue(success)) { + // 发送 MQ 消息:用户创建 + registerCouponProducer.sendUserCreateMessage(user.getId()); + } + return user; }