【研发培训】基础-集成平台处理逻辑

277 阅读11分钟

一. 概述

纷享集成平台是用来做CRM和其它IT系统间对接的支撑平台。具有如下特点:

  1. 支持CRM和其它IT系统(不限于ERP)之间数据同步。

  2. 用于数据对接,而不是流程对接。比如CRM的审批流和外部OA的审批流要交替审批,这种场景是不支持的。

外部的数据源,用外部对象元数据管理(对应的菜单是 连接器管理->连接对象)抽象为对象。所有的对接,都变成CRM对象和外部对象的对接,外部对象可以是ERP,可以是文件,可以是数据库。

image.png

image.png

二. 集成平台开通

按照连接器在fs租户下,购买集成平台销售订单,就能在 管理 频道下看到集成平台入口了。

image.png

三. 连接器和集成流

连接器负责调用外部IT系统读写接口。连接器是按照系统划分的,云星空是一个连接器,SAP是一个连接器,CRM也是一个连接器。

集成流负责把源系统数据"加工"成目标系统的数据。

集成实施步骤:确定好对接需求->配置连接器->配置集成流->启用集成流->日程运维。

image.png

1. 连接器说明

外部对象管理

  • 主键

    相当于CRM的_id字段。每条数据必须有唯一的主键,主键必须具有唯一性。两条不同的数据,主键必须是不同的。主键的作用,用来识别调用更新接口的时候,找到待更新数据。

    image.png

  • 主属性

    默认是name字段。

  • 单选option和label

    option是代码使用,label用来帮助人眼阅读。选项映射的时候,option一定要对齐。

  • 引用字段

    如果引用的是单选字段,对接会有问题。因为CRM默认查到的是字段的label, 查不到option。

  • 虚拟字段

    crm和erp上的非真实字段,集成平台为了方便对接而自动添加上去的字段。比如K3C上的是否开启批次和序列号。

  • 虚拟复合字段

    多个字段拼接在一起的虚拟字段,比如k3c上销售订单使用ID+编码作为主键, 那么 回款明细要关联订单,就使用 ID+编码拼成的虚拟复合字段 查找关联订单。

image.png

读写外部接口说明

image.png

账套管理

通常一个连接器,连接一个外部系统。如果有多套外部系统要对接,需要创建多个连接器。

比如一个企业对接云星空的2个数据中心,和一套SAP,那么需要3个连接器。

系统字段管理

这里处理的是CRM和外部都不是对象,又需要转换的字段。这类数据无法通过对接对象来完成。主要是以下数据

  • 国家
  • 省市区
  • 乡镇

部门和人员,产品分类在CRM已经做了对象化,最好是使用 对象对接的方式。

账户绑定

主要是CRM和外部的人员绑定。

CRM如果使用人员对象对接的话,这里的数据由集成平台自动维护,无需再手工导入。

标准API说明

image.png

image.png

image.png

2. 集成流说明

执行顺序

在集成流配置页面看到的图,就是一条数据经过集成流处理时的执行顺序

image.png

上图中,一条数据从金蝶K3C读回来,先经过数据范围过滤,然后做字段转换,最后写入目标系统。

读写外部数据的方式

  • PAAS事件。CRM数据变化(页面编辑和PAAS后台计算)时,触发CRM->ERP数据同步。
  • 轮询。集成平台定时调用queryMasterBatch获取外部数据。
  • 推送。外部系统通过asyncpush接口往集成平台推送数据。

erp->CRM如果不是对时效性要求很高的话,尽量用轮询而不是推送。因为使用轮询,重试或者刷历史数据这类操作可以自助完成,不需要客户方IT人员配合。

什么时候触发同步

ERP->CRM方向,只要轮询到主数据就会触发发生数据同步。
CRM->ERP方向,(1)只要CRM上数据的字段内容发生变化就会触发数据同步。(2)从数据发生变化,则主数据也会触发同步。

以下情况会阻断数据同步。
1.同步策略没有开启,数据不会做同步。
2.不符合数据范围的数据,同步过程会被阻断。
3.对于新增到目标系统:变化的字段既没有做过字段映射,又没有配置过数据范围,则该条数据的同步会被阻断。
4.对于更新到目标系统:变化的字段没有做过字段映射,则该条数据的同步会被阻断。

事件转换说明

源事件到目标事件的转换逻辑如下表

image.png

