吉客云·奇门数据集成到用友BIP:销售单退货处理
在复杂的企业数据系统中,实现多个平台之间的数据无缝对接是一个非常具有挑战性的任务。本文将聚焦于如何通过高效的技术手段,将吉客云·奇门中的销售订单数据集成到用友BIP系统中,完成销售退货单据的处理。本次案例分享的实际运行方案被命名为:"2B吉客云-销售单--->YS-销售退货单-成功"。
接口调用与数据抓取
首先,我们需要从吉客云·奇门获取相关的销售订单数据。为此,调用jackyun.tradenotsensitiveinfos.list.get
API来定时、可靠地抓取所需信息。这一过程不仅涉及大量的数据吞吐,还要求我们能够处理分页和限流问题,以确保不会遗漏任何重要数据。
实时监控与异常检测
为了保障整个数据传输过程顺利进行,本案例实施了全面的实时监控和异常检测机制。通过这一机制,可以即时发现并解决在API调用过程中可能出现的问题,确保每一次的数据传输都是准确无误且完整稳定的。
自定义数据转换与映射
由于吉客云·奇门和用友BIP之间存在不同的数据格式差异,我们特别设计了一套自定义的数据转换逻辑,将获取到的数据转化为适用于用友BIP格式。在具体实施过程中,通过动态脚本配置实现了灵活、高效和精准地满足业务需求。
批量写入与性能优化
接下来就是将转换后的数据信息批量快速写入到用友BIP系统,对应API yonbip/sd/vouchersalereturn/singleSave
被精心选配以保证高吞吐量下依然保持极佳性能表现。同时,为了避免因突发大规模请求而导致服务瘫痪,多策略组合应用,如异步队列、并行处理等有效提升了整体效率及可靠性。
本篇文章开头直接切入技术主题,从接口调用、实时监控、自定义转换以及批量写入等方面阐述解决方案框架,让大家可以快速进入实战核心部分,并为后续详细探讨提供清晰思路。
调用吉客云·奇门接口jackyun.tradenotsensitiveinfos.list.get获取并加工数据
在数据集成的生命周期中,第一步是从源系统获取数据。本文将详细探讨如何通过轻易云数据集成平台调用吉客云·奇门接口jackyun.tradenotsensitiveinfos.list.get
来获取并加工数据。
接口配置与调用
首先,我们需要配置接口的元数据,以确保能够正确调用和处理数据。以下是接口的基本配置:
{
"api": "jackyun.tradenotsensitiveinfos.list.get",
"method": "POST",
"number": "tradeNo",
"id": "tradeId",
"pagination": {
"pageSize": 20
},
"idCheck": true,
"autoFillResponse": true,
"condition": [
[
{"field":"tradeStatus","logic":"egt","value":"6000"},
{"field":"shopCode","logic":"in","value":"NBKH,ZYDP,BJKH,TYKH,HWKH,HYKH,XSKH,XXKH,CTQD0001,HYKK0003"},
{"field":"goodsDetail.goodsNo","logic":"neqv2"},
{"field":"goodsDetail.sellCount","logic":"neqv2","value":"0"}
]
],
"request": [
{"field":"modified_begin","label":"起始时间","type":"string","describe":"修改起始时间,和结束时间必须同时存在,时间间隔不能超过七天,与线上单号不能同时为空"},
{"field":"modified_end","label":"结束时间","type":"string","describe":"修改结束时间,和起始时间必须同时存在,时间间隔不能超过七天,与线上单号不能同时为空"},
{"field":"startModified","label":"最后修改时间(起始)","type":"string"},
{"field":"endModified","label":"最后修改时间(截止)","type":"string"},
{"field":"tradeNo","label":"销售单号,多个用半角逗号分隔","type":"string"},
{"field":"pageSize","label":"每页记录数,默认50,最大1000","type":"string","value":"50"},
{"field":"pageIndex","label":"页码,0为第1页","type":"string"},
{"field":"hasTotal","label":"默认返回,首次调用时可以传1获取总记录数","type":"string","value":"1"},
{"field":"startCreated","label":"创建时间(起始)","type":"string"},
{"field":"endCreated","label":"创建时间(截止)","type\":\"string\"},
{"field\":\"startAuditTime\",\"label\":\"审核时间(起始)\",\"type\":\"string\"},
{"field\":\"endAuditTime\",\"label\":\"审核时间(截止)\",\"type\":\"string\"},
{\"field\":\"startConsignTime\",\"label\":\"发货时间(起始)\",\"type\":\"string\",\"value\":\"{{DAYS_AGO_1|datetime}}\"},
{\"field\":\"endConsignTime\",\"label\":\"发货时间(截止)\",\"type\":\"string\",\"value\":\"{{CURRENT_TIME|datetime}}\"},
{\"field\":\"tradeStatus\",\"label\":\"订单状态\",\"type\":\"string\"},
{\"field\":\"tradeType\",\"label\":\"订单类型\",\"type\":\"string\",\"value\":\"8\"},
{\"field\":\"sourceTradeNos\",\"label\":\"网店订单号\",\"type\":\"string\"},
{\"field\":\"fields\",\"label\":\"需要返回字段列表逗号分隔\",\"type\": \"string\", \"value\": \"checkTotal,tradeNo,postFee,otherFee,chargeCurrency,..."}
],
\"omissionRemedy\": {
\"crontab\": \"20 */2 * * *\",
\"takeOverRequest\": [
{\"field\": \"startConsignTime\", \"value\": \"_function from_unixtime(({CURRENT_TIME}-172800),'%Y-%m-%d %H:%i:%s')\", \"type\": \"string\", \"label\": \"接管字段\", \"formModel\": {\"enable\": false}, \"tableModel\": {\"enable\": false}, \"physicalModel\": {\"enable\": false}},
{\"field\": \"endConsignTime\", \"value\": \"_function from_unixtime(({CURRENT_TIME}-86400),'%Y-%m-%d %H:%i:%s')\", \"type\": \"string\", \"label\": \"接管字段\", \"formModel\":{\"enable\":false},\"tableModel\":{\"enable\":false},\"physicalModel\":{\"enable\":false}}
]
}
}
数据请求与清洗
在配置好元数据后,我们需要进行实际的数据请求。通过POST方法发送请求,并根据条件过滤出所需的数据。以下是一个示例请求:
{
"modified_begin": "2023-01-01T00:00:00Z",
"modified_end": "2023-01-07T23:59:59Z",
"pageSize": 50,
"pageIndex": 0,
"hasTotal": 1,
"fields": "checkTotal,tradeNo,postFee,..."
}
在这个请求中,我们指定了查询的起始和结束时间,同时设置了分页参数以控制每次请求返回的数据量。此外,通过fields
参数,我们可以精确控制返回的数据字段,从而减少不必要的数据传输。
数据转换与写入
获取到原始数据后,需要对其进行清洗和转换,以便后续写入目标系统。在清洗过程中,可以根据业务需求对数据进行过滤、格式化和校验。例如:
def clean_data(raw_data):
cleaned_data = []
for record in raw_data:
if record['goodsDetail']['sellCount'] > 0:
cleaned_record = {
'tradeNo': record['tradeNo'],
'postFee': record['postFee'],
'goodsName': record['goodsDetail']['goodsName'],
'sellCount': record['goodsDetail']['sellCount']
}
cleaned_data.append(cleaned_record)
return cleaned_data
在上述代码中,我们过滤掉了销售数量为零的记录,并提取了关键信息进行格式化处理。
实践案例
假设我们需要将清洗后的数据写入另一个系统,可以使用以下方式:
def write_to_target_system(cleaned_data):
for record in cleaned_data:
# 假设目标系统提供了一个API接口用于接收数据
response = requests.post("https://target-system/api/receive", json=record)
if response.status_code != 200:
print(f"Failed to write record: {record['tradeNo']}")
# 获取原始数据
raw_data = fetch_raw_data()
# 清洗数据
cleaned_data = clean_data(raw_data)
# 写入目标系统
write_to_target_system(cleaned_data)
通过以上步骤,我们实现了从吉客云·奇门接口获取、清洗并写入目标系统的完整流程。这不仅提高了数据处理的效率,也确保了数据的一致性和准确性。
用友BIPAPI接口数据转换与写入技术案例
在轻易云数据集成平台的生命周期中,第二步是将已经集成的源平台数据进行ETL转换,转为目标平台用友BIPAPI接口所能够接收的格式,并最终写入目标平台。本文将详细探讨如何使用提供的元数据配置,将2B吉客云的销售单数据转换为用友BIPAPI接口所需的销售退货单格式。
数据请求与清洗
首先,我们需要从源系统获取销售单数据,并对其进行必要的清洗和预处理。这一步确保了后续的数据转换操作能够顺利进行。
{
"tradeNo": "S0T5-0000000000-20210831-000000",
"customerName": "聚好看科技股份有限公司(海信)",
"sellerMemo": "备注信息",
"consignTime": "2021-08-31 00:00:00",
"seller": "销售员名称",
"customerAccount": "客户账户",
"buyerMemo": "买家备注",
"payment": -312.00,
"goodsDetail": [
{
"goodsNo": "商品编号",
"sellCount": -100,
"shareFavourableAfterFee": -500.00
}
],
"warehouseCode": "仓库编码"
}
数据转换
在清洗后的数据基础上,我们需要按照用友BIPAPI接口的要求进行字段映射和格式转换。以下是关键字段的映射和转换规则:
-
幂等性保证:通过
resubmitCheckKey
字段确保每次请求都是唯一的。{ "field": "resubmitCheckKey", "value": "{tradeNo}-20240327" }
-
单据编码:直接使用源系统中的交易号
tradeNo
。{ "field": "code", "value": "{tradeNo}" }
-
销售组织:根据客户名称进行条件判断。
{ "field": "salesOrgId", "value": "_function case '{customerName}' when '聚好看科技股份有限公司(海信)' then '0001' else '{sellerMemo}' end" }
-
交易类型:固定值为
J02
。{ "field": "transactionTypeId", "value": "J02" }
-
客户:通过客户名称查找对应的ID或代码。
{ "field": "_findCollection find code from 990e889e-37b2-3286-8158-9876d4030bd1 where name.simplifiedName={customerName}" }
-
单据日期:直接使用源系统中的发货时间
consignTime
。{ "field": "_findCollection find code from b336bfe6-125a-3e8e-a939-df93ab6eeeae where name={seller}" }
-
开票组织:同样根据客户名称进行条件判断。
{ "_function case '{customerName}' when '聚好看科技股份有限公司(海信)' then '0001' else '{sellerMemo}' end" }
-
币种:固定值为
CNY
。{ "_findCollection find unitCode from 7aed2c28-cc02-35c8-aa6a-2d750373f9e1 where code={{goodsDetail.goodsNo}}" }
-
退货单详情:处理复杂的嵌套结构,特别是商品明细部分,需要对每个商品进行详细的数据转换,包括数量、金额、税额等计算。
{ "_function '{{goodsDetail.sellCount}}'*(-1)" }, { "_function abs(round(({{goodsDetail.shareFavourableAfterFee}}\/{{goodsDetail.sellCount}}),2))" }, { "_function abs(round({{goodsDetail.shareFavourableAfterFee}},2))" }, { "_function abs(round({{goodsDetail.shareFavourableAfterFee}}\/(1+0.13),2))" }, { "_function abs(round({{goodsDetail.shareFavourableAfterFee}}\/(1+0.13),2)-{{goodsDetail.shareFavourableAfterFee}})" }
数据写入
完成所有字段的映射和转换后,通过POST请求将数据发送到用友BIPAPI接口。
POST /yonbip/sd/vouchersalereturn/singleSave HTTP/1.1
Host: api.yonyoucloud.com
Content-Type: application/json
{
// 转换后的JSON数据结构
}
实时监控与错误处理
在整个ETL过程中,实时监控和错误处理至关重要。确保每个步骤都能捕获并记录错误信息,以便及时修正和重试。
通过以上步骤,我们成功地将2B吉客云中的销售单数据转换为用友BIPAPI接口所需的格式,并顺利写入目标平台。这一过程展示了轻易云数据集成平台强大的ETL能力以及对异构系统间无缝对接的支持。