其他分享
首页 > 其他分享> > SpringBoot整合activiti5-外置表单

SpringBoot整合activiti5-外置表单

作者:互联网

系列文章目录(springboot整合activiti5)

所谓的外置表单方式,就是先把表单内容写好并保存为.form模板文件,然后配置流程中每个节点的Form Key属性指定这个模板文件。
创建start.form

<table border="0" cellpadding="2" cellspacing="1" style="width:100%">
    <tr>
    <td nowrap align="right" width="13%">费用</td>
    <td width="19%"><input type='text' id='fee' name='fee' value='' /></td>
    <td width="13%" align="right" nowrap>费用类型</td>
    <td width="55%"><select id="type" name="type">
      <option value="差旅费">差旅费</option>
      <option value="书报费">书报费</option>
      <option value="会议费">会议费</option>
      <option value="其他费">其他费</option>
    </select></td>
    </tr>
    <tr>
      <td nowrap align="right">发生日期</td>
      <td colspan="3"><input type='text' id='feedate' name='feedate' value='' onClick="WdatePicker()"/></td>
    </tr>
    <tr>
    <td nowrap align="right" width="13%">说明</td>
    <td colspan="3"><textarea id='note' name='note' rows="5" cols="50"></textarea></td>
    </tr>
</table>

创建conform1.form

<table border="0" cellpadding="2" cellspacing="1" style="width:100%">
    <tr>
    <td nowrap align="right" width="13%">申请人</td>
    <td  colspan="3">${startUserId}</td>
    </tr>
	<tr>
    <td nowrap align="right" width="13%">费用</td>
    <td width="19%">${fee}</td>
    <td width="13%" align="right" nowrap>费用类型</td>
    <td width="55%">${type}</td>
    </tr>
    <tr>
      <td nowrap align="right">发生日期</td>
      <td colspan="3">${feedate}</td>
    </tr>
    <tr>
    <td nowrap align="right" width="13%">说明</td>
    <td colspan="3">${note}</td>
    </tr>
	<tr>
    <td nowrap align="right" width="13%">部门领导意见</td>
    <td colspan="3"><textarea id='bmyj' name='bmyj' rows="5" cols="50"></textarea></td>
    </tr>
</table>

创建conform2.form

<table border="0" cellpadding="2" cellspacing="1" style="width:100%">
    <tr>
    <td nowrap align="right" width="13%">申请人</td>
    <td  colspan="3">${startUserId}</td>
    </tr>
	<tr>
    <td nowrap align="right" width="13%">费用</td>
    <td width="19%">${fee}</td>
    <td width="13%" align="right" nowrap>核实费用</td>
    <td width="55%"><input type='text' id='refee' name='refee' value='' /></td>
    </tr>
    <tr>
      <td nowrap align="right">发生日期</td>
      <td>${feedate}</td>
	  <td width="13%" align="right" nowrap>费用类型</td>
      <td width="55%">${type}</td>
    </tr>
    <tr>
    <td nowrap align="right" width="13%">说明</td>
    <td colspan="3">${note}</td>
    </tr>
	<tr>
    <td nowrap align="right" width="13%">部门领导意见</td>
    <td colspan="3">${bmyj}</td>
    </tr>
	<tr>
    <td nowrap align="right" width="13%">财务部门意见</td>
    <td colspan="3"><textarea id='bzhu' name='bzhu' rows="5" cols="50"></textarea></td>
    </tr>
</table>

创建conform3.form

<table border="0" cellpadding="2" cellspacing="1" style="width:100%">
    <tr>
    <td nowrap align="right" width="13%">费用</td>
    <td width="19%">${fee}</td>
    <td width="13%" align="right" nowrap>核实费用</td>
    <td width="55%">${refee}</td>
    </tr>
    <tr>
      <td nowrap align="right">发生日期</td>
      <td>${feedate}</td>
	  <td width="13%" align="right" nowrap>费用类型</td>
      <td width="55%">${type}</td>
    </tr>
    <tr>
    <td nowrap align="right" width="13%">说明</td>
    <td colspan="3">${note}</td>
    </tr>
	<tr>
    <td nowrap align="right" width="13%">部门领导意见</td>
    <td colspan="3">${bmyj}</td>
    </tr>
	<tr>
    <td nowrap align="right" width="13%">财务部门意见</td>
    <td colspan="3">${bzhu}</td>
    </tr>
</table>

创建流程定义文件reimbursement-1.bpmn并将activiti:formKey指定为对应的form

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.zioer.com/reimbursement-1">
  <process id="reimbursement-1" name="费用报销-1" isExecutable="true">
    <startEvent id="startevent1" name="Start" activiti:initiator="startUserId" activiti:formKey="start.form"></startEvent>
    <userTask id="usertask1" name="部门领导审批" activiti:assignee="${startUserId}" activiti:formKey="conform1.form"></userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <userTask id="usertask2" name="财务部门审批" activiti:assignee="${startUserId}" activiti:formKey="conform2.form"></userTask>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
    <userTask id="usertask3" name="申请人确认" activiti:assignee="${startUserId}" activiti:formKey="conform3.form"></userTask>
    <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_reimbursement-1">
    <bpmndi:BPMNPlane bpmnElement="reimbursement-1" id="BPMNPlane_reimbursement-1">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="180.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="260.0" y="180.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="410.0" y="180.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
        <omgdc:Bounds height="55.0" width="105.0" x="560.0" y="180.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="710.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="215.0" y="207.0"></omgdi:waypoint>
        <omgdi:waypoint x="260.0" y="207.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="365.0" y="207.0"></omgdi:waypoint>
        <omgdi:waypoint x="410.0" y="207.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="515.0" y="207.0"></omgdi:waypoint>
        <omgdi:waypoint x="560.0" y="207.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="665.0" y="207.0"></omgdi:waypoint>
        <omgdi:waypoint x="710.0" y="207.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

在这里插入图片描述

外置表单和流程定义文件进行打包
在这里插入图片描述
存放在指定目录
在这里插入图片描述
并修改前面通过压缩包部署的代码指定文件路径
在这里插入图片描述
通过压缩包部署
在这里插入图片描述
可以看出,部署成功了。

编写控制层代码操作外置表单

package com.xquant.platform.test.activiti.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricDetail;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value = "/keyform")
public class KeyformController {
    
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private FormService formService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RuntimeService runtimeService;
    
    @RequestMapping(value = "/add")
    public String add(Model model,HttpSession session) {
    	if (session.getAttribute("userId") == null){
    		return "redirect:/login/";
    	}

        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        		.processDefinitionKey("reimbursement-1")
        		.latestVersion().singleResult();

        Object startForm = formService.getRenderedStartForm(processDefinition.getId());
        //String formkey = formService.getStartFormKey(processDefinition.getId());
        
		model.addAttribute("formData", startForm);
    	return "reimbursement-1_start";
    }
    
    /**
     * 提交启动流程
     */
    @RequestMapping(value = "/start/save")
    public String saveStartForm(Model model,HttpServletRequest request,HttpSession session) {
    	String userId = session.getAttribute("userId") == null ? null : session.getAttribute("userId").toString();
    	if (userId == null){
    		return "redirect:/login/";
    	}
    	
    	Map formProperties = PageData(request);
        ProcessDefinition processDefinition = repositoryService
        		.createProcessDefinitionQuery()
        		.processDefinitionKey("reimbursement-1")
        		.latestVersion().singleResult();
        String processDefinitionId = processDefinition.getId();
        try {
            identityService.setAuthenticatedUserId(userId);
            formService.submitStartFormData(processDefinitionId, formProperties);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }

        return "redirect:/keyform/list";
    }

    @RequestMapping(value = "/list")
    public String list(Model model,HttpSession session) {
    	String userId = session.getAttribute("userId") == null ? null : session.getAttribute("userId").toString();
    	if (userId == null){
    		return "redirect:/login/";
    	}
    	List<Task> tasks = new ArrayList<Task>();
    	
    	//获得当前用户的任务
    	tasks = taskService.createTaskQuery()
    			.taskCandidateOrAssigned(userId).processDefinitionKey("reimbursement-1")
    			.active()
    			.orderByTaskId().desc().list();
    	
    	model.addAttribute("list", tasks);
    	
    	return "reimbursement-1_list";
    }
    
    /**
     * 初始化启动流程,读取启动流程的表单字段来渲染start form
     */
    @RequestMapping(value = "/startform/{taskId}")
    public String StartTaskForm(@PathVariable("taskId") String taskId,Model model,HttpSession session) throws Exception {
    	String userId = session.getAttribute("userId") == null ? null : session.getAttribute("userId").toString();
    	if (userId == null){
    		return "redirect:/login/";
    	}
    	Object taskForm = formService.getRenderedTaskForm(taskId);        
        String startUserId = (String) taskService.getVariable(taskId, "startUserId"); 
        
        model.addAttribute("formData", taskForm);
        model.addAttribute("taskId", taskId);
        model.addAttribute("startUserId", startUserId);
        
        return "reimbursement-1_edit";
    }
    /**
     * 提交启动流程
     */
    @RequestMapping(value = "/startform/save/{taskId}")
    public String saveTaskForm(@PathVariable("taskId") String taskId,HttpSession session,HttpServletRequest request) {
    	String userId = session.getAttribute("userId") == null ? null : session.getAttribute("userId").toString();
    	if (userId == null){
    		return "redirect:/login/";
    	}

    	Map formProperties = PageData(request);
        
        try {
            identityService.setAuthenticatedUserId(userId);
            formService.submitTaskFormData(taskId, formProperties);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }

        return "redirect:/keyform/list";
    }

