欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NetCore对接各大财务软件凭证API——金蝶系列

程序员文章站 2022-05-04 11:37:48
作为一名程序猿我们在拿到类似的接口对接需求,第一件是肯定是看相关文档,然后做接口分析,最后是封装接口,运用到我们的项目中去,所以对于我们来说,第一步就是寻找相关的开发文档...

   今天要讲的是金蝶系列的api,大家都知道,金蝶的产品是比较多的,那么我们这次要讲解的就是金蝶云星空,或者叫k3cloud。

首先,作为一名程序猿我们在拿到类似的接口对接需求,第一件是肯定是看相关文档,然后做接口分析,最后是封装接口,运用到我们的项目中去,所以对于我们来说,第一步就是寻找相关的开发文档,在这方面不得不承认,金蝶社区是个好地方。里面有关于产品的所有知识点和大家遇到的各种问题。废话不多说,文档哪里找,请看下面的步

一.k3cloud接口地址以及财务环境的登录信息

我们在做.netcore对接财务系统时,要用到的几个参数有:账套号,用户名,密码,财务环境地址(支持外网访问)

这个信息你可以找你对接的客户要,最好是能要到外网登录的地址,因为这样省去你远程登录的麻烦,其次,账号的权限也很重要,该账号下必须能看到名为-- webapi的菜单,因为我们需要的接口信息包括后续的测试等都可以在这里处理。如下图所示

.NetCore对接各大财务软件凭证API——金蝶系列

 

 

二.对接要用到的接口列表

既然将凭证api,那么我们需要用到的几个菜单在财务会计--总账下:主要有科目查询接口、凭证字查询接口、凭证新增接口

每个操作我们都可以通过在线测试webapi来验证我们的接口信息,查询接口的请求参数说明详见下图

.NetCore对接各大财务软件凭证API——金蝶系列

1.唯一码的formid

formid为每个业务对象的表单id,如科目对应的就是bd_account,这里建议我们在开发时,可以提前将这些用到的表单id统一设置为常量。参考以下代码片段,当然实际开发中我们可能用不到这么多,大家根据自己的情况进行合理的取舍。

