收藏 分享(赏)

用户权限系统设计方案.doc

上传人:dzzj200808 文档编号:2723007 上传时间:2018-09-26 格式:DOC 页数:20 大小:614.50KB
下载 相关 举报
用户权限系统设计方案.doc_第1页
第1页 / 共20页
用户权限系统设计方案.doc_第2页
第2页 / 共20页
用户权限系统设计方案.doc_第3页
第3页 / 共20页
用户权限系统设计方案.doc_第4页
第4页 / 共20页
用户权限系统设计方案.doc_第5页
第5页 / 共20页
点击查看更多>>
资源描述

1、 用户权限系统设计方案摘要本文介绍一个应用于企业应用通用的用户权限系统的设计框架,其设计思想与主要文档来源自 SunWu Software Studio 的 iSecurityManager 产品。本指南适用于体系结构设计人员和开发人员。目录简介用户与角色动作定义应用模块授权总结链接资源简介安全始终是可信赖的企业应用的基石。在企业应用中,通常需要控制用户对业务操作的权限管理与控制。稍加分析不难发现这会涉及到这三个对象:用户/角色、动作/ 操作、授权状态,进一步分析,我们可发现 “动作/操作”通常是针对某个特定的对象,譬如 新增动作可对应于采购申请单也可对应于销售出库单等,这些动作对应的对象我们

2、将其称之为“应用模块”。至此,用户权限系统中的基本逻辑显形:谁(用户/角色)对什么(应用模块)是否具有某项操作(动作)的授权(授权状态:授予-Grant 、拒绝-Deny 、继承-Revoke ) 。用户与角色使用权限的基本单位,角色是具有一组相同授权的用户的交集。用户与用户之间没有互相隶属的关系,它只可以隶属于角色,角色可以隶属于另一角色,并且可具有多重隶关系。用户或角色通常具有以下属性:编号,在系统中唯一。名称,在系统中唯一。用户口令(角色无此属性)当然,在实际的商业应用中,可能还需要更多的属性来描述特定的业务需求。如在 iSecurityManager 中用户和角色的信息就有如下:图一:

3、角色信息图二:用户信息有了用户和角色对象,还必须有一个描述他们之间隶属关系的对象,这样的对象我们称之为“成员关系(Member)”,通常它可能有如下属性:用户编号角色编号该“用户编号” 和“ 角色编号 ”组合唯一约束,这里的“用户编号”可能是一个用户对象的编号,也可能是一个角色对象的编号,而“角色编号”则始终只能对应一个角色对象的编号。一个成员关系对象表示某个用户或角色隶属于另个角色。在 iSecurityManager 中可能有如下界面表示:图三:用户/角色成员关系在 iSecurityManager 中通过成员设置窗口来设置任何一个用户或角色(系统固定用户和角色除外)所隶属于的角色,也可以

4、通过角色属性窗口来设置所属于当前角色的直接下级成员。动作定义在涉及数据库操作的应用中,四个基本操作是“查看(Select)”、 “删除(Delete)”、 “新增(Insert)”以及“更新(Update)”。在一个企业应用中当然还会有更多其他的操作,尽管这些操作可能最终都基于这四个基本操作,也可能是其他的非数据操作,而我们始终无法在刚开始就完全固定这些可能的操作,为此,必须能让系统开发人员根据每个具体的应用模块来定义其所属的特定的动作/操作。动作/操作通常具有以下属性:名称,在系统中唯一。备注,描述动作/操作。在 iSecurityManager 中“动作定义”的信息就有如下:图四:动作定义

5、事实上,有些动作是需要针对具体的数据实例的,譬如“查看”、 “删除”和“ 更新”等,这种对数据实例级别的控制比针对“应用模块”级的控制要更精细。譬如,某个用户能进行对【采购申请单】的各项操作,他应该能查看他刚填写的单据并进行某些适当的修改,但是他却不应该看到其他人填写的数据。那么,这种粗粒度的权限设置显然无法控制数据级的访问,在 iSecurityManager 中,专门使用“流程控制”的方案和技术来达致更细粒度的对数据实例级的访问和控制。应用模块应用模块通常是指对应于企业应用中的某种类型的业务单据,譬如 ERP 系统中的【采购申请单】 、 【销售出库单】 、 【客户基础资料】等,这些业务单据

