2017.2.28 activiti实战--第七章--Spring容器集成应用实例(五)普通表单

学习资料:《Activiti实战》

 

第七章  Spring容器集成应用实例(五)普通表单

第六章中介绍了动态表单、外置表单。这里讲解第三种表单:普通表单。

普通表单的特点:

1 把表单内容写在表现层(JSP、JSF、HTML)文件中
2 一个用户任务对应一个页面
3 业务数据和流程数据分离
4 适用于业务相对固定但复杂、流程相对固定但表现层变化多的情况

 

因为普通表单中,业务数据和流程数据是分离的,所以存在统一事务管理的问题。要保证Activiti和业务数据操作在同一个事务中执行。前面集成Spring时的事务管理器的配置可表明这点。本节基于第六章的主要针请假流程,对数据和表单都分离的情况下,采用普通表单实现该功能。

本节采用Spring、SpringMVC和Hibernete。

 

7.5.1 业务建模

(1)表结构

 

(2)其他

DAO和Manger用来针对请假实体的CRUD,Leave-workflowService用来处理流程相关操作。

 

7.5.2 启动流程

(1)部署流程

在启动流程之前,先部署流程。

第六章已经实现过这个页面,不再提。总之,点击浏览,选择文件,然后submit,将chapter7/leave.bpmn和leave.png打包部署。部署完毕之后,在该列表页面中,会出现一个新的processDefinition记录。

 

(2)jsp

普通表单使用时,需要将表单内容保存在一个单独的文件中。这里采用jsp文件格式。

表单设计如下:

 1     
2 3 4
5 请假申请 6 7
8 9
10 17
18
19
20 21
22 23 24
25
26
27 28
29 30 31
32
33
34 35
36 37
38
39
40 41
42
43
form

 

webapp/WEB-INF/views/chapter7/leave/leaveApply.jsp如下:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2 
 3 
 4 
 5     <%@ include file="/common/global.jsp"%>
 6     <%@ include file="/common/meta.jsp" %>
 7     <%@ include file="/common/include-base-styles.jsp" %>
 8     
 9     请假申请
10     
11     
12     
13     
14     
28 
29 
30     if test="${not empty message}">
31         
${message}
32 33 38 39
40 41
42 43
View Code

 

(3)Controller

 在上面的流程定义列表页面中,增加一个字段"操作",里面包含两个button,一个是启动,一个是删除。

当点击"启动时",应该要显示表单,并且点击申请时,流程启动。

 1 @Controller
 2 @RequestMapping(value = "/chapter7/leave")
 3 public class LeaveController {
 4 
 5     private Logger logger = LoggerFactory.getLogger(getClass());
 6 
 7     @Autowired
 8     private LeaveManager leaveManager;
 9 
10     @Autowired
11     private LeaveWorkflowService leaveService;
12 
13     @Autowired
14     private TaskService taskService;
15 
16     @Autowired
17     private RuntimeService runtimeService;
18 
19     @RequestMapping(value = {"apply", ""})
20     public String createForm(Model model) {
21         model.addAttribute("leave", new Leave());
22         return "/chapter7/leave/leave-apply";
23     }
24 
25     /**
26      * 启动请假流程
27      */
28     @RequestMapping(value = "start", method = RequestMethod.POST)
29     public String startWorkflow(Leave leave, RedirectAttributes redirectAttributes, HttpSession session) {
30         try {
31             User user = UserUtil.getUserFromSession(session);
32             Map variables = new HashMap();
33             ProcessInstance processInstance = leaveService.startWorkflow(leave, user.getId(), variables);
34             redirectAttributes.addFlashAttribute("message", "流程已启动,流程ID:" + processInstance.getId());
35         } catch (ActivitiException e) {
36             if (e.getMessage().indexOf("no processes deployed with key") != -1) {
37                 logger.warn("没有部署流程!", e);
38                 redirectAttributes.addFlashAttribute("error", "没有部署请假流程");
39             } else {
40                 logger.error("启动请假流程失败:", e);
41                 redirectAttributes.addFlashAttribute("error", "系统内部错误!");
42             }
43         } catch (Exception e) {
44             logger.error("启动请假流程失败:", e);
45             redirectAttributes.addFlashAttribute("error", "系统内部错误!");
46         }
47         return "redirect:/chapter7/leave/apply";
48     }
49     
50     ...
51 }

 

(4)Service

前面提过,这里要实现业务和流程数据的分离。即业务数据存在一个表里,流程数据存在另一个表。但是又要将二者联系起来。

这里采取的办法是:

1 业务表:增加一个字段process_instance_id,方便从业务层面查询流程数据。
2 流程表:用entity的ID作为processDefinitionKey,方便从流程层面查询业务数据。

 

可以从代码中看出来,这里不只是单纯的启动流程。还进行了数据的存储与关联。

 1 @Service
 2 @Transactional
 3 public class LeaveWorkflowService {
 4 
 5     private Logger logger = LoggerFactory.getLogger(getClass());
 6 
 7     @Autowired
 8     LeaveManager leaveManager;
 9 
10     @Autowired
11     private IdentityService identityService;
12 
13     @Autowired
14     private RuntimeService runtimeService;
15 
16     @Autowired
17     private TaskService taskService;
18 
19     @Autowired
20     private RepositoryService repositoryService;
21 
22     /**
23      * 保存请假实体并启动流程
24      */
25     public ProcessInstance startWorkflow(Leave entity, String userId, Map variables) {
26         if (entity.getId() == null) {
27             entity.setApplyTime(new Date());
28             entity.setUserId(userId);
29         }
30         leaveManager.save(entity);//持久化请假实体
31         String businessKey = entity.getId().toString();//实体保存后的ID,作为流程中的业务key
32 
33         // 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
34         identityService.setAuthenticatedUserId(userId);
35 
36         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave", businessKey, variables);//将业务主ID设置为流程实例的key
37         String processInstanceId = processInstance.getId();
38         entity.setProcessInstanceId(processInstanceId);// 将流程实例的ID保存至业务表
39         logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{"leave", businessKey, processInstanceId, variables});
40         leaveManager.save(entity);
41         return processInstance;
42     }
43 
44     ...
45 }

 

 7.5.3 任务读取

转载于:https://www.cnblogs.com/lyh421/p/6484373.html

你可能感兴趣的:(java,javascript,ViewUI)