基于DNN UDT模块搭建动态窗体以及公文流转的设想


(此文写在DnnWorkflow模块出来之前,是对UDT模块的一个分析,和基于UDT模式进行扩展的一个想法,放在这里,算是一个思路的启发过程)

  基于DNN UDT模块搭建动态窗体以及公文流转的设想

  一、DNN开发情况简介

  DNN是指DotNetNuke,是基于.Net Framework,采用微软Visual Studio 2003/2005开发的Portal系统,经过一段时间的研究,该系统可以说是功能非常强大的信息发布平台,可以在该系统的基础上,搭建非常多的专业级业务应用。同时,由于该产品是基于开源(Open Source)的,因此,所有的该系统的源代码均可以轻松获得,可以用来方便的编辑和查看,是快速搭建企业级应用的强有力的工具。

  目前基于DNN的想法是,以DNN为基础核心平台,搭建强大、灵活、可以方便定制的业务系统或者网站。如果用DNN搭建业务系统的话,将会有以下的好处:

  1、架构是最先进的、基于.Net的发布平台,已经经过众多专业团队的开发、建设和不断升级,是非常值得信赖的优秀产品;

  2、系统的用户管理、权限管理等太多基础工作已经完全可以放心的交给DNN去做,我们要做的只是特定的业务模块;

  3、网上不断有DNN的升级模块和功能,该产品不断被优化和升级,因此不存在该框架过时的问题;

  4、产品的界面可以完全不用关心,可以完全使用系统提供的界面,如果不满意,也可以在互联网下载各种其他界面;

  5、开发语言为C#和VB.Net等,上手迅速;

  因此,基于DNN,快速搭建企业级应用,是目前快速出产品的最好的方法。

  在企业应用中有很多功能需要进行定制,比如:车辆管理、图书管理、考勤管理等等小模块;还包括比如公文流转系统等较大的功能。如果基于DNN去开发这些模块的话,也是可以的,但是如果可以通过一种方式,去“定制”系统的界面和流程的话,就会非常方便,类似一些公司的公文格式设计工具。但是,这些公司的公文工具只是用来设计公文等审批业务,在使用范围上还是非常狭窄,并不是一种很好的方式;可以采用这种方式,不但定义公文,也可以定义各种互动模块,如果这样的话,扩展性就很强了。同时需要注意的是:DNN提供了强大的模块开发接口,因此,如果是非常特殊、业务逻辑较为复杂的业务,不必拘泥于非要定制不可,完全可以通过模块开发,去实际的做出一个模块出来。这样,整个系统的扩展性就会比一般的公文设计工具强大很多
因此,基于DNN的开发模式应该是这样的:

  较为简单的功能:通过表单定制实现

  较为复杂的功能:通过模块开发实现

  以上应该作为基于DNN快速开发和实施的准则。

  二、基于DNN的表单定义的实现方式

  基于DNN实现用户输入表单的定制功能,即用户的录入界面是可以通过后台进行定义的,根据用户在设计时指定的数据类型等信息,在进入录入界面时,自动创建录入表单。这一点,DNN的模块UserDefinedTable已经实现了较为充分的模型,为了体现“快速开发”的目标,可以以UDT为模型,对UDT 进行扩展,通过这种扩展,实现用户窗体的自定义。

  1、UDT(UserDefinedTable)简介

  UserDefinedTable(以下简称UDT)是基于DotNetNuke产品的一个模块,目的是可以使DNN的管理员在无须编程的情况下,定制录入表单。整个系统分为列表界面和录入界面两个部分,列表界面是数据的列表,哪些项目可以在列表中展现可以由管理员进行配置;录入界面是用户的输入界面,这个界面是根据后台的定义而自动产生的。

  UDT已经是自定义用户窗体的较为完备的雏形,通过UDT,用户已经完全可以定义一个模块中有哪些字段、各个字段分别是哪些数据类型等等。根据代码的注释可以看到,UDT模块至少从2004年就已经在开发了,是DNN的核心模块之一,功能非常强大。比如,数据类型就包括Text、Rich Text、Integer、Decimal、Date and Time、Date、Time、True/False、Email、Currency、URL、Image、Download和Caculated Column等字段,在存储时有相关数据类型的校验。

  2、分析UDT的存储

  经过对后台的分析,UDT的存储主要是以下的形式:

  UserDefinedFields:该表存储用户定义的结构,如字段名称、名称、是否必填、数据类型、缺省值、附加设置等等
