原标题:基于工作流的平台管理连串规划

Activiti工作流引擎使用

澳门金沙4787.com官网 1

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

对于工作流引擎的分解请参见百度完善:干活流引擎

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

对此工作流引擎的分解请参考百度完善:干活流引擎

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

对此工作流引擎的分解请参见百度完善:办事流引擎

对于互联网经济平台来说,首要的事体愈发是关联资金业务相关操作时都有须求有相关的审批流程.同时在流水线的流转进度中须求和一一业务系统进行互动,达成真正的业务处理,
并记录这一个过程中所有人的操作以及每一步操作时所涉及数额快照,以便于内外部审计和题材的追溯.

1.1 我与做事流引擎

在首先家商家工作的时候根本义务就是开发OA系统,当然基本都是有工作流的支撑,然则当下使用的工作流引擎是店铺部分牛人开发的(据说是用一个开源的引擎修改的),名称叫CoreFlow;作用相对Activiti来说相比弱,可是能满足日常的接纳,当然也有成百上千的题目由此后来大家只可以修改引擎的代码打补丁。

现今是自家工作的第二家商厦,因为要开发ERP、OA等系统要求动用工作流,在档次调研阶段自己先找找资料选用使用哪个开源工作流引擎,最后确定了Activiti5并按照商家的架构做了有些DEMO。

1.1 我与办事流引擎

在首先家集团做事的时候根本义务就是开发OA系统,当然基本都是有工作流的支撑,但是当下使用的工作流引擎是合营社部分牛人开发的(据说是用一个开源的引擎修改的),名称叫CoreFlow;功效相对Activiti来说比较弱,可是能满意平常的采纳,当然也有过多的题目由此后来大家不得不修改引擎的代码打补丁。

今昔是自己工作的第二家公司,因为要开发ERP、OA等系统要求动用工作流,在品种调研阶段自己先找找资料选用采用哪个开源办事流引擎,最后确定了Activiti5并基于商家的架构做了部分DEMO。

1.1 我与做事流引擎

在首先家协作社工作的时候根本义务就是开发OA系统,当然基本都是有工作流的支撑,然而当下采取的干活流引擎是公司部分牛人开发的(据说是用一个开源的引擎修改的),名称叫CoreFlow;成效相对Activiti来说相比弱,然而能满意普通的采纳,当然也有成千成万的题材由此后来我们只好修改引擎的代码打补丁。

前日是自己工作的第二家公司,因为要开发ERP、OA等体系必要动用工作流,在品种调研阶段自己先找找资料采取选用哪个开源行事流引擎,最后确定了Activiti5并基于商家的架构做了一些DEMO。

◆✦下边为五个杰出的业务流程✦◆

1.2 Activiti与JBPM5?

对此Activiti、jBPM4、jBPM5大家应有怎么样抉择,在InfoQ上有一篇文章写的很好,从大的框框比较各类引擎之间的分裂,请参见文章:纵观jBPM:从jBPM3到jBPM5以及Activiti5

1.2 Activiti与JBPM5?

对此Activiti、jBPM4、jBPM5大家应该怎么样抉择,在InfoQ上有一篇小说写的很好,从大的框框相比种种引擎之间的距离,请参见小说:纵观jBPM:从jBPM3到jBPM5以及Activiti5

1.2 Activiti与JBPM5?

对此Activiti、jBPM4、jBPM5大家应当怎么抉择,在InfoQ上有一篇小说写的很好,从大的框框相比较种种引擎之间的异样,请参见作品:纵观jBPM:从jBPM3到jBPM5以及Activiti5

(注: 为了证实方便, 已经简化和修改相关手续, 和点融实际操作不平等)

【澳门金沙4787.com官网】Activiti工作流引擎使用,工作流引擎Activiti使用总括。1.3 Activiti资料

  • 官网:

  • 下载:

  • 本子:Activiti的版本是从5开始的,因为Activiti是使用jBPM4的源码;本子公布:三个月宣布四回。

  • Eclipse Plugin: 

  • Activit中文群:5435716

1.3 Activiti资料

  • 官网:

  • 下载:

  • 本子:Activiti的本子是从5开始的,因为Activiti是使用jBPM4的源码;本子公布:四个月发表三回。

  • Eclipse Plugin: 

  • Activit中文群:236540304

1.3 Activiti资料

  • 官网:

  • 下载:

  • 本子:Activiti的版本是从5开始的,因为Activiti是使用jBPM4的源码;本子公布:多个月揭橥一遍。

  • Eclipse Plugin: 

  • Activit中文群:236540304

澳门金沙4787.com官网 2

2.起头使用蒙受题目收集

因为Activiti刚刚退出不久所以资料相比空缺,粤语资料越发少的可怜,所以开首的时候一头雾水(固然事先用过工作流,可是感觉距离很多),而且官方的手册还不是很圆满;所以我把自家在上学使用的进度遇到的有的问题都位列出来分享给我们;以下几点是自身遇见和想到的,假设你还有怎样问题可以在评论中和我互换再补充。

2.第一使用碰着问题采访

因为Activiti刚刚退出不久所以资料比较空缺,汉语资料越发少的可怜,所以初步的时候一头雾水(固然事先用过工作流,不过感觉距离很多),而且官方的手册还不是很圆满;所以我把自己在学习使用的历程蒙受的一部分疑点都位列出来分享给咱们;以下几点是本人境遇和想到的,如若你还有何样问题可以在评论中和本身调换再补充。

