解决Unknown property used in expression: ${nrOfActivelnstances == 0}

This commit is contained in:
guoshengxiong 2024-08-10 14:36:11 +08:00
parent 520fcbe6bd
commit 8242b3e2a5
2 changed files with 84 additions and 30 deletions

View File

@ -2,15 +2,10 @@ package com.wflow.workflow;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wflow.bean.do_.UserDeptDo; import com.wflow.bean.do_.UserDeptDo;
import com.wflow.bean.entity.WflowModelHistorys;
import com.wflow.mapper.WflowModelHistorysMapper;
import com.wflow.service.OrgRepositoryService; import com.wflow.service.OrgRepositoryService;
import com.wflow.utils.R;
import com.wflow.workflow.bean.dto.ProcessInstanceOwnerDto; import com.wflow.workflow.bean.dto.ProcessInstanceOwnerDto;
import com.wflow.workflow.bean.process.HttpDefinition; import com.wflow.workflow.bean.process.HttpDefinition;
import com.wflow.workflow.bean.process.OrgUser; import com.wflow.workflow.bean.process.OrgUser;
@ -22,19 +17,15 @@ import com.wflow.workflow.execute.HttpExecute;
import com.wflow.workflow.execute.JsExecute; import com.wflow.workflow.execute.JsExecute;
import com.wflow.workflow.service.UserDeptOrLeaderService; import com.wflow.workflow.service.UserDeptOrLeaderService;
import com.zhgd.xmgl.tenant.TenantContextHolder; import com.zhgd.xmgl.tenant.TenantContextHolder;
import com.zhgd.xmgl.tenant.TenantHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Maps;
import org.flowable.engine.HistoryService; import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService; import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService; import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity; import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -64,6 +55,9 @@ public class UELTools {
@Autowired @Autowired
private RuntimeService runtimeService; private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired @Autowired
private HistoryService historyService; private HistoryService historyService;
@ -109,6 +103,44 @@ public class UELTools {
return false; return false;
} }
/**
* 判断节点是否结束被flowable调用
*
* @param execution 上下文
* @param type 节点类型
* @return 是否结束
*/
public boolean nodeIsComplete(ExecutionEntity execution, String type) {
//读取当前节点内3个变量: 已完成的任务数任务总数未处理的任务数
Number nrOfCompletedInstances = execution.getVariable("nrOfCompletedInstances", Number.class);
Number nrOfActiveInstances = execution.getVariable("nrOfActiveInstances", Number.class);
if (Objects.isNull(nrOfCompletedInstances)){
nrOfCompletedInstances = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(execution.getProcessInstanceId())
.taskDefinitionKey(execution.getActivityId())
.finished().count();
}
switch (type) {
case "OR":
return nrOfCompletedInstances.longValue() >= 0;
case "AND":
case "NEXT":
if (Objects.nonNull(nrOfActiveInstances)){
return nrOfActiveInstances.longValue() == 0;
}else {
Number nrOfInstances = execution.getVariable("nrOfInstances", Number.class);
if (Objects.nonNull(nrOfInstances)){
return nrOfCompletedInstances.equals(nrOfInstances);
} else {
//nrOfInstances和 nrOfActiveInstances 变量都不存在
nrOfActiveInstances = taskService.createTaskQuery().active().count();
return nrOfActiveInstances.longValue() == 0;
}
}
}
return false;
}
/** /**
@ -122,7 +154,7 @@ public class UELTools {
Map variable = execution.getVariable(WflowGlobalVarDef.WFLOW_NODE_PROPS, Map.class); Map variable = execution.getVariable(WflowGlobalVarDef.WFLOW_NODE_PROPS, Map.class);
DelayProps props = (DelayProps) variable.get(execution.getActivityId()); DelayProps props = (DelayProps) variable.get(execution.getActivityId());
String date = null; String date = null;
if (DelayProps.Type.AUTO.equals(props.getType())){ if (DelayProps.Type.AUTO.equals(props.getType())) {
date = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE) + "T" + props.getDateTime().trim(); date = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE) + "T" + props.getDateTime().trim();
} else if (DelayProps.Type.PRECISE.equals(props.getType())) { } else if (DelayProps.Type.PRECISE.equals(props.getType())) {
date = LocalDateTime.parse(props.getDateTime().trim(), date = LocalDateTime.parse(props.getDateTime().trim(),
@ -151,13 +183,14 @@ public class UELTools {
/** /**
* 校验条件公共函数 * 校验条件公共函数
*
* @param props 条件设置 * @param props 条件设置
* @param ctx 变量 * @param ctx 变量
* @return 校验结果 * @return 校验结果
*/ */
public Boolean conditionCompare(ConditionProps props, Map<String, Object> ctx){ public Boolean conditionCompare(ConditionProps props, Map<String, Object> ctx) {
//拿到前端的条件节点props设置项后开始校验条件 //拿到前端的条件节点props设置项后开始校验条件
switch (props.getMode()){ switch (props.getMode()) {
case SIMPLE: case SIMPLE:
return validateSimpleCd(props, ctx); return validateSimpleCd(props, ctx);
case UEL: case UEL:
@ -168,17 +201,19 @@ public class UELTools {
Boolean.class, ctx); Boolean.class, ctx);
case HTTP: case HTTP:
return new HttpExecute().execute(BeanUtil.mapToBean(props.getHttp(), HttpDefinition.class, true), executorService, Boolean.class, ctx); return new HttpExecute().execute(BeanUtil.mapToBean(props.getHttp(), HttpDefinition.class, true), executorService, Boolean.class, ctx);
default: return false; default:
return false;
} }
} }
/** /**
* 校验简单模式条件设置 * 校验简单模式条件设置
*
* @param ctx 系统变量 * @param ctx 系统变量
* @param props 条件设置项 * @param props 条件设置项
* @return 校验结果 * @return 校验结果
*/ */
private Boolean validateSimpleCd(ConditionProps props, Map<String, Object> ctx){ private Boolean validateSimpleCd(ConditionProps props, Map<String, Object> ctx) {
int groupConditionSuccess = 0; int groupConditionSuccess = 0;
for (ConditionProps.Group group : props.getGroups()) { for (ConditionProps.Group group : props.getGroups()) {
int subConditionSuccess = 0; int subConditionSuccess = 0;
@ -207,6 +242,7 @@ public class UELTools {
/** /**
* 子条件校验 * 子条件校验
*
* @param condition 子条件配置 * @param condition 子条件配置
* @param compareVal 子条件比较值 * @param compareVal 子条件比较值
* @return 校验结果 * @return 校验结果
@ -243,18 +279,18 @@ public class UELTools {
case "IN": case "IN":
return values.contains(compareVal.toString()); return values.contains(compareVal.toString());
case "DEPT": case "DEPT":
if (compareVal instanceof List){ if (compareVal instanceof List) {
List<String> ids = ((List<Map>) compareVal).stream().map(v -> String.valueOf(v.get("id"))).collect(Collectors.toList()); List<String> ids = ((List<Map>) compareVal).stream().map(v -> String.valueOf(v.get("id"))).collect(Collectors.toList());
List<String> pids = values.stream().map(v -> String.valueOf(((Map)v).get("id"))).collect(Collectors.toList()); List<String> pids = values.stream().map(v -> String.valueOf(((Map) v).get("id"))).collect(Collectors.toList());
for (String sid : ids) { for (String sid : ids) {
boolean result = false; boolean result = false;
for (String pid : pids) { for (String pid : pids) {
if (sid.equals(pid) || userDeptOrLeaderService.deptIsBelongToDept(sid, pid)){ if (sid.equals(pid) || userDeptOrLeaderService.deptIsBelongToDept(sid, pid)) {
result = true; result = true;
break; break;
} }
} }
if (!result){ if (!result) {
return false; return false;
} }
} }
@ -271,14 +307,14 @@ public class UELTools {
} }
return null; return null;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
if (compareVal instanceof List){ if (compareVal instanceof List) {
List<String> ids = ((List<Map>) compareVal).stream().map(v -> String.valueOf(v.get("id"))).collect(Collectors.toList()); List<String> ids = ((List<Map>) compareVal).stream().map(v -> String.valueOf(v.get("id"))).collect(Collectors.toList());
for (String id : ids) { for (String id : ids) {
if (orgContains(id, orgs)){ if (orgContains(id, orgs)) {
return true; return true;
} }
} }
}else { } else {
return orgContains(String.valueOf(compareVal), orgs); return orgContains(String.valueOf(compareVal), orgs);
} }
return false; return false;
@ -291,6 +327,7 @@ public class UELTools {
/** /**
* 获取流程实例上下文变量 * 获取流程实例上下文变量
*
* @param execution 上下文 * @param execution 上下文
* @return 流程实例上下文变量 * @return 流程实例上下文变量
*/ */
@ -301,6 +338,7 @@ public class UELTools {
/** /**
* 获取流程实例上下文变量 * 获取流程实例上下文变量
*
* @param instanceId 实例ID * @param instanceId 实例ID
* @param defId 流程定义ID * @param defId 流程定义ID
* @return 流程实例上下文变量 * @return 流程实例上下文变量
@ -312,6 +350,7 @@ public class UELTools {
/** /**
* 组装流程实例上下文变量 * 组装流程实例上下文变量
*
* @param instanceId 实例ID * @param instanceId 实例ID
* @param defId 流程定义ID * @param defId 流程定义ID
* @param variables 流程实例上下文变量 * @param variables 流程实例上下文变量
@ -344,7 +383,7 @@ public class UELTools {
return variables; return variables;
} }
private double toDouble(Object val){ private double toDouble(Object val) {
return NumberUtil.parseNumber(val.toString()).doubleValue(); return NumberUtil.parseNumber(val.toString()).doubleValue();
} }
} }

View File

@ -1,5 +1,6 @@
package com.wflow.workflow.config; package com.wflow.workflow.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.wflow.workflow.bean.process.OrgUser; import com.wflow.workflow.bean.process.OrgUser;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -9,6 +10,8 @@ import java.util.regex.Pattern;
* @date : 2022/9/4 * @date : 2022/9/4
*/ */
public class WflowGlobalVarDef { public class WflowGlobalVarDef {
//数据库类型在启动时加载进去
public static DbType DB_TYPE = DbType.MYSQL;
//审批自动驳回 //审批自动驳回
public static final String WFLOW_TASK_REFUSE = "WFLOW_TASK_REFUSE"; public static final String WFLOW_TASK_REFUSE = "WFLOW_TASK_REFUSE";
@ -17,8 +20,20 @@ public class WflowGlobalVarDef {
//流程Node节点变量KEY //流程Node节点变量KEY
public static final String WFLOW_NODE_PROPS = "WFLOW_NODE_PROPS"; public static final String WFLOW_NODE_PROPS = "WFLOW_NODE_PROPS";
//最近一个审批的节点
public static final String PREVIOUS_AP_NODE = "PREVIOUS_AP_NODE";
//流程出现回退及节点驳回的标记
public static final String NODE_RETURN = "NODE_RETURN";
//表单变量KEY //表单变量KEY
public static final String WFLOW_FORMS = "WFLOW_FORMS"; public static final String WFLOW_FORMS = "WFLOW_FORMS";
//部门变量名
public static final String START_DEPT = "startDept";
//发起人信息变量名
public static final String OWNER = "owner";
//任务处理结果变量前缀
public static final String TASK_RES_PRE = "approve_";
//系统审批管理员角色 //系统审批管理员角色
public static final String WFLOW_APPROVAL_ADMIN = "WFLOW_APPROVAL_ADMIN"; public static final String WFLOW_APPROVAL_ADMIN = "WFLOW_APPROVAL_ADMIN";