工作流元素¶
工作流元素是对工作流API的二次封装,提供比底层API更加符合使用习惯的函数。
对于已经存在于系统中的工作流元素,提供常用信息的查询和流程及任务实例的基本操作功能。
实例化工作流元素¶
例如系统中存在工作流test_task
:
可以通过提供元素名 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')]
对应前端配置如下:
全局变量
[3]:
test_task.global_params
[3]:
[Value(value={'prefix': 'wfv$', 'code': 'var1', 'objectPath': None, 'type': 'STRING', 'enableList': False, 'name': None}, valueType='VARIABLE')]
对应前端配置如下:
消息列表
[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')]
对应前端配置如下:
流程实例¶
流程实例在工作流中由已发布的工作流发起流程后产生,并有唯一的流程实例id。
取决于配置,可在启动时指定启动参数,在有业务键配置时,启动参数将构成唯一的业务键,且进行中的流程实例间业务键需唯一。
当前示例工作流启动参数:
业务参数:
启动¶
鉴于当前工作流配置,在启动时必须提供启动参数,可以通过如下调用方式启动,并备注”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
的流程画布如下:
可知,在启动后,将处于等待信息message2
的状态,因此启动后可在流程监控中看到相应的流程实例,如下图所示:
在流程详情内,可见备注与启动提供的一致:
批量启动*¶
启动接口在同一个流程中,发起间隔不能小于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 ,以便进一步进行筛选处理
[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}
[11]:
test_task.send_msg_to_processes(
msg_code='message2',
msg_body={'is_active': True},
processes=[resp.procInstId]
)
注意事项
此处msg_code即为消息事件
列表中的消息编码,msg_body的格式来自消息事件
列表中的消息参数,如查看的是消息属性
界面,需排除其中来源为预置
的字段。
广播至所有订阅者
[12]:
test_task.broadcast(
msg_code='message2',
msg_body={'is_active': True}
)
任务实例¶
在流程实例的执行过程中,根据流程画布配置,可能会有单人任务
或多人任务
节点,并在执行到相应步骤时,在相关人员的任务中心
中显示,例如发送信息后,经过了等待信息这步,当前流程实例详情如下:
而在任务中心
里,可以看到如下任务:
在此过程中,会产生任务实例,并有唯一的任务实例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 参数作为结果选项
。
典型的使用样例为,查询当前用户进行中
的任务,统一完成并选择结果为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'
)
操作结果:
流程实例详情: