1 文档使用说明
自定义连接器适用于纷享销客CRM与其他能够提供api的SaaS或私有化系统的集成,如客户自研或其他SaaS系统的集成场景。对接后,用户可以通过连接器实现双方系统业务单据的自动同步,而无需登录双方系统录入数据并核对准确性。
本文档包含自定义连接器步骤指引及常见问题,适用对象:实施顾问、技术顾问、销售经理、CSM等;
2 自定义连接器实施配置
2.1 实施前置条件
实施前,请确认客户租户环境已开通,且已购买自定义连接器产品(注意核对订单为已生效!)。
2.2 实施配置
2.2.1 连接配置
新建连接器,连接器类型选择自定义连接器,填写连接器信息:

结果格式 填写说明:如返回值为下面的json,则 error code字段为code,error msg字段为message,数据字段为data,成功的code为0 。
{
"code": "0",
"message": "成功",
"data": {
...
}
}获取header脚本填写说明:现在在请求中添加header有两种方式,两种都配置的话以Hearders参数配置为准!
1、Hearders参数配置,参数值支持使用占位符,占位符暂时只支持企业Id和推送token(连接对象-api配置-时间订阅-参数说明-Header参数-token)


2、自定义APL函数,例如:
return ["token":"test123", "tenantId":context.tenantId]2.2.2 接口配置
继续根据客户给的接口示例及接口说明配置对象结构和字段,配置完成后,可以通过 api配置查看请求和返回接口。此时,亦可以参考请求路径 请求模板使用postman发出请求验证,对照响应体示例查看是否符合通信协议。


2.2.3 接口适配
使用api函数实现对象的增删查改:假如租户的服务和标准连接器的协议不兼容,可以使用自定义函数来实现对服务的请求,并将返回值改造为符合平台连接器配置的接口的协议。下面是各个请求的自定义函数的示例,也可以在创建函数时选择对应的函数模板进行改造。

注意:创建函数后,需要先在右上角设置参数 类型:Map, 名称:syncArg。syncArg中都有objectData参数,但在各个API接口中含义不一样。

api函数通用返回值说明:

