Activiti工作流引擎使用

作者:澳门微尼斯人娱乐

是因为那样四个运行管理种类涉及到各类区别的事体数据. 如借款人音信有关关系借款ID, 银行卡新闻等; 如出借人新闻则提到用户ID, 电话号码等; 而对此开支相关如提前还款则关乎到提前还款日期, 还款金额等. 所以1套支撑分裂实际事情的流水生产线数据表结构也是丰富主要.

1.3 Activiti资料

  • 官网:

  • 下载:

  • 本子:Activiti的版本是从5开始的,因为Activiti是使用jBPM4的源码;本子发表:五个月宣布三遍。

  • Eclipse Plugin: 

  • Activit中文群:5435716

九.三 获取流程发起人

比方在起步流程的时候调用了上边包车型大巴代码:

?

1
identityService.setAuthenticatedUserId(currentUserId);

引擎会记录启摄人心魄,即在ACT_HI_PROINST表的START_USER_ID字段,可以因此下边包车型大巴代码获取。

?

1
2
HistoricProcessInstance hi = historyService.createHistoricProcessInstanceQuery().singleResult();
hi.getStartUserId();

玖.动态钦赐任务办理人

壹. 借款人银行卡消息修改

2.3.2 startProcessInstanceById

javadoc对其认证:

startProcessInstanceById(String processDefinitionId, String businessKey, Map variables) 
          Starts a new process instance in the exactly specified version of the process definition with the given id.

 

processDefinitionId:这几个参数的值能够通过repositoryService.createProcessDefinitionQuery()措施查询,对应数据库:ACT_RE_PROCDEF;每趟陈设一次流程定义就会添加一条数据,同名的本子号添加。

专门表明: 此可以钦赐分化版本的流程定义,让用户多1层选用。

2.三 业务和流程的涉及方式

本条标题在群里面很几个人都问过,那也是自身刚刚起初吸引的地方;

后来看了以下API发现RuntimeService有多个措施:

4.用到单元测试

单元测试均使用Spring的AbstractTransactionalJUnit四SpringContextTests作为SuperClass,并且在测试类添加:

?

1
2
@ContextConfiguration(locations = { "/applicationContext-test.xml" })
@RunWith(SpringJUnit4ClassRunner.class)

尽管Activiti也提供了测试的片段超类,可是感觉不佳用,所以自个儿包装了某个艺术。

代码请转移:

正如下面曾说起, 对于3个系统规划, 不恐怕一步到位, 在中期时要抓住最须求解决的题材, 比如在这么些系列早先阶段, 最基本的设计包罗:

二.2 使用引擎提供的Form还是自定义业务Form

一.简单介工作流引擎与Activiti

对于工作流引擎的分解请参考百度宏观:工作流引擎

玖.二 自动安装任务办理人

下边包车型大巴代码是接纳initiator作用,设置一个称号(不是变量而是变量名)到起步事件上,并且在起步流程时调用1些底下的方法:

?

1
identityService.setAuthenticatedUserId(currentUserId);

里头currentUserId表示近来用户,也便是开发银行流程的人,配置如下所示:

?

1
2
<startevent id="startevent1" name="Start" activiti:initiator="applyUserId"></startevent>
<usertask id="reportBack" name="销假" activiti:assignee="${applyUserId}"></usertask>

诸如此类流程运行之后如若职分流转至"销毁伪劣货物"节点则会自动把职责分配给运行流程的人。

公共化学工业作流模块:

Activiti工作流引擎使用

3.1 集成Spring

对此和Spring的集成Activiti做的没错,简单布署部分Bean代理即可兑现,可是有七个和作业相关的地点要提拔:

  • 配置processEngineConfiguration的时候属性transactionManager要采用和业务职能的同三个事务管理Bean,不然事务不一起。

  • 对于贯彻了org.activiti.engine.delegate包中的接口的类必要被工作控制的兑现类须要被Spring代理,并且增进事务的Annotation恐怕在xml中布局,例如:

?

1
2
3
4
5
6
7
8
9
10
/**
 * 创建缴费流程的时候自动创建实体
 *
 * @author HenryYan
 */
@Service
@Transactional
public class CreatePaymentProcessListener implements ExecutionListener {
   ....
}

二.一.一 修改源代码形式

修改源码

org.activiti.engine.impl.bpmn.diagram.ProcessDiagramCanvas

在构造方法

