package cn.palmte.work.service; import cn.palmte.work.config.activiti.ActConstant; import cn.palmte.work.config.activiti.ActTaskIndexEnum; import cn.palmte.work.model.ActTaskDef; import cn.palmte.work.model.ActTaskDefRepository; import cn.palmte.work.pojo.ActModel; import cn.palmte.work.utils.InterfaceUtil; import cn.palmte.work.utils.StrKit; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import org.activiti.bpmn.converter.BpmnXMLConverter; import org.activiti.bpmn.model.*; import org.activiti.bpmn.model.Process; import org.activiti.editor.language.json.converter.BpmnJsonConverter; import org.activiti.engine.RepositoryService; import org.activiti.engine.delegate.BaseExecutionListener; import org.activiti.engine.delegate.TaskListener; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.DeploymentBuilder; import org.activiti.engine.repository.Model; import org.activiti.engine.repository.ProcessDefinition; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import top.jfunc.common.db.QueryHelper; import top.jfunc.common.db.bean.Page; import top.jfunc.common.db.utils.Pagination; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @Service public class ActModelService { private static final Logger logger = LoggerFactory.getLogger(ActModelService.class); @Autowired private RepositoryService repositoryService; //管理流程定义 与流程定义和部署对象相关的Service @Autowired private ActTaskDefRepository actTaskDefRepository; @Autowired Pagination pagination; public Page list(ConcurrentHashMap searchInfo, int pageNumber, int pageSize) { String select = "a.ID_ as id,a.REV_ as rev,a.NAME_ as modelName,a.KEY_ as procDefKey,a.CREATE_TIME_ as createdTime,a.LAST_UPDATE_TIME_ as lastUpdatedTime"; QueryHelper queryHelper = new QueryHelper(select, " act_re_model a"); String name = searchInfo.get("name"); queryHelper.addCondition(StringUtils.isNotEmpty(name), "(a.NAME_ like ? or a.KEY_ like ?)", "'%" + name + "%'", "'%" + name + "%'"); queryHelper.addOrderProperty("a.LAST_UPDATE_TIME_", false); return pagination.paginate(queryHelper.getSql(), ActModel.class, pageNumber, pageSize); } public ActModel findByProcDefKey(String procDefKey) { return pagination.findFirst("select * from act_re_model where KEY_=? ", ActModel.class, procDefKey); } public void createModel(String processId, String modelName) throws Exception { ObjectMapper objectMapper = new ObjectMapper(); ObjectNode editorNode = objectMapper.createObjectNode(); editorNode.put("id", "canvs"); editorNode.put("resourceId", "canvs"); ObjectNode stencilSetNode = objectMapper.createObjectNode(); stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#"); //命名空间(禁止修改) stencilSetNode.put("author", ""); //流程节点作者 editorNode.set("stencilset", stencilSetNode); ObjectNode propertiesNode = objectMapper.createObjectNode(); propertiesNode.put("process_id", processId); //流程唯一标识 propertiesNode.put("process_author", InterfaceUtil.getAdmin().getUserName()); //流程作者 propertiesNode.put("name", modelName); //流程名称 editorNode.set("properties", propertiesNode); ObjectNode modelObjectNode = objectMapper.createObjectNode(); modelObjectNode.put("name", modelName); //模型名称 modelObjectNode.put("revision", 1); //模型版本 modelObjectNode.put("description", ""); //模型描述 Model modelData = repositoryService.newModel(); //modelData.setCategory(category); //模型分类 modelData.setDeploymentId(null); modelData.setKey(processId); modelData.setMetaInfo(modelObjectNode.toString()); modelData.setName(modelName); //模型名称 modelData.setTenantId(""); modelData.setVersion(1); //保存模型,存储数据到表:act_re_model 流程设计模型部署表 repositoryService.saveModel(modelData); repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));//保存资源,存储数据到表:act_ge_bytearray 二进制数据表 } /** * 删除模型 * act_re_model 和 act_ge_bytearray 两张表中相关数据都删除 * * @param modelId */ public void deleteModel(String modelId) { repositoryService.deleteModel(modelId); } /** * 部署流程 * * @param modelId * @throws Exception */ public void deploy(String modelId) throws Exception { Model modelData = repositoryService.getModel(modelId); JSONObject metaInfo = JSON.parseObject(modelData.getMetaInfo()); String description = metaInfo.getString("description"); ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId())); byte[] bpmnBytes = null; BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); BpmnModel model = jsonConverter.convertToBpmnModel(modelNode); List taskList = new ArrayList<>(); Process process = model.getMainProcess(); Collection flowElements = process.getFlowElements(); //设置流程监听器 setExecutionListener(process); int i = 0; ActTaskDef taskDef; ActTaskDef first = null; for (FlowElement element : flowElements) { if (element instanceof UserTask) { UserTask userTaskElement = (UserTask) element; taskDef = new ActTaskDef(); taskDef.setTaskName(element.getName()); taskDef.setTaskKey(element.getId()); MultiInstanceLoopCharacteristics loopCharacteristics = userTaskElement.getLoopCharacteristics(); if (loopCharacteristics != null) { //多实列 taskDef.setTaskType(ActConstant.TASK_TYPE_MULTI); }else { taskDef.setTaskType(ActConstant.TASK_TYPE_SINGE); } //任务监听器 setTaskListener(userTaskElement); if (i == 1) {//画流程图时,要保证第一个用户任务一定要先画 taskDef.setTaskIndex(ActTaskIndexEnum.FIRST_USER_TASK.getIndex()); first = taskDef; } taskList.add(taskDef); } i ++; } bpmnBytes = new BpmnXMLConverter().convertToXML(model); String processName = modelData.getName() + ".bpmn20.xml"; DeploymentBuilder deploymentBuilder = repositoryService.createDeployment().name(modelData.getName()); //部署名称 deploymentBuilder.addString(processName, new String(bpmnBytes, "utf-8")); Deployment deployment = deploymentBuilder.deploy(); //完成部署 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult(); for (ActTaskDef actTaskDef : taskList) { if (first != null) { actTaskDef.setRollbackTaskKey(first.getTaskKey()); } actTaskDef.setProcDefId(processDefinition.getId()); actTaskDef.setProcDefName(processDefinition.getName()); actTaskDef.setProcDefKey(processDefinition.getKey()); actTaskDef.setCreatedTime(new Date()); actTaskDef.setLastUpdatedTime(new Date()); } //更新流程定义的描述 if(StrKit.notBlank(description)){ actTaskDefRepository.updateProcDefDesc(description, processDefinition.getId()); } actTaskDefRepository.save(taskList); logger.info("deploy success: deploymentId:{}, procDefName:{}, procDefKey:{}", deployment.getId(), processDefinition.getName(), processDefinition.getKey()); } private void setTaskListener(UserTask userTaskElement) { ActivitiListener taskListener = new ActivitiListener(); taskListener.setEvent(TaskListener.EVENTNAME_CREATE); taskListener.setImplementation("${actListenerService.create(task)}"); taskListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION); List taskListenerList = new ArrayList<>(1); taskListenerList.add(taskListener); userTaskElement.setTaskListeners(taskListenerList); } private void setExecutionListener(Process process) { ActivitiListener executionListener = new ActivitiListener(); executionListener.setEvent(BaseExecutionListener.EVENTNAME_END); executionListener.setImplementation("${actListenerService.end(execution)}"); executionListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION); List executionListenerList = new ArrayList<>(1); executionListenerList.add(executionListener); process.setExecutionListeners(executionListenerList); } }