d2js + activiti 备忘

很久没玩 activiti 了再摸起来都有点陌生了,梳理了一下要点如下:

1. d2js 作为业务端发起流程。

d2js.exports.vocationRequest = 
d2js.vocationRequest = function(params){
	try{
		$V(this, params, {
			reason : T.string,
			duration : T.int 
		});
		
		this.startProcess('请假', params);
		
		this.session.message = 'vocation request success'  
	} catch(e){
		logger.error('error', Error.toJava(e));
		this.session.message = e + '';
	}
	this.response.sendRedirect(this.request.getHeader('referer'));
}

流程一般都是由业务系统发起的,这里假定为 d2js。

startProcess 封装了 activiti.runtimeService.startProcessInstanceByKey,其中第一个参数是已部署流程的流程名,第二个参数是变量。这些变量在流程的表达式里可以访问。

2. 流程引擎在 startProcess 或任务完成后自动进入下一个任务。

2.1 任务在设计器里可以指定 assignee,如果没有指定,应由 d2js 代码认领。

d2js.exports.listCandidateTasks =
d2js.listCandidateTasks = function(users, groups){
    sql{.
        select t.id_, t.name_, t.description_, t.task_def_key_, t.execution_id_,t.proc_inst_id_, t.create_time_, t.task_def_key_  
            from activiti.act_ru_task t , activiti.act_ru_identitylink l
            where t.assignee_ is null and (l.user_id_ = any(:users) or l.group_id_ = any(:groups)) and t.id_ = l.task_id_
            order by t.id_
    .}
         
    return this.query(sql, {users: $ARRAY('varchar', users || []), groups: $ARRAY('varchar', groups || [])});
}

d2js.exports.setAssignee = 
d2js.setAssignee = function(taskId){
    activiti.taskService.setAssignee(taskId, this.session.user.id);
}
d2js.exports.claim =
d2js.claim = function(params){
    try{
        application.activiti.taskService.claim(params.task, this.session.user.id);
        
        this.session.message = 'claim success'  
    } catch(e){
        this.session.message = e + '';
    }
    this.response.sendRedirect(this.request.getHeader('referer'));
}

setAssignee 和 claim 是等效的,claim 看起来更偏业务。(claim 可能不支持重入,这里不考证了)

2.2 Assignee 可以查看自己的任务。

d2js.exports.listAssignedTasks = 
d2js.listAssignedTasks = function(params){
    sql{.
        select t.id_, t.name_, t.description_, t.task_def_key_, t.execution_id_,t.proc_inst_id_, t.create_time_, t.task_def_key_
            from activiti.act_ru_task t where t.assignee_ = ?
    .}
         
    return this.query(sql, [this.session.user.id + '']);
}

3. 当 assignee 在现实世界处理完任务后,将处理结果提交并结束任务。结束任务在业务系统触发,而不是在规则引擎。

d2js.exports.handleRequest = 
d2js.handleRequest = function(params){
    try{
        var result = {approved: params.result == 'approved', 
                      managerMotivation: params.managerMotivation};
        application.activiti.taskService.complete(params.task, result.toJava());
        
        this.session.message = 'handle success'  
    } catch(e){
        this.session.message = e + '';
    }
    this.response.sendRedirect(this.request.getHeader('referer'));
}

4. 当规则引擎收到处理结果后,对处理结果进行判验,根据判验结果进入下一个分支。

 如图,d2js 通过completeTask 发来的变量可在连线的条件表达式中直接使用。

要之,在 d2js 和 activiti 配合时,业务系统不负责流向,规则引擎不负责业务,通常一个 bpmn 和一个 d2js 配合,前者如同指挥,后者如同乐队,配合完成演出。业务系统的 user id 权限等不需要暴露给规则引擎,二者没有太深耦合。

原文地址:https://www.cnblogs.com/inshua/p/12036343.html