Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

跨技术栈的后台权限管理子应用方案设计 #63

Open
wuyanqian0503 opened this issue Jul 14, 2021 · 0 comments
Open

跨技术栈的后台权限管理子应用方案设计 #63

wuyanqian0503 opened this issue Jul 14, 2021 · 0 comments

Comments

@wuyanqian0503
Copy link
Owner

wuyanqian0503 commented Jul 14, 2021

背景

  • 后台系统多而且技术栈不统一
  • 权限管理的业务功能几乎需求一样,没有定制化的需求

功能页面

权限管理子应用所包含的页面一共有十几个页面,一级页面主要有

  • 用户管理
  • 组织架构
  • 角色管理
  • 节点配置

设计的主旨

  • 保证业务系统快速接入
  • 跨技术栈(UMI、Ant Design Pro、Vue-Element-Admin等等)

设计的难点

如何加载子应用

可行的方案有iframe、npm包,CDN引入,微前端框架等,最后使用了npm包的方式
选择npm包的方式主要是考虑到易于接入和维护的因素。

  • 通过发布到npm私服的方式供主应用安装
  • 在对应页面中引用组件即可显示子应用内容

设计子应用的入口

我们知道后台系统是一个SPA页面,通常后台系统还有一个左侧的菜单栏,所有的路由都需要在路由表中进行配置,否则你在刷新页面的时候可能就会报错,那么我们子应用的页面如果想要融入主应用中,就需要在路由表中配置子应用的页面路由和对应的组件。

子应用中包含的页面有很多,但我们希望用户不需要关心页面对应的子应用组件是哪一个,而且接入时最好是不同页面都可以通过统一的应用入口去加载子应用。所以我们的包导组件只有一个子应用入口组件,主应用中不同的路由都指向同一个业务组件A,在A中再去引用我们的子应用入口组件B。B内部通过接收到的的页面名称参数判断需要渲染哪一个页面组件。

因为子应用的页面中也存在跳转到另一个子应用页面的场景,就需要业务系统中配置的路由path与我们子应用中的路由path是一致的,才能保证子应用中发生跳转时能够访问到正确的页面。

为了保证主应用和子应用的路由一致,又希望能够减轻用户接入时的工作,我们没有让用户自行编写路由具体path,而是将页面的path、名称、对应的组件名称都在子应用中进行硬编码,并且通过一个大的Components对象导出,业务系统中的路由表可以直接引用Components进行配置自己需要的页面。

如何切换路由,并保证面包屑的响应

解决方案:接收主应用的router实例,代理history.push

后台系统通常都有面包屑,用来表示当前用户所处的页面,并且可以让用户通过面包屑快速返回到上层的页面

这个面包屑通常都是后台框架提供的,比如vue-element-admin以及ant-design-pro都有提供面包屑功能,那么要理解面包屑变更的原理,就要知道面包屑如何监听路由的变化,这也就涉及到了react-router的原理。

前端路由模式

我们知道现代页面为了快速加载应用,除了第一次访问页面时,是直接从服务器获取页面的html等资源来展示的,后续的页面路由切换,正常情况下并不会再去向服务器请求页面资源。这种模式我们称之为前端路由。

前端路由有两种模式,hash和history,对应react-router中也分别通过这两种模式实现了两种路由方案,Hash-Router和Browser-Router。

hash模式的路由中,hash的变化是可以通过onHashChange来监听的,但是histroy模式的路由是通过pushState或者replaceState实现,并没有原生api可以监听,所以这种情况下,react-router通过代理原生history.push这个方法,提供给用户包装过的history,在触发push的时候主动去执行注册的事件监听器。而通过Context的特性,React 又提供了 useHistory 这样的hook,当路由发生变更后,所有使用了useHistory的函数组件都会重新执行。

所以面包屑之所以能够监听到路由发生了变更,是因为我们修改路由时都是通过了react提供的push方法,push方法会通知到面包屑路由发生了变更。所以子应用中的路由切换也应当使用业务系统中的router实例提供的history.push才能够通知到面包屑。

基于这个原理,又因为要跨技术栈,所以我们增加了一个入参router,也就是业务系统的router实例,通过代理router实例的histroy.push方法来兼容不同框架的切换路由的API

如何隔离样式

解决方案:css-loader支持模块化的配置,通过模块化配置中的 getLocalIdent 方法来自定义导出css样式的类名,为子应用的样式统一添加前缀来避免污染主应用的样式

如何保证请求失败的处理逻辑与主应用一致

例如无权操作的处理方案,登陆失效的处理方案等

后端的权限管理也是一个独立的包,响应的数据结构以及错误码和主应用有可能不一样,所以采用提供默认的处理方案,但是也允许外部传入方法来覆盖。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant