Skip to main content

执行人函数扩展实现

1.1 新增业务构件

用于执行人函数配置,请参考构件示例 vbase_workflow_exeunit_func_test, 引入构件并发布到执行系统;

1.2 新建流程执行人函数

新建流程执行人函数扩展后台代码规则:

①在Eclipse中新建V3 Serverrule ProjectV3服务规则项目:

img

②设置Artifact Id(项目唯一标识符) 和 RuleName(规则名称)。

img

③修改 pom.xml 文件1:修改模块中文名称 和 模块英文名称

img

<properties>
<bundle.name>Serverrule_test_GetExecutionSuperior</bundle.name>
<bundle.description>流程扩展执行人函数后台规则示例</bundle.description>
</properties>

④修改 pom.xml 文件2:添加流程执行人函数扩展依赖模块

<dependency>
<groupId>com.toone.v3.platform</groupId>
<artifactId>34vbase-bizmodules-workflow-common</artifactId>
<version>3.22.0</version>
<type>bundle</type>
<scope>provided</scope>
</dependency>

这里依赖的 <version>版本号可通过服务的控制台页面的首页 /系统高级配置 /构件管理 /本地构件管理页面查询到。

img

完整pom.xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.toone.v3.platform</groupId>
<artifactId>platform-parent</artifactId>
<version>3.3.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>com.toone.v3.platform-Serverrule_test_GetExecutionSuperior</name>
<groupId>com.toone.v3.platform</groupId>
<artifactId>Serverrule_test_GetExecutionSuperior</artifactId>
<version>3.2.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<bundle.name>Serverrule_test_GetExecutionSuperior</bundle.name>
<bundle.description>流程扩展执行人函数后台规则示例</bundle.description>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Include-Resource>resources=resources,extension=extension</Include-Resource>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>com.toone.v3.platform</groupId>
<artifactId>01core</artifactId>
<version>3.3.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.toone.v3.platform</groupId>
<artifactId>03pojo</artifactId>
<version>3.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.toone.v3.platform</groupId>
<artifactId>07service</artifactId>
<version>3.3.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.toone.v3.platform</groupId>
<artifactId>34vbase-bizmodules-workflow-common</artifactId>
<version>3.22.0</version>
<type>bundle</type>
<scope>provided</scope>
</dependency>
</dependencies>

</project>

⑤ 修改继承类为执行人函数的继承类,并修改需要重载的方法

img

⑥执行人函数参数获取方式:

img

具体可参照示例 Serverrule_test_GetExecutionSuperior.java源码:

package com.toone.itop.formula.rule.inte;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.toone.exception.BusinessException;
import com.toone.itop.formula.spi.Func;
import com.toone.itop.formula.spi.Function;
import com.toone.itop.metadata.apiserver.DataView;
import com.toone.itop.rule.apiserver.model.RuleContext;
import com.toone.itop.workflow.engine.apiserver.model.TProcessInstance;
import com.toone.itop.workflow.engine.apiserver.model.Task;
import com.toone.itop.workflow.engine.vbase.common.apiserver.factory.VBASEWorkFlowServiceFactory;
import com.toone.itop.workflow.engine.vbase.common.apiserver.task.TaskQuery;
import com.toone.itop.workflow.engine.vbase.common.apiserver.util.WorkFlowOrganizationUtils;
import com.toone.itop.workflow.engine.vbase.common.spiserver.rule.WorkFlowExecutionUnitFuncRule;
import com.toone.itop.workflow.pvm.apiserver.Activity;
import com.toone.itop.workflow.pvm.apiserver.ProcessExecution;
import com.toone.itop.workflow.pvm.apiserver.state.State;
import com.toone.util.ArrayUtils;
import com.toone.util.CollectionUtils;
import com.toone.util.StringUtils;
import com.toone.vcore.component.annotations.Component;
import com.toone.vcore.component.annotations.Instantiate;
import com.toone.vcore.component.annotations.Provides;

