如何在應(yīng)用系統(tǒng)中實現(xiàn)數(shù)據(jù)權(quán)限的控制功能(2)

關(guān)于數(shù)據(jù)權(quán)限的控制湘捎,可能我們在做很多大型一點的系統(tǒng)都會碰到過阎抒,可能每個人設(shè)計和解決問題的思路都有所不同,本文介紹我自己框架里面的解決思路消痛。從上一篇《如何在應(yīng)用系統(tǒng)中實現(xiàn)數(shù)據(jù)權(quán)限的控制功能》里面我們可能對權(quán)限控制和數(shù)據(jù)權(quán)限的控制有了一個初步的了解,本文接著進一步介紹在應(yīng)用系統(tǒng)中都哭,如何集成數(shù)據(jù)權(quán)限的控制功能秩伞。

1、數(shù)據(jù)權(quán)限實現(xiàn)思路分析

為了實現(xiàn)數(shù)據(jù)權(quán)限的控制欺矫,我們需要在通用的權(quán)限系統(tǒng)里面保存好對應(yīng)角色具有哪些組織機構(gòu)的數(shù)據(jù)權(quán)限纱新,然后在應(yīng)用系統(tǒng)中調(diào)用API進行過濾數(shù)據(jù)處理即可。
為了實現(xiàn)以上的功能需求脸爱,我們需要在權(quán)限系統(tǒng)里面,角色控制哪里增加一個數(shù)據(jù)權(quán)限的數(shù)據(jù)存儲未妹。
實際的應(yīng)用系統(tǒng)簿废,當用戶登陸成功后,我們獲取并記錄好其可以管理的公司或者部門络它,如果是主管的角色族檬,可能有多個公司的數(shù)據(jù)可以管理,那么可以在程序的頂部化戳,讓用戶選擇管理那個公司的數(shù)據(jù)即可单料,如果切換公司,那么刷新現(xiàn)有的界面數(shù)據(jù)顯示就可以了。



在用戶成功登陸后扫尖,我們可以記錄用戶的相關(guān)權(quán)限控制信息白对,如他所能控制數(shù)據(jù)的公司或者部門,把它記錄下來换怖。

Portal.gc.CompanyList = BLLFactory<RoleData>.Instance.GetBelongCompanysByUser(info.ID);
List<int> deptList = BLLFactory<RoleData>.Instance.GetBelongDeptsByUser(info.ID);
Portal.gc.DeptList = deptList;

然后存儲用戶默認的公司ID甩恼,并根據(jù)用戶是否為管理員(超級管理員、公司管理員)狰域,然后構(gòu)造一個通用的過濾條件媳拴,放到全局緩存里面,方便各個模塊使用兆览,如下代碼所示铐炫。

//設(shè)置選定的公司ID(默認為用戶所在公司的ID)
Cache.Instance["SelectedCompanyID"] = info.Company_ID;
//設(shè)置過濾條件給界面基類使用
string filterCondition = string.Format(" Company_ID = '{0}' ", info.Company_ID);
if (!Portal.gc.IsAdmin)
{
    if (deptList.Count > 0)
    {
        filterCondition += string.Format(" AND Dept_ID IN ({0})", string.Join(",", deptList));
    }
    else
    {
        filterCondition += string.Format(" AND Creator = '{0}' ", info.ID);
    }
}
Cache.Instance["DataFilterCondition"] = filterCondition;

在主界面的時候典奉,我們可以根據(jù)用戶所能管理的公司數(shù)據(jù),在頂部初始化公司列表,方便切換選擇模狭,以下是初始化的代碼。

//添加受管理的公司機構(gòu)
//判斷如果用戶管理的公司數(shù)據(jù)多于一個玉工,那么就顯示選擇單位列表缚俏,并綁定公司數(shù)據(jù)
if (Portal.gc.CompanyList.Count > 1)
{
    this.repositoryCompanyItem.Items.Clear();
    foreach (int company in Portal.gc.CompanyList)
    {
        OUInfo companyInfo = BLLFactory<OU>.Instance.FindByID(company);
        if (companyInfo != null)
        {
            this.repositoryCompanyItem.Items.Add(new CListItem(companyInfo.Name, companyInfo.ID.ToString()));
        }
    }

    //多于一個顯示公司下拉列表
    this.barCompanyItem.Visibility = DevExpress.XtraBars.BarItemVisibility.Always;
}
else
{
    //只有一個公司時候,屏蔽公司選擇列表
    this.barCompanyItem.Visibility = DevExpress.XtraBars.BarItemVisibility.Never;
}