    @RequestMapping(value = "/hlist")
    public String historylist(Model model,HttpSession session) {
    	String userId = session.getAttribute("userId") == null ? null : session.getAttribute("userId").toString();
    	if (userId == null){
    		return "redirect:/login/";
    	}
    	    	
    	List<Map> hlist = new ArrayList<Map>();
    	List historylist = historyService.createHistoricProcessInstanceQuery()
    			.processDefinitionKey("reimbursement-1")
                .startedBy(userId).list();

    	for (int i=0;i<historylist.size();i++){
    		Map<String, Object> map = new HashMap<String, Object>();
    		HistoricProcessInstanceEntity hpe = (HistoricProcessInstanceEntity) historylist.get(i);
    		
    		map.put("id", hpe.getId());
    		map.put("startUserId", hpe.getStartUserId());
    		map.put("processInstanceId", hpe.getProcessInstanceId());
    		map.put("endTime", hpe.getEndTime());
    		map.put("startTime", hpe.getStartTime());
    		if (hpe.getEndTime() == null){
    			Task task =  taskService.createTaskQuery().processInstanceId(hpe.getProcessInstanceId()).active().singleResult();
    			if (task != null){
    				map.put("name", task.getName());
    			}
    		}else{
    			map.put("name", "已完成");
    		}
    		hlist.add(map);
    	}
    	
    	//获得当前用户的任务
    	model.addAttribute("list", hlist);
    	
    	return "reimbursement_hlist";
    }
    
    @RequestMapping(value = "/hview/{pId}")
    public String historyView(@PathVariable("pId") String pId,Model model,HttpSession session) {
    	String userId = session.getAttribute("userId") == null ? null : session.getAttribute("userId").toString();
    	if (userId == null){
    		return "redirect:/login/";
    	}
    	
    	List<HistoricDetail> details = historyService
    		    .createHistoricDetailQuery()
    		    .processInstanceId(pId)
    		    .orderByTime().asc()
    		    .list();
    	
    	model.addAttribute("list", details);
    	return "reimbursement_hview";
    }
    
    public Map PageData(HttpServletRequest request){
		Map properties = request.getParameterMap();
		Map returnMap = new HashMap(); 
		Iterator entries = properties.entrySet().iterator(); 
		Map.Entry entry; 
		String name = "";  
		String value = "";  
		while (entries.hasNext()) {
			entry = (Map.Entry) entries.next(); 
			name = (String) entry.getKey(); 
			Object valueObj = entry.getValue(); 
			if(null == valueObj){ 
				value = ""; 
			}else if(valueObj instanceof String[]){ 
				String[] values = (String[])valueObj;
				for(int i=0;i<values.length;i++){ 
					 value = values[i] + ",";
				}
				value = value.substring(0, value.length()-1); 
			}else{
				value = valueObj.toString(); 
			}
			returnMap.put(name, value); 
		}
		return returnMap;
	}
}

通过http://localhost:8080/keyform/add发起访问
此时会查出外置表单
在这里插入图片描述
由于表单已经有了,所以jsp文件reimbursement-1_start.jsp非常简单

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html lang="en">
<head>
    <title>费用报销-新增</title>
    <link rel="stylesheet" rev="stylesheet" href="<%=basePath%>css/style.css" type="text/css" media="all" />
	<script type="text/javascript" src="<%=basePath%>js/My97DatePicker/WdatePicker.js"></script>
	<script language=JavaScript>
		function save(){
		   document.getElementById("form").submit();
		}
	</script>
</head>
<body class="ContentBody">
<form action="start/save" method="post" name="form" id="form">
<div class="MainDiv">
<table width="90%" border="0" cellpadding="0" cellspacing="0" class="CContent">
  <tr>
      <th class="tablestyle_title" >费用报销-新增</th>
  </tr>
  <tr>
    <td class="CPanel">
		<table border="0" cellpadding="0" cellspacing="0" style="width:100%">
            <TR>
                <TD width="100%">
                    <fieldset style="height:100%;">
                    <legend>内容填写</legend>
                          ${formData}
                    </fieldset>			
                </TD>
            </TR>
		</TABLE>
	 </td>
  </tr>
  <tr>
    <TD colspan="2" align="center" height="50px">
        <input type="button" name="Submit" value="保存" class="button" onclick="save();"/>    
        <input type="button" name="Submit2" value="返回" class="button" onclick="window.history.go(-1);"/>
    </TD>
  </tr>
