# AFCenter中查看报表的权限控制
# 1.场景介绍
AFCenter中对于不同机构,不同岗位(负责人和普通销售)的员工,进行报表查看时,可以查看到的报表与报表中显示的范围是不一致的。
例如: 销售人员依据员工岗位不同,在销售统计中查看到的数据范围不同。
1.机构负责人可以查看该机构及其子机构(多个)中所有员工的销售数据。
2.非负责人员工只能查看自己的销售数据。
# 2.效果展示
- 机构负责人-张三:可以查看负责的机构及其子机构(多个)中所有员工的销售数据。
- 普通销售-王芳:只能查看自己的销售数据。
# 3.实现思路
1.在iData平台中,创建非Administrator账号,并在AFCenter系统变量中绑定。
2.在低开中,新建报表构建包,设计销售报表看板,并发布菜单到AFCenter中。
3.在低开中,开发逻辑流服务:
分支一:如果当前登录员工为普通销售,则逻辑流只返回该员工自己的员工id。
分支二:如果当前登录员工为机构负责人,则逻辑流返回该员工负责的机构和其机构下所有员工的id。
4.在iData平台中,创建http服务数据源,并新建查询模板,调用逻辑流服务。
5.在低开中,通过查询模板对报表数据集的维度列做权限控制。
# 4.操作步骤
前置操作:iData报表安装与集成,参考文档:"iData报表安装与集成"
# 4.1开发报表
iData平台自带Administrator(admin)用户会无视权限规则对数据的控制,所以需要创建非Administrator用户,与AFCenter做对接。
# 4.1.1创建非Administrator用户与AFCenter对接
iData平台-管理-用户管理,创建一个报表数据管理员(idataadmin),同时把Administrator(admin)用户权限交接至报表数据管理员(idataadmin)。
在AFCenter-应用中心-通用管理-系统变量,修改BI_USERNAME和BI_PASSWORD为上一步创建的报表数据管理员(idataadmin)。
# 4.1.2开发销售业务报表看板
创建并初始化销售业务数据表。
注:该案例中不提供示例数据,销售业务数据表中的销售员工编码和销售人,实际需要和AFCenter员工表中的ID和NAME字段值对应,才能通过获取当前登录用户的员工id来对报表的数据显示做范围控制。
cont_order_prod_new(业务表)与afc_employee(系统中员工表)对应关系:
cont_order_prod_new | (业务表) | 对应关系 | afc_employee | (系统中员工表) |
---|---|---|---|---|
EMPLOYEEID | 销售员工编码 | ⇔ | ID | ID |
PRODSALENAME | 销售员工姓名 | ⇔ | NAME | 姓名 |
... | ... | ... | ... | |
... | ... | ... | ... | |
其他字段 | 其他字段 | 其他字段 | 其他字段 |
添加报表数据源-把业务表所在数据库添加到报表数据源中。
开发中心-报表数据源-新建报表数据源。
点击开发,新建构建包,勾选是否报表构建包。
新建数据集,选择添加的数据源,填写sql查询语句,加载并设计需要的维度列和指标列,并保存。
数据集中维度列必需存在的字段:EMPLOYEEID(销售人员编码)
新建看板,添加内嵌图表,设计看板报表。
图表中维列中必需添加的维度列:销售人员编码
右键看板,发布菜单,使报表看板挂载到AFCenter应用中。
发布菜单时,需要选择对应角色以查看报表,可以单独创建一个查看报表的角色,并赋予机构内的员工。
至此报表开发完成。
# 4.2开发逻辑流服务
注:开发的逻辑流服务,可以作为远程http服务调用,此服务被iData查询模板调用后,需要返回特定的String数组,该数组会被iData平台转化为单列表格,表格中的数据作为模板和报表中特定列数据作 == 判断,并过滤数据在报表中显示的内容。
# 4.2.1创建逻辑流服务
新建构建包,在通用业务下新建获取员工id
逻辑流服务。
逻辑流预览:
点击逻辑流空白处,添加需要的变量和逻辑流返回值。
关于数据类型:在低开中,部分系统表对应的数据类型默认集成进逻辑流中,比如:afc_user:USER、afc_employee:EMPLOYEE、afc_org:ORG等等。
需要用到的变量和返回值:
名称 | 数据类型 | 是否数组 | 描述 | 类型 |
---|---|---|---|---|
Org | ORG | 否 | 机构查询条件 | (变量) |
orgs | ORG | 是 | 当前员工负责的机构 | (变量) |
orgIds | String | 否 | 机构id查询条件 | (变量) |
employees | DataObject | 否 | 员工 | (变量) |
empIds | String | 是 | 机构下员工id | (返回值) |
连接一个赋值图元,把当前登录用户的员工id赋值给查询条件中的负责人id,左值:Org/managerId,右值:m:userObject/attributes/employeeId,右值类别:变量,赋值方式:传引用。
连接一个查询实体图元,用Org查询条件,查询出当前员工负责的所有机构,参数:Org 变量 传引用,返回值:orgs 变量。
# 4.2.2如果当前员工不是任何机构负责人分支:
添加一个赋值图元与查询实体图元连线,双击连线添加条件:左值:orgs,比较操作符:NULLOREMPTY。
双击赋值图元,把当前登录用户id直接赋值给返回值empIds[1]对象,左值:empIds[1],右值:m:userObject/attributes/employeeId。
结束。
如果执行到此,说明当前员工不是任何机构的负责人,则返回自己的员工id(只能看到自己的数据)。
# 4.2.3如果当前员工是机构负责人(一个或多个)分支:
此分支需要调用远程接口/api/afc/orgs/org/employees,查询机构和其子机构下的所有员工,接口详情访问swagger API接口文档:http://192.168.1.XX:28079/swagger-ui.html
接口调用需要的参数:
参数名 | 类型 | 描述 | 示例 |
---|---|---|---|
isFirst | string | 是否查询子机构 | 0 或 不填 |
orgIds | string | 机构ID,逗号分割 | 7,8,9 |
添加脚本图元,生成REST服务所需要的orgIds参数类型和格式,赋值变量orgIds:机构id查询条件。
// 数组转换为REST服务查询条件:orgIds : 机构ID,逗号分割
context.orgIds = context.orgs.collect { Org -> Org.id }.join(',')
添加一个REST服务图元,获取机构及其子机构下的所有员工,该逻辑流最终根据传入的orgIds参数,获取orgIds中,每个机构id对应的机构和其子机构下所有员工。
属性设置:
显示名称:获取负责机构及其子机构的员工
远程URL: http://{ip}:{port}/api/afc/orgs/org/employees
Http Method:GET
参数配置表:
类型 | 名称 | 数据类型 | 是否数组 | 传参类型 | 值 | 类别 |
---|---|---|---|---|---|---|
参数 | orgIds | string | 否 | URI | orgIds | 变量 |
参数 | isFirst | String | 否 | URI | 0 | 常量 |
返回值 | employees | DataObject | employees | 变量 |
添加脚本图元,从employees.data集合中,拿取所有的员工id放进最后返回值empIds中。
// 所有员工的id放进empIds数组
context.empIds = context.employees.data.collect { it -> it.id }
结束。
如果执行到此,该逻辑流最终返回当前登录用户负责的机构及其子机构下所有员工id。
至此逻辑流开发完成。
# 4.3数据集中维度列权限控制
# 4.3.1创建http数据源
登录创建的报表管理员账号idataadmin,配置-数据源管理,新建http数据源并保存。
http://192.168.1.XX:28079/EOSLOWCODE/salesStatistics.quaryEmployeeId.biz.ext
服务地址解析:
http://{ip}:{port}}/{服务所在应用名}/{服务所在构建包名.服务名}.biz.ext
# 4.3.2创建查询模板
点击管理-查询模板,添加模板。
数据源:选择上一步创建的http数据源。
请求路径:与上一步数据源内服务地址一致。
Method:请求方法为POST。
请求头:// ${bus_token}会自动获取AFCenter当前登录用户的Authorization
1.Authorization:${bus_token}
2.Content-Type:application/json
解析属性:逻辑流服务返回的empIds变量,写法:$.{变量名}。
# 4.3.3编辑维度权限规则
回到低开-销售报表构建包-数据集,点击配置销售人员编码维度列,高级配置中,勾选权限规则,选择刚才创建的查询模板。
至此,报表权限控制完成。