public ProcessDiagramCanvas(int width, int height)

中有1行代码是安装字体的,暗许是用Arial字体,那就是乱码发生的原故,把字改为本土的中文字体即可,例如:

?

1
Font font = new Font("WenQuanYi Micro Hei", Font.BOLD, 11);

自然假诺你有配备文件读取工具那么能够设置在*.properties文件中,作者便是如此做的:

?

1
Font font = new Font(PropertyFileUtil.get("activiti.diagram.canvas.font"), Font.BOLD, 11);

5.12本子伊始协助设置字体名称,在外燃机中添加如下设置,在生成图片时即可使用微软雅黑安装图片中的文字。

?

1
<property name="activityFontName" value="微软雅黑"></property>

◆✦以下对第一、三点进展拓展✦◆

8.结束

事先就想写那篇小说,未来好不简单成功了,费用了多少个钟头,希望能省掉你几天的光阴。

请读者仔细翻阅Activiti的用户手册和Javadoc。

来自:

6.UI及截图

结合实际业务描述二个工作从初阶到完工的经过,对于吸引的同窗看完出现转机了;这里运用请假作为例子。

5.各样气象的职分查询以及和业务对象关联

我们最近分为四中状态:未签收、办理中、运转中、已形成。

询问到职务如故流程实例后要展现在页面,那年须要充足业务数据,最终结果就是业务和流程的并集,请参考6.2

主编:

贰.5.1 我们的不二诀要

恐怕你会惊奇,因为我们并未有行使Activiti Modeler,我们以为用Viso已经能发挥流程图的趣味了,而且项目高管也是技巧出身,和开发人士也易于沟通。

当下以此类型是率先个应用Activiti的,起初大家在需求调查研讨阶段采纳Viso设计流程图,利用泳道流程图规划和客户关系,明确后由负责流程的开发人士用Eclipse Designer设计赢得bpmn20.xml,最后布署。

伍.种种气象的职分查询以及和事务对象关联

我们眼下分为4中状态:未签收、办理中、运营中、已形成。

询问到职务照旧流程实例后要显得在页面,这年须求充分业务数据,最后结果正是业务和流程的并集,请参考6.2

陆.一 单独二个列表负责申请

诸如此类的裨益是报名和流程办理分离开处理,列表展现未运维流程的请假记录(数据库PROCESS_INSTANCE_ID为空)。

报名界面的截图:

图片 1

❺ 生成还款结清注明

五.5 查询时和事情关系

唤醒:在此以前在工作对象添加了PROCESS_INSTANCE_ID字段

思路:今后能够运用那一个字段查询了,不管是Task依然ProcessInstance都得以收获流程实例ID,可以依据流程实例ID查询实体然后把流程对象设置到实体的壹性子质中由Action大概Controller输出到前台。

代码请参见:

二.伊始使用境遇难题采访

因为Activiti刚刚退出不久所以资料相比空缺,汉语资料更少的可怜,所以起先的时候一头雾水(即便事先用过工作流,但是感觉距离很多),而且官方的手册还不是很周到;所以自个儿把自个儿在学习运用的进程遇到的1部分疑点都位列出来分享给大家;以下几点是本身遇见和想到的,要是您还有何难题能够在评论中和本身调换再补偿。

7.开启Logger

  1. 添加log4j的jar
  2. 设置log4j.logger.java.sql=DEBUG

图片 2回去微博,查看越多

5.3 运行中(ProcessInstance)

简单的说正是未有终结的流水生产线,全体参预过的人都应有能够见到那些实例,可是Activiti的API未有可以经过用户查询的章程,这几个只可以协调用hack的艺术处理了,笔者眼下还未有拍卖。

从表ACT_RU_EXECUTION中查询数据。

对应的API查询:

