package art.kexue.sxwz.controller; import art.kexue.sxwz.annotation.Log; import art.kexue.sxwz.annotation.PreventDuplicateSubmission; import art.kexue.sxwz.common.CacheManager; import art.kexue.sxwz.common.CommonResult; import art.kexue.sxwz.entity.request.LoginDto; import art.kexue.sxwz.entity.request.LoginUserDto; import art.kexue.sxwz.entity.request.PhoneLoginDto; import art.kexue.sxwz.service.SysUserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import org.redisson.api.RedissonClient; import static cn.dev33.satoken.SaManager.log; /** * (SysUser)表控制层 * * @author 王志维 * @since 2024-04-13 01:25:22 */ @Log(module = "登录认证") @RestController @RequestMapping("api/login") @CrossOrigin(origins = "*") @Tag(name = "登录|登出 Api") public class LoginController { /** * 服务对象 */ @Resource private SysUserService sysUserService; /** * Redisson客户端 */ @Resource private RedissonClient redissonClient; /** * 用户登录 * * @param loginDto 登录信息 * @return 登录结果 */ @PostMapping("/accountLogin") @Operation(summary = "用户登录", description = "用户登录") @PreventDuplicateSubmission public CommonResult login(@RequestBody LoginDto loginDto) { return CommonResult.success(sysUserService.login(loginDto)); } /** * 用户登出 * * @return 登出结果 */ @PostMapping("/accountLogout") @Operation(summary = "用户登出", description = "用户登出") public CommonResult logout() { try { // 获取当前用户的 token String token = cn.dev33.satoken.stp.StpUtil.getTokenValue(); // 从 Redis 中删除用户信息 if (token != null && !token.isEmpty()) { redissonClient.getBucket("loginUser:" + token).delete(); // 从缓存中移除 token 映射 String username = CacheManager.getUsernameFromToken(token); if (username != null) { CacheManager.removeTokenFromCache(username); } } // 使用 Sa-Token 登出(这会清除 Sa-Token 内部的会话信息) cn.dev33.satoken.stp.StpUtil.logout(); log.info("用户登出成功,token 已清理"); return CommonResult.success("登出成功"); } catch (Exception e) { log.error("登出异常:{}", e.getMessage()); // 如果获取 token 失败,仍然执行登出操作 cn.dev33.satoken.stp.StpUtil.logout(); return CommonResult.success("登出成功"); } } /** * 发送手机验证码 * * @param phone 手机号 * @return 发送结果 */ @PostMapping("/sendCode") @Operation(summary = "发送手机验证码", description = "向指定手机号发送登录验证码") public CommonResult sendCode(@RequestParam("phone") String phone) { boolean success = sysUserService.sendSmsCode(phone); if (success) { return CommonResult.success("验证码发送成功"); } else { return CommonResult.failed("验证码发送失败"); } } /** * 手机号登录 * * @param phoneLoginDto 手机号登录信息 * @return 登录结果 */ @PostMapping("/phoneLogin") @Operation(summary = "手机号登录", description = "使用手机号和验证码登录") public CommonResult phoneLogin(@RequestBody PhoneLoginDto phoneLoginDto) { return CommonResult.success(sysUserService.phoneLogin(phoneLoginDto)); } /** * 验证token是否有效 * * @return 验证结果 */ @PostMapping("/validateToken") @Operation(summary = "验证token是否有效", description = "验证token是否有效") public CommonResult validateToken() { try { // 使用Sa-Token检查登录状态 cn.dev33.satoken.stp.StpUtil.checkLogin(); return CommonResult.success(true); } catch (Exception e) { return CommonResult.failed("无效的token,请重新登录"); } } }