Files
cpzs-backend/src/main/java/com/xy/xyaicpzs/service/impl/UserServiceImpl.java

332 lines
13 KiB
Java
Raw Normal View History

2025-08-01 19:09:57 +08:00
package com.xy.xyaicpzs.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xy.xyaicpzs.common.ErrorCode;
import com.xy.xyaicpzs.constant.UserConstant;
import com.xy.xyaicpzs.domain.dto.user.UserPhoneLoginRequest;
import com.xy.xyaicpzs.domain.dto.user.UserPhoneRegisterRequest;
import com.xy.xyaicpzs.domain.entity.User;
import com.xy.xyaicpzs.exception.BusinessException;
import com.xy.xyaicpzs.mapper.UserMapper;
import com.xy.xyaicpzs.service.SmsService;
import com.xy.xyaicpzs.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author XY003
* @description 针对表user(用户表)的数据库操作Service实现
* @createDate 2025-06-14 09:48:10
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService{
/**
* 盐值混淆密码
*/
private static final String SALT = "xy";
@Autowired
private SmsService smsService;
@Override
public long userRegister(String userAccount, String userName, String userPassword, String checkPassword) {
// 1. 校验
if (StringUtils.isAnyBlank(userAccount, userName, userPassword, checkPassword)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
}
if (userAccount.length() < 4) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
}
if (userName.length() > 40) {
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, "两次输入的密码不一致");
}
synchronized (userAccount.intern()) {
// 账户不能重复
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
long count = this.baseMapper.selectCount(queryWrapper);
if (count > 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
}
// 2. 加密
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
// 3. 插入数据
User user = new User();
user.setUserAccount(userAccount);
user.setUserName(userName);
user.setUserPassword(encryptPassword);
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
// 设置为VIP用户有效期10天
user.setIsVip(1);
Date vipExpireDate = new Date(System.currentTimeMillis() + 10L * 24 * 60 * 60 * 1000);
user.setVipExpire(vipExpireDate);
boolean saveResult = this.save(user);
if (!saveResult) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误");
}
return user.getId();
}
}
@Override
public User userLogin(String userAccount, String userPassword, HttpServletRequest request) {
// 1. 校验
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, "密码错误");
}
// 2. 加密
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
// 查询用户是否存在
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, "用户不存在或密码错误");
}
// 3. 记录用户的登录态
request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, user);
return getSafetyUser(user);
}
/**
* 获取当前登录用户
*
* @param request
* @return
*/
@Override
public User getLoginUser(HttpServletRequest request) {
// 先判断是否已登录
Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
User currentUser = (User) userObj;
if (currentUser == null || currentUser.getId() == null) {
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
}
// 从数据库查询(追求性能的话可以注释,直接走缓存)
long userId = currentUser.getId();
currentUser = this.getById(userId);
if (currentUser == null) {
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
}
return currentUser;
}
/**
* 用户注销
*
* @param request
*/
@Override
public boolean userLogout(HttpServletRequest request) {
if (request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE) == null) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
}
// 移除登录态
request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
return true;
}
@Override
public User getSafetyUser(User originUser) {
if (originUser == null) {
return null;
}
User safetyUser = new User();
safetyUser.setId(originUser.getId());
safetyUser.setUserName(originUser.getUserName());
safetyUser.setUserAccount(originUser.getUserAccount());
safetyUser.setUserAvatar(originUser.getUserAvatar());
safetyUser.setUserRole(originUser.getUserRole());
safetyUser.setCreateTime(originUser.getCreateTime());
safetyUser.setUpdateTime(originUser.getUpdateTime());
return safetyUser;
}
@Override
public boolean isAdmin(HttpServletRequest request) {
// 仅管理员可查询
Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
User user = (User) userObj;
return isAdmin(user);
}
@Override
public boolean isAdmin(User user) {
return user != null && (UserConstant.ADMIN_ROLE.equals(user.getUserRole())
|| UserConstant.SUPER_ADMIN_ROLE.equals(user.getUserRole()));
}
@Override
public long userPhoneRegister(UserPhoneRegisterRequest userPhoneRegisterRequest) {
if (userPhoneRegisterRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
String userAccount = userPhoneRegisterRequest.getUserAccount();
String userPassword = userPhoneRegisterRequest.getUserPassword();
String checkPassword = userPhoneRegisterRequest.getCheckPassword();
String phone = userPhoneRegisterRequest.getPhone();
String code = userPhoneRegisterRequest.getCode();
String userName = userPhoneRegisterRequest.getUserName();
// 1. 校验
if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword, phone, code)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
}
// 用户名可以为空,如果为空则默认使用账号
if (StringUtils.isBlank(userName)) {
userName = userAccount;
}
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, "两次输入的密码不一致");
}
// 验证手机号格式
String phoneRegex = "^1[3-9]\\d{9}$";
if (!phone.matches(phoneRegex)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式错误");
}
// 验证短信验证码
boolean isCodeValid = smsService.verifyCode(phone, code);
if (!isCodeValid) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误或已过期");
}
synchronized (userAccount.intern()) {
// 账户不能重复
QueryWrapper<User> accountQueryWrapper = new QueryWrapper<>();
accountQueryWrapper.eq("userAccount", userAccount);
long accountCount = this.baseMapper.selectCount(accountQueryWrapper);
if (accountCount > 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号已存在");
}
// 手机号不能重复
QueryWrapper<User> phoneQueryWrapper = new QueryWrapper<>();
phoneQueryWrapper.eq("phone", phone);
long phoneCount = this.baseMapper.selectCount(phoneQueryWrapper);
if (phoneCount > 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号已注册");
}
// 2. 加密
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
// 3. 插入数据
User user = new User();
user.setUserAccount(userAccount);
user.setUserPassword(encryptPassword);
user.setPhone(phone);
// 设置用户名
user.setUserName(userName);
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
// 设置为VIP用户有效期10天
user.setIsVip(0);
Date vipExpireDate = new Date(System.currentTimeMillis() + 10L * 24 * 60 * 60 * 1000);
user.setVipExpire(vipExpireDate);
boolean saveResult = this.save(user);
if (!saveResult) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误");
}
return user.getId();
}
}
@Override
public User userPhoneLogin(UserPhoneLoginRequest userPhoneLoginRequest, HttpServletRequest request) {
if (userPhoneLoginRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
String phone = userPhoneLoginRequest.getPhone();
String code = userPhoneLoginRequest.getCode();
// 1. 校验参数
if (StringUtils.isAnyBlank(phone, code)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
}
// 验证手机号格式
String phoneRegex = "^1[3-9]\\d{9}$";
if (!phone.matches(phoneRegex)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式错误");
}
// 验证短信验证码
boolean isCodeValid = smsService.verifyCode(phone, code);
if (!isCodeValid) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误或已过期");
}
// 查询用户是否存在
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("phone", phone);
User user = this.baseMapper.selectOne(queryWrapper);
// 用户不存在
if (user == null) {
log.info("user login failed, phone number not registered");
throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号未注册");
}
// 3. 记录用户的登录态
request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, user);
return getSafetyUser(user);
}
@Override
public String encryptPassword(String password) {
if (StringUtils.isBlank(password)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码不能为空");
}
return DigestUtils.md5DigestAsHex((SALT + password).getBytes());
}
}