邮箱添加

This commit is contained in:
zzc 2024-09-12 22:56:22 +08:00
parent 6235b44459
commit 0a06e8a5cf
4 changed files with 161 additions and 15 deletions

View File

@ -5,6 +5,7 @@ import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -81,7 +82,7 @@ public class CaptchaController {
*/
@RateLimiter(key = "#email", time = 60, count = 1)
@GetMapping("/resource/email/code")
public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") @Email String email) {
if (!mailProperties.getEnabled()) {
return R.fail("当前系统没有开启邮箱功能!");
}

View File

@ -6,38 +6,48 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.domain.model.RegisterBody;
import org.dromara.common.core.enums.UserType;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.exception.user.CaptchaException;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.MimeTypeUtils;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.log.event.LogininforEvent;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.config.properties.CaptchaProperties;
import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.bo.SysUserPasswordBo;
import org.dromara.system.domain.bo.SysUserProfileBo;
import org.dromara.system.domain.vo.*;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.*;
import org.dromara.web.domain.bo.EqAppHomeBo;
import org.dromara.web.domain.bo.EqAreaBo;
import org.dromara.web.domain.bo.EqEquipmentBo;
import org.dromara.web.domain.bo.EqShareBo;
import org.dromara.web.domain.bo.*;
import org.dromara.web.domain.vo.EqAreaVo;
import org.dromara.web.domain.vo.EqEquipmentVo;
import org.dromara.web.domain.vo.EqShareVo;
import org.dromara.web.domain.vo.EqUserConfigVo;
import org.dromara.web.service.IEqAreaService;
import org.dromara.web.service.IEqEquipmentService;
import org.dromara.web.service.IEqShareService;
import org.dromara.web.service.IEqUserConfigService;
import org.dromara.web.service.*;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -46,6 +56,8 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* app用户相关
@ -235,5 +247,114 @@ public class EqUserController extends BaseController {
private final IEqShareService eqShareService;
private final SysUserMapper userMapper;
private final CaptchaProperties captchaProperties;
private final SysRegisterService registerService;
private final ISysConfigService configService;
private final IEqUserConfigService iEqUserConfigService;
/**
* 邮箱注册
*/
//@ApiEncrypt
@PostMapping("/emailRegister")
public R<Void> register(@Validated @RequestBody RegisterBody user) {
if (!configService.selectRegisterEnabled(user.getTenantId())) {
return R.fail("当前系统没有开启注册功能!");
}
emailRegister(user);
SysUserVo sysUserVo = userService.selectUserByUserName(user.getUsername());
EqUserConfigBo bo = new EqUserConfigBo();
bo.setUserId(sysUserVo.getUserId());
bo.setLanguageType("zh_CN");
bo.setTimezoneType("1");//默认 UTC+08:00
bo.setZoneId("UTC+08:00");
bo.setTimeFormat("YYYY-MM-DD");
bo.setCreateBy(sysUserVo.getUserId());
bo.setUpdateBy(sysUserVo.getUserId());
iEqUserConfigService.insertByBo(bo);
return R.ok();
}
public void emailRegister(RegisterBody registerBody) {
String tenantId = registerBody.getTenantId();
String username = registerBody.getUsername();
String password = registerBody.getPassword();
// 校验用户类型是否存在
String userType = UserType.getUserType(registerBody.getUserType()).getUserType();
if (!validEmail(username)) throw new UserException("user.email.not.valid");
validateEmailCode(tenantId, username, registerBody.getCode());
SysUserBo sysUser = new SysUserBo();
sysUser.setUserName(username);
sysUser.setNickName(username);
sysUser.setPassword(BCrypt.hashpw(password));
sysUser.setUserType(userType);
boolean exist = TenantHelper.dynamic(tenantId, () -> {
return userMapper.exists(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getUserName, sysUser.getUserName()));
});
if (exist) {
throw new UserException("user.register.save.error", username);
}
boolean regFlag = userService.registerUser(sysUser, tenantId);
if (!regFlag) {
throw new UserException("user.register.error");
}
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success"));
}
/**
* 校验邮箱验证码
*/
private boolean validateEmailCode(String tenantId, String email, String emailCode) {
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
if (emailCode == null) {
recordLogininfor(tenantId, email, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException();
}
if (code == null || !code.equalsIgnoreCase(emailCode)) {
recordLogininfor(tenantId, email, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
throw new CaptchaException();
}
return code.equals(emailCode);
}
/**
* 记录登录信息
*
* @param tenantId 租户ID
* @param username 用户名
* @param status 状态
* @param message 消息内容
* @return
*/
private void recordLogininfor(String tenantId, String username, String status, String message) {
LogininforEvent logininforEvent = new LogininforEvent();
logininforEvent.setTenantId(tenantId);
logininforEvent.setUsername(username);
logininforEvent.setStatus(status);
logininforEvent.setMessage(message);
logininforEvent.setRequest(ServletUtils.getRequest());
SpringUtils.context().publishEvent(logininforEvent);
}
//邮箱格式的验证
public static boolean validEmail(String userEmail) {
Pattern p = Pattern.compile("[a-zA-Z0-9]+@[A-Za-z0-9]+\\.[a-z0-9]");
Matcher m = p.matcher(userEmail);
if(m.find()){
return true;
} else {
return false;
}
}
}

View File

@ -97,7 +97,7 @@ spring.data:
# 数据库索引
database: 2
# redis 密码必须配置
password: ruoyi123
# password: ruoyi123
# 连接超时时间
timeout: 10s
# 是否开启ssl
@ -127,18 +127,40 @@ redisson:
subscriptionConnectionPoolSize: 50
--- # mail 邮件发送
#mail:
# enabled: true
# host: smtp.qq.com
# port: 465
# # 是否需要用户名密码验证
# auth: true
# # 发送方遵循RFC-822标准
# from: 1278921369@qq.com
# # 用户名注意如果使用foxmail邮箱此处user为qq号
# user: 1278921369@qq.com
# # 密码注意某些邮箱需要为SMTP服务单独设置密码详情查看相关帮助
# pass: wynqzknymvnkhjea
# # 使用 STARTTLS安全连接STARTTLS是对纯文本通信协议的扩展。
# starttlsEnable: true
# # 使用SSL安全连接
# sslEnable: true
# # SMTP超时时长单位毫秒缺省值不超时
# timeout: 0
# # Socket连接超时值单位毫秒缺省值不超时
# connectionTimeout: 0
mail:
enabled: false
host: smtp.163.com
enabled: true
host: smtp.qiye.aliyun.com
port: 465
# 是否需要用户名密码验证
auth: true
# 发送方遵循RFC-822标准
from: xxx@163.com
from: aioc-service@mocdoor.com
# 用户名注意如果使用foxmail邮箱此处user为qq号
user: xxx@163.com
user: aioc-service@mocdoor.com
# 密码注意某些邮箱需要为SMTP服务单独设置密码详情查看相关帮助
pass: xxxxxxxxxx
pass: PsoFT63GWn4Jdi8C
# 使用 STARTTLS安全连接STARTTLS是对纯文本通信协议的扩展。
starttlsEnable: true
# 使用SSL安全连接

View File

@ -124,7 +124,9 @@ security:
# actuator 监控配置
- /actuator
- /actuator/**
## app
- /app/text/**
- /app/user/**
# 多租户配置
tenant: