package cn.pluss.platform.aop;

import cn.pluss.platform.annotation.OpLog;
import cn.pluss.platform.api.Result;
import cn.pluss.platform.entity.OperationRecord;
import cn.pluss.platform.entity.UserApp;
import cn.pluss.platform.operationRecord.OperationRecordService;
import cn.pluss.platform.userApp.UserAppService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 因为登录注册，以及忘记密码的时候，没有token，所以这三个操作的操作日志不通过注解实现
 * 保存APP操作日志，取请求头中的用户信息
 */
@Slf4j
@Aspect
@Component
public class OpLogAspect {

    @Autowired
    private OperationRecordService opRecordService;

    @Autowired
    private UserAppService userAppService;

    // 定义切点
    // 记录后台接口的操作记录
    // 拦截Controller所在的包
    @Pointcut("execution(* cn.pluss.platform.controller..*.*(..)) && @annotation(cn.pluss.platform.annotation.OpLog))")
    public void executionService() {
    }


    @AfterReturning(returning="rvt", value = "executionService()")
    public void after(JoinPoint point, Object rvt) {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request;
        if (attributes != null) {
            request = ((ServletRequestAttributes) attributes).getRequest();
        } else {
            log.warn("未获取到request");
            return;
        }

        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        OpLog annotation = method.getAnnotation(OpLog.class);

        String token = request.getHeader("token");
        String myLoginName = request.getHeader("myLoginName");

        UserApp ua;
        if (token == null || myLoginName == null) {
            return;
        }

        //
        LambdaQueryWrapper<UserApp> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(UserApp::getToken, token);
        ua = userAppService.getOne(qWrapper);

        OperationRecord opRecord = new OperationRecord();
        opRecord.setDictValue(annotation.opCode());
        opRecord.setRemark(annotation.opDetail());
        opRecord.setOperator(ua.getUserId() + "");
        opRecord.setUserId(ua.getUserId() + "");

        if (rvt instanceof Result) {
            Object data = ((Result) rvt).getData();
            try {
                JSONObject jsonObject = (JSONObject) JSON.toJSON(data);
                String orderNumber = jsonObject.getString("orderNumber");
                JSONObject extra = new JSONObject();
                extra.put("orderNumber", orderNumber);
                opRecord.setExtension(extra);
            } catch (Exception e) {
            }
        }

        opRecordService.save(opRecord);
    }
}
