如何在應用系統中實現數據權限的控制功能

在很多應用行業里面,都對數據的權限做了特別的聲明,如對于銷售,財務的數據,它們是非常敏感的,因此要求對數據權限進行控制,對于基于集團性的應用系統而言,就更多需要控制好各自公司的數據了。如默認只能看本公司、或者本部門的數據,對于特殊的領導,可能需要跨部門的數據,因此不能硬編碼那個領導該訪問哪些數據,需要進行后臺的權限和數據權限的控制為佳,本文主要針對這個特點,對這個數據權限的功能模塊進行探討,并以我的Winform開發框架的實際案例進行剖析,介紹實際項目中對數據權限的控制管理。

1、權限系統的控制

剛才說到,對數據進行控制最好通過彈性的方式,在一個系統里面或者功能模塊里面對用戶角色或者崗位進行設置,一般權限控制默認在一個權限管理系統模塊進行設定,數據權限也應該如此。
權限系統除了可以對用戶能操作那些功能進行限定,也還可以對其訪問那些組織機構的數據進行限定,我們通過權限系統,把這些權限控制的數據進行保存,在應用系統模塊里面進行整合即可,根據角色擁有的數據權限,授予用戶對其他部門或者機構的數據進行訪問。如下面是我權限系統模塊里面對角色權限的設置操作。
1)對角色功能權限進行設置



2)對角色數據權限進行控制



當對角色的數據權限進行保存后,我們就可以把這個角色能夠訪問的組織機構(公司、部門、工作組等等)進行記錄起來了。

2、應用系統的集成,實現數據權限的控制

如我的一個病人資料應用系統,客戶要求就是基于互聯網的應用系統,因此使用WCF數據通訊模式實現數據的集中管理,而且他們要基于醫院單位的數據管理模式,也就是每個單位管理各自的數據,我們可以把不同的醫院單位作為不同的公司性質來區分,這樣在權限模塊中進行設置即可。
1)在應用程序中,通過在程序頭部,讓可以管理多個醫院機構的用戶選擇管理的數據訪問,即可實現不同的數據區分管理。



2)當用戶在上面切換不同的機構,所有存在的界面數據全部實現刷新,如打開了很多界面,那么這些界面的數據也隨之更新為對應新的機構下的數據。
了解了上面大致的需求,我們應該如何通過整合權限管理系統實現在應用系統的數據權限控制和集成呢?
首先我們需要在用戶登陸的時候,獲取對應用戶的數據權限內容,然后把它轉化為我們需要的信息,如下代碼所示。

//判斷如果用戶管理的公司數據多于兩個,那么就顯示選擇單位列表,并綁定公司數據
List<RoleDataInfo> roleDataList = CallerFactory<IRoleDataService>.Instance.FindByUser(info.ID);
List<int> companyList = new List<int>();
foreach (RoleDataInfo roleDataInfo in roleDataList)
{
    if (!string.IsNullOrEmpty(roleDataInfo.BelongCompanys))
    {
        string[] companyArray = roleDataInfo.BelongCompanys.Split(',');
        foreach (string company in companyArray)
        {
            if (!string.IsNullOrEmpty(company) && ValidateUtil.IsNumber(company.Trim()))
            {
                if (!companyList.Contains(company.ToInt32()))
                {
                    companyList.Add(company.ToInt32());
                }
            }
        }
    }
}
Portal.gc.CompanyList = companyList;

//設置選定的公司ID
Cache.Instance["SelectedCompanyID"] = info.Company_ID;
//設置過濾條件給界面基類使用
Cache.Instance["DataFilterCondition"] = string.Format(" (Company_ID is null OR Company_ID = '{0}')", info.Company_ID);

其中CallerFactory方式調用,是以WCF的方式獲取對應的數據庫數據。在上面代碼里面,有一個RoleDataInfo的實體類,這個就是用來承載用戶角色的數據權限數據,其中包括了

BelongCompanys(所屬公司)和 BelongDepts(所屬部門 )的屬性,我們把它解析為我需要的數據List<int> companyList 、 SelectedCompanyID 和 DataFilterCondition,當然如果有部門的控制,可以做的更多,我這里僅僅以醫院機構進行區分即可。

SelectedCompanyID 就是用戶選擇查看的組織機構ID,DataFilterCondition就是用來構建一個數據過濾腳本,對用戶看到的數據進行一個過濾篩選作用。我們把這兩個數據內容,放到Winform的緩存里面,如果是Web可以用Session代替,這樣可以在多個模塊或者界面中方便訪問使用。

為了實現用戶選擇不同的機構,所有打開的窗體數據實現相應的更新,那么我們需要處理公司選擇的操作,具體實現代碼如下所示。

private void txtCompany_EditValueChanged(object sender, EventArgs e)
{
    //如果用戶選擇公司,以選擇為主,否則以當前客戶所在公司
    if (this.txtCompany.EditValue != null)
    {
        CListItem item = this.txtCompany.EditValue as CListItem;
        if (item != null)
        {
            //設置選定的公司ID
            Cache.Instance["SelectedCompanyID"] = item.Value;
            SetSelectedCompanyName();

            //設置過濾條件給界面基類使用
            string condition = string.Format(" Company_ID = '{0}'", item.Value);
            Cache.Instance["DataFilterCondition"] = condition;
            
            //遍歷全部窗口,更新
            foreach (WHC.Framework.BaseUI.BaseDock form in this.MdiChildren)
            {
                form.SelectedCompanyID = item.Value;
                form.DataFilterCondition = condition;
                form.FormOnLoad();
            } 

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

上面是對所有打開的窗體,傳遞了對應的信息,然后進行了刷新。那么我們在看看窗體本身內部的數據顯示邏輯是如何的。

我們以病人資料的查詢界面為例,根據不同的輸入條件,對數據進行不同查詢外,還增加了一個對組織機構過濾的條件,如下所示。

/// <summary>
/// 根據查詢條件構造查詢語句
/// </summary> 
private string GetConditionSql()
{
    //如果存在高級查詢對象信息,則使用高級查詢條件,否則使用主表條件查詢
    SearchCondition condition = advanceCondition;
    if (condition == null)
    {
        condition = new SearchCondition();
        condition.AddCondition("BedNo", this.txtBedNo.Text.Trim(), SqlOperator.Like);
        condition.AddCondition("TumorPart", this.txtTumorPart.Text.Trim(), SqlOperator.Like);
        ........................
        condition.AddDateCondition("InDate", this.txtInDate, this.txtInDateEnd);
        condition.AddDateCondition("LeaveDate", this.txtLeaveDate, this.txtLeaveDateEnd);if (this.chkHasReferral.Checked)
        {
            condition.AddCondition("HasReferral", "是", SqlOperator.Equal, true);
        }
        ...................
    }

    string where = condition.BuildConditionSql().Replace("Where", "");
    
    //如果公司過濾條件不為空,那么需要進行過濾
    if (!string.IsNullOrEmpty(this.DataFilterCondition))
    {
        where += string.Format(" AND {0}", this.DataFilterCondition);
    }

    return where;
}

/// <summary>
/// 綁定列表數據
/// </summary>
private void BindData()
{
    //entity
    this.winGridViewPager1.DisplayColumns = "HandNo,BedNo,MidVideo,Name,Sex,IdentityCard,Age,Birthday,HospitalNo,IDNumber,InDate,InDiagnosis,SurgeryDate,DirectorSurgeon,LeaveDate,TumorPart,LeaveDiagnosis,IsFirstTime,LeaveSpecimens,OuterFilm,PreMRI,PreCT,PrePicture,MidPathology,AfterCTMRI,AfterPicture,AfterVideo,LeavePicture,Endocrine,Professor,Address,Telephone,HasReferral,ReferralDate,ReferralTime,Pathology,Note,Report";
    this.winGridViewPager1.ColumnNameAlias = CallerFactory<IPatientService>.Instance.GetColumnNameAlias();//字段列顯示名稱轉義

    string where = GetConditionSql();
    PagerInfo pagerInfo = this.winGridViewPager1.PagerInfo;
    List<PatientInfo> list = CallerFactory<IPatientService>.Instance.FindWithPager(where, ref pagerInfo);
    this.winGridViewPager1.DataSource = new WHC.Pager.WinControl.SortableBindingList<PatientInfo>(list);
    this.winGridViewPager1.PrintTitle = "病人基本資料信息報表";
}

以上綁定代碼實現了:分頁、條件查詢、高級查詢、字段列表顯示、中文名稱轉義,以及最重要的,根據公司條件進行數據過濾的操作,從而讓用戶只能管理自己的數據。

以上就是結合權限管理系統模塊,在應用系統中實現功能權限控制和數據權限的控制的操作例子和代碼展示,希望對大家有幫助。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容