八百里加急$数据结构追加2组织权限设计
在任何系统中,权限设计是最基础的东西,本文给出一个基于角色的权限设计的循序渐进的设计方案。
在权限系统中,功能(权限)是最小的单位,比如起草新闻、编辑新闻、审核新闻、删除新闻等,而角色是一类功能的集合,比如新闻编辑这个角色,他可能有起草新闻、编辑新闻等功能集合,而责任编辑他可能就有更多的权限,比如除了新闻编辑的功能,还有审核新闻、删除新闻等功能,给张三赋予新闻编辑的角色(其实我更愿意说把张三加入到新闻编辑这个角色中去),张三就可以起草新闻、编辑新闻了,给李四赋予责任编辑的角色,李四就可以起草新闻、编辑新闻、审核新闻、删除新闻了。
我们来看看版本一的解决方案:
我们来模拟一下上面的数据:
用户信息表:
UserID |
UserName |
U1 |
张三 |
U2 |
李四 |
角色表:
RoleID |
RoleName |
R1 |
新闻编辑 |
R2 |
责任编辑 |
角色用户表:
RoleID |
UserID |
R1 |
U1 |
R2 |
U2 |
功能表:
FunctionID |
FunctionName |
F1 |
起草新闻 |
F2 |
编辑新闻 |
F3 |
审核新闻 |
F4 |
删除新闻 |
角色功能表:
RoleID |
FunctionID |
R1 |
F1 |
R1 |
F2 |
R2 |
F1 |
R2 |
F2 |
R2 |
F3 |
R2 |
F4 |
我们来看看如何判断一个用户具有某个功能权限:
首先在用户张三登录的时候,获取张三的全部功能列表:
Select FunctionID From 角色功能表 Where RoleID In (Select RoleID From 用户角色表 Where UserID=’U1’)
这样就可以得到张三的全部功能列表Functions,在起草新闻的页面我们就可以做如下判断:
Functions.Contain(‘F1’);//当然你可以把这个’F1’定义成一个常量:NewsFunction.Draft
如果为true就说明张三有起草新闻的权限。
当然对于web应用,您可以把Functions 用session保存起来,以避免每打开一个页面都去数据库中获取。
似乎看起来是一个不错的解决方案。
还是新闻系统,最初新闻系统没有分类,但是随着新闻的增加,没有分类的新闻看起来总是乱的,于是张三和李四给新闻添加了分类A、分类B,还是由张三负责起草,李四负责审核,以后又添加了更多的分类,并且也增加了人手,这个时候就有新的要求出来了:希望张三只负责分类A的起草,分类B的起草交给其他人做,李四呢也只负责分类A的审核(就相当于是一个栏目的责任编辑)。
针对这样的需求,版本一就无能为力了(当然你也可以增加几个功能:比如分类A的新闻起草和分类B的新闻起草,再把这个功能添加到相应的角色里面去,但是这个应该不是我们要得解决方案吧,不过版本二也是基于这个思想来解决的)。
其实比新闻更好的例子是论坛板块的版主。
下面是版本二的解决方案:
在版本二的功能表中加入了一个ResourceType这个字段,这个字段用来表示对某个资源的分类(比如新闻),我们同样来模拟一下(新闻分类A的ResourceType为:NTA,分类B为:NTB):
功能表:
FunctionID |
ResourceType |
FunctionName |
F1 |
NTA |
起草新闻:分类A |
F2 |
NTA |
编辑新闻:分类A |
F3 |
NTA |
审核新闻:分类A |
F4 |
NTA |
删除新闻:分类A |
F1 |
NTB |
起草新闻:分类B |
F2 |
NTB |
编辑新闻:分类B |
F3 |
NTB |
审核新闻:分类B |
F4 |
NTB |
删除新闻:分类B |
然后在角色表添加相应的角色,在角色功能表中添加对应的功能。
获取Functions的语句也相应地做变化:
Select FunctionID + ‘,’ + ResourceType From 角色功能表 Where RoleID In (Select RoleID From 用户角色表 Where UserID=’U1’)
权限的判断也就变成:
Functions.Contain(‘F1,NTA’);
在新添加一个分类的时候,同时也在功能表中增加相应的记录(当然不是在数据库里面直接添加,由和功能相关的函数来添加)。
使用这种解决方案可以简单地对有分类的应用(比如论坛系统)的每个分类实行不同的控制(比如VIP板块,就只能拥有VIP角色的用户才能浏览、发表等,而其他板块只要是注册用户就可以使用了)。
在实际应用中FunctionID并不是随便的一个字符串,而是进行了编码,其编码中包含了模块ID以及能够体现出父子关系,举个例子来说:对于论坛系统,我们给它一个模块ID为”30”,论坛的功能我们先分成2类,一类是管理类(比如删除帖子),一类是使用类(比如发帖、回帖、浏览帖子等),给管理类一个编码:01,使用类一个编码:02,我们就对FunctionID进行如下的编码:
300101:删除帖子
300201:发帖
300202:回帖
300203:浏览帖子
对于资源(比如某个板块1,板块的ID为:01),我们可以组合出如下的Functions(当然这个组合你也可以不用逗号分隔,用其他的组合方式也可以,不过不要产生歧义):
300101,01:板块1删除帖子的功能
300201,01:板块1发帖的功能
……
对于RoleID也是采用的编码方式,也能体现角色的父子关系,也可以实现角色功能的继承等(当然获取角色功能列表的SQL语句就不是现在这么简单了)。在我现在的应用里面没有实现角色的继承(虽然角色的编码体现出了角色的父子关系)。
转载:http://tubo.cnblogs.com/archive/2005/09/02/228828.html
权限管理
权限管理,主要是人员和权限之间的关系,但是如果让人员直接和权限打交道,那么权限的赋值、权限的撤销以及权限的变动会非常的麻烦,这样引入了,角色,给角色赋权限,然后给用户分配角色。
这个设计主要涉及6张表,
用户表,(用于存储用户的所有信息)
权限表,(用于存储所有的权限)
角色表,(用于存储所有的角色)
用户和角色的关联表,(用户和角色的关联)
角色和权限的关联表,(角色和权限的关联)
菜单表,(里面关联了权限,主要是现实用的)
用户表
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->CREATE TABLE [dbo].[Users](
[UserID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nvarchar](50) primary key,--帐号
[Password] [nvarchar](50) ,
[UserDspName] [nvarchar](50) ,
[Sex] [char](1),
[Birthday] [datetime],
[Phone] [nvarchar](20) ,
[Email] [nvarchar](100),
[EmployeeID] [nvarchar](20) ,
[Activity] [bit],--是否可用
[UserType] [char](2) ,
[Style] [nvarchar](50)
)
权限表:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->CREATE TABLE [dbo].[Permission](
[PermissionID] int identity,
[Description] [nvarchar](50) --权限名称
)
角色表:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->CREATE TABLE [dbo].[Roles](
[RoleID] [int] IDENTITY,
[Description] [nvarchar](200)--角色名称
)
用户和角色的关联表:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->CREATE TABLE [dbo].[UserRoles](
[UserID] [int] NOT NULL,--用户ID
[RoleID] [int] not null ,--权限ID
CONSTRAINT [PK_UserRoles] PRIMARY KEY CLUSTERED
(
[UserID] ASC,
[RoleID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
角色和权限的关联表:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->CREATE TABLE [dbo].[RolePermissions](
[RoleID] int NOT NULL,--角色ID
[PermissionID]int NOT NULL,--权限ID
CONSTRAINT [PK_RolePermissions] PRIMARY KEY CLUSTERED
(
[RoleID] ASC,
[PermissionID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
菜单表:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->CREATE TABLE [dbo].[menu](
[ID] [int] IDENTITY(1,1) NOT NULL,
[TextCH] [nvarchar](100) NULL,--菜单的中文显示
[TextEN] [nvarchar](200) NULL,--菜单的英文名称
[ParentID] [int] NULL,--父节点
[orderID] [int] NULL,--同一个父节点下面的排序
[Url] [nvarchar](200) ,--菜单对于的权限
[PermissionID] [int] NULL,--权限ID
[ImageUrl] [nvarchar](50) NULL--菜单图片链接
) ON [PRIMARY]
--用户登陆
select * from Accounts_Users where username='admin' and [password] ='admin'
--1 用户角色表中的用户ID=登陆的用户ID
--用户角色中的角色ID=角色许可表中的角色ID
--角色许可表中的模型ID=模型ID
--最终取出模型表中的相关数据
数据库
--作者:张涛
use master
Go
create database AccountsRole
go
use AccountsRole
go
create table userLog --用户登陆表
(
userId int primary key,
userName nvarchar(20),
userPwd nvarchar(20),
isSuper bit --是否是管理员
)
go
insert into userLog values(1,'admin','admin',0)
insert into userLog values(2,'user','user',1)
go
create table Roles --角色表
(
roleId int primary key, --角色编号
roleName nvarchar(50), --角色名称
texts text
)
go
insert into roles values(1,'系统管理员','s')
insert into roles values(2,'管理员','s')
insert into roles values(3,'科长','s')
insert into roles values(4,'科员','s')
go
create table menu --菜单表
(
menuId int primary key, --菜单编号
menuValue nvarchar(50), --菜单名称
menuUrl nvarchar(50)
)
go
insert into menu values(1,'签发文件','http://baidu.com')
insert into menu values(2,'职称修改','http://baidu.com')
insert into menu values(3,'文件修改','http://baidu.com')
insert into menu values(4,'未发','http://baidu.com')
insert into menu values(5,'已发','http://baidu.com')
insert into menu values(6,'所有计划','http://baidu.com')
go
create table userRole --用户角色表
(
id int primary key identity(1,1),
userId int references userLog(userId), --用户编号
roleId int references Roles(roleId), --角色编号
)
go
insert into userrole values(1,1)
insert into userrole values(2,2)
go
create table RolePermission
(
id int primary key identity(1,1),
roleId int references Roles(roleId), --角色编号
menuId int references menu(menuId), --角色编号
)
go
insert into RolePermission values(1,1)
insert into RolePermission values(1,2)
insert into RolePermission values(1,3)
insert into RolePermission values(1,4)
insert into RolePermission values(2,1)
insert into RolePermission values(2,2)
insert into RolePermission values(2,3)
go
select * from userLog
select * from Roles
select * from userRole
select * from menu
select * from RolePermission
--用户登陆
select * from userLog where username='admin' and userpwd='admin'and issuper=0
--按照用户名查找用户角色 根据用户角色查找菜单项 管理员登陆
select roleid from userrole where userid=1 --根据角色的个数循环执行下面的sql语句
select distinct m.menuvalue,m.menuurl from userRole as r ,menu as m ,RolePermission as p
where r.userid=1 and r.roleId=p.roleId and p.menuId=m.menuId
go
--用户登陆
select roleid from userrole where userid=2 --根据角色的个数循环执行下面的sql语句
select distinct m.menuvalue,m.menuurl from userRole as r ,menu as m ,RolePermission as p
where r.userid=2 and r.roleId=p.roleId and p.menuId=m.menuId
go
select m.menuvalue,m.menuurl from userRole as r ,menu as m where r.userid=1 andr.roleId=1 and r.menuId=m.menuId
--登陆验证
select * from userlog where username='admin' and userpwd='admin' and issuper=0
--根据用户具有的角色角色许可 对应的菜单
select distinct m.menuvalue,m.menuurl from userRole as u,RolePermission as p,menu as m
where u.userid=1 and u.roleId=p.roleid and p.menuid=m.menuid
go
--用户登陆
select distinct m.menuvalue,m.menuurl from userRole as u,RolePermission as p,menu as m
where u.userid=2 and u.roleId=p.roleid and p.menuid=m.menuid
go
--添加菜单
insert into menu values(7,'测试菜单','http://www.google.com')
--给角色添加权限
insert into RolePermission values(1,5)
insert into RolePermission values(1,6)
insert into RolePermission values(1,7)
insert into RolePermission values(2,4)
go
代码:
protected void Page_Load(object sender, EventArgs e)
{
//判断用户的权限 根据登陆的用户名的编号 查询权限并得到相应的结果 r.userid=1
string sql = "select distinct m.menuvalue,m.menuurl from userRole as r ,menu as m ,RolePermission as p where r.userid=1 and r.roleId=p.roleId and p.menuId=m.menuId";
SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=AccountsRole;Integrated Security=True");
SqlDataAdapter sqldad = new SqlDataAdapter(sql, conn);
DataTable dt = new DataTable();
sqldad.Fill(dt);
this.GridView1 .DataSource=dt;
this.GridView1 .DataBind();
//普通用户登陆 r.userid=2
//string sql = "select distinct m.menuvalue,m.menuurl from userRole as r ,menu as m ,RolePermission as p where r.userid=2 and r.roleId=p.roleId and p.menuId=m.menuId";
//SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=AccountsRole;Integrated Security=True");
//SqlDataAdapter sqldad = new SqlDataAdapter(sql, conn);
//DataTable dt = new DataTable();
//sqldad.Fill(dt);
//this.GridView1.DataSource = dt;
//this.GridView1.DataBind();
} // 管理员登陆 用户登陆
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
、
一,前言
权限管理系统的应用者应该有三种不同性质上的使用,
A,使用权限
B,分配权限
C,授权权限
本文只从《使用权限》和《分配权限》这两种应用层面分析,暂时不考虑《授权权限》这种。
二,初步分析
用户和角色
说到权限管理,首先应该想到,当然要设计一个用户表,一个权限表。这样就决定了一个人有什么样的权限。
做着做着就会发现这样设计太过繁琐,如果公司里面所有员工都有这样的权限呢,每一个人都要配置?那是一件很痛苦的事情。因此再添加一个角色表,把某些人归为一类,然后再把权限分配给角色。角色属下的用户也就拥有了权限。
用户、角色之间的关系是一个用户可以对应多个角色,一个角色可以对应多个用户。多对多关系。
所以需要一个中间表,相信大家都很熟悉,自然不会有疑问。
应用场景
有了用户和角色以后,就需要设计应用场景,比如一个应用程序有几大模块(系统模块、项目管理模块、销售模块),
类似这样的模块就是一种应用场景,常见的还有 菜单 、 操作 等等。
假设现在我们设计好了,应用场景包括 模块、菜单、和操作,那么应该有以下六种关系
- 一个用户可以对应多个模块,一个模块可以对应多个用户。多对多关系。
- 一个用户可以对应多个菜单,一个菜单可以对应多个用户。多对多关系。
- 一个用户可以对应多个操作,一个操作可以对应多个用户。多对多关系。
- 一个角色可以对应多个模块,一个模块可以对应多个角色。多对多关系。
- 一个角色可以对应多个菜单,一个菜单可以对应多个角色。多对多关系。
- 一个角色可以对应多个操作,一个操作可以对应多个角色。多对多关系。
于是建立六张表来维护这六种关系。
这样设计看起来没什么问题。是的,如果没有加入新的关系的话,这样是已经可以满足大部分的需求了。可是如果就是如果,新的关系(需求)往往会加入到系统进来。这个时候就需要再建立一个新的表。系统的复杂度也随着增加。
可以看出,这样的设计有几个问题:
- 数据表设计太复杂
- 应对系统方案过于固定
三,把问题简单化
不同的应用场合,你可能会想出不同的需求,提了一个新的需求以后,可能会发现原来的设计没方法实现了,于是还要添加一个新的表。这也是上面所提到的问题。
其实不必想得那么复杂,权限可以简单描述为:
某某主体 在 某某领域 有 某某权限
1,主体可以是用户,可以是角色,也可以是一个部门
2, 领域可以是一个模块,可以是一个页面,也可以是页面上的按钮
3, 权限可以是“可见”,可以是“只读”,也可以是“可用”(如按钮可以点击)
其实就是Who、What、How的问题
因此上面所提到的六张表其实可以设计一张表:
四,实例说明
下面用一个例子做设计说明。“用户、角色在页面上的是使用权限”
详细设计:
1,把菜单的配置放在数据库上,每一个菜单对于一个唯一的编码MenuNo,每一个“叶节点”的菜单项对于一个页面(url)。
2,把按钮的配置放在数据库上,并归属于一个菜单项上(其实就是挂在某一个页面上)。应该一个页面可能会有几个按钮组,比如说有两个列表,这两个列表都需要有“增加、修改、删除”。所以需要增加一个按钮分组的字段来区分。
3,把菜单权限分配给用户/角色,PrivilegeMaster为"User"或"Role",PrivilegeMasterValue为UserID或RoleID,PrivilegeAccess为“Menu",PrivilegeAccessValue为MenuNo,PrivilegeOperation为"enabled"
4,把按钮权限分配给用户/角色,PrivilegeMaster为"User"或"Role",PrivilegeMasterValue为UserID或RoleID,PrivilegeAccess为“Button",PrivilegeAccessValue为BtnID,PrivilegeOperation为"enabled"
5,如果需要禁止单个用户的权限,PrivilegeOperation 设置为"disabled"。
如果不清楚的可以看下图:
数据库设计:
四,结语
说了这么多,其实我推荐的只是Privilege的表设计。这个表是who、what、how问题原型的设计。不仅扩展性、灵活性都很好,而且将复杂的权限管理系统浓缩成一句话。
而PrivilegeOperation不仅仅只是使用和禁止两种,包括分配权限、授权权限,都可以用这个字段定义。只是这无疑加大了应用程序的设计难度,但是对于表设计可以不做出任何的修改就可以完成,可以看出其灵活性。
设计思想
设计实例
权限表permission
英文描述 |
类型 |
长度 |
是否主键 |
备注 |
id |
int |
11 |
Y |
主键 |
name |
string |
255 |
N |
权限名 |
column_id |
int |
11 |
N |
与权限分栏字段关联 |
permission |
string |
255 |
N |
与权限映射表相关联,权限操作信息 |
create_date |
string |
255 |
N |
创建时间 |
create_by |
string |
25 |
N |
创建人 |
update_date |
string |
255 |
N |
修改时间 |
update_by |
string |
25 |
N |
修改人 |
角色表role
英文描述 |
类型 |
长度 |
是否主键 |
备注 |
id |
int |
11 |
Y |
主键 |
name |
string |
255 |
N |
角色名 |
info |
string |
255 |
N |
角色信息 |
create_date |
string |
255 |
N |
创建时间 |
create_by |
string |
25 |
N |
创建人 |
update_date |
string |
255 |
N |
修改时间 |
update_by |
string |
25 |
N |
修改人 |
用户表person_user
英文描述 |
类型 |
长度 |
是否主键 |
备注 |
id |
string |
20 |
Y |
人员编号 |
employee_name |
string |
10 |
N |
人员姓名 |
birthday |
date |
N |
出生日期 |
|
address |
string |
255 |
N |
居住地 |
sex |
string |
2 |
N |
性别 |
work_experience |
string |
3 |
N |
工作年限 |
id_number |
string |
18 |
N |
身份证号码 |
account_location |
string |
255 |
N |
户口所在地 |
marred |
string |
10 |
N |
婚姻状况 |
political_status |
string |
20 |
N |
政治面貌 |
zip_code_1 |
string |
6 |
N |
居住地邮编 |
zip_code_2 |
string |
6 |
N |
户口所在地邮编 |
mobile_number |
string |
11 |
N |
联系电话 |
emergency_call |
string |
11 |
N |
晋级联系电话 |
|
string |
50 |
N |
邮箱 |
file_location |
string |
255 |
N |
档案所在地 |
file_location_type |
string |
255 |
N |
档案管理形式 |
social_insurance |
string |
10 |
N |
是否缴纳社会保险 |
social_insurance_type |
string |
20 |
N |
保险形式 |
provident_fund |
string |
10 |
N |
是否缴纳公积金 |
provident_fund_type |
string |
255 |
N |
公积金形式 |
social_security_number |
string |
30 |
N |
社保卡号码 |
provident_fund_number |
string |
30 |
N |
公积金号码 |
social_security_kind |
string |
10 |
N |
社会保险险种 |
depart_id |
string |
20 |
N |
所属部门 |
position_id |
string |
20 |
N |
职位 |
entry_time |
string |
20 |
N |
入职时间 |
employee_state |
string |
10 |
N |
在职状态1:在职0:离职 |
create_date |
date |
N |
录入时间 |
|
create_by |
string |
10 |
N |
录入人 |
update_date |
date |
N |
更新时间 |
|
update_by |
string |
20 |
N |
更新人 |
权限映射表role_permission
英文描述 |
类型 |
长度 |
是否主键 |
备注 |
id |
int |
11 |
Y |
|
permission |
string |
255 |
N |
关联权限 |
role_id |
int |
11 |
N |
关联角色 |
create_date |
string |
255 |
N |
创建时间 |
create_by |
string |
25 |
N |
创建人 |
update_date |
string |
255 |
N |
修改时间 |
update_by |
string |
25 |
N |
修改人 |
用户映射表user_role
英文描述 |
类型 |
长度 |
是否主键 |
备注 |
id |
int |
11 |
Y |
|
role_id |
int |
11 |
N |
角色id |
user_id |
string |
20 |
N |
用户id |
create_date |
string |
255 |
N |
创建时间 |
create_by |
string |
25 |
N |
创建人 |
update_date |
string |
255 |
N |
修改时间 |
update_by |
string |
25 |
N |
修改人 |
八百里加急$数据结构追加2组织权限设计相关推荐
- C语言/C++常见习题问答集锦[八十三]之数据结构顺序表(operand types are error: no match for “operator==“)
C语言/C++常见习题问答集锦[八十三]之数据结构顺序表{operand types are error: no match for "operator=="} 程序之美 前言 主 ...
- Vue 人资 实战篇八 权限设计 重点!!!路由访问权限,左侧导航栏显示等等,还有 mixin 混入方法
1.0 权限设计-RBAC的权限设计思想 传统的权限设计是对每个人进行单独的权限设置,但这种方式已经不适合目前企业的高效管控权限的发展需求,因为每个人都要单独去设置权限 基于此,RBAC的权限模型就应 ...
- 权限系统设计学习总结(2)——SAAS后台权限设计案例分析
分享一个大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!点击浏览教程 saas平台由于其本身"按需购买"的特性,在设计规划权限时,需 ...
- 权限设计的一些想法和思考
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:cross my.oschina.net/cloudcros ...
- 浅谈OFBiz之权限设计
简介 Apache Open For Business(Apache OFBiz) 是Apache开源的一个经典ERP项目.它提供了一套企业应用,用于集成以及自动化一些企业的"商业流程&qu ...
- 一个页面区分管理者和普通用户如何设计_产品经理要做的操作权限/数据权限设计...
产品经理在工作中还需要知道一个:用户权限设计能力.权限设计理念贯穿于后台产品.以及用户前端产品. 权限能力包括两类:数据权限.系统操作权限 有的人会好奇,为什么前端产品会有有权限管理的要求?接下来我将 ...
- 系统解读:权限设计指南
前言 本文针对初阶的产品经理.产品体验设计师,以及承担部分产品边界工作的交互设计师,较为系统地介绍了中后台权限系统的模型组成以及元素梳理.流程界面设计的诸多要点,读者可以以此来自查梳理内容是否充分以及 ...
- 一文带你学习DWS数据库用户权限设计与管理
前言 本文将介绍DWS基于RBAC(Role-Based Access Control,基于角色的访问控制)的数据库用户权限管理.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成 ...
- java的string访问某个元素_架构师必懂的——RBAC基于角色的访问权限设计
RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理.这 ...
最新文章
- 解析几何:第三章 平面上的直线
- CentOS命令行界面与图形界面切换(图文详解)
- 纯css实现移动端横向滑动列表
- mxnet基础到提高(48)-ones和ones_like
- android鼠标滚轮事件坐标,android 处理鼠标滚轮事件 【转】
- 前端实习生笔试_2016春网易前端暑期实习生笔试面经(二面已挂)
- 《长安十二时辰》背后的文娱大脑:如何提升爆款的确定性?
- python自动测试n_接口自动化:Jenkins 自动构建python+nose测试
- sketch钢笔工具_设计工具(Sketch,Adobe XD,Figma和InVision Studio)中奇怪的一项功能
- lgg6 android 9,LG G6的18:9屏幕用起来到底是什么样
- thinkphp php5.4报错,ThinkPHP6.0在PHP8下报错解决方法
- Elasticsearch了解多少,说说你们公司es的集群架构,索引数据大小,分片有多少,以及一些调优手段 。
- PLSQL Developer简单使用教程
- 北大生物信息学学习(2) 生物学及生物学信息学的发展
- C++学生信息管理系统1.0
- 实现asp程序调用摄像头并控制摄像头进行拍照
- eova中日期框、查找框、下拉框取值方法
- 从SVN检出项目下载到本地后出现错误
- 【语音信号处理】3语音信号可视化——prosody
- python长度转换代码尺和米_尺,寸,跟米,厘米的换算??
热门文章
- linux机顶盒 安卓机顶盒 优劣势分析,智能电视、网络机顶盒root好不好?优缺点详解...
- 神经网络的偏差和方差,神经网络均方误差公式
- 计算机毕业设计java+ssm医药进销存管理系统(源码+系统+mysql数据库+Lw文档)
- pandas对重复日期取均值合并再放回dataframe里
- 【算法设计与分析】动态规划:最优二叉搜索树
- 射频知识基础:三种接收机的介绍
- 最简版本mysql安装_最简单的配置mysql免安装版本的方法
- TF卡插到电脑时显示目录打不开请问如何才能修复?
- thinkphp中提示Warning:Invalid argument supplied for foreach()的解决方法
- 3DMM反射光线3D表达