4.1【函数组件】同步前中后函数

一、同步前自定义函数执行支持数据过滤

即函中返回结果中包含"isExec":"false",即该次同步将不再往后执行,目标数据将不会做出相应的更改。
测试场景:在自定义函数返回的Map中加入"isExec":"false",或"isExec":false目标数据将不会发生更改。
函数代码: Map map = ["details":syncArg.details, "objectData":syncArg.objectData, "isExec":"false" ]; return map;

二、同步中执行自定义函数

函数执行后,在函数中编写的映射值修改,企业id和对象apiName不会更改。
测试场景:只有新增数据,才会携带从对象;更新时会更新对象映射值,因此如果没有对从对象做出特殊鉴别,更新的对象将不区分主从对象,一律更新,主从对象名称都会更新为自定义函数赋值
函数代码:
log.info("事件类型:" + syncArg.destEventType); log.info(syncArg.objectData); log.info(syncArg.details); Map objectData = syncArg.objectData as Map; objectData.name = "自定义函数修改" Map map = ["details":syncArg.details, "objectData":syncArg.objectData]; log.info(map); return map;

三、同步后执行自定义函数

函数执行后,在函数中编写的映射值修改,企业id和对象apiName不会更改。
测试场景:数据同步不会受到影响,只是将数据传给自定义函数即可,需要通过查看日志进行判断
函数代码: Map map = ["details":context.details, "objectData":context.data, "afterSync" : "yes001"]; return map;
具体入参字段(如果不清楚入参有什么字段就先把函数写好,然后打印入参看一下,注意新增和更新入参不一样)和函数例子如下
同步前:通过数据范围的校验之后
主要入参字段: { "destObjectApiName": "",//目标对象apiName "sourceData": {"字段apiName":"字段值"}//对象字段信息 }
简单例子:
log.info(syncArg); String destObjApiName=syncArg["destObjectApiName"] as String; log.info("destObjectApiName:"+destObjApiName); if("object_xo21i__c"==destObjApiName){ return syncArg; } Map objectData=syncArg["objectData"] as Map; String customerCode=objectData["customerCodeHead"] as String; syncArg["isExec"]=false;//把这个字段设置为false,会过滤掉这条数据不同步 return syncArg;
同步中:写入目标系统之前
主要入参字段: { "destDetailSyncDataIdAndDestDataMap": {"":{"字段apiName":"字段值"}},//目标对象明细 "destData": {"字段apiName":"字段值"}//目标对象字段信息 //如果新增主对象在destData,明细数据在destDetailSyncDataIdAndDestDataMap,如果是更新主从数据都在destData(更新是单独更新的) }
简单例子:
//修改customerShortName字段值 log.info(syncArg); syncArg["objectData"]["customerShortName"]="dddddd" log.info(syncArg); return syncArg;
同步后:写入目标系统之后
主要入参字段: { "sourceDataId": "5fead1146660700001170e3d",//源数据id,只有crm->erp方向有这个字段 "sourceObjectApiName": "AccountObj",//源对象apiName "completeDataWriteResult": {//写入目标数据的结果 "detailWriteResults": [],//明细数据结果 "errCode": 0, "success": true, "destEventType": 1, "errMsg": "success", "writeResult": {//主数据结果,errCode为s106240000成功,其他的失败接口返回的错误码 "errCode": 5001, "success": false, "syncDataId": "3ab1c2c2ffe04111b3e713632d5a4f76", "errMsg": "预处理服务调用错误:调用外部http接口失败,错误信息:100,SAP系统BP名称已创建,不允许重复创建。::errCode=s306240003", "destDetailSyncDataIdAndDestDataMap": {} } }, "destObjectApiName": "AccountObj_1el03su6s",//目标数据对象apiName "objectData": {//目标数据 "tenant_id": "706089",//企业ei "object_describe_api_name": "AccountObj_1el03su6s",//对象apiName "_id": "5fead2696532bf0001e524e4" }, "details": {},//明细数据 }
简单例子: //crm->erp,把目标对象的id写到crm源对象 log.info(syncArg) if(syncArg["objectData"]["_id"]!=null&&syncArg["objectData"]["_id"]!="" &&syncArg["sourceDataId"]!=null&&syncArg["sourceDataId"]!=""){ String destDataId=syncArg["objectData"]["_id"] as String;//目标数据id String sourceDataId=syncArg["sourceDataId"] as String;//源数据id String errCode=syncArg["completeDataWriteResult"]["writeResult"]["errCode"]as String; log.info("--"+errCode) if (errCode =="0"){//&&destDataId.length()<11 def (Boolean error,Map data,String errorMessage) = Fx.object.update("AccountObj",sourceDataId, ["field_b25i7__c":destDataId],true); log.info(errorMessage) } } return syncArg;

 四、 登录k3的webapi获取数据

//定义请求参数,url,用户名,密码,数据中心 String url = "";//http://jxsz.fortiddns.com:58000/k3cloud/ String userName = ""; String passWord = ""; String acctId = "";//62415a905fb572 //请求头 Map headMap = ["Content-Type":"application/json"]; //金蝶k3c登录授权处理,登录授权需要参数:URL地址,登录用户名,密码,语言,数据中心ID,调用方法名 String login = "Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc"; //查询接口方法 String queryMethod = "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc"; Map bodyMap1 = [:]; //返回结构 Map returnMap = [:]; bodyMap1.put("lcid", "2052"); bodyMap1.put("userName", userName); bodyMap1.put("passWord", passWord); bodyMap1.put("acctId", acctId); StringBody body = StringBody.builder().content(bodyMap1).build() Request request = Request.builder() .method("POST") .url(url+login) .timeout(7000) .retryCount(0) .header("Content-Type","application/json") .body(body) .build() def(Boolean error1, HttpResult data1, String errorMessage1) = Fx.http.execute(request); if(error1){ log.info("调用登录接口异常:"+errorMessage1) } //从登录结果取kdservice-sessionid和ASP.NET_SessionId Map headers = data1["headers"] as Map; if(headers==null){ Fx.message.throwErrorMessage("登录失败:"+data1); } String Cookies = headers["Cookies"] as String; log.info("Cookies是"+Cookies); String sessionid=Cookies.split(";")[0]; String NET_SessionId=Cookies.split(";")[1]; sessionid=sessionid.split("=")[1]; NET_SessionId=NET_SessionId.split("=")[1]; //请求体 Map bodyMap = [:]; //返回最大行数 Integer TopRowCount=0; //需查询的字段key集合 String FieldKeys="FCUSTID,FNumber"; //业务对象表单Id, String FormId="BD_Customer"; //查询条件 String FilterString="FNumber != ''"; //最大行数 Integer Limit=10; //开始行索引 Integer StartRow=0; //组合参数 //组合查询条件参数 Map data = ["TopRowCount":TopRowCount,"FieldKeys":FieldKeys,"FormId":FormId,"FilterString":FilterString,"Limit":Limit,"StartRow":StartRow]; bodyMap.put("data", data); //查询数据 StringBody body1 = StringBody.builder().content(bodyMap).build() Request request1 = Request.builder() .method("POST") .url(url+queryMethod) .timeout(7000) .retryCount(0) .header("Content-Type","application/json") .header("kdservice-sessionid",sessionid) .header("ASP.NET_SessionId",NET_SessionId) .body(body1) .build() //log.info(url+method); def(Boolean error, HttpResult Result, String Message) = Fx.http.execute(request1); log.info("返回的数据信息为:"+Result); //开始处理数据 String contentStr = Result["content"] as String; if(contentStr){ //查询失败 if(contentStr.contains("ResponseStatus")){ Fx.message.throwErrorMessage(contentStr); } //有数据就开始处理,返回为空就跳过 List contentList = Fx.json.parseList(contentStr); log.info("contentList:"+contentList); String[] keyList = FieldKeys.split(","); contentList.each{ item -> List eachDataList=item as List; log.info("eachDataList:"+eachDataList) Map eachData=[:] //每一条数据 eachDataList.eachWithIndex{ value,int i -> eachData.put(keyList[i], value) } log.info("eachData:"+eachData) } }
2023-01-05
0 5