2
0

feat: add register

This commit is contained in:
caiyuchao
2024-11-27 18:36:18 +08:00
parent dd62a85f51
commit f13548d937
18 changed files with 212 additions and 36 deletions

View File

@@ -0,0 +1,4 @@
ALTER TABLE `wfc-cloud`.`sys_user`
ADD COLUMN `full_name` varchar(64) NULL COMMENT '用户姓名' AFTER `nick_name`,
ADD COLUMN `age` int(11) NULL COMMENT '年龄' AFTER `password`,
ADD COLUMN `address` varchar(255) NULL COMMENT '地址' AFTER `age`;

View File

@@ -1,8 +1,5 @@
package org.wfc.system.api.domain;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.wfc.common.core.annotation.Excel;
@@ -12,6 +9,12 @@ import org.wfc.common.core.annotation.Excels;
import org.wfc.common.core.web.domain.BaseEntity;
import org.wfc.common.core.xss.Xss;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
/**
* 用户对象 sys_user
*
@@ -55,6 +58,15 @@ public class SysUser extends BaseEntity
/** 密码 */
private String password;
/** 用户姓名 */
private String fullName;
/** 年龄 */
private Integer age;
/** 地址 */
private String address;
/** 帐号状态0正常 1停用 */
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
@@ -99,6 +111,30 @@ public class SysUser extends BaseEntity
this.userId = userId;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Long getUserId()
{
return userId;

View File

@@ -21,6 +21,8 @@ import org.wfc.user.api.domain.UUser;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequest;
/**
* token 控制
*
@@ -88,7 +90,7 @@ public class TokenController
public R<?> register(@RequestBody RegisterBody registerBody)
{
// 用户注册
sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
sysLoginService.register(registerBody);
return R.ok();
}
}

View File

@@ -1,11 +1,14 @@
package org.wfc.auth.service;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.wfc.common.core.constant.CacheConstants;
import org.wfc.common.core.constant.Constants;
import org.wfc.common.core.constant.GlobalConstants;
import org.wfc.common.core.constant.SecurityConstants;
import org.wfc.common.core.constant.UserConstants;
import org.wfc.common.core.domain.LoginUser;
import org.wfc.common.core.domain.R;
import org.wfc.common.core.enums.UserStatus;
import org.wfc.common.core.exception.ServiceException;
@@ -13,12 +16,11 @@ import org.wfc.common.core.text.Convert;
import org.wfc.common.core.utils.DateUtils;
import org.wfc.common.core.utils.StringUtils;
import org.wfc.common.core.utils.ip.IpUtils;
import org.wfc.common.core.web.form.RegisterBody;
import org.wfc.common.redis.service.RedisService;
import org.wfc.common.security.utils.SecurityUtils;
import org.wfc.system.api.RemoteUserService;
import org.wfc.system.api.domain.SysUser;
import org.wfc.common.core.domain.LoginUser;
import org.wfc.user.api.domain.UUser;
/**
* 登录校验方法
@@ -128,8 +130,10 @@ public class SysLoginService
/**
* 注册
*/
public void register(String username, String password)
public void register(RegisterBody registerBody)
{
String username = registerBody.getUsername();
String password = registerBody.getPassword();
// 用户名或密码为空 错误
if (StringUtils.isAnyBlank(username, password))
{
@@ -151,12 +155,22 @@ public class SysLoginService
sysUser.setUserName(username);
sysUser.setNickName(username);
sysUser.setPassword(SecurityUtils.encryptPassword(password));
sysUser.setAge(registerBody.getAge());
sysUser.setAddress(registerBody.getAddress());
sysUser.setEmail(registerBody.getEmail());
sysUser.setFullName(registerBody.getFullName());
sysUser.setSex(registerBody.getSex());
sysUser.setPhonenumber(registerBody.getPhonenumber());
R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
if (R.FAIL == registerResult.getCode())
{
throw new ServiceException(registerResult.getMsg());
}
// 注册成功删除redis
if (StrUtil.isNotBlank(registerBody.getEmail())) {
redisService.deleteObject(GlobalConstants.CAPTCHA_CODE_KEY + registerBody.getEmail());
}
recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功");
}
}

View File

@@ -112,6 +112,11 @@ public class Constants
*/
public static final long CAPTCHA_EXPIRATION = 2;
/**
* 邮箱验证码有效期(分钟)
*/
public static final long MAIL_CAPTCHA_EXPIRATION = 30;
/**
* 资源映射路径 前缀
*/

View File

@@ -1,11 +1,43 @@
package org.wfc.common.core.web.form;
import lombok.Data;
/**
* 用户注册对象
*
*
* @author wfc
*/
public class RegisterBody extends LoginBody
{
@Data
public class RegisterBody extends LoginBody {
/**
* 用户邮箱
*/
private String email;
/**
* 用户姓名
*/
private String fullName;
/**
* 年龄
*/
private Integer age;
/**
* 地址
*/
private String address;
/**
* 性别
*/
private String sex;
/**
* 性别
*/
private String phonenumber;
}

View File

@@ -25,7 +25,9 @@ user.phonenumber.not.blank=Phone number cannot be blank
user.mobile.phone.number.not.valid=Phone number format error
user.login.success=Login successful
user.register.success=Register successful
user.register.save.error=Failed to save user {0}, The registered account already exists
user.register.save.error=The registered username already exists
user.register.phone.save.error=The registered phone already exists
user.register.email.save.error=The registered email already exists
user.register.error=Register failed, please contact system administrator
user.notfound=Please login again
user.forcelogout=The administrator is forced to exitplease login again

View File

@@ -25,7 +25,9 @@ user.phonenumber.not.blank=用户手机号不能为空
user.mobile.phone.number.not.valid=手机号格式错误
user.login.success=登录成功
user.register.success=注册成功
user.register.save.error=保存用户 {0} 失败,注册账号已存在
user.register.save.error=注册账号已存在
user.register.phone.save.error=注册手机已存在
user.register.email.save.error=注册邮箱已存在
user.register.error=注册失败,请联系系统管理人员
user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录

View File

@@ -52,7 +52,7 @@ class SwaggerDocRegister extends Subscriber<InstancesChangeEvent>
@Autowired
private DiscoveryClient discoveryClient;
private final static String[] EXCLUDE_ROUTES = new String[] { "wfc-gateway", "wfc-auth", "wfc-file", "wfc-monitor" };
private final static String[] EXCLUDE_ROUTES = new String[] { "wfc-gateway", "wfc-file", "wfc-monitor" };
public SwaggerDocRegister(SwaggerUiConfigProperties swaggerUiConfigProperties, DiscoveryClient discoveryClient)
{

View File

@@ -15,10 +15,15 @@ import org.springframework.context.annotation.Configuration;
public class CaptchaProperties
{
/**
* 验证码开关
* 图片验证码开关
*/
private Boolean enabled;
/**
* 邮箱验证码开关
*/
private Boolean mailEnabled;
/**
* 验证码类型math 数组计算 char 字符)
*/
@@ -43,4 +48,12 @@ public class CaptchaProperties
{
this.type = type;
}
public Boolean getMailEnabled() {
return mailEnabled;
}
public void setMailEnabled(Boolean mailEnabled) {
this.mailEnabled = mailEnabled;
}
}

View File

@@ -1,8 +1,7 @@
package org.wfc.gateway.filter;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
@@ -10,14 +9,16 @@ import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.wfc.common.core.utils.ServletUtils;
import org.wfc.common.core.utils.StringUtils;
import org.wfc.gateway.config.properties.CaptchaProperties;
import org.wfc.gateway.service.ValidateCodeService;
import reactor.core.publisher.Flux;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
/**
* 验证码过滤器
*
@@ -26,7 +27,8 @@ import reactor.core.publisher.Flux;
@Component
public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
{
private final static String[] VALIDATE_URL = new String[] { "/auth/login", "/auth/register" };
private final static String[] VALIDATE_URL = new String[] { "/auth/login" };
private final static String[] MAIL_VALIDATE_URL = new String[] { "/auth/register" };
@Autowired
private ValidateCodeService validateCodeService;
@@ -38,14 +40,18 @@ public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
private static final String UUID = "uuid";
private static final String EMAIL = "email";
@Override
public GatewayFilter apply(Object config)
{
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 非登录/注册请求或验证码关闭,不处理
if (!StringUtils.equalsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled())
// 非登录请求且验证码启用,非注册请求且邮箱验证码启用, 不处理
boolean enabledLoginCaptcha = StringUtils.equalsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) && captchaProperties.getEnabled();
boolean enabledRegisterCaptcha = StringUtils.equalsAnyIgnoreCase(request.getURI().getPath(), MAIL_VALIDATE_URL) && captchaProperties.getMailEnabled();
if (!enabledLoginCaptcha && !enabledRegisterCaptcha)
{
return chain.filter(exchange);
}
@@ -54,7 +60,14 @@ public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
{
String rspStr = resolveBodyFromRequest(request);
JSONObject obj = JSON.parseObject(rspStr);
validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(UUID));
// 图片验证码启用
if (enabledLoginCaptcha) {
validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(UUID), true);
}
// 邮箱验证码启用
if (enabledRegisterCaptcha) {
validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(EMAIL), false);
}
}
catch (Exception e)
{

View File

@@ -1,9 +1,10 @@
package org.wfc.gateway.service;
import java.io.IOException;
import org.wfc.common.core.exception.CaptchaException;
import org.wfc.common.core.web.domain.AjaxResult;
import java.io.IOException;
/**
* 验证码处理
*
@@ -19,5 +20,5 @@ public interface ValidateCodeService
/**
* 校验验证码
*/
public void checkCaptcha(String key, String value) throws CaptchaException;
public void checkCaptcha(String key, String value, boolean isPic) throws CaptchaException;
}

View File

@@ -5,8 +5,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;
import org.wfc.common.core.constant.CacheConstants;
import org.wfc.common.core.constant.Constants;
import org.wfc.common.core.constant.GlobalConstants;
import org.wfc.common.core.exception.CaptchaException;
import org.wfc.common.core.utils.StringUtils;
import org.wfc.common.core.utils.sign.Base64;
@@ -63,7 +63,7 @@ public class ValidateCodeServiceImpl implements ValidateCodeService
// 保存验证码信息
String uuid = IdUtils.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
String capStr = null, code = null;
BufferedImage image = null;
@@ -109,19 +109,21 @@ public class ValidateCodeServiceImpl implements ValidateCodeService
* 校验验证码
*/
@Override
public void checkCaptcha(String code, String uuid) throws CaptchaException
public void checkCaptcha(String code, String uuid, boolean isPic) throws CaptchaException
{
if (StringUtils.isEmpty(code))
{
throw new CaptchaException("user.jcaptcha.not.blank");
}
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisService.getCacheObject(verifyKey);
if (captcha == null)
{
throw new CaptchaException();
}
redisService.deleteObject(verifyKey);
if (isPic) {
redisService.deleteObject(verifyKey);
}
if (!code.equalsIgnoreCase(captcha))
{
throw new CaptchaException();

View File

@@ -47,9 +47,9 @@ public class SysEmailController extends BaseController {
}
String key = GlobalConstants.CAPTCHA_CODE_KEY + email;
String code = RandomUtil.randomNumbers(4);
redisService.setCacheObject(key, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
redisService.setCacheObject(key, code, Constants.MAIL_CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
try {
MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
MailUtils.sendText(email, "Registration verification code", "Your verification code is: " + code + ", The validity period is " + Constants.MAIL_CAPTCHA_EXPIRATION + " minutes, please fill in as soon as possible.");
} catch (Exception e) {
log.error("验证码短信发送异常 => {}", e.getMessage());
return R.fail(e.getMessage());

View File

@@ -1,6 +1,7 @@
package org.wfc.system.controller;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.validation.annotation.Validated;
@@ -30,6 +31,7 @@ import org.wfc.system.api.domain.SysDept;
import org.wfc.system.api.domain.SysRole;
import org.wfc.system.api.domain.SysUser;
import org.wfc.common.core.domain.LoginUser;
import org.wfc.system.domain.query.UserRepeatQuery;
import org.wfc.system.service.ISysConfigService;
import org.wfc.system.service.ISysDeptService;
import org.wfc.system.service.ISysPermissionService;
@@ -79,12 +81,24 @@ public class SysUserController extends BaseController
private MessageSource messageSource;
/**
* 获取用户列表
* 测试国际化
*/
@GetMapping("/test")
public String test()
{
return MessageUtils.message("user.jcaptcha.error");
return MessageUtils.message("user.register.save.error", "test");
}
/**
* 检查重复
*/
@PostMapping("/checkRepeat")
public R<Boolean> checkRepeat(@RequestBody UserRepeatQuery query)
{
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(query, sysUser);
return R.ok(!userService.checkUserNameUnique(sysUser) || !userService.checkPhoneUnique(sysUser)
|| !userService.checkEmailUnique(sysUser));
}
/**
@@ -165,8 +179,19 @@ public class SysUserController extends BaseController
}
if (!userService.checkUserNameUnique(sysUser))
{
return R.fail("保存用户'" + username + "'失败,注册账号已存在");
return R.fail("user.register.save.error");
}
if (!userService.checkPhoneUnique(sysUser))
{
return R.fail("user.register.phone.save.error");
}
if (!userService.checkEmailUnique(sysUser))
{
return R.fail("user.register.email.save.error");
}
return R.ok(userService.registerUser(sysUser));
}

View File

@@ -0,0 +1,15 @@
package org.wfc.system.domain.query;
import lombok.Data;
/**
* @description: 用户重复query
* @author: caiyuchao
* @date: 2024-11-27
*/
@Data
public class UserRepeatQuery {
private String userName;
private String email;
private String phonenumber;
}

View File

@@ -1,9 +1,10 @@
package org.wfc.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.wfc.system.api.domain.SysUser;
import java.util.List;
/**
* 用户表 数据层
*

View File

@@ -23,6 +23,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="fullName" column="full_name" />
<result property="age" column="age" />
<result property="address" column="address" />
<association property="dept" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap>
@@ -156,6 +159,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">status,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="fullName != null and fullName != ''">full_name,</if>
<if test="age != null and age != ''">age,</if>
<if test="address != null and address != ''">address,</if>
create_time
)values(
<if test="userId != null and userId != ''">#{userId},</if>
@@ -170,6 +176,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">#{status},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="fullName != null and fullName != ''">#{fullName},</if>
<if test="age != null and age != ''">#{age},</if>
<if test="address != null and address != ''">#{address},</if>
sysdate()
)
</insert>