package com.onekeycall.videotablet.controller; import com.onekeycall.videotablet.dto.TokenPair; import com.onekeycall.videotablet.entity.User; import com.onekeycall.videotablet.result.Result; import com.onekeycall.videotablet.service.UserService; import com.onekeycall.videotablet.utils.JwtUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import java.util.*; @RestController @RequestMapping("/public") public class LoginController { private final UserService userService; private final AuthenticationManager authenticationManager; @Autowired private RedisTemplate redisTemplate; @Autowired private JwtUtil jwtUtil; Logger logger = LoggerFactory.getLogger(LoginController.class); @Autowired public LoginController(UserService userService, AuthenticationManager authenticationManager) { this.userService = userService; this.authenticationManager = authenticationManager; } @PostMapping("/register") public Result registerUser(@RequestHeader("Device-ID") String deviceId, @RequestParam(value = "user_id") String userId, @RequestParam String password) { try { userService.registerUser(userId, password); return Result.ok().message("User registered successfully"); } catch (RuntimeException e) { return Result.error().message(e.getMessage()); } } @PostMapping("/login") public Result login( @RequestHeader("Device-ID") String deviceId, @RequestParam(value = "user_id") String userId, @RequestParam String password) { // 1. 创建认证令牌 Authentication authenticationToken = new UsernamePasswordAuthenticationToken(userId, password); // 2. 使用 AuthenticationManager 进行认证(核心步骤) Authentication authentication = authenticationManager.authenticate(authenticationToken); // 3. 认证成功后生成 JWT User userDetails = (User) authentication.getPrincipal(); TokenPair tokenPair = jwtUtil.generateTokenPair(userDetails.getUserId(), deviceId); // 4. 返回 Token return Result.ok().data(Collections.singletonMap("token", tokenPair.toMap())); } @PostMapping("/phone_login") public Result phoneLogin( @RequestHeader("Device-ID") String deviceId, @RequestParam String phone, @RequestParam String password) { logger.info("phoneLogin: phone={}, password={}, deviceId={}", phone, password, deviceId); User user = userService.getUserByPhone(phone); if (user == null) { return Result.error().message("手机号未注册"); } String userId = user.getUserId(); // 1. 创建认证令牌 Authentication authenticationToken = new UsernamePasswordAuthenticationToken(userId, password); try { // 2. 使用 AuthenticationManager 进行认证(核心步骤) Authentication authentication = authenticationManager.authenticate(authenticationToken); // 3. 认证成功后生成 JWT User userDetails = (User) authentication.getPrincipal(); TokenPair tokenPair = jwtUtil.generateTokenPair(userDetails.getUserId(), deviceId); // 4. 返回 Token return Result.ok().data(Collections.singletonMap("token", tokenPair.toMap())); } catch (Exception e) { e.printStackTrace(); return Result.error().message("登录失败:密码错误"); } } @PostMapping("/phone_register") public Result registerByPhone( @RequestParam String phone, @RequestParam String code, @RequestParam(value = "verify_key") String verifyKey, @RequestParam(value = "device_id") String deviceId) { logger.info("registerByPhone: phone={}, code={}, verifyKey={}, deviceId={}", phone, code, verifyKey, deviceId); // if (TextUtils.isEmpty(verifyKey)) { // return Result.error().message("verify key is empty", HttpStatus.BAD_REQUEST); // } Map map = (Map) redisTemplate.opsForValue().get(phone); if (map != null) { String redisVerifyKey = (String) map.get("verifyKey"); if (!Objects.equals(redisVerifyKey, verifyKey)) { return Result.error().message("verify key is not same"); } String redisCode = map.get("code").toString(); if (!Objects.equals(redisCode, code)) { return Result.error().message("code is not same"); } try { User user = userService.registerByPhone(phone, code, deviceId, new Date()); logger.info("loginByPhoneCode: user={}", user.toString()); TokenPair tokenPair = jwtUtil.generateTokenPair(user.getUserId(), deviceId); //返回给app保存,access_token用来加入header请求接口,refresh_token用来更换access_token Map tokenMap = new HashMap<>(); tokenMap.put("new_user", user.isNewUser()); tokenMap.put("user_id", user.getUserId()); tokenMap.put("has_password", user.isHasPassword()); tokenMap.put("token", tokenPair.toMap()); redisTemplate.delete(phone); return Result.ok().data(tokenMap); } catch (RuntimeException e) { return Result.error().message(e.getMessage()); } } else { // return Result.error().message("verify key is expired"); return Result.error().message("验证码已过期,请重新获取"); } } @PostMapping("/phone_code_login") public Result loginByPhoneCode( @RequestParam String phone, @RequestParam String code, @RequestParam(value = "verify_key") String verifyKey, @RequestParam(value = "device_id") String deviceId) { Map map = (Map) redisTemplate.opsForValue().get(phone); if (map != null) { String redisVerifyKey = (String) map.get("verifyKey"); if (!Objects.equals(redisVerifyKey, verifyKey)) { return Result.error().message("verify key is not same"); } String redisCode = map.get("code").toString(); if (!Objects.equals(redisCode, code)) { return Result.error().message("code is not same"); } try { User user = userService.loginByPhone(phone, code); logger.info("loginByPhoneCode: user={}", user); // 生成并返回JWT令牌(实际项目中需要实现JWT逻辑) TokenPair tokenPair = jwtUtil.generateTokenPair(user.getUserId(), deviceId); Map tokenMap = new HashMap<>(); tokenMap.put("new_user", user.isNewUser()); tokenMap.put("user_id", user.getUserId()); tokenMap.put("has_password", user.isHasPassword()); tokenMap.put("token", tokenPair.toMap()); redisTemplate.delete(phone); return Result.ok().data(tokenMap); } catch (RuntimeException e) { return Result.error().message(e.getMessage()); } } else { return Result.error().message("verify key is expired"); } } // @PostMapping("/device_login") // public Result loginByDeviceSn(){ // // } }