6、可能对应一或多张数据库表。如果从面向对象(Object Oriented)的视角去看,似乎可以将本文中所描述的这些概念理解成这样:“应用模块” 是类, “动作/操作”则是类的方法,而“应用模块”对应的数据库表(表结构)则是类的属性,表中的这些数据/记录就是类的实例了。在定义规划系统中的“应用模块”时,通常还需要指定某个“应用模块”可能具有的“ 动作/操作”,而这些“ 动作/操作”由动作定义中进行了定义。注意:应用模块是系统中的一种逻辑组织单位。应用模块通常具有以下属性:名称,在系统中唯一。标题,描述动作/操作。动作列表,表示该应用模块所可能具有的所有操作。在 iSecurityManager

7、中“应用模块”的信息就有如下:图五:应用模块定义授权顾名思义,授权是指用户/角色能对哪些应用模块中的某些操作(动作)是否具有执行的许可。这里的“是否具有执行的许可”实际上指的是授权的三种状态:授予-Grant、拒绝-Deny、继承-Revoke 。授予:用户/角色对某个应用模块的某项操作具有执行的权力。拒绝:用户/角色对某个应用模块的某项操作没有执行的权力。继承:用户/角色对某个应用模块的某项操作是否具有执行的权力要取决于它的父角色的授权定义。如果对某个角色授予某项权力,其下属的用户或角色是可以覆盖该项授权定义的。默认情况下,采用就近优先、拒绝优先的原则。在 iSecurityManager

8、中“授权设置”的信息如下所示:图六:权限设置总结通常“应用模块” 和“ 动作定义 ”是由系统开发商在系统设计、开发阶段就定义好了,在系统交付给用户使用后就不再对此更改了(当然这也不是绝对的,不是吗?) 。至此,有关用户权限的各项设置、定义都完成了,事实上,这并不会立即为你的应用系统带来任何安全保障,这只是一堆关于用户和授权定义的设置数据而已,还必须在应用系统中去应用这些设置数据并根据其定义的控制逻辑以对业务数据进行控制。如何利用这些用户授权数据来控制应用系统对业务数据的访问,有很多不同的解决方案,但是我认为建立一个中间数据存储层来统一所有客户端对数据源的存储访问是个不错的主意,并在这个数据访问

9、层中应用安全设置来对业务数据的各种访问进行授权验证和控制,这样就可以统一各种客户端对数据存储的安全应用(事实上 iSecurityManager 也正是如此处理这个问题的) 。权限设计数据库结构表 -权限许可 create table res_permission ( roleid INTEGER, resourceid varchar2(30), operationid integer, primary key(roleid,resourceid,operationid) ) -角色定义 create table res_role ( roleid INTEGER, rolename var

10、char2(30), roledesc varchar2(100), primary key(roleid) ) -角色权限 create table res_userrole ( roleid INTEGER, userid varchar2(30),-用户名 primary key(roleid,userid) ) -资源 create table res_resource ( resourceid varchar2(20), resourcename varchar2(30), resourcedesc varchar2(100), primary key(resourceid) ) -

11、操作信息 create table res_operation ( operationid varchar2(20), operationname varchar2(30), operationdesc varchar2(100), primary key(operationid) ) -res_operation 表的序列号 create sequence res_operation_seq; -res_role 表的序列 create sequence res_role_seq; -建立 soperationid 与 sroleid 两个序列分别用来产生 Operation 表与 Role

12、 表的 ID 列 create sequence soperationid increment by 1 start with 1 nomaxvalue minvalue 1; create sequence sroleid increment by 1 start with 1 nomaxvalue minvalue 1; -表设计的原理-根据交叉法来匹配权限-1:根据用户表中的用户 id 关联到 res_userrole 的 userid,然后再关联到 res_role,查出用户对应的所有权限,存放到 list 中-2:根据资源和操作查询出用户可以操作的所有许可 res_permissio

13、n,存放到 list 中-3:通过同时遍历两个 list,查询出是否存在交叉,如果存在就是有权限,否则为无权限四海同志的文章中有这样一句话:“传统业务系统中,存在着两种权限管理,其一是功能权限的管理,而另外一种则是资源权限的管理,在不同系统之间,功能权限是可以重用的,而资源权限则不能“。似乎他的那个权限设计也没有能够解决资源重用的问题。当然,如果它把资源文件分别存放在不通的文件夹中,通过 url 来根据权限来判断那就另当别论了。我这个人比较懒,总是想用一个通用的方法,放在哪里都合适,因此在数据库的设计上费了一番脑筋了。其实,很多的权限管理系统都不太一样,因此,很多开发者开发出来的权限管理系统放

14、在别的地方,就不一定合适了,往往需要重新开发,权限管理系统的结构不能变,变的仅仅是数据。在这样的一个思想的指导下,我们就想法让我们的结构不要变,尽可能的通用,其实结构在哪里,还是体现在数据库上了。四海同志说:“权限”, “组”和“人”。而这三种元素可以任意添加,彼此之间不受影响。而我却认为,一个完整的权限管理系统应该包括:用户、角色、模块、资源这四个部分,在数据库的表设计上,这四张表叫做权限管理系统的实体表,只要把这四个实体表做出来,权限管理系统的架构就搭建完整了,这样的权限管理系统翻译成中文那就是:权限管理系统是判断(可能用判断这个词不是很准确)用户或角色对什么资源是否有什么功能的这样一个系

15、统。这样设计出来的权限管理系统通用性、扩展性才够强,系统足够完整。四张实体表做好了,就意味着架构搭建好了,那么逻辑关系怎么办呢?我当时设计的时候用另外的4张表来存储他们之间的逻辑关系,总共8张表,四张实体表,四张逻辑关系表。 其它的权限管理系统可能少于8张表,一般通用性不会太好的。通常都是在完整的基础上做了下变化,有的利用继承来做,有的利用位运算,还有的虽然不通用,但是也是充分利用了自身的特点,一般都会少于8张表,但是一般翻译成汉语都不完整。通常为:用户对资源是否有什么功能、用户或角色对资源是否有权限等等。 。 。 。切记,通用的权限管理系统无论是用户、角色、模块、资源哪个方面,都可以在不改变

16、架构的条件下去动态的扩展,改变的仅仅是数据,而只要有这个思想,再结合自身项目的特点,相信设计和开发各种各样不通的权限管理系统不会有问题的用户权限管理 2008-01-03通用权限管理系统设计篇(一)一引言 因为做过的一些系统的权限管理的功能虽然在逐步完善,但总有些不尽人意的地方,总想抽个时间来更好的思考一下权限系统的设计。权限系统一直以来是我们应用系统不可缺少的一个部分,若每个应用系统都重新对系统的权限进行设计,以满足不同系统用户的需求,将会浪费我们不少宝贵时间,所以花时间来设计一个相对通用的权限系统是很有意义的。二设计目标设计一个灵活、通用、方便的权限管理系统。在这个系统中,我们需要对系统的

17、所有资源进行权限控制,那么系统中的资源包括哪些呢?我们可以把这些资源简单概括为静态资源(功能操作、数据列)和动态资源(数据) ,也分别称为对象资源和数据资源,后者是我们在系统设计与实现中的叫法。系统的目标就是对应用系统的所有对象资源和数据资源进行权限控制,比如应用系统的功能菜单、各个界面的按钮、数据显示的列以及各种行级数据进行权限的操控。三相关对象及其关系大概理清了一下权限系统的相关概念,如下所示:1. 权限系统的所有权限信息。权限具有上下级关系,是一个树状的结构。下面来看一个例子系统管理用户管理查看用户新增用户修改用户删除用户对于上面的每个权限,又存在两种情况,一个是只是可访问,另一种是可授

18、权,例如对于“查看用户”这个权限,如果用户只被授予“ 可访问”,那么他就不能将他所具有的这个权限分配给其他人。2. 用户应用系统的具体操作者,用户可以自己拥有权限信息,可以归属于0n 个角色,可属于0n 个组。他的权限集是自身具有的权限、所属的各角色具有的权限、所属的各组具有的权限的合集。它与权限、角色、组之间的关系都是 n 对 n 的关系。3. 角色为了对许多拥有相似权限的用户进行分类管理,定义了角色的概念,例如系统管理员、管理员、用户、访客等角色。角色具有上下级关系,可以形成树状视图,父级角色的权限是自身及它的所有子角色的权限的综合。父级角色的用户、父级角色的组同理可推。4. 组为了更好地

19、管理用户,对用户进行分组归类,简称为用户分组。组也具有上下级关系,可以形成树状视图。在实际情况中,我们知道,组也可以具有自己的角色信息、权限信息。这让我想到我们的 QQ 用户群,一个群可以有多个用户,一个用户也可以加入多个群。每个群具有自己的权限信息。例如查看群共享。QQ 群也可以具有自己的角色信息,例如普通群、高级群等。针对上面提出的四种类型的对象,让我们通过图来看看他们之间的关系。有上图中可以看出,这四者的关系很复杂,而实际的情况比这个图还要复杂,权限、角色、组都具有上下级关系,权限管理是应用系统中比较棘手的问题,要设计一个通用的权限管理系统,工作量也着实不小。当然对于有些项目,权限问题并

20、不是那么复杂。有的只需要牵涉到权限和用户两种类型的对象,只需要给用户分配权限即可。在另一些情况中,引入了角色对象,例如基于角色的权限系统, 只需要给角色分配权限,用户都隶属于角色,不需要单独为用户分配角色信息。在下一篇中,我们将讲述权限管理的数据库设计等内容。欢迎各位拍砖或给出宝贵意见。用权限管理设计篇(二) 数据库设计理清了对象关系之后,让我们接着来进行数据库的设计。在数据库建模时,对于 N 对 N 的关系,一般需要加入一个关联表来表示关联的两者的关系。初步估计一下,本系统至少需要十张表,分别为:权限表、用户表、角色表、组表、用户权限关联表、用户角色关联表、角色权限关联表、组权限关联表、组角

21、色关联表、用户属组关联表。当然还可能引出一些相关的表。下面让我们在 PowerDesigner 中画出各表吧。各表及其关系如下:1. 用户表用户表(TUser)字段名称 字段 类型 备注记录标识 tu_id bigint pk, not null所属组织 to_id bigint fk, not null登录帐号 login_name varchar(64) not null用户密码 password varchar(64) not null用户姓名 vsername varchar(64) not null手机号 mobile varchar(20) 电子邮箱 email varchar(6

22、4) 创建时间 gen_time datetime not null登录时间 login_time datetime 上次登录时间 last_login_time datetime 登录次数 count bigint not null2. 角色表角色表(TRole)字段名称 字段 类型 备注角色 ID tr_id bigint pk, not null父级角色 ID parent_tr_id bigint not null角色名称 role_name varchar(64) not null创建时间 gen_time datetime not null角色描述 description varc

23、har(200) 3. 权限表权限表(TRight)字段名称 字段 类型 备注权限 ID tr_id bigint pk, not null父权限 parent_tr_id bigint not null权限名称 right_name varchar(64) not null权限描述 description varchar(200) 4. 组表组表(TGroup)字段名称 字段 类型 备注组 ID tg_id bigint pk, not null组名称 group_name varchar(64) not null父组 parent_tg_id bigint not null创建时间 gen

24、_time datetime not null组描述 description varchar(200) 5. 角色权限表角色权限表(TRoleRightRelation )字段名称 字段 类型 备注记录标识 trr_id bigint pk, not null角色 Role_id bigint fk, not null权限 right_id bigint fk, not null权限类型 right_type int not null(0:可访问,1:可授权)6. 组权限表组权限表( TGroupRightRelation)字段名称 字段 类型 备注记录标识 tgr_id bigint pk,

25、 not null组 tg_id bigint fk, not null权限 tr_id bigint fk, not null权限类型 right_type int not null(0:可访问,1:可授权)7. 组角色表组角色表(TGroupRoleRelation)字段名称 字段 类型 备注记录标识 tgr_id bigint pk, not null组 tg_id bigint fk, not null角色 tr_id bigint pk, not null8. 用户权限表用户权限表( TUserRightRelation)字段名称 字段 类型 备注记录标识 tur_id bigint

26、 pk, not null用户 tu_id bigint fk, not null通用权限管理系统设计篇(三) 概要设计说明书在前两篇文章中,不少朋友对我的设计提出了异议,认为过于复杂,当然在实际的各种系统的权限管理模块中,并不像这里设计得那么复杂,我以前所做的系统中,由只有用户和权限的,有只有用户、权限和角色的,还有一个系统用到了用户、权限、角色、组概念,这个系统是我在思考以前所做系统的权限管理部分中找到的一些共性而想到的一个设计方案,当然还会有不少设计不到位的地方,在设计开发过程中会慢慢改进,这个系统权当学习只用,各位朋友的好的建议我都会考虑到设计中,感谢各位朋友的支持。今天抽时间整了一份

27、概念设计出来,还有一些地方尚未考虑清楚,贴出1.0版,希望各位朋友提出宝贵建议。大家也可以点击此处 通用权限管理概要设计说明书自行下载,这是1.0版本,有些地方可能还会进行部分修改,有兴趣的朋友请关注我的 blog。1. 引言1.1 编写目的本文档对通用权限管理系统的总体设计、接口设计、界面总体设计、数据结构设计、系统出错处理设计以及系统安全数据进行了说明。1.2 背景a、 软件系统的名称:通用权限管理系统;b、 任务提出者、开发者:谢星星;c、 在 J2EE 的 web 系统中需要使用权限管理的系统。1.3 术语本系统:通用权限管理系统;SSH:英文全称是 Secure Shell。1.4

28、预期读者与阅读建议预期读者 阅读重点开发人员 总体设计、接口设计、数据结构设计、界面总体设计、系统出错处理设计设计人员 总体设计、接口设计、数据结构设计、系统安全设计1.5 参考资料通用权限管理系统需求规格说明书通用权限管理系统数据库设计说明书2. 总体设计2.1 设计目标权限系统一直以来是我们应用系统不可缺少的一个部分,若每个应用系统都重新对系统的权限进行设计,以满足不同系统用户的需求,将会浪费我们不少宝贵时间,所以花时间来设计一个相对通用的权限系统是很有意义的。本系统的设计目标是对应用系统的所有资源进行权限控制,比如应用系统的功能菜单、各个界面的按钮控件等进行权限的操控。2.2 运行环境操

29、作系统:Windows 系统操作系统和 Linux 系列操作系统。2.3 网络结构通用权限管理系统可采用 Java Swing 实现,可以在桌面应用和 Web 应用系统中进行调用。如果需要要适应所有开发语言,可以将其 API 发布到 WEB Service 上。暂时用 Java Swing 实现。2.4 总体设计思路和处理流程在说明总体设计思路前,我们先说明本系统的相关概念:1.权限资源系统的所有权限信息。权限具有上下级关系,是一个树状的结构。下面来看一个例子系统管理用户管理查看用户新增用户修改用户删除用户对于上面的每个权限,又存在两种情况,一个是只是可访问,另一种是可授权,例如对于“查看用户

30、”这个权限,如果用户只被授予“可访问 ”,那么他就不能将他所具有的这个权限分配给其他人。2.用户应用系统的具体操作者,用户可以自己拥有权限信息,可以归属于0n 个角色,可属于0n 个组。他的权限集是自身具有的权限、所属的各角色具有的权限、所属的各组具有的权限的合集。它与权限、角色、组之间的关系都是 n 对 n 的关系。3.角色为了对许多拥有相似权限的用户进行分类管理,定义了角色的概念,例如系统管理员、管理员、用户、访客等角色。角色具有上下级关系,可以形成树状视图,父级角色的权限是自身及它的所有子角色的权限的综合。父级角色的用户、父级角色的组同理可推。4.组为了更好地管理用户,对用户进行分组归类

31、,简称为用户分组。组也具有上下级关系,可以形成树状视图。在实际情况中,我们知道,组也可以具有自己的角色信息、权限信息。这让我想到我们的 QQ 用户群,一个群可以有多个用户,一个用户也可以加入多个群。每个群具有自己的权限信息。例如查看群共享。QQ 群也可以具有自己的角色信息,例如普通群、高级群等。针对如上提出的四种对象,我们可以整理得出它们之间的关系图,如下所示:总体设计思路是将系统分为组权限管理、角色权限管理、用户权限管理、组织管理和操作日志管理五部分。其中组权限管理包括包含用户、所属角色、组权限资源和组总权限资源四部分,某个组的权限信息可用公式表示:组权限 = 所属角色的权限合集 + 组自身