/**
 * 获取未经完成的流程实例查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicProcessInstanceQuery createUnFinishedProcessInstanceQuery(String userId) {
    ProcessInstanceQuery unfinishedQuery = runtimeService.createProcessInstanceQuery().processDefinitionKey(getProcessDefKey())
            .active();
    returnunfinishedQuery;
}

?

2.二.壹 引擎提供的Form

概念表单的艺术在种种Task标签中定义extensionElementsactiviti:formProperty即可,到达那一个节点的时候能够透过API读取表单成分。

Activiti官方的例子使用的正是在流程定义中设置每1个节点呈现怎么的表单哪些字段要求显示、哪些字段只读、哪些字段必填。

然而那种格局唯有适用于比较不难的流水生产线,对于某个复杂只怕页面供给工作逻辑的判定的处境就不适用了。

对于数据的保存都以在电动机的表中,不便宜和其他表的关系、对总种类统的安插性也不利!

二.5 流程图设计工具用哪些

Activiti提供了多少个流程设计工具,但是面向对象差别。

  • Activiti Modeler,面向业务人士,使用开源的BPMN设计工具Signavio,使用BPMN描述业务流程图

  • Eclipse Designer,面向开发人士,Eclipse的插件,能够让开发职员定制每种节点的习性(ID、Name、Listener、Attr等)

➤ 依照作业需求提供ASync的processor处理基类, 因为实际利用中发觉, 壹些事务的处理(如批量)需求一段时间的执行才能成功, 而异步处理基类则形成基础完毕, 并由相应子类去贯彻虚函数即可.

2.壹.一 修改源代码格局

修改源码

org.activiti.engine.impl.bpmn.diagram.ProcessDiagramCanvas

在构造方法

public ProcessDiagramCanvas(int width, int height)

中有壹行代码是安装字体的,私下认可是用 Arial 字体,那便是乱码发生的原委,把字改为本地的汉语字体即可,例如:

Font font = new Font("WenQuanYi Micro Hei", Font.BOLD, 11);

当然假若你有布置文件读取工具那么能够安装在*.properties文件中,我就是那般做的:

Font font = new Font(PropertyFileUtil.get("activiti.diagram.canvas.font"), Font.BOLD, 11);
二.一.2.贰 使用Ant脚本打包Zip文件

那也是我们利用的法门,你能够手动选项xml和png打包成zip格式的文件,也足以像我们一致使用ant target的不二等秘书诀打包那八个文本。

123456789101112
<?xml version="1.0" encoding="UTF-8"?><project name="foo">     <property name="workflow.definition" value="foo-common-core/src/main/resources/diagrams" />    <property name="workflow.deployments" value="foo-common-core/src/main/resources/deployments" /> <target name="workflow.package.oa.leave">     <echo>打包流程定义及流程图::OA-请假</echo>        <zip destfile="${workflow.deployments}/oa/leave.zip" basedir="${workflow.definition}/oa/leave" update="true"            includes="*.xml,*.png" /> </target></project>

view rawbuild.xml hosted with ❤ by GitHub

那样当修改流程定义文件后1旦运维ant命令就足以打包了:

ant workflow.package.oa.leave

现在配置bar只怕zip文件查看流程图图片就不是乱码了,而是你的压缩包里面包车型客车png文件。

4.贰 业务对象和流程关联测试

代码请转移:

二个好的宏图不是一步到位的宏图, 而是三个循规蹈矩的长河以及不断重构的进度. 但是丰富重要的一点就是在壹从头能够依据当下的供给以及所能预言的急需开始展览规划, 并且在那么些基础框架代码上支付要尤其有利于和简洁.

②.6 Eclipse Designer存在的难题

本条插件有一个很看不惯的Bug平素未修复,安装了插件后Eclipse的复制和粘帖快速键会被转换为(Ctrl Insert、Shift Insert);Bug描述请见:

  • Activit Forums中告知的Bug

  • Jira的登记

故此最后大家不得不单独开一个设置了Eclipse Designer的Eclipse专门用来规划流程图,那样就不影响健康使用Eclipse JAVAEE了。

2.3.1 startProcessInstanceByKey

javadoc对其证实:

startProcessInstanceByKey(String processDefinitionKey, Map variables) 
          Starts a new process instance in the latest version of the process definition with the given key

其中businessKey就是业务ID,例如要申请请假,那么先填写登记音信,然后(保存 运转流程),因为请假是独立设计的数据表,所以保存后得到实体ID就足以把它传给processInstanceBusinessKey艺术运维流程。当需求基于businessKey查询流程的时候就能够通过API查询:

?

1
runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(processInstanceBusinessKey, processDefinitionKey)

建议数据库冗余设计:在业务表设计的时候添加一列:PROCESS_INSTANCE_ID varchar2(64),在流程运维今后把流程ID更新到事情表中,那样不管从作业依旧流程都能够查询到对方!

特意表达: 此方法运行时自动选择新型版本的流程定义。

贰.二.1 引擎提供的Form

概念表单的章程在每一种Task标签中定义extensionElementsactiviti:formProperty即可,到达那几个节点的时候能够由此API读取表单成分。

Activiti官方的例证使用的就是在工艺流程定义中安装每三个节点彰显怎么的表单哪些字段必要体现、哪些字段只读、哪些字段必填。

可是那种措施唯有适用于相比较不难的流程,对于有个别复杂或许页面须求工作逻辑的判定的情状就不适用了。

对于数据的保存都以在内燃机的表中,不便于和任何表的涉及、对总连串统的宏图也有损!

这么只怕那样的狐疑也许斗争,

2.贰.二 自定义业务Form

那种办法应该是豪门用的最多的了,因为相似的事情种类业务逻辑都会比较复杂,而且数据库中过多表都会有依靠关系,表单中有很多意况判断。

诸如大家的种类适用jQuery UI作为UI,有众多javascript代码,页面包车型客车大队人马操作要求新鲜处理(例如:七个采用的排斥、各个节点遵照项目和操作人展现不相同的按钮);基本每种商行都有一套自身的UI风格,要维持八个系统的操作习惯壹致只好利用自定义表单才能满足。

1.2 Activiti与JBPM5?

对于Activiti、jBPM四、jBPM5我们应当怎么抉择,在InfoQ上有一篇文章写的很好,从大的范畴相比各种引擎之间的歧异,请参考小说:纵观jBPM:从jBPM3到jBPM5以及Activiti5

玖.一 手动设置任务办理人

?

1
<usertask id="hrAudit" name="人事审批" activiti:assignee="${hrUserId}"></usertask>

动态钦命任务办理人是群里面询问比较多的题材之一,其实正是一层窗户纸,只要在职务完毕的时候传递activiti:assignee属性中的变量即可。


Map<String, Object> variables = new HashMap<String, Object>();

variables.put("hrUserId", hrUserId);

taskService.complete(taskId, variables);


Activiti中提供便捷的查询类, 如: ProcessInstanceQuery, TaskQuery. 其同时协助依照Process和Task相应的属性数据实行查询, 和Request/Snapshot以及property有相当的大的相似之处, 借鉴并依照实际情形贯彻协调的RequestQuery类, 协助种种复杂查询, 如: 依据钦定的property的name和value查询, 支持or的询问等。

贰.一 安排流程图后汉语乱码

乱码是直接缠绕着国人的标题,此前各种技术、工具出现乱码的题材写过无数篇章,那里也不例外……,Activiti的乱码难点在流程图中。

流程图的乱码如下图所示:

图片 3

化解办法有二种:

陆.三 流程跟踪

图形情势浮现当前节点:

图片 4

列表情势体现流程流转进程:

图片 5

10. 职务代办

有的是人问“Owner”属性为啥是空的,几时用?要询问它的功能首先要领会“代办”。

代办的定义能够用上边包车型地铁一句话总结:

你领导接到一个任务,让你代办,你办理完成后任务还是回归到你的领导,事情是你做的,功劳是你领导的,此乃代办也!

看看这么些单元测试你就知道怎么着是代办:ProcessTestDelegateTask

最好把activiti-study本条类型下载下来导入到Eclipse中运转一下:

原标题:基于工作流的阳台管理体系规划

四.壹 验证流程图设计是不是正确

代码请转移:

九.1 手动设置职责办理人

?

1
<usertask id="hrAudit" name="人事审批" activiti:assignee="${hrUserId}"></usertask>

动态钦点任务办理人是群里面询问相比多的题材之一,其实正是一层窗户纸,只要在职分到位的时候传递activiti:assignee属性中的变量即可。


Map<String, Object> variables = new HashMap<String, Object>();

variables.put("hrUserId", hrUserId);

taskService.complete(taskId, variables);


2.叁.三 如何抉择

建议选取startProcessInstanceByKey,特殊意况需求使用过去的本子选取选取startProcessInstanceById

那边举多少个例证

贰.2.一 引擎提供的Form

概念表单的措施在各个Task标签中定义extensionElementsactiviti:formProperty即可,到达这些节点的时候能够透过API读取表单成分。

Activiti官方的例证使用的正是在流水生产线定义中装置每三个节点显示怎么的表单哪些字段供给显示、哪些字段只读、哪些字段必填。

不过那种办法唯有适用于对比简单的流水生产线,对于有个别复杂只怕页面须求工作逻辑的判定的气象就不适用了。

对于数据的保留都以在外燃机的表中,不便民和其他表的涉嫌、对总连串统的布置性也有损!

5.1 未签收(Task)

该类任务针对于把Task分配给四个剧中人物时,例如部门管理者,因为单位长官角色能够钦赐多个人所以供给先签收再办理,术语:抢占式

对应的API查询:

?

1
2
3
4
5
6
7
8
9
10
/**
 * 获取未签收的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
public TaskQuery createUnsignedTaskQuery(String userId) {
    TaskQuery taskCandidateUserQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey())
            .taskCandidateUser(userId);
    return taskCandidateUserQuery;
}

2.三 业务和流程的涉嫌格局

以此标题在群里面很多个人都问过,那也是本人刚刚先导吸引的地方;

新生看了以下API发现RuntimeService有多少个主意:

图片 6

二.肆.一 提出处理情势

Activiti有一个IdentityService接口,通过这些接口能够操控Activiti的ACT_ID_*表的数据,1般的做法是用工作系统的权限管理模块维护用户数据,当实行CRUD操作的时候在本来业务逻辑前面添加同步到Activiti的代码;例如添加八个用户时同步Activiti User的代码片段:

/**
 * 保存用户信息 并且同步用户信息到activiti的identity.User,同时设置角色
 * @param user
 * @param roleIds
 */
