动态单据框架使用总结

更新时间:2024-02-03 20:07:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

动态单据框架使用总结

1、引言

最近我们协同系统部办公自动化组开发了一个流程管理模块,使用了最新的动态单据框架,现在这个模块已基本完成了一期的发布。整个开发过程,也是一个摸索和学习的过程,由于是一个新框架,说明文档和参考资料也不是很多,其间我们也遇到过不少问题,也走了一些弯路,现在将我在整个开发过程中的体会记录下来,以供自己和初次使用动态框架的同事参考。

2、动态框架简介

动态单据框架是直接基于JSF和ExtJS开发的,而不是在WAF框架之上开发的,所以在性能方面相对要好很多。动态单据框架主要功能是让我们可以通过设计器拖放和做一些配置来生成序时簿页面和单据编辑页面,而不需要像以前那样手工写bill.xhtml页面和后台管理的BillBean,这些工作框架都帮我们做好了,如果要做一些通用功能之外的自定义操作,我们也只需要写一个插件,并将操作写在插件中就可以实现了。这样就极大的简化了开发单据的过程,提高了开发效率。

3 、动态框架的使用

1>、动态单据的基本用法

首先,创建所需实体。然后打开金碟EAS客户端,在功能菜单中选系统平台,再双击动态单据配置,如图:

然后再选择要放到哪个子系统之下,确定之后出现如下界面:

这就是我们设计动态单据的主界面了(做过Winform的朋友一定看出来了,这和Winform非常相似,也为我们提供相当易用的人机界面,包括工具栏上的一系列布局按钮,让我们使用起来相当方便),右边的子系统区域显示了刚才所选的子系统下的所有动态单列表,我们可以在这修改已存在的单据,也可以新建一个动态单据。点新建按钮,选择一个模板,确定就根据模板生成了一张新的动态单据,我们也可以创建自已的模板,过程和新建单据基本一致,只要最后修改一下数据库记录即可,后面会谈到这个。 设计单据的过程比较简单,从工具箱里拖出控件,在属性面板中修改相应的属性,再保存,就可以了,这里只是重点提一下单据和控件的绑定,其它的在这不多涉及。

首先要给单据绑定实体,选定单据(注意:不是选定控件,要选择最外面的框),然后在属性面板中点绑定实体右边的按钮(如左图),弹出选择业务对象对话框,在这里我们选择最开始创建的实体,确定,就完成了单据和实体的绑定。这样我们的这张动态单据的序时簿和编辑界面就可以显示和修改所绑定的实体的属性了。 然后点下面的操作列表,定义这张单可以执行的据所有操作(如下图)。这里框架给我们提供了20多种内置的操作。我们在这选了单据所具有的操作功能(比如说保存操作),后面才能在给按钮事件添加Action时调用单据的保存功能,这也包括在工具条上的按钮要调用单据功能的情况。

操作列表里的权限是指执行某一操作所必须的权限项,如果为某个操作配了权限项,则框架在执行这个操作之前会先验权,如果有相应权限则执行,没有则抛出异常并终止执行操作。检查工作流是指在执行操作前是否要先检查该记录有没有在工作流之中,如设置为检查则当该记录已在工作流中时给出提示并取消操作,不在工作流中才往下执行。

单据中的控件都要和实体的一个属性绑定,这样才能在单据编辑页面读出实体的属性值或在保存时将控件的值存入实体相应属性里。对于文本框和日期框等,当我们点绑定实体属性右边的安钮时,会自动找出该单据所绑定实体的所有字符属性或日期属性。下拉列表框则会找出所有枚举属性供选择。对于基础资料控件,除了绑定实体属性外,还要选择基础资料类型和关联的基础资料字段名,实际上就是指定当点击这个F7控件时,要去找哪个基础资料实体的哪个字段的值显示在控件上。

另外提一下默认值的问题,我们可以给单据的某个或几个字段设置默认值,这样当新建单据时会自动为这个字段给上默认值,这对于一些不能让用户修改的字段如创建人等特别有用。设置默认值只需要选中控件,在缺省值中填入要取的值即可。目前框架还没有提供让我们直接选择就能设好默认值的方法。我们只能手工输入表达式来达到这个目的,下面是几种常用的默认值表达式写法(照下面的输入即可,不用改动):

getUser(@CONTEXT, Person) 取当前登录的职员 getUser(@CONTEXT, User) 取当前登录的用户 getBillNumber(@CONTEXT,@THIS,@MAINORG) 自动生成单据编号 getDate() 取当前日期 getOrgUnit(@CONTEXT, LoginOrg, @MAINORGTYPE) 取当前登录组织 在创建并保存了单据之后,我们就可以看到单据的序时簿界面和单据编辑界面了。键入以下地址就可以查看了:http://localhost:6888/easweb/dynform/demo.jsf

