ORACLE R12中与二次开发相关技术的探讨与研究.ppt

上传人:文库蛋蛋多 文档编号:2998905 上传时间:2023-03-07 格式:PPT 页数:77 大小:1.14MB
返回 下载 相关 举报
ORACLE R12中与二次开发相关技术的探讨与研究.ppt_第1页
第1页 / 共77页
ORACLE R12中与二次开发相关技术的探讨与研究.ppt_第2页
第2页 / 共77页
ORACLE R12中与二次开发相关技术的探讨与研究.ppt_第3页
第3页 / 共77页
ORACLE R12中与二次开发相关技术的探讨与研究.ppt_第4页
第4页 / 共77页
ORACLE R12中与二次开发相关技术的探讨与研究.ppt_第5页
第5页 / 共77页
点击查看更多>>
资源描述

《ORACLE R12中与二次开发相关技术的探讨与研究.ppt》由会员分享,可在线阅读,更多相关《ORACLE R12中与二次开发相关技术的探讨与研究.ppt(77页珍藏版)》请在三一办公上搜索。

1、1,ORACLE R12中与二次开发相关技术的探讨与研究,2,内容安排,ORACLE R12 综述OAF综述OAF界面上的字段查询R12安全性新特性R12功能模块的变化R12其它细节性变化,3,ORACLE R12综述,ORACLE R12整套服务体系组成结构Oracle自带组件(ORACLE HOME路径下)其它组件(APPL_TOP下)第三方组件(APPL_TOP下)下图展示的是ORACLE R12版本中涉及的一些主要应用技术层的组件,图中红色高亮部分涉及到与之前版本的差异,将在综述中被介绍,4,R12 应用技术-总体变化,数据库层Oracle Database 9i Oracle dat

2、abase 10g应用层Application Server:1.0 10.1Oracle HTTP Server/Apache:1.3.19 10.1.3*Oracle Developer:6i 10g技术组件Servlet Container:JServ OC4J核心文件系统11i 的文件系统被替代成新的版本,5,R12 应用技术-高层分级结构,6,R12 应用技术-应用层自带组件,Oracle Database AS Client Libraries10.1.0.4.2Oracle Developer Client Libraries10.1.0.4.2Oracle JDeveloper

3、10.1.3Oracle AS Discoverer 10g10.1.2.0.2OJSP10.1.3Oracle HTTP Server/Oracle HTTP Client10.1.3(基于 Apache 1.3),7,R12 应用技术-应用层附带组件,Business Intelligence(BI)Beans3.1Java Database Connectivity(JDBC)10.2,BI Beans,JDBC,8,R12 应用技术-第三方组件,JDK for Web tier5.0JDK for Concurrent Processing tier5.0Sun Java Plug-i

4、n5.0,9,R12 应用技术-非嵌入式技术,Oracle AS 10g Portal10.1.4Oracle AS 10g Single Sign-On and Oracle Internet Directory10.1.2.0.2Oracle Collaboration Suite10g Release 1Oracle Enterprise Manager10g Release 1,10,R12 应用技术-优点,精简了一些比较旧版本的产品的使用率提高了业务相关组件的利用率第三方组件与之前版本相比,更加规范和完整,11,R12 应用技术-参考文献,更多产品信息http:/,12,R12 开发

5、机制,开发工具由Develop 向 JDevelop 缓慢过渡Form、Report、Java并存 R12大多数功能沿用原来的FORM机制,也有很多地方采用新的ORACLE OAF开发技术。FORM 界面和web界面并存OAF的开发 Oracle Jdeveloper9.0.3 Oracle Jdeveloper10g ORACLE 产品发展方向平稳中慢慢变化,大方向坚定,13,OAF简介-总体架构层次,PG(Page Region)层CO(Controller)层AM(Application Module)层VO(View Object)层EO(Entity Object)层,14,OAF简

6、介-PG(PageRegion)层,与FORM比较PG Canvas在IE上显示的最终用户图形界面通过JDeveloper10g来开发XML文件不是像VB那样去拖拉控件也不是全部手写的XML文件一种基于两者之间,在JDeveloper10g中会出现XML的层次构架可以在每个节点下添加控件 设置控件属性来控制WEB控件的显示格式和显示位置 page上用的都是ORACLE封装过的控件有些功能很容易实现但有的功能无法实现,15,OAF简介-CO(Controller)层,与FROM比较CO Form触发器和程序单元OAF通过CO控制页面,页面的任何动作都会在这里进行,包含两个methodproces

