vue+antd :通过SQL条件分组功能实现数据授权

【需求说明】MOM项目开发中,有一个角色管理的页面,涉及到对具体的角色进行授权的功能。要实现的功能是,不仅要对这个角色授权指定的几个页面,还要能授权该页面上的某些按钮,以及页面中的某些数据。数据的授权,就是允许该角色下的用户,拥有查看指定数据的授权,或者对满足一定条件的一类数据拥有查看权限。对数据的授权,我们称为数据授权。

比如角色role1,已经赋予了人员管理页面的权限,以及人员管理页面新增按钮的权限。所谓数据授权,就是要将人员管理页面中人员详情的表格数据,有选择性的授权给role1角色查看。比如将工号小于00123456的人员数据,授权给角色role1。这样角色role1下的用户,登录系统后,就能看到人员管理页面,以及人员管理页面的新增按钮,当然,也能看到工号小于00123456的职员信息数据。

数据授权的具体实现,是在对角色授权时,通过设置一定的过滤条件,对页面中一类数据进行批量授权的功能。比如对角色Role1进行数据授权时,只允许Role1查看页面Page1(如下图)的表格中,用户名包含srx的数据,如下图所示。这样,Role1下的用户登录进来后,只能看到第一条包含srx的数据,看不到第二条数据。

Page1页面

【需求分析】该功能实际上就是将SQL的查询条件在WEB端界面化了。本来多个查询条件并列在界面上,也没有什么难度,但是,由于领导坚持认为现有的办公工具TFS上,bug单的过滤条件支持分组的功能非常好用,所以,他要求数据授权的查询条件,也要支持条件分组功能。如下图所示,是TFS上的bug单分组的界面。

TFS上bug单分组查询功能

【开发人员的内心独白】

条件分组,实际上就是给SQL语句加小括号的意思么,可以按照上图,设置每一个查条件,但是,不分组,用另外的textarea替代,让用户将上面配置的多个条件,通过加减乘除等符号,自由组合,灵活多变,想怎么配就怎么配,分组只能实现简单的场景;实际上就一句话,要实现分组,太南啦~~

【方案分析】

既然说服不了领导,那就开发吧,领导的高度,或许在我开发完了才能明白。

要开始开发了,我分享下我自己的思考过程,还原下当时的场景。

首先要考虑左侧的分组竖线如何画。跟同事讨论后,他建议左侧的竖线放在一个浮动层,右侧始终是一个并列的对象数组。意思是,竖线是竖线,条件是条件,条件代表的是数据,竖线代表了数据的分组关系。可是,所有的方案,最后都要抽象为数字模型。问题来了,竖线代表的关系,抽象为怎样的数据模型呢?又怎么跟过滤条件的数据对应起来呢?具体到前台开发,就是要思考给后台提交的数据格式,以及前台根据返回的数据,如何还原用户画的竖线关系。任务不是分给同事的,他可能不会深入思考这个问题,所以,他的建议不可取。至少他还没有深入到分析出来数据模型来。

跟后台商讨接口时,后台人员给出了一个带有groups属性的对象,看到这个对象,我恍然大悟,我一直纠结条件分组如何在界面表现,实际上他们就是一个树形结构的数据关系。如何标记多个条件属于一个小组,实际上就是树形结构中的children(我们这里定义为groups),带有children的条件,跟其他条件又构成一个大组。完成树形数据的层层嵌套,而且树形结构的数据,能完全还原用户界面上的设置,不会导致条件数据的顺序发生改变。当然,后台定义的带有groups的对象是不合理的,树嘛,应该是对象数组,便于递归查找。我们定下来数据结构是这样的。当然,id,parentId,floor都是后来慢慢增加的,用来满足查找树上的节点数据而产生的。

数据结构1
数据结构2

抽象模型解决后,方向是明确的了,分析的过程就完成一大半了。接下来,要考虑的3个问题是:

问题1、分组线条的实现。数据结构搞明白后,划线其实就比较容易了,渲染带groups的数据时,先左右各一个div,左边的小div,就是一个带有上下左三边边框的div,模拟划线;右边的div,就是这一组的的条件。当然这个要通过递归实现树的渲染。

