电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

纯代码生成基础资料/单据

来源:金蝶云社区作者:金蝶2024-09-165

纯代码生成基础资料/单据

场景:

1、客户第三方数据保存到中间表,需要从中间表读取数据写入到星空公有云;

2、客户有2个基础资料、12张单据的数据需要同步到星空系统;

3、客户一个月的数据量大概80万条记录(单据比较特殊,只有表头信息),其中有一大半是在月底一次性同步;


开发思路:


开发方案标题优点缺点
方案一后台直接写数据库性能最优如果单据上后续调整计算逻辑,需要修改插件代码
方案二(本示例方案)建立模型调用单据保存方法单据计算逻辑可以自适应,保存逻辑调整也可以自适应性能没直接写数据库快
方案三调用API接口进行保存(未尝试)(未尝试)


性能测试结果(开启5线程):

序号流程名称表记录基数同步记录数耗时(秒)平均(秒)
1
基础资料(新增或更新)
3118610.0196
2单据(只新增)1600万38412936270.0094
3单据(只新增)几十万
3739695320.0014
4

单据(判断原单据不存在则新增)

2021-08-03更新

一百多万415860
48600.0117


详细插件代码示例:


1、引用(不是所有必须的,先使用后删除不需要的就行)

using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Core.Validation;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;


2、保存一张单据的入口函数,

        /// <summary>
        /// 根据业务对象类型
        /// </summary>
        /// <param name="ctx">星空上下文</param>
        /// <param name="objectTypeId">单据类型,该参数非必要,根据客户需求增加用作区分不同单据的处理</param>
        /// <param name="mySqlDR">数据集,该参数非必要,本例是对接mySql,结合单据类型在后面填充字段值时使用</param>
        /// <param name="PkValue">单据ID值,该参数非必要,外面读取单据是否已经存在</param>
        /// <param name="strErrorList">收集错误信息,该参数非必要,根据开发设计用作日志记录</param>
        /// <param name="FillBillPropertys">做了个填充字段值的方法指针</param>
        public void ImportBill(Context ctx, string objectTypeId, MySqlDataReader mySqlDR, Object PkValue, ref List<string> strErrorList, Action<IBillView, string, MySqlDataReader, List<string>> FillBillPropertys)
        {

            try
            {

                // 构建一个IBillView实例,通过此实例,可以方便的填写业务对象各属性
                IBillView billView = CreateBillView(ctx, objectTypeId, PkValue,ref strErrorList);

                if (billView == null)
                {
                    strErrorList.Add("构建一个IBillView实例出现异常,请再尝试一次同步。");
                    return;
                }

                // 新建一个空白实例
                ((IBillViewService)billView).LoadData();

                // 触发插件的OnLoad事件:
                // 组织控制基类插件,在OnLoad事件中,对主业务组织改变是否提示选项进行初始化。
                // 如果不触发OnLoad事件,会导致主业务组织赋值不成功
                DynamicFormViewPlugInProxy eventProxy = billView.GetService<DynamicFormViewPlugInProxy>();
                eventProxy.FireOnLoad();

                // 填写业务对象实例各属性
                FillBillPropertys(billView, objectTypeId, mySqlDR, strErrorList);
                //同步赋值有问题,就直接退出
                if (strErrorList.Count > 0)
                {
                    return;
                }

                // 保存业务对象实例
                List<ValidationErrorInfo> errorList = new List<ValidationErrorInfo>();
                SaveBill(ctx, billView, OperateOption.Create(), out errorList);

                foreach (ValidationErrorInfo item in errorList)
                {
                    strErrorList.Add(item.Message);
                }

            }
            catch (Exception ex)
            {
                strErrorList.Add(ex.Message);
            }
        }

3、创建单据视图(该方法基本不用调整)

        /// <summary>
        /// 创建一个单据视图,后续将利用此视图的各种方法,设置业务对象字段值
        /// </summary>
        /// <remarks>
        /// 理论上,也可以直接修改业务对象的数据包达成修改数据的目的
        /// 但是,利用单据视图更具有优势:
        /// 1. 视图会自动触发插件,这样逻辑更加完整;
        /// 2. 视图会自动利用单据元数据,填写字段默认值,不用担心字段值不符合逻辑;
        /// 3. 字段改动,会触发实体服务规则;
        /// 
        /// 而手工修改数据包的方式,所有的字段值均需要自行填写,非常麻烦
        /// </remarks>
        private IBillView CreateBillView(Context ctx, string objectTypeId, object PkValue, ref List<string> strErrorList)
        {
            try
            {

                // 读取业务对象的元数据
                FormMetadata meta = MetaDataServiceHelper.Load(ctx, objectTypeId) as FormMetadata;

                //业务对象整体信息
                Form form = meta.BusinessInfo.GetForm();
                // 动态领域模型服务提供类,通过此类,构建MVC实例
                var provider = form.GetFormServiceProvider();

                // 创建用于引入数据的单据view
                Type type = Type.GetType("Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web");
                var billView = (IDynamicFormViewService)Activator.CreateInstance(type);

                // 开始初始化billView:
                // 创建视图加载参数对象,指定各种参数,如FormId, 视图(LayoutId)等
                BillOpenParameter openParam = CreateOpenParameter(ctx, meta, PkValue);
                if (openParam == null)
                {
                    return null;
                }
                billView.Initialize(openParam, provider);
                return billView as IBillView;
            }
            catch (Exception ex)
            {
                strErrorList.Add(ex.Message);
                return null;
            }
        }

4、创建视图加载参数对象(该方法基本不用调整)

        /// <summary>
        /// 创建视图加载参数对象,指定各种初始化视图时,需要指定的属性
        /// </summary>
        /// <param name="meta">元数据</param>
        /// <returns>视图加载参数对象</returns>
        private BillOpenParameter CreateOpenParameter(Context ctx, FormMetadata meta, object PkValue)
        {

            try
            {


                Form form = meta.BusinessInfo.GetForm();
                // 指定FormId, LayoutId
                BillOpenParameter openParam = new BillOpenParameter(form.Id, meta.GetLayoutInfo().Id);
                // 数据库上下文
                openParam.Context = ctx;
                // 本单据模型使用的MVC框架
                openParam.ServiceName = form.FormServiceName;
                // 随机产生一个不重复的PageId,作为视图的标识
                openParam.PageId = Guid.NewGuid().ToString();
                // 元数据
                openParam.FormMetaData = meta;

                // 界面状态:新增 (修改、查看)
                openParam.Status = OperationStatus.ADDNEW;
                openParam.PkValue = null;
                // 单据主键
                if (PkValue != null && Convert.ToInt64(PkValue) > 0)
                {
                    openParam.PkValue = PkValue;
                    openParam.Status = OperationStatus.EDIT;
                }

                // 界面创建目的:普通无特殊目的 (为工作流、为下推、为复制等)
                openParam.CreateFrom = CreateFrom.Default;
                // 基础资料分组维度:基础资料允许添加多个分组字段,每个分组字段会有一个分组维度
                // 具体分组维度Id,请参阅 form.FormGroups 属性
                openParam.GroupId = "";
                // 基础资料分组:如果需要为新建的基础资料指定所在分组,请设置此属性
                openParam.ParentId = 0;
                // 单据类型
                openParam.DefaultBillTypeId = "";
                // 业务流程
                openParam.DefaultBusinessFlowId = "";
                // 主业务组织改变时,不用弹出提示界面
                openParam.SetCustomParameter("ShowConfirmDialogWhenChangeOrg", false);
                // 插件
                List<AbstractDynamicFormPlugIn> plugs = form.CreateFormPlugIns();
                openParam.SetCustomParameter(FormConst.PlugIns, plugs);
                PreOpenFormEventArgs args = new PreOpenFormEventArgs(ctx, openParam);
                //foreach (var plug in plugs)
                //{// 触发插件PreOpenForm事件,供插件确认是否允许打开界面
                //    plug.PreOpenForm(args);
                //}
                if (args.Cancel == true)
                {// 插件不允许打开界面
                 // 本案例不理会插件的诉求,继续....
                }
                // 返回
                return openParam;
            }
            catch (Exception)
            {
                return null;
            }
        }

5、给业务对象各属性赋值,根据不同的业务对象类型(自定义的),分别调用不同方法,方便管理

        /// <summary>
        /// 各属性赋值,填写到IBillView当前所管理的业务对象
        /// </summary>
        /// <param name="billView"></param>
        private static void FillBillPropertys(IBillView billView, string objectTypeId, MySqlDataReader mySqlDR, List<string> strErrorList)
        {

            switch (objectTypeId)
            {
                case "xxx":
                    {
                        FillBillPropertys_xxx(billView, objectTypeId, mySqlDR, strErrorList);
                    }
                    break;
                case "yyy":
                case "zzz":
                case "PSEA_PurAdvance_buffet":
                    {
                        FillBillPropertys_yyyzzz(billView, objectTypeId, mySqlDR, strErrorList);
                    }
                    break;
                default:
                    break;
            }


            #region 赋值示例

            //基础资料:填写ID或者编码
            //dynamicObject = this.View.Model.GetValue("F_ZHMS_OrgId") as DynamicObject;
            //setValue = Convert.ToString(dynamicObject["Number"]);
            //dynamicFormView.SetItemValueByID("FCreateOrgId", 1, 0)
            //dynamicFormView.SetItemValueByNumber("FCreateOrgId", "1", 0)

            //辅助资料:填写编码
            //dynamicObject = this.View.Model.GetValue("F_ZHMS_TaxType") as DynamicObject;
            //setValue = Convert.ToString(dynamicObject["FNumber"]);
            //dynamicFormView.SetItemValueByNumber("FTaxType", setValue, 0);

            //分组:填写编码
            //dynamicObject = this.View.Model.GetValue("F_ZHMS_MaterialGroup") as DynamicObject;
            //setValue = Convert.ToString(dynamicObject["Number"]);
            //dynamicFormView.UpdateValue("FMaterialGroup", 0, setValue);

            //文本:填写内容
            //setValue = Convert.ToString(this.View.Model.GetValue("FDescription", thisRowIndex));
            //dynamicFormView.UpdateValue("FDescription", 0, "描述(JD-001)");

            // 下拉列

纯代码生成基础资料/单据

场景:1、客户第三方数据保存到中间表,需要从中间表读取数据写入到星空公有云;2、客户有2个基础资料、12张单据的数据需要同步到星空系统...
点击下载文档文档为doc格式

声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。

已经是第一篇
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信