工作流元素

工作流元素是对工作流API的二次封装,提供比底层API更加符合使用习惯的函数。

对于已经存在于系统中的工作流元素,提供常用信息的查询和流程及任务实例的基本操作功能。

实例化工作流元素

例如系统中存在工作流test_task:

c9b50eb2790c4e7a9965851c787a95c5

可以通过提供元素名 test_task 初始化,若元素名不唯一,增加提供path信息即可

[1]:
from deepfos.element.workflow import *

test_task = WorkFlow('test_task')

常用信息

在该元素类中提供了若干cached_property,用以提供工作流配置信息。

  • 启动参数

[2]:
test_task.launch_params
[2]:
[ProcessLaunchParamsVO(canIsNull=False, code='input1', isArray=False, type='STRING'),
 ProcessLaunchParamsVO(canIsNull=False, code='input2', isArray=False, type='INTEGER'),
 ProcessLaunchParamsVO(canIsNull=False, code='input3', isArray=False, type='DECIMAL')]

对应前端配置如下:

1be3dc705e5e4247926da91578203d4d

  • 全局变量

[3]:
test_task.global_params
[3]:
[Value(value={'prefix': 'wfv$', 'code': 'var1', 'objectPath': None, 'type': 'STRING', 'enableList': False, 'name': None}, valueType='VARIABLE')]

对应前端配置如下:

ff6c66796cc641c7ba69496f5f541656

  • 消息列表

[4]:
test_task.msg_list
[4]:
[Message(code='message1', context=[{'code': 'code', 'enableList': False, 'source': 'PRESET', 'type': 'STRING'}, {'code': 'name', 'enableList': False, 'source': 'PRESET', 'type': 'STRING'}, {'code': 'sent_user_id', 'enableList': False, 'source': 'PRESET', 'type': 'STRING'}, {'code': 'sent_time', 'enableList': False, 'source': 'PRESET', 'type': 'DATETIME'}], id='Message_6f77ad9', name='消息事件', params=[], type='CUSTOM'),
 Message(code='message2', context=[{'code': 'code', 'enableList': False, 'source': 'PRESET', 'type': 'STRING'}, {'code': 'name', 'enableList': False, 'source': 'PRESET', 'type': 'STRING'}, {'code': 'sent_user_id', 'enableList': False, 'source': 'PRESET', 'type': 'STRING'}, {'code': 'sent_time', 'enableList': False, 'source': 'PRESET', 'type': 'DATETIME'}], id='Message_146f657', name='消息事件', params=[KeyDetail(code='is_active', enableList=False, enableNotNull=False, type='BOOLEAN')], type='CUSTOM')]

对应前端配置如下:

a2b2219ad46e436db28cd065fac02f7c

流程实例

流程实例在工作流中由已发布的工作流发起流程后产生,并有唯一的流程实例id。

取决于配置,可在启动时指定启动参数,在有业务键配置时,启动参数将构成唯一的业务键,且进行中的流程实例间业务键需唯一。

当前示例工作流启动参数:

bd482ded2c3048e0a082bf99b6887778

业务参数:

ad8dbee1a46045a5a0d56218ab20db79

启动

鉴于当前工作流配置,在启动时必须提供启动参数,可以通过如下调用方式启动,并备注”called from SDK”:

[5]:
resp = test_task.launch_process(
    param={'input1': 'test', 'input2': 1, 'input3': 1.1},
    comment='called from SDK'
)
resp
[5]:
LaunchReturnVO(businessKey='test|1', paramMap={'input1': 'test', 'input2': 1, 'input3': 1.1}, procInstId='37df1f37-ed71-11ed-88c1-c65a503b41ed')

当前工作流test_task的流程画布如下:

503d4c7dc2774f4499cbb2e13fbcf94a

可知,在启动后,将处于等待信息message2的状态,因此启动后可在流程监控中看到相应的流程实例,如下图所示:

74c16bf9630f465484cbcc32cbb06a55

在流程详情内,可见备注与启动提供的一致:

7321db0bed5f4899b648d2a1f8209889

批量启动*

启动接口在同一个流程中,发起间隔不能小于5秒,因此在V1.0.49和V1.1.1以后,增加封装了批量启动接口

用法与单个启动类似,差异在于提供的是启动参数列表,且 需要增加alias参数

[6]:
batch_resp = test_task.batch_launch_process(
    params=[
        dict(alias=1, paramMap={'input1': 'test', 'input2': 10, 'input3': 10.1},comment='batch called from SDK'),
        dict(alias=2, paramMap={'input1': 'test', 'input2': 11, 'input3': 11.1},comment='batch called from SDK'),
    ]
)
batch_resp
[6]:
[LaunchReturnForBatchVO(alias='1', businessKey='test|10', errorMsg=None, paramMap={'input1': 'test', 'input2': 10, 'input3': 10.1}, procInstId='606dd043-ed71-11ed-88c1-c65a503b41ed', success=True),
 LaunchReturnForBatchVO(alias='2', businessKey='test|11', errorMsg=None, paramMap={'input1': 'test', 'input2': 11, 'input3': 11.1}, procInstId='60a189b5-ed71-11ed-88c1-c65a503b41ed', success=True)]

查询

在元素类中,提供了3种查询流程实例的方式,对于配置并使用了启动参数的,可以通过启动参数查询,对于启用了业务键的,可通过业务键来查询:

  • 启动参数查询

[7]:
test_task.get_process_by_param({'input1': 'test', 'input2': 1, 'input3': 1.1})
[7]:
[ProcessInstanceVO(businessKey='test|1', dueTime=None, endTime=None, expiredStatus='NORMAL', procDefId='bb5d5978-b641-11ed-a82b-ba2649b8ce0e', procDisplayName='工作流', procElementFolderId='0', procElementName='test_task', procElementPath='\\', procInstId='37df1f37-ed71-11ed-88c1-c65a503b41ed', processId='p9309bddb028542569c598767a635ec95', startTime='2023-05-08 15:23:24', startUser=UserDetailVO(adminTag=None, avatar=None, email='wenjun.zhu@proinnova.com.cn', mobilePhone=None, nickName='朱文君', nickname='朱文君', status='1', userId='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', userName='m12a1956uj', username='m12a1956uj'), startUserId='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', state='InProgress', version='V10.0')]
  • 业务键查询

[8]:
test_task.get_process_by_business_key(resp.businessKey)
[8]:
[ProcessInstanceVO(businessKey='test|1', dueTime=None, endTime=None, expiredStatus='NORMAL', procDefId='bb5d5978-b641-11ed-a82b-ba2649b8ce0e', procDisplayName='工作流', procElementFolderId='0', procElementName='test_task', procElementPath='\\', procInstId='37df1f37-ed71-11ed-88c1-c65a503b41ed', processId='p9309bddb028542569c598767a635ec95', startTime='2023-05-08 15:23:24', startUser=UserDetailVO(adminTag=None, avatar=None, email='wenjun.zhu@proinnova.com.cn', mobilePhone=None, nickName='朱文君', nickname='朱文君', status='1', userId='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', userName='m12a1956uj', username='m12a1956uj'), startUserId='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', state='InProgress', version='V10.0')]
  • 基于状态查询

如果该流程的启动无需启动参数,或启动参数和业务键都未知,则可通过流程实例状态查询,该查询等效于流程监控前端界面,支持将返回值转换为 Pandas DataFrame ,以便进一步进行筛选处理

cdbb0669c2ff48fba4d0a88a25e98107