7、sRequest:initialize pre-form触发器processFormRequest:event 各种block和item层触发器不能在触发submit请求后直接更改WEBBIN属性,16,OAF简介-AM(Application Module)层,与FORM比较AM 联系Form中各种组件的枢纽和机制AM层是中间控制层只能通过CO调用 可以在AM层对DB端进行调用(VO)缺点:ORACLE不让在这里写太多的验证逻辑,17,OAF简介-VO(View Object)层,与Form比较 VO Block基于数据库的字段Web界面上的取数来源可以通过VO读取数据库里的数据并放到缓存或

8、EO中,18,OAF简介-EO(Entity Object)层,与Form比较EO Block所基于的视图或基表归根到底是一段SQL取自数据库中的表,试图或者同义词等对象在这里直接与DB数据进行交互,19,OAF简介-最简单的OAF应用开发过程,开发工具:Jdeveloper10g 第一步 在Jdeveloper中,创建一个 工作区,工作区的名字取为 TestProject,在应用程序模板一项 中,选择WEB APPLICATION(DEFAULT),确认后的工作区如图 所示,我们先建立Business Service 层的持久层对象。,20,OAF简介-最简单的OAF应用开发过程,在Mode

9、l这个工程上边,右键单击新建,然后选择Business Tier 下的Business Component,选择EntityObject,然后出现如图所示schema Object是让我们选择数据库中的表或者同义词等对象,name 是我们建立的持久层对象的名字,这里我们把name命名为CdtEquipmentEO,package指定这个对象放在什么包下面。,21,OAF简介-最简单的OAF应用开发过程,第二步建完持久层的实体对象后,我们就需要建立数据访问层的视图对象(ViewObject)。右键单击Model,新建选择ViewObject出现图,左边是供我们选择已经存在的持久层的实体对象(En

10、tityObject),这里面我们选择刚建好的CdtEquipmentEO这个实体对象。,22,OAF简介-最简单的OAF应用开发过程,第三步需要建立接口层(ApplicationModule),将数据访问层的视图对象(ViewObject)注册到ApplicationModule中,如图所示,我们选择CdtEquipmentView1这个视图对象,并把它添加到AppModul1中。,23,OAF简介-最简单的OAF应用开发过程,第四步按照OAF架构,Model层我们基本不需要作什么工作,那么我们下面开始建立Controller层,首先需要建立DataPage,可以是UIX格式的也可以是JSP

11、,这里我们用UIX格式。在Struts-config.xml中,从右侧的component中,可以直接选择DataPage,拖拽过来,listEquipment是我们给定的名字。,24,OAF简介-最简单的OAF应用开发过程,第五步建完Controller层,需要建立展现层(View),在listEquipment.uix页面中设置页面布局,可以对DataControl中的View进行拖拽,如图所示,我们选择Data Control 面板中的CdtEquipmentView1,这就是我们刚才建立的View,下面的拖拽类型选择只读表就可以了。,25,OAF简介-最简单的OAF应用开发过程,第六步

12、我们单击listEquipment.uix这个文件,选择运行(如下面左图所示),就可以直接得出所有设备的数据了,运行的效果(如下面右图所示)。,26,OAF简介-总结,优点在Jdeveloper10g中结合OAF框架,使开发人员能够从零开始构建J2EE应用程序和WEB服务。因为Oracle OAF的高度结合性,以及它里面提供的优秀技术,使得开发应用变得十分简单方便,从而大大提高了应用程序的开发效率,具有很高的应用价值。缺点OAF架构层次与FORM相比过于复杂,紧密,拘束类似于EJB,虽然有着非常完美的模型层次结构,在复杂的业务逻辑开发上更具大局观,但在一些需要快速完成的业务开发上反受其累。,2