@Component
@Provides(specifications = Function.class)
@Instantiate
@Func(name = "Serverrule_test_GetExecutionSuperior")
public class Serverrule_test_GetExecutionSuperior extends
WorkFlowExecutionUnitFuncRule {
/**
* 规则定义参数Key
*/
private static enum RCKey {
// 1取上一步执行人的上级2指定流程变量
sourceType,
// 流程变量编码
varCode,
// 是否获取直接上级
isGetSuperior,
// 是否获取直属上级
isGetDirectlySuperior
}

@Override
public Object enhancedEvaluate(RuleContext ruleContext) {
ruleContext.setResultToJson(false);

Map<String, Object> ruleConfigInParams = ruleContext.getRuleConfig()
.getConfigParams();

String sourceTypeVar = (String) ruleConfigInParams.get(RCKey.sourceType
.name());
String varCodeVar = (String) ruleConfigInParams.get(RCKey.varCode
.name());
boolean isGetSuperior = Boolean
.parseBoolean((String) ruleConfigInParams
.get(RCKey.isGetSuperior.name()));
boolean isGetDirectlySuperior = Boolean
.parseBoolean((String) ruleConfigInParams
.get(RCKey.isGetDirectlySuperior.name()));
if ("1".equals(sourceTypeVar)) {
// 取上一步执行人
return getSuperior(ruleContext, isGetSuperior,
isGetDirectlySuperior);
} else {
// 指定执行人
return getWorkFlowVarSuperior(ruleContext, varCodeVar,
isGetSuperior, isGetDirectlySuperior);
}
}

// 根据流程变量获取上级
private DataView getWorkFlowVarSuperior(RuleContext ruleContext,
String varCode, boolean isGetSuperior, boolean isGetDirectlySuperior) {
Map<String, Object> flowVariables = super.getFlowVariables(ruleContext);
// 创建dataview对象数据
DataView dataview = WorkFlowOrganizationUtils
.createExecutionUnitDataView();

// 获取流程变量中对应外部制定执行人ID串对应的流程变量值
String varValue = (String) flowVariables.get(varCode);
if (StringUtils.isEmpty(varValue)) {
throw new BusinessException("【执行人函数:人资系统-获取指定人员的上级】运行异常:"
+ "根据流程变量key = " + varCode + "获取变量值" + varValue + "为空");
}
varValue = varValue.trim();
// 多个执行人id用逗号分隔
String[] userIds = varValue.split(",");
if (userIds != null && userIds.length > 0) {
String[] superiorsIds = null;
String[] directSuperiorsIds = null;
if (isGetSuperior) {
// 根据员工id取员工管理找直接上级
superiorsIds = getSuperiorsByUserID(Arrays.asList(userIds));
}
if (isGetDirectlySuperior) {
// 根据员工id取员工管理找直属上级
directSuperiorsIds = getDirectSuperiorsByUserID(Arrays
.asList(userIds));
}
String[] totalIds = conCatStrs(superiorsIds, directSuperiorsIds);
// 组建机构用户列表
if (totalIds != null && totalIds.length > 0) {
WorkFlowOrganizationUtils
.getOrgUserListByUserIdsWithSingleQuery(dataview,
totalIds);
}
}

return dataview;
}

// 取上一步执行人
private DataView getSuperior(RuleContext ruleContext,
boolean isGetSuperior, boolean isGetDirectlySuperior) {
List<String> vSysUserIds = new ArrayList<String>();
// 创建dataview对象数据
DataView dataview = WorkFlowOrganizationUtils
.createExecutionUnitDataView();
// 当前流程实例
TProcessInstance processInstance = super
.getCurrentProcessInstance(ruleContext);
// 如果没有当前流程实例则认为是流程启动的时候请求执行人函数的,此时上一步执行人为当前登录人
if (processInstance == null) {
String loginUserId = null;
Map<String, Object> flowVariables = super
.getFlowVariables(ruleContext);
if (null != flowVariables
&& flowVariables.containsKey("StartExecutionUnitId")) {
loginUserId = (String) flowVariables
.get("StartExecutionUnitId");
}
if (StringUtils.isEmpty(loginUserId)) {
throw new BusinessException(
"【执行人函数Hr_GetExecutionSuperior:取上一步执行人的直接上级】运行异常:"
+ "通过系统变量:v_sys_userID,获取当前登录人id为空");
}
vSysUserIds.add(loginUserId);
} else {
Activity currentActivity = super.getCurrentActivity(ruleContext);
String curActivityId = currentActivity.getId();

boolean isRejectOrSkip = isRejectOrSkip(ruleContext);

ProcessExecution fromProcessExecution = getFromProcessExecution(ruleContext);
if (isRejectOrSkip) {
// 来源当前信号为回退或跳转,需要找到回退或跳转活动的最后一次运行过的活动实例的来源活动。
fromProcessExecution = getMatchExecutionFromAllRunnedExecutions(
ruleContext, curActivityId);
fromProcessExecution = fromProcessExecution.getFrom();
}

if (null != fromProcessExecution) {

// 根据指定的活动实例ID寻找已完成的任务列表
TaskQuery taskQuery = VBASEWorkFlowServiceFactory
.getVBASEWorkFlowService().getTaskQuery();
List<Task> matchTaskLst = taskQuery
.findByExecutionIdAndStatesOrderByOrderNoASC(
fromProcessExecution.getId(),
new String[] { State.Running.name(),
State.Complete.name() });
if (!CollectionUtils.isEmpty(matchTaskLst)) {
// 收集匹配的活动上的已完成的任务对应的任务执行人
for (Task matchTask : matchTaskLst) {
String ownerId = matchTask.getOwner();
vSysUserIds.add(ownerId);
}
}
}
}
if (vSysUserIds != null && vSysUserIds.size() > 0) {
String[] superiorsIds = null;
String[] directSuperiorsIds = null;
if (isGetSuperior) {
// 根据员工id取员工管理找直接上级
superiorsIds = getSuperiorsByUserID(vSysUserIds);
}
if (isGetDirectlySuperior) {
// 根据员工id取员工管理找直属上级
directSuperiorsIds = getDirectSuperiorsByUserID(vSysUserIds);
}
String[] totalIds = conCatStrs(superiorsIds, directSuperiorsIds);
// 组建机构用户列表
if (totalIds != null && totalIds.length > 0) {
WorkFlowOrganizationUtils
.getOrgUserListByUserIdsWithSingleQuery(dataview,
totalIds);
}
}

return dataview;
}

// 合并两个字符串数组
private String[] conCatStrs(String[] superiorsIds,
String[] directSuperiorsIds) {
if (superiorsIds != null && directSuperiorsIds != null) {
return (String[]) ArrayUtils.addArrayElement(superiorsIds,
directSuperiorsIds);
}
if (superiorsIds == null && directSuperiorsIds == null) {
return null;
}
if (superiorsIds != null) {
return superiorsIds;
}
if (directSuperiorsIds != null) {
return directSuperiorsIds;
}
return null;
}

// 获取直接上级
private String[] getSuperiorsByUserID(List<String> vSysUserIds) {
List<String> results = new ArrayList<String>();
// 根据执行人Id数组vSysUserIds按照自己的业务规则查找直接上级Id列表并返回
// ....此处为自己的业务规则
return results.toArray(new String[results.size()]);
}

// 获取直属上级
private String[] getDirectSuperiorsByUserID(List<String> vSysUserIds) {
List<String> results = new ArrayList<String>();
// 根据执行人Id数组vSysUserIds按照自己的业务规则查找直属上级Id列表并返回
// ....此处为自己的业务规则
return results.toArray(new String[results.size()]);
}

}

1.3 发布流程执行人函数

发布流程执行人函数扩展后台代码规则到执行系统,可通过补丁方式或者发布到构件 库然后添加启动清单的方式,由项目根据实际情况自行决定。

1.4 在系统里新增执行人函数

在系统里新增执行人函数以及执行人函数配置方法如下:

① 访问首页 /业务系统初始化配置 /流程管理 /流程定义 /执行人函数管理页面:

img

②新增函数定义

img

注意:此处的规则英文名必须填写前面Serverrule_test_GetExecutionSuperior.java源码中@Func注解中的名字。其他必填项按实际情况填写即可。

③配置窗体编码

img

需要先部署vbase_workflow_exeunit_func_test构件。

④点击确定按钮保存配置

img

⑤在流程定义的执行人配置里面使用自己定义的执行人函数:

img

⑥这里会看到我们前面自己创建的执行人函数配置页面,然后输入执行人函数代码规则执行的参数就配置好了

img