UserDefinedRows:该表存储数据行和模块的对应关系,只有两个字段,UserDefindRowId和ModuleId;

  UserDefinedData: 该表存储的是数据;

  其他的信息如模块的设置等,存在系统的统一设置表中(ModuleSettings和TabModuleSettings)。

  通过阅读代码知道,系统在3.3.5版本的时候,数据的存储进行了调整,原来UserDefinedData表的FieldValue字段是NVarchar类型,调整为了NTEXT类型,NTEXT可以存储最大2GB的数据,因此系统具有较强的存储能力。

  3、UDT自定义表单的原理

  经过对UDT的分析和研究,对UDT的动态表单原理已经非常清楚了,完全可以基于UDT进行表单的扩展。

  目前的方式:目前,UDT对不同类型的数据动态创建控件,然后将这些控件插入到表单的特定表格中(tblFields),其中,tblFields采用的是.Net的服务器端控件,在程序生成其他控件的时候,动态的创建TableRow控件和TableCell控件,被创建的标签(如说明性文字)或者录入框等,被插入到特定的TableCell中。就是通过这种原理,实现表单的动态生成。

  4、UDT自定义表单的扩展

  通过如下的方式对UDT自定义的表单进行扩展:

  1)、UDT的表格和控件现在是结合在一起的,可以考虑增加一个空的TableRow控件,用于在设计表单的时候,通过增加表格的空行来定义格式(需修改数据结构);

  2)、目前录入的控件大小是固定的,如Text,在创建该控件的时候就写死了该控件的长度,这个可以扩展为用户设计时定义(需修改数据结构);

  3)、录入框目前是单行模式,可以通过调整,使之支持多行模式(需修改数据结构,增加属性);

  4)、目前的TableRow只有3行:Title、是否必填、字段控件,为了适应多样化的表格,可以考虑对表格进行扩展,支持更多的列,以及可以进行列合并等
5)、目前的权限设置是要么只能看列表,要么可以看详细内容(进入编辑页面),但进入编辑界面就已经有了编辑权限,这个需要进行调整,增加一个类似 View的功能,用户可以进去,但是只能View,而不能进行编辑。View界面有可能也需要设计,或者隐藏掉部分内容。

  总之,对自定义表单的扩展,基本上都是在现有的基础上,对表单进行细微的修修补补,完全不用影响到UDT的核心,UDT的核心仍然像原来一样保持正常的运作;列表界面也基本上完全不用修改(除了可能显示的美化稍微调整),列表的可定义排序功能更是非常完备。

  具体内容仍需要细化,但可以肯定的是,在不修改核心代码的基础上,对EditUserDefinedTable.ascx.vb的 BuildEditForm函数进行改造,可以实现表单的更大范围的自定义(这些自定义主要是集中在坐标、大小等内容上,对核心不会造成影响)。

  5、UDT自定义表单方式探讨

  对于通过UDT模块如何实现用户自定义格式的表单,在之前的想法中,希望通过动态创建Server端Table控件的方式实现;经过近期的考虑,认为通过动态创建Server端Table控件,确实是一个可行的办法,但存在的问题是:A、如何在数据库中存储动态的表格结构,尤其是在有行合并、列合并等不规则表格的形式下,如何存储这些内容?如果存储不好的话,可能会导致表格混乱;B、如何采用较为方便的方式使用户设计表格也是一个难题,在Web端应该如何动态设计页面?对于DNN而言,太复杂的业务逻辑和展现层次并不太适合,最好是以简洁的形式实现;C、如何存储每个单元格(TableCell)的格式?

  关于如何产生表格的问题,有以下三种思路:

  A、通过遍历控件的方式创建表格:这种方式的思路是跟UDT目前的思路一致的,在遍历控件的时候,检索其对应的表格(TableCell或者 TableRow)信息,先产生表格,然后再产生控件,将控件插入到表格中。这种方式需要在数据库中增加表格的存储和相关属性;这种方式的优点是尽量保持现有UDT的BuildEditForm的方式,但是缺点是在处理合并单元格的时候,有所限制