[9]:
test_task.list_process()
[9]:
[FlowInstanceDto(currTaskName='等待消息', definitionKey='p9309bddb028542569c598767a635ec95', description=None, displayName='工作流', endTime=None, expireTime=None, expiredStatus='NORMAL', folderId='0', instanceId='60a189b5-ed71-11ed-88c1-c65a503b41ed', name='test_task', path='\\', principals=[], processDefinitionId='bb5d5978-b641-11ed-a82b-ba2649b8ce0e', startTime='2023-05-08 15:24:33', startUser=UserDetailVO(adminTag=None, avatar=None, email='wenjun.zhu@proinnova.com.cn', mobilePhone=None, nickName='朱文君', nickname='朱文君', status='1', userId='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', userName='m12a1956uj', username='m12a1956uj'), status='InProgress', userPage=None, userPageStatus='DISABLE', userPageUrl=None, version='V10.0'),
 FlowInstanceDto(currTaskName='等待消息', definitionKey='p9309bddb028542569c598767a635ec95', description=None, displayName='工作流', endTime=None, expireTime=None, expiredStatus='NORMAL', folderId='0', instanceId='606dd043-ed71-11ed-88c1-c65a503b41ed', name='test_task', path='\\', principals=[], processDefinitionId='bb5d5978-b641-11ed-a82b-ba2649b8ce0e', startTime='2023-05-08 15:24:32', startUser=UserDetailVO(adminTag=None, avatar=None, email='wenjun.zhu@proinnova.com.cn', mobilePhone=None, nickName='朱文君', nickname='朱文君', status='1', userId='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', userName='m12a1956uj', username='m12a1956uj'), status='InProgress', userPage=None, userPageStatus='DISABLE', userPageUrl=None, version='V10.0'),
 FlowInstanceDto(currTaskName='等待消息', definitionKey='p9309bddb028542569c598767a635ec95', description=None, displayName='工作流', endTime=None, expireTime=None, expiredStatus='NORMAL', folderId='0', instanceId='37df1f37-ed71-11ed-88c1-c65a503b41ed', name='test_task', path='\\', principals=[], processDefinitionId='bb5d5978-b641-11ed-a82b-ba2649b8ce0e', startTime='2023-05-08 15:23:24', startUser=UserDetailVO(adminTag=None, avatar=None, email='wenjun.zhu@proinnova.com.cn', mobilePhone=None, nickName='朱文君', nickname='朱文君', status='1', userId='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', userName='m12a1956uj', username='m12a1956uj'), status='InProgress', userPage=None, userPageStatus='DISABLE', userPageUrl=None, version='V10.0')]

基于状态查询流程实例默认查询进行中的流程实例,并返回原始数据,如需查询进行中已终止并转换为 Pandas DataFrame ,可以在 status 参数中指定:

[10]:
test_task.list_process(['in_progress', 'terminated'], as_dataframe=True)
[10]:
currTaskName definitionKey description displayName endTime expireTime expiredStatus folderId instanceId name path principals processDefinitionId startTime startUser status userPage userPageStatus userPageUrl version
0 等待消息 p9309bddb028542569c598767a635ec95 None 工作流 None None NORMAL 0 60a189b5-ed71-11ed-88c1-c65a503b41ed test_task \ [] bb5d5978-b641-11ed-a82b-ba2649b8ce0e 2023-05-08 15:24:33 {'adminTag': None, 'avatar': None, 'email': 'w... InProgress None DISABLE None V10.0
1 等待消息 p9309bddb028542569c598767a635ec95 None 工作流 None None NORMAL 0 606dd043-ed71-11ed-88c1-c65a503b41ed test_task \ [] bb5d5978-b641-11ed-a82b-ba2649b8ce0e 2023-05-08 15:24:32 {'adminTag': None, 'avatar': None, 'email': 'w... InProgress None DISABLE None V10.0
2 等待消息 p9309bddb028542569c598767a635ec95 None 工作流 None None NORMAL 0 37df1f37-ed71-11ed-88c1-c65a503b41ed test_task \ [] bb5d5978-b641-11ed-a82b-ba2649b8ce0e 2023-05-08 15:23:24 {'adminTag': None, 'avatar': None, 'email': 'w... InProgress None DISABLE None V10.0

发送消息

启动流程实例的例子中,产生了一条等待消息的流程实例,如无消息message2的触发,将不会进行下去,除了另起一个发送消息的流程实例,亦可使用SDK中的方法达到同样的效果。

当前发送消息支持两种模式,一种为发送至特定流程实例列表,一种为广播至所有订阅者,依据配置和场景使用即可。

  • 发送至特定流程实例列表

根据消息参数配置,发送{'is_active': True}

11bc5997f6864e08b1b4726b5f8cde10

[11]:
test_task.send_msg_to_processes(
    msg_code='message2',
    msg_body={'is_active': True},
    processes=[resp.procInstId]
)

注意事项

此处msg_code即为消息事件列表中的消息编码,msg_body的格式来自消息事件列表中的消息参数,如查看的是消息属性界面,需排除其中来源为预置的字段。

7563228f9c5d4d38b708928c4963217d

  • 广播至所有订阅者

[12]:
test_task.broadcast(
    msg_code='message2',
    msg_body={'is_active': True}
)

任务实例

在流程实例的执行过程中,根据流程画布配置,可能会有单人任务多人任务节点,并在执行到相应步骤时,在相关人员的任务中心中显示,例如发送信息后,经过了等待信息这步,当前流程实例详情如下:

df60f2e207714c1ca26c48ae13b0859c

而在任务中心里,可以看到如下任务:

6248f0f9066c4f5c8d06e8619fac9276

在此过程中,会产生任务实例,并有唯一的任务实例id,任务实例id由系统生成,当前只能通过查询的方式得到。

查询

在元素类中,提供了3种查询任务实例的方式,对于配置并使用了启动参数的,可以通过启动参数或业务键来查询:

  • 启动参数查询

[13]:
test_task.get_task_by_param({'input1': 'test', 'input2': 1, 'input3': 1.1})
[13]:
[TaskInstanceVO(assignee='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', assigneeType='USER', businessKey='test|1', endTime=None, owner=None, priority='LOW', procDefId='bb5d5978-b641-11ed-a82b-ba2649b8ce0e', procDisplayName='工作流', procElementFolderId='0', procElementName='test_task', procElementPath='\\', procInstId='37df1f37-ed71-11ed-88c1-c65a503b41ed', processId='p9309bddb028542569c598767a635ec95', startTime='2023-05-08 15:26:03', state='InProgress', taskCode='user_task1', taskDisplayName='单人任务', taskId='96a730be-ed71-11ed-88c1-c65a503b41ed', taskName='单人任务', version='V10.0')]
  • 业务键查询

[14]:
test_task.get_task_by_business_key(resp.businessKey)
[14]:
[TaskInstanceVO(assignee='17eed86c-9573-4733-9ee3-1f5ee72b4ceb', assigneeType='USER', businessKey='test|1', endTime=None, owner=None, priority='LOW', procDefId='bb5d5978-b641-11ed-a82b-ba2649b8ce0e', procDisplayName='工作流', procElementFolderId='0', procElementName='test_task', procElementPath='\\', procInstId='37df1f37-ed71-11ed-88c1-c65a503b41ed', processId='p9309bddb028542569c598767a635ec95', startTime='2023-05-08 15:26:03', state='InProgress', taskCode='user_task1', taskDisplayName='单人任务', taskId='96a730be-ed71-11ed-88c1-c65a503b41ed', taskName='单人任务', version='V10.0')]
  • 基于状态查询

与流程实例的状态查询类似,任务实例也支持通过实例状态筛选任务实例,并可将结果转换成 Pandas DataFrame ,默认查询进行中的任务实例。

[15]:
test_task.list_my_task(['in_progress'], as_dataframe=True)
[15]:
app claimStatus definitionName description dueTime elementName enableAllowedComment enableQuickComplete endTime executor ... startUser taskCode taskDefinitionKey taskId taskName taskStatus userPage userPageStatus userPageUrl version
0 zauoyn105 CLAIMED 工作流 None None test_task False False None {'adminTag': None, 'avatar': None, 'email': 'w... ... {'adminTag': None, 'avatar': None, 'email': 'w... user_task1 p9309bddb028542569c598767a635ec95 9a8f4094-ed71-11ed-88c1-c65a503b41ed 单人任务 InProgress None DISABLE None V10.0
1 zauoyn105 CLAIMED 工作流 None None test_task False False None {'adminTag': None, 'avatar': None, 'email': 'w... ... {'adminTag': None, 'avatar': None, 'email': 'w... user_task1 p9309bddb028542569c598767a635ec95 9a9979f3-ed71-11ed-88c1-c65a503b41ed 单人任务 InProgress None DISABLE None V10.0
2 zauoyn105 CLAIMED 工作流 None None test_task False False None {'adminTag': None, 'avatar': None, 'email': 'w... ... {'adminTag': None, 'avatar': None, 'email': 'w... user_task1 p9309bddb028542569c598767a635ec95 96a730be-ed71-11ed-88c1-c65a503b41ed 单人任务 InProgress None DISABLE None V10.0

3 rows × 34 columns

完成任务

在通过查询得到了任务实例id后,可以使用该id操作完成任务,等效于在前端操作。

对于任务可选结果不唯一的,需提供 outcome 参数作为结果选项

c0f9797135e54e039fed2b875db4332c

典型的使用样例为,查询当前用户进行中的任务,统一完成并选择结果为approve(同意):

[16]:
for task in test_task.list_my_task():
    test_task.complete_task_by_id(
        task_id=task.taskId,
        outcome='approve',
        comment='Completed by SDK'
    )

操作结果:

1db5e6a0d228494c847306fa53137e88

流程实例详情:

5c73e9ea68494bc6bed438d6fdc0d7a2