问题2、如何判断用户随便选择的几个条件,能否合法的划分为一个组。事实证明,判断当前勾选的条件能否划分为一个组,是后续的实现过程中,逻辑最复杂的一部分。合法分组的依据是,同属于一个groups下的至少两个条件,才能划分为一个组;如果groups下包含子groups,则子groups整体作为一个条件,要么都选择,要么都不选择,这两者都是合法的,部分选择则不合法。实际上,判断能否分组,也是让我绞尽了脑汁。具体的实现算法是,将所选择的多个条件的父id都找出来作为一个数组,如下图,我勾选了四个条件,则就有四行数据,每一行代表一个勾选条件数据的所有父id。-1表示是根节点了,这样就能找出-1是所选条件的公共父id,这样把最小父id找后,父id的groups中的所有数据就能找到。判断改groups中,有几个条件被选中,至少两个就是合法的,如果包含子的groups,则子groups全选代表选中,不全选代表不选中,部分选中的话,都不用往下判断了,直接就不合法,不能分组。

寻找最小父节点id算法
合法分组的要求
分组和取消分组的判断逻辑
分组和取消分组的判断逻辑示例

问题3、如何判断用户随机选择的几个条件,能合法的取消分组。合法取消分组的依据是,所选择的所有条件,要同属于一个groups组,这时取消分组的按钮才可使用,否则取消分组的按钮只能置灰。取消分组的算法,也是先找到最小的公共父id,然后看父的groups中的数据是否全部选中,如果选中,则可以取消分组

问题4、每一个组,都需要一个三边有border的div来表示,宽度为d个像素,这样右侧的div就会往右移动d个像素,多层嵌套后,右侧条件是无法对其的,如下图所示。

左侧线条导致groups内的条件右移,条件无法对齐

此时数据上带的floor就该上场了。右侧的条件div,强制往左移动floor*d个像素,floor是当前条件所在的层数。如下图的style所示。

条件对齐的解决方法

这样对齐问题也就解决了。如下图所示。

条件分组最终界面

到此,基本工作算是完成了。注意:

1、只能以最大的组为单位再次分组

2、删除一个条件后,如果此时分组内只剩下最后一个条件,要解散当前的分组,这最后一个条件的floor要减1

3、每次分组后,这一组的数据的floor必须加1


【学会的东西】

1、vue数据驱动的思想:当我想要删除界面上的一个条件时,我首先想的是如何删除条件对应的dom元素以及相应变量的销毁。思考过后发现,vue数据驱动的思想,之前我没有完全领悟其中的奥妙,此时正是用它的时候。我只要保证对数据的操作正确,其他都交给vue就好了。我把树形数据的相应条件数据删除,vue自动重绘我的数据,相应的那一个条件的dom条件也就没有了。

2、组件销毁不需要手动执行。界面上销毁一行条件,只能数据驱动,意思是想办法删除这一条数据后,组件自己会跟着销毁

3、当然,上述是理想状态下的。实际上,数据改变时,组件重新渲染时出了问题。删除一个条件,界面上看到的是,条件的数量确实少了一个,但是少的哪一个不是我删除的,意思是确实重绘了,但是条件的具体值没有重新加载。比如我删除了下图的第一行数据,正常情况下,只剩下值为bb和cc的数据了,实际情况是,cc消失了,aa和bb都存在。确认数据处理没有问题后,我就怀疑是vue重绘时出错了,重新绘制了,但是传参有问题。

删除aa结果界面上cc消失了

百度出了一个非常有用的处理方法,如下所示,我要监听我的树形数据的变化,一旦改变,则通过v-if销毁组件,在vue自动重绘后,我再让v-if为true,相当于强制重新绘制了一变。这样能确保界面上所绘制的,一定来源于我的真正的数据。

参见https://www.cnblogs.com/zyulike/p/12036456.html

4、我自己会开发一个树组件了。各个组件库的树组件要做的工作,跟我完成的工作是相同的,第三方树组件,再也不那么神秘了。

5、学会使用vue组件的递归,以及理解vue实例中name属性的用途了。树组件的实现,要用到vue的组件递归(自己调用自己,组件name的用处)

vue的组件递归

6、读取html上的dom元素,组织成树形json数据。这个想法是错误的,多想想vue能帮我做什么,省去我操作dom的工作。对数据驱动理解不够深刻,加上被递归弄迷糊了,其实,dom的层级关系,抽象成数学模型,就是树结构的数据,dom就是树形数据的呈现

7、监听数组变化,需要增加deep: true属性,深度监听。如下图所示

深度监听

8、监听字符串,需要增加immediate: true

字符串监听

【遗留问题】

1、子组件修改父组组件传递的props后,父组件中值会不会改变?

答案:会。但是vue会报错,单向数据流禁止这样的操作。正确的方式式,子组件通过$emit触发父组件自己内部修改。形成一个可控的数据流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342