109 lines
4.0 KiB
Java
109 lines
4.0 KiB
Java
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();
|
||
}
|
||
|
||
}
|