日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

flowable 配置自定义表单_Flowable用代码自定义流程

發布時間:2025/4/16 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 flowable 配置自定义表单_Flowable用代码自定义流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

項目集成flowable有段時間了,發現行業的流程業務全是一條直線加3,4個人工審核的節點,并沒有分支網關等其它節點。因此原來用的model設計器組件多參數復雜,客戶現場的體驗不是很好。所以根據現場的實際業務自己調api的方式實現個簡單的流程設計器。

最終的實現的效果是由開始節點[StartEvent]和結束結點[EndEvent]及用戶任務節點[UserTask]組成的直線審核流程,并兼容用原生的流程設計器打開編輯。最終的效果如下圖所示:

最終的效果

前端界面設計介紹,用戶界面可以增加節點,刪除節點。對節點命名,定義節點的審核用戶[普通用戶或角色],具體效果圖如下所示:

用戶界面

定義收集前端參數的對象,具體代碼如下所示

@Data

public class ProcessParam {

//流程ID

private String modelId;

//流程定義key

private String key;

//流程名字

private String name;

//流程節點

private List tasks;

//開始結點名稱

private String startNodeName;

//結束節點名稱

private String endNodeName;

}

@Data

public class TaskParam {

public TaskParam(){

}

public TaskParam(String name,String no,String userType,List userOrRoleIds,String userOrRoleName){

this.name = name;

this.no = no;

this.userType = userType;

this.userOrRoleIds = userOrRoleIds;

this.userOrRoleName = userOrRoleName;

}

//節點名稱

private String name;

//節點編號

private String no;

//審核用戶類型 用戶(user)或角色(role)

private String userType;

//審核用戶或角色id

private List userOrRoleIds;

//用戶或角色名稱

private String userOrRoleName;

}

保存流程設計器的數據,具體的代媽如下:

大體思路是,構建一個BpmnModel對象,構建出各節點對象并設置好相關的參數,如名稱,編號,審核人等,用SequenceFlow對象按順序連接各節點對象,特別注意要設置各節點對象的outgoing屬性網上很多教程沒有提到這個,不設置會導致連接不正確。最后用BpmnAutoLayout對象自動設置好節點的坐標信息,不然也會導致流程在原生設計器顯示不正常。

public void saveModelData(ProcessParam processParam){

Model model = modelService.getModel(processParam.getModelId());

Process process = new Process();

process.setId(model.getKey());

process.setName(model.getName());

BpmnModel bpmnModelNew = new BpmnModel();

bpmnModelNew.addProcess(process);

List nodeList = processParam.getTasks();

//開始事件

StartEvent startEvent = new StartEvent();

startEvent.setId("start");

startEvent.setName(processParam.getStartNodeName());

process.addFlowElement(startEvent);

FlowElement waitNode = startEvent;

int i = 0;

for ( ;i < nodeList.size(); i++) {

TaskParam taskParam = nodeList.get(i);

UserTask userTask = new UserTask();

userTask.setId((i+1)+"");

userTask.setName(taskParam.getName());

if("user".equals(taskParam.getUserType())){

userTask.setCandidateUsers(taskParam.getUserOrRoleIds());

}

if("role".equals(taskParam.getUserType())){

userTask.setCandidateGroups(taskParam.getUserOrRoleIds());

}

process.addFlowElement(userTask);

SequenceFlow sequenceFlow = new SequenceFlow(waitNode.getId(), userTask.getId());

process.addFlowElement(sequenceFlow);

//設置當前節點的出口這個很關鍵,不設置這個的話生的流程圖會錯亂,網上很多教程也沒有提到

if(i==0){

((StartEvent) waitNode).setOutgoingFlows(ListUtil.toList(sequenceFlow));

}else {

((UserTask) waitNode).setOutgoingFlows(ListUtil.toList(sequenceFlow));

}

waitNode = userTask;

}

//結束事件

EndEvent completeEvent = new EndEvent();

completeEvent.setId("complete");

completeEvent.setName(processParam.getEndNodeName());

process.addFlowElement(completeEvent);

SequenceFlow endSequenceFlow = new SequenceFlow(waitNode.getId(), completeEvent.getId());

((UserTask) waitNode).setOutgoingFlows(ListUtil.toList(endSequenceFlow));

process.addFlowElement(endSequenceFlow);

//這句很關鍵讓程序自動部局各節點的位置,網上很多教程沒有提到

new BpmnAutoLayout(bpmnModelNew).execute();

//把BpmnModel轉成json格式進行保存

BpmnJsonConverter jsonConverter = new BpmnJsonConverter();

ObjectNode jsonNode = jsonConverter.convertToJson(bpmnModelNew);

modelService.saveModel(model.getId(),model.getName(),model.getKey(),model.getDescription(),jsonNode.toString(),true,"",new UserWf());

}

