131 lines
4.9 KiB
Java
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);
|
|
}
|
|
}
|