1. 修改 SysNotification 实体,新增 senderId, senderName, targetType 字段 2. 新增 SendNotificationRequest 请求DTO 3. 扩展通知类型至6种(新增用户通知、课程通知) 4. 实现角色层级权限控制,支持多级管理员通知下级 5. 支持老师群发课程通知给学生 6. 新增批量发送接口和权限配置
141 lines
4.4 KiB
Java
141 lines
4.4 KiB
Java
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<LoginUserDto> login(@RequestBody LoginDto loginDto) {
|
||
return CommonResult.success(sysUserService.login(loginDto));
|
||
}
|
||
|
||
/**
|
||
* 用户登出
|
||
*
|
||
* @return 登出结果
|
||
*/
|
||
@PostMapping("/accountLogout")
|
||
@Operation(summary = "用户登出", description = "用户登出")
|
||
public CommonResult<String> 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<String> 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<LoginUserDto> phoneLogin(@RequestBody PhoneLoginDto phoneLoginDto) {
|
||
return CommonResult.success(sysUserService.phoneLogin(phoneLoginDto));
|
||
}
|
||
|
||
/**
|
||
* 验证token是否有效
|
||
*
|
||
* @return 验证结果
|
||
*/
|
||
@PostMapping("/validateToken")
|
||
@Operation(summary = "验证token是否有效", description = "验证token是否有效")
|
||
public CommonResult<Object> validateToken() {
|
||
try {
|
||
// 使用Sa-Token检查登录状态
|
||
cn.dev33.satoken.stp.StpUtil.checkLogin();
|
||
return CommonResult.success(true);
|
||
} catch (Exception e) {
|
||
return CommonResult.failed("无效的token,请重新登录");
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|