用户登录  |  用户注册
首 页商业源码原创产品编程论坛
当前位置:PB创新网文章中心编程技巧Delphi

菜单权限控制:源码奉送***

减小字体 增大字体 作者:佚名  来源:本站整理  发布时间:2009-03-16 20:05:58

*****菜单权限分配源码奉送V2.0*****

针对以前版本功能有所扩展,增加了模块单元的操作控制

//使用ActionMainMenuBar、ActionManager、ActionToolBar效果更佳
//也可以MainMenu、ToolBar、ActionList的组合
数据库表:

CREATE TABLE [操作员] (
 [操作员ID] [varchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [姓名] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [口令] [varchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [级别] [tinyint] NOT NULL CONSTRAINT [DF_操作员_级别] DEFAULT (2),
 [部门ID] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [标志] [bit] NOT NULL CONSTRAINT [DF_操作员_标志] DEFAULT (0),
 CONSTRAINT [PK_操作员] PRIMARY KEY  CLUSTERED
 (
  [操作员ID]
 )  ON [PRIMARY]
) ON [PRIMARY]
GO


CREATE TABLE [操作员权限] (
 [操作员ID] [char] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [Visible] [bit] NOT NULL CONSTRAINT [DF_操作员权限_Visible] DEFAULT (0),
 [Enabled] [bit] NOT NULL CONSTRAINT [DF_操作员权限_Enabled] DEFAULT (0),
 [权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 CONSTRAINT [PK_操作员权限] PRIMARY KEY  CLUSTERED
 (
  [操作员ID],
  [功能ID]
 )  ON [PRIMARY]
) ON [PRIMARY]
GO


CREATE TABLE [权限组] (
 [权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [权限组名称] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [标志] [tinyint] NOT NULL CONSTRAINT [DF_权限组_标志] DEFAULT (0),
 CONSTRAINT [PK_权限组] PRIMARY KEY  CLUSTERED
 (
  [权限组ID]
 )  ON [PRIMARY]
) ON [PRIMARY]
GO


CREATE TABLE [权限组功能分配] (
 [权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 CONSTRAINT [PK_权限组功能分配] PRIMARY KEY  CLUSTERED
 (
  [权限组ID],
  [功能ID]
 )  ON [PRIMARY]
) ON [PRIMARY]
GO


CREATE TABLE [系统功能] (
 [功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [菜单名] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [说明] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
 [分类] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 CONSTRAINT [PK_系统功能] PRIMARY KEY  CLUSTERED
 (
  [功能ID]
 )  ON [PRIMARY]
) ON [PRIMARY]
GO

--“分类”字段的类型改为varchar(50)//原版本为bit

--增加了“操作标识”字段:由6位数字组成,
  约定:第一位:无意义,以1表示,
        第二位:增加,以1或0表示,
        第三位:修改,以1或0表示,
        第四位:删除,以1或0表示,
        第五位:查询,以1或0表示,
        第六位:打印,以1或0表示

操作标识有两层含义:1、系统功能的“操作标识”,2、操作员的的“操作标识”

操作员的的“操作标识”,例如:字符串‘110010’表示可以增加和查询,不能修改、删除和打印

系统功能的“操作标识”:必须在设计期间定义Action的操作标识,表示有没有该项功能

例如:字符串‘100011’表示该模块有查询、打印功能,没有增加、修改、删除


有效利用Action的各项属性:

Name: 功能ID
Caption:菜单名
Hint:说明
Category:分类
Tag:操作标识


定义全局变量:

var
  ActName,OperaID:TStringList; //功能ID列表,操作标识列表。变量创建过程,这里省略
  CurrentOperaID:String;       //当前操作标识


//权限分配方法
procedure TMainFrm.AssignLimit;
var
  i, j, k, TlbLen: integer;
  Ks, Ms: Boolean;
begin

  for i := 0 to ActionList1.ActionCount - 1 do //所有功能不可用
  begin
    TAction(ActionList1.Actions[i]).Visible := False;
    TAction(ActionList1.Actions[i]).Enabled := False;
  end;

  ActName.Clear;  //清除功能ID列表
  OperaID.Clear;  //清除操作标识列表

  for i := 0 to ActionList1.ActionCount - 1 do //分配权限
  begin
    if LoginFrm.CDSLimit.Locate(''功能ID'', TAction(ActionList1.Actions[i]).Name, [loPartialKey]) then
    begin
      TAction(ActionList1.Actions[i]).Enabled := LoginFrm.CDSLimit.FieldByName(''Enabled'').AsBoolean;
      TAction(ActionList1.Actions[i]).Visible := LoginFrm.CDSLimit.FieldByName(''Visible'').AsBoolean;
     
      ActName.Add(TAction(ActionList1.Actions[i]).Name);//加入功能ID
      OperaID.Add(LoginFrm.CDSLimit.FieldByName(''操作标识'').AsString);//加入操作标识
    end;
  end;

//----------------------------菜单效果------------------------------------------

  if LoginFrm.Grade = ''0'' then //超级管理员固定权限
  begin
    mmMenuInit.Visible := True; //功能初始化
    mmPopGroup.Visible := True; //权限组功能分配
    ActOperAssign.Visible := True; //操作员权限分配
    ActOperAssign.Enabled := True;
    ActSysLogQry.Visible := True; //操作员权限分配
    ActSysLogQry.Enabled := True;
  end else
  begin
    mmMenuInit.Visible := false;
    mmPopGroup.Visible := false;
  end;

  Ks := False;
  Ms := False;

  for I := 0 to MainMenu.Items.Count - 1 do //一级菜单
  begin
    for J := 0 to MainMenu.items[I].count - 1 do //二级菜单
    begin
      if MainMenu.items[I].Items[J].Count > 0 then //若存在三级菜单
      begin
        for K := 0 to MainMenu.items[I].Items[J].Count - 1 do //三级菜单
        begin
          if (MainMenu.items[I].Items[J].Items[K].Visible) and
            (MainMenu.items[I].Items[J].Items[K].Caption <> ''-'') then
          begin
            Ks := True;
            Break; //在三级菜单中若存在Visible为True则跳出循环
          end;
        end;
        MainMenu.items[I].Items[J].Visible := Ks;
        if Ks then Ms := True;
        Ks := False;
      end else
        if (MainMenu.items[I].Items[J].Visible) and
          (MainMenu.items[I].Items[J].Caption <> ''-'') then
        begin
          Ms := True; //在二级菜单中若存在Visible为True则主菜单可见
        end;
    end;
    MainMenu.items[I].Visible := Ms;
    Ms := False;
  end;

//-------------------------------快捷菜单效果-----------------------------------

  TlbLen := 0;
  j:=0;
  k:=0;
  for i := 0 to ToolBar1.ButtonCount - 1 do
  begin
    if ToolBar1.Buttons[i].Visible then
    begin
      if (j=0)and(ToolBar1.Buttons[i].Style=tbsSeparator) then
        ToolBar1.Buttons[i].Visible:=false        //屏蔽分割快捷按钮            
      else
      begin
        if ToolBar1.Buttons[i].Style=tbsSeparator then inc(k);
        if k=2 then        //如果连续排列两个分割快捷按钮
        begin
          ToolBar1.Buttons[i].Visible:=false;   //屏蔽分割快捷按钮
          k:=1;
        end else
        begin
          TlbLen:=TlbLen+ToolBar1.Buttons[i].Width;
          inc(j);
        end;
      end;
    end;
  end;
  CoolBar1.Bands[0].Width := TlbLen + 15;//15这个值是个校正值,可能不适合你
//
end;

在每个Action的执行代码中,额外加入以下代码

procedure TMainFrm.ActWareBuyPlanExecute(Sender: TObject);
begin
 CurrentOperaID:=OperaID[ActName.IndexOf(TAction(Sender).Name)];//取得当前操作员当前模块的操作标识
 ....
end;

全局函数:

//解析操作标识
function ParseOperaID(const AoperaID:string;index:integer):Boolean;
var
  TmpPos:integer;
begin
  TmpPos:=Index+1;
  if Index<1 then TmpPos:=2;  //把Index固定在1..5之间
  if Index>5 then TmpPos:=6;
  Result:=Copy(AoperaID,TmpPos,1)=1;
end;

使用方法例如:

BtnAdd.Enable:=ParseOperaID(CurrentOperaID,1);//增加
BtnModi.Enable:=ParseOperaID(CurrentOperaID,2);//修改
BtnDel.Enable:=ParseOperaID(CurrentOperaID,3);//删除

建议使用按钮的Tag属性

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

与之相关的功能列表:

1、系统功能初始化:

2、权限组功能分配:

3、操作员功能分配:

限于篇幅,源代码不再贴出,都是简单的数据库操作。

注意一点:

  操作标识的显示问题,//总不能把‘100110’显示出来吧


最后一段代码:
在数据集字段的OnGetText事件中:

var
  Str:string;
begin
  if ParseO

Tags:

作者:佚名

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
PB创新网ourmis.com】Copyright © 2000-2009 . All Rights Reserved .
页面执行时间:18,046.88000 毫秒
Email:ourmis@126.com QQ:2322888 蜀ICP备05006790号