如果多于一個公司怠益,那么正常的需求是可以切換公司來查看其它公司的數(shù)據(jù)的仪搔,要實現(xiàn)這個功能,那么就需要修改登陸的那個全局的過濾條件:Cache.Instance["DataFilterCondition"]了蜻牢。

我們來看看代碼的實現(xiàn)烤咧,其主要的邏輯就是獲取用戶選擇的公司ID,然后根據(jù)公司抢呆、部門信息煮嫌,重新構(gòu)建一個全局的過濾條件,并重新緩存到對應(yīng)的鍵值里面去抱虐,供后面的窗體實現(xiàn)數(shù)據(jù)的過濾更新昌阿。

CListItem item = this.barCompanyItem.EditValue as CListItem;
if (item != null)
{
    //設(shè)置選定的公司ID
    Cache.Instance["SelectedCompanyID"] = item.Value;
    SetSelectedCompanyName();

    //設(shè)置過濾條件給界面基類使用
    string filterCondition = string.Format(" Company_ID = '{0}' ", item.Value);
    if (!Portal.gc.IsAdmin)
    {
        if (Portal.gc.DeptList.Count > 0)
        {
            filterCondition += string.Format(" AND Dept_ID IN ({0})", string.Join(",", Portal.gc.DeptList));
        }
        else
        {
            filterCondition += string.Format(" AND Creator = '{0}' ", Portal.gc.UserInfo.ID);
        }
    }
    Cache.Instance["DataFilterCondition"] = filterCondition;

如果需要對已有的窗體實現(xiàn)數(shù)據(jù)更新,那么遍歷窗體恳邀,并統(tǒng)一實現(xiàn)數(shù)據(jù)刷新即可懦冰。

//遍歷全部窗口,更新
foreach (WHC.Framework.BaseUI.BaseDock form in this.MdiChildren)
{
    form.SelectedCompanyID = item.Value;
    form.DataFilterCondition = filterCondition;
    form.FormOnLoad();
}

string message = string.Format("您已經(jīng)切換數(shù)據(jù)顯示:{0}", item.Text);
MessageDxUtil.ShowTips(message);

2谣沸、窗體數(shù)據(jù)過濾的實現(xiàn)

從上面的步驟代碼儿奶,我們可以看到如何構(gòu)建一個全局的過濾條件,但是我們獲取數(shù)據(jù)的時候鳄抒,如何才能實現(xiàn)數(shù)據(jù)權(quán)限的控制闯捎,讓用戶所能看到的數(shù)據(jù)在可控的范圍內(nèi)呢椰弊?

我們知道,一般窗體數(shù)據(jù)列表的綁定操作類似如下代碼所示

/// <summary>
/// 綁定列表數(shù)據(jù)
/// </summary>
private void BindData()
{
    //entity
    this.winGridViewPager1.DisplayColumns = displayColumns;
    this.winGridViewPager1.ColumnNameAlias = CallerFactory<ICustomerService>.Instance.GetColumnNameAlias();//字段列顯示名稱轉(zhuǎn)義

    string where = GetConditionSql();
    PagerInfo pagerInfo = this.winGridViewPager1.PagerInfo;
    List<CustomerInfo> list = CallerFactory<ICustomerService>.Instance.FindWithPager(where, ref pagerInfo);
    this.winGridViewPager1.DataSource = new WHC.Pager.WinControl.SortableBindingList<CustomerInfo>(list);
    this.winGridViewPager1.PrintTitle = "客戶信息列表";
}

所以主要的數(shù)據(jù)控制瓤鼻,就在函數(shù)GetConditionSql()里面了秉版,那么這個里面,我們?nèi)绾握锨懊娴倪^濾條件呢茬祷?

下面是一個案例代碼清焕。