public void saveUser(User user, List<Long> roleIds, boolean synToActiviti) {
    accountManager.saveEntity(user);
    String userId = user.getId().toString();

    if (synToActiviti) {
        List<org.activiti.engine.identity.User> activitiUsers = identityService.createUserQuery().userId(userId).list();
        if (activitiUsers.size() == 1) {
            //更新信息
            org.activiti.engine.identity.User activitiUser = activitiUsers.get(0);
            activitiUser.setFirstName(user.getName());
            activitiUser.setLastName("");
            activitiUser.setPassword(user.getPassword());
            activitiUser.setEmail(user.getEmail());
            identityService.saveUser(activitiUser);

            // 删除用户的membership
            List<Group> activitiGroups = identityService.createGroupQuery().groupMember(userId).list();
            for (Group group : activitiGroups) {
                identityService.deleteMembership(userId, group.getId());
            }

            // 添加membership
            for (Long roleId : roleIds) {
                Role role = roleManager.getEntity(roleId);
                identityService.createMembership(userId, role.getEnName());
            }

        } else {
            org.activiti.engine.identity.User newUser = identityService.newUser(userId);
            newUser.setFirstName(user.getName());
            newUser.setLastName("");
            newUser.setPassword(user.getPassword());
            newUser.setEmail(user.getEmail());
            identityService.saveUser(newUser);

            // 添加membership
            for (Long roleId : roleIds) {
                Role role = roleManager.getEntity(roleId);
                identityService.createMembership(userId, role.getEnName());
            }
        }
    }

}

 

