在绘制流程图或者直接在流程文件中通过Assignee来指定的方式。直接是写死的。
Flowable使用UEL进行表达式解析。UEL代表Unified Expression Language,是EE6规范的一部分(查看EE6规范了解更多信息)。
表达式可以用于Java服务任务(Java Service task)、执行监听器(Execution Listener)、任务监听器(Task Listener) 与 条件顺序流(Conditional sequence flow)等。尽管有值表达式与方法表达式这两种不同的表达式,Flowable通过抽象,使它们都可以在需要表达式的地方使用。
值表达式 Value expression: 解析为一个值。默认情况下,所有流程变量都可以使用。(若使用Spring)所有的Spring bean也可以用在表达式里。例如:
${myVar}
${myBean.myProperty}
myBean是Spring容器中的个Bean对象,表示调用的是bean的addNewOrder方法
首先新建一个值表达式的例子
可视编辑器–>分配用户–>固定值—>${assignee1}
/**
* 启动流程实例
*/
@Test
public void TestDeploymentRun() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 流程变量
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("assignee0", "张三");
variables.put("assignee1", "李四");
// 启动流程实例
// ProcessInstance processInstance = runtimeService.startProcessInstanceById("holidayRequest:1:37504", variables);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("MyHolidayUI001", variables);
System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // MyHolidayUI001:1:37504
System.out.println("processInstance.getProcessDefinitionKey() = " + processInstance.getProcessDefinitionKey());// MyHolidayUI001
System.out.println("processInstance.getActivityId() = " + processInstance.getActivityId());
System.out.println("processInstance.getId()" + processInstance.getId());// 40001
}
/**
* 完成任务
*/
@Test
public void TestCompleteTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processInstanceId("40001") //根据流程实例编号查找
.taskAssignee("张三")
.singleResult();
taskService.complete(task.getId());
}
调用一个方法,可以带或不带参数。当调用不带参数的方法时,要确保在方法名后添加空括号(以避免与值表达式混淆)
传递的参数可以是字面值(literal value),也可以是表达式,它们会被自动解析。例如:
${printer.print()}
${myBean.addNewOrder('orderName')}
${myBean.doSomething(myVar, execution)}
请注意,表达式支持解析(及比较)原始类型(primitive)、bean、list、array与map。
任务监听器(Task Listener)
我们在此处使用监听器来完成审批人的动态指定,那么我们在流程设计的时候就不需要指定assignee。但是需要指定任务监听器。
创建自定义监听器:
/**
* 动态指定部门经理审批监听器
*
* @return
* @author wangl
* @date 2023-12-15
*/
public class DeptLeaderTaskListener implements TaskListener {
private static final Logger LOGGER = LoggerFactory.getLogger(DeptLeaderTaskListener.class);
/**
* 注入字段(名称与流程设计时字段名称一致) 参数 多个的话用分号隔开 实例 userCode:00004737;status:1
*/
private FixedValue level;
private static final long serialVersionUID = 1L;
private TaskService taskService = SpringUtils.getBean(TaskService.class);
private ISysDeptService flowThirdService = SpringUtils.getBean(ISysDeptService.class);
RuntimeService runtimeService = SpringUtils.getBean(RuntimeService.class);
@Override
public void notify(DelegateTask delegateTask) {
String taskId = delegateTask.getId();
// 获取流程发起人
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(delegateTask.getProcessInstanceId())
.singleResult();
String startUserId = processInstance.getStartUserId();
// 获取部门负责人列表
List<String> depIds = flowThirdService.getLeaderByUserId(Long.valueOf(startUserId));
if (CollectionUtil.isEmpty(depIds)) {
LOGGER.warn("申请人[{}] 未指定部门领导人", startUserId);
return;
}
int level_int = Integer.parseInt(level.toString());
String leaderId = "";
for (int i = 0; i < depIds.size(); i++) {
if (i == level_int - 1) {
leaderId = depIds.get(i);
}
}
Map<String, Object> variables = taskService.getVariables(taskId);
delegateTask.setAssignee(leaderId);
variables.put("DeptLeaderTaskListener", leaderId);
taskService.setVariables(taskId, variables);
}
}