PowerBuilder设置操作员对菜单项的操作权限

来源:互联网 发布:咏春拳软件 编辑:程序博客网 时间:2024/05/20 14:20

问题的提出:作者在从事“住房公积金管理系统”的开发过程中,曾经遇到如下用户需求:1、公积金管理中心及其下属缴存单位要使用不同的管理功能模块;2、同一单位的操作员,可以通过级别来控制其对某些功能模块的使用,以此实现其业务的分工及其责任的界定;3、操作员级别的界定因单位不同,具体要求也有差别,因此,对此操作权限的控制要具有充分的灵活性和随意性;
思路:1、将系统的所有功能模块封装在系统菜单中,以便统一控制;2、所有需要控制的功能菜单项,都能通过操作员权限开关进行设置;3、增加、删除或修改菜单项相关属性后,能自动变更控制项目,实现其自适应性。
实现过程如下:
1.
数据结构
l
创建操作员表 T_operators

 

字段名称

 

 

数据类型

 

 

说明

 

 

Oper_id

 

 

Char(3)

 

 

操作员编号 3位字符

 

 

Oper_name

 

 

Char(8)

 

 

操作员姓名 8位字符

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Flag_power

 

 

Char(60)

 

 

操作员权限60位字符,分别对应于60个功能菜单项的执行开关(1 0关)

 



l
创建菜单项控制表 T_menu

 

字段名称

 

 

数据类型

 

 

说明

 

 

menu_id

 

 

Integer

 

 

菜单项目编号 整数型

 

 

menu_name

 

 

Char(30)

 

 

菜单项目名称 30位字符

 

 

Menu_flag

 

 

integer

 

 

菜单项的执行开关(1 0关)

 



2.
创建系统菜单 m_frame
(如图)
假设“支取申请”功能仅限于由缴存单位使用,即需要纳入功能控制范围,则设置其Tag属性为1(整数型,对应于T_menu表的“menu_id”字段,在系统菜单中,该值不能重复),而“表格打印”项属于公共使用功能,不需纳入功能控制范围,因此,不设置Tag属性。

3.
创建全局函数F_fillmenu(menu sysmenu)
参数:sysmenu
menu对象型
功能:根据系统菜单,填充菜单控制表T_menu。仅将菜单项的Tag值为数值型的菜单项插入该表,因此对不需要功能控制的菜单项,可不设置其Tag属性。
源码如下:
定义全局变量:
Boolean
Gb_init=TURE
//控制“菜单控制表T_menu”的初始化
Datastore
ds_power
定义局部变量:
String
ls_opid,mysmenu,ls_name,ls_powerno,ls_syntax,ls_error
Integer
nrow,li_opid,i,j,curlevel,sublevel,pos,CurRow
Boolean
access

if Gb_Init then
//“菜单控制表T_menu”初始化

delete from T_menu ;
//删除菜单控制表

if sqlca.sqlcode < 0 then

messagebox(“系统提示”,“删除菜单控制表错误!”)

return –1
else

commit;

endif

ds_power=create datastore

ds_power.DataObject="dw_menu"
//菜单控制表t_menu 的数据窗口

ds_power.settransObject(sqlca)

ds_power.reset()

Gb_Init=False
end if
curlevel=upperBound(sysmenu.item)
for i= 1 to curLevel

ls_name= sysmenu.item.text

if ls_name='-' then
//跳过菜单分割线

continue

end if

ls_powerno=sysmenu.item.tag

if IsNumber(ls_powerno) then//如果Tag属性值为数值型,则纳入功能控制

pos=integer(ls_powerno)

ls_name=sysmenu.item.text

for j=1 to ds_power.RowCount()
//检查菜单项目编号是否重复

if ds_power.object.no[j]=pos then

messagebox("Error","菜单编号["+string(pos)+'__'+ls_name+"]重复!"+'~n~n'+
'此项将被忽略!')

exit

end if

next

if j>ds_power.RowCount() then
//如果不重复,插入菜单控制表

CurRow=ds_power.insertRow(0)

ds_power.SetItem(CurRow,"menu_id",pos)

ds_power.SetItem(CurRow,"menu_flag",0)

ds_power.SetItem(CurRow,"Menu_Name",ls_name)

end if

end if

sublevel=upperBound(sysmenu.item.item)
//检查子菜单项

if sublevel>0 then


Init=False

f_FillMenu(sysmenu.Item)

//递归调用

end if
Next
ds_power.update()
if sqlca.sqlcode < 0 then

messagebox(“系统提示”,“保存菜单控制表错误!”)

return –1
else

commit;

endif
return 0
4.
创建全局函数F_SetMenu(menu sysmenu)
参数:sysmenu
menu对象型
功能:根据操作员的权限控制字符串,设置菜单项是否可用
源码如下:
定义全局变量:
string
Gs_powerflag
//操作员的权限控制字符串,第n位对应t_menu
//表中menu_id=n 的菜单项,值=1开启0关闭
定义局部变量:
String
ls_opid,mysmenu,ls_name,ls_powerno
Integer
nrow,li_opid,i,j,curlevel,sublevel,pos
Boolean

access
curlevel=upperBound(mymenu.item)
for i= 1 to curLevel

ls_name= mymenu.item.text

if ls_name='-' then

continue

end if

access=TRUE

ls_powerno=mymenu.item.tag

if IsNumber(ls_powerno) then

pos=integer(ls_powerno)

if mid(gs_powerflag,pos,1)='0' then
//=1开启0关闭

access=False

end if

end if

ls_name=mymenu.item.text

if
access then
//设置具体菜单项的可用性

if mymenu.item.visible then

mymenu.item.enabled=TRUE

mymenu.item.ToolBarItemVisible=TRUE

else

mymenu.item.enabled=FALSE

mymenu.item.ToolBarItemVisible=FALSE

end if

else

if mymenu.item.Visible then

mymenu.item.enabled=FALSE

mymenu.item.ToolBarItemVisible=FALSE

end if

end if

sublevel=upperBound(myMenu.item.item)

if sublevel>0 then


F_SetMenu(MyMenu.Item)
//递归调用

end if
Next
return 0
5.
在系统中的具体应用
l
菜单项目设置
进入系统连接数据库成功后,出现操作员注册画面,登录成功后,从操作员表T_operators中,取出权限字段内容存入全局变量Gs_powerFlag,调用F_SetMenu()进行菜单项目设置即可。在操作员注册窗口中具体实现如下:
menu
menu_system
menu_system=w_frame.menuid
//w_frame为系统主窗口 MdiHelp!
:
操作员登录处理
:
F_SetMenu(menu_system)
//菜单项目设置
l
操作员权限设置(如图)


左边为操作员列表(T_operators)数据窗口dw_1,右边为菜单控制项目(T_menu)数据窗口dw_2,其中T_menu.menu_flag字段设置为CheckBox风格,左边选中操作员后,取出其权限控制串T_operators.flag_power,设置菜单控制项目的开关字段T_menu.menu_flag,再对该字段重新修改后,单击“保存”按钮,改写操作员的T_operators.Flag_power字段。上图中的T_menu.menu_flag的设置,对应于T_operators.flag_power的第18—26位为:011011011
其中:Dw_1.RowFocusChanged事件的编码如下:
int
ls_opid,li_row,li_right,i,j,li_currow
string

ls_powerflag
li_currow=dw_1.getrow()
ls_powerflag = dw_1.GetItemstring(li_currow, "flag_power")
li_row= dw_2.Retrieve()
gs_powerflag=ls_powerflag
for i=1
to li_row

li_right=integer(mid(ls_powerflag,i,1))

dw_2.setitem( i,"flag",li_right)
next
保存”按钮clicked事件的编码如下:
String
ls_user, ls_pass,ls_power
Int i, rcnt, grow,iops
IF dw_1.ModifiedCount() < 1 and dw_2.modifiedCount()<1 then Return
grow = dw_1.GetRow()
rcnt = dw_2.RowCount()
ls_power=Fill("0",100)
//"000...0" len=100
FOR i = 1 TO rcnt

ipos=dw_2.GetItemNumber(i, "no")
//菜单项编号

ls_flag=string(dw_2.GetItemNumber(i, "flag"))

ls_power=Replace(ls_power,ipos,1,ls_flag)

NEXT
dw_1.SetItem(grow,"PowerFlag",ls_power)
dw_1.update()
IF Sqlca.sqlcode <> 0 THEN

Rollback;

MessageBox("系统提示", "保存操作员失败!")
ELSE


Commit;
END IF
本程序在Windows 2000/PowerBuilder 8.0下调试通过

原创粉丝点击