除去操作也和这一个看似!

无论是从工作体系保证用户如故从Activiti维护,肯定要规定一方,然后CRUD的时候一起到对方,假设急需壹起五个子系统那么能够再调用WebService实现。

玖.二 自动安装职务办理人

上面包车型客车代码是使用initiator功效,设置三个称号(不是变量而是变量名)到运转事件上,并且在起步流程时调用壹些上边包车型大巴主意:

?

1
identityService.setAuthenticatedUserId(currentUserId);

个中currentUserId表示近期用户,也正是运转流程的人,配置如下所示:

?

1
2
<startevent id="startevent1" name="Start" activiti:initiator="applyUserId"></startevent>
<usertask id="reportBack" name="销假" activiti:assignee="${applyUserId}"></usertask>

这么流程运转之后纵然职分流转至"销毁伪劣货物"节点则会自动把职务分配给运维流程的人。

5.伍 查询时和事务关系

唤醒:在此以前在作业对象添加了PROCESS_INSTANCE_ID字段

思路:现在得以行使这些字段查询了,不管是Task照旧ProcessInstance都足以收获流程实例ID,能够根据流程实例ID查询实体然后把流程对象设置到实体的一特性格中由Action恐怕Controller输出到前台。

代码请参考:

◆✦下边为多少个典型的业务流程✦◆

四.选用单元测试

单元测试均选取Spring的AbstractTransactionalJUnit四SpringContextTests作为SuperClass,并且在测试类添加:

