From 0140571d040178c6a1c4c6f66f8df0dcb46ab5ac Mon Sep 17 00:00:00 2001 From: KKSU <15274802129@163.com> Date: Tue, 18 Feb 2025 11:01:09 +0800 Subject: [PATCH] feat(user): 重构用户注册逻辑并添加钱包功能 --- src/main/java/cc/mrbird/febs/user/req/ApiRegisterDto.java | 9 src/main/java/cc/mrbird/febs/user/contant/MemberConstant.java | 36 +++ src/main/java/cc/mrbird/febs/user/service/IChatWalletService.java | 13 + src/main/java/cc/mrbird/febs/user/service/Impl/ChatWalletServiceImpl.java | 69 +++++ src/main/resources/mapper/modules/ChatWalletMapper.xml | 12 + src/main/java/cc/mrbird/febs/user/service/Impl/ChatMemberServiceImpl.java | 142 +++-------- src/main/java/cc/mrbird/febs/user/service/Impl/AsyncServiceImpl.java | 60 +++++ src/main/java/cc/mrbird/febs/user/service/AsyncService.java | 23 + src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java | 280 +++++++++++++++++++++++ src/main/java/cc/mrbird/febs/user/mapper/ChatWalletMapper.java | 10 src/main/java/cc/mrbird/febs/user/entity/ChatMember.java | 2 src/main/java/cc/mrbird/febs/user/entity/ChatWallet.java | 23 + 12 files changed, 567 insertions(+), 112 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java b/src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java new file mode 100644 index 0000000..83a8b90 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java @@ -0,0 +1,280 @@ +package cc.mrbird.febs.common.utils; + +import cc.mrbird.febs.common.exception.FebsException; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * 实体验证工具类 + */ +public class ValidateEntityUtils { + + /** + * 确保指定列的有效性,并返回相应的实体对象 + * selectOne方法 + * 此方法用于验证数据库中某列的值是否存在,并返回包含该值的实体对象 + * 如果指定的值不存在或为null,将抛出异常 + * + * @param valueToCheck 需要验证的值 + * @param columnExtractor 列值提取器,用于指定需要验证的列 + * @param queryWrapperExtractor 查询包装器提取器,用于执行数据库查询 + * @param errMsg 错误消息格式字符串 + * @param columnExtractors 可变参数(varargs)查询字段,可选,如果没有就是查询全部 + * @param <T> 实体类类型 + * @param <R> 列值类型 + * @param <V> 需要验证的值的类型 + * @return 返回包含指定列值的实体对象 + * @throws IllegalArgumentException 如果需要验证的值为null + * @throws FebsException 如果查询结果为空或列值为null,或查询过程中发生异常 + */ + public static <T, R, V> T ensureColumnReturnEntity( + V valueToCheck, + SFunction<T, R> columnExtractor, + SFunction<LambdaQueryWrapper<T>, T> queryWrapperExtractor, + String errMsg, + SFunction<T, R>... columnExtractors) { + + // 检查输入参数是否为null + if (valueToCheck == null) { + throw new IllegalArgumentException("The value to check cannot be null while ensureColumnReturnEntity column"); + } + if (columnExtractor == null || queryWrapperExtractor == null) { + throw new IllegalArgumentException("Column extractor and query wrapper extractor cannot be null while ensureColumnReturnEntity column"); + } + + T entity = null; + try { + // 创建LambdaQueryWrapper并配置查询条件 + LambdaQueryWrapper<T> wrapper = Wrappers.lambdaQuery(); + if (columnExtractors != null && columnExtractors.length > 0) { + wrapper.select(columnExtractors); + } + wrapper.eq(columnExtractor, valueToCheck) + .last("limit 1"); + + // 执行查询并获取结果实体 + entity = queryWrapperExtractor.apply(wrapper); + + // 如果查询结果为空,则抛出异常 + if (entity == null) { + throw new FebsException(StrUtil.format(errMsg, valueToCheck)); + } + + // 提取查询结果中的列值 + R columnValue = columnExtractor.apply(entity); + // 如果列值为null,则抛出异常 + if (columnValue == null) { + throw new FebsException(StrUtil.format(errMsg, valueToCheck)); + } + + } catch (FebsException e) { + // 记录异常日志 + throw e; + } catch (Exception e) { + // 记录异常日志 + throw new FebsException(StrUtil.format("An error occurred while ensuring column return entity: {}", valueToCheck)); + } + + // 返回查询到的实体类对象 + return entity; + } + + /** + * 确保指定列的有效性,并返回相应的实体对象列表 + * selectList方法 + * 此方法用于验证数据库中某列的值是否存在,并返回包含该值的实体对象列表 + * 如果指定的值不存在或为null,将抛出异常 + * + * @param valueToCheck 需要验证的值 + * @param columnExtractor 列值提取器,用于指定需要验证的列 + * @param queryWrapperExtractor 查询包装器提取器,用于执行数据库查询 + * @param errMsg 错误消息格式字符串 + * @param columnExtractors 可变参数(varargs)查询字段,可选,如果没有就是查询全部 + * @param <T> 实体类类型 + * @param <R> 列值类型 + * @param <V> 需要验证的值的类型 + * @return 返回包含指定列值的实体对象列表 + * @throws IllegalArgumentException 如果需要验证的值为null + * @throws FebsException 如果查询结果为空或列值为null,或查询过程中发生异常 + */ + public static <T, R, V> List<T> ensureColumnReturnEntityList( + V valueToCheck, + SFunction<T, R> columnExtractor, + SFunction<LambdaQueryWrapper<T>, List<T>> queryWrapperExtractor, + String errMsg, + SFunction<T, R>... columnExtractors) { + // 检查需要验证的值是否为null + if (valueToCheck == null) { + throw new IllegalArgumentException("The value to check cannot be null while ensureColumnReturnEntityList column"); + } + List<T> entities = new ArrayList<>(); + try { + // 创建LambdaQueryWrapper并配置查询条件 + LambdaQueryWrapper<T> wrapper = Wrappers.lambdaQuery(); + if (columnExtractors != null && columnExtractors.length > 0) { + wrapper.select(columnExtractors); + } + wrapper.eq(columnExtractor, valueToCheck); + + // 执行查询并获取结果实体列表 + entities = queryWrapperExtractor.apply(wrapper); + } catch (Exception e) { + // 记录异常日志 + throw new FebsException(StrUtil.format("An error occurred while ensureColumnReturnEntityList column: {}", valueToCheck)); + } + // 如果查询结果为空,则抛出异常 + if (entities == null || entities.isEmpty()) { + throw new FebsException(StrUtil.format(errMsg, valueToCheck)); + } + + // 返回查询到的实体类对象列表 + return entities; + } + + /** + * 确保指定列的值在数据库中是存在的 + * selectOne方法 + * 该方法通过查询数据库来验证给定的列值是否存在如果不存在,则抛出异常 + * + * @param valueToCheck 需要验证的列值 + * @param columnExtractor 用于提取实体类中列值的函数式接口 + * @param queryWrapperExtractor 用于构建查询条件并返回实体类的函数式接口 + * @param errMsg 当列值无效时抛出的异常消息格式字符串 + * @throws IllegalArgumentException 如果需要验证的值为null + * @throws FebsException 如果在数据库中找不到指定的列值或列值为null,或者在查询过程中发生异常 + */ + public static <T, R, V> void ensureColumnValid( + V valueToCheck, + SFunction<T, R> columnExtractor, + SFunction<LambdaQueryWrapper<T>, T> queryWrapperExtractor, + String errMsg) { + // 检查需要验证的值是否为null + if (valueToCheck == null) { + throw new IllegalArgumentException("The value to check cannot be null while ensureColumnValid column"); + } + + try { + // 创建LambdaQueryWrapper并配置查询条件 + LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(); + wrapper.select(columnExtractor) + .eq(columnExtractor, valueToCheck) + .last("limit 1"); + + // 执行查询并获取结果实体 + T entity = queryWrapperExtractor.apply(wrapper); + // 如果查询结果为空,则抛出异常 + if (entity == null) { + throw new FebsException(StrUtil.format(errMsg, valueToCheck)); + } + + // 提取查询结果中的列值 + R columnValue = columnExtractor.apply(entity); + // 如果列值为null,则抛出异常 + if (columnValue == null) { + throw new FebsException(StrUtil.format(errMsg, valueToCheck)); + } + } catch (Exception e) { + // 记录异常日志 + throw new FebsException(e.getMessage()); + } + } + + /** + * 确保指定值在数据库中是唯一的 + * selectCount方法 + * 该方法通过查询数据库来验证给定的列值是否已经存在,如果存在,则抛出异常,以确保数据的唯一性 + * + * @param valueToCheck 需要检查的值 + * @param columnExtractor 用于提取实体类字段的函数式接口 + * @param countWrapperExtractor 用于获取查询条件包装器中记录数的函数式接口 + * @param errMsg 错误消息模板,当值不唯一时使用 + * @param <T> 实体类类型 + * @param <R> 字段类型 + * @param <V> 需要检查的值的类型 + * @throws IllegalArgumentException 如果需要检查的值为null,则抛出此异常 + * @throws FebsException 如果值已存在或在检查过程中发生错误,则抛出此异常 + */ + public static <T, R, V> void ensureUnique( + V valueToCheck, + SFunction<T, R> columnExtractor, + SFunction<LambdaQueryWrapper<T>, Integer> countWrapperExtractor, + String errMsg) { + // 检查输入值是否为null,如果为null,则抛出IllegalArgumentException异常 + if (valueToCheck == null) { + throw new IllegalArgumentException("The value to check cannot be null while ensureUnique column"); + } + if (columnExtractor == null) { + throw new IllegalArgumentException("The columnExtractor cannot be null while ensureUnique column"); + } + if (countWrapperExtractor == null) { + throw new IllegalArgumentException("The countWrapperExtractor cannot be null while ensureUnique column"); + } + + int count = 0; + try { + // 创建LambdaQueryWrapper对象,用于构建查询条件 + LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(); + // 添加等于条件,检查的字段=需要检查的值 + wrapper.eq(columnExtractor, valueToCheck); + // 执行查询并获取结果数量 + count = countWrapperExtractor.apply(wrapper); + + } catch (Exception e) { + // 记录异常日志 + throw new FebsException(StrUtil.format("An error occurred while ensureUnique column: {}", valueToCheck)); + } + + // 如果结果数量大于0,说明值已存在,抛出FebsException异常 + if (count > 0) { + throw new FebsException(StrUtil.format(errMsg, valueToCheck)); + } + } + + + /** + * 确保两个参数相等,如果不相等则抛出异常 + * + * @param value1 第一个参数 + * @param value2 第二个参数 + * @param errMsg 当两个参数不相等时抛出的异常消息格式字符串 + * @throws FebsException 如果两个参数不相等 + */ + public static <T> void ensureEqual( + T value1, + T value2, + String errMsg) { + // 使用 Objects.equals 处理 null 值,避免显式 null 检查 + if (!Objects.equals(value1, value2)) { + // 延迟字符串格式化,只在需要抛出异常时进行 + throw new FebsException(StrUtil.format(errMsg, value1, value2)); + } + } + + + /** + * 确保两个参数不相等,如果相等则抛出异常 + * + * @param value1 第一个参数 + * @param value2 第二个参数 + * @param errMsg 当两个参数相等时抛出的异常消息格式字符串 + * @throws FebsException 如果两个参数相等 + */ + public static <T> void ensureNotEqual( + T value1, + T value2, + String errMsg) { + // 使用 Objects.equals 处理 null 值,避免显式 null 检查 + if (Objects.equals(value1, value2)) { + // 延迟字符串格式化,只在需要抛出异常时进行 + throw new FebsException(StrUtil.format(errMsg, value1, value2)); + } + } + + +} diff --git a/src/main/java/cc/mrbird/febs/user/contant/MemberConstant.java b/src/main/java/cc/mrbird/febs/user/contant/MemberConstant.java new file mode 100644 index 0000000..b898d7d --- /dev/null +++ b/src/main/java/cc/mrbird/febs/user/contant/MemberConstant.java @@ -0,0 +1,36 @@ +package cc.mrbird.febs.user.contant; + +public class MemberConstant { + //添加途径 1-正常注册 0-后台添加 + public static final Integer ADD_TYPE_NORMAL = 1; + public static final Integer ADD_TYPE_BACK = 0; + + //性别 0-女 1-男性 2-未填写 + public static final Integer FEMALE = 0; + public static final Integer MALE = 1; + public static final Integer UNKNOWN = 2; + + + + /** + * 账户状态;1-正常 0-禁用 + */ + public static final Integer ACCOUNT_STATUS_NORMAL = 1; + public static final Integer ACCOUNT_STATUS_TEST = 0; + + + /** + * 账户类型;1-正常用户 0-测试账户 + */ + public static final Integer ACCOUNT_TYPE_NORMAL = 1; + public static final Integer ACCOUNT_TYPE_TEST = 0; + + + /** + * 是否是主账号 1-是 0-否 + */ + public static final Integer DIRECTER_YES = 1; + public static final Integer DIRECTER_NO = 0; + + +} diff --git a/src/main/java/cc/mrbird/febs/user/entity/ChatMember.java b/src/main/java/cc/mrbird/febs/user/entity/ChatMember.java index 7d38bba..9c15768 100644 --- a/src/main/java/cc/mrbird/febs/user/entity/ChatMember.java +++ b/src/main/java/cc/mrbird/febs/user/entity/ChatMember.java @@ -18,7 +18,6 @@ `invite_id` varchar(8) DEFAULT NULL COMMENT '邀请码', `referrer_id` varchar(8) DEFAULT NULL COMMENT '推荐人邀请码', `referrer_ids` text COMMENT '推荐人线路', - `level` varchar(255) DEFAULT NULL COMMENT '代理层级', `account_status` int DEFAULT '1' COMMENT '账户状态;1-正常 0-禁用', `account_type` int DEFAULT '0' COMMENT '账户类型;1-正常用户 0-测试账户', `avatar` varchar(500) DEFAULT NULL COMMENT '头像', @@ -42,7 +41,6 @@ private String inviteId;//邀请码 private String referrerId;//推荐人邀请码 private String referrerIds;//推荐人线路 - private String level;//代理层级 private Integer accountStatus;//账户状态;1-正常 0-禁用 private Integer accountType;//账户类型;1-正常用户 0-测试账户 private String avatar;//头像 diff --git a/src/main/java/cc/mrbird/febs/user/entity/ChatWallet.java b/src/main/java/cc/mrbird/febs/user/entity/ChatWallet.java new file mode 100644 index 0000000..177acae --- /dev/null +++ b/src/main/java/cc/mrbird/febs/user/entity/ChatWallet.java @@ -0,0 +1,23 @@ +package cc.mrbird.febs.user.entity; + +import cc.mrbird.febs.common.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@TableName("chat_wallet") +public class ChatWallet extends BaseEntity { + + /** + * 用户ID + */ + private Long memberId; + + /** + * 余额 + */ + private BigDecimal balance; + +} diff --git a/src/main/java/cc/mrbird/febs/user/mapper/ChatWalletMapper.java b/src/main/java/cc/mrbird/febs/user/mapper/ChatWalletMapper.java new file mode 100644 index 0000000..7a4d8f0 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/user/mapper/ChatWalletMapper.java @@ -0,0 +1,10 @@ +package cc.mrbird.febs.user.mapper; + +import cc.mrbird.febs.user.entity.ChatWallet; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface ChatWalletMapper extends BaseMapper<ChatWallet> { + + int updateBalanceWithVersion(ChatWallet wallet); + +} diff --git a/src/main/java/cc/mrbird/febs/user/req/ApiRegisterDto.java b/src/main/java/cc/mrbird/febs/user/req/ApiRegisterDto.java index 9aa774d..d4480b3 100644 --- a/src/main/java/cc/mrbird/febs/user/req/ApiRegisterDto.java +++ b/src/main/java/cc/mrbird/febs/user/req/ApiRegisterDto.java @@ -14,10 +14,6 @@ @ApiModelProperty(value = "邮箱", example = "152@163.com") private String account; - @NotBlank(message = "类型不能为空!") - @ApiModelProperty(value = "类型 1-手机号 2-邮箱", example = "1") - private String type = "1"; - @NotBlank(message = "验证码不能为空") @ApiModelProperty(value = "验证码", example = "123456") private String code; @@ -33,7 +29,6 @@ @ApiModelProperty(value = "邀请码") private String inviteId; - @NotBlank(message = "注册类型不能为空") - @ApiModelProperty(value = "注册类型 1-正常注册 0-手动添加子账号", example = "1") - private Integer registerType;//注册类型 1-正常注册 0-手动添加子账号 + @ApiModelProperty(hidden = true) + private Integer addType;//添加途径 1-正常注册 0-后台添加 } diff --git a/src/main/java/cc/mrbird/febs/user/service/AsyncService.java b/src/main/java/cc/mrbird/febs/user/service/AsyncService.java new file mode 100644 index 0000000..f8156ef --- /dev/null +++ b/src/main/java/cc/mrbird/febs/user/service/AsyncService.java @@ -0,0 +1,23 @@ +package cc.mrbird.febs.user.service; + +import cc.mrbird.febs.common.entity.FebsConstant; +import cc.mrbird.febs.user.entity.ChatMember; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.scheduling.annotation.Async; + +public interface AsyncService extends IService<ChatMember> { + + /** + * 初始化钱包信息 + * @param memberId + */ + @Async(FebsConstant.ASYNC_POOL) + void initWallet(Long memberId); + + /** + * 初始化推荐人信息 + * @param memberId + */ + @Async(FebsConstant.ASYNC_POOL) + void initMemberReferrerIds(Long memberId,String referrerId); +} diff --git a/src/main/java/cc/mrbird/febs/user/service/IChatWalletService.java b/src/main/java/cc/mrbird/febs/user/service/IChatWalletService.java new file mode 100644 index 0000000..bc8340a --- /dev/null +++ b/src/main/java/cc/mrbird/febs/user/service/IChatWalletService.java @@ -0,0 +1,13 @@ +package cc.mrbird.febs.user.service; + +import cc.mrbird.febs.user.entity.ChatWallet; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.math.BigDecimal; + +public interface IChatWalletService extends IService<ChatWallet> { + + void addBalance(BigDecimal amount, Long member); + + void reduceBalance(BigDecimal amount, Long memberId); +} diff --git a/src/main/java/cc/mrbird/febs/user/service/Impl/AsyncServiceImpl.java b/src/main/java/cc/mrbird/febs/user/service/Impl/AsyncServiceImpl.java new file mode 100644 index 0000000..b776de8 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/user/service/Impl/AsyncServiceImpl.java @@ -0,0 +1,60 @@ +package cc.mrbird.febs.user.service.Impl; + +import cc.mrbird.febs.user.entity.ChatMember; +import cc.mrbird.febs.user.entity.ChatWallet; +import cc.mrbird.febs.user.mapper.ChatMemberMapper; +import cc.mrbird.febs.user.mapper.ChatWalletMapper; +import cc.mrbird.febs.user.service.AsyncService; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AsyncServiceImpl extends ServiceImpl<ChatMemberMapper, ChatMember> implements AsyncService { + + private final ChatWalletMapper chatWalletMapper; + @Override + public void initWallet(Long memberId) { + ChatWallet wallet = new ChatWallet(); + wallet.setBalance(BigDecimal.ZERO); + wallet.setMemberId(memberId); + chatWalletMapper.insert(wallet); + } + + @Override + public void initMemberReferrerIds(Long memberId, String parentId) { + boolean flag = false; + if (StrUtil.isBlank(parentId)) { + flag = true; + } + String ids = ""; + while (!flag) { + if (StrUtil.isBlank(ids)) { + ids += parentId; + } else { + ids += ("," + parentId); + } + ChatMember chatMemberParent = this.baseMapper.selectOne(new LambdaQueryWrapper<ChatMember>().eq(ChatMember::getInviteId, parentId)); + if (chatMemberParent == null) { + break; + } + parentId = chatMemberParent.getReferrerId(); + if (StrUtil.isBlank(chatMemberParent.getReferrerId())) { + flag = true; + } + } + + ChatMember chatMember = this.baseMapper.selectById(memberId); + if (StrUtil.isNotBlank(ids)) { + chatMember.setReferrerIds(ids); + this.baseMapper.updateById(chatMember); + } + } +} diff --git a/src/main/java/cc/mrbird/febs/user/service/Impl/ChatMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/user/service/Impl/ChatMemberServiceImpl.java index e7963ea..3f2896a 100644 --- a/src/main/java/cc/mrbird/febs/user/service/Impl/ChatMemberServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/user/service/Impl/ChatMemberServiceImpl.java @@ -1,30 +1,24 @@ package cc.mrbird.febs.user.service.Impl; import cc.mrbird.febs.common.entity.FebsResponse; -import cc.mrbird.febs.common.enumerates.YesOrNoEnum; import cc.mrbird.febs.common.exception.FebsException; -import cc.mrbird.febs.common.utils.AppContants; import cc.mrbird.febs.common.utils.ShareCodeUtil; -import cc.mrbird.febs.mall.entity.MallMember; -import cc.mrbird.febs.mall.entity.MallMemberWallet; -import cc.mrbird.febs.mall.entity.RunVip; +import cc.mrbird.febs.common.utils.ValidateEntityUtils; +import cc.mrbird.febs.mall.service.impl.CommonService; +import cc.mrbird.febs.user.contant.MemberConstant; import cc.mrbird.febs.user.entity.ChatMember; import cc.mrbird.febs.user.mapper.ChatMemberMapper; import cc.mrbird.febs.user.req.ApiRegisterDto; +import cc.mrbird.febs.user.service.AsyncService; import cc.mrbird.febs.user.service.IChatMemberService; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.List; @Slf4j @Service @@ -32,116 +26,58 @@ @Transactional public class ChatMemberServiceImpl extends ServiceImpl<ChatMemberMapper, ChatMember> implements IChatMemberService { + private final CommonService commonService; + private final AsyncService asyncService; + @Override public FebsResponse register(ApiRegisterDto apiRegisterDto) { String account = apiRegisterDto.getAccount(); - - MallMember mallMember = this.baseMapper.selectInfoByAccount(account); - if (mallMember != null) { - throw new FebsException("手机号已注册"); - } - /** - * 验证两次密码是否一致 - */ - String password = registerDto.getPassword(); - String passwordAgain = registerDto.getPasswordAgain(); - if(!password.equals(passwordAgain)){ - throw new FebsException("密码不一致"); - } - - //邀请码为admin的时候(后台添加用户),不需要验证验证码 - if (!"admin".equals(registerDto.getRegistType())) { - String code = registerDto.getCode(); + String password = apiRegisterDto.getPassword(); + String passwordAgain = apiRegisterDto.getPasswordAgain(); + String refInviteId = apiRegisterDto.getInviteId(); + String code = apiRegisterDto.getCode(); + //后台添加用户,不需要验证验证码 + Integer addType = apiRegisterDto.getAddType(); + if (MemberConstant.ADD_TYPE_NORMAL == addType) { boolean flags = commonService.verifyCode(account, code); if (!flags) { throw new FebsException("验证码错误"); } } + ValidateEntityUtils.ensureEqual(password, passwordAgain, "两次密码不一致"); + ValidateEntityUtils.ensureUnique(account, ChatMember::getEmail, this.baseMapper::selectCount, "邮箱已使用"); - mallMember = new MallMember(); - mallMember.setPassword(SecureUtil.md5(registerDto.getPassword())); + ChatMember chatMember = new ChatMember(); + chatMember.setEmail(account); + chatMember.setPassword(SecureUtil.md5(password)); + chatMember.setName(account); + chatMember.setSex(MemberConstant.UNKNOWN); - // 判断账号类型 - if (AppContants.ACCOUNT_TYPE_MOBILE.equals(registerDto.getType())) { - mallMember.setPhone(registerDto.getAccount()); - } else { - mallMember.setEmail(registerDto.getAccount()); - } //对于邀请码的验证和上级联系人的验证 Integer count = this.baseMapper.selectCount(null); if (count != null && count != 0) { - if(StrUtil.isEmpty(registerDto.getInviteId())){ - throw new FebsException("请输入邀请码"); - } - String inviteId = registerDto.getInviteId(); - MallMember inviteMember = this.baseMapper.selectInfoByInviteId(inviteId); - if (inviteMember == null) { - throw new FebsException("邀请码不存在"); - } - mallMember.setReferrerId(registerDto.getInviteId()); -// if(!StrUtil.isEmpty(registerDto.getInviteId())){ -// String inviteId = registerDto.getInviteId(); -// MallMember inviteMember = this.baseMapper.selectInfoByInviteId(inviteId); -// if (inviteMember == null) { -// throw new FebsException("邀请码不存在"); -// } -// mallMember.setReferrerId(registerDto.getInviteId()); -// } - } - mallMember.setName(account); - mallMember.setAvatar("https://res.runstep.cc/rslogo.png"); - mallMember.setAccountStatus(YesOrNoEnum.YES.getValue()); - mallMember.setAccountType(MallMember.ACCOUNT_TYPE_NORMAL); - mallMember.setSex("男"); - mallMember.setDirector(YesOrNoEnum.NO.getValue()); - mallMember.setDirectorTime(DateUtil.date()); - mallMember.setBindPhone(account); - - this.baseMapper.insert(mallMember); - - String inviteId = ShareCodeUtil.toSerialCode(mallMember.getId()); - mallMember.setInviteId(inviteId); - - //推荐人和推荐人链 - boolean flag = false; - String parentId = mallMember.getReferrerId(); - if (StrUtil.isBlank(parentId)) { - flag = true; - } - String ids = ""; - while (!flag) { - if (StrUtil.isBlank(ids)) { - ids += parentId; - } else { - ids += ("," + parentId); - } - MallMember parentMember = this.baseMapper.selectInfoByInviteId(parentId); - if (parentMember == null) { - break; - } - parentId = parentMember.getReferrerId(); - if (StrUtil.isBlank(parentMember.getReferrerId())) { - flag = true; + if(StrUtil.isNotEmpty(refInviteId)){ + ChatMember chatMemberInvite = ValidateEntityUtils.ensureColumnReturnEntity(refInviteId, ChatMember::getInviteId, this.baseMapper::selectOne, "邀请码不存在"); + chatMember.setReferrerId(chatMemberInvite.getInviteId()); } } + chatMember.setAccountStatus(MemberConstant.ACCOUNT_STATUS_NORMAL); + chatMember.setAccountType(MemberConstant.ACCOUNT_TYPE_NORMAL); + // --todo 默认头像为空 +// chatMember.setAvatar("https://res.runstep.cc/rslogo.png"); + chatMember.setDirector(MemberConstant.DIRECTER_YES); + chatMember.setLastLoginTime(DateUtil.date()); + // -- todo 默认主账号的角色设置没有设置 + chatMember.setRoleId(0L); + this.baseMapper.insert(chatMember); - if (StrUtil.isNotBlank(ids)) { - mallMember.setReferrerIds(ids); - } - //会员VIP等级 - List<RunVip> runVips = runVipMapper.selectList(new LambdaQueryWrapper<RunVip>().orderByAsc(RunVip::getOrderNumber)); - if (StrUtil.isBlank(mallMember.getLevel()) && CollUtil.isNotEmpty(runVips)) { - RunVip runVip = runVips.get(0); - mallMember.setLevel(runVip.getVipCode()); - } - this.baseMapper.updateById(mallMember); + //公司ID默认为主账号的会员ID + chatMember.setCompanyId(chatMember.getId()); + chatMember.setInviteId(ShareCodeUtil.toSerialCode(chatMember.getId())); + //推荐人链 + asyncService.initMemberReferrerIds(chatMember.getId(),chatMember.getReferrerId()); + asyncService.initWallet(chatMember.getId()); - MallMemberWallet wallet = new MallMemberWallet(); - wallet.setBalance(BigDecimal.ZERO); - wallet.setMemberId(mallMember.getId()); - mallMemberWalletMapper.insert(wallet); - - agentProducer.sendNodeUpMsg(mallMember.getId()); return new FebsResponse().success().message("注册成功"); } } diff --git a/src/main/java/cc/mrbird/febs/user/service/Impl/ChatWalletServiceImpl.java b/src/main/java/cc/mrbird/febs/user/service/Impl/ChatWalletServiceImpl.java new file mode 100644 index 0000000..788caa7 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/user/service/Impl/ChatWalletServiceImpl.java @@ -0,0 +1,69 @@ +package cc.mrbird.febs.user.service.Impl; + +import cc.mrbird.febs.common.exception.FebsException; +import cc.mrbird.febs.common.utils.ValidateEntityUtils; +import cc.mrbird.febs.user.entity.ChatWallet; +import cc.mrbird.febs.user.mapper.ChatWalletMapper; +import cc.mrbird.febs.user.service.IChatWalletService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ChatWalletServiceImpl extends ServiceImpl<ChatWalletMapper, ChatWallet> implements IChatWalletService { + + @Override + public void addBalance(BigDecimal amount, Long memberId) { + if (BigDecimal.ZERO.compareTo(amount) > 0) { + throw new FebsException("增加余额异常"); + } + int i = 0; + boolean flag = true; + + while (flag) { + i++; + ChatWallet wallet = ValidateEntityUtils.ensureColumnReturnEntity(memberId, ChatWallet::getMemberId, this.baseMapper::selectOne, "钱包不存在"); + wallet.setBalance(wallet.getBalance().add(amount)); + int result = this.baseMapper.updateBalanceWithVersion(wallet); + if (result > 0) { + flag = false; + } else { + if (i > 2) { + throw new FebsException("操作失败"); + } + } + } + } + + @Override + public void reduceBalance(BigDecimal amount, Long memberId) { + int i = 0; + boolean flag = true; + + while (flag) { + i++; + ChatWallet wallet = ValidateEntityUtils.ensureColumnReturnEntity(memberId, ChatWallet::getMemberId, this.baseMapper::selectOne, "钱包不存在"); + if (amount.compareTo(wallet.getBalance()) > 0) { + throw new FebsException("余额不足"); + } + + wallet.setBalance(wallet.getBalance().subtract(amount)); + + int result = this.baseMapper.updateBalanceWithVersion(wallet); + if (result > 0) { + flag = false; + } else { + if (i > 2) { + throw new FebsException("操作失败"); + } + } + } + } + + +} diff --git a/src/main/resources/mapper/modules/ChatWalletMapper.xml b/src/main/resources/mapper/modules/ChatWalletMapper.xml new file mode 100644 index 0000000..47b09df --- /dev/null +++ b/src/main/resources/mapper/modules/ChatWalletMapper.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="cc.mrbird.febs.user.mapper.ChatWalletMapper"> + + <update id="updateBalanceWithVersion"> + update chat_wallet + set revision = revision + 1, + balance = #{record.balance} + where id=#{record.id} and revision=#{record.revision} + </update> + +</mapper> \ No newline at end of file -- Gitblit v1.9.1