IntelliJ-platform plugIn 插件开发专题内容介绍,学习指导(一)

本文档详尽介绍了IntelliJ IDEA插件开发,包括基础、图形化开发、智能代码和实战案例。内容涵盖插件开发环境、生命周期、UI组件、代码分析、项目结构等多个方面,适合初学者和进阶开发者。通过实例代码和功能测试,帮助读者掌握插件开发的各个环节。
摘要由CSDN通过智能技术生成

这系列文章出炉对于笔者来说确实不容易,历时快两年了,先后迭代了3版本,暂时与官方最新版本API同步(2024.03),文章内容覆盖2022~2024版内容

专题由来

最早接触插件开发是源于公司一个国际化项目,当时公司有800多个应用要做本地语言转换,无奈本组就30多人真的无法靠人来堆。最后讨论后开发了这样一个idea插件,可实现源码扫描和k-v的抽取和自动翻译,准确率大概在95%左右。写这个插件时因为有工期限制,所以是连copy再堆的可以说代码烂的是一B。

  1. 后来有时间想系统学习下,但发现网上资料简直了。也花钱买过一些教程,发现基本没用;所以整理了一次(比较基础,就是已经发到CSDN上的这些);
  2. 整理完上述文章后又因为工作原因写过几个组内要用的插件,主要是和静态代码相关的;
  3. 再最后结合之前的积累,重新整理了一套完整的电子版,就是本专题要发布的这些文章。文章从零开始,涉及Intellij 的各个方面,包括项目、结构、配置、智能代码等等。

专题大纲

本开发指导手册由上册、下册以及附录三个独立的文档组成,全部手册由四部分内容组成:

  • 第一部分:上册,Intellij platform插件开发基础;
  • 第二部分:上册,Intellij platform图形化插件开发;
  • 第三部分:下册,Intellij platform语言类插件开发;
  • 第四部分:附录,详细罗列出Intellij platform插件开发所涉及的工具、参考资料等;
    如果您只想编写一些基于UI界面的插件,如框架集成、代码统计、效率工具类的插件,需要您详细了解第一、二、四三部分;
    如果您想编写一些高级插件或是收费类插件,如代码自动完成、代码依赖管理、代码检查或是其它基于代码的插件,则只需要您熟悉第一、三部分内容后,详细了解第三部分内容;

注:开发一个可被市场认可的插件并不是一件容易的事,需要大量的编码实践和多次的版本迭代,甚至想掌握Intellij
platform插件开发的基础内容,也需要大量的编码练习。

本开发指导手册基于官方指导、个人实践经验以及网上资料参考,虽然经过了多次总结和梳理,难免存在部分遗漏和错误之处,欢迎讨论指导!

第一部分:Intellij platform插件开发基础

在这里插入图片描述

