电话 400-111-2626

# 流程推送开发指南

# 功能介绍

七巧低码开发平台面向第三方统一待办类产品,提供了流程引擎数据的主动推送机制,满足待办、已办、已阅等数据实时集成场景。

# 使用教程

# 流程推送配置

  • 配置新增待办URL:用于新增待办、待阅;
  • 配置修改待办URL:用于待办转已办,待阅转已阅,更新单据内容(例如:标题、当前节点、流程状态);
  • 配置删除待办URL:用于删除待办、删除已办、删除待阅、删除已阅;
  • Token:为以上3个接口的请求数据的AES的密钥;
  • 流程数据推送范围:勾选流程后,对应流程的变更后将会主动推送到第三方服务;

# 流程推送接口说明

# 查询租户内流程推送数据接口说明

  1. 开发平台公共API管理处勾选查询租户内流程推送数据权限后,才能通过OpenApi的方式调用查询查询租户内流程推送数据接口。

  1. 获取OpenAPI接口的token,参考文档:「集成中心」->「OpenAPI使用指南」->「通过AccessKey获取Token」
  2. 调用OpenAPI调用查询租户内流程推送数据接口

功能描述

查询租户内流程推送数据

请求说明

请求方式:Get 请求URL :https://qiqiao.do1.com.cn/plus/cgi-bin/open/third/process/todo/record (opens new window)

请求参数

参数 数据类型 必须 说明
page int 页码
pageSize int 页数大小(默认10)
workId String 工单id
startTime long 开始时间(yyyy-MM-dd HH:mm:ss)
endTime long 结束时间(yyyy-MM-dd HH:mm:ss)

返回结果

参数 数据类型 必须 说明
code int 0为成功,其他失败
msg string
data Object

返回结果Data说明

参数 数据类型 必须 说明
currPage int 当前页
pageSize int 每页条数
totalCount int 总数
totalPage int 总页数
list Array 数据集合

返回结果list说明

参数 数据类型 必须 说明
tenantId string 租户id
applicationId string 应用id
processModelId string 流程模型id
processDefinitionId string 流程定义id
processInstanceId string 流程实例id
taskId string 节点任务id
userId string 用户id
workId string 单据id
processName string 流程名称
workTitle string 流程标题
workUrl string 流程跳转url
workType int 单据类型:0待办、1待阅、2已办、3已阅
workStatus string 流程状态(中文)
workCreator string 发起人id
workName string 发起人名称
currentNodeId string 当前节点定义Id
currentNodeName string 当前节点名称
workCreateTime string 工单创建时间
workDealTime string 工单处理时间
createTime string 创建时间
updateTime string 更新时间
{
  "msg": "执行成功",
  "traceId": "10ce053eb4910e9f92c4d2495da84cd8",
  "code": 0,
  "data": {
    "currPage": 1,
    "pageSize": 10,
    "totalCount": 2,
    "totalPage": 1,
    "list": [
      {
        "applicationId": "60b9fdeec4a88332821818e6",
        "createTime": 1659077738180,
        "currentNodeId": "obj_03",
        "currentNodeName": "人工任务1",
        "processDefinitionId": "6691261217077854209",
        "processInstanceId": "6714034989108953088",
        "processModelId": "6691261217077854208",
        "processName": "统一待办推送测试",
        "taskId": "6714034989108953094",
        "tenantId": "2efc32ee89074e919afa2219e3cace53",
        "updateTime": 1658977911786,
        "userId": "3534b08f0ca503a2dca7bf0ff691dff4",
        "workCreateTime": 1659077737201,
        "workCreator": "b2c26e0438a654765d932c510d071eb8",
        "workDealTime": 1658977909708,
        "workId": "6714035057828397056",
        "workName": "刘言",
        "workStatus": "已完成",
        "workTitle": "刘言的统一待办推送测试_2022072914",
        "workType": "2",
        "workUrl": "https://xxxx/mruntime/?agentCode=qiqiao2dev&corp_id=ww4852f35d45307a6f#/admin/workflow/detail/6714034989108953088?applicationId=60b9fdeec4a88332821818e6&activityDefinitionId=obj_03&scope=TODO&taskId=6714034989108953094&sourceType=YBG_TODO"
      },
      {
        "applicationId": "60b882a10cf2ab377c02a757",
        "createTime": 1658989010000,
        "currentNodeId": "obj_03",
        "currentNodeName": "人工任务",
        "processDefinitionId": "6257ebddcf588d42b3c7ed95",
        "processInstanceId": "0aeb1e6cf272463dbc1e65e6b76c8db6",
        "processModelId": "6257eba2cf588d42b3c7ed94",
        "processName": "流程名称很长流程名称很长流程名称很长流程",
        "taskId": "f68e9fadb0e24d99a8e7a4981c28efbf",
        "tenantId": "2efc32ee89074e919afa2219e3cace53",
        "updateTime": 1658989010000,
        "userId": "56e9f9b4851dd08259fb16a271864663",
        "workCreateTime": 1654753971413,
        "workCreator": "baff3ca77b70b703ec28a01afee81ba6",
        "workDealTime": null,
        "workId": "001bd5bde0a647e1a75f8af8391be7b5",
        "workName": "殷素云",
        "workStatus": "审批中",
        "workTitle": "殷素云的流程名称很长流程名称很长流程名称很长流程_2022060913",
        "workType": "0",
        "workUrl": "https://xxxx/mruntime/?agentCode=xxx2dev&corp_id=#/admin/workflow/detail/0aeb1e6cf272463dbc1e65e6b76c8db6?applicationId=60b882a10cf2ab377c02a757&activityDefinitionId=obj_03&scope=TODO&taskId=f68e9fadb0e24d99a8e7a4981c28efbf&sourceType=YBG_TODO"
      }
    ]
  }
}

# 推送方式及加密说明

新增待办推送接口、更新待办推送接口、删除待办推送接口均采用Post请求,由七巧低代码推送至第三方配置的地址

(1) AES对称加密

AES对称加密

  • 加密模式:ECB
  • 填充:pkcs7
  • 数据块:128位
  • 密钥:用户设置的token字符串
  • 字符集:utf8

加密内容输出方式

将加密后的内容通过base64字符串方式输出

加密算法示例

/**添加依赖**/
    <dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.60</version>
    </dependency>

加密工具类

public final class EncryptUtils {
    /**
* 加密算法
*/
    private static final String ENCRY_ALGORITHM = "AES";

    /**
* 加密算法/加密模式/填充类型
* 采用AES加密,ECB加密模式,PKCS7Padding填充
*/
    private static final String CIPHER_MODE = "AES/ECB/PKCS7Padding";

    /**
* 设置加密字符集
* 采用 UTF-8 字符集
*/
    private static final String CHARACTER = "UTF-8";

    private EncryptUtils() {
    }

    /**
* AES加密
*
* @param content    加密内容
* @param encryptKey 加密密钥
* @return
*/
    private static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
        if (StringUtils.isEmpty(content)) {
            log.error("The encrypted content must not be null!");
            throw new EncryptContentNullException("The encrypted content must not be null!");
        }
        SecretKey key = getKey(encryptKey);
        log.info("密钥:{}", cn.com.do1.qiqiao.webhook.encrypt.utils.Base64.encode(key.getEncoded()));

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(CIPHER_MODE);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(content.getBytes(CHARACTER));
    }

    /**
* 生成密钥
*
* @param strKey
* @return
*/
    public static SecretKey getKey(String strKey) {
        try {
            KeyGenerator generator = KeyGenerator.getInstance(ENCRY_ALGORITHM);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(strKey.getBytes());
            generator.init(128, secureRandom);
            return generator.generateKey();
        } catch (Exception e) {
            throw new RuntimeException(" 初始化密钥出现异常 ");
        }
    }

    /**
* AES解密
*
* @param encryptBytes 待解密的byte[]
* @param decryptKey   解密密钥
* @return 解密后的String
* @throws Exception
*/
    private static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
        SecretKey key = getKey(decryptKey);
        log.info("密钥:{}", cn.com.do1.qiqiao.webhook.encrypt.utils.Base64.encode(key.getEncoded()));
        // 添加加密模式
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(CIPHER_MODE);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(encryptBytes), CHARACTER);
    }

    /**
* base 64 encode
*
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
    private static String base64Encode(byte[] bytes) {
        try {
            log.info("加密后的内容:{}", bytes);
            return new String(Base64.encode(bytes), CHARACTER);//   new BASE64Encoder().encode(bytes);
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage());
        }
        return null;
    }

    /**
* base 64 decode
*
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws Exception
*/
private static byte[] base64Decode(String base64Code) throws Exception {
return Base64.decode(base64Code.getBytes(CHARACTER));
}

