Apache Ant 1.9.4 构建工具实战指南

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Apache Ant是一个用于Java项目的开源构建工具,它提供了自动化编译、打包和测试等功能。该工具的1.9.4版本提供了一个稳定且功能丰富的构建环境。Ant通过构建文件(build.xml)定义项目的构建步骤和依赖关系。它包含可执行脚本、库文件、用户手册和版权声明。开发者需将Ant添加到PATH环境变量,并创建自定义构建文件来定义目标和任务,以实现编译、打包和复制等功能。Ant支持条件语句和循环来构建复杂流程,并允许自定义任务。虽然现代工具如Gradle和Maven在大型项目中逐渐取代Ant,但Ant仍然是理解构建工具基础的重要工具。 apache-ant

1. Apache Ant简介

Apache Ant是一个Java语言编写的构建工具,它用于自动化编译、测试、打包以及部署应用程序的过程。Ant的设计初衷是为了解决跨平台和可移植性的需求,它利用XML文件来描述构建过程和配置,这种设计使得Ant在软件开发的构建过程中具有很高的灵活性和可配置性。

1.1 Apache Ant的历史和发展

Ant自2000年由Apache软件基金会正式发布以来,就以其独特的项目构建方式赢得了广泛的认可。最初,Ant是作为Jakarta项目的一部分被开发出来的,目的是为了提供一个比当时流行的Make工具更好的解决方案。随着时间的推移,Ant不断更新和改进,成为了Java领域内最流行的构建工具之一。

1.2 Ant的核心概念

Ant的核心是一个名为 build.xml 的XML配置文件,这个文件定义了项目的构建过程和相关的参数。开发者可以通过编写XML脚本来指定编译源代码、运行测试、生成文档、打包以及部署等任务。Ant还提供了一系列内置任务和类型,这些内置组件可以通过XML配置文件进行参数化,以适应不同的构建需求。

1.3 Ant的应用场景

尽管在现代化的构建工具如Maven和Gradle的冲击下,Ant的使用率有所下降,但它依然在一些特定的场景下保有其价值。例如,一些遗留项目或特定的定制化构建流程中,Ant因其简单直接和高度可定制的特点,仍然是开发者的首选。此外,Ant的脚本也可以很容易地与现代构建工具结合使用,以实现更为复杂的构建过程。

通过接下来的章节,我们将深入探讨Apache Ant 1.9.4版本的特点,包括新增功能和改进、兼容性和迁移指南,以及如何编写和配置构建文件(build.xml),从而帮助读者更好地理解和利用这个强大的构建工具。

2. Ant 1.9.4版本特点

2.1 新增功能和改进

2.1.1 语言和API的改进

Apache Ant 1.9.4版本在语言和API方面进行了一些显著的改进。这些改进旨在提高开发者的编码效率,同时也使得构建脚本更加易于理解和维护。在这个版本中,Ant引入了一些新的属性和类型,以便更好地支持构建过程中的各种需求。

例如,Ant引入了新的属性类型,允许开发者在构建过程中动态地定义和使用属性。这些属性可以基于环境变量或者其他外部输入来动态设置,使得构建脚本能够更加灵活地适应不同的构建环境。

<property environment="env"/>
<property name="output.dir" value="${env.USERPROFILE}/build-output"/>

上述代码展示了如何使用环境变量来设置属性。在这里,我们定义了一个名为 output.dir 的属性,它的值是环境变量 USERPROFILE 的值。

2.1.2 内置任务和类型更新

Ant 1.9.4还对一些内置任务和类型进行了更新和增强。例如, <exec> 任务现在支持更多的操作系统特定的功能,允许开发者在不同的操作系统上执行相同的命令而不需要进行修改。此外,对于文件处理相关的类型,如 <move> <copy> ,也增加了更多的选项来控制文件的操作行为,如是否覆盖目标位置的文件。

<exec executable="python" failonerror="true">
  <arg value="script.py"/>
</exec>

上述代码展示了如何使用 <exec> 任务来执行一个Python脚本。这里,我们通过 executable 属性指定了要执行的命令,通过 <arg> 子元素传递了脚本名称。 failonerror 属性设置为 true 表示如果执行失败,构建过程将停止。

