1、如何实现审核的上级获取(任务逐级审批)

这个是必备功能,通过Spring的注入+Activiti表达式可以很容易解决。

可参考:

http://blog.csdn.net/sunxing007/article/details/8491552

http://linhongyu.blog.51cto.com/6373370/1656596

2、如何设置流程发起人,并动态在其他任务中使用

通过变量,在启动的时候设置。

activiti里设置流程发起人的功能很绕。

activiti 指定发起人,并作为流程变量在流程中的其他任务中使用,

 在流程文件中定义开始事件
<startEvent id="start" activiti:initiator="initiator" /> initiator 作为一个流程变量在其他任务节点中使用
<userTask id="theTask" name="My Task">
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${initiator}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>

发起流程时指定发起人:

identityService.setAuthenticatedUserId("startuser");

runtimeService.startProcessInstanceByKey("simpleProcess");

3、spring帮助TaskListener自动注入依赖

1. 如果想让spring对ExecutionListener实现依赖注入。就要让spring管理对应的bean,再从spring中获取这个bean。关键就是不能自己new一个class,如果你自己new了一个class,spring怎么知道这个class什么时候需要注入?

2. 确认spring管理好bean之后,在actviiti中,使用expression表达式引用这个bean。

不能用这种方式,这种方式就是直接new一个class,创建出的实例不是spring托管的,无法自动注入依赖:

<activiti:executionlistener< span=""><activiti:executionListener class="org.activiti.engine.test.bpmn.event.IntermediateNoneEventTest$MyExecutionListener" event="start" />

要使用expression从spring中获取托管的bean,expression部分写bean的id:

<activiti:executionlistener< span=""><activiti:executionListener delegateExpression="${myExecutionListener}" event="end" />

4、流程图中文乱码

解决方法:设置ProcessEngineConfiguration中的属性,注意版本必须是5.13或以上版本,老版本不支持labelFontName

<property name="activityFontName" value="宋体"/>
<property name="labelFontName" value="宋体"/>

参考https://github.com/xuhuisheng/activiti-demo/blob/master/src/main/resources/spring/applicationContext-activiti.xml

衍生问题:设置了字体之后,图片依然乱码,有两种可能:

  • 没有重新部署流程,所以没有重新使用新配置生成图片。
  • 没有使用cmd的方式包装生成图片的方法,导致配置没有启用

通过封装cmd的方式调用生成图片的方法:

https://github.com/xuhuisheng/activiti-demo/blob/master/src/main/java/com/mossle/bpm/cmd/ProcessDefinitionDiagramCmd.java

如果不想用优雅的封装cmd的方法,只能手工初始化Context了。

Context.setProcessEngineConfiguration(processEngine.getProcessEngineConfiguration());

5、在流程运行中指定下一个处理人

前一个节点设置流程变量,completeTask(taskId, map)这样传递进一个变量,叫step3Assignee="nextUserName"

下一个节点设置activiti:assigne="${step3Assignee}",就实现了前一个节点指定后一个节点的负责人

手动设置任务办理人

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

6、activiti如何与现有系统集成

要走的路任重道远:

1.集成用户账号

2.集成组织机构

3.集成权限

4.集成事务

5.集成业务数据

6.集成表单体系

7.集成服务

8.组件服务:人员、组、上级、组织架构通用选择器

7、自定义业务流程关联

定义表单的方式在每个Task标签中定义extensionElementsactiviti:formProperty即可,到达这个节点的时候可以通过API读取表单元素。

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

但是这种方式仅仅适用于比较简单的流程,对于稍微复杂或者页面需要业务逻辑的判断的情况就不适用了。

业务和流程关联可以用

startProcessInstanceByKey

其中businessKey就是业务ID,例如要申请请假,那么先填写登记信息,然后(保存+启动流程),因为请假是单独设计的数据表,所以保存后得到实体ID就可以把它传给processInstanceBusinessKey方法启动流程。当需要根据businessKey查询流程的时候就可以通过API查询。

建议数据库冗余设计:在业务表设计的时候添加一列:PROCESS_INSTANCE_ID varchar2(64),在流程启动之后把流程ID更新到业务表中,这样不管从业务还是流程都可以查询到对方!

特别说明: 此方法启动时自动选择最新版本的流程定义。

startProcessInstanceById

javadoc对其说明:

