mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-28 16:58:43 +08:00 
			
		
		
		
	flowable单元测试
This commit is contained in:
		| @@ -64,5 +64,18 @@ | ||||
|             <groupId>cn.iocoder.boot</groupId> | ||||
|             <artifactId>yudao-spring-boot-starter-flowable</artifactId> | ||||
|         </dependency> | ||||
|         <!--junit4--> | ||||
|         <dependency> | ||||
|             <groupId>junit</groupId> | ||||
|             <artifactId>junit</artifactId> | ||||
|             <version>4.11</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.h2database</groupId> | ||||
|             <artifactId>h2</artifactId> | ||||
|             <version>1.4.196</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| </project> | ||||
|   | ||||
| @@ -0,0 +1,78 @@ | ||||
| package cn.iocoder.yudao.module.bpm; | ||||
|  | ||||
| import org.flowable.engine.*; | ||||
| import org.flowable.engine.impl.ProcessEngineImpl; | ||||
| import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; | ||||
| import org.flowable.engine.impl.test.TestHelper; | ||||
| import org.flowable.engine.test.FlowableRule; | ||||
| import org.junit.AfterClass; | ||||
| import org.junit.Before; | ||||
| import org.junit.BeforeClass; | ||||
| import org.junit.Rule; | ||||
|  | ||||
| /** | ||||
|  * 抽象测试基类 | ||||
|  * | ||||
|  * @author henryyan cuicui | ||||
|  */ | ||||
| public abstract class AbstractOATest { | ||||
|  | ||||
|     protected String configurationResource = "flowable.cfg.xml"; | ||||
|  | ||||
|     /** | ||||
|      * 专门用于测试套件 | ||||
|      */ | ||||
|     @Rule | ||||
|     public FlowableRule activitiRule = new FlowableRule("flowable.cfg.xml"); | ||||
|  | ||||
|     protected ProcessEngineConfigurationImpl processEngineConfiguration; | ||||
|  | ||||
|     protected ProcessEngine processEngine; | ||||
|     protected RepositoryService repositoryService; | ||||
|     protected RuntimeService runtimeService; | ||||
|     protected TaskService taskService; | ||||
|     protected HistoryService historyService; | ||||
|     protected IdentityService identityService; | ||||
|     protected ManagementService managementService; | ||||
|     protected FormService formService; | ||||
|  | ||||
|     /** | ||||
|      * 开始测试 | ||||
|      */ | ||||
|     @BeforeClass | ||||
|     public static void setUpForClass() throws Exception { | ||||
|         System.out.println("++++++++ 开始测试 ++++++++"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 结束测试 | ||||
|      */ | ||||
|     @AfterClass | ||||
|     public static void testOverForClass() throws Exception { | ||||
|         System.out.println("-------- 结束测试 --------"); | ||||
|     } | ||||
|  | ||||
|     protected void initializeProcessEngine() { | ||||
|         processEngine = TestHelper.getProcessEngine(configurationResource); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 初始化变量 | ||||
|      */ | ||||
|     @Before | ||||
|     public void setUp() throws Exception { | ||||
|         if (processEngine == null) { | ||||
|             initializeProcessEngine(); | ||||
|         } | ||||
|  | ||||
|         processEngineConfiguration = ((ProcessEngineImpl) processEngine).getProcessEngineConfiguration(); | ||||
|         repositoryService = processEngine.getRepositoryService(); | ||||
|         runtimeService = processEngine.getRuntimeService(); | ||||
|         taskService = processEngine.getTaskService(); | ||||
|         historyService = processEngine.getHistoryService(); | ||||
|         identityService = processEngine.getIdentityService(); | ||||
|         managementService = processEngine.getManagementService(); | ||||
|         formService = processEngine.getFormService(); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,226 @@ | ||||
| package cn.iocoder.yudao.module.bpm; | ||||
|  | ||||
| import org.flowable.engine.history.HistoricDetail; | ||||
| import org.flowable.engine.history.HistoricFormProperty; | ||||
| import org.flowable.engine.history.HistoricProcessInstance; | ||||
| import org.flowable.engine.history.HistoricVariableUpdate; | ||||
| import org.flowable.engine.repository.ProcessDefinition; | ||||
| import org.flowable.engine.runtime.ProcessInstance; | ||||
| import org.flowable.engine.test.Deployment; | ||||
| import org.flowable.task.api.Task; | ||||
| import org.joda.time.DateTime; | ||||
| import org.junit.Test; | ||||
|  | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.*; | ||||
|  | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
|  | ||||
| /** | ||||
|  * 条件测试 | ||||
|  * 1 某个节点-支付额度需要大于70% | ||||
|  * 2 支付条件完成后,开始倒计时15天,要完成流程处理 | ||||
|  * @author cuicui | ||||
|  */ | ||||
| public class ConditionTest extends AbstractOATest { | ||||
|  | ||||
|     @Test | ||||
|     @Deployment(resources = {"chapter6/leave-timeLimit-money/leave-formkey-ext.bpmn", "chapter6/leave-timeLimit-money/leave-start.form", | ||||
|             "chapter6/leave-timeLimit-money/approve-deptLeader.form", "chapter6/leave-timeLimit-money/approve-hr.form", "chapter6/leave-timeLimit-money/report-back.form", | ||||
|             "chapter6/leave-timeLimit-money/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"); | ||||
|         //手动设置支付金额 | ||||
|         variables.put("amountMoney", "19999"); | ||||
|         formService.submitTaskFormData(hrTask.getId(), variables); | ||||
|         //判断支付金额是否>1万元 | ||||
|         // 财务打款通过 | ||||
|         Task caiwuTask = taskService.createTaskQuery().taskCandidateGroup("caiwu").singleResult(); | ||||
|         printTask(caiwuTask); | ||||
|         taskService.complete(caiwuTask.getId()); | ||||
|         //判断倒计时15天 | ||||
|         Task chuNaTask = taskService.createTaskQuery().taskCandidateGroup("chuNa").singleResult(); | ||||
|         printTask(chuNaTask); | ||||
|         taskService.complete(chuNaTask.getId()); | ||||
|  | ||||
|         // 销假(根据申请人的用户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")); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询过期任务 | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"chapter6/leave-timeLimit-money/leave-formkey-ext.bpmn", "chapter6/leave-timeLimit-money/leave-start.form", | ||||
|             "chapter6/leave-timeLimit-money/approve-deptLeader.form", "chapter6/leave-timeLimit-money/approve-hr.form", "chapter6/leave-timeLimit-money/report-back.form", | ||||
|             "chapter6/leave-timeLimit-money/modify-apply.form"}) | ||||
|     public void dueDate() 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"); | ||||
|         //手动设置支付金额 | ||||
|         variables.put("amountMoney", "19999"); | ||||
|         formService.submitTaskFormData(hrTask.getId(), variables); | ||||
|         //判断支付金额是否>1万元 | ||||
|         // 财务打款通过 | ||||
|         Task caiwuTask = taskService.createTaskQuery().taskCandidateGroup("caiwu").singleResult(); | ||||
|         printTask(caiwuTask); | ||||
|  | ||||
|         //设置5天前就过期了 | ||||
|         DateTime dateTime = DateTime.now(); | ||||
|         DateTime minusDays = dateTime.minusDays(5); | ||||
|         taskService.setDueDate(caiwuTask.getId(),minusDays.toDate()); | ||||
|         //查询今天以前的过期任务 | ||||
|         List<Task> listTask = taskService.createTaskQuery().taskDueBefore(new Date()).list(); | ||||
|         for (Task task : listTask) { | ||||
|             printTask(task); | ||||
|         } | ||||
|  | ||||
|         // 销假(根据申请人的用户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")); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 任意流程的跳转 | ||||
|      */ | ||||
|     @Test | ||||
|     public void taskJump(){ | ||||
|         // 当前任务 | ||||
|         String taskId="ddd"; | ||||
|         Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); | ||||
|         String assignee = "下一个自由跳转人"; | ||||
|         taskService.setAssignee(taskId,assignee); | ||||
|         // 自由跳转 | ||||
|         String taskDefKey="目标-任务名称"; | ||||
|         //moveActivityIdTo的两个参数,源任务key,目标任务key | ||||
|         runtimeService.createChangeActivityStateBuilder().processInstanceId(task.getProcessInstanceId()).moveActivityIdTo(task.getTaskDefinitionKey(), taskDefKey).changeState(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 读取历史变量并封装到Map中 | ||||
|      */ | ||||
|     private Map<String, Object> packageVariables(ProcessInstance processInstance) { | ||||
|         Map<String, Object> historyVariables = new HashMap<String, Object>(); | ||||
|         List<HistoricDetail> list = historyService.createHistoricDetailQuery().processInstanceId(processInstance.getId()).list(); | ||||
|         for (HistoricDetail historicDetail : list) { | ||||
|             if (historicDetail instanceof HistoricFormProperty) { | ||||
|                 // 表单中的字段 | ||||
|                 HistoricFormProperty field = (HistoricFormProperty) historicDetail; | ||||
|                 historyVariables.put(field.getPropertyId(), field.getPropertyValue()); | ||||
|                 System.out.println("form field: taskId=" + field.getTaskId() + ", " + field.getPropertyId() + " = " + field.getPropertyValue()); | ||||
|             } else if (historicDetail instanceof HistoricVariableUpdate) { | ||||
|                 HistoricVariableUpdate variable = (HistoricVariableUpdate) historicDetail; | ||||
|                 historyVariables.put(variable.getVariableName(), variable.getValue()); | ||||
|                 System.out.println("variable: " + variable.getVariableName() + " = " + variable.getValue()); | ||||
|             } | ||||
|         } | ||||
|         return historyVariables; | ||||
|     } | ||||
|     private void printTask(Task task){ | ||||
|         System.out.println(task.getName()+" : " + task.getDueDate()); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,177 @@ | ||||
| package cn.iocoder.yudao.module.bpm; | ||||
|  | ||||
| import org.flowable.engine.history.HistoricDetail; | ||||
| import org.flowable.engine.history.HistoricFormProperty; | ||||
| import org.flowable.engine.history.HistoricProcessInstance; | ||||
| import org.flowable.engine.history.HistoricVariableUpdate; | ||||
| import org.flowable.engine.repository.ProcessDefinition; | ||||
| import org.flowable.engine.runtime.ProcessInstance; | ||||
| import org.flowable.engine.test.Deployment; | ||||
| import org.flowable.task.api.Task; | ||||
| import org.junit.Test; | ||||
|  | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Calendar; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
|  | ||||
| /** | ||||
|  * @author henryyan | ||||
|  */ | ||||
| public class LeaveFormKeyTest extends AbstractOATest { | ||||
|  | ||||
|     @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")); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 任意流程的跳转 | ||||
|      */ | ||||
|     @Test | ||||
|     public void taskJump(){ | ||||
|         // 当前任务 | ||||
|         String taskId="ddd"; | ||||
|         Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); | ||||
|         String assignee = "下一个自由跳转人"; | ||||
|         taskService.setAssignee(taskId,assignee); | ||||
|         // 自由跳转 | ||||
|         String taskDefKey="目标-任务名称"; | ||||
|         //moveActivityIdTo的两个参数,源任务key,目标任务key | ||||
|         runtimeService.createChangeActivityStateBuilder().processInstanceId(task.getProcessInstanceId()).moveActivityIdTo(task.getTaskDefinitionKey(), taskDefKey).changeState(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 领导驳回后申请人取消申请 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = "chapter6/dynamic-form/leave.bpmn") | ||||
|     public void cancelApply() throws Exception { | ||||
|  | ||||
|         // 设置当前用户 | ||||
|         String currentUserId = "henryyan"; | ||||
|         identityService.setAuthenticatedUserId(currentUserId); | ||||
|  | ||||
|         ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave").singleResult(); | ||||
|  | ||||
|         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); | ||||
|         String endDate = sdf.format(ca.getTime()); | ||||
|  | ||||
|         // 启动流程 | ||||
|         variables.put("startDate", startDate); | ||||
|         variables.put("endDate", endDate); | ||||
|         variables.put("reason", "公休"); | ||||
|         ProcessInstance processInstance = formService.submitStartFormData(processDefinition.getId(), variables); | ||||
|         assertNotNull(processInstance); | ||||
|  | ||||
|         // 部门领导审批通过 | ||||
|         Task deptLeaderTask = taskService.createTaskQuery().taskCandidateGroup("deptLeader").singleResult(); | ||||
|         variables = new HashMap<String, String>(); | ||||
|         variables.put("deptLeaderApproved", "false"); | ||||
|         formService.submitTaskFormData(deptLeaderTask.getId(), variables); | ||||
|  | ||||
|         // 调整申请 | ||||
|         Task modifyApply = taskService.createTaskQuery().taskAssignee(currentUserId).singleResult(); | ||||
|         variables = new HashMap<String, String>(); | ||||
|         variables.put("reApply", "false"); | ||||
|         variables.put("startDate", startDate); | ||||
|         variables.put("endDate", endDate); | ||||
|         variables.put("reason", "公休"); | ||||
|         formService.submitTaskFormData(modifyApply.getId(), variables); | ||||
|  | ||||
|         // 读取历史变量 | ||||
|         Map<String, Object> historyVariables = packageVariables(processInstance); | ||||
|  | ||||
|         // 验证执行结果 | ||||
|         assertEquals("canceled", historyVariables.get("result")); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 读取历史变量并封装到Map中 | ||||
|      */ | ||||
|     private Map<String, Object> packageVariables(ProcessInstance processInstance) { | ||||
|         Map<String, Object> historyVariables = new HashMap<String, Object>(); | ||||
|         List<HistoricDetail> list = historyService.createHistoricDetailQuery().processInstanceId(processInstance.getId()).list(); | ||||
|         for (HistoricDetail historicDetail : list) { | ||||
|             if (historicDetail instanceof HistoricFormProperty) { | ||||
|                 // 表单中的字段 | ||||
|                 HistoricFormProperty field = (HistoricFormProperty) historicDetail; | ||||
|                 historyVariables.put(field.getPropertyId(), field.getPropertyValue()); | ||||
|                 System.out.println("form field: taskId=" + field.getTaskId() + ", " + field.getPropertyId() + " = " + field.getPropertyValue()); | ||||
|             } else if (historicDetail instanceof HistoricVariableUpdate) { | ||||
|                 HistoricVariableUpdate variable = (HistoricVariableUpdate) historicDetail; | ||||
|                 historyVariables.put(variable.getVariableName(), variable.getValue()); | ||||
|                 System.out.println("variable: " + variable.getVariableName() + " = " + variable.getValue()); | ||||
|             } | ||||
|         } | ||||
|         return historyVariables; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,208 @@ | ||||
| package cn.iocoder.yudao.module.bpm; | ||||
|  | ||||
| import org.flowable.engine.history.HistoricDetail; | ||||
| import org.flowable.engine.history.HistoricFormProperty; | ||||
| import org.flowable.engine.history.HistoricProcessInstance; | ||||
| import org.flowable.engine.history.HistoricVariableUpdate; | ||||
| import org.flowable.engine.repository.ProcessDefinition; | ||||
| import org.flowable.engine.runtime.ProcessInstance; | ||||
| import org.flowable.engine.test.Deployment; | ||||
| import org.flowable.task.api.Task; | ||||
| import org.junit.Test; | ||||
|  | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.*; | ||||
|  | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
|  | ||||
| /** | ||||
|  * @author henryyan | ||||
|  * testMultiInstanceForUserTask 会签 | ||||
|  * cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmUserTaskActivityBehavior#handleAssignments(org.flowable.task.service.TaskService, java.lang.String, java.lang.String, java.util.List, java.util.List, org.flowable.task.service.impl.persistence.entity.TaskEntity, org.flowable.common.engine.impl.el.ExpressionManager, org.flowable.engine.delegate.DelegateExecution, org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl) | ||||
|  * | ||||
|  * 发生了死锁 | ||||
|  * cn.iocoder.yudao.module.bpm.controller.admin.task.BpmProcessInstanceController#createProcessInstance(cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO) | ||||
|  * 执行了两次,任务分配到了同一个人 | ||||
|  */ | ||||
| public class MultiInstancesTest extends AbstractOATest { | ||||
|  | ||||
|     /** | ||||
|      * Java Service多实例(是否顺序结果一样) | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/testMultiInstanceFixedNumbers.bpmn"}) | ||||
|     public void testParallel() throws Exception { | ||||
|         Map<String, Object> variables = new HashMap<String, Object>(); | ||||
|         long loop = 3; | ||||
|         variables.put("loop", loop); | ||||
|         variables.put("counter", 0); // 计数器 | ||||
|         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceFixedNumbers", variables); | ||||
|         Object variable = runtimeService.getVariable(processInstance.getId(), "counter"); | ||||
|         assertEquals(loop, variable); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 用户任务多实例--顺序 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.sequential.bpmn"}) | ||||
|     public void testForUserSequence() throws Exception { | ||||
|         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask"); | ||||
|         long count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); | ||||
|         assertEquals(1, count); | ||||
|  | ||||
|         Task task = taskService.createTaskQuery().singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|         count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); | ||||
|         assertEquals(1, count); | ||||
|  | ||||
|         task = taskService.createTaskQuery().singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|         count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); | ||||
|         assertEquals(1, count); | ||||
|  | ||||
|         task = taskService.createTaskQuery().singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|         count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); | ||||
|         assertEquals(0, count); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 用户任务多实例--并行 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.nosequential.bpmn"}) | ||||
|     public void testForUserNoSequential() throws Exception { | ||||
|         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask"); | ||||
|         long count = taskService.createTaskQuery().processInstanceId(processInstance.getId()).count(); | ||||
|         assertEquals(3, count); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 用户任务多实例,通过用户数量决定实例个数--并行 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.nosequential.bpmn"}) | ||||
|     public void testForUserCreateByUsersNoSequential() throws Exception { | ||||
|         Map<String, Object> variables = new HashMap<String, Object>(); | ||||
|         List<String> users = Arrays.asList("user1", "user2", "user3"); | ||||
|         variables.put("users", users); | ||||
|         runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); | ||||
|         for (String userId : users) { | ||||
|             assertEquals(1, taskService.createTaskQuery().taskAssignee(userId).count()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 用户任务多实例,通过用户数量决定实例个数--顺序 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.bpmn"}) | ||||
|     public void testForUserCreateByUsersSequential() throws Exception { | ||||
|         Map<String, Object> variables = new HashMap<String, Object>(); | ||||
|         List<String> users = Arrays.asList("user1", "user2", "user3"); | ||||
|         variables.put("users", users); | ||||
|         runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); | ||||
|         for (String userId : users) { | ||||
|             Task task = taskService.createTaskQuery().taskAssignee(userId).singleResult(); | ||||
|             taskService.complete(task.getId()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 用户任务多实例,按照任务完成的百分比比率决定是否提前结束流程 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.users.sequential.with.complete.conditon.bpmn"}) | ||||
|     public void testForUserCreateByUsersSequentialWithCompleteCondition() throws Exception { | ||||
|         Map<String, Object> variables = new HashMap<String, Object>(); | ||||
|         List<String> users = Arrays.asList("user1", "user2", "user3"); | ||||
|         variables.put("users", users); | ||||
|         variables.put("rate", 0.6d); | ||||
|         runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); | ||||
|  | ||||
|         Task task = taskService.createTaskQuery().taskAssignee("user1").singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|  | ||||
|         task = taskService.createTaskQuery().taskAssignee("user2").singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|  | ||||
|         long count = historyService.createHistoricProcessInstanceQuery().finished().count(); | ||||
|         assertEquals(1, count); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 用户任务多实例,按照任务完成的百分比比率决定是否提前结束流程 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/testMultiInstanceForUserTask.exception.bpmn"}) | ||||
|     public void testForUserCreateByUsersException() throws Exception { | ||||
|         Map<String, Object> variables = new HashMap<String, Object>(); | ||||
|         List<String> users = Arrays.asList("user1", "user2", "user3"); | ||||
|         variables.put("users", users); | ||||
|         runtimeService.startProcessInstanceByKey("testMultiInstanceForUserTask", variables); | ||||
|  | ||||
|         Task task = taskService.createTaskQuery().taskAssignee("user1").singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|  | ||||
|         task = taskService.createTaskQuery().taskAssignee("user2").singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|  | ||||
|         task = taskService.createTaskQuery().taskAssignee("user3").singleResult(); | ||||
|         taskService.complete(task.getId()); | ||||
|  | ||||
|         List<Task> list = taskService.createTaskQuery().list(); | ||||
|         for (Task task2 : list) { | ||||
|             System.out.println("============" + task2.getName()); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     ///////////////////////////////////////////////// | ||||
|     /** | ||||
|      * 全部通过 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/leave-countersign.bpmn"}) | ||||
|     public void testAllApproved() throws Exception { | ||||
|         Map<String, Object> variables = new HashMap<String, Object>(); | ||||
|         List<String> users = Arrays.asList("groupLeader", "deptLeader", "hr"); | ||||
|         variables.put("users", users); | ||||
|         identityService.setAuthenticatedUserId("henryyan"); | ||||
|         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-countersign", variables); | ||||
|         for (String user : users) { | ||||
|             Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee(user).singleResult(); | ||||
|             Map<String, Object> taskVariables = new HashMap<String, Object>(); | ||||
|             taskVariables.put("approved", "true"); | ||||
|             taskService.complete(task.getId(), taskVariables); | ||||
|         } | ||||
|  | ||||
|         Task task = taskService.createTaskQuery().taskAssignee("henryyan").singleResult(); | ||||
|         assertNotNull(task); | ||||
|         assertEquals("销假", task.getName()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 部分通过 | ||||
|      */ | ||||
|     @Test | ||||
|     @Deployment(resources = {"diagrams/chapter9/leave-countersign.bpmn"}) | ||||
|     public void testNotAllApproved() throws Exception { | ||||
|         Map<String, Object> variables = new HashMap<String, Object>(); | ||||
|         List<String> users = Arrays.asList("groupLeader", "deptLeader", "hr"); | ||||
|         variables.put("users", users); | ||||
|         identityService.setAuthenticatedUserId("henryyan"); | ||||
|         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-countersign", variables); | ||||
|         for (String user : users) { | ||||
|             Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee(user).singleResult(); | ||||
|             Map<String, Object> taskVariables = new HashMap<String, Object>(); | ||||
|             taskVariables.put("approved", "false"); | ||||
|             taskService.complete(task.getId(), taskVariables); | ||||
|         } | ||||
|  | ||||
|         Task task = taskService.createTaskQuery().taskAssignee("henryyan").singleResult(); | ||||
|         assertNotNull(task); | ||||
|         assertEquals("调整申请", task.getName()); | ||||
|     } | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -0,0 +1,198 @@ | ||||
| <?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.kafeitu.me/activiti/leave"> | ||||
|   <process id="leave" name="请假流程-动态表单" isExecutable="true"> | ||||
|     <documentation>请假流程演示-动态表单</documentation> | ||||
|     <startEvent id="startevent1" name="Start" activiti:initiator="applyUserId"> | ||||
|       <extensionElements> | ||||
|         <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
|         <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
|         <activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty> | ||||
|         <activiti:formProperty id="validScript" type="javascript" default="alert('表单已经加载完毕');"></activiti:formProperty> | ||||
|       </extensionElements> | ||||
|     </startEvent> | ||||
|     <userTask id="deptLeaderAudit" name="部门领导审批" activiti:candidateGroups="deptLeader"> | ||||
|       <extensionElements> | ||||
|         <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="deptLeaderApproved" name="审批意见" type="enum" required="true"> | ||||
|           <activiti:value id="true" name="同意"></activiti:value> | ||||
|           <activiti:value id="false" name="拒绝"></activiti:value> | ||||
|         </activiti:formProperty> | ||||
|       </extensionElements> | ||||
|     </userTask> | ||||
|     <exclusiveGateway id="exclusivegateway5" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <userTask id="modifyApply" name="调整申请" activiti:assignee="${applyUserId}"> | ||||
|       <extensionElements> | ||||
|         <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
|         <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
|         <activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty> | ||||
|         <activiti:formProperty id="reApply" name="重新申请" type="enum" required="true"> | ||||
|           <activiti:value id="true" name="重新申请"></activiti:value> | ||||
|           <activiti:value id="false" name="取消申请"></activiti:value> | ||||
|         </activiti:formProperty> | ||||
|       </extensionElements> | ||||
|     </userTask> | ||||
|     <userTask id="hrAudit" name="人事审批" activiti:candidateGroups="hr"> | ||||
|       <extensionElements> | ||||
|         <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="hrApproved" name="审批意见" type="enum" required="true"> | ||||
|           <activiti:value id="true" name="同意"></activiti:value> | ||||
|           <activiti:value id="false" name="拒绝"></activiti:value> | ||||
|         </activiti:formProperty> | ||||
|       </extensionElements> | ||||
|     </userTask> | ||||
|     <exclusiveGateway id="exclusivegateway6" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <userTask id="reportBack" name="销假" activiti:assignee="${applyUserId}"> | ||||
|       <extensionElements> | ||||
|         <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty> | ||||
|         <activiti:formProperty id="reportBackDate" name="销假日期" type="date" default="${endDate}" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
|       </extensionElements> | ||||
|     </userTask> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <exclusiveGateway id="exclusivegateway7" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <sequenceFlow id="flow2" sourceRef="startevent1" targetRef="deptLeaderAudit"></sequenceFlow> | ||||
|     <sequenceFlow id="flow3" sourceRef="deptLeaderAudit" targetRef="exclusivegateway5"></sequenceFlow> | ||||
|     <sequenceFlow id="flow4" name="拒绝" sourceRef="exclusivegateway5" targetRef="modifyApply"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'false'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow5" name="同意" sourceRef="exclusivegateway5" targetRef="hrAudit"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow6" sourceRef="hrAudit" targetRef="exclusivegateway6"></sequenceFlow> | ||||
|     <sequenceFlow id="flow7" name="同意" sourceRef="exclusivegateway6" targetRef="reportBack"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow8" name="销假" sourceRef="reportBack" targetRef="endevent1"> | ||||
|       <extensionElements> | ||||
|         <activiti:executionListener event="take" expression="${execution.setVariable('result', 'ok')}"></activiti:executionListener> | ||||
|       </extensionElements> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow9" name="拒绝" sourceRef="exclusivegateway6" targetRef="modifyApply"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApproved == 'false'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow10" name="重新申请" sourceRef="exclusivegateway7" targetRef="deptLeaderAudit"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow11" sourceRef="modifyApply" targetRef="exclusivegateway7"></sequenceFlow> | ||||
|     <sequenceFlow id="flow12" name="结束流程" sourceRef="exclusivegateway7" targetRef="endevent1"> | ||||
|       <extensionElements> | ||||
|         <activiti:executionListener event="take" expression="${execution.setVariable('result', 'canceled')}"></activiti:executionListener> | ||||
|       </extensionElements> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'false'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <textAnnotation id="textannotation1" textFormat="text/plain"> | ||||
|       <text>请求被驳回后员工可以选择继续申请,或者取消本次申请</text> | ||||
|     </textAnnotation> | ||||
|     <association id="association1" sourceRef="modifyApply" targetRef="textannotation1"></association> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_leave"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="10.0" y="30.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="deptLeaderAudit" id="BPMNShape_deptLeaderAudit"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="90.0" y="20.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway5" id="BPMNShape_exclusivegateway5"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="250.0" y="27.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="modifyApply" id="BPMNShape_modifyApply"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="218.0" y="108.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="hrAudit" id="BPMNShape_hrAudit"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="358.0" y="20.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway6" id="BPMNShape_exclusivegateway6"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="495.0" y="27.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="reportBack" id="BPMNShape_reportBack"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="590.0" y="20.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="625.0" y="223.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway7" id="BPMNShape_exclusivegateway7"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="250.0" y="220.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="textannotation1" id="BPMNShape_textannotation1"> | ||||
|         <omgdc:Bounds height="57.0" width="120.0" x="361.0" y="174.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="45.0" y="47.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="90.0" y="47.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> | ||||
|         <omgdi:waypoint x="195.0" y="47.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="250.0" y="47.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> | ||||
|         <omgdi:waypoint x="270.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="270.0" y="108.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="22.0" x="280.0" y="67.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5"> | ||||
|         <omgdi:waypoint x="290.0" y="47.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="358.0" y="47.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="22.0" x="300.0" y="30.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"> | ||||
|         <omgdi:waypoint x="463.0" y="47.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="495.0" y="47.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7"> | ||||
|         <omgdi:waypoint x="535.0" y="47.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="590.0" y="47.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="22.0" x="544.0" y="30.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8"> | ||||
|         <omgdi:waypoint x="642.0" y="75.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="642.0" y="223.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="22.0" x="652.0" y="75.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9"> | ||||
|         <omgdi:waypoint x="515.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="514.0" y="135.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="323.0" y="135.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="22.0" x="525.0" y="67.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10"> | ||||
|         <omgdi:waypoint x="250.0" y="240.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="142.0" y="239.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="142.0" y="75.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="44.0" x="152.0" y="221.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11"> | ||||
|         <omgdi:waypoint x="270.0" y="163.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="270.0" y="220.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12"> | ||||
|         <omgdi:waypoint x="290.0" y="240.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="625.0" y="240.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="44.0" x="429.0" y="247.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="association1" id="BPMNEdge_association1"> | ||||
|         <omgdi:waypoint x="323.0" y="135.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="421.0" y="174.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 28 KiB | 
| @@ -0,0 +1,31 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">申请人:</label> | ||||
| 	<div class="controls">${applyUserId}</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${startDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="endDate">结束时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="endDate" name="endDate" value="${endDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">请假原因:</label> | ||||
| 	<div class="controls"> | ||||
| 		<textarea id="reason" name="reason" readonly>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="deptLeaderApproved">审批意见:</label> | ||||
| 	<div class="controls"> | ||||
| 		<select name="deptLeaderApproved" id="deptLeaderApproved"> | ||||
| 			<option value="true">同意</option> | ||||
| 			<option value="false">拒绝</option> | ||||
| 		</select> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,31 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">申请人:</label> | ||||
| 	<div class="controls">${applyUserId}</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${startDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="endDate">结束时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="endDate" name="endDate" value="${endDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">请假原因:</label> | ||||
| 	<div class="controls"> | ||||
| 		<textarea id="reason" name="reason" readonly>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="hrApproved">审批意见:</label> | ||||
| 	<div class="controls"> | ||||
| 		<select name="hrApproved" id="hrApproved"> | ||||
| 			<option value="true">同意</option> | ||||
| 			<option value="false">拒绝</option> | ||||
| 		</select> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,151 @@ | ||||
| <?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.kafeitu.me/activiti"> | ||||
|   <process id="leave-formkey" name="请假流程-外置表单" isExecutable="true"> | ||||
|     <documentation>《Activiti实战》第6章的例子--外置表单</documentation> | ||||
|     <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-deptLeader.form"></userTask> | ||||
|     <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <userTask id="hrVerify" name="人事经理审批" activiti:candidateGroups="hr" activiti:formKey="chapter6/leave-formkey/approve-hr.form"></userTask> | ||||
|     <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <userTask id="reportBack" name="销假" activiti:assignee="${applyUserId}" activiti:formKey="chapter6/leave-formkey/report-back.form"></userTask> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <userTask id="modifyApply" name="调整申请内容" activiti:assignee="${applyUserId}" activiti:formKey="chapter6/leave-formkey/modify-apply.form"></userTask> | ||||
|     <exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="deptLeaderVerify"></sequenceFlow> | ||||
|     <sequenceFlow id="flow2" sourceRef="deptLeaderVerify" targetRef="exclusivegateway1"></sequenceFlow> | ||||
|     <sequenceFlow id="flow3" name="同意" sourceRef="exclusivegateway1" targetRef="hrVerify"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow4" sourceRef="hrVerify" targetRef="exclusivegateway2"></sequenceFlow> | ||||
|     <sequenceFlow id="flow5" name="同意" sourceRef="exclusivegateway2" targetRef="reportBack"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow6" sourceRef="reportBack" targetRef="endevent1"> | ||||
|       <extensionElements> | ||||
|         <activiti:executionListener event="take" expression="${execution.setVariable('result', 'ok')}"></activiti:executionListener> | ||||
|       </extensionElements> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow7" name="不同意" sourceRef="exclusivegateway2" targetRef="modifyApply"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApproved == 'false'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow8" name="不同意" sourceRef="exclusivegateway1" targetRef="modifyApply"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow9" sourceRef="modifyApply" targetRef="exclusivegateway3"></sequenceFlow> | ||||
|     <sequenceFlow id="flow10" name="调整后继续申请" sourceRef="exclusivegateway3" targetRef="deptLeaderVerify"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow11" name="取消申请,并设置取消标志" sourceRef="exclusivegateway3" targetRef="endevent1"> | ||||
|       <extensionElements> | ||||
|         <activiti:executionListener event="take" expression="${execution.setVariable('result', 'canceled')}"></activiti:executionListener> | ||||
|       </extensionElements> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'false'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <textAnnotation id="textannotation1" textFormat="text/plain"> | ||||
|       <text>请求被驳回后员工可以选择继续申请,或者取消本次申请</text> | ||||
|     </textAnnotation> | ||||
|     <association id="association1" sourceRef="modifyApply" targetRef="textannotation1"></association> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_leave-formkey"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="leave-formkey" id="BPMNPlane_leave-formkey"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="10.0" y="50.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="deptLeaderVerify" id="BPMNShape_deptLeaderVerify"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="90.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="230.0" y="47.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="hrVerify" id="BPMNShape_hrVerify"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="310.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="470.0" y="47.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="reportBack" id="BPMNShape_reportBack"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="580.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="615.0" y="213.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="modifyApply" id="BPMNShape_modifyApply"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="198.0" y="120.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway3" id="BPMNShape_exclusivegateway3"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="230.0" y="210.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="textannotation1" id="BPMNShape_textannotation1"> | ||||
|         <omgdc:Bounds height="57.0" width="112.0" x="340.0" y="168.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="45.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="90.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="195.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="230.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> | ||||
|         <omgdi:waypoint x="270.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="310.0" y="67.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="22.0" x="269.0" y="50.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> | ||||
|         <omgdi:waypoint x="415.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="470.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5"> | ||||
|         <omgdi:waypoint x="510.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="580.0" y="67.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="22.0" x="529.0" y="50.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"> | ||||
|         <omgdi:waypoint x="632.0" y="95.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="632.0" y="213.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7"> | ||||
|         <omgdi:waypoint x="490.0" y="87.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="490.0" y="147.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="303.0" y="147.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="33.0" x="438.0" y="119.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8"> | ||||
|         <omgdi:waypoint x="250.0" y="87.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="250.0" y="120.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="33.0" x="260.0" y="87.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9"> | ||||
|         <omgdi:waypoint x="250.0" y="175.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="250.0" y="210.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10"> | ||||
|         <omgdi:waypoint x="230.0" y="230.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="142.0" y="230.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="142.0" y="95.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="11.0" width="77.0" x="159.0" y="210.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11"> | ||||
|         <omgdi:waypoint x="270.0" y="230.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="615.0" y="230.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="33.0" width="100.0" x="58.0" y="-37.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="association1" id="BPMNEdge_association1"> | ||||
|         <omgdi:waypoint x="303.0" y="147.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="396.0" y="168.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 27 KiB | 
										
											Binary file not shown.
										
									
								
							| @@ -0,0 +1,18 @@ | ||||
| <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> | ||||
| @@ -0,0 +1,27 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${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" value="${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>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">是否继续申请:</label> | ||||
| 	<div class="controls"> | ||||
| 		<select id="reApply" name="reApply"> | ||||
| 			<option value='true'>重新申请</option> | ||||
| 			<option value='false'>结束流程</option> | ||||
| 		</select> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,28 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">申请人:</label> | ||||
| 	<div class="controls">${applyUserId}</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${startDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="endDate">结束时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="endDate" name="endDate" value="${endDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">请假原因:</label> | ||||
| 	<div class="controls"> | ||||
| 		<textarea id="reason" name="reason" readonly>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reportBackDate">销假日期:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="reportBackDate" name="reportBackDate" class="datepicker" data-date-format="yyyy-mm-dd" required /> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,31 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">申请人:</label> | ||||
| 	<div class="controls">${applyUserId}</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${startDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="endDate">结束时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="endDate" name="endDate" value="${endDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">请假原因:</label> | ||||
| 	<div class="controls"> | ||||
| 		<textarea id="reason" name="reason" readonly>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="deptLeaderApproved">审批意见:</label> | ||||
| 	<div class="controls"> | ||||
| 		<select name="deptLeaderApproved" id="deptLeaderApproved"> | ||||
| 			<option value="true">同意</option> | ||||
| 			<option value="false">拒绝</option> | ||||
| 		</select> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,31 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">申请人:</label> | ||||
| 	<div class="controls">${applyUserId}</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${startDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="endDate">结束时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="endDate" name="endDate" value="${endDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">请假原因:</label> | ||||
| 	<div class="controls"> | ||||
| 		<textarea id="reason" name="reason" readonly>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="hrApproved">审批意见:</label> | ||||
| 	<div class="controls"> | ||||
| 		<select name="hrApproved" id="hrApproved"> | ||||
| 			<option value="true">同意</option> | ||||
| 			<option value="false">拒绝</option> | ||||
| 		</select> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,188 @@ | ||||
| <?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.kafeitu.me/activiti"> | ||||
|   <process id="conditionTest" name="请假流程-外置表单" isExecutable="true"> | ||||
|     <documentation>《Activiti实战》第6章的例子--外置表单</documentation> | ||||
|     <extensionElements> | ||||
|       <activiti:executionListener event="start" delegateExpression="${execution.setVariable('leave', leaveEntityManager.newLeave(execution))}"></activiti:executionListener> | ||||
|     </extensionElements> | ||||
|     <startEvent id="startevent1" name="Start" activiti:initiator="applyUserId" activiti:formKey="chapter6/leave-timeLimit-money/leave-start.form"></startEvent> | ||||
|     <userTask id="deptLeaderVerify" name="部门经理审批" activiti:candidateGroups="deptLeader" activiti:formKey="chapter6/leave-timeLimit-money/approve-deptLeader.form"> | ||||
|       <extensionElements> | ||||
|         <activiti:taskListener event="complete" expression="${leave.setDeptLeaderApproved(deptLeaderApproved)}"></activiti:taskListener> | ||||
|       </extensionElements> | ||||
|     </userTask> | ||||
|     <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <userTask id="hrVerify" name="人事经理审批" activiti:candidateGroups="hr" activiti:formKey="chapter6/leave-timeLimit-money/approve-hr.form"></userTask> | ||||
|     <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <userTask id="modifyApply" name="调整申请内容" activiti:assignee="${applyUserId}" activiti:formKey="chapter6/leave-timeLimit-money/modify-apply.form"></userTask> | ||||
|     <exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="deptLeaderVerify"></sequenceFlow> | ||||
|     <sequenceFlow id="flow2" sourceRef="deptLeaderVerify" targetRef="exclusivegateway1"></sequenceFlow> | ||||
|     <sequenceFlow id="flow3" name="同意" sourceRef="exclusivegateway1" targetRef="hrVerify"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow4" sourceRef="hrVerify" targetRef="exclusivegateway2"></sequenceFlow> | ||||
|     <sequenceFlow id="flow7" name="不同意" sourceRef="exclusivegateway2" targetRef="modifyApply"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApproved == 'false'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow8" name="不同意" sourceRef="exclusivegateway1" targetRef="modifyApply"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow9" sourceRef="modifyApply" targetRef="exclusivegateway3"></sequenceFlow> | ||||
|     <sequenceFlow id="flow10" name="调整后继续申请" sourceRef="exclusivegateway3" targetRef="deptLeaderVerify"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <sequenceFlow id="flow11" name="取消申请,并设置取消标志" sourceRef="exclusivegateway3" targetRef="endevent1"> | ||||
|       <extensionElements> | ||||
|         <activiti:executionListener event="take" expression="${execution.setVariable('result', 'canceled')}"></activiti:executionListener> | ||||
|       </extensionElements> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'false'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <exclusiveGateway id="exclusivegateway4" name="Exclusive Gateway"></exclusiveGateway> | ||||
|     <sequenceFlow id="flow12" name="同意" sourceRef="exclusivegateway2" targetRef="exclusivegateway4"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApproved == 'true'}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <userTask id="usertask1" name="财务打款" activiti:candidateGroups="caiwu" activiti:dueDate="${moneyDateVariable}"> | ||||
|       <documentation>倒计时30秒</documentation> | ||||
|     </userTask> | ||||
|     <sequenceFlow id="flow13" name="金额 >= 1万元" sourceRef="exclusivegateway4" targetRef="usertask1"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${amountMoney >= 10000}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <userTask id="usertask2" name="金额不够重新付款"></userTask> | ||||
|     <sequenceFlow id="flow14" name="金额 < 1万" sourceRef="exclusivegateway4" targetRef="usertask2"> | ||||
|       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${amountMoney < 10000}]]></conditionExpression> | ||||
|     </sequenceFlow> | ||||
|     <userTask id="usertask3" name="打款完成" activiti:candidateGroups="chuNa"></userTask> | ||||
|     <sequenceFlow id="flow15" sourceRef="usertask1" targetRef="usertask3"></sequenceFlow> | ||||
|     <textAnnotation id="textannotation1" textFormat="text/plain"> | ||||
|       <text>请求被驳回后员工可以选择继续申请,或者取消本次申请</text> | ||||
|     </textAnnotation> | ||||
|     <association id="association1" sourceRef="modifyApply" targetRef="textannotation1"></association> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_conditionTest"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="conditionTest" id="BPMNPlane_conditionTest"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="10.0" y="50.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="deptLeaderVerify" id="BPMNShape_deptLeaderVerify"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="90.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="230.0" y="47.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="hrVerify" id="BPMNShape_hrVerify"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="310.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="470.0" y="47.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="615.0" y="213.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="modifyApply" id="BPMNShape_modifyApply"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="198.0" y="120.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway3" id="BPMNShape_exclusivegateway3"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="230.0" y="210.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="exclusivegateway4" id="BPMNShape_exclusivegateway4"> | ||||
|         <omgdc:Bounds height="40.0" width="40.0" x="600.0" y="47.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="760.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="568.0" y="140.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="910.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="textannotation1" id="BPMNShape_textannotation1"> | ||||
|         <omgdc:Bounds height="57.0" width="112.0" x="340.0" y="168.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="45.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="90.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="195.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="230.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> | ||||
|         <omgdi:waypoint x="270.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="310.0" y="67.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="42.0" width="22.0" x="269.0" y="50.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> | ||||
|         <omgdi:waypoint x="415.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="470.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7"> | ||||
|         <omgdi:waypoint x="490.0" y="87.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="490.0" y="147.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="303.0" y="147.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="42.0" width="33.0" x="438.0" y="119.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8"> | ||||
|         <omgdi:waypoint x="250.0" y="87.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="250.0" y="120.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="42.0" width="33.0" x="260.0" y="87.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9"> | ||||
|         <omgdi:waypoint x="250.0" y="175.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="250.0" y="210.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10"> | ||||
|         <omgdi:waypoint x="230.0" y="230.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="142.0" y="230.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="142.0" y="95.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="42.0" width="77.0" x="159.0" y="210.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11"> | ||||
|         <omgdi:waypoint x="270.0" y="230.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="615.0" y="230.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="42.0" width="100.0" x="58.0" y="-37.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12"> | ||||
|         <omgdi:waypoint x="510.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="600.0" y="67.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="14.0" width="24.0" x="510.0" y="67.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13"> | ||||
|         <omgdi:waypoint x="640.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="760.0" y="67.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="14.0" width="72.0" x="640.0" y="67.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14"> | ||||
|         <omgdi:waypoint x="620.0" y="87.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="620.0" y="140.0"></omgdi:waypoint> | ||||
|         <bpmndi:BPMNLabel> | ||||
|           <omgdc:Bounds height="14.0" width="54.0" x="620.0" y="87.0"></omgdc:Bounds> | ||||
|         </bpmndi:BPMNLabel> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15"> | ||||
|         <omgdi:waypoint x="865.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="910.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="association1" id="BPMNEdge_association1"> | ||||
|         <omgdi:waypoint x="303.0" y="147.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="396.0" y="168.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 17 KiB | 
| @@ -0,0 +1,18 @@ | ||||
| <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> | ||||
| @@ -0,0 +1,27 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${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" value="${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>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">是否继续申请:</label> | ||||
| 	<div class="controls"> | ||||
| 		<select id="reApply" name="reApply"> | ||||
| 			<option value='true'>重新申请</option> | ||||
| 			<option value='false'>结束流程</option> | ||||
| 		</select> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,28 @@ | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">申请人:</label> | ||||
| 	<div class="controls">${applyUserId}</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="startDate">开始时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="startDate" name="startDate" value="${startDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="endDate">结束时间:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="endDate" name="endDate" value="${endDate}" readonly /> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reason">请假原因:</label> | ||||
| 	<div class="controls"> | ||||
| 		<textarea id="reason" name="reason" readonly>${reason}</textarea> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="control-group"> | ||||
| 	<label class="control-label" for="reportBackDate">销假日期:</label> | ||||
| 	<div class="controls"> | ||||
| 		<input type="text" id="reportBackDate" name="reportBackDate" class="datepicker" data-date-format="yyyy-mm-dd" required /> | ||||
| 	</div> | ||||
| </div> | ||||
| @@ -0,0 +1,152 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
| 	<process id="leave-countersign" name="请假流程-会签" isExecutable="true"> | ||||
| 		<documentation>请假流程演示-会签</documentation> | ||||
| 		<startEvent id="startevent1" name="Start" activiti:initiator="applyUserId"> | ||||
| 			<extensionElements> | ||||
| 				<activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="users" name="审批参与人" type="users" required="true"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="validScript" type="javascript" default="alert('表单已经加载完毕');"></activiti:formProperty> | ||||
| 			</extensionElements> | ||||
| 		</startEvent> | ||||
| 		<userTask id="countersign" name="[部门/人事]联合会签" activiti:assignee="${user}"> | ||||
| 			<extensionElements> | ||||
| 				<activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="approved" name="审批意见" type="enum" required="true"> | ||||
| 					<activiti:value id="true" name="同意"></activiti:value> | ||||
| 					<activiti:value id="false" name="拒绝"></activiti:value> | ||||
| 				</activiti:formProperty> | ||||
| 				<activiti:taskListener event="complete" delegateExpression="${leaveCounterSignCompleteListener}"></activiti:taskListener> | ||||
| 			</extensionElements> | ||||
| 			<multiInstanceLoopCharacteristics isSequential="false" activiti:collection="users" | ||||
| 				activiti:elementVariable="user"></multiInstanceLoopCharacteristics> | ||||
| 		</userTask> | ||||
| 		<userTask id="reportBack" name="销假" activiti:assignee="${applyUserId}"> | ||||
| 			<extensionElements> | ||||
| 				<activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="reportBackDate" name="销假日期" type="date" default="${endDate}" datePattern="yyyy-MM-dd" | ||||
| 					required="true"></activiti:formProperty> | ||||
| 			</extensionElements> | ||||
| 		</userTask> | ||||
| 		<endEvent id="endevent1" name="End"></endEvent> | ||||
| 		<sequenceFlow id="flow2" sourceRef="startevent1" targetRef="countersign"> | ||||
| 			<extensionElements> | ||||
| 				<activiti:executionListener event="take" expression="${execution.setVariable('approvedCounter', 0)}"></activiti:executionListener> | ||||
| 			</extensionElements> | ||||
| 		</sequenceFlow> | ||||
| 		<sequenceFlow id="flow8" name="销假" sourceRef="reportBack" targetRef="endevent1"> | ||||
| 			<extensionElements> | ||||
| 				<activiti:executionListener event="take" expression="${execution.setVariable('result', 'ok')}"></activiti:executionListener> | ||||
| 			</extensionElements> | ||||
| 		</sequenceFlow> | ||||
| 		<sequenceFlow id="flow13" name="全部通过" sourceRef="exclusivegateway1" targetRef="reportBack"> | ||||
| 			<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvedCounter == users.size()}]]></conditionExpression> | ||||
| 		</sequenceFlow> | ||||
| 		<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway> | ||||
| 		<sequenceFlow id="flow14" sourceRef="countersign" targetRef="exclusivegateway1"></sequenceFlow> | ||||
| 		<userTask id="modifyApply" name="调整申请" activiti:assignee="${applyUserId}"> | ||||
| 			<extensionElements> | ||||
| 				<activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty> | ||||
| 				<activiti:formProperty id="reApply" name="重新申请" type="enum" required="true"> | ||||
| 					<activiti:value id="true" name="重新申请"></activiti:value> | ||||
| 					<activiti:value id="false" name="取消申请"></activiti:value> | ||||
| 				</activiti:formProperty> | ||||
| 			</extensionElements> | ||||
| 		</userTask> | ||||
| 		<sequenceFlow id="flow15" name="部分通过" sourceRef="exclusivegateway1" targetRef="modifyApply"> | ||||
| 			<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvedCounter < users.size()}]]></conditionExpression> | ||||
| 		</sequenceFlow> | ||||
| 		<exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway> | ||||
| 		<sequenceFlow id="flow16" sourceRef="modifyApply" targetRef="exclusivegateway2"></sequenceFlow> | ||||
| 		<sequenceFlow id="flow17" sourceRef="exclusivegateway2" targetRef="endevent1"> | ||||
| 			<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'false'}]]></conditionExpression> | ||||
| 		</sequenceFlow> | ||||
| 		<sequenceFlow id="flow18" name="重新申请" sourceRef="exclusivegateway2" targetRef="countersign"> | ||||
| 			<extensionElements> | ||||
| 				<activiti:executionListener event="take" expression="${execution.setVariable('approvedCounter', 0)}"></activiti:executionListener> | ||||
| 			</extensionElements> | ||||
| 			<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'true'}]]></conditionExpression> | ||||
| 		</sequenceFlow> | ||||
| 	</process> | ||||
| 	<bpmndi:BPMNDiagram id="BPMNDiagram_leave-countersign"> | ||||
| 		<bpmndi:BPMNPlane bpmnElement="leave-countersign" id="BPMNPlane_leave-countersign"> | ||||
| 			<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
| 				<omgdc:Bounds height="35.0" width="35.0" x="10.0" y="30.0"></omgdc:Bounds> | ||||
| 			</bpmndi:BPMNShape> | ||||
| 			<bpmndi:BPMNShape bpmnElement="reportBack" id="BPMNShape_reportBack"> | ||||
| 				<omgdc:Bounds height="55.0" width="105.0" x="340.0" y="20.0"></omgdc:Bounds> | ||||
| 			</bpmndi:BPMNShape> | ||||
| 			<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
| 				<omgdc:Bounds height="35.0" width="35.0" x="375.0" y="203.0"></omgdc:Bounds> | ||||
| 			</bpmndi:BPMNShape> | ||||
| 			<bpmndi:BPMNShape bpmnElement="countersign" id="BPMNShape_countersign"> | ||||
| 				<omgdc:Bounds height="55.0" width="105.0" x="90.0" y="20.0"></omgdc:Bounds> | ||||
| 			</bpmndi:BPMNShape> | ||||
| 			<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1"> | ||||
| 				<omgdc:Bounds height="40.0" width="40.0" x="220.0" y="27.0"></omgdc:Bounds> | ||||
| 			</bpmndi:BPMNShape> | ||||
| 			<bpmndi:BPMNShape bpmnElement="modifyApply" id="BPMNShape_modifyApply"> | ||||
| 				<omgdc:Bounds height="55.0" width="105.0" x="188.0" y="110.0"></omgdc:Bounds> | ||||
| 			</bpmndi:BPMNShape> | ||||
| 			<bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2"> | ||||
| 				<omgdc:Bounds height="40.0" width="40.0" x="220.0" y="200.0"></omgdc:Bounds> | ||||
| 			</bpmndi:BPMNShape> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
| 				<omgdi:waypoint x="45.0" y="47.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="90.0" y="47.0"></omgdi:waypoint> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8"> | ||||
| 				<omgdi:waypoint x="392.0" y="75.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="392.0" y="203.0"></omgdi:waypoint> | ||||
| 				<bpmndi:BPMNLabel> | ||||
| 					<omgdc:Bounds height="11.0" width="100.0" x="-22.0" y="-17.0"></omgdc:Bounds> | ||||
| 				</bpmndi:BPMNLabel> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13"> | ||||
| 				<omgdi:waypoint x="260.0" y="47.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="340.0" y="47.0"></omgdi:waypoint> | ||||
| 				<bpmndi:BPMNLabel> | ||||
| 					<omgdc:Bounds height="11.0" width="100.0" x="-29.0" y="-17.0"></omgdc:Bounds> | ||||
| 				</bpmndi:BPMNLabel> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14"> | ||||
| 				<omgdi:waypoint x="195.0" y="47.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="220.0" y="47.0"></omgdi:waypoint> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15"> | ||||
| 				<omgdi:waypoint x="240.0" y="67.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="240.0" y="110.0"></omgdi:waypoint> | ||||
| 				<bpmndi:BPMNLabel> | ||||
| 					<omgdc:Bounds height="11.0" width="100.0" x="10.0" y="0.0"></omgdc:Bounds> | ||||
| 				</bpmndi:BPMNLabel> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16"> | ||||
| 				<omgdi:waypoint x="240.0" y="165.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="240.0" y="200.0"></omgdi:waypoint> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17"> | ||||
| 				<omgdi:waypoint x="260.0" y="220.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="375.0" y="220.0"></omgdi:waypoint> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 			<bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18"> | ||||
| 				<omgdi:waypoint x="220.0" y="220.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="142.0" y="220.0"></omgdi:waypoint> | ||||
| 				<omgdi:waypoint x="142.0" y="75.0"></omgdi:waypoint> | ||||
| 				<bpmndi:BPMNLabel> | ||||
| 					<omgdc:Bounds height="11.0" width="100.0" x="9.0" y="14.0"></omgdc:Bounds> | ||||
| 				</bpmndi:BPMNLabel> | ||||
| 			</bpmndi:BPMNEdge> | ||||
| 		</bpmndi:BPMNPlane> | ||||
| 	</bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 20 KiB | 
| @@ -0,0 +1,44 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
|   <process id="testMultiInstanceFixedNumbers" name="testMultiInstanceFixedNumbers" isExecutable="true"> | ||||
|     <startEvent id="startevent1" name="Start"></startEvent> | ||||
|     <serviceTask id="servicetask1" name="Service Task" activiti:expression="${counter + 1}" activiti:resultVariableName="counter"> | ||||
|       <multiInstanceLoopCharacteristics isSequential="false"> | ||||
|         <loopCardinality>${loop}</loopCardinality> | ||||
|       </multiInstanceLoopCharacteristics> | ||||
|     </serviceTask> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <sequenceFlow id="flow2" sourceRef="receivetask1" targetRef="endevent1"></sequenceFlow> | ||||
|     <receiveTask id="receivetask1" name="Receive Task"></receiveTask> | ||||
|     <sequenceFlow id="flow3" sourceRef="servicetask1" targetRef="receivetask1"></sequenceFlow> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceFixedNumbers"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="testMultiInstanceFixedNumbers" id="BPMNPlane_testMultiInstanceFixedNumbers"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="50.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="116.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="410.0" y="50.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="receivetask1" id="BPMNShape_receivetask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="260.0" y="40.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="85.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="116.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="365.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="410.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> | ||||
|         <omgdi:waypoint x="221.0" y="67.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="260.0" y="67.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
| @@ -0,0 +1,42 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
|   <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true"> | ||||
|     <startEvent id="startevent1" name="Start"></startEvent> | ||||
|     <userTask id="usertask1" name="User Task" activiti:assignee="${user}"> | ||||
|       <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user"></multiInstanceLoopCharacteristics> | ||||
|     </userTask> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <sequenceFlow id="flow2" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow> | ||||
|     <userTask id="usertask2" name="User Task2"></userTask> | ||||
|     <sequenceFlow id="flow3" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="70.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="340.0" y="190.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="180.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="125.0" y="97.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="170.0" y="97.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="275.0" y="207.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="340.0" y="207.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> | ||||
|         <omgdi:waypoint x="222.0" y="125.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="222.0" y="180.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 12 KiB | 
| @@ -0,0 +1,35 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
|   <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true"> | ||||
|     <startEvent id="startevent1" name="Start"></startEvent> | ||||
|     <userTask id="usertask1" name="User Task"> | ||||
|       <multiInstanceLoopCharacteristics isSequential="false"> | ||||
|         <loopCardinality>3</loopCardinality> | ||||
|       </multiInstanceLoopCharacteristics> | ||||
|     </userTask> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="70.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="330.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="125.0" y="97.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="170.0" y="97.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="275.0" y="97.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="330.0" y="97.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
| @@ -0,0 +1,35 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
|   <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true"> | ||||
|     <startEvent id="startevent1" name="Start"></startEvent> | ||||
|     <userTask id="usertask1" name="User Task"> | ||||
|       <multiInstanceLoopCharacteristics isSequential="true"> | ||||
|         <loopCardinality>3</loopCardinality> | ||||
|       </multiInstanceLoopCharacteristics> | ||||
|     </userTask> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="70.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="330.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="125.0" y="97.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="170.0" y="97.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="275.0" y="97.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="330.0" y="97.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
| @@ -0,0 +1,33 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
|   <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true"> | ||||
|     <startEvent id="startevent1" name="Start"></startEvent> | ||||
|     <userTask id="usertask1" name="User Task" activiti:assignee="${user}"> | ||||
|       <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user"></multiInstanceLoopCharacteristics> | ||||
|     </userTask> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="90.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="130.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="290.0" y="90.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="85.0" y="107.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="130.0" y="107.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="235.0" y="107.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="290.0" y="107.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
| @@ -0,0 +1,33 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
|   <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true"> | ||||
|     <startEvent id="startevent1" name="Start"></startEvent> | ||||
|     <userTask id="usertask1" name="User Task" activiti:assignee="${user}"> | ||||
|       <multiInstanceLoopCharacteristics isSequential="true" activiti:collection="${users}" activiti:elementVariable="user"></multiInstanceLoopCharacteristics> | ||||
|     </userTask> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="90.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="130.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="290.0" y="90.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="85.0" y="107.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="130.0" y="107.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="235.0" y="107.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="290.0" y="107.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
| @@ -0,0 +1,35 @@ | ||||
| <?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: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.activiti.org/test"> | ||||
|   <process id="testMultiInstanceForUserTask" name="testMultiInstanceForUserTask" isExecutable="true"> | ||||
|     <startEvent id="startevent1" name="Start"></startEvent> | ||||
|     <userTask id="usertask1" name="User Task" activiti:assignee="${user}"> | ||||
|       <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user"> | ||||
|         <completionCondition>${nrOfCompletedInstances / nrOfInstances >= rate}</completionCondition> | ||||
|       </multiInstanceLoopCharacteristics> | ||||
|     </userTask> | ||||
|     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> | ||||
|     <endEvent id="endevent1" name="End"></endEvent> | ||||
|     <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> | ||||
|   </process> | ||||
|   <bpmndi:BPMNDiagram id="BPMNDiagram_testMultiInstanceForUserTask"> | ||||
|     <bpmndi:BPMNPlane bpmnElement="testMultiInstanceForUserTask" id="BPMNPlane_testMultiInstanceForUserTask"> | ||||
|       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="90.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> | ||||
|         <omgdc:Bounds height="55.0" width="105.0" x="130.0" y="80.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> | ||||
|         <omgdc:Bounds height="35.0" width="35.0" x="290.0" y="90.0"></omgdc:Bounds> | ||||
|       </bpmndi:BPMNShape> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> | ||||
|         <omgdi:waypoint x="85.0" y="107.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="130.0" y="107.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> | ||||
|         <omgdi:waypoint x="235.0" y="107.0"></omgdi:waypoint> | ||||
|         <omgdi:waypoint x="290.0" y="107.0"></omgdi:waypoint> | ||||
|       </bpmndi:BPMNEdge> | ||||
|     </bpmndi:BPMNPlane> | ||||
|   </bpmndi:BPMNDiagram> | ||||
| </definitions> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 7.8 KiB | 
| @@ -0,0 +1,21 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://www.springframework.org/schema/beans | ||||
| 				http://www.springframework.org/schema/beans/spring-beans.xsd"> | ||||
|  | ||||
| 	<bean id="processEngineConfiguration" class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration"> | ||||
| 		<!--保存到文件模式--> | ||||
| 		<!--<property name="jdbcUrl" value="jdbc:h2:file:~/activiti-in-action-chapter6;AUTO_SERVER=TRUE" />--> | ||||
| 		<!--内存模式--> | ||||
| 		<property name="jdbcUrl" value="jdbc:h2:mem:activiti-in-action-chapter6;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" /> | ||||
| 		<property name="jdbcDriver" value="org.h2.Driver" /> | ||||
| 		<property name="jdbcUsername" value="sa" /> | ||||
| 		<property name="jdbcPassword" value="" /> | ||||
|  | ||||
| 		<!--HistoryLevel--> | ||||
| 		<property name="history" value="full" /> | ||||
| 		<property name="databaseSchemaUpdate" value="true" /> | ||||
| 		<property name="flowable5CompatibilityEnabled" value="false" /> | ||||
| <!--		<property name="jobExecutorActivate" value="false" />--> | ||||
| 	</bean> | ||||
| </beans> | ||||
		Reference in New Issue
	
	Block a user
	 cuicui20210817
					cuicui20210817