荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: oopilix (优雅的), 信区: Visual
标  题: [zl]delphi-菜单权限控制
发信站: 荔园晨风BBS站 (Fri Jul 18 23:22:36 2003), 站内信件


*****菜单权限分配源码奉送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


http://expert.csdn.net/Expert/topic/1553/1553175.xml?temp=.9509394
--


 ※ 虚拟IP来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM:210.39.255.255]



※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 61.144.235.41]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店