高效解决跨平台数据对接:从营销云到金蝶云的ETL技术

  • 轻易云集成顾问-姚缘

汤臣倍健营销云数据集成到金蝶云星辰V2案例分享:退货入库(佰嘉)杭州佰健盛庆

在这个技术案例中,我们将深入探讨如何成功实现汤臣倍健营销云的数据集成到金蝶云星辰V2,聚焦于"退货入库(佰嘉)杭州佰健盛庆"方案。此过程中,我们面对的核心挑战包括确保数据不漏单、处理接口限流和分页问题以及应对两者之间的数据格式差异。

首先,通过调用/erp/api/order/query/saleReturnOrder API接口,从汤臣倍健营销云获取具体的销售退货订单信息。在此过程中,为了保证数据抓取可靠性与时效性,我们采用定时任务机制,确保可以准时稳定地从源系统提取信息。此外,为解决API接口可能存在的限流与分页问题,每次请求都伴随有细致的断点续传和重试策略,以防止任何因网络抖动或系统限制带来的数据丢失或重复。

获取的数据经过预处理后,将被写入金蝶云星辰V2,此过程通过调用其 /jdy/v2/scm/sal_in_bound API接口完成。这里涉及大量数据批量写入的问题。因此,在架构设计上,我们采用分片上传和多线程并发操作,实现大规模数据快速、高效、安全地导入目标系统。同时为适配两个不同平台的数据格式差异,需要进行定制化的数据映射,对接前先整理并转换相关字段,使之符合金蝶云星辰V2要求。

整个流程还包含一项重要工作,即实时监控及日志记录。这不仅能帮助我们追踪每个环节中的状态变化,还能及时发现并解决异常情况。例如,当某一次对接出现失败或出错时,可以迅速通过日志定位问题,并触发自动重试机制,从而避免业务停滞或关键节点上的故障扩散。

总之,通过合理利用各种技术手段,如定时任务、分页处理、多线程批量操作等,不仅有效解决了跨平台数据对接中的诸多难题,也为未来类似项目提供了一种可借鉴的方法论。 如何对接金蝶云星空API接口

调用源系统汤臣倍健营销云接口获取并加工数据

在数据集成生命周期的第一步中,我们需要调用源系统汤臣倍健营销云的接口/erp/api/order/query/saleReturnOrder,以获取并加工退货入库相关的数据。本文将详细探讨该API接口的技术细节及其在数据集成中的应用。

接口配置与请求参数

该API接口采用POST方法进行数据请求,主要用于查询销售退货订单。以下是元数据配置中的具体参数说明:

  • tenantId(经销商id):必填项,用于标识经销商身份。例如:34cc4109705e4c058b7b3b0352e57d31。
  • yxyNumber(营销云销售订单号):可选项,传此参数时,其他时间状态等条件无效。例如:YD1215710122031701。
  • number(系统订单号):可选项,传此参数时,其他时间状态等条件无效。例如:XOUT0000000293。
  • status(订单状态):可选项,用于筛选订单状态。0表示未审核,1表示已审核(已出库)。默认值为1。
  • beginTime(开始时间):必填项,如果不传单号则必须填写。格式为YYYY-MM-DDYYYY-MM-DD HH:MM:SS。基于创建时间或更新时间查询。
  • endTime(结束时间):必填项,如果不传单号则必须填写。格式同上。
  • pageNo(页码):可选项,默认值为1。
  • pageSize(每页条数):可选项,默认值为30。
  • timeType(时间段标志):可选项,用于标识查询时间段。0表示创建时间(默认),1表示最后更新时间。

请求示例

以下是一个完整的请求示例:

{
  "tenantId": "34cc4109705e4c058b7b3b0352e57d31",
  "status": "1",
  "beginTime": "{{LAST_SYNC_TIME|datetime}}",
  "endTime": "{{CURRENT_TIME|datetime}}",
  "pageNo": "1",
  "pageSize": "30",
  "timeType": "1"
}

数据清洗与转换

