blob: bb6c0a98eafd79b234c0e2cc2aa9cd6a3ce08052 [file] [log] [blame]
wuchimedes079c1632025-04-02 22:01:20 +08001package com.example.g8backend.controller;
2
夜雨声烦e73ff922025-05-13 18:49:03 +08003import com.example.g8backend.dto.ApiResponse;
wuchimedes5280aa72025-04-03 20:49:34 +08004import com.example.g8backend.dto.UserRegisterDTO;
wuchimedes079c1632025-04-02 22:01:20 +08005import com.example.g8backend.entity.User;
wuchimedes22ee83c2025-04-25 00:17:47 +08006import com.example.g8backend.entity.UserStats;
wuchimedes079c1632025-04-02 22:01:20 +08007import com.example.g8backend.service.IUserService;
wuchimedes22ee83c2025-04-25 00:17:47 +08008import com.example.g8backend.service.IUserStatsService;
wuchimedes079c1632025-04-02 22:01:20 +08009import com.example.g8backend.util.JwtUtil;
wuchimedes5280aa72025-04-03 20:49:34 +080010import com.example.g8backend.util.mailUtil;
wuchimedes079c1632025-04-02 22:01:20 +080011import org.springframework.beans.factory.annotation.Autowired;
wuchimedes18addec2025-04-03 17:59:02 +080012import org.springframework.data.redis.core.RedisTemplate;
22301071fa22ac62025-05-24 21:38:17 +080013import org.springframework.security.core.context.SecurityContextHolder;
wuchimedes079c1632025-04-02 22:01:20 +080014import org.springframework.security.crypto.password.PasswordEncoder;
15import org.springframework.web.bind.annotation.*;
22301071fa22ac62025-05-24 21:38:17 +080016import jakarta.servlet.http.HttpServletRequest;
wuchimedes079c1632025-04-02 22:01:20 +080017import java.util.HashMap;
18import java.util.Map;
wuchimedes5280aa72025-04-03 20:49:34 +080019import java.util.UUID;
wuchimedes079c1632025-04-02 22:01:20 +080020
21@RestController
22@RequestMapping("/auth")
23public class AuthController {
24
25 @Autowired
26 private IUserService userService;
夜雨声烦e73ff922025-05-13 18:49:03 +080027
wuchimedes079c1632025-04-02 22:01:20 +080028 @Autowired
wuchimedes22ee83c2025-04-25 00:17:47 +080029 private IUserStatsService userStatsService;
夜雨声烦e73ff922025-05-13 18:49:03 +080030
wuchimedes22ee83c2025-04-25 00:17:47 +080031 @Autowired
wuchimedes5280aa72025-04-03 20:49:34 +080032 private mailUtil mailUtil;
夜雨声烦e73ff922025-05-13 18:49:03 +080033
wuchimedes5280aa72025-04-03 20:49:34 +080034 @Autowired
wuchimedes079c1632025-04-02 22:01:20 +080035 private PasswordEncoder passwordEncoder;
夜雨声烦e73ff922025-05-13 18:49:03 +080036
wuchimedes079c1632025-04-02 22:01:20 +080037 @Autowired
38 private JwtUtil jwtUtil;
夜雨声烦e73ff922025-05-13 18:49:03 +080039
wuchimedes18addec2025-04-03 17:59:02 +080040 @Autowired
夜雨声烦e73ff922025-05-13 18:49:03 +080041 private RedisTemplate<String, Object> redisTemplate;
wuchimedes18addec2025-04-03 17:59:02 +080042
wuchimedes5280aa72025-04-03 20:49:34 +080043 // 发送验证码
44 @PostMapping("/send_verification_code")
夜雨声烦e73ff922025-05-13 18:49:03 +080045 public ApiResponse<String> sendVerificationCode(@RequestBody UserRegisterDTO registerDTO) {
wuchimedes5280aa72025-04-03 20:49:34 +080046 if (userService.getUserByEmail(registerDTO.getEmail()) != null) {
夜雨声烦e73ff922025-05-13 18:49:03 +080047 return ApiResponse.error(400, "邮箱已存在");
wuchimedes5280aa72025-04-03 20:49:34 +080048 }
49
50 String verificationCode = UUID.randomUUID().toString().substring(0, 6);
51 mailUtil.sendMail(registerDTO.getEmail(), "PT平台注册验证码", "您的验证码为:" + verificationCode + ",验证码十分钟内有效,请勿泄露。");
52
53 redisTemplate.opsForValue().set(registerDTO.getEmail(), verificationCode, 10 * 60, java.util.concurrent.TimeUnit.SECONDS);
夜雨声烦e73ff922025-05-13 18:49:03 +080054 return ApiResponse.success("验证码发送成功");
wuchimedes5280aa72025-04-03 20:49:34 +080055 }
56
wuchimedes079c1632025-04-02 22:01:20 +080057 // 用户注册
58 @PostMapping("/register")
夜雨声烦e73ff922025-05-13 18:49:03 +080059 public ApiResponse<String> register(@RequestBody UserRegisterDTO registerDTO) {
wuchimedes5280aa72025-04-03 20:49:34 +080060 if (userService.getUserByName(registerDTO.getUserName()) != null) {
夜雨声烦e73ff922025-05-13 18:49:03 +080061 return ApiResponse.error(400, "用户名已存在");
wuchimedes079c1632025-04-02 22:01:20 +080062 }
wuchimedes5280aa72025-04-03 20:49:34 +080063
64 if (!redisTemplate.hasKey(registerDTO.getInvitationCode())) {
夜雨声烦e73ff922025-05-13 18:49:03 +080065 return ApiResponse.error(400, "邀请码错误");
wuchimedes5280aa72025-04-03 20:49:34 +080066 }
夜雨声烦e73ff922025-05-13 18:49:03 +080067
68 Object cachedCode = redisTemplate.opsForValue().get(registerDTO.getEmail());
69 if (!registerDTO.getVerificationCode().equals(cachedCode)) {
70 return ApiResponse.error(400, "验证码错误");
wuchimedes5280aa72025-04-03 20:49:34 +080071 }
夜雨声烦e73ff922025-05-13 18:49:03 +080072
wuchimedes5280aa72025-04-03 20:49:34 +080073 redisTemplate.delete(registerDTO.getEmail());
74
75 User user = new User();
76 user.setUserName(registerDTO.getUserName());
77 user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
78 user.setEmail(registerDTO.getEmail());
wuchimedesa0649c62025-04-05 15:53:39 +080079 user.setPasskey(UUID.randomUUID().toString().replace("-", ""));
wuchimedese5722e32025-04-13 17:38:50 +080080 userService.save(user);
wuchimedes5280aa72025-04-03 20:49:34 +080081
wuchimedes22ee83c2025-04-25 00:17:47 +080082 UserStats userStats = new UserStats();
83 userStats.setUserId(user.getUserId());
84 userStats.setPasskey(user.getPasskey());
85 userStatsService.save(userStats);
86
夜雨声烦e73ff922025-05-13 18:49:03 +080087 return ApiResponse.message("注册成功");
wuchimedes079c1632025-04-02 22:01:20 +080088 }
89
90 // 用户登录
91 @PostMapping("/login")
夜雨声烦e73ff922025-05-13 18:49:03 +080092 public ApiResponse<Map<String, String>> login(@RequestBody User user) {
wuchimedes079c1632025-04-02 22:01:20 +080093 User existingUser = userService.getUserByEmail(user.getEmail());
94 if (existingUser == null || !passwordEncoder.matches(user.getPassword(), existingUser.getPassword())) {
夜雨声烦e73ff922025-05-13 18:49:03 +080095 return ApiResponse.error(400, "用户名或密码错误");
wuchimedes079c1632025-04-02 22:01:20 +080096 }
夜雨声烦e73ff922025-05-13 18:49:03 +080097
夜雨声烦7affa472025-05-20 19:27:16 +080098 if (existingUser.getIsBanned()) {
99 return ApiResponse.error(403, "账号已被封禁,请联系管理员");
100 }
101
wuchimedes223bfab2025-04-04 17:16:05 +0800102 String token = jwtUtil.generateToken(existingUser.getUserId());
wuchimedes079c1632025-04-02 22:01:20 +0800103 Map<String, String> response = new HashMap<>();
104 response.put("token", token);
夜雨声烦e73ff922025-05-13 18:49:03 +0800105
106 return ApiResponse.success(response);
wuchimedes079c1632025-04-02 22:01:20 +0800107 }
wuchimedes18addec2025-04-03 17:59:02 +0800108
夜雨声烦e73ff922025-05-13 18:49:03 +0800109 // 测试 Redis
wuchimedes18addec2025-04-03 17:59:02 +0800110 @GetMapping("/test_redis")
夜雨声烦e73ff922025-05-13 18:49:03 +0800111 public ApiResponse<String> testRedis() {
112 Object value = redisTemplate.opsForValue().get("test");
113 return ApiResponse.success("test redis ok");
wuchimedes18addec2025-04-03 17:59:02 +0800114 }
22301071fa22ac62025-05-24 21:38:17 +0800115
116 //刷新token
117 @PostMapping("/refresh-token")
118 public ApiResponse<String> refreshToken(HttpServletRequest request) {
119 Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
120 if (!(principal instanceof Long userId)) {
121 return ApiResponse.error(401, "未认证,无法刷新token");
122 }
123 String oldToken = request.getHeader("Authorization");
124 if (oldToken != null && oldToken.startsWith("Bearer ")) {
125 oldToken = oldToken.substring(7);
126 }
127 String newToken = jwtUtil.generateToken(userId);
128 return ApiResponse.success("Token刷新成功", newToken);
129 }
夜雨声烦e73ff922025-05-13 18:49:03 +0800130}