public class billkeyconst
    {
        #region 财务会计 总账 

        public const string 科目 = "bd_account";

        public const string 帐薄 = "bd_accountbook";

        public const string 会计日历 = "bd_accountcalendar";

        public const string 会计要素 = "bd_accountgroup";

        public const string 币别 = "bd_currency";

        public const string 费用项目 = "bd_expense";

        public const string 汇率 = "bd_rate";

        public const string 结算方式 = "bd_settletype";

        public const string 凭证字 = "bd_vouchergroup";

        public const string 调整期间管理 = "gl_adjustperiod";

        public const string 自动转账 = "gl_autotransfer";

        public const string 现金流量项目 = "gl_cashflow";

        public const string 附表项目指定 = "gl_cashindirectitem";

        public const string 智能转存 = "gl_depositscheme";

        public const string 期末调汇 = "gl_exchangescheme";

        public const string 摘要库 = "gl_explanation";

        public const string 附表项目调整 = "gl_indirectitemadjust";

        public const string 帐薄隶属关系 = "gl_multibookmergescheme";

        public const string 结转损益 = "gl_plscheme";

        public const string t型账 = "gl_taccount";

        public const string 凭证 = "gl_voucher";

        public const string 凭证摊销 = "gl_voucheramortize";

        public const string 模式凭证 = "gl_vouchermodel";

        public const string 凭证预提 = "gl_voucherprovision";

        public const string 会计核算体系 = "org_accountsystem";

        #endregion

        #region 财务会计 智能会计平台

        public const string 业务凭证 = "bas_businessvoucher";

        public const string 凭证生成 = "bas_makebizvchwizard";

        public const string 分录类型 = "bas_vchentrytype";

        public const string 凭证模板 = "bas_vchtemplate";

        public const string 增值税发票单据 = "gl_addedtaxbill";

        public const string 增值税发票识别 = "gl_addedtaxocrresult";

        public const string 凭证自动生成方案 = "gl_autobuildvoucherscheme";

        public const string 扫描识别模板管理 = "gl_billocrtemplate";

        public const string 对账方案 = "gl_checkscheme";

        public const string 自定义单据识别 = "gl_ocrresultbase";

        public const string 扫描仪注册登记 = "gl_scannersign";

        public const string 银行回单_付款 = "gl_yhhdfk";

        public const string 银行回单_收款 = "gl_yhhdsk";

        #endregion

        #region 供应链 采购单据

        public const string scm_警示灯方案 = "scm_warnscheme";

        public const string bd_采购条款 = "bd_purclause";

        public const string bd_采购折扣表 = "bd_purdiscount";

        public const string pur_评估等级 = "pur_assessment";

        public const string pur_采购评估指标 = "pur_assessmentindex";

        public const string pur_采购评估方案 = "pur_assessmentplans";

        public const string pur_货源清单 = "pur_catalog";

        public const string pur_采购合同 = "pur_contract";

        public const string pur_采购合同变更单 = "pur_contractchange";

        public const string pur_期初采购退料单 = "pur_initmrs";

        public const string pur_退料申请单 = "pur_mrapp";

        public const string pur_采购退料单 = "pur_mrb";

        public const string pur_采购调价表 = "pur_pat";

        public const string pur_采购定价变更单 = "pur_pochange";

        public const string pur_采购定价新变更单 = "pur_poxchange";

        public const string pur_采购价目表 = "pur_pricecategory";

        public const string pur_物权转移单 = "pur_propertyconvert";

        public const string pur_采购订单 = "pur_purchaseorder";

        public const string pur_收料通知单 = "pur_receivebill";

        public const string pur_采购申请单 = "pur_requisition";

        public const string pur_供应商评分表 = "pur_supplierasseementtb";

        public const string pur_消耗汇总表 = "pur_vmiconsumesum";

        public const string stk_期初采购入库单 = "stk_initinstock";

        public const string stk_采购入库单 = "stk_instock";

        #endregion

        #region 供应链 销售管理

        public const string bd_云之家考勤设置 = "bd_attendancesetting";

        public const string bd_轻应用自定义字段设置 = "bd_mobextendfieldconfig";

        public const string bd_销售折扣表 = "bd_sal_discountlist";

        public const string bd_销售价目表 = "bd_sal_pricelist";

        public const string bd_销售条款 = "bd_salclause";

        public const string sal_销售调价方案 = "sal_adjustprice";

        public const string sal_可发量查询 = "sal_availablequery";

        public const string sal_批量调价单 = "sal_batchadjustprice";

        public const string sal_寄售结算单 = "sal_consignmentsettle";

        public const string sal_客户物料对应表 = "sal_custmatmapping";

        public const string sal_发货通知单 = "sal_deliverynotice";

        public const string sal_期初销售出库单 = "sal_initoutstock";

        public const string sal_电子面单 = "sal_kuaidibill";

        public const string sal_销售物流信息 = "sal_logisticsinfo";

        public const string sal_销售出库单 = "sal_outstock";

        public const string sal_销售报价单 = "sal_quotation";

        public const string sal_退货通知单 = "sal_returnnotice";

        public const string sal_销售退货单 = "sal_returnstock";

        public const string sal_销售订单 = "sal_saleorder";

        public const string sal_销售订单变更单 = "sal_saleorderchange";

        public const string sal_模拟报价单 = "sal_simulatequotation";

        public const string sal_标准费率维护 = "sal_stdexchangerate";

        public const string sal_销售订单新变更单 = "sal_xorder";

        public const string sal_销售报价变更单 = "sal_xquotation";

        #endregion

        #region 供应链 信用管理

        public const string cre_信用检查规则 = "cre_checkrule";

        public const string cre_信用表更 = "cre_creditchange";

        public const string cre_信用总额特批 = "cre_creditsumpermit";

        public const string cre_信用档案 = "cre_custarchives";

        public const string cre_客户物料信用档案 = "cre_custmaterialarchive";

        public const string cre_信用评估模型 = "cre_evalmodel";

        public const string cre_信用评估指标 = "cre_evaluateindex";

        public const string cre_信用等级方案 = "cre_gade";

        public const string cre_信用评分表 = "cre_scoringtable";

        public const string cre_信用特批权限 = "cre_specpermission";

        public const string cre_临时信用档案 = "cre_tmpcustarchives";


        #endregion

        #region 供应链 库存管理

        public const string bd_归档序列号 = "bd_archivedserial";

        public const string bd_批号主档 = "bd_batchmainfile";

        public const string bd_批号_序列号属性 = "bd_lotcodeitem";

        public const string bd_批号_序列号编码规则 = "bd_lotcoderule";

        public const string bd_生产追溯序列号主档 = "bd_mtserialmainfile";

        public const string bd_序列号主档 = "bd_serialmainfile";

        public const string bd_仓库 = "bd_stock";

        public const string bd_仓库最大最小安全库存 = "bd_stockalert";

        public const string bd_库存状态 = "bd_stockstatus";

        public const string sp_简单生成入库单 = "sp_instock";

        public const string sp_简单生成退库单 = "sp_outstock";

        public const string sp_简单生成领料单 = "sp_pickmtrl";

        public const string sp_简单生成退料单 = "sp_returnmtrl";

        public const string stk_组装拆卸单 = "stk_assembledapp";

        public const string stk_周期盘点计划 = "stk_cyclecountplan";

        public const string bd_物料周期盘点表 = "stk_cyclecounttable";

        public const string stk_即时库存 = "stk_inventory";

        public const string stk_初始库存 = "stk_invinit";

        public const string stk_库存锁库 = "stk_lockstock";

        public const string stk_锁库日志 = "stk_lockstocklog";

        public const string stk_批号调整单 = "stk_lotadjust";

        public const string stk_abc分配组 = "stk_materialabcgroup";

        public const string stk_其他入库单 = "stk_miscellaneous";

        public const string stk_其他出库单 = "stk_misdelivery";

        public const string stk_委托加工材料入库单 = "stk_oeminstock";

        public const string stk_委托加工材料退料单 = "stk_oeminstockreturn";

        public const string stk_委托加工材料收料单 = "stk_oemreceive";

        public const string stk_出库申请单 = "stk_outstockapply";

        public const string stk_形态转换单 = "stk_statusconvert";

        public const string stk_库存状态转换 = "stk_stockconvert";

        public const string stk_盘盈单 = "stk_stockcountgain";

        public const string stk_物料盘点作业 = "stk_stockcountinput";

        public const string stk_盘亏单 = "stk_stockcountloss";

        public const string stk_盘点方案 = "stk_stockcountscheme";

        public const string stk_调拨申请单 = "stk_transferapply";

        public const string stk_直接调拨单 = "stk_transferdirect";

        public const string stk_分布式调入单 = "stk_transferin";

        public const string stk_分布式调出单 = "stk_transferout";

        #endregion

        #region 供应链  组织间结算

        public const string ios_应付结算清单_物料 = "ios_apsettlement";

        public const string ios_应付结算清单_费用 = "ios_apsettlementexp";

        public const string ios_应付结算清单_资产 = "ios_apsettlementfa";

        public const string ios_应收结算清单_物料 = "ios_arsettlement";

        public const string ios_应收结算清单_费员 = "ios_arsettlementexp";

        public const string ios_应收结算清单_资产 = "ios_arsettlementfa";

        public const string ios_组织间结算价目表 = "ios_pricelist";

        public const string ios_定时结算 = "ios_schedulesettle";

        public const string ios_组织间结算关系 = "ios_settlerelation";

        public const string ios_跨组织业务类型 = "ios_transferbiztype";

        #endregion

        #region 供应链 条码管理

        public const string bd_异步生成数据 = "bd_asyncbillscandata";

        public const string bd_条码盘点清单 = "bd_barcodeinventorydata";

        public const string bd_条码属性 = "bd_barcodeitem";

        public const string bd_条码主档 = "bd_barcodemainfile";

        public const string bd_条码打印 = "bd_barcodeprint";

        public const string bd_条码规则 = "bd_barcoderule";

        public const string bd_条码扫描 = "bd_barcodescan";

        public const string bd_条码拆分 = "un_barcodesplit";

        public const string bd_物料编码解析对应表 = "un_materialmap";

        public const string bd_条码拆箱表 = "un_packaging";

        public const string bd_扫描配置 = "un_scan";

        public const string bd_扫描记录 = "un_scanrecordset";

        public const string bd_条码扫描任务 = "un_scantask";

        public const string bd_条码扫描任务生成日志 = "un_scantaskcreatelog";

        public const string bd_条码扫描任务方案 = "un_scantaskscheme";

        #endregion

        #region 供应链 供应商管理

        public const string svm_企业公告 = "svm_businessbulletin";

        public const string svm_比价单 = "svm_compareprice";

        public const string svm_询价单 = "svm_inquirybill";

        public const string svm_报价单 = "svm_quotebill";

        public const string svm_供应商角色 = "svm_role";

        public const string svm_供应商用户 = "svm_supplieruser";

        #endregion

        #region 供应链 供应商协同

        public const string scp_供应商协同条码打印 = "scp_barcodeprint";

        public const string scp_供应商协同条码扫描 = "scp_barcodescan";

        public const string scp_企业公告 = "scp_businessbulletin";

        public const string scp_询价单 = "scp_inquirybill";

        public const string scp_采购入库单 = "scp_instock";

        public const string scp_退料通知单 = "scp_mrapp";

        public const string scp_采购退料单 = "scp_mrb";

        public const string scp_应付单 = "scp_payable";

        public const string scp_采购订单变更单 = "scp_pochange";

        public const string scp_采购订单 = "scp_purchaseorder";

        public const string scp_报价单 = "scp_quotebill";

        public const string scp_送货通知单 = "scp_receivebill";

        public const string scp_供应商协同即时库存查询 = "scp_stkinventory";

        public const string scp_供应商评估报告 = "scp_supplierassresport";

        public const string scp_供应商注册资料 = "scp_supreg";

        public const string scp_供应商协同vmi消耗汇总表 = "scp_vmiconsumesum";

        #endregion

        #region 基础管理--基础资料

        public const string 关键字_智能机器人 = "bas_robotkeywords";

        public const string 消息任务_智能机器人 = "bas_robotmsgtask";

        public const string 关键字服务_智能机器人 = "bas_robotservice";

        public const string 会计政策 = "bd_acctpolicy";

        public const string 辅助属性值组合 = "bd_auxptyvalcom";

        public const string 辅助属性值 = "bd_auxptyvalue";

        public const string 银行 = "bd_bank";

        public const string 联系对象 = "bd_contactobject";

        public const string 客户 = "bd_customer";

        public const string 客户_包含非交易客户 = "bd_customer_all";

        public const string 部门 = "bd_department";

        public const string 员工 = "bd_empinfo";

        public const string 快递100物流公司 = "bd_kd100logisticscom";

        public const string 物料 = "bd_material";

        public const string 存货类别 = "bd_materialcategory";

        public const string 存货模板 = "bd_materialtemplate";

        public const string 物料单位换算 = "bd_materialunitconvert";

        public const string 员工任岗信息 = "bd_newstaff";

        public const string 业务员 = "bd_operator";

        public const string 业务组 = "bd_operatorgroupbill";

        public const string 付款条件 = "bd_paymentcondition";

        public const string 岗位汇报 = "bd_postreport";

        public const string 收款条件 = "bd_reccondition";

        public const string 供应商 = "bd_supplier";

        public const string 税组合 = "bd_taxmix";

        public const string 税率 = "bd_taxrate";

        public const string 税务规则 = "bd_taxrule";

        public const string 税收制度 = "bd_taxsystem";

        public const string 税种 = "bd_taxtype";

        public const string 计量单位 = "bd_unit";

        public const string 银行账号 = "cn_bankacnt";

        public const string 现金账号 = "cn_cashaccount";

        public const string 内部账户 = "cn_inneraccount";

        public const string 其他往来单位 = "fin_others";

        public const string 岗位信息 = "hr_org_hrpost";

        #endregion

        #region 基础管理--组织管理

        public const string 组织隶属关系 = "org_affiliation";

        public const string 分配执行情况 = "org_autoallocateloginfo";

        public const string 基础资料自动分配计划 = "org_autoallocateplan";

        public const string 基础资料控制策略 = "org_basedatacontrolpolicy";

        public const string 组织业务关系 = "org_bizrelation";

        public const string 组织变更检查规则 = "org_changechkrule";

        public const string 组织变更方案 = "org_changesolution";

        public const string 组织机构 = "org_organizations";

        public const string 组织形态 = "org_orgbodyform";

        public const string 组织用户维护 = "org_orguserrolemap";

        #endregion
    }

 2.查询字段集合

