package com.ruoyi.framework.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.enums.DictEnum;
import com.ruoyi.common.utils.SecurityUtil;
import com.ruoyi.framework.annotation.RyLog;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
import org.noear.solon.core.wrap.MethodWrap;

/**
 * 操作日志记录
 * @author ruoyi
 */
public class LogAspect implements Filter {

    @Inject
    ISysOperLogService sysOperLogService;

    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        handleFilter(ctx, chain);
    }

    /**
     * 保存操作日志
     * @param ctx
     * @param chain
     * @throws Throwable
     */
    private void handleFilter(Context ctx, FilterChain chain) throws Throwable {
        chain.doFilter(ctx);

        MethodWrap method = ctx.action().method();
        RyLog ryLog = method.getAnnotation(RyLog.class);

        SysOperLog sol = new SysOperLog();
        sol.setTitle(ryLog.title());
        sol.setBusinessType(ryLog.businessType().ordinal());
        sol.setMethod(method.getDeclaringClz() + "." + method.getName() + "()");
        sol.setRequestMethod(ctx.method());
        sol.setOperatorType(SecurityUtil.getDeviceType());
        sol.setOperName(SecurityUtil.getUserName());
        sol.setOperUrl(ctx.path());
        sol.setOperIp(ctx.realIp());
        if(ryLog.isSaveRequestData()) {
            sol.setOperParam(StrUtil.isNotBlank(ctx.body()) ? ctx.body() : ctx.paramMap().toString());
        }
        if(ryLog.isSaveResponseData()) {
            sol.setJsonResult(JSONUtil.toJsonStr(ctx.result));
        }
        if(ObjectUtil.isNull(ctx.errors)) {
            sol.setStatus(DictEnum.COMMON_SUCCESS_FAIL.SUCCESS.getValue());
        } else {
            sol.setStatus(DictEnum.COMMON_SUCCESS_FAIL.FAIL.getValue());
            sol.setErrorMsg(ctx.errors.toString());
        }
        sysOperLogService.save(sol);
    }

}
