sxwz2.0/src/main/java/art/kexue/sxwz/controller/LoginController.java
wangzhiwei 5f5c0759ce feat(notification): 实现通知功能,支持角色层级发送和课程群发
1. 修改 SysNotification 实体,新增 senderId, senderName, targetType 字段

2. 新增 SendNotificationRequest 请求DTO

3. 扩展通知类型至6种(新增用户通知、课程通知)

4. 实现角色层级权限控制,支持多级管理员通知下级

5. 支持老师群发课程通知给学生

6. 新增批量发送接口和权限配置
2026-05-15 16:57:07 +08:00

141 lines
4.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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请重新登录");
}
}
}