# 平台模式 ## 1.平台模式简介 平台模式是将流程引擎与其他功能解耦,作为独立的模块。这样第三方系统可以通过外部接口调用平台上面设计好的流程,将表单提交至流程中进行流转;而平台内本身的功能,则通过内部接口进行调用流程引擎。 ## 2.思路 **场景设定** 第三方系统A,想实现订单申请的功能,需要有严格的流程审批操作,例如发起流程、提交流程、回退流程,获取最新的流程状态等,但是想保留系统页面整体更改,只是想调用插件的形式,调用BPM系统的流程引擎,进行审批和回退的操作,这样具体的思路如下: 1、发起的入口在本系统,需要自己设计页面,实现了增、删、改、查。 2、在BPM系统中,软件设置为平台模式下(新建软件,可以选择此模式),再配置流程逻辑。 3、在本系统页面中,具体操作按钮,触发时调用对接流程引擎的接口,发起流程的顺序是:第一步是先生成accessToken ,获取用户凭证(有效期一个小时),第二步是发起流程(返回流程实例是关键),第三步是再执行提交/审批流程的接口,最后如果需要回退等特殊操作,则执行对应接口;审批流程顺序是:第一步是先生成accessToken ,获取用户凭证(有效期一个小时),第二步是执行提交/审批流程的接口,如果例子中使用到的接口如下。(实例仅供参考) 1. 生成AccessToken Restful接口:/rest/accessToken 2. 发起流程:POST /api/rest/bpm/runtime/start 3. 流程状态:GET /api/rest/bpm/query/states 4. 获取流程提交面板:POST /api/rest/bpm/query/submission 5. 提交和审批流程:POST /api/rest/bpm/runtime/submission 6. 获取流程回退面板:POST /api/rest/bpm/query/back 7. 流程驳回:POST /api/rest/bpm/runtime/back **注:上面七个接口完成提交和回退的操作,参数详细查看当前RESTful API文档。** ## 3.平台模式配置和流程的操作 ### 3.1.配置软件模式为平台模式(已配置,则略过) ![img](./images/1628580884.jpg) **如果重新配置,操作步骤如下** ![img](./images/wps3.jpg) 第一步:填写软件基本信息 ![img](./images/wps4.jpg) **配置信息:** 软件名称:设置软件的名称。 排序号:设置此软件在软件列表的排序位置。 数据源:数据库连接方式,需在高级工具-数据源中创建数据源后才可进行选择。 **操作栏:** RESTful API文档:对平台模式接口调用的API,第三方系统可调用接口 保存:保存当前页面信息。 退出:返回软件列表信息界面。 ![img](./images/wps5.png) 第二步:配置数据源 选择数据源,首先填写名称之后选择数据类型, 数据库支持多种类型,例如: MySQL、Oracle、SQLSever、DB2等等常用数据库,之后填写对应数据库的连接地址,填写完之后点击测试数据库进行验证是否能连接成功。 ![img](./images/wps6.jpg) ![img](./images/wps7.jpg) **注: 平台安装的时候会默认给用户安装MySQL数据库,用户自行在下载数据库客户端工具进行连接,连接****端口为localhost,端口****号为3307,****账号为root,****密码****为空****,****库可以由用户自己新建或者是直接使用系统库****OBPM****。** ### 3.2.流程配置 流程是用于设置表单提交后的流转过程,在流程中可对表单的流转条件进行判断、可自动流转、可提交人工审批等。 #### 3.2.1.流程界面 ![img](./images/wps8.jpg) **配置信息:** 主题:定义流程的名称,必填,不可重名。 作者:定义创建流程的用户,目前默认为超级管理员admin。 查看源代码:用户在图表中设计好流程图,切换到代码模式复制流程代码之后到另一个流程面板中粘贴即可复制流程。 流程设计工具:关联线、开始节点、结束节点、自动节点、人工节点、子流程节点。 清除:清除流程编辑器中选中的节点。 #### 3.2.2.关联线 设置节点与节点之间的关联,在关联线中用户可以填写脚本或者通过设计模式设置节点进入条件。 ![img](./images/wps9.jpg) #### 3.2.3.节点配置 节点配置这里采用的是角色 ![img](./images/wps10.jpg) **角色配置** 角色是软件中权限管理的基本单位,流程处理也是针对角色进行的,角色可以按照客户需求自己新建的,可以在角色下添加用户,一个角色可添加多个用户。 在软件-常用工具,新建角色,填写角色名称。 ![img](./images/wps11.jpg) **注:是否****为默认****角色****,如果****勾选了****“是”之后,****所有****新建的用户都****会****添加该角色****。** 配置完成后,在企业域中添加设置好的软件 ![img](./images/wps12.jpg) 用户进行角色的添加 ![img](./images/wps13.jpg) #### 3.2.3.配置回调信息(按需配置,可跳过) BPM平台模式软件有关回调的说明: 当BPM平台模式的软件定义的流程触发到"跳过""过期""自动审批""子流程回调"等流程事件时,BPM平台会调用回调服务,将有关流程实例以及事件类型的信息传递给第三方业务系统,由第三方系统自行处理回调逻辑。 回调配置说明: | (1)URL:第三方业务系统的事件回调服务地址,负责接收或处理BPM平台发送的回调事件信息;例如:https://127.0.0.1:8080/CallbackEvent | | ------------------------------------------------------------ | | (2)Token:BPM平台将请求发送到第三方业务系统,需通过第三方业务系统的身份验证,该Token为第三方业务系统所定义的令牌,随数据一同发送至第三方业务系统 | | (3)EncodingAESkey:BPM平台将请求发送到第三方业务系统,需通过第三方业务系统的身份验证,该Token为第三方业务系统所定义的解密密钥,随数据一同发送至第三方业务系统 | ![img](./images/wps14.png) #### 3.3.4.调用接口 平台模式使用的流程接口都是使用的restful接口完成的动作,所以accessToken是用来认证的是否可以使用接口的权限。 **注:如果是发起流程,首先调用启动流程接口,再调用提交流程接口,如果是审批流程,则只需要调用提交流程接口。** **注:accessToken,applicationid,flowid参数在4.1,4.2,4.3中说明了。** ##### 启动流程 案例中把接口调用写在controller层,把我们的要调用的接口地方进行调用和其他的流程操作。 发起流程:POST /api/rest/bpm/runtime/start 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ------------------------------------------------------------ | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | applicationId | String | 平台模式软件的id(软件id固定),参考常用参数获取方法-如何获取applicationid | | userCode | String | 启动流程审批人的账号(必须有审批权限)(并非用户UUID) | | flowId | String | 流程ID,参考常用参数获取方法-如何获取flowId | | | | | **请求包体:** ``` {'id':'可设置自己的表单id(唯一值)','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}} ``` 代码如下: ``` @Test //启动 public void testFlowStart(){ long __start = System.currentTimeMillis(); RestTemplate restTemplate = new RestTemplate(); // http://10.74.68.27:8080/obpm/rest/bpm/runtime/start String content=""; //String ret= HttpUtils.getInstance().postOkHttpData(content,url); //eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoMCIsImV4cCI6MTU4Nzg5MzEwNywidXNlcm5hbWUiOiJ1bmRlZmluZWQifQ.CVa957oEqzYs3qfIPYAXEu6xiepktq_Pxz9QE8P9Mz0 String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); // accessToken1 = "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoMCIsImV4cCI6MTU4OTI3MDU1NSwidXNlcm5hbWUiOiJ1bmRlZmluZWQifQ.nG0tazAUI057zffDFJN_ODu3rcrECnwsRFwwm4Oox3o"; // 流程启动接口 String applicationId="__rEGKuyPJhV4qdCuitKd"; // 审批员code String userCode="admin1"; // 流程ID String flowId="__LrcK3s4zB4ojJgdKwTJ"; String url="http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/start"; url= url+"?accessToken="+accessToken1+"&applicationId="+applicationId+"&userCode="+userCode+"&flowId="+flowId; // 拼接请求的包体 String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String startResult=restTemplate.postForObject(url,formEntity,String.class); // 解析 JSONObject startJsonObject=JSONObject.parseObject(startResult); String data=startJsonObject.getString("data"); JSONArray list1 = startJsonObject.parseArray(data); System.out.println("data:"+data.toString()); String instanceId=list1.getJSONObject(0).getString("instanceId"); System.out.println("流程实例Id:"+instanceId); System.err.println("submitWorkflow step -1 :" + (System.currentTimeMillis() - __start)); } ``` 启动成功后会返回json需要拿到流程实例id,json如下 ``` {"errcode":0,"errmsg":"success","data":[{"instanceId":"nGXxB33aRi0fv05ium5","flowName":"demo","flowId":"sdJnGepjKEirS2ctPQT","nodes":[{"nodeId":"1562684178918","stateLabel":"申请","state":0,"auditors":[{"id":"11e4-63ff-5d9df2ad-9f19-57d7b83ae7be","name":"admin","userCode":"admin1"},{"id":"11e8-46a9-8d876d13-94a7-9b60038597d7","name":"happy爱我中国信","userCode":"happy"}],"coAuditors":[]}]}]} ``` Errcode:返回状态码,0为成功; Errmsg:返回错误信息, instanceId:流程实例ID,如果针对同一张审批单,虽然审批状态会不断改变,流程实例ID是不变。 flowName:流程名称。 Flowid:流程ID。 Nodeid:当前状态的节点ID。 stateLabel:当前状态。 State:流程状态码,0为启动状态,256=审批中,流程正常流程的状态,65536=否决,流程被否决,1048576=流程已完结。 Auditors:当前审批人数组信息。 coAuditors:当前协办人的数组信息。 ##### 提交面板 场景说明:提交时调用流程提交面板获取下一节点的信息 POST /api/rest/bpm/query/submission 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | l流程实例id | | applicationId | String | 应用Id | | userCode | String | 用户编码(账号) | | flowId | String | 流程id(注:不是流程实例id) | **请求包体:** ``` {'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}} ``` **参数说明:** 此代码仅供参考 ``` @Test public void testSubmissionPanel(){ RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); //流程实例id String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; //表单id String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String url = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/query/submission?accessToken=" + accessToken1 + "&applicationId=__rEGKuyPJhV4qdCuitKd&userCode=admin1&flowId=__LrcK3s4zB4ojJgdKwTJ&&instanceId=" + instance; //获取提交面板(panel) String panelResult = restTemplate.postForObject(url, formEntity, String.class); //解析流程启动返回的json进行解析(需要获取生成的流程实例id并放入表单中为后面的获取流程提交面板和提交流程) System.out.println("流程面板"+panelResult); } ``` 返回结果 ``` {"errcode":0,"errmsg":"success","data":{"isSplit":false,"instanceId":"123456789030-__YtCyk0oFAoaY7Zu4ZWF","nextNodes":[{"name":"开发","checked":true,"id":"1590669895255","type":"ManualNode","locked":false}],"isToPerson":true,"currentNodeId":"1581326887815","flowId":"__8bj1HcIt5CawwFlZvh5","splitToken":"1581326887815"}} ``` ##### 提交流程 提交和审批流程:POST /api/rest/bpm/runtime/submission 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | ------------- | ------------------------------------------------------------ | | accessToken | String | 认证的标识 | | applicationId | String | 平台模式软件的id | | instanceId | String | 流程实例id | | userCode | String | 审批的用户账号 | | postBody | String | 请求的包体必须按照如下个格式拼接({'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}}) | | flowtype | String | 类型不同数字不同,这里使用80提交(1>开始->手工 2>开始->自动 42>开始->子流程 8>终止 80>提交 81>退回 83>运行->自动 85>回撤) | | currNodeId | String | 当前节点id(通过获取流程提交面板获取) | | nextNodeids | Array[string] | **下一节点的节点定义对象的集合(数组)** | | comment | String | **审批意见可以为空** | **请求包体:** ``` {'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}} ``` **参数说明:** 实现代码如下: 思路需要先获取流程提交的面板,获取返回的json数据,解析出来需要使用的参数值如: (currNodeId和nextNodeids参数),在进行流程的提交 ``` @Test //提交 public void testSubmission(){ RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); //流程实例id String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String url = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/query/submission?accessToken=" + accessToken1 + "&applicationId=__rEGKuyPJhV4qdCuitKd&userCode=admin1&flowId=__LrcK3s4zB4ojJgdKwTJ&&instanceId=" + instance; //获取提交面板(panel) String panelResult = restTemplate.postForObject(url, formEntity, String.class); //解析流程启动返回的json进行解析(需要获取生成的流程实例id并放入表单中为后面的获取流程提交面板和提交流程) JSONObject paneljsonObject = JSONObject.parseObject(panelResult); String currentNodeId = paneljsonObject.getJSONObject("data").getString("currentNodeId"); String nextNodes = paneljsonObject.getJSONObject("data").getString("nextNodes"); //流程实例id(因返回的json中包含list数据需要进行list遍历获取流程实例id) List studentList1 = paneljsonObject.parseArray(nextNodes); //下一节点id String nextNode = ((JSONArray) studentList1).getJSONObject(0).getString("id"); //提交流程restful url = rest/bpm/runtime/submission String urlSubmission = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/runtime/submission?accessToken=" + accessToken1 + "&applicationId=__rEGKuyPJhV4qdCuitKd&userCode=admin1&comment=111111&instanceId=" + instance + "&nextNodeIds=" + nextNode + "&flowType=80&currNodeId=" + currentNodeId; //获取提交的成功返回值 String submissionResult = restTemplate.postForObject(urlSubmission, formEntity, String.class); System.out.println("submissionResult"+submissionResult); } ``` 请求成功返回的json如下: ``` {"errcode":0,"errmsg":"success","data":[{"instanceId":"123456789030-__YtCyk0oFAoaY7Zu4ZWF","flowName":"测试","flowId":"__8bj1HcIt5CawwFlZvh5","nodes":[{"nodeId":"1590669895255","stateLabel":"开发","state":0,"auditors":[{"id":"zPsp2hk7CEwtqeMCwtj","name":"管理员","userCode":"admin1"},{"id":"0TblO2uKjQ2sLDY64yF","name":"junye","userCode":"junye"}],"coAuditors":[]}]}]} ``` ##### 回退面板 场景说明:表单中的按钮来进行流程的回退,回退需要利用获取流程回退的面板,先获取之前走过的流程节点信息,之后再调用回退的接口,回退历史指定节点。 POST /api/rest/bpm/query/back 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | userCode | String | 审批的用户账号 | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | applicationId | String | 软件id | 此代码仅供参考 ``` @Test //回退 public void testBackPanel(){ RestTemplate restTemplate = new RestTemplate(); String secret="1234567890001-7rVQQ9LuJev8ZD2Hjdz"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); //流程实例id String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); //获取流程回退面板的调用 String url = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/query/back?accessToken=" + accessToken1 + "&applicationId=__rEGKuyPJhV4qdCuitKd&userCode=admin1&instanceId=" + instance; //获取流程回退面板 String panelResult = restTemplate.postForObject(url, formEntity, String.class); System.out.println(panelResult.toString()); } ``` ##### 流程回退 流程驳回:POST /api/rest/bpm/runtime/back 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | ------------- | ------------------------------------------------------------ | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | applicationId | String | 平台模式软件的id(软件id固定),参考常用参数获取方法-如何获取applicationid | | instanceId | String | 从接口上一步提交流程的接口返回值中获取 | | userCode | String | 审批的用户账号 | | postBody | String | 请求的包体必须按照如下个格式拼接({'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}}) | | flowtype | String | 类型不同数字不同,这里使用81回退(1>开始->手工 2>开始->自动 42>开始->子流程 8>终止 80>提交 81>退回 83>运行->自动 85>回撤) | | currNodeId | String | 当前节点id(通过获取流程提交面板获取currNodeId) | | nextNodeids | Array[string] | 下一节点的节点定义对象的集合(backNodes的某个节点id) | | comment | String | 审批意见必须填写 | | flowid | String | 流程ID,参考常用参数获取方法-如何获取flowId | **请求包体:** ``` {'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}} ``` 代码如下: ``` @Test //回退 public void testBack(){ RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); //流程实例id String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); //获取流程回退面板的调用 String url = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/query/back?accessToken=" + accessToken1 + "&applicationId=__rEGKuyPJhV4qdCuitKd&userCode=admin1&instanceId=" + instance; //获取提交面板(panel) String panelResult = restTemplate.postForObject(url, formEntity, String.class); //解析流程启动返回的json进行解析(需要获取生成的流程实例id并放入表单中为后面的获取流程提交面板和提交流程) JSONObject paneljsonObject = JSONObject.parseObject(panelResult); String currentNodeId = paneljsonObject.getJSONObject("data").getString("currentNodeId"); String nextNodes = paneljsonObject.getJSONObject("data").getString("backNodes");//上一节点id数组 //流程实例id(因返回的json中包含list数据需要进行list遍历获取流程实例id) //data的格式:[{"instanceId":"kctdYk9GBOCmP0icER4","nodes":[{"auditors":[{"name":"admin","id":"11e4-63ff-5d9df2ad-9f19-57d7b83ae7be","userCode":"admin1"}],"stateLabel":"申请","coAuditors":[],"state":0,"nodeId":"1561633008392"}],"flowName":"demoflow","flowId":"gMQk2QAkwpL33z7gUJt"}] List studentList1 = paneljsonObject.parseArray(nextNodes); //上一节点id String nextNode = ((JSONArray) studentList1).getJSONObject(0).getString("id"); //提交流程restful url = /rest/bpm/runtime/back String urlBack = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/runtime/back?accessToken=" + accessToken1 + "&applicationId=__rEGKuyPJhV4qdCuitKd&userCode=admin1&comment=111111&instanceId=" + instance + "&nextNodeIds=" + nextNode + "&flowId=__LrcK3s4zB4ojJgdKwTJ&flowType=81&currNodeId=" + currentNodeId; //获取回退的返回值 String backResult = restTemplate.postForObject(urlBack, formEntity, String.class); System.out.println("back:"+backResult); } ``` 回退成功返回值json ``` {"errcode":0,"errmsg":"success","data":[{"instanceId":"DYuTIOYnbWheGjQ946P","flowName":"demo","flowId":"sdJnGepjKEirS2ctPQT","nodes":[{"nodeId":"1562684178918","stateLabel":"申请","state":0,"auditors":[{"id":"11e4-63ff-5d9df2ad-9f19-57d7b83ae7be","name":"admin","userCode":"admin1"}],"coAuditors":[]}]}]} ``` ##### 流程回撤 场景说明:当用户提交到错误节点时,需要追回自己提交权限 POST /api/rest/bpm/runtime/retracement 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | applicationId | String | 应用Id | | userCode | String | 用户编码 | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | | | | **请求包体:** ``` {'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}}** ``` 此代码仅供参考 ``` @Test //撤回 public void testRetracement(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/retracement?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=admin1"; String result=restTemplate.postForObject(url,formEntity,String.class); // 解析 JSONObject startJsonObject=JSONObject.parseObject(result); System.out.println("撤回"+startJsonObject.toString()); } ``` ##### 添加流程节点审批人(主办) 场景说明:当前节点需要给予当前审批人以外的人审批时 POST /api/rest/bpm/runtime/auditor 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 软件id | **请求包体:** ``` "[0URvyCUds2T4PGx4yLB,0JyBHSIZPmSOQpQwd1K]" ``` 此代码仅供参考 ``` @Test //添加节点审批人 public void testupdateAuditor(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String ids = "[__06kBKpwSEwyFaIaCT5S]"; // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(ids,headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/auditor?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=admin1"; String startResult=restTemplate.postForObject(url,formEntity,String.class); System.out.println(startResult.toString()); } ``` ##### 编辑流程节点审批人(主办) 场景说明:可删除和增加当前节点的审批人 POST /api/rest/bpm/runtime/approvers 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 软件id | **请求包体:** ``` "[0URvyCUds2T4PGx4yLB,0JyBHSIZPmSOQpQwd1K]" ``` 此代码仅供参考 ``` @Test //编辑流程节点审批人 public void testupdateApprovers(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String ids = "[__06kBKpwSEwyFaIaCT5S]"; // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(ids,headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/approvers?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=admin1"; String startResult=restTemplate.postForObject(url,formEntity,String.class); System.out.println(startResult.toString()); } ``` ##### ##### 流程添加协办人 场景说明:当前协办人不满足审批权限时,需要添加另外的协办人 POST /api/rest/bpm/runtime/assist/addition 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 应用id | | | | | 此代码仅供参考 ``` @Test //添加协办人 public void testaddCoAuditor(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String reportId="1234567890001"; //用户id String ids = "[__06kBKpwSEwyFaIaCT5S]"; // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(ids,headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/assist/addition?accessToken="+accessToken1+"&instanceId="+reportId+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=admin1"; String startResult=restTemplate.postForObject(url,formEntity,String.class); System.out.println(startResult); } ``` ##### 流程协办 场景说明:审批协办 Post /api/rest/bpm/runtime/assist 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 应用id | | comment | String | 审批意见 | 此代码仅供参考 ``` @Test //协办 public void testdoAssist(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity("",headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/assist?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=444"+"&comment=111"; String startResult=restTemplate.postForObject(url,formEntity,String.class); // 解析 JSONObject startJsonObject=JSONObject.parseObject(startResult); } ``` ##### 流程挂起 场景说明:当此流程实力不需要再运行,但是之后还可能恢复运行时 POST /api/rest/bpm/runtime/suspend 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | applicationId | String | 应用id | | userCode | String | 用户账号 | **请求包体:** ``` {'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}}** ``` 此代码仅供参考 ``` @Test //挂起 public void testSuspend(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/suspend?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=444"; String startResult=restTemplate.postForObject(url,formEntity,String.class); // 解析 JSONObject result=JSONObject.parseObject(startResult); System.out.println("挂起"+result.toString()); } ``` ##### 流程恢复 场景说明:恢复挂起的流程 POST /api/rest/bpm/runtime/recovery 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 应用id | **请求包体:** ``` {'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}}** ``` 此代码仅供参考 ``` @Test //挂机->恢复 public void testRecovery(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String reportId="1234567890001"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/recovery?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=444"; String result=restTemplate.postForObject(url,formEntity,String.class); System.out.println("恢复"+result.toString()); } ``` ##### 流程终止 场景说明:终止流程,之后不需要恢复,相当于结束 GET /api/rest/bpm/runtime/termination 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 应用id | **请求包体:** ``` {'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}}** ``` 此代码仅供参考 ``` @Test public void testterminate(){ String instance = "123456789029-__YZzS6TqkoYrl1c8bUPX"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String reportId="123456789029"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String url = "http://127.0.0.1:8083/obpm/rest/bpm/runtime/termination?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__S9IYpOoGT5Acu5oyKwJ"+"&userCode=junye"; String startResult=restTemplate.postForObject(url,formEntity,String.class); // 解析 JSONObject startJsonObject=JSONObject.parseObject(startResult); System.out.println("终止"+startJsonObject.toString()); } ``` ##### 流程催办面板 场景说明:使用流程催办接口时,此接口获取可催办节点 GET /api/rest/bpm/query/remind 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 应用id | ``` @Test //催办面板 public void testReminderPanel(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); // 调用HTTP String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/query/remindpanel?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=444"; String result=restTemplate.getForObject(url,String.class); System.out.println("催办"+result.toString()); } ``` 此代码仅供参考 ``` @Test //催办 public void testReminderPanel(){ String instance = "123456789041-__3yCSkekESpdXHm1z74t"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); // 调用HTTP String url = "http://127.0.0.1:8083/obpm/rest/bpm/query/remindpanel?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__S9IYpOoGT5Acu5oyKwJ"+"&userCode=janceshi"; String result=restTemplate.getForObject(url,String.class); System.out.println("催办"+result.toString()); } ``` ##### 流程催办 场景说明:提醒审批人处理流程 POST /api/rest/bpm/runtime/remind 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | applicationId | String | 应用id | **请求包体:** ``` "[节点id1,节点id2]" ``` 此代码仅供参考 ``` @Test //催办 public void testReminder(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); //催办面板接口拿到的 String ids = "[1626333305435]"; // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(ids,headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/remind?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=444&reminderContent=111111222222"; String result=restTemplate.postForObject(url,formEntity,String.class); System.out.println("催办"+result.toString()); } ``` ##### 催办历史 场景说明:查看催办历史 GET /rest/bpm/history/remind 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | userCode | String | 用户账号 | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | l流程实例id | | applicationId | String | 应用id | 此代码仅供参考 ``` @Test //催办历史 public void testReminderhis(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); // 调用HTTP String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/history/remindhis?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=444"; String result=restTemplate.getForObject(url,String.class); System.out.println("催办"+result.toString()); } ``` ##### 添加/补签意见 场景说明:需要在当前流程再补签自己的意见 GET /api/rest/bpm/runtime/supplement 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | 流程实例id | | userCode | String | 用户账号 | | comments | String | 补签意见 | | applicationId | String | 应用id | 此代码仅供参考 ``` @Test //补签 public void testSupplement(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); // 调用HTTP HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity("",headers); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/runtime/supplement?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"+"&userCode=444&content=111111222222"; String result=restTemplate.postForObject(url,formEntity,String.class); System.out.println("补签"+result.toString()); } ``` ##### 获取流程中所在节点的状态值 场景:可以在申请的页面中,通过接口调用/rest/bpm/query/states,获取流程状态的信息 流程状态:GET /api/rest/bpm/query/states 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | -------- | ------------------------------------------------------------ | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | applicationId | String | 平台模式软件的id(软件id固定),参考常用参数获取方法-如何获取applicationid | | instanceId | String | 流程实例id | 接口请求成功后的返回的json如下: ``` 返回的json {"errcode":0,"data":[{"instanceId":"123456789009-__b79dhPs3XzsQ9aMLnXX","nodes":[{"auditors":[{"name":"junye","id":"0TblO2uKjQ2sLDY64yF","userCode":"junye"},{"name":"管理员","id":"zPsp2hk7CEwtqeMCwtj","userCode":"admin1"}],"stateLabel":"子节点一","coAuditors":[],"state":0,"nodeId":"1590140751432"}],"flowName":"子流程","flowId":"__5E4FAfPReq0roKZsa1S","currStateId":"123456789009-__b79dhPs3XzsQ9aMLnXX"}],"errmsg":"success"} ``` 获取返回json解析,代码如下 ``` @Test //流程状态 public void testGetState(){ // String instance = "123456789009-__KG7q91d4brCxnY1BCAK"; String id = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/query/states?userCode=admin1&applicationId=__rEGKuyPJhV4qdCuitKd&accessToken="+accessToken1+"&instanceId="+id; String result = restTemplate.getForObject(url,String.class); JSONObject jsonPending = JSONObject.parseObject(result); System.out.println("a------->"+jsonPending.toString()); } ``` 效果: ![img](./images/wps25.png) ##### 流程提交指定审批人 场景说明:如果下个节点有N个审批人,流程可以设置指定审批人的操作,并提供相应接口 POST /api/rest/bpm/runtime/submit **指定审批人接口可以参考提交流程的写法,注意:指定审批人的json拼接的格式** 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------- | ------------- | ------------------------------------------------------------ | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | applicationId | String | 平台模式软件的id(软件id固定),参考常用参数获取方法-如何获取applicationid | | instanceId | String | 从接口上一步提交流程的接口返回值中获取 | | userCode | String | 审批的用户账号 | | postBody | String | 请求的包体必须按照如下个格式拼接({'id':'可设置自己的表单id','summary':'业务表单摘要描述','items':{‘自己的字段名 ':'值 ','name':'hahaha','age':24}, 'submitTo':[{'nodeid':'下一节点id','isToPerson':true,'userids':'审批人id'}]}) | | flowtype | String | 类型不同数字不同,这里使用80提交(1>开始->手工 2>开始->自动 42>开始->子流程 8>终止 80>提交 81>退回 83>运行->自动 85>回撤) | | currNodeId | String | 当前节点id(通过获取流程提交面板获取) | | nextNodeids | Array[string] | **下一节点的节点定义对象的集合(数组)** | | comment | String | **审批意见可以为空** | 具体的请求参数查看 (提交和审批流程)唯一不同的是请求的包体中需要拼接一下部分 ``` submitTo:[{'nodeid': '下一节点id','isToPerson':true,'userids':'指定审批人的用户id'}] ``` 此代码仅供参考 ``` @Test //提交(指定审批人) public void testSubmit(){ RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); //流程实例id String instance = "123456789027-__3L30YYuLT6f3UOoYi68"; String reportId="123456789027"; Map param= Maps.newHashMap("",""); param.put("itemName","keyanReportId"); param.put("itemValue","ky000011"); JSONObject json=new JSONObject(); json.put("id",reportId); json.put("summary","可研报告流程测试"); json.put("items",param); String subinfo = "[{'nodeid':'1590669895255','isToPerson':true,'userids':'zPsp2hk7CEwtqeMCwtj'}]"; json.put("submitTo",JSONObject.parseArray(subinfo)); HttpHeaders headers=new HttpHeaders(); MediaType type1=MediaType.parseMediaType("application/json;charset=UTF-8"); headers.setContentType(type1); HttpEntity formEntity=new HttpEntity(JSONObject.toJSONString(json),headers); String url = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/query/submission?accessToken=" + accessToken1 + "&applicationId=__S9IYpOoGT5Acu5oyKwJ&userCode=junye&flowId=__8bj1HcIt5CawwFlZvh5&&instanceId=" + instance; //获取提交面板(panel) String panelResult = restTemplate.postForObject(url, formEntity, String.class); //解析流程启动返回的json进行解析(需要获取生成的流程实例id并放入表单中为后面的获取流程提交面板和提交流程) JSONObject paneljsonObject = JSONObject.parseObject(panelResult); String currentNodeId = paneljsonObject.getJSONObject("data").getString("currentNodeId"); String nextNodes = paneljsonObject.getJSONObject("data").getString("nextNodes"); //流程实例id(因返回的json中包含list数据需要进行list遍历获取流程实例id) List studentList1 = paneljsonObject.parseArray(nextNodes); //下一节点id String nextNode = ((JSONArray) studentList1).getJSONObject(0).getString("id"); //提交流程restful url = rest/bpm/runtime/submission String urlSubmission = "http://127.0.0.1:8083/obpm/" + "api/rest/bpm/runtime/submit?accessToken=" + accessToken1 + "&applicationId=__S9IYpOoGT5Acu5oyKwJ&userCode=junye&comment=111111&instanceId=" + instance + "&nextNodeIds=" + nextNode + "&flowType=80&currNodeId=" + currentNodeId; //获取提交的成功返回值 String submissionResult = restTemplate.postForObject(urlSubmission, formEntity, String.class); System.out.println("submissionResult"+submissionResult); } ``` ##### 流程历史 场景说明:查看流程历史 GET /api/rest/bpm/history/flowHistory 需要的参数有: | 参数名 | 参数类型 | 备注 | | ----------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | id | String | 自主定义的表单id(启动流程包体内的id) | 此代码仅供参考 ``` @Test //流程历史 public void testGethis(){ RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String url = "http://127.0.0.1:8083/obpm/rest/bpm/history/flowHistory?accessToken="+accessToken1"+&id=123456789002"; String result = restTemplate.getForObject(url,String.class); // JSONObject myProcessing = JSONObject.parseObject(result); System.out.println("a------->"+result.toString()); } ``` ##### 流程图 场景说明:查看流程图 GET /api/rest/bpm/history/flowPhoto 需要的参数有: | 参数名 | 参数类型 | 备注 | | ----------- | -------- | ---------------------------------------------------- | | accessToken | String | 认证的标识,参考常用参数获取方法-如何生成accessToken | | instanceId | String | l流程实例id | 此代码仅供参考 ``` @Test //流程图 public void testGetflowPhoto(){ String instance = "1234567890001-7rVQQ9LuJev8ZD2Hjdz"; RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/history/flowPhoto?accessToken="+accessToken1+"&instanceId="+instance+"&applicationId=__rEGKuyPJhV4qdCuitKd"; String result = restTemplate.getForObject(url,String.class); System.out.println("result"+result); // System.out.println("a------->"+myProcessing.getJSONObject("data").toString()); } ``` ##### 待办接口 场景说明:可以在本身系统中,提供菜单入口,查询申请人的待办信息,页面需要自己写,接口可以调用 GET /api/rest/bpm/myPending 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------ | -------- | ---------------------------------------- | | accessToken | String | 认证的标识 | | userCode | String | 用户账号(这里直接使用当前登陆账号即可) | | pageNo | String | 现在的页数 | | linesPerPage | String | 每页显示的条数。 | 代码如下(仅供参考) ``` @Test //待办 public void testGetPending(){ RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"/api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/myPending?userCode=admin1&accessToken="+accessToken1+"&pageNo=1&linesPerPage=5"; String result = restTemplate.getForObject(url,String.class); JSONObject jsonPending = JSONObject.parseObject(result); System.out.println("a------->"+jsonPending.getJSONObject("data").toString()); } ``` 返回的json如下需要自己进行处理解析json ##### 经办接口 场景说明:可以在本身系统中,提供菜单入口,查询申请人的待办信息,页面需要自己写,接口可以调用 GET /api/rest/bpm/myProcessing 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------------ | -------- | ---------------------------------------- | | accessToken | String | 认证的标识 | | userCode | String | 用户账号(这里直接使用当前登陆账号即可) | | pageNo | String | 现在的页数 | | linesPerPage | String | 每页显示的条数。 | 代码如下(仅供参考) ``` @Test //经办 public void testGetProcessing(){ RestTemplate restTemplate = new RestTemplate(); String secret="11ea-68bf-1f01df4d-bac5-5720a8c56616"; String url1="http://127.0.0.1:8083/obpm/"+"api/rest/accessToken?secret="+secret; String result1=restTemplate.getForObject(url1,String.class); JSONObject jsonObject=JSONObject.parseObject(result1); String accessToken1=jsonObject.getJSONObject("data").getString("accessToken"); String url = "http://127.0.0.1:8083/obpm/api/rest/bpm/myProcessing?userCode=admin1&accessToken="+accessToken1+"&pageNo=1&linesPerPage=5"; String result = restTemplate.getForObject(url,String.class); JSONObject myProcessing = JSONObject.parseObject(result); System.out.println("a------->"+myProcessing.getJSONObject("data").toString()); } ``` 返回的json如下需要自己进行处理解析json ## 4.常用的参数获取方法 ### 4.1.如何生成accessToken 接口名称:[/rest/accessToken](#!/生成accessToken执行模块/accessTokenUsingGET) **(****A****ccess****Token****生命周期为一小时)** 需要的参数有: | 参数名 | 参数类型 | 备注 | | ------ | -------- | -------------------- | | secret | String | 后台管理员的开发密钥 | secret是后台企业域管理员的密钥,可通过查询obpm-demo/superuser.json文件中获取所需要的密钥或者方法如下 企业域中生成accessToken ![img](./images/wps16.jpg) ![img](./images/wps15.jpg) 发送成功后返回json并解析获取accessToken值为后面 ![img](./images/wps31.png) ``` 请求成功返回json: { "errcode": 0, "errmsg": "success", "data": { "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NjIyMTE2NTEsInN1YiI6ImFkbWluIiwiZXhwIjoxNTYyMjE1MjUxLCJuYmYiOjE1NjIyMTE2NTF9.kAbZi-8dii3dgZ4TD8J0ZkQvmswmWTXo5mi0qmdEKzg" } } ``` 代码块如下: ``` private static final String URL = "http://office.teemlink.com:8083/obpm2/";//平台的访问地址 @Autowired private RestTemplate restTemplate;// 简化了发起HTTP请求以及处理响应的过程,并且支持REST。 /** * 封装获取accessToken值方法 * @return */ @GetMapping("/accessToken ") private String accessToken(){ //获取accessToken认证restful接口 String secret = "11e9-1ae6-a7f51dcc-aff9-e359336bcd13";//这里给的是超级管理员id,为了后面调用其他接口时验证 String url1 =URL+"rest/accessToken?secret="+secret; String result1 = restTemplate.getForObject(url1,String.class); JSONObject jsonObject = JSONObject.parseObject(result1); String accessToken1 = jsonObject.getJSONObject("data").getString("accessToken"); return accessToken1; } ``` ### 4.2.如何获取applicationid applicationid为软件Id,在软件的基本信息页面,右键菜单-参考框架的源代码,在另外的页面URL就有显示id的值。 在企业域中获取 ![img](./images/wps17.jpg) ![img](./images/wps18.jpg) ### 4.3.如何获取flowId ![img](./images/wps18.jpg) ## 5.接口返回值说明 Errcode:返回状态码,0为成功; Errmsg:返回错误信息, instanceId:流程实例ID,如果针对同一张审批单,虽然审批状态会不断改变,流程实例ID是不变。 flowName:流程名称。 Flowid:流程ID。 Nodeid:当前状态的节点ID。 stateLabel:当前状态。 State:流程状态码,0为启动状态,128是审批状态。 Auditors:当前审批人数组信息。 coAuditors:当前协办人的数组信息。 ``` {"errcode":0,"errmsg":"success","data":[{"instanceId":"nGXxB33aRi0fv05ium5","flowName":"demo","flowId":"sdJnGepjKEirS2ctPQT","nodes":[{"nodeId":"1562684178918","stateLabel":"申请","state":0,"auditors":[{"id":"11e4-63ff-5d9df2ad-9f19-57d7b83ae7be","name":"admin","userCode":"admin1"},{"id":"11e8-46a9-8d876d13-94a7-9b60038597d7","name":"happy爱我中国信","userCode":"happy"}],"coAuditors":[]}]}]} ``` ## 6.常用接口 \1. 生成accessToken Restful接口:/api/rest/accessToken \2. 发起流程:POST /api/rest/bpm/runtime/start \3. 流程状态:GET /api/rest/bpm/query/states \4. 获取流程提交面板:POST/api/rest/bpm/query/submission \5. 提交和审批流程:POST/api/rest/bpm/runtime/submission \6. 获取流程回退面板:POST /api/rest/bpm/query/back \7. 流程驳回:POST /api/rest/bpm/runtime/back \8. 流程提交指定审批人POST /api/rest/bpm/runtime/submission ## 7.常见问题 \1. Usercode为用户账号,而非用户UUID \2. 接口文档参数问题(大小写区分):参数默认都是小写开头 \3. 请求的包体:注意json格式的拼接 \4. accessToken多久失效:有效期一个小时 \5. 如果判断流程是否完结?可以调用接口/rest/bpm/query/states,获取流程状态或者从返回值state,可以判断流程是否完结,流程状态码,0为启动状态,256=审批中,流程正常流程的状态,65536=否决,流程被否决,1048576=流程已完结。 **注意****:****其他流程接口请查看restful API文档进行调用和参数的传递,具体案例代码查看附件。**