Activity7动态创建工作流

package org.example.core;

import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.repository.Deployment;
import org.activiti.bpmn.model.*;

import org.apache.commons.io.FileUtils;
import org.example.listener.FlowEndListener;
import org.example.listener.TaskCompleteListener;
import org.example.listener.TaskCreateListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 动态Bpmn服务
 */
@Service
public class DynamicWorkflowService {

    @Autowired
    private RepositoryService repositoryService;/**
     * 动态创建和部署工作流
     */
    public void createWorkflowAndDeploy() {
        // 创建一个新的BPMN模型
        BpmnModel bpmnModel = new BpmnModel();
        Process process = new Process();
        bpmnModel.addProcess(process);
        process.setId("flowDefId");
        process.setName("流程名称");

        // 添加开始事件
        StartEvent startEvent = new StartEvent();
        startEvent.setId("START");
        startEvent.setName("开始");
        process.addFlowElement(startEvent);

        // 添加用户任务
        UserTask userTask1 = createUserTask("userTask1", "User Task 1", "user1");
        process.addFlowElement(userTask1);
        UserTask userTask2 = createUserTask("userTask2", "User Task 2", "user2");
        process.addFlowElement(userTask2);
        UserTask userTask3 = createUserTask("userTask3", "User Task 3", "user3");
        process.addFlowElement(userTask3);

        // 添加结束事件
        EndEvent endEvent = createEndEvent("END", "结束");
        process.addFlowElement(endEvent);

        // 添加顺序流转
        SequenceFlow sequenceFlow1 = new SequenceFlow("START", "userTask1");
        sequenceFlow1.setId("flow1");
        SequenceFlow sequenceFlow2 = new SequenceFlow("userTask1", "userTask2");
        sequenceFlow2.setId("flow2");
        sequenceFlow2.setName("通过");
        SequenceFlow sequenceFlow3 = new SequenceFlow("userTask2", "userTask3");
        sequenceFlow3.setId("flow3");
        sequenceFlow3.setName("通过");
        SequenceFlow sequenceFlow4 = new SequenceFlow("userTask3", "END");
        sequenceFlow4.setId("flow4");
        sequenceFlow4.setName("通过");

        SequenceFlow rejectFlow1 = new SequenceFlow("userTask2", "userTask1");
        rejectFlow1.setName("驳回");
        rejectFlow1.setId("rejectFlow1");
        SequenceFlow rejectFlow2 = new SequenceFlow("userTask3", "END");
        rejectFlow2.setName("驳回");
        rejectFlow2.setId("rejectFlow2");

        process.addFlowElement(sequenceFlow1);
        process.addFlowElement(sequenceFlow2);
        process.addFlowElement(sequenceFlow3);
        process.addFlowElement(sequenceFlow4);
        process.addFlowElement(rejectFlow1);
        process.addFlowElement(rejectFlow2);

        List<String> taskNodeIds = Arrays.asList(userTask1.getId(), userTask2.getId(), userTask3.getId());
        List<String> flowIds = Arrays.asList(sequenceFlow1.getId(), sequenceFlow2.getId(), sequenceFlow3.getId(), sequenceFlow4.getId());
        List<SequenceFlow> rejectFlows = Arrays.asList(rejectFlow1, rejectFlow2);
        addBpmnDiInfo(bpmnModel, taskNodeIds, flowIds, rejectFlows);


        // 将BPMN模型转换为XML格式
        BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
        byte[] bpmnBytes = bpmnXMLConverter.convertToXML(bpmnModel);


        // 将BPMN XML保存到文件系统
        try {
            FileUtils.writeByteArrayToFile(new File("dynamic-process.bpmn20.xml"), bpmnBytes);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        // 部署BPMN模型
        Deployment deployment = repositoryService.createDeployment()
                .addBytes("dynamic-process.bpmn20.xml", bpmnBytes)
                .name("Dynamic Process Deployment")
                .deploy();

    }


    private UserTask createUserTask(String id, String name, String assignee) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        userTask.setAssignee(assignee);

        // 添加任务创建事件监听器
        ActivitiListener createListener = new ActivitiListener();
        createListener.setEvent(TaskListener.EVENTNAME_CREATE);
        createListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
        createListener.setImplementation(TaskCreateListener.class.getName());
        userTask.getTaskListeners().add(createListener);

        // 添加任务完成事件监听器
        ActivitiListener completeListener = new ActivitiListener();
        completeListener.setEvent(TaskListener.EVENTNAME_COMPLETE);
        completeListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
        completeListener.setImplementation(TaskCompleteListener.class.getName());
        userTask.getTaskListeners().add(completeListener);

        return userTask;
    }