2.发轫使用遇到问题采访

因为Activiti刚刚退出不久所以资料相比较空缺,中文资料尤其少的可怜,所以起首的时候一头雾水(固然事先用过工作流,可是感觉距离很多),而且官方的手册还不是很圆满;所以我把自家在就学使用的进度碰到的一些质疑都位列出来分享给我们;以下几点是自己遇上和想到的,如若你还有怎样问题可以在评论中和自家调换再补充。

一. 借款人银行卡音讯修改

2.1 布署流程图后汉语乱码

乱码是平素缠绕着国人的题材,往日各种技术、工具出现乱码的题材写过不少篇章,那里也不例外……,Activiti的乱码问题在流程图中。

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

澳门金沙4787.com官网 3

解决办法有三种:

2.1 安顿流程图后汉语乱码

乱码是直接缠绕着国人的题目,此前种种技术、工具出现乱码的问题写过不少小说,那里也不例外……,Activiti的乱码问题在流程图中。

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

澳门金沙4787.com官网 4

解决办法有三种:

2.1 部署流程图后粤语乱码

乱码是直接缠绕着国人的题材,以前各种技术、工具出现乱码的题目写过许多篇章,那里也不例外……,Activiti的乱码问题在流程图中。

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

澳门金沙4787.com官网 5

解决办法有三种:

该流程发起原因根本是出于借款人银行卡转移原因须要修改. 流程关键步骤为:

2.1.1 修改源代码格局

修改源码

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.1.1 修改源代码格局

修改源码

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

在构造方法

public ProcessDiagramCanvas(int width, int height)

中有一行代码是安装字体的,默许是用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>

2.1.1 修改源代码方式

修改源码

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

在构造方法

public ProcessDiagramCanvas(int width, int height)

中有一行代码是安装字体的,默许是用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>

❶ 用户联系客户服务人员,提交报名, 包涵借款音信, 手持身份证照片,
银行卡新闻等

2.1.2 使用压缩包格局安插

Activiti扶助布署*.bpmn20.xml、bar、zip格式的流程定义。

应用Activit Deisigner工具设计流程图的时候会有三个品类的公文:

  • .activiti设计工具使用的文书

  • .bpmn20.xml规划工具自动按照.activiti文件生成的xml文件

  • .png流程图图片

解决办法就是把xml文件和图片文件同时安顿,因为在独立陈设xml文件的时候Activiti会自动生成一张流程图的图片文件,但是如此在采纳的时候坐标和图片对应不起来……

于是把xml和图纸同时陈设的时候Activiti自动关联xml和图表,当要求取得图片的时候一向回到陈设时压缩包里面的图片文件,而不是Activiti自动生成的图纸文件

2.1.2 使用压缩包格局配置

Activiti协理布署*.bpmn20.xml、bar、zip格式的流水线定义。

选取Activit Deisigner工具设计流程图的时候会有多个体系的文件:

  • .activiti设计工具使用的文本

  • .bpmn20.xml规划工具自动按照.activiti文件生成的xml文件

  • .png流程图图片

解决办法就是把xml文件和图片文件同时计划,因为在独立安顿xml文件的时候Activiti会自动生成一张流程图的图形文件,可是如此在运用的时候坐标和图片对应不起来……

故而把xml和图纸同时配备的时候Activiti自动关联xml和图表,当要求得到图片的时候一向回到安顿时压缩包里面的图形文件,而不是Activiti自动生成的图样文件

2.1.2 使用压缩包方式配置

Activiti协助安顿*.bpmn20.xml、bar、zip格式的流程定义。

行使Activit Deisigner工具设计流程图的时候会有三个品种的文本:

  • .activiti设计工具使用的文件

  • .bpmn20.xml规划工具自动根据.activiti文件生成的xml文件

  • .png流程图图片

解决办法就是把xml文件和图片文件同时布署,因为在独立布署xml文件的时候Activiti会自动生成一张流程图的图片文件,可是那样在选取的时候坐标和图纸对应不起来……

由此把xml和图表同时布署的时候Activiti自动关联xml和图片,当必要取得图片的时候从来重返安插时压缩包里面的图片文件,而不是Activiti自动生成的图纸文件

❷ 申请提交系统后, 由风控举办审批

2.1.2.1 使用工具打包Bar文件

右键项目名称然后点击“Create deployment
artifacts”,会在src目录中创设deployment文本夹,里面包涵*.bar文件.

2.1.2.1 使用工具打包Bar文件

在“Package Explorer”视图中右键项目名称然后点击“Create deployment
artifacts”,会在src目录中开创deployment文件夹,里面富含*.bar文件.

2.1.2.1 使用工具打包Bar文件

在“Package Explorer”视图中右键项目名称然后点击“Create deployment
artifacts”,会在src目录中开创deployment文本夹,里面包罗*.bar文件.

❸ 运营单位展开修改操

2.1.2.2 使用Ant脚本打包Zip文件

那也是我们应用的主意,你可以手动接纳xml和png打包成zip格式的文书,也能够像大家同样选取ant
target的措施打包那三个文本。

<?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>

这么当修改流程定义文件后一旦运行ant命令就足以打包了:

ant workflow.package.oa.leave

现在安顿bar或者zip文件查看流程图图片就不是乱码了,而是你的压缩包里面的png文件。

2.1.2.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

如此当修改流程定义文件后若是运行ant命令就可以打包了:

ant workflow.package.oa.leave

