电话 400-101-6950

# 流程待办推送事件开发指南

# 功能介绍

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

# 使用教程

# 流程推送配置

打开低码中心>>OpenAPI>>API管理>>推送管理 流程待办推送入口.png

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

# 流程推送接口说明

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

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

流程待办URL配置.png

  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位
  • 密钥(Secret):用户设置的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