In the actual work, to-do items are generally queried by the user ID, so that it is more simple and convenient. In Activiti, when the Human task node of the process is drawn, in order to facilitate later maintenance, and in order to better match the actual scenario, the assignee is usually not assigned directly, but rather the candidate group, which is the usual role. And many times, this role only a user, but in the implementation of the Activiti, which need an intermediate link, is to sign, this sign of the process, is not smart enough, the user will be very natural feel superfluous, a step unnecessary operation, then can this link to be omitted? This article will provide a way to solve this problem.
This problem, can only study the source code of the next Activiti, if you can find the extension point, then this problem is good to do, after research, found not difficult, the workload is not big, the following details (the premise is activiti and spring integration, other environments please extrapolate).
One, custom defaultactivitybehaviorfactory, the purpose of customizing this class is to create a custom usertaskactivitybehavior, The custom defaultactivitybehaviorfactory needs to be injected into the springprocessengineconfiguration by the Set method;
Second, the custom Usertaskactivitybehavior, through the extension Handleassignments method, carries on the processing to the assignee, the candidate and the candidate group. It should be noted that as to how to determine a candidate group only one user, how to obtain the only user, the developer needs to determine, the following sample code is for reference only.
import org.activiti.bpmn.model.usertask;import org.activiti.engine.impl.bpmn.behavior.usertaskactivitybehavior;import org.activiti.engine.impl.bpmn.parser.factory.defaultactivitybehaviorfactory;import org.activiti.engine.impl.task.taskdefinition;import org.springframework.beans.beansexception;import Org.springframework.context.applicationcontext;import org.springframework.context.applicationcontextaware ;p ublic class processactivitybehaviorfactory extends defaultactivitybehaviorfactory implements applicationcontextaware{ private applicationcontext applicationcontext; @Override public usertaskactivitybehavior createusertaskactivitybehavior ( usertask usertask, taskdefinition taskdefinition) { processusertaskactivitybehavior taskactivitybehavior = (Processusertaskactivitybehavior) Applicationcontext.getbean (" Taskactivitybehavior "); taskactivitybehavior.settaskdefinition ( Taskdefinition); return taskactivitybehavior; } @Override public void Setapplicationcontext (Applicationcontext applicationcontext) throws BeansException { this.applicationContext = applicationContext; }}
import java.util.collection;import java.util.list;import java.util.map;import Org.activiti.engine.activitiexception;import org.activiti.engine.activitiillegalargumentexception;import org.activiti.engine.TaskService;import org.activiti.engine.delegate.Expression;import org.activiti.engine.impl.bpmn.behavior.usertaskactivitybehavior;import org.activiti.engine.impl.persistence.entity.taskentity;import org.activiti.engine.impl.pvm.delegate.activityexecution;import org.activiti.engine.impl.task.taskdefinition;import Org.springframework.beans.factory.annotation.autowired;public class processusertaskactivitybehavior extends UserTaskActivityBehavior { @Autowired private taskservice taskservice; public Processusertaskactivitybehavior () { super (null); &nbsP; } public void settaskdefinition ( Taskdefinition taskdefinition) { super.taskdefinition = taskdefinition; } public Processusertaskactivitybehavior (taskdefinition taskdefinition) { super (taskdefinition); } @Override protected void handleassignments (taskentity task,activityexecution execution) { String assignee = null; List<String> candidateUserId = null,candidateGroupId = null; if ( Taskdefinition.getassigneeexpression () != null) { assignee = (String) taskdefinition.getassigneeexpression (). GetValue (execution); task.setassignee (Assignee,true,false); } if (Taskdefinition.getownerexpression () != null) { task.setowner (String) taskdefinition.getownerexpression (). GetValue ( Execution)); } if (!taskdefinition.getcandidategroupidexpressions (). IsEmpty ()) { for (expression groupidexpr : Taskdefinition.getcandidategroupidexpressions ()) { object value = Groupidexpr.getvalue (execution); if (value instanceof string) { candidategroupid = extractcandidates (String) value); Task.addcandidategroups (candidategroupid); } else if (value instanceof collection) { task.addcandidategroups (Collection) Value); } else { throw new activitiillegalargumentexception ("Expression did Not resolve to a string or collection of strings "); } } } if (!taskdefinition.getcandidateuseridexpressions (). IsEmpty ()) { for (expression useridexpr : Taskdefinition.getcandidateuseridexpressions ()) { object value = useridexpr.getvalue (execution); if (value instanceof string) { &nbsP; candidateuserid = extractcandidates (String) value); task.addcandidateusers (candidateUserId); } else if (value instanceof collection) { Task.addcandidateusers ((Collection) value); } else { throw new activitiexception ("expression did not resolve to a String or collection of strings "); } } } if (assignee == null && candidateuserid == null && candidategroupid.size () ==1) { string groupid = candidategroupid.get (0); // The following code developer self-determines the processing method string sql = "select user_id from sys_role_user where role_id = " + groupid + "' AND ROLE_TYPE = ' 3 '"; coretemplate coretemplate = corecontextcontainer.getcontext (). Getcoretemplate (); list data = coretemplate.find (sql,nUll,true); if (Data.size () == 1) { String userId = (String ) ((MAP) data.get (0)). Get ("user_id"); taskservice.claim (Task.getid (), userId);//eligible for automatic sign-off } } }}
The following is the corresponding spring configuration file, in particular, it is important to note that Taskactivitybehavior cannot be a singleton, the corresponding scope value is prototype.
<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "http://www.springframework.org/ Schema/beans " xmlns:xsi=" Http://www.w3.org/2001/XMLSchema-instance " xmlns:context= "Http://www.springframework.org/schema/context" xsi:schemalocation= "http://www.springframework.org/schema/beans http:// www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/ Spring-context-4.1.xsd "> <bean id=" Processengineconfiguration " class=" Com.process.ProcessEngineConfiguration "> <property name= "Activitybehaviorfactory" ref= "activityBehaviorFactory"/ > </bean > <bean id= " Activitybehaviorfactory " class=" Com.process.ProcessActivityBehaviorFactory "/> <bean id= "Taskactivitybehavior" class= "Com.process.ProcessUserTaskActivityBehavior" scope= "Prototype"/></beans>
The above code is tested in the Activiti5.15.1 version.
A method for automatic sign-off in Activiti when there is only one person in the candidate group