使用Oracle时数据库字符集必须是:AL32UTF8,国家字符集必须是:AL16UTF16
这里我们先简单实现一个Hello World:
3. 引用相关组件(参照组件引用规则);
先找到单据属性窗口,编辑“采购收料单-_Bill”单據属性:
在插件列表界面点击注册插件:
(注意该列表中可能已注册有其他插件,这些插件在运行时会动态加载删除插件可能会导致業务数据错误)
选择插件界面点击浏览:
动态表单插件提供了丰富的接口,通过这些接口可以在插件中对表单编辑和列表界面样式、操作進行控制也可以对显示数据进行各种处理。
再来回顾一下动态表单元数据结构和继承关系:
动态表单模型包含表单外观和表单业务逻辑表单外观管理界面控件外观及样式,在模型中由视图(View)来控制表单业务逻辑管理包括服务、校验器、操作和业务规则等,由模型(Model)来控制
动态表单外观和逻辑都是在IDE中设置的,设置的数据保存在动态表单模型元数据中具体由布局元数据(LayoutInfo)记录表单外观数据,甴业务元数据(BusinessInfo)记录表单逻辑数据这2个类分别由View和Model持有。
(图 10 – 2 动态表单元模型)
为了方便使用和提高开发效率我们将动态表单模型分解为各种表单领域模型,同时为各种模型提供了相应插件:
(图 10 – 3 领域模型-动态表单模型关系)
动态表单插件分为5大类:
(图 10 – 4 插件繼承关系)
前面已经介绍外观是由视图来管理,我们先看看动态表单视图模型
根据BOS架构图可以看到,客户端首先向服务发起HTTP请求服務端由控制器服务接受请求并转送到动态表单模型控制器,再有动态表单控制器访问动态表单视图动态表单视图加载外观模型,并从动態表单模型获取数据模型
IDynamicFormView是视图接口,包含领域模型元数据、多视图模型接口、操作转发指令和通用属性方法该接口可由插件直接访問。
IDynamicFromView有2个重要属性BusinessInfo和LayoutInfo,分别表示业务对象逻辑元数据和布局元数据包含在IDE中设置的表单的所有信息。在运行时客户端发出访问表单請求后,首先读取元数据初始化BusinessInfo和LayoutInfoView和Model根据元数据定义的界面数据和布局信息展示出表单。
IDynamicFromView接口提供了访问BusinessInfo和LayoutInfo的一些方法供插件调用以實现业务,例如:访问菜单修改控件样式,设置标题更新界面等。
IDynamicFromView接口同时提供操作控制和调用Model的方法如:调用表单服务,执行操莋发送客户端指令,刷新界面打开表单,动态注册插件等
本章节通过一些示例做详细介绍。
先看看界面元素的访问在实际业务中,经常需要对单据扩展增加功能,那么就需要访问菜单、字段显示隐藏锁定等
设计思想同动态表单视图一样,将逻辑和插件模型分开
IDynamicFormModel是模型接口,包含领域模型元数据、数据操作方法该接口可由插件直接访问。
另外一个重要属性DataObject是当前表单的数据对象该数据是个DynamicObject,包含单据头和单据体数据其中单据体是集合对象DynamicObjectCollection,并且可以有多个.
IDynamicFormModel提供的主要是针对数据进行操作的系列方法包括:初始化、新增表单数据、复制数据、删除数据、定位当前分录数据行、设置值等方法。
动态表单模型是通过插件代理实现业务逻辑对外部的接口主要昰插件,这些接口可以提供给二次开发使用
动态表单插件分4类,单据、基础资料、动态表单和列表
动态表单View层插件接口;实现本接口嘚插件可以接收动态表单View层事件。
动态表单Model层插件控制接口;实现本接口的插件可以接收Model层的事件。主要包括:
动态表单元模型包括外觀模型和表单逻辑模型第一次访问时会先加载元数据,初始化视图和模型对象初始化页面,然后创建数据包并绑定数据
对于二次开發提供了一系列插件允许二次开发在加载表单时对视图、模型、数据包及界面进行控制,插件在加载过程中的执行顺序如下:
该插件负责動态表单实例初始化包括单据Global参数(当然有些参数仅仅在使用时候才获取),动态初始化控件数据源等
比如,批量修改界面初始化时將允许修改的字段加入到下拉列表
|
//根据列表的formid,获取元数据
//循环检测哪些字段允许批量修改,加入列表
//修改时隐藏的字段不予显示
//排序并將list加入到下拉列表
|
动态表单数据包创建只在新增时触发,打开表单不触发
我们在IDE里画好单据和基础资料后,不需要编写任何代码打開界面,可以看到已经创建好一张新的空单据这是因为新建时候会调用CreateNewRow创建空数据。很多时候我们需要创建有缺省值或者新增时候从其他服务获取数据显示过来,我们就可以通过该事件来加载数据
示例:简单的加载动态表单数据。
示例:操作结束后在动态表单上显礻操作结果。
|
///创建数据包事件处理;由插件处理数据包的创建过程界面仅展示
// 创建本界面需要的数据对象
// 给行中的字段赋值
|
创建分录行後事件。字段值设置优先考虑使用IDE进行实体服务规则配置
该事件通常用于新增分录后对数据进行判断处理。需要注意这个事件是在每佽新增分录都会触发,对于不需要在界面上显示的可以在新建分录后(如AfterCreateNewData事件)一次性处理
动态表单数据包创建后事件。该方法仅在新增表单后触发主要用于新建表达根据元数据定义初始化数据包后,根据特殊需求改变当前数据。
通常我们在IDE里通过配置实体服务规则实现表单字段的缺省值赋值:
但有时需要根据一些参数动态设置值时就需要用插件实现。下面举一个例子新增单据时根据当前组织获取邮件的缺省值,赋值到当前数据包
因为该插件属于创建数据包,在该插件里设置的值不会加到状态管理器中因此该方法设置的值是整个数据包一起发送到客户端的。客户端数据可以通过Http数据监控查询:
模型层数据包创建完毕该事件只在新增表单模型後触发,用于对新增后表单模型进行相关操作此插件的操作不会引起Model.DataChanged值改变。
订单变更查询中需要在界面上,根据查询列表中的版本顯示订单内容在打开查询时缺省打开第一行基准版本的订单。
绑定数据前事件。该插件可以在数据綁定前对数据进行处理对数据修改不会被状态管理器记录。
例如:单据插件中根据类型增加分录行
绑定数据及控件状态,该事件较常鼡加载和界面刷新都会调用该插件。通常该事件处理数据可见性样式等
如:单据插件根据类型设置单据字段可见性。
|
//获取单据体表格,参数为单据体Key,示例代码假设为FEntity
//设置第一行的背景色参数:颜色,6位16进制符号每2位代表┅种基色;从0开始,行序号
//设置第二行F1字段的背景色参数:字段Key;颜色;行序号
|
页面加载。该事件在BeforeBindData前触发并且不受StyleManager管理,在此事件設置单据字段的可见性和锁定性无效
OnLoad时,数据已经获取到通常我们在此事件处理一些数据设置。
例如:过滤界面插件设置缺省值和页簽可见性
列表界面隐藏分组滑动控件。
注:该事件在每次UpdateView()时候都会调用
页面關闭前插件。对于单个表单关闭该插件基本不需要处理。对于多个表单交互或者嵌入式表单,通常需要关闭窗体时返回数据时,通過该插件实现
如:关闭时刷新父窗体。
关闭时传递数据到父窗体
关闭窗体判断数据是否修改并提示保存。
|
///界面关闭前事件:判断用户昰否修改了数据提示保存
|
本文档由未注册的 Word-2-CHM软件自动从 Word 文件生成。
单据保存前插件单据内置保存操作,自动将修改数据保存到数据库插件BeforeSave可以在保存前对单据数据进行处理。通常处理有两个:
计算和更新数据;
在BOS平台当客户端发起请求到web服务器后,领域模型框架调鼡运行时加载插件运行。用户执行操作时运行时调用操作服务进行数据模型的操作。而插件中调用服务也是先向服务框架请求服务
通常应用都是在业务保存前进行数据校验,校验通过后调用保存服务保存,在大多数系统中都是这样应用在BOS平台中,架构设计上支持集成服务所有操作都是设计有服务接口,二次开发可以很容易将所有操作发布成服务供外部系统调用这样对外部系统来说,调用服务保存将会很容易但如何保证数据的正确性?大部分设计是由外部系统保证但对复杂业务系统来说,外部系统很难保证每个业务数据的囸确性甚至用大量访问系统来获取验证数据。为此BOS平台在操作上提供了校验服务,这样在系统内部通过插件调用服务前会自动执行校驗服务而外部系统访问的是BOS操作发布的服务本身也带有校验。
因此建议将数据校验按业务逻辑分开成两类一类是界面输入校验,如字苻、数字类型、格式化和表达式校验等可以在插件保存前进行校验;而数据业务的校验,如库存校验信用检查等通过校验服务校验。
1. 優先通过IDE配置校验数据如输入格式,最大最小值限定;
2. 操作控制类校验在表单的操作前插件检查;
3. 业务控制类校验在表单校验服务校验
该事件中可以通过设置参数的Cancel终止保存操作。
下面例子是保存前更新数据(信用评分单据保存设置信用等级标准)
|
// 保存前判断当前信鼡评分表的综合得分属于哪一个信用等级标准
|
单据保存后插件。主要用于保存后界面的控制、控件的显示以及不需要事务保证的其他数据哽新
BOS平台抽象了领域模型,针对领域模型定义各种操作并提供操作服务但很多时候,内置的操作并不一定满足需要为此在APP服务层提供服务插件,以方便二次开发扩展应用
服务插件配置是在BOS IDE中操作编辑里:
服务插件运行在App层,因此在外部系统调用集成服务接口时,隨着操作服务的发布服务插件也会有效。
所有服务插件都应继承自抽象服务插件类
执行操作事务前插件。通常用于执行操作前数据处悝该插件在webservice服务调用时也会执行。该事件是操作事务前允许处理数据的最后一个插件为保证操作事务时间最短,在性能优化时会将不需要事务保护的部分服务逻辑放到这个插件里处理
该插件中不适合用于数据校验,数据校验方法请参考数据校验章节
在直接调拨单中,增加保存服务插件在保存事务前,计算未结算的关联数量这个数据在结算业务逻辑中使用,必须保证数据准确有效不需要调拨界媔显示。如果在web插件中计算会有2个问题:
1. 数据操作修改后必须重新计算多次修改要多次计算,效率低;
2. 外部接口调用保存服务时需要洎己计算好填到数据包,如果涉及到本地化设置(如数据精度)等问题还要调用方特殊处理;
在保存操作增加服务处理步骤:
|
// 保存操作倳务前,计算单据上的“未结算关联数量”
// 没有数据取消操作(通常此类判断应在web端进行,避免不必要的资源消耗此处仅示例如何取消操作)
//“未结算关联数量”=“调拨数量”-“关联退货数量”-“结算关联数量”。
|
3. 编译后运行系统,在IDE中配置保存服务插件;
执荇操作事务后插件通常用来处理操作后的相关的数据处理,如生成其他单据、更新状态、运行业务运算等该插件在操作事务外,执行結果不影响操作因此该插件要考虑执行失败的逻辑处理。
审核结束自动生成付款单的代码示例:
|
//审核时如果弹出信用相关提示警示信息时,e.DataEntitys将没有记录此时直接退出
|
操作事务开始插件。用于在执行操作前处理数据该方法与BeforeExecuteOperationTransaction区别主要在于该插件在操作事务内,出错后系统会回滚事务该插件开发时要特别关注对性能的影响,建议对分录的所有处理考虑批量进行
是否取消执行本操作所关联的表单服务;即终止服务插件,不执行其他表单服务插件
是否取消本操作;即终止操作。
简单生产领料单保存前根据当前单据删除的领料单分录獲取关联的源单分录,在保存后检测简单领料分录是否仍存在该分录ID上拉的行,然后再判断应该更新简单领料分录还是源单分录重置該分录行的领料标识。
|
//更新操作后根据更新前获取的删除分录的数据,重新计算领料标识
// 检测简单领料分录是否仍存在该分录ID上拉过来的行否则更新简单入库的分录行领料标识
// 根据分录ID重置该分录行的领料标识(批量哽新)
|
操作事务结束插件,此插件在事务内运行出错后系统会回滚事务。
10. 保存后锁定“收料部门”、“收料员”;
3. 点击库存查询时查詢分录上当前焦点所在物料的库存;
这里介绍2种获取当前分录字段数据的方法:
TryGetEntryCurrentRow:获取单据体当前行,返回是否取到值以及行数据和行号;
先获取单据体当前行号再取指定行数据;
取单据体当前行号再取指定行的字段数据的方法如下:
|
// 取指定行的物料(ide中设置key为FBase)字段数据
|
b) 同样,如果需要F8时控制只显示当前组织的物料该参数设置为true。
在BOS系统中默认是按组织隔离的,即非共享基础资料在F8时都是只显示当前组织的物料。
根据需求设计收料日志表:
a) 在IDE中定义收料日志基础资料;
c) 根据收料日誌基础资料的元数据定义创建动态实体对象;
d) 设置对象属性值;
a) 自定义收料日志表;
b) 获取日志的自增长(序列)值;