如上图,就是刚刚创建的“导出测试”单据的序时簿界面,连快速查询都帮我们生成了,同时我们也可以在左侧的单据中找到“导出测试”的单据编辑界面。动态单据框架真是强大,我们没有写一行代码就配出了序时簿和编辑界面,基本功能也都有了,如果摸熟了肯定会让开发效率上一台阶的。

2>、动态单据框架使用进阶

上面所说的只是动态单据框架的基本用法,我们要实现一些自定义的功能或其他操作,还要做这几件事:给序时簿添加工具条,为序时簿和编辑页面写插件,在插件中实现我们的功能,将插件注册到单据。

1)、给序时簿添加工具条

按照以上步骤做出来的单据序时簿页面是没有如上图中的查看,删除,刷新等工具按钮的,因为我们还没有做相关配置。但是我们都知道,序时簿页面的主要功能是要靠工具按钮来实现的,如果没有工具条,那我们在序时簿就只能简单的查看一下记录,做不了更多的事,这样的序时簿显然是不实用的。

接下来我们就来让工具条现身。很愦憾,目前框图架还没有提供设计界面来配置工具条(但是我们相信,动态框架很快就支持这个功能的),我们只能以手工方式来配置数据库来达到这个目的。以下就详细介绍如何配置数据库来添加工具条,其中可能牵涉了多张表,因而会多花一些篇幅来介绍表的结构和各表之间的关系。我们或许可以认为既然框架马上就会提供设计界面来支持工具条了,那为什么还要花时间去了解这些表结构呢,因为我们相信一个开发人员如果能更多的了解某个框架的底层技术细节,那么他所开发出来的程序不管是在运行效率上,还是在逻辑架构和扩展性方面,都会比一个完全不清楚框架的程序员所写的程序要完善很多,同时了解框架构成也有助于我们在开发时调错。

整个动态单据框架中最基础的表要算T_BAS_Form表了,我们每创建一张动态单据,都会在这个表里写入一条记录,包括动态单据的模板,也是在这张表里记录着。它的主要字段如下:

FID 主键,唯一标识,一个28位的字符串,在整个EAS系统中都是唯一

FName_L1 FElementTypeID

的,这也是其它表中所频繁使用的FormID。

动态单据名称或模板名称,FName_L2和FName_L3是多语言的名称 Form类型,一般我们创建的单据(在这也可以称Form)这个字段的值是100,如果我们在保存了单据之后,再手工把单据的这个字段改成-100(或是小于0的其它整数),那么这张单就会成为模板,我们在上面第二张图的子系统里将不会再看到FElemetTypeID为负数的单据,而是会在点设计器的新建时会看到这张单已经显示在右边的模板里面了,(如下图)

小技巧:当我们开发时要做2张或2张以上比较相似的单据,只有少量字段不同,我们可以先做一张,然后将这张单的FElementTypeID改为-100,再点新建,以刚才那张单为模板复制一张新单,稍做修改,最后再把第一张单的FElementTypeID改回100就可以了,这样会大大减少开发相似单据的工作量。

FBosType FPermissionItem FVersion

动态单据所绑定的实体的BosType,就是我们最开始所创建的实体的BosType,然后在上面用设计器绑定到了这张单上。 权限项字段

Form 的版本号,是一个Timestamp值,当我们做完下面的步骤,配好工具条后,刷新或重启IE,可能发现工具条并没有出现,只有重启服务器之后才会出现,但是这样影响开发效率,这时我们只需要改一下Form的FVersion值,再刷新IE就会看到了。其他的一些修改也是如此。

子系统ID,记录单据是属于哪个子系统,二级子系统可以到T_BAS_FormSubSystem表中查,一级子系统可以到T_BAS_FormTopClass表是查。

如果单据是从模板新建的,将会把模板的FID写到这里,否则为空

FSubsysID

FTemplateID

T_BAS_FormEntity表,记录了Form对应的实体,FTableName是单据绑定的实体对应的实体表名,FBosType和FFormID字段都和T_BAS_Form表相对应。

T_BAS_FormField表,记录动态单据的所有字段信息,主要字段如下: FFormID 该字段是属于哪一个Form的

FKey 字段的key值,也就是在设计器中该控件的“标识”属性的值,在插件编

程时会用到key值来标识该控件。

FFieldName 该控件所绑定的实体属性所对应的实体表的字段名,也就是在设计器为

控件绑定实体属性之后,在字段名中所显示的值(灰色,不可更改)

FElementTypeID 控件类型,是文本框还是下拉框,可以在T_BAS_ElementType表中查 FDataScope 取值范围,示例:0,255表示可以取0-255之间的值 FLookUpObjectID 针对F7字段,确定点F7时弹出窗口要使用哪个查询,对应于

T_BAS_LookUpClass表的FID,如一个行政组织的F7他的FLookUPObjectID是0,查T_BAS_LookUpClass表,对应的QueryInfo就是com.kingdee.eas.basedata.org.app.AdminOrgUnitQuery

FControlFieldKey 主要用在字段值携带时,设置当哪个key值的字段发生变化时,要相应