2.1.3 性能优化和bug修复

性能优化是Ant 1.9.4中的一个重要方面。在这个版本中,Ant对一些核心任务进行了性能优化,特别是在处理大量文件和目录时。这使得构建过程更加高效,尤其是在大型项目中,可以显著减少构建时间。

此外,Ant 1.9.4还修复了大量的bug,这些bug可能会影响构建的稳定性和可靠性。通过修复这些bug,Ant 1.9.4为用户提供了一个更加健壮和可靠的构建环境。

2.2 兼容性和迁移

2.2.1 与旧版本的兼容性对比

当一个新的版本发布时,开发者通常会关心新版本与旧版本之间的兼容性问题。Ant 1.9.4在这方面做了很好的工作,尽量保持了与旧版本的兼容性,以便开发者可以平滑地迁移到新版本。

Ant 1.9.4在设计时考虑到了向后兼容性,这意味着大多数在旧版本中编写的构建脚本在没有修改的情况下就可以在新版本中运行。当然,对于一些新引入的特性和改进,开发者可能需要做一些小的调整。

2.2.2 迁移指南和注意事项

对于那些想要从旧版本迁移到Ant 1.9.4的用户,Ant提供了详细的迁移指南和注意事项。这些指南详细描述了新版本中引入的变更,以及如何修改现有的构建脚本来适应这些变更。

在进行迁移时,开发者需要注意以下几点:

  1. 检查所有自定义任务和类型是否与新版本兼容。
  2. 更新任何过时的API和属性使用。
  3. 测试构建脚本以确保功能的正确性。

通过遵循这些指南和注意事项,开发者可以确保他们的构建脚本在Ant 1.9.4中正常运行,并充分利用新版本提供的改进和新功能。

3. 构建文件(build.xml)的作用

在本章节中,我们将深入探讨Apache Ant的核心组件之一——构建文件(build.xml)。构建文件是Ant构建过程中的蓝图,它定义了构建过程中需要执行的任务和目标。通过本章节的介绍,我们将了解构建文件的基本结构、构建过程的配置,以及如何组织任务和目标以实现有效的构建。

3.1 build.xml的基本结构

3.1.1 项目的定义和属性设置

构建文件的开始通常是项目(project)的定义。项目是构建过程的最高层次,包含了构建过程中的所有任务和目标。项目定义中可以设置项目的名称、默认目标、基目录等属性。

<project name="MyProject" default="build" basedir=".">
    <!-- 属性设置 -->
    <property name="src.dir" location="src"/>
    <property name="build.dir" location="build"/>
    <property name="dist.dir" location="dist"/>
    <!-- 其他任务和目标 -->
</project>

在上述代码中, <project> 标签定义了项目的基本信息。 name 属性表示项目的名称, default 属性指定了默认执行的目标(target),而 basedir 属性定义了项目的基础目录。 <property> 标签用于设置项目属性,如源代码目录( src.dir )、构建输出目录( build.dir )和发行目录( dist.dir )。

3.1.2 任务和目标的组织

任务(task)是构建过程中执行的具体操作,如编译、测试、打包等。目标(target)是一组任务的集合,可以被单独调用或按照依赖关系顺序执行。

<target name="clean">
    <delete dir="${build.dir}"/>
</target>

<target name="compile" depends="clean">
    <mkdir dir="${build.dir}"/>
    <javac srcdir="${src.dir}" destdir="${build.dir}"/>
</target>

<target name="package" depends="compile">
    <jar destfile="${dist.dir}/MyProject.jar" basedir="${build.dir}"/>
</target>

<target name="default" depends="package"/>

在这个例子中, clean 目标首先删除构建目录, compile 目标依赖于 clean ,它创建构建目录并编译源代码, package 目标依赖于 compile ,它将编译后的类打包成JAR文件。最后, default 目标作为默认执行的目标,依赖于 package

3.2 构建过程的配置

3.2.1 编译、测试和打包的配置

编译、测试和打包是构建过程中的常见步骤。Ant通过内置的任务提供了这些功能,同时也支持自定义任务的集成。

