如何使用流程 中的 DataObject 并為流程設(shè)置租戶
不知道小伙伴們有沒有留意過(guò),在 Flowable 流程圖的繪制過(guò)程中,我們可以編寫一個(gè)名為 dataObject 的元素,這個(gè)元素可以指定變量的 id、名稱以及數(shù)據(jù)類型等各種屬性,并且在流程實(shí)例啟動(dòng)的時(shí)候,會(huì)自動(dòng)將 dataObject 元素的信息轉(zhuǎn)換為流程實(shí)例變量,這個(gè)東西也蠻好玩的,今天松哥就帶領(lǐng)小伙伴們來(lái)捋一捋 Flowable 中的 dataObject。
1. 添加 dataObject
首先我們來(lái)看下,在流程繪制的過(guò)程中,如何去添加 dataObject 對(duì)象。
IDEA 上的 Flowable 流程圖繪制插件中還不能添加 dataObject 屬性,這個(gè)需要我們?nèi)?flowable-ui 中去添加。
我們來(lái)隨便繪制一個(gè)如下這樣簡(jiǎn)單的流程圖:
看過(guò)松哥之前幾篇文章的小伙伴應(yīng)該對(duì)這張圖很熟悉了,松哥這里也不多說(shuō)。
我現(xiàn)在就想給這個(gè)流程圖,添加 dataObject 屬性,方式如下:
首先打開流程圖,不要選擇任何節(jié)點(diǎn),在下方可以找到數(shù)據(jù)對(duì)象屬性,如下圖:
點(diǎn)擊之后,就可以添加 dataObject 了,如下:
配置完成之后,點(diǎn)擊保存按鈕。然后我們下載這個(gè)流程圖,下載之后,打開,我們會(huì)發(fā)現(xiàn)這次的 XMl 節(jié)點(diǎn)比之前的 XML 節(jié)點(diǎn)多出來(lái)了如下一些內(nèi)容:
<dataObject id="name" name="流程繪制人" itemSubjectRef="xsd:string">
<extensionElements>
<flowable:value>javaboy</flowable:value>
</extensionElements>
</dataObject>
<dataObject id="site" name="流程作者網(wǎng)站" itemSubjectRef="xsd:string">
<extensionElements>
<flowable:value>www.javaboy.org</flowable:value>
</extensionElements>
</dataObject>
<dataObject id="date" name="流程繪制時(shí)間" itemSubjectRef="xsd:datetime">
<extensionElements>
<flowable:value>2022-09-23T00:00:00</flowable:value>
</extensionElements>
</dataObject>
2. 查詢 dataObject
接下來(lái),按照之前文章介紹的方式,我們先來(lái)部署并啟動(dòng)這個(gè)流程圖。
當(dāng)流程部署成功之后,我們可以在 ACT_RU_VARIABLE 表中查看到 dataObject 中的數(shù)據(jù),如下圖:
可以看到,dataObject 的數(shù)據(jù)是和執(zhí)行實(shí)例 ID 以及流程實(shí)例 ID 相關(guān)的。
接下來(lái),我們可以通過(guò)如下方式來(lái)查詢 ACT_RU_VARIABLE 表中的數(shù)據(jù):
@Test
void test08() {
List<Execution> list = runtimeService.createExecutionQuery().list();
for (Execution execution : list) {
DataObject data = runtimeService.getDataObject(execution.getId(), "流程繪制人");
logger.info("key:{},name:{},value:{}",data.getDataObjectDefinitionKey(),data.getName(),data.getValue());
}
}
這里打印出來(lái)的信息就是我們剛剛在定義的時(shí)候配置的所有流程信息了。
我們來(lái)看看這里查詢的表:
可以看到,這里先去 ACT_RU_EXECUTION 表中查詢執(zhí)行實(shí)例 ID,然后再根據(jù)拿到的執(zhí)行實(shí)例 ID 去 ACT_RU_VARIABLE 表中查詢 dataObject 信息。
這就是 dataObject 的使用,其實(shí)非常 Easy!dataObject 平時(shí)主要可以用來(lái)定義一些全局的屬性。
3. 租戶
說(shuō)到這里,就順便再來(lái)和小伙伴們聊一聊 Flowable 中的租戶。
租戶這個(gè)其實(shí)好理解,舉個(gè)栗子:
假設(shè)我們現(xiàn)在有 A、B、C、D 四個(gè)子系統(tǒng),四個(gè)子系統(tǒng)都要部署同一個(gè)名為 leave 的流程,如何區(qū)分四個(gè)不同子系統(tǒng)的的流程呢?通過(guò)租戶可以解決這個(gè)問(wèn)題。
Flowable 中的租戶其實(shí)很好理解,其實(shí)就是在流程中,多一個(gè)一個(gè) TenantID 加以區(qū)分每一個(gè)流程屬于哪個(gè)租戶。
我舉個(gè)簡(jiǎn)單的例子,假設(shè)我現(xiàn)在想要根據(jù)不同的子系統(tǒng)來(lái)部署流程,那么我可以按照如下方式來(lái)設(shè)計(jì)接口:
@RestController
public class ProcessDeployController {
@Autowired
RepositoryService repositoryService;
@PostMapping("/deploy")
public RespBean deploy(MultipartFile file,String tenantId) throws IOException {
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
.category("javaboy的工作流分類")
.name("javaboy的工作流名稱")
.addInputStream("fff.bpmn", file.getInputStream())
.tenantId(tenantId)
.key("javaboy的工作流key666");
Deployment deployment = deploymentBuilder
.deploy();
return RespBean.ok("部署成功",deployment.getId());
}
}
接下來(lái)我們通過(guò) POSTMAN 來(lái)發(fā)送一個(gè) POST 請(qǐng)求,提交流程圖和租戶 ID 這兩個(gè)參數(shù),如下圖:
小伙伴們注意,我這里提交了兩個(gè)參數(shù),一個(gè)是流程圖本身,還有一個(gè)是租戶 ID。
當(dāng)這個(gè)流程圖部署成功之后,我們?cè)诹鞒潭x表 ACT_RE_PROCDEF 中可以看到剛剛設(shè)置的租戶 ID:
接下來(lái)我們需要啟動(dòng)流程實(shí)例的時(shí)候,就不能單純拿著流程部署的 ID 去啟動(dòng)了,還得拿上流程的租戶 ID。如果只拿流程本身的信息去啟動(dòng),會(huì)拋出如下異常:
正確的啟動(dòng)方式如下:
@Test
void test09() {
identityService.setAuthenticatedUserId("wangwu");
ProcessInstance pi = runtimeService.startProcessInstanceByKeyAndTenantId("leave","A");
logger.info("id:{},activityId:{}", pi.getId(), pi.getActivityId());
}
在后續(xù)的 Task 查詢中,我們也可以根據(jù)具體的租戶 ID 來(lái)查詢,這個(gè)就看具體情況了。