package com.shkj.framework.aspectj;

import com.shkj.common.annotation.DataScopeConsignor;
import com.shkj.common.core.domain.BaseEntity;
import com.shkj.common.core.domain.entity.SysRole;
import com.shkj.common.core.domain.entity.SysUser;
import com.shkj.common.core.domain.model.LoginUser;
import com.shkj.common.utils.SecurityUtils;
import com.shkj.common.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 数据过滤处理
 *
 * @author lch
 */
@Aspect
@Component
public class DataScopeConsignorAspect {

    /**
     * 数据权限过滤关键字
     */
    public static final String DATA_SCOPE = "dataScopeConsignor";
    public static final String DATA_SCOPE_BRANCH = "dataScopeBranch";

    @Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScopeConsignor controllerDataScope) throws Throwable {
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }

    protected void handleDataScope(final JoinPoint joinPoint, DataScopeConsignor controllerDataScope) {
        // 获取当前的用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNotNull(loginUser)) {
            SysUser currentUser = loginUser.getUser();
            // 如果是超级管理员，则不过滤数据
            if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
                dataScopeFilter(joinPoint, currentUser, controllerDataScope.consignorAlias(), controllerDataScope.branchAlias());
            }
        }
    }

    /**
     * 数据范围过滤
     *
     * @param joinPoint      切点
     * @param user           用户
     * @param branchAlias
     * @param consignorAlias 别名
     */
    public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String consignorAlias, String branchAlias) {
        StringBuilder branchSql = new StringBuilder();
        //设置仓库数据权限
        if (user.getCurrentBranchId() != null && user.getCurrentBranchId() != 0L) {
            //已指定仓库
            branchSql.append(StringUtils.format(
                    " OR {}.branch_id = {} ", branchAlias,
                    user.getCurrentBranchId()));
        } else {
            //系统用户
            List<Long> branchIds = SecurityUtils.getBranchIds();
            if (CollectionUtils.isEmpty(branchIds)) {
                branchIds = new ArrayList<>();
                branchIds.add(-1L);
            }
            for (Long branchId : branchIds) {
                branchSql.append(StringUtils.format(
                        " OR {}.branch_id =  {} ", branchAlias, branchId));
            }

        }
        if (StringUtils.isNotBlank(branchSql.toString())) {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getBranchParams().put(DATA_SCOPE_BRANCH, " AND (" + branchSql.substring(4) + ")");
            }
        }


        StringBuilder sqlString = new StringBuilder();
        //设置货主数据权限
        for (SysRole role : user.getRoles()) {
            if (user.getCurrentBranchId() != null && user.getCurrentBranchId() != 0L) {
                //已指定仓库
                sqlString.append(StringUtils.format(
                        " OR {}.consignor_id IN (SELECT DISTINCT src.consignor_id FROM sys_role_consignor src join base_consignor bcon on src.consignor_id = bcon.id where bcon.branch_id = {} and src.role_id = {} ) ",
                        consignorAlias, user.getCurrentBranchId(), role.getRoleId()));
            }else {
                sqlString.append(StringUtils.format(
                        " OR {}.consignor_id IN ( SELECT consignor_id FROM sys_role_consignor WHERE role_id = {} ) ", consignorAlias,
                        role.getRoleId()));
            }

        }

        if (StringUtils.isNotBlank(sqlString.toString())) {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getConsignorParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
            }
        }
    }

    /**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint) {
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
            BaseEntity baseEntity = (BaseEntity) params;
            Map<String, Object> consignorParams = new HashMap<>();
            consignorParams.put(DATA_SCOPE, "");
            baseEntity.setConsignorParams(consignorParams);
            Map<String, Object> branchParams = new HashMap<>();
            branchParams.put(DATA_SCOPE_BRANCH, "");
            baseEntity.setBranchParams(branchParams);
        }
    }
}