事件过滤说明

  1. 目标事件如果不在已勾选的执行动作中,则丢弃改事件,数据不做同步。比如下图中目标系统不允许调用编辑接口,那么对于目标事件是编辑的,则丢弃事件。

    image.png

  2. CRM数据风暴规避。只针对CRM->ERP。

    (1)源事件更新,目标事件是新增的。变化的字段如果不在数据范围中也不在字段映射中,则丢弃本次事件。

    (2)目标事件是更新的。如果变化的字段不在字段映射中,则丢弃本次事件。如果变化的字段在映射字段中,但它是个引用字段且实际的值没有变化,也会丢弃事件。

    补充背景:原来有同事在CRM中增加一个计算字段,导致CRM全量数据的计算字段都发生字段变化,然后触发CRM->ERP同步。

    实际上计算字段如果不做字段映射,是不需要同步的。

数据范围说明

  1. 主从对象独立设置过滤条件。主数据使用主对象的数据范围条件做检查,从数据使用从对象的数据范围条件做检查。

  2. 主对象数据还会检查从数据。如果从数据全部不满足数据范围且设置了  "没有从数据则不同步主数据",则主数据也会被阻挡。

最常见的情况是:一主多从,部分从被过滤掉,则满足条件的主数据和满足条件的部分从数据会继续同步。

从对象事件转为主对象事件

如果主数据还没有中间表映射关系,则该从事件丢弃,发出一个主数据同步的事件。

从触发主 这个逻辑,是导致偶发的页面操作一次,CRM->ERP发生多次写的根源。但是为什么还要保留这个逻辑呢?

请查阅 引申阅读:

lexiangla.com/teams/k1000…

字段转换说明

  • 引用字段。源数据中把引用字段替换为真实的值再进行其它转换。
  • 查找关联类型的,自动替换。比如erp订单数据查找关联erp客户id, 则字段转换时,自动把erp客户id转为crm客户id。
  • 主从类型的,自动替换。比如erp订单明细上有erp订单主id, 则字段转换时,自动把erp订单主id转为crm订单主id。
  • 设置为固定值的,塞入固定值。
  • 国家省市区通过系统字段中的映射关系自动替换。
  • 人员id通过人员绑定关系表自动替换。
  • 单选字段类型的,把源option替换为目标系统option。
  • 默认直接拷贝。

四.自定义函数说明

同步前、中、后函数入参和返回值类型都是Map,参数名为syncArg。

同步前函数

场景:复杂的数据过滤条件在数据范围表达不出来,可以用同步前函数实现。

即函中返回结果中包含"isExec":"false",即该次同步将不再往后执行,目标数据将不会做出相应的更改。

同步中函数

场景:在目标数据调用写接口之前,修改目标数据。

同步后函数

场景:调用目标系统写接口之后,添加后动作。比如CRM->ERP同步了一个订单,把ERP接口调用成功或失败的状态写入CRM的字段。业务人员就能看到这条数据是否同步成功了。

回填状态的功能现在可以通过回写组件配置完成。其它更复杂的后动作可以通过同步后函数完成。

触发CRM——>ERP数据同步

使用场景:在CRM列表、详情页配置按钮,触发数据同步。可用于解决CRM数据不方便修改或刷数据需求。

//必填,CRM对象apiName
def crmObjApiName = context.data.object_describe_api_name;
//必填,CRM数据Id
def crmDataId = context.data._id
//选填,ERP中间对象apiName,不指定会同步所有策略,填写则只同步到指定目标ERP对象的策略
def erpObjApiName = null //"BD_Customer.BillHead"
def type = "manualSyncCrm2Erp"
def params = ["crmObjectApiName":crmObjApiName,
    "crmDataId":crmDataId,
    "erpObjectApiName":erpObjApiName]
def arg = ["type":type,
    "params":Fx.json.toJson(params)]
def ret = Fx.proxy.callAPI("erp.syncData.executeCustomFunction", [:], arg)
//同步结果处理逻辑:
log.info(ret)

触发ERP——>CRM数据同步

//必填,CRM对象apiName
def crmObjApiName = context.data.object_describe_api_name;
//必填,CRM数据Id
def crmDataId = context.data._id
//必填,ERP中间对象apiName
def erpObjApiName = "BD_Customer.BillHead"
//该类型用于触发ERP往CRM数据同步,使用crm数据id
def type = "manualSyncErpDataByCrmDataId"
def params = ["crmObjectApiName":crmObjApiName,
    "crmDataId":crmDataId,
    "erpObjectApiName":erpObjApiName]
def arg = ["type":type,
    "params":Fx.json.toJson(params)]
