update 流程图,会签
This commit is contained in:
@@ -30,16 +30,9 @@
|
|||||||
<artifactId>laws-base-generater</artifactId>
|
<artifactId>laws-base-generater</artifactId>
|
||||||
<version>${jero.version}</version>
|
<version>${jero.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.activiti.dependencies/activiti-dependencies -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.activiti.dependencies</groupId>
|
|
||||||
<artifactId>activiti-dependencies</artifactId>
|
|
||||||
<version>${activiti.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.activiti</groupId>
|
<groupId>org.activiti</groupId>
|
||||||
<artifactId>activiti-spring-boot-starter</artifactId>
|
<artifactId>activiti-spring-boot-starter-rest-api</artifactId>
|
||||||
<version>${activiti.version}</version>
|
<version>${activiti.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.jero.modules.activiti.config;
|
||||||
|
|
||||||
|
import com.jero.modules.activiti.service.impl.image.ICustomProcessDiagramGenerator;
|
||||||
|
import org.activiti.engine.impl.form.DoubleFormType;
|
||||||
|
import org.activiti.spring.SpringProcessEngineConfiguration;
|
||||||
|
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liJiaRao
|
||||||
|
* @date 2023-09-05 17:53
|
||||||
|
*/
|
||||||
|
public class ActivitiConfig implements ProcessEngineConfigurationConfigurer {
|
||||||
|
@Autowired
|
||||||
|
private ICustomProcessDiagramGenerator customProcessDiagramGenerator;
|
||||||
|
@Autowired
|
||||||
|
private DoubleFormType doubleFormType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解決工作流生成图片乱码问题
|
||||||
|
*
|
||||||
|
* @param processEngineConfiguration
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
|
||||||
|
int[] result = {};
|
||||||
|
processEngineConfiguration.setActivityFontName("宋体");
|
||||||
|
processEngineConfiguration.setAnnotationFontName("宋体");
|
||||||
|
processEngineConfiguration.setLabelFontName("宋体");
|
||||||
|
processEngineConfiguration.setProcessDiagramGenerator(customProcessDiagramGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
-2097
File diff suppressed because it is too large
Load Diff
-1604
File diff suppressed because it is too large
Load Diff
+29
@@ -0,0 +1,29 @@
|
|||||||
|
package com.jero.modules.activiti.config;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.activiti.bpmn.model.FlowElement;
|
||||||
|
import org.activiti.bpmn.model.UserTask;
|
||||||
|
import org.activiti.engine.delegate.DelegateExecution;
|
||||||
|
import org.activiti.engine.delegate.DelegateTask;
|
||||||
|
import org.activiti.engine.delegate.ExecutionListener;
|
||||||
|
import org.activiti.engine.delegate.TaskListener;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liJiaRao
|
||||||
|
* @date 2023-09-05 14:54
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class MultiInstanceTaskHandler implements TaskListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(DelegateTask delegateTask) {
|
||||||
|
DelegateExecution execution = delegateTask.getExecution();
|
||||||
|
System.out.println("流程实例总数:" + execution.getVariable("nrOfInstances"));
|
||||||
|
System.out.println("当前活动的流程实例总数:" + execution.getVariable("nrOfActiveInstances"));
|
||||||
|
System.out.println("已经完成实例的数目:" + execution.getVariable("nrOfCompletedInstances"));
|
||||||
|
System.out.println("leader:" + execution.getVariable("leader"));
|
||||||
|
System.out.println("---------------------------------------分隔线----------------------------------------------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.jero.modules.activiti.config;
|
||||||
|
|
||||||
|
import org.activiti.engine.impl.cfg.IdGenerator;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liJiaRao
|
||||||
|
* @date 2023-09-05 17:39
|
||||||
|
*/
|
||||||
|
public class MyGen implements IdGenerator {
|
||||||
|
private AtomicLong aLong = new AtomicLong(100);
|
||||||
|
@Override
|
||||||
|
public synchronized String getNextId() {
|
||||||
|
return String.valueOf(aLong.incrementAndGet());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package com.jero.modules.activiti.config;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常量类
|
||||||
|
*@author jjd
|
||||||
|
**/
|
||||||
|
public final class WorkflowConstants {
|
||||||
|
|
||||||
|
/**businessKey**/
|
||||||
|
public static final String WORKLOW_BUSINESS_KEY = "businessKey";
|
||||||
|
/**按钮网关**/
|
||||||
|
public static final String WAY_TYPE = "wayType";
|
||||||
|
/**按钮网关**/
|
||||||
|
public static final String WAY_TYPE_PREFIX = "way_type_";
|
||||||
|
/**项目id**/
|
||||||
|
public static final String PROJECT_ID = "projectId";
|
||||||
|
/**核心企业Id变量**/
|
||||||
|
public static final String CORE_ENTERPRISE_ID="coreEnterpriseId";
|
||||||
|
/**链属企业Id变量**/
|
||||||
|
public static final String CHAIN_ENTERPRISE_ID="chainEnterpriseId";
|
||||||
|
/**银行企业Id变量**/
|
||||||
|
public static final String BANK_ENTERPRISE_ID="bankEnterpriseId";
|
||||||
|
/**保理公司Id变量**/
|
||||||
|
public static final String BAOLI_ENTERPRISE_ID="baoliEnterpriseId";
|
||||||
|
/**立账开立企业Id变量**/
|
||||||
|
public static final String START_ENTERPRISE_ID="startEnterpriseId";
|
||||||
|
/**立账合作企业Id变量**/
|
||||||
|
public static final String PARTNER_ENTERPRISE_ID="partnerEnterpriseId";
|
||||||
|
/**母公司企业id**/
|
||||||
|
public static final String PARENT_ENTERPRISE_ID="parentEnterpriseId";
|
||||||
|
/**指定签收企业id**/
|
||||||
|
public static final String RECEIVE_ENTERPRISE_ID ="receiveEnterpriseId";
|
||||||
|
/**转出方企业Id变量**/
|
||||||
|
public static final String TRANSFER_ENTERPRISE_ID="transEnterpriseId";
|
||||||
|
/**指定签收企业id**/
|
||||||
|
public static final String AC_TASK_ID ="acTaskId";
|
||||||
|
/**企业所有角色**/
|
||||||
|
public static final String ENT_ALL_ROLE ="all";
|
||||||
|
/**运营所有角色**/
|
||||||
|
public static final String OPER_ALL_ROLE ="oper";
|
||||||
|
/**流程定义缓存时间**/
|
||||||
|
public static final int PROCESS_DEFINITION_CACHE = 60;
|
||||||
|
/**流程实例激活**/
|
||||||
|
public static final int PROCESS_INSTANCE_ACTIVE = 1;
|
||||||
|
|
||||||
|
/**流程实例挂起**/
|
||||||
|
public static final int PROCESS_INSTANCE_SUSPEND = 0;
|
||||||
|
|
||||||
|
/**读取图片**/
|
||||||
|
public static final String READ_IMAGE = "image";
|
||||||
|
|
||||||
|
/**读取xml**/
|
||||||
|
public static final String READ_XML = "xml";
|
||||||
|
|
||||||
|
/**流程激活**/
|
||||||
|
public static final Integer ACTIVE_PROCESSDEFINITION = 1;
|
||||||
|
|
||||||
|
/**流程挂起**/
|
||||||
|
public static final Integer SUSPEND_PROCESSDEFINITION = 2;
|
||||||
|
|
||||||
|
/**流程状态:0-全部,1-正常,2-已挂起**/
|
||||||
|
public static final int QUERY_ALL = 0;
|
||||||
|
public static final int QUERY_NORMAL = 1;
|
||||||
|
public static final int QUERY_SUSPENDED = 2;
|
||||||
|
|
||||||
|
/**流程实例状态:0-全部,1-正常,2-已删除**/
|
||||||
|
public static final int INSTANCE_ALL = 0;
|
||||||
|
public static final int INSTANCE_NOT_DELETED = 1;
|
||||||
|
public static final int INSTANCE_DELETED = 2;
|
||||||
|
|
||||||
|
/** 系统管理员ID **/
|
||||||
|
public static final String INTERFACE_SYSTEM_ID = "-1";
|
||||||
|
/** 系统管理员名称 **/
|
||||||
|
public static final String INTERFACE_SYSTEM_NAME = "系统操作";
|
||||||
|
|
||||||
|
/** 流程部署类型:1-启动并激活,2-启动即挂起 **/
|
||||||
|
public static final int PROCESS_START_ACTIVE = 1;
|
||||||
|
public static final int PROCESS_START_SUSPEND = 2;
|
||||||
|
|
||||||
|
/** 用于标识流程项目配置信息校验结果:1:新流程,2:新版本, 3:流程类别有误 **/
|
||||||
|
public static final int CHECK_NEW_PROCESS = 1;
|
||||||
|
public static final int CHECK_NEW_VERSION = 2;
|
||||||
|
public static final int CHECK_ERROR_PROCESS_TYPE = 3;
|
||||||
|
|
||||||
|
/** 默认网关条件值 **/
|
||||||
|
public static final Integer default_GATEWAY_CONDITION_VALUE = 1;
|
||||||
|
|
||||||
|
/** 工作流-业务状态表数据类型:1-工作流状态,2-业务状态 **/
|
||||||
|
public static final Integer PROCESS_STATUS = 1;
|
||||||
|
public static final Integer BIZNESS_STATUS = 2;
|
||||||
|
|
||||||
|
/** 新增流程时标识:1-直接保存,2-提示覆盖 **/
|
||||||
|
public static final Integer PROCESS_STATUS_SAVE = 1;
|
||||||
|
public static final Integer BIZNESS_STATUS_WARN = 2;
|
||||||
|
|
||||||
|
/** 模板类型标识:1-新创建或直接导入的模板,2-默认模板生成 **/
|
||||||
|
public static final Integer MODEL_TYPE_1 = 1;
|
||||||
|
public static final Integer MODEL_TYPE_2 = 2;
|
||||||
|
|
||||||
|
/** 查询流程定义标识:1-查询最新版本流程定义,2-查询所有版本 **/
|
||||||
|
public static final Integer QUERY_PROCESS_LATEST_VERSION = 1;
|
||||||
|
public static final Integer QUERY_PROCESS_ALL_VERSION = 2;
|
||||||
|
|
||||||
|
/** 按钮网关 通过1 */
|
||||||
|
public static final String WAY_TYPE_PASS = "1";
|
||||||
|
/** 按钮网关 驳回或结束0 */
|
||||||
|
public static final String WAY_TYPE_REJECT = "0";
|
||||||
|
|
||||||
|
/** 按钮网关 退回2 */
|
||||||
|
public static final String WAY_TYPE_BACK = "2";
|
||||||
|
|
||||||
|
/**任务参数为空**/
|
||||||
|
public static final int TASK_CHECK_PARAM_NULL = -1;
|
||||||
|
/**任务已办理**/
|
||||||
|
public static final int TASK_CHECK_COMPLETED = 1;
|
||||||
|
/**无权限办理**/
|
||||||
|
public static final int TASK_CHECK_NO_PERMISSIONS= 2;
|
||||||
|
/**任务校验通过**/
|
||||||
|
public static final int TASK_CHECK_PASS = 0;
|
||||||
|
/** 动态流程图颜色定义 **/
|
||||||
|
public static final Color COLOR_NORMAL = new Color(0, 205, 0);
|
||||||
|
public static final Color COLOR_CURRENT = new Color(255, 0, 0);
|
||||||
|
|
||||||
|
/** 定义生成流程图时的边距(像素) **/
|
||||||
|
public static final int PROCESS_PADDING = 5;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,7 +10,10 @@ import io.swagger.annotations.ApiParam;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.activiti.bpmn.converter.BpmnXMLConverter;
|
import org.activiti.bpmn.converter.BpmnXMLConverter;
|
||||||
import org.activiti.bpmn.model.BpmnModel;
|
import org.activiti.bpmn.model.BpmnModel;
|
||||||
|
import org.activiti.bpmn.model.FlowElement;
|
||||||
|
import org.activiti.bpmn.model.UserTask;
|
||||||
import org.activiti.engine.*;
|
import org.activiti.engine.*;
|
||||||
|
import org.activiti.engine.delegate.DelegateExecution;
|
||||||
import org.activiti.engine.repository.Deployment;
|
import org.activiti.engine.repository.Deployment;
|
||||||
import org.activiti.engine.repository.ProcessDefinition;
|
import org.activiti.engine.repository.ProcessDefinition;
|
||||||
import org.activiti.engine.repository.ProcessDefinitionQuery;
|
import org.activiti.engine.repository.ProcessDefinitionQuery;
|
||||||
@@ -21,12 +24,15 @@ import org.apache.commons.io.IOUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.i18n.LocaleContextHolder;
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
@@ -48,18 +54,28 @@ public class AController {
|
|||||||
|
|
||||||
@GetMapping("/deploy")
|
@GetMapping("/deploy")
|
||||||
public Result<Map<String, String>> deploy(@RequestParam(value = "name", required = false) String name,
|
public Result<Map<String, String>> deploy(@RequestParam(value = "name", required = false) String name,
|
||||||
@RequestParam(value = "classpathResource") String classpathResource) {
|
@RequestParam(value = "classpathResource") String classpathResource,
|
||||||
if (StringUtils.isNotBlank(name)) {
|
@RequestParam(value = "resourceName") String resourceName,
|
||||||
|
@RequestPart(value = "files", required = false) MultipartFile file) {
|
||||||
|
if (StringUtils.isBlank(name)) {
|
||||||
//根据流程定义Key查询
|
//根据流程定义Key查询
|
||||||
name = "出差申请流程";
|
name = "出差申请流程";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3、使用RepositoryService进行部署
|
// 3、使用RepositoryService进行部署
|
||||||
Deployment deployment = repositoryService.createDeployment()
|
Deployment deployment = null;
|
||||||
|
try {
|
||||||
|
deployment = repositoryService.createDeployment()
|
||||||
//.addClasspathResource("bpmn/diagram_1.bpmn20.xml") // 添加bpmn资源
|
//.addClasspathResource("bpmn/diagram_1.bpmn20.xml") // 添加bpmn资源
|
||||||
//.addClasspathResource("bpmn/business-trips.png") // 添加png资源
|
//.addClasspathResource("bpmn/business-trips.png") // 添加png资源
|
||||||
.addClasspathResource(classpathResource)
|
//.addClasspathResource(classpathResource)
|
||||||
|
.addInputStream(resourceName, file.getInputStream())
|
||||||
|
.key(name)
|
||||||
.name(name)
|
.name(name)
|
||||||
.deploy();
|
.deploy();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
// 4、输出部署信息
|
// 4、输出部署信息
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
|
|
||||||
@@ -114,9 +130,12 @@ public class AController {
|
|||||||
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
|
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
|
||||||
// 2、获取RunTimeService
|
// 2、获取RunTimeService
|
||||||
RuntimeService runtimeService = processEngine.getRuntimeService();
|
RuntimeService runtimeService = processEngine.getRuntimeService();
|
||||||
|
Map<String, Object> vars = new HashMap<>();
|
||||||
|
vars.put("mainDrafter", "admin");
|
||||||
|
|
||||||
// 3、根据流程定义Id启动流程
|
// 3、根据流程定义Id启动流程
|
||||||
ProcessInstance processInstance = runtimeService
|
ProcessInstance processInstance = runtimeService
|
||||||
.startProcessInstanceByKey(key);
|
.startProcessInstanceByKey(key, vars);
|
||||||
|
|
||||||
// 输出内容
|
// 输出内容
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
@@ -155,12 +174,21 @@ public class AController {
|
|||||||
|
|
||||||
@GetMapping("/complete")
|
@GetMapping("/complete")
|
||||||
public Result<Object> complete(@RequestParam(value = "taskId") String taskId) {
|
public Result<Object> complete(@RequestParam(value = "taskId") String taskId) {
|
||||||
taskService.complete(taskId);
|
Map<String, Object> vars = new HashMap<>();
|
||||||
|
List<String> otherDrafterList = new ArrayList<>();
|
||||||
|
otherDrafterList.add("zhangsan");
|
||||||
|
otherDrafterList.add("lisi");
|
||||||
|
otherDrafterList.add("wangwu");
|
||||||
|
vars.put("leaderList", otherDrafterList);
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("status", 2);
|
||||||
|
taskService.complete(taskId, map, vars);
|
||||||
return Result.OK();
|
return Result.OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加签
|
* 加签
|
||||||
|
*
|
||||||
* @param taskId
|
* @param taskId
|
||||||
* @param loginName
|
* @param loginName
|
||||||
* @return
|
* @return
|
||||||
@@ -187,13 +215,19 @@ public class AController {
|
|||||||
|
|
||||||
@GetMapping(value = "/readResource")
|
@GetMapping(value = "/readResource")
|
||||||
@ApiOperation(value = "获取实时流程图", notes = "获取实时流程图,输出跟踪流程信息")
|
@ApiOperation(value = "获取实时流程图", notes = "获取实时流程图,输出跟踪流程信息")
|
||||||
public void getFlowImgByInstanceId(@RequestParam(value = "processInstanceId") String processInstanceId, HttpServletResponse response) {
|
public void getFlowImgByInstanceId(@RequestParam(value = "processInstanceId") String
|
||||||
processService.getFlowImgByInstanceId(processInstanceId, response);
|
processInstanceId, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
processService.readResource(processInstanceId, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/export/{modelId}")
|
@GetMapping(value = "/export/{modelId}")
|
||||||
@ApiOperation(value = "将流程模型导出为 bpmn文件", notes = "将流程模型导出为 bpmn文件")
|
@ApiOperation(value = "将流程模型导出为 bpmn文件", notes = "将流程模型导出为 bpmn文件")
|
||||||
public void export(@PathVariable("modelId") @ApiParam("流程模型Id") String modelId, HttpServletResponse response) {
|
public void export(@PathVariable("modelId") @ApiParam("流程模型Id") String modelId, HttpServletResponse
|
||||||
|
response) {
|
||||||
try {
|
try {
|
||||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(modelId);
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(modelId);
|
||||||
|
|
||||||
@@ -214,6 +248,7 @@ public class AController {
|
|||||||
log.error("导出model的bpmn文件失败:modelId={}", modelId, e);
|
log.error("导出model的bpmn文件失败:modelId={}", modelId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("test")
|
@GetMapping("test")
|
||||||
public Result<String> getRedisTest() {
|
public Result<String> getRedisTest() {
|
||||||
String msg1 = MessageUtils.getMessage("message");
|
String msg1 = MessageUtils.getMessage("message");
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* @date 2023-08-03 15:37
|
* @date 2023-08-03 15:37
|
||||||
*/
|
*/
|
||||||
public interface ProcessService {
|
public interface ProcessService {
|
||||||
void getFlowImgByInstanceId(String pProcessInstanceId, HttpServletResponse response);
|
|
||||||
|
|
||||||
Object addTask(String taskId, String assignee);
|
Object addTask(String taskId, String assignee);
|
||||||
|
|
||||||
|
void readResource(String pProcessInstanceId, HttpServletResponse response) throws Exception;
|
||||||
}
|
}
|
||||||
|
|||||||
+165
-209
@@ -1,10 +1,11 @@
|
|||||||
package com.jero.modules.activiti.service.impl;
|
package com.jero.modules.activiti.service.impl;
|
||||||
|
|
||||||
import com.jero.common.exception.JeroBootException;
|
import com.jero.common.exception.JeroBootException;
|
||||||
import com.jero.modules.activiti.config.DefaultProcessDiagramGenerator;
|
import com.jero.modules.activiti.config.WorkflowConstants;
|
||||||
import com.jero.modules.activiti.entity.ActGeBytearray;
|
import com.jero.modules.activiti.entity.ActGeBytearray;
|
||||||
import com.jero.modules.activiti.mapper.ActGeBytearrayMapper;
|
import com.jero.modules.activiti.mapper.ActGeBytearrayMapper;
|
||||||
import com.jero.modules.activiti.service.ProcessService;
|
import com.jero.modules.activiti.service.ProcessService;
|
||||||
|
import com.jero.modules.activiti.service.impl.image.ICustomProcessDiagramGenerator;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.activiti.bpmn.BpmnAutoLayout;
|
import org.activiti.bpmn.BpmnAutoLayout;
|
||||||
import org.activiti.bpmn.converter.BpmnXMLConverter;
|
import org.activiti.bpmn.converter.BpmnXMLConverter;
|
||||||
@@ -13,23 +14,30 @@ import org.activiti.bpmn.model.*;
|
|||||||
import org.activiti.engine.*;
|
import org.activiti.engine.*;
|
||||||
import org.activiti.engine.history.HistoricActivityInstance;
|
import org.activiti.engine.history.HistoricActivityInstance;
|
||||||
import org.activiti.engine.history.HistoricProcessInstance;
|
import org.activiti.engine.history.HistoricProcessInstance;
|
||||||
|
import org.activiti.engine.impl.RepositoryServiceImpl;
|
||||||
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||||
import org.activiti.engine.impl.persistence.deploy.DeploymentManager;
|
import org.activiti.engine.impl.persistence.deploy.DeploymentManager;
|
||||||
|
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
|
||||||
|
import org.activiti.engine.repository.ProcessDefinition;
|
||||||
|
import org.activiti.engine.repository.ProcessDefinitionQuery;
|
||||||
import org.activiti.engine.runtime.Execution;
|
import org.activiti.engine.runtime.Execution;
|
||||||
|
import org.activiti.engine.runtime.ProcessInstance;
|
||||||
import org.activiti.engine.task.Task;
|
import org.activiti.engine.task.Task;
|
||||||
|
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,87 +62,6 @@ public class ProcessServiceImpl implements ProcessService {
|
|||||||
@Resource
|
@Resource
|
||||||
private ActGeBytearrayMapper actGeBytearrayMapper;
|
private ActGeBytearrayMapper actGeBytearrayMapper;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getFlowImgByInstanceId(String processInstanceId, HttpServletResponse response) {
|
|
||||||
InputStream imageStream = null;
|
|
||||||
try {
|
|
||||||
// 获取历史流程实例
|
|
||||||
HistoricProcessInstance historicProcessInstance = historyService
|
|
||||||
.createHistoricProcessInstanceQuery()
|
|
||||||
.processInstanceId(processInstanceId).singleResult();
|
|
||||||
if (historicProcessInstance == null){
|
|
||||||
throw new JeroBootException("历史流程不存在");
|
|
||||||
}
|
|
||||||
// 获取流程中已经执行的节点,按照执行先后顺序排序
|
|
||||||
List<HistoricActivityInstance> historicActivityInstances = historyService
|
|
||||||
.createHistoricActivityInstanceQuery()
|
|
||||||
.processInstanceId(processInstanceId)
|
|
||||||
.orderByHistoricActivityInstanceId()
|
|
||||||
.asc().list();
|
|
||||||
// 高亮已经执行流程节点ID集合
|
|
||||||
List<String> highLightedActivitiIds = new ArrayList<>();
|
|
||||||
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
|
|
||||||
// 用默认颜色
|
|
||||||
highLightedActivitiIds.add(historicActivityInstance.getActivityId());
|
|
||||||
}
|
|
||||||
// 正在执行的节点
|
|
||||||
List<Execution> runTaskList = runtimeService.createExecutionQuery()
|
|
||||||
.processInstanceId(processInstanceId)
|
|
||||||
.list();
|
|
||||||
List<String> runningActivityIdList = new ArrayList<>();
|
|
||||||
for (Execution execution : runTaskList) {
|
|
||||||
if (!StringUtils.isEmpty(execution.getActivityId())) {
|
|
||||||
runningActivityIdList.add(execution.getActivityId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<String> currIds = historicActivityInstances.stream()
|
|
||||||
.filter(item -> item.getEndTime() != null)
|
|
||||||
.map(HistoricActivityInstance::getActivityId).collect(Collectors.toList());
|
|
||||||
|
|
||||||
// 获得流程引擎配置
|
|
||||||
ProcessEngineConfiguration processEngineConfiguration = processEngine.getProcessEngineConfiguration();
|
|
||||||
|
|
||||||
BpmnModel bpmnModel = repositoryService
|
|
||||||
.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
|
|
||||||
// 高亮流程已发生流转的线id集合
|
|
||||||
List<String> highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances);
|
|
||||||
//
|
|
||||||
imageStream = new DefaultProcessDiagramGenerator().generateDiagram(
|
|
||||||
bpmnModel,
|
|
||||||
"png",
|
|
||||||
highLightedActivitiIds,//所有活动过的节点,包括当前在激活状态下的节点
|
|
||||||
currIds,//当前为激活状态下的节点
|
|
||||||
highLightedFlowIds,//活动过的线
|
|
||||||
"宋体",
|
|
||||||
"宋体",
|
|
||||||
"宋体",
|
|
||||||
processEngineConfiguration.getClassLoader(),
|
|
||||||
1.0,
|
|
||||||
runningActivityIdList);
|
|
||||||
|
|
||||||
OutputStream out = null;
|
|
||||||
out = response.getOutputStream();
|
|
||||||
int len = 0;
|
|
||||||
byte[] b = new byte[1024];
|
|
||||||
while ((len = imageStream.read(b)) != -1) {
|
|
||||||
out.write(b, 0, len);
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
if (imageStream != null) {
|
|
||||||
try {
|
|
||||||
imageStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object addTask(String taskId, String assignee) {
|
public Object addTask(String taskId, String assignee) {
|
||||||
// 1、创建ProcessEngine
|
// 1、创建ProcessEngine
|
||||||
@@ -191,154 +118,183 @@ public class ProcessServiceImpl implements ProcessService {
|
|||||||
flow.setTargetRef(to);
|
flow.setTargetRef(to);
|
||||||
return flow;
|
return flow;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @param bpmnModel bpmnModel
|
|
||||||
* @param historicActivityInstanceList historicActivityInstanceList
|
|
||||||
* @return HighLightedFlows
|
|
||||||
*/
|
|
||||||
public List<String> getHighLightedFlows(BpmnModel bpmnModel,
|
|
||||||
List<HistoricActivityInstance> historicActivityInstanceList) {
|
|
||||||
//historicActivityInstanceList 是 流程中已经执行的历史活动实例
|
|
||||||
// 已经流经的顺序流,需要高亮显示
|
|
||||||
List<String> highFlows = new ArrayList<>();
|
|
||||||
|
|
||||||
|
private List<String> getHighLightedFlows(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> historicActivityInstances) {
|
||||||
|
// 高亮流程已发生流转的线id集合
|
||||||
|
List<String> highLightedFlowIds = new ArrayList<>();
|
||||||
// 全部活动节点
|
// 全部活动节点
|
||||||
List<FlowNode> allHistoricActivityNodeList = new ArrayList<>();
|
List<FlowNode> historicActivityNodes = new ArrayList<>();
|
||||||
|
// 已完成的历史活动节点
|
||||||
|
List<HistoricActivityInstance> finishedActivityInstances = new ArrayList<>();
|
||||||
|
|
||||||
// 拥有endTime的历史活动实例,即已经完成了的节点
|
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
|
||||||
List<HistoricActivityInstance> finishedActivityInstancesList = new ArrayList<>();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 循环的目的:
|
|
||||||
* 获取所有的历史节点FlowNode并放入allHistoricActivityNodeList
|
|
||||||
* 获取所有确定结束了的历史节点finishedActivityInstancesList
|
|
||||||
*/
|
|
||||||
for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
|
|
||||||
// 获取流程节点
|
|
||||||
// bpmnModel.getMainProcess()获取一个Process对象
|
|
||||||
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true);
|
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true);
|
||||||
allHistoricActivityNodeList.add(flowNode);
|
historicActivityNodes.add(flowNode);
|
||||||
|
|
||||||
// 如果结束时间不为空,表示当前节点已经完成
|
|
||||||
if (historicActivityInstance.getEndTime() != null) {
|
if (historicActivityInstance.getEndTime() != null) {
|
||||||
finishedActivityInstancesList.add(historicActivityInstance);
|
finishedActivityInstances.add(historicActivityInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlowNode currentFlowNode;
|
FlowNode currentFlowNode = null;
|
||||||
FlowNode targetFlowNode;
|
FlowNode targetFlowNode = null;
|
||||||
HistoricActivityInstance currentActivityInstance;
|
// 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
|
||||||
|
for (HistoricActivityInstance currentActivityInstance : finishedActivityInstances) {
|
||||||
// 遍历已经完成的活动实例,从每个实例的outgoingFlows中找到已经执行的
|
// 获得当前活动对应的节点信息及outgoingFlows信息
|
||||||
for (int k = 0; k < finishedActivityInstancesList.size(); k++) {
|
|
||||||
currentActivityInstance = finishedActivityInstancesList.get(k);
|
|
||||||
|
|
||||||
// 获得当前活动对应的节点信息以及outgoingFlows信息
|
|
||||||
currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
|
currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
|
||||||
|
List<SequenceFlow> sequenceFlows = currentFlowNode.getOutgoingFlows();
|
||||||
|
|
||||||
// 当前节点的所有流出线
|
/**
|
||||||
List<SequenceFlow> outgoingFlowList = currentFlowNode.getOutgoingFlows();
|
* 遍历outgoingFlows并找到已已流转的 满足如下条件认为已已流转: 1.当前节点是并行网关或兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转
|
||||||
|
|
||||||
/*
|
|
||||||
* 遍历outgoingFlows并找到已经流转的 满足如下条件认为已经流转:
|
|
||||||
* 1、当前节点是并行网关或者兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已经流转
|
|
||||||
* 2、当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转
|
|
||||||
* (第二点有问题,有过驳回的,会只绘制驳回的流程线,通过走向下一级的流程线没有高亮显示)
|
|
||||||
*/
|
*/
|
||||||
if ("parallelGateway".equals(currentActivityInstance.getActivityType()) ||
|
if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
|
||||||
"inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
|
|
||||||
// 遍历历史活动节点,找到匹配流程目标节点的
|
// 遍历历史活动节点,找到匹配流程目标节点的
|
||||||
for (SequenceFlow outgoingFlow : outgoingFlowList) {
|
for (SequenceFlow sequenceFlow : sequenceFlows) {
|
||||||
// 获取当前节点流程线对应的下一级节点
|
targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true);
|
||||||
targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(outgoingFlow.getTargetRef(), true);
|
if (historicActivityNodes.contains(targetFlowNode)) {
|
||||||
|
highLightedFlowIds.add(targetFlowNode.getId());
|
||||||
// 如果下级节点包含在所有历史节点中,则将当前节点的流出线高亮显示
|
|
||||||
if (allHistoricActivityNodeList.contains(targetFlowNode)) {
|
|
||||||
highFlows.add(outgoingFlow.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
|
||||||
* 2、当前节点不是并行网关或者兼容网关
|
|
||||||
* 【已解决-问题】如果当前节点有驳回功能,驳回到申请节点,
|
|
||||||
* 则因为申请节点在历史节点中,导致当前节点驳回到申请节点的流程线被高亮显示,但实际并没有进行驳回操作
|
|
||||||
*/
|
|
||||||
List<Map<String, Object>> tempMapList = new ArrayList<>();
|
List<Map<String, Object>> tempMapList = new ArrayList<>();
|
||||||
|
for (SequenceFlow sequenceFlow : sequenceFlows) {
|
||||||
// 当前节点ID
|
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
|
||||||
String currentActivityId = currentActivityInstance.getActivityId();
|
|
||||||
|
|
||||||
int size = historicActivityInstanceList.size();
|
|
||||||
boolean ifStartFind = false;
|
|
||||||
boolean ifFinded = false;
|
|
||||||
HistoricActivityInstance historicActivityInstance;
|
|
||||||
|
|
||||||
// 循环当前节点的所有流出线
|
|
||||||
// 循环所有的历史节点
|
|
||||||
// log.info("【开始】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
|
|
||||||
// log.info("循环历史节点");
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
// // 如果当前节点流程线对应的下级节点在历史节点中,则该条流程线进行高亮显示(【问题】有驳回流程线时,即使没有进行驳回操作,因为申请节点在历史节点中,也会将驳回流程线高亮显示-_-||)
|
|
||||||
// if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
|
|
||||||
// Map<String, Object> map = new HashMap<>();
|
|
||||||
// map.put("highLightedFlowId", sequenceFlow.getId());
|
|
||||||
// map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
|
|
||||||
// tempMapList.add(map);
|
|
||||||
// // highFlows.add(sequenceFlow.getId());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 历史节点
|
|
||||||
historicActivityInstance = historicActivityInstanceList.get(i);
|
|
||||||
// log.info("第【{}/{}】个历史节点-ActivityId=【{}】", i + 1, size, historicActivityInstance.getActivityId());
|
|
||||||
|
|
||||||
// 如果循环历史节点中的id等于当前节点id,从当前历史节点继续先后查找是否有当前流程线等于的节点
|
|
||||||
// 历史节点的序号需要大于等于已经完成历史节点的序号,放置驳回重审一个节点经过两次时只取第一次的流出线高亮显示,第二次的不显示
|
|
||||||
if (i >= k && historicActivityInstance.getActivityId().equals(currentActivityId)) {
|
|
||||||
// log.info("第【{}】个历史节点和当前节点一致-ActivityId=【{}】", i + 1, historicActivityInstance.getActivityId());
|
|
||||||
ifStartFind = true;
|
|
||||||
// 跳过当前节点继续查找下一个节点
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ifStartFind) {
|
|
||||||
// log.info("[开始]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
|
|
||||||
|
|
||||||
ifFinded = false;
|
|
||||||
for (SequenceFlow sequenceFlow : outgoingFlowList) {
|
|
||||||
// 如果当前节点流程线对应的下级节点在其后面的历史节点中,则该条流程线进行高亮显示
|
|
||||||
// 【问题】
|
|
||||||
// log.info("当前流出线的下级节点=[{}]", sequenceFlow.getTargetRef());
|
|
||||||
if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
|
if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
|
||||||
// log.info("当前节点[{}]需高亮显示的流出线=[{}]", currentActivityId, sequenceFlow.getId());
|
Map<String, Object> map = new HashMap<>();
|
||||||
highFlows.add(sequenceFlow.getId());
|
map.put("highLightedFlowId", sequenceFlow.getId());
|
||||||
// 暂时默认找到离当前节点最近的下一级节点即退出循环,否则有多条流出线时将全部被高亮显示
|
map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
|
||||||
ifFinded = true;
|
tempMapList.add(map);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// log.info("[完成]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
|
|
||||||
}
|
}
|
||||||
if (ifFinded) {
|
|
||||||
// 暂时默认找到离当前节点最近的下一级节点即退出历史节点循环,否则有多条流出线时将全部被高亮显示
|
if (!CollectionUtils.isEmpty(tempMapList)) {
|
||||||
break;
|
// 遍历匹配的集合,取得开始时间最早的一个
|
||||||
|
long earliestStamp = 0L;
|
||||||
|
String highLightedFlowId = null;
|
||||||
|
for (Map<String, Object> map : tempMapList) {
|
||||||
|
long highLightedFlowStartTime = Long.valueOf(map.get("highLightedFlowStartTime").toString());
|
||||||
|
if (earliestStamp == 0 || earliestStamp >= highLightedFlowStartTime) {
|
||||||
|
highLightedFlowId = map.get("highLightedFlowId").toString();
|
||||||
|
earliestStamp = highLightedFlowStartTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// log.info("【完成】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
|
|
||||||
// if (!CollectionUtils.isEmpty(tempMapList)) {
|
highLightedFlowIds.add(highLightedFlowId);
|
||||||
// // 遍历匹配的集合,取得开始时间最早的一个
|
}
|
||||||
// long earliestStamp = 0L;
|
|
||||||
// String highLightedFlowId = null;
|
}
|
||||||
// for (Map<String, Object> map : tempMapList) {
|
|
||||||
// long highLightedFlowStartTime = Long.valueOf(map.get("highLightedFlowStartTime").toString());
|
}
|
||||||
// if (earliestStamp == 0 || earliestStamp <= highLightedFlowStartTime) {
|
return highLightedFlowIds;
|
||||||
// highLightedFlowId = map.get("highLightedFlowId").toString();
|
}
|
||||||
// earliestStamp = highLightedFlowStartTime;
|
|
||||||
// }
|
@Override
|
||||||
// }
|
public void readResource(String pProcessInstanceId, HttpServletResponse response)
|
||||||
// highFlows.add(highLightedFlowId);
|
throws Exception {
|
||||||
// }
|
// 设置页面不缓存
|
||||||
|
response.setHeader("Pragma", "No-cache");
|
||||||
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
|
response.setDateHeader("Expires", 0);
|
||||||
|
|
||||||
|
String processDefinitionId = "";
|
||||||
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(pProcessInstanceId).singleResult();
|
||||||
|
if(processInstance == null) {
|
||||||
|
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(pProcessInstanceId).singleResult();
|
||||||
|
processDefinitionId = historicProcessInstance.getProcessDefinitionId();
|
||||||
|
} else {
|
||||||
|
processDefinitionId = processInstance.getProcessDefinitionId();
|
||||||
|
}
|
||||||
|
ProcessDefinitionQuery pdq = repositoryService.createProcessDefinitionQuery();
|
||||||
|
ProcessDefinition pd = pdq.processDefinitionId(processDefinitionId).singleResult();
|
||||||
|
|
||||||
|
String resourceName = pd.getDiagramResourceName();
|
||||||
|
|
||||||
|
if(resourceName.endsWith(".png") && StringUtils.isEmpty(pProcessInstanceId) == false)
|
||||||
|
{
|
||||||
|
getActivitiProccessImage(pProcessInstanceId,response);
|
||||||
|
//ProcessDiagramGenerator.generateDiagram(pde, "png", getRuntimeService().getActiveActivityIds(processInstanceId));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 通过接口读取
|
||||||
|
InputStream resourceAsStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName);
|
||||||
|
|
||||||
|
// 输出资源内容到相应对象
|
||||||
|
byte[] b = new byte[1024];
|
||||||
|
int len = -1;
|
||||||
|
while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
|
||||||
|
response.getOutputStream().write(b, 0, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return highFlows;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流程图像,已执行节点和流程线高亮显示
|
||||||
|
*/
|
||||||
|
public void getActivitiProccessImage(String pProcessInstanceId, HttpServletResponse response) {
|
||||||
|
//logger.info("[开始]-获取流程图图像");
|
||||||
|
try {
|
||||||
|
// 获取历史流程实例
|
||||||
|
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||||
|
.processInstanceId(pProcessInstanceId).singleResult();
|
||||||
|
|
||||||
|
if (historicProcessInstance == null) {
|
||||||
|
//throw new BusinessException("获取流程实例ID[" + pProcessInstanceId + "]对应的历史流程实例失败!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 获取流程定义
|
||||||
|
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
|
||||||
|
.getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
|
||||||
|
|
||||||
|
// 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
|
||||||
|
List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
|
||||||
|
.processInstanceId(pProcessInstanceId).orderByHistoricActivityInstanceId().asc().list();
|
||||||
|
|
||||||
|
// 已执行的节点ID集合
|
||||||
|
List<String> executedActivityIdList = new ArrayList<String>();
|
||||||
|
int index = 1;
|
||||||
|
//logger.info("获取已经执行的节点ID");
|
||||||
|
for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
|
||||||
|
executedActivityIdList.add(activityInstance.getActivityId());
|
||||||
|
|
||||||
|
//logger.info("第[" + index + "]个已执行节点=" + activityInstance.getActivityId() + " : " +activityInstance.getActivityName());
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
|
||||||
|
|
||||||
|
// 已执行的线集合
|
||||||
|
List<String> flowIds = new ArrayList<String>();
|
||||||
|
// 获取流程走过的线 (getHighLightedFlows是下面的方法)
|
||||||
|
flowIds = getHighLightedFlows(bpmnModel,processDefinition, historicActivityInstanceList);
|
||||||
|
|
||||||
|
// // 获取流程图图像字符流
|
||||||
|
// ProcessDiagramGenerator pec = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
|
||||||
|
// //配置字体
|
||||||
|
// InputStream imageStream = pec.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds,"宋体","微软雅黑","黑体",null,2.0);
|
||||||
|
|
||||||
|
Set<String> currIds = runtimeService.createExecutionQuery().processInstanceId(pProcessInstanceId).list()
|
||||||
|
.stream().map(e->e.getActivityId()).collect(Collectors.toSet());
|
||||||
|
|
||||||
|
ICustomProcessDiagramGenerator diagramGenerator = (ICustomProcessDiagramGenerator) processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
|
||||||
|
InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", executedActivityIdList,
|
||||||
|
flowIds, "宋体", "宋体", "宋体", null, 1.0, new Color[] { WorkflowConstants.COLOR_NORMAL, WorkflowConstants.COLOR_CURRENT }, currIds);
|
||||||
|
|
||||||
|
response.setContentType("image/png");
|
||||||
|
OutputStream os = response.getOutputStream();
|
||||||
|
int bytesRead = 0;
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
|
||||||
|
os.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
os.close();
|
||||||
|
imageStream.close();
|
||||||
|
}
|
||||||
|
//logger.info("[完成]-获取流程图图像");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
//logger.error("【异常】-获取流程图失败!" + e.getMessage());
|
||||||
|
//throw new BusinessException("获取流程图失败!" + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+163
-1111
File diff suppressed because it is too large
Load Diff
+196
-654
@@ -1,395 +1,97 @@
|
|||||||
package com.jero.modules.activiti.service.impl.image;
|
package com.jero.modules.activiti.service.impl.image;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.activiti.bpmn.model.Process;
|
import org.activiti.bpmn.model.Process;
|
||||||
import org.activiti.bpmn.model.*;
|
import org.activiti.bpmn.model.*;
|
||||||
|
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.imageio.stream.ImageOutputStream;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
/**
|
public class CustomProcessDiagramGenerator extends DefaultProcessDiagramGenerator implements ICustomProcessDiagramGenerator{
|
||||||
* Class to generate an image based the diagram interchange information in a BPMN 2.0 process.
|
//预初始化流程图绘制,大大提升了系统启动后首次查看流程图的速度
|
||||||
* 在 BPMN 2.0 流程中基于图表交换信息生成图像的类。
|
static {
|
||||||
*
|
new CustomProcessDiagramCanvas(10,10,0,0,"png", "宋体","宋体","宋体",null);
|
||||||
* @author Joram Barrez
|
|
||||||
* @author Tijs Rademakers
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGenerator {
|
|
||||||
|
|
||||||
protected String ACTIVITY_FONT_NAME = "微软雅黑";
|
|
||||||
protected String LABEL_FONT_NAME = "微软雅黑";
|
|
||||||
protected String ANNOTATION_FONT_NAME = "微软雅黑";
|
|
||||||
|
|
||||||
protected Map<Class<? extends BaseElement>, ActivityDrawInstruction> activityDrawInstructions = new HashMap<>();
|
|
||||||
protected Map<Class<? extends BaseElement>, ArtifactDrawInstruction> artifactDrawInstructions = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The instructions on how to draw a certain construct is
|
|
||||||
* created statically and stored in a map for performance.
|
|
||||||
*/
|
|
||||||
public CustomProcessDiagramGenerator() {
|
|
||||||
// start event
|
|
||||||
activityDrawInstructions.put(StartEvent.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
StartEvent startEvent = (StartEvent) flowNode;
|
|
||||||
if (startEvent.getEventDefinitions() != null && !startEvent.getEventDefinitions().isEmpty()) {
|
|
||||||
EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
|
|
||||||
if (eventDefinition instanceof TimerEventDefinition) {
|
|
||||||
processDiagramCanvas.drawTimerStartEvent(flowNode.getId(), graphicInfo);
|
|
||||||
} else if (eventDefinition instanceof ErrorEventDefinition) {
|
|
||||||
processDiagramCanvas.drawErrorStartEvent(flowNode.getId(), graphicInfo);
|
|
||||||
} else if (eventDefinition instanceof SignalEventDefinition) {
|
|
||||||
processDiagramCanvas.drawSignalStartEvent(flowNode.getId(), graphicInfo);
|
|
||||||
} else if (eventDefinition instanceof MessageEventDefinition) {
|
|
||||||
processDiagramCanvas.drawMessageStartEvent(flowNode.getId(), graphicInfo);
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawNoneStartEvent(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawNoneStartEvent(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// signal catch
|
|
||||||
activityDrawInstructions.put(IntermediateCatchEvent.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) flowNode;
|
|
||||||
if (intermediateCatchEvent.getEventDefinitions() != null && !intermediateCatchEvent
|
|
||||||
.getEventDefinitions().isEmpty()) {
|
|
||||||
if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingSignalEvent(flowNode.getId(), flowNode.getName(), graphicInfo, true);
|
|
||||||
} else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingTimerEvent(flowNode.getId(), flowNode.getName(), graphicInfo, true);
|
|
||||||
} else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingMessageEvent(flowNode.getId(), flowNode.getName(), graphicInfo, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// signal throw
|
|
||||||
activityDrawInstructions.put(ThrowEvent.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
ThrowEvent throwEvent = (ThrowEvent) flowNode;
|
|
||||||
if (throwEvent.getEventDefinitions() != null && !throwEvent.getEventDefinitions().isEmpty()) {
|
|
||||||
if (throwEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
|
|
||||||
processDiagramCanvas.drawThrowingSignalEvent(flowNode.getId(), graphicInfo);
|
|
||||||
} else if (throwEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
|
|
||||||
processDiagramCanvas.drawThrowingCompensateEvent(flowNode.getId(), graphicInfo);
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawThrowingNoneEvent(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawThrowingNoneEvent(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// end event
|
|
||||||
activityDrawInstructions.put(EndEvent.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
EndEvent endEvent = (EndEvent) flowNode;
|
|
||||||
if (endEvent.getEventDefinitions() != null && !endEvent.getEventDefinitions().isEmpty()) {
|
|
||||||
if (endEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) {
|
|
||||||
processDiagramCanvas.drawErrorEndEvent(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawNoneEndEvent(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawNoneEndEvent(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// task
|
|
||||||
activityDrawInstructions.put(Task.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// user task
|
|
||||||
activityDrawInstructions.put(UserTask.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawUserTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// script task
|
|
||||||
activityDrawInstructions.put(ScriptTask.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawScriptTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// service task
|
|
||||||
activityDrawInstructions.put(ServiceTask.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
ServiceTask serviceTask = (ServiceTask) flowNode;
|
|
||||||
processDiagramCanvas.drawServiceTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// receive task
|
|
||||||
activityDrawInstructions.put(ReceiveTask.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawReceiveTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// send task
|
|
||||||
activityDrawInstructions.put(SendTask.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawSendTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// manual task
|
|
||||||
activityDrawInstructions.put(ManualTask.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawManualTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// businessRuleTask task
|
|
||||||
activityDrawInstructions.put(BusinessRuleTask.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawBusinessRuleTask(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// exclusive gateway
|
|
||||||
activityDrawInstructions.put(ExclusiveGateway.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawExclusiveGateway(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// inclusive gateway
|
|
||||||
activityDrawInstructions.put(InclusiveGateway.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawInclusiveGateway(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// parallel gateway
|
|
||||||
activityDrawInstructions.put(ParallelGateway.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawParallelGateway(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// event based gateway
|
|
||||||
activityDrawInstructions.put(EventGateway.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawEventBasedGateway(flowNode.getId(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Boundary timer
|
|
||||||
activityDrawInstructions.put(BoundaryEvent.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
BoundaryEvent boundaryEvent = (BoundaryEvent) flowNode;
|
|
||||||
if (boundaryEvent.getEventDefinitions() != null && !boundaryEvent.getEventDefinitions().isEmpty()) {
|
|
||||||
if (boundaryEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingTimerEvent(flowNode.getId(), flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity());
|
|
||||||
} else if (boundaryEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingErrorEvent(flowNode.getId(), graphicInfo, boundaryEvent.isCancelActivity());
|
|
||||||
} else if (boundaryEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingSignalEvent(flowNode.getId(), flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity());
|
|
||||||
} else if (boundaryEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingMessageEvent(flowNode.getId(), flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity());
|
|
||||||
} else if (boundaryEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
|
|
||||||
processDiagramCanvas.drawCatchingCompensateEvent(flowNode.getId(), graphicInfo, boundaryEvent.isCancelActivity());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public CustomProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType,
|
||||||
});
|
List<String> highLightedActivities, List<String> highLightedFlows, String activityFontName,
|
||||||
|
String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor,
|
||||||
|
Color[] colors, Set<String> currIds) {
|
||||||
|
|
||||||
// subprocess
|
if(null == highLightedActivities) {
|
||||||
activityDrawInstructions.put(SubProcess.class, new ActivityDrawInstruction() {
|
highLightedActivities = Collections.<String>emptyList();
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
|
|
||||||
processDiagramCanvas.drawCollapsedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, false);
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawExpandedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, SubProcess.class);
|
|
||||||
}
|
}
|
||||||
}
|
if(null == highLightedFlows) {
|
||||||
});
|
highLightedFlows = Collections.<String>emptyList();
|
||||||
|
|
||||||
// Event subprocess
|
|
||||||
activityDrawInstructions.put(EventSubProcess.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
|
|
||||||
processDiagramCanvas.drawCollapsedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, false);
|
|
||||||
} else {
|
|
||||||
processDiagramCanvas.drawExpandedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, Transaction.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// call activity
|
|
||||||
activityDrawInstructions.put(CallActivity.class, new ActivityDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
|
||||||
processDiagramCanvas.drawCollapsedCallActivity(flowNode.getId(), flowNode.getName(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// text annotation
|
|
||||||
artifactDrawInstructions.put(TextAnnotation.class, new ArtifactDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) {
|
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
|
|
||||||
TextAnnotation textAnnotation = (TextAnnotation) artifact;
|
|
||||||
processDiagramCanvas.drawTextAnnotation(textAnnotation.getId(), textAnnotation.getText(), graphicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// association
|
|
||||||
artifactDrawInstructions.put(Association.class, new ArtifactDrawInstruction() {
|
|
||||||
@Override
|
|
||||||
public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) {
|
|
||||||
Association association = (Association) artifact;
|
|
||||||
String sourceRef = association.getSourceRef();
|
|
||||||
String targetRef = association.getTargetRef();
|
|
||||||
|
|
||||||
// source and target can be instance of FlowElement or Artifact
|
|
||||||
BaseElement sourceElement = bpmnModel.getFlowElement(sourceRef);
|
|
||||||
BaseElement targetElement = bpmnModel.getFlowElement(targetRef);
|
|
||||||
if (sourceElement == null) {
|
|
||||||
sourceElement = bpmnModel.getArtifact(sourceRef);
|
|
||||||
}
|
|
||||||
if (targetElement == null) {
|
|
||||||
targetElement = bpmnModel.getArtifact(targetRef);
|
|
||||||
}
|
|
||||||
List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
|
|
||||||
graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
|
|
||||||
int[] xPoints = new int[graphicInfoList.size()];
|
|
||||||
int[] yPoints = new int[graphicInfoList.size()];
|
|
||||||
for (int i = 1; i < graphicInfoList.size(); i++) {
|
|
||||||
GraphicInfo graphicInfo = graphicInfoList.get(i);
|
|
||||||
GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
|
|
||||||
|
|
||||||
if (i == 1) {
|
|
||||||
xPoints[0] = (int) previousGraphicInfo.getX();
|
|
||||||
yPoints[0] = (int) previousGraphicInfo.getY();
|
|
||||||
}
|
|
||||||
xPoints[i] = (int) graphicInfo.getX();
|
|
||||||
yPoints[i] = (int) graphicInfo.getY();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AssociationDirection associationDirection = association.getAssociationDirection();
|
prepareBpmnModel(bpmnModel);
|
||||||
processDiagramCanvas.drawAssociation(xPoints, yPoints, associationDirection, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
CustomProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
|
||||||
protected CustomProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities, List<String> runningActivityIdList, List<String> highLightedFlows, List<String> runningActivityFlowsIds,
|
|
||||||
String activityFontName, String labelFontName, String annotationFontName) {
|
|
||||||
|
|
||||||
CustomProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, activityFontName, labelFontName, annotationFontName);
|
|
||||||
|
|
||||||
// Draw pool shape, if process is participant in collaboration
|
// Draw pool shape, if process is participant in collaboration
|
||||||
for (Pool pool : bpmnModel.getPools()) {
|
for (Pool pool : bpmnModel.getPools()) {
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
|
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
|
||||||
processDiagramCanvas.drawPoolOrLane(pool.getId(), pool.getName(), graphicInfo);
|
processDiagramCanvas.drawPoolOrLane(pool.getName(), graphicInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw lanes
|
// Draw lanes
|
||||||
for (Process process : bpmnModel.getProcesses()) {
|
for (Process process : bpmnModel.getProcesses()) {
|
||||||
for (Lane lane : process.getLanes()) {
|
for (Lane lane : process.getLanes()) {
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());
|
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());
|
||||||
processDiagramCanvas.drawPoolOrLane(lane.getId(), lane.getName(), graphicInfo);
|
processDiagramCanvas.drawPoolOrLane(lane.getName(), graphicInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw activities and their sequence-flows
|
// Draw activities and their sequence-flows
|
||||||
/**
|
for (Process process: bpmnModel.getProcesses()) {
|
||||||
* 绘制流程图上的所有节点和流程线,对高亮显示的节点和流程线进行特殊处理
|
List<FlowNode> flowNodeList= process.findFlowElementsOfType(FlowNode.class);
|
||||||
*/
|
for (FlowNode flowNode : flowNodeList) {
|
||||||
for (FlowNode flowNode : bpmnModel.getProcesses().get(0).findFlowElementsOfType(FlowNode.class)) {
|
drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor, colors, currIds);
|
||||||
drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, runningActivityIdList,
|
}
|
||||||
highLightedFlows, runningActivityFlowsIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw artifacts
|
// Draw artifacts
|
||||||
for (Process process : bpmnModel.getProcesses()) {
|
for (Process process : bpmnModel.getProcesses()) {
|
||||||
|
|
||||||
for (Artifact artifact : process.getArtifacts()) {
|
for (Artifact artifact : process.getArtifacts()) {
|
||||||
drawArtifact(processDiagramCanvas, bpmnModel, artifact);
|
drawArtifact(processDiagramCanvas, bpmnModel, artifact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<SubProcess> subProcesses = process.findFlowElementsOfType(SubProcess.class, true);
|
||||||
|
if (subProcesses != null) {
|
||||||
|
for (SubProcess subProcess : subProcesses) {
|
||||||
|
for (Artifact subProcessArtifact : subProcess.getArtifacts()) {
|
||||||
|
drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return processDiagramCanvas;
|
return processDiagramCanvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Desc: 绘制流程图上的所有节点和流程线,对高亮显示的节点和流程线进行特殊处理
|
|
||||||
*
|
|
||||||
* @param processDiagramCanvas
|
|
||||||
* @param bpmnModel
|
|
||||||
* @param flowNode
|
|
||||||
* @param highLightedActivities
|
|
||||||
* @param highLightedFlows
|
|
||||||
* @author Fuxs
|
|
||||||
*/
|
|
||||||
protected void drawActivity(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode,
|
protected void drawActivity(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode,
|
||||||
List<String> highLightedActivities, List<String> runningActivityIdList, List<String> highLightedFlows, List<String> runningActivityFlowsIds) {
|
List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, Color[] colors, Set<String> currIds) {
|
||||||
|
|
||||||
ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
|
ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
|
||||||
if (drawInstruction != null) {
|
if (drawInstruction != null) {
|
||||||
|
|
||||||
drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
|
drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
|
||||||
|
|
||||||
// Gather info on the multi instance marker
|
// Gather info on the multi instance marker
|
||||||
boolean multiInstanceSequential = false;
|
boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false;
|
||||||
boolean multiInstanceParallel = false;
|
|
||||||
boolean highLighted = false;
|
|
||||||
if (flowNode instanceof Activity) {
|
if (flowNode instanceof Activity) {
|
||||||
Activity activity = (Activity) flowNode;
|
Activity activity = (Activity) flowNode;
|
||||||
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
|
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
|
||||||
@@ -399,39 +101,37 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather info on the highLighted marker
|
// Gather info on the collapsed marker
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
||||||
if (!(flowNode instanceof SubProcess)) {
|
if (flowNode instanceof SubProcess) {
|
||||||
if (flowNode instanceof CallActivity) {
|
collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
|
||||||
highLighted = true;
|
} else if (flowNode instanceof CallActivity) {
|
||||||
}
|
collapsed = true;
|
||||||
} else {
|
|
||||||
highLighted = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), multiInstanceSequential, multiInstanceParallel, highLighted);
|
if (scaleFactor == 1.0) {
|
||||||
|
// Actually draw the markers
|
||||||
|
processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(),(int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(),
|
||||||
|
multiInstanceSequential, multiInstanceParallel, collapsed);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw highlighted activities
|
// Draw highlighted activities
|
||||||
if (highLightedActivities.contains(flowNode.getId())) {
|
if (highLightedActivities.contains(flowNode.getId())) {
|
||||||
/*
|
if(!CollectionUtils.isEmpty(currIds)
|
||||||
* 如果节点为当前正在处理中的节点,则红色高亮显示
|
&&currIds.contains(flowNode.getId())
|
||||||
*/
|
&& !(flowNode instanceof Gateway)) {//非结束节点,并且是当前节点
|
||||||
if (runningActivityIdList.contains(flowNode.getId())) {
|
drawHighLight((flowNode instanceof StartEvent), processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[1]);
|
||||||
log.debug("[绘制]-当前正在处理中的节点-红色高亮显示节点[{}-{}]", flowNode.getId(), flowNode.getName());
|
}else {//普通节点
|
||||||
drawRunningActivityHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
|
drawHighLight((flowNode instanceof StartEvent)||(flowNode instanceof EndEvent),processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[0]);
|
||||||
} else {
|
|
||||||
log.debug("[绘制]-高亮显示节点[{}-{}]", flowNode.getId(), flowNode.getName());
|
|
||||||
drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
}
|
||||||
* 绘制当前节点的流程线
|
|
||||||
*/
|
// Outgoing transitions of activity
|
||||||
for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
|
for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
|
||||||
boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));
|
String flowId = sequenceFlow.getId();
|
||||||
|
boolean highLighted = (highLightedFlows.contains(flowId));
|
||||||
String defaultFlow = null;
|
String defaultFlow = null;
|
||||||
if (flowNode instanceof Activity) {
|
if (flowNode instanceof Activity) {
|
||||||
defaultFlow = ((Activity) flowNode).getDefaultFlow();
|
defaultFlow = ((Activity) flowNode).getDefaultFlow();
|
||||||
@@ -440,22 +140,20 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isDefault = false;
|
boolean isDefault = false;
|
||||||
if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
|
if (defaultFlow != null && defaultFlow.equalsIgnoreCase(flowId)) {
|
||||||
isDefault = true;
|
isDefault = true;
|
||||||
}
|
}
|
||||||
boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null
|
// boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
|
||||||
&& !(flowNode instanceof Gateway);
|
|
||||||
|
|
||||||
String sourceRef = sequenceFlow.getSourceRef();
|
String sourceRef = sequenceFlow.getSourceRef();
|
||||||
String targetRef = sequenceFlow.getTargetRef();
|
String targetRef = sequenceFlow.getTargetRef();
|
||||||
FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
|
FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
|
||||||
FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
|
FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
|
||||||
List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
|
List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(flowId);
|
||||||
if (graphicInfoList != null && graphicInfoList.size() > 0) {
|
if (graphicInfoList != null && graphicInfoList.size() > 0) {
|
||||||
graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement,
|
graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
|
||||||
targetElement, graphicInfoList);
|
int xPoints[]= new int[graphicInfoList.size()];
|
||||||
int[] xPoints = new int[graphicInfoList.size()];
|
int yPoints[]= new int[graphicInfoList.size()];
|
||||||
int[] yPoints = new int[graphicInfoList.size()];
|
|
||||||
|
|
||||||
for (int i=1; i<graphicInfoList.size(); i++) {
|
for (int i=1; i<graphicInfoList.size(); i++) {
|
||||||
GraphicInfo graphicInfo = graphicInfoList.get(i);
|
GraphicInfo graphicInfo = graphicInfoList.get(i);
|
||||||
@@ -469,18 +167,17 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
|
|||||||
yPoints[i] = (int) graphicInfo.getY();
|
yPoints[i] = (int) graphicInfo.getY();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//画高亮线
|
||||||
|
processDiagramCanvas.drawSequenceflow(xPoints, yPoints, false, isDefault, highLighted, scaleFactor, colors[0]);
|
||||||
|
|
||||||
if (highLightedFlows.contains(sequenceFlow.getId()) && runningActivityFlowsIds.contains(sequenceFlow.getId())) {
|
// Draw sequenceflow label
|
||||||
processDiagramCanvas.drawLastSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted);
|
// GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(flowId);
|
||||||
} else {
|
// if (labelGraphicInfo != null) {
|
||||||
processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted);
|
// processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);
|
||||||
}
|
// }else {//解决流程图连线名称不显示的BUG
|
||||||
|
GraphicInfo lineCenter = getLineCenter(graphicInfoList);
|
||||||
/*
|
processDiagramCanvas.drawLabel(highLighted, sequenceFlow.getName(), lineCenter, Math.abs(xPoints[1]-xPoints[0]) >= 5);
|
||||||
* 绘制流程线名称
|
// }
|
||||||
*/
|
|
||||||
// GraphicInfo lineCenter = getLineCenter(graphicInfoList);
|
|
||||||
// processDiagramCanvas.drawLabel(sequenceFlow.getName(), lineCenter, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,66 +185,90 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
|
|||||||
if (flowNode instanceof FlowElementsContainer) {
|
if (flowNode instanceof FlowElementsContainer) {
|
||||||
for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
|
for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
|
||||||
if (nestedFlowElement instanceof FlowNode) {
|
if (nestedFlowElement instanceof FlowNode) {
|
||||||
drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement, highLightedActivities,
|
drawActivity_highOne(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor, colors, currIds);
|
||||||
runningActivityIdList, highLightedFlows, runningActivityFlowsIds);
|
//drawActivity,这个是activiti自带的,子流程会出现多次高亮问题,改用 drawActivity_highOne
|
||||||
|
/*drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement,
|
||||||
|
highLightedActivities, highLightedFlows, scaleFactor);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method makes coordinates of connection flow better.
|
* 解决子流程多次高亮问题
|
||||||
*
|
|
||||||
* @param processDiagramCanvas
|
|
||||||
* @param bpmnModel
|
|
||||||
* @param sourceElement
|
|
||||||
* @param targetElement
|
|
||||||
* @param graphicInfoList
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
protected static List<GraphicInfo> connectionPerfectionizer(CustomProcessDiagramCanvas processDiagramCanvas,
|
protected void drawActivity_highOne(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode,
|
||||||
BpmnModel bpmnModel, BaseElement sourceElement, BaseElement targetElement,
|
List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, Color[] colors, Set<String> currIds) {
|
||||||
List<GraphicInfo> graphicInfoList) {
|
ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
|
||||||
GraphicInfo sourceGraphicInfo = bpmnModel.getGraphicInfo(sourceElement.getId());
|
if (drawInstruction != null) {
|
||||||
GraphicInfo targetGraphicInfo = bpmnModel.getGraphicInfo(targetElement.getId());
|
|
||||||
|
|
||||||
CustomProcessDiagramCanvas.SHAPE_TYPE sourceShapeType = getShapeType(sourceElement);
|
drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
|
||||||
CustomProcessDiagramCanvas.SHAPE_TYPE targetShapeType = getShapeType(targetElement);
|
|
||||||
|
|
||||||
return processDiagramCanvas.connectionPerfectionizer(sourceShapeType, targetShapeType, sourceGraphicInfo,
|
// Gather info on the multi instance marker
|
||||||
targetGraphicInfo, graphicInfoList);
|
boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false;
|
||||||
|
if (flowNode instanceof Activity) {
|
||||||
|
Activity activity = (Activity) flowNode;
|
||||||
|
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
|
||||||
|
if (multiInstanceLoopCharacteristics != null) {
|
||||||
|
multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
|
||||||
|
multiInstanceParallel = !multiInstanceSequential;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Gather info on the collapsed marker
|
||||||
* This method returns shape type of base element.<br>
|
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
|
||||||
* Each element can be presented as rectangle, rhombus, or ellipse.
|
if (flowNode instanceof SubProcess) {
|
||||||
*
|
collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
|
||||||
* @param baseElement
|
} else if (flowNode instanceof CallActivity) {
|
||||||
* @return CustomProcessDiagramCanvas.SHAPE_TYPE
|
collapsed = true;
|
||||||
*/
|
|
||||||
protected static CustomProcessDiagramCanvas.SHAPE_TYPE getShapeType(BaseElement baseElement) {
|
|
||||||
if (baseElement instanceof Task || baseElement instanceof Activity || baseElement instanceof TextAnnotation) {
|
|
||||||
return CustomProcessDiagramCanvas.SHAPE_TYPE.Rectangle;
|
|
||||||
} else if (baseElement instanceof Gateway) {
|
|
||||||
return CustomProcessDiagramCanvas.SHAPE_TYPE.Rhombus;
|
|
||||||
} else if (baseElement instanceof Event) {
|
|
||||||
return CustomProcessDiagramCanvas.SHAPE_TYPE.Ellipse;
|
|
||||||
} else {
|
|
||||||
// unknown source element, just do not correct coordinates
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static GraphicInfo getLineCenter(List<GraphicInfo> graphicInfoList) {
|
if (scaleFactor == 1.0) {
|
||||||
GraphicInfo gi = new GraphicInfo();
|
// Actually draw the markers
|
||||||
|
processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(),(int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(),
|
||||||
|
multiInstanceSequential, multiInstanceParallel, collapsed);
|
||||||
|
}
|
||||||
|
|
||||||
int[] xPoints = new int[graphicInfoList.size()];
|
// Draw highlighted activities
|
||||||
int[] yPoints = new int[graphicInfoList.size()];
|
if (highLightedActivities.contains(flowNode.getId())) {
|
||||||
|
if(!CollectionUtils.isEmpty(currIds)
|
||||||
|
&&currIds.contains(flowNode.getId())
|
||||||
|
&& !(flowNode instanceof Gateway)) {//非结束节点,并且是当前节点
|
||||||
|
drawHighLight((flowNode instanceof StartEvent), processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[1]);
|
||||||
|
}else {//普通节点
|
||||||
|
drawHighLight((flowNode instanceof StartEvent)||(flowNode instanceof EndEvent),processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outgoing transitions of activity
|
||||||
|
for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
|
||||||
|
String flowId = sequenceFlow.getId();
|
||||||
|
boolean highLighted = (highLightedFlows.contains(flowId));
|
||||||
|
String defaultFlow = null;
|
||||||
|
if (flowNode instanceof Activity) {
|
||||||
|
defaultFlow = ((Activity) flowNode).getDefaultFlow();
|
||||||
|
} else if (flowNode instanceof Gateway) {
|
||||||
|
defaultFlow = ((Gateway) flowNode).getDefaultFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDefault = false;
|
||||||
|
if (defaultFlow != null && defaultFlow.equalsIgnoreCase(flowId)) {
|
||||||
|
isDefault = true;
|
||||||
|
}
|
||||||
|
// boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
|
||||||
|
|
||||||
|
String sourceRef = sequenceFlow.getSourceRef();
|
||||||
|
String targetRef = sequenceFlow.getTargetRef();
|
||||||
|
FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
|
||||||
|
FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
|
||||||
|
List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(flowId);
|
||||||
|
if (graphicInfoList != null && graphicInfoList.size() > 0) {
|
||||||
|
graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
|
||||||
|
int xPoints[]= new int[graphicInfoList.size()];
|
||||||
|
int yPoints[]= new int[graphicInfoList.size()];
|
||||||
|
|
||||||
double length = 0;
|
|
||||||
double[] lengths = new double[graphicInfoList.size()];
|
|
||||||
lengths[0] = 0;
|
|
||||||
double m;
|
|
||||||
for (int i=1; i<graphicInfoList.size(); i++) {
|
for (int i=1; i<graphicInfoList.size(); i++) {
|
||||||
GraphicInfo graphicInfo = graphicInfoList.get(i);
|
GraphicInfo graphicInfo = graphicInfoList.get(i);
|
||||||
GraphicInfo previousGraphicInfo = graphicInfoList.get(i-1);
|
GraphicInfo previousGraphicInfo = graphicInfoList.get(i-1);
|
||||||
@@ -559,76 +280,35 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
|
|||||||
xPoints[i] = (int) graphicInfo.getX();
|
xPoints[i] = (int) graphicInfo.getX();
|
||||||
yPoints[i] = (int) graphicInfo.getY();
|
yPoints[i] = (int) graphicInfo.getY();
|
||||||
|
|
||||||
length += Math.sqrt(Math.pow((int) graphicInfo.getX() - (int) previousGraphicInfo.getX(), 2) + Math.pow(
|
|
||||||
(int) graphicInfo.getY() - (int) previousGraphicInfo.getY(), 2));
|
|
||||||
lengths[i] = length;
|
|
||||||
}
|
}
|
||||||
m = length / 2;
|
//画高亮线
|
||||||
int p1 = 0, p2 = 1;
|
processDiagramCanvas.drawSequenceflow(xPoints, yPoints, false, isDefault, highLighted, scaleFactor, colors[0]);
|
||||||
for (int i = 1; i < lengths.length; i++) {
|
|
||||||
double len = lengths[i];
|
// Draw sequenceflow label
|
||||||
p1 = i - 1;
|
// GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(flowId);
|
||||||
p2 = i;
|
// if (labelGraphicInfo != null) {
|
||||||
if (len > m) {
|
// processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);
|
||||||
break;
|
// }else {//解决流程图连线名称不显示的BUG
|
||||||
|
GraphicInfo lineCenter = getLineCenter(graphicInfoList);
|
||||||
|
processDiagramCanvas.drawLabel(highLighted, sequenceFlow.getName(), lineCenter, Math.abs(xPoints[1]-xPoints[0]) >= 5);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicInfo graphicInfo1 = graphicInfoList.get(p1);
|
|
||||||
GraphicInfo graphicInfo2 = graphicInfoList.get(p2);
|
|
||||||
|
|
||||||
double AB = (int) graphicInfo2.getX() - (int) graphicInfo1.getX();
|
|
||||||
double OA = (int) graphicInfo2.getY() - (int) graphicInfo1.getY();
|
|
||||||
double OB = lengths[p2] - lengths[p1];
|
|
||||||
double ob = m - lengths[p1];
|
|
||||||
double ab = AB * ob / OB;
|
|
||||||
double oa = OA * ob / OB;
|
|
||||||
|
|
||||||
double mx = graphicInfo1.getX() + ab;
|
|
||||||
double my = graphicInfo1.getY() + oa;
|
|
||||||
|
|
||||||
gi.setX(mx);
|
|
||||||
gi.setY(my);
|
|
||||||
return gi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawArtifact(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel,
|
protected void drawHighLight(boolean isStartOrEnd, CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo, Color color) {
|
||||||
Artifact artifact) {
|
processDiagramCanvas.drawHighLight(isStartOrEnd, (int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), color);
|
||||||
|
|
||||||
ArtifactDrawInstruction drawInstruction = artifactDrawInstructions.get(artifact.getClass());
|
|
||||||
if (drawInstruction != null) {
|
|
||||||
drawInstruction.draw(processDiagramCanvas, bpmnModel, artifact);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void drawHighLight(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) {
|
protected static CustomProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType,
|
||||||
processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo
|
String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
|
||||||
.getWidth(), (int) graphicInfo.getHeight());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Desc:绘制正在执行中的节点红色高亮显示
|
|
||||||
*
|
|
||||||
* @param processDiagramCanvas CustomProcessDiagramCanvas
|
|
||||||
* @param graphicInfo GraphicInfo
|
|
||||||
* @author Fuxs
|
|
||||||
*/
|
|
||||||
private static void drawRunningActivityHighLight(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) {
|
|
||||||
processDiagramCanvas.drawRunningActivityHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo
|
|
||||||
.getWidth(), (int) graphicInfo.getHeight());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static CustomProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String activityFontName,
|
|
||||||
String labelFontName, String annotationFontName) {
|
|
||||||
|
|
||||||
// We need to calculate maximum values to know how big the image will be in its entirety
|
// We need to calculate maximum values to know how big the image will be in its entirety
|
||||||
double minX = 1.7976931348623157E308D;
|
double minX = Double.MAX_VALUE;
|
||||||
double maxX = 0.0D;
|
double maxX = 0;
|
||||||
double minY = 1.7976931348623157E308D;
|
double minY = Double.MAX_VALUE;
|
||||||
double maxY = 0.0D;
|
double maxY = 0;
|
||||||
|
|
||||||
|
|
||||||
for (Pool pool : bpmnModel.getPools()) {
|
for (Pool pool : bpmnModel.getPools()) {
|
||||||
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
|
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
|
||||||
@@ -748,178 +428,40 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case, see http://jira.codehaus.org/browse/ACT-1431
|
// Special case, see https://activiti.atlassian.net/browse/ACT-1431
|
||||||
if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) {
|
if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) {
|
||||||
// Nothing to show
|
// Nothing to show
|
||||||
minX = 0.0D;
|
minX = 0;
|
||||||
minY = 0.0D;
|
minY = 0;
|
||||||
}
|
|
||||||
//width和height代表最大的长宽
|
|
||||||
return new CustomProcessDiagramCanvas((int) maxX + 30, (int) maxY + 50, (int) minX, (int) minY, activityFontName, labelFontName, annotationFontName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static List<Artifact> gatherAllArtifacts(BpmnModel bpmnModel) {
|
return new CustomProcessDiagramCanvas((int) maxX + 10,(int) maxY + 10, (int) minX, (int) minY,
|
||||||
List<Artifact> artifacts = new ArrayList<Artifact>();
|
imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
|
||||||
for (Process process : bpmnModel.getProcesses()) {
|
|
||||||
artifacts.addAll(process.getArtifacts());
|
|
||||||
}
|
|
||||||
return artifacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static List<FlowNode> gatherAllFlowNodes(BpmnModel bpmnModel) {
|
|
||||||
List<FlowNode> flowNodes = new ArrayList<FlowNode>();
|
|
||||||
for (Process process : bpmnModel.getProcesses()) {
|
|
||||||
flowNodes.addAll(gatherAllFlowNodes(process));
|
|
||||||
}
|
|
||||||
return flowNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static List<FlowNode> gatherAllFlowNodes(FlowElementsContainer flowElementsContainer) {
|
|
||||||
List<FlowNode> flowNodes = new ArrayList<FlowNode>();
|
|
||||||
for (FlowElement flowElement : flowElementsContainer.getFlowElements()) {
|
|
||||||
if (flowElement instanceof FlowNode) {
|
|
||||||
flowNodes.add((FlowNode) flowElement);
|
|
||||||
}
|
|
||||||
if (flowElement instanceof FlowElementsContainer) {
|
|
||||||
flowNodes.addAll(gatherAllFlowNodes((FlowElementsContainer) flowElement));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flowNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Class<? extends BaseElement>, ActivityDrawInstruction> getActivityDrawInstructions() {
|
|
||||||
return activityDrawInstructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActivityDrawInstructions(Map<Class<? extends BaseElement>, ActivityDrawInstruction> activityDrawInstructions) {
|
|
||||||
this.activityDrawInstructions = activityDrawInstructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Class<? extends BaseElement>, ArtifactDrawInstruction> getArtifactDrawInstructions() {
|
|
||||||
return artifactDrawInstructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArtifactDrawInstructions(Map<Class<? extends BaseElement>, ArtifactDrawInstruction> artifactDrawInstructions) {
|
|
||||||
this.artifactDrawInstructions = artifactDrawInstructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected interface ActivityDrawInstruction {
|
|
||||||
void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected interface ArtifactDrawInstruction {
|
|
||||||
void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Desc: 输入所有的参数,以获取图像
|
|
||||||
*
|
|
||||||
* @param bpmnModel
|
|
||||||
* @param highLightedActivities
|
|
||||||
* @param runningActivityIdList
|
|
||||||
* @param highLightedFlows
|
|
||||||
* @param activityFontName
|
|
||||||
* @param labelFontName
|
|
||||||
* @param annotationFontName
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> runningActivityIdList,
|
|
||||||
List<String> highLightedFlows,
|
|
||||||
List<String> runningActivityFlowsIds,
|
|
||||||
String activityFontName,
|
|
||||||
String labelFontName,
|
|
||||||
String annotationFontName) {
|
|
||||||
// TODO
|
|
||||||
return generateProcessDiagram(bpmnModel,
|
|
||||||
highLightedActivities,
|
|
||||||
runningActivityIdList,
|
|
||||||
highLightedFlows,
|
|
||||||
runningActivityFlowsIds,
|
|
||||||
activityFontName,
|
|
||||||
labelFontName,
|
|
||||||
annotationFontName).generateImage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities,
|
||||||
List<String> highLightedActivities,
|
List<String> highLightedFlows, String activityFontName, String labelFontName, String annotationFontName,
|
||||||
List<String> runningActivityIdList,
|
ClassLoader customClassLoader, double scaleFactor, Color[] colors, Set<String> currIds) {
|
||||||
List<String> highLightedFlows,
|
CustomProcessDiagramCanvas customProcessDiagramCanvas = generateProcessDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows,
|
||||||
String activityFontName,
|
activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor,colors, currIds);
|
||||||
String labelFontName,
|
BufferedImage bufferedImage = customProcessDiagramCanvas.generateBufferedImage(imageType);
|
||||||
String annotationFontName) {
|
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||||
return generateProcessDiagram(bpmnModel,
|
ImageOutputStream imOut;
|
||||||
highLightedActivities,
|
try {
|
||||||
runningActivityIdList,
|
imOut = ImageIO.createImageOutputStream(bs);
|
||||||
highLightedFlows,
|
ImageIO.write(bufferedImage, "PNG", imOut);
|
||||||
Collections.emptyList(),
|
} catch (IOException e) {
|
||||||
activityFontName,
|
e.printStackTrace();
|
||||||
labelFontName,
|
|
||||||
annotationFontName).generateImage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputStream is = new ByteArrayInputStream(bs.toByteArray());
|
||||||
|
return is;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
|
||||||
List<String> highLightedActivities,
|
return generateDiagram(bpmnModel, imageType, Collections.<String>emptyList(), Collections.<String>emptyList(),
|
||||||
List<String> highLightedFlows,
|
activityFontName, labelFontName, annotationFontName, customClassLoader, 1.0, new Color[] {Color.BLACK, Color.BLACK}, null);
|
||||||
String activityFontName,
|
|
||||||
String labelFontName,
|
|
||||||
String annotationFontName) {
|
|
||||||
return generateProcessDiagram(bpmnModel,
|
|
||||||
highLightedActivities,
|
|
||||||
Collections.emptyList(),
|
|
||||||
highLightedFlows,
|
|
||||||
Collections.emptyList(),
|
|
||||||
activityFontName,
|
|
||||||
labelFontName,
|
|
||||||
annotationFontName).generateImage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> runningActivityIdList,
|
|
||||||
List<String> highLightedFlows,
|
|
||||||
List<String> runningActivityFlowsIds) {
|
|
||||||
return generateProcessDiagram(bpmnModel,
|
|
||||||
highLightedActivities,
|
|
||||||
runningActivityIdList,
|
|
||||||
highLightedFlows,
|
|
||||||
runningActivityFlowsIds,
|
|
||||||
ACTIVITY_FONT_NAME,
|
|
||||||
LABEL_FONT_NAME,
|
|
||||||
ANNOTATION_FONT_NAME).generateImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> runningActivityIdList,
|
|
||||||
List<String> highLightedFlows) {
|
|
||||||
return generateProcessDiagram(bpmnModel,
|
|
||||||
highLightedActivities,
|
|
||||||
runningActivityIdList,
|
|
||||||
highLightedFlows,
|
|
||||||
Collections.emptyList(),
|
|
||||||
ACTIVITY_FONT_NAME,
|
|
||||||
LABEL_FONT_NAME,
|
|
||||||
ANNOTATION_FONT_NAME).generateImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> highLightedFlows) {
|
|
||||||
return generateProcessDiagram(bpmnModel,
|
|
||||||
highLightedActivities,
|
|
||||||
Collections.emptyList(),
|
|
||||||
highLightedFlows,
|
|
||||||
Collections.emptyList(),
|
|
||||||
ACTIVITY_FONT_NAME,
|
|
||||||
LABEL_FONT_NAME,
|
|
||||||
ANNOTATION_FONT_NAME).generateImage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-53
@@ -1,61 +1,15 @@
|
|||||||
package com.jero.modules.activiti.service.impl.image;
|
package com.jero.modules.activiti.service.impl.image;
|
||||||
|
|
||||||
import org.activiti.bpmn.model.BpmnModel;
|
import org.activiti.bpmn.model.BpmnModel;
|
||||||
|
import org.activiti.image.ProcessDiagramGenerator;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
public interface ICustomProcessDiagramGenerator extends ProcessDiagramGenerator {
|
||||||
* bpmnModel bpmn模型
|
InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities,
|
||||||
* activityFontName 活动字体
|
List<String> highLightedFlows, String activityFontName, String labelFontName, String annotationFontName,
|
||||||
* labelFontName 标签字体
|
ClassLoader customClassLoader, double scaleFactor, Color[] colors, Set<String> currIds);
|
||||||
* annotationFontName 标注字体
|
|
||||||
* highLightedActivities 高亮活动节点(绿色)
|
|
||||||
* runningActivityIdList 正在运行的活动节点(红色)
|
|
||||||
* highLightedFlows 高亮顺序流(绿色)
|
|
||||||
* lastFlowIdList 最后一条执行的顺序流(红色) ——————未实现
|
|
||||||
*/
|
|
||||||
public interface ICustomProcessDiagramGenerator{
|
|
||||||
|
|
||||||
//指定字体
|
|
||||||
InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> runningActivityIdList,
|
|
||||||
List<String> highLightedFlows,
|
|
||||||
List<String> runningActivityFlowsIds,
|
|
||||||
String activityFontName,
|
|
||||||
String labelFontName,
|
|
||||||
String annotationFontName);
|
|
||||||
|
|
||||||
InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> runningActivityIdList,
|
|
||||||
List<String> highLightedFlows,
|
|
||||||
String activityFontName,
|
|
||||||
String labelFontName,
|
|
||||||
String annotationFontName);
|
|
||||||
|
|
||||||
InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> highLightedFlows,
|
|
||||||
String activityFontName,
|
|
||||||
String labelFontName,
|
|
||||||
String annotationFontName);
|
|
||||||
|
|
||||||
//无指定字体,使用默认字体
|
|
||||||
InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> runningActivityIdList,
|
|
||||||
List<String> highLightedFlows,
|
|
||||||
List<String> runningActivityFlowsIds);
|
|
||||||
|
|
||||||
InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> runningActivityIdList,
|
|
||||||
List<String> highLightedFlows);
|
|
||||||
|
|
||||||
InputStream generateDiagramCustom(BpmnModel bpmnModel,
|
|
||||||
List<String> highLightedActivities,
|
|
||||||
List<String> highLightedFlows);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.jero.modules.activiti.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liJiaRao
|
||||||
|
* @date 2023-09-05 17:16
|
||||||
|
*/
|
||||||
|
public enum CamundaTag {
|
||||||
|
assignee("assignee", "camunda:assignee","activiti:assignee","指派人"),
|
||||||
|
candidateUsers("candidateUsers", "camunda:candidateUsers","activiti:candidateUsers","候选人"),
|
||||||
|
candidateGroups("candidateGroups", "camunda:candidateGroups","activiti:candidateGroups","候选组"),
|
||||||
|
exclusive("exclusive", "camunda:exclusive","activiti:exclusive","独家"),
|
||||||
|
taskListener("taskListener", "camunda:taskListener","activiti:taskListener","监听"),
|
||||||
|
;
|
||||||
|
private String attribute;
|
||||||
|
private String camundaName;
|
||||||
|
private String activitiName;
|
||||||
|
private String note;
|
||||||
|
|
||||||
|
|
||||||
|
CamundaTag(String attribute, String camundaName, String activitiName, String note) {
|
||||||
|
this.attribute = attribute;
|
||||||
|
this.camundaName = camundaName;
|
||||||
|
this.activitiName = activitiName;
|
||||||
|
this.note = note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttribute() {
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttribute(String attribute) {
|
||||||
|
this.attribute = attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCamundaName() {
|
||||||
|
return camundaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCamundaName(String camundaName) {
|
||||||
|
this.camundaName = camundaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getActivitiName() {
|
||||||
|
return activitiName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivitiName(String activitiName) {
|
||||||
|
this.activitiName = activitiName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNote() {
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNote(String note) {
|
||||||
|
this.note = note;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
package com.jero.modules.activiti.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import org.dom4j.*;
|
||||||
|
import org.dom4j.io.OutputFormat;
|
||||||
|
import org.dom4j.io.SAXReader;
|
||||||
|
import org.dom4j.io.XMLWriter;
|
||||||
|
import org.dom4j.tree.AbstractAttribute;
|
||||||
|
import org.dom4j.tree.DefaultAttribute;
|
||||||
|
import org.dom4j.tree.DefaultElement;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作者 CG
|
||||||
|
* 时间 2021/4/12 14:21
|
||||||
|
* 备注 camunda 和 activiti xml 互相转换
|
||||||
|
* 参数
|
||||||
|
*/
|
||||||
|
public class ConversionUtil {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
File file1 = new File("E:\\Data\\Downloads\\sign.bpmn");
|
||||||
|
camundaToActiviti(file1,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作者 CG
|
||||||
|
* 时间 2021/4/12 14:22
|
||||||
|
* 备注 判断文件名字是否是xml,不是xml转换为xml
|
||||||
|
* 参数
|
||||||
|
*/
|
||||||
|
public static File isXml(File file) {
|
||||||
|
// 判断是否为null
|
||||||
|
String name = FileUtil.mainName(file);
|
||||||
|
String parent = file.getParent();
|
||||||
|
boolean bpmn = FileUtil.pathEndsWith(file, "bpmn");
|
||||||
|
if (bpmn) {
|
||||||
|
//转换为xml
|
||||||
|
File xmlFile = FileUtil.file(parent, name + ".xml");
|
||||||
|
File copy = FileUtil.copy(file, xmlFile, true);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 作者 CG
|
||||||
|
* 时间 2021/4/12 15:57
|
||||||
|
* 备注 属性转换
|
||||||
|
* 参数 [file, flag camunda->activiti=true activiti->camunda=false]
|
||||||
|
*/
|
||||||
|
public static void camundaToActiviti(File file, Boolean flag) {
|
||||||
|
//判断文件后缀名是否正确
|
||||||
|
try {
|
||||||
|
File xml = isXml(file);
|
||||||
|
//转换为文档
|
||||||
|
SAXReader reader = new SAXReader();
|
||||||
|
// 转换为Document
|
||||||
|
Document doc = reader.read(xml);
|
||||||
|
//获取根节点
|
||||||
|
Element rootElement = doc.getRootElement();
|
||||||
|
//获取命名空间
|
||||||
|
//flag camunda->activiti=true activiti->camunda=false
|
||||||
|
NamespaceHandler(rootElement, flag);
|
||||||
|
//处理userTask
|
||||||
|
Element process = rootElement.element("process");
|
||||||
|
List<Element> userTask = process.elements("userTask");
|
||||||
|
CamundaTag[] values = CamundaTag.values();
|
||||||
|
if (!CollectionUtils.isEmpty(userTask)) {
|
||||||
|
for (CamundaTag value : values) {
|
||||||
|
userTask(userTask, value, flag);
|
||||||
|
}
|
||||||
|
//处理监听
|
||||||
|
userTaskListener(userTask, flag);
|
||||||
|
}
|
||||||
|
//保存文档
|
||||||
|
saveDocument(doc, file);
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 作者 CG
|
||||||
|
* 时间 2021/4/12 17:45
|
||||||
|
* 备注 处理命名空间
|
||||||
|
* 参数 [rootElement, flag]
|
||||||
|
*/
|
||||||
|
public static void NamespaceHandler(Element rootElement, Boolean flag) {
|
||||||
|
NamespaceName camundaNamespace = NamespaceName.camunda;
|
||||||
|
NamespaceName activitiNamespace = NamespaceName.activiti;
|
||||||
|
Namespace activiti = rootElement.getNamespaceForPrefix(flag ? camundaNamespace.getName() : activitiNamespace.getName());
|
||||||
|
if (activiti != null) {
|
||||||
|
//删除camunda命名空间
|
||||||
|
rootElement.remove(activiti);
|
||||||
|
//添加activiti命名空间
|
||||||
|
Namespace namespace = new Namespace(flag ? activitiNamespace.getName() : camundaNamespace.getName(), flag ? activitiNamespace.getUrl() : camundaNamespace.getUrl());
|
||||||
|
rootElement.add(namespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作者 CG
|
||||||
|
* 时间 2021/4/12 15:36
|
||||||
|
* 备注 userTask 参数转换
|
||||||
|
* 参数 [userTask 要处理的集合, camundaTag 要处理的参数类型, flag camunda->activiti=true activiti->camunda=false]
|
||||||
|
*/
|
||||||
|
public static void userTask(List<Element> userTask, CamundaTag camundaTag, Boolean flag) {
|
||||||
|
for (Element element : userTask) {
|
||||||
|
Attribute assignee = element.attribute(camundaTag.getAttribute());
|
||||||
|
if (assignee != null) {
|
||||||
|
element.remove(assignee);
|
||||||
|
AbstractAttribute abstractAttribute = new AbstractAttribute() {
|
||||||
|
@Override
|
||||||
|
public QName getQName() {
|
||||||
|
QName qName = new QName(flag ? camundaTag.getActivitiName() : camundaTag.getCamundaName());
|
||||||
|
return qName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return assignee.getValue();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
element.add(abstractAttribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 作者 CG
|
||||||
|
* 时间 2021/4/12 15:36
|
||||||
|
* 备注 userTask 参数转换
|
||||||
|
* 参数 [userTask 要处理的集合, camundaTag 要处理的参数类型, flag camunda->activiti=true activiti->camunda=false]
|
||||||
|
*/
|
||||||
|
public static void userTaskListener(List<Element> userTask, Boolean flag) {
|
||||||
|
CamundaTag listener = CamundaTag.taskListener;
|
||||||
|
for (Element element : userTask) {
|
||||||
|
Element extensionElements = element.element("extensionElements");
|
||||||
|
if (extensionElements!=null){
|
||||||
|
//是否有监听
|
||||||
|
Element taskListener = extensionElements.element(listener.getAttribute());
|
||||||
|
if (taskListener!=null){
|
||||||
|
//获取节点所有参数
|
||||||
|
List<Attribute> attributes = taskListener.attributes();
|
||||||
|
DefaultElement defaultElement = new DefaultElement(flag?listener.getActivitiName():listener.getCamundaName());
|
||||||
|
//将参数拷贝到新的节点
|
||||||
|
for (Attribute attribute : attributes) {
|
||||||
|
DefaultAttribute defaultAttribute = new DefaultAttribute(attribute.getName(), attribute.getValue());
|
||||||
|
defaultElement.add(defaultAttribute);
|
||||||
|
}
|
||||||
|
//删除原有节点
|
||||||
|
extensionElements.remove(taskListener);
|
||||||
|
//添加新构建的节点
|
||||||
|
extensionElements.add(defaultElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 作者 CG
|
||||||
|
* 时间 2021/4/12 15:45
|
||||||
|
* 备注 文档保存
|
||||||
|
* 参数 [document, xmlFile]
|
||||||
|
*/
|
||||||
|
public static void saveDocument(Document document, File xmlFile) throws IOException {
|
||||||
|
Writer osWrite = new OutputStreamWriter(new FileOutputStream(xmlFile));//创建输出流
|
||||||
|
OutputFormat format = OutputFormat.createPrettyPrint(); //获取输出的指定格式
|
||||||
|
format.setEncoding("UTF-8");//设置编码 ,确保解析的xml为UTF-8格式
|
||||||
|
XMLWriter writer = new XMLWriter(osWrite, format);//XMLWriter 指定输出文件以及格式
|
||||||
|
writer.write(document);//把document写入xmlFile指定的文件(可以为被解析的文件或者新创建的文件)
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.jero.modules.activiti.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liJiaRao
|
||||||
|
* @date 2023-09-05 17:16
|
||||||
|
*/
|
||||||
|
public enum NamespaceName {
|
||||||
|
activiti("activiti","http://activiti.org/bpmn"),
|
||||||
|
camunda("camunda","http://camunda.org/schema/1.0/bpmn"),
|
||||||
|
;
|
||||||
|
private String name;
|
||||||
|
public String url;
|
||||||
|
|
||||||
|
NamespaceName(String name, String url) {
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,457 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1dx83c4" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.13.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.19.0">
|
||||||
|
<bpmn:process id="Process_17bj7d9" isExecutable="true">
|
||||||
|
<bpmn:startEvent id="StartEvent_1">
|
||||||
|
<bpmn:outgoing>Flow_0ln2zen</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0ln2zen" sourceRef="StartEvent_1" targetRef="Activity_0v98tow" />
|
||||||
|
<bpmn:userTask id="Activity_0v98tow" name="填写基本信息,在线编辑,分发其他起草人" camunda:assignee="${mainDrafter}">
|
||||||
|
<bpmn:incoming>Flow_0ln2zen</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1dmfby6</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1dmfby6" sourceRef="Activity_0v98tow" targetRef="Activity_1d2la4l" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_0hkyh3o" sourceRef="Activity_1d2la4l" targetRef="Activity_1dz3u0m" />
|
||||||
|
<bpmn:userTask id="Activity_1dz3u0m" name="主起草人汇总" camunda:assignee="${mainDrafter}">
|
||||||
|
<bpmn:incoming>Flow_0hkyh3o</bpmn:incoming>
|
||||||
|
<bpmn:incoming>Flow_0dlfvoz</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0iw6bki</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="Activity_0m576ex" name="标准化审批" camunda:candidateGroups="bjhGroup">
|
||||||
|
<bpmn:incoming>Flow_0iw6bki</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0rw7rph</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0iw6bki" name="" sourceRef="Activity_1dz3u0m" targetRef="Activity_0m576ex" />
|
||||||
|
<bpmn:userTask id="Activity_1d2la4l" name="其他起草人线下填写,上传" camunda:assignee="${user}">
|
||||||
|
<bpmn:incoming>Flow_1dmfby6</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0hkyh3o</bpmn:outgoing>
|
||||||
|
<bpmn:multiInstanceLoopCharacteristics camunda:collection="otherDrafterList" camunda:elementVariable="otherDrafter">
|
||||||
|
<bpmn:completionCondition xsi:type="bpmn:tFormalExpression">${nrOfInstances== nrOfCompletedInstances}</bpmn:completionCondition>
|
||||||
|
</bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:exclusiveGateway id="Gateway_0vz4kbb">
|
||||||
|
<bpmn:incoming>Flow_0rw7rph</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0dlfvoz</bpmn:outgoing>
|
||||||
|
<bpmn:outgoing>Flow_07x6x68</bpmn:outgoing>
|
||||||
|
</bpmn:exclusiveGateway>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0rw7rph" sourceRef="Activity_0m576ex" targetRef="Gateway_0vz4kbb" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_0dlfvoz" name="驳回" sourceRef="Gateway_0vz4kbb" targetRef="Activity_1dz3u0m">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${!pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:sequenceFlow id="Flow_07x6x68" name="通过" sourceRef="Gateway_0vz4kbb" targetRef="Activity_1qhpnpa">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:userTask id="Activity_1qhpnpa" name="评分人评分">
|
||||||
|
<bpmn:incoming>Flow_07x6x68</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1gc5b6z</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="Activity_1siuksf" name="标准化确认是否开启征求意见">
|
||||||
|
<bpmn:incoming>Flow_1gc5b6z</bpmn:incoming>
|
||||||
|
<bpmn:incoming>Flow_0lxhrf3</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0s3et9m</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1gc5b6z" sourceRef="Activity_1qhpnpa" targetRef="Activity_1siuksf" />
|
||||||
|
<bpmn:exclusiveGateway id="Gateway_04sf5vu">
|
||||||
|
<bpmn:incoming>Flow_0s3et9m</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1ts1npj</bpmn:outgoing>
|
||||||
|
<bpmn:outgoing>Flow_1yn3bo0</bpmn:outgoing>
|
||||||
|
</bpmn:exclusiveGateway>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0s3et9m" sourceRef="Activity_1siuksf" targetRef="Gateway_04sf5vu" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_1ts1npj" name="开启" sourceRef="Gateway_04sf5vu" targetRef="Activity_1ns6olf">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${open}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1yn3bo0" name="不开启" sourceRef="Gateway_04sf5vu" targetRef="Activity_11uuyg0" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_14y4j6o" sourceRef="Activity_1ns6olf" targetRef="Activity_04m430n" />
|
||||||
|
<bpmn:userTask id="Activity_04m430n" name="责任人填写征求意见">
|
||||||
|
<bpmn:extensionElements />
|
||||||
|
<bpmn:incoming>Flow_14y4j6o</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1x9nrbh</bpmn:outgoing>
|
||||||
|
<bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
<bpmn:completionCondition xsi:type="bpmn:tFormalExpression">${nrOfInstances== nrOfCompletedInstances}</bpmn:completionCondition>
|
||||||
|
</bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="Activity_1ns6olf" name="部门联络人分发责任人">
|
||||||
|
<bpmn:incoming>Flow_1ts1npj</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_14y4j6o</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1x9nrbh" sourceRef="Activity_04m430n" targetRef="Activity_1riqzkp" />
|
||||||
|
<bpmn:userTask id="Activity_1riqzkp" name="汇总数据">
|
||||||
|
<bpmn:incoming>Flow_1x9nrbh</bpmn:incoming>
|
||||||
|
<bpmn:incoming>Flow_0b6hwpr</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1jfhrkk</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1jfhrkk" sourceRef="Activity_1riqzkp" targetRef="Activity_1ralk8e" />
|
||||||
|
<bpmn:userTask id="Activity_1ralk8e" name="责任人的主管审批">
|
||||||
|
<bpmn:incoming>Flow_1jfhrkk</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0n3oqju</bpmn:outgoing>
|
||||||
|
<bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
<bpmn:completionCondition xsi:type="bpmn:tFormalExpression">${nrOfInstances== nrOfCompletedInstances}</bpmn:completionCondition>
|
||||||
|
</bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:exclusiveGateway id="Gateway_0fczaih">
|
||||||
|
<bpmn:incoming>Flow_0n3oqju</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0b6hwpr</bpmn:outgoing>
|
||||||
|
<bpmn:outgoing>Flow_0viypc1</bpmn:outgoing>
|
||||||
|
</bpmn:exclusiveGateway>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0n3oqju" sourceRef="Activity_1ralk8e" targetRef="Gateway_0fczaih" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_0b6hwpr" name="驳回" sourceRef="Gateway_0fczaih" targetRef="Activity_1riqzkp">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${!pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0viypc1" name="通过" sourceRef="Gateway_0fczaih" targetRef="Activity_1hb9aun">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0lxhrf3" sourceRef="Activity_1hb9aun" targetRef="Activity_1siuksf" />
|
||||||
|
<bpmn:userTask id="Activity_1hb9aun" name="主起草人汇总" camunda:assignee="${mainDrafter}">
|
||||||
|
<bpmn:incoming>Flow_0viypc1</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0lxhrf3</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0114fp7" sourceRef="Activity_11uuyg0" targetRef="Activity_1seways" />
|
||||||
|
<bpmn:userTask id="Activity_1seways" name="其它起草人校对">
|
||||||
|
<bpmn:incoming>Flow_0114fp7</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_15vlua6</bpmn:outgoing>
|
||||||
|
<bpmn:multiInstanceLoopCharacteristics camunda:collection="otherDrafterList" camunda:elementVariable="otherDrafter">
|
||||||
|
<bpmn:completionCondition xsi:type="bpmn:tFormalExpression">${nrOfInstances== nrOfCompletedInstances}</bpmn:completionCondition>
|
||||||
|
</bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="Activity_1l028rz" name="主管审批">
|
||||||
|
<bpmn:incoming>Flow_1uaxx7p</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_02wh2wo</bpmn:outgoing>
|
||||||
|
<bpmn:multiInstanceLoopCharacteristics />
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1uaxx7p" name="通过" sourceRef="Gateway_0a6pmod" targetRef="Activity_1l028rz">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:exclusiveGateway id="Gateway_0a6pmod">
|
||||||
|
<bpmn:incoming>Flow_15vlua6</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1uaxx7p</bpmn:outgoing>
|
||||||
|
<bpmn:outgoing>Flow_1k4inp1</bpmn:outgoing>
|
||||||
|
</bpmn:exclusiveGateway>
|
||||||
|
<bpmn:sequenceFlow id="Flow_15vlua6" sourceRef="Activity_1seways" targetRef="Gateway_0a6pmod" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_1k4inp1" name="驳回" sourceRef="Gateway_0a6pmod" targetRef="Activity_11uuyg0">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${!pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:exclusiveGateway id="Gateway_07iwvx9">
|
||||||
|
<bpmn:incoming>Flow_02wh2wo</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0v50urt</bpmn:outgoing>
|
||||||
|
<bpmn:outgoing>Flow_0rkg4il</bpmn:outgoing>
|
||||||
|
</bpmn:exclusiveGateway>
|
||||||
|
<bpmn:sequenceFlow id="Flow_02wh2wo" sourceRef="Activity_1l028rz" targetRef="Gateway_07iwvx9" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_0v50urt" name="通过" sourceRef="Gateway_07iwvx9" targetRef="Activity_0uxua0b">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0rkg4il" name="驳回" sourceRef="Gateway_07iwvx9" targetRef="Activity_11uuyg0">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${!pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:exclusiveGateway id="Gateway_18kluhj">
|
||||||
|
<bpmn:incoming>Flow_1cg7p7q</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0jc597n</bpmn:outgoing>
|
||||||
|
<bpmn:outgoing>Flow_03b0vp0</bpmn:outgoing>
|
||||||
|
</bpmn:exclusiveGateway>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1cg7p7q" sourceRef="Activity_0uxua0b" targetRef="Gateway_18kluhj" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_0jc597n" name="通过" sourceRef="Gateway_18kluhj" targetRef="Activity_05pybsc">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:sequenceFlow id="Flow_03b0vp0" name="驳回" sourceRef="Gateway_18kluhj" targetRef="Activity_11uuyg0">
|
||||||
|
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${!pass}</bpmn:conditionExpression>
|
||||||
|
</bpmn:sequenceFlow>
|
||||||
|
<bpmn:userTask id="Activity_05pybsc" name="主管部门的领导会签">
|
||||||
|
<bpmn:incoming>Flow_0jc597n</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_093us1v</bpmn:outgoing>
|
||||||
|
<bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
<bpmn:completionCondition xsi:type="bpmn:tFormalExpression">${nrOfInstances== nrOfCompletedInstances}</bpmn:completionCondition>
|
||||||
|
</bpmn:multiInstanceLoopCharacteristics>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="Activity_0uxua0b" name="标准化审批" camunda:candidateGroups="bjhGroup">
|
||||||
|
<bpmn:incoming>Flow_0v50urt</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1cg7p7q</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_093us1v" sourceRef="Activity_05pybsc" targetRef="Activity_1yr56ac" />
|
||||||
|
<bpmn:userTask id="Activity_1yr56ac" name="总工程师批准">
|
||||||
|
<bpmn:incoming>Flow_093us1v</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_09gf9nd</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_09gf9nd" sourceRef="Activity_1yr56ac" targetRef="Activity_0n0h60s" />
|
||||||
|
<bpmn:userTask id="Activity_0n0h60s" name="主起草人发布" camunda:assignee="${mainDrafter}">
|
||||||
|
<bpmn:incoming>Flow_09gf9nd</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0r1lb59</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="Activity_11uuyg0" name="主起草人上传会议纪要和参会人员" camunda:assignee="${mainDrafter}">
|
||||||
|
<bpmn:incoming>Flow_1yn3bo0</bpmn:incoming>
|
||||||
|
<bpmn:incoming>Flow_1k4inp1</bpmn:incoming>
|
||||||
|
<bpmn:incoming>Flow_0rkg4il</bpmn:incoming>
|
||||||
|
<bpmn:incoming>Flow_03b0vp0</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0114fp7</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:endEvent id="Event_0ke21ds">
|
||||||
|
<bpmn:incoming>Flow_0r1lb59</bpmn:incoming>
|
||||||
|
</bpmn:endEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0r1lb59" sourceRef="Activity_0n0h60s" targetRef="Event_0ke21ds" />
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_17bj7d9">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds x="179" y="102" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1m8g93w_di" bpmnElement="Activity_0v98tow">
|
||||||
|
<dc:Bounds x="270" y="80" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_01vt5l3_di" bpmnElement="Activity_1dz3u0m">
|
||||||
|
<dc:Bounds x="270" y="234" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_0k1zkgx_di" bpmnElement="Activity_0m576ex">
|
||||||
|
<dc:Bounds x="550" y="240" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_16f180l_di" bpmnElement="Activity_1d2la4l">
|
||||||
|
<dc:Bounds x="440" y="80" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Gateway_0vz4kbb_di" bpmnElement="Gateway_0vz4kbb" isMarkerVisible="true">
|
||||||
|
<dc:Bounds x="705" y="255" width="50" height="50" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1oifyhb_di" bpmnElement="Activity_1qhpnpa">
|
||||||
|
<dc:Bounds x="810" y="240" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="BPMNShape_1ierpcl" bpmnElement="Activity_1siuksf">
|
||||||
|
<dc:Bounds x="980" y="240" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Gateway_04sf5vu_di" bpmnElement="Gateway_04sf5vu" isMarkerVisible="true">
|
||||||
|
<dc:Bounds x="1145" y="255" width="50" height="50" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_0ci4vvt_di" bpmnElement="Activity_04m430n">
|
||||||
|
<dc:Bounds x="1440" y="240" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1k8uq9q_di" bpmnElement="Activity_1ns6olf">
|
||||||
|
<dc:Bounds x="1270" y="240" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_09v5428_di" bpmnElement="Activity_1riqzkp">
|
||||||
|
<dc:Bounds x="1270" y="360" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_0w8za61_di" bpmnElement="Activity_1ralk8e">
|
||||||
|
<dc:Bounds x="1560" y="360" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Gateway_0fczaih_di" bpmnElement="Gateway_0fczaih" isMarkerVisible="true">
|
||||||
|
<dc:Bounds x="1725" y="375" width="50" height="50" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_0meshwh_di" bpmnElement="Activity_1hb9aun">
|
||||||
|
<dc:Bounds x="1370" y="120" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_04b43yp_di" bpmnElement="Activity_1seways">
|
||||||
|
<dc:Bounds x="440" y="490" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1rukkqw_di" bpmnElement="Activity_1l028rz">
|
||||||
|
<dc:Bounds x="680" y="490" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Gateway_0a6pmod_di" bpmnElement="Gateway_0a6pmod" isMarkerVisible="true">
|
||||||
|
<dc:Bounds x="585" y="505" width="50" height="50" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Gateway_07iwvx9_di" bpmnElement="Gateway_07iwvx9" isMarkerVisible="true">
|
||||||
|
<dc:Bounds x="825" y="505" width="50" height="50" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Gateway_18kluhj_di" bpmnElement="Gateway_18kluhj" isMarkerVisible="true">
|
||||||
|
<dc:Bounds x="1065" y="505" width="50" height="50" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1xmao86_di" bpmnElement="Activity_05pybsc">
|
||||||
|
<dc:Bounds x="1160" y="490" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1ksqzhd_di" bpmnElement="Activity_0uxua0b">
|
||||||
|
<dc:Bounds x="920" y="490" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1nxdc8r_di" bpmnElement="Activity_1yr56ac">
|
||||||
|
<dc:Bounds x="1160" y="610" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_0p30sst_di" bpmnElement="Activity_0n0h60s">
|
||||||
|
<dc:Bounds x="270" y="610" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_128yaxk_di" bpmnElement="Activity_11uuyg0">
|
||||||
|
<dc:Bounds x="270" y="360" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Event_0ke21ds_di" bpmnElement="Event_0ke21ds">
|
||||||
|
<dc:Bounds x="179" y="632" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0ln2zen_di" bpmnElement="Flow_0ln2zen">
|
||||||
|
<di:waypoint x="215" y="120" />
|
||||||
|
<di:waypoint x="270" y="120" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1dmfby6_di" bpmnElement="Flow_1dmfby6">
|
||||||
|
<di:waypoint x="370" y="120" />
|
||||||
|
<di:waypoint x="440" y="120" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0hkyh3o_di" bpmnElement="Flow_0hkyh3o">
|
||||||
|
<di:waypoint x="490" y="160" />
|
||||||
|
<di:waypoint x="490" y="190" />
|
||||||
|
<di:waypoint x="320" y="190" />
|
||||||
|
<di:waypoint x="320" y="234" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0iw6bki_di" bpmnElement="Flow_0iw6bki">
|
||||||
|
<di:waypoint x="370" y="280" />
|
||||||
|
<di:waypoint x="550" y="280" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0rw7rph_di" bpmnElement="Flow_0rw7rph">
|
||||||
|
<di:waypoint x="650" y="280" />
|
||||||
|
<di:waypoint x="705" y="280" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0dlfvoz_di" bpmnElement="Flow_0dlfvoz">
|
||||||
|
<di:waypoint x="730" y="305" />
|
||||||
|
<di:waypoint x="730" y="340" />
|
||||||
|
<di:waypoint x="330" y="340" />
|
||||||
|
<di:waypoint x="330" y="320" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="739" y="310" width="21" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_07x6x68_di" bpmnElement="Flow_07x6x68">
|
||||||
|
<di:waypoint x="755" y="280" />
|
||||||
|
<di:waypoint x="810" y="280" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="761" y="262" width="22" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1gc5b6z_di" bpmnElement="Flow_1gc5b6z">
|
||||||
|
<di:waypoint x="910" y="280" />
|
||||||
|
<di:waypoint x="980" y="280" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0s3et9m_di" bpmnElement="Flow_0s3et9m">
|
||||||
|
<di:waypoint x="1080" y="280" />
|
||||||
|
<di:waypoint x="1145" y="280" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1ts1npj_di" bpmnElement="Flow_1ts1npj">
|
||||||
|
<di:waypoint x="1195" y="280" />
|
||||||
|
<di:waypoint x="1270" y="280" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="1219" y="262" width="21" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1yn3bo0_di" bpmnElement="Flow_1yn3bo0">
|
||||||
|
<di:waypoint x="1170" y="306" />
|
||||||
|
<di:waypoint x="1170" y="380" />
|
||||||
|
<di:waypoint x="370" y="380" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="1174" y="322" width="32" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_14y4j6o_di" bpmnElement="Flow_14y4j6o">
|
||||||
|
<di:waypoint x="1370" y="280" />
|
||||||
|
<di:waypoint x="1440" y="280" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1x9nrbh_di" bpmnElement="Flow_1x9nrbh">
|
||||||
|
<di:waypoint x="1490" y="320" />
|
||||||
|
<di:waypoint x="1490" y="340" />
|
||||||
|
<di:waypoint x="1320" y="340" />
|
||||||
|
<di:waypoint x="1320" y="360" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1jfhrkk_di" bpmnElement="Flow_1jfhrkk">
|
||||||
|
<di:waypoint x="1370" y="400" />
|
||||||
|
<di:waypoint x="1560" y="400" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0n3oqju_di" bpmnElement="Flow_0n3oqju">
|
||||||
|
<di:waypoint x="1660" y="400" />
|
||||||
|
<di:waypoint x="1725" y="400" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0b6hwpr_di" bpmnElement="Flow_0b6hwpr">
|
||||||
|
<di:waypoint x="1750" y="425" />
|
||||||
|
<di:waypoint x="1750" y="470" />
|
||||||
|
<di:waypoint x="1320" y="470" />
|
||||||
|
<di:waypoint x="1320" y="440" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="1719" y="435" width="21" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0viypc1_di" bpmnElement="Flow_0viypc1">
|
||||||
|
<di:waypoint x="1750" y="375" />
|
||||||
|
<di:waypoint x="1750" y="160" />
|
||||||
|
<di:waypoint x="1470" y="160" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="1719" y="322" width="22" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0lxhrf3_di" bpmnElement="Flow_0lxhrf3">
|
||||||
|
<di:waypoint x="1370" y="160" />
|
||||||
|
<di:waypoint x="1030" y="160" />
|
||||||
|
<di:waypoint x="1030" y="240" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0114fp7_di" bpmnElement="Flow_0114fp7">
|
||||||
|
<di:waypoint x="320" y="440" />
|
||||||
|
<di:waypoint x="320" y="530" />
|
||||||
|
<di:waypoint x="440" y="530" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1uaxx7p_di" bpmnElement="Flow_1uaxx7p">
|
||||||
|
<di:waypoint x="635" y="530" />
|
||||||
|
<di:waypoint x="680" y="530" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="647" y="512" width="22" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_15vlua6_di" bpmnElement="Flow_15vlua6">
|
||||||
|
<di:waypoint x="540" y="530" />
|
||||||
|
<di:waypoint x="585" y="530" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1k4inp1_di" bpmnElement="Flow_1k4inp1">
|
||||||
|
<di:waypoint x="610" y="505" />
|
||||||
|
<di:waypoint x="610" y="410" />
|
||||||
|
<di:waypoint x="370" y="410" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="615" y="455" width="21" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_02wh2wo_di" bpmnElement="Flow_02wh2wo">
|
||||||
|
<di:waypoint x="780" y="530" />
|
||||||
|
<di:waypoint x="825" y="530" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0v50urt_di" bpmnElement="Flow_0v50urt">
|
||||||
|
<di:waypoint x="875" y="530" />
|
||||||
|
<di:waypoint x="920" y="530" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="887" y="512" width="22" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0rkg4il_di" bpmnElement="Flow_0rkg4il">
|
||||||
|
<di:waypoint x="850" y="505" />
|
||||||
|
<di:waypoint x="850" y="410" />
|
||||||
|
<di:waypoint x="370" y="410" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="855" y="455" width="21" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1cg7p7q_di" bpmnElement="Flow_1cg7p7q">
|
||||||
|
<di:waypoint x="1020" y="530" />
|
||||||
|
<di:waypoint x="1065" y="530" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0jc597n_di" bpmnElement="Flow_0jc597n">
|
||||||
|
<di:waypoint x="1115" y="530" />
|
||||||
|
<di:waypoint x="1160" y="530" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="1127" y="512" width="22" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_03b0vp0_di" bpmnElement="Flow_03b0vp0">
|
||||||
|
<di:waypoint x="1090" y="505" />
|
||||||
|
<di:waypoint x="1090" y="410" />
|
||||||
|
<di:waypoint x="370" y="410" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="1095" y="455" width="21" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_093us1v_di" bpmnElement="Flow_093us1v">
|
||||||
|
<di:waypoint x="1210" y="570" />
|
||||||
|
<di:waypoint x="1210" y="610" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_09gf9nd_di" bpmnElement="Flow_09gf9nd">
|
||||||
|
<di:waypoint x="1160" y="650" />
|
||||||
|
<di:waypoint x="370" y="650" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0r1lb59_di" bpmnElement="Flow_0r1lb59">
|
||||||
|
<di:waypoint x="270" y="650" />
|
||||||
|
<di:waypoint x="215" y="650" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>
|
||||||
@@ -2,7 +2,9 @@ package com.jero;
|
|||||||
|
|
||||||
import com.jero.common.util.oConvertUtils;
|
import com.jero.common.util.oConvertUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.activiti.spring.boot.SecurityAutoConfiguration;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
@@ -21,7 +23,8 @@ import java.net.UnknownHostException;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
|
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
|
||||||
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
|
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
|
||||||
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class})
|
SecurityAutoConfiguration.class,
|
||||||
|
ManagementWebSecurityAutoConfiguration.class})
|
||||||
public class JeroSystemSingleApplication extends SpringBootServletInitializer {
|
public class JeroSystemSingleApplication extends SpringBootServletInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
<dom4j.version>1.6.1</dom4j.version>
|
<dom4j.version>1.6.1</dom4j.version>
|
||||||
<qiniu-java-sdk.version>7.4.0</qiniu-java-sdk.version>
|
<qiniu-java-sdk.version>7.4.0</qiniu-java-sdk.version>
|
||||||
<log4j2.version>2.15.0</log4j2.version>
|
<log4j2.version>2.15.0</log4j2.version>
|
||||||
<activiti.version>7.1.0.M1</activiti.version>
|
<activiti.version>6.0.0</activiti.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
Reference in New Issue
Block a user