大概分为17个章节,主要内容如下:
在这里插入图片描述
01 插件开发基础 1

  1. Intellij Platform 2
    1.1 术语 2
    1.2 IDE插件类型 2
  2. 插件开发要求 3
    2.1 开发环境要求 3
    2.2 开发技术要求 3
    2.3 手册示例开发环境 4
  3. 插件开发概述 4
    3.1 插件功能 4
    3.2 开发流程 5
    3.3 开发教程 5
    3.4 参考网站 7
    02 开发第一个插件 8
  4. 构建插件工程 9
    1.1 配置Intellij Idea工具 9
    1.2 创建Intellij插件工程 9
    1.3 Intellij插件工程配置 11
    1.4 测试插件工程配置 20
    1.5 编译运行插件 21
  5. 编写插件代码 21
    2.1 创建Action 21
    2.2 查看Action配置 22
    2.3 编写Action代码 22
    2.4 运行插件 23
    2.5 运行日志 24
  6. 本地发布插件 25
    3.1 本地发布插件 25
    3.2 开发环境目录 25
    03 插件内容结构 27
  7. 插件发布包结构 28
    1.1 没有依赖性的插件 28
    1.2 具有依赖性的插件 28
    1.3 开放API类型的插件 29
  8. 可自定义的插件内容 30
    2.1 Actions 30
    2.2 Extensions 31
    2.3 Extension Points 32
    2.3 Services 35
    2.4 Listeners 37
  9. 插件依赖项 41
    3.1 查找插件ID 42
    3.2 配置插件依赖项 42
    3.3 声明插件依赖 42
  10. plugin.xml配置说明 43
    4.1 basic配置 43
    4.2 Action配置 44
    4.3 Extentions和Services配置 44
    4.4 Listeners配置 45
    4.5 Extention Points配置 45
  11. 资源文件 46
    5.1 工具类 46
    5.2自动匹配 46
  12. 国际化 47
  13. 插件图标 47
    04 IDE基础设施 48
  14. 插件生命周期 49
    1.1 初始化 49
    1.2 资源注册 49
    1.3 插件关闭 50
    1.4 插件管理 51
  15. Intellij平台提供的线程 51
    2.1 数据读写 51
    2.2 线程控制 52
    2.3 获取线程进度 52
    2.4 耗时操作的处理 53
  16. 消息框架 53
    3.1 核心组成 54
    3.2 自定义消息实现 55
  17. 日志及运行信息获取 56
    4.1 日志 56
    4.2 获取IDE运行时信息 57
    4.3 设置插件帮助web页面 57
    4.4 省电模式 57
  18. 错误报告 57
    5.1 注册扩展点 58
    5.2 实现扩展点 58
    5.3 测试错误报告 59
    05 Intellij UI简介 61
  19. Swing图形化开发基础 62
    1.1 Swing UI组件 62
    1.2 Swing UI开发示例 64
  20. Intellij图形化开发基础 65
    2.1 Intellij UI体系 66
    2.2 JBTList和JBTree组件 67
    2.3 工具栏装饰器组件 67
  21. Intellij插件UI开发概述 67
    06 Intellij UI开发 69
  22. ToolWindow工具窗口 70
    1.1 概述 70
    1.2. 代码示例-添加新菜单 71
  23. Dialog对话窗口 73
    2.1 概述 73
    2.2 代码示例-Dialog对话框 74
  24. Popup弹出窗口 76
    3.1 概述 76
    3.2 代码示例-Popuo弹出窗口 76
  25. Notification通知 78
    4.1 概述 78
    4.2 代码示例-Balloon通知 79
  26. File选择器 80
    5.1 概述 80
    5.2 代码示例-文件选择 81
  27. Editor-文本编辑器 82
    6.1 概述 83
    6.2 代码示例-文本替换 84
    6.3 代码示例-文本插入 85
    6.4 代码示例-Handler实现文件操作 86
  28. Status Bar Widget状态栏 87
    7.1 实现 87
  29. Icon and Image图标和图像 88
    8.1 老UI 88
    8.2 新UI 90
    8.3 辅助工具 91
  30. JCEF 谷歌浏览器 91
    9.1 概述 91
    9.1 示例代码-IDE中嵌入浏览器 91
    9.2 示例代码-在IDEA中远程调用JCFF进行调试 92
    9.3 示例代码-JBCefJS查询 93
    07 AnAction动作 94
  31. 概述 95
    1.1 涉及的EP扩展点 95
    1.2 添加到工具栏 95
  32. AnAction类详解 96
    2.1 .actionPerformed() 96
    2.2 .update() 96
    2.3 .getActionUpdateThread() 97
  33. 配置详解 97
    3.1 基本配置 97
    3.2 快捷搜索 98
    3.3 资源文件 98
    3.4 添加位置 98
    3.5 自定义组 98
  34. 代码示例 100
    4.1 Action实现 100
    4.2 添加到菜单栏 101
    4.3 添加到右键菜单 101
    4.3 静态组添加 102
    4.4 动态组添加 103
    08 Setting设置面板 105
  35. 数据持久化 106
    1.1. 组件状态持久化 106
    1.2. 敏感数据持久化 108
  36. Settings设置 109
    2.1 概述 110
    2.2 代码示例-自定义设置面板 113
    2.3 功能测试 115
    09 File系统概述 117
  37. VFS虚拟文件系统 118
    1.1 快照文件的更新 118
    1.2 快照文件的删除 118
    1.3 监听VFS事件 118
  38. VF虚拟文件 119
    2.1 获取VF 119
    2.2 操作VF 120
  39. Document文档 120
    3.1 获取Document 120
    3.2 创建Document 120
    3.3 监听Document 121
    3.4 操作Document 121
    10 Document 编辑 122
  40. Document编辑基础 123
    1.1 基础对象 123
    1.2 文本操作 123
    1.3 坐标系统 125
    1.3 编辑器事件 127
  41. SelectHandler文本选择 129
  42. Caret插入模型 130
    3.1 插入位置选择 130
    3.2 EditorHandler编辑事件 130
    3.3 EditorDelegate可编辑的动作 130
    11 配置运行程序 132
  43. 架构设计 133
    1.1 基础架构 133
    1.2 执行流程 134
    1.3 执行监听器 136
  44. Configuration运行配置 136
    2.1 基础架构 136
    2.1 创建RunConfiguration实例 138
    2.2 验证RunConfiguration配置 139
    2.3 运行RunConfiguration实例 139
    2.4 存储RunConfiguration数据 140
    2.5 其它运行配置相关内容 140
  45. 代码示例 141
    3.1 实现ConfigurationType配置类型 142
    3.2注册ConfigurationType配置类型 142
    3.3 实施ConfigurationFactory配置工厂 142
    3.4 实现RunConfiguration配置项 143
    3.5 实现RunConfiguration配置项存储 143
    3.5 实现SettingsEditor配置项编辑器 144
    3.6 功能测试 144
    12 项目结构 145
  46. 项目结构 146
    1.1 项目基本信息获取 146
    1.2 改变项目结构 147
    1.3 项目侦听器 148
    1.4 代码示例-获取项目信息 148
  47. 可信任的项目 149
  48. 项目向导 149
    3.1 创建新模块类型 150
    3.2 添加项目创建向导 150
    3.3 导入已有项目 151
    3.4 代码示例-创建新建项目向导 151
  49. 项目视图 153
    4.1. 代码示例-过滤项目视图内容 154
    13 项目框架 156
  50. 创建FrameWork 157
    1.1 plugin.xml配置 157
    1.2 java代码实现 157
  51. 功能测试 158
    14 项目Module 159
  52. 概述 160
  53. 模块相关操作 160
    2.1 获取项目包含的模块列表 160
    2.2 获取模块的依赖项和类路径 160
    2.3 获得模块使用的SDK 161
    2.4 获得模块直接依赖的模块列表 161
    2.5 获得依赖于此模块的模块列表 161
    2.6 获得指定文件或PSI元素所属的模块 161
    2.7 访问路径 162
    2.8 模块更改侦听器 162
  54. 示例代码-获取模块信息 162
    3.1 plugin.xml配置 162
    3.2 java代码实现 163
    3.3 功能测试 163
    15 项目Library 164
  55. 概述 165
    1.1 Library分类 165
    1.2 访问Library以及jar 165
  56. 代码示例-查看依赖库 167
    2.1 plugin.xml配置 167
    2.2 java代码实现 167
    2.3 功能测试 169
  57. 代码示例-添加依赖库 169
    3.1 plugin.xml配置 169
    3.2 java代码实现 169
    3.3 功能测试 170
    16 项目Facet 171
    1、创建Facet 172
    1.1 定义FacetType 172
    1.2 定义Facet 172
    1.3 定义DemoFacetConfiguration 173
    1.4 定义State 173
    1.5 定义DemoFacetEditor 174
  58. 功能测试 175
    17 项目SDK 176
  59. 概述 177
    1.1 获取项目SDK信息 177
    1.2 设置项目SDK属性 177
    1.3 使用自定义SDK 177
    1.4 协助设置SDK 178
  60. 代码示例-更改项目SDK配置 178
    2.1 plugin.xml配置 178
    2.2 java代码实现 179
    2.3 功能测试 179
    结语 181

共记181页左右,5W+字(不算代码)

第二部分:Intellij platform插件图形化开发

在这里插入图片描述
大概8个章节,详细如下:
在这里插入图片描述

01 PSI程序结构接口 1

  1. 概述 2
    1.1. PSIFile 2
    获取PSIFile 2
    操作PSIFile 3
    侦听PSIFile 3
    1.2 FileViewProvider 3
    获取FileViewProvider 3
    操作FileViewProvider 4
    扩展FileViewProvider 4
    1.3 PSIElement 4
    获取PSIElement 4
    Element Patterns 4
  2. 浏览 PSI 6
    2.1 自上而下 6
    2.2 自下而上 6
    2.3 References 7
    搜索References 7
    处理多个解析结果 7
    2.4 常用的API 8
  3. 修改PSI 8
    创建新的PSI 9
    代码格式化处理 10
    结合PSI 和Document 10
    需要谨慎使用的操作 10
    缓存重计算的结果 10
  4. 代码示例-获取元素PSI对象 10
    4.1 plugin.xml配置 11
    4.2 java代码实现 11
    4.3 功能测试 12
    02 文件索引 13
  5. 概述 14
    1.1 Dumb 14
    1.2 Gist 14
  6. 基于File的索引 14
    2.1 实现基于文件的索引 14
    2.2 访问基于文件的索引 15
    2.3 索引的标准实现 15
  7. 基于Stub的索引 16
    3.1 创建Stud索引 16
    创建Stud树 16
    序列化Stud数据 17
    3.2 访问Stub索引 17
    03 UAST简介 19
  8. 概述 20
  9. 扩展 20
  10. 操作 20
    3.1 PSI与UAST互转 20
    psi2uast 20
    uast2psi 21
    3.2 访问UAST 21
    04 XML DOM 23
  11. 创建XML 24
    1.1 标签内容 24
    1.2 标签属性 25
    1.3 子标签 25
    1.4 命名空间 26
  12. 编辑XML 26
    2.1 连接XML PSI 26
    2.2 获取XML树结构 27
    2.3 节点有效性验证 27
    2.4 反射 27
    2.5 Presentation 27
    2.6 Event 27
    2.7 注解突出显示 28
    2.8 自动高亮显示 28
  13. Mock and Stable 28
    3.1 Mock数据 28
    3.2 Stable​​​​​​​状态 28
  14. Visitor 29
  15. 特殊的取值方法 29
  16. 跨多个文件的模型 29
  17. XML Stud 30
    05 代码编辑 31
    1.实时模板 32
    1.1 创建实时模板 32
    plugin.xml配置 32
    java代码实现 33
    功能测试 33
    1.1 创建预定义函数和变量 33
    java代码实现 33
    添加自定义函数 34
    plugin.xml配置 34
  18. 文件和代码模板 35
    2.1 概述 35
    2.2 自定义模板变量 35
    2.3 以编程方式使用文件模板 36
    从模板创建新文件 37
    发布新模板 37
    自定义“从模板创建文件”操作 37
    将文件另存为模板 38
  19. 帮助文档 38
  20. 意图 39
    5.1 Intentions预览 40
    5.2 实现自定义Intentions预览 40
    5.3 示例代码-代码意图提示 40
    plugin.xml配置 40
    java代码实现 41
    template配置 43
    06 代码分析 44
  21. 语法错误 45
    1.1 忽略 HTML 文件中不匹配的结束标记 45
    1.2 忽略 Markdown 代码块中代码的语法错误 45
  22. 控制高亮显示 46
    2.1 在调试器代码编辑器中禁止报告未处理的异常 47
    2.2 使用 Lombok时禁止报告项目中的误报错误 47
  23. 代码检查和纠正 51
    3.1 声明性检查 51
    3.2 基于UI的检查 52
    单个复选框 52
    多个复选框 52
  24. 代码示例-检查使用==比较string 53
    4.1 plugin.xml配置 53
    4.2 相关的配置文件 53
    .properties配置 53
    .html错误帮助文档提示 54
    4.2 java代码实现 54
    工具类 54
    检查类实现 54
    4.3 功能测试 57
    4.4 功能单元测试 57
    07 项目视图 59
  25. 概述 60
  26. 代码示例-过滤项目视图内容 60
    2.1 plugin.xml配置 60
    2.2 java代码实现 60
    2.3 功能测试 61
  27. 代码示例-替换项目视图文件图标 61
    3.1 plugin.xml 61
    3.2 java代码实现 61
    自定义新的ProjectViewNode 61
    自定义项目面板 64
    08 项目构建 67
  28. 外部构建流程工作流程 68
    1.1. 增量构建 68
  29. 外部构建器 69
    2.1 扩展外部构建器服务 69
    2.2 为外部构建器注册插件 69
    2.3 调试外部构建器插件 69
    2.4 分析外部构建过程 69
    2.5 从外部构建访问项目模型和配置 70
    2.6 实现自定义构建器 70

