朔州有企业微信公众号小程序开发公司;朔州存在企业网页设计方案;朔州有做网站开发的价格;朔州有微信公众号制作运营的报价明细表;朔州有网站设计公司的费用;朔州有网站推广大概所需的费用。
朔州处在中国山西省的北部,其位置处于桑干河的上游。它的西北方向与内蒙古自治区相邻,在南边则扼守着雁门关隘。从地貌轮廓来看,总体上是北、西、南三面环绕着山脉,这些山脉的山势比较高;而中间部分是桑乾河域的冲积平原,相对来说地势较低。朔州属于温带大陆性季风气候。它下辖二区一市三县,分别是朔城区、平鲁区、怀仁市、山阴县、应县、右玉县,一共有 73 个乡镇(含街道办),1591 个行政村。其总面积为 1.06 万平方公里,在 2017 年的时候,常住人口达到 177.6 万。 [1]
朔州市的平均海拔为 1000 米。这里寒来暑往,四季的特点十分分明。它是全国著名的避暑胜地,也是京津地区避暑休闲的“后花园”。全市拥有各类规模的旅游景区景点达 80 处。其中有 4 处是 4A 级景区,1 处是国家级水利风景区,6 处是国家级文物保护单位,19 处是省级文物保护单位,42 处是市级重点文物保护单位。在历史上,先后涌现出了西汉时期著名的女诗人班婕妤、三国时期的名将张辽、唐朝的开国元勋尉迟恭以及明朝的首辅王家屏等一批杰出人物。 [3]
2020 年,朔州市达成了地区生产总值为 1100.5 亿元这一成果。在 2020 年,该生产总值比 2019 年增长了 4.1%,具体数据为[22]。
在权限的设计中,较为常见的是 RBAC 基于角色的访问控制。其基本思想为,对于系统操作的各类权限,并非直接授予具体的用户,而是在用户集合与权限集合之间构建一个角色集合。并且每一种角色都对应着一组相应的权限。
用户被分配适当角色后,就拥有此角色的所有操作权限。好处在于,不用每次创建用户时都进行分配权限操作,只需分配用户相应角色就行。同时,角色的权限变更比用户的权限变更少很多,这能简化用户的权限管理,减少系统开销。
在构建的单页面应用里,要实现这样的架构,我们得额外做些事情。从整个项目来看,大概有 3 个地方,前端工程师需要对其进行处理。
UI 会根据用户所拥有的权限来进行处理,判断页面上的某些内容是否应该显示。
当用户访问一个没有权限访问的 url 时,会进行路由处理,然后跳转到一个错误提示的页面。
当我们发送一个数据请求时,如果返回的是 401 或者 401 这种情况,通常会重定向到一个带有错误提示的页面。
如何实现?
首先要在启动前获取当前用户的所有信息。比较优雅的方式是通过一个存放映射关系的东西来实现。对于 UI 处理页面上的内容是否根据权限显示,我们应该通过一个特定的方式来达成。处理完这些后,在添加一个路由时,要额外为其添加一个“”属性,并给这个属性赋值,表明拥有哪些权限的角色可以跳转这个 URL,然后通过监听事件来校验当前用户是否拥有此 URL 的访问权限。最后还需要一个 HTTP 拦截器,监控当一个请求返回 401 或者 403 时,将页面跳转至一个错误提示页面。
工作大致上就是这些,看起来数量较多。但实际上,一个一个去处理的话,还是挺好处理的。
在运行之前获取到的映射关系
项目由 ng-app 启动,然而在某些情形下,我们期望项目的启动处于我们的掌控之中。就像当下这种情况,我期望在获取到当前登录用户的所有映射关系之后,再启动 App。值得庆幸的是,其本身提供了这种方式,即……
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre style="box-sizing: border-box; overflow: auto; font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 12px; line-height: 20px; font-family: "courier new"; padding: 10px 20px; margin-top: 20px; margin-bottom: 20px; color: rgb(248, 248, 212); overflow-wrap: break-word; background-color: rgb(74, 74, 74); border: none; border-radius: 4px;">var permissionList;
angular 中的 element 对 document 进行操作,当 document 准备好后,执行一个函数。
使用`$.get`方法获取`/api/UserPermission`,然后在获取到的数据的回调函数中进行相关操作。
permissionList = data;
angular 对文档进行引导操作,引导的内容是 ['App'] 。
});
});</pre></p>
仔细观察的人或许会留意到,这里采用的是$.get()。没有误用的是而不是$或者$http,原因在于在这个时刻还未启动,所以我们无法使用它。
使用上面的代码能够把获取到的映射关系放置到一个作为全局变量的地方去使用。
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre style="box-sizing: border-box; overflow: auto; font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 12px; line-height: 20px; font-family: "courier new"; padding: 10px 20px; margin-top: 20px; margin-bottom: 20px; color: rgb(248, 248, 212); overflow-wrap: break-word; background-color: rgb(74, 74, 74); border: none; border-radius: 4px;">// app.js
有一个名为 app 的变量,它是通过 angular.module('myApp', []) 创建的,还有一个 permissionList 。
app 运行时需要获取权限,具体如下: 首先获取 permissions 相关权限。
设置权限(permissionList)。
});
angular.element(document).ready(function() {
permissionList = data;
angular.bootstrap(document, ['App']);
});
});
// common_service.js
angular 模块名为“myApp”。
在“permissions”这个方面,函数是这样的:它接收一个参数 $rootScope ,并在内部进行相关的操作和处理。
var permissionList;
return {
这个函数用于设置权限,参数为 permissions 。
permissionList 等于 permissions 。
$rootScope 广播了 'permissionsChanged' 事件。
}
};
});</pre></p>
取得当前用户的权限集合后,我们把这个集合存档到相应的一个地方,接着做了两件事:
将其存放到变量里,能让它一直保留在内存中,这样就实现了全局变量的作用,同时又没有对命名空间造成污染。
(2) 通过$广播事件,当权限发生变更的时候.
如何确定UI组件的依据权限进行显隐
这里我们需要自行编写一个,它会按照权限关系来决定是显示还是隐藏元素。
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre style="box-sizing: border-box; overflow: auto; font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 12px; line-height: 20px; font-family: "courier new"; padding: 10px 20px; margin-top: 20px; margin-bottom: 20px; color: rgb(248, 248, 212); overflow-wrap: break-word; background-color: rgb(74, 74, 74); border: none; border-radius: 4px;">
<div has-permission='Edit'>
{{ name }}
</div>
<div has-permission='!Edit'>
{{ name }}
</div></pre></p>
这里看到的比较理想的情况是:如果当前用户有一个通过了 has-属性校验的 name,就将其显示出来;如果当前用户没有这样的 name,就将其隐藏起来。
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre style="box-sizing: border-box; overflow: auto; font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 12px; line-height: 20px; font-family: "courier new"; padding: 10px 20px; margin-top: 20px; margin-bottom: 20px; color: rgb(248, 248, 212); overflow-wrap: break-word; background-color: rgb(74, 74, 74); border: none; border-radius: 4px;">angular 的 module 名为“myApp”,它有一个 directive 名为“hasPermission”,这个 directive 在 function 内部使用了 permissions 。
return {
链接:函数(作用域、元素、属性){
如果不是字符串类型的 attrs.hasPermission 。
抛出“hasPermission 值必须是一个字符串”;
value 等于 attrs.hasPermission 经过去除空格后的结果。
变量 notPermissionFlag 等于 value 的第一个元素等于 '!' ;
如果没有权限标志,那么(进行相应操作)。
value 进行了切片操作,从索引 1 开始,然后进行了去除两端空白字符的操作。
}
函数以权限为依据来对可见性进行切换操作。
var 表示是否具有权限,即权限对象 permissions 具有特定值 value 的权限,其结果赋值给 hasPermission 变量。
如果有权限并且没有禁止权限标志,或者没有权限并且有禁止权限标志。
element.show();
else
element.hide();
}
根据权限来切换可见性。
语言风格:保持原文风格,去掉最前面的序号,把
}
};
});</pre></p>
扩展一下之前的:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre style="box-sizing: border-box; overflow: auto; font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 12px; line-height: 20px; font-family: "courier new"; padding: 10px 20px; margin-top: 20px; margin-bottom: 20px; color: rgb(248, 248, 212); overflow-wrap: break-word; background-color: rgb(74, 74, 74); border: none; border-radius: 4px;">angular 模块名为 'myApp' 。
3. var permissionList;
4. return {
设置权限:函数(权限)。
permissionList 等于 permissions 。
$rootScope 触发了 'permissionsChanged' 的广播。
8. },
这个函数用于判断是否具有特定的权限。它接收一个参数 permission,用于表示要判断的权限。通过这个函数,可以确定当前对象是否拥有指定的权限。
permission 等于 permission 经过去除两端空白字符后的结果。
返回一些满足条件的元素,条件是在 permissionList 中,通过函数 (item) 来判断。具体来说,就是找到那些使得函数 (item) 返回 true 的元素并返回它们。
如果 item.Name 是字符串类型。
检查返回的 item.Name 进行修剪后的结果是否等于 permission 。即判断 item.Name 去除两端空白字符后的内容与 permission 是否相等 。
14. });
15. }
16. };
17. });</pre></p>
路由上的依权限访问
然后根据校验结果决定是跳转成功还是跳转到错误提示页面。
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre style="box-sizing: border-box; overflow: auto; font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 12px; line-height: 20px; font-family: "courier new"; padding: 10px 20px; margin-top: 20px; margin-bottom: 20px; color: rgb(248, 248, 212); overflow-wrap: break-word; background-color: rgb(74, 74, 74); border: none; border-radius: 4px;">app 进行配置,在这个配置过程中,通过 function ($routeProvider) 来进行相关操作。
2. $routeProvider
3. .when('/', {
templateUrl 为 'views/viewCourses.html' 。
controller 表示 'viewCoursesCtrl' 。
6. })
当出现“/unauthorized”时,在{ }内进行相关操作。
templateUrl 的值为 'views/error.html' 。
controller 表示的是 'ErrorCtrl' 。
10. })
当访问 '/courses/:id/edit' 路径时,在以下情况下:
templateUrl 为 'views/editCourses.html' 。
controller 的操作是 'editCourses'。
权限:“编辑”
15. });
16. });</pre></p>
.js 或者 .js (总之是父层)
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre style="box-sizing: border-box; overflow: auto; font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 12px; line-height: 20px; font-family: "courier new"; padding: 10px 20px; margin-top: 20px; margin-bottom: 20px; color: rgb(248, 248, 212); overflow-wrap: break-word; background-color: rgb(74, 74, 74); border: none; border-radius: 4px;">app 控制器名为“mainAppCtrl”,它接收三个参数,分别是$scope、$location 和 permissions,函数体如下:
$scope 监听了 '$routeChangeStart' 事件,当该事件触发时,会传入 scope、next 和 current 这三个参数,具体的函数定义如下:function(scope, next, current) { }
var 表示获取下一个路由的权限,将其赋值给 permission 变量,即 permission 等于 next.$$route.permission 。
如果 permission 是字符串类型,并且 permissions 没有该权限 permission ,则……
将路径设置为“/unauthorized”;$location.path 被设置为“/unauthorized”;路径被设置为“/unauthorized”,通过 $location.path 来实现;$location.path 执行了将路径设置为“/unauthorized”的操作;路径经由 $location.path 被设置为“/unauthorized”;$location.path 把路径设置成了“/unauthorized”;设置路径为“/unauthorized”,通过 $location.path 来进行;$location.path 负责将路径设置为“/unauthorized”;路径被 $location.path 设定为“/unauthorized”
6. });
7. });</pre></p>
这里再次使用了之前所写的内容,这些东西具备高度的可复用性。如此一来就完成了,在每次 view 的路由跳转之前,在父容器中去判断它是否具有跳转的权限就可以了。 |