PermissionCheckAspect.java 8.63 KB
package com.hotent.runtime.aop;

import com.fasterxml.jackson.databind.JsonNode;
import com.hotent.base.context.BaseContext;
import com.hotent.base.enums.ResponseErrorEnums;
import com.hotent.base.exception.BaseException;
import com.hotent.base.query.*;
import com.hotent.base.util.BeanUtils;
import com.hotent.base.util.ContextThread;
import com.hotent.base.util.JsonUtil;
import com.hotent.base.util.StringUtil;
import com.hotent.bpm.persistence.manager.BpmDefActManager;
import com.hotent.bpm.persistence.manager.BpmDefAuthorizeManager;
import com.hotent.bpm.persistence.manager.BpmProcessInstanceManager;
import com.hotent.bpm.persistence.manager.BpmTaskManager;
import com.hotent.bpm.persistence.model.BpmDefAuthorizeType;
import com.hotent.bpm.persistence.model.DefaultBpmProcessInstance;
import com.hotent.bpm.persistence.model.DefaultBpmTask;
import com.hotent.runtime.annotation.PermissionCheck;
import com.hotent.runtime.manager.IFlowManager;
import com.hotent.uc.api.impl.util.ContextUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.formula.functions.T;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;

/**
 * 流程实例和待办任务权限校验
 * <pre>
 * 流程实例和待办任务权限校验
 * </pre>
 *
 * @company 广州宏天软件股份有限公司
 * @author yijj
 * @email yijj@jee-soft.cn
 * @date 2022年11月01日
 */
@Aspect
@Component
public class PermissionCheckAspect {

    @Resource
    IFlowManager iFlowManager;
    @Resource
    BaseContext baseContext;
    @Resource
    BpmDefAuthorizeManager bpmDefAuthorizeManager;
    @Resource
    BpmProcessInstanceManager bpmProcessInstanceManager;
    @Resource
    BpmTaskManager bpmTaskManager;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Around("execution(* *..*Controller.*(..)) && @annotation(com.hotent.runtime.annotation.PermissionCheck)")
    public Object permissionCheck(ProceedingJoinPoint joinPoint) throws Throwable{
        //获取注解标注的方法
        Class<?> targetClass = joinPoint.getTarget().getClass();
        String methodName =joinPoint.getSignature().getName();
        Method[] methods = targetClass.getMethods();
        Object[] args = joinPoint.getArgs();
        // 当前切中的方法
        Method method = null;
        for (int i = 0; i < methods.length; i++){
            if (methods[i].getName().equals(methodName)){
                method = methods[i];
                break;
            }
        }
        PermissionCheck permissionCheck = method.getAnnotation(PermissionCheck.class);

        //获取被拦截方法参数名列表(使用Spring支持类库)
        LocalVariableTableParameterNameDiscoverer localVariableTable = new LocalVariableTableParameterNameDiscoverer();
        String[] paraNameArr = localVariableTable.getParameterNames(method);
        //使用SPEL进行key的解析
        ExpressionParser parser = new SpelExpressionParser();
        //SPEL上下文
        StandardEvaluationContext context = new StandardEvaluationContext();
        //把方法参数放入SPEL上下文中
        for(int i=0;i<paraNameArr.length;i++) {
            context.setVariable(paraNameArr[i], args[i]);
        }
        String instanceId = permissionCheck.instanceId();
        String taskId = permissionCheck.taskId();
        String isDefAuthorize = permissionCheck.isDefAuthorize();
        // 使用变量方式传入业务动态数据
        if(instanceId.matches("^#.*.$")) {
            instanceId = parser.parseExpression(instanceId).getValue(context, String.class);
        }
        if(taskId.matches("^#.*.$")) {
            taskId = parser.parseExpression(taskId).getValue(context, String.class);
        }
        if(isDefAuthorize.matches("^#.*.$")) {
            isDefAuthorize = parser.parseExpression(isDefAuthorize).getValue(context, String.class);
        }

        String currentUserAccount = baseContext.getCurrentUserAccout();
        String currentUserId = baseContext.getCurrentUserId();
        boolean isPermissions=true;

        //判断是否是流程分管授权进来
        if ("true".equals(isDefAuthorize)){
            if (ContextUtil.getCurrentUser().isAdmin()){
                return joinPoint.proceed();
            }
            Map<String, Object> actRight = bpmDefAuthorizeManager.getActRightByUserId(currentUserId, BpmDefAuthorizeType.BPMDEFAUTHORIZE_RIGHT_TYPE.INSTANCE, true, false);
            DefaultBpmProcessInstance processInstance=new DefaultBpmProcessInstance();
            String procDefKey="";
            if (StringUtil.isNotEmpty(instanceId)){
                processInstance = bpmProcessInstanceManager.get(instanceId);
                procDefKey=processInstance.getProcDefKey();
            }
            if(StringUtil.isNotEmpty(taskId)){
                DefaultBpmTask defaultBpmTask = bpmTaskManager.get(taskId);
                procDefKey=defaultBpmTask.getProcDefKey();
            }
            if (actRight.containsKey("defKeys")){
                if (!Arrays.asList(actRight.get("defKeys").toString().split(",")).contains("'"+procDefKey+"'")){
                    isPermissions=false;
                }
            }
        }else {
            if (StringUtil.isNotEmpty(instanceId)){
                isPermissions=this.isInstancePermission(instanceId);
            }

            if (StringUtil.isNotEmpty(taskId)){
                QueryFilter<DefaultBpmTask> queryFilter = QueryFilter.build();
                queryFilter.addFilter("bt.id_",taskId,QueryOP.EQUAL,FieldRelation.AND);
                long todoTotal = iFlowManager.getTodoList(currentUserAccount,queryFilter).get().getTotal();
                long leaderTotal=0;
                try {
                    leaderTotal = iFlowManager.getLeaderTodoList(currentUserAccount, getQueryFilter("task_id_",taskId)).getTotal();
                }catch (Exception e){}
                isPermissions=!(todoTotal==0&&leaderTotal==0);
            }
        }

        if (!isPermissions){
            throw new BaseException(ResponseErrorEnums.USER_PERMISSION);
        }

        return joinPoint.proceed();
    }

