springboot2+activiti7+bpmn-js使用入门

本示例使用springboot2+activiti7+bpmn-js(vue+elementUI)环境;

官网:https://www.activiti.org/

搭建

  • 首先搭建好springboot项目的开发环境;

  • 添加maven依赖(目前git上最新版是7.1.0.M13,但是我在阿里云的maven仓库里找到的最新的是7.1.0.M6)

  • <properties>
        <java.version>1.8</java.version>
        <activiti.version>7.1.0.M6</activiti.version>
    </properties>
    <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>1.4.01</version>
    </dependency>
    <dependency>
        <groupId>org.activiti.dependencies</groupId>
        <artifactId>activiti-dependencies</artifactId>
        <version>${activiti.version}</version>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-spring-boot-starter</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-image-generator</artifactId>
        <version>${activiti.version}</version>
    </dependency>
  • 修改application.properties

# activiti配置
# 自动部署验证设置:true-开启(默认)、false-关闭
spring.activiti.check-process-definitions=false
# 自动创建表
# spring.activiti.database-schema-update=drop-create
spring.activiti.database-schema-update=false
# 使用历史表
spring.activiti.db-history-used=true
spring.activiti.history-level=full
# 关闭自动部署
spring.activiti.deployment-mode=never-fail
# 自动部署文件路径前后缀
# spring.activiti.process-definition-location-prefix=classpath:/process/
# spring.activiti.process-definition-location-suffixes=**.bpmn,**.bpmn20.xml
  • 启动类@SpringBootApplication注解加一下参数(关闭activiti自带的权限)

@SpringBootApplication(exclude = {
        org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
        org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class
})

到此就可以读取指定目录下的流程配置文件使用流程了(我这里没用这种方式)。

表结构和组件

activiti工作流总共包含25张表,都已act_开头(activiti7与老版本的activiti表结构还是有些小变化的);其中:


ACT_GE_:通用,用在各种情况下,2张;

ACT_HI_:历史,8张,默认提供了4种历史级别:

none:不保存历史记录,性能最好;

activity:保存流程实例、任务、活动信息;

audit:默认,保存实例、任务、活动、表单属性;

full:保存完整的历史记录;

ACT_RE_:仓库,3张,保存一些静态信息,如流程定义、资源(图片,规则等);

ACT_RU_:运行,10张,保存流程实例、任务、变量等运行时数据,流程结束后会立即移除数据;

还有两张:ACT_EVT_LOG:存储事件处理日志;ACT_PROCDEF_INFO:流程定义信息;

(老版本的activiti少了4张ACT_RU_,多了4张ACT_ID_的表(用于管理用户和用户组,作用不大))


常用的流程服务组件有:


RepositoryService:提供管理流程定义和部署的API;

RuntimeService:在流程运行时对流程实例进行管理与控制;

TaskService:对流程任务进行管理,如:任务提醒、任务完成和创建;

ManagementService:提供对流程引擎进行管理和维护的服务;

HistoryService:对流程历史数据进行操作;

DynamicBpmnService:实现在不重新部署流程的情况下对流程模型进行部分修改;

流程设计器

依赖

首先需要搭建好vue+elementUI的开发环境;

安装:yarn add bpmn-js bpmn-js-properties-panel(注意bpmn-js的版本不能太高,不然整合activiti可能会报错,我这里使用的这个版本)

"bpmn-js": "~7.5.0",
"bpmn-js-properties-panel": "~0.43.1",

整合activiti

bpmn-js整合activiti需要下面这个json

{
  "name": "Activiti",
  "uri": "http://activiti.org/bpmn",
  "prefix": "activiti",
  "xml": {
    "tagAlias": "lowerCase"
  },
  "associations": [],
  "types": [
    {
      "name": "Definitions",
      "isAbstract": true,
      "extends": [
        "bpmn:Definitions"
      ],
      "properties": [
        {
          "name": "diagramRelationId",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "InOutBinding",
      "superClass": [
        "Element"
      ],
      "isAbstract": true,
      "properties": [
        {
          "name": "source",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "sourceExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "target",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "businessKey",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "local",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "variables",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "In",
      "superClass": [
        "InOutBinding"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:CallActivity"
        ]
      }
    },
    {
      "name": "Out",
      "superClass": [
        "InOutBinding"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:CallActivity"
        ]
      }
    },
    {
      "name": "AsyncCapable",
      "isAbstract": true,
      "extends": [
        "bpmn:Activity",
        "bpmn:Gateway",
        "bpmn:Event"
      ],
      "properties": [
        {
          "name": "async",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "asyncBefore",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "asyncAfter",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "exclusive",
          "isAttr": true,
          "type": "Boolean",
          "default": true
        }
      ]
    },
    {
      "name": "JobPriorized",
      "isAbstract": true,
      "extends": [
        "bpmn:Process",
        "activiti:AsyncCapable"
      ],
      "properties": [
        {
          "name": "jobPriority",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "SignalEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:SignalEventDefinition"
      ],
      "properties": [
        {
          "name": "async",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        }
      ]
    },
    {
      "name": "ErrorEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:ErrorEventDefinition"
      ],
      "properties": [
        {
          "name": "errorCodeVariable",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "errorMessageVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Error",
      "isAbstract": true,
      "extends": [
        "bpmn:Error"
      ],
      "properties": [
        {
          "name": "activiti:errorMessage",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "PotentialStarter",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "resourceAssignmentExpression",
          "type": "bpmn:ResourceAssignmentExpression"
        }
      ]
    },
    {
      "name": "FormSupported",
      "isAbstract": true,
      "extends": [
        "bpmn:StartEvent",
        "bpmn:UserTask"
      ],
      "properties": [
        {
          "name": "formHandlerClass",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "formKey",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "TemplateSupported",
      "isAbstract": true,
      "extends": [
        "bpmn:Process",
        "bpmn:FlowElement"
      ],
      "properties": [
        {
          "name": "modelerTemplate",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Initiator",
      "isAbstract": true,
      "extends": [
        "bpmn:StartEvent"
      ],
      "properties": [
        {
          "name": "initiator",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ScriptTask",
      "isAbstract": true,
      "extends": [
        "bpmn:ScriptTask"
      ],
      "properties": [
        {
          "name": "resultVariable",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "resource",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Process",
      "isAbstract": true,
      "extends": [
        "bpmn:Process"
      ],
      "properties": [
        {
          "name": "candidateStarterGroups",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "candidateStarterUsers",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "versionTag",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "historyTimeToLive",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "isStartableInTasklist",
          "isAttr": true,
          "type": "Boolean",
          "default": true
        },
        {
          "name": "executionListener",
          "isAbstract": true,
          "type": "Expression"
        }
      ]
    },
    {
      "name": "EscalationEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:EscalationEventDefinition"
      ],
      "properties": [
        {
          "name": "escalationCodeVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "FormalExpression",
      "isAbstract": true,
      "extends": [
        "bpmn:FormalExpression"
      ],
      "properties": [
        {
          "name": "resource",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "multiinstance_type",
      "superClass": [
        "Element"
      ]
    },
    {
      "name": "multiinstance_condition",
      "superClass": [
        "Element"
      ]
    },
    {
      "name": "Assignable",
      "extends": [
        "bpmn:UserTask"
      ],
      "properties": [
        {
          "name": "assignee",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "candidateUsers",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "candidateGroups",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "dueDate",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "followUpDate",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "priority",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "multiinstance_condition",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "CallActivity",
      "extends": [
        "bpmn:CallActivity"
      ],
      "properties": [
        {
          "name": "calledElementBinding",
          "isAttr": true,
          "type": "String",
          "default": "latest"
        },
        {
          "name": "calledElementVersion",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "calledElementVersionTag",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "calledElementTenantId",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "caseRef",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "caseBinding",
          "isAttr": true,
          "type": "String",
          "default": "latest"
        },
        {
          "name": "caseVersion",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "caseTenantId",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "variableMappingClass",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "variableMappingDelegateExpression",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ServiceTaskLike",
      "extends": [
        "bpmn:ServiceTask",
        "bpmn:BusinessRuleTask",
        "bpmn:SendTask",
        "bpmn:MessageEventDefinition"
      ],
      "properties": [
        {
          "name": "expression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "class",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "delegateExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "resultVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "DmnCapable",
      "extends": [
        "bpmn:BusinessRuleTask"
      ],
      "properties": [
        {
          "name": "decisionRef",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "decisionRefBinding",
          "isAttr": true,
          "type": "String",
          "default": "latest"
        },
        {
          "name": "decisionRefVersion",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "mapDecisionResult",
          "isAttr": true,
          "type": "String",
          "default": "resultList"
        },
        {
          "name": "decisionRefTenantId",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ExternalCapable",
      "extends": [
        "activiti:ServiceTaskLike"
      ],
      "properties": [
        {
          "name": "type",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "topic",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "TaskPriorized",
      "extends": [
        "bpmn:Process",
        "activiti:ExternalCapable"
      ],
      "properties": [
        {
          "name": "taskPriority",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Properties",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "*"
        ]
      },
      "properties": [
        {
          "name": "values",
          "type": "Property",
          "isMany": true
        }
      ]
    },
    {
      "name": "Property",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "id",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "value",
          "type": "String",
          "isAttr": true
        }
      ]
    },
    {
      "name": "Connector",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "activiti:ServiceTaskLike"
        ]
      },
      "properties": [
        {
          "name": "inputOutput",
          "type": "InputOutput"
        },
        {
          "name": "connectorId",
          "type": "String"
        }
      ]
    },
    {
      "name": "InputOutput",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:FlowNode",
          "activiti:Connector"
        ]
      },
      "properties": [
        {
          "name": "inputOutput",
          "type": "InputOutput"
        },
        {
          "name": "connectorId",
          "type": "String"
        },
        {
          "name": "inputParameters",
          "isMany": true,
          "type": "InputParameter"
        },
        {
          "name": "outputParameters",
          "isMany": true,
          "type": "OutputParameter"
        }
      ]
    },
    {
      "name": "InputOutputParameter",
      "properties": [
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        },
        {
          "name": "definition",
          "type": "InputOutputParameterDefinition"
        }
      ]
    },
    {
      "name": "InputOutputParameterDefinition",
      "isAbstract": true
    },
    {
      "name": "List",
      "superClass": [
        "InputOutputParameterDefinition"
      ],
      "properties": [
        {
          "name": "items",
          "isMany": true,
          "type": "InputOutputParameterDefinition"
        }
      ]
    },
    {
      "name": "Map",
      "superClass": [
        "InputOutputParameterDefinition"
      ],
      "properties": [
        {
          "name": "entries",
          "isMany": true,
          "type": "Entry"
        }
      ]
    },
    {
      "name": "Entry",
      "properties": [
        {
          "name": "key",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        },
        {
          "name": "definition",
          "type": "InputOutputParameterDefinition"
        }
      ]
    },
    {
      "name": "Value",
      "superClass": [
        "InputOutputParameterDefinition"
      ],
      "properties": [
        {
          "name": "id",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Script",
      "superClass": [
        "InputOutputParameterDefinition"
      ],
      "properties": [
        {
          "name": "scriptFormat",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "resource",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Field",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "activiti:ServiceTaskLike",
          "activiti:ExecutionListener",
          "activiti:TaskListener"
        ]
      },
      "properties": [
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "expression",
          "type": "String"
        },
        {
          "name": "stringValue",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "string",
          "type": "String"
        }
      ]
    },
    {
      "name": "InputParameter",
      "superClass": [
        "InputOutputParameter"
      ]
    },
    {
      "name": "OutputParameter",
      "superClass": [
        "InputOutputParameter"
      ]
    },
    {
      "name": "Collectable",
      "isAbstract": true,
      "extends": [
        "bpmn:MultiInstanceLoopCharacteristics"
      ],
      "superClass": [
        "activiti:AsyncCapable"
      ],
      "properties": [
        {
          "name": "collection",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "elementVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "FailedJobRetryTimeCycle",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "activiti:AsyncCapable",
          "bpmn:MultiInstanceLoopCharacteristics"
        ]
      },
      "properties": [
        {
          "name": "body",
          "isBody": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ExecutionListener",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:Task",
          "bpmn:ServiceTask",
          "bpmn:UserTask",
          "bpmn:BusinessRuleTask",
          "bpmn:ScriptTask",
          "bpmn:ReceiveTask",
          "bpmn:ManualTask",
          "bpmn:ExclusiveGateway",
          "bpmn:SequenceFlow",
          "bpmn:ParallelGateway",
          "bpmn:InclusiveGateway",
          "bpmn:EventBasedGateway",
          "bpmn:StartEvent",
          "bpmn:IntermediateCatchEvent",
          "bpmn:IntermediateThrowEvent",
          "bpmn:EndEvent",
          "bpmn:BoundaryEvent",
          "bpmn:CallActivity",
          "bpmn:SubProcess",
          "bpmn:Process"
        ]
      },
      "properties": [
        {
          "name": "expression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "class",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "delegateExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "event",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "script",
          "type": "Script"
        },
        {
          "name": "fields",
          "type": "Field",
          "isMany": true
        }
      ]
    },
    {
      "name": "TaskListener",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:UserTask"
        ]
      },
      "properties": [
        {
          "name": "expression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "class",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "delegateExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "event",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "script",
          "type": "Script"
        },
        {
          "name": "fields",
          "type": "Field",
          "isMany": true
        }
      ]
    },
    {
      "name": "FormProperty",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:StartEvent",
          "bpmn:UserTask"
        ]
      },
      "properties": [
        {
          "name": "id",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "type",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "required",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "readable",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "writable",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "variable",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "expression",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "datePattern",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "default",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "values",
          "type": "Value",
          "isMany": true
        }
      ]
    },
    {
      "name": "FormProperty",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "id",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "label",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "type",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "datePattern",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "defaultValue",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "properties",
          "type": "Properties"
        },
        {
          "name": "validation",
          "type": "Validation"
        },
        {
          "name": "values",
          "type": "Value",
          "isMany": true
        }
      ]
    },
    {
      "name": "Validation",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "constraints",
          "type": "Constraint",
          "isMany": true
        }
      ]
    },
    {
      "name": "Constraint",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "config",
          "type": "String",
          "isAttr": true
        }
      ]
    },
    {
      "name": "ConditionalEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:ConditionalEventDefinition"
      ],
      "properties": [
        {
          "name": "variableName",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "variableEvent",
          "isAttr": true,
          "type": "String"
        }
      ]
    }
  ],
  "emumerations": []
}

使用

<template>
  <div style="width: 100%; height: 100%">
    <div ref="bpmn" style="width: 100%; height: 100%;"></div>
    <div ref="panel" class="panel"></div>
    <button @click="showSave = true" class="saveBtn" style="margin-left: -50px;">保存</button>
    <button @click="loadData" class="saveBtn" style="margin-left: 50px;">重置</button>
    
    <el-dialog title="保存流程图" :visible.sync="showSave">
      <el-form :model="model">
        <el-form-item label="key">
          <el-input v-model="model.key" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="name">
          <el-input v-model="model.name" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showSave = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  
  // 这个只能预览
  // import BpmnViewer from 'bpmn-js/lib/Viewer'
  import Modeler from 'bpmn-js/lib/Modeler'
  // 面板
  import propertiesPanelModule from 'bpmn-js-properties-panel'
  import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/bpmn'
  // 适应activiti
  import activiti from '@/components/activiti/activiti.json'
  // 汉化
  /// import customTranslate from '@/components/activiti/customTranslate.js'
  
  export default {
    data() {
      return {
        showSave: false, model: {id: '', key: '', name: '', xml: ''}, modeler: null
      }
    },
    mounted() {
      this.modeler = new Modeler({
        container: this.$refs.bpmn, propertiesPanel: {parent: this.$refs.panel},
        additionalModules: [
          propertiesPanelModule, propertiesProviderModule,
          /// {translate: ['value', customTranslate]}
        ],
        moddleExtensions: {
          activiti: activiti
        }
      })
      this.loadData()
    },
    methods: {
      loadData() {
        this.model.id = this.$route.query.id
        new Promise(resolve => {
          if (this.model.id) {
            this.$apis.act.act.getModel.req({id: this.model.id}).then(res => {
              if (res.data && res.data.metaInfo) {
                this.model = res.data
              }
              resolve(this.model.metaInfo)
            })
          } else {
            resolve()
          }
        }).then(xml => {
          xml ? this.modeler.importXML(xml) : this.modeler.createDiagram()
        })
      },
      save() {
        this.modeler.saveXML().then(xml => {
          this.model.xml = xml.xml
          this.$apis.act.act.saveModel.req(this.model).then(res => {
            this.$message({type: 'success', message: '成功'})
            this.$router.push({path: '/bpmn/modelEdit', query: {id: res.data.id}})
            this.loadData()
          })
        })
        /*this.modeler.saveSVG().then(b => {
          console.log(b)
        })*/
      },
    }
  }
</script>

<style scoped>
  /* 基础样式 */
  @import '~bpmn-js/dist/assets/diagram-js.css';
  @import '~bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
  @import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
  @import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
  /* 右侧面板样式 */
  @import '~bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css';
  
  .saveBtn {
    position: absolute;
    top: 80%;
    left: 50%;
    padding: 12px 16px;
    border-radius: 10px;
    font-size: 18px;
    cursor: pointer;
  }
  
  .panel {
    position: absolute;
    box-sizing: border-box;
    width: 400px;
    height: 100%;
    padding: 10px 15px;
    top: 80px;
    right: 15px;
    overflow: auto;
  }
</style>

API

数据查询

activiti的每一个服务组件都有一个query对象,可以通过服务组件的createXxxQuery方法得到;可用于查询流程数据(可以查询model、部署的流程、流程实例、流程历史等信息),这里就不细说了;

保存流程设计

@PostMapping("/saveModel")
@ApiOperation("保存流程")
public R<String> saveModel(String id, String name, String xml) {
    Model model = repositoryService.getModel(id);
    if (model == null) {
        model = repositoryService.newModel();
    }
    model.setMetaInfo(xml);
    model.setName(name);
    model.setKey("testKey");
    //保存模型
    repositoryService.saveModel(model);
    return R.success(model.getId());
}


部署

流程部署可以根据model、xml、zip等不同的数据源来部署,这里是根据流程设计器保存的提供的xml来部署流程,部署成功后会在ACT_RE_的部分表中有体现。

@GetMapping("/deploy")
@ApiOperation("部署流程")
public R<String> deploy(String modelId) {
    Model model = repositoryService.getModel(modelId);
    String deploymentId = model.getDeploymentId();
    if (StringUtils.hasText(deploymentId)) {
        return R.error("流程已部署" + deploymentId);
    }
    // 部署流程
    Deployment deployment = repositoryService.createDeployment().name(model.getName()).key(model.getKey())
        .addString(model.getName() + ".bpmn20.xml", model.getMetaInfo()).deploy();
    model.setDeploymentId(deployment.getId());
    repositoryService.saveModel(model);
    return R.success(deployment.getId());
}

启动

@GetMapping("/start")
@ApiOperation("启动流程")
public R<String> start(String deploymentId, String businessKey) {
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .deploymentId(deploymentId).active().latestVersion().singleResult();
    List<ProcessInstance> list = runtimeService.createProcessInstanceQuery()
        .processDefinitionId(processDefinition.getId()).processInstanceBusinessKey(businessKey).list();
    if (list != null && !list.isEmpty()) {
        return R.error("businessKey重复");
    }
    // 启动流程
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessKey);
    return R.success(processInstance.getId());
}

审批

@GetMapping("/audit")
@ApiOperation("审核流程")
public R audit(String processInstanceId) {
    Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
    if (task == null) {
        return R.error("任务不存在");
    }
    // 通过
    taskService.complete(task.getId());
    // 驳回
    /// taskService.resolveTask(task.getId());
    return R.success();
}

流程图

这里返回的是svg图片

@GetMapping("/img")
@ApiOperation("流程图")
public R<String> img(String defId, String businessKey) throws IOException {
    BpmnModel bpmnModel = repositoryService.getBpmnModel(defId);
    List<String> activityIds = new ArrayList<>();
    HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();
    List<HistoricActivityInstance> list1 = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstance.getId()).list();
    for (HistoricActivityInstance instance : list1) {
        activityIds.add(instance.getActivityId());
    }
    ProcessDiagramGenerator imageGenerator = new DefaultProcessDiagramGenerator();
    String activityFontName = "宋体";
    String labelFontName = "宋体";
    String annotationFontName = "宋体";
    Process process = bpmnModel.getMainProcess();
    List<String> flows = new ArrayList<>();
    for (FlowElement flowElement : process.getFlowElements()) {
        boolean isExecute = (flowElement instanceof Activity || flowElement instanceof Event) && activityIds.contains(flowElement.getId());
        if (isExecute) {
            flows.addAll(((FlowNode) flowElement).getIncomingFlows().stream().map(BaseElement::getId).collect(Collectors.toList()));
        }
    }
    InputStream is = imageGenerator.generateDiagram(bpmnModel, activityIds, flows,
                                                    activityFontName, labelFontName, annotationFontName, true);
    byte[] bytes = new byte[is.available()];
    int len = is.read(bytes);
    is.close();
    String svgImg = new String(bytes, 0, len);
    return R.success(svgImg);
}


到此,一个简单的流程就可以使用上面的api来操作了。

转自:https://blog.csdn.net/nzgry_csdn/article/details/118342217