123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- package com.example.demo.user.service.impl;
- import cn.hutool.core.util.IdUtil;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.example.demo.common.utils.Md5Util;
- import com.example.demo.common.utils.RedisClient;
- import com.example.demo.common.utils.TokenUtils;
- import com.example.demo.user.domain.User;
- import com.example.demo.user.dto.LoginDto;
- import com.example.demo.user.dto.PerfectDto;
- import com.example.demo.user.dto.PhoneDto;
- import com.example.demo.user.dto.RegisterDto;
- import com.example.demo.user.service.UserService;
- import com.example.demo.user.dao.UserMapper;
- import com.example.demo.user.vo.ResultVo;
- import lombok.extern.slf4j.Slf4j;
- import org.redisson.api.RLock;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.stereotype.Service;
- import java.util.UUID;
- import java.util.concurrent.TimeUnit;
- /**
- * @author 徐乐
- * @description 针对表【user(用户基础信息表)】的数据库操作Service实现
- * @createDate 2025-06-04 17:31:35
- */
- @Slf4j
- @Service
- public class UserServiceImpl extends ServiceImpl<UserMapper, User>
- implements UserService{
- @Autowired
- private UserMapper userMapper;
- @Autowired
- private RedissonClient redissonClient;
- @Autowired
- private RedisTemplate<String,String> redisTemplate;
- @Autowired
- private RedisClient redisClient;
- @Override
- public ResultVo register(RegisterDto dto) {
- // 获取验证码
- Object code = getVerificationCode(dto.getPhone());
- if (code == null) {
- return ResultVo.error(201, "验证码已过期");
- }
- String codeStr = String.valueOf(code);
- String userCode = dto.getCode();
- if (!codeStr.equals(userCode)) {
- return ResultVo.error(202, "验证码错误");
- }
- // 删除已使用的验证码
- deleteVerificationCode(dto.getPhone());
- QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
- userQueryWrapper.eq("phone", dto.getPhone());
- log.info("加锁");
- RLock lock = redissonClient.getLock(dto.getPhone());
- try {
- log.info("获取锁");
- boolean lockSuccess = lock.tryLock(3, TimeUnit.SECONDS);
- if (!lockSuccess) {
- throw new RuntimeException("操作频繁,请稍后再试");
- }
- User user = userMapper.selectOne(userQueryWrapper);
- if (user != null) {
- return ResultVo.error("用户已存在");
- }
- log.info("注册");
- User u = new User();
- u.setId(IdUtil.getSnowflake().nextId());
- //生成盐值
- String uuid = UUID.randomUUID().toString().replaceAll("-", "");
- u.setSalt(uuid);
- //获取密码
- String password = dto.getPassword();
- //加密
- String md5Password = Md5Util.MD5(uuid + password);
- u.setPassword(md5Password);
- u.setPhone(dto.getPhone());
- u.setEmail(u.getPhone()+"@example.com");
- userMapper.insert(u);
- return ResultVo.success("注册成功");
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException("注册过程中出现异常,请稍后再试");
- } finally {
- if (lock.isLocked() && lock.isHeldByCurrentThread()) {
- log.info("释放锁");
- lock.unlock();
- }
- }
- }
- /**
- * 统一获取验证码方法
- * @param phone 手机号
- * @return 验证码
- */
- private Object getVerificationCode(String phone) {
- String key = "CODE:" + phone;
- return redisClient.get(key);
- }
- /**
- * 统一删除验证码方法
- * @param phone 手机号
- */
- private void deleteVerificationCode(String phone) {
- String key = "CODE:" + phone;
- redisClient.del(key);
- }
- @Override
- public ResultVo login(LoginDto dto) {
- QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
- userQueryWrapper.eq("phone",dto.getPhone());
- User user = userMapper.selectOne(userQueryWrapper);
- if (user==null){
- return ResultVo.error("用户不存在");
- }
- //获取盐值
- String salt = user.getSalt();
- //获取密码
- String password = dto.getPassword();
- //加密
- String encryptedPassword = Md5Util.MD5(salt + password);
- if (encryptedPassword.equals(user.getPassword())){
- String token = TokenUtils.createJwtToken(user.getId().toString());
- // 使用用户ID作为键名的一部分
- redisTemplate.opsForValue().set("userToken:" + user.getId(), token);
- redisTemplate.expire("userToken:" + user.getId(), 24, TimeUnit.HOURS); // 设置24小时过期
- return ResultVo.success(token);
- }
- return ResultVo.error("用户名或密码有误");
- }
- @Override
- public ResultVo phoneLogin(PhoneDto dto) {
- // 参数校验
- if (dto.getPhone() == null ||!dto.getPhone().matches("1[3-9]\\d{9}")) {
- return ResultVo.error(400, "手机号格式错误");
- }
- // 获取验证码
- Integer code = (Integer) getVerificationCode(dto.getPhone());
- if (code == null) {
- // logger.info("手机号 {} 验证码已过期", dto.getPhone());
- return ResultVo.error(201, "验证码已过期");
- }
- // 验证验证码
- String codeStr = String.valueOf(code);
- String userCode = dto.getCode();
- if (userCode == null ||!userCode.matches("\\d{6}")) {
- // logger.info("手机号 {} 输入的验证码格式错误", dto.getPhone());
- return ResultVo.error(203, "验证码格式错误");
- }
- if (!codeStr.equals(userCode)) {
- // logger.info("手机号 {} 验证码错误,Redis: {}, 用户输入: {}",
- // dto.getPhone(), codeStr, userCode);
- return ResultVo.error(202, "验证码错误");
- }
- // 验证通过后删除验证码
- deleteVerificationCode(dto.getPhone());
- // 先判断账号是否存在
- QueryWrapper<User> queryWrapper = new QueryWrapper<>();
- queryWrapper.lambda().eq(User::getPhone, dto.getPhone());
- User user = userMapper.selectOne(queryWrapper);
- // if (user == null) {
- // user.setUsername("随机账户"+String.valueOf(IdUtil.getSnowflake().nextId()));
- // user.setId(IdUtil.getSnowflake().nextId());
- // userMapper.insert(user);
- // redisClient.set("uid", user.getId());
- // redisClient.expire("uid", 60*60);
- // Long id = user.getId();
- // String token = AppJwtUtil.getToken(id);
- // redisClient.set("token", token);
- // Map<String, String> map = new HashMap<>();
- // map.put("token",token);
- // return ResultVo.success(map);
- // }
- // redisClient.set("uid", user.getId());
- // redisClient.expire("uid", 60*60);
- String token = TokenUtils.createJwtToken(user.getId().toString());
- // 使用用户ID作为键名的一部分
- redisTemplate.opsForValue().set("userToken:" + user.getId(), token);
- redisTemplate.expire("userToken:" + user.getId(), 24, TimeUnit.HOURS); // 设置24小时过期
- return ResultVo.success(token);
- }
- @Override
- public ResultVo forget(RegisterDto dto) {
- QueryWrapper<User> queryWrapper = new QueryWrapper<>();
- queryWrapper.eq("phone",dto.getPhone());
- User user = userMapper.selectOne(queryWrapper);
- if (user==null){
- return ResultVo.error("用户不存在");
- }
- // 获取验证码
- Object code = getVerificationCode(dto.getPhone());
- if (code == null) {
- return ResultVo.error(201, "验证码已过期");
- }
- String codeStr = String.valueOf(code);
- String userCode = dto.getCode();
- if (!codeStr.equals(userCode)) {
- return ResultVo.error(202, "验证码错误");
- }
- // 删除已使用的验证码
- deleteVerificationCode(dto.getPhone());
- //生成盐值
- String uuid = UUID.randomUUID().toString().replaceAll("-", "");
- user.setSalt(uuid);
- //获取密码
- String password = dto.getPassword();
- //加密
- String md5Password = Md5Util.MD5(uuid + password);
- user.setPassword(md5Password);
- userMapper.updateById(user);
- return ResultVo.success("找回成功");
- }
- @Override
- public ResultVo logout(String token) {
- if (token == null || token.isEmpty()) {
- return ResultVo.error("无效的token");
- }
-
- try {
- // 解析token获取用户ID
- Long userId = TokenUtils.getUserId(token);
- if (userId == null) {
- return ResultVo.error("无效的token");
- }
-
- // 从Redis删除token
- redisTemplate.delete("userToken:" + userId);
-
- // 可以设置token黑名单,防止已注销的token被再次使用
- String blacklistKey = "token:blacklist:" + token;
- redisTemplate.opsForValue().set(blacklistKey, "1");
- redisTemplate.expire(blacklistKey, 24, TimeUnit.HOURS); // 设置黑名单24小时过期
-
- log.info("用户{}已成功退出登录", userId);
- return ResultVo.success("退出成功");
- } catch (Exception e) {
- log.error("注销失败", e);
- return ResultVo.error("注销失败,请稍后再试");
- }
- }
- @Override
- public ResultVo perfect(String token,PerfectDto dto) {
- Long userId = TokenUtils.getUserId(token);
- if (userId==null){
- return ResultVo.error("用户不存在");
- }
- User user = userMapper.selectById(userId);
- user.setUsername(dto.getUsername());
- user.setEmail(dto.getEmail());
- user.setAvatar(dto.getAvatar());
- userMapper.updateById(user);
- return ResultVo.success("完善用户信息成功");
- }
- }
|