|
|
@ -1,6 +1,5 @@
|
|
|
|
package com.yami.shop.api.controller;
|
|
|
|
package com.yami.shop.api.controller;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.util.IdUtil;
|
|
|
|
import cn.hutool.core.util.IdUtil;
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
@ -24,7 +23,9 @@ import jakarta.validation.Valid;
|
|
|
|
import java.util.Date;
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 用户信息
|
|
|
|
* 用户注册相关接口的控制器类,用于处理用户注册以及修改密码等与用户信息相关的核心操作,
|
|
|
|
|
|
|
|
* 通过调用不同的服务层方法以及相关的工具类来完成业务逻辑,例如验证用户名是否已存在、密码加密、生成用户标识等操作,
|
|
|
|
|
|
|
|
* 并以统一的响应格式返回操作结果给前端使用。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @author SJL
|
|
|
|
* @author SJL
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -34,68 +35,118 @@ import java.util.Date;
|
|
|
|
@AllArgsConstructor
|
|
|
|
@AllArgsConstructor
|
|
|
|
public class UserRegisterController {
|
|
|
|
public class UserRegisterController {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 通过构造函数注入的方式引入用户服务层接口,用于调用与用户相关的业务逻辑方法,比如保存用户信息、根据条件查询用户等操作。
|
|
|
|
private final UserService userService;
|
|
|
|
private final UserService userService;
|
|
|
|
|
|
|
|
// 通过构造函数注入的方式引入密码编码器,用于对用户密码进行加密处理,保证密码在存储和传输过程中的安全性。
|
|
|
|
private final PasswordEncoder passwordEncoder;
|
|
|
|
private final PasswordEncoder passwordEncoder;
|
|
|
|
|
|
|
|
// 通过构造函数注入的方式引入令牌存储相关的类,用于处理用户登录后令牌的生成、存储以及获取相关信息等操作,实现用户身份认证和授权相关功能。
|
|
|
|
private final TokenStore tokenStore;
|
|
|
|
private final TokenStore tokenStore;
|
|
|
|
|
|
|
|
// 通过构造函数注入的方式引入密码管理相关的类,可能用于对用户输入的密码进行解密(如果有加密传输等情况)或者其他密码相关的管理操作。
|
|
|
|
private final PasswordManager passwordManager;
|
|
|
|
private final PasswordManager passwordManager;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 用户注册或绑定手机号的方法,接收包含用户注册信息的参数对象,先进行用户名的合法性验证(若昵称为空则使用用户名作为昵称),
|
|
|
|
|
|
|
|
* 然后检查用户名是否已被注册,若未被注册则创建新用户对象,设置相关属性(如注册时间、状态等),对密码进行解密和加密处理后保存用户信息到数据库,
|
|
|
|
|
|
|
|
* 最后模拟用户登录操作,生成并返回包含令牌信息的响应结果给前端,用于后续的身份认证和授权访问。
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param userRegisterParam 包含用户注册信息的参数对象,通过请求体传入,且经过了参数验证(@Valid 注解),例如用户名、密码、邮箱等信息。
|
|
|
|
|
|
|
|
* @return 包含令牌信息的 ServerResponseEntity,以 TokenInfoVO 类型封装令牌相关内容,若注册成功则返回对应的令牌信息,若用户名已注册等情况则抛出相应异常。
|
|
|
|
|
|
|
|
*/
|
|
|
|
@PostMapping("/register")
|
|
|
|
@PostMapping("/register")
|
|
|
|
@Operation(summary = "注册", description = "用户注册或绑定手机号接口")
|
|
|
|
@Operation(summary = "注册", description = "用户注册或绑定手机号接口")
|
|
|
|
public ServerResponseEntity<TokenInfoVO> register(@Valid @RequestBody UserRegisterParam userRegisterParam) {
|
|
|
|
public ServerResponseEntity<TokenInfoVO> register(@Valid @RequestBody UserRegisterParam userRegisterParam) {
|
|
|
|
|
|
|
|
// 如果用户注册参数中的昵称(nickName)为空字符串,则将用户名(userName)作为昵称使用,保证昵称有值。
|
|
|
|
if (StrUtil.isBlank(userRegisterParam.getNickName())) {
|
|
|
|
if (StrUtil.isBlank(userRegisterParam.getNickName())) {
|
|
|
|
userRegisterParam.setNickName(userRegisterParam.getUserName());
|
|
|
|
userRegisterParam.setNickName(userRegisterParam.getUserName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 正在进行申请注册
|
|
|
|
|
|
|
|
|
|
|
|
// 通过用户服务层的方法,使用 MyBatis Plus 的 LambdaQueryWrapper 构建查询条件,统计数据库中昵称与传入的昵称相同的用户数量,
|
|
|
|
|
|
|
|
// 如果数量大于 0,则表示该用户名(昵称)已被注册,抛出异常提示用户无法重新注册。
|
|
|
|
if (userService.count(new LambdaQueryWrapper<User>().eq(User::getNickName, userRegisterParam.getNickName())) > 0) {
|
|
|
|
if (userService.count(new LambdaQueryWrapper<User>().eq(User::getNickName, userRegisterParam.getNickName())) > 0) {
|
|
|
|
// 该用户名已注册,无法重新注册
|
|
|
|
// 该用户名已注册,无法重新注册
|
|
|
|
throw new YamiShopBindException("该用户名已注册,无法重新注册");
|
|
|
|
throw new YamiShopBindException("该用户名已注册,无法重新注册");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建当前时间对象,用于设置用户的修改时间、注册时间等属性,确保记录的时间信息准确。
|
|
|
|
Date now = new Date();
|
|
|
|
Date now = new Date();
|
|
|
|
|
|
|
|
// 创建一个新的用户对象,用于填充用户注册信息并保存到数据库中。
|
|
|
|
User user = new User();
|
|
|
|
User user = new User();
|
|
|
|
|
|
|
|
// 设置用户的修改时间为当前时间,表示该用户信息的最近一次修改时间。
|
|
|
|
user.setModifyTime(now);
|
|
|
|
user.setModifyTime(now);
|
|
|
|
|
|
|
|
// 设置用户的注册时间为当前时间,记录用户注册的具体时间点。
|
|
|
|
user.setUserRegtime(now);
|
|
|
|
user.setUserRegtime(now);
|
|
|
|
|
|
|
|
// 设置用户状态为有效(这里假设状态值为 1 表示有效,可根据实际业务定义调整)。
|
|
|
|
user.setStatus(1);
|
|
|
|
user.setStatus(1);
|
|
|
|
|
|
|
|
// 设置用户的昵称,使用经过前面逻辑处理后的昵称值(可能是原昵称或者用户名)。
|
|
|
|
user.setNickName(userRegisterParam.getNickName());
|
|
|
|
user.setNickName(userRegisterParam.getNickName());
|
|
|
|
|
|
|
|
// 设置用户的邮箱信息,从注册参数中获取并赋值给用户对象。
|
|
|
|
user.setUserMail(userRegisterParam.getUserMail());
|
|
|
|
user.setUserMail(userRegisterParam.getUserMail());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 通过密码管理类的方法,对用户注册参数中传入的密码进行解密操作(可能是之前加密传输过来的情况),获取解密后的密码字符串。
|
|
|
|
String decryptPassword = passwordManager.decryptPassword(userRegisterParam.getPassWord());
|
|
|
|
String decryptPassword = passwordManager.decryptPassword(userRegisterParam.getPassWord());
|
|
|
|
|
|
|
|
// 使用密码编码器对解密后的密码进行加密处理,将加密后的密码设置到用户对象中,保证密码在数据库中以加密形式存储,提高安全性。
|
|
|
|
user.setLoginPassword(passwordEncoder.encode(decryptPassword));
|
|
|
|
user.setLoginPassword(passwordEncoder.encode(decryptPassword));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 Hutool 工具类生成一个简单的唯一用户 ID(这里采用 UUID 的简化形式,可根据实际需求调整生成方式),作为用户的标识。
|
|
|
|
String userId = IdUtil.simpleUUID();
|
|
|
|
String userId = IdUtil.simpleUUID();
|
|
|
|
|
|
|
|
// 将生成的用户 ID 设置到用户对象中,确保每个用户在系统中有唯一的标识。
|
|
|
|
user.setUserId(userId);
|
|
|
|
user.setUserId(userId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用用户服务层的保存方法,将填充好信息的用户对象保存到数据库中,完成用户注册操作。
|
|
|
|
userService.save(user);
|
|
|
|
userService.save(user);
|
|
|
|
// 2. 登录
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟用户登录操作,创建一个用于存储在令牌中的用户信息对象,填充用户 ID、用户类型(这里设置为普通用户,通过枚举值获取)、是否为管理员(这里设置为否)以及是否启用等信息。
|
|
|
|
UserInfoInTokenBO userInfoInTokenBO = new UserInfoInTokenBO();
|
|
|
|
UserInfoInTokenBO userInfoInTokenBO = new UserInfoInTokenBO();
|
|
|
|
userInfoInTokenBO.setUserId(user.getUserId());
|
|
|
|
userInfoInTokenBO.setUserId(user.getUserId());
|
|
|
|
userInfoInTokenBO.setSysType(SysTypeEnum.ORDINARY.value());
|
|
|
|
userInfoInTokenBO.setSysType(SysTypeEnum.ORDINARY.value());
|
|
|
|
userInfoInTokenBO.setIsAdmin(0);
|
|
|
|
userInfoInTokenBO.setIsAdmin(0);
|
|
|
|
userInfoInTokenBO.setEnabled(true);
|
|
|
|
userInfoInTokenBO.setEnabled(true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 通过令牌存储类的方法,将用户信息存储并生成对应的令牌信息对象,然后返回包含令牌信息的响应结果给前端,方便后续用户进行身份认证和授权访问。
|
|
|
|
return ServerResponseEntity.success(tokenStore.storeAndGetVo(userInfoInTokenBO));
|
|
|
|
return ServerResponseEntity.success(tokenStore.storeAndGetVo(userInfoInTokenBO));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 修改用户密码的方法,接收包含修改密码相关信息的参数对象,先根据用户名从数据库中查询用户信息,若用户不存在则抛出异常,
|
|
|
|
|
|
|
|
* 接着对新密码进行解密和合法性验证(不能为空且不能与原密码相同),然后对新密码进行加密处理,更新用户的密码信息到数据库中,
|
|
|
|
|
|
|
|
* 最后返回表示修改成功的响应结果给前端,若验证不通过等情况则抛出相应的异常。
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param userPwdUpdateParam 包含修改密码相关信息的参数对象,通过请求体传入,且经过了参数验证(@Valid 注解),例如用户名、新密码等信息。
|
|
|
|
|
|
|
|
* @return 表示修改密码操作成功的 ServerResponseEntity,若修改成功则返回空的成功响应,若用户不存在、新密码不符合要求等情况则抛出相应异常。
|
|
|
|
|
|
|
|
*/
|
|
|
|
@PutMapping("/updatePwd")
|
|
|
|
@PutMapping("/updatePwd")
|
|
|
|
@Operation(summary = "修改密码", description = "修改密码")
|
|
|
|
@Operation(summary = "修改密码", description = "修改密码")
|
|
|
|
public ServerResponseEntity<Void> updatePwd(@Valid @RequestBody UserRegisterParam userPwdUpdateParam) {
|
|
|
|
public ServerResponseEntity<Void> updatePwd(@Valid @RequestBody UserRegisterParam userPwdUpdateParam) {
|
|
|
|
|
|
|
|
// 通过用户服务层的方法,使用 MyBatis Plus 的 LambdaQueryWrapper 构建查询条件,根据用户名(昵称)从数据库中查询对应的用户信息,若查询不到则抛出异常提示无法获取用户信息。
|
|
|
|
User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getNickName, userPwdUpdateParam.getNickName()));
|
|
|
|
User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getNickName, userPwdUpdateParam.getNickName()));
|
|
|
|
if (user == null) {
|
|
|
|
if (user == null) {
|
|
|
|
// 无法获取用户信息
|
|
|
|
// 无法获取用户信息
|
|
|
|
throw new YamiShopBindException("无法获取用户信息");
|
|
|
|
throw new YamiShopBindException("无法获取用户信息");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 通过密码管理类的方法,对用户修改密码参数中传入的新密码进行解密操作(可能是之前加密传输过来的情况),获取解密后的密码字符串。
|
|
|
|
String decryptPassword = passwordManager.decryptPassword(userPwdUpdateParam.getPassWord());
|
|
|
|
String decryptPassword = passwordManager.decryptPassword(userPwdUpdateParam.getPassWord());
|
|
|
|
|
|
|
|
// 如果解密后的新密码为空字符串,则抛出异常提示新密码不能为空。
|
|
|
|
if (StrUtil.isBlank(decryptPassword)) {
|
|
|
|
if (StrUtil.isBlank(decryptPassword)) {
|
|
|
|
// 新密码不能为空
|
|
|
|
// 新密码不能为空
|
|
|
|
throw new YamiShopBindException("新密码不能为空");
|
|
|
|
throw new YamiShopBindException("新密码不能为空");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 使用密码编码器对解密后的新密码进行加密处理,得到加密后的密码字符串。
|
|
|
|
String password = passwordEncoder.encode(decryptPassword);
|
|
|
|
String password = passwordEncoder.encode(decryptPassword);
|
|
|
|
|
|
|
|
// 如果加密后的新密码与用户原密码相同,则抛出异常提示新密码不能与原密码相同,保证密码修改的合理性。
|
|
|
|
if (StrUtil.equals(password, user.getLoginPassword())) {
|
|
|
|
if (StrUtil.equals(password, user.getLoginPassword())) {
|
|
|
|
// 新密码不能与原密码相同
|
|
|
|
// 新密码不能与原密码相同
|
|
|
|
throw new YamiShopBindException("新密码不能与原密码相同");
|
|
|
|
throw new YamiShopBindException("新密码不能与原密码相同");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置用户的修改时间为当前时间,表示此次密码修改操作的时间。
|
|
|
|
user.setModifyTime(new Date());
|
|
|
|
user.setModifyTime(new Date());
|
|
|
|
|
|
|
|
// 将加密后的新密码设置到用户对象中,更新用户的密码信息到数据库中,完成密码修改操作。
|
|
|
|
user.setLoginPassword(password);
|
|
|
|
user.setLoginPassword(password);
|
|
|
|
|
|
|
|
// 调用用户服务层的更新方法,将更新后的用户对象信息保存到数据库中,确保密码修改生效。
|
|
|
|
userService.updateById(user);
|
|
|
|
userService.updateById(user);
|
|
|
|
|
|
|
|
|
|
|
|
return ServerResponseEntity.success();
|
|
|
|
return ServerResponseEntity.success();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|