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