</table>
</div>
</form>
</body>
</html>

在这里插入图片描述
输入数据之后点击保存
在这里插入图片描述
保存就会将数据发送到后台的控制层
在这里插入图片描述
在这里插入图片描述
用户提交完成之后,重定向并查询当前用户的任务。
在这里插入图片描述
通过reimbursement-1_list.jsp渲染

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf8" %> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<title>Zioer-Activiti示例</title>
<link rel="stylesheet" rev="stylesheet" href="<%=basePath%>css/style.css" type="text/css" media="all" />
<script language=JavaScript>

</script>
</head>

<body class="ContentBody">
<form action="add" method="post" name="fom" id="fom">
<div class="MainDiv">
<table width="90%" border="0" cellpadding="0" cellspacing="0" class="CContent">
  <tr>
      <th class="tablestyle_title" >费用报销管理-待办工作</th>
  </tr>
  <tr>
    <td class="CPanel">
		<table id="subtree1" style="DISPLAY: " width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td><table width="95%" border="0" align="center" cellpadding="0" cellspacing="0">
          	 
              <tr>
                <td height="40" class="font42">
				<table width="100%" border="0" cellpadding="4" cellspacing="1" bgcolor="#FFFFEE" class="newfont03">
				 <tr class="CTitle" >
                    	<td height="22" colspan="5" align="center" style="font-size:16px">当前用户办理工作列表</td>
                  </tr>
                  <tr bgcolor="#EEEEEE">
				    <td width="10%" height="30">任务ID</td>
					<td width="20%">当前节点</td>
                    <td width="20%">办理人</td>
                    <td width="36%">创建时间</td>
					<td width="17%">操作</td>
                  </tr>
                  <c:forEach items="${list}" var="var" varStatus="vs">
                  <tr  <c:if test="${vs.count%2==0}">bgcolor="#AAAABB"</c:if> align="left" >
				    <td >${var.id}</td>
				    <td  height="30">${var.name}</td>
					<td >${var.assignee}</td>                    
					<td ><fmt:formatDate value="${var.createTime}" type="both"/></td>                    
					<td ><a href="<%=basePath%>keyform/startform/${var.id}">办理</a></td>
                  </tr>
                  </c:forEach>
            </table></td>
        </tr>
      </table>
      </td>
  </tr>
</table>
	 </td>
  </tr>
  
</table>
</div>
</form>
</body>
</html>

在这里插入图片描述
点击办理,进入keyform/startform/流程,获取外置表单
在这里插入图片描述
对应页面也非常简单,跟前面一样,因为主要的表单信息已经包含在外置表单当中了

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html lang="en">
<head>
    <title>费用报销-审批</title>
    <link rel="stylesheet" rev="stylesheet" href="<%=basePath%>css/style.css" type="text/css" media="all" />
	<script type="text/javascript" src="<%=basePath%>js/My97DatePicker/WdatePicker.js"></script>
	<script language=JavaScript>
		function save(){
		   document.getElementById("form").submit();
		}
	</script>
</head>
<body>
<form action="save/${ taskId}" method="post" name="form" id="form">
<div class="MainDiv">
<table width="60%" border="0" cellpadding="0" cellspacing="0" class="CContent">
  <tr>
      <th class="tablestyle_title" >费用报销-审批</th>
  </tr>
  <tr>
    <td class="CPanel">
		<table border="0" cellpadding="0" cellspacing="0" style="width:100%">
            <TR>
                <TD width="100%">
                    <fieldset style="height:100%;">
                    <legend>内容填写</legend>
                        ${formData}
                    </fieldset>
                </TD>
            </TR>
		</TABLE>
	 </td>
  </tr>
  <tr>
    <TD colspan="2" align="center" height="50px">
        <input type="button" name="Submit" value="保存" class="button" onclick="save();"/>     
        <input type="button" name="Submit2" value="返回" class="button" onclick="window.history.go(-1);"/>
    </TD>
  </tr>
</table>
</div>
</form>
</body>
</html>

在这里插入图片描述
点击保存,又会进入到save方法,其实就是提交当前的流程了
在这里插入图片描述
后面的流程就基本差不多一致了。

标签:SpringBoot,userId,外置,activiti5,session,value,import,null,String
来源: https://blog.csdn.net/m0_37607945/article/details/115256505