    /**
     * 判断当前用户是否有权限访问流程实例
     * @param instanceId 流程实例ID
     * @return 结果
     * @throws Throwable
     */
    private Boolean isInstancePermission(String instanceId) throws Throwable {
        String currentUserAccount = baseContext.getCurrentUserAccout();
        //获取已办数量
        if(iFlowManager.getDoneInstList(currentUserAccount,
                getQueryFilter("wfInst.id_", instanceId), null)
                .get().getTotal() > 0){
            return true;
        }
        //获取已阅任务(知会任务)
        if(iFlowManager.getNoticeDoneReadList(currentUserAccount,
                getQueryFilter("bpm_task_notice_done.proc_inst_id_",instanceId))
                .getTotal() > 0){
            return true;
        }
        //获取我的请求列表
        if(iFlowManager.myRequest(currentUserAccount,
                getQueryFilter("bpm_pro_inst.id_",instanceId))
                .getTotal() > 0){
            return true;
        }
        //获取待阅任务(知会任务)
        if(iFlowManager.getNoticeTodoReadList(currentUserAccount,
                getQueryFilter("bpm_task_notice.proc_inst_id_",instanceId))
                .getTotal() > 0){
            return true;
        }
        //获取我传阅的任务(知会任务)
        if(iFlowManager.getMyNoticeReadList(currentUserAccount,
                getQueryFilter("bpm_task_notice.proc_inst_id_",instanceId))
                .getTotal() > 0){
            return true;
        }
        //获取用户转办代理事宜
        return iFlowManager.getDelegate(currentUserAccount,
                getQueryFilter("a.proc_inst_id_", instanceId))
                .getTotal() > 0;
    }

    private QueryFilter getQueryFilter(String property,String value){
        QueryFilter queryFilter = QueryFilter.build();
        queryFilter.setPageBean(new PageBean(1, 1, true));
        queryFilter.addFilter(property,value,QueryOP.EQUAL,FieldRelation.AND,"permissionCheck");
        return queryFilter;
    }

}