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 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 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 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 accountQueryWrapper = new QueryWrapper<>(); accountQueryWrapper.eq("userAccount", userAccount); long accountCount = this.baseMapper.selectCount(accountQueryWrapper); if (accountCount > 0) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号已存在"); } // 手机号不能重复 QueryWrapper 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 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()); } }