在获取到原始数据后,需要对其进行清洗和转换,以便后续的数据处理和写入步骤。这一过程包括但不限于以下操作:

  1. 字段映射与重命名

    • 将API返回的数据字段映射到目标系统所需的字段名称。例如,将number映射为目标系统的订单编号字段。
  2. 数据类型转换

    • 确保所有字段的数据类型符合目标系统的要求。例如,将字符串类型的日期转换为标准日期格式。
  3. 数据过滤与校验

    • 根据业务规则过滤无效或重复的数据,并进行必要的校验。例如,确保所有订单状态均为已审核。

实践案例

假设我们从API获取到如下原始数据:

{
  "orders": [
    {
      "id": "12345",
      "number": "XOUT0000000293",
      "status": "1",
      "createTime": "2023-10-01 12:00:00",
      "updateTime": "2023-10-02 12:00:00"
    },
    {
      "id": "12346",
      "number": "",
      "status": "",
      "createTime": "",
      "updateTime": ""
    }
  ]
}

经过清洗和转换后的数据应如下所示:

{
  "orders": [
    {
      "order_id": "12345",
      "order_number": "XOUT0000000293",
      "order_status": true,
      "created_at": "2023-10-01T12:00:00Z",
      "updated_at": "2023-10-02T12:00:00Z"
    }
  ]
}

在这个过程中,我们进行了以下操作:

  • id重命名为order_id
  • number重命名为order_number
  • 将状态字段从字符串转换为布尔值。
  • 将日期字符串转换为ISO标准日期格式。

通过上述步骤,我们完成了从调用API接口到数据清洗和转换的一系列操作,为后续的数据写入做好了准备。这一过程不仅提高了数据处理的效率,也确保了数据的一致性和准确性。 金蝶与MES系统接口开发配置

使用轻易云数据集成平台将数据转换并写入金蝶云星辰V2 API接口

在数据集成生命周期的第二阶段,我们需要将已经集成的源平台数据进行ETL转换,并转为目标平台——金蝶云星辰V2 API接口所能够接收的格式,最终写入目标平台。以下是详细的技术实现步骤和配置解析。

配置元数据

首先,我们需要配置好元数据,以确保数据能够正确地从源平台转换并写入到金蝶云星辰V2。以下是我们使用的元数据配置:

{
  "api": "/jdy/v2/scm/sal_in_bound",
  "effect": "EXECUTE",
  "method": "POST",
  "number": "id",
  "id": "id",
  "name": "id",
  "idCheck": true,
  "request": [
    {"field":"bill_source","label":"来源","type":"string","value":"ISV"},
    {"field":"bill_date","label":"出库日期","type":"string","describe":"出库日期,格式:2019-01-01","value":"{{auditTime|date}}"},
    {"field":"customer_id","label":"客户","type":"string","describe":"客户","value":"_findCollection find id from b41660e7-fa00-318f-bbee-1395e229ee6b where number={extCusCode}"},
    {"field":"remark","label":"单据备注","type":"string","describe":"上传的附件url","value":"{remark}-来自营销云-{number}"},
    {"field":"contact_address","label":"联系信息-详细地址","type":"string","describe":"联系信息-详细地址","value":"{shippingAddress}"},
    {"field":"contact_linkman","label":"联系信息-联系人","type":"string","describe":"联系信息-联系人","value":"{contacts}"},
    {"field":"contact_phone","label":"联系信息-联系方式","type":"string","describe":"联系信息-联系方式","value":"{phone}"},
    {"field":"dept_number","label":"部门编码","type":"string","describe":"业务员","value":"BM00004"},
    {
      "field": "material_entity",
      "label": "商品分录",
      "type": "array",
      "describe": "商品分录",
      "value": "itemList",
      "children": [
        {"field": "material_id", "label": "商品id", "type": "string", "describe": "商品id", 
            "value": "_findCollection find id from 395d1591-aee0-3f10-ad09-d5593167af48 where number={extMaterialNo}"},
        {"field": "stock_id", "label": "仓库id", "type": "string", 
            "describe": "仓库id", 
            "value": 
            "1320321200345340928"},
        {"field": 
            "qty", 
            "label":
                "数量", 
            "type":
                "int", 
            "describe":
                "数量", 
            "value":
                "{{itemList.opernumber}}"
        },
        {"field":
                "tax_price", 
            "label":
                "含税单价", 
            "type":
                "int", 
            "describe":
                "含税单价", 
            "value":
                "{{itemList.taxunitprice}}"
        },
        {"field":
                "is_free", 
            "label":
                "是否赠品", 
            "type":
                "bool", 
            "describe":
                "是否赠品", 
            "value":
                false
        },
        {"field":
                "unit_id",
                 label:
                 '单位id',
                 type:
                 'string',
                 describe:
                 '单位id',
                 value:
                 '_findCollection find base_unit_id from 395d1591-aee0-3f10-ad09-d5593167af48 where number={extMaterialNo}'
        },
        {
          field: 'batch_no',
          label: '批次号',
          type: 'string',
          describe: '批次号',
          value: '{{itemList._Flot}}'
        },
        {
          field: 'comment',
          label: '行备注',
          type: 'string',
          describe: '行备注',
          value: '{{itemList.remark}}'
        },
        {
          field: 'kf_date',
          label: '生产日期',
          type: 'string',
          describe: '生产日期',
          value: '{{itemList._Fmfg}}'
        },
        {
          field: 'valid_date',
          label: '有效日期',
          type: 'string',
          describe: '有效日期',
          value: '{{itemList._Fexp}}'
        },
        {
            field:'kf_period',  
            label:'保质期天数',  
            type:'string',  
            describe:'保质期天数',   
            value:'730'
       },
       {
            field:'kf_type',    
            label:'保质期类型',  
            type:'string',  
            describe:'保质期类型,1:天,2:月,3:年',   
            value:'1'
       }
     ]
   }
 ]
}