第三部分:Intellij platform插件智能代码

在这里插入图片描述
大概6个章节,详细如下:
在这里插入图片描述

09 自定义语言-注册新语言 71

  1. 文件类型 73
    1.1 注册文件类型 73
    1.2 验证文件类型 74
    1.3. 与操作系统关联 74
  2. 实现Lexer词汇分析器 75
    2.1 Lexer状态 75
    2.2 Lexer实现 75
    2.3 Token类型 76
    2.4 嵌入式语言 77
  3. 实现Parser和PSI 77
    3.1 实现Parser 78
    空格和注释 80
    3.2 实现PSI 80
  4. 语法错误和高亮显示 81
    4.1 突出显示文本范围 81
    4.2 文本颜色设置 81
    4.3 Lexer高亮显示 82
    4.4 Annotator 85
    10 自定义语言-代码编辑 88
  5. 元素引用 89
    1.1 PSI引用 89
    1.2实现逻辑 91
  6. 元素声明 92
    2.1 引用参考 92
    自身引用 92
    外部引用 93
    隐式引用 93
  7. 代码代码导航 93
    3.1 直接导航 93
    3.2 符号导航 93
    3.3 显示用法 93
  8. 代码完成 94
    4.1 reference completion 94
    4.2 Contributor-based completion 94
    4.3 Lookup items 94
    11 自定义语言-代码重构 96
  9. 查找用法 97
    1.1 实现步骤 97
    1.2 结果分组 98
  10. 重命名 99
    2.1 名称验证 99
    2.2 自定义重命名UI和工作流程 101
  11. 安全删除 104
    12 自定义语言-高级编辑 106
  12. 代码格式化 107
    1.1 非空白修改 108
    前置处理器 108
    后置处理器 110
    代码重编排 112
    1.2 代码样式设置 112
  13. 代码检查与意图 112
    2.1 代码检查 113
    2.2 代码意图 115
  14. 文件结构视图 116
  15. 导航栏(面包屑) 120
    4.1 静态导航栏 121
    4.2 动态导航栏 121
  16. 代码围绕 121
  17. Go to Class/Symbol 122
  18. 文档 123
    7.1 获取文档 123
    文档EP 123
    文档目标 124
  19. 参数信息 127
    8.1 实现 128
    初始阶段 128
    更新阶段 128
    更多提示 129
  20. 镶嵌提示 131
    9.1 实现 131
    简单镶嵌提示 131
    高级镶嵌提示 133
    更多提示 134
  21. 拼写检查 134
    10.1拼写检查策略 135
    Tokenize分词器 135
    10.2 禁止拼写检查 139
    10.3 基于字典的检查 142
    运行时字典提供者 142
    13 自定义语言-基它功能 143
  22. 括号匹配 144
  23. quote处理 144
  24. comment代码 144
  25. 代码折叠 147
  26. 加入线 147
  27. 智能进入 147
  28. 左/右移动元素 147
  29. 命名建议 148
  30. 语义高亮使用 148
  31. TODO视图 148
  32. 上下文信息 148
  33. 颜色预览/选择器 148
  34. 包含文件 148
  35. 识别复杂的块表达式 149
  36. 面包屑 149
  37. 阅读器模式 149
  38. 编辑器和项目视图背景颜色 149
  39. 编辑器选项卡的自定义名称和工具提示 149
  40. 防止错误突出显示文件 150
  41. 为元素提供完全限定名称(FQN) 150
  42. 将文件标记为测试文件 150
  43. 在编辑器中上下移动语句 150
    14 自定义语言-实战 151
  44. 定义语言和文件类型 152
    1.1 代码实现 152
    定义Language 152
    定义LanguageIcon 152
    定义LanguageFileType 152
    1.2 plugin.xml配置 153
    1.3 功能测试 153
  45. 定义文件语法和语法解析器 154
    2.1 代码实现 154
    定义TokenType 154
    定义ElementType 155
    2.2 定义语法 155
    配置PSI生成工具类 155
    定义属性搜索工具类 157
    2.3 生成语法解析器 158
  46. 实现Lexer和解析器 159
    3.1 代码实现 159
    生成Lexer 159
    生成Lexer解析类 160
    定义Lexer适配器 161
    定义PSI root根文件 161
    定义TokenSets 161
    定义解析器 162
    注册解析器 163
    3.2 功能测试 163
  47. 代码高亮与颜色设置 163
    4.1 SyntxHighlighter代码高亮显示 163
    定义SyntxHighlighter工厂 165
    注册SyntxHighlighter工厂 165
    代码高亮功能测试 165
    4.2 SyntxHighlighter代码高亮颜色配置页面 165
    定义配置页面 165
    代码高亮颜色测试 167
    4.3 Annotator代码注释辅助显示 167
    代码实现 168
    功能测试 170
  48. gutter图标设置 170
    5.1 标记实现 170
    5.2 注册标记 171
    5.3 功能测试 171
  49. 代码自动完成 172
    6.1 基于预定义的实现 172
    代码实现 172
    注册自动完成 172
    功能测试 173
    6.2 基于动态引用的实现 173
    实现PsiNamedElement 173
    实现基于引用的实现 174
    支持引用实现的重构 175
    功能测试 176
  50. 查找用法 176
    7.1 代码实现 176
    7.2 注册查找功能 177
    7.3 功能测试 178
  51. 引用折叠 178
    8.1 代码实现 178
    8.2 注册折叠器 180
    8.3 功能测试 180
  52. 查找声明 180
    9.1 代码实现 180
    9.2 注册查找声明 181
    9.3 功能测试 181
  53. 结构视图 182
    10.1 定义模型 182
    10.2 定义元素 182
    10.3 定义工厂 184
    10.4 注册工厂 184
    10.5 功能测试 184
  54. 结构感知面包屑 184
    11.1 代码实现 185
    11.2 注册 185
    11.3 功能测试 185
  55. 代码样式设置 186
    12.1 代码格式化 186
    定义块 186
    定义格式化模型 187
    注册格式化模型 187
    12.2 代码样式 187
    定义代码样式设置 187
    定义代码样式设置提供程序 188
    注册代码样式设置提供程序 188
    定义语言代码样式设置提供程序 189
    注册语言代码样式设置提供程序 189
    功能测试 190
  56. 注释支持 190
    13.1 代码实现 190
    13.2 plugin.xml配置 191
    13.3 功能测试 191
  57. 快速修复 191
    14.1 定义元素工厂 191
    14.2 定义意向动作 192
    14.3 定义注解器 193
    14.4 注册注解器 194
    14.5 功能测试 194
  58. 拼写检查 195
    15.1 代码实现 195
    15.2 功能注册 196
    15.3 功能测试 196
  59. 文档关联 197
    16.1 实现方式一 197
    定义文档来源 197
    延迟文档显示 200
    注册扩展点 201
    16.2 实现方式二 201