现在布局bar或者zip文件查看流程图图片就不是乱码了,而是你的压缩包里面的png文件。

2.1.2.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

如此当修改流程定义文件后只要运行ant命令就足以打包了:

ant workflow.package.oa.leave

现在安排bar或者zip文件查看流程图图片就不是乱码了,而是你的压缩包里面的png文件。

二. 提前还款流程

2.2 使用引擎提供的Form照旧自定义业务Form

2.2 使用引擎提供的Form依旧自定义业务Form

2.2 使用引擎提供的Form仍然自定义业务Form

发起流程的根本原因是用户愿意根据合同举办提前还款. 流程关键步骤为:

2.2.1 引擎提供的Form

概念表单的措施在各样Task标签中定义extensionElementsactiviti:formProperty即可,到达这么些节点的时候可以由此API读取表单元素。

Activiti官方的例证使用的就是在工艺流程定义中设置每一个节点突显怎么的表单哪些字段要求出示、哪些字段只读、哪些字段必填。

而是那种办法只有适用于比较简单的流程,对于有些复杂或者页面须要工作逻辑的判定的场地就不适用了。

对于数据的保留都是在发动机的表中,不便利和任何表的涉及、对整种类统的筹划也不利于!

2.2.1 引擎提供的Form

概念表单的格局在各类Task标签中定义extensionElementsactiviti:formProperty即可,到达那些节点的时候可以通过API读取表单元素。

Activiti官方的例证使用的就是在流水线定义中安装每一个节点彰显怎么的表单哪些字段需求出示、哪些字段只读、哪些字段必填。

可是那种方法只有适用于相比不难的流程,对于有些复杂或者页面必要工作逻辑的判断的情状就不适用了。

对于数据的保存都是在发动机的表中,不便于和其余表的涉嫌、对所有系统的统筹也不利!

2.2.1 引擎提供的Form

概念表单的方法在各样Task标签中定义extensionElementsactiviti:formProperty即可,到达那一个节点的时候可以因此API读取表单元素。

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

可是那种艺术唯有适用于相比简单的流水线,对于有些复杂或者页面须求工作逻辑的论断的图景就不适用了。

对于数据的保存都是在发动机的表中,不便宜和任何表的关系、对整个系统的设计也不利于!

❶ 借款人联系客服人士, 提交报名

2.2.2 自定义业务Form

那种措施应该是豪门用的最多的了,因为相似的政工连串业务逻辑都会相比复杂,而且数据库中许多表都会有依靠关系,表单中有成百上千动静判断。

比如大家的连串适用jQuery
UI作为UI,有众多javascript代码,页面的诸多操作须要独特处理(例如:五个挑选的排斥、每个节点依据项目和操作人突显区其他按钮);基本每个公司都有一套自己的UI风格,要保全三个系统的操作习惯一致只好利用自定义表单才能满意。

2.2.2 自定义业务Form

那种措施应该是大家用的最多的了,因为相似的事体序列业务逻辑都会比较复杂,而且数据库中过多表都会有依靠关系,表单中有不可胜言景观判断。

比如说大家的系统适用jQuery
UI作为UI,有为数不少javascript代码,页面的不少操作须求独特处理(例如:多个挑选的排挤、每个节点依据项目和操作人展现分化的按钮);基本每个集团都有一套自己的UI风格,要保险八个连串的操作习惯一致只可以选拔自定义表单才能满意。

2.2.2 自定义业务Form

那种艺术应该是豪门用的最多的了,因为一般的事情系统工作逻辑都会相比复杂,而且数据库中诸多表都会有依靠关系,表单中有许多景况判断。

比如大家的连串适用jQuery
UI作为UI,有不胜枚举javascript代码,页面的成百上千操作须求特殊处理(例如:多个挑选的排挤、每个节点依据项目和操作人显示不一致的按钮);基本每个公司都有一套自己的UI风格,要保持三个系统的操作习惯一致只好动用自定义表单才能知足。

❷ 运营生成提前还款表达书, 其包涵详细金额多少

2.3 业务和流程的涉及格局

以此题目在群里面很四人都问过,那也是自身刚刚初始迷惑的地方;

新兴看了以下API发现Runtime瑟维斯(Service)(Service)有八个方式:

2.3 业务和流程的关联格局

其一题目在群里面很几人都问过,那也是我刚刚开始迷惑的地点;

新生看了以下API发现Runtime瑟维斯(Service)有八个主意:

2.3 业务和流程的涉嫌格局

其一题材在群里面很三人都问过,那也是自个儿刚刚初阶迷惑的地方;

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

❸ 借款人确认, 通过客服服务人员上传签字照片

2.3.1 startProcessInstanceByKey

javadoc对其表明:

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

 

其中businessKey就是事情ID,例如要提请请假,那么先填写登记音信,然后(保存+启动流程),因为请假是单身设计的数据表,所以保存后拿走实体ID就可以把它传给processInstanceBusinessKey主意启动流程。当需求根据businessKey查询流程的时候就可以通过API查询:

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

 

议数据库冗余设计:在业务表设计的时候添加一列:PROCESS_INSTANCE_ID varchar2(64),在流程启动将来把流程ID更新到业务表中,那样不管从事情依然流程都足以查询到对方!

更加表达: 此方法启动时自动选用新型版本的流水线定义。

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更新到工作表中,那样无论从工作照旧流程都得以查询到对方!