從數據庫獲取流程設計數據給到前端,具體代碼如下:

大體思路是:調用api獲取model對象,從model對象獲取流程的json字符串然后用工具類轉成BpmnModel對象,然后根據他們的關系生成ProcessParam對象傳到前端去。

public ProcessParam getModelData(String modelId){

ProcessParam processParam = new ProcessParam();

List tasks = new ArrayList<>();

processParam.setTasks(tasks);

Model model = modelService.getModel(modelId);

processParam.setModelId(model.getId());

processParam.setKey(model.getKey());

processParam.setName(model.getName());

//獲取流程設計器的json數據

String modelEditorJson = model.getModelEditorJson();

ObjectNode editorJsonNode = null;

try {

editorJsonNode = (ObjectNode) objectMapper.readTree(modelEditorJson);

} catch (IOException e) {

e.printStackTrace();

return processParam;

}

BpmnJsonConverter jsonConverter = new BpmnJsonConverter();

//把json轉成bpmnModel對象

BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorJsonNode);

Process process = bpmnModel.getMainProcess();

Map allNode = process.getFlowElementMap();

if(allNode==null||allNode.size()<1){//沒有節點信息直接返回

return processParam;

}

List startEventList = process.findFlowElementsOfType(StartEvent.class);

StartEvent startEvent = startEventList.get(0);

processParam.setStartNodeName(startEvent.getName());

String nextNodeId = startEvent.getOutgoingFlows().get(0).getTargetRef();

while (allNode.get(nextNodeId)!=null){

FlowElement fe = allNode.get(nextNodeId);

if(fe instanceof UserTask){

UserTask userTask = (UserTask) fe;

List userOrRoleIds = null;

String userOrRoleInfo = "";

String userType = null;

if(StrUtil.isNotBlank(userTask.getAssignee())){

userOrRoleIds = ListUtil.toList(userTask.getAssignee());

userType = "user";

}

if(userTask.getCandidateUsers()!=null&&userTask.getCandidateUsers().size()>0){

userOrRoleIds = userTask.getCandidateUsers();

userType = "user";

}

if(userTask.getCandidateGroups()!=null&&userTask.getCandidateGroups().size()>0){

userOrRoleIds = userTask.getCandidateGroups();

userType = "role";

}

//查詢用戶或角色名稱

if ("user".equals(userType)) {

userOrRoleInfo = this.getUserInfo(userOrRoleIds);

}

if ("role".equals(userType)) {

userOrRoleInfo = this.getRoleInfo(userOrRoleIds);

}

if(userTask.getOutgoingFlows().size()>1){

throw new RuntimeException("不支持多個分支流程數據,請使用高級流程設計器");

}

tasks.add(new TaskParam(userTask.getName(),userTask.getId(),userType,userOrRoleIds,userOrRoleInfo));

nextNodeId = userTask.getOutgoingFlows().get(0).getTargetRef();

}else if(fe instanceof EndEvent){

EndEvent endEvent = (EndEvent) fe;

processParam.setEndNodeName(endEvent.getName());

nextNodeId = "";

break;

}else {

throw new RuntimeException("不支持當前流程數據,請使用高級流程設計器");

}

}

return processParam;

}

總結

以上是生活随笔為你收集整理的flowable 配置自定义表单_Flowable用代码自定义流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。