跳转至

用户相关操作

1. 整体架构

此项目运用了 Spring Boot 框架构建 Web 应用,采用 MVC(Model - View - Controller)架构模式。Controller 层负责处理 HTTP 请求,Service 层承担业务逻辑处理,Mapper 层(借助 MyBatis - Plus 实现)负责与数据库交互。

2. 注册功能实现技术

2.1 接口定义

UserController 里定义了 /user/register 接口,其接收 UserRegisterRequest 对象,这是一个封装了用户注册所需信息(如用户账户、密码、确认密码)的 DTO(Data Transfer Object)。

Java
1
2
3
4
@PostMapping("/register")
public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
    // ...
}

2.2 业务逻辑处理

UserServiceImpl 类中的 userRegister 方法实现了注册的具体逻辑: - 参数校验:检查用户账户、密码和确认密码是否为空,以及账户长度是否小于 4 位、密码长度是否小于 8 位,还有两次输入的密码是否一致。

Java
if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
}
if (userAccount.length() < 4) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
}
if (userPassword.length() < 8 || checkPassword.length() < 8) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
}
if (!userPassword.equals(checkPassword)) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
}
- 账户唯一性检查:使用 QueryWrapper 查询数据库,判断该账户是否已存在。
Java
1
2
3
4
5
6
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
long count = this.baseMapper.selectCount(queryWrapper);
if (count > 0) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
}
- 密码加密:运用 DigestUtils.md5DigestAsHex 方法对密码进行 MD5 加密,同时添加盐值(SALT)增强安全性。
Java
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
- 数据插入:创建 User 对象,将加密后的密码和用户账户信息存入其中,再调用 save 方法将用户信息插入数据库。
Java
1
2
3
4
5
6
7
User user = new User();
user.setUserAccount(userAccount);
user.setUserPassword(encryptPassword);
boolean saveResult = this.save(user);
if (!saveResult) {
    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误");
}

3. 登录功能实现技术

3.1 接口定义

UserController 中定义了 /user/login 接口,接收 UserLoginRequest 对象和 HttpServletRequest 对象。

Java
1
2
3
4
@PostMapping("/login")
public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
    // ...
}

3.2 业务逻辑处理

UserServiceImpl 类中的 userLogin 方法实现了登录的具体逻辑: - 参数校验:检查用户账户和密码是否为空,以及账户长度是否小于 4 位、密码长度是否小于 8 位。

Java
1
2
3
4
5
6
7
8
9
if (StringUtils.isAnyBlank(userAccount, userPassword)) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
}
if (userAccount.length() < 4) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");
}
if (userPassword.length() < 8) {
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
}
- 密码加密:同样使用 DigestUtils.md5DigestAsHex 方法对输入的密码进行 MD5 加密,并添加盐值。
Java
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
- 用户查询:使用 QueryWrapper 根据用户账户和加密后的密码查询数据库,判断用户是否存在。
Java
1
2
3
4
5
6
7
8
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
queryWrapper.eq("userPassword", encryptPassword);
User user = this.baseMapper.selectOne(queryWrapper);
if (user == null) {
    log.info("user login failed, userAccount cannot match userPassword");
    throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
}
- 记录登录状态:将用户信息存入 HttpSession 中,以此记录用户的登录状态。
Java
request.getSession().setAttribute(USER_LOGIN_STATE, user);

4. 注销功能实现技术

4.1 接口定义

UserController 中定义了 /user/logout 接口,接收 HttpServletRequest 对象。

Java
1
2
3
4
@PostMapping("/logout")
public BaseResponse<Boolean> userLogout(HttpServletRequest request) {
    // ...
}

4.2 业务逻辑处理

UserServiceImpl 类中的 userLogout 方法实现了注销的具体逻辑: - 检查登录状态:判断 HttpSession 中是否存在用户登录状态信息。

Java
1
2
3
if (request.getSession().getAttribute(USER_LOGIN_STATE) == null) {
    throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
}
- 移除登录状态:从 HttpSession 中移除用户登录状态信息。
Java
request.getSession().removeAttribute(USER_LOGIN_STATE);

5. 其他技术要点

  • 异常处理:运用自定义的 BusinessException 类处理业务异常,通过 ErrorCode 枚举类统一管理错误码。
  • 数据脱敏:定义 LoginUserVOUserVO 类对用户信息进行脱敏处理,避免敏感信息泄露。
  • 线程安全:在用户注册和微信登录时,使用 synchronized 关键字保证同一账户或 unionId 的操作是线程安全的。