共计10W(不算代码)

第四部分:Intellij platform插件开发附录

这部分内容比较杂,主要是测试、发布、资源生态等的描述
在这里插入图片描述
大概6个章节,详细如下:
在这里插入图片描述
这部分内容可直接下载笔者整理的电子书:
Intellij platform plugin开发指导手册,java集成开发环境Intellij idea插件开发

在这里插入图片描述

第五部分:Intellij platform插件实战

这里会讲两个笔者公司现在用到的自已开发的插件:

i18n国际化插件

在这里插入图片描述

服务编排流程引擎

在这里插入图片描述

文章内容

内容安排

每一篇文章大纲都可以零基础学习,内容安排有:

  • 概念:
  • 术语:
  • API讲解:
  • 相关示例:
  • 注意事项:

内容示例

概述部分

在这里插入图片描述

API详解

在这里插入图片描述

示例代码和效果演示

<action id="org.intellij.sdk.action.PopupDialogAction" class="org.intellij.sdk.action.PopupDialogAction"
        text="Pop Dialog Action" description="SDK action example"
        icon="SdkIcons.Sdk_default_icon">
  <add-to-group group-id="ToolsMenu" anchor="first"/>
  <override-text place="MainMenu" text="Pop Dialog Action"/>
</action>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

korgs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值