/**
* AES加密为base 64 code
*
* @param content    待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的base 64 code
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception {
return base64Encode(aesEncryptToBytes(content, encryptKey));
}

/**
* 将base 64 code AES解密
*
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
return StringUtils.isBlank(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
}
}

(2)url有效性鉴权

POST http://example.com/qiqiao/hook?timestamp=1498586609

    Headers:{
    "Content-type":"application/json",
        "X-Auth0-DeliverId":"31a2ae17-2661-4234-8d79-f62f3175fd75",
        }

Body:{
    "eventType":"URL_VERIFY",
        "data": "随机字符串"
}

Response: {
    "msg":"执行成功",
        "code": 0,
        "data": {
        "token" : "zvmPTQAcEmxGbMoOLPjpoCPk/Oh096ZaORQ8o2iu8Cg="
            }
}

校验流程如下:

接受到body里面的一个随机字符串,使用上述设置的token进行加密并生成的Base64的签名,直接返回;当系统用同样条件生成的签名与第三方系统生成的签名一致时,表示url校验通过;

# 新增待办推送接口说明

  • 接口含义:批量新增待办/待阅
  • 请求方式:Post
  • 请求地址:/batchAddReceiptTodo

请求参数:

参数 数据类型 说明
addList List 新增待办/待阅集合
orgId String 机构id

返回值:

UpdateTodoDTO详细说明:

字段 类型 允许为空 描述
receiptDTO object 单据实体类DTO
addWaitUserIds List 新增待办用户userId集合
addReadUserIds List 新增待阅用户userId集合
orgId String 机构id

receiptDTO参数详细说明:

字段 类型 允许为空 描述
workId String 工单id,即一张待办单据的主键
workTitle String 工单标题(流程标题)
workUrl String 工单url的全路径,用于点击跳转
workCreateTime String 工单创建时间yyyy-MM-dd HH:mm:ss
workCreator String 工单创建人id(发起人id)
workName String 工单创建人姓名(发起人姓名)
workStatus String 工单状态中文(流转状态)
currentNodeName String 工单当前节点中文(当前节点名称)
customList MytodoCustomDTO 自定义参数

MytodoCustomDTO参数

字段 类型 允许为空 描述
customName String 自定义字段名
customValue String 自定义字段值
POST 
https://第三方域名/batchAddReceiptTodo?timestamp=1498586609

Headers:{
    "Content-type":"application/json",
    "X-Auth0-DeliverId":"31a2ae17-2661-4234-8d79-f62f3175fd75",
}
Body:{
    "eventType":"PROCESS_ADD_TODO",
    "applicationId":"应用Id",
    "eventBusinessId":"",
    "data": "zvmPTQAcEmxGbMoOLPjpoCPk/Oh096ZaORQ8o2iu8Cg="
}
Response: {
    "msg":"执行成功",
    "code": 0,
    "data": {}
}
加密结构:
[{
    addList:[
       {
          "receiptDTO":{
                //工单id,即第三方一张待办单据的主键
                "workId":"work123",
                //流程标题
                "workTitle":"流程标题",
                //第三方统一待办系统跳转七巧低代码流程详情的url
                "workUrl":"https://qiqiao-tcb-qa.qiweioa.cn/qiqiao2/mruntime/?agentCode=qiqiao2qa&corp_id=ww4852f35d45307a6f#/admin/workflow/detail/6538414979086811136?applicationId=60c35cc2efc18e0216665c2b&activityDefinitionId=obj_02&scope=TODO&taskId=6538427486031577089&sourceType=YBG_TODO",
                //待办创建时间
                "workCreateTime":"2020-01-01 00:00:00",
                //发起人id
                "workCreator":"zhangsan",
                //发起人名称
                "workName":"张三",
                //流转审批状态
                "workStatus":"审批中",
                //当前节点名称
                "currentNodeName":"节点1",
                "customList":[{
                   //当前节点定义id
                   "customName":"currentNodeId",
                   "customValue":"obj1"
                  },{
                    //流程模型id
                   "customName":"processModelId",
                   "customValue":"6538427486031577089"
                  },{
                   //流程名称
                   "customName":"processName",
                   "customValue":"流程名称"
                  },{
                    //流程实例id
                   "customName":"processInstanceId",
                   "customValue":"6538414979086811136"
                  },{
                   //应用id
                   "customName":"applicationId",
                   "customValue":"60c35cc2efc18e0216665c2b"
                  },{
                    //任务id
                   "customName":"taskId",
                   "customValue":"6538427486031577089"
                  }]
            },
            "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4",
            //待办用户集合(一条待办对应一条待办工单)
            "addWaitUserIds":[
                "204dcac59b288a1731b81e6e8ac6822e"
            ],
            "addReadUserIds":[]
        }
    ],
    orgId:"b17efb43-292e-4cc9-ac5d-0b46bce059c4"
}]

# 更新待办推送接口说明

  • 接口含义:批量更新待办/待阅,待办转已办,待阅转已阅
  • 请求方式:Post
  • 请求地址:/batchUpdateReceiptTodo

请求参数:

参数 数据类型 说明
updateList List 更新对象集合
orgId String 机构id

返回值:

UpdateTodoDTO详细说明:

字段 类型 允许为空 描述
receiptDTO object 单据实体类DTO
updateWaitUserIds List 需要变成已办状态的用户userId集合
updateReadUserIds List 需要变成已办状态的用户userId集合
updateReceipt Boolean 是否需要更新单据(不需要更新单据dto可只传workId)更新待办时不能为空

receiptDTO参数详细说明:

字段 类型 允许为空 描述
workId String 工单id,即一张待办单据的主键
workTitle String 工单标题(流程标题)
workUrl String 工单url的全路径,用于点击跳转
workCreateTime String 工单创建时间yyyy-MM-dd HH:mm:ss
workCreator String 工单创建人id(发起人id)
workName String 工单创建人姓名(发起人姓名)
workStatus String 工单状态中文(流转状态)
currentNodeName String 工单当前节点中文(当前节点名称)

请求MytodoCustomDTO参数

字段 类型 允许为空 最大长度 描述
customName String 自定义字段名
customValue String 自定义字段值
POST 
https://第三方域名/batchUpdateReceiptTodo?timestamp=1498586609

Headers:{
  "Content-type":"application/json",
  "X-Auth0-DeliverId":"31a2ae17-2661-4234-8d79-f62f3175fd75",
}
Body:{
  "eventType":"PROCESS_UPDATE_TODO",
  "applicationId":"应用Id",
  "eventBusinessId":"",
  "data": "zvmPTQAcEmxGbMoOLPjpoCPk/Oh096ZaORQ8o2iu8Cg="
}
Response: {
  "msg":"执行成功",
  "code": 0,
  "data": {}
}

传参示例(加密结构):

//更新已办
[{
    "updateList":[
        {
            "receiptDTO":{
                "workId":"work123"
            },
            "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4",
            //更新用户单据为已办
            "updateWaitUserIds":[
                "204dcac59b288a1731b81e6e8ac6822e"
            ],
            "updateReceipt":true
        }
    ],
    "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4"
}]
//更新已阅
[{
  "updateList":[
    {
      "receiptDTO":{
        "workId":"work1234"
      },
      "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4",
      //更新用户单据为已阅
      "updateReadUserIds":[
        "204dcac59b288a1731b81e6e8ac6822e"
      ],
      "updateReceipt":true
    }
  ],
  "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4"
}]
//更新单据内容
[{
    "updateList":[
        {
            "receiptDTO":{
                //工单id,即第三方一张待办单据的主键
                "workId":"work1234",
                //流程标题
                "workTitle":"流程标题",
                //第三方统一待办系统跳转七巧低代码流程详情的url
                "workUrl":"https://qiqiao-tcb-qa.qiweioa.cn/qiqiao2/mruntime/?agentCode=qiqiao2qa&corp_id=ww4852f35d45307a6f#/admin/workflow/detail/6538414979086811136?applicationId=60c35cc2efc18e0216665c2b&activityDefinitionId=obj_02&scope=TODO&taskId=6538427486031577089&sourceType=YBG_TODO",
                //待办创建时间
                "workCreateTime":"2020-01-01 00:00:00",
                //发起人id
                "workCreator":"lisi",
                //发起人名称
                "workName":"李四",
                //流转审批状态
                "workStatus":"完成",
                //当前节点名称
                "currentNodeName":"节点1",
                "customList":[{
                   //当前节点定义id
                   "customName":"currentNodeId",
                   "customValue":"obj1"
                  },{
                    //流程模型id
                   "customName":"processModelId",
                   "customValue":"6538427486031577089"
                  },{
                   //流程名称
                   "customName":"processName",
                   "customValue":"流程名称"
                  },{
                    //流程实例id
                   "customName":"processInstanceId",
                   "customValue":"6538414979086811136"
                  },{
                   //应用id
                   "customName":"applicationId",
                   "customValue":"60c35cc2efc18e0216665c2b"
                  },{
                    //任务id
                   "customName":"taskId",
                   "customValue":"6538427486031577089"
                  }]
            },
            "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4",
            "updateReceipt":true
        }
    ],
    "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4"
}]

# 删除待办推送接口说明

  • 接口含义:批量删除待办或者待阅
  • 请求方式:Post
  • 请求地址:/batchDeleteReceiptTodo

请求参数:

参数 数据类型 说明
deleteReceiptTodoDTO object 删除待办/待办对象

返回值:

deleteReceiptTodoDTO参数详细说明:

字段 类型 允许为空 描述
orgId String 机构id
workIds List 需要删除的工单id集合
POST 
https://第三方域名/batchDeleteReceiptTodo?timestamp=1498586609

Headers:{
    "Content-type":"application/json",
    "X-Auth0-DeliverId":"31a2ae17-2661-4234-8d79-f62f3175fd75",
}
Body:{
    "eventType":"PROCESS_DELETE_TODO",
    "applicationId":"应用Id",
    "eventBusinessId":"",
    "data": "zvmPTQAcEmxGbMoOLPjpoCPk/Oh096ZaORQ8o2iu8Cg="
}
Response: {
    "msg":"执行成功",
    "code": 0,
    "data": {}
}
//删除单据加密结构
[{
    "deleteReceiptTodoDTO":{
        "orgId":"b17efb43-292e-4cc9-ac5d-0b46bce059c4",
        "workIds":[
            "work8c10327e0c3a42a3bb1f7a92c06619ae"
        ]
    }
}]

#

1 / 0