1.部署流程模型为流程定义
| @PostMapping(value = "/addDeploymentByString") |
| public AjaxResult addDeploymentByString(@RequestParam("stringBPMN") String stringBPMN) { |
| processDefinitionService.addDeploymentByString(stringBPMN); |
| return AjaxResult.success(); |
| } |
| |
| public void addDeploymentByString(String stringBPMN) { |
| repositoryService.createDeployment() |
| .addString("CreateWithBPMNJS.bpmn", stringBPMN) |
| .deploy(); |
| } |
说明:stringBPMN该字符串其实就是一个xml,但与Modeler生成的内容不同;此处没有创建模型,直接进行部署。如果后期需求变更,可以基于该模型进行修改后再次部署,区别在于版本号+1,同时最新创建的流程实例是根据最新版本的流程定义创建的。
2.挂起/激活流程定义
| @PostMapping("/suspendOrActiveApply") |
| @ResponseBody |
| public AjaxResult suspendOrActiveApply(@RequestBody ProcessDefinitionDTO processDefinition) { |
| processDefinitionService.suspendOrActiveApply(processDefinition.getId(), processDefinition.getSuspendState()); |
| return AjaxResult.success(); |
| } |
| |
| public void suspendOrActiveApply(String id, Integer suspendState) { |
| if (1==suspendState) { |
| |
| |
| |
| repositoryService.suspendProcessDefinitionById(id); |
| } else if (2==suspendState) { |
| repositoryService.activateProcessDefinitionById(id); |
| } |
| } |
3.删除流程定义
| @DeleteMapping(value = "/remove/{deploymentId}") |
| public AjaxResult delDefinition(@PathVariable("deploymentId") String deploymentId) { |
| return toAjax(processDefinitionService.deleteProcessDefinitionById(deploymentId)); |
| } |
| |
| public int deleteProcessDefinitionById(String id) { |
| repositoryService.deleteDeployment(id, false); |
| return 1; |
| } |
4.查询流程定义
| @GetMapping(value = "/list") |
| public TableDataInfo list(ProcessDefinitionDTO processDefinition) { |
| PageDomain pageDomain = TableSupport.buildPageRequest(); |
| return getDataTable(processDefinitionService.selectProcessDefinitionList(processDefinition, pageDomain)); |
| } |
| |
| public Page<ProcessDefinitionDTO> selectProcessDefinitionList(ProcessDefinitionDTO processDefinition, PageDomain pageDomain) { |
| Page<ProcessDefinitionDTO> list = new Page<>(); |
| ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery().orderByProcessDefinitionId().orderByProcessDefinitionVersion().desc(); |
| if (StringUtils.isNotBlank(processDefinition.getName())) { |
| processDefinitionQuery.processDefinitionNameLike("%" + processDefinition.getName() + "%"); |
| } |
| if (StringUtils.isNotBlank(processDefinition.getKey())) { |
| processDefinitionQuery.processDefinitionKeyLike("%" + processDefinition.getKey() + "%"); |
| } |
| List<ProcessDefinition> processDefinitions = processDefinitionQuery.listPage((pageDomain.getPageNum() - 1) * pageDomain.getPageSize(), pageDomain.getPageSize()); |
| long count = processDefinitionQuery.count(); |
| list.setTotal(count); |
| if (count!=0) { |
| |
| Set<String> ids = processDefinitions.parallelStream().map(pdl -> pdl.getDeploymentId()).collect(Collectors.toSet()); |
| |
| List<ActReDeploymentVO> actReDeploymentVOS = actReDeploymentMapper.selectActReDeploymentByIds(ids); |
| |
| List<ProcessDefinitionDTO> processDefinitionDTOS = processDefinitions.stream() |
| .map(pd -> new ProcessDefinitionDTO((ProcessDefinitionEntityImpl) pd, actReDeploymentVOS.parallelStream().filter(ard -> pd.getDeploymentId().equals(ard.getId())).findAny().orElse(new ActReDeploymentVO()))) |
| .collect(Collectors.toList()); |
| list.addAll(processDefinitionDTOS); |
| } |
| return list; |
| } |
5.上传并部署流程定义
| public AjaxResult uploadStreamAndDeployment(@RequestParam("file") MultipartFile file) throws IOException { |
| processDefinitionService.uploadStreamAndDeployment(file); |
| return AjaxResult.success(); |
| } |
| |
| public void uploadStreamAndDeployment(MultipartFile file) throws IOException { |
| |
| String fileName = file.getOriginalFilename(); |
| |
| InputStream fileInputStream = file.getInputStream(); |
| |
| String extension = FilenameUtils.getExtension(fileName); |
| |
| if (extension.equals("zip")) { |
| ZipInputStream zip = new ZipInputStream(fileInputStream); |
| repositoryService.createDeployment() |
| .addZipInputStream(zip) |
| .deploy(); |
| } else { |
| repositoryService.createDeployment() |
| .addInputStream(fileName, fileInputStream) |
| .deploy(); |
| } |
| } |
6.查看流程模型
| public void getProcessDefineXML(HttpServletResponse response,@RequestParam("deploymentId") String deploymentId,@RequestParam("resourceName") String resourceName) throws IOException { |
| processDefinitionService.getProcessDefineXML(response, deploymentId, resourceName); |
| } |
| |
| public void getProcessDefineXML(HttpServletResponse response, String deploymentId, String resourceName) throws IOException { |
| InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, resourceName); |
| int count = inputStream.available(); |
| byte[] bytes = new byte[count]; |
| response.setContentType("text/xml"); |
| OutputStream outputStream = response.getOutputStream(); |
| while (inputStream.read(bytes) != -1) { |
| outputStream.write(bytes); |
| } |
| inputStream.close(); |
| } |
返回是xml
| <?xml version="1.0" encoding="UTF-8"?> |
| <bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://activiti.org/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"> |
| <bpmn2:process id="material_apply" name="物料申请1.2" isExecutable="true" activiti:versionTag="1.2.0"> |
| <bpmn2:startEvent id="StartEvent_1" name="Start" activiti:initiator="applyUserId"> |
| <bpmn2:outgoing>Flow_0w19svd</bpmn2:outgoing> |
| </bpmn2:startEvent> |
| <bpmn2:endEvent id="Event_15f0qdt" name="End"> |
| <bpmn2:incoming>Flow_1mzijq0</bpmn2:incoming> |
| <bpmn2:incoming>Flow_0eqii1k</bpmn2:incoming> |
| </bpmn2:endEvent> |
| <bpmn2:userTask id="saleSupportVerify" name="销售支持部审批" activiti:formKey="saleSupportVerify" activiti:candidateUsers="${sale_support_member}"> |
| <bpmn2:extensionElements> |
| <activiti:formProperty id="FormProperty_27mbu4f--__!!radio--__!!审批意见--__!!i--__!!同意--__--不同意" type="string" label="单选按钮" /> |
| <activiti:formProperty id="FormProperty_2am58qs--__!!textarea--__!!批注--__!!f__!!null" type="string" /> |
| </bpmn2:extensionElements> |
| <bpmn2:incoming>Flow_0w19svd</bpmn2:incoming> |
| <bpmn2:outgoing>Flow_156vjgs</bpmn2:outgoing> |
| </bpmn2:userTask> |
| <bpmn2:exclusiveGateway id="Gateway_1wob96l" name="网关3"> |
| <bpmn2:incoming>Flow_156vjgs</bpmn2:incoming> |
| <bpmn2:outgoing>Flow_1mzijq0</bpmn2:outgoing> |
| <bpmn2:outgoing>Flow_0eqii1k</bpmn2:outgoing> |
| </bpmn2:exclusiveGateway> |
| <bpmn2:sequenceFlow id="Flow_156vjgs" sourceRef="saleSupportVerify" targetRef="Gateway_1wob96l" /> |
| <bpmn2:sequenceFlow id="Flow_1mzijq0" name="同意" sourceRef="Gateway_1wob96l" targetRef="Event_15f0qdt"> |
| <bpmn2:extensionElements> |
| <activiti:executionListener class="com.chosenmed.workflow.oa.listener.MaterialListener" event="take"> |
| <activiti:field name="state"> |
| <activiti:string>3</activiti:string> |
| </activiti:field> |
| </activiti:executionListener> |
| </bpmn2:extensionElements> |
| <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${FormProperty_27mbu4f==0}</bpmn2:conditionExpression> |
| </bpmn2:sequenceFlow> |
| <bpmn2:sequenceFlow id="Flow_0w19svd" sourceRef="StartEvent_1" targetRef="saleSupportVerify" /> |
| <bpmn2:sequenceFlow id="Flow_0eqii1k" name="驳回" sourceRef="Gateway_1wob96l" targetRef="Event_15f0qdt"> |
| <bpmn2:extensionElements> |
| <activiti:executionListener class="com.chosenmed.workflow.oa.listener.MaterialListener" event="take"> |
| <activiti:field name="state"> |
| <activiti:string>2</activiti:string> |
| </activiti:field> |
| </activiti:executionListener> |
| </bpmn2:extensionElements> |
| </bpmn2:sequenceFlow> |
| </bpmn2:process> |
| <bpmndi:BPMNDiagram id="BPMNDiagram_1"> |
| <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="material_apply"> |
| <bpmndi:BPMNEdge id="Flow_0eqii1k_di" bpmnElement="Flow_0eqii1k"> |
| <di:waypoint x="820" y="105" /> |
| <di:waypoint x="820" y="292" /> |
| <bpmndi:BPMNLabel> |
| <dc:Bounds x="825" y="196" width="21" height="14" /> |
| </bpmndi:BPMNLabel> |
| </bpmndi:BPMNEdge> |
| <bpmndi:BPMNEdge id="Flow_0w19svd_di" bpmnElement="Flow_0w19svd"> |
| <di:waypoint x="208" y="80" /> |
| <di:waypoint x="530" y="80" /> |
| </bpmndi:BPMNEdge> |
| <bpmndi:BPMNEdge id="Flow_1mzijq0_di" bpmnElement="Flow_1mzijq0"> |
| <di:waypoint x="845" y="80" /> |
| <di:waypoint x="1090" y="80" /> |
| <di:waypoint x="1090" y="310" /> |
| <di:waypoint x="838" y="310" /> |
| <bpmndi:BPMNLabel> |
| <dc:Bounds x="1094" y="193" width="23" height="14" /> |
| </bpmndi:BPMNLabel> |
| </bpmndi:BPMNEdge> |
| <bpmndi:BPMNEdge id="Flow_156vjgs_di" bpmnElement="Flow_156vjgs"> |
| <di:waypoint x="630" y="80" /> |
| <di:waypoint x="795" y="80" /> |
| </bpmndi:BPMNEdge> |
| <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> |
| <dc:Bounds x="172" y="62" width="36" height="36" /> |
| <bpmndi:BPMNLabel> |
| <dc:Bounds x="181" y="105" width="25" height="14" /> |
| </bpmndi:BPMNLabel> |
| </bpmndi:BPMNShape> |
| <bpmndi:BPMNShape id="Event_15f0qdt_di" bpmnElement="Event_15f0qdt"> |
| <dc:Bounds x="802" y="292" width="36" height="36" /> |
| <bpmndi:BPMNLabel> |
| <dc:Bounds x="811" y="335" width="20" height="14" /> |
| </bpmndi:BPMNLabel> |
| </bpmndi:BPMNShape> |
| <bpmndi:BPMNShape id="Activity_0i9t2gt_di" bpmnElement="saleSupportVerify"> |
| <dc:Bounds x="530" y="40" width="100" height="80" /> |
| </bpmndi:BPMNShape> |
| <bpmndi:BPMNShape id="Gateway_1wob96l_di" bpmnElement="Gateway_1wob96l" isMarkerVisible="true"> |
| <dc:Bounds x="795" y="55" width="50" height="50" /> |
| <bpmndi:BPMNLabel> |
| <dc:Bounds x="805" y="31" width="29" height="14" /> |
| </bpmndi:BPMNLabel> |
| </bpmndi:BPMNShape> |
| </bpmndi:BPMNPlane> |
| </bpmndi:BPMNDiagram> |
| </bpmn2:definitions> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了