13、7,OAF界面上的字段查询,对于传统的Form,当我们需要知道其后台对应的表的时候,可以通过菜单栏上的”帮助”来获得。疑问:如果是一张WEB界面,我们又该 如何取得DB端的数据呢?WEB界面和FORM界面到底有何 异同?R12的WEB界面11i界面相 比较,有哪些新增功能?,28,OAF界面上的字段查询,路径:OM_订单管理系统超级用户-客户-标准视觉效果HeadBodyFoot,29,OAF界面上的字段查询,接下来我们要做一个简单的查询,并对查询到的内容进行诊断以确定其数据库来源第一步键入查询条件进入选中记录,30,OAF界面上的字段查询,查询得到的界面如下主体字段弹性域字段,31,OAF界

14、面上的字段查询,第二步诊断主体字段点击”关于此页”进入诊断界面“关于此页”“帮助”,32,OAF界面上的字段查询,第三步点击”全部展开”,展现页面层次结构stackLayout-tableLayout-rowLayout-cellLayout类似于html标签中的-,相信做过html网页的朋友应该不会感到陌生明细行附带CO,AM,VO信息,察看属性这一栏位表示当前字段的字段名“关于此页”-”视图对象”“帮助”-”历史记录”,33,OAF界面上的字段查询,第四步点击进入”客户类型”所对应的VO对象可以看到”客户类型”所对应的基表和字段名,34,OAF界面上的字段查询,第五步诊断弹性域字段方法一:

15、沿用主体字段的诊断方法我们可以看到,出于安全性的考虑,弹性域字段所对应的VO无法点击进入记录VO NAME=HzPuiCrUpCustActVO,点击进入”客户类型”所对应的VO,35,OAF界面上的字段查询,在”Select a view object”下拉框选择”HzPuiCrUpCustActVO”即可得到完整的sql查询语句,36,OAF界面上的字段查询,方法二:使用ORACLE R12新增的弹性域参考返回诊断界面,最底下有个”弹性域参考”的栏位,点击”显示全部详细资料”,我们可以看到跟该界面相关的弹性域参考的详细信息都在这里显示。,37,OAF界面上的字段查询,由于这是一个说明性弹性

16、域,我们可以找到与此非常相似的Form界面,38,OAF界面上的字段查询,知道了弹性域的名称,我们可以通过下面的sql来获得其更详细的信息查询得到的结果如下,其中APPLICATION_TABLE_NAME代表其所对应的基表,从而可以由此获取最详细的弹性域信息,39,OAF界面上的字段查询,回到我们刚点击进入”关于此页”的位置(红字部分为ORACLE R12新增功能)页个性化页上下文技术组件Java系统属性配置文件Patch,40,OAF界面上的字段查询,个性化“关于此页”-”个性化”“帮助”-”诊断”-”自定义代码”-”个性化”,41,OAF界面上的字段查询,页上下文记录了数据库存储路径记录

17、了当前用户,当前职责,当前模块名组织,语种,时区,默认时区等信息,42,OAF界面上的字段查询,技术组件记录了OA结构及其所使用的组件,包括一些第三方组件(如JDBC驱动程序),43,OAF界面上的字段查询,Java系统属性记录了一些常用环境变量名及其所对应的值,可以查到如class_path,FND_TOP等常用环境变量的值,44,OAF界面上的字段查询,配置文件本页关联的所有profile,45,OAF界面上的字段查询,Patch这是ORACLE R12新增的功能,显示已经打过的所有patch的记录,46,OAF界面上的字段查询,另一种诊断字段的方法-OAF Trace将FND:诊断这个预

18、置文件针对用户设成Y进入页面后点击右上方的“诊断”在下拉框中选择“Set Trace Level”,点击开始选择单选框后,按“保存”,会给出文件号。就回到操作页面操作操作完后再进入诊断,可能会给出多个文件名,将所有文件下载下来看trace信息将trace失效掉,47,R12安全性新特性,场景PO_LINES指向po.po_lines_all 对po_lines求count 对po.po_lines_all求count,48,R12安全性新特性,Po_lines和po.po_lines_all应该是同一个对象,但是为什么从同义词上求COUNT时没数据而从基表上求COUNT时有数据呢?原因就在下面

19、的SQL上,简单的说就是R12中的VPD特性,因为同义词PO_LINES上有一个策略函数MO_GLOBAL.ORG_SECURITY,49,R12安全性新特性,MOAC(Multi-Org Access Control)R12中,同一个职责的同一个界面,可以操作多个OU的数据。而11i只能操作一个OU的数据。什么是MOAC?所谓MOAC就是多组织访问控制,通过MOAC,可以在同一个职责下操作操作多个OU的数据,比如,我们可以在AR超级用户下,操作整个集团的所有公司的数据。而且MOAC是一个组织控制概念,不只是控制OU,还可以控制库存组织等其他用途,也就是说,只要是在通过/设置/组织 这个地方定

