数据集成:从旺店通到金蝶云星空的最佳实践

  • 轻易云集成顾问-谢楷斌

旺店通·旗舰奇门数据集成到金蝶云星空的案例分享

在实现旺店通·旗舰奇门与金蝶云星空的数据对接过程中,我们面临着多种技术挑战。本文将详细剖析如何利用API接口wdt.wms.stockother.outquery.querywithdetail从旺店通·旗舰奇门获取其他出库单数据,并通过batchSave接口实现批量写入金蝶云星空,确保高效、可靠的数据传输和处理。

1. 保证不漏单的数据获取

为了准确无误地抓取所有必要的其他出库单数据,我们设计了一个定时任务,通过调用wdt.wms.stockother.outquery.querywithdetail接口进行周期性抓取。这个过程需要特别小心的地方在于分页和限流问题,为此我们采用了分布式锁机制配合分页拉取策略,避免由于短时间大量请求而导致的接口限流,同时确保每一页数据全部成功获取:

def fetch_stockout_data(page_number, page_size):
    while True:
        response = requests.get(
            url="https://api.example.com/wdt.wms.stockother.outquery.querywithdetail", 
            params={"page": page_number, "pageSize": page_size}
        )
        if response.status_code == 200:
            data = response.json()
            process_data(data)
            if len(data) < page_size:
                break
        else:
            handle_api_error(response)

fetch_stockout_data(1, 100)

2. 数据格式差异转换与映射

处理两套系统之间的数据格式差异是另一个关键环节。在实际操作中,对从旺店通·旗舰奇门获取的数据进行必要的清洗、转换,以契合金蝶云星空所需的格式。这包括字段名转换、数据类型变化以及逻辑上的一致性校验。例如,将日期格式统一为ISO标准并确保字段名称匹配:

def transform_format(raw_data):
    transformed_data = []
    for record in raw_data:
        transformed_record = {
            "Date": convert_date_to_iso(record["date"]),
            "OrderID": record["order_id"],
            # 映射更多字段...
        }
        transformed_data.append(transformed_record)
    return transformed_data

cleaned_data = transform_format(fetched_raw_data)

3. 实现批量、高速写入金蝶云星空

为了提升大规模数据写入效率,使用 batchSave API 批量提交整理好的其他出库单信息至 金蝶 云 星空。在这一环节,我们设立重试机制以应对偶发性错误,并实时记录日志以监控整个流程进展及异常情况:

