五级权限查询以及ESOP组织机构树构造原理
一.基本概念
客户管理将操作员分为五个角色,分为五级:省级管理员,地市级管理员,区县管理员,客户经理主管,客户经理
对应的字典如下:
select * from dict_item where groupid = 'NGMgrRight';
在业务数据查询时都是需要分权限查询的,省级管理员查询全省的数据,地市管理员查询本地市的数据,区县管理员查询本区县的数据,客户经理查询自己管辖的客户
角色定义在workgroup这个视图中,而给操作员分配对应的角色定义在operator_workgroup视图中。
二.五级权限查询以及组织机构树
1.ESOP系统中五级查询有哪五级,又是如何实现的呢?
ESOP系统中的五级查询分为:省(查询全省数据),市(查询本市数据),县(查询本区县数据),部门(查询部门数据),人员(查询管辖下的数据)
1)省级,地市级操作员查询时只需要region限制条件即可
2)区县一级需要根据区县的id,到v_esop_organization_m视图中迭代出下属所有的组织机构,查询出所有组织机构的值
3)同2)
4)人员一级,需要关联cm_cu_groupcustservchannel(集团客户服务渠道表)查询出本操作员所管辖的集团客户数据
2.当一个操作员登陆时,我们是如何知道他属于哪一级,且最大的组织机构是什么,即操作员的最大权限是如何得到的?
1)首先要了解ESOP系统的权限分为角色权限和数据权限(数据权限,目前只有江苏在用),获取操作员的最大权限,即是取此操作员的角色权限和数据权限的最大值
2)通过查询v_esop_userdataauth表获取操作员的最大数据权限对应的orgid,orglevel。取orglevel最小的一条记录。
selectorg.orgid, org.orglevel, org.orgname, org.parentid, org.region, org.esop_type
fromv_esop_organization_m org
whereorg.orgid in (select t.authobjectid
from v_esop_userdataauth t
where t.staffid = #staffid#
and t.AUTHID = #authid#) and org.esop_type=#esopType#
3)如果是最大数据权限为空,则通过操作员的工号查询operator_workgroup表获取操作员的最大角色,然后根据操作员的不同角色通过查询v_esop_organization_m以及district,organization等表获取角色对应的最大的组织机构orgid,orglevel。
① 取最大的权限角色: select dict.dictid,
dict.dictname,
dict.groupid,
dict.sortorder,
dict.status,
dict.statusdate,
dict.description
from dict_item dict
where dict.groupid = #groupid#
and dict.dictid in (select w.ROLEID
fromoperator_workgroup w
where w.OPERID =#operid#
and w.STATUS = '1')
and status = 1
② 如果没有权限角色,则返回操作员自己:select * from operator t where t.region =#region# and t.OPERID = #operId#
③ 具有省级数据权限(最大的权限角色sql中,sortorder 为 1):
select t.orgid, t.orglevel, t.orgname, t.parentid,t.region, t.esop_type
from v_esop_organization_m t
where t.esop_type = #esopType#
<!-- 添加查询指定orgid的信息chenqing-->
<isNotEmptyprepend="and" property="level">
t.orglevel= #level#
</isNotEmpty>
<isNotEmptyprepend="and" property="orgid">
<![CDATA[
t.orgid= #orgid# and rownum < 2]]>
</isNotEmpty>
④ 具有地市权限(最大的权限角色sql中,sortorder 为 2):
selectt.orgid, t.orglevel, t.orgname, t.parentid, t.region, t.esop_type
from v_esop_organization_m t
where t.region = (select oper.Region
from operator oper
where oper.OPERID = #staffid#
and oper.STATUS = '1')
and t.esop_type = #esopType#
and t.orglevel = '2'
⑤ 具有区县权限(最大的权限角色sql中,sortorder 为 3):先根据opcode:GetRealteDistrictInfoByOrgID查询countryId,即查询操做员的区县。然后根据countryId查询单位信息。
selectesoporg.orgid,
esoporg.orglevel,
esoporg.orgname,
esoporg.parentid,
esoporg.region,
esoporg.esop_type
from v_esop_organization_m esoporg
where esoporg.orgid = #countryId#――
and esoporg.esop_type = #esopType#
and esoporg.orglevel = '3'
⑥ 主管权限(最大的权限角色sql中,sortorder 为 4): select org.orgid,
org.orglevel,
org.orgname,
org.parentid,
org.region,
org.esop_type
from v_esop_organization_m org
where org.orgid = (select oper.ORGID
from operator oper
where oper.OPERID =#staffid#
and oper.STATUS = '1')
andorg.orglevel = '4'
⑦ 客户经理(最大的权限角色sql中,sortorder 为 5):
select t.orgid, t.orglevel, t.orgname,t.parentid, t.region, t.esop_type
from v_esop_organization_m t
where t.orgid = #staffid# and t.orglevel='5'
4)综合2)和3)的最大值,得到操作员所管辖的的orgid,orglevel
3.根据操作员的最大orgid,orglevel,查询v_esop_organization_m视图(通过parentid),采用懒加载的方式构造组织机构树
注:v_esop_organization_m视图的orglevel跟五级权限没有任何关系,这个字段只是用来区分省(1),市(2),区县(3),部门(4),人员(5)
不能说部门(4)一定是区县(3)的下级,有可能部门(4)是挂在市(2),甚至是省(1)下面的;orglevel可以用来确定查询时走不同的查询分支(提高查询性能)
<!-- 按照五级权限查询 -->
<isEqual prepend ="and" property="purviewLevel" compareValue="3">
a.orgid in (
select distinct t.orgid from v_esop_organization_m t
where t.orglevel >= 3 andt.orglevel <= 4
and t.esop_type = 1
start with t.orgid =#orgaid#
and t.esop_type = 1
connect by prior t.orgid= t.parentid
and t.esop_type = 1
)
</isEqual>
<isEqual prepend ="and" property="purviewLevel" compareValue="4">
a.orgid in( SELECT distinct orgid
FROMv_esop_organization_m condi
wherecondi.esop_type = 2
andcondi.orglevel = 4
STARTWITH condi.orgid = #orgaid# and condi.esop_type = 2
CONNECT BY PRIOR condi.orgid =condi.parentid
and condi.esop_type=2)
</isEqual>
<isEqual prepend ="and" property="purviewLevel" compareValue="5">
exists ( select gs.subsid
from cm_cu_custServChannel gs
where gs.subsid = a.subsid
and gs.region = #region#
and gs.custmgr = #currentOperID#
)
</isEqual>