package art.kexue.sxwz.aspect; import art.kexue.sxwz.exception.BizException; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Collections; import java.util.List; @Aspect @Component @Slf4j public class EduPermissionAspect { @Resource private RedissonClient redissonClient; @Around("execution(* art.kexue.sxwz.service.impl.Edu*ServiceImpl.*(..))") public Object checkEduPermission(ProceedingJoinPoint joinPoint) throws Throwable { try { cn.dev33.satoken.stp.StpUtil.checkLogin(); Long userId = cn.dev33.satoken.stp.StpUtil.getLoginIdAsLong(); String token = cn.dev33.satoken.stp.StpUtil.getTokenValue(); // SUPER角色拥有所有权限,直接放行 if (cn.dev33.satoken.stp.StpUtil.hasRole("SUPER")) { log.info("用户ID: {} 拥有SUPER角色,直接放行,访问方法: {}", userId, joinPoint.getSignature().getName()); return joinPoint.proceed(); } List permissions = getUserPermissions(token); String requiredPermission = generatePermissionCode(joinPoint); log.info("用户ID: {}, 访问方法: {}, 需要权限: {}", userId, joinPoint.getSignature().getName(), requiredPermission); if (permissions == null || permissions.isEmpty()) { log.warn("用户未配置任何权限"); throw new BizException(403, "没有相应操作权限"); } if (!permissions.contains(requiredPermission)) { log.warn("用户缺少权限: {}", requiredPermission); throw new BizException(403, "没有相应操作权限"); } log.info("权限验证通过: {}", requiredPermission); } catch (cn.dev33.satoken.exception.NotLoginException e) { log.error("未登录:{}", e.getMessage()); throw new BizException(401, "请先登录认证后操作"); } catch (BizException e) { throw e; } catch (Exception e) { log.error("权限验证失败:{}", e.getMessage()); throw new BizException(403, "权限验证失败"); } return joinPoint.proceed(); } private List getUserPermissions(String token) { try { String loginUserJson = (String) redissonClient.getBucket("loginUser:" + token).get(); if (loginUserJson != null && !loginUserJson.isEmpty()) { cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(loginUserJson); cn.hutool.json.JSONArray permissionsArray = jsonObject.getJSONArray("permissions"); if (permissionsArray != null) { return permissionsArray.toList(String.class); } } } catch (Exception e) { log.error("从Redis获取用户权限失败:{}", e.getMessage()); } return Collections.emptyList(); } private String generatePermissionCode(ProceedingJoinPoint joinPoint) { String className = joinPoint.getTarget().getClass().getSimpleName(); String methodName = joinPoint.getSignature().getName(); String module = extractModule(className); String action = extractAction(methodName); return String.format("%s:%s", module, action); } private String extractModule(String className) { if (className.startsWith("EduCourse")) { return "course"; } else if (className.startsWith("EduStudent")) { return "user:student"; } else if (className.startsWith("EduTeacher")) { return "user:teacher"; } else if (className.startsWith("EduHomework")) { return "homework"; } else if (className.startsWith("EduExam")) { return "exam"; } else if (className.startsWith("EduAttendance")) { return "attendance"; } else if (className.startsWith("EduExcellentWork")) { return "excellent"; }else if (className.startsWith("EduSchool")) { return "school"; } else { return className.replace("Edu", "").replace("ServiceImpl", "").toLowerCase(); } } private String extractAction(String methodName) { if (methodName.startsWith("save") || methodName.startsWith("create")) { return "add"; } else if (methodName.startsWith("update") && !methodName.startsWith("updateStatus")) { return "update"; // 修改:update方法返回update而非edit } else if (methodName.startsWith("updateStatus")) { return "updateStatus"; // 新增:状态变更方法 } else if (methodName.startsWith("edit")) { return "edit"; } else if (methodName.startsWith("delete") || methodName.startsWith("remove")) { return "delete"; } else if (methodName.equals("pageList")) { return "pageList"; // 新增:分页查询方法 } else if (methodName.startsWith("query") || methodName.startsWith("get") || methodName.startsWith("list")) { return "query"; } else if (methodName.startsWith("addStudent")) { return "student:add"; } else if (methodName.startsWith("removeStudent")) { return "student:remove"; } else if (methodName.startsWith("submit")) { return "submit"; } else if (methodName.startsWith("grade")) { return "grade"; } else if (methodName.startsWith("publish")) { return "publish"; } else if (methodName.startsWith("mark")) { return "mark"; } else if (methodName.startsWith("addLike")) { return "like"; } else if (methodName.startsWith("removeLike")) { return "like:remove"; } else if (methodName.startsWith("countLikes")) { return "like:count"; } else if (methodName.startsWith("recordAttendance")) { return "record"; } else if (methodName.startsWith("batchCreate")) { return "batch:add"; } else if (methodName.startsWith("isStudentIn")) { return "student:exists"; } else if (methodName.startsWith("sendNotification")) { return "notification:send"; } else if (methodName.startsWith("markAsRead")) { return "notification:read"; } else if (methodName.startsWith("createMakeup")) { return "makeup"; } else { return methodName.toLowerCase(); } } }