def batch_save
![金蝶与外部系统打通接口](https://pic.qeasy.cloud/D27.png~tplv-syqr462i7n-qeasy.image)
### 调用源系统旺店通·旗舰奇门接口获取并加工数据

在数据集成生命周期的第一步,我们需要从源系统获取数据,并对其进行初步的清洗和加工。本文将详细介绍如何通过调用旺店通·旗舰奇门接口`wdt.wms.stockother.outquery.querywithdetail`来实现这一过程。

#### 接口调用配置

该接口使用POST方法,主要用于查询其他出库单的详细信息。以下是元数据配置的详细说明:

```json
{
  "api": "wdt.wms.stockother.outquery.querywithdetail",
  "method": "POST",
  "number": "other_out_no",
  "id": "other_out_no",
  "idCheck": true,
  "request": [
    {
      "field": "params",
      "label": "查询参数",
      "type": "object",
      "children": [
        {
          "field": "time_type",
          "label": "时间类型",
          "type": "string",
          "describe": "1:创建时间;2:最后修改时间 不传默认为创建时间"
        },
        {
          "field": "start_time",
          "label": "开始时间",
          "type": "string",
          "describe": "起始时间,若无业务单号,则为必填。yyyy-MM-dd HH:mm:ss格式",
          "value": "_function DATE_SUB(now(),INTERVAL 15 DAY)"
        },
        {
          "field": "end_time",
          "label": "结束时间",
          "type": "string",
          "describe": "结束时间,上同开始时间.",
          "value": "{{CURRENT_TIME|datetime}}"
        },
        {
          ...
        }
      ]
    },
    {
      ...
    }
  ]
}

请求参数详解

  1. params: 查询参数对象,包含以下字段:

    • time_type: 时间类型,1表示创建时间,2表示最后修改时间。如果不传,则默认为创建时间。
    • start_time: 起始时间,格式为yyyy-MM-dd HH:mm:ss。如果没有业务单号,则此字段为必填项。默认值为当前时间减去15天。
    • end_time: 结束时间,与开始时间格式相同。默认值为当前系统时间。
    • warehouse_no: 仓库编号,用于指定查询的仓库。
    • other_out_no: 业务单号,用于精确查询特定的出库单。
    • status: 业务单据状态,多个状态值用逗号分隔。例如:65表示待结算,70表示已完成。
  2. pager: 分页参数对象,包含以下字段:

    • page_size: 每页记录数,默认值为10。
    • page_no: 页码,从1开始。

数据请求与清洗

在调用接口获取数据后,需要对返回的数据进行初步清洗和加工,以便后续的数据转换和写入步骤。以下是一个示例代码片段,用于展示如何处理接口返回的数据:

import requests
import json
from datetime import datetime, timedelta

# 定义请求URL和头部信息
url = 'https://api.wangdian.cn/openapi2/wdt.wms.stockother.outquery.querywithdetail'
headers = {'Content-Type': 'application/json'}

# 定义请求参数
params = {
    'time_type': '1',
    'start_time': (datetime.now() - timedelta(days=15)).strftime('%Y-%m-%d %H:%M:%S'),
    'end_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
    'warehouse_no': '',
    'other_out_no': '',
    'status': '65,70'
}

pager = {
    'page_size': '10',
    'page_no': '1'
}

# 构建请求体
data = {
    'params': params,
    'pager': pager
}

# 发起POST请求
response = requests.post(url, headers=headers, data=json.dumps(data))

# 检查响应状态码
if response.status_code == 200:
    result = response.json()

    # 数据清洗与加工
    cleaned_data = []
    for record in result['data']:
        cleaned_record = {
            'out_no': record['other_out_no'],
            'warehouse': record['warehouse_no'],
            ...
        }
        cleaned_data.append(cleaned_record)

    # 输出清洗后的数据
    print(json.dumps(cleaned_data, indent=4))
else:
    print(f"Error: {response.status_code}")

总结

通过上述步骤,我们成功调用了旺店通·旗舰奇门接口wdt.wms.stockother.outquery.querywithdetail并对返回的数据进行了初步清洗和加工。这一步骤是数据集成生命周期中的关键环节,为后续的数据转换与写入奠定了基础。在实际应用中,可以根据具体需求进一步优化和扩展数据处理逻辑,以满足不同业务场景的要求。 金蝶与SCM系统接口开发配置

使用轻易云数据集成平台实现金蝶云星空API接口的数据ETL转换

在数据集成生命周期的第二步中,我们需要将已经集成的源平台数据进行ETL(提取、转换、加载)转换,使其符合目标平台金蝶云星空API接口的要求,并最终写入目标平台。本文将详细探讨如何通过轻易云数据集成平台实现这一过程。

配置元数据

首先,我们需要配置元数据以便与金蝶云星空API接口进行交互。以下是一个典型的元数据配置示例:

{
  "api": "batchSave",
  "method": "POST",
  "idCheck": true,
  "operation": {
    "rowsKey": "array",
    "rows": 1,
    "method": "batchArraySave"
  },
  "request": [
    {"field":"FBillNo","label":"单据编号","type":"string","describe":"单据编号","value":"{other_out_no}"},
    {"field":"FBillTypeID","label":"单据类型","type":"string","describe":"单据类型","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"{reason}","mapping":"62e8ddee55eec0316710dab6","mappingDirection":"positive"},
    {"field":"FStockOrgId","label":"库存组织","type":"string","describe":"组织","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"100"},
    {"field":"FPickOrgId","label":"领用组织","type":"string","describe":"组织","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"100"},
    {"field":"FStockDirect","label":"库存方向","type":"string","describe":"下拉列表"},
    {"field":"FDate","label":"日期","type":"string","describe":"日期","value":"{{modified|datetime}}"},
    {"field":"FCustId","label":"客户","type":"string","describe":"基础资料","parser":{"name":"ConvertObjectParser","params":"FNumber"}},
    {"field":"FDeptId","label":"领料部门","type": "string", "describe": "基础资料", "parser": { "name": "ConvertObjectParser", "params": "FNumber" }, "value": "{prop1}", "mapping": "62e8d45581cfb6359213a5b7", "mappingDirection": "positive" },
    {"field": "FPickerId", "label": "领料人", "type": "string", "describe": "基础资料", "parser": { "name": "ConvertObjectParser", "params": "FNumber" } },
    {"field": "FBizType", "label": “业务类型”, “type”: “string”, “describe”: “下拉列表”},
    {"field”: “FOwnerTypeIdHead”, “label”: “货主类型”, “type”: “string”, “describe”: “多类别基础资料列表”, “value”: “BD_OwnerOrg”},
    {"field”: “FOwnerIdHead”, “label”: “货主”, “type”: “string”, “describe”: “多类别基础资料”, “parser”: {“name”:“ConvertObjectParser”,“params”:“FNumber”},“value”:“100”},
    {"field”:“FNote”,“label”:“备注”,“type”:“string”,“describe”:”多行文本“,“value”:”{remark}”},
    {
      ”field”:”FEntity”,
      ”label”:”明细信息”,
      ”type”:”array”,
      ”children”:[
        {”field”:”FMaterialId”,”label”:”物料编码”,”type”:”string”,”describe”:”基础资料”,”parser”:{”name”:”ConvertObjectParser”,”params”:”FNumber”,},”value”:{{detail_list.goods_no}},”parent”:”FEntity”,},
        {”field”:”FCMKBarCode”,"label":"零售条形码","type":"string","describe":"文本","parent":"FEntity"},
        { ” field ”: ” FQty ”, ” label ”: ” 实发数量 ”, ” type ”: ” string ”, ” describe ”: ” 数量 ”, ” value : {{ detail_list.num }} , parent : FEntity , },
        { field : FStockId , label : 发货仓库 , type : string , describe : 基础资料 , parser : name : ConvertObjectParser , params : FNumber , value : warehouse_no , parent : FEntity , },
        { field : FStockLocId , label : 仓位 , type : string , describe : 维度关联字段 , parser : name : ConvertObjectParser , params : FNumber , parent : FEntity , },
        { field : FAmount , label : 总成本 , type : string , describe 金额 parent FEntity },
        { field : FPrice , label : 成本价 , type : string , describe : 单价 , parent : FEntity },
        { field : FSrcBillTypeId , label : 源单类型 , type : string , describe : 源单类型 , parent : FEntity },
        { field : FSrcBillNo , label : 源单编号 , type : string , describe : 源单编号 , parent : FEntity },
        { field : FOwnerTypeId , label : 货主类型 , type : string , describe 多类别基础资料列表 value BD_OwnerOrg parent FEntity },
        { field :FOwnerId, label:货主, type:string, describe:多类别基础资料, value:100, parent:FEntity, parser:{ name: ConvertObjectParser, params: FNumber }},
        { field: FEntryNote, label:备注, type:string, describe:多行文本, parent:FEntity }
      ],
      value:detail_list,
     }
   ],
   otherRequest:[ 
     {
       field:FormId,
       label:业务对象表单 Id,
       type: string,
       describe 必须填写金蝶的表单 ID 如 PUR_PurchaseOrder,
       value STK_MisDelivery,
     },
     {
       field IsAutoSubmitAndAudit,
       label 提交并审核,
       type bool,
       value false,
     },
     {
       field IsVerifyBaseDataField,
       label 验证基础资料,
       type bool,
       describe 是否验证所有的基础资料有效性,布尔类,默认 false(非必录),
       value true,
     },
     {
       field Operation,
       label 执行的操作,
       type string,
       value Save,
     } 
   ]
}

数据提取与清洗

在数据提取阶段,我们从源系统获取原始数据。该过程通常包括从数据库或API中提取数据,并对其进行初步清洗和标准化处理,以确保后续步骤能够顺利进行。

数据转换

在数据转换阶段,我们将清洗后的数据按照目标平台金蝶云星空API接口的要求进行格式转换。这一步至关重要,因为不同系统之间的数据格式和结构可能存在显著差异。

  1. 字段映射与解析

    • 使用ConvertObjectParser解析器将源系统中的字段值转换为目标系统所需的格式。例如,将reason字段映射为FBillTypeID,并使用mapping参数指定具体的映射规则。
    • 对于复杂的数据结构,如数组或嵌套对象,可以通过配置children字段来处理。例如,明细信息(FEntity)中的每个子项都需要进行相应的解析和映射。
  2. 日期与时间格式

    • 使用模板语法(如{{modified|datetime}})将日期和时间字段转换为目标系统所需的格式。
  3. 静态值设置

    • 对于某些固定不变的字段,可以直接在元数据配置中设置静态值。例如,将库存组织(FStockOrgId)和领用组织(FPickOrgId)设置为固定值 100

数据加载

在完成数据转换后,我们使用配置好的API接口将处理后的数据写入目标平台金蝶云星空。通过调用配置中的API方法(如 batchSave),并传递处理后的请求参数,实现最终的数据加载。

{
  api: 'batchSave',
  method: 'POST',
  idCheck: true,
  operation: {
    rowsKey: 'array',
    rows: 1,
    method: 'batchArraySave'
  },
  request: [
    // 已处理好的请求参数
  ],
  otherRequest:[
    {
      field:'FormId',
      label:'业务对象表单 Id',
      type:'string',
      describe:'必须填写金蝶的表单 ID 如 PUR_PurchaseOrder',
      value:'STK_MisDelivery'
    },
    {
      field:'IsAutoSubmitAndAudit',
      label:'提交并审核',
      type:'bool',
      value:false
    },
    {
      field:'IsVerifyBaseDataField',
      label:'验证基础资料',
      type:'bool',
      describe:'是否验证所有的基础资料有效性,布尔类,默认 false(非必录)',
      value:true
    },
    {
      field:'Operation',
      label:'执行的操作',
      type:'string',
      value:'Save'
    }
  ]
}

通过上述步骤,我们成功地将源平台的数据经过ETL转换后写入到金蝶云星空,实现了不同系统间的数据无缝对接。 钉钉与CRM系统接口开发配置

更多系统对接方案