OpenAPI
金蝶云星空OpenAPI目前提供.Net、JAVA、Python等多语言版本SDK
以下笔记使用Python版本的SDK进行记录
新增用户
使用 Administrator
登录金蝶云星空
系统管理 -> 系统管理 -> 创建用户 -> 保存
- 基本信息
- 用户账号:api_test
- 用户名称:API测试
- 部门分组:运营中心
- 联系对象类型:员工
- 移动电话:13888888888
- 注册用户许可分组
- 除"仅查询应用"外,拉满
- 组织角色
- 右侧TAB,选择"行🔍"->勾选角色后,点击返回数据(不是保存,保存是记录勾选情况)
授权
系统管理 -> 系统管理 -> 第三方系统登录授权 -> 新增 -> 获取应用ID -> 点击"复制网址" -> 跳转到金蝶云星空开放平台
登录(没有的话注册一个)-> 第三方系统登录授权 -> 新增授权 -> 填写如下信息(以私有云为例):
- 环境类型:选择私有云
- 产品唯一码:默认自动带上(可在"金蝶管理中心->软件许可引入->产品唯一码"查看)
- 用途:测试环境或生产环境(根据实际情况填写)
- 数据中心标识:默认自动带上(正式环境建议保留不动,测试环境可以考虑留空,便于多个测试数据中心公用同一个应用信息进行生成)
点击提交后会跳转到一个新页面,把"应用信息"复制出来
回到"点击'复制网址'"的页面 -> 粘贴"应用信息" -> 点击确认 -> 填写剩下的信息
- 应用ID、应用密钥(已自动生成)
- 应用名称(随意填写),如:crm_api
- 集成用户(不要用Administrator,获取不到业务接口信息),使用刚才新增的"API测试"
- 会话有效时间(随意填写),如:120分钟
- 白名单配置(正式环境建议配置),如:180.101.49.12
点击"保存",完成配置
SDK
pip install 绝对路径/k3cloud_webapi_sdk-3.0.0-py3-none-any.whl
config.py
ENV = 'TEST'
# 测试环境
if ENV == 'TEST':
# 第三方系统登录授权的账套ID(开放平台->数据中心标识)
AcctID = 'aabbccddeeffgg'
# 第三方系统登录授权的用户(云星空配置->集成用户)
UserName = 'API测试'
# 第三方系统登录授权的应用ID(云星空配置->应用ID)
AppID = 'abcdefghijklmnopqrstuvwxyz'
# 第三方系统登录授权的应用密钥(云星空配置->应用密钥)
AppSec = 'zyxwvutsrqponmlkjihgfedcba'
# 私有云地址(私有云部署必填)
ServerUrl = 'http://112.80.248.75:8090/k3cloud/'
else: # 正式环境
# 第三方系统登录授权的账套ID(开放平台->数据中心标识)
AcctID = 'ggffeeddccbbaa'
# 第三方系统登录授权的用户(云星空配置->集成用户)
UserName = 'API正式'
# 第三方系统登录授权的应用ID(云星空配置->应用ID)
AppID = 'zyxwvutsrqponmlkjihgfedcba'
# 第三方系统登录授权的应用密钥(云星空配置->应用密钥)
AppSec = 'abcdefghijklmnopqrstuvwxyz'
# 私有云地址(私有云部署必填)
ServerUrl = 'http://112.80.248.75:8090/k3cloud/'
sdk.py
from k3cloud_webapi_sdk.main import K3CloudApiSdk
import config
'''
部分常用接口
@see https://openapi.open.kingdee.com/ApiCenterDoc
'''
class K3Service:
def __init__(self):
self.api_sdk = K3CloudApiSdk()
self.api_sdk.InitConfig(config.AcctID, config.UserName, config.AppID, config.AppSec, config.ServerUrl)
def View(self, params):
# print(api_sdk.View("BD_MATERIAL", {"Number": "Webb2021031216102410001"}))
return self.api_sdk.View(params['object'], params['params'])
def Allocate(self, params):
# 分配的前提:必须启用多组织
# print(api_sdk.Allocate("BD_MATERIAL", {"PkIds": "105328,105329", "TOrgIds": "1033"}))
return self.api_sdk.Allocate(params['object'], params['params'])
def Audit(self, params):
# print(api_sdk.Audit.("BD_MATERIAL", {"Numbers": ["Webb2021031216092010001"]}))
return self.api_sdk.Audit(params['object'], params['params'])
def Delete(self, params):
# print(api_sdk.Delete("BD_MATERIAL", {"Numbers": ["Webb2021031216092010001"]}))
return self.api_sdk.Delete(params['object'], params['params'])
def ExecuteBillQuery(self, params):
# 比如查询“物料”(BD_MATERIAL)单据中的“名称”和“编码”字段
# print(api_sdk.ExecuteBillQuery( {"FormId": "BD_Customer", "FieldKeys": "FName,FNumber", "FilterString": "FNumber in ('Webb2021083117391510001','Webb2021083117400510001','Webb2021083117401510001')", "TopRowCount": 100}))
return self.api_sdk.ExecuteBillQuery(params)
def ExcuteOperation(self, params):
# 此处以禁用Forbid/反禁用Enable为例
# 禁用 print(api_sdk.ExcuteOperation("BD_MATERIAL", "Forbid", {"Numbers": ["Webb2021031216102410001"]}))
# 反禁用 print(api_sdk.ExcuteOperation("BD_MATERIAL", "Enable", {"Numbers": ["Webb2021031216102410001"]}))
return self.api_sdk.ExcuteOperation(params['object'], params['status'], params['params'])
def GetDataCenters(self, params):
# print(api_sdk.GetDataCenters())
return self.api_sdk.GetDataCenters()
def Save(self, params):
# 此处仅构造保存接口的部分字段数据示例,使用时请参考WebAPI具体接口的实际参数列表
# current_time = time.strftime('%Y%m%d%H%M%S', time.localtime())
# save_data = {"Model": {"FCreateOrgId": {"FNumber": 100}, "FUserOrgId": {"FNumber": 100}, "FNumber": "Webb" + current_time + "10001", "FName": "物料名称" + current_time + "10001"}}
# 调用sdk中的保存接口
# print(api_sdk.Save("BD_Material", save_data))
return self.api_sdk.Save(params['object'], params['params'])
def Submit(self, params):
# print(api_sdk.Submit("BD_MATERIAL", {"Numbers": ["Webb2021031216092010001"]}))
return self.api_sdk.Submit(params['object'], params['params'])
def UnAudit(self, params):
# print(api_sdk.UnAudit("BD_MATERIAL", {"Numbers": ["Webb2021031216092010001"]}))
return self.api_sdk.UnAudit(params['object'], params['params'])
def BatchSave(self, params):
# 调用sdk中的批量保存接口(同步模式)
# save_data = {"Model": [{"FCreateOrgId": {"FNumber": 100}, "FUserOrgId": {"FNumber": 100}, "FNumber": "Webb1", "FName": "物料名称1" }, {"FCreateOrgId": {"FNumber": 100}, "FUserOrgId": {"FNumber": 100}, "FNumber": "Webb2", "FName": "物料名称2" } ]}
# print(api_sdk.BatchSave("BD_Material", save_data))
return self.api_sdk.BatchSave(params['object'], params['params'])
def BatchSaveQuery(self, params):
# 调用sdk中的批量保存接口(轮询模式)
# save_data = {"Model": [{"FCreateOrgId": {"FNumber": 100}, "FUserOrgId": {"FNumber": 100}, "FNumber": "Webb1", "FName": "物料名称1" }, {"FCreateOrgId": {"FNumber": 100}, "FUserOrgId": {"FNumber": 100}, "FNumber": "Webb2", "FName": "物料名称2" } ]}
# print(api_sdk.BatchSaveQuery("BD_Material", save_data))
return self.api_sdk.BatchSaveQuery(params['object'], params['params'])
example.py
from app.Services.K3Service import K3Service
sdk = K3Service()
params = {
'object': 'BD_Empinfo',
'params': {
"CreateOrgId": 0,
"Number": "110112",
"Id": ""
}
}
res = sdk.View(params)
print(res)
修改
金蝶没有单独的修改接口,使用保存接口进行修改
- 修改数据需要传递单据内码,传单据编码不可以
- 修改分录需要传入分录内码,不需要修改的分录,需要传入IsDeleteEntry为false,防止被删除
- 只需要传入修改字段的数据包,格式跟保存新增格式一样,如果传入的数据包中包含了不需要修改的字段,可以通过NeedUpDateFields参数限定需要修改的字段
- 设置参数IsDeleteEntry为false,防止未传内码的分录被删除
- 设置参数NeedUpDateFields,限定需要修改的字段,如果是分录字段,还需要把分录的Key也放到里面
- 设置参数NeedReturnFields,返回更新后的结果当然也可以通过修改新增分录
例如:修改销售出库单物流跟踪信息分录(对分录进行修改或新增)
# 该代码请求金蝶中间有一个Python的中转层,只看数据结构就行
$args = [
'object' => 'SAL_OUTSTOCK',
'params' => [
'NeedUpDateFields' => ['FOutStockTrace', 'FLogComId', 'F_LOGISTICS', 'FCarryBillNo'], # 修改物流跟踪信息分录FOutStockTrace下的相关信息
'IsDeleteEntry' => false, # 不删除已存在的分录
'IsUserModelInit' => true, # 忽略网控
'Model' => [
'FID' => 112211,
'FOutStockTrace' => [
[ // 新增一条分录
'FLogComId' => [
'FCODE' => 'jd'
],
'F_LOGISTICS' => [
'FCODE' => 'jd'
],
'FCarryBillNo' => 'jd112211'
],
[ // 更新一条分录
'FEntryID' => 1,
'FLogComId' => [
'FCODE' => 'jd'
],
'F_LOGISTICS' => [
'FCODE' => 'jd'
],
'FCarryBillNo' => 'jd221122'
],
]
]
]
];