<target name="build" description="Build the project.">
    <javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false"/>
    <junit fork="true" haltonfailure="true">
        <classpath path="${build.dir}"/>
        <formatter type="xml"/>
        <test name="com.example.MyTest"/>
    </junit>
    <jar destfile="${dist.dir}/MyProject.jar" basedir="${build.dir}"/>
</target>

在上述代码中, <javac> 任务用于编译Java源代码, <junit> 任务用于运行JUnit测试,而 <jar> 任务用于打包成JAR文件。 <target> 标签的 description 属性提供了目标的描述信息。

3.2.2 自定义任务的集成

除了内置任务,Ant还支持通过扩展自定义任务。自定义任务通常需要编写Java类,并在Ant的配置文件中注册。

package com.example.ant;

import org.apache.tools.ant.Task;

public class MyTask extends Task {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public void execute() {
        System.out.println(message);
    }
}

上述Java类定义了一个简单的自定义任务 MyTask ,它继承自 Task 类,并重写了 execute 方法。任务的配置文件 build.xml 中需要注册并使用这个自定义任务。

<taskdef name="mytask" classname="com.example.ant.MyTask"/>

<target name="custom-task">
    <mytask message="Hello, Ant!"/>
</target>

build.xml 中, <taskdef> 标签用于注册自定义任务,而 <mytask> 标签则在目标 custom-task 中使用这个自定义任务。

通过本章节的介绍,我们了解了构建文件(build.xml)的基本结构和构建过程的配置方法。下一章节我们将继续探讨Ant的主要目录结构,包括核心目录和文件、插件和扩展目录的概述,以及如何进行目录结构的定制。

4. Ant的主要目录结构

4.1 目录结构概述

4.1.1 核心目录和文件

Apache Ant是一个基于Java的构建工具,它的核心目录结构非常直观,主要分为以下几个部分:

  • bin/ :包含Ant的可执行脚本和库文件,这是使用Ant时最先关注的目录。
  • lib/ :包含Ant运行所需的库文件,包括Ant的核心库和第三方库。
  • docs/ :存放Ant的文档,包括安装指南、用户手册和API文档。
  • src/ :包含Ant的源代码,如果你需要深入研究Ant的内部机制,这是一个非常好的起点。

Ant的 bin/ 目录包含 ant ant.bat (在Unix/Linux和Windows系统上分别是脚本和批处理文件),这些是启动Ant构建过程的入口点。 lib/ 目录包含了Ant的核心库文件,以及Ant任务和类型定义所需的第三方库。这些文件对于Ant的运行至关重要。

4.1.2 插件和扩展目录

除了核心目录之外,Ant的插件和扩展通常位于 lib/ext/ 目录下。用户可以将额外的库文件放置在此目录中,以增强Ant的功能。例如,可以在此处添加JDBC驱动程序或其他特定于项目的库。

graph TD
    A[Ant的根目录] --> B[bin]
    A --> C[lib]
    A --> D[docs]
    A --> E[src]
    C --> F[lib/ext]
    F --> G[插件和扩展]

4.2 目录结构的定制

4.2.1 自定义安装和部署

用户可以根据自己的需要对Ant的目录结构进行自定义安装。例如,如果你希望将Ant与其他Java应用程序一起部署,可以将 lib/ 目录中的库文件合并到主应用程序的库目录中。此外,也可以通过设置环境变量来指定Ant的 lib/ 目录路径。

代码示例:设置环境变量
export ANT_HOME=/path/to/your/ant
export PATH=$ANT_HOME/bin:$PATH

4.2.2 目录结构优化实践

在大型项目中,优化Ant的目录结构可以提高构建效率和可维护性。例如,可以将常用的库文件放置在项目特定的目录中,而不是全局的 lib/ 目录。这样可以避免版本冲突,并且使得项目依赖更加清晰。

代码示例:构建文件中使用自定义路径
<property name="my.lib.dir" location="/path/to/my/lib" />
<taskdef resource="net/sf/antlib/antlib.xml">
  <classpath>
    <fileset dir="${my.lib.dir}">
      <include name="*.jar" />
    </fileset>
  </classpath>