fieldkeys为要查询的字段key集合,如我需要查询的字段有fname,fnumber等,详细的字段说明可以通过保存接口查看

那么我们只需要传入fname,fnumber即可。

3.返回结果的处理

返回的结果是个数组类型,所以我们无法直接通过.net序列化为对象,所以建议是直接序列化为jarry数组,然后进行取值。

三. .netcore对接处理

3.1登录以及业务接口处理

有了以上的对接参数和简单的接口信息了解之后,我们就可以开始我们的api接口对接工作了,

首先,在社区一位大佬封装的webapi的基础上,我们来处理.netcore环境下的webapi接口,非常感谢大佬,我们可以看到封装的接口文件如下图所示:

.NetCore对接各大财务软件凭证API——金蝶系列

 

常用的有query、batchsave类,如下图所示

query操作

    /// <summary>
    /// 执行查询操作。
    /// </summary>
    public class query : formoperation
    {
        #region 公共覆盖操作参数

        /// <summary>
        /// 操作的服务名称定义。
        /// </summary>
        public override string servicename
        {
            get
            {
                return "kingdee.bos.webapi.servicesstub.dynamicformservice.executebillquery";
            }
        }//end property

        /// <summary>
        /// 操作的请求参数。
        /// </summary>
        public override string requestparameters
        {
            get
            {
                var parametersarray = new object[]
                {
                    new 
                    {
                        formid = this.objecttypeid,
                        toprowcount = this.toprowcount,
                        limit = this.pagerowcount == default(int) ? 2000 : this.pagerowcount,
                        startrow = this.pageindex,
                        filterstring = this.filter,
                        orderstring = this.orderby,
                        fieldkeys = string.join(",", this.fieldkeys)
                    }
                };

                return jsonconvert.serializeobject(parametersarray);
            }
        }//end property

        #endregion

        #region 公共操作参数属性

        /// <summary>
        /// 读写最多允许查询的数量属性值。
        /// </summary>
        /// <remarks>
        /// 0或者不要此属性表示不限制。
        /// </remarks>
        public virtual int toprowcount { get; set; }//end property

        /// <summary>
        /// 读写分页取数每页允许获取的数据属性值。
        /// </summary>
        /// <remarks>
        /// 最大不能超过2000。
        /// </remarks>
        public virtual int pagerowcount { get; set; }//end property

        /// <summary>
        /// 读写分页取数开始行索引属性值。
        /// </summary>
        /// <remarks>
        /// 从0开始,例如每页10行数据,第2页开始是10,第3页开始是20,以此类推,当不提供此属性,表示仅查询limit中填写的数据量。
        /// </remarks>
        public virtual int pageindex { get; set; }//end property

        /// <summary>
        /// 读写过滤条件属性值。
        /// </summary>
        public virtual string filter { get; set; }//end property

        /// <summary>
        /// 读写排序条件属性值。
        /// </summary>
        public virtual string orderby { get; set; }//end property

        /// <summary>
        /// 读写表单返回数据字段的索引键属性值。
        /// </summary>
        public virtual list<string> fieldkeys { get; set; }//end property

        #endregion

        #region 公共方法

        /// <summary>
        /// 设置读写动态表单类型标识。
        /// </summary>
        /// <param name="objecttypeid">动态表单类型标识。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual query setobjecttypeid(string objecttypeid)
        {
            return this.setobjecttypeid<query>(objecttypeid);
        }//end method

        /// <summary>
        /// 设置最多允许查询的单据数量。
        /// </summary>
        /// <param name="toprowcount">单据数量值。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual query settoprowcount(int toprowcount)
        {
            this.toprowcount = toprowcount;
            return this;
        }//end method

        /// <summary>
        /// 设置分页取数每页允许获取的单据数量。
        /// </summary>
        /// <param name="pagerowcount">分页数量值。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual query setpagerowcount(int pagerowcount)
        {
            this.pagerowcount = pagerowcount;
            return this;
        }//end method

        /// <summary>
        /// 设置分页取数开始行索引。
        /// </summary>
        /// <param name="pageindex">索引值。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual query setpageindex(int pageindex)
        {
            this.pageindex = pageindex;
            return this;
        }//end method

        /// <summary>
        /// 设置过滤条件。
        /// </summary>
        /// <param name="filter">过滤条件。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual query setfilter(string filter)
        {
            this.filter = filter;
            return this;
        }//end method

        /// <summary>
        /// 设置排序条件。
        /// </summary>
        /// <param name="orderby">排序条件。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual query setorderby(string orderby)
        {
            this.orderby = orderby;
            return this;
        }//end method

        /// <summary>
        /// 表单返回数据字段。
        /// </summary>
        /// <param name="fieldkey">字段索引键。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual query addfieldkey(string fieldkey)
        {
            if (this.fieldkeys == null)
            {
                this.fieldkeys = new list<string>();
            }//end if

            this.fieldkeys.add(fieldkey);
            return this;
        }//end method

        #endregion

    }//end class