startProcessInstanceById(String processDefinitionId, String businessKey, Map<string,object> 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;每次部署一次流程定义就会添加一条数据,同名的版本号累加。

8、查询我发起的流程

首先要通过setAuthenticatedUserid("lingo")在发起流程之前设置流程发起人。

然后可以通过processEngine.getHistoryService().createHistoricProcessInstanceQuery().starterUserid("lingo").list()

Liferay7 BPM门户开发之8: Activiti实用问题集合的更多相关文章

  1. Liferay7 BPM门户开发之11: Activiti工作流程开发的一些统一规则和实现原理(完整版)

    注意:以下规则是我为了规范流程的处理过程,不是Activiti公司的官方规定. 1.流程启动需要设置启动者,在Demo程序中,“启动者变量”名统一设置为initUserId 启动时要做的: ident ...

  2. Liferay7 BPM门户开发之7: Activiti中的重要概念和主要数据库结构

    流程的人员参与角色: Assignee :签收者(即待办人) Candidate:候选人 Owner:拥有者 Starter:启动者 participant:参与者,包含查阅 流程变量的类型: Str ...

  3. Liferay7 BPM门户开发之6: Activiti数据库换为mysql

    第一步: 在mysql中创建数据库名字叫 'activiti' 执行D:\activiti-5.21.0\database\create下的脚本 第二步: 打开=> apache-tomcat/ ...

  4. Liferay7 BPM门户开发之5: Activiti和Spring集成

    参考文档: https://github.com/jbarrez/spring-boot-with-activiti-examplehttps://github.com/sxyx2008/spring ...

  5. Liferay7 BPM门户开发之4: Activiti事件处理和监听Event handlers

    事件机制从Activiti 5.15开始引入,这非常棒,他可以让你实现委托. 可以通过配置添加事件监听器,也可以通过Runtime API加入注册事件. 所有的事件参数子类型都来自org.activi ...

  6. Liferay7 BPM门户开发之3: Activiti开发环境搭建

    下载地址: http://activiti.org/download.html 源码: https://github.com/Activiti/Activiti 环境准备(检查项): JDK 1.7 ...

  7. Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)

    开发目的: 实现通用流程自动化处理(即实现不需要hardcode代码的bpm统一处理后台,仅需要写少量前端html form代码和拖拽设计BPM定义) 既可独立运行或可依托于Liferay或依托其它门 ...

  8. Liferay7 BPM门户开发之37: Liferay7下的OSGi Hook集成开发

    hook开发是Liferay客制扩展的一种方式,比插件灵活,即可以扩展liferay门户,也能对原有特性进行更改,Liferay有许多内置的服务,比如用hook甚至可以覆盖Liferay服务. 可作为 ...

  9. Liferay7 BPM门户开发之17: Portlet 生命周期

    Portlet 生命周期 init() =〉 render() =〉 processAction() =〉 processEvent() =〉 serveResource() =〉destroy() ...

随机推荐

  1. html5移动端查找

    用form包裹住input,修改input的类型为seach,然后给input绑定seach事件,当输入状态是输入键盘上会出现搜索,点击搜索就可以查找了 <form action="& ...

  2. CORSFilter 跨域资源访问

    CORS 定义 Cross-Origin Resource Sharing(CORS)跨来源资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 ...

  3. linux网络日志分析

    1.清空日志的技巧 2.访问日志格式分析 3. web日志统计举例

  4. datatables插件提示Cannot reinitialise DataTable的解决办法

    这个错误是由于重新设置数据源,又没有将原来的数据清空导致的. 网上有很多解决方案,试了都不管用. 最后找到一种方法,将原来的table销毁,再初始化. 方法是在datatable初始化的时候加入属性 ...

  5. Windows server 2012 R2 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同

    Windows server 2012 R2 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同.”使用克隆的系统时,加域是出现如下问题.“无法完成域加入,原因是试图加入的域的SI ...

  6. 图论最短路径算法总结(Bellman-Ford + SPFA + DAGSP + Dijkstra + Floyd-Warshall)

    这里感谢百度文库,百度百科,维基百科,还有算法导论的作者以及他的小伙伴们...... 最短路是现实生活中很常见的一个问题,之前练习了很多BFS的题目,BFS可以暴力解决很多最短路的问题,但是他有一定的 ...

  7. AudiosessionSetActive

    IOS audiosession 会话控制声音播放 今天遇到一个问题: 当我外部想要关闭声音播放的时候 audiosessionsetActive(false) 居然报错了,但是作用起了  AVAud ...

  8. 251. Flatten 2D Vector 平铺二维矩阵

    [抄题]: Implement an iterator to flatten a 2d vector. Example: Input: 2d vector = [ [1,2], [3], [4,5,6 ...

  9. RFC

    一.简介   二.常用 1)TLSv1.2 Protocol https://tools.ietf.org/html/rfc5246

  10. javascript函数闭包(closure)

    一,首先感受下javascript函数的闭包 二,闭包 1,定义:闭包就是能够读取其他函数内部变量的函数,由于在javascript语言中,只有在函数内部的子函数才能够读取局部变量,因此可以把闭包简单 ...