调用旺店通API并实现数据初步处理的方法

  • 轻易云集成顾问-卢剑航
### 案例:旺店通·旗舰奇门数据集成到金蝶云星空 在业务系统对接过程中,我们选择了使用轻易云数据集成平台来完成将旺店通·旗舰奇门的销售出库单数据无缝对接至金蝶云星空。该方案不仅确保了数据的完整性和一致性,还实现了高效的数据处理和监控,使得整个流程更加透明化和自动化。 #### 集成解决方案概览 为了有效应对大规模的数据传输需求,此次实施重点关注以下关键技术点: 1. **批量集成及快速写入机制** 为满足大量订单实时写入金蝶云星空的需求,构建了一套稳定且高效的批量数据写入机制。通过调用金蝶云星空`batchSave`接口,可以在保证事务性的基础上,实现大量销售出库单信息的快速处理。 2. **API接口分页与限流策略** 旺店通·旗舰奇门API (`wdt.wms.stockout.sales.querywithdetail`) 在获取销售出库单详情时,有严格的分页限制和请求频率控制。因此,设计了一套智能分页与限流策略,以最大程度利用API资源,同时避免触发限流机制,提高整体系统性能。 3. **定制化数据映射与格式转换** 考虑到两者之间的数据格式差异,特别是字段命名规则、数值类型等问题,通过自定义脚本实时完成源目的端的数据映射与转换。这种定制化映射能有效减少后续错误发生,并提升整体适配度。 4. **异常处理与重试机制** 针对网络不稳定或因其他原因导致的数据传输失败情况,引入了异常捕获和自动重试机制。一旦出现HTTP请求错误或操作未成功,会根据预设规则进行多次重试,确保最终任务执行成功。此外,还记录详细日志以供事后追溯分析。 5. **实时监控与日志管理** 通过平台内置功能,对每个环节进行全程监控,从抓取旺店通·旗舰奇门接口开始,到最终写入金蝶云星空均支持可视化查看并生成详尽日志报表,为日常运维提供有力保障。同时,这也使得整个过程变得更加透明,让技术人员可以及时发现并排除任何潜在的问题。 ![金蝶与WMS系统接口开发配置](https://pic.qeasy.cloud/D23.png~tplv-syqr462i7n-qeasy.image) ### 调用旺店通·旗舰奇门接口wdt.wms.stockout.sales.querywithdetail获取并加工数据 在数据集成的生命周期中,调用源系统接口是至关重要的第一步。本文将深入探讨如何通过轻易云数据集成平台调用旺店通·旗舰奇门接口`wdt.wms.stockout.sales.querywithdetail`,并对获取的数据进行初步加工处理。 #### 接口概述 `wdt.wms.stockout.sales.querywithdetail`接口用于查询销售出库单的详细信息。该接口采用POST请求方式,通过分页参数和业务参数来过滤和获取所需的数据。 #### 元数据配置解析 根据提供的元数据配置,我们可以看到以下关键字段: - **api**: `wdt.wms.stockout.sales.querywithdetail` - **effect**: `QUERY` - **method**: `POST` - **number**: `order_no` - **id**: `stockout_id` - **name**: `order_no` - **idCheck**: `true` 这些字段定义了接口的基本信息和请求方式。下面我们详细解析请求参数部分: ##### 分页参数 分页参数用于控制每次请求返回的数据量和页码,避免一次性获取过多数据导致性能问题。 ```json { "field": "pager", "label": "分页参数", "type": "object", "describe": "分页参数", "children": [ { "field": "page_size", "label": "分页大小", "type": "int", "describe": "分页大小", "value": "150" }, { "field": "page_no", "label": "页号", "type": "int", "describe": "页号", "value": "1" } ] } ``` ##### 业务参数 业务参数用于指定查询条件,如时间范围、状态、仓库编码等。这些参数可以帮助我们精确地筛选出所需的销售出库单信息。 ```json { "field": "params", "label": "业务参数", "type": "object", "describe": "业务参数", ... } ``` 其中,关键字段包括: - **start_time** 和 **end_time**:用于指定查询的时间范围。 - **status_type** 和 **status**:用于过滤出库单的状态。 - **warehouse_no**:指定仓库编码。 - **stockout_no**:出库单编号。 - **shop_nos**:多个店铺编号,用英文逗号分隔。 - **src_order_no**:系统订单号。 - **need_sn**:是否返回SN信息。 - **position**:是否按照货位排序。 #### 请求示例 基于上述元数据配置,我们构建一个具体的请求示例: ```json { "pager": { "page_size": 150, "page_no": 1 }, "params": { "start_time": "{{LAST_SYNC_TIME|datetime}}", "end_time": "{{CURRENT_TIME|datetime}}", ... } } ``` 在实际应用中,`start_time` 和 `end_time` 会被替换为具体的时间值,例如: ```json { ..., "params": { ..., "start_time": "2023-10-01T00:00:00Z", ... } } ``` #### 数据加工处理 在成功调用接口并获取到数据后,需要对数据进行初步加工处理,以便后续的数据转换与写入阶段使用。常见的数据加工操作包括: 1. **数据清洗**:去除无效或重复的数据记录。 2. **格式转换**:将日期、数值等字段转换为目标系统所需的格式。 3. **字段映射**:根据目标系统要求,对字段进行重命名或重新组织。 例如,对于返回的JSON数据,可以使用Python脚本进行初步处理: ```python import json def process_data(response_data): processed_data = [] for record in response_data['data']: processed_record = { 'order_id': record['order_no'], 'warehouse': record['warehouse_no'], 'status': record['status'], 'timestamp': record['created_at'] } processed_data.append(processed_record) return processed_data # 假设response_data是从API获取到的原始数据 response_data = json.loads(api_response) cleaned_data = process_data(response_data) ``` 通过上述步骤,我们可以确保从源系统获取到的数据符合目标系统的要求,为后续的数据转换与写入打下坚实基础。 #### 总结 本文详细介绍了如何通过轻易云数据集成平台调用旺店通·旗舰奇门接口`wdt.wms.stockout.sales.querywithdetail`,并对获取的数据进行初步加工处理。这一步骤是整个数据集成生命周期中的关键环节,为后续的数据处理奠定了基础。 ![企业微信与ERP系统接口开发配置](https://pic.qeasy.cloud/S22.png~tplv-syqr462i7n-qeasy.image) ### 轻易云数据集成平台生命周期的第二步:ETL转换与写入金蝶云星空 在数据集成过程中,ETL(Extract, Transform, Load)转换是将源平台的数据转化为目标平台所能接收的格式的关键步骤。本文将详细探讨如何使用轻易云数据集成平台,将旺店通销售出库单的数据转换并写入到金蝶云星空API接口中。 #### 接口配置与元数据解析 在进行ETL转换时,首先需要了解目标平台的API接口配置。以下是金蝶云星空API接口的元数据配置: ```json { "api": "batchSave", "method": "POST", "idCheck": true, "operation": { "rowsKey": "array", "rows": 10, "method": "batchArraySave" }, "request": [ {"field":"FBillTypeID","label":"单据类型","type":"string","describe":"单据类型","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"XSCKD01_SYS"}, {"field":"FBillNo","label":"单据编号","type":"string","describe":"单据编号","value":"{order_no}"}, {"field":"FDate","label":"日期","type":"string","describe":"日期","value":"{{consign_time|datetime}}"}, {"field":"FSaleOrgId","label":"销售组织","type":"string","describe":"组织","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"100"}, {"field":"FCustomerID","label":"客户","type":"string","describe":"基础资料","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"_findCollection find FNumber from 6a332f6f-a902-3af2-9fbb-56a6870f18fb where F_UBGN_Text_qtr={shop_no}"}, {"field":"FSaleDeptID","label":"销售部门","type":"string","describe":"基础资料","parser":{"name":"ConvertObjectParser","params":"FNumber"}}, {"field":"FCorrespondOrgId","label":"对应组织","type":"string","describe":"组织","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"100"}, {"field": "FSalesManID", "label": "销售员", "type": "string", "describe": "基础资料", "parser": {"name": "ConvertObjectParser", "params": "FNumber"}}, {"field": "FStockOrgId", "label": "发货组织", "type": "string", "describe": "组织", "parser": {"name": "ConvertObjectParser", "params": "FNumber"}, "value": "100"}, {"field": "FDeliveryDeptID", "label": "发货部门", "type": "string", "describe": "基础资料", "parser": {"name": "ConvertObjectParser", "params": "FNumber"}}, {"field": "FNote", "label": "备注", "type": "string", "describe": "多行文本", "value": "{remark}"}, {"field": "FOwnerTypeIdHead", "label": "货主类型", "type": "string", "describe": "多类别基础资料列表", "value": "BD_OwnerOrg"}, {"field": "FOwnerIdHead", "label": "货主", "type": "string", "describe": "多类别基础资料", "parser":{ "name": "ConvertObjectParser", "value" : 100}, {"label" :"原始单号" ,"field" :"F_UBGN_Text" ,"type" :"string"} ,{"label" :"预估货品成本" ,"field" :"F_TPRO_Decimal1" ,"type" :"string" ,value : "{goods_cost}" }, { field: 'FEntity', label: '明细信息', type: 'array', children: [ { field: 'FMaterialID', label: '物料编码', type: 'string', describe: '基础资料', parser: { name: 'ConvertObjectParser', params: 'FNumber' }, value: '{{detail_list.spec_no}}', parent: 'FEntity' }, { field: 'FRealQty', label: '实发数量', type: 'string', describe: '数量', value: '{{details_list.goods_count}}', parent: 'FEntity' }, { field: 'FTaxPrice', label: '含税单价', type: 'string', describe: '单价', value:'_function {receivable}/{goods_count2}', parent:' FEntity' }, { field:' FIsFree ', label :'是否赠品_function case '{{details_list.share_price}}' when'0.0000' then true else false end ', type :' string ', describe :'复选框 ', parent :' FEntity ' }, { field :' FEntryTaxRate ', label :'税率% ', type :' string ', describe :'小数 ', parent :' FEntity ' }, { field :' FStockID ', label :'仓库 ', type :' string ', describe :'基础资料 ', parser :{ name:' ConvertObjectParser ', params :' FNumber '} ,value :'{ warehouse_no }',parent:' FEntity ' }, { field:' FEntrynote ', label:'备注', type:' string ', describe:'文本', value : '{{details_list.remark}}', parent : ' FEntity ' }, { parent : ' FEntity ', label : '成本价(旺店通)', field : ' F_UBGN_Decimal ', type : ' string ', value : '{{details_list.cost_price}}' }, { field : ‘ _UBGN_Decimal1 ’, label : ‘总成本(旺店通)’, type : ‘ string ’, value : ‘_function {{details_list.cost_price}}*{{details_list.goods_count}}’ } ], value : ‘ details_list ’ }, { field : ‘ _F_UBGN_LargeText1 ’, label : ‘订单编码(旺店通)’, type : ‘ string ’, value : ‘{ trade_no }’ }, { field : ‘ _F_UBGN_LargeText ’, label : ‘原始单号(旺店通)’, type : ‘ string ’, value : ‘{ src_trade_no }’ } ], otherRequest:[ { field: ‘ FormId ’, label: ‘业务对象表单Id’, type: ‘ string ’, describe: ‘必须填写金蝶的表单ID如:PUR_PurchaseOrder’,value: ‘ SAL_OUTSTOCK ’ }, { field: ‘ Operation ’, label: ‘执行的操作’,value: ‘ Save ’ }, { field: ‘ IsAutoSubmitAndAudit ’,label: ‘提交并审核’,type: ‘ bool ’,value: true }, { field: ‘ IsVerifyBaseDataField ’,label: ‘验证基础资料’,type: bool ,default:false,value:true }, { field: SubSystemId,label:System模块,type:string,default仓库模块,value:21} ] } ``` #### 数据请求与清洗 在ETL流程中,首先要从源平台获取数据,并进行必要的清洗和预处理。例如,从旺店通获取销售出库单信息,并确保数据格式符合目标平台的要求。 ```python def fetch_and_clean_data(): # 从旺店通获取数据 raw_data = get_data_from_wdt() # 清洗和预处理数据,例如日期格式转换、字段映射等 cleaned_data = [] for record in raw_data: cleaned_record = {} cleaned_record['FBillNo'] = record['order_no'] cleaned_record['FDate'] = convert_date_format(record['consign_time']) cleaned_record['FCustomerID'] = find_customer_id(record['shop_no']) # ...其他字段处理... cleaned_data.append(cleaned_record) return cleaned_data def convert_date_format(date_str): # 转换日期格式为目标平台所需格式 return datetime.strptime(date_str, '%Y-%m-%d').strftime('%Y-%m-%d') ``` #### 数据转换与写入 接下来,将清洗后的数据按照目标平台API接口要求进行转换,并通过API接口写入到金蝶云星空。 ```python def transform_and_write_to_kd(data): transformed_data = [] for record in data: transformed_record = {} # 映射字段和转换值 transformed_record['FBillTypeID'] = {'FNumber': record.get('FBillTypeID', 'XSCKD01_SYS')} transformed_record['FBillNo'] = record.get('FBillNo') transformed_record['FDate'] = record.get('FDate') transformed_record['FSaleOrgId'] = {'FNumber': record.get('FSaleOrgId', '100')} # ...其他字段映射... transformed_data.append(transformed_record) # 构建请求体并调用API接口写入金蝶云星空 request_body = { 'FormId': 'SAL_OUTSTOCK', 'Operation': {'rowsKey': transformed_data}, # ...其他请求参数... } response = call_kd_api(request_body) def call_kd_api(request_body): url = '<金蝶云星空API地址>' headers = {'Content-Type': 'application/json'} response = requests.post(url, json=request_body, headers=headers) if response.status_code == 200: print('Data successfully written to Kingdee Cloud.') else: print(f'Failed to write data. Status code: {response.status_code}') ``` #### 总结 通过上述步骤,我们可以完成从源平台到目标平台的数据ETL转换,并成功将数据写入到金蝶云星空。关键在于理解目标平台API接口的元数据配置,正确地进行字段映射和值转换,确保数据格式符合要求。在实际应用中,还需根据具体业务需求进一步调整和优化这些步骤。 ![如何开发金蝶云星空API接口](https://pic.qeasy.cloud/T28.png~tplv-syqr462i7n-qeasy.image)