From 0a06e8a5cf74dccf24a6d78ddf028654b9a17dcb Mon Sep 17 00:00:00 2001 From: zzc <1278921369@qq.com> Date: Thu, 12 Sep 2024 22:56:22 +0800 Subject: [PATCH] =?UTF-8?q?=E9=82=AE=E7=AE=B1=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/CaptchaController.java | 3 +- .../web/controller/app/EqUserController.java | 137 +++++++++++++++++- .../src/main/resources/application-dev.yml | 34 ++++- .../src/main/resources/application.yml | 2 + 4 files changed, 161 insertions(+), 15 deletions(-) diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java index 1a476a94a..fee7eb103 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java @@ -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 emailCode(@NotBlank(message = "{user.email.not.blank}") String email) { + public R emailCode(@NotBlank(message = "{user.email.not.blank}") @Email String email) { if (!mailProperties.getEnabled()) { return R.fail("当前系统没有开启邮箱功能!"); } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/app/EqUserController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/app/EqUserController.java index ef6e5a553..e3c0c6de1 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/controller/app/EqUserController.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/app/EqUserController.java @@ -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 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() + .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; + } + } } diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index e3559ee00..280486e08 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -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安全连接 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index c8257f84e..f5f059249 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -124,7 +124,9 @@ security: # actuator 监控配置 - /actuator - /actuator/** + ## app - /app/text/** + - /app/user/** # 多租户配置 tenant: