Justep X3中的组织模型核心设计
1.1 背景和需求
企业是一个整体协作的团队,无论大小,都会有组织机构存在。我们要设计和开发的平台,也是为企业应用服务的,因此也必须有一套完善的组织机构模型,并且能够支持业务分工、权限控制、分级授权、业务协作等符合企业现实经营活动要求的功能。如果需要,以后还可以考虑支持业务系统与群件(OA、Email)系统的一体化、和基于组织机构的即时通讯(IM)。
1.1.1 支持建立完整的企业组织机构模型
框架z应该提供对组织机构的全面管理支持,包括机构、部门、岗位、人员、分工、职权等等。在企业中,组织是为了完成企业目标而形成的具有特定结构、分工协作的团队。组织模型就是用来定义企业的组织形式的模型,它以职责、权限的形式定义了企业成员、企业各个部门的作用与任务,同时提供灵活的结构以适应不同的企业或企业中不同的组织结构,组织模型是业务模型(或称企业模型)的重要组成部分和基础。
图 1.1团队和组织机构管
1.1.2 支持现代矩阵式的组织机构
平台应该支持层级机构和工作组机构,满足现代企事业机构复杂、灵活的矩阵式组织模型的要求。
n 支持工作组模型
工作组是在企业经营活动中为了执行某一任务、适应市场变化或者其他临时需要而动态组建的、可以跨部门划分的一种组织形式,它是面向过程的,对企业的一种横向划分的组织方式。
n 支持层级式组织机构(金字塔)
企业的组织机构由一系列层次化的组织单元构成,每一个组织单元属于某一个层次,对其下一层次的组织单元具有管理职责与权限,并对上一层次的组织单元负责,从而形成企业的组织树。组织树中的每一个节点定义了对底层节点的约束和目标。
1.1.3 支持灵活和扁平化的组织机构
组织机构的任意调整,提供灵活的结构以适应不同的企业或企业中不同的组织结构。同时可以跨部门划分组织机构,对企业进行横向划分和管理。
n 一人多岗
一个实际的组织机构人员可以拥有多个岗位。每一个员工根据其职责或掌握的技能可能承担一个或多个岗位职责。
n 代理
在企业中,如某人外出,需要把自己的全部或部分岗位职责委托给他人(可以委托给多人),通过代理机制,代理人可以以被代理人的身份运行系统,从而实现被代理人的岗位职责,代其完成工作或执行任务。
n 委托
支持某个人员的所有工作都委托给另外一个人员进行处理。
1.1.4 支持业务分工和权限管理
平台必须能够通过对各类操作权限设置和组织机构设置,来实现业务分工以及业务权限管理。权限设置不仅可以对组织、机构、岗位、人员进行一般性的权限配置,还可以实现权限分层管理以及权限继承等复杂的权限管理功能。
平台对业务分工以及业务权限管理的能力应该包括:
n 权限管理
包括业务分工、分级授权、部门和岗位管理权限等。管理权限定义组织单元或岗位能管理的组织成员,体现组织成员的行政职能。
n 业务分工(功能权限)
通过功能权限定义组织成员所能执行的业务职能的范围。功能权限赋予组织单元或岗位能够执行的工作或者任务,限定了它们可执行的业务功能范围和功能活动范围。
n 操作权限
包括界面访问权限、动作控制权限、事件访问权限。用户可以通过业务操作,依据业务操作策略来管理和限制操作者的业务操作权限。这里的业务操作特指对具有相同业务共性的抽取,例如是否能够保存数据、是否可以查询之类的动作。
n 数据权限
包括访问权限、数据操纵权限、访问限制等等,支持通过语义层进行权限管理。数据权限用以定义组织单元或岗位对数据的访问、操作和控制范围,从组织层上对数据存取访问做的限制。
n 分级授权
支持当前运行系统的人员成员把自己拥有的功能权限分配给下属,以及当前运行系统的人员成员把自己拥有的管理权限分配给下属。按照组织机构、岗位、角色、用户等的综合权限配置,可以方便快捷的对权限进行分层。通过权限分层,各个不同级别上的岗位、角色均可以对上层岗位、角色分配给属于自己权限范围进行权限管理,也就是说可以对自己的下层级别岗位、角色、人员进行权限管理。
1.1.5 支持完整的企业组织机构和权限模型
n 基于业务
在组织机构内部,大量的协作是针对业务协同展开的,平台是面向业务的团队协作系统,是融合在管理信息系统之中,实现团队的业务协作。
n 全面性
实现数据共享、信息共享、团队沟通、业务协作和工作流的全面协作。实现业务系统与群件(OA)系统的一体化。
n 统一性
在统一的组织机构管理、业务分工、权限控制、流程管理下,实现团队协作。
1.1.6 支持权限与业务的紧密结合
n 业务协同处理
在统一的业务分工和工作流机制下,实现工作流程协同、任务自动调度和通知、信息自动传递和过滤。
n 信息共享和沟通
支持业务协作中的信息共享;支持信息发布、通知、广播、讨论;支持组织内外、局域和广域的邮件收发。
n 团队协作能力
在组织机构内部,大量的协作是针对业务协同展开的,平台是面向业务的团队协作系统,是融合在管理信息系统之中,实现团队的业务协作。在统一的组织机构管理、业务分工、权限控制、流程管理下,实现团队协作。
1.1.7 支持权限的用户自定义
对于团队和组织机构管理和业务分工和权限管理都可以由用户自主维护和定制。
1.1.8 支持通过语义层进行权限管理
通过业务语义策略从业务语义层上对数据进行约束,与业务语义层配合在较大范围内对数据进行约束。
1.1.9 提供可扩展的组织机构接口
提供足够的对外扩展接口,支持与其他系统在组织机构上兼容统一,使之能够在平台上开发对组织机构进行维护管理的功能。
n 组织单元属性的灵活扩展
支持对组织单元现有的属性信息进行扩展,即对组织单元增加新的属性。扩展属性不仅仅是存储在组织机构扩展表中,而且还会当做组织单元的属性存储。
n 提供与HR系统的连接接口
应该具备与业务系统的人事信息管理、组织机构信息与业务信息无缝结合的能力。
1.2 组织模型概论
在企业中,组织是为了完成企业目标而形成的具有特定结构、分工协作的团队。组织模型就是用来定义企业的组织形式的模型,它以职责、权限的形式定义了企业成员、企业各个部门的作用与任务,同时提供灵活的结构以适应不同的企业或企业中不同的组织结构。
组织模型是业务模型的重要组成部分和基础,它是企业中组织机构计算机化的抽象定义,对应于一个业务模型,其组织模型是唯一的。在整个业务模型层次体系中,组织模型处于功能层和流程层之间,为这两个层次的最终应用提供支持。
图1.2 组织模型层次关系图
在实际应用中,功能、流程和组织三者紧密结合在一起。企业的经营活动是由多个业务功能组成的,业务功能作为功能权限被分配到组织模型中的组织单元,从而形成业务分工,最后由组织模型中的人员登录系统运行业务功能,实现企业经营活动。在这些业务功能中,有些是可以独立执行的,而大多是根据其逻辑关系串接组合在一起,形成一系列的经营过程,即业务流程,人员通过运行业务功能借以启动、执行、控制流程,最终实现企业的经营过程的运作。
图1.3 组织模型与业务模型体系各个部分的关系图
为了建立能够支持现代企业组织动态特性的组织模型,在组织建模过程中,分成了人员、岗位和组织机构三个部分,允许企业根据自身的需要建立任意的组织形式,并赋予它们相应的权限和职责,从而达到对企业组织柔性建模的目的,为实现企业重组,提高企业的柔性和敏捷性提供支持。
1.1 人员(Person)
人员是指一个独立的、具有一定行为能力和一定技术能力的人的实体,它对应于企业中的每一个雇员。人员是企业的主体,企业的经营活动主要是人员的活动,企业的组织机构最终也是对人员的组织形式。人员具有一定的独立性,但又不能独立存在,在企业的人事行政管理中,它总是需要归属到一个部门或者机构。
人员是组织模型中最基本的要素。在企业的实际经营活动中,人员是一种具备抽象和共性的对象(因为每一个员工根据其职责或掌握的技能可能承担一个或多个岗位职责),因此,在组织模型中,将人员作为一种组织单元单独的独立出来进行建模设计。
图1.4 Business Studio中的人员设计界面(参考)
此外,人员是能够登录系统,直接操作功能的唯一对象,只有他(她)才能实现功能本身的真正价值。
需要注意的是:在系统中,人员大多都是以在组织机构中的机构或部门下的形式出现的(如图1.4所示),这样只是为了在表现上直观接近企业实际的人事行政管理情况(在企业的人事行政管理中,人员总是需要归属到一个部门或者机构),其实本质上人员并没有位于部门下。在系统内部的底层设计中,对应于组织机构中的每一个机构或部门,在人员根节点下都有一个同名文件夹与之对应(所有机构和部门文件夹位于人员根节点下的同一层。人员是放在所对应的机构或部门文件夹下的(同理,如果在表现上人员位于组织机构根节点下,则本质上该人员是放在人员根节点下的)。
例如:在图1.4中可以看到,人员“王小明”是位于“组织机构/世纪伟达科技公司/开发部”下的,可是他的BizURL字符串却为Org:/PERSON/WXM.psn,文件名为Org:/PERSON/KFB.DFD/WXM.psn,其中:Org:/PERSON表示为人员根节点,KFB.DFD表示“开发部”对应文件夹,WXM.psn表示人员“王小明”。由此可见,人员“王小明”实际是放在“开发部”所对应人员根节点下的部门文件夹下的。
1.2 岗位(Position)
岗位是一种以职责或技能作为前提,具有相同的目标,能够进行某种决策或完成某项功能的人员的总称。例如,所有开发部门的经理和程序员就是岗位。经理需要定期开会协调程序员的工作,控制整个开发项目的进度情况;而程序员负责编写程序代码,进行产品开发,对项目经理负责。尽管每个经理和程序员有完全不同的工作(负责开发的项目不同),但是他们的职责相同。
对于企业来说,岗位的种类有限,是一种具有共性、统一性,能够抽象并重复使用的对象(一个岗位可以分配到不同的部门,即不同的部门可以有相同的岗位职责,如:每个部门都可以有“部门经理”这个岗位),因此,在组织模型中,将岗位也作为一种组织单元单独的独立出来进行建模设计。另外,为了使岗位的设计更加清晰,在岗位的建模设计中支持了岗位分组(按文件夹分组)。
图1.5 Business Studio中的岗位设计界面(参考)
1.3 组织机构(Organization)
组织机构是对实际企业组织形式进行的抽象描述。企业的组织机构由一系列层次化的组织单元(OrgUnit)构成,每一个组织单元属于某一个层次,对其下一层次的组织单元具有管理职责与权限,并对上一层次的组织单元负责,从而形成企业的组织树。组织树中的每一个节点定义了对底层节点的约束和目标。
构成组织机构的组织单元包括:机构、部门、岗位成员、人员成员和工作组。其中,机构、部门、岗位成员、人员成员间的层次联系构成组织机构树,它描述了企业的静态组织结构,适用于企业传统的层次型组织方式,体现了传统的面向职能的企业组织形式。针对某一项目,企业可以组织项目团队,构成工作组,工作组描述了企业的动态组织结构,适用于面向临时工作任务、并行工程、敏捷制造等企业组织方式,它是面向过程而设立的。通过同时使用组织机构树和工作组两种描述方法,可以描述混合型的企业组织方式,满足现代企事业机构复杂、灵活的矩阵式组织模型的要求。
图1.6 Business Studio中的组织机构设计界面(参考)
1.3.1 机构(Organ)
机构是对一个经营实体的统称,处于组织机构的最高层,对应着实际企业经营活动中的一个公司、集团或者工厂等。
机构下可以设置子机构和部门。一个机构下需要设置多少个子机构和部门,以及怎样划分合理的组织层次,可以根据企业的实际组织形式来构建和划分。
1.3.2 部门(Dept)
部门对应于企业的静态结构划分,由企业的实际部门设置情况来决定,是以传统的面向职能或者现在流行的面向过程与客户方式对机构进行的划分,是机构的主要组成部分。例如:某公司的人事、销售、市场等部门,以及各个科室等等,都可以认为是部门。
对应着企业的实际经营活动,部门下可以设置子部门和分配岗位。部门不能独立存在,必须从属于机构或上级部门。
1.3.3 岗位成员(PositionMember)
将岗位(Position)分配到部门下,形成一个新的组织单元,即岗位成员。岗位成员不是新建出来的,是由岗位分配到部门下而得到,它具有岗位所有的职责和权限。在组织模型中,岗位只是对职责或技能共性的一种抽象对象,组织机构中的岗位成员才是组织中岗位职责的具体体现。同一岗位可以分配到多个部门下,形成多个岗位成员,岗位和岗位成员是一对多的关系(岗位被分配到部门才有意义,一个部门中可以包括多个岗位成员,这些构成组织机构中的岗位分工)。
图1.7 岗位和岗位成员的关系图
1.3.4 人员成员(PersonMember)
将人员(Person)分配到组织机构中岗位成员,形成一个新的组织单元,即人员成员。每一个人员根据其职责或掌握的技能可能承担一个或多个岗位职责,在组织模型中,人员只是对应到企业中员工的一种抽象对象,所以只有把人员分配到能够具体体现岗位职责的岗位成员而成为人员成员,才能使他(她)承担起岗位职责,实现他(她)的使命。人员登录系统后,只能以人员成员的身份运行系统,才能实现其岗位职责。如果登录人员承担了多个岗位职责(对应多个人员成员),可以通过切换岗位的方式转换到以其他人员成员身份运行系统,从而实现自己在不同岗位上的职责。
图1.8 人员和人员成员关系图
1.4 组织单元(OrgUnit)
组织单元是对组织模型中的人员、岗位、机构、部门、岗位成员、人员成员、工作组的统称。
每个组织单元都有一个用于标识自己的ID和用于显示的名称(DISPLAYNAME),以及说明自己是哪种组织单元的类型属性。
组织单元的ID和显示名称有如下规则:
l ID只能由合法字符a…z 、A…Z 、0...9或下划线组成;
l 对于部门、机构、工作组,ID是唯一的,即不能存在ID相同的部门、机构或工作组;
l 对于岗位,ID是唯一的,即不能存在ID相同的岗位;
l 对于人员,ID是唯一的,即不能存在ID相同的人员;
l 岗位成员的ID与所对应的岗位ID相同;
l 人员成员的ID与所对应的人员ID相同;
l 显示名称可以是汉字、数字或其他任意字符的字符串;
l 不同的组织单元,其显示名称可以重复;
l 岗位成员的显示名称与所对应的岗位的显示名称相同;
l 人员成员的显示名称与所对应的人员的显示名称相同。
1.4.1 组织单元的定位方式
组织模型是一个树形结构,它分成了人员、岗位和组织机构三个部分,这三个部分分别对应它的三个相对独立的子树,组织单元的定位方式就是指在组织模型的树形结构中唯一的确定一个组织单元的方式。组织单元的定位方式有两种:三个ID方式和BizURL方式。
l 三个ID方式
三个ID的定位方式是以组织单元的ID为基础的,该定位方式中的“三个ID”分别称为:部门ID(DeptID)、岗位ID(PositionID)、人员ID(PersonID),通过这三个ID可以在组织模型中唯一的定位组织单元。用三个ID定位组织单元的规则如下表:
表1.1 ID定位组织单元的规则表
三个ID 组织单元类型 | 部门ID | 岗位ID | 人员ID |
人员 | 空 | 空 | 人员的ID |
岗位 | 空 | 岗位的ID | 空 |
机构 | 机构的ID | 空 | 空 |
部门 | 部门的ID | 空 | 空 |
岗位成员 | 上层部门的ID | 岗位成员的ID | 空 |
人员成员 | 上层部门的ID | 上层岗位成员的ID | 人员成员的ID |
l BizURL 方式
BizURL定位方式以业务定位来定位组织单元,是以在组织模型树中从根到该组织单元的绝对路径来进行定位的。组织模型树根节点的BizURL字符串表示为:Org:;对应于人员、岗位、组织机构三个相对独立的子树的根节点,分别称为人员根节点、岗位根节点、组织机构根节点,其BizURL字符串表示分别为:Org:/PERSON、Org:/POSITION、Org:/ROOT。
1.4.2 OrgURL
系统中定义了TOrgURL类,一个TOrgURL类的实例对象就能够代表一个组织单元,因为它提供了定位组织单元所需的所有信息,并且支持两种定位方式的表现形式的转换(即三个ID和BizURL 方式的转换)。
1.4.3 组织单元逻辑删除
所谓逻辑删除是指:在组织机构系统表中,只是在被删除组织单元的相关字段中作上删除标记,并未将组织单元彻底除去。
组织单元的逻辑删除通常用在如下情况:某员工已经离职,将被禁止登录系统,但是为了对企业中各项工作做到有案可查(如查看流程历史中某任务的执行者),还需要保留该员工的信息,这时就可以把该人员逻辑删除掉。
逻辑删除组织单元时,如果删除的是人员,则其对应的所有人员成员也一起被逻辑删除;如果删除的是岗位,则其对应的所有岗位成员也一起被逻辑删除。
对于逻辑删除的组织单元:
l 组织机构所有相关表现组件都不能表现逻辑删除的组织单元(包括其下级组织单元);
l 如果是机构、部门、岗位、人员,则不能再创建一个ID相同的组织单元;如果是岗位成员,则在同一部门下不能再分配一个ID相同的岗位成员;如果是人员成员,则在同一岗位成员下不能再分配一个ID相同的人员成员;
l 如果是人员,则该人员不能再登录系统;如果是岗位成员,则人员登录系统后,不能通过切换岗位的方式切换到以该岗位成员下的人员成员身份运行系统。
被逻辑删除的组织单元会被放入回收站中。回收站是一个存放被逻辑删除的组织单元的容器。
对于被逻辑删除的组织单元,可以将其从回收站中恢复还原。当恢复岗位成员或人员成员时,如果所对应的岗位或人员不存在(已被逻辑删除),则不能恢复。
1.5 管理权限
管理权限定义了组织单元所能管理的下属范围,即定义哪些组织单元成为它的下属。管理权限体现了组织单元的行政职能。
管理权限包括组织管理权限和业务管理权限。组织管理权限描述了组织上的上下级关系(如:对于组织上的下级,上级可以对它进行工作或任务的分配,或者再给它分配下级),它定义的下属称为组织下属;而业务管理权限不同,它描述的是业务上的分管,即业务上的下属,提供了对业务监控、上下级业务管理的支持,业务管理权限定义的下属称为业务下属。例如:某部门经理,他的组织上的下属为部门A(组织管理权限),此外,他还分管部门B的销售业务(业务管理权限),即部门B是他业务上的下属。业务管理权限是通过给管理权限加上一个业务类型实现的,此业务类型代表了管理权限的业务意义。在上例中,给该部门经理分配部门B时,须加上表示业务类型的字符串“销售”;分配部门A时,则无需加(该字符串为空表示组织管理权限)。
在系统中,可以分配管理权限的组织单元类型有:岗位、岗位成员、人员成员;分配的管理权限中可以包括的组织单元类型有:机构、部门、岗位成员和岗位。
组织单元的下属范围包括管理权限中定义的组织单元及其下级组织单元。如:对人员成员A分配的管理权限中包含机构B,则机构B及其下级的所有部门、岗位成员、人员成员都将成为人员成员A的下属。另外,如果对某组织单元分配的管理权限中包含岗位,则该岗位对应的所有岗位成员及下面的人员成员,都将成为该组织单元的下属。
1.5.1 管理权限的继承
管理权限的继承是指组织单元拥有其他可继承组织单元的管理权限,也就是说一个组织单元所具有的管理权限除了分配给它自身的管理权限外,还包括它所继承的管理权限。管理权限继承机制描述如下:
l 对于岗位成员,继承所对应岗位的管理权限;
l 对于人员成员,继承上层岗位成员的管理权限。
如:有三个组织单元,分别是岗位A,岗位成员B,人员成员 C,其中岗位成员B是岗位A分配到某部门形成的,人员成员C是某人员分配到岗位成员B下形成的。对于岗位A分配的管理权限为组织单元X,岗位成员B分配的管理权限为组织单元Y,人员成员C分配的管理权限为组织单元Z。则岗位成员B所具有的管理权限为组织单元X和组织单元Y,人员成员C所具有的管理权限为组织单元X、组织单元Y和组织单元Z。
1.5.2 管理权限的分级授权
管理权限的分级授权,是指对组织管理权限的逐级往下分配,即组织单元把自己具有的组织管理权限(或部分)分配给组织下属,而组织下属又可以把获得的组织管理权限(或部分)分配给它自己的组织下属,依此类推,逐级向下分配。
这里包括两个范围的约束:
l 只能给自己的组织下属分配管理权限;
l 可以分配的管理权限只能是自己所具有的组织管理权限的子集。
在进行分级授权时,对于分配给下属的管理权限,可以是组织管理权限也可以是业务管理权限,而对于下属来说,只能把分配给它的组织管理权限继续往下分配。
1.6 功能权限
功能权限定义了组织单元对业务功能的职能权利范围。组织单元对业务功能有两种权限,即功能权限包括两种:运行和管理,对于这两种权限范围内的业务功能分别称为运行功能和管理功能,其中运行功能定义了组织单元所能执行的业务功能的集合,是组织单元业务职能的体现,它赋予组织单元能够执行的工作或者任务,限定了组织单元可执行的业务功能范围和功能活动范围;而管理功能定义了组织单元所能管理的业务功能范围,用于功能权限的分级授权。组织单元对同一业务功能即可以有运行权限也可以有管理权限。
在系统中,可以分配功能权限的组织单元类型有:岗位、机构、部门、岗位成员、人员成员。
1.6.1 运行功能
在分配功能权限时,如果给某个组织单元分配的是运行功能,则该组织单元对所分配的业务功能有运行的权限,即具有该权限的人员成员在系统中可以运行这些业务功能,执行相应的工作或任务。
1.6.2 管理功能
管理功能是为功能权限的分级授权做支持的。在分配功能权限时,如果给某个组织单元分配的是管理功能,则该组织单元对所分配的业务功能有管理的权限,所谓管理,是指具有该权限的组织单元可以把这些管理功能分配给其他组织单元。
1.6.3 功能权限的继承
对于企业中某部门的所有员工来说,有些工作是大家都需要做的(比如每个员工都需要填写工作日志),如果把这些工作作为功能权限分配给每一个员工,这将是一个很烦琐的事情,为了解决类似问题,引入了功能权限的继承。
功能权限的继承是指,组织单元拥有其他可继承组织单元的功能权限。这种继承关系表现在组织机构树中基本是:某个组织单元继承上层所有父组织单元的功能权限,特别地,对于岗位成员,除了基本的继承关系外,还继承其所对应岗位的功能权限。随着树中组织单元层次的从高到低,继承的功能权限越来越多,权限范围越来越大。对应于不同类型的组织单元,其功能权限继承机制如下表:
表1.2 功能权限继承机制表
组织单元类型 | 继承机制 |
岗位 | 无 |
机构 | 继承上层父机构的功能权限 |
部门 | 继承上层父机构或父部门的功能权限 |
岗位成员 | 继承所对应岗位及上层部门的功能权限 |
人员成员 | 继承上层岗位成员的功能权限 |
有了功能权限的继承机制,对于在第一段中描述的问题,就可以把功能权限直接分配到该部门组织单元上,而该部门下的所有员工都会继承其功能权限,从而避免了对每个员工的分配。
1.6.4 功能权限的分级授权
功能权限的分级授权,是指对功能权限中具有管理权限的业务功能逐级往下分配,即组织单元把自己具有的管理功能(或部分)分配给组织下属,而组织下属又可以把获得的管理功能(或部分)分配给它自己的组织下属,依此类推,逐级向下分配。
功能权限的分级授权也包括两个范围的约束:
l 可以给哪些组织单元分配功能权限?这是由组织管理权限决定的,只可以给自己的组织下属,即组织管理权限范围内的组织单元分配功能权限。
l 给组织下属分配功能权限时,可以分配哪些业务功能?这是由自身的功能权限决定的,即可以分配的业务功能只能是自己所具有的管理功能。
另外,进行分级授权时,对于分配给下属的业务功能,可以是运行的权限也可以是管理的权限,而对于下属来说,只能把分配给它的可以管理的业务功能(即管理功能)继续往下分配。
1.7 数据权限
数据权限定义了组织单元对业务数据的访问、操作和控制权限,是从组织层上对业务数据存取访问做的定义和限制。
组织单元上定义的数据权限,针对的目标是该组织单元分配的运行功能中包含的数据。数据权限通过添加数据策略来实现,数据策略最终作用到业务数据集上,通过指定策略的目标,对指定目标中包含的业务数据集进行数据约束。通过对组织单元定义数据权限,可以使不同的组织单元在运行功能时实现对相同数据的不同存取访问限制。例如:有一业务数据集名称为“订单业务数据集”,该数据集被很多业务功能所使用到,当运行业务功能时,要求对于人员成员A可以对该业务数据集进行添加、修改、删除,而对于人员成员B,则只能浏览该业务数据集中的数据,不能修改。对于这种情况,就可以通过分别对人员成员A和人员成员B定义不同的数据权限实现。
在系统中,可以定义数据权限的组织单元类型有:岗位、机构、部门、岗位成员、人员成员。
1.7.1 数据集策略
在组织单元的数据权限中可以添加数据集策略,数据集策略的目标只能是该组织单元分配的业务功能引用到的业务信息中包含的业务数据集。
1.7.2 数据语义策略
在组织单元的数据权限中可以添加数据语义策略,数据语义策略的目标只能是该组织单元分配的业务功能引用到的业务信息或引用到的业务信息所在的业务空间、业务信息空间。
1.7.3 数据权限的继承
数据权限的继承是指,组织单元拥有其他可继承组织单元的数据权限。与功能权限相似,这种继承关系表现在组织机构树中基本是:某个组织单元继承上层所有父组织单元的数据权限,特别地,对于岗位成员,除了基本的继承关系外,还继承其所对应岗位的数据权限。不同的是,对于功能权限,随着继承权限的越来越多组织单元的功能权限范围越来越大,而对于数据权限,随着继承的权限越来越多,该组织单元对数据存取访问的限制越来越严格,对业务数据的访问权限越来越小。对应于不同类型的组织单元,其数据权限继承机制如下表:
表1.3 数据权限继承机制表
组织单元类型 | 继承机制 |
岗位 | 无。 |
机构 | 继承上层父机构的功能权限。 |
部门 | 继承上层父机构或父部门的数据权限。 |
岗位成员 | 继承所对应岗位及上层部门的数据权限。 |
人员成员 | 继承上层岗位成员的数据权限。 |
1.8 操作权限
操作权限定义了组织单元在功能运行时所禁止的动作范围,是从组织层上对功能运行时所能进行的操作做的限制。
组织单元上定义的操作权限,最终体现在该组织单元分配的运行功能上,即决定了业务功能运行时有哪些动作被禁止了。操作权限是通过添加操作策略来实现的。通过对组织单元定义操作权限,可以使相同功能在不同组织单元运行时实现不同的操作限制。例如:在“销售订单”业务功能中有一个审批操作,销售人员和销售经理都对这个业务功能有使用权限,但是销售人员是没有审批的权限的,对于这种情况,就可以通过对销售人员定义数据权限来实现禁止其使用审批操作。
在系统中,可以定义操作权限的组织单元类型有:岗位、机构、部门、岗位成员、人员成员。
1.8.1 操作策略
操作权限通过添加操作策略来实现,操作策略中设置了被禁止的业务操作。操作策略最终作用到业务功能中的业务操作代理组件,那些被分配到操作策略的业务操作在运行功能时被禁止,而对应到功能中的具体哪些动作被禁止(业务操作代表的动作),是由业务操作代理来实现的。
在为组织单元定义操作权限时,所有的业务操作会被分配到一个默认的操作策略中,所以无需添加操作策略。
1.8.2 操作权限的继承
操作权限也可以继承,它的继承机制与数据权限相同。随着继承的操作权限越来越多,组织单元在运行功能时的操作限制越来越严格,所允许的动作越来越少。
1.9 代理
代理是指某人代替其他人、以其他人的身份进行某种活动,其中被代替的一方称为被代理人,代替方称为代理人。
在企业中,如某人外出,需要把自己的全部或部分岗位职责委托给他人(可以委托给多人),这时就需要用到代理。代理人登录系统后,以被代理人的身份运行系统,从而实现被代理人的岗位职责,代其完成工作或执行任务。
需要说明的是:在系统中,被代理的只能是人员成员,即只能把被代理人的某个人员成员的岗位职责代理出去,如果想把某个人员的所有岗位职责全部代理出去,需要对该人员所对应的所有人员成员分别指定代理人(当然,也可以指定到同一个代理人)。代理人登录系统后,可以通过切换岗位的方式切换到被代理的人员成员,并以被代理的人员成员身份运行系统,从而实现被代理人的岗位职责;被代理人不能再承担被代理出去的人员成员的岗位职责,在表现上,被代理人登录系统后,在进行岗位切换时,不能切换到(也不能看到)被代理出去的人员成员。例如:对于人员A,对应着两个人员成员,分别记为A1和A2;对于人员B,也对应着两个人员成员,分别记为B1和B2。如果人员A代理了B1,则人员A登录系统后,进行岗位切换时,就可以切换到B1,以B1的身份运行系统,从而实现B1的岗位职责;而人员B登录系统后,则不能再切换到B1。
1.9.1 代理的收回
代理的收回是指取消代理人对被代理的人员成员的代理,并保留代理的历史记录。代理收回后,代理人和被代理人的代理关系取消,被代理的人员成员的岗位职责重新由被代理人来承担。
1.9.2 代理的删除
代理的删除是指收回代理并删除代理记录,不保留历史。
1.10 组织模型存储
1.10.1 存储体系
组织模型的存储包括三个部分:组织模型自身组织形式,即组织模型结构的存储;组织单元的属性存储;组织单元权限的存储。
1. 组织模型结构的存储
组织模型结构的存储是基于虚拟文件系统的。组织模型是一个树形结构,它分成了人员、岗位和组织机构三个部分,这三个部分对应它的三个相对独立的子树。为了得到节点在虚拟文件系统中(树形)的位置表示,每个节点对象都需存储以下几个信息:用于标示自己的ID、类型(用扩展名表示)、所在路径、所在空间、文件名等。其中(ID + 类型)组成了节点的文件名,而(所在路径 + 文件名)组成了节点完整的文件名,(所在空间 + 文件名)组成了节点完整的BizURL定位字符串,用于组织单元在虚拟文件系统中的定位。介于组织单元支持三个ID的定位方式,所以还需要对三个ID进行存储。另外还存储了每个节点用于全局唯一表示自己的GUID、父节点GUID、以及支持逻辑删除的标示。这些信息都存储在组织机构系统表(TORGSYSTEM)中。
2. 组织单元属性的存储
组织单元的属性包括创建时间、修改时间、显示名称等。每个属性都有一个ID表示,如显示名称的ID为DISPLAYNAME。组织单元属性是以(属性ID = 属性值)的成对关系存储在组织机构属性表(TORGATTRIBUTE)中的。
3. 组织单元权限的存储
组织单元权限分为两种方式进行存储的:流方式、索引方式。其中,管理权限、功能权限、以这两种方式存储;而操作权限只是以流方式存储,没有索引。流方式是把信息以二进制流的方式作为一个字段存储在组织机构内容表(TORGCONTENT)中的。索引方式是为了信息的快速查找,而专门的把它们的信息存储在了组织机构索引表(TORGINDEX)中,每项权限在索引表中都存储了一条记录,每条记录包括三个信息:组织单元GUID(表明是哪个组织单元的索引信息),索引类别ID(表明是哪类索引),索引值。各类别索引ID及索引值描述如下表:
表1.4 各类索引ID及索引值描述表
类别 | 索引类别ID | 索引值描述 | |
管理权限 | 组织管理权限 | “OrgUnit.Subordination” | 所分配下属的URL定位字符串 |
业务管理权限 | “OrgUnit.Subordination”+“.”+业务类型字符串 | ||
功能权限 | 管理功能 | “FuncAlloc.Manage” | 所分配功能的URL定位字符串 |
运行功能 | “OrgUnit.FuncRef” |
1.10.2 表结构
与组织模型存储相关的四个系统表及表结构如下:
1. TORGSYSTEM(组织机构系统表)
表1.5 组织机构系统表
字段显示名称 | 字段ID | 数据类型 | 字段说明 |
GUID | FGUID | 字符 | 全局唯一标示字符串GUID |
父GUID | FPARENTGUID | 字符 | 父节点的GUID |
文件名 | FFILENAME | 字符 |
|
主要文件名 | FID | 字符 | 标示ID |
扩展名 | FKIND | 字符 | 扩展名表示了类型 |
路径 | FPATH | 字符 | 所在路径 |
删除版本号 | FDELETELEVEL | 整数 | 逻辑删除标示,为0表示没有被逻辑删除,》=0表示已经被逻辑删除。 |
显示名称 | FDISPLAYNAME | 字符 |
|
顺序 | FSEQUENCE | 整数 | 在组织模型树中的显示顺序 |
文件标记 | FFLAG | 字符 | 16字节长度的字符串, 1..8个保留给通用的文件系统层, 9..16可自定义,第1位:用'1'标记是目录; |
部门 | FDEPT | 字符 | 部门ID |
岗位 | FPOSITION | 字符 | 岗位ID |
人员 | FPERSON | 字符 | 人员ID |
2. TORGATTRIBUTE(组织机构属性表)
表1.6 组织机构属性表
字段显示名称 | 字段ID | 数据类型 | 字段说明 |
GUID | FGUID | 字符 | 全局唯一标示字符串GUID |
ID | FID | 字符 | 属性ID |
值 | FVALUE | 字符 | 属性值 |
3. TORGCONTENT(组织机构内容表)
表1.7 组织机构内容表
字段显示名称 | 字段ID | 数据类型 | 字段说明 |
GUID | FGUID | 字符 | 全局唯一标示字符串GUID |
内容 | FCONTENT | 二进制流 | 组织单元相关信息的二进制流表示 |
4. TORGINDEX(组织机构索引表)
表1.8 组织机构索引表
字段显示名称 | 字段ID | 数据类型 | 字段说明 |
GUID | FGUID | 字符 | 全局唯一标示字符串GUID |
ID | FID | 字符 | 索引类别ID |
值 | FVALUE | 字符 | 索引值 |
下面是这几张表的关系图:
图1.9 组织模型存储表关系图
1.11 组织机构扩展
组织机构扩展是指对组织单元现有的属性信息进行扩展,即对组织单元增加新的属性。
在系统中,内置的对组织单元的管理,只是包含了ID、显示名称等基本的属性信息,就组织机构系统表而言,对组织单元也只是提供了这几个基本的属性信息的存储,为了对组织单元增加更多、更详尽的描述信息(如对人员增加性别、年龄),以满足用户的需求,提出了组织机构扩展。
组织机构的扩展是以组织机构扩展表为基础的,扩展属性不仅仅是存储在组织机构扩展表中,而且还会当做组织单元的属性存储(关于属性存储,请参考8.10节)。
1.11.1 组织机构扩展表
为了支持组织机构的扩展,在组织机构系统表的基础上扩展出三个扩展表:人员表(TPERSON)、岗位表(TPOSITION)和部门表(TDEPT)。其中,人员表存储了人员信息;岗位表存储了岗位信息;部门表存储了机构、部门和工作组信息。
这三张表中的内容是对组织机构系统表的重复,系统中的组织机构底层调用不会倚赖这三张扩展表,它们只是为了组织机构信息的扩展而扩展出来的,里面的内容与系统表同步维护。
组织机构扩展表的表结构如下:
1. TPERSON(人员表)
表1.9 人员表
字段显示名称 | 字段ID | 数据类型 | 字段说明 |
GUID | FGUID | 字符 | 全局唯一标示字符串GUID |
ID | FID | 字符 | 主文件名 |
显示名称 | FDISPLAYNAME | 字符 |
|
部门编号 | FDEPTID | 字符 | 所属部门 |
账号 | FLOGINID | 字符 | 暂没有用到,保留字段 |
删除版本号 | FDELETELEVEL | 整数 | 逻辑删除标示,为0表示没有被逻辑删除 |
属性 | FPROPERTY | 二进制流 | 组织单元相关信息的二进制流表示,同TORGCONTENT(组织机构内容表)表中的FCONTENT字段 |
2. TPOSITION(岗位表)
表1.10 岗位表
字段显示名称 | 字段ID | 数据类型 | 字段说明 |
GUID | FGUID | 字符 | 全局唯一标示字符串GUID |
ID | FID | 字符 | 主文件名 |
显示名称 | FDISPLAYNAME | 字符 |
|
删除版本号 | FDELETELEVEL | 整数 | 逻辑删除标示,为0表示没有被逻辑删除 |
属性 | FPROPERTY | 二进制流 | 组织单元相关信息的二进制流表示,同TORGCONTENT(组织机构内容表)表中的FCONTENT字段 |
3. TDEPT(部门表)
表1.11 部门表
字段显示名称 | 字段ID | 数据类型 | 字段说明 |
GUID | FGUID | 字符 | 全局唯一标示字符串GUID |
父GUID | FPARENTGUID | 字符 | 父部门或机构的GUID |
ID | FID | 字符 | 主文件名 |
类型 | FKIND | 字符 | 表明是机构、部门或工作组 |
显示名称 | FDISPLAYNAME | 字符 |
|
删除版本号 | FDELETELEVEL | 整数 | 逻辑删除标示,为0表示没有被逻辑删除 |
属性 | FPROPERTY | 二进制流 | 组织单元相关信息的二进制流表示,同TORGCONTENT(组织机构内容表)表中的FCONTENT字段 |
1.12 组织机构表达式
通常,查找组织单元只能靠组织机构底层提供的各种函数、方法,可是提供的这些函数和方法是在枚举用户有可能的使用方式,它们的能力远远不能达到用户的需求,取到的组织单元也不能方便的参与业务运算。为了解决这一系列的问题,同时也为了给用户提供一个可操作性、可扩展性更好的组织机构系统,提出了组织机构表达式。
组织机构表达式就是通过表达式的方式来指定组织单元的范围和条件从而得到满足条件的组织单元。组织机构表达式可以嵌入到业务表达式中。它主要由组织机构表达式原子和组织机构表达式函数构成。
1.12.1 组织机构表达式原子
组织机构表达式原子就是OrgCondition,它是用来定义查找条件的,是组织机构表达式的基本元素,也是最小组成单位。OrgCondition的格式是:OrgCondition(文件条件,属性条件,索引条件)。它包括文件条件、属性条件、索引条件三个参数,这三个参数不能同时为空。
l 文件条件
每个组织单元都有一个唯一标示自己的文件名,此参数就是用来定义与文件名有关的条件的。例如:要查找文件扩展名为“.ogn”(机构)或“.dpt”(部门)的组织单元,则定义表达式原子为OrgCondition('*.ogn ; *. dpt ', '', '')。
l 属性条件
每个组织单元都有若干用于描述自己的属性,如显示名称、创建时间等,此参数就是用来定义与这些属性有关的条件的。例如:要查找组织单元的显示名称包含“销售”字样的组织单元,则定义表达式原子为OrgCondition('', :DISPLAYNAME like '%部门%', '')。
l 索引条件
在组织机构索引表中存储了有关组织单元的索引信息,此参数就是用来定义与索引有关的条件的。例如:要查找功能权限中运行功能分配了业务功能“工作任务”(此业务功能在系统空间下,URL定位字符串为“Biz:/SYSTEM/TasksFunc.Func”)的组织单元,则定义表达式原子为OrgCondition('', ' ', :OrgUnit.FuncRef = '/SYSTEM/TasksFunc.Func')。
组织机构表达式原子之间可以进行逻辑运算,例如:要查找功能权限中运行功能分配了业务功能“工作任务”,且显示名称包含“销售”的机构或部门,可以定义为OrgCondition('', ' ', :OrgUnit.FuncRef = '/SYSTEM/TasksFunc.Func') And OrgCondition('', :DISPLAYNAME like '%部门%', '') And OrgCondition('*.ogn ; *. dpt ', '', '')。当然,这三个原子可以合并为一个,此处只是为了说明原子间的逻辑运算。
组织机构表达式原子不能独立使用,它只是定义了要查找的组织单元的条件,必须配合组织机构表达式函数使用,才能使组织机构表达式完整,从而达到查找组织单元的目的。
1.12.2 组织机构表达式函数
组织机构表达式函数描述了要查找的组织单元范围。在组织机构表达式函数里通常会用到组织机构范围表达式和组织机构条件表达式这两个概念,在此先对这两个概念做一下解释:
l 组织机构范围表达式
它就是一个组织机构表达式。在组织机构表达式函数中用来限定组织单元范围。
l 组织机构条件表达式
它是由组织机构表达式原子(一个或多个)组成的,在组织机构表达式函数中用来做条件限定。
组织机构表达式函数包括以下十个:
l OrgKey
它通过部门ID、岗位ID、人员ID确定一个唯一的组织单元。OrgKey的格式是:OrgKey(部门ID,岗位ID,人员ID),三个参数不能同时都为空。例如:查找ID为BM1的部门,表达式为OrgKey('BM1', '', '')。
l OrgSelect
查找符合条件的组织单元。OrgSelect的格式是:OrgSelect(组织机构条件表达式)。其中“组织机构条件表达式”定义了要查找符合哪些条件的组织单元,在函数OrgSelect中“组织机构条件表达式”不能为空。例如:查找所有人员成员,表达式为OrgSelect(OrgCondition('*.PSM', '', ''))。
l OrgParent
查找组织单元的父。OrgParent的格式是:OrgParent(组织机构范围表达式,组织机构条件表达式,是否取所有父,是否包含自己)。其中“组织机构范围表达式”定义了要查找哪些组织单元的父,此参数不能为空;“组织机构条件表达式”定义了查找符合哪些条件的父(父要满足哪些条件),此参数可以为空;“是否取所有父”是一个值只能为True或者False的参数,当值为True时代表要取所有的父,反之当值为False时只取直接的父(第一层父);“是否包含自己”也是一个值只能为True或者False的参数,当值为True时代表取到的组织单元包含“组织机构范围表达式”定义的组织单元自身,反之当值为False时则不包含。例如:查找部门1(ID为BM1)的上级所有部门,并且包括部门1,表达式为OrgParent(OrgKey('BM1', '', ''), OrgCondition('*.DPT', '', ''), True, True)。
l OrgChildren
查找组织单元的子。OrgChildren的格式是:OrgChildren(组织机构范围表达式,组织机构条件表达式,是否取所有子,是否包含自己)。其中“组织机构范围表达式”定义了要查找哪些组织单元的子,此参数不能为空;“组织机构条件表达式”定义了要查找符合哪些条件的子(子要满足哪些条件),此参数可以为空;“是否取所有子”是一个值只能为True或者False的参数,当值为True时代表要取所有的子,反之当值为False时只取直接的子(第一层子);“是否包含自己”也是一个值只能为True或者False的参数,当值为True时代表取到的组织单元包含“组织机构范围表达式”定义的组织单元自身,反之当值为False时则不包含。例如:查找部门1(ID为BM1)下的所有的人员成员,表达式为OrgChildren(OrgKey('BM1', '', ''), OrgCondition('*.PSM', '', ''), True, False)。
l OrgFamily
查找组织单元相关的单元(相关单元包括父、子和自己)。OrgFamily的格式是:OrgFamily(组织机构范围表达式,组织机构条件表达式,是否取所有)。其中“组织机构范围表达式”定义了要查找哪些组织单元相关的单元,此参数不能为空;“组织机构条件表达式”定义了查找符合哪些条件的相关单元(相关单元要满足哪些条件)此参数可以为空;“是否取所有”是一个值只能为True或者False的参数,当值为True时代表要取所有的相关单元(所有的父、所有的子和自己),反之当值为False时只取直接的相关单元(直接父,直接子和自己)。例如:查找部门1(ID为BM1)的所有相关单元,表达式为OrgFamily(OrgKey('BM1', '', ''), '', True)。
l OrgSibling
查找组织单元的兄弟单元(在同一父单元下处于同级的组织单元)。OrgSibling的格式是:OrgSibling(组织机构范围表达式,组织机构条件表达式,是否包含自己)。其中“组织机构范围表达式”定义了要查找哪些组织单元的兄弟单元,此参数不能为空;“组织机构条件表达式”定义了查找符合哪些条件的兄弟单元(兄弟单元要满足哪些条件),此参数可以为空;“是否包含自己”是一个值只能为True或者False的参数,当值为True时代表取到的组织单元包含“组织机构范围表达式”定义的组织单元自身,反之当值为False时则不包含。例如:查找部门1(ID为BM1)的所有兄弟单元,并且包含自己,表达式为OrgSibling (OrgKey('BM1', '', ''), '', True)。
l OrgManager
在描述此函数之前,先明确几个概念:组织单元相对于其下属来说,称为其下属的管理者。对于某组织单元B,如果它被直接包含在组织单元A的管理权限中,则称组织单元A是组织单元B的直接管理者;如果组织单元B没有被直接包含在组织单元A的管理权限中,但是它的上级单元被包含在组织单元A的管理权限中,则称组织单元A是组织单元B的间接管理者。
此函数的作用就是查找组织单元的管理者。OrgManager的格式是:OrgManager(组织机构范围表达式,管理类型,是否只取直接管理者)。其中“组织机构范围表达式”定义了要查找哪些组织单元的管理者,此参数不能为空;“管理类型”定义了查找哪些业务上的管理者,此参数为空时表示查找组织上的管理者;“是否只取直接管理者”是一个值只能为True或者False的参数,当值为True时代表要取的是直接管理者,反之当值为False时既取直接管理者也取间接管理者。例如:查找部门1(ID为BM1)的组织上的直接管理者,表达式为OrgManager (OrgKey('BM1', '', ''), '', True)。
l OrgSubordination
查找组织单元的下属(管理权限中定义的下属)。OrgSubordination的格式是:OrgSubordination(组织机构范围表达式,管理类型)。其中“组织机构范围表达式”定义了要查找哪些组织单元的下属,此参数不能为空;“管理类型”定义了查找哪些业务上的下属,此参数为空时表示查找组织上的下属。例如:查找部门1(ID为BM1)下的部门经理岗位(ID为BMJL)分管的“销售”业务的下属,表达式为OrgSubordination (OrgKey('BM1', 'BMJL', ''), '销售')。
组织机构表达式的多个函数之间可以进行逻辑运算,例如:查找ID为BM1的部门以及所有的人员成员,表达式为OrgKey('BM1', '', '') Or OrgSelect(OrgCondition('*.PSM', '', ''))。
1.12.3 组织机构表达式的典型例子分析
l OrgSelect(OrgCondition('*.DPT', :DisplayName='办公室', '') AND
OrgCondition('*.PSM', :DisplayName='技术员', ''))
这个组织机构表达式的初衷是取得办公室的技术员岗位成员。但是,这样写没有任何组织单元会符合上述条件的,因为,第一个条件是限定的是显示名称为“办公室”的部门,第二个条件限定的是显示名称为“技术员”的岗位成员,没有哪个组织单元能够既是部门,又是岗位成员。应该首先取到办公室,然后取这个组织单元的子中“显示名称=技术员”的组织单元。如下:
OrgChildren(OrgSelect(OrgCondition('*.DPT', :DisplayName='办公室', '')),
OrgCondition('*.PSM', :DisplayName='技术员', ''), False, False)
l OrgSelect(OrgCondition('', , :OrgUnit.FuncRef = '/JUSTEPDEMOSYSTEM/fun_CPDG.Func'))
取所有具有某个功能(功能URL为“/JUSTEPDEMOSYSTEM/fun_CPDG.Func”)的组织单元。
l OrgSelect(OrgContion('*.PTM', :DisplayName='总经理', ''))
取所有名称为“总经理”的岗位成员。
l OrgChildren(OrgSelect(OrgCondition('','',:OrgUnit.FuncRef = '/JUSTEPDEMOSYSTEM/fun_CPDG.Func')), OrgCondition('*.psm', '', ''), True) or OrgSelect(OrgCondition('*.psm','',:OrgUnit.FuncRef = '/JUSTEPDEMOSYSTEM/fun_CPDG.Func'))
取拥有某个功能(功能URL为“/JUSTEPDEMOSYSTEM/fun_CPDG.Func”)的所有人员成员。其中:
OrgChildren(OrgSelect(OrgCondition('','',:OrgUnit.FuncRef = '/JUSTEPDEMOSYSTEM/fun_CPDG.Func')), OrgCondition('*.psm', '', ''), True) 表示取所有分配了该功能的组织单元的类型为人员成员的子,即取得的人员成员是通过继承拥有的该功能;
OrgSelect(OrgCondition('*.psm','',:OrgUnit.FuncRef = '/JUSTEPDEMOSYSTEM/fun_CPDG.Func')) 表示取所有分配了该功能的人员成员。
1.12.4 组织机构表达式在业务流程中的使用
当组织机构表达式在流程中作为任务执行者表达式使用的时候,在组织机构表达式函数的基础上流程扩充出了查找任务执行者的函数,这些扩充的函数只能在流程中使用,如:GetProcUnitExecutor、GetProcUnitExecutorPositionMember、GetProcUnitExecutorPosition、GetProcUnitExecutorDept、GetProcUnitExecutorOgn等。
1.13 组织机构权限的实现原理
1.13.1 组织机构权限的存储
所有组织机构的权限:功能、管理、数据和操作权限,都是基于组织单元进行存取访问的。因此,权限的存储,也是依附于组织单元进行的。
组织单元权限分为两种方式进行存储的:流方式、索引方式。其中,管理权限、功能权限以这两种方式存储;而数据权限和操作权限以流方式存储,没有存储索引。
流方式把TOrgUnit对象状态信息进行序列化,然后以文件流的方式作为一个Blob字段的内容存储在组织机构内容表(TORGCONTENT)中。使用权限的时候,先通过虚拟文件系统从数据库中获得文件流,然后再反序列化成TOrgUnit对象,然后访问Module属性中相应的权限属性即可。Module属性及其权限属性的详细内容,请参考1.13.2 。
关于流方式存储时的文件流的格式和内容,请参考下面的实例:
代理权限 |
管理功能权限 |
|
|
|
object TOrgModule RunFuncAlloc = < item FuncURL = 'Biz:/JUSTEPCOOPERATIONSYSTEM/CRMSPACE/CustomerArchvieFunc.Func' end item FuncURL = 'Biz:/JUSTEPCOOPERATIONSYSTEM/CRMSPACE/LinkManFunc.Func' end item FuncURL = 'Biz:/JUSTEPCOOPERATIONSYSTEM/CRMSPACE/SaleChanceFunc.Func' end item FuncURL = 'Biz:/JUSTEPCOOPERATIONSYSTEM/CRMSPACE/CustomerComunicateFunc.Func' end item FuncURL = 'Biz:/JUSTEPCOOPERATIONSYSTEM/CRMSPACE/CustomerTrackTaskFunc.Func' end item FuncURL = 'Biz:/JUSTEPCOOPERATIONSYSTEM/CRMSPACE/SChemeFunc.Func' end > ManageFuncAlloc = <> Subordinations = < item DeptID = 'JS99' end item PositionID = 'BMCY' end> Deputies = <> object DataSetPolicy1: TDataSetPolicy BizRange.Text = 'CRM_CUSTOMER.PROVIENCE = '#39'130000'#39 ApplyCheckConstraint = True CheckErrorMessage = #8220#23458#25143#26723#26696#34920'.'#30465#20221#8221#24517#39035#26159#39'130000'#39 Operations = [ooModify, ooInsert] Target.Reference = '@Biz:/JUSTEPCOOPERATIONSYSTEM/CRMSPACE/CustomerArchivesInfo.Info' + '/sdsDetail.DataSet' ReadOnlyFields.Strings = ( 'CUSTOMERID' 'CUSTOMERNAME') end end |
索引方式是为了满足某些特定信息的快速查找而专门提出的,例如查询存储在流中的功能权限信息。它把信息存储在组织机构索引表(TORGINDEX)中,每项权限在索引表中都存储了一条记录,每条记录包括三个信息:组织单元的GUID(表明是哪个组织单元的索引信息)、索引类别ID(表明是哪类索引)、索引值。
各种索引类别、索引ID及其索引值的详细说明如下表所示:
表1.12 各类索引ID及索引值描述表
类别 | 索引类别ID | 索引值描述 | |
管理权限 | 组织管理权限 | “OrgUnit.Subordination” | 所分配下属的URL定位字符串 |
业务管理权限 | “OrgUnit.Subordination”+“.”+业务类型字符串 | ||
功能权限 | 管理功能 | “FuncAlloc.Manage” | 所分配功能的URL定位字符串 |
运行功能 | “OrgUnit.FuncRef” |
上表中的几种索引信息的保存和维护,外部不需要关心,由组织机构系统底层在保存组织单元时自动进行维护。
关于索引方式存储的具体实例,可以参考下图:
图 1.10组织机构索引表的示例数据
1.13.2 组织单元及其权限存储类的类设计
所有的权限都是在组织单元上定义的,因此,在存取访问权限时,也是基于组织单元进行的。在设计类时,组织单元类TOrgUnit上公布了用于存储组织单元权限的Module属性,此属性是TOrgModule类型,专门负责存储分配到组织单元上的各种权限。
组织单元类和后代类、以及权限保存类之间的关系如下图所示:
图 1.11组织单元类和后代类及其存储模块类(TOrgModule)的关系
1. TOrgUnit类(组织单元)
TOrgUnit = class
private
FBizURL: TReadOnlyBizURL;
FOrgKind: TOrgUnitKind;
FDisplayName: string;
FAttribute: TOrgAttribute;
FModule: TOrgModule;
function GetAttribute: TOrgAttribute;
function GetModule: TOrgModule;
function GetID: string;
function GetParent: TOrgUnit;
procedure Save;
protected
function CreateModule: TOrgModule; virtual;
function GetDisplayName: string; virtual;
procedure SetDisplayName(const Value: string); virtual;
public
constructor Create(const ABizURL: TBizURL);
destructor Destroy; override;
property Attribute: TOrgAttribute read GetAttribute;
property Module: TOrgModule read GetModule;
property BizURL: TReadOnlyBizURL read FBizURL;
property OrgKind: TOrgUnitKind read FOrgKind;
property ID: string read GetID;
property DisplayName: string read GetDisplayName write SetDisplayName;
property Parent: TOrgUnit read GetParent;
end;
Module属性是此类的关键所在。由于不同的组织单元还可能会使用不同的Module保存权限,所以Protected部分的CreateModule方法声明为虚拟方法。
组织机构系统保存组织单元时,最终调用到private部分的Save方法,此方法内负责进行常规文件属性、索引信息和权限的保存,不过,保存权限时候,是将Module属性指向的TOrgModule对象通过虚拟文件系统保存到组织对应的文件内容中。
2. TOrgModule类(组织单元存储模块)
TOrgModule = class(TComponent, IBizModuleSupport)
private
FOwnerUnit: TOrgUnit;
FFuncURLs: TStringList;
FRunFuncAlloc: TOrgFuncAllocItems;
FManageFuncAlloc: TOrgFuncAllocItems;
FSubordinations: TOrgSubordinationItems;
FDeputies: TOrgDeputyItems;
procedure SetFuncURLs(const Value: TStringList);
procedure SetRunFuncAlloc(const Value: TOrgFuncAllocItems);
procedure SetManageFuncAlloc(const Value: TOrgFuncAllocItems);
procedure SetSubordinations(const Value: TOrgSubordinationItems);
procedure SetDeputies(const Value: TOrgDeputyItems);
protected
procedure LoadFromStream(AStream: TStream);
procedure SaveToStream(AStream: TStream);
{ IBizModuleSupport }
function GetLoading: Boolean;
function GetLoadingBizURL: TBizURL;
function GetBizURL: TBizURL;
public
constructor Create(const AOwnerUnit: TOrgUnit); reintroduce;
destructor Destroy; override;
procedure GetDataPolicy(APolicies: TList);
procedure GetOperationPolicy(APolicies: TList);
property OwnerUnit: TOrgUnit read FOwnerUnit;
published
property RunFuncAlloc: TOrgFuncAllocItems read FRunFuncAlloc write ……;
property ManageFuncAlloc: TOrgFuncAllocItems read FManageFuncAlloc write ……;
property Subordinations: TOrgSubordinationItems read FSubordinations write ……;
property Deputies: TOrgDeputyItems read FDeputies write SetDeputies;
end;
图 1.12 TOrgModule类和内部权限项类的关系
此类最重要的是published部分的4个权限项目集合类:RunFuncAlloc(运行功能权限)、ManageFuncAlloc(管理功能权限)、Subordinations(管理权限)和Deputies(代理权限),这4个类都从TCollection继承,相应的项目类从TCollectionItem继承。
在此需要特别说明的是:数据权限和操作权限的存取问题。在类的published部分,我们看不到类似Subordinations或者RunFuncAlloc之类的属性,那么数据权限和操作权限是怎么存取的呢?
对于数据权限,通过往Module中插入数据集策略(TDataSetPolicy)和数据语义策略(TSememicDataPolicy)业务组件的方式来实现的,这么做,主要是为了重用这两个业务组件来统一实现数据权限扩展功能;操作权限同理,也是往Module中插入业务操作策略(TOperationPolicy)组件来实现的。关于数据集策略(TDataSetPolicy)、数据语义策略(TSememicDataPolicy)和业务操作策略(TOperationPolicy)这三个业务组件的详细介绍,请参考本文尾的附录,限于篇幅和所讲内容,此节不进行详细介绍。
3. TDept类(部门)
TDept = class(TOrgUnit)
end;
部门类比较简单,用于表示机构和部门这两种组织单元。
4. TPerson类(人员)
TPerson = class(TOrgUnit)
public
property Password: string read GetPassword write SetPassword;
property LoginID: string read GetLoginID write SetLoginID;
end;
人员类扩展了LoginID(登录名)和Password(密码)两个属性。需要特别说明的是:这两个属性通过文件属性保存到组织机构文件属性表(TOrgFileAttribute)中,而不是以流的方式保存到文件内容中。
5. TPosition类(岗位)
TPosition = class(TOrgUnit)
end;
6. TPositionMember(岗位成员)
TPositionMember = class(TOrgUnit)
private
function GetPosition: TPosition;
protected
function GetDisplayName: string; override;
procedure SetDisplayName(const Value: string); override;
public
property Position: TPosition read GetPosition;
end;
7. TPersonMember(人员成员)
TPersonMember = class(TOrgUnit)
private
function GetPerson: TPerson;
protected
function GetDisplayName: string; override;
procedure SetDisplayName(const Value: string); override;
public
property Person: TPerson read GetPerson;
end;
8. TWorkGroup(工作组)
TWorkGroup = class(TOrgUnit)
private
function GetMembers: TOrgMemberItems;
procedure SetMembers(const Value: TOrgMemberItems);
function GetKind: string;
procedure SetKind(const Value: string);
protected
function CreateModule: TOrgModule; override;
public
property Members: TOrgMemberItems read GetMembers write SetMembers;
property Kind: string read GetKind write SetKind;
end;
(工作组目前的设计和实现方式都不是太好,还需要进一步根据需求进行修改。)
1.14 组织机构权限的应用
组织机构权限在登录系统时候、或之后应用。当使用一个合法的用户名和口令登录系统后,会得到一个用户(User)对象,从此对象上能够获取到该用户在组织机构中定义的所有权限。
l 拥有的功能列表 l 拥有的管理权限列表 l 拥有的数据权限定义 l 拥有的操作权限定义 l 对应的人员成员,及所属的岗位和部门信息 l …… l |
平台 |
用户(TUser类实例对象) |
功能权限 |
管理权限 |
数据权限 |
操作权限 |
组织机构 |
登录 |
得到 |
权限应用和控制 |
1.15 附录1 数据集策略(DataSetPolicy)和数据语义策略(SememicDataPolicy)组件
1.15.1 数据集策略(DataSetPolicy)
数据集策略(DataSetPolicy)组件用于约束业务信息内指定的业务数据集,可以限制业务数据集获取数据的范围、只读字段、隐藏字段以及是否允许对其进行插入、删除、修改等动作。
数据集策略被应用到业务功能、组织机构和业务流程的功能环节中。业务信息必须在功能中被引用才能够使业务信息中的业务数据集受到数据集策略的约束。数据集策略最终是要被施加到具体的数据集对象上的,当数据集打开时,会发送业务消息到业务功能、组织机构和业务流程,以便获取到约束该数据集的策略后将其应用到自身上。当数据集打开后,如果数据集策略发生改变,则等到该数据集再次打开后新的约束才会起作用。
设置信息策略需要以下几个步骤:
1) 定义目标
目标(Target)属性用于确定数据集策略所要施加到哪个业务数据集,即指定被约束数据集的位置,业务数据集必须位于业务信息中,而业务信息又必须被业务功能所引用。。由于数据集策略可以被应用到很多环境下,在不同环境下目标属性所能够指定的数据集也具有同的含义:
l 业务功能中,可以直接在功能中为已分配信息内的数据集施加数据集策略;
l 组织机构中,可以在组织机构中的成员或岗位上为其所分配的业务功能中的业务信息内的数据集施加数据集策略;
l 业务流程中,可以为流程的功能环节所对应的业务功能中的业务信息内的数据集施加数据集策略。
2) 定义施加给数据集的策略
数据集策略中包括了对数据集获取数据的范围上的约束、表现上的约束以及操作上的约束:
l 数据范围(Range)、应用数据范围(ApplyRange)
l 隐藏字段(HiddenFields)、只读字段(ReadOnlyFields)
l 数据操作权限(Operations)、应用约束条件(ApplyCheckConstraint)、约束错误提示(CheckErrorMessage)
这些约束最终被应用到指定的目标数据集上。
当业务数据集打开时,会向其父环境发送业务消息,并可获取到应用到该业务数据集上的数据策略(数据策略包括数据集策略和数据语义策略)。然后将这些数据策略合并,一次性应用到数据集中。其合并原则如下表:
表1.13 数据策略的合并原则
策略属性 | 合并规则 | 描述 |
Range | AND | 两个Range合并时使用AND操作符进行合并。当ApplyRange为True时Range才参与合并。 |
ApplyRange | 不合并 | 用于控制Range是否参与合并。当为False时Range不会被应用到数据集上。 |
ApplyCheckConstraint | 不合并 | 用于控制是否将Range转换为数据集的“数据约束条件” |
CheckErrorMessage | 不合并 | 用于描述由Range转换为数据集的“数据约束条件”的错误提示信息。 |
HiddenFields | OR | 只要有一个数据策略设置了某个字段为隐藏,则该字段为隐藏字段。 |
ReadOnlyFields | OR | 只要有一个数据策略设置了某个字段为只读,则该字段为只读字段。 |
Operations | AND | 必须全部的数据策略都允许某种操作(插入、删除、修改),数据集才可能会允许做该操作。 |
DataSetPolicy组件的类名是TDataSetPolicy,它继承于TBaseDataPolicy类。具有数据策略的基本特性。下面的表列出的是TDataSetPolicy类的属性。
表1.14 TDataSetPolicy的属性
属性名 | 用途 |
Target | 数据集策略的目标,以确定其要约束的业务数据集。 |
Range | 设置对数据集施加的过滤条件。 |
ApplyRange | 是否应用过滤条件到目标数据集上。 |
ApplyCheckConstraint | 是否将数据范围(Range)转换为业务数据集中的数据约束条件。 |
CheckErrorMessage | 设置数据约束条件所对应的错误提示信息。 |
HiddenFields | 设置在目标数据集中需要隐藏的字段。 |
ReadOnlyFields | 设置在目标数据集中需要只读的字段。 |
Operations | 设置目标数据集所允许的操作。ooModify:修改;ooInsert,:插入;ooDelete:删除 |
Target属性只允许选择一个业务数据集作为目标。
Range属性中指定了为业务数据集施加的范围约束,其值最终会被应用到业务数据集发往服务器的查询SQL语句的WHERE部分,其与原始的WHERE部分是以AND关系合并的。
ApplyRange属性用于控制是否要将Range值应用给目标数据集。默认值为True。只有为True时才应用Range。
ApplyCheckConstraint属性的默认值为False。当为True时,会将Range条件转换为目标数据的数据约束条件(CheckConstraint)属性;为False时,则不会将Range转换为数据约束条件。其数据约束条件触发时的出错提示由CheckErrorMessage属性指定。
另外,简单的数据约束条件在数据集中,还会被自动转换成业务字段的自动填充。例如,Range为’ZD1 = 1’,如果ApplyCheckConstraint为True,则业务数据集的数据约束条件中就会多了一个约束条件,当用户修改ZD1的值为2时,就会提示CheckErrorMessage属性中的错误信息,并且当用户添加一条记录时,ZD1的值会被自动填充为1。
HiddenFields和ReadOnlyFields属性用来设置目标数据集中,被数据集策略所约束的隐藏字段和只读字段。最终会合并到数据集的HiddenFields和ReadOnlyFields中。
Operations属性用于约束目标数据集是否允许修改、插入、删除,应用到业务数据集后,业务数据集会根据此设置和业务数据自身上的设置来确定是否允许插入、删除和修改。在数据集上判断是否允许插入、删除和修改可以使用CanInsert 、CanDelete、CanEdit方法。
1.15.2 数据语义策略(SememicDataPolicy)
数据语义策略(SemenicDataPoliy)组件用于约束业务信息内所有业务数据集、甚至可以约束某个空间下所有信息内的所有业务数据集,可以限制业务数据集获取数据的范围、只读字段、隐藏字段以及是否允许对其进行插入、删除、修改等动作。其权限的种类与数据集策略一样,但由于数据语义策略针对的目标是多个业务数据集,而这些业务数据集可能位于不同的业务信息中和不同的业务空间下,所以数据语义策略不会去理解某一个业务数据集中的具体字段,而是采用语义层的定义对数据集进行约束。
所谓语义层的定义指的是业务元素(BizElement)和业务数据库中表内的字段定义(BizFieldDef),下面介绍一些这两种语义层的定义在数据语义策略中的应用:
l 业务元素可以代表一些具有相同业务含义的字段,所代表的这些字段可以是字段定义(BizFieldDef)、也可以是数据集中的用户数据字段(TUserDataField)。业务数据集中的业务字段(BizField)可能会对应到业务数据库中表内的某个字段定义,用户数据字段也是数据集业务字段的一部分,也就是说业务元素最终可代表数据集中的实际字段。
数据范围(Range)属性值必须使用语义条件,语义条件则是指带有业务元素的条件表达式,其中不能包含具体的字段名。
l 字段定义可以被不同的业务数据集中的业务字段所引用。字段定义被应用到数据语义策略的隐藏字段(HiddenFields)和只读字段(ReadOnlyFields)中。所选择字段定义的意义在于,字段定义可用于表示数据集中的业务字段。
数据语义策略和数据集策略被统称为数据策略。数据语义策略的设置步骤、作用范围、施加到业务数据集上的机制、以及合并规则都与数据集策略一样。不同的是,数据集策略是针对于单个业务数据集的具体内容进行约束,而数据语义策略是针对于多个业务数据集的语义上的约束。
当业务数据集应用这些数据策略时,会将具有语义含义的部分转换为针对该数据集的实际内容。业务元素和字段定义都是对字段的抽象,所以会由业务数据集负责将单个业务元素或字段定义转换为实际的业务字段。转换过程则遵循如下原则:
l 当一个业务元素(或字段定义)对应于业务数据集中多个业务字段时,会以查找到的第一个业务字段为准。
l 含有业务元素的过滤条件,当条件中包含的业务元素在业务数据集中找不到对应的业务字段时,则该条件将不会参与合并,也就是说不会将这个条件应用到业务数据集上。例如,有两个业务语义策略,并且数据范围中都使用到了包含业务元素的语义条件,如果其中一个数据语义策略的数据范围无法正确转换,则只会应用另外一个数据语义策略的数据范围到数据集上。
l 含有字段定义的字段列表中,当业务数据集无法找到其中的某字段定义与业务数据集中业务字段的对应关系时,则忽略这个字段定义,并试图转换其他的字段定义。而不是将整个列表都忽略掉。
需要注意的是,业务数据集转换业务字段和字段定义时,只会根据其现有的业务字段来判断是否能够正常转换。即使当业务数据集所涉及的表定义中,存在与之相对应的字段定义时,如果业务数据集没有选择这个字段,则也被认为业务元素或字段定义不对于业务数据集中的业务字段。
SememicDataPolicy组件的类名是TSememicDataPolicy,它继承于TBaseDataPolicy类。具有数据策略的基本特性,下表列出了它的属性。
表1.15 TSememicDataPolicy的属性
属性名 | 用途 |
Targets | 数据语义策略的目标,以确定其要约束的一些业务数据集所在的位置。 |
Range | 设置对目标数据集施加的语义过滤条件。 |
ApplyRange | 是否应用语义过滤条件到目标数据集上。 |
ApplyCheckConstraint | 是否将数据范围(Range)转换为业务数据集中的数据约束条件。 |
CheckErrorMessage | 设置数据约束条件所对应的错误提示信息。 |
HiddenFields | 设置在目标数据集中需要隐藏的字段,使用字段定义表示。 |
ReadOnlyFields | 设置在目标数据集中需要只读的字段,使用字段定义表示。 |
Operations | 设置目标数据集所允许的操作。ooModify:修改;ooInsert,:插入;ooDelete:删除 |
Targets属性允许选择一个或多个业务信息、业务信息空间、业务空间。用于表示其所约束的业务数据集所在的位置范围。被选择的业务信息、业务信息空间、业务空间下的所有业务数据集都属于数据语义策略的最终目标。业务语义策略的目标也可以为空,为空时表示其所在环境中下的所有业务数据集,例如,在业务功能中的、未指定目标业务语义策略,则表示该策略会约束到这个功能下的所有已分配信息内的业务数据集。
Range属性中指定了为所有目标数据集施加的范围约束,这个范围用一个语义条件来表示,在应用到业务数据集后,由业务数据集将其转换为最终的过滤条件,并且会将整个条件应用到业务数据集发往服务器的查询SQL语句的WHERE部分,其与原始的WHERE部分是以AND关系合并的。
ApplyRange属性用于控制是否要将Range值应用给所有目标数据集。默认值为True。只有为True时才应用Range。
ApplyCheckConstraint属性与数据集策略的ApplyCheckConstraint属性作用一样。只不过是在转换成业务数据集的数据约束条件前,有一个将语义条件转变为实际条件的过程。
HiddenFields和ReadOnlyFields属性用来设置所有目标数据集中,被数据语义策略所约束的隐藏字段和只读字段,这些字段在数据语义策略中是使用字段定义描述的,由业务数据集负责转换成对应的实际字段。最终也会合并到数据集的HiddenFields和ReadOnlyFields中。
Operations属性用于约束所有目标数据集是否允许修改、插入、删除,应用到业务数据集后,业务数据集会根据此设置和业务数据自身上的设置来确定是否允许插入、删除和修改。在数据集上判断是否允许插入、删除和修改可以使用CanInsert 、CanDelete、CanEdit方法。