def ret = Fx.proxy.callAPI("erp.syncData.executeCustomFunction", [:], arg)
//同步结果处理逻辑:
log.info(ret)

操作集成平台中间表

Map header=[:]
//创建数据映射
Map param1=["ployDetailId":"155bd981457343f291e0edc13776217f",//策略明细id(见下图),如果策略被删除重新建了,这里需要改动
"sourceObjectApiName":"AccountObj",//源对象apiName,如果对象apiName变了,这里要改动
"destObjectApiName":"BD_Customer.BillHead",//目标对象apiName,如果对象apiName变了,这里要改动
"sourceDataId":"sourceDataId123",//源对象数据id
"destDataId":"destDataId123666",//目标对象数据id
"sourceDataName":"sourceDataName3666",//源对象数据name属性
"destDataName":"destDataName66",//目标对象数据name属性
"remark":"remark1341"];//备注
def result1=Fx.proxy.callAPI("erp.syncData.createSyncDataMapping",header,param1);
//[false, HttpResult(statusCode=200, content={"errCode":"s106240000","errMsg":"成功"}, bytes=null), ]   s106240000成功,其他失败
log.info(result1)

//根据源对象数据id更新目标对象数据id
Map param2=["sourceObjectApiName":"AccountObj",//源对象apiName,如果对象apiName变了,这里要改动
"destObjectApiName":"BD_Customer.BillHead",//目标对象apiName,如果对象apiName变了,这里要改动
"sourceDataId":"sourceDataId123",//源对象数据id
"destDataId":"destDataId123666"]//目标对象数据id
def result2=Fx.proxy.callAPI("erp.syncData.updateSyncDataMapping",header,param2);
//[false, HttpResult(statusCode=200, content={"errCode":"s106240000","errMsg":"成功"}, bytes=null), ]   s106240000成功,其他失败
log.info(result2)

//查询源对象数据id是否存在映射关系
Map param3=["sourceObjectApiName":"AccountObj",//源对象apiName,如果对象apiName变了,这里要改动
"destObjectApiName":"BD_Customer.BillHead",//目标对象apiName,如果对象apiName变了,这里要改动
"sourceDataId":["sourceDataId123"]]//源对象数据ids,List
def result3=Fx.proxy.callAPI("erp.syncData.getSyncDataMappingBySourceDataId",header,param3);
// [false, HttpResult(statusCode=200, content={"data":{"sourceDataId123":{"sourceDataId":"sourceDataId123","isCreated":true,"destDataId":"destDataId123666","sourceDataName":"sourceDataName1233","updateTime":1611047455451,"lastSyncStatus":6,"destDataName":"destDataName123","destTenantId":"81138","sourceObjectApiName":"AccountObj","destObjectApiName":"BD_Customer.BillHead","sourceTenantId":"81138","statusName":"新增成功","id":"aa46ed320312476485e932a1ca4b4263","lastSyncDataId":"92c86fb175254e54b990bd86b6ce1145","status":1}},"errCode":"s106240000","errMsg":"成功"}, bytes=null), ]
//s106240000成功,其他失败
//data是一个Map,存储着存在映射关系的数据,key是源数据id,value是已存在的对应关系,
log.info(result3)

五.运维相关

告警

熔断

熔断有两种:

集成流的熔断。错误数据超过阈值,集成流被强制停止了。

getbyid接口的熔断。集成流不会停止,只是不会再调用getbyid接口了,依赖getbyid接口的功能都被禁止了。

监控

六.问题排查

日志存储说明

一个租户能存储的日志量,是通过资源包控制的。

下完销售订单以后,会根据连接器的类型,自动赠送一个资源包。如果日志量超过资源包的值,就会把最老的日志滚掉。

资源包控制的日志包括:

  1. 详情页快照。

  2. 访问ERP接口的日志

  3. 全流程日志。全流程的日志,一部分是复用了详情页快照的日志。

排查和解决问题方法

  1. 数据维护查看详情,报错提示
  2. 接口调用参数和返回结果说明
  3. FAQ
  4. 跳转各渠道排查方法(K3webapi、第三方系统接口,函数)

正确的提问方法

  1. 提问之前:先自查。非配置导致的接口问题需要找接口提供方解决。
  2. 在哪或者向谁提问:如何提系统对接的问题
  3. 怎么提问题:提供完整信息,企业、ERP中间对象apiName、CRM中间对象apiName和数据ID、尽量具体(到秒)的发生时间、报错信息、问题现象和描述、自己排查的结果