package com.template.aop;

import com.alibaba.fastjson.JSON;
import com.template.annotation.DESRespondSecret;
import com.template.common.utils.EncryptUtil;
import com.template.model.result.CommonResult;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Author: xwt
 * @Date: 2024/2/26 星期一 10:02
 * @Description: com.template.aop
 * @Version: 1.0
 */
@Component
@Aspect
//规定AOP的执行顺序
//Order(1) 多个aop时可通过该注解来确定执行顺序
public class DESResponseSecretAspect {

    // 定义切点，使用了@DESRespondSecret注解的类 或 使用了@DESRespondSecret注解的方法

    /**
     * 切点，方法上有注解或类上有注解
     * 拦截类或者是方法上标注注解的方法
     */
    @Pointcut("@within(com.template.annotation.DESRespondSecret) || @annotation(com.template.annotation.DESRespondSecret)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object after(ProceedingJoinPoint joinPoint) throws Throwable {
        Object rvt = joinPoint.proceed(joinPoint.getArgs());
        return rvt;
    }

    /**
     * 与After的区别在于AfterReturning只有在方法执行成功之后才会被植入，如果After和
     * AfterReturning同时存在于一个文件中，谁写在前面谁先运行
     *
     * @param joinpoint
     * @param rvt
     * @return
     */
    @AfterReturning(pointcut = "execution(public * com.template.controller.*.*(..))", returning = "rvt")
    public Object log(JoinPoint joinpoint, Object rvt) {
        //获取被代理对象
        Object target = joinpoint.getTarget();
        //获取通知签名 获取方法上的DESRespondSecret注解
        MethodSignature signature = (MethodSignature) joinpoint.getSignature();
        try {
            // 获取被代理方法
            Method pointMethod = target.getClass().getMethod(signature.getName(), signature.getParameterTypes());
            // 获取被代理方法上面的注解@DESRespondSecret
            DESRespondSecret secret = pointMethod.getAnnotation(DESRespondSecret.class);
            // 被代理方法上没有，则说明@DESRespondSecret注解在被代理类上
            if (secret == null) {
                secret = target.getClass().getAnnotation(DESRespondSecret.class);
            }
            //类上也没有 直接返回
            if (secret == null) {
                return rvt;
            }
            // 如果有，并且值为false，则不进行加密
            if (secret != null && !secret.validated()) {
                return rvt;
            } else {
                CommonResult baseVo1 = (CommonResult) rvt;
                // 获取返回值json字符串
                Object data = baseVo1.getData();
                if (null != data) {
                    String jsonString = JSON.toJSONString(data);
                    // 加密
                    String s = EncryptUtil.encrypt(jsonString);
                    baseVo1.setData(s);
                }
                return baseVo1;

            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return rvt;
    }

}