    private EndEvent createEndEvent(String id, String name) {
        EndEvent endEvent = new EndEvent();
        endEvent.setId(id);
        endEvent.setName(name);

        // 添加执行结束事件监听器
        ActivitiListener endListener = new ActivitiListener();
        endListener.setEvent(ExecutionListener.EVENTNAME_END);
        endListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
        endListener.setImplementation(FlowEndListener.class.getName());
        endEvent.getExecutionListeners().add(endListener);
        return endEvent;
    }


    private static void addBpmnDiInfo(BpmnModel model, List<String> taskNodeIds, List<String> flowIds, List<SequenceFlow> rejectFlows) {
        double x = 100;
        double y = 100;
        double startEndWidth = 30;
        double startEndHeight = 30;
        double taskWidth = 100;
        double taskHeight = 60;
        double gap = 100;
        double startX = x;
        double startEndY = y + (taskHeight - startEndHeight) / 2.0;
        //画节点
        model.addGraphicInfo("START", createGraphicInfo(startX, startEndY, startEndWidth, startEndHeight));
        x = x + startEndWidth + gap;
        for (String taskNodeId : taskNodeIds) {
            model.addGraphicInfo(taskNodeId, createGraphicInfo(x, y, taskWidth, taskHeight));
            x = x + taskWidth + gap;
        }
        model.addGraphicInfo("END", createGraphicInfo(x, startEndY, startEndWidth, startEndHeight));

        //画前进线
        double point1X = startX + startEndWidth;
        double pointY = y + taskHeight / 2.0;
        double point2X = point1X + gap;
        for (String flowId : flowIds) {
            model.addFlowGraphicInfoList(flowId, createFlowGraphicInfo(point1X, pointY, point2X, pointY));
            point1X = (point2X + taskWidth);
            point2X = (point1X + gap);
        }

        //画后退线
        int rejectHeightGap = 30;
        int i = 0;
        for (SequenceFlow rejectFlow : rejectFlows) {
            String fromTaskNodeId = rejectFlow.getSourceRef();
            String toTaskNodeId = rejectFlow.getTargetRef();
            int formIndex = taskNodeIds.indexOf(fromTaskNodeId);
            int toIndex = taskNodeIds.indexOf(toTaskNodeId);
            double x1 = getRejectStartX(startEndWidth, taskWidth, gap, startX, formIndex);
            double y1 = y + taskHeight;
            double x2 = x1;
            double y2 = y1 + 30 + i * rejectHeightGap;
            double x4 = getRejectEndX(startEndWidth, taskWidth, gap, startX, toIndex, taskNodeIds.size());
            double y4 = y1;
            double x3 = x4;
            double y3 = y2;
            model.addFlowGraphicInfoList(rejectFlow.getId(), createFlowGraphicInfo(x1, y1, x2, y2, x3, y3, x4, y4));
            i++;
        }
    }

    private static double getRejectStartX(double startEndWidth, double taskWidth, double gap, double startX, int taskIndex) {
        return startX + startEndWidth + (taskIndex + 1) * gap + taskIndex * taskWidth + taskWidth / 2.0;
    }

    private static double getRejectEndX(double startEndWidth, double taskWidth, double gap, double startX, int taskIndex, int taskSize) {
        if (taskIndex != -1) {
            //打回到指定任务
            return getRejectStartX(startEndWidth, taskWidth, gap, startX, taskIndex);
        } else {
            //打回到结束
            return startX + startEndWidth + (taskSize + 1) * gap + taskSize * taskWidth + startEndWidth / 2.0;
        }
    }

    private static GraphicInfo createGraphicInfo(double x, double y, double width, double height) {
        GraphicInfo graphicInfo = new GraphicInfo();
        graphicInfo.setX(x);
        graphicInfo.setY(y);
        graphicInfo.setWidth(width);
        graphicInfo.setHeight(height);
        return graphicInfo;
    }

    private static List<GraphicInfo> createFlowGraphicInfo(double... waypoints) {
        List<GraphicInfo> flowGraphicInfoList = new ArrayList<>();
        for (int i = 0; i < waypoints.length; i += 2) {
            GraphicInfo graphicInfo = new GraphicInfo();
            graphicInfo.setX(waypoints[i]);
            graphicInfo.setY(waypoints[i + 1]);
            flowGraphicInfoList.add(graphicInfo);
        }
        return flowGraphicInfoList;
    }

}

 

posted @ 2024-07-02 15:19  追极  阅读(6)  评论(0编辑  收藏  举报