ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:574.66KB ,
资源ID:27455468      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/27455468.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(做减法的二次开发平台.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

做减法的二次开发平台.docx

1、做减法的二次开发平台做减法的二次开发平台拼出一张世界地图一位软件开发商的老总曾经问,“当初自己做项目时就用Delphi,几个人3个月的时间完成了。为什么现在十几个人,用了这个平台那个框架,还需要半年多的时间。”在笔者不知如何作答之际,老总自己说出了心中的答案,“可能是现在需要实现的不是几个业务功能而是一个大的业务系统,要写大量的项目文档量,比起C/S,B/S的这种多层架构在技术上需要考虑的东西也更多了”。每一次计算模式与通讯模式的变革,都会摧生一批相应的二次开发平台,好比一次次航海技术与行陆技术的升级之后,人们总会发现未知的世界。如果将C/S架构带来的新世界比作一个岛屿,B/S架构带来就是一个

2、新大陆,后者需要更多的勘探时间。没有人能在很短的时间内走遍这块大陆,务实的做法是将一部分地域勘探清楚,测绘出局部地图,若干份局部地图拼起来构成全貌。因此,一个有趣的现象是在C/S时代,Delphi、PowerBuilder、Notes二次开发平台或工具自成体系,并基本是互斥的;而在B/S时代,数据持久层框架、业务对象层框架、表现层框架是相互配合的。C/S时代的技术假设是以桌面操作系统为前台环境,业务逻辑前置;B/S时代的技术假设是以浏览器为前台环境,业务逻辑后置,原来的二次开发平台已无用武之地。多数公司选择了重要而且紧急的后台业务逻辑框架作为研发重点,少数公司,选择了重要但不紧急的表现层框架作

3、为研发重点。这好比多数人从大陆的一端开始勘探,少数人从另一端开始,经过一段时间的各自努力,在内陆会师。交换成果后,大家发现至少可以拼成一张贯穿大陆主线的地图。在表现层框架成熟之时,构建一个真正意义上的贯穿前后台的快速开发平台就成为可能,这也意味着占代码量50%的前台开发有规范与标准可依。新一代的二次开发平台应该是:1, 较为完整,涵盖从前台到后台的软件架构各个层次。2, 组装灵活,可以使用全部也可以使用其中一部分。3, 开放度高,当某一层出现更为先进的框架时,可以取代现有该层框架。换言之,用户可以用做加减法的方式,将不需要的部分从该平台中移除,将需要的部分引入,从而调整出适用某个项目需求的最精

4、简的开发架构平台。随着这样的二次开发平台不断发展,用户将更多地做减法。由简入繁难,由繁入简易有过J2EE Web应用开发经历的程序员都知道,对于每一个应用我们除了要处理复杂的界面与排版之外,还要处理诸如权限、异常、日志等等这些与业务无关但又不可或缺的功能,实现这些功能要占用我们的大量时间,让本来就短的项目工期更显得捉襟见肘。 按照做减法的二次开发平台的设想,我们选取对应于软件架构中各层的成熟框架,以松耦合的形式将这些框架整合到一起协调工作,这样就可以初步满足上述需求了。 J2EE Web系统开发中最麻烦的不是占50%工作量后台业务逻辑,而是另一个50%前台界面开发,我们引入展现中间件来负责这一

5、层,后台业务逻辑层中众多的Java对象与属性配置文件的管理交给业务对象层,再加上必需的应用中间件与数据库,就构成了二次开发平台的核心。数据库里存放的是平面化的二维数据,在面向对象的开发模式中,操作的是立体化的对象数据,增加一个持久层框架来负责这个O/R mapping的过程。需要细化对系统资源的权限管理,比如按角色方式管理用户能否访问页面、组件、组件里的元素及后台的Java方法,可以引入一个权限框架。在强调业务流转或规则计算的场景中可以引入工作流管理系统与规则引擎。如果业务流转跨系统并涉及SOA架构体系,可以引入企业服务总线层。(图:二次开发平台功能由简单到复杂)加上基于该二次开发平台的示例应

6、用页面,整个体系可能看上去已比较庞大,大多数情况下,我们只会用其中一部分,而不是整个体系,以避免层次太多,过度设计。常言道“由俭入侈易,由侈入俭难”,在架构增删上,则是“由繁入简易,由简入繁难”。将松耦合的一个大架构删减为一个小架构,比起从无到有地搭建出这个小架构,工作量上会小很多。(图:做减法的二次开发平台总揽)dorado应用基础框架(MARMOT)从2000年开始,笔者所在公司BSTEK的研发团队就开始专注于交互型Web应用系统的表现层的技术研发,2002年BSTEK成立,2003年推出Extra 3,2005年推出dorado 4,2006年推出企业级AJAX展现中间件dorado 5

7、。dorado的出现解决了B/S应用的前端展现问题,使我们原来要花费一天时间才能做好的界面现在一个小时或更短的时间就可以完成了。用户提出在此基础上如果提供现成的更加贴近于应用的诸如各种展现组件自定义、权限等相关功能的实现,将进一步优化dorado的实际应用效果,另一方面,每家软件开发商引入dorado展现中间件都或多或少有一个与既有开发平台整合的过程。为此,BSTEK推出了dorado应用基础框架(代号Marmot )。MARMOT在英文是土拨鼠、旱獭的意思。每年2月2日是传统的“土拨鼠日”(Groundhog Day)。民间传说,如果土拨鼠在这一天出洞时看到自己影子的话,会回洞继续冬眠,那意

8、味着冬天还将持续6周,反之则意味着春天的脚步近了。因此每逢此日,经历着漫漫长冬的人们便关注着土拨鼠“预报员”的春天预言。最初给起代号的时候,需要一个能让联想到“Hibernate、Spring”的单词,会冬眠而又能预言春天来临的土拨鼠是不是很可爱呢。名字就这样延用下来,现在又增加了像土拨鼠一样打通应用架构中的各个环节的喻意。DORADO设计与实现 在介绍Marmot之前,先介绍一下DORADO展现中间件的设计与实现,其设计有以下几个特点:1, OPOB设计模式。OPOB - One Page One Business,即通过一个页面完成一个业务功能,是更适应页面复杂操作频繁的交互型MIS类业务

9、需求的设计模式。之前的MPOB是适应浏览型与填报型业务需求的设计模式。2, 数据模型驱动。表现层框架数据与UI组件相分离,通过具有管理功能的对象(dataset称为数据集合或数据模型)保证各种数据控件具有一致的行为,用户完全通过各种数据感知控件来观察和操作数据模型中的数据。dorado所采用的数据与表象分离的设计方式,事实上就是一种MVC的架构模式,是存在于Client端内部的“迭代式的MVC架构”。(图:dorado中的数据模型驱动)dorado中的组件主要分为Dataset和Control两种。Dataset用于分装展现层中的数据,Control用于封装各种界面元素和操作逻辑。Contro

10、l主要用于与用户交互,Dataset主要用于与后台数据、业务逻辑交互。(图:dorado实现原理)随着技术的发展,对数据的管理、对UI组件的管理、对AJAX通信的封装、国际化等等表现层的功能和设计已经变得越来越复杂,现在已经不再是那个表现层里只有HTML的年代了,已经成为了一个跨越Server端和Client端的子系统。3, 松耦合整合。表现层框架与后台业务逻辑框架的对接采取松耦合模式,只要能把数据塞给表现层框架,表现层框架就能展现,并能够把数据回填给后台业务逻辑框架。4, 性能优化。DORADO客户端的优化包括通过大量测试寻到最优实现方案(JavaScript+DHTML的使用方面) 、复杂

11、界面按需初始化、规避由浏览器BUG导致的内存泄露等,对网络通讯的优化包括数据的懒加载、利用GZIP对通讯数据进行压缩、利用JavaScript编译器对库文件进行代码压缩、利用Ajax改善用户的操作体验等。DORADO展现中间件的实现,有以下几个层次:1,表现层4大功能。数据通过各种控件展示,进行查询、增加、修改、删除、保存等操作,占表现层技术需求的80%,这是DORADO本身研发实现的重点,提供控件Widget Lib、国际化I18N、皮肤Skin,角色Role、AJAX通讯引擎等支持通过视图模型viewModel进行表现层建模。剩余20%包括报表与打印、复杂图形与数据分析、文书等,通过与第三

12、方产品整合或集成来实现。2,前后台交互。通过不同的数据集合dataset支持不同的后台,包括SQL查询结果集,POJO(Javabean或Map的collection),Web Service,XML,定制的数据集合等,对框架而言,支持Spring、Hibernate/ibatis、WfMC/BPEL/自有标准流程引擎等。3,开发与调试环境。提供集成开发工具 dorado studio与Eclipse插件用于提供针对产品所需的各种源文件的模版化生成、创建向导、可视化配置,以及一些简单的编译、部署、测试等功能。Debugger提供评估JavaScript并计时、显示调试日志、显示部分系统信息等功

13、能的简单JS调试小工具。4,性能测试与调优。内置多种浏览器端性能优化措施。提供Web Console进行参数配置与性能监控。提供自主研发开源小工具TestFrame专用于测试页面刷新用时、提交用时等浏览器端页面性能定量指标。MARMOT核心整合原理在引入DORADO时,开发商可能并不希望自己的业务逻辑层的实现代码与之发生耦合。因此往往需要在原有的核心代码与第三方产品之间建立一个胶合层,利用这层代码完成对第三方产品的集成工作。这里的胶合层应该是轻量的、灵活可配的。在实现此胶合层的过程中,Spring作为一个成熟的、被广泛认可的IOC框架应当是一个很自然的选择。另一方面,随着技术的发展,基于Str

14、uts、WebWork、Spring、Hibernate、iBatis等开源框架的开发模式正被越来越多的开发商所接受。当他们又要引入一个DORADO来增进前台的展现能力时往往会无从下手,弄不清框架中的各个部件应该如何与DORADO协调合作。MARMOT填补了这个空缺,使DORADO与各种后台框架能够很好的进行协调配合。MARMOT提供了DORADO展现层中间件与后台业务逻辑层框架的无缝整合方案,并提供源代码。如果与项目需求匹配度高,可以直接使用MARMOT,如果有差距,可以在其基础上修改,或者至少可以当成一个范例来看。具体说来MARMOT是包括展现中间件dorado、业务对象层框架Spring

15、、数据持久层框架,流程引擎、权限框架、企业服务总线,以及报表工具、门户引擎、规则引擎、页面控制层框架等以松耦合集成形式形成的大型Web应用系统的开发平台与运行平台。在MARMOT没有出现时,我们可以把下图想象成传统开发模式与DORADO之间的关系。(图:尚未集成的框架)如图所示,其中的Business Logic代表开发商现有的业务逻辑代码。而DORADO包含了服务端引擎和客户端引擎两部分,这两个部分是密切相关,相互配合的,他们共同完成了表现层的功能。与业务逻辑的对接将主要通过与DORADO Server Engine之间的交互来完成。基本的集成思路大致如下。(图:基本的集成思路图)如上图,D

16、ORADO Server Engine与Business Logic直接的通过Spring来起到承上启下的作用。而在DORADO的Server Engine和Client Engine之间我们也可以看到一些变化,那就是控制层的引入。对于AJAX应用而言在操作的过程中客户端存在着大量的远程过程调用(RPC),这里的RPC并不是我们通常意义上所说的Server-Server的远程调用,而是指从浏览器客户端到服务端,利用JavaScript中的iFrame或XMLHttpRequest完成的方法调用。这些来自客户端的RPC请求,需要类似Servlet这样的对象来接收和处理。在上图中可以看出,我们利用

17、了开源控制层框架(Spring MVC、Struts、WebWork)来处理这些请求。使用这种方式主要基于如下的考虑: 这些是应用非常广泛的产品,开发商原有的开发框架中极有可能已经使用了其中的某一个,在这种情况下没有必要为RPC请求单独注册一组Servlet。 目前的技术人员可能已经常常熟悉其中的某种框架,他们可以在MARMOT中直接选择他们熟悉的框架来使用,这有利于他们更快的了解MARMOT运转机制。这些框架往往都提供了很完善的配置方案和扩展机制。例如其中的Spring MVC和WebWork都能很好的利用AOP机制来辅助功能扩展。回到前面的话题,在集成Business Logic、Spri

18、ng、DORADO、Controller的过程中我们需要一些代码和配置来完成整个工作。MARMOT为我们填补了这些空缺。(图:MARMOT在集成过程中的作用)MARORT应用框架正是基于上述基础架构之上开发的一套包含WEB应用系统常见功能的应用框架,开发人员可以将MARMOT作为软件开发的基础,对于MARMOT没有的功能,开发人员也可以方便的进行扩充。MARMOT各层框架的选择 表现层框架是展现中间件dorado。dorado支持OPOB设计模式、迭代式表现层MVC架构与视图建模,丰富的控件库Widget Lib由BRICH引擎统一驱动,内置AJAX通讯引擎、数据抽象集合是其一大特色、此外还提

19、供国际化、表现层角色控制、外观皮肤切换等辅助功能。对于复杂页面,传统JSP中代码很长很复杂,不利于项目开发,更不利于上线后的维护。基于dorado的复杂页面,JSP中只保留TagLib的声明代码与排版代码,复杂的部分被剥离出来放到一个XML中。一些特效,如表格行通过鼠标drag&drop进行表格行拖动,已在控件中实现,开箱即用。因此基于dorado建设J2EE Web应用,开发迅速,维护方便。业务对象层框架选择的是Spring。Spring是基于依赖注入(DI)设计模式等设计的BO层框架,采用XML格式的文件来指定业务对象之间的关系。Spring的作者在编写Spring之前先是写了一本书介绍其

20、设计思想,这种“兵马未动粮草先行”的做事风格值得称道。数据持久层框架是对象关系映射框架,对JDBC进行轻量级的对象封装,负责Java对象和关系数据库之间的映射的ORM,使用对象编程思维来操纵数据库,自动化或半自动化地完成数据持久化功能、POJO 与SQL之间的映射关系等。通常采用XML格式的文件来指定对象和关系数据之间的映射,在运行时,根据这个映射文件来生成各种SQL语句,使应用程序可以在不同数据库平台下迁移。数据持久层框架选择的是Hibernate与iBatis。前者是“全自动”ORM 实现,后者是半自动的。权限框架选择的是Acegi。Acegi是为基于Spring的应用提供的声明式安全框架

21、。它通过在Spring的应用上下文中配置一系列的Bean完成安全设置,完成利用了Spring提供的依赖注入和IoC编程方式。为了保证Web应用的安全需求,Acegi使用过滤器拦截servlet请求,并执行认证来执行安全措施。 Acegi通过安全方法级调用来执行更低层次的安全需求。通过使用Spring的AOP,Acegi使用代理对象来确保用户有适当的权限来调用被保护的方法。无论是较高层次的Web应用的安全,还是较低层次的方法级安全,Acegi都可以通过四个主要组件完成安全需求。 Security Interceptor 用于拦截那些需要访问受保护资源的请求。 Authentication Man

22、agers 用于验证主体的身份,如principal(典型的如用户名)和Credentials(典型的如密码)。能过验证,可以证明Who are you 。 Access Decision Mangers 用于决定已验证通过的principal是否有访问受保护资源的特权。 Run-as Managers 用于在通过验证和并得到授权之后,对访问资源进行更多的安全约束。流程引擎既可以WfMC标准,也可以是BPEL标准。WfMC(Workflow Management Coalition,工作流管理联盟)是创建于1993年8月,由工作流软件供应商、用户、大学以及其他研究团体共同组成的一个非盈利性的国

23、际组织。其任务是制订标准推动工作流管理的应用和发展,统一工作流软件术语,加强工作流产品供应商之间的协同工作与联系。WfMC对工作流(Workflow)的定义是:自动运作的业务过程的部分或整体,表现为参与者对文件、信息或任务按照规程采取行动,并令其在参与者之间传递。简单地说,工作流就是一系列相互衔接、自动进行的业务活动或任务。BPEL(业务流程执行语言Business Process Execution Language)是一门用于自动化业务流程的形式规约语言。 用XML文档写入BPEL中的流程能在Web 服务之间以标准化的交互方式得到精心组织。这些流程能够在任何一个符合BPEL规范的平台或产品

24、上执行。通过允许顾客们在各种各样的创作工具和执行平台之间移动这些流程,BPEL使得他们保护了他们在流程自动化上的投资。WfMC更接近于人机交互,倾向于审批流转型Workflow;BPEL更接近于数据与服务,倾向于自动执行型Business Process。近年来支持BPEL标准的厂商在其产品中增加了Human Task,以适用审批型需求。企业服务总线选择的是IBM WebSphere Process Server。ESB (Enterprise Service Bus,企业服务总线)是为分散服务提供交互、组合和治理,是实现SOA的基础架构。ESB支持多类信息服务(multiple messag

25、ing services),提供不同格式数据的转换引擎,事件通知功能及注册及储存(registry/repository)功能。报表工具、门户引擎、规则引擎、页面控制层框架等都可以根据实际需求灵活选择。MARMOT的三大亮点Marmot为我们解决了企业应用开发中的一些与具体业务无关的基础问题。在该框架中我们除了可以使用标准Dorado所提供的标准功能以外,Marmot还提供了一些扩展的功能,如Dorado表格表单的个性化定制、系统导航菜单的定制、权限异常日志的管理、万能查询的定制保存与加载、系统内部消息发送、业务流程的控制等。这其中Dorado表格表单的个性化定制、权限控制的实现和万能查询的定

26、制保存与加载构成了Marmot的三大亮点。表格的个性化定制。标准的Dorado表格用户可以改变列头的位置、设置显示和隐藏列、设置锁定列等,一旦页面刷新用户调整的效果也就会丢失,表格会恢复到初始状态。在Marmot中改变了这一局面,默认情况下可以把用户对Dorado表格所做的各种调整都记录下来,这样当用户刷新页面或重登录系统看到的就是他最近一次对表格调整的效果。同时通过Marmot我们还可以对Dorado表格做更为精细的调整(如列名,列组合,单元格编辑器类型等),所有这些调整完成后都可以记录下来,从而达到用户对自己看到的表格的个性化定制。(图:Marmot中的表格自定义)表单的个性化定制。当开发

27、人员完成对dorado里的表单(AutoForm)开发后,用户是无法对表单的布局、编辑器类型、表单分组进行调整的。在Marmot中对标准的Dorado里的表单做了一些扩展,使的普通的用户可以根据自己的喜好对表单的布局、分组、字段的编辑器类型、大小等各种属性做一些个性化的定制,同样定制完成后可以保存下来,这样用户刷新页面或下次登录时就可以见到自己最近一次对表单做的调整。(图:Marmot中的表单自定义)万能查询与查询预案。查询、检索是信息系统中数据维护的标准功能,每一个应用界面,只要涉及到数据的维护都要求有对数据的检索功能,同时我们又会发现,这些查询功能基本上都是类似的,但为了需求的实现,我们不

28、得不为每一个维护界面开发出检索功能。Marmot中的万能查询可以帮助程序员快速的实现这一功能,在Marmot中,我们只需做些简单的配置就可以呼叫出Marmot的万能查询页面,从而实现对数据的查询与检索。同时,对于应用系统的某些操作员来说,可能他每次登录系统后都要在某个功能模块页里的查询窗口输入相同或相似的条件来检索到一批结果集进行处理,如果他每次输入的只有一两个条件问题还不是很大,假如他每次要输入四五个甚至上十个条件相信效率是非常低的。在Marmot中的万能查询还提供了另外一个功能,那就是查询预案的保存与加载。通过这种机制,操作员可以把自己在查询窗口里设置的条件保存为一个方案,这样下次就可以通

29、过下拉框选择的形式加载自己保存过的查询方案,这样就可以大大提高操作的效率,同时也给用户带来很好的操作体验。(图:Marmot中的万能查询)权限控制的实现。Marmot可以让用户轻易的实现让某些用户或角色有权或无权访问某些资源,具体分为三层,第一层为URL,第二层为组件以及组件里的元素(如指定表格中的某列为只读等),第三层为后台的Java方法。开发时,程序员不用考虑权限问题,开发完成后,上线之前进行权限配置即可。权限信息来源可以是LDAP,也可以是数据库的中几张表,根据具体情况实现预留的接口即可。默认情况下当某一个资源没有被分配给任何一个人或角色的时候那么这个资源是公共的,所有的系统用户都有权限

30、访问,一旦该资源分配给了某个用户或角色,那么这个资源只能由该用户或角色可访问,其它用户或角色就无权访问该资源。默认情况下Marmot中的资源访问权限是分配给角色的,同时还提供了一个名为“角色代理”的功能,指当一个某个用户因为某些原因不能处理当前自己权限范围可以完成的工作时,可以把自己的这个权限暂时分配给其它人代为处理一下。界面风格的选择是Marmot中提供的一种特色功能。通过在登录页中的Style的选择,用户可以根据自己的喜好,选择自己喜欢的操作界面。开发者可以以这些示例作为应用框架的模版,也可以根据需要通过一些简单的配置创建全新风格的主框架。(图:用户操作风格的选择)Marmot提供了以数据

31、库方式存贮系统导航菜单结构的基础实现。包括菜单结构的维护界面、快速生成各种菜单的工具类,通过Marmot提供的菜单工具类可以实现菜单的一次性装载或懒装载。菜单的工具类包含以下两大类: LazyMenuUtils:用于生成支持懒装载的菜单、支持菜单栏、Outlook栏、导航树等多种菜单类型。懒装载菜单适合展示菜单层数和项数均较多的菜单,通过对菜单项的懒装载可以保证界面的初始化速度不会因菜单过于复杂而降低。DiligentMenuUtils:Diligent取Lazy之反义,用于生成一次性装载的菜单,支持菜单栏、Outlook栏、导航树、多页标签等菜单类型。一次性装载的菜单适合那些层数和项数均较少

32、的简单菜单。通过替换MenuFactory的实现类就可以将Marmot的菜单功能与其他存储机制接驳,例如:其他结构的数据库、XML等,并且也可以在MenuFactory的实现类中植入对菜单项的权限控制逻辑。收藏夹是Marmot中提供的一个小的辅助功能。它可以把我们应用操作中常用的页面像浏览器的收藏夹一样收藏起来,这样下次登录系统后可以通过收藏夹功能快速的导航到需要操作的功能模块页面。实时消息是一套消息发送的功能,利用这个功能可以向系统中的其它用户或用户组发送定时消息(如果不指定时间,那消息会在第一时间送达接收者),同时消息发送过程中用户还可以指定是否同时发送到对方邮箱,当然开发者也可以做适当扩展,加上短消息发送等功能。实时消息的发送不要求接收者一定在线,如果接收者在线它会在指定时间收到发送者发送的消息,如果接收者不在线,下次登录后他还会在指定时间收到消息。Marmot中提供了默认的数据字典功能的实现,包括内嵌的数据字典读取装载逻辑、数据库结构、专用的数据字段维护界面。数据字典信息的装载支持“设计时装载”或“运行时装载”方式,其中“设计时装载”的效率稍高,但不利于实时的反应数据字典中的信息.而“运行时装

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1