专程表达: 此方法启动时自动选用新型版本的流水线定义。

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更新到事情表中,那样无论从业务照旧流程都可以查询到对方!

越发表明: 此方法启动时自动接纳新型版本的流水线定义。

❹ 运营代扣还款金额, 结清借款

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;每一趟安顿一遍流程定义就会添加一条数据,同名的本子号添加。

特意表达: 此可以指定分歧版本的流程定义,让用户多一层选取。

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;每趟安插一回流程定义就会添加一条数据,同名的本子号添加。

专程表达: 此可以指定分化版本的流水线定义,让用户多一层采纳。

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;每一回安排四回流程定义就会添加一条数据,同名的本子号添加。

越发表明: 此可以指定不一致版本的流程定义,让用户多一层采取。

❺ 生成还款结清声明

2.3.3 怎样抉择

提出利用startProcessInstanceByKey,特殊处境须要接纳过去的本子选拔使用startProcessInstanceById

2.3.3 怎么着选用

提出拔取startProcessInstanceByKey,特殊意况须要采纳过去的本子接纳拔取startProcessInstanceById

2.3.3 怎么着接纳

提出使用startProcessInstanceByKey,特殊景况要求动用过去的版本选拔选用startProcessInstanceById

在平台的骨子里运营中, 有各式种种的政工必要处理, 包蕴借款人, 出借人,
资金等等, 同时还关系到各样不一致的业务部门,
而且流程的漂泊操作人士和机关也随着公司业务的前进而各异的调整.
设计一个基础的流水线框架和贯彻基础代码, 形成不难的费用格局是该种类的严重性.
由此所有系统的布置性涉及到以下重点多少个地点:

2.4 同步用户数量

本条题目也是相比多的人询问过,Activiti协理对职责分配到:指定人、指定组、两者结合,而这几个人和组的信息都保存在ACT_ID..表中,有协调的用户和组(角色)管理让许四个人心慌了;原因是因为种种系统都会设有一个权力管理模块(维护:用户、部门、角色、授权),不了然该怎么和Activiti同步。

2.4 同步用户数量

那么些题目也是相比较多的人通晓过,Activiti匡助对任务分配到:指定人、指定组、两者结合,而那么些人和组的音讯都保存在ACT_ID..表中,有和好的用户和组(角色)管理让众多少人心惊肉跳了;原因是因为每个系统都会存在一个权力管理模块(维护:用户、部门、角色、授权),不晓得该怎么和Activiti同步。

2.4 同步用户数量

其一问题也是相比较多的人明白过,Activiti帮忙对职分分配到:指定人、指定组、两者结合,而这么些人和组的新闻都保存在ACT_ID..表中,有自己的用户和组(角色)管理让很四个人慌慌张张了;原因是因为每个系统都会存在一个权力管理模块(维护:用户、部门、角色、授权),不知情该怎么和Activiti同步。

☞ 选择合适的做事流引擎

2.4.1 指出处理格局

Activiti有一个IdentityService接口,通过那些接口可以操控Activiti的ACT_ID_*表的多寡,一般的做法是用工作种类的权位管理模块维护用户数量,当举行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的时候共同到对方,如若急需一块三个子系统那么可以再调用Web瑟维斯(Service)完结。

2.4.1 指出处理方式

Activiti有一个IdentityService接口,通过这一个接口可以操控Activiti的ACT_ID_*表的多寡,一般的做法是用工作系统的权力管理模块维护用户数量,当进行CRUD操作的时候在原始业务逻辑前面添加同步到Activiti的代码;例如添加一个用户时同步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的时候一起到对方,若是急需一块三个子系统那么能够再调用Web瑟维斯(Service)完结。

2.4.1 提出处理格局

Activiti有一个IdentityService接口,通过那么些接口可以操控Activiti的ACT_ID_*表的多寡,一般的做法是用工作系统的权能管理模块维护用户数据,当进行CRUD操作的时候在本来工作逻辑后边添加同步到Activiti的代码;例如添加一个用户时同步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的时候共同到对方,如果要求共同五个子系统那么可以再调用Web瑟维斯(Service)完成。

对此一个类似涉及到审批以及履行实际事务的系统, 基于不难的情况控制的宏图,
或者电动开发类工作流引擎轮子的做法都是不合适.
所以一个开源并且被广大应用的做事流引擎是一个不错而且必须的选取. Activiti
工作流引擎由于其轻量级, 易用性等优点近期在业界被周边使用.
其工作流的状态机和表面系统的连天只须要经过一个ID进行关联即可,
即activiti的business key. (如下图)

2.5 流程图设计工具用什么样

Activiti提供了七个流程设计工具,不过面向对象差别。

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

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

2.5 流程图设计工具用怎么着

Activiti提供了四个流程设计工具,可是面向对象分裂。

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

  • Eclipse
    Designer,面向开发人士,Eclipse的插件,可以让开发人员定制每个节点的特性(ID、Name、Listener、Attr等)

2.5 流程图设计工具用什么

Activiti提供了五个流程设计工具,不过面向对象分歧。

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

  • Eclipse
    Designer,面向开发人员,Eclipse的插件,可以让开发人士定制每个节点的性质(ID、Name、Listener、Attr等)

澳门金沙4787.com官网 6

2.5.1 大家的法门

唯恐你会惊奇,因为大家没有应用Activiti
Modeler,我们认为用Viso已经能表明流程图的意味了,而且项目COO也是技术出身,和开发人士也便于沟通。

