解决Unknown property used in expression: ${nrOfActivelnstances == 0}
This commit is contained in:
parent
520fcbe6bd
commit
8242b3e2a5
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user