- 浏览: 7961612 次
- 性别:
- 来自: 广州
-
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
http://blog.csdn.net/qq_30739519/article/details/51225067
我们在使用activiti 工作流引擎的时候,最常用的肯定是任务节点,因为在OA系统、审批系统、办公自动化系统中核心的处理就是流程的运转,流程的运转依赖于人员如何设置,人员的设置是非常重要的一个环节,所以说如果能让activiti 工作流引擎运转的核心,就必须要支持强大的人员组织架构设计。下面我们先说一下activiti 工作流引擎自身支持的可以直接使用的地方。我们来看一下,人员如何设置。
1.1.2. 处理人分配方式
处理人分配的方式有六种设置方式,可以让我们很轻松的结合业务来设置任务节点的处理人,如下图所示:
任务处理人的设置如下图所示:
下面,我们就看一下每一种方式的具体操作:
1.1.3. act_ru_identitylink
因为处理人除了直接设置指定人处理的方式,act_ru_identitylink表没有数据,其他的方式都是在这个表有记录的,所以还是很有必要说一下这个表结构,表结构如下图所示:
act_ru_identitylink表结构说明:
task_id 对应act_ru_task中的主键id_
type_:对应类别有starter流程实例的发起者、candidate:节点的候选人
group_id:候选组的id主键,
user_id:对应人的id_主键
rev_:版本号
其中group_id、user_id不一定是activiti工作流引擎中人员组织关系,有可能使我们自定义的人员架构关系,这一点重点说明一下,因为后面的文章,我们会讲解如何扩展工作流人员架构
1.1.4. 第一种方式assignee
这种方式就是就是指定的具体处理人,xml配置信息对应如下所示:
1.1.4.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:assignee="分享牛原创" >
<extensionElements>
</userTask>
当我们运行的时候可以看到act_ru_task表中assignee_字段使我们设置的值
1.1.5. 第二种方式assignee 变量方式
这种方式就是就是指定的具体处理人,xml配置信息对应如下所示:
1.1.5.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:assignee="${分享牛原创}" >
<extensionElements>
</userTask>
运行的时候把当${分享牛原创}"分享牛原创变量传递进去,也就是把${}里面的变量传递进去就可以,我们运行的时候可以看到act_ru_task表中assignee_字段使我们设置的值,注意这个变量传递一定要在流程还没有到达这个任务节点的时候传递,否则当流程到达这个节点的时候,在传递变量就不行了。因为当前的节点设置的是下一个节点的变量值信息。
1.1.6. 第三种方式后候选组的方式
这种方式就是就是指定多个人去处理,xml配置信息对应如下所示:
1.1.6.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateUsers="分享牛原创">
</userTask>
候选组使用的时候,多个就是,分割。比如我们需要设定当前的任务处理人是a、b、c三个人处理,那我们怎么设置呢?设置的时候,我们就设置为a,b,c即可。
当流程运转到当前的节点的时候a、b、c三个人都可以查询到代办信息,然后对应的操作。
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
1.1.7. 第三中方式后候选组的方式 候选组是一个集合
这种方式就是就是指定多个人去处理,xml配置信息对应如下所示:
1.1.7.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateUsers="${分享牛原创}">
</userTask>
设置的时候我们可以指定一个集合,这个集合变量,我们在程序运行的时候,也是,分割的形式,进行传递值,不过需要注意,这种方式必须是一个集合对象,而不是一个字符串类型。
看下面的两种方式赋值:
第一种方式:
String candidateUsers="a,b,c";
task.setVariable("分享牛原创", candidateUsers);
这种方式是错误的,程序运行的时候会报错,报错信息就是没有分享牛原创这个集合。
正确的方式如下:
String [] candidateUsers={"a","b","c"};
task.setVariable("分享牛原创", Arrays.asList(candidateUsers));
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
1.1.8. 第四种方式 角色的方式
这种方式就是就是指定多角色去处理,xml配置信息对应如下所示:
1.1.8.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateGroups="分享牛原创">
lt;/userTask>
角色使用的时候,多个就是,分割。比如我们需要设定当前的任务处理角色是a、b、c三个角色处理,那我们怎么设置呢?设置的时候,我们就设置为a,b,c即可。
当流程运转到当前的节点的时候a、b、c三个角色都可以查询到代办信息,然后对应的操作。
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
1.1.9. 第五种方式 角色的方式 变量方式
这种方式就是就是指定多角色去处理,xml配置信息对应如下所示:
1.1.9.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateGroups="分享牛原创">
lt;/userTask>
设置的时候我们可以指定一个集合,这个集合变量,我们在程序运行的时候,也是,分割的形式,进行传递值,不过需要注意,这种方式必须是一个集合对象,而不是一个字符串类型。
看下面的两种方式赋值:
第一种方式:
String candidateUsers="a,b,c";
task.setVariable("分享牛原创", candidateUsers);
这种方式是错误的,程序运行的时候会报错,报错信息就是没有分享牛原创这个集合。
正确的方式如下:
String [] candidateUsers={"a","b","c"};
task.setVariable("分享牛原创", Arrays.asList(candidateUsers));
1.1.10. 第六种方式 监听器方式
监听器方式,我们可以动态的控制,在这个监听器中,我们可以从数据库中查询出来对应的人或者角色中的人,变量的方式设置进去,达到灵活多用。
具体的监听器的配置如下:
具体的xml如下:
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" >
<extensionElements>
<activiti:taskListener event="assignment" class="com.daling.bpmn.extend.MyTaskListener"></activiti:taskListener>
</extensionElements>
</userTask>
具体的监听实现类如下:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
public class MyTaskListener implements TaskListener {
@Override
public void notify(DelegateTask task) {
String [] candidateUsers={"a","b","c"};
task.setVariable("分享牛原创", Arrays.asList(candidateUsers));
}
}
1.1.11. 总结
activiti 任务节点处理人的设置总结如下:
1.指定具体的处理人,可以使用变量方式设置人。也可以直接在模板中定义。
2.候选组,可以在模版中定义,不灵活。灵活的做法,可以指定一个变量赋值。
3.角色,可以在模版中定义,不灵活。灵活的做法,可以指定一个变量赋值。
4.可以使用任务监听器的方式进行赋值操作。
5.变量的方式比较灵活,模板中直接定义不灵活,因为处理节点的人或者角色可能变化。
1.1.12. 遗留点
上面的几种方式我们总结了一下,第一就是指定人、组、角色,这典型是个一维的数据结构,但是实际的项目中,我们的人员关系,一般是,人、角色、部门,这是一个二维结构,很显然上面这种方式就不行了,因为程序是没有办法,同时去区到底是是角色还是部门,而且我们可能还要对角色、部门求交集、并集的需求以及更加复杂的运算,所以我们还是需要扩展工作流中人员设置这一块的。后续的章节详细的讲解。
我们在使用activiti 工作流引擎的时候,最常用的肯定是任务节点,因为在OA系统、审批系统、办公自动化系统中核心的处理就是流程的运转,流程的运转依赖于人员如何设置,人员的设置是非常重要的一个环节,所以说如果能让activiti 工作流引擎运转的核心,就必须要支持强大的人员组织架构设计。下面我们先说一下activiti 工作流引擎自身支持的可以直接使用的地方。我们来看一下,人员如何设置。
1.1.2. 处理人分配方式
处理人分配的方式有六种设置方式,可以让我们很轻松的结合业务来设置任务节点的处理人,如下图所示:
任务处理人的设置如下图所示:
下面,我们就看一下每一种方式的具体操作:
1.1.3. act_ru_identitylink
因为处理人除了直接设置指定人处理的方式,act_ru_identitylink表没有数据,其他的方式都是在这个表有记录的,所以还是很有必要说一下这个表结构,表结构如下图所示:
act_ru_identitylink表结构说明:
task_id 对应act_ru_task中的主键id_
type_:对应类别有starter流程实例的发起者、candidate:节点的候选人
group_id:候选组的id主键,
user_id:对应人的id_主键
rev_:版本号
其中group_id、user_id不一定是activiti工作流引擎中人员组织关系,有可能使我们自定义的人员架构关系,这一点重点说明一下,因为后面的文章,我们会讲解如何扩展工作流人员架构
1.1.4. 第一种方式assignee
这种方式就是就是指定的具体处理人,xml配置信息对应如下所示:
1.1.4.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:assignee="分享牛原创" >
<extensionElements>
</userTask>
当我们运行的时候可以看到act_ru_task表中assignee_字段使我们设置的值
1.1.5. 第二种方式assignee 变量方式
这种方式就是就是指定的具体处理人,xml配置信息对应如下所示:
1.1.5.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:assignee="${分享牛原创}" >
<extensionElements>
</userTask>
运行的时候把当${分享牛原创}"分享牛原创变量传递进去,也就是把${}里面的变量传递进去就可以,我们运行的时候可以看到act_ru_task表中assignee_字段使我们设置的值,注意这个变量传递一定要在流程还没有到达这个任务节点的时候传递,否则当流程到达这个节点的时候,在传递变量就不行了。因为当前的节点设置的是下一个节点的变量值信息。
1.1.6. 第三种方式后候选组的方式
这种方式就是就是指定多个人去处理,xml配置信息对应如下所示:
1.1.6.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateUsers="分享牛原创">
</userTask>
候选组使用的时候,多个就是,分割。比如我们需要设定当前的任务处理人是a、b、c三个人处理,那我们怎么设置呢?设置的时候,我们就设置为a,b,c即可。
当流程运转到当前的节点的时候a、b、c三个人都可以查询到代办信息,然后对应的操作。
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
1.1.7. 第三中方式后候选组的方式 候选组是一个集合
这种方式就是就是指定多个人去处理,xml配置信息对应如下所示:
1.1.7.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateUsers="${分享牛原创}">
</userTask>
设置的时候我们可以指定一个集合,这个集合变量,我们在程序运行的时候,也是,分割的形式,进行传递值,不过需要注意,这种方式必须是一个集合对象,而不是一个字符串类型。
看下面的两种方式赋值:
第一种方式:
String candidateUsers="a,b,c";
task.setVariable("分享牛原创", candidateUsers);
这种方式是错误的,程序运行的时候会报错,报错信息就是没有分享牛原创这个集合。
正确的方式如下:
String [] candidateUsers={"a","b","c"};
task.setVariable("分享牛原创", Arrays.asList(candidateUsers));
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
1.1.8. 第四种方式 角色的方式
这种方式就是就是指定多角色去处理,xml配置信息对应如下所示:
1.1.8.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateGroups="分享牛原创">
lt;/userTask>
角色使用的时候,多个就是,分割。比如我们需要设定当前的任务处理角色是a、b、c三个角色处理,那我们怎么设置呢?设置的时候,我们就设置为a,b,c即可。
当流程运转到当前的节点的时候a、b、c三个角色都可以查询到代办信息,然后对应的操作。
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
1.1.9. 第五种方式 角色的方式 变量方式
这种方式就是就是指定多角色去处理,xml配置信息对应如下所示:
1.1.9.1. xml
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" activiti:candidateGroups="分享牛原创">
lt;/userTask>
设置的时候我们可以指定一个集合,这个集合变量,我们在程序运行的时候,也是,分割的形式,进行传递值,不过需要注意,这种方式必须是一个集合对象,而不是一个字符串类型。
看下面的两种方式赋值:
第一种方式:
String candidateUsers="a,b,c";
task.setVariable("分享牛原创", candidateUsers);
这种方式是错误的,程序运行的时候会报错,报错信息就是没有分享牛原创这个集合。
正确的方式如下:
String [] candidateUsers={"a","b","c"};
task.setVariable("分享牛原创", Arrays.asList(candidateUsers));
1.1.10. 第六种方式 监听器方式
监听器方式,我们可以动态的控制,在这个监听器中,我们可以从数据库中查询出来对应的人或者角色中的人,变量的方式设置进去,达到灵活多用。
具体的监听器的配置如下:
具体的xml如下:
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<userTask id="usertask1" name="商务采购" >
<extensionElements>
<activiti:taskListener event="assignment" class="com.daling.bpmn.extend.MyTaskListener"></activiti:taskListener>
</extensionElements>
</userTask>
具体的监听实现类如下:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
public class MyTaskListener implements TaskListener {
@Override
public void notify(DelegateTask task) {
String [] candidateUsers={"a","b","c"};
task.setVariable("分享牛原创", Arrays.asList(candidateUsers));
}
}
1.1.11. 总结
activiti 任务节点处理人的设置总结如下:
1.指定具体的处理人,可以使用变量方式设置人。也可以直接在模板中定义。
2.候选组,可以在模版中定义,不灵活。灵活的做法,可以指定一个变量赋值。
3.角色,可以在模版中定义,不灵活。灵活的做法,可以指定一个变量赋值。
4.可以使用任务监听器的方式进行赋值操作。
5.变量的方式比较灵活,模板中直接定义不灵活,因为处理节点的人或者角色可能变化。
1.1.12. 遗留点
上面的几种方式我们总结了一下,第一就是指定人、组、角色,这典型是个一维的数据结构,但是实际的项目中,我们的人员关系,一般是,人、角色、部门,这是一个二维结构,很显然上面这种方式就不行了,因为程序是没有办法,同时去区到底是是角色还是部门,而且我们可能还要对角色、部门求交集、并集的需求以及更加复杂的运算,所以我们还是需要扩展工作流中人员设置这一块的。后续的章节详细的讲解。
发表评论
-
复习:强迫线程顺序执行方式
2019-01-03 23:42 1604方法1: 三个线程,t1,t2,t3,如果一定要按顺序执行, ... -
(转)不错的前后端处理异常的方法
2019-01-02 23:16 2028前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是 ... -
info q的极客时间大咖说等资料下载
2018-08-15 08:40 3485info q的极客时间大咖说等资料下载,还有不少思维导图 链 ... -
CXF 客户端超时时间设置(非Spring配置方式)
2018-07-03 22:38 2248import org.apache.cxf.endpoint. ... -
(转)synchronized关键字画像:正确打开方式
2018-06-14 09:25 502https://mp.weixin.qq.com/s/b3Sx ... -
CountDownLatch的例子
2018-06-13 14:10 701public class StatsDemo { ... -
两道面试题,带你解析Java类加载机制
2018-06-12 16:29 628https://mp.weixin.qq.com/s/YTa0 ... -
Spring中获取request的几种方法,及其线程安全性分析
2018-06-11 09:03 680https://mp.weixin.qq.com/s/KeFJ ... -
内部类小结
2018-06-06 10:25 446https://mp.weixin.qq.com/s/hErv ... -
JVM虚拟机小结1
2018-06-04 20:43 5581 jps -l //列出详细的类名和进程ID 2)jps ... -
windows下自带命令行工具查看CPU资源情况等
2018-06-04 12:53 3117微软提供了不少命令行 ... -
(收藏)深入分析Java的序列化与反序列化
2018-05-30 15:21 628https://mp.weixin.qq.com/s/T2Bn ... -
apache common包中的序列化工具
2018-05-30 09:10 1853什么是序列化 我们的 ... -
JAVA8 JVM的变化: 元空间(Metaspace)
2018-05-24 22:30 974本文将会分享至今为至我收集的关于永久代(Permanent G ... -
(转)服务器性能指标(一)——负载(Load)分析及问题排查
2018-05-21 21:03 1384原创: Hollis Hollis 负载 ... -
(转)对象复用
2018-05-20 15:27 875public class Student { priv ... -
mapreduce中入门中要注意的几点
2018-05-06 08:59 682在 mapreduce中,比如有如下的词: I love b ... -
HDFS的基本操作
2018-05-02 21:47 949-mkdir 在HDFS创建目录 ... -
一个不错的开源工具类,专门用来解析日志头部的,好用
2018-05-02 20:00 779一个不错的开源工具类,专门用来解析日志头部的,好用。 http ... -
介绍个不错的RESTFUL MOCK的工具wiremock
2018-04-27 21:02 1915介绍个不错的RESTFUL MOCK的工具wiremock,地 ...
相关推荐
4. **处理条件表达式**:在某些情况下,下一步节点的选择可能依赖于某些条件。例如,通过网关(Exclusive Gateway)时,只有一个符合条件的出口会被执行。这时,我们需要评估这些条件表达式,例如`activiti:...
因此,只有当办理人设置成功后,任务才会被正式创建。 #### 六、泳池和泳道 **泳池**和**泳道**是用于组织流程图的图形元素,有助于清晰地展示流程中涉及的不同角色或部门。 - **泳池**可以进一步划分为多个**...
伪汇总审批,就是每一条流程都是独立的,这些独立的流程在走到某个节点的时候,这个节点的审批人可以一次性进行多个任务的审批
2. 遍历流程图元素:遍历流程图的各个元素,包括任务节点和连接线,然后根据任务状态设置相应的颜色。 3. 自定义颜色映射:定义颜色映射规则,例如,当前任务为红色,已完成的任务为绿色,连线文字颜色可以自定义为...
在Activiti中,个人任务(User Task)代表了流程中的一个节点,这个节点只能由特定的用户或用户组来处理。这种任务的分配方式确保了任务的执行者明确,有助于提高工作效率,防止工作流混乱。个人任务通常通过定义`...
- **设计流程图**:使用BPMN 2.0标准的工具(如Activiti Modeler)设计流程图,定义各个任务节点、流程分支和用户任务。 - **导出流程定义**:将设计好的流程图导出为`.bpmn20.xml`和对应的`.png`图片文件。 **3. ...
例如,可以统计某段时间内某个任务的平均处理时长,或者查找导致异常的流程实例。 四、历史数据的应用场景 1. 过程审计:通过对历史记录的分析,可以验证流程是否按照预期执行,是否存在违规操作。 2. 性能优化:...
4. **自定义服务任务**:除了标准的任务节点,你还可以通过编写自定义服务任务来实现更复杂的会签逻辑。比如,你可以根据业务规则动态地添加或移除参与者,或者在所有子任务完成后执行额外的操作。 5. **代码实现**...
当任务被领取(`taskService.claim(Task task, String userId)`)并完成(`taskService.complete(Task task)`)时,流程会自动流转到下一个任务节点。 此外,为了监控和管理流程,我们还可以创建一个后台服务,定期...
"指定流程节点执行人"是Activiti的一个重要功能,它允许我们在流程定义中为每个任务节点指定一个或多个负责人。这通常是通过用户任务(User Task)的`assignee`属性来完成的,可以设置成具体的用户ID或者用户组ID。在...
在请假流程中,每个审批节点对应一个任务,审批人需要在任务列表中找到自己的任务,进行审批操作。 7. 结束流程: 当所有必要的审批环节完成,流程到达结束事件,表明请假申请已被处理完毕。Activiti会记录整个...
- 执行任务:Activiti维护了一个任务列表,每个任务代表流程中的一个活动节点。任务完成后,会自动触发下一个任务的执行。 - 用户任务:涉及人参与的任务,可以通过TaskService查询并完成任务,如claim、complete...
通过浏览器访问项目提供的URL,可以直观地看到流程图,拖拽节点、设置流转条件、定义任务分配等,实现流程设计的可视化操作。此外,Activiti还提供了丰富的API和工具,使得开发者可以轻松地将流程与应用程序集成,...
在任务节点中,可以添加扩展元素来实现更复杂的功能。如上例所示,`<extensionElements>`包含两个`<activiti:taskListener>`,分别监听“create”和“complete”事件。这些监听器可以通过实现`TaskListener`接口的...
学习过Activiti的朋友都知道,Activiti的创始人也就是JBPM(也是一个优秀的BPM引擎)的创始人,从Jboss离职后开发了一个新的BPM引擎:Activiti。所以,Activiti有很多地方都有JBPM的影子。所以,据说学习过JBPM的...
- **优先级调节**:针对紧急程度不同的任务设置不同级别,确保重要事项优先得到处理。 - **批量操作支持**:如批量分配、批量完成等,适用于大量相似任务的快速处理场景。 #### 六、REST API集成 - **API文档完善*...
在"oa项目中的activiti流程demo"中,可能包含了不同角色(如申请人、审批人)的任务节点,以及如何通过和驳回的逻辑。 4. **服务任务与JavaDelegate** 为了实现具体的业务逻辑,Activiti支持服务任务。服务任务...
7. **指定流程节点执行人**: 在流程定义中,可以使用`userTask`元素的`assignee`属性或`activiti:candidateUsers`标签指定任务执行人。在示例代码中,可能包含设置特定节点执行人的逻辑。 8. **监听器和事件**: ...
7. **事件和监听器**:Activiti 支持事件机制,允许用户定义监听器来捕获流程中的特定事件,如任务完成、流程结束等,从而进行相应的处理。 8. **审计和日志**:Activiti 提供了详细的审计日志,记录了每个流程实例...
3. **任务(Task)**:流程中的工作单元,一个任务可以被一个人或一组人执行。任务可以通过Activiti的工作流引擎进行分配、领取和完成。 4. **表单(Form)**:与任务相关联的数据输入和输出界面,可以是简单的HTML...