batchsave操作,主要用于凭证的批量保存

    /// <summary>
    /// 执行批量保存操作。
    /// </summary>
    public class batchsave : save
    {
        #region 公共覆盖操作参数

        /// <summary>
        /// 操作的服务名称定义。
        /// </summary>
        public override string servicename
        {
            get
            {
                return "kingdee.bos.webapi.servicesstub.dynamicformservice.batchsave";
            }
        }//end property

        /// <summary>
        /// 待保存的数据对象。
        /// </summary>
        public override string requestparameters
        {
            get
            {
                var parametersarray = new object[]{
                    this.objecttypeid,
                    new
                    {
                        creator = string.isnullorempty(this.creator) ? "it" : this.creator ,
                        needupdatefields = this.needupdatefieldkeys,
                        needreturnfieldkeys=this.needreturnfieldkeys,
                        model = this.models,
                        isentrybatchfill=this.isentrybatchfill,
                        isdeleteentry = this.isdeleteentry,
                        subsystemid = this.subsystemid,
                        isautosubmitandaudit=this.isautosubmitandaudit,
                        isverifybasedatafield = this.isverifybasedatafield,
                        numbersearch = (this.bdsetter == basedatasetter.number),
                        batchcount=this.batchcount
                    }
                };

                return jsonconvert.serializeobject(parametersarray);
            }
        }//end property

        #endregion

        #region 公共操作参数属性

        /// <summary>
        /// 读写待保存的数据对象。
        /// </summary>
        public override object model
        {
            get
            {
                return this.models == null ? null : this.models.firstordefault();
            }
            set
            {
                if (this.models == null)
                {
                    this.models = new list<object>();
                }//end if
                this.models.add(value);
            }
        }//end property

        /// <summary>
        /// 读写待保存的多个数据对象。
        /// </summary>
        public virtual list<object> models { get; set; }//end property

        /// <summary>
        /// 是否批量填充分录。
        /// </summary>
        public virtual bool isentrybatchfill { get; set; }//end property

        public virtual bool isautosubmitandaudit { get; set; }
        public virtual int batchcount { get; set; }

        #endregion

        #region 公共方法

        /// <summary>
        /// 添加待保存的数据对象。
        /// </summary>
        /// <param name="model">待保存的数据对象。</param>
        /// <returns>返回类本身实例对象。</returns>
        public virtual batchsave addmodel(object model)
        {
            if (this.models == null)
            {
                this.models = new list<object>();
            }//end if
            this.models.add(model);
            return this;
        }//end method

        /// <summary>
        /// 设置待保存的数据对象,但无论执行多少次只会保留最后一次设置的数据对象。
        /// </summary>
        /// <param name="model">待保存的数据对象。</param>
        /// <returns>返回类本身实例对象。</returns>
        new public virtual batchsave setmodel(object model)
        {
            return this.setmodel<batchsave>(model);
        }//end method

        #endregion

    }//end class

 然后我们来看apiexception类,可以看到该异常处理类统一继承自kingdee.bos.webapi.client.serviceexception.

