大放血高分求方案!!MIS系统的权限管理方案。(100分)

  • 主题发起人 主题发起人 王森章
  • 开始时间 开始时间
大家一起干。
 
我现在也正在准备做一个权限控制的,可一直也没有好方案,关注!!!
 
to 南宫吹云:
我认为zlj555的意思是这样的,用一个二进制数的每一位作为一种权限。
不知道理解正确否。

 
同意LiZhongYu的看法。
例如先按部门分组,再按职务分级,再按...
如果组织的好,用二维或三维表的方法容易管理
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1772991
 
看看这个方法是否可以
--------------------------
1、 权限管理表单设计
SYSTEM_PRIVILEGES:记录系统中所有需要进行权限设置的菜单或按钮的信息。
表单结构如下:
ITEM_CHILD,NAME_CHILD,W_CHILD,PRIVILEGE,NAME_PARENT,W_PARENT
说明如下:
ITEM_CHILD:
整个权限表在程序中将以TREEVIEW形式显示,该字段存储菜单或按钮的显示名称,如:成品入库单(菜单),新增(按钮)等.
NAME_CHILD:
记录菜单或按钮的NAME属性.如:M_CPRK(菜单),B_ADD(按钮)
W_CHILD:
记录菜单或按钮所在的WINDOW的NAME属性.
W_CHILD字段和NAME_CHILD字段唯一决定了一个菜单或按钮.(因为不同的窗口上的按钮或菜单的NAME属性可能相同,而WINDOW的NAME属性在整个程序中是唯一的)
PRIVILEGE
读取用户权限时使用,见后述
NAME_PARENT
对菜单或按钮的含义有所不同,分别叙述如下:
菜单:
菜单的NAME属性,NAME属性为NAME_CHILD的菜单由它直接展开.
按钮:
按钮的NAME属性,NAME属性为NAME_CHILD的按钮所在的WINDOW由它直接打开.
W_PARENT
NAME属性为NAME_PARENT的按钮或菜单所在的WINDOW
整张表由NAME_PARENT,W_PARENT相关联,构成一个TREEVIEW数据结构,这样菜单的级数和窗口的嵌套层数没有任何限制可以进行任意的权限设置
示例数据如下:
ITEM_CHILD ,NAME_CHILD, W_CHILD, NAME_PARENT, W_PARENT, STYLE
业务部 BUSS_DEPT W_MAIN M
工程部 ENG_DEPT W_MAIN M
业务信息 BUSS_INFO W_MAIN BUSS_DEPT W_MAIN M
材料入库 MAT_IN W_MAIN ENG_DEPT W_MAIN M
新增 ADD W_INFO BUSS_INFO W_MAIN M
删除 DELETE W_INFO BUSS_INFO W_MAIN B
修改 MODIFY W_INFO BUSS_INFO W_MAIN B
查询 QUERY W_INFO BUSS_INFO W_MAIN B
新增 ADD W_IN MAT_IN W_MAIN B
删除 DELETE W_IN MAT_IN W_MAIN B
修改 MODIFY W_IN MAT_IN W_MAIN B
查询 QUERY W_IN MAT_IN W_MAIN B
帐目查询 ACCOUNT_QUERY W_ACCNT QUERY W_INFO B
其它查询 OTHERS_QUERY W_ACCNT QUERY W_INFO B

因[业务部]和[工程部]是系统主窗口W_MAIN的顶级菜单,故其无NAME_PARENT及W_PARENT

则该表数据在TREEVIEW中显示如下
财务部
业务信息
新增
删除
修改
查询
帐目查询
其它查询
工程部
材料入库
新增
删除
修改
查询
注:
上面图中项目前都有一个CHECKBOX

USER_PRIVILEGES
该表记录系统用户所具有的权限,结构如下
USER_ID, NAME_CHILD ,W_CHILD

USER_ID:系统用户的识别码
NAME_CHILD:系统用户所具有的权限项目的NAME属性,与SYSTEM_PRIVILEGES中的NAME_CHILD相对应
W_CHILD:系统用户所具有的权限项目所在WINDOW的NAME属性,与SYSTEM_PRIVILEGES中的W_CHILD相对应.