现阶段这一个项目是第三个利用Activiti的,开端大家在急需调研阶段采用Viso设计流程图,利用泳道流程图设计和客户调换,确定后由负责流程的开发人员用Eclipse
Designer设计赢得bpmn20.xml,最终布置。

2.5.1 大家的法子

莫不你会惊叹,因为我们向来不选拔Activiti
Modeler,大家以为用Viso已经能发布流程图的意味了,而且项目主管也是技巧出身,和开发人士也便于沟通。

现阶段以此体系是首先个使用Activiti的,起先大家在须要调研阶段采纳Viso设计流程图,利用泳道流程图设计和客户联系,确定后由负责流程的开发人士用Eclipse
Designer设计赢得bpmn20.xml,最终安插。

2.5.1 大家的格局

或是你会咋舌,因为大家尚无选择Activiti
Modeler,我们觉得用Viso已经能表明流程图的情致了,而且项目老总也是技巧出身,和开发人士也简单沟通。

眼前以此项目是第三个利用Activiti的,开端大家在须求调研阶段采取Viso设计流程图,利用泳道流程图统筹和客户互换,确定后由负责流程的开发人员用Eclipse
Designer设计赢得bpmn20.xml,最终安顿。

☞设计通用的最底层数据来支撑不相同的政工

2.6 Eclipse Designer存在的问题

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

  • Activit
    Forums中告诉的Bug

  • Jira的登记

之所以最后大家只可以单独开一个安装了Eclipse
Designer的Eclipse专门用来布置流程图,那样就不影响健康使用Eclipse
JAVAEE了。

2.6 Eclipse Designer存在的题目

其一插件有一个很厌恶的Bug一向未修复,安装了插件后Eclipse的复制和粘帖急忙键会被转移为(Ctrl+Insert、Shift+Insert);Bug描述请见:

  • Activit
    Forums中告知的Bug

  • Jira的登记

所以最终我们只可以单独开一个设置了Eclipse
Designer的Eclipse专门用来规划流程图,这样就不影响正常使用Eclipse
JAVAEE了。

2.6 Eclipse Designer存在的题材

本条插件有一个很讨厌的Bug一贯未修复,安装了插件后Eclipse的复制和粘帖连忙键会被撤换为(Ctrl+Insert、Shift+Insert);Bug描述请见:

  • Activit
    Forums中报告的Bug

  • Jira的登记

故而最终我们不得不单独开一个设置了Eclipse
Designer的Eclipse专门用来规划流程图,那样就不影响正常使用Eclipse
JAVAEE了。

是因为那样一个运营管理连串关系到各样分化的政工数据.
如借款人信息有关涉嫌借款ID, 银行卡新闻等; 如出借人音信则涉嫌用户ID,
电话号码等; 而对此资金有关如提前还款则涉及到提前还款日期, 还款金额等.
所以一套支撑不一致实际工作的流水线数据表结构也是分外重要.

3.配置

3.配置

3.配置

☞ 基础框架代码的规划

3.1 集成Spring

对于和Spring的集成Activiti做的正确性,简单布置部分Bean代理即可完毕,可是有八个和事情相关的地点要指示:

  • 配置processEngineConfiguration的时候属性transactionManager要拔取和事务职能的同一个事务管理Bean,否则事务不一起。

  • 对此完成了org.activiti.engine.delegate包中的接口的类要求被工作控制的完结类须要被Spring代理,并且拉长事务的Annotation或者在xml中布署,例如:

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

?

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 {
   ....
}

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 {
   ....
}

一个好的布署不是一步到位的陈设,
而是一个渐进的历程以及持续重构的进度.
不过格外紧要的一些就是在一发端可以根据当下的急需以及所能预感的急需开展设计,
并且在那些基础框架代码上支付要越发便利和简洁.

4.行使单元测试

单元测试均接纳Spring的AbstractTransactionalJUnit4SpringContextTests作为SuperClass,并且在测试类添加:

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

?

虽说Activiti也提供了测试的一部分超类,可是感觉糟糕用,所以自己包裹了有的艺术。

代码请转移:

4.选拔单元测试

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

?

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

即使Activiti也提供了测试的一些超类,可是感觉不佳用,所以自己包裹了有的主意。

代码请转移:

4.用到单元测试

单元测试均选拔Spring的AbstractTransactionalJUnit4SpringContextTests作为SuperClass,并且在测试类添加:

?

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

固然Activiti也提供了测试的有些超类,可是感觉不佳用,所以自己包裹了有的方法。

代码请转移:

◆✦以下对第二、三点开展举行✦◆

4.1 验证流程图设计是或不是正确

代码请转移:

4.1 验证流程图设计是或不是科学

代码请转移:

4.1 验证流程图设计是不是正确

代码请转移:

澳门金沙4787.com官网 7

4.2 业务对象和流程关联测试

代码请转移:

4.2 业务对象和流程关联测试

代码请转移:

4.2 业务对象和流程关联测试

代码请转移:

数据库设计

5.各类景况的职责查询以及和事情对象关系

咱俩眼前分为4中状态:未签收、办理中、运行中、已成功。

询问到义务如故流程实例后要显得在页面,那些时候须求加上业务数据,最终结出就是事情和流程的并集,请参见6.2

5.各类景况的职务查询以及和工作对象关系

咱俩当下分为4中状态:未签收、办理中、运行中、已成功。

询问到职分照旧流程实例后要浮现在页面,这么些时候须求添加业务数据,最终结出就是工作和流程的并集,请参见6.2

