baogutang-music/src/main/java/top/baogutang/music/service/impl/UserServiceImpl.java
2024-12-13 18:32:31 +08:00

131 lines
4.9 KiB
Java

package top.baogutang.music.service.impl;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import top.baogutang.music.dao.entity.UserEntity;
import top.baogutang.music.dao.mapper.UserMapper;
import top.baogutang.music.domain.req.user.UserRegisterAndLoginReq;
import top.baogutang.music.domain.res.user.UserLoginRes;
import top.baogutang.music.enums.UserLevel;
import top.baogutang.music.enums.UserRole;
import top.baogutang.music.exceptions.BusinessException;
import top.baogutang.music.exceptions.LoginException;
import top.baogutang.music.service.IUserService;
import top.baogutang.music.utils.CacheUtil;
import top.baogutang.music.utils.TokenUtil;
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static top.baogutang.music.constants.CacheKey.KEY_LOGIN_PREFIX;
import static top.baogutang.music.constants.CacheKey.LOCK_REGISTER_PREFIX;
/**
*
* @description:
*
* @author: N1KO
* @date: 2024/12/13 : 16:44
*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements IUserService {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
public void register(UserRegisterAndLoginReq req) {
// 校验
UserEntity existsUser = this.validate(req);
if (Objects.nonNull(existsUser)) {
throw new BusinessException("当前用户名已被注册");
}
// 密码加密
UserEntity user = new UserEntity();
user.setUsername(req.getUsername());
user.setPassword(encryptPassword(req.getPassword()));
user.setRole(UserRole.NORMAL);
user.setLevel(UserLevel.NORMAL);
user.setCreateTime(LocalDateTime.now());
save(user);
}
@Override
public UserLoginRes login(UserRegisterAndLoginReq req) {
UserEntity existsUser = this.validate(req);
if (Objects.isNull(existsUser)) {
throw new BusinessException("用户不存在");
}
boolean checkRes = this.verifyPassword(req.getPassword(), existsUser.getPassword());
if (!Boolean.TRUE.equals(checkRes)) {
throw new LoginException("用户名或密码错误");
}
UserLoginRes loginRes = new UserLoginRes();
loginRes.setId(existsUser.getId());
loginRes.setUsername(existsUser.getUsername());
loginRes.setLevel(existsUser.getLevel());
loginRes.setRole(existsUser.getRole());
// 生成token
String token = TokenUtil.token(existsUser.getId(), loginRes.getUsername());
redisTemplate.opsForValue().set(KEY_LOGIN_PREFIX + existsUser.getId(), token, 86400000, TimeUnit.MILLISECONDS);
loginRes.setToken(token);
return loginRes;
}
@Override
public void logout(Long id) {
redisTemplate.delete(KEY_LOGIN_PREFIX + id);
}
private UserEntity validate(UserRegisterAndLoginReq req) {
if (StringUtils.isBlank(req.getUsername())) {
throw new BusinessException("用户名不能为空");
}
if (StringUtils.isBlank(req.getPassword())) {
throw new BusinessException("密码不能为空");
}
if (req.getPassword().length() < 6 || req.getPassword().length() > 16) {
throw new BusinessException("密码长度不合规");
}
if (req.getUsername().length() < 4 || req.getUsername().length() > 12) {
throw new BusinessException("用户名长度不合规");
}
return new LambdaQueryChainWrapper<>(baseMapper)
.eq(UserEntity::getUsername, req.getUsername())
.eq(UserEntity::getDeleted, Boolean.FALSE)
.last(" limit 1")
.one();
}
// 密码加密方法
public String encryptPassword(String password) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new BusinessException("请稍后再试");
}
}
// 登录验证方法
public boolean verifyPassword(String inputPassword, String encryptedPassword) {
String inputEncryptedPassword = encryptPassword(inputPassword);
return encryptedPassword.equals(inputEncryptedPassword);
}
}