32、的权限。角色权限管理包括包含用户、包含组和角色权限三部分,某个角色的权限的计算公式为:角色权限 = 角色自身权限。用户权限管理包括所属角色、所属组、用户权限、用户总权限资源和组织管理五部分。某个用户总的权限信息存在如下计算公式:用户权限 = 所属角色权限合集 + 所属组权限合集 + 用户自身权限。组织管理即对用户所属的组织进行管理,组织以树形结构展示,组织管理具有组织的增、删、改、查功能。操作日志管理用于管理本系统的操作日志。注意:因为组和角色都具有上下级关系,所以下级的组或角色的权限只能在自己的直属上级的权限中选择,下级的组或者角色的总的权限都不能大于直属上级的总权限。2.5 模块结构设计本

33、系统的具有的功能模块结构如下图所示:2.6 尚未解决的问题无。3. 接口设计(暂略)3.1 用户接口(暂略)3.2 外部接口(暂略)3.3 内部接口(暂略)4. 界面总体设计本节将阐述用户界面的实现,在此之前对页面元素做如下约定:序号 页面元素 约定1 按钮 未选中时:按钮名称选中时:按钮名称2 单选框 选项3 复选框 选项4 下拉框 选项, 5 文本框 |_|6 TextArea |7 页签 未选中时:选项名称选中时:选项名称8 未选中链接 链接文字9 选中链接 链接文字10 说明信息 说明信息4.1 组权限管理4.1.1包含用户组信息组 1组11组12组组2组21组22组所选择组:组1包含

34、用户 所属角色 组权限 总权限修改用户名 姓名 手机号 最近登录时间 登录次数阿蜜果 谢星星 13666666666 2007-10-8 66sterning xxx 13555555555 2007-10-8 10 当用户选择“修改 ”按钮时,弹出用户列表,操作人可以通过勾选或取消勾选来修改该组所包含的用户。4.1.2所属角色组信息组 1组11组12组组2组21组22组所选择组:组1包含用户 所属角色 组权限 总权限修改角色 ID 角色名称 角色描述1 访客 -2 初级用户 -当用户选择“修改 ”按钮时,弹出角色树形结构,操作人可以通过勾选或取消勾选来修改该组所属的角色。4.1.3组权限组信

35、息组 1组11组12组组2组21组22组所选择组:组1包含用户 所属角色 组权限 总权限保存 取消4.1.4总权限组信息组 1组11组12组组2组21组22组所选择组:组1包含用户 所属角色 组权限 总权限保存 取消通过对已具有的权限取消勾选,或为某权限添加勾选,来修改组的权限信息,点击“保存”按钮保存修改信息。4.1.5组管理在下图中,选中组1的时候,右键点击可弹出组的操作列表,包括添加、删除和修改按钮,从而完成在该组下添加子组,删除该组以及修改该组的功能。组信息组 1组11组12组组2组21组22组所选择组:组1包含用户 所属角色 组权限 总权限修改用户名 姓名 手机号 最近登录时间 登录

36、次数阿蜜果 谢星星 13666666666 2007-10-8 66sterning xxx 13555555555 2007-10-8 10 4.2 角色权限管理4.2.1包含用户角色信息角色 1角色11角色12角色角色2角色21角色22角色所选择角色:角色1包含用户 包含组 角色权限修改用户名 姓名 手机号 最近登录时间 登录次数阿蜜果 谢星星 13666666666 2007-10-8 66sterning xxx 13555555555 2007-10-8 10 当用户选择“修改 ”按钮时,弹出用户列表,操作人可以通过勾选或取消勾选来修改该角色所包含的用户。4.2.2包含组角色信息角色

37、 1角色11角色12所选择角色:角色1包含用户 包含组 角色权限修改组 ID 组名称 组描述角色角色2角色21角色22角色1 xxx1 -2 xxx2 - 当用户选择“修改 ”按钮时,弹出用户列表,操作人可以通过勾选或取消勾选来修改该角色所包含的组。4.2.3角色权限角色信息角色 1角色11角色12角色角色2角色21角色22角色所选择角色:角色1包含用户 包含组 角色权限保存 取消通过对已具有的权限取消勾选,或为某权限添加勾选,来修改角色的权限信息,点击“保存”按钮保存修改信息。4.2.4管理角色在下图中,选中组1的时候,右键点击可弹出组的操作列表,包括添加、删除和修改按钮,从而完成在该组下添加子组,删除该组以及修改该组的功能。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报