.NetCore对接各大财务软件凭证API——金蝶系列

所以我们要引用 kingdee.bos.webapi.client.dll

另外这里官网给的代码示例中有句话很值得重视:// 使用webapi引用组件kingdee.bos.webapi.client.dll

这个组件我们可以在金蝶的安装目录下找到,当你兴致勃勃的找到这个dll,并将它引用到你的.netcore的项目中时,编译运行你会发现有个serviceexception类在.netcore环境下不支持,因为它仅在.net framework支持。

所以呢,我们的第一反应是这可咋办,别着急,我们总有办法解决,反编译应该是我们在开发过程中比较常见的解决问题的办法,所以当我们将上述的dll进行反编译以后,我们可以得到如下一堆文件

.NetCore对接各大财务软件凭证API——金蝶系列

 

接着我们就可以来处理我们的接口了,按照示例代码中的一样,我们来实现登录接口

/// <summary>
/// 实现登录。
/// </summary>
/// <returns>返回api结果。</returns>
public virtual apiresponse<loginresult> login()
{
var result = apiclient.createapioperation<loginbyuserpassword>(_config.url)
.setdbid(_config.dbid)
.setusername(_config.username)
.setpassword(_config.password)
.tokdapirequest()
.toapiresponse<loginresult>();
return result;
}