20、义的所有组织都应该可以起用MOAC特性,目前我只知道OU和库存组织是可以的。不过我们最关心的是OU的控制。,50,R12安全性新特性,如何启用MOAC路径:全局 HRMS 管理员/安全性/配置文件我们可以在这里定义一个业务组,51,R12安全性新特性,提交并发请求路径:全局 HRMS 管理员/请求/维护安全性清单,52,R12安全性新特性,在职责或用户层设置安全性配置文件路径:系统管理员/配置文件/系统,53,R12安全性新特性,几个MOAC相关的重要PROFILEMO:安全性配置文件 这个是定义安全性配置文件的PROFILE,定义这个PROFILE,这个职责或用户就可以同时访问多个组织。MO

21、:默认业务实体 如果定义了MO:Security Profile,则可以选择一个默认的OU,当用户进入某个应用时,默认OU就是这个PROFILE的值。MO:业务实体这是11i的参数,如果设置了MO:安全性配置文件,则这个PROFILE不生效,反之,这个PROFILE生效。,54,R12安全性新特性,哪些模块可以使用MOAC由于MOAC特殊的控制结构,需要应用程序做支持才能启用,因此在启用MOAC之前,有必要清楚哪些应用支持MOAC特性。我们使用如右图所示脚本进行检查使用fnd_mo_product_init_pkg.register_application 注册MOAC支持 使用fnd_mo_

22、product_init_pkg.remove_application 取消MOAC支持,55,R12安全性新特性,两张重要的MOAC表 MO_GLOB_ORG_ACCESS_TMP 记载了当前session所能访问的组织,对写程序有比较大的用处 FND_MO_SP_PREFERENCES记录了用户,职责和安全配置文件的组合,用以计算默认OU,不过写程序很少用到 FORM中如何控制MOAC标准FORM 进入FORM时,执行 mo_global.init(p_appl_shortname);当选择某个OU时,执行:mo_global.set_policy_context(S,&p_org_id)

