5.流程定義ProcessDefinitionController
1.查詢流程串列
使用repositoryService提供的API,同模型查詢同理,詳細邏輯見注釋,

@GetMapping(value = "/list")
public Result list(ProcessDefinitionQueryVo processDefinitionQueryVo) {
// 呼叫API創建查詢工廠
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
if (CommonFlowableUtil.isNotEmpty(processDefinitionQueryVo.getProcessDefinitionId())) {
processDefinitionQuery.processDefinitionId(processDefinitionQueryVo.getProcessDefinitionId());
}
if (CommonFlowableUtil.isNotEmpty(processDefinitionQueryVo.getProcessDefinitionCategory())) {
processDefinitionQuery.processDefinitionCategoryLike(
CommonFlowableUtil.convertToLike(processDefinitionQueryVo.getProcessDefinitionCategory()));
}
if (CommonFlowableUtil.isNotEmpty(processDefinitionQueryVo.getProcessDefinitionKey())) {
processDefinitionQuery.processDefinitionKeyLike(
CommonFlowableUtil.convertToLike(processDefinitionQueryVo.getProcessDefinitionKey()));
}
if (CommonFlowableUtil.isNotEmpty(processDefinitionQueryVo.getProcessDefinitionName())) {
processDefinitionQuery.processDefinitionNameLike(
CommonFlowableUtil.convertToLike(processDefinitionQueryVo.getProcessDefinitionName()));
}
if (CommonFlowableUtil.isNotEmpty(processDefinitionQueryVo.getProcessDefinitionVersion())) {
processDefinitionQuery.processDefinitionVersion(processDefinitionQueryVo.getProcessDefinitionVersion());
}
Boolean suspended = CommonFlowableUtil.isEmptyDefault(processDefinitionQueryVo.getSuspended(), false);
Boolean active = CommonFlowableUtil.isEmptyDefault(processDefinitionQueryVo.getActive(), false);
if (!suspended.equals(active)) {
if (suspended) {
processDefinitionQuery.suspended();
}
if (active) {
processDefinitionQuery.active();
}
}
if (processDefinitionQueryVo.getLatestVersion()) {
processDefinitionQuery.latestVersion();
}
if (!CommonFlowableUtil.isEmpty(processDefinitionQueryVo.getStartableByUser())) {
processDefinitionQuery.startableByUser(processDefinitionQueryVo.getStartableByUser());
}
if (!CommonFlowableUtil.isEmpty(processDefinitionQueryVo.getTenantId())) {
processDefinitionQuery.processDefinitionTenantId(processDefinitionQueryVo.getTenantId());
}
List list = null;
//執行API的查詢與排序
FlowablePage page = this.pageList(processDefinitionQueryVo, processDefinitionQuery, ProcDefListWrapper.class,
ALLOWED_SORT_PROPERTIES);
return Result.ok(page);
}
2.查詢可發起的流程
查詢原理同上文,查詢可發起的流程定義(發起流程),查詢條件是已經激活,且可由本人發起的流程,詳細邏輯見注釋,

@GetMapping(value = "/listMyself")
public Result listMyself(ProcessDefinitionQueryVo processDefinitionQueryVo) {
// 呼叫API創建查詢工廠
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
if (!CommonFlowableUtil.isEmpty(processDefinitionQueryVo.getProcessDefinitionName())) {
processDefinitionQuery.processDefinitionNameLike(
CommonFlowableUtil.convertToLike(processDefinitionQueryVo.getProcessDefinitionName()));
}
//查詢條件為已經激活,且能夠被當前人發起
processDefinitionQuery.latestVersion().active()
.startableByUser(SecurityUtils.getUserId());
//執行API的查詢與排序
FlowablePage page = this.pageList(processDefinitionQueryVo, processDefinitionQuery, ProcDefListWrapper.class,
ALLOWED_SORT_PROPERTIES);
return Result.ok(page);
}
3.發起流程定義渲染申請表單
在發起流程后,會顯示開始流程需要填寫的表單,介面使用了formService.getRenderedStartForm()API,會回傳配置的申請表單json,然后前段進行渲染,詳細邏輯見注釋,

@GetMapping(value = "/renderedStartForm")
public Result renderedStartForm(@RequestParam String processDefinitionId) {
// 驗證用戶是否有權限
permissionService.validateReadPermissionOnProcessDefinition(SecurityUtils.getUserId(),
processDefinitionId);
//呼叫api回傳申請表單json
Object renderedStartForm = formService.getRenderedStartForm(processDefinitionId);
if(renderedStartForm == null){
renderedStartForm ="";
}
boolean showBusinessKey = this.isShowBusinessKey(processDefinitionId);
return Result.ok(ImmutableMap.of("renderedStartForm", renderedStartForm != null ? renderedStartForm : "",
"showBusinessKey", showBusinessKey));
}
4.查詢流程圖
在發起審批時可以查看流程圖,介面實作主要呼叫InputStream imageStream = repositoryService.getProcessDiagram(processDefinition.getId());提供的API生成流程圖的流,詳細邏輯見注釋,


@GetMapping(value = "/image")
public ResponseEntity<byte[]> image(@RequestParam String processDefinitionId, @RequestParam String access_token) {
// 驗證當前人員權限
permissionService.validateReadPermissionOnProcessDefinition(SecurityUtils.getUserId(), processDefinitionId);
// 查詢流程定義
ProcessDefinition processDefinition = processDefinitionService.getProcessDefinitionById(processDefinitionId);
// 呼叫api圖片流
InputStream imageStream = repositoryService.getProcessDiagram(processDefinition.getId());
if (imageStream == null) {
throw new FlowableException(CommonFlowableUtil
.messageFormat("Process definition image is not found with id {0}", processDefinitionId));
}
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.IMAGE_PNG);
try {
//將流物件加入回傳物件中
return new ResponseEntity<>(IOUtils.toByteArray(imageStream), responseHeaders, HttpStatus.OK);
} catch (Exception e) {
throw new FlowableException(CommonFlowableUtil
.messageFormat("Process definition image read error with id {0}", processDefinitionId), e);
}
}
5.匯出獲取流程定義xml
將bpmn.xml匯出,介面通過repositoryService.getResourceAsStream(deploymentId, resourceId);提供的api匯出xml,詳細邏輯見注釋,

@GetMapping(value = "/xml")
public ResponseEntity<byte[]> xml(@RequestParam String processDefinitionId) {
// 驗證當前用戶是否有獲取權限
permissionService.validateReadPermissionOnProcessDefinition(SecurityUtils.getUserId(),
processDefinitionId);
// 查詢流程定義
ProcessDefinition processDefinition = processDefinitionService.getProcessDefinitionById(processDefinitionId);
String deploymentId = processDefinition.getDeploymentId();
String resourceId = processDefinition.getResourceName();
// 未部署的不能匯出
if (deploymentId == null || deploymentId.length() == 0) {
throw new FlowableException(CommonFlowableUtil
.messageFormat("Process definition deployment id is not found with id {0}", processDefinitionId));
}
if (resourceId == null || resourceId.length() == 0) {
throw new FlowableException(CommonFlowableUtil
.messageFormat("Process definition resource id is not found with id {0}", processDefinitionId));
}
//獲取部署物件詳細資訊(流程定義物件)
Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
if (deployment == null) {
throw new FlowableException(CommonFlowableUtil
.messageFormat("Process definition deployment is not found with deploymentId " + "{0}", deploymentId));
}
//獲取流程定義的資源id(圖片,xml,表單)
List<String> resourceList = repositoryService.getDeploymentResourceNames(deploymentId);
if (CommonFlowableUtil.isEmpty(resourceList) || !resourceList.contains(resourceId)) {
throw new FlowableException(CommonFlowableUtil.messageFormat(
"Process definition resourceId {0} is not found with " + "deploymentId {1}", resourceId, deploymentId));
}
//呼叫API獲取xml流資訊
InputStream resourceStream = repositoryService.getResourceAsStream(deploymentId, resourceId);
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.TEXT_XML);
try {
//加入回傳物件
return new ResponseEntity<>(IOUtils.toByteArray(resourceStream), responseHeaders, HttpStatus.OK);
} catch (Exception e) {
throw new FlowableException(CommonFlowableUtil
.messageFormat("獲取流程定義XML資訊例外:ProcessDefinition xml read error with id {0}", deploymentId), e);
}
}
6.洗掉流程定義
呼叫了repositoryService.deleteDeployment(processDefinition.getDeploymentId());,其中正在運行流程定義的不能洗掉,詳細邏輯見注釋,

@DeleteMapping(value = "/delete")
public Result delete(@RequestParam String processDefinitionId, @RequestParam(required = false, defaultValue =
"false") Boolean cascade) {
//呼叫service方法
processDefinitionService.delete(processDefinitionId, cascade);
return Result.ok();
}
public void delete(String processDefinitionId, Boolean cascade) {
//獲取流程定義詳細資訊
ProcessDefinition processDefinition = getProcessDefinitionById(processDefinitionId);
if (processDefinition.getDeploymentId() == null) {
throw new FlowableException("Process definition has not deployed with id " + processDefinitionId);
}
//如果洗掉歷史任務
if (cascade) {
List<Job> jobs = managementService.createTimerJobQuery().processDefinitionId(processDefinitionId).list();
for (Job job : jobs) {
managementService.deleteTimerJob(job.getId());
}
repositoryService.deleteDeployment(processDefinition.getDeploymentId(), true);
}
else {
//獲取正在運行的該流程定義的數量
long processCount =
runtimeService.createProcessInstanceQuery().processDefinitionId(processDefinitionId).count();
//正在執行的流程定義不可洗掉
if (processCount > 0) {
throw new FlowableException(
"There are running instances with process definition id " + processDefinitionId);
}
long jobCount = managementService.createTimerJobQuery().processDefinitionId(processDefinitionId).count();
if (jobCount > 0) {
throw new FlowableException(
"There are running time jobs with process definition id " + processDefinitionId);
}
//呼叫API洗掉流程定義
repositoryService.deleteDeployment(processDefinition.getDeploymentId());
}
}
7.激活流程定義
當流程定義發布后,可以掛起和激活,這里使用了repositoryService.activateProcessDefinitionById(processDefinitionId, actionRequest.isIncludeProcessInstances(),未激活的流程定義不能發起,詳細邏輯見注釋,

@PutMapping(value = "/activate")
public Result activate(@RequestBody ProcessDefinitionRequest actionRequest) {
//呼叫service方法
processDefinitionService.activate(actionRequest);
return Result.ok();
}
public void activate(ProcessDefinitionRequest actionRequest) {
String processDefinitionId = actionRequest.getProcessDefinitionId();
//呼叫api獲取流程定義,且驗證為掛起狀態
ProcessDefinition processDefinition = getProcessDefinitionById(processDefinitionId);
if (!processDefinition.isSuspended()) {
throw new FlowableException("Process definition is not suspended with id " + processDefinitionId);
}
//呼叫API激活流程定義
repositoryService.activateProcessDefinitionById(processDefinitionId, actionRequest.isIncludeProcessInstances(),
actionRequest.getDate());
}
8.掛起流程定義
同理此處也呼叫了repositoryService.suspendProcessDefinitionById(processDefinition.getId(),
actionRequest.isIncludeProcessInstances(), actionRequest.getDate());詳細邏輯見注釋,

@PutMapping(value = "/suspend")
public Result suspend(@RequestBody ProcessDefinitionRequest actionRequest) {
//呼叫service方法
processDefinitionService.suspend(actionRequest);
return Result.ok();
}
public void suspend(ProcessDefinitionRequest actionRequest) {
String processDefinitionId = actionRequest.getProcessDefinitionId();
//獲取流程定義詳細資訊,且驗證不為掛起狀態
ProcessDefinition processDefinition = getProcessDefinitionById(processDefinitionId);
if (processDefinition.isSuspended()) {
throw new FlowableException("Process definition is already suspended with id " + processDefinitionId);
}
//呼叫API掛起流程定義
repositoryService.suspendProcessDefinitionById(processDefinition.getId(),
actionRequest.isIncludeProcessInstances(), actionRequest.getDate());
}
9.匯入流程定義
同匯入模型邏輯,在此基礎上加入部署邏輯,而匯入模型需要部署才能生成流程定義,詳細邏輯見注釋,

@PostMapping(value = "/import")
public Result doImport(@RequestParam(required = false) String tenantId, HttpServletRequest request) {
//呼叫service方法
processDefinitionService.doImport(tenantId, request);
return Result.ok();
}
public void doImport(String tenantId, HttpServletRequest request) {
// 驗證匯入檔案資訊
if (!(request instanceof MultipartHttpServletRequest)) {
throw new IllegalArgumentException("request must instance of MultipartHttpServletRequest");
}
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
if (multipartRequest.getFileMap().size() == 0) {
throw new IllegalArgumentException("request file is empty");
}
MultipartFile file = multipartRequest.getFileMap().values().iterator().next();
String fileName = file.getOriginalFilename();
// 檔案型別必須為以下的檔案型別
boolean isFileNameInValid =
CommonFlowableUtil.isEmpty(fileName) || !(fileName.endsWith(".bpmn20.xml") || fileName.endsWith(".bpmn")
|| fileName.toLowerCase().endsWith(".bar") || fileName.toLowerCase().endsWith(".zip"));
if (isFileNameInValid) {
throw new IllegalArgumentException("Request file must end with .bpmn20.xml,.bpmn|,.bar,.zip");
}
try {
// 新建流程定義物件
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
boolean isBpmnFile = fileName.endsWith(".bpmn20.xml") || fileName.endsWith(".bpmn");
if (isBpmnFile) {
// 決議二級制流為物件資訊
deploymentBuilder.addInputStream(fileName, file.getInputStream());
StreamSource xmlSource = new InputStreamSource(file.getInputStream());
BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xmlSource, false, false, "UTF-8");
org.flowable.bpmn.model.Process process = bpmnModel.getMainProcess();
// 獲取所有的任務節點
Collection<FlowElement> flowElements = process.getFlowElements();
Map<String, String> formKeyMap = new HashMap<String, String>(16);
// 遍歷所有的任務節點
for (FlowElement flowElement : flowElements) {
String formKey = null;
// 如果為開始節點 獲取申請表單id
if (flowElement instanceof StartEvent) {
StartEvent startEvent = (StartEvent)flowElement;
if (startEvent.getFormKey() != null && startEvent.getFormKey().length() > 0) {
formKey = startEvent.getFormKey();
}
// 如果為任務節點 獲取任務節點表單id
} else if (flowElement instanceof UserTask) {
UserTask userTask = (UserTask)flowElement;
if (userTask.getFormKey() != null && userTask.getFormKey().length() > 0) {
formKey = userTask.getFormKey();
}
}
if (formKey != null && formKey.length() > 0) {
if (formKeyMap.containsKey(formKey)) {
continue;
} else {
String formKeyDefinition = formKey.replace(".form", "");
// 查詢表單資訊
FlowableFormVO form = flowableFormService.queryFlowableFormById(formKeyDefinition);
if (form != null && form.getFormJson() != null && form.getFormJson().length() > 0) {
byte[] formJson = form.getFormJson().getBytes("UTF-8");
ByteArrayInputStream bi = new ByteArrayInputStream(formJson);
deploymentBuilder.addInputStream(formKey, bi);
//物件中加入表單資訊
formKeyMap.put(formKey, formKey);
} else {
throw new FlowableObjectNotFoundException(
"Cannot find formJson with formKey " + formKeyDefinition);
}
}
}
}
} else if (fileName.toLowerCase().endsWith(FlowableConstant.FILE_EXTENSION_BAR)
|| fileName.toLowerCase().endsWith(FlowableConstant.FILE_EXTENSION_ZIP)) {
deploymentBuilder.addZipInputStream(new ZipInputStream(file.getInputStream()));
}
//流程定義名稱為檔案名
deploymentBuilder.name(fileName);
if (tenantId != null && tenantId.length() > 0) {
deploymentBuilder.tenantId(tenantId);
}
//部署成流程定義
deploymentBuilder.deploy();
} catch (FlowableObjectNotFoundException e) {
throw e;
} catch (Exception e) {
throw new FlowableException("Process definition import error", e);
}
}
6.流程授權ProcessDefinitionIdentityLinkController
流程授權,沒有必要的業務邏輯這里省略,
7.流程定義任務ProcessDefinitionJobController
流程定義任務,沒有必要的業務邏輯這里省略,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/356143.html
標籤:其他
