
简介本资源是面向Delphi中高级开发者的专业级图形控件库专为快速构建流程图、组织结构图、UML图表及交互式可视化界面而设计兼容Delphi 7至最新13.1Florence全版本显著降低复杂图表开发门槛。压缩包共276个文件含56个核心Pas源码单元、40个DPK包定义、23个DFM窗体设计、38个DPROJ工程配置及60个RES资源文件完整覆盖控件编译、安装与示例运行所需全部组件2.72MB体积精炼高效附带CHM帮助文档与Demo工程如DiagramDemo.cpp、fMain.dfm等便于即装即用与深度定制。已有73人学习下载开发者可直接调试源码、修改渲染逻辑、扩展节点行为或适配高DPI界面尤其适合需长期维护、二次开发或集成到企业级Delphi系统的项目团队。1. 项目概述一份来自Delphi黄金时代的“宝藏”如果你是一位资深的Delphi开发者看到“TMS Diagram Studio v4.33.0.0 for Delphi 7-13 Florence Full Source.rar”这个文件名你的心跳可能会漏跳一拍。这不仅仅是一个控件包更像是一份穿越了Delphi近十年发展历程的“考古发现”。TMS Diagram Studio这个在图表绘制和流程图设计领域享有盛誉的第三方控件套件其4.33.0.0版本并且附带了从Delphi 7到Delphi 10.3 Rio代号“Florence”的完整源代码对于任何一个仍在维护或开发Delphi项目的团队或个人来说其价值不言而喻。简单来说这是一个功能强大的图表绘制组件库。它允许开发者在自己的应用程序中以可视化的方式轻松创建、编辑和管理各种图表比如流程图、组织结构图、网络拓扑图、UML图甚至是简单的思维导图。用户可以通过拖拽形状、连接线设置样式和属性快速构建出专业的图表界面。而“Full Source”完整源代码这四个字则是这份资源的灵魂所在。它意味着你不仅可以使用它更能深入其内部理解每一行代码的逻辑根据项目需求进行定制化修改甚至修复潜在的兼容性问题。尤其是在面对从古老的Delphi 7到相对现代的Delphi 10.3 Rio这样宽广的版本跨度时拥有源代码是确保控件能在不同环境下稳定运行的唯一可靠保障。这份资源适合谁首先是那些仍在维护基于Delphi 7、Delphi 2007、XE、XE2等历史版本大型项目且项目中需要图表功能的开发者。其次是希望学习优秀第三方控件设计思想的中高级Delphi程序员通过研读TMS这样的商业级源码能极大提升自己的架构和编码能力。最后对于那些在新项目如使用Delphi 10.3/10.4 Sydney中需要图表功能但预算有限或对控件有深度定制需求的团队这份带有历史版本兼容性代码的完整源码提供了一个绝佳的起点和参考。2. 核心价值与版本兼容性深度解析2.1 “Full Source”的不可替代性在商业软件开发中使用第三方控件通常有两种方式一是购买编译好的二进制包.bpl, .dcu二是购买附带源代码的授权。前者是“黑盒”你只能使用它提供的接口一旦遇到Bug、性能瓶颈或者需要与新版IDE、新操作系统特性适配时你将束手无策只能被动等待控件厂商的更新——而很多老牌控件的更新速度可能远跟不上你的项目节奏。“Full Source”彻底打破了这种限制。以这个TMS Diagram Studio v4.33.0.0为例拥有其源代码意味着深度调试与问题根治当图表在某个特定操作下崩溃或渲染出现异常时你可以直接进入控件内部设置断点一步步跟踪数据流和绘制逻辑精准定位问题根源而不是漫无目的地猜测API调用方式。无缝版本迁移与适配Delphi不同版本间的RTL运行时库、VCL可视化组件库存在差异。例如从AnsiString到UnicodeString的转变Delphi 2009为分水岭图形接口的更新以及高DPI感知的支持等。拥有源码你可以亲自修改这些兼容性代码让一个为Delphi 7设计的控件平稳运行在Windows 10/11的高分屏下。这是预编译二进制控件根本无法做到的。功能定制与扩展项目需求千变万化。也许你需要为流程图节点添加一种全新的数据绑定方式或者需要将图表导出为一种特殊的矢量格式。基于源码你可以直接在其架构上增加新的类、新的属性方法实现完全贴合业务逻辑的功能而不是被控件的既有功能所限制。长期项目保障对于生命周期长达十年甚至更久的工业、医疗、金融等领域的Delphi应用确保其所有依赖的可持续性至关重要。源代码在手即使未来TMS公司停止对该产品的支持你的项目也不会因此陷入绝境。2.2 版本跨度Delphi 7 - 10.3 Florence的挑战与机遇支持从Delphi 7到Delphi 10.3 Rio这个版本范围覆盖了Borland时代到Embarcadero时代见证了Delphi的变迁。要让一个控件兼容如此大的跨度其代码本身就必须具备良好的设计和高度的可配置性。编译器指令的艺术这类多版本兼容的源码中必然会大量使用{$IFDEF}、{$IF}等条件编译指令。例如{$IFDEF VER150} // Delphi 7 // Delphi 7特定的代码可能涉及老的Graphics单元API {$ENDIF} {$IF CompilerVersion 20.0} // Delphi 2009及以后 // 使用Unicode字符串和新的泛型容器 {$IFEND} {$IFDEF DPI_AWARE} // 高DPI缩放相关的处理代码 {$ENDIF}阅读这些代码就像在读一本Delphi的演进史。你需要理解不同版本下哪些单元、哪些类、哪些方法发生了变化。运行时库RTL差异最典型的莫过于字符串。Delphi 7使用AnsiString单字节/多字节而Delphi 2009及以后全面转向UnicodeStringUTF-16。控件内部所有涉及字符串处理、文件读写、Windows API调用的地方都必须妥善处理。在源码中你会看到大量使用TEncoding类、String自动适配以及显式的类型转换来保证兼容性。VCL图形与消息循环图形绘制部分从TCanvas到TDirect2DCanvasFMX及后期VCL引入的演进消息处理机制的精进都需要控件代码做出适配。例如在支持触摸操作的现代Delphi版本中控件可能需要响应WM_GESTURE消息而在老版本中则无需考虑。包Package管理与设计期支持不同Delphi版本的IDE对设计期包Design-time package的注册和管理方式也有细微差别。源码中通常会包含多个.dpk包项目文件分别对应不同的Delphi版本它们会引用不同的路径和条件定义以确保在对应版本的IDE中能正确安装并显示在组件面板上。注意虽然资源标题写着支持到Delphi 10.3 “Florence”但实际编译时对于更新的Delphi 10.4 Sydney、11 Alexandria甚至12 Athens你可能需要根据编译错误提示手动调整少量条件编译指令或引用单元。这恰恰是拥有源码的优势——你可以自己动手让它支持未来版本。3. TMS Diagram Studio 核心功能与架构探秘3.1 控件核心架构解析TMS Diagram Studio作为一个成熟的图表控件其架构设计通常遵循MVC模型-视图-控制器或类似模式以实现数据、显示和操作的分离。通过分析其完整源代码我们可以一窥其设计精髓模型层Model这是图表的灵魂负责存储所有图表元素的数据结构。核心类可能命名为TDiagramModel或类似。它内部会维护两个主要集合Shapes一个对象列表每个元素代表一个图形节点如矩形、圆形、菱形包含其位置、尺寸、样式、文本、以及最重要的——自定义数据对象Tag或Data属性。Connectors一个对象列表每个元素代表一条连接线记录其起始形状、终止形状、连接点类型、路由路径可能是直线、折线或曲线以及样式信息。 模型层不关心如何绘制只负责数据的增删改查和序列化保存/加载。视图层View这是图表的画布核心控件通常是TDiagram或TDiagramView继承自TCustomControl。它的职责是监听模型层的变化事件如OnShapeAdded。在Paint方法中遍历模型中的Shapes和Connectors调用各自的Draw方法进行渲染。处理视图变换如缩放和平移。这通常通过操作TCanvas的Scale和Offset或维护一个视图矩阵来实现。管理视觉状态如选择框、拖动时的预览效果等。控制器层Controller这是用户交互的处理器。它通常内嵌在视图控件中通过重写鼠标事件MouseDown,MouseMove,MouseUp、键盘事件来实现。选择工具判断鼠标点击位置落在哪个形状或连接线上更新模型的选择状态并通知视图重绘。拖动工具在鼠标移动时计算偏移量更新被拖动形状的模型坐标。连接工具在从一个形状的连接点拖出时动态创建一条临时连接线并在鼠标释放时在模型层建立正式的连接关系。缩放和平移工具响应鼠标滚轮或拖拽画布背景更新视图变换参数。3.2 关键功能实现细节连接线与自动布线这是流程图控件的核心难点。简单的实现是直接连接两个形状的几何中心或边界点。但TMS Diagram Studio这类商业控件通常支持更智能的“避障布线”。查找算法在源码中你可能会发现一个独立的布线器类TConnectionRouter。它可能使用简单的A*寻路算法在由形状边界和画布边界构成的“网格”或“图”中为连接线寻找一条不穿过其他形状的最短路径。连接点Connection Points每个形状可以定义多个连接点上、下、左、右或自定义位置。布线算法会优先尝试将线连接到这些指定的点上使图表更规整。序列化与持久化如何将复杂的图表保存为文件或流常见方案有自定义二进制格式效率高但可读性差。控件可能定义了一套记录Record结构直接将对象字段写入流。基于RTTI的流化利用Delphi的TPersistent类和TReader/TWriter可以自动保存/加载 published 属性。这是VCL的经典方式但灵活性稍差。文本格式如XML/JSON可读性好易于与其他系统交换。在源码的SaveToFile/LoadFromFile方法中你可能会看到使用TXMLDocument或第三方JSON库来解析和生成文档的代码。拥有源码你可以轻松修改序列化格式以适应你的后端接口。撤销/重做Undo/Redo栈一个专业的编辑器必须支持撤销。实现方式通常是命令模式Command Pattern。定义一个抽象的TUndoCommand类包含Execute执行和Unexecute撤销方法。每一个用户操作移动形状、修改文本、添加连接都封装成一个具体的命令对象如TMoveShapeCommand。执行命令时命令对象会保存操作前的状态如旧坐标然后修改模型。所有成功执行的命令被压入一个UndoStack。撤销时从栈顶取出命令调用其Unexecute方法然后将其压入RedoStack。 在TMS的源码中寻找TUndoManager或类似名称的类是理解其撤销机制的关键。4. 从源码到集成完整实操指南4.1 源码获取与环境准备假设你已经获得了“TMS Diagram Studio v4.33.0.0 for Delphi 7-13 Florence Full Source.rar”这个压缩包。解压后你可能会看到类似如下的目录结构TMS Diagram Studio/ ├── Source/ // 核心源代码目录 │ ├── Diagram.pas │ ├── DiagramShapes.pas │ ├── DiagramConnectors.pas │ ├── ... (其他核心单元) │ └── DesignTime/ // 设计期包源码 ├── Packages/ │ ├── D7/ // Delphi 7 的包项目文件 (.dpk, .dproj) │ ├── D2007/ │ ├── DXE2/ │ ├── ... // 其他版本目录 │ └── D10.3/ ├── Demos/ // 示例程序 ├── Help/ // 帮助文档 └── Readme.txt // 说明文件第一步选择正确的开发环境。根据你的目标Delphi版本打开对应目录下的包项目文件。例如你使用Delphi 10.3 Rio就打开Packages/D10.3/TMSDiagramStudio_D10_3.dproj或.dpk。第二步解决路径依赖。在打开项目前最好先将Source目录添加到Delphi的全局库路径Tools - Options - Language - Delphi Options - Library - Library path或项目的搜索路径中。这能确保所有单元都能被正确找到。第三步编译设计期包。通常包项目分为“运行时包”和“设计期包”。设计期包负责在IDE的组件面板上注册控件。你需要先编译运行时包通常不包含_D后缀再编译设计期包通常包含_D或Designtime后缀。编译时请务必选择“Build”而非“Compile”以确保所有依赖被正确处理。4.2 编译安装与常见问题排查即使拥有源码编译过程也可能不会一帆风顺。以下是一些常见问题及解决思路编译错误[Fatal Error] File not found: ‘xxx.dcu’ 或 ‘xxx.pas’原因搜索路径配置不正确或者该单元依赖于另一个你可能没有的TMS组件包如TMS Core库。解决仔细检查Readme.txt看是否有对其他库的依赖说明。在项目设置中将Source目录及其所有子目录完整添加到搜索路径。如果确实依赖其他TMS组件你可能需要先获得或注释掉相关功能。在源码中全局搜索{$I}或uses部分找到缺失的单元尝试在条件编译中将其排除{$IFDEF HAS_TMS_CORE}或者寻找替代实现。编译警告W1058 Implicit string cast from ‘AnsiString’ to ‘string’原因这是Unicode迁移的典型警告在跨版本源码中很常见。解决对于只是使用可以暂时忽略这些警告。但为了代码清洁你可以逐一审查警告位置。通常的修复方法是使用AnsiString(MyString)进行显式转换或者使用TEncoding系列函数来处理字符串编码。切记修改前备份原文件。安装成功但组件面板不显示或图标异常原因1设计期包没有正确注册。尝试以管理员身份运行Delphi IDE然后重新安装包。原因2不同Delphi版本的IDE对bpl包库的缓存机制不同。关闭Delphi手动删除%AppData%\Embarcadero\BDS\xx.xxx.x是你的Delphi版本号目录下的bpl缓存文件夹再重启IDE。原因3资源文件.dcr未正确链接。.dcr文件包含了组件面板上的图标。确保在包项目中.dcr文件与对应的.pas文件同名且在同一目录并被包含在包内。运行时错误如“Invalid pointer operation”或图形绘制异常原因这通常是对象生命周期管理问题如访问已释放的对象或特定Windows版本下的图形资源句柄泄漏。解决拥有源码的最大优势在此体现。在Delphi IDE中开启最详细的调试选项在出错时查看调用堆栈直接定位到源码中的问题行。常见问题包括在Destroy析构函数中未将对象引用置为nil。在重写的Paint方法中未正确配对Canvas.Brush/Canvas.Pen的Save和Restore。在多线程环境下非线程安全地访问VCL图形对象。4.3 在你的项目中集成与基础使用安装成功后你可以在组件面板的“TMS”或“Diagram”页签下找到TAdvDiagram或类似名称组件。基础集成步骤将其拖放到你的窗体Form上。在窗体OnCreate事件或按钮点击事件中动态创建图形和连接线procedure TForm1.FormCreate(Sender: TObject); var RectShape, CircleShape: TDiagramShape; Connector: TDiagramConnector; begin // 1. 创建矩形 RectShape : AdvDiagram1.Shapes.Add; RectShape.ShapeType : stRectangle; // 假设枚举值为stRectangle RectShape.Left : 50; RectShape.Top : 50; RectShape.Width : 100; RectShape.Height : 60; RectShape.Text : 开始; // 2. 创建圆形 CircleShape : AdvDiagram1.Shapes.Add; CircleShape.ShapeType : stEllipse; CircleShape.Left : 200; CircleShape.Top : 50; CircleShape.Width : 80; CircleShape.Height : 80; CircleShape.Text : 处理; // 3. 创建连接线 Connector : AdvDiagram1.Connectors.Add; Connector.FromShape : RectShape; Connector.ToShape : CircleShape; Connector.Style : lsArrow; // 带箭头的线 // 4. 可选设置选中和悬停样式 AdvDiagram1.DefaultStyle.SelectionColor : clBlue; AdvDiagram1.DefaultStyle.HoverColor : clYellow; end;实现交互你可以通过AdvDiagram1.OnShapeClick、OnShapeDblClick、OnConnectionClick等事件来响应用户操作实现业务逻辑。高级定制示例自定义一个显示数据库表名的形状假设你需要一个特殊的形状内部显示数据库表名并且双击可以打开表结构编辑器。你可以通过继承TDiagramShape来实现unit CustomTableShape; interface uses DiagramShapes; // 引用TMS Diagram Studio的形状单元 type TTableDiagramShape class(TDiagramShape) // 假设基类名 private FTableName: string; FFieldCount: Integer; procedure SetTableName(const Value: string); protected procedure DrawInternal(ACanvas: TCanvas); override; // 重写绘制方法 public property TableName: string read FTableName write SetTableName; property FieldCount: Integer read FFieldCount write FFieldCount; end; implementation procedure TTableDiagramShape.SetTableName(const Value: string); begin if FTableName Value then begin FTableName : Value; Changed(ctLayout); // 通知控件需要重绘或重新布局 end; end; procedure TTableDiagramShape.DrawInternal(ACanvas: TCanvas); var R: TRect; begin inherited; // 先调用父类绘制标准背景边框等 // 自定义绘制在形状中心绘制表名和字段数 R : GetClientRect; // 获取形状内部区域 InflateRect(R, -5, -5); // 内边距 ACanvas.Font.Style : [fsBold]; ACanvas.TextOut(R.Left, R.Top, FTableName); ACanvas.Font.Style : []; ACanvas.TextOut(R.Left, R.Top ACanvas.TextHeight(FTableName) 2, Format(字段数: %d, [FFieldCount])); end; end.然后在你的主程序中注册并使用这个自定义形状类。通过源码你可以清晰地看到形状的绘制、事件处理等所有环节使得这种深度定制成为可能。5. 性能优化与高级应用场景5.1 处理大规模图表的性能考量当图表中包含成千上万个节点和连接线时性能会成为瓶颈。通过分析源码我们可以找到优化方向虚拟化渲染这是最有效的优化手段。控件的视图层不应一次性绘制所有元素而只绘制当前视口Viewport内的部分。你需要检查TDiagram的Paint方法。如果它遍历了模型中的所有形状那么就需要改造。可以引入一个空间索引结构如四叉树Quadtree或网格索引Grid Index。优化思路在模型层每个形状被添加、移动或改变大小时将其注册到空间索引中。在视图层的Paint方法中首先根据当前画布的缩放和平移参数计算出视口在世界坐标系中的范围VisibleRect然后向空间索引查询所有与VisibleRect相交的形状只绘制这些形状及其相关的连接线。连接线布线的性能自动布线算法如A*复杂度较高。对于静态或变化不频繁的图表可以缓存布线结果。当形状被移动时只对受影响的连接线即与该形状相连的线重新计算布线而不是全图重算。画布操作优化双缓冲确保控件已经启用了双缓冲DoubleBuffered : True这是减少闪烁的基础。批量绘制对于样式相同的多个形状可以尝试批量设置Canvas属性减少GDI调用次数。但VCL的TCanvas本身开销较大在极端性能要求下可以考虑在支持Direct2D的Delphi版本中使用TDirect2DCanvas进行硬件加速渲染。查看源码中是否有IFDEF定义的Direct2D绘制路径。数据模型与UI的异步更新如果图表数据来自网络或数据库且更新频繁应避免在数据到达时直接操作UI线程的模型。可以使用TThread.Queue或TThread.Synchronize将模型更新和视图刷新操作抛回主线程执行防止界面卡死。5.2 扩展应用场景从流程图到专业领域拥有完整源码意味着你可以将TMS Diagram Studio从一个通用流程图控件改造成一个垂直领域的专业设计器。工业控制组态软件自定义形状库代表水泵、阀门、传感器、PLC等。每个形状可以绑定实时数据源OPC UA、Modbus动态改变颜色或数值显示。连接线可以代表管道或信号流。你需要扩展形状类增加Tag对象来绑定数据点并实现一个定时刷新机制。网络拓扑图编辑器形状代表路由器、交换机、防火墙、服务器。连接线代表物理或逻辑链路可以显示带宽、利用率通过线条粗细或颜色渐变。双击设备形状可以弹出配置界面。这需要你深度定制形状的属性和绘制逻辑并可能集成SNMP等网络管理协议。UML建模工具实现完整的UML图形状类、接口、用例、活动等并支持根据UML规范生成代码骨架或从代码反向工程生成图表。这需要你建立一套复杂的元模型Meta-Model来管理图形元素之间的关系远超简单形状连接线的范畴。实现一个简单的实时数据绑定示例// 假设我们有一个表示温度传感器的自定义形状 TTemperatureSensorShape class(TDiagramShape) private FCurrentTemp: Double; FTempSource: TDataSource; // 你的数据源抽象 procedure OnTempUpdate(Sender: TObject; NewTemp: Double); protected procedure DrawInternal(ACanvas: TCanvas); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure BindToSource(ASource: TDataSource); end; procedure TTemperatureSensorShape.OnTempUpdate(Sender: TObject; NewTemp: Double); begin FCurrentTemp : NewTemp; // 标记需要重绘使用Queue避免多线程问题 TThread.Queue(nil, procedure begin Invalidate; // 请求重绘 end); end; procedure TTemperatureSensorShape.DrawInternal(ACanvas: TCanvas); var R: TRect; displayText: string; begin inherited; R : GetClientRect; // 根据温度值改变填充色 if FCurrentTemp 80.0 then ACanvas.Brush.Color : clRed else if FCurrentTemp 50.0 then ACanvas.Brush.Color : clYellow else ACanvas.Brush.Color : clGreen; ACanvas.FillRect(R); // 用颜色填充背景 displayText : Format(传感器\n%.1f°C, [FCurrentTemp]); DrawText(ACanvas.Handle, PChar(displayText), Length(displayText), R, DT_CENTER or DT_VCENTER or DT_WORDBREAK); end;这个例子展示了如何将外部实时数据与图形元素的视觉表现结合起来这是许多专业监控和组态软件的基础。6. 源码学习与长期维护建议6.1 如何从这份源码中汲取养分对于希望提升自身水平的Delphi开发者这份完整的商业级源码是一个宝库。学习设计模式仔细阅读代码识别其中使用的设计模式。除了前面提到的命令模式撤销/重做你可能还会发现观察者模式模型Model通知视图View更新。策略模式不同的连接线布线算法直线、折线、曲线可能被封装成可互换的策略对象。工厂方法模式用于创建不同类型的形状对象。访问者模式用于对复杂的图表结构进行统一的操作如序列化或导出。研究内存管理与对象生命周期Delphi的TObject和接口Interface引用计数机制是如何被运用的控件是如何管理形状和连接线对象的所有权的注意Owner机制和Free/FreeAndNil的调用位置学习如何避免内存泄漏和无效指针访问。分析事件机制VCL的事件是委托方法指针的经典应用。查看控件是如何定义自己的事件属性如OnShapeClick: TDiagramShapeEvent并在内部触发它们的。这能帮助你设计出更清晰、解耦的组件接口。钻研图形绘制技巧TCanvas的Pen,Brush,Font属性Polyline,PolyBezier,Arc等函数的使用以及如何实现反锯齿通过TGPGraphics等GDI接口和渐变填充。这些是Delphi GUI编程的硬核知识。6.2 长期维护与版本迭代策略当你决定在正式项目中使用这份修改后的源码时必须建立一套维护策略。代码版本控制立即将整个Source目录纳入你的Git或SVN仓库。这是底线。为原始版本打上v4.33.0.0-original的标签。你所有的修改都在此基础上进行。修改记录文档创建一个MODIFICATIONS.md文件详细记录你做的每一次重要修改日期与版本2023-10-27 v1.0.1 (基于 v4.33.0.0)修改文件Diagram.pas,DiagramShapes.pas修改原因修复在Delphi 11 Alexandria下因TMetafile类变更导致的图表导出为WMF格式崩溃的问题。具体改动将TMetaFile替换为TMetafile并调整了相关API调用。测试情况在D11下编译通过导出功能测试正常。建立条件编译隔离墙对于你为适应新版本Delphi或新增功能而添加的代码尽量使用条件编译指令与你自己的自定义标识如MY_CUSTOM_FEATURE包裹起来而不是直接修改原版核心逻辑。procedure TCustomDiagram.AdvancedPaint; begin // ... 原有代码 ... {$IFDEF MY_CUSTOM_FEATURE} // 这是我添加的硬件加速渲染实验代码 if FUseHardwareAcceleration then DoDirect2DPaint else {$ENDIF} DoStandardPaint; // ... 原有代码 ... end;这样当未来你需要合并官方可能发布的更新尽管对于此旧版本可能性很小时可以更清晰地分离改动。创建自动化构建脚本为不同版本的Delphi编写简单的批处理或Pascal脚本自动完成编译、链接和单元测试。这能确保你的修改在所有需要支持的Delphi版本上都能通过编译。最后我想分享一点个人体会处理像TMS Diagram Studio这样历史悠久、代码量庞大的第三方控件源码就像接手一座古老的、功能强大的但图纸可能部分遗失的机械钟。你需要耐心、细致并怀有敬畏之心。每一次成功的编译、每一个被修复的Bug、每一项被加入的新功能不仅让你的项目受益更让你对Delphi这门语言、对大型组件的架构设计有脱胎换骨般的理解。这份“宝藏”的价值远不止于它提供的图表功能本身。本文还有配套的精品资源点击获取