_config.url---对应我们的金蝶财务环境的登录地址

_config.dbid--对应我们要操作的账套号---怎么查看到这个账套号是多少呢?还记得我们上面说的那个webapi菜单嘛,没错就是那里。我们随便点开一个菜单,比如我这里以科目为例,我们选中科目后,点击在线测试webapi按钮,就能找到我们所需的各自参数了。

.NetCore对接各大财务软件凭证API——金蝶系列

_config.username --登录的用户名

_config.password -- 登录的用户名的密码

这四个参数就对应我们登录接口的四个参数。

要注意的一点是我们在调用我们的业务接口时,必须先调用登录接口以实现登录操作。不然无法操作我们的业务接口。

        /// <summary>
        /// 查询人民币币别编码
        /// </summary>
        /// <returns></returns>
        public string querycurrency()
        {
            this.login();
            var result = apiclient.createapioperation<query>(_config.url)
                .setobjecttypeid(billkeyconst.币别)
                .addfieldkey("fnumber")
                .addfieldkey("fname")
                .setfilter("fname like '%人民币%'")
                .toapirequest<kdapirequest>().execute<jarray>();
            if (result.count > 0)
            {
                return result[0][0].tostring();
            }
            else
            {
                return "";
            }
        }

如我们上图所示的查询人民币的名称和编码。当然这只是查询单个实体,当我们查询所有的数据时,就可能会用到分页查询,因为金蝶的查询接口默认一次查询2000条数据,所以当总数量超过2000时,我们就需要用到分页查询了。

       public string querybasicinfobypagelist(string typeid, string fieldname, string filter, int pageindex)
        {
            this.login();
            var result = apiclient.createapioperation<query>(_config.url)
                .setobjecttypeid(typeid)
                .addfieldkey(fieldname)
                .setfilter(filter)
                .setpageindex(pageindex)
                .toapirequest<kdapirequest>().execute<string>();
            return result;
        }

