一、需求(qiú)分析(xī):l1j红软基地
1、 页面结构:
一般的管理(lǐ)系统界(jiè)面,即页面(miàn)分为三个部分,上部是有关公(gōng)司的图片信息,左边是(shì)树形菜单,左边是(shì)具体菜单对应(yīng)的页面。
2、 权限分析:结合(hé)客户的意思和实际经验(yàn),将权限分为两部分:
1》、大(dà)权(quán)限:即控制不同角色用户看到不同的树形菜(cài)单,只能看(kàn)到(dào)与该(gāi)用户(hù)角(jiǎo)色对
应的菜单(dān)权限
2》、小权限:即使某几种角(jiǎo)色的(de)拥(yōng)有相同(tóng)的左菜单权限(xiàn)。但(dàn)是根据具体的角色再细
分,控制在菜单对应(yīng)的具体页(yè)面上有不(bú)同的增、删、改、差权限(xiàn)
3、控制(zhì)Session过(guò)时(shí)的人性化
二(èr)、数(shù)据库设计(jì):
根据以上(shàng)要求,开(kāi)始(shǐ)数据库设计,需要五(wǔ)个表:用(yòng)户表(biǎo)、菜(cài)单树(shù)表、角色(sè)菜单表(biǎo)、页面表和子页面表
1、 用户表:除了包含用(yòng)户的基本信息,其(qí)中(zhōng)还有一列(liè)是‘Role’列(liè),代表该(gāi)用户的角
色,或者是(shì)用户类型
2、 菜单树表:如下图
其(qí)中PageName列就是菜(cài)单对应的页面对(duì)应的类(lèi)的名字,也就是页面类名
3、 角色菜单表:应该是用户表和菜单树(shù)表的一个间接(jiē)中间表,如(rú)下图
该表记录(lù)了不同的(de)用(yòng)户类(lèi)型对应的不同的菜单(dān)和(hé)菜单连接页面的增删改查(chá)权限,以后将根据该表来决(jué)定用户的权限。页面上的增删改(gǎi)查(chá)按钮的Enable属性(xìng)将与这(zhè)里(lǐ)的表值对应(yīng)
4、 页(yè)面表(biǎo)和子页面表(biǎo):这里为什么说子页面(miàn)表,我这里子页(yè)面(miàn)表(biǎo)的定义(yì)是相(xiàng)对(duì)页面表来说(shuō)的(de),因为页面表上有一些增删改差按钮,点击这些按钮的时候,我让他(tā)转(zhuǎn)到(或弹出)另一(yī)个(gè)页面去操作(zuò),那(nà)么(me)这些页面就成为子页面(miàn)。如下图:
页面(miàn)表
子页面表
三、代码设(shè)计与(yǔ)关(guān)键代码实现:
根据以上需求(qiú)和数(shù)据库信息(xī)来实现系(xì)统架构(gòu)设计。
1、做菜单控制比较简单(dān),仅仅(jǐn)根据sql语句(jù)选择不同角色对应的不同树而已。
2、控制Session人性(xìng)化。由(yóu)于我们(men)不能将session过时的(de)异常(cháng)信息直接呈现给客户,弄(nòng)的客户一头雾(wù)水,不(bú)知所(suǒ)措。我们需要给客户人(rén)性化(huà)的 提示信(xìn)息(xī)。
1》 解决(jué)方(fāng)案一:在(zài)每个页面判断session,这是可以(yǐ)的(de)。但是需要我们在进入每个
页面的时(shí)候都需(xū)要(yào)判断,很麻烦,也容易忘记,尤其是公(gōng)司一(yī)个团(tuán)队开发的时候(hòu),某(mǒu)个程(chéng)序员难免会忘记,以造成麻烦。
2》 解决方案二(èr):这也是我自认(rèn)为最好(hǎo)的解决方案,如果有更好(hǎo)的方案,请(qǐng)将(jiāng)你(nǐ)的方案发(fā)到我的邮箱,我将感激不尽。
也就是我让每(měi)个(gè)页面都继(jì)承一个BasePage类,而该类继承System.Web.UI.Page。该类需要重(chóng)写基(jī)类的(de)这个方法protected override void OnLoad(EventArgs e),这个方法的(de)功能是在加(jiā)载每个页面前都(dōu)要(yào)先执(zhí)行(háng)这个方法(fǎ),一切(qiē)的判断都放在这(zhè)个方(fāng)法里(lǐ)面进行,当session过时的时候,就跳到提示页面,否则(zé)进行(háng)其他判断(例如页面的(de)增删改(gǎi)查权限)然后(hòu)响(xiǎng)应浏览器端的请(qǐng)求。
3、 控(kòng)制每个页面的增(zēng)删改查权限:由于OnLoad方法的功能,我们将这(zhè)个操作也放在
这里进(jìn)行,并且在(zài)session没有过时的情况(kuàng)下(道理很简单,不(bú)再(zài)多说)。
1》、我们(men)需要一个权限(xiàn)管理的类UserPrivilege。这个(gè)类有(yǒu)一个静态字段private static DataTable tablePrivilege,它相(xiàng)当于一个(gè)Application类型的全(quán)局变量,当第一个用户登陆进来后就已经初始化(huà)。它是(shì)一个表,保存了所有用户类型(xíng)对应(yīng)的(de)页面类名字和响应(yīng)的增删改差权限,我么以后的判断都(dōu)是对这个变量进行操作(zuò)。如果(guǒ)某个用(yòng)户修改了权限表,那么这个变(biàn)量(liàng)也将(jiāng)立(lì)即更改
2》、已经基本准备好(hǎo),但是这时(shí)候OnLoad方法里应该怎(zěn)样做呢?这里要介绍一个技(jì)巧,就是(shì)怎样在获得派生类的名字(zì)呢?其实也(yě)很简单,就是利(lì)用this.GetType().Name 来获取当前成员的名字(zì),但(dàn)是这个(gè)名字与我们(men)的页面类名是有一点不(bú)同的,就是在我们的页面类名字(zì)后加了个(gè)‘_aspx’后缀(zhuì),这个信息对我们来(lái)说是(shì)很宝贵(guì)的,可以据此来(lái)获得类的名字,不(bú)在(zài)介绍。根据用户类(lèi)型(用(yòng)户登录的时候,我们已经(jīng)将用户的角色类(lèi)型保存到session里了(le))和该页面类(lèi)的名字和UserPrivilege类中的静态(tài)字段tablePrivilege就可以轻松获得该用户在(zài)该页面的具体权限。
3》、我们如何把这(zhè)个权限(xiàn)传递给具体(tǐ)的页面,这时候(hòu)我们需要在基(jī)类中定义一个受保(bǎo)护的抽象方法protected abstract void SetButtonEnable();那么继承该类的所有页面都必须(xū)实现这(zhè)个方法,然后基类调用这(zhè)个方法即可