baogutang-music/src/main/java/top/baogutang/music/aspect/VipAspect.java
2024-12-31 09:45:01 +08:00

109 lines
4.0 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 top.baogutang.music.aspect;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.baogutang.music.annos.Vip;
import top.baogutang.music.domain.res.user.UserLoginRes;
import top.baogutang.music.enums.UserLevel;
import top.baogutang.music.exceptions.LoginException;
import top.baogutang.music.exceptions.VipException;
import top.baogutang.music.service.IUserService;
import top.baogutang.music.utils.CacheUtil;
import top.baogutang.music.utils.TokenUtil;
import top.baogutang.music.utils.UserLevelThreadLocal;
import top.baogutang.music.utils.UserThreadLocal;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import static top.baogutang.music.aspect.LoginAspect.AUTHORIZATION;
import static top.baogutang.music.constants.CacheKey.KEY_USER_LEVEL_PREFIX;
import static top.baogutang.music.constants.CacheKey.KEY_USER_LOGIN_PREFIX;
/**
*
* @description:
*
* @author: N1KO
* @date: 2024/12/13 : 18:36
*/
@Slf4j
@Aspect
@Component
public class VipAspect {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private IUserService userService;
@Pointcut("@annotation(top.baogutang.music.annos.Vip)")
public void vip() {
}
@Around("vip()")
public Object around(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
Vip vip = method.getAnnotation(Vip.class);
if (vip != null) {
Cookie[] cookies = request.getCookies();
if (Objects.isNull(cookies) || cookies.length == 0) {
throw new LoginException("请登录后操作");
}
Cookie tokenCookie = Arrays.stream(cookies)
.filter(cookie -> AUTHORIZATION.equalsIgnoreCase(cookie.getName()))
.findFirst()
.orElse(null);
if (Objects.isNull(tokenCookie) || StringUtils.isBlank(tokenCookie.getValue())) {
throw new LoginException("请登录后操作");
}
String token = tokenCookie.getValue();
UserLoginRes userLoginRes = TokenUtil.verify(token);
Long userId = userLoginRes.getId();
Object val = redisTemplate.opsForValue().get(KEY_USER_LOGIN_PREFIX + userId);
if (Objects.isNull(val)) {
throw new LoginException("登录已失效");
}
if (!token.equals(val.toString())) {
throw new LoginException("登录已失效");
}
UserThreadLocal.set(userId);
String userLevelCacheKey = KEY_USER_LEVEL_PREFIX + userId;
UserLevel userLevel = CacheUtil.cacheOrSupply(userLevelCacheKey,
null,
null,
redisTemplate,
() -> userService.queryUserLevel(userId),
new TypeReference<UserLevel>() {
});
UserLevelThreadLocal.set(userLevel);
if (Objects.equals(UserLevel.NORMAL, userLevel)) {
throw new VipException("请升级当前登录用户等级再操作~详情联系微信18010816106");
}
}
return point.proceed();
}
@After("vip()")
public void after() {
UserLevelThreadLocal.remove();
}
}