2017.2.28 activiti实战--第六章--任务表单(二)外置表单
学习资料:《Activiti实战》
第六章 任务表单(二)外置表单
6.3 外置表单
考虑到动态表单的缺点(见上节),外置表单使用的更多。
外置表单的特点:
页面的原样显示
字段值的自动填充
6.3.1 流程定义
(1)form文件

leave-start.form作为示例展示(字段要和后面代码中variables变量的key互相对应):
<div class="control-group">
<label class="control-label" for="startDate">开始时间:</label>
<div class="controls">
<input type="text" id="startDate" name="startDate" class="datepicker" data-date-format="yyyy-mm-dd" required />
</div>
</div>
<div class="control-group">
<label class="control-label" for="endDate">结束时间:</label>
<div class="controls">
<input type="text" id="endDate" name="endDate" class="datepicker" data-date-format="yyyy-mm-dd" required />
</div>
</div>
<div class="control-group">
<label class="control-label" for="reason">请假原因:</label>
<div class="controls">
<textarea id="reason" name="reason" required></textarea>
</div>
</div>
(2)流程文件
这里只显示部分xml内容,其他的一些见上节动态表单。这里的xml文件只是为了展示外置表单的使用方法。
基本使用方式就是:activiti:formkey="chapter6/leave-formkey/approve.form"
form的值支持动态设置:activiti:formkey="${fooFormName}.form"
<process id="leave-formkey" name="请假流程-外置表单">
<startEvent id="startevent1" name="Start"
activiti:initiator="applyUserId"
activiti:formkey="chapter6/leave-formkey/leave-start.form">
</startEvent>
<userTask id="deptLeaderVerify" name="部门经理审批"
activiti:candidateGroups="deptLeader"
activiti:formkey="chapter6/leave-formkey/approve.form">
</userTask>
<userTask id="hrVerify" name="人事审批"
activiti:candidateGroups="hr"
activiti:formkey="chapter6/leave-formkey/approve.form">
</userTask>
<userTask id="reportBack" name="销假"
activiti:assignee="${applyUserId}"
activiti:formkey="chapter6/leave-formkey/report-back.form">
</userTask>
<userTask id="modifyApply" name="调整申请内容"
activiti:assignee="${applyUserId}"
activiti:formkey="chapter6/leave-formkey/modify-apply.form">
</userTask>
<endEvent id="endevent1" name="End"
</endEvent>
</process>
(3)单元测试
部署表单流程时需要把bpmn文件和form文件同时打包部署。这样部署了同名的form文件时多个流程定义,或相同流程不同版本之间,都不会有冲突。
public class LeaveFormKeyTest extends AbstractTest {
@Test
@Deployment(resources = {"chapter6/leave-formkey/leave-formkey.bpmn",
"chapter6/leave-formkey/leave-start.form",
"chapter6/leave-formkey/approve-deptLeader.form",
"chapter6/leave-formkey/approve-hr.form",
"chapter6/leave-formkey/report-back.form",
"chapter6/leave-formkey/modify-apply.form"})
public void allPass() throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Map<String, String> variables = new HashMap<String, String>();
Calendar ca = Calendar.getInstance();
String startDate = sdf.format(ca.getTime());
ca.add(Calendar.DAY_OF_MONTH, 2); // 当前日期加2天
String endDate = sdf.format(ca.getTime());
// 启动流程
variables.put("startDate", startDate);
variables.put("endDate", endDate);
variables.put("reason", "公休");
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
// 读取启动表单
Object renderedStartForm = formService.getRenderedStartForm(processDefinition.getId());
assertNotNull(renderedStartForm);
// 启动流程
// 设置当前用户
String currentUserId = "henryyan";
identityService.setAuthenticatedUserId(currentUserId);
ProcessInstance processInstance = formService.submitStartFormData(processDefinition.getId(), variables);
assertNotNull(processInstance);
// 部门领导审批通过
Task deptLeaderTask = taskService.createTaskQuery().taskCandidateGroup("deptLeader").singleResult();
assertNotNull(formService.getRenderedTaskForm(deptLeaderTask.getId()));
variables = new HashMap<String, String>();
variables.put("deptLeaderApproved", "true");
formService.submitTaskFormData(deptLeaderTask.getId(), variables);
// 人事审批通过
Task hrTask = taskService.createTaskQuery().taskCandidateGroup("hr").singleResult();
assertNotNull(formService.getRenderedTaskForm(hrTask.getId()));// 读取任务表单
variables = new HashMap<String, String>();
variables.put("hrApproved", "true");
formService.submitTaskFormData(hrTask.getId(), variables);
// 销假(根据申请人的用户ID读取)
Task reportBackTask = taskService.createTaskQuery().taskAssignee(currentUserId).singleResult();
assertNotNull(formService.getRenderedTaskForm(reportBackTask.getId()));
variables = new HashMap<String, String>();
variables.put("reportBackDate", sdf.format(ca.getTime()));
formService.submitTaskFormData(reportBackTask.getId(), variables);
// 验证流程是否已经结束
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().finished().singleResult();
assertNotNull(historicProcessInstance);
// 读取历史变量
Map<String, Object> historyVariables = packageVariables(processInstance);
// 验证执行结果
assertEquals("ok", historyVariables.get("result"));
}
...
}
6.3.2 自定义表单引擎
activiti既可以可以支持B/S结构的应用,也可以支持C/S结构的应用。getRenderd***Form()返回的内容是经过activiti的默认Form引擎处理过的,返回的值可以让B/S结构的应用直接使用,但是却不能直接支持C/S结构的应用。所以如果要生成C/S程序需要的java控件,需要事先自定义的form引擎。
这一块暂时用不到,略过。
6.3.3 读取流程启动表单
Activiti Explorer支持动态表单,却不支持外置表单。所以需要为Activiti Explorer增加外置表单支持。
2017.2.28 activiti实战--第六章--任务表单(二)外置表单的更多相关文章
- 2017.2.28 activiti实战--第六章--任务表单(一)动态表单
学习资料:<Activiti实战> 第六章 任务表单(一)动态表单 内容概览:本章要完成一个OA(协同办公系统)的请假流程的设计,从实用的角度,讲解如何将activiti与业务紧密相连. ...
- 2017.2.28 activiti实战--第七章--Spring容器集成应用实例(五)普通表单
学习资料:<Activiti实战> 第七章 Spring容器集成应用实例(五)普通表单 第六章中介绍了动态表单.外置表单.这里讲解第三种表单:普通表单. 普通表单的特点: 把表单内容写在 ...
- 2017.2.22 activiti实战--第六章--任务表单
学习资料:<Activiti实战> 第六章 任务表单 本章将一步步完成一个协同办公系统(OA)的请假流程的设计,讲解如何将Activiti和实际业务联系起来. 首先讲解动态表单与外置表单的 ...
- 2017.2.28 activiti实战--第五章--用户与组及部署管理(三)部署流程及资源读取
学习资料:<Activiti实战> 第五章 用户与组及部署管理(三)部署流程及资源读取 内容概览:如何利用API读取已经部署的资源,比如读取流程定义的XML文件,或流程对应的图片文件. 以 ...
- 2017.2.28 activiti实战--第五章--用户与组及部署管理(二)部署流程资源
学习资料:<Activiti实战> 第五章 用户与组及部署管理(二)部署流程资源 内容概览:讲解流程资源的读取与部署. 5.2 部署流程资源 5.2.1 流程资源 流程资源常用的有以下几种 ...
- 2017.2.21 activiti实战--第十三章--流量数据查询与跟踪(一)查询接口介绍及运行时数据查询
学习资料:<Activiti实战> 第十三章 流量数据查询与跟踪 本章讲解运行时与历史数据的查询方法.主要包含三种:标准查询,Native查询,CustomSql查询. 13.1 Quer ...
- 2017.2.21 activiti实战--第七章--Activiti与spring集成(一)配置文件
学习资料:<Activiti实战> 第七章 Activiti与容器集成 本章讲解activiti-spring可以做的事情,如何与现有系统集成,包含bean的注入.统一事务管理等. 7.1 ...
- 2017.2.20 activiti实战--第五章--用户与组及部署管理(一)用户与组
学习资料:<Activiti实战> 第五章 用户与组及部署管理(一)用户与组 内容概览:讲解activiti中内置的一套用户.组的关系,以及如何通过API添加.删除.查询. 5.1 用户与 ...
- 2017.2.20 activiti实战--第二章--搭建Activiti开发环境及简单示例(二)简单示例
学习资料:<Activiti实战> 第一章 搭建Activiti开发环境及简单示例 2.5 简单流程图及其执行过程 (1)leave.bpmn 后缀名必须是bpmn.安装了activiti ...
随机推荐
- Linux下如何挂载和卸载硬盘?
fdisk -l 查看所有被系统识别的磁盘 df -h 查看磁盘占用情况 sudo umount -v /media 卸载挂载点的硬件 df -T 查看所有磁盘的文件系统类型(type) mount ...
- 201621123034 《Java程序设计》第2周学习总结
1. 本周学习总结 本周学习了基本数据类型.包装类,自动装箱与自动拆箱.数组.ArrayList.包装类可以更加方便的转换基本数据类型,而其存放的是对象的引用,而非对象本身,在对其内容进行比较时,要使 ...
- 【Luogu】P2173网络(LCT)
题目链接 这次坑我的是与或的结合顺序…… 开十个LCT记录一下即可.以上. #include<cstdio> #include<cstring> #include<cst ...
- location.origin兼容
if (!window.location.origin) { window.location.origin = window.location.protocol + "//" + ...
- 【CCF】 Markdown 模拟
#include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...
- Vue实现增删改查功能
简单的表单CURD功能demo <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...
- 【12】vue-router 之路由重定向
看之前的项目,突然发现一个不算bug的bug,之前也是一直没有想到,现在发现之后越来越觉得有必要改掉, 项目用的是vue做的,自然切换用的就是路由,一级路由包括:首页.记录和个人中心,二级路由是在记录 ...
- PowerDesigner常用快捷键
一般快捷键 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部 ...
- Eclipse SVN冲突详细解决方案
大家一起开发,难免有时会同时修改同一个文件,这样就要学会解决冲突.当大家更新代码,发现以下情况的时候,就说明你的修改的文件和服务器的文件产生了冲突(一般是别人也改了同一个文件). 1)和服务 ...
- 51Nod 1003 1004 1009
1003 阶乘后面0的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 n的阶乘后面有多少个0? 6的阶乘 = 1*2*3*4*5*6 = 720,720后面有1 ...