</taskdef>

在上述示例中,我们定义了一个属性 my.lib.dir 指向自定义的库目录,并在定义Ant任务时通过 classpath 元素指定该目录。这种方式使得Ant的构建过程更加灵活,同时也便于在不同项目中复用和共享Ant脚本。

总结来说,Ant的目录结构虽然简单,但是通过合理的自定义和优化,可以大大提高开发和构建的效率。无论是对于小型项目还是大型企业级应用,理解并掌握Ant的目录结构对于构建过程的管理和优化都是至关重要的。

5. 用户手册和版权声明

5.1 用户手册的内容概览

5.1.1 安装和配置指南

在本章节中,我们将介绍Apache Ant的安装和配置过程,这对于新用户来说是基础且重要的一步。Ant的安装过程相对简单,主要分为下载、解压和设置环境变量三个步骤。

首先,访问Apache Ant的官方网站下载最新版本的Ant分发包。选择对应的操作系统版本进行下载,例如Windows或Linux。下载完成后,解压到用户指定的目录中。

接下来,设置环境变量以确保Ant可以在命令行中全局使用。在Windows系统中,你需要将Ant的bin目录添加到系统的PATH环境变量中。在Linux或Mac系统中,你可以在 .bashrc .bash_profile 文件中添加相应的PATH配置。

export ANT_HOME=/path/to/apache-ant
export PATH=$PATH:$ANT_HOME/bin

执行 source ~/.bashrc (或对应的配置文件)以使配置生效。

5.1.2 常用命令和使用示例

Ant提供了丰富的命令行工具和任务,以支持各种构建需求。通过 ant 命令可以启动构建过程,而 ant -help 则会列出所有可用的任务和属性。

下面是一个简单的构建示例,展示了如何使用Ant构建一个Java项目:

<!-- build.xml -->
<project name="HelloWorld" default="build" basedir=".">
    <property name="src" location="src"/>
    <property name="build" location="build"/>
    <property name="dist" location="dist"/>

    <target name="init">
        <mkdir dir="${build}"/>
    </target>

    <target name="compile" depends="init">
        <javac srcdir="${src}" destdir="${build}"/>
    </target>

    <target name="build" depends="compile">
        <jar destfile="${dist}/hello-world.jar" basedir="${build}"/>
    </target>

    <target name="clean">
        <delete dir="${build}"/>
        <delete file="${dist}/hello-world.jar"/>
    </target>
</project>

要构建项目,只需在命令行中执行 ant 命令。Ant将按照 build.xml 中定义的目标顺序执行任务。

ant

此命令将依次执行 init compile build 目标,最终生成一个名为 hello-world.jar 的压缩包。

5.2 版权声明和许可协议

5.2.1 Apache License v2.0简介

Apache License v2.0是Ant采用的开源许可协议,它允许用户自由地使用、修改和分发软件,同时确保原作者的贡献得到认可。该协议的主要特点包括:

  • 自由度 :用户可以自由使用软件,无需担心许可限制。
  • 贡献者保护 :对原作者的贡献给予明确的版权声明,确保其知识产权得到保护。
  • 兼容性 :允许分发修改后的软件,并要求修改后的代码也采用相同的许可证。

5.2.2 贡献者和归属信息

在使用Ant的过程中,用户可能会对源代码进行修改或扩展,这时应当遵守Apache License v2.0的相关规定。如果用户想要贡献自己的代码,可以通过Apache软件基金会的官方渠道进行。

每个贡献的代码都应该包含相应的归属信息,表明原作者对该代码的贡献,并且遵循许可证的要求。在代码中添加注释是一种常见的做法,如下所示:

/**
 * This file is part of Apache Ant.
 *
 * Apache Ant is free software; you can redistribute it and/or modify
 * it under the terms of the Apache License as published by
 * the Apache Software Foundation; either version 2.0 of the License,
 * or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * Apache License for more details.
 */

这段注释提供了版权和许可协议的基本信息,并且声明了代码的归属。当用户阅读这段注释时,他们可以了解该文件的使用条件和归属信息,这对于维护软件的开源生态是非常重要的。

