package com.zcxk.logAdvice;

import com.zcxk.dao.OperateLogMapper;
import com.zcxk.entity.OperateLogEntity;
import com.zcxk.model.LoginUser;
import com.zcxk.util.UserUtil;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @description 统一日志处理 :通过自定义注解获取操作名称
 * @auto wangli
 * @data 2020-11-09 8:43
 */
@Aspect
@Component
public class OperateLogAdvice {

    @Resource
    private OperateLogMapper operateLogMapper;

    @Around(value = "@annotation(com.zcxk.logAdvice.LogAnnotation)")
    public Object logSave(ProceedingJoinPoint joinPoint) throws Throwable {
        //参数存储
        StringBuffer stringBuffer=new StringBuffer();
        try{
            //1.获取到所有的参数值的数组
            Object[] args = joinPoint.getArgs();
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            //2.获取到方法的所有参数名称的字符串数组
            String[] parameterNames = methodSignature.getParameterNames();
            //拼装参数
            for (int i =0 ,len=parameterNames.length;i < len ;i++){
                stringBuffer.append("\r\n参数名："+ parameterNames[i] + " = " +args[i]);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        OperateLogEntity operateLog = new OperateLogEntity();
        LoginUser user = UserUtil.getCurrentUser();
        if (user != null) {
            // 设置当前登录用户
            operateLog.setUserName(user.getUsername());
            operateLog.setPhone(user.getPhoneNumber());
            operateLog.setTenantId(user.getTenantId());
            operateLog.setCompanyId(user.getCompanyId());
            operateLog.setDepartmentId(user.getDepartmentId());
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

            String module = null;//ApiOperation注解的模块名
            LogAnnotation logAnnotation = methodSignature.getMethod().getDeclaredAnnotation(LogAnnotation.class);
            module = logAnnotation.module();
            ApiOperation methodApiOperation = methodSignature.getMethod().getDeclaredAnnotation(ApiOperation.class);
            if (methodApiOperation != null) {
                module =methodApiOperation.value();
            }

            // 没有指定日志module ,获取方法
            if (StringUtils.isEmpty(module)) {
                Method method = methodSignature.getMethod();
                module= method.getDeclaringClass().getName()+method.getName();
            }
            operateLog.setOperateContent(module);

            try {
                return  joinPoint.proceed();
            } catch (Exception e) {
                operateLog.setOperateContent(operateLog.getOperateContent()+"__操作抛出异常");
                throw e;
            } finally {
                if (operateLog.getUserName() != null) {
                    operateLog.setCreateTime(new Date());
                    operateLogMapper.insert(operateLog);
                }
            }
        }else {
            return joinPoint.proceed();
        }
    }
}