2、权限管理
系统权限管理的画面为WINDOW左右两边各是一个TREEVIEW控件,左边是系统用户的组织结构图,右边是系统权限表
点击左边TREEVIEW中的任何一个用户,则右边TREEVIEW中将显示该用户所具有的权限,若该用户具有某个权限,则该项目左边的CHECKBOX将被选中,否则相反.

权限读取过程如下:

首先系统获取选中用户的USER_ID(UID),其次从USER_PRIVILEGES表中读取USER_ID为UID的权限,每读取一项,就把SYSTEM_PRIVILEGES中NAME_CHILD,W_CHILD与USER_PRIVILEGES中的NAME_CHILD,W_CHILD相同的记录的PRIVILEGE设置为1,全部设定完毕之后,右边的TREEVIEW从SYSTEM_PRIVILEGES中读取所有记录,若该记录的PRIVILEGE的值为1,则该项目左边的CHECKBOX将处于被选中状态,也就意味着该用户具有该项权限.

权限设置(修改)如下:
若想让该用户具有某项权限,则将TREEVIEW中该项目左边的CHECKBOX选中,否则不选中.设置完毕之后,点击确认,则系统首先在USER_PRIVILEGES表中把USER_ID与当前需设置(修改)权限的USER_ID相同的权限全部删除,然后遍历权限TREEVIEW,若项目被选中,则在USER_PRIVILEGES中插入该项目.

2、 权限设置

用户登录系统后,则该用户的USER_ID将被记录在一个全局变量中(假定为UID).该用户打开任何一个WINDOW(通过菜单项或按钮),则系统将进行如下操作,
1、 判断该WINDOW是否具有菜单,若有,则遍历该菜单,每遍历一个菜单项,则记录该菜单项的NAME(M_NAME)属性,随同该菜单项所在WINDOW的NAME(W_NAME)属性,到SYSTEM_PRIVILEGES中查找NAME_CHILD为M_NAME,W_CHILD为W_NAME的项目,若未找到,则说明该项目无需通过权限控制,略过该项目,继续遍历.否则,到USER_PRIVILEGES中查找NAME_CHILD为M_NAME,W_CHILD为W_NAME的记录.若找到,则说明该用户具有该权限,则设置该菜单项为可见.否则,设置该采单项为不可见.
2、 遍历该WINDOW中的所有BUTTON,设置过程同上.

注:若用户不具有某菜单项或按钮的权限,则必须标志该菜单或按钮的某个属性(假设为:P)为FALSE,因为有些菜单项或按钮的VISIBLE属性会在程序中改变.例如,通常在进入一个WINDOW中时,该WINDOW的ADD若可用的话,则DELETE,MODIFY通常为不可用。若该用户不具备DELETE,MODIFY权限,则DELETE,MODIFY应始终不可见,但当用户新增记录并存盘成功时,通常会程序中改变DELETE,MODIFY的状态,这时这几个按钮将不仅可见而且可用,致使权限设置失效。所以若设置用户不具备权限的菜单或按钮的P属性为FALSE,则在设置菜单或按钮的状态时,应先判断该菜单或按钮的P属性,若为FALSE则不改变该菜单或按钮的状态,使权限设置可以始终有效地工作。



该模块对菜单的级数或窗口的嵌套深度无任何限制.只要在SYSTEM_PRIVILEGES中设置好数据权限权限设置就能有效地工作.若系统中新增或删除任何功能,只需修改SYSTEM_PRIVILEGES中相应的数据即可,而无须对本权限设置模块进行任何修改,方便了系统的维护.
 
如何为应用软件加入全面的功能权限控制

关键词:Delphi - MIS

如何为应用软件加入全面的功能权限控制

在软件开发中,为软件加入权限控制功能,使不同的用户有不同的使用权限,是非常重要的一项功能,由其在开发数据库方面的应用,这项功能更为重要。但是,要为一个应用加入全面的权限控制功能,又怎样实现呢?笔者在软件开发过程中,曾被此问题困挠过。大家知道,现在的应用,一般均以菜单访问功能的形式出现,按照常规的做法,只要让注册进入应用的不同用户,可以访问不同的功能菜单,从而实现功能权限的控制,但是,有这样一个问题,此种方法便无能为力,现在的应用软件,为了提高软件的易操作性,同一功能可能有多种不同的访问方式,如工具条,右键菜单等;同样,同一个功能,也可能在软件的不同地方被调用,而不仅仅被限制为用程序的主菜单来调用,这样,才能保证应用的易用性。写到这,问题已经非常清楚,对于要限制的软件功能,仅通过一次代码设计,无论在整个应用的任何地方或通过何种形式调用此功能,都能被功能权限所限制。