@ContextConfiguration(locations = { "/applicationContext-test.xml"})
@RunWith(SpringJUnit4ClassRunner.class)

?

就算如此Activiti也提供了测试的壹些超类,可是感觉倒霉用,所以自身包裹了部分措施。

代码请转移:

二.四.壹 提出处理方式

Activiti有一个IdentityService接口,通过那些接口能够操控Activiti的ACT_ID_*表的多寡,壹般的做法是用工作体系的权位管理模块维护用户数量,当实行CRUD操作的时候在原始业务逻辑前边添加同步到Activiti的代码;例如添加3个用户时同步Activiti User的代码片段:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
/** * 保存用户信息 并且同步用户信息到activiti的identity.User,同时设置角色 * @param user * @param roleIds */public void saveUser(User user, List<Long> roleIds, boolean synToActiviti) { accountManager.saveEntity(user); String userId = user.getId().toString();   if (synToActiviti) {      List<org.activiti.engine.identity.User> activitiUsers = identityService.createUserQuery().userId(userId).list();       if (activitiUsers.size() == 1) {          //更新信息         org.activiti.engine.identity.User activitiUser = activitiUsers.get(0);          activitiUser.setFirstName(user.getName());           activitiUser.setLastName("");          activitiUser.setPassword(user.getPassword());            activitiUser.setEmail(user.getEmail());          identityService.saveUser(activitiUser);             // 删除用户的membership          List<Group> activitiGroups = identityService.createGroupQuery().groupMember(userId).list();            for (Group group : activitiGroups) {                identityService.deleteMembership(userId, group.getId());          }            // 添加membership          for (Long roleId : roleIds) {               Role role = roleManager.getEntity(roleId);                identityService.createMembership(userId, role.getEnName());           }        } else {         org.activiti.engine.identity.User newUser = identityService.newUser(userId);          newUser.setFirstName(user.getName());            newUser.setLastName("");           newUser.setPassword(user.getPassword());         newUser.setEmail(user.getEmail());           identityService.saveUser(newUser);          // 添加membership          for (Long roleId : roleIds) {               Role role = roleManager.getEntity(roleId);                identityService.createMembership(userId, role.getEnName());           }        }    } }

view rawAccountServiceImpl.java hosted with ❤ by GitHub

删去操作也和那么些就好像!

不管从工作系统尊敬用户依旧从Activiti维护,肯定要明确一方,然后CRUD的时候共同到对方,固然急需1块多少个子系统那么能够再调用WebService达成。

3.配置

二. 提前还款流程

3.1 集成Spring

对于和Spring的集成Activiti做的正确,简单安顿部分Bean代理即可兑现,但是有四个和工作相关的地点要提示:

  • 配置processEngineConfiguration的时候属性transactionManager要利用和工作成效的同一个事务管理Bean,不然事务分裂台。

  • 对于实现了org.activiti.engine.delegate包中的接口的类要求被工作控制的落到实处类供给被Spring代理,并且增加事务的Annotation只怕在xml中配备,例如:

    /**
     * 创建缴费流程的时候自动创建实体
     *
     * @author HenryYan
     */
    @Service
    @Transactional
    publicclass CreatePaymentProcessListener implementsExecutionListener {
       ....
    }
    

?

5.4 已完成(HistoricProcessInstance)

业已竣工的流水生产线实例。

从表ACT_HI_PROCINST中查询数据。

?

1
2
3
4
5
6
7
8
9
10
/**
 * 获取已经完成的流程实例查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
public HistoricProcessInstanceQuery createFinishedProcessInstanceQuery(String userId) {
    HistoricProcessInstanceQuery finishedQuery = historyService.createHistoricProcessInstanceQuery()
            .processDefinitionKey(getProcessDefKey()).finished();
    return finishedQuery;
}

5.1 未签收(Task)

此类职务针对于把Task分配给贰个剧中人物时,例如部门首长,因为机构经理剧中人物能够指定几个人所以要求先签收再办理,术语:抢占式

对应的API查询:

?

1
2
3
4
5
6
7
8
9
10
/**
 * 获取未签收的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
public TaskQuery createUnsignedTaskQuery(String userId) {
    TaskQuery taskCandidateUserQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey())
            .taskCandidateUser(userId);
    return taskCandidateUserQuery;
}

本文由威尼斯人科技发布,转载请注明来源

关键词: 微尼斯人娱乐 威尼斯www608cc