6. 环境变量配置

6.1 环境变量的作用

6.1.1 PATH和CLASSPATH的配置

环境变量是操作系统用来指定执行程序或脚本时系统搜索路径的配置项。在使用Ant进行项目构建时,正确的环境变量配置至关重要。

PATH环境变量

PATH环境变量用于指定系统命令搜索的路径。虽然Ant本身不需要在PATH中,但是如果你需要在构建脚本中调用系统命令(如 javac 编译器),则必须确保这些命令的路径被包含在PATH中。

CLASSPATH环境变量

CLASSPATH环境变量用于指定Java类加载器在运行时查找类文件的路径。对于Ant而言,当你在构建脚本中使用 <java> 任务来运行Java应用程序或者类时,CLASSPATH变得尤为重要。

6.1.2 环境变量对构建的影响

环境变量的设置直接影响Ant构建过程。例如,ANT_HOME环境变量应指向Ant的安装目录,而JAVA_HOME应指向Java的安装目录。这些变量不仅帮助Ant找到必要的工具,还有助于构建过程的自动化和标准化。

6.2 配置实例和注意事项

6.2.1 操作系统环境配置示例

Windows系统

在Windows系统中,你可以通过“控制面板” -> “系统” -> “高级系统设置” -> “环境变量”来配置环境变量。

ANT_HOME=C:\apache-ant-1.9.4
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_211
PATH=%PATH%;%ANT_HOME%\bin;%JAVA_HOME%\bin
CLASSPATH=.;%ANT_HOME%\lib
Unix/Linux系统

在Unix/Linux系统中,你可以在 .bashrc .bash_profile 文件中添加环境变量的配置。

export ANT_HOME=/usr/local/apache-ant-1.9.4
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
export PATH=$PATH:$ANT_HOME/bin:$JAVA_HOME/bin
export CLASSPATH=.

6.2.2 配置常见问题及解决方案

问题1:ANT_HOME未正确设置

如果ANT_HOME没有被正确设置,Ant命令将无法找到Ant的安装目录,导致无法执行。

解决方案:

确保ANT_HOME环境变量指向Ant的安装目录。

问题2:CLASSPATH设置不正确

CLASSPATH没有正确设置可能导致类文件找不到,从而影响到需要加载类的任务执行。

解决方案:

确保CLASSPATH包含所有必要的类路径,特别是当你在构建脚本中使用自定义任务时。

问题3:系统路径冲突

有时候,系统的PATH环境变量中可能存在多个Java版本的路径,这可能导致Java工具链出现问题。

解决方案:

清理PATH变量,确保它只包含所需的Java和Ant工具路径。

通过本章节的介绍,我们了解了环境变量在使用Ant构建过程中的重要性,并提供了操作系统级别的配置示例。理解并正确配置这些环境变量,是确保构建过程顺利进行的关键步骤。在本章节中,我们详细解释了PATH和CLASSPATH的作用,并通过实例展示了如何在不同的操作系统中进行配置。此外,我们还讨论了一些常见问题及其解决方案,帮助你避免在配置环境变量时遇到的常见陷阱。总结来说,良好的环境变量配置能够为使用Ant进行项目构建打下坚实的基础。

7. 构建文件创建与任务定义

7.1 创建build.xml文件

7.1.1 文件结构和内容要点

在Apache Ant中, build.xml 文件是构建过程的核心。它定义了构建过程中的任务(Task)和目标(Target),以及它们之间的依赖关系。以下是 build.xml 文件的基本结构和内容要点:

<project name="project-name" default="default-target" basedir="project-directory">
    <!-- 初始化属性 -->
    <property name="var-name" value="var-value" />
    <!-- 依赖的目标 -->
    <target name="target-name" depends="depends-target">
        <!-- 任务列表 -->
        <task-name attribute="value" />
    </target>
</project>
  • <project> 标签是构建文件的根元素,其中包含 name (项目名称)、 default (默认目标)、 basedir (项目基础目录)等属性。
  • <property> 标签用于定义项目属性,例如版本号、路径等,这些属性可以在整个构建文件中使用。
  • <target> 标签定义了一个目标,它包含了一系列的任务。 depends 属性指定了该目标依赖的目标。
  • <task-name> 是Ant内置任务的名称,每个任务都可以有自己的属性,用于控制任务的行为。

