简介
与企企系统对接过程中,,从第三方系统传输数据到企企,或者从企企获取数据,实现两个系统之间的数据对接。本教程将介绍如果通过开放平台openApi实现两个系统之间的数据对接。
操作流程
数据传输方向如下所示:

本教程通过 API 实现企企与第三方系统的对接,操作时序图如下所示:

使用到的 OpenAPI
本教程将调用以下 OpenAPI 接口
| 方法(API) | 操作 | 访问凭证 |
|---|---|---|
| POST /v1/list 标准接口 (所有开放对象的查询都可使用此接口) | 查询对象列表 | openid(v1 版本) |
| PUT /v1/update 标准接口 (所有开放对象的查询都可使用此接口) | 更新对象(单据状态为:草稿、已退回、已撤回 时支持更新) | openid(v1 版本) |
| POST /v1/delete 标准接口 (所有开放对象的查询都可使用此接口) | 删除对象 | openid(v1 版本) |
| POST /v1/batchDo 仅支持单据,不支持档案 | 同步任务接口,用于单据状态变更(支持状态:提交,撤回,弃审,同意状态) | openid(v1 版本) |
| GET /v1/code 仅支持单据,不支持档案 | 根据code获取openid | 无需openid |
企企系统数据传至第三方系统
实时同步部门档案
步骤一: 新建部门
在企企系统中新建部门,基础数据-> 部门-> 新建