数据请求与清洗

在进行ETL转换之前,我们需要确保从源系统获取的数据已经经过清洗和预处理。通过轻易云的数据请求与清洗功能,可以自动化处理这些步骤。例如,通过_findCollection函数来查找对应的ID值:

{"field":"customer_id",
  ...
  ...
"value":"'_findCollection find id from b41660e7-fa00-318f-bbee-1395e229ee6b where number={extCusCode}'"}

此段代码表示从指定集合中查找客户ID,其中extCusCode为外部系统提供的客户编码。

数据转换与写入

在完成数据清洗后,接下来就是将这些数据转换为金蝶云星辰V2 API所能接受的格式,并通过POST方法写入目标平台。以下是几个关键字段的转换示例:

  1. 出库日期

    {"field": "bill_date",
     ...
     ...
    ,"value":"'{{auditTime|date}}'"}

    auditTime字段通过管道符号|date进行格式化处理,确保符合目标API要求的日期格式。

  2. 商品分录

    {
     ...
     ...
     ,"children":[
       {
         ...
         ...
         ,"value":"'_findCollection find id from 395d1591-aee0-3f10-ad09-d5593167af48 where number={extMaterialNo}'"
       }
       ,
       ...
       ...
     ]
    }

    在子项中,通过类似方式查找商品ID、仓库ID等字段,并确保每个子项都符合API要求。

  3. 数量与价格

    {
     ...
     ...
     ,"children":[
       {
         ...
         ...
         ,"value":"'{{itemList.opernumber}}'"
       }
       ,
       {
         ...
         ...
         ,"value":"'{{itemList.taxunitprice}}'"
       }
     ]
    }

    opernumbertaxunitprice分别代表商品数量和含税单价,通过模板变量直接引用源系统中的对应字段。

提交请求

最后,通过配置好的元数据,将所有字段组装成一个完整的JSON对象,并通过POST方法提交到金蝶云星辰V2 API接口:

import requests

url = "/jdy/v2/scm/sal_in_bound"
headers = {'Content-Type': 'application/json'}
data = { ... } # 根据上述配置生成的数据对象

response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
    print("Data successfully written to Kingdee Cloud.")
else:
    print("Failed to write data:", response.text)

以上代码展示了如何利用Python脚本发送HTTP POST请求,将处理后的数据写入目标平台。

通过以上步骤,我们成功地将源平台的数据进行了ETL转换,并将其写入到金蝶云星辰V2 API接口。这一过程不仅提高了数据处理效率,也确保了不同系统之间的数据一致性和准确性。 打通用友BIP数据接口

更多系统对接方案