最近,笔者利用Delphi平台作应用开发时,通过Delphi4提供的VCL控件解决了这一问题。在了解如何实现功能权限控制之前,得先看一下Delphi4提供的新控件TActionList,通过TActionList,应用程序可以统一管理其TAction,这里的Action,可以理解为应用程序的功能。在应用的设计期间,可以通过TActionList编辑器将功能(Action)加入TActionList,将Action加入TActionList后,就可能通过Object Inspector设置Action的属性或为其建立事件句柄。在这里,我们可以用Action的OnExecute事件句柄实现具体的功能,如下代码来显示一个操作窗体:

procedure TfrmMain.SetUserExecute(Sender: TObject);

begin

frmUser.showModal;

end;

当要限定这一功能时,可能利用TAction的Enabled,将其设为False,此功能对于用户将被屏蔽掉,如果要此功能对用户不可见,则可以设定Visible为False。

当成功能的建立了TActionList后,可能有人问,如果使用其中的Action,其实,在Delphi4中,象TButton、TMenuItem、TSpeedButton、TRadioButton等控件,均有一个属性Action,正是通过它,我们可以将Menu或Button连接到TActionList中TAction,从而实现功能按钮或菜单的功能。

在理解了Delphi中的TActionList及TAction之后,就可以看看功能权限的具体实现方法。

第一步,建立两张表,一张表存储用户信息,另一张表存储权限定义。

用户信息表User结构如下:

字段名称
类型
字段说明

UserID
String
用户的ID号,为表关键字

UserName
String
用户名称

UserPassWord
String
用户口令


UserRight表结构如下:

字段名称
类型
字段说明

UserID
String
用户的ID号,为表关键字

ActionCaption
String
存储功能的名称,即Action的Caption属性值

ActionEnable
Boolean
存储功能是否可以访问,即Action的Enable 属性值

ActionVisible
Boolean
存储功能是否可见,即Action的visible属性值


第二步,增加用户时填加用户功能权限

当向User表中增加用户时,需要向UserRight中增加功能设置记录,先看看下面的实现代码:

procedure TfrmUser.N1Click(Sender: TObject);

var

i:Integer;

Action:TAction;

begin

//Add Action into user right cds.

with frmMain do begin

for i:=0 to ActionList1.actioncount-1 do begin

Action:=ActionList1.Actions;

cdsUserRight.AppendRecord([cdsUser.FieldByName('userName').AsString,TAction(Action).Caption,TAction(Action).Enabled,i]);

end;

end;

end;

在这段代码中,用到了TActionList的两个属性,一个是ActionCount,另一个是Actions。ActionCount表示TactionList中有多少功能,即Action,Actions是一个数组属性,通过索引可能访问每一个TAction,从而可以设置其具体的属性,象上面提到的Enable及Visible,从而达到限制的目的,通过这段代码,将应用程序的所有功能都加入了UserRight表中。

第三步,可以用Grid对上一步产生的表进行编辑操作

第四步,利用第二、三步产生的功能限制表UserRight,限制用户的权限,这可以在应用程序的主窗体的OnCreate 中实现。

procedure TfrmMain.FormCreate(Sender: TObject);

const

testUser='yh';

var

cdsRight:TClientDataSet;

i:Integer;

begin

//set right of function

cdsRight:=TClientDataSet.Create(self);

try

cdsRight.LoadFromFile('Right.CDS');

cdsRight.AddIndex('id','UserName;ActionCaption',[],'','',0);

cdsRight.IndexName:='id';

for i:=0 to ActionList1.ActionCount-1 do begin

if cdsRight.FindKey([TestUser,TAction(ActionList1.Actions).Caption]) then

TAction(ActionList1.Actions).Enabled:=cdsRight.FieldByName('ActionEnable').AsBoolean;

end;

finally

cdsRight.Close;

cdsRight.Free;

end;

end;

这段代码中,假设当前的用户ID为yh,同时只设定了功能的Enable属性。

最后,笔者为了演示功能权限的设定功能,制作了demo程序,感兴趣者可以向作者索取。在demo程序中,同时还使用了内存表ClientDataSet的使用方法,不用BDE建立瘦数据库应用程序。


--------------------------------------------------------------------------------

 delphi其他
利用Dll实现通用密码验证框

 
---- 在我们编制Delphi应用程序,常常需要提供一个密码验证框,对应用程序的使用者进行身份核对。如果能有一个通用的密码验证框,便能够为我们的工作节约不少的时间,更能使我们编制的程序小而快。以下的程序为你提供了这样的一个DLL文件。

//文件名为CheckPasswordForm.dpr;
编译此文件生成CheckPasswordForm.dll
library CheckPasswordForm;

uses
XcqCheck in 'XcqCheck.pas' {XcqForm};

exports
CheckPassword name 'CheckPassword';//dll入口

begin
end.


//文件名为XcqCheck.pas
unit XcqCheck;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, Mask, Menus;

type
TXcqForm = class(TForm)
XcqEdit: TMaskEdit;//密码输入框
OkBtn: TButton;
procedure OkBtnClick(Sender: TObject);
end;

var
XcqForm: TXcqForm;
Check: Boolean;//验证输入密码的正确性
function CheckPassword: Boolean;export;
//本dll文件的关键实现

implementation

{$R *.DFM}

procedure TXcqForm.OkBtnClick(Sender: TObject);
begin
if XcqEdit.Text = 'xcq' then
Check := True;
Close;
end;

function CheckPassword;export;
begin
Check := False;
XcqForm := TXcqForm.Create(Application);
//创建密码输入框
XcqForm.ShowModal;//显示密码输入框;
注意:不能用XcqForm.Show!
Result := Check;//返回给调用本dll的应用程序判断
XcqForm.Free;//释放本dll文件所占资源
end;
end.

---- 在调用以上dll中CheckPassword函数的应用程序中只需加入以下语句在implementation 后,function CheckPassword: Boolean; external 'CheckPasswordForm.dll' name 'CheckPassword';在需要进行密码验证的地方加入下面的条件语句就完全实现了密码验证的功能。
if CheckPassword then
begin
...//如XcqQuery.Open;
end;

---- 上面的程序只是一个简单的密码验证框,我们可以将密码以写入注册表或文件的方式保存,动态修改,更可以利用算术算法对密码进行简单的加密等,使要保密的数据更安全。
---- 其实,上文中如何在dll中实现窗口让我走了不少弯路,我觉得此法对大家更有意义,这是避免程序庞大的一种有效方法,不妨试试。


 
to fieldbyname:你的设计很详细,也很复杂的,实现过程太复杂,要用户为每个画面,每个按钮设权限不太现实
to all:
我以前做过一个成功的案例。
简介一下:
一、表结构:
pub_user(user_id,user_name,user_dept,...)用来存放用户
pub_sys(sys_id,sys_name,sys_title,...)用来存放系统或子系统
pub_level(sys_id,user_id,user_level)用来存放用户在某一系统中的权限级别
pub_prg(prg_sysid,prg_id,prg_ename,prg_cname,a_level,b_level,...,h_level,
a_code,b_code,...,h_code)用来存放程序的权限设定,其中a_level到h_level
存放A到H级别的用户是否可以使用本程序,a_code到h_code存放A到H级别的
用户在使用本程序时的权限,5个字符11111分别代表可新增、删除、修改、查询、特殊
二、实现方法:
1。主程序依据登录的用户,到level表中查询该用户的级别,再根据级别到prg表中查询可用的
程序列表,依据列表设定程序是否可以使用。
2。子程序中定义可新增、删除、修改、查询、特殊5个逻辑变量,主程序呼叫子程序时
把查询到的权限传入子程序。
三、优劣:
用此方案实现的权限管理只能分A到H个组的权限级别,是有限的,不过一般系统都不需要用
8种角色,所以有普遍性。
 
我也正在做些权限管理,刚开始做是一头雾水,希望继续讨论!!
 
后退
顶部