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 implements IUserService { @Resource private RedisTemplate 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); } }