按同步动作,详细说明各同步接口参数和函数示例:
2.2.3.1 新建
objectData参数说明:
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| masterFieldVal | 主对象数据 | |
| detailFieldVals | 明细对象数据 | key是明细对象apiName,value是明细数据列表List |
api函数示例:
/**
* 连接器对象api-创建
* todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
String dataKey = "data" // 数据字段名称-需要和连接器配置的 数据字段 对应
String dataIdKey = "masterDataId" // 主对象数据id字段名称
String detailDataIdsKey = "detailDataIds" // 从对象数据Id字段名称
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
def masterData = objectData["masterFieldVal"] // 主对象数据
// 明细对象数据,key是明细对象apiName,value是明细数据列表List
Map<String, List<Map<String, Object>>> detailMap = objectData["detailFieldVals"] as Map
// todo 创建
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx//create"
Map<String, Object> arg = ["objAPIName": apiName, "masterData": masterData, "detailMap": detailMap]
def (Boolean error, HttpResult httpResult, String msg) = http.post(url, headers, arg)
if (error) {
log.info("创建erp对象错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("创建erp对象,url:" + url + " 参数:" + arg + " 返回值:" + httpResult)
Map createDataResult = httpResult.content as Map
// todo 构建对象数据
String masterDataId = createDataResult["data"]["masterDataId"]
// todo 从对象数据Id,key是明细对象apiName,value是明细数据id列表List,需按入参顺序返回数据id列表
Map<String, List<String>> detailIdsMap = createDataResult["data"]["detailDataIds"] as Map
Map<String, Object> data = [:]
data[dataIdKey] = masterDataId
data[detailDataIdsKey] = detailIdsMap
// 返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
result[dataKey] = data
return result
2.2.3.2 编辑
objectData参数说明:
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| masterFieldVal | 主对象数据 | |
| detailFieldVals | 明细对象数据 | key是明细对象apiName,value是明细数据列表List |
api函数示例:
/**
* 连接器对象api-更新
* todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
String dataKey = "data" // 数据字段名称-需要和连接器配置的 数据字段 对应
String dataIdKey = "masterDataId" // 主对象数据id字段名称
String detailDataIdsKey = "detailDataIds" // 从对象数据Id字段名称
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
def masterData = objectData["masterFieldVal"] // 主对象数据
// 明细对象数据,key是明细对象apiName,value是明细数据列表List
Map<String, List<Map<String, Object>>> detailMap = objectData["detailFieldVals"] as Map
// todo 修改
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx//update"
Map<String, Object> arg = ["objAPIName": apiName, "masterData": masterData, "detailMap": detailMap]
def (Boolean error, HttpResult httpResult, String msg) = http.post(url, headers, arg)
if (error) {
log.info("更新erp对象错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("更新erp对象,url:" + url + " 参数:" + arg + " 返回值:" + httpResult)
Map updateDataResult = httpResult.content as Map
// todo 构建对象数据
String masterDataId = updateDataResult["data"]["masterDataId"] as String
// todo 从对象数据Id,key是明细对象apiName,value是明细数据id列表List,需按入参顺序返回数据id列表
Map<String, List<String>> detailIdsMap = updateDataResult["data"]["detailDataIds"] as Map
Map<String, Object> data = [:]
data[dataIdKey] = masterDataId
data[detailDataIdsKey] = detailIdsMap
// 返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
result[dataKey] = data
return result2.2.3.3 批量查询修改/作废
批量查询修改和批量查询作废的协议是相同的。注意:一次批量查询会分页调用多次批量查询接口,使用参数中的offset和limit区分。
objectData参数说明:
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| startTime | 数据变更的开始时间戳 | 单位:毫秒 |
| endTime | 数据变更的结束时间戳 | 单位:毫秒 |
| offset | 获取记录的偏移 | |
| limit | 当前请求记录条数 |
api函数示例:
/**
* 连接器对象api-根据时间获取erp对象数据 批量查询
* todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
String dataKey = "data" // 数据字段名称-需要和连接器配置的 数据字段 对应
String totalKey = "totalNum" // 数据总条数字段名称
String dataListKey = "dataList" // 数据详情列表字段名称
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
def startTime = objectData["startTime"] // 数据变更的开始时间(unix时间戳,单位毫秒)
def endTime = objectData["endTime"] // 数据变更的结束时间(unix时间戳,单位毫秒)
def includeDetail = objectData["includeDetail"] // 是否包含明细
def offset = objectData["offset"] // 获取记录的偏移
def limit = objectData["limit"] // 当前请求记录条数
// todo 获取数据
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx/queryMasterBatch?objAPIName=" + apiName + "&startTime=" + startTime + "&endTime=" + endTime + "&includeDetail=" + includeDetail + "&offset=" + offset + "&limit=" + limit
def (Boolean error, HttpResult httpResult, String msg) = http.get(url, headers)
if (error) {
log.info("根据时间获取erp对象数据错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("根据时间获取erp对象数据,url:" + url + " 返回值:" + httpResult)
Map<String, Object> queryDataByTimeResult = httpResult.content as Map
int totalNum = queryDataByTimeResult["data"]["totalNum"] as Integer
List<Map<String, Object>> dataList = queryDataByTimeResult["data"]["dataList"] as List
// 构建对象数据
Map<String, Object> data = [:]
data[totalKey] = totalNum
data[dataListKey] = dataList
// 返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
result[dataKey] = data
return result2.2.3.4 单条(ID)查询
objectData参数说明:
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| dataId | 数据id | |
| includeDetail | 是否包含从对象数据 |
api函数示例:
/**
* 连接器对象api-通过id查询
* todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
String dataKey = "data" // 数据字段名称-需要和连接器配置的 数据字段 对应
String masterDataKey = "masterFieldVal" // 主对象数据字段名称
String detailDataKey = "detailFieldVals" // 从对象数据字段名称
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
def dataId = objectData["dataId"] // 数据id
def includeDetail = objectData["includeDetail"] // 是否包含从对象数据
// todo 获取对象数据
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx/queryMasterById?objAPIName=" + apiName + "&dataId=" + dataId + "&includeDetail=" + includeDetail
def (Boolean error, HttpResult httpResult, String msg) = http.get(url, headers)
if (error) {
log.info("获取erp对象数据错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("获取erp对象,url:" + url + " 返回值:" + httpResult)
Map<String, Object> erpData = httpResult.content as Map
// todo 拆分主从对象数据
Map<String, Object> masterData = erpData["data"]["masterData"] as Map
// todo 从对象数据;key:从对象apiName,value:从对象数据
Map<String, List<Map<String, Object>>> detailsDataList = dataResult["data"]["detailData"] as Map
// 构建对象数据
Map<String, Object> data = [:]
data[masterDataKey] = masterData
data[detailDataKey] = detailsDataList
// 返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
result[dataKey] = data
return result
2.2.3.5 作废
objectData参数说明:
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| masterFieldVal | 主对象数据 | 主对象数据id:"_id" |
api函数示例:
/**
* 连接器对象api-作废
* todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
def dataId = objectData["masterFieldVal"]["_id"] // 主对象数据id
// todo 作废
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx//invalid"
Map<String, Object> arg = ["objAPIName": apiName, "masterFieldVal": ["_id": dataId]]
def (Boolean error, HttpResult httpResult, String msg) = http.post(url, headers, arg)
if (error) {
log.info("作废erp对象错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("作废erp对象,url:" + url + " 参数:" + arg + " 返回值:" + httpResult)
// 返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
return result2.2.3.6 反禁用
objectData参数说明:
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| masterFieldVal | 主对象数据 | 主对象数据id:"_id" |
api函数示例:
/**
* 连接器对象api-反禁用
* todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
def dataId = objectData["masterFieldVal"]["_id"] // 主对象数据id
// todo 反禁用
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx//enable"
Map<String, Object> arg = ["objAPIName": apiName, "masterFieldVal": ["_id": dataId]]
def (Boolean error, HttpResult httpResult, String msg) = http.post(url, headers, arg)
if (error) {
log.info("反禁用erp对象错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("反禁用erp对象,url:" + url + " 参数:" + arg + " 返回值:" + httpResult)
//返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
return result
2.2.3.7 作废明细
objectData参数说明:
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| masterFieldVal | 主对象数据 | 主对象数据id:"_id" |
| detailFieldVals | 明细对象数据 | key:从对象apiName,value:从对象数据id |
api函数示例:
/**
* 连接器对象api-作废从对象
* todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
def dataId = objectData["masterFieldVal"]["_id"] // 主对象数据id
// 从对象数据;key:从对象apiName,value:从对象数据id
Map<String, String> detailDataIdMap = objectData["detailFieldVals"] as Map
// todo 作废
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx//invalidDetail"
Map<String, Object> arg = ["objAPIName": apiName, "masterFieldVal": ["_id": dataId], "detailFieldVal": detailDataIdMap]
def (Boolean error, HttpResult httpResult, String msg) = http.post(url, headers, arg)
if (error) {
log.info("作废erp从对象错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("作废erp从对象,url:" + url + " 参数:" + arg + " 返回值:" + httpResult)
// 返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
return result2.2.3.8 事件订阅
objectData参数说明(特别说明:金蝶K3C的推送中,masterFieldVal对象里需要有"id":"ID"。更多使用说明点击查看:事件订阅):
| 字段名称 | 含义 | 备注 |
|---|---|---|
| objAPIName | ERP对象apiName | |
| masterFieldVal | 主对象数据 | |
| detailFieldVals | 明细对象数据 | key是明细对象apiName,value是明细数据列表List |
api函数示例:
todo的为需要用户自己修改添加的,
* 需要先在右上角设置参数 Map类型syncArg
**/
String errorCodeKey = "code" // 错误返回码字段名称-需要和连接器配置的 error code字段 对应
String successCode = "0" // 成功时的错误返回码-需要和连接器配置的 成功的code 对应
String errorMessageKey = "message" // 错误提示语字段名称-需要和连接器配置的 error msg字段 对应
String dataKey = "data" // 数据字段名称-需要和连接器配置的 数据字段 对应
String dataListKey = "dataList" // 标准数据列表字段名称
String masterDataKey = "masterFieldVal" // 主对象数据字段名称
String detailDataKey = "detailFieldVals" // 从对象数据字段名称
Map objectData = syncArg["objectData"] as Map
def apiName = objectData["objAPIName"] // ERP对象apiName 例如:BD_MATERIAL
Map<String, Object> masterData = objectData["masterFieldVal"] as Map // 主对象数据
// 明细对象数据,key是明细对象apiName,value是明细数据列表List
Map<String, List<Map<String, Object>>> detailMap = objectData["detailFieldVals"] as Map
// todo 调整数据
Map<String, String> headers = ["token": "xxxxxx"]
def url = "http://xxx/xxx//asyncpush"
Map<String, Object> arg = ["objAPIName": apiName, "masterFieldVal": ["_id": masterData["dataId"]]]
def (Boolean error, HttpResult httpResult, String msg) = http.post(url, headers, arg)
if (error) {
log.info("推送erp对象错误:" + msg)
// 返回错误数据
Map<String, Object> result = [:]
result[errorCodeKey] = "500"
result[errorMessageKey] = msg
return result
}
log.info("推送erp对象,url:" + url + " 参数:" + arg + " 返回值:" + httpResult)
Map<String, Object> dataResult = httpResult.content as Map
// todo 构建对象数据
Map<String, Object> object = dataResult["data"]["masterData"] as Map
// todo 从对象数据;key:从对象apiName,value:从对象数据
Map<String, List<Map<String, Object>>> detailsDataList = dataResult["data"]["detailData"] as Map
// 构建对象数据
Map<String, Object> pushData = [:]
pushData[masterDataKey] = object
pushData[detailDataKey] = detailsDataList
Map<String, Object> data = [:]
data[dataListKey] = [pushData]
// 返回数据
Map<String, Object> result = [:]
result[errorCodeKey] = successCode
result[errorMessageKey] = ""
result[dataKey] = data
return result2.3 使用代理服务支持(可选)
假如租户不支持外网,或者没有对外的服务,需要使用代理服务支持(附件为代理程序的代码)。代理服务配置说明:
修改application.properties中的token,用于验证身份,确保调用请求来自纷享集成平台。
注意: 需要再连接配置的header中,配置上X-fs-erpdss-token代理服务中配置的值。


实现RouterAdaptController
- create是在ERP新建,
- update是在ERP更新,
- invalid作废ERP主数据
- queryMasterBatch是ERP->CRM同步时查询ERP的增量数据
- queryMasterById 是ERP->CRM时根据ERP这边的主键查询单条数据
3 FAQ
建设中...
附件