只需要在原有的基础上,增加pageindex-页码参数即可,不过要注意的是每次查询的起始页码是不一样的,这样才能通过循环来得到我们需要的列表数据。

3.2 凭证保存接口

        /// <summary>
        /// 批量保存单据实体
        /// </summary>
        /// <param name="typeid"></param>
        /// <param name="models"></param>
        /// <returns></returns>
        public string batchsave(string typeid, list<object> models)
        {
            this.login();
            var client = apiclient.createapioperation<batchsave>(_config.url);
            client.setobjecttypeid(typeid);
            client.models = models;
            return client.toapirequest<kdapirequest>().execute<string>();
        }

凭证批量保存接口,所以当我们在外部构造好凭证实体后,就可直接通过该接口来处理凭证的保存工作。凭证保存实体如下cloudsavevouchermodel

  public class cloudsavevouchermodel
    {
        public string fvoucherid { get; set; }
        public fvouchernumber faccountbookid { get; set; }
        public string fdate { get; set; }
        public fvouchernumber fvouchergroupid { get; set; }
        public string fvouchergroupno { get; set; }
        public string fisadjustvoucher { get; set; }
        public string fdocumentstatus { get; set; }
        public string fyear { get; set; }
        public fvouchernumber fsourcebillkey { get; set; }
        public string fperiod { get; set; }
        public string fimportversion { get; set; }
        public fentity[] fentity { get; set; }
    }
    public class fvouchernumber
    {
        public string fnumber { get; set; }
    }
    public class fentity
    {
        public string fentryid { get; set; }
        public string fexplanation { get; set; }
        public fvouchernumber faccountid { get; set; }
        public fdetailid fdetailid { get; set; }
        public fvouchernumber fcurrencyid { get; set; }
        public fvouchernumber fexchangeratetype { get; set; }
        public string fexchangerate { get; set; }
        public fvouchernumber funitid { get; set; }
        public string fprice { get; set; }
        public string fqty { get; set; }
        public decimal famountfor { get; set; }
        public decimal fdebit { get; set; }
        public decimal fcredit { get; set; }
        public fvouchernumber fsettletypeid { get; set; }
        public string fsettleno { get; set; }
        public string fexportentryid { get; set; }
    }
    public class fdetailid
    {
        /// <summary>
        /// 费用项目
        /// </summary>
        public fvouchernumber fdetailid__fflex9 { get; set; }
        /// <summary>
        /// 供应商
        /// </summary>
        public fvouchernumber fdetailid__fflex4 { get; set; }
        public fvouchernumber fdetailid__fflex5 { get; set; }
        /// <summary>
        /// 客户
        /// </summary>
        public fvouchernumber fdetailid__fflex6 { get; set; }
        /// <summary>
        /// 员工
        /// </summary>
        public fvouchernumber fdetailid__fflex7 { get; set; }
        /// <summary>
        /// 物料
        /// </summary>
        public fvouchernumber fdetailid__fflex8 { get; set; }
        /// <summary>
        /// 资产类别
        /// </summary>
        public fvouchernumber fdetailid__fflex10 { get; set; }
        /// <summary>
        /// 组织机构
        /// </summary>
        public fvouchernumber fdetailid__fflex11 { get; set; }
        /// <summary>
        /// 物料分组
        /// </summary>
        public fvouchernumber fdetailid__ff100005 { get; set; }
        public fvouchernumber fdetailid__fflex12 { get; set; }
        public fvouchernumber fdetailid__fflex13 { get; set; }
    }