5.各个情形的任务查询以及和事务对象关系

咱俩眼前分成4中状态:未签收、办理中、运行中、已到位。

询问到职务照旧流程实例后要突显在页面,那么些时候须要添加业务数据,最终结果就是工作和流程的并集,请参考6.2

如上所说, 那样的一个多少陈设必须可以满足:

5.1 未签收(Task)

此类职分针对于把Task分配给一个角色时,例如部门官员,因为部门管理者角色可以指定两人所以须求先签收再办理,术语:抢占式

对应的API查询:

/**
 * 获取未签收的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicTaskQuery createUnsignedTaskQuery(String userId) {
    TaskQuery taskCandidateUserQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey())
            .taskCandidateUser(userId);
    returntaskCandidateUserQuery;
}

?

5.1 未签收(Task)

此类职务针对于把Task分配给一个角色时,例如部门高管,因为部门管理者澳门金沙4787.com官网 ,角色可以指定五人所以须要先签收再办理,术语:抢占式

对应的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;
}

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;
}
  1. 可见满意差别的业务域的急需, 如出借, 借款, 资金相关的切切实实事务数据

  2. 可见记录每一步的操作审批或作业执行结果, 同时记录相关的数额快照

5.2 办理中(Task)

该类任务数据类源有三种:

  • 签收后的,5.1中签收后就应当为办理中状态

  • 节点指定的是具体到一个人,而不是角色

对应的API查询:

/**
 * 获取正在处理的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicTaskQuery createTodoTaskQuery(String userId) {
    TaskQuery taskAssigneeQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey()).taskAssignee(userId);
    returntaskAssigneeQuery;
}

?

5.2 办理中(Task)

此类任务数据类源有两种:

  • 签收后的,5.1中签收后就应有为办理中状态

  • 节点指定的是具体到一个人,而不是角色

对应的API查询:

?

1
2
3
4
5
6
7
8
9
/**
 *
获取正在处理的任务查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
TaskQuery createTodoTaskQuery(String userId) {
    TaskQuery
taskAssigneeQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey()).taskAssignee(userId);
    return
taskAssigneeQuery;
}

5.2 办理中(Task)

该类任务数据类源有二种:

  • 签收后的,5.1中签收后就应该为办理中状态

  • 节点指定的是具体到一个人,而不是角色

对应的API查询:

?

1
2
3
4
5
6
7
8
9
/**
 *
获取正在处理的任务查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
TaskQuery createTodoTaskQuery(String userId) {
    TaskQuery
taskAssigneeQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey()).taskAssignee(userId);
    return
taskAssigneeQuery;
}

就此, 基于实际的工作展开数据表的安顿是不恰当的, 且不可能增加.
常见的筹划为根据Key-Value的规划,
而key则是逐一分化工作体系关系到的metadata. 如USER_ID(用户ID),
LOAN_ID(借款ID)等等. 设计概述如下:

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;
}

?

5.3 运行中(ProcessInstance)

不难就是从未终止的流程,所有出席过的人都应有可以见见这几个实例,可是Activiti的API没有得以因此用户查询的方法,这么些只好协调用hack的方法处理了,我当下还未曾处理。

从表ACT_RU_EXECUTION中询问数据。

对应的API查询:

?

1
2
3
4
5
6
7
8
9
10
/**
 *
获取未经完成的流程实例查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
ProcessInstanceQuery createUnFinishedProcessInstanceQuery(String userId) {
    ProcessInstanceQuery
unfinishedQuery = runtimeService.createProcessInstanceQuery().processDefinitionKey(getProcessDefKey())
            .active();
    return
unfinishedQuery;
}

5.3 运行中(ProcessInstance)

简单就是从未终止的流程,所有参预过的人都应该可以看出那几个实例,可是Activiti的API没有得以经过用户查询的情势,那些只好协调用hack的格局处理了,我当下还从未处理。

从表ACT_RU_EXECUTION中询问数据。

对应的API查询:

?

1
2
3
4
5
6
7
8
9
10
/**
 *
获取未经完成的流程实例查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
ProcessInstanceQuery createUnFinishedProcessInstanceQuery(String userId) {
    ProcessInstanceQuery
unfinishedQuery = runtimeService.createProcessInstanceQuery().processDefinitionKey(getProcessDefKey())
            .active();
    return
unfinishedQuery;
}

澳门金沙4787.com官网 8

5.4 已完成(HistoricProcessInstance)

业已达成的流程实例。

从表ACT_HI_PROCINST中询问数据。

/**
 * 获取已经完成的流程实例查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicHistoricProcessInstanceQuery createFinishedProcessInstanceQuery(String userId) {
    HistoricProcessInstanceQuery finishedQuery = historyService.createHistoricProcessInstanceQuery()
            .processDefinitionKey(getProcessDefKey()).finished();
    returnfinishedQuery;
}

 

?

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.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;
}

一个Request代表某一个人发起的请求, Snapshot代表那么些流程的每一步操作.
Property则分别为Request的Snapshot的有血有肉的数目,
当其REQUEST_ID非空SNAPSHOT_ID为空时表示其为REQUEST的习性(SNAPSHOT同理),
即用户发起呼吁所指引的数据. 如: 用户音信修改:
PROPERTY则包罗NAME(KEY)为USER_ID(用户唯一ID),
ATTACHMENT(用户手持身份证照片), EMAIL(修改项)等相应的值. 而对于SNAPSHOT,
则记录对应审核以及操作的音讯,
其相应的PROPERTY则保留了对某个数据修改前后的值.

5.5 查询时和事情关联

提醒:以前在事情对象添加了PROCESS_INSTANCE_ID字段

思路:现在得以运用那几个字段查询了,不管是Task仍然ProcessInstance都可以获取流程实例ID,可以根据流程实例ID查询实体然后把流程对象设置到实体的一个性质中由Action或者Controller输出到前台。

代码请参见:

5.5 查询时和事情涉及

升迁:从前在业务对象添加了PROCESS_INSTANCE_ID字段

思路:现在得以接纳这几个字段查询了,不管是Task照旧ProcessInstance都可以赢得流程实例ID,可以按照流程实例ID查询实体然后把流程对象设置到实体的一个性能中由Action或者Controller输出到前台。

代码请参见:

5.5 查询时和工作涉及

提拔:从前在业务对象添加了PROCESS_INSTANCE_ID字段

思路:现在得以利用那个字段查询了,不管是Task依然ProcessInstance都可以博得流程实例ID,可以依据流程实例ID查询实体然后把流程对象设置到实体的一个特性中由Action或者Controller输出到前台。

代码请参见:

基本功框架代码设计

6.UI及截图

结合实际业务描述一个工作从起先到截至的经过,对于迷惑的校友看完茅塞顿开了;那里运用请假作为例子。

6.UI及截图

结合实际业务描述一个政工从开首到停止的经过,对于迷惑的同窗看完茅塞顿开了;那里运用请假作为例子。

6.UI及截图

结合实际业务描述一个事情从早先到完工的进度,对于迷惑的同室看完恍然大悟了;那里运用请假作为例子。

起先的气象和需求包涵:

6.1 单独一个列表负责申请

那样的功利是报名和流程办理分离开处理,列表呈现未启动流程的请假记录(数据库PROCESS_INSTANCE_ID为空)。

报名界面的截图:

澳门金沙4787.com官网 9

6.1 单独一个列表负责申请

如此的好处是报名和流程办理分离开处理,列表展现未启动流程的请假记录(数据库PROCESS_INSTANCE_ID为空)。

申请界面的截图:

澳门金沙4787.com官网 10

6.1 单独一个列表负责申请

诸如此类的好处是申请和流程办理分离开处理,列表显示未启动流程的请假记录(数据库PROCESS_INSTANCE_ID为空)。

提请界面的截图:

澳门金沙4787.com官网 11

  1. 有些通用的activiti流程,
    如一步操作即创办后只必要一步成功操作, 两步流程 –
    成立后一步审核一步操作等, 差别的事情会利用相同的流程.

  2. 在activiti流程相同的情景下,
    不相同的作业的步调其处理人/组则分歧

  3. 不等业务流程的莫过于代码开发相应简洁,
    和劳作流引擎解耦, 即实际的开 发人士在不打听办事流引擎具体做事原理的情状下得以举行急忙的付出, 并
    只须求关爱具体 的事务必要

6.2 流程状态

澳门金沙4787.com官网 12

6.2 流程状态

澳门金沙4787.com官网 13

6.2 流程状态

澳门金沙4787.com官网 14

为驾驭决#1的题材,
则须要定义出流程–步骤—业务(请求类型)—处理人/组 的安排 关系,
并在工艺流程流转时自动安装, 而不是在流水线描述文件 (bpmn)里 指定

6.3 流程跟踪

图表方式显示当前节点:

澳门金沙4787.com官网 15

列表方式显得流程流转过程:

澳门金沙4787.com官网 16

6.3 流程跟踪

图片方式体现当前节点:

澳门金沙4787.com官网 17

列表形式显得流程流转进度:

澳门金沙4787.com官网 18

6.3 流程跟踪

图片形式浮现当前节点:

澳门金沙4787.com官网 19

列表方式突显流程流转进程:

澳门金沙4787.com官网 20

为了缓解 #2 的问题,
则要求用服务举行打包, 抽象出一部分接口以及基类的实 现, 并
应用有的广阔的设计形式(工厂方式)和java的特征(反射).

6.3.1 当前节点定位JS

Java代码请移步:

Javascript思路:先通过Ajax获取当前节点的坐标,在指定地点添加黑色边框,然后加载图片。

代码移步:

6.3.1 当前节点定位JS

Java代码请移步:

Javascript思路:先经过Ajax获取当前节点的坐标,在指定地方添加黑色边框,然后加载图片。

代码移步:

6.3.1 当前节点定位JS

Java代码请移步:

Javascript思路:先通过Ajax获取当前节点的坐标,在指定地点添加灰色边框,然后加载图片。

代码移步:

下图为主干的架构设计

7.开启Logger

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

7.开启Logger

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

7.开启Logger

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

澳门金沙4787.com官网 21

8.结束

以前就想写那篇小说,现在算是形成了,开销了多少个钟头,希望能省去你几天的日子。

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

来自:

8.结束

事先就想写那篇文章,现在好不不难成功了,开支了多少个小时,希望能省掉你几天的时间。

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

借使有啥样问题如故对于作用的完结有更好的章程欢迎提议、分享。

8.结束

后面就想写那篇小说,现在算是达成了,开支了多少个钟头,希望能省掉你几天的时刻。

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

要是有哪些疑点依然对于功用的贯彻有更好的不二法门欢迎提议、分享。

据悉这样的框架形成基础代码后,
最后对于一个落成具体作业的开发人员来说, 其完成一个业务流程代码紧要概括:

9.动态指定义务办理人

9.动态指定职分办理人

  1. 落到实处一个开立Request的页面,
    用于录入工作数据

  2. 贯彻一个Request详细页面, 用于展现详情,
    包涵操作历史, 和事情操作按钮

9.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);


9.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);


3.
完结该工作涉及的具体步骤的操作processor类(如审批或和其余系统联网,
完结实际的事情),

9.2 自动安装职责办理人

上边的代码是拔取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>

诸如此类流程启动将来要是任务流转至”销假”节点则会自行把职务分配给启动流程的人。

9.2 自动安装职责办理人

下边的代码是采纳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>

那般流程启动之后假如职分流转至”销假”节点则会自动把职责分配给启动流程的人。

  1. 将流程涉及的processor和相应的业务品种,
    流程名, 流程步骤进行挂号绑定

9.3 获取流程发起人

假设在开行流程的时候调用了下边的代码:

?

1
identityService.setAuthenticatedUserId(currentUserId);

引擎会记录启动人,即在ACT_HI_PROINST表的START_USER_ID字段,可以因此上面的代码获取。

?

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

9.3 获取流程发起人

比方在启动流程的时候调用了下边的代码:

?

1
identityService.setAuthenticatedUserId(currentUserId);

引擎会记录启动人,即在ACT_HI_PROINST表的START_USER_ID字段,可以因而上边的代码获取。

?

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

形成历程

10. 职务代办

不少人问“Owner”属性为何是空的,哪天用?要询问它的效能首先要精通“代办”。

代办的定义可以用上边的一句话概括:

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

看样子这么些单元测试你就明白怎么是代办:ProcessTestDelegateTask

最好把activiti-study那几个项目下载下来导入到Eclipse中运作一下:

原创小说,转发请注解:转载自:办事流引擎Activiti使用计算

10. 任务代办

众多人问“Owner”属性为何是空的,几时用?要询问它的功力首先要询问“代办”。

代办的定义可以用上面的一句话概括:

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

看到这些单元测试你就清楚怎么是代办:ProcessTestDelegateTask

最好把activiti-study那些类型下载下来导入到Eclipse中运作一下:

正如下面曾说到, 对于一个体系规划, 无法一步到位,
在早期时要掀起最亟需缓解的问题, 比如在那么些种类初阶阶段,
最中央的筹划包蕴:

➤ 数据库设计 和RequestService对底层数据操作的包装

➤ WorkflowService对工作流引擎的包裹

➤可配置化的基于业务体系(Request Type)
和配置(process_cfg)在运作时动态设置流程相应的处理人/组

连发的重构包蕴:

➤将各类处理类(业务处理类, 流程处理人/组分配处理类, 通告处理类)
通过Register瑟维斯(Service)(Service)的统一登记管理,
并且接济使用对于特定的流水线落成特定的处理类来替代默许的处理类

➤RequestQuery协助统一的查询入口对业务流程数据开展询问

➤ 依照业务要求提供ASync的processor处理基类, 因为实在应用中发现,
一些业务的拍卖(如批量)需求一段时间的实践才能做到,
而异步处理基类则成功基础达成, 并由相应子类去落到实处虚函数即可.

公共化工作流模块:

➤ 目前, 此外一个品类其使用到的场馆和那一个序列有类似之处,
其独立于该业务管理平台. 在那种情景下, 将该工作流相关的模块进行公共化,
以JAR包的花样提供, 使得别的一个系统的用度可以长期内完成平等的功力

借鉴Activiti的源代码

在规划和贯彻该系统时会有

那般或者那样的迷惑或者斗争,

哪个种类已毕更好?

旁人的系统是何许促成的?

那边举多少个例子

Property表里是还是不是须求必要用差距的字段(LONG_VALUE,
TEXT_VALUE, DOUBLE_VALUE等)存不一样品类的值;照旧一向都存成字符串,
在代码中再根据必要转成Long, Double等?当然三种完毕都是有效的,
并且各有利弊,
并且个人认为存在分化的字段上亮点更大一些(主要展现在查询功效),
可是哪些进一步的让自己信服?
在看activiti的文档时发现外部的事体数据以Map的方法存在activiti的数据库中,
那么activiti的设计者一样会遇上同样的问题.
通过查看源代码以及其数据库设计, 发现其将数据存入分歧的字段.
不过在自家的规划中, 我并从未完全照搬Activiti的处理方式, 比如:
我从没为布尔类型加单独的字段,
而是以0或者1的措施存入LONG_VALUE里。

Activiti中提供便民的查询类, 如: ProcessInstanceQuery, TaskQuery.
其同时支持按照Process和Task相应的属性数据举行查询,
和Request/Snapshot以及property有很大的相似之处,
借鉴并基于实际情形贯彻团结的RequestQuery类, 支持各项复杂查询, 如:
按照指定的property的name和value查询, 扶助or的查询等。

Activiti的数据库版本的机关升级. 当大家升级activiti的版本时,
其实大家只要求立异JAR的本子号, 而不用关爱起底层数据库是不是须要提高,
activiti在其表中会记录数据库scheme的本子号,
启动时会自动判断并依照要求自动更新数据库. 那也是可怜值得借鉴的地方,
尤其是当那么些模块被八个系统所使用时。

澳门金沙4787.com官网 22回去天涯论坛,查看越多

义务编辑:

相关文章