From 7fdd36d97978be36d0ea45dcb5e840b1cf76c865 Mon Sep 17 00:00:00 2001 From: owen Date: Mon, 2 Oct 2023 21:27:46 +0800 Subject: [PATCH 1/2] =?UTF-8?q?Review=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...dConsumer.java => UserCreateConsumer.java} | 8 ++--- .../mq/message/coupon/UserCreateMessage.java | 29 +++++++++++++++++ .../service/coupon/CouponServiceImpl.java | 2 +- .../yudao-module-member-api/pom.xml | 7 ---- .../member/enums/ErrorCodeConstants.java | 4 +-- .../vo/config/MemberSignInConfigBaseVO.java | 8 +++++ .../mq/message/user/UserCreateMessage.java} | 6 ++-- .../producer/user/RegisterCouponProducer.java | 32 ------------------- .../mq/producer/user/UserCreateProducer.java | 31 ++++++++++++++++++ .../signin/MemberSignInConfigServiceImpl.java | 15 ++------- .../service/user/MemberUserServiceImpl.java | 19 +++++++---- 11 files changed, 92 insertions(+), 69 deletions(-) rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/{RegisterCouponSendConsumer.java => UserCreateConsumer.java} (65%) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java rename yudao-module-member/{yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java => yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/UserCreateMessage.java} (76%) delete mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/UserCreateProducer.java 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; } From d0f0bc58888f16f0b02c9252283c2d00709192f5 Mon Sep 17 00:00:00 2001 From: owen Date: Mon, 2 Oct 2023 23:51:49 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=88=86=E9=94=80=EF=BC=9A=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A8=E5=B9=BF=E4=BA=BA=E5=88=97=E8=A1=A8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/collection/CollectionUtils.java | 7 + .../trade/enums/ErrorCodeConstants.java | 1 + .../mysql/brokerage/BrokerageUserMapper.java | 37 ++---- .../brokerage/BrokerageUserServiceImpl.java | 120 +++++++----------- .../mapper/brokerage/BrokerageUserMapper.xml | 21 +-- 5 files changed, 72 insertions(+), 114 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java index 15fa4e03b..12d18dc95 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java @@ -78,6 +78,13 @@ public class CollectionUtils { return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toSet()); } + public static Map convertMapByFilter(Collection from, Predicate filter, Function keyFunc) { + if (CollUtil.isEmpty(from)) { + return new HashMap<>(); + } + return from.stream().filter(filter).collect(Collectors.toMap(keyFunc, v -> v)); + } + public static Map convertMap(Collection from, Function keyFunc) { if (CollUtil.isEmpty(from)) { return new HashMap<>(); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index e6ed1b897..ef5ff7273 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -81,6 +81,7 @@ public interface ErrorCodeConstants { ErrorCode BROKERAGE_BIND_MODE_REGISTER = new ErrorCode(1_011_007_005, "只有在注册时可以绑定"); ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1_011_007_006, "已绑定了推广人"); ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1_011_007_007, "下级不能绑定自己的上级"); + ErrorCode BROKERAGE_USER_LEVEL_NOT_SUPPORT = new ErrorCode(1_011_007_008, "目前只支持 level 小于等于 2"); // ========== 分销提现 模块 1-011-008-000 ========== diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java index c17975677..0e41c6124 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.trade.dal.mysql.brokerage; +import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.SortingField; @@ -17,6 +18,8 @@ import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.time.LocalDateTime; +import java.util.Collection; +import java.util.Collections; import java.util.List; /** @@ -27,12 +30,12 @@ import java.util.List; @Mapper public interface BrokerageUserMapper extends BaseMapperX { - default PageResult selectPage(BrokerageUserPageReqVO reqVO, List bindUserIds) { + default PageResult selectPage(BrokerageUserPageReqVO reqVO, List ids) { return selectPage(reqVO, new LambdaQueryWrapperX() + .inIfPresent(BrokerageUserDO::getId, ids) .eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled()) .betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime()) .betweenIfPresent(BrokerageUserDO::getBindUserTime, reqVO.getBindUserTime()) - .inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds) .orderByDesc(BrokerageUserDO::getId)); } @@ -124,11 +127,6 @@ public interface BrokerageUserMapper extends BaseMapperX { .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null)); } - default Long selectCountByBindUserIdIn(List bindUserIds) { - return selectCount(new LambdaQueryWrapperX() - .inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds)); - } - @Select("SELECT bind_user_id AS id, COUNT(1) AS brokerageUserCount FROM trade_brokerage_user " + "WHERE bind_user_id IS NOT NULL AND deleted = FALSE " + "AND bind_user_time BETWEEN #{beginTime} AND #{endTime} " + @@ -143,32 +141,21 @@ public interface BrokerageUserMapper extends BaseMapperX { * * @param bizType 业务类型 * @param status 状态 - * @param bindUserIds 绑定用户编号列表 + * @param ids 用户编号列表 * @param sortingField 排序字段 * @return 下级分销统计分页列表 */ IPage selectSummaryPageByUserId(Page page, @Param("bizType") Integer bizType, @Param("status") Integer status, - @Param("bindUserIds") List bindUserIds, + @Param("ids") Collection ids, @Param("sortingField") SortingField sortingField); - /** - * 下级分销统计(不分页) - * - * @param bizType 业务类型 - * @param status 状态 - * @param bindUserIds 绑定用户编号列表 - * @param sortingField 排序字段 - * @return 下级分销统计列表 - */ - List selectSummaryListByUserId(@Param("bizType") Integer bizType, - @Param("status") Integer status, - @Param("bindUserIds") List bindUserIds, - @Param("sortingField") SortingField sortingField); - - default List selectListByBindUserId(Long bindUserId) { - return selectList(BrokerageUserDO::getBindUserId, bindUserId); + default List selectIdListByBindUserIdIn(Collection bindUserIds) { + return Convert.toList(Long.class, + selectObjs(new LambdaQueryWrapperX() + .select(Collections.singletonList(BrokerageUserDO::getId)) + .in(BrokerageUserDO::getBindUserId, bindUserIds))); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java index 71922615c..aa8a3a7cd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java @@ -31,10 +31,9 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; 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.convertMapByFilter; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** @@ -67,8 +66,12 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { @Override public PageResult getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) { - List bindUserIds = buildBindUserIdsByLevel(pageReqVO.getBindUserId(), pageReqVO.getLevel()); - return brokerageUserMapper.selectPage(pageReqVO, bindUserIds); + List childIds = getChildUserIdsByLevel(pageReqVO.getBindUserId(), pageReqVO.getLevel()); + // 有”绑定用户编号“查询条件时,没有查到下级会员,直接返回空 + if (pageReqVO.getBindUserId() != null && CollUtil.isEmpty(childIds)) { + return PageResult.empty(); + } + return brokerageUserMapper.selectPage(pageReqVO, childIds); } @Override @@ -154,11 +157,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { @Override public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) { - List bindUserIds = buildBindUserIdsByLevel(bindUserId, level); - if (CollUtil.isEmpty(bindUserIds)) { - return 0L; - } - return brokerageUserMapper.selectCountByBindUserIdIn(bindUserIds); + List childIds = getChildUserIdsByLevel(bindUserId, level); + return (long) CollUtil.size(childIds); } @Override @@ -226,70 +226,29 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { @Override public PageResult getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) { - // 生成推广员编号列表 - List bindUserIds = buildBindUserIdsByLevel(userId, pageReqVO.getLevel()); - - // TODO @疯狂:情况一和情况二,可以合并哈; - // 如果有 nickname 的时候,相当于提前查询 users,然后 nickname 过滤掉 bindUserIds; - // 之后,继续使用 selectSummaryPageByUserId 里面 in bindUserIds 查询; - - // 情况一:没有昵称过滤条件时,直接使用数据库的分页查询 - if (StrUtil.isBlank(pageReqVO.getNickname())) { - // 1.1 分页查询 - IPage pageResult = brokerageUserMapper.selectSummaryPageByUserId( - MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(), - BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), bindUserIds, pageReqVO.getSortingField() - ); - - // 1.2 拼接数据并返回 - List userIds = convertList(pageResult.getRecords(), AppBrokerageUserChildSummaryRespVO::getId); - Map userMap = memberUserApi.getUserMap(userIds); - BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap); - return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); - } - - // 情况二:有昵称过滤条件时,需要跨模块(Member)过滤 - // 2.1 查询所有匹配的分销用户 - List list = brokerageUserMapper.selectSummaryListByUserId( - BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), - bindUserIds, pageReqVO.getSortingField() - ); - if (CollUtil.isEmpty(list)) { + // 1.1 查询下级用户编号列表 + List childIds = getChildUserIdsByLevel(userId, pageReqVO.getLevel()); + if (CollUtil.isEmpty(childIds)) { return PageResult.empty(); } - // 2.2 查出对应的用户信息 - List users = memberUserApi.getUserList(convertList(list, AppBrokerageUserChildSummaryRespVO::getId)); - if (CollUtil.isEmpty(users)) { - return PageResult.empty(); - } - - // 2.3 根据昵称过滤出用户编号 - Map userMap = users.stream() - .filter(user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname())) - .collect(Collectors.toMap(MemberUserRespDTO::getId, dto -> dto)); + // 1.2 根据昵称过滤下级用户 + Map userMap = convertMapByFilter(memberUserApi.getUserList(childIds), + user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname()), + MemberUserRespDTO::getId); if (CollUtil.isEmpty(userMap)) { return PageResult.empty(); } - // 2.4 根据用户编号过滤结果 - list.removeIf(vo -> !userMap.containsKey(vo.getId())); - if (CollUtil.isEmpty(list)) { - return PageResult.empty(); - } + // 2 分页查询 + IPage pageResult = brokerageUserMapper.selectSummaryPageByUserId( + MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(), + BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), userMap.keySet(), pageReqVO.getSortingField() + ); - // 2.5 处理分页 - List result = list.stream() - .skip((long) (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize()) - .limit(pageReqVO.getPageSize()) - .collect(Collectors.toList()); - if (CollUtil.isEmpty(result)) { - return PageResult.empty(); - } - - // 2.6 拼接数据并返回 - BrokerageUserConvert.INSTANCE.copyTo(result, userMap); - return new PageResult<>(result, (long) list.size()); + // 3 拼接数据并返回 + BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap); + return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); } private boolean isUserCanBind(BrokerageUserDO user) { @@ -360,24 +319,35 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { } /** - * 根据绑定用户编号,获得绑定用户编号列表 + * 根据绑定用户编号,获得下级用户编号列表 * * @param bindUserId 绑定用户编号 - * @param level 绑定用户的层级。 + * @param level 下级用户的层级。 * 如果 level 为空,则查询 1+2 两个层级 - * @return 绑定用户编号列表 + * @return 下级用户编号列表 */ - private List buildBindUserIdsByLevel(Long bindUserId, Integer level) { + private List getChildUserIdsByLevel(Long bindUserId, Integer level) { if (bindUserId == null) { return Collections.emptyList(); } - Assert.isTrue(level == null || level <= 2, "目前只支持 level 小于等于 2"); - List bindUserIds = CollUtil.newArrayList(); - if (level == null || level == 1) { - bindUserIds.add(bindUserId); + + // 先查第 1 级 + List bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(Collections.singleton(bindUserId)); + if (CollUtil.isEmpty(bindUserIds)) { + return Collections.emptyList(); } - if (level == null || level == 2) { - bindUserIds.addAll(convertList(brokerageUserMapper.selectListByBindUserId(bindUserId), BrokerageUserDO::getId)); + + if (level == null) { + // level 为空,再查第 2 级,并合并结果 + bindUserIds.addAll(brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds)); + } else if (level == 2) { + // 只查第 2 级 + bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds); + } else if (level == 1) { + // 只查第 1 级 + return bindUserIds; + } else { + throw exception(BROKERAGE_USER_LEVEL_NOT_SUPPORT); } return bindUserIds; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml b/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml index 362cf7621..066f75d4e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml @@ -2,7 +2,9 @@ - + - - -