通过前面的batchsave类,我们可以看到有个属性叫做needreturnfieldkeys -- 意为需要返回的字段,等于是在执行成功保存操作后,金蝶可以直接将我们需要返回的字段返回回来,传递形式还是和查询的fieldskey格式一样,但是在实际的开发过程中我发现其实即便你传了needreturnfieldkeys,但是在返回值中并没有正常返回。我曾经在论坛里找个该问题,发现有小伙伴也遇到同样的问题。但是都没有得到解决,因为我在实际的逻辑中还需要得到类似总金额,凭证日期,凭证号等字段,所以没办法只能通过查询接口再执行一次查询操作了,当然不涉及后续的业务处理的话,可以不用执行该步骤的。

ps:当你执行批量保存操作时,如果一次操作的json数据量过大时,接口提示操作超时,所以在实际开发中建议可以分批次进行保存操作。

四.结语

相对来说,k3cloud的接口文档还是比较全面的,所以当时在实际开发的时候,并没有遇到很多坑,只是在api封装的过程中,如上述说到的.netcore环境不支持的情况,这样的话通过反编译来处理问题也是一个不错的办法。后续我们还会在处理用友的一个产品时同样使用反编译来处理问题。

以上就是自己在实际生产过程中处理k3cloudapi接口时的一些想法和思路。比如金蝶社区,论坛是不错的选择。同样qq群也是一个沟通交流的途径。比如上面说到的批量保存时json串过大导致接口操作超时的问题,就是通过群里一个小伙伴的提醒,改变了思路通过分批传递的方法来解决问题的。我想说的是在开发过程中我们会遇到各种各样的问题,但是通过解决这些问题我们就能得到锻炼和成长,这就是我们的财富。说实话在之前我从没接触过这些知识点和业务范围,但是这不是也是一种成长的方式嘛。希望可以给在开发对接此产品的小伙伴一点帮助,一点支持就够了。

附上本文中的示例代码:k3cloud接口

转自:https://www.cnblogs.com/wnxyz8023/p/12791899.html