一、总体设计思路:
(1)Cloud的权限 与 cloud的业务单据没有直接联系,它们通过权限框架提供的权限项、权限对象、数据范围关联起来构成cloud业务对象的整个权限控制;
(2)cloud产品没有菜单权限、没有数据权限;
(3)菜单的实质是功能,故菜单权限可以通过功能权限进行反算,所以大家在发布菜单的时候需要绑定权限项,以表示这个菜单验证什么样的功能权限,比如发布的菜单是列表,则一般绑定查看权限项,即没有查看权,则不能看到这个菜单;就像我们去餐馆吃饭,我们不吃辣,则不要把有辣味的菜给我列出来;
(4)数据权限不能独立存在,比如我们在公司不能看(功能权限)电视(范围,数据权限:看电脑,看笔记本),但是回到家则可以看电视,所以数据权限是依赖于不同的场景的,与单据本身有关;数据权限还与功能权限相关:又比如我们能看(功能权限)订单金额为10万以下(数据权限)的单据,但只能审核(功能权限)订单金额为3万以下的单据;
所以,针对订单,在采购订单和销售订单上,我们不但可以设置订单本身的数据范围,还可以设置同一个基础资料的不同范围;
(5)权限对象和权限项的配置和新增,请以管理员身份进入,系统管理节点中;
二、权限配置:
(1)需要为一个订单配置权限,步骤是(boside中):勾选“权限控制”,为其指定一个“权限对象”,即需授权的范围,发布的时候,选择菜单需验证的“权限”;
(2)操作列表,关联权限项,以验证权限,不配置则不验证;
以上配置目前版本不够清晰,在3.0版本我们用一个界面统一管理,并在配置不正确的地方将给与提示;
三、知识点、二次开发等问题:
(1)单据界面上的基础资料的手工录入或者是F8选择,均不验证功能权限,只验证功能权限上配置的数据范围,当然,打开的列表,如果点击它的菜单,则根据它本身的功能权限来控制;
(2)对于帐表,也可以进行数据范围设置,是通过基础资料的范围来控制的;帐表中,加入基础资料列,则在授权的地方能对其进行范围设置;使用的时候,在帐表服务端插件中,sql关联该基础资料范围表即可,不设置范围,则该临时表不会存在;
// Summary:
// 报表数据源参数接口
public interface IRptParams
{
// Summary:
// 基础资料临时表; 如果设置了数据范围,该表会把根据数据范围过滤出来的内码存入临时表;
List<Kingdee.BOS.Core.Permission.Objects.BaseDataTempTable> BaseDataTempTable { get; set; }
(3)数据范围也是可以自定义的,即可以自己定义一个数据范围界面,开发复杂的条件,自己插件解析;boside中有数据范围服务端插件;需继承抽象类:AbstractDataRuleServicePlugIn
简要示例(声明,以下代码非本人所写!):
namespace Kingdee.K3.HR.ORG.App.Core
{
public class OrgHrDataRuleService : AbstractDataRuleServicePlugIn
{
public override void BeforeAnalyzeDataRule(BOS.Core.Permission.Args.DataRuleArgs e)
{
base.BeforeAnalyzeDataRule(e);
IHrDataRule dataRuleService = HRServiceHelper.GetService<IHrDataRule>();
List<string> fliters = new List<string>();
List<string> permissList = new List<string>();
List<string> forbidList = new List<string>();
foreach (var dataRule in e.DataRules)
{
if (dataRule != null && dataRule.CustomFilterObject != null)
{
if (fliters.Contains(dataRule.Id))
{
continue;
}
DynamicObjectCollection objs = dataRuleService.GetRoleUnitSec(this.Context, dataRule.Id);
if (objs != null && objs.Count > 0)
{
List<string> shemeList = new List<string>();
List<string> myPermissList = new List<string>();
List<string> myForbidList = new List<string>();
Dictionary<string, Tuple<string, string>> headerList = new Dictionary<string, Tuple<string, string>>();
dataRuleService.GetHrFilterList(objs, shemeList, myPermissList, myForbidList, headerList);
permissList.AddRange(myPermissList);
forbidList.AddRange(myForbidList);
}
}
}
string permissStr = "";
if (permissList.Count > 0)
{
permissStr = string.Join(" or ", permissList);
}
string forbidStr = "";
if (permissList.Count > 0)
{
forbidStr = string.Join(" and ", forbidList);
}
string selfCodeFilter = "";
if (permissStr.Length > 0)
{
selfCodeFilter += "(" + permissStr + ")";
}
if (forbidStr.Length > 0)
{
if (selfCodeFilter.Length > 0)
{
selfCodeFilter += " and ";
}
selfCodeFilter += "(" + forbidStr + ")";
}
if (string.IsNullOrEmpty(selfCodeFilter))
{
if (GetIsHRControl())
{
selfCodeFilter = " 0=-1";
}
else
{
selfCodeFilter = "";
}
}
e.Filter = selfCodeFilter;
}
private bool GetIsHRControl()
{
if (this.Context.UserId == OtherConst.AdminId)
{
return false;
}
ICommonService commonService = HRServiceHelper.GetService<ICommonService>();
//根据系统参数,控制是否显示
return commonService.GetSystemProfile(this.Context, this.Context.CurrentOrganizationInfo.ID, SystemParams.IsControlByHr, "IsHRControl", false).ConvertTo<bool>();
}
}
}
(4)权限服务类为:PermissionServiceHelper,
a,里面包含如何判断某个业务对象在哪个场景下的权限,返回结果中包含在哪些对象中有权限等重要信息;FuncPermissionAuth
b,可以获得某个业务对象在哪个场景下的权限,这些权限是在哪个组织下具有的?GetPermissionOrg(Context ctx, BusinessObject bizObject, string strPerItemId)
c,如何获得数据范围:/// <summary>
/// 获得列表上,由数据规则解析出来的过滤
/// </summary>
/// <param name="ctx"></param>
/// <param name="dataRuleFilterParamenter"></param>
/// <returns></returns>
public static DataRuleFilterObject LoadDataRuleFilter(Context ctx, DataRuleFilterParamenter dataRuleFilterParamenter)
里面还有其他丰富的接口,不在赘述;
推荐阅读