K/3 Cloud 技术开发培训 ----BOS 业务插件开发 注:云图标可根据标题长度适度调整移动,以标题右上角,与标题上、右均等距离7个像素为标准。
课程说明: 课程简介: 本课程介绍K/3 Cloud BOS 业务插件的开发及配置,以功能讲解辅之案例演练帮助学员快速掌握K/3 Cloud BOS平台的核心功能。
目录 概述 业务插件概览 如何开发插件 案例演练
目录 概述 业务插件概览 如何开发插件 案例演练
K/3 Cloud 分层架构图 Http Http 展示层 服务层 动 态 表 单 元 数 内核层 据 扩展逻辑层 Silverlight Web客户端 WPF 桌面客户端 Office客户端 移动客户端 客户端公共编程模型+客户端插件+第三方设备集成接口 Http Http 服务层 动 态 表 单 元 数 据 Web 服 务 器 动态表单UI生成服务 动态表单控制服务 业务服务 内核层 表单动态生成引擎 动态表单控制器 动态表单视图模型 动态表单数据模型 动态表单编程接口 扩展逻辑层 表单生成插件 表单逻辑服务 表单操作 缺省值计算函数 业务插件 应用服务 器 动态表单逻辑组件 动态表单服务端编程接口 动态表单服务端插件 校验规则 数据库服务器 元数据 业务数据
目录 概述 业务插件概览 如何开发插件 案例演练
BOS业务插件开发概览 BOS业务插件用以解决什么问题? 有哪些插件? 标准业务对象的的业务逻辑应用: 客户二次开发的需求; Web层 标准业务对象没有实现的控制; 已有操作和服务未支持的功能; 更灵活的控制方式和客户化定制; 客户二次开发的需求; 快速开发、快速实施、快速应用; 可配置,可测试,快速部署; 有哪些插件? Web层 表单插件 列表插件 表单构建插件 App层 服务插件 什么时候用插件:实体服务规则/值更新事件/配置服务无法满足需要时,才采用插件二次开发
BOS业务插件开发概览 插件接口特性 支持插件顺序 支持动态语言 使用C# 4.0 支持继承和扩展 已封装业务插件; 组织控制; 基础资料分配 ……… 支持插件顺序 支持动态语言 IronPython 2.6.1
BOS业务插件开发概览—插件分类 表单插件 用于单个表单编辑界面 运行于Web层 列表插件 用于列表
BOS业务插件开发概览 – 插件分类 服务插件 插件配置入口 操作列表 – 编辑操作 挂在操作上的服务插件,对于操作进行扩展 和校验器配合使用 运行于App层 插件配置入口 操作列表 – 编辑操作
BOS业务插件开发概览 – 插件分类 表单构建插件 对于表单界面进行自定义的插件 运行于Web层 自定义菜单、控件
BOS业务插件开发概览 动态表单元数据结构
BOS业务插件开发概览 动态表单元数据结构
目录 概述 业务插件概览 如何开发插件 接口结构 插件中常用的对象说明 具体的代码示例 案例演练
目录 概述 业务插件概览 如何开发插件 接口结构 插件中常用的对象说明 具体的代码示例 案例演练
如何开发插件 – 接口结构 表单插件和列表插件 继承层次 表单 单据 单据列表 基础资料 插件针对对象 动态表单
如何开发插件 – 接口结构 AbstractBillPlugIn 接口 动态表单视图插件编程模型接口 定义了视图模型扩展 允许通过接口处理视图,实现特定业务需求
AbstractBillPlugIn的ViewPlugin插件接口 如何开发插件 – 接口结构 AbstractBillPlugIn的ViewPlugin插件接口 OnBillInitialize 视图模型初始化事件 AfterBindData 绑定数据后事件处理接口 BeforeF7Select 基础资料弹出前事件 BeforeClosed 窗口关闭前事件
AbstractBillPlugIn的ViewPlugin插件接口 如何开发插件 – 接口结构 AbstractBillPlugIn的ViewPlugin插件接口 BarItemClick 菜单单击事件处理扩展接口 AfterBarItemClick 菜单单击事件后 BeforeDoOperation 操作调用前事件 AfterDoOperation 操作调用完成后事件 ButtonClick 按钮单击事件 AfterButtonClick 按钮单击后事件
AbstractBillPlugIn的ViewPlugin插件接口 如何开发插件 – 接口结构 AbstractBillPlugIn的ViewPlugin插件接口 ListViewClick 列表项目单击事件 TreeNodeClick 树控件单击事件 TreeDragDrop 树控件拖拽 EntityRowClick 分录行单击事件
AbstractBillPlugIn的ModelPlugIn接口 如何开发插件 – 接口结构 AbstractBillPlugIn的ModelPlugIn接口 动态表单数据模型插件编程接口 定义了数据模型扩展 允许通过接口处理数据,以实现特定业务需求
AbstractBillPlugIn插件方法 如何开发插件 – 接口结构 AbstractBillPlugIn插件方法 CreateNewData 数据模型创建实体对象事件 AfterCreateNewData 数据模型创建实体对象完成后事件 BeforeUpdateValue 数据更新前事件 DataChanged 数据改变后事件
AbstractBillPlugIn插件方法 如何开发插件 – 接口结构 AbstractBillPlugIn插件方法 CreateNewEntryRow 创建分录行事件 BeforeDeleteRow 删除分录行事件 AfterDeleteRow 删除分录后事件
如何开发插件 – 接口结构 列表插件接口 继承AbstractListPlugIn IListViewPlugIn IListModelPlugIn
AbstractListPlugIn 的ViewPlugIn接口 如何开发插件 – 接口结构 AbstractListPlugIn 的ViewPlugIn接口 序时簿视图插件编程模型接口 定义了序时簿视图模型扩展 允许通过接口处理视图,实现特定业务需求
AbstractListPlugIn 的ViewPlugIn接口 如何开发插件 – 接口结构 AbstractListPlugIn 的ViewPlugIn接口 ListInitialize 视图模型初始化事件 AfterGetData 完成取数后事件 FormatCellValue 列表格式化接口
AbstractListPlugIn 的ViewPlugIn接口 如何开发插件 – 接口结构 AbstractListPlugIn 的ViewPlugIn接口 BeforeButtonClick 按钮和菜单单击前事件 AfterButtonClick 按钮和菜单单击后事件 CellDbButtonClick 单元格双击事件
AbstractListPlugIn 的ModelPlugIn接口 如何开发插件 – 接口结构 AbstractListPlugIn 的ModelPlugIn接口 序时簿数据模型插件编程接口 定义了序时簿数据模型扩展 允许通过接口处理数据,以实现特定业务需求
AbstractListPlugIn插件方法 如何开发插件 – 接口结构 AbstractListPlugIn插件方法 PrepareFilterParameter 准备过滤条件 CreateFilterEditorControl 触发创建过滤条件控件事件 BatchCopyData 复制单据事件 AfterBatchCopyData 复制单据完毕事件
如何开发插件 – 接口结构 服务插件 插件特性 插件针对对象 IOperationServicePlugin 一般会附加校验器 运行于App层 事务保护 插件针对对象 操作
如何开发插件 – 接口结构 服务插件接口 服务插件 AbstractOperationServicePlugIn 应用服务器插件与业务数据更新操作在一个事务执行 校验器插件 AbstractValidator 在服务插件的OnAddValidators加入
AbstractOperationServicePlugIn插件方法 如何开发插件 – 接口结构 AbstractOperationServicePlugIn插件方法 OnPreparePropertys 可以定制加载指定字段到实体里 OnAddValidators 添加自定义数据校验器
AbstractOperationServicePlugIn插件方法 如何开发插件 – 接口结构 AbstractOperationServicePlugIn插件方法 BeforeExecuteOperationTransaction 执行操作事务前事件 AfterExecuteOperationTransaction 执行操作事务后事件 BeginOperationTransaction 调用操作事件前触发(支持事务) EndOperationTransaction 调用操作事件完毕(支持事务)
如何开发插件 – 接口结构 表单构建插件 继承层次 表单 单据 叙事簿 基础资料 插件针对对象 动态表单
AbstractDynamicWebFormBuilderPlugIn插件方法 如何开发插件 – 接口结构 AbstractDynamicWebFormBuilderPlugIn插件方法 CreateControl 构建界面元素事件 AfterCreateControl 构建界面元素后事件 CreateMainMenu 构建菜单事件 AfterCreateMainMenu 构建菜单后事件
如何开发插件 – 接口结构 表单插件调用过程 由控制器创建视图、模型、插件代理 初始化视图、模型 由插件服务注册到插件代理 插件代理初始化插件 加载数据,通知插件创建数据,创建表单数据包 表单操作 插件服务调用代理,发送事件通知 插件代理调用插件,执行事件 返回执行结果
业务插件 插件调用过程
业务插件 插件调用过程
如何开发插件 – 接口结构 动态语言支持 IronPython 脚本语言 支持和C#交互调用 事件接口和C#完全一致 更加简练明白
目录 概述 业务插件概览 如何开发插件 接口结构 插件中常用的对象说明 具体的代码示例 案例演练
如何开发插件 – 常用对象 View对象 属性 this.View(View接口) this.View的常用属性 BillBusinessInfo(界面业务对象元数据) LayoutInfo(布局元数据) Model(动态表单模型接口) OpenParameter(页面调用时传入的参数) 方法 GetFieldEditor (获取界面控件对象) ShowMessage(显示信息)
如何开发插件 – 常用对象 View对象 更改界面控件状态 this.View. GetFieldEditor 示例: /// <summary> /// 设置金额列精度 /// </summary> /// <param name="iScale"></param> /// <param name="strField"></param> private void SetColumnScale(short iScale, string strField) { this.View.GetFieldEditor<DecimalFieldEditor>(strField, -1).Scale = iScale; }
如何开发插件 – 常用对象 View对象 if (e.CurParentId == "0") { 显示信息 this.View.ShowMessage 示例: if (e.CurParentId == "0") { this.View.ShowMessage(“请先选择顶层组织。”); return; }
如何开发插件 – 常用对象 Model对象 属性 this.View.Model(动态表单模型接口) DataObject 当前对象的数据实体 方法 GetEntryCurrentRowIndex(获取分录当前行索引) GetEntryRowCount(获取分录行数量) CreateNewEntryRow(新建分录行) GetValue(获取字段(对象)值) SetValue(设置字段(对象)值)
如何开发插件 – 常用对象 Model对象 获取单据属性:例如分录集合 this.View.Model.DataObject 示例: /// <summary> /// 获取分录集合 /// </summary> DynamicObjectCollection entrys = (DynamicObjectCollection)this.View.Model.DataObject["POOrderEntry"];
如何开发插件 – 常用对象 Model对象 /// <summary> /// 单据复制完成事件 新增单据体分录行 this.View.Model.CreateNewEntryRow 示例: /// <summary> /// 单据复制完成事件 /// </summary> /// <param name="e"></param> public override void AfterCopyData(CopyDataEventArgs e) { base.AfterCopyData(e); //单据复制完,处理单据体 _billFormID = “”; this.View.Model.CreateNewEntryRow(“FFieldControl”); UpdateFieldControlRowLock(); }
如何开发插件 – 常用对象 Model对象 //获取根节点组织复制到目标节点 获取字段值 this.View.Model.GetValue 示例: //获取根节点组织复制到目标节点 Organization org = (DynamicObject) this.View.Model.GetValue("FRootORGID"); targetRoot.id = rootOrgId; targetRoot.text = org.Name.ToString(); targetRoot.children = new List<TreeNode>(); ctl = this.View.GetControl<TreeView>("FOrgTree"); ctl.SetRootNode(targetRoot);
如何开发插件 – 常用对象 Model对象 设置字段值 this.View.Model.SetValue 示例: /// <summary> /// 字段修改事件函数重载 /// </summary> public override void DataChanged(DataChangedEventArgs e) { switch (e.Key.ToUpper()) case "FPARENTDEPTID": //组织隶属方案和上级部门变化,重新生成部门全称 this.View.Model.SetValue(“FFullName”, GetFullName(e.Key)); break; }
目录 概述 业务插件概览 如何开发插件 接口结构 插件中常用的对象说明 具体的代码示例 案例演练
如何开发插件 – 代码示例 表单插件 OnBillInitialize初始化事件 BillInitializeEventArgs 示例: public override void OnBillInitialize(BillInitializeEventArgs e) { base.OnBillInitialize(e); msgType = this.View.OpenParameter.GetCustomParameter("MessageType"); }
如何开发插件 – 代码示例 表单插件 AfterBindData绑定数据后事件 示例: public override void AfterBindData(EventArgs e) { base.AfterBindData(e); DynamicObject dy = this.View.Model.GetValue("FAccountBookID") as DynamicObject; if (dy != null && !string.IsNullOrWhiteSpace(dy["Id"].ToString())) DynamicObject org = dy["AccountOrgID"] as DynamicObject; if (org != null && !string.IsNullOrWhiteSpace(org["Id"].ToString())) this.View.Model.SetValue("FACCBOOKORGID", org); }
如何开发插件 – 代码示例 表单插件 BeforeClosed绑定数据后事件 BeforeClosedEventArgs 示例: public override void BeforeClosed(BeforeClosedEventArgs e) { ReturnData(); base.BeforeClosed(e); }
如何开发插件 – 代码示例 表单插件 BeforeF7Select BeforeF7SelectEventArgs 示例: public override void BeforeF7Select(BeforeF7SelectEventArgs e) { base.BeforeF7Select(e); bool success = true; switch (e.FieldKey) case "FAccountOrg": e.ListFilterParameter.Filter = this.GetAccountOrgFilter(e.ListFilterParameter.Filter, out success); break; case "FAccountBook": e.ListFilterParameter.Filter = this.GetAccountBookFilter(e.ListFilterParameter.Filter, out success); } e.Cancel = !success;
如何开发插件 – 代码示例 表单插件 ButtonClick ButtonClickEventArgs 示例: public override void ButtonClick(ButtonClickEventArgs e) { base.ButtonClick(e); switch (e.Key) case "FBtOK": this.StartDeposit(); break; default: }
如何开发插件 – 代码示例 表单插件 DataChanged DataChangedEventArgs 示例: public override void DataChanged(DataChangedEventArgs e) { switch (e.Key) case "fdiffadjusttype": case "fexpuniontype": SetEnableAndValue(); break; default: } base.DataChanged(e);
如何开发插件 – 代码示例 动态语言支持 IronPython 示例: from System import StringComparison def DataChanged(e): if e.Field.Key.Equals("FIsTrans", StringComparison.OrdinalIgnoreCase): # isTrans = clr.Reference[bool]() isTrans = e.NewValue if isTrans == False : this.View.Model.SetValue("FPriority", 0)
如何开发插件 – 代码示例 服务插件 OnPreparePropertys PreparePropertysEventArgs 示例: public override void OnPreparePropertys(PreparePropertysEventArgs e) { e.FieldKeys.Add("FAccountSystemEntry"); e.FieldKeys.Add("FMainOrgId"); e.FieldKeys.Add("FAcctPolicy"); e.FieldKeys.Add("FDefAcctPolicy"); base.OnPreparePropertys(e); }
如何开发插件 – 代码示例 服务插件 OnAddValidators AddValidatorsEventArgs 示例: public override void OnAddValidators(AddValidatorsEventArgs e) { SaveValidator saveValid = new SaveValidator(); saveValid.EntityKey = "FBillHead"; e.Validators.Add(saveValid); SaveAuditValidator saveAcctValid = new SaveAuditValidator(); saveAcctValid.option = this.Option; saveAcctValid.EntityKey = "FBillHead"; e.Validators.Add(saveAcctValid); }
如何开发插件 – 代码示例 private class SaveValidator : AbstractValidator { public override void Validate(ExtendedDataEntity[] dataEntities, ValidateContext validateContext, Context ctx) foreach (var acct in dataEntities) AccountSystem dEntity = (AccountSystem)acct.DataEntity; if (dEntity == null) continue; foreach (var acctSys in dEntity.AccountSystemEntrys) if (acctSys == null || acctSys.MainOrgId <= 0) continue; if (!acctSys.AccountSystemDetails.Any(p => p != null && p.SubOrgId > 0)) ValidationErrorInfo errorInfo = new ValidationErrorInfo("", dEntity.Id.ToString(), acct.DataEntityIndex, acct.DataEntityIndex, "BD", string.Format("核算组织【{0}】的下级组织不允许为空。", acctSys.MainOrgName.ToString()), string.Format("{0}【{1}】", dEntity.Name.ToString(), dEntity.Number)); validateContext.AddError(null, errorInfo); }
如何开发插件 – 代码示例 表单构建插件 CreateControl事件 CreateControlEventArgs 示例: public override void CreateControl(CreateControlEventArgs e) { if (e.ControlAppearance.Key.EqualsIgnoreCase("FORGID")) if (this.Context.IsMultiOrg == false) e.Control.Put("visible", 0); } base.CreateControl(e);
如何开发插件 – 接口结构 表单插件
业务插件 列表插件
目录 概述 业务插件概览 如何开发插件 案例演练
案例演练 业务插件开发 建立部门基础资料 增加部门全名(带上级部门前缀,以点分隔) 部门隶属关系变化后需要修改部门全名前缀 建立员工基础资料 增加禁用状态,不能在界面上用复制功能复制禁用员工