7.1.2 编写构建规则和逻辑

在编写 build.xml 时,你需要根据项目的需求来定义构建规则和逻辑。例如,以下是一个简单的构建规则示例:

<project name="example-project" default="build" basedir=".">
    <!-- 定义项目属性 -->
    <property name="build.dir" value="${basedir}/build" />
    <property name="dist.dir" value="${basedir}/dist" />
    <!-- 创建构建目录 -->
    <target name="init">
        <mkdir dir="${build.dir}" />
    </target>
    <!-- 编译源代码 -->
    <target name="compile" depends="init">
        <javac srcdir="${basedir}/src" destdir="${build.dir}" />
    </target>
    <!-- 打包 -->
    <target name="package" depends="compile">
        <jar destfile="${dist.dir}/example.jar" basedir="${build.dir}" />
    </target>
    <!-- 默认目标 -->
    <target name="build" depends="package" />
</project>

在这个示例中,我们定义了三个目标: init compile package init 目标用于创建构建目录, compile 目标依赖于 init 并编译源代码, package 目标依赖于 compile 并打包成JAR文件。

7.2 任务和目标的定义

7.2.1 内置任务的使用

Ant提供了丰富的内置任务,可以直接在 build.xml 中使用。例如:

  • <javac> :编译Java源代码。
  • <jar> :创建JAR文件。
  • <copy> :复制文件和目录。
  • <delete> :删除文件和目录。

以下是如何在 build.xml 中使用这些内置任务的示例:

<project name="example-project" default="build" basedir=".">
    <!-- 编译源代码 -->
    <target name="compile">
        <javac srcdir="${basedir}/src" destdir="${build.dir}" />
    </target>
    <!-- 复制资源文件 -->
    <target name="copy-resources" depends="compile">
        <copy todir="${build.dir}/resources">
            <fileset dir="${basedir}/resources" includes="**/*.properties" />
        </copy>
    </target>
    <!-- 默认目标 -->
    <target name="build" depends="copy-resources" />
</project>

在这个示例中,我们定义了两个目标: compile copy-resources compile 目标编译源代码,而 copy-resources 目标复制资源文件到构建目录。

7.2.2 自定义任务的编写和集成

除了内置任务外,Ant还允许用户编写自定义任务。自定义任务通常是一个Java类,它需要继承自 Task 类,并覆盖 execute 方法。以下是一个简单的自定义任务示例:

import org.apache.tools.ant.Task;

public class MyTask extends Task {
    private String message;
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public void execute() {
        System.out.println("Custom task: " + message);
    }
}

然后,你需要在 build.xml 中注册这个自定义任务:

<project name="example-project" default="build" basedir=".">
    <!-- 注册自定义任务 -->
    <taskdef name="mytask" classname="example.MyTask" />
    <!-- 使用自定义任务 -->
    <target name="custom-task">
        <mytask message="Hello, Ant!" />
    </target>
    <!-- 默认目标 -->
    <target name="build" depends="custom-task" />
</project>

在这个示例中,我们定义了一个名为 mytask 的自定义任务,并在 build.xml 中注册了它。然后在 custom-task 目标中使用了这个自定义任务。

通过这种方式,你可以根据项目的需求编写自定义任务,以扩展Ant的功能。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Apache Ant是一个用于Java项目的开源构建工具,它提供了自动化编译、打包和测试等功能。该工具的1.9.4版本提供了一个稳定且功能丰富的构建环境。Ant通过构建文件(build.xml)定义项目的构建步骤和依赖关系。它包含可执行脚本、库文件、用户手册和版权声明。开发者需将Ant添加到PATH环境变量,并创建自定义构建文件来定义目标和任务,以实现编译、打包和复制等功能。Ant支持条件语句和循环来构建复杂流程,并允许自定义任务。虽然现代工具如Gradle和Maven在大型项目中逐渐取代Ant,但Ant仍然是理解构建工具基础的重要工具。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值