/// <summary>
/// 根據(jù)查詢條件構(gòu)造查詢語句
/// </summary> 
private string GetConditionSql()
{
    //如果存在高級查詢對象信息,則使用高級查詢條件祭犯,否則使用主表條件查詢
    SearchCondition condition = advanceCondition;
    if (condition == null)
    {
        condition = new SearchCondition();
        if(customGridLookUpEdit1.EditValue != null)
        {
            condition.AddCondition("ID", customGridLookUpEdit1.EditValue.ToString(), SqlOperator.Equal);
        }
        condition.AddCondition("Deleted", 0, SqlOperator.Equal);//不顯示刪除的
    }
    string where = condition.BuildConditionSql().Replace("Where", "");

    //如果是單擊節(jié)點得到的條件秸妥,則使用樹列表的,否則使用查詢條件的
    if (!string.IsNullOrEmpty(treeConditionSql))
    {
        where = treeConditionSql + " AND Deleted = 0 ";//不顯示刪除的
    }

    //數(shù)據(jù)權(quán)限的過濾:過濾規(guī)則沃粗,如果指定公司粥惧,以公司過濾,如果進一步指定部門最盅,以公司+部門進行過濾突雪;否則以個人的數(shù)據(jù)展示
    //如果過濾條件不為空,那么需要進行過濾
    if (!string.IsNullOrEmpty(this.DataFilterCondition))
    {
        where += string.Format(" AND {0}", this.DataFilterCondition);
    }
    return where;
}

我們主要關(guān)注下上面紅色部分即可涡贱,因為我們已經(jīng)加上了標準的過濾條件了咏删,這樣我們就可以看到自己管理的數(shù)據(jù)了。
為了實現(xiàn)統(tǒng)一的數(shù)據(jù)控制问词,我們要求整個業(yè)務(wù)表的設(shè)計督函,需要引入下面幾個標準的字段,這樣就能很好使用過濾條件進行數(shù)據(jù)的過濾了激挪。




前面也介紹到了侨核,窗體可以統(tǒng)一刷新,其奧秘就是它們遵循統(tǒng)一的一個數(shù)據(jù)加載接口灌灾,我們初始化窗體數(shù)據(jù)的函數(shù)代碼如下所示。

/// <summary>
/// 編寫初始化窗體的實現(xiàn)悲柱,可以用于刷新
/// </summary>
public override void FormOnLoad()
{
    InitDictItem();

    BindData();
    InitCustomerPage();
}

所以它們就能夠統(tǒng)一調(diào)用FormOnLoad來統(tǒng)一刷新數(shù)據(jù)锋喜,就是這個道理。

//遍歷全部窗口豌鸡,更新
foreach (WHC.Framework.BaseUI.BaseDock form in this.MdiChildren)
{
    form.SelectedCompanyID = item.Value;
    form.DataFilterCondition = filterCondition;
    form.FormOnLoad();
}

以上就是我對數(shù)據(jù)權(quán)限控制的一些心得和實現(xiàn)思路嘿般,希望大家能夠體會其中的思路,并批判性的提出意見和建議涯冠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炉奴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蛇更,更是在濱河造成了極大的恐慌瞻赶,老刑警劉巖赛糟,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砸逊,居然都是意外死亡璧南,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門师逸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來司倚,“玉大人,你說我怎么就攤上這事篓像《” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵员辩,是天一觀的道長盒粮。 經(jīng)常有香客問我,道長屈暗,這世上最難降的妖魔是什么拆讯? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮养叛,結(jié)果婚禮上种呐,老公的妹妹穿的比我還像新娘。我一直安慰自己弃甥,他們只是感情好爽室,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著淆攻,像睡著了一般阔墩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓶珊,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天啸箫,我揣著相機與錄音,去河邊找鬼伞芹。 笑死忘苛,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的唱较。 我是一名探鬼主播扎唾,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼南缓!你這毒婦竟也來了胸遇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤汉形,失蹤者是張志新(化名)和其女友劉穎纸镊,沒想到半個月后倍阐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡薄腻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年收捣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庵楷。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡罢艾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尽纽,到底是詐尸還是另有隱情咐蚯,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布弄贿,位于F島的核電站春锋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏差凹。R本人自食惡果不足惜期奔,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望危尿。 院中可真熱鬧呐萌,春花似錦、人聲如沸谊娇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽济欢。三九已至赠堵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間法褥,已是汗流浹背茫叭。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留半等,地道東北人揍愁。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像酱鸭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子垛吗,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容