改变本字段的值,要配合FPropertyName,FRefPropertyName和FLink字段一起使用

FDefValue 控件的默认值,写法参见上面说明 FEnumType 针对下拉列表字段,跟FLookUpObjectID一样,标识要使用哪个枚举,

在这要查T_BAS_FormEnum表

T_BAS_FormFunction表,框架内置函数表,记录了当前动态单据框架所支持的内置函数及用法示例,之前所介绍的默认值的用法,我们也可以在这张表里查到,以后如果框架添加了新的内置函数,也可在这里看到。 T_BAS_FormOperation表,单据功能操作列表,我们在为单据绑定操作列表时(如上面的操作列表选择图),所选的操作,都会在这个表中生成一条相关记录,代表了这个Form所能调用的单据功能有哪些,目前一共有25种操作,可以在T_BAS_FormOperationType表中查询。 FFormID 单据的formID FPermissionItem 权限项,如果配了,则操作前要先验权

FStateField 操作执行后要更改的字段名,如没有,则空。比如说我们在提交操作之

后要将工作流状态字段置1,则这里填工作流状态字段名FworkflowStatus,在下面的FSuccessSateValue中填1

FSuccessSateValue 操作成功后要将FStateField所设定的字段更改为的目标值。 FFailedSateValue 操作失败后要将FStateField所设定的字段更改为的目标值。 FOperationID 操作代码,对应T_BAS_FormoperationType的FID字段 FCheckWfState 操作前是否检查工作流状态,-1为默认,0为不检查,1为检查

T_BAS_FormoperationType表,

FOperation 操作标识,我们在后面的T_BAS_FormActionList 表中调用单据功能时,

配FParaments参数,要和这里相对应。

FName_L2 操作名,FName_L1,FName_L3为多语言 FIsConfirm 操作前是否要确认,0为不要,1为要确认

FEnabledState 在哪种单据状态中可用,VIEW查看页面,ADDNEW新建页面,EDIT

编辑页面

T_BAS_FormLayout表,记录了Form的显示样式的一些参数,如标题,Form的高度和宽度,每页行数等信息。 T_BAS_FormLayoutField表,记录了每个字段的显示样式参数,如文本,大小,颜色,位置,顺序,是否锁定,可见性等。 T_BAS_FormConsoleGroups表,以流程管理为例,如下图,定义了流程管理模块左边树形导航的根节点。FName_L2是显示的文本,FIsExpanded定义初始时是否展开。

T_BAS_FormTreeNode表,定义导航树的下级节点,如上图,我的流程,我审批的流程,基础设置这3个的FParentID都指向T_BAS_FormConsoleGroups中所定义的流程管理的FID,而新建,草稿,进行中,已完成的FParentID都指向T_BAS_FormTreeNode表中我的流程的FID,它们的FConsoleGroupID才是指向T_BAS_FormConsoleGroups中所定义的流程管理的FID,这就确定也树节点之间的层次关系。FIsExpanded设置初始时是否展开该节点,1为展开,0为不展开。如上图所示,“我的流程”的FIsExpanded设为1,刚打开页面时将看到我的流程节点已经是展开的了。FIsLeaf表示是否是叶节点,只有叶节点Furl字段才有值,定义点了草稿之后要转向哪个URL(在右边的框架中打开,而不是在整个窗口中打开)。前面提到过了,我们可以在这个地址查看我们所创建的动态单据的序时簿和编辑界面http://localhost:6888/easweb/dynform/demo.jsf,但这只是个演示地址,在实际的应用中我们可以用如下URL访问:

http://192.168.17.230:6999/easweb/servlet/ListServlet?formID=svlnODODSJOEAYSjEzgWzpp+rpI= 上面这个就是我们流程管理模块的草稿这张动态单据的序时簿URL,只要在ListServlet后面加上formID参数就可以了,这个formID正是我们在T_BAS_Form表中草稿的FID,不过对其进行了URL编码,将一些特殊字符转换了一下。

http://localhost:6888/easweb/servlet/BillServlet?status=EDIT&formID=svlnODODSJOEAYSjEzgWzpp+rpI=&fromList=false&layoutID=fjtykhjkDSJhgS76zpp+rpI=&sourcePK=gkjJOEAYSjEzhhzpp+rpI=&

上面这个就是我们草稿的编辑页面的URL,在BillServlet 后加上formID,layoutID,sourcePK几个参数就可以了,sourcePK是指草稿所对应的实体表中的FID,以标明我们是要查看哪一条记录的详情。Status取EDIT是编辑页面,可以修改和保存,取VIEW是查看页面,只能查看,不能保存。 以上介绍了下几张基础表,接下来的这几张表就跟工具息息相关了。 T_BAS_FormMenu表,定义了每一个Form对应的工具条的ID(FMenuID),FType是用来标识工具条类型的,2表示工具条将显示在序时簿页面,1表示工具条显示在编辑页面。我们用的多的一般是序时簿工具条。 T_BAS_BarItem表,工具条按钮表,定义了工具条上都有哪些按钮。主要字段如下: FMenuID 按钮是属于哪个菜单的,与T_BAS_FormMenu的FMenuID相对应 FCaption_L2 按钮显示的文字,FCaption_L1和FCaption_L3是多语言文字。 FName 按钮的标识,在后面的按钮Action表中要用到,在插件中也会用得到。 FEnabled 是否启用 FVisible 可见性

FStyle 类型,一般的按钮为0,代表整个工具条的为12,相当于按钮的容器,

每个MenuID一般只有一个FStyle为12的。

T _BAS_BarItemLink表,工具条按钮关系表,定义了工具条按钮是否显示在工具条上,和显示的顺序等,主要字段如下: FMenuID 对应T_BAS_BarItem表的FMenuID字段。 FBarItemID 对应T_BAS_BarItem表的FID字段,填写FStyle为0的FID

FParentID 也是对应T_BAS_BarItem表的FID字段,不过我们在这个字段填写的

是在T_BAS_BarItem表中FStyle为12的那条记录的FID,也就是说要填写按钮容器的FID,这样就把一个个按钮加入到了工具条中

FIndex 按钮在工具条中的顺序,同一个FParentID的按钮顺序值不能重复,从

0开始,逐次递增1。

当我们把T_BAS_FormMenu、T_BAS_BarItem、T_BAS_BarItemLink这3张表配好后,并修改T_BAS_Form表对应的FVersion字段值后,刷新IE,将会看到工具条在序时簿上出现了,不过这时的工具条是没有功能的,点击之后是没有任何动作的。如果要让工具条按钮生效,就要用到下面几张表了。

T_BAS_FormActionList表,定义Form中的按钮等的动作,主要字段如下: FFormID 对应T_BAS_Form的FID FLayoutID 相应的元素的layoutID

FObjectKey 元素标识,可以是T_BAS_FormField表的FKey值,也可以是

T_BAS_BarItem表的FName值。

FObjectType 元素类型,设计界面上的按钮为3,工具条上的按钮为5,界面上的隐

藏元素为4

FActionID 动作的ID,对应T_BAS_FormAction表的FID字段,T_BAS_FormAction

表内建了36种动作类型,能满足大多数的需要,我们用得多的是23调用单据功能,28调用序时簿功能,30显示弹出页面,36调用自定义功能。更多的可以查看该表,有对应说明,在这不多介绍。

FActionType 触发动作的事件类型,目前我们主要用2种:ClickActions点击事件,

UpdateActions值更新事件。

FParaments

动作参数,我们如果FActionID填的是23调用单据功能,这个参数一般如[\就是调用单据的保存功能,而这个”Save”可以查看T_BAS_OperationType表的FOperation字段,目前表中定义了25种单据功能可供调用,这里要提一下,我们要调用单据功能,必须在前面为单据绑定实体后选择操作列表时选中了相应操作,这里才可以调用,也就是说要在T_BAS_FormOperation表中存在该FormID和FOperationID相对应的记录才行。

FActionID为28调用序时簿功能也是一样,FParaments填[New]是新建,[Delete]是删除,[Refesh] 是刷新序时簿。(请特别注意,这个单词不是笔者写错了,一定要写成“Refesh”才行,不是 “Refresh”,原因是当时框架是这么写的,后来又有一些部门基于框架开发了一些模块,如果 将单词改了会影响以前的模块,而将来框架会有设计界面来支持不用再手工配置了,我们也就 不会再看到这个小问题了)

FActionID为30时打开弹出页面,参数要这样配:[\

\审批意见\\,openNewWindow代表打开新窗口,后面跟的是URL,billId是URL参数 名,getSelectedRow()是内置函数,可以取出在序时簿中所选行的id值,title是弹出窗口的标题, name是窗口名称,x和y分别是宽和高。

FActionID为36时调用自定义功能,FParaments最多可以有7个参数,如下所示: [\打印','L3':'OK3'}\

其中,[1]Print为操作名称,在插件中能捕获到这个操作名称 [2]操作描述 [3]权限项,上面为 空,表示该操作不需要验权 [4]是否检查工作流状态,为TRUE检查,FALSE不检查 [5]是否 触发工作流 [6]是否操作前提示 [7]是否操作前确认数据修改,这7个参数中,[1]和[2]为必须 参数,其它为可选参数。

在了解了T_BAS_FormMenu、T_BAS_BarItem、T_BAS_BarItemLink、T_BAS_FormActionList这4张表的结构后,我们就可以完全的掌控住工具条了,下面给出一个完整的示例SQL语句,以供参考:

/****** 这里先在T_BAS_FormMenu表中添加一条记录并确定MenuID ******/

DELETE T_BAS_FormMenu WHERE FFormID='svlnODODSJOEAYSjEzgWzpp+rpI=';

INSERT INTO T_BAS_FormMenu(FID,FFormID,FType,FMenuID) VALUES (

'shg65VuuTfSFdk5jfhbt3ueIdrii','svlnODODSJOEAYSjEzgWzpp+rpI=',2,'Opd9Kxfhdg3dqC7P0oL') ;

/******接下来在T_BAS_FormMenuScheme 添加一条记录,表示工具条方案,这张表在前面没有提到,

这张表的记录可以有,也可以没有 ******/

DELETE T_BAS_FormMenuScheme WHERE fid in ( select fmenuid from t_bas_formmenu where fformid='svlnODODSJOEAYSjEzgWzpp+rpI=');

INSERT INTO T_BAS_FormMenuScheme(FID,FName_L1,FName_L2,FName_L3) VALUES ( 'Opd9Kxfhdg3dqC7P0oL',N'草稿序时簿工具条',N'草稿序时簿工具条',N'草稿序时簿工具条') ;

/******在 T_BAS_BarItem 表中添加按钮,下面添加了6个按钮和一个工具条 ******/

DELETE T_BAS_BarItem WHERE FMenuId in ( select FMenuId from T_BAS_FormMenu where fformid='svlnODODSJOEAYSjEzgWzpp+rpI=');

INSERT INTO T_BAS_BarItem

(FID,FMenuID,FCaption_L1,FCaption_L2,FCaption_L3,FName,FDescription_L1,FDescription_L2,FDescripti

on_L3,FToolTip_L1,FToolTip_L2,FToolTip_L3,FStyle,FImageKey,FEnabled,FChecked,FVisible,FShortcut) VALUES ('3yku6Ceq0k56gfhfi73s','Opd9Kxfhdg3dqC7P0oL',null,N'打印',null,'mnuPrint',null,N'打印',null,null,N'打印',null,0,' ',1,0,1,' ') ; INSERT INTO T_BAS_BarItem

(FID,FMenuID,FCaption_L1,FCaption_L2,FCaption_L3,FName,FDescription_L1,FDescription_L2,FDescription_L3,FToolTip_L1,FToolTip_L2,FToolTip_L3,FStyle,FImageKey,FEnabled,FChecked,FVisible,FShortcut) VALUES ('56jhC9HkOd6gfhdg3dI','Opd9Kxfhdg3dqC7P0oL',null,N'编辑',null,'mnuEditModify',null,N'编辑',null,null,N'编辑',null,0,' ',1,0,1,' ') ; INSERT INTO T_BAS_BarItem

(FID,FMenuID,FCaption_L1,FCaption_L2,FCaption_L3,FName,FDescription_L1,FDescription_L2,FDescription_L3,FToolTip_L1,FToolTip_L2,FToolTip_L3,FStyle,FImageKey,FEnabled,FChecked,FVisible,FShortcut) VALUES ('ehuPVk6hrwejfhjXeId','Opd9Kxfhdg3dqC7P0oL',null,N'刷新',null,'mnuDataRefesh',null,N'刷新',null,null,N'刷新',null,0,' ',1,0,1,' ') ; INSERT INTO T_BAS_BarItem

(FID,FMenuID,FCaption_L1,FCaption_L2,FCaption_L3,FName,FDescription_L1,FDescription_L2,FDescription_L3,FToolTip_L1,FToolTip_L2,FToolTip_L3,FStyle,FImageKey,FEnabled,FChecked,FVisible,FShortcut) VALUES ('fkihsrhhOd6fhwtg3r5','Opd9Kxfhdg3dqC7P0oL',null,N'删除',null,'mnuEditDelete',null,N'删除',null,null,N'删除',null,0,' ',1,0,1,' ') ; INSERT INTO T_BAS_BarItem

(FID,FMenuID,FCaption_L1,FCaption_L2,FCaption_L3,FName,FDescription_L1,FDescription_L2,FDescription_L3,FToolTip_L1,FToolTip_L2,FToolTip_L3,FStyle,FImageKey,FEnabled,FChecked,FVisible,FShortcut) VALUES ('ky4fhkOd654dIder5gB','Opd9Kxfhdg3dqC7P0oL',null,N'查看',null,'mnuView',null,N'查看',null,null,N'查看',null,0,' ',1,0,1,' ') ; INSERT INTO T_BAS_BarItem

(FID,FMenuID,FCaption_L1,FCaption_L2,FCaption_L3,FName,FDescription_L1,FDescription_L2,FDescription_L3,FToolTip_L1,FToolTip_L2,FToolTip_L3,FStyle,FImageKey,FEnabled,FChecked,FVisible,FShortcut) VALUES ('lorPVkouuk5j5flkei9','Opd9Kxfhdg3dqC7P0oL',null,N'提交',null,'mnuSubmit',null,N'提交',null,null,N'提交',null,0,' ',1,0,1,' ') ; INSERT INTO T_BAS_BarItem

(FID,FMenuID,FCaption_L1,FCaption_L2,FCaption_L3,FName,FDescription_L1,FDescription_L2,FDescription_L3,FToolTip_L1,FToolTip_L2,FToolTip_L3,FStyle,FImageKey,FEnabled,FChecked,FVisible,FShortcut) VALUES ('yw3g4hjYah055Zh64j','Opd9Kxfhdg3dqC7P0oL',null,N'工具条',null,'mnuToolbar',null,N'工具条',null,null,N'工具条',null,12,' ',1,0,1,' ') ;

/****** 在T_BAS_BarItemLink 表中将按钮加入到工具条,并调整好他们之间的顺序 ******/

DELETE T_BAS_BarItemLink WHERE FMenuId in ( select FMenuId from T_BAS_FormMenu where fformid='svlnODODSJOEAYSjEzgWzpp+rpI=');

INSERT INTO T_BAS_BarItemLink(FID,FMenuID,FBarItemID,FParentID,FIndex) VALUES (

'xfhd9HkOdrfgeYd654dI1a','Opd9Kxfhdg3dqC7P0oL','ky4fhkOd654dIder5gB','yw3g4hjYah055Zh64j',0) ; INSERT INTO T_BAS_BarItemLink(FID,FMenuID,FBarItemID,FParentID,FIndex) VALUES (

'xfhd9HkOdrfgeYd654dI1b','Opd9Kxfhdg3dqC7P0oL','56jhC9HkOd6gfhdg3dI','yw3g4hjYah055Zh64j',1) ; INSERT INTO T_BAS_BarItemLink(FID,FMenuID,FBarItemID,FParentID,FIndex) VALUES (

'xfhd9HkOdrfgeYd654dI1c','Opd9Kxfhdg3dqC7P0oL','lorPVkouuk5j5flkei9','yw3g4hjYah055Zh64j',2) ; INSERT INTO T_BAS_BarItemLink(FID,FMenuID,FBarItemID,FParentID,FIndex) VALUES (

'xfhd9HkOdrfgeYd654dI1d','Opd9Kxfhdg3dqC7P0oL','fkihsrhhOd6fhwtg3r5','yw3g4hjYah055Zh64j',3) ; INSERT INTO T_BAS_BarItemLink(FID,FMenuID,FBarItemID,FParentID,FIndex) VALUES (

'xfhd9HkOdrfgeYd654dI1e','Opd9Kxfhdg3dqC7P0oL','ehuPVk6hrwejfhjXeId','yw3g4hjYah055Zh64j',4) ; INSERT INTO T_BAS_BarItemLink(FID,FMenuID,FBarItemID,FParentID,FIndex) VALUES (

'xfhd9HkOdrfgeYd654dI1f','Opd9Kxfhdg3dqC7P0oL','3yku6Ceq0k56gfhfi73s','yw3g4hjYah055Zh64j',5) ;

/****** 最后,在T_BAS_FormActionList表中定义按钮功能,我们在这调用了序时簿的删除、编辑和刷新功能,调用了单据的保存,提交和关闭功能 ******/

DELETE T_BAS_FormActionList WHERE FFormID='svlnODODSJOEAYSjEzgWzpp+rpI=';

INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('58r8iss5oUqzjHdfgnTopHeI0khw','svlnODODSJOEAYSjEzgWzpp+rpI=', 'TNI5T/hQQZugRZCaiziSKZp+rpI=','mnuEditDelete',5,28,0,'ClickActions','[Delete]',N' ',0) ; INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('CRp+NUTCSj64nAizbMr4Fpp+rpI=','svlnODODSJOEAYSjEzgWzpp+rpI=', 'TNI5T/hQQZugRZCaiziSKZp+rpI=','FbtnSubmit',3,23,0,'ClickActions','[\INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('gj64whs5oUqzjHdfghkFJ56I0kd4','svlnODODSJOEAYSjEzgWzpp+rpI=', 'TNI5T/hQQZugRZCaiziSKZp+rpI=','mnuEditModify',5,28,0,'ClickActions','[Edit]',N' ',0) ; INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('hjk644k5oUqzjHdfhhkFJ56t7od3','svlnODODSJOEAYSjEzgWzpp+rpI=', 'TNI5T/hQQZugRZCaiziSKZp+rpI=','mnuDataRefesh',5,28,0,'ClickActions','[Refresh]',N' ',0) ; INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('IfHxJ2scTpmOPPaPjcfviJp+rpI=','svlnODODSJOEAYSjEzgWzpp+rpI=', 'TNI5T/hQQZugRZCaiziSKZp+rpI=','FbtnSave',3,23,0,'ClickActions','[\INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('wF1Lr9wcTi+0fVENvrNHtZp+rpI=','svlnODODSJOEAYSjEzgWzpp+rpI=', 'TNI5T/hQQZugRZCaiziSKZp+rpI=','FbtnClose',3,23,0,'ClickActions','[\

下面还给出了添加打开弹出窗口的调用自定义功能的SQL语句 INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('hr9ZuT4yt83rror9tyu68dy+rpI=','kSdMyUmYQKC7tzo9xr0XV5p+rpI=',

'NUjG3OnGQ9a8fP5andTIS5p+rpI=','mnuFlowMap',5,30,0,'ClickActions',N'[\easweb/workflow/approveHistory.jsf\审批意见\INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('Eujv7yIOT6WHZx/f4+OXMJp+rpI=','kSdMyUmYQKC7tzo9xr0XV5p+rpI=', 'NUjG3OnGQ9a8fP5andTIS5p+rpI=','mnuFilePrint',5,36,0,'ClickActions','[\打印','L2':'打印','L3':'打印'}\ 相信有了上面对表结构的认识和示例,我们对工具条应该已经用得得心应手了。

2)、为序时簿和编辑页面注册插件

通过上面的配置,我们已经看到了一个比较完整的序时簿和单据编辑(或查看)页面了,其间我们没

有写过一行代码,我们要做的只是使用设计器设计单据,再对数据库做相应配置即可,动态单据框图架是不是很强大?但是我们的单据目前还只有系统内置的功能,如保存,删除,打开弹出窗口等。假如我们要在序时簿中对单据做导入导出成Excel文件,在编辑页面发邮件,那我们刚刚配出来的单据就无法完成了,别担心,框架早已考虑到了这些,并为我们提供了相应的支持。 前面提到了,当在T_BAS_FormActionList表中将FActionID配置为36时,是调用的自定义功能,自定义功能的扩展性比较强,能实现相当复杂的操作,当然这个得我们自己来写代码实现,框架只是给我们提供了一个调用的接口,插件就给我们提供了这样一种通用的手段。 编写插件并不复杂,我们只需要写一个类从相应的基类派生即可。一般有2种插件,序时簿插件和编辑页面插件,编辑页插件从AbstractBillPlugin派生,序时簿插件从ListPlugin派生,这里强调一下命名规范,编辑页面插件一般以***Plugin的形式命名,序时簿插件则一般以***ListPlugin的形式命名。如下示例:

public class BillMessagePlugin extends com.kingdee.eas.base.form.plugin。AbstractBillPlugin {}

public class BillQueryListPlugin extends

com.kingdee.eas.base.form.model.list.ListPlugin {}

这样就写好插件了,当然这个插件并不具备什么功能,我们将在下面介绍如何写插件以实现功能。但是这样写好插件,框架并不知道我们这个插件是为哪个Form写的,我们还需要为Form注册插件才行,只有注册之后的插件,在运行时才会被框架调用,才能起作用。 注册插件要用到T_BAS_FormPlugin表,表的主要字段如下: FFormID 插件对应的formID FDesc 描述 FClassName 插件对应的类名,要有包名 FSeq 插件顺序,一个Form可以有多个插件,按这个顺序调用,从0开始 FType 插件类型,1为单据插件,2为序时簿插件,跟之前的工具条表一样 清楚了表结构,我们也就知道该如何注册插件了,以下给出一个示例SQL:

DELETE T_BAS_FormPlugin WHERE FFormID='kSdMyUmYQKC7tzo9xr0XV5p+rpI=';

/**********注册一个编辑页面插件**********/

INSERT INTO T_BAS_FormPlugin(FID,FFormID,FDesc,FClassName,FSeq,FType) VALUES (

'HU6GJi6XROulKc14mbVix5p+rpI=','kSdMyUmYQKC7tzo9xr0XV5p+rpI=',null,'com.kingdee.eas.cp.wfm.plugins.BillMessagePlugin',0,1) ;

/**********注册一个序时簿插件***********/

INSERT INTO T_BAS_FormPlugin(FID,FFormID,FDesc,FClassName,FSeq,FType) VALUES (

'r76GJi6XROulKc14mbVix5p+rpI=','kSdMyUmYQKC7tzo9xr0XV5p+rpI=',null,'com.kingdee.eas.cp.wfm.plugins.BillQueryListPlugin',0,2) ;

3)、如何编写插件

[1]编辑页面插件

插件也是使用事件驱动的方式来编程,AbstractBillPlugin中定义了很多方法,分别会在不同的事件发生时执行。如onLoad方法会在页面加载时被调用,dataChanged会在页面控件数据发生改变时被调用。比方说我们要在页面加载时给某个控件设一个默认值,除了前面说的在设计时配置外,还可以在onLoad方法中写上这么一句:

application.setValue(\, getCompany(), 0);

其中,basedataCompany是设计时该控件的标识,getCompany()是我们自己写的取当前登录人员的公司的方法,0是顺序,一般我们都用0。这样就可以在页面加载时自动调用onLoad方法,将当前登录人员的公司取出,并set到basedataCompany控件中。

application是父类的一个属性,通过这个属性我们可以得到很多我们有用的信息,也可以执行一些操作,比如说application.getContext()可以取到当前上下文,application.getValue (\,0)可以取得\控件的值。application.lockElement(\, true)可以锁定\控件

其他的如public boolean onInitialize(OpenBillParameter param) throws EASBizException,BOSException方法在初始化时调用,这个比onLoad的执行顺序还靠前。public void beforeBarItemClick(BeforeCommandArg beforeCommandArg) throws BOSException 在单击按钮并调用按钮功能之前执行,在这个方法里可以用这句beforeCommandArg.setCancel(true);取消按钮功能的调用,而以其它代码来代替。除此之外还有很多方法,我们看一下方法名也就大概知道是干什么用的了,这不多述及。

[2]序时簿插件

序时簿插件和编辑页面插件有些类似,不过他的基类是ListPlugin,所以有些方法会有一点点差异。下面介绍几个方法的用法,并给出示例代码来实现我们前面所配的自定义功能。

首先,onInitialize方法在序时簿初始化时被调用,在这个方法中可以设置序时簿时只能选一行,还是可以选择多行,如下,为true是只以单选。

public boolean onInitialize(OpenListParameter param) throws

EASBizException,BOSException{

}

param.singleSelect = true;

return super.onInitialize(param);

onBeforeQuery在每次查询前被调用,在这我们可以设置filter以便只查出我们所需要数据,也可设置OrderBy来排序。如下:

beforeBarItemClick方法在单击按钮并调用按钮功能前被调用,如下所示代码,可以先判断是

否选了一行或选了多行数据,如果不符合条件,则取消操作: public void beforeBarItemClick(BeforeCommandArg beforeCommandArg) throws

BOSException {

public void onBeforeQuery(BeforeQueryArg arg){ }

super.onBeforeQuery(arg);

arg.setFilterBy(\ );

arg.setOrderBy(\);

if (beforeCommandArg.getKey().equalsIgnoreCase(\)) { }

String[] pks=application.getListView().getSelectedBillIds(); if(pks == null || pks.length == 0){

application.showMessage(\请选择一行数据!\); beforeCommandArg.setCancel(true);

application.showMessage(\不能选择多行数据!\); beforeCommandArg.setCancel(true);

}else if(pks.length > 1){

}

} 其中的mnuEditView就是我们之前在T_BAS_BarItem表中为这个编辑按钮指定的FName字段的值。application.showMessage(\提示信息\);语句用来向客户端给出一个提示框。

doCustomOperation方法就是我们在T_BAS_FormActionList表中将FActionID配为36所调 用的自定义功能,在插件中会执行的相应方法。我们的自定义操作都可以写在这个方法中。如前面我们配了一条这样的记录:

INSERT INTO T_BAS_FormActionList

(FID,FFormID,FLayoutID,FObjectKey,FObjectType,FActionID,FDefineType,FActionType,FParaments,FExpression,FSeq) VALUES ('Eujv7yIOT6WHZx/f4+OXMJp+rpI=','kSdMyUmYQKC7tzo9xr0XV5p+rpI=', 'NUjG3OnGQ9a8fP5andTIS5p+rpI=','mnuPrint',5,36,0,'ClickActions','[\打印','L2':'打印','L3':'打印'}\ 则可以在下面的方法中这样写,来实现序时簿的打印功能(这只是示例,具体情况可能会有些不一样,要实际情况实际分析):

public void doCustomOperation(String operation){

afterOperation方法,在操作执行完后,被调用,一般可以放诸如刷新之类的操作(像删除等操作,执行完后序时簿会发生变化,如果不刷新,就不能及时看到这些变化),如下,这行代码就实现了在操作之后刷新序时簿。请注意:可能我们会这样写代码,执行了操作之后,直接在最后加上刷新语句就行了,但是这样是不行的,因为我们的代码执行了之后,框架还有一些需要执行的,如果此时刷新了,就会导致框架读不到相关数据而报错,所以一般刷新操作要写在afterOperation方法中。 public void afterOperation(FormOperation formOperation){

}

}

if (beforeCommandArg.getKey().equalsIgnoreCase(\){

String[] pks=application.getListView().getSelectedBillIds(); IObjectValue objectValue = DAOHelper.getDAO().load(

application.getContext(), pks[0], null);

DocumentInfoInfo info = (DocumentInfoInfo) objectValue; TemplateInfo templateInfo = TemplateFactory.getLocalInstance(

application.getContext()).getTemplateInfo( new ObjectUuidPK(info.getTemplateId()));

String formId = templateInfo.getFormID(); String layoutId = templateInfo.getLayoutID();

String[] srcBillPks = new String[]{info.getSourcePK()};

application.getListView().print(formId, layoutId, srcBillPks);

}

application.getListView().refresh();

4、总结

经过一段时间的使用和摸索,慢慢的了解了动态单据框架的强大功能,和给开发效率带来的巨大提升,尽管框架还有一些地方需要完善,但是只要我们能更多的了解框架的实现细节和其实现原理,就一定能很好的驾驭并让他更好的为我们服务。

本文来源:https://www.bwwdw.com/article/2b5w.html

Top