23、,此时,mo_global.current_org_id就等于&p_org_id 客户化FORM 为了让客户化的FORM也具有MOAC特性,则需要在pre-form和选择OU时分别执行以上两个步骤,56,R12安全性新特性,在客户端如何模拟FORM获得数据获取一个OU的数据 进入SQL窗口后,执行mo_global.set_policy_context(S,57,R12安全性新特性,多组织并发请求 通过启用MOAC控制并发请求所能访问的数据 如果安全性配置文件可以访问5个OU的话,那么并发请求就可以同时访问5个OU的数据 虽然前文已经提到如何模拟FORM从客户端取数据,理论上来说只要起用了MO

24、AC特性,默认情况下就应该可以取到5个OU的数据 事实上,如果不启用多组织并发请求特性,将取不出任何数据 从底层看,多组织并发请求在表fnd_concurrent_programs中加了个字段multi_org_category,58,R12安全性新特性,为了让并发请求具有MOAC特性,需要到如下截面设置“业务实体模式”路径:系统管理/并发/程序,59,R12安全性新特性,提交并发请求的FORM多出一个字段“业务实体”,控制这个字段是否可用的字段是multi_org_category,当为S时,则这个字段为必须录入的字段,如果为空或M时,则这个字段为不可维护的字段,见下图,60,R12安全性新

25、特性,11i升级到12i MOAC过程 对这个特性一般不会使用,但是我们可以从转换的脚本了解MOAC的本质,转换脚本见ad_mo_util_pkg,注意看一下脚本就知道有五个操作,这五个操作体现了MOAC的本质。总结来说就是如下几个步骤 删除视图(只是那些组织屏蔽的视图,比如(po_vendor_sites)修改基表中org_id的默认值为NULL 新建同义词指向基表 从FND_VIEW中删除视图Fnd_Dictionary_Pkg.RemoveView 为同义词增加策略(VPD)dbms_rls.add_policy,61,R12安全性新特性,ORACLE VPD简介虚拟专用数据库(VPD)

26、也称为细粒度访问控制,它提供强大的行级安全功能。它是在 Oracle8i 中推出的,已经受到广泛的欢迎,并且在从教育软件到金融服务等各种应用程序得到采用。VPD 的工作方法 通过透明地更改对数据的请求,基于一系列定义的标准向用户提供表的局部视图 在运行时,所有查询都附加了谓词,以便筛选出准许用户看到的行,例如,如果只允许用户查看帐户管理员 SCOTT 的帐户,则 VPD 设置自动地将查询:select*from accounts;重写为:select*from accounts where am_name=SCOTT;,62,R12安全性新特性,DBA 在表 ACCOUNTS 上设置了一项安全

27、策略。该策略具有一个相关函数,称为policy function,它返回一个用作谓词的字符串 where am_name=SCOTT。你在SQL窗口执行的是select*from accounts,而实际上执行的是select*from accounts where am_name=SCOTT,那么它是怎么实现这个技术的呢?要了解这个问题,我们需要重新回到VPD的核心:APPLICATION CONTEXT:应用程序上下文 POLICY FUNCTION:策略函数 POLICY TYPE:策略类型,63,R12安全性新特性,APPLICATION CONTEXT:应用程序上下文 应用程序上下文

28、简单通俗的说,就是个环境变量,也就是全局变量,在SESSION的生命周期内有效。其目的就是要让策略函数取得这个值。从而返回正确的谓词(其实也就是WHERE 条件字符串)使用以下语句创建应用程序上下文:CREATE CONTEXT cux_context_name USING apps.cux_vpd_globalcux_context_name 是应用程序上下文的名称(namespace)apps.cux_vpd_global是可以对这个namespace进行变量的创建和删除的package,64,R12安全性新特性,使用以下语句检查上下文:检查应用程序上下文名称检查应用程序上下文中的变量名称

29、及值12i MOAC使用的应用程序上下文MULTI_ORG,MULTI_ORG2到这里,我们已经很清晰的知道,应用程序上下文的用途是什么,怎么检查应用程序上下文。,65,R12安全性新特性,POLICY FUNCTION:策略函数 策略函数是作用在对象上(表,视图,同义词等),根据应用程序上下文返回一个特定的谓词也就是WHERE条件字符串,从而使得查询表,视图时自动给查询加上一个where条件什么时候策略函数会执行?当查询对象时会执行策略函数,条件是先使用dbms_rls.add_policy将对象和策略函数绑定在一起。12i MOAC使用的策略函数,66,R12安全性新特性,POLICY T

30、YPE:策略类型 生成谓词所需的重复分析是一种在某些情况下可以进行修整的开销。例如,在大部分实际情况中,谓词并不象 am_name=SCOTT 那样是静态的 它基于用户的身份、用户的权限级别、用户向哪个帐户管理员进行报告等情况,可能更具有动态性 由策略函数创建并返回的字符串可能会具有很强的动态性,而为了保证其结果,Oracle 必须每次重新执行策略函数,既浪费资源又降低性能 在这种类型的策略中,谓词每次执行时可能会有很大的差别,该策略称为“动态”策略,在 Oracle9i 数据库以及以前的版本中已经提供了这种策略 除了保留动态策略之外,Oracle 数据库 10g 还基于谓词的构造推出了几种新

31、类型的策略,为提高性能提供了更好的控制context_sensitiveshared_context_sensitiveshared_static 和 static,67,R12安全性新特性,从上面可以知道,ORACLE 10g一共提供了五种策略类型:DYNAMIC、context_sensitive、shared_context_sensitive、shared_static 和 static。MOAC中,重点使用的是DYNAMIC,shared_context_sensitive 如何设置策略函数的策略类型 dbms_rls.add_policy(policy_type=dbms_rls.

32、shared_context_sensitive);shared_context_sensitive 是 constant类型的变量,68,R12安全性新特性,启用VPD特性的步骤创建应用程序上下文 参考CREATE CONTEXT cux_context_name USING apps.cux_vpd_global 创建策略函数 参考:MO_GLOBAL.ORG_SECURITY 为对象添加策略函数 参考:dbms_rls.add_policy,69,R12安全性新特性,在12i中给客户化表启用VPD特性 创建表(cux_vpd_tests_all),org_id默认为空创建同义词cux_v

33、pd_test指向cux_vpd_tests_all 为同意词添加策略函数 12i中MOAC最重要的PACKAGE mo_global,70,R12业务模块的变化,12i在功能模块上的变化很多,比如,基本每个模块都启用了MOAC特性,新增加了子帐模块,税模块等等很多新的模块,OPM库存和离散库存集成了。总的来说变化最大的是GL模块和OM模块 新增子账模块。所有的子模块会计分录都可以使用特定的公式配置出来但是对技术而言,我们不太关心如何配置生成会计分录,我们只关心子模块的会计分录和GL的会计分路之间的关联性,以方便我们做子模块和GL的对应报表 要做对应的报表,必须要了解子账,71,R12业务模块

34、的变化,SLA(Subledger Accounting)概念 子帐是子分类帐会计的简称,字面上的含义就是子分类帐会计分录子分类帐会计其实就是连接子模块会计和GL凭证之间的桥梁,更简单的说,就是子模块和GL之间的桥梁。所有子模块(包括FA)产生的会计分录都是使用SLA产生的,存放在SLA的表中,然后通过过帐程序过帐到GL。有点类gl_interface表的功能。子分类帐会计的第二层意思:在各个子模块都有一套独立的会计分录,看起来跟GL其实没太大区别,这就意味着在子模块其实就可以计算科目余额了。只是可惜,到目前为止我还没有类似gl_balance的表来存放科目余额。各子模块目前还是可以有自己的分

35、配帐户(就是以前查看会计科目看到的东西),分别存放在自己的分配表中,比如,AP还是存放在ap_invoices_distributions中,引入SLA后,把这个功能称为“事物处理会计”,和子分类帐会计的不同点在于,事物处理会计是通过自动会计或分配产生,而子分类帐会计是根据定义会计事件等公式产生的,分别存于不同的地方。,72,R12业务模块的变化,子帐架构 解释:子分类帐的产生有两种方式,一种方式是直接从子模块的事物处理会计,一种是直接从子模块的事物处理上取得。子模块的事物处理会计和子分类帐会计是两个不同的东西,一定要区别对待,传送到GL的是子分类帐会计,并非事物处理会计。由于子分类帐会计的来

36、源可能是事物处理,也可能是事物处理会计,因此很可能存在差异,这是SLA目前的缺陷。,73,R12业务模块的变化,子分类帐带来的益处 灵活的定义会计分录的产生规则,包括摘要,借方和贷方 一个事物处理可以过帐到多个ledger(就是11i的帐簿),这给跨国集团管理多个帐簿带来很大的好处 统一了子模块会计分录的存放和产生规则,也就是说,各个子模块都可以根据自身的情况设置会计规则,但是这些规则产生的会计分录都回存放在SLA的表中 利于扩展,ORACLE委托外包的子模块产生的会计分录更容易集成到EBS,74,R12业务模块的变化,SLA&GL关系模型 基础事件关系图 xla_entity_types_v

37、l(事件实体)xla_entity_id_mappings(实体ID对应表)xla_event_classes_v(事件分类)xla_event_types_vl(事件类型)子分类帐关系图 xla_events(会计事件)xla_ae_headers(子帐头)xla_ae_lines(子帐行)xla_distribution_links(关联事物处理信息)子模块和关系图 gl_import_references(总帐参考)(gl_sl_link_id,gl_sl_link_table)xla_ae_lines(子帐行)说明:GL和子模块之间的关联是通过gl_import_reference实现

38、的,关键字段是gl_sl_link_id,gl_sl_link_table。,75,R12其它一些细节性的变化,总体视觉显示变成了更具亲和力和能显著降低视觉疲劳度的浅蓝色登陆界面改变登陆用户名区分大小写Jinit不再像以前那样需要安装,只需将其置为可信控件,会自动下载到本地Form的视觉体系变得和OAF/JTT产品一致编译命令改变,编译工具:frmcmp_batch,不支持f60gen,76,R12其它一些细节性的变化,新增弹性域字段验证定义弹性域字段的时候可以在其之上定义where子句,以对其值进行合法性约束新增两个弹性域类型PL/SQL validated value setsKey flexfield validated value sets,77,Thanks And Bow!,提供一个可以公网访问的R12 Demo环境,供各位同事平时研究http:/密码:1583AL感谢资料提供者甘立周肖谨,

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

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号