云计算百科
云计算领域专业知识百科平台

流量没有了强制授权——管理员为什么能越权操作辖区内的流程

流量没有了,强制授权——管理员为什么能越权操作辖区内的流程

政务审批系统里,普通操作员只能看自己的任务。但任务可能挂在某个请假的人名下三天没人动,或者分配逻辑出错导致任务到了不该接的人手里。这时候管理员需要一个"强制授权"能力——越过权限限制,看到并操作辖区范围内的所有流程任务。

文章目录

  • 流量没有了,强制授权——管理员为什么能越权操作辖区内的流程
    • 一、问题:任务卡住了,必须有人能救火
    • 二、三级数据权限——不是所有人能看所有任务
    • 三、BMLD角色——部门领导的权限放大
    • 四、selectAllRun——管理员的全量视图
    • 五、前端样式——跑马灯防屏幕休眠
    • 六、强制授权的完整调用链
    • 七、这套设计的价值
    • 八、结语

一、问题:任务卡住了,必须有人能救火

工作流分配不是完美的。三种常见情况:

  • 分配出错——任务分给了不应该收的人,那个人自己都不知道有这个任务
  • 经办人不在——任务挂的人请假了,没人替他处理,业务卡了几天
  • 领导视察——科长想看全科今天有多少任务在跑,不能一个一个人问
  • 这时候需要一种能力:某个人可以不依赖"分配给自己"这个条件,直接看到并操作辖区内的所有任务。就是"强制授权"。


    二、三级数据权限——不是所有人能看所有任务

    — 等级1:普通操作员——只能看到自己经办的任务
    select * from act_ru_task where assignee_ = #{userId};

    — 等级2:部门领导——能看到自己+本单位所有人员的任务
    select * from act_ru_task
    where assignee_ = #{userId}
    or assignee_ in (
    select psn_id from op_person
    where dept_id in (
    select dept_id from op_person
    where psn_id = #{userId}
    and exists (
    select 1 from role_person_map
    where role_id = 'BMLD' and psn_id = op_person.psn_id
    )
    )
    );

    — 等级3:管理员/全区——能看到本单位(含下级单位)所有任务
    select * from act_ru_task
    where assignee_ in (
    select psn_id from op_person
    where dept_id in (select unit_id from op_unit where unit_id like #{areaNo} || '%')
    );

    三级权限的逻辑:

    级别角色能看到什么
    个人 普通操作员 assignee_ = 自己
    部门 部门领导(BMLD) 自己 + 同部门所有人的任务
    辖区 管理员 本辖区所有单位的任务

    权限不是写在Java代码里的,是用SQL的 exists + in 子查询控制的。同一个人,查任务时走的SQL不同,看到的结果集就不同。


    三、BMLD角色——部门领导的权限放大

    — selectbyuseridrun2 的核心过滤条件
    and exists (
    select 1 from ACT_HI_TASKINST b
    where a.PROC_INST_ID_ = b.PROC_INST_ID_
    and (
    b.ASSIGNEE_ = #{userId} — ① 自己的任务
    or b.ASSIGNEE_ in ( — ② 同级单位所有人员的任务
    select psn_id from op_person
    where dept_id in (
    select dept_id from op_person c
    where psn_id = #{userId}
    and exists (
    select 1 from role_person_map
    where role_id = 'BMLD'
    and psn_id = c.psn_id
    )
    )
    )
    )
    )

    这段SQL做三件事:

  • 查这个人有没有 BMLD(部门领导)角色
  • 有的话——找到他所在的部门,再找到这个部门的所有人员
  • 把过滤条件从"只看自己的任务"扩展为"看本部门所有人的任务"
  • 如果这个人没有 BMLD 角色,exists(select 1… role_id='BMLD') 返回空,in() 的子查询无结果,条件退化为 ASSIGNEE_ = #{userId} ——和普通操作员一样。

    这就是"强制授权"的实现——不改任何业务逻辑,只改查询条件的SQL。


    四、selectAllRun——管理员的全量视图

    runingAll.jsp 页面用的是 selectAllRun 这个查询:

    select a.PROC_INST_ID_, a.PROC_DEF_ID_, a.START_TIME_,
    b.matter_name, c.name_ taskname, c.id_ as taskid,
    c.create_time_ taskcreatetime,
    case when (select psn_name from op_person t where t.psn_id=c.assignee_) is null
    then (select unit_name from op_unit where unit_id = substr(c.assignee_, INSTR(c.assignee_, '#', '1') + 1))
    || '-' || (select role_name from op_role where role_id = substr(c.assignee_, 2, INSTR(c.assignee_, '#', '1') – 2))
    else (select psn_name from op_person t where t.psn_id=c.assignee_)
    end as psn_name
    from ACT_HI_PROCINST a, v_business_table b, act_ru_task c
    where a.END_TIME_ is null
    and a.proc_inst_id_ = b.proc_inst_id_(+)
    and a.proc_inst_id_ = c.proc_inst_id_
    and exists (
    select 1 from act_hi_taskinst
    where proc_inst_id_ = a.proc_inst_id_
    and assignee_ in (
    select aa.psn_id from op_person aa, ab01 bb
    where aa.dept_id = bb.unit_id
    )
    )

    这个查询没有 userId 参数——它就是全单位的。exists 子查询里的 assignee_ in (本单位所有人员) 决定了这个页面展示的是本单位辖区范围内所有在跑的任务,不管是谁的。

    页面上能看到:

    • 事项名称(参保登记、待遇核定……)
    • 当前任务名称(初审、复核……)
    • 当前任务处理人(具体到人还是角色)
    • 任务创建时间

    管理员在这个页面可以做两件事:直接处理(把任务接过来自己处理),或改派(把任务改分配给另一个人)。


    五、前端样式——跑马灯防屏幕休眠

    runingAll.jsp 还有一个隐藏的设计:自动刷新。

    // 每30秒自动刷新一次——做"流量没有了"时的跑马灯效果
    setInterval(function() {
    location.reload();
    }, 30000);

    这个设计不是为了体验——是为了防屏幕休眠。政务大厅的监控屏幕如果不动,系统会自动休眠或被检测为离线。30秒一刷,大屏幕永远显示最新数据,永远不会休眠。

    "流量没有了"是内部调侃——任务量少的时候页面几乎没变化,但刷新不能停,因为刷新的目的从来不是为了看新数据,是保持大屏存活。


    六、强制授权的完整调用链

    管理员打开 runingAll.jsp
    │
    ▼
    selectAllRun → 查本单位辖区所有在办任务
    │
    ▼
    管理员看到某任务卡住了(如请假的张三名下有3个待办)
    │
    ▼
    管理员点"处理" → 调用 claim(taskid, 管理员id)
    │ → 把任务的 assignee_ 从 #role#dept 改为 管理员本人的psn_id
    │ → 管理员进入处理界面 → 处理完成 → 流程流转
    │
    ▼ 或者
    管理员点"改派" → 调用 transferAssignee(taskid, 另一个人id)
    │ → 把任务分配给别人
    │
    ▼
    old_task 表记录改派日志(追溯审计)

    关键:管理员处理完或改派完的任务,流程会正常流转——下一个环节仍然走自动分配逻辑(prc_alloc),管理员不会一直持有这个任务。


    七、这套设计的价值

    权限控制不在Java代码里,在SQL的where条件里。 三个等级对应三条SQL,改权限策略不改业务逻辑。

    BMLD角色是开关——同一个操作员,有BMLD角色就能看全部门的任务,没有就只能看自己的。角色赋权或撤权即时生效,因为每次查询都在判断 exists(select 1 from role_person_map where role_id='BMLD')。

    改派可追溯——每次强制改派都写 old_task 表。审计时问"张三的参保登记审批为什么变成李四处理的",查 old_task 就能看到。不是你手动把 assignee 改了又改,是从 task→old_task→old_task 有一条完整的改派链。


    八、结语

    强制授权的本质不是"超级管理员拥有一切权限",而是角色决定SQL的where条件范围。同一个查询方法,不同角色走不同的子查询,返回不同的结果集。没有写死权限的if-else,权限策略完整体现在SQL里。改权限只需要改角色表中的一条记录,SQL自动走不同的分支。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 流量没有了强制授权——管理员为什么能越权操作辖区内的流程
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!