步骤二: 监听消息队列
企企系统中创建部门信息后,第三方系统要监听消息队列,达到实时获取部门档案最近变化数据的目的。监听消息后,Entity 的CUD时间发生后,企企将消息发送到SQS队列,开发者获取到消息后,可根据消息返回到信息,查询部门信息。
java sdk使用示例
package com.q7link.openapi.example;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.opensdk.BaseRequest;
import com.amazonaws.opensdk.SdkRequestConfig;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.q7link.openapi.Openapi;
import com.q7link.openapi.model.GetQueueRequest;
import com.q7link.openapi.model.Queue;
import java.util.List;
/**
* sqs request example
*/
public class AmazonSqsReceiveMessage {
private static Regions regions = Regions.CN_NORTH_1;
private static AmazonSQS amazonSQS;
private static Openapi openapi;
private static final String ACCESS_KEY_ID = "";
private static final String SECRET_KEY = "";
private static final String OPEN_ID = "";
public static void main(String[] args) {
// 通过openapi queue接口获取queueUrl
Queue queue = getQueue();
String queueUrl = queue.getQueueUrl();
while (true) {
// 接收消息
List<Message> messages = receiveMessages(queueUrl);
for (Message message : messages) {
// 消息体
String body = message.getBody();
// do something (构建查询参数,调用查询接口)
System.out.println(body);
// 删除消息
amazonSQS().deleteMessage(queueUrl, message.getReceiptHandle());
}
}
}
/**
* 接收消息,推荐使用长轮询
* <pre>
* 1.最大等待时间:20秒 值范围:1-20秒
* 2.最大接收消息数:10 值范围:1-10
* 3.默认可见性超时:60秒 值范围:0-12天
* 根据业务需求适当调整可见性超时时间
* </pre>
*
* @param queueUrl 队列url
* @return 消息列表
*/
private static List<Message> receiveMessages(String queueUrl) {
ReceiveMessageRequest request = new ReceiveMessageRequest()
// 队列url
.withQueueUrl(queueUrl)
// 可见性超时:默认60秒,收到消息在可见性超时时间内不会再次收到该消息。注意:可见性超时无法保证不会接收消息两次
.withVisibilityTimeout(10)
// 最大等待时间:20秒 值范围:1-20秒
.withWaitTimeSeconds(5)
// 最大接收消息数:10 值范围:1-10
.withMaxNumberOfMessages(10);
return amazonSQS().receiveMessage(request).getMessages();
}
/**
* 获取队列信息
*
* @return 队列对象
*/
private static Queue getQueue() {
GetQueueRequest request = new GetQueueRequest();
request.sdkRequestConfig(getSdkRequestConfig(request));
return openapi().getQueue(request).getQueue();
}
private static SdkRequestConfig getSdkRequestConfig(BaseRequest request) {
return request.sdkRequestConfig().copyBuilder()
.customHeader("Content-Type", "application/json")
.customHeader("Access-Key-Id", ACCESS_KEY_ID)
.customHeader("Open-Id", OPEN_ID)
.build();
}
public static Openapi openapi() {
if (openapi == null) {
String accessKey = ACCESS_KEY_ID;
String accessSecret = SECRET_KEY;
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, accessSecret);
openapi = Openapi.builder()
.iamCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
return openapi;
}
public static AmazonSQS amazonSQS() {
if (amazonSQS == null) {
String accessKey = ACCESS_KEY_ID;
String accessSecret = SECRET_KEY;
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, accessSecret);
amazonSQS = AmazonSQSClientBuilder.standard()
.withRegion(regions)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
return amazonSQS;
}
}
- 监听到的消息体为:
{
"tenantId":"XXXX", // 租户id
"objectName":"Department", // 对象类型
"objectId":"KBJG]03V", // 对象id
"operation":"create", // 操作为新增
"billTypeId":"EV2VP160CXE000B", // 单据ID
"billTypeCode":"EX052" // 单据编码
}
- 使用官方提供的php获取消息队列,如果出现以下错误信息,请修改key 为region 的参数,改为: cn-northwest-1 报错信息:
Error executing "ReceiveMessage" on "https://sqs.cn-northwest-1.amazonaws.com.cn/6208XXXXXX99/KBXWXXXXXX6000W-RRBQXXXXXTB0029"; AWS HTTP error: Client error: `POST https://sqs.cn-northwest-1.amazonaws.com.cn/6208XXXXXX99/KBXWXXXXXX6000W-RRBQXXXXXTB0029` resulted in a `403 Forbidden` response: SenderS (truncated...) SignatureDoesNotMatch (client): Credential should be scoped to a valid region. - SenderSignatureDoesNotMatchCredential should be scoped to a valid region. 6a14219a-dad2-5ce0-9b60-7cd80014beef
步骤三: 同步部门信息
根据以上消息中返回的的objectName,objectId 查询部门信息,调用查询接口,查询到部门数据后,可将改数据 传入第三方系统
使用接口
a. POST https://api2.77hub.com/v1/list 查询接口
b. 在请求体(Body)中,以 JSON 格式填写请求参数。
{"json":"{\"objectType\":\"Department\",\"criteriaStr\":\"id ='\''KBJG]03V'\''\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"parent\",\"fields\":[\"id\",\"name\",\"code\"]},{\"fieldName\":\"manager\",\"fields\":[\"id\",\"name\",\"code\"]},\"executiveId\",\"characterId\",\"annualNumber\"]}"}
body的json 值:
{
"objectType":"Department", // 查询的对象名称,从数据字典中查看对象名称
"criteriaStr":"id ='KBJG]03V'", // 查询条件
"fields":[ //该对象下要查询的字段
"id",
"name",
"code",
{
"fieldName":"parent",
"fields":[
"id",
"name",
"code"
]
},
{
"fieldName":"manager",
"fields":[
"id",
"name",
"code"
]
},
"executiveId",
"characterId",
"annualNumber"
]
}
参数说明:
- objectType: 查询对象名称
- criteriaStr :查询条件
- fields:该对象下要查询的字段
c. 使用 curl 命令行工具调用查询接口,获取相关对象信息:
-- 发送请求的参数应包含参与签名的所有参数,并且保持结构一致
curl -X POST 'https://api2.77hub.com/v1/list' \
-H 'Authorization: AWS4-HMAC-SHA256 Credential=AKIAZBC3TYIX7E3BRKX4/20220727/cn-northwest-1/execute-api/aws4_request,SignedHeaders=access-key-id;content-type;host;open-id;x-amz-date,Signature=a1028e7f986fa0403dac021edd278eaa89f71a9ebb0dd0806903c27893361e8a' \
-H 'Access-Key-Id: AKIAZBTYIX7E3BRKX4' \
-H 'Open-Id: 7cfbacd2e2d63b1021bae0277a9e5' \
-H 'X-Amz-Date: 20220727T091444Z' \
-H 'Content-Type: application/json' \
-d'{"json":"{\"objectType\":\"Department\",\"criteriaStr\":\"id ='\''KBJG]03V'\''\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"parent\",\"fields\":[\"id\",\"name\",\"code\"]},{\"fieldName\":\"manager\",\"fields\":[\"id\",\"name\",\"code\"]},\"executiveId\",\"characterId\",\"annualNumber\"]}"}'
d. java sdk查询接口示例:
publicj void testList() {
PostListRequest request = new PostListRequest();
ApiParams apiParams = new ApiParams();
apiParams.setJson("{\"objectType\":\"Department\",\"criteriaStr\":\"id ='KBJG]03V'\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"parent\",\"fields\":[\"id\",\"name\",\"code\"]},{\"fieldName\":\"manager\",\"fields\":[\"id\",\"name\",\"code\"]},\"executiveId\",\"characterId\",\"annualNumber\"]}");
System.out.println(apiParams.getJson());
request.sdkRequestConfig(getSdkRequestConfig(request));
request.setApiParams(apiParams);
PostListResult postListResult = openapi().postList(request);
ApiResponse apiResponse = postListResult.getApiResponse();
}
e. 调用结果
- 成功调用后的返回信息如下图所示:
{
"json": "{\"data\":{\"list\":[{\"parent\":{\"code\":\"zongbu001\",\"name\":\"总部\",\"id\":\"1EAV3K501JR0001\"},\"annualNumber\":0,\"code\":\"0001\",\"manager\":{\"code\":\"000000003\",\"name\":\"人员C\",\"id\":\"G7TCQX50CPA002J\"},\"executiveId\":\"HVR2NT50E4W002Q\",\"name\":\"建设管理部\",\"id\":\"RLSLT462XPV0081\"}]},\"errors\":[]}"
}
- 如果返回以下报错信息,请检查相关查询参数是否符合数据字典数据结构
[{"description":"Sub selection required for type null of field children","locations":[{"line":4,"column":27}],"message":"Validation error of type SubSelectionRequired: Sub selection required for type null of field children","validationErrorType":"SubSelectionRequired"}]]
步骤四: 修改部门档案同步
-
在企企系统中修改部门,基础数据-> 部门-> 修改

-
部门修改,按照 步骤二 监听消息队列,获取到消息体为:
{
"tenantId":"XXXX", // 租户ID
"objectName":"Department", // 对象名称,与数据字典中的对象名称符合
"objectId":"KBJG]03V", // 对象id
"operation":"update", // 操作为更新
"billTypeId":"EV2VP160CXE000B",
"billTypeCode":"EX052"
}
- 根据消息中返回的的objectName,objectId 按照步骤三查询部门信息,即可获取最近的部门档案数据
步骤五: 删除部门档案同步
- 在企企系统中修改部门,基础数据-> 部门-> 删除
- 部门删除,按照 步骤二 监听消息队列,获取到消息体为:
{
"tenantId":"XXXX", // 租户ID
"objectName":"Department", // 对象名称,与数据字典中的对象名称符合
"objectId":"KBJG]03V", // 对象id
"operation":"delete", // 操作为更新
"billTypeId":"EV2VP160CXE000B",
"billTypeCode":"EX052"
}
- 根据消息中返回的的objectName,objectId 删除第三方系统中的部门数据。