前期准备工作
画流程图
访问modeler工程: http://localhost:8888/flowable-modeler 使用账号 admin/test进行登录
点击创建流程
流程图名称只能为英文, 描述可以为中文
创建活动节点,点击开始节点,点击任务头像
确定动作
确定动作的编号,点击节点,设置id值
在启动流程之后调用接口根据动作设置执行者的用户id
确定流程的逻辑的实现:
依次执行直接:连线即可,如果需要判断条件需要点击该连线设置Flow condition的值
如果该逻辑有多个可能:
不管怎么样,只有一个会执行:
使用排他网关,Gateways->Exclusive gateway 拖动到右边即可,可以默认执行线,点击线条,在下方点击Default flow
多个都要执行完成:
使用并行网关,Gateways->Parallel gateway 拖动到右边即可,每条线可以设置一个判断条件,并且必须在使用完并行网关之后再使用一个并行网关把上一个网关连出的线再连进来并由该这个将线连出
最后一个节点需要设置一个结束节点,图标为0
最后保存该文件并且下载bpmn xml文件
php端如何使用
前缀: http://host:port/flowable-rest
部署模板
请求: POST /service/repository/deployments
{
file:文件 //模板文件
}
响应:
201成功,已创建
500服务器异常
模拟响应
{
"id": "6c795214-44cf-11e9-96df-7845c42f05a4",
"name": "常规商品生产模型",
"deploymentTime": "2019-03-12T22:02:08.032+08:00",
"category": null,
"parentDeploymentId": null,
"url": "http://localhost:8086/flowable-rest/service/repository/deployments/6c795214-44cf-11e9-96df-7845c42f05a4",
"tenantId": ""
}
启动流程
请求: POST /service/runtime/process-instances
{
"processDefinitionKey":"generalProductModel", // 模板码
}
响应:
201成功,已创建,已部署
400失败:
入参未传
入参类型不对
数据库中不存在该processDefinitionId的值
500失败:
该模板被挂起
{
"id": "881b2d91-4555-11e9-98f8-7845c42f05a4",
"url": "http://localhost:8086/flowable-rest/service/runtime/process-instances/881b2d91-4555-11e9-98f8-7845c42f05a4",
"name": null,
"businessKey": null,
"suspended": false,
"ended": false,
"processDefinitionId": "generalProductModel:1:3cc0c24b-44d1-11e9-96df-7845c42f05a4",
"processDefinitionUrl": "http://localhost:8086/flowable-rest/service/repository/process-definitions/generalProductModel:1:3cc0c24b-44d1-11e9-96df-7845c42f05a4",
"processDefinitionName": "常规商品生产模型",
"processDefinitionDescription": "常规商品生产模型",
"activityId": null,
"startUserId": null,
"startTime": "2019-03-13T14:02:06.953+08:00",
"variables": [],
"callbackId": null,
"callbackType": null,
"tenantId": "",
"completed": false
}
从中取出流程id作为流程实例id (后续操作会用到)
模拟请求:
{
"processDefinitionKey":"generalProductModel"
}
查看节点和操作
批量操作流程
请求: POST /customService/processActionBatch
[
{
"businessKey":"spu-test1", // 流程码,必填
"userId":"", // 用户id,必填
"action":"complete"||"reject", // 操作的动作(完结/驳回),必填
"completeNodeIds":[""], // 完结的节点id列表,不传时为下一个
"rejectNodeIds":[""] // 驳回的节点id列表,不传时为上一个
}
]
响应:
如果有下一级的话就返回下一级节点和上一级点击
{
compeletableNodeIds:[],
rejectableNodeIds:[]
}
模拟请求:
[
{
"businessKey":"spu-test1",
"userId":"",
"action":"complete"||"reject",
"completeNodeIds":[""],
"rejectNodeIds":[""],
}
]
模拟响应:
{
compeletableNodeIds:[],
rejectableNodeIds:[]
}
测试范围到部门
接口地址为: http://localhost:8086/flowable-rest/service
1、
查看流程模板图片信息
首先需要查询指定sku的流程实例 接口得到流程定义id
通过该流程定义id查询流程定义图形
GET /repository/process-definitions/{processDefinitionId}/model
{processDefinitionId} 流程定义id
2、启动流程
查看流程的信息
启动流程之后就会生成流程任务
我们通常的业务为需要查询指定流程的待当前流程任务
根据流程业务key(processInstanceBusinessKey)查询流程任务列表并取第一个即可
GET /runtime/process-instances
响应码:
200成功
400入参类型错误
Parameter | Value | Description | Parameter Type | Data Type |
---|---|---|---|---|
businessKey | 业务key | query | string |
查看流程的运行情况
GET /runtime/process-instances/{processInstanceId}/diagram
{processInstanceId} 流程实例id
3.1、设置任务的处理人
PUT /runtime/tasks/{taskId}
{taskId} 任务节点id
请求:
assignee (string, optional) 处理人用户id
3.2、查询我的任务节点
GET /runtime/tasks
响应码:
200成功
404资源不存在
请求:
Parameter | Value | Parameter Type | Data Type |
---|---|---|---|
assignee | query | string | |
active | true false | query | boolean |
响应:
模型体
3.3、提交我的任务节点
POST /runtime/tasks/{taskId}
请求数据模型
action (string): complete, claim, delegate or resolve 完结/认领/委派/返回
assignee (string, optional):认领人id/被委派者id
formDefinitionId (string, optional): 引用表单的id
outcome (string, optional): accepted/rejected 设置表单 完结/认领 后结果,要么为接受/拒绝
variables (Array[RestVariable], optional): 设置该节点的变量列表
transientVariables (Array[RestVariable], optional): 当前操作的变量列表
响应数据模型
name (string, optional): 变量名称
type (string, optional): 变量类型
value (object, optional): 变量值
valueUrl (string, optional):变量的地址
scope (string, optional): 范围
完成流程任务
{
"action":"complete"
}
4.0、查询该流程中有哪些节点可以进行跳转
通过key去查询流程对象
GET /repository/process-definitions
响应:
200成功
400请求参数类型异常
请求:
key 流程定义key,业务key string 必须传
响应:
[Data]
Data{
id (string, optional), 流程定义id
}
test_rollback:1:9db2b816-3f11-11e9-b3e6-7845c42f05a4
根据流程id查询流程模型值
GET /repository/process-definitions/{processDefinitionId}/model
{processDefinitionId} 流程定义id
响应码:
404失败,请求资源不存在
响应:
BpmnModel {
definitionsAttributes (inline_model_3, optional),
processes (Array[Process], optional),
locationMap (inline_model_4, optional),
labelLocationMap (inline_model_5, optional),
flowLocationMap (inline_model_6, optional),
signals (Array[Signal], optional),
pools (Array[Pool], optional),
imports (Array[Import], optional),
interfaces (Array[Interface], optional),
globalArtifacts (Array[Artifact], optional),
resources (Array[Resource], optional),
targetNamespace (string, optional),
sourceSystemId (string, optional),
userTaskFormTypes (Array[string], optional),
startEventFormTypes (Array[string], optional),
errors (inline_model_7, optional),
messages (Array[Message], optional),
mainProcess (Process, optional),
messageFlows (inline_model_8, optional),
itemDefinitions (inline_model_9, optional),
dataStores (inline_model_10, optional),
namespaces (inline_model_11, optional)
}inline_model_3 {}Process {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_46, optional),
attributes (inline_model_47, optional),
name (string, optional),
executable (boolean, optional),
documentation (string, optional),
ioSpecification (IOSpecification, optional),
executionListeners (Array[FlowableListener], optional),
lanes (Array[Lane], optional),
dataObjects (Array[ValuedDataObject], optional),
candidateStarterUsers (Array[string], optional),
candidateStarterGroups (Array[string], optional),
eventListeners (Array[EventListener], optional),
flowElementMap (inline_model_48, optional),
initialFlowElement (FlowElement, optional),
enableEagerExecutionTreeFetching (boolean, optional),
artifacts (Array[Artifact], optional),
flowElements (Array[FlowElement], optional)
}inline_model_4 {}inline_model_5 {}inline_model_6 {}Signal {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_51, optional),
attributes (inline_model_52, optional),
name (string, optional),
scope (string, optional)
}Pool {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_44, optional),
attributes (inline_model_45, optional),
name (string, optional),
processRef (string, optional),
executable (boolean, optional)
}Import {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_30, optional),
attributes (inline_model_31, optional),
importType (string, optional),
location (string, optional),
namespace (string, optional)
}Interface {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_32, optional),
attributes (inline_model_33, optional),
name (string, optional),
implementationRef (string, optional),
operations (Array[Operation], optional)
}Artifact {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model, optional),
attributes (inline_model_0, optional)
}Resource {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_49, optional),
attributes (inline_model_50, optional),
name (string, optional)
}inline_model_7 {}Message {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_38, optional),
attributes (inline_model_39, optional),
name (string, optional),
itemRef (string, optional)
}inline_model_8 {}inline_model_9 {}inline_model_10 {}inline_model_11 {}inline_model_46 {}inline_model_47 {}IOSpecification {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_28, optional),
attributes (inline_model_29, optional),
dataInputs (Array[DataSpec], optional),
dataOutputs (Array[DataSpec], optional),
dataInputRefs (Array[string], optional),
dataOutputRefs (Array[string], optional)
}FlowableListener {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_26, optional),
attributes (inline_model_27, optional),
event (string, optional),
implementationType (string, optional),
implementation (string, optional),
fieldExtensions (Array[FieldExtension], optional),
onTransaction (string, optional),
customPropertiesResolverImplementationType (string, optional),
customPropertiesResolverImplementation (string, optional)
}Lane {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_36, optional),
attributes (inline_model_37, optional),
name (string, optional),
parentProcess (Process, optional),
flowReferences (Array[string], optional)
}ValuedDataObject {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_53, optional),
attributes (inline_model_54, optional),
name (string, optional),
documentation (string, optional),
executionListeners (Array[FlowableListener], optional),
itemSubjectRef (ItemDefinition, optional),
value (object, optional),
type (string, optional)
}EventListener {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_17, optional),
attributes (inline_model_18, optional),
events (string, optional),
implementationType (string, optional),
implementation (string, optional),
entityType (string, optional),
onTransaction (string, optional)
}inline_model_48 {}FlowElement {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_24, optional),
attributes (inline_model_25, optional),
name (string, optional),
documentation (string, optional),
executionListeners (Array[FlowableListener], optional)
}inline_model_51 {}inline_model_52 {}inline_model_44 {}inline_model_45 {}inline_model_30 {}inline_model_31 {}inline_model_32 {}inline_model_33 {}Operation {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_42, optional),
attributes (inline_model_43, optional),
name (string, optional),
implementationRef (string, optional),
inMessageRef (string, optional),
outMessageRef (string, optional),
errorMessageRef (Array[string], optional)
}inline_model {}inline_model_0 {}inline_model_49 {}inline_model_50 {}inline_model_38 {}inline_model_39 {}inline_model_28 {}inline_model_29 {}DataSpec {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_13, optional),
attributes (inline_model_14, optional),
name (string, optional),
itemSubjectRef (string, optional),
collection (boolean, optional)
}inline_model_26 {}inline_model_27 {}FieldExtension {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_22, optional),
attributes (inline_model_23, optional),
fieldName (string, optional),
stringValue (string, optional),
expression (string, optional)
}inline_model_36 {}inline_model_37 {}inline_model_53 {}inline_model_54 {}ItemDefinition {
id (string, optional),
xmlRowNumber (integer, optional),
xmlColumnNumber (integer, optional),
extensionElements (inline_model_34, optional),
attributes (inline_model_35, optional),
structureRef (string, optional),
itemKind (string, optional)
}inline_model_17 {}inline_model_18 {}inline_model_24 {}inline_model_25 {}inline_model_42 {}inline_model_43 {}inline_model_13 {}inline_model_14 {}inline_model_22 {}inline_model_23 {}inline_model_34 {}inline_model_35 {}
解析:
假设请求到数据返回为data
var flowElementMap = data.locationMap;
遍历flowElementMap的Key,除了前后两个都是执行节点
var flowElementMapKeys = Object.keys(flowElementMap);
从process中拿到具体名称
for(var felmk of flowElementMapKeys){
data.processes[0][felmk].name ==> 节点名称
}
4、驳回流程 到指定节点
POST /runtime/process-instances/{processInstanceId}/change-state
{processInstanceId} 流程实例Id
响应码:
200成功,跳转成功
400请求参数缺失
404操作的流程不存在
409操作已经完成
500请求方法不存在
请求:
cancelActivityIds (Array[string], optional): 当前活动点的id,流程图中节点的id
startActivityIds (Array[string], optional): 目标活动点的id,流程图中节点的id
5、驳回之后审核成功之后返回到上一步节点
5.1获取审核前的节点的id值
GET /history/historic-task-instances
响应码:
200成功
请求参数:
processBusinessKey 流程实例key
sort 排序字段 值为endTime
响应:
Array[Data]
Data{
taskDefinitionKey (string, optional), 流程定义id
}
取数组中第二个对象的taskDefinitionKey属性的值
5.2自由跳转到审核前的节点
POST /runtime/process-instances/{processInstanceId}/change-state
{processInstanceId} 流程实例Id
响应码:
200成功,跳转成功
400请求参数缺失
404操作的流程不存在
409操作已经完成
500请求方法不存在
请求:
cancelActivityIds (Array[string], optional): 当前活动点的id,流程图中节点的id
startActivityIds (Array[string], optional): 目标活动点的id,流程图中节点的id
测试脚本
ebuy-workflow-engine.postman_collection.json