B、通过遍历表格的方式创建控件:这种方式是对UDT设计的一种增强,先通过UDT设计现有的界面,产生控件,然后设计表格,表格(TableCell)与控件进行关联,通过这种方式,在创建表格的时候,产生控件,并且将控件增加到对应的表格中即可;

  C、通过固定表格技术创建控件:这种方式是完全与以上两种方式不同的考虑,通过这种方式,不用创建服务器端的Table,只需要通过任何工具去创建一般的 Table即可,通过这种方式,设计者可以通过任何工具来创建表格,创建的表格事先定好所有的格式;在设计好表格后,在表格的对应位置添加占位符(类似.Net的PlaceHolder),比如,占位符的形式可能是这样的:<#名称#>,当服务器读到这样的占位符后,自动解释为对应的控件;生成最终的HTML格式,发送到客户端即可。这种方式的好处是可以通过各种工具来方便的设计整个界面,但是缺点是,由于是客户端的控件,并且整张表格以一个字符串的形式统一存储,所以如果需要不同的步骤对表格的单元格进行动态的显示、隐藏操作,则不可能实现(但是仍然可以对控件进行控制)。但是这种需要对词法进行解析。——这里一开始想错了,其实完全可以每个步骤对应一个文件,在步骤控制上,灵活性更强。

  产生表格的三种形式,目前的想法是第一种相对比较差,第二种方式较为理想,第三种方式最好。但是第三种方式如何进行词法解析需要好好考虑一下。

  三、引入“步骤”和“步骤权限”的概念

  在完成自定义表单的优化之后,如果需要对系统进行更深入的扩展,就需要引入“步骤”和“步骤权限”的概念。这里是将流程的概念逐渐引入到UDT,使UDT 不仅仅是一个简单的“用户定义表格”的概念,而是该模块可以实现中国人的“流程审批”的概念,可以定义流程。这是更为丰富的扩展,这里的扩展,将对UDT 做更大的改变,UDT目前的设计将成为多层次审批中的一个基础
1、引入部门及地址本的概念

  需要增加一个模块,这个模块是定义系统的部门架构的,这个对一个业务系统很重要。这个模块可以考虑做成一个后台的系统管理模块,而不是普通模块(普通模块可以有多个实例,对部门管理来说没有太大意义)。

  之所以要在DNN中引入部门及地址本的概念,是为了业务系统扩展的需要。对于DNN的一般性网站来说,主要的功能是用户和网站进行交互,而这个网站的用户之间的交互是非常分散的,而不是集中式的。例如,用户在网站上看到一篇文章,对这篇文章进行评论等动作,这时候,用户的对象其实主要是网站,隐含的对象是文章的作者,因此,这种交互方式是较为零散的,并没有一种方式,可以让用户看到DNN中所有的其他用户,并从其中挑选若干个,进行某种动作。这是由DNN 的性质所决定的。如果要在业务上进行扩展,尤其是在中国的现在环境下,必须对DNN进行功能的扩展。这种扩展实际上并不复杂,只是将分散的用户通过另外一种方式进行重组。

  1)、引入部门管理:从某种程度上来说,DNN的安全角色(Security Roles)已经算是一种“部门”了,但是,安全角色(Security Roles)由于在每个模块的设置中都会出现,如果使用安全组定义部门结构的话,A、安全组没有层级的概念,不能嵌套;B、安全组的太多修改对后台影响较大。因此,引入专门的部门概念,部门支持层级结构,可以添加、删除用户、支持用户排序等等中国特性,具有较强的扩展性。通过部门与安全角色的协作,可以完成较多的工作,也具有较强的灵活性。至于是否需要在系统中增加“组”的概念,则需要在开发中进行评估。

  2)、引入地址本:目前的DNN,是没有一个地址本的,所以,如果用户并不是单纯的浏览这个网站,而是希望从这个网站上向另外一个用户做动作(比如发送文件等等),如果让用户手工输入其他用户的名称或者代码的话,是非常不方便的,非常不“中国式”,因此,在DNN中引入地址本的概念。地址本,就是为了本网站的用户可以方便的找到其他的用户,并且进行协作。


  2、引入步骤管理和步骤权限管理

  步骤管理和步骤权限管理可以在模块的设置页面进行开发,通过一个DataGrid,将系统可以有的步骤都列举出来,用户可以增加步骤、修改步骤、删除步骤。每个步骤可以对控件设置权限(编辑、只读、可见等),可以设置步骤之间的关系等。从而使一个步骤可以到达下一个步骤。在这里需要注意的是,尽量以信息发布系统的概念去考虑这里的概念,不要受太多原来流程的限制,可以不用太灵活,不用太完备的流转判断

本文作者:
« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3