MybatisPlus自动生成模板代码

在这里插入图片描述

一、引入依赖

		<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>

二、自动生成代码的类

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class CodeAuto {
    public static void main(String[] args) {
        // 构建一个代码生成器对象
        AutoGenerator mpg = new AutoGenerator();

        // 配置策略
        // 1. 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath+"/src/main/java");
        gc.setAuthor("Mioky");
        gc.setOpen(false);
        gc.setFileOverride(false); // 是否覆盖
        gc.setXmlName("%sMapper");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setControllerName("%sController");
        gc.setIdType(IdType.ASSIGN_UUID);
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);

        // 2. 设置数据源
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/shequ20?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&allowMultiQueries=true&serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        mpg.setDataSource(dsc);

        // 3. 包的配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.community");
        pc.setModuleName("demo");
        pc.setEntity("model");
        pc.setService("service");
        pc.setMapper("dao");
        pc.setController("controller");
        mpg.setPackageInfo(pc);

        // 4.策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("t_402_activitytype"); // 设置要映射的表名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setTablePrefix("t_402");
        strategy.setEntityLombokModel(true); // 自动lombok
        strategy.setLogicDeleteFieldName("IsDel"); // 逻辑删除
        // 自动填充配置
        TableFill addTime = new TableFill("AddDate", FieldFill.INSERT);
        // TableFill editTime = new TableFill("edit_time", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(addTime);
        // tableFills.add(editTime);
        strategy.setTableFillList(tableFills);
        // 乐观锁
        // strategy.setVersionFieldName("version");
        // strategy.setRestControllerStyle(true);
        // strategy.setControllerMappingHyphenStyle(true); // localhost:8080/hello_id_2
        mpg.setStrategy(strategy);

        // 配置自定义模板
        TemplateConfig templateConfig = new TemplateConfig()
                // 关闭默认 xml 生成,调整生成 至 根目录
                .setXml(null);
        // 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
        // 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置:
        templateConfig.setEntity("templates/entity.java.vm");
        templateConfig.setMapper("templates/mapper.java.vm");
        templateConfig.setXml("templates/mapper.xml.vm");
        templateConfig.setService("templates/service.java.vm");
        templateConfig.setServiceImpl("templates/serviceImpl.java.vm");
        templateConfig.setController("templates/controller.java.vm");
        mpg.setTemplate(templateConfig);

        mpg.execute(); // 执行

    }
}

三、在resource的templates包下添加模板

1. controller.java.vm

package ${package.Controller};

#if(${restControllerStyle})
import org.springframework.web.bind.annotation.RestController;
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
#if(${swagger2})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
#end
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import javax.servlet.http.HttpServletRequest;
import lombok.var;
import java.util.List;
import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
import java.text.SimpleDateFormat;

/**
 *
 * @author ${author}
 * @since ${date}
 */
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@RequestMapping("${entity}/")
#if(${swagger2})
@Api(value = "/${table.controllerName}", tags = "")
#end
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
    @Autowired
    public ${table.serviceName} i${entity}Service;

    @Autowired
    private HttpServletRequest request;

    // 用户信息对象,响应对象BoardMessage的最后一个参数,测试时不需要验证用户信息暂时给null值,放开此项同时相应的应该把每个接口中【验证用户信息的代码】删除,项目中可把此参数删除
    // private ModelAccountInfo tempVal = null;

    /**
     * 分页查询数据
     *
     * @param pageQuery  查询条件 Page,Row 为必要参数
     * @return BoardMessage
     */
    @PostMapping(value = "Get${entity}PageList")
    @ResponseBody
    #if(${swagger2})
    @ApiOperation(value = "获取分页列表", notes = "获取分页列表", response = BoardMessage.class)
    #end
    public BoardMessage Get${entity}PageList(@RequestBody PageQuery pageQuery) {

        // 验证用户信息
        var tempVal = TokenUse.verificationTokenInfo(request);
        if (tempVal == null) {
            return new BoardMessage(ErrorCode.getTokenId(), "Token无效,请重新登入", " Get${entity}PageList",null);
        }

        BoardMessage message;
        try {
            Page<${entity}> page = i${entity}Service.select${entity}Page(pageQuery);
            return new BoardMessage(ErrorCode.getSuccess(),"",page," Get${entity}PageList", tempVal);
        } catch (Exception e) {
            message = new BoardMessage(ErrorCode.getException(),e.toString()," Get${entity}PageList", tempVal);
        }
        return message;
    }

    /**
    * 查询列表数据
    * @return BoardMessage
    */
    @GetMapping(value = "Get${entity}List")
    @ResponseBody
    @ApiOperation(value = "查询列表数据", notes = "查询列表数据", response = BoardMessage.class)
    public BoardMessage Get${entity}List() {

        // 验证用户信息
        var tempVal = TokenUse.verificationTokenInfo(request);
        if (tempVal == null) {
            return new BoardMessage(ErrorCode.getTokenId(), "Token无效,请重新登入", " Get${entity}List",null);
        }

        BoardMessage message;
        try {
            List<${entity}> list = i${entity}Service.list();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            list.forEach(item->{
            item.setAddTimeStr(simpleDateFormat.format(item.getAddTime()));
            });
            return new BoardMessage(ErrorCode.getSuccess(),"",list," Get${entity}List", tempVal);
        } catch (Exception e) {
            message = new BoardMessage(ErrorCode.getException(),e.toString()," Get${entity}List", tempVal);
        }
        return message;
    }

    /**
     * 查询树列表
     * @return BoardMessage
     */
    @PostMapping(value = "Get${entity}TreeList")
    @ResponseBody
    @ApiOperation(value = "查询树列表", notes = "查询树列表", response = BoardMessage.class)
    public BoardMessage Get${entity}TreeList() {

        // 验证用户信息
        var tempVal = TokenUse.verificationTokenInfo(request);
        if (tempVal == null) {
        return new BoardMessage(ErrorCode.getTokenId(), "Token无效,请重新登入", " Get${entity}TreeList",null);
        }

        BoardMessage message;
        try {
        List<${entity}> list = i${entity}Service.list();
        Map<Integer, List<${entity}>> mapByPid = list.stream().collect(Collectors.groupingBy(${entity}::getPId));
        list.forEach(department->{
        department.setChildren(mapByPid.get(department.getId()));
        });
        List<${entity}> collect = list.stream().filter(v -> v.getPId().equals(0)).collect(Collectors.toList());
        return new BoardMessage(ErrorCode.getSuccess(),"",collect," Get${entity}TreeList", tempVal);
        } catch (Exception e) {
        message = new BoardMessage(ErrorCode.getException(),e.toString()," Get${entity}TreeList", tempVal);
        }
        return message;
    } 

    /**
     * 添加${entity}
     * @param vue${entity} 请求参数对象
     * @return BoardMessage
     */
    @PostMapping(value = "Insert${entity}")
    #if(${swagger2})
    @ApiOperation(value = "添加${entity}", notes = "添加${entity}", response = BoardMessage.class)
    #end
    @ResponseBody
    public BoardMessage Insert${entity}(@RequestBody Vue${entity} vue${entity}) {

        // 验证用户信息
        var tempVal = TokenUse.verificationTokenInfo(request);
        if (tempVal == null) {
            return new BoardMessage(ErrorCode.getTokenId(), "Token无效,请重新登入", tempVal);
        }

        BoardMessage message;
        try {
            if (i${entity}Service.IsNameExists(vue${entity}.getName(), 0)) {
                message = new BoardMessage(ErrorCode.getFail(), "名称已存在", "Insert${entity}", tempVal);
                return message;
            }
            ${entity} demo${entity} = new ${entity}();
            // 此处为对象赋值(把第一个参数对象的属性值赋给第二个参数对象)
            BeanUtils.copyProperties(vue${entity},demo${entity});

            if (i${entity}Service.save(demo${entity})) {
                message = new BoardMessage(ErrorCode.getSuccess(), "", "Insert${entity}", tempVal);
            } else {
                message = new BoardMessage(ErrorCode.getFail(), "", "Insert${entity}", tempVal);
            }
        } catch (Exception e) {
            message = new BoardMessage(ErrorCode.getException(), e.toString(), "Insert${entity}", tempVal);
        }
        return message;
    }

    /**
     * 修改${entity}
     * @param vue${entity} 请求参数对象
     * @return BoardMessage
     */
    @PostMapping(value = "Update${entity}")
    @ApiOperation(value = "修改${entity}", notes = "修改${entity}", response = BoardMessage.class)
    @ResponseBody
    public BoardMessage Update${entity}(@RequestBody Vue${entity} vue${entity}) {

        // 验证用户信息
        var tempVal = TokenUse.verificationTokenInfo(request);
        if (tempVal == null) {
            return new BoardMessage(ErrorCode.getTokenId(), "Token无效,请重新登入", tempVal);
        }

        BoardMessage message;
        try {
            if (i${entity}Service.IsNameExists(vue${entity}.getName(),vue${entity}.getId())) {
                message = new BoardMessage(ErrorCode.getFail(), "名称已存在", "Update${entity}", tempVal);
                return message;
            }
            ${entity} demo${entity} = new ${entity}();
            // 此处为对象赋值(把第一个参数对象的属性值赋给第二个参数对象)
            BeanUtils.copyProperties(vue${entity},demo${entity});

            if (i${entity}Service.updateById(demo${entity})) {
                message = new BoardMessage(ErrorCode.getSuccess(), "", "Update${entity}", tempVal);
            } else {
             message = new BoardMessage(ErrorCode.getFail(), "", "Update${entity}", tempVal);
            }
        } catch (Exception e) {
            message = new BoardMessage(ErrorCode.getException(), e.toString(), "Update${entity}", tempVal);
        }
        return message;
    }

    /**
     * 删除${entity}
     * @param id ${entity}主键
     * @return BoardMessage
     */
    @PostMapping(value = "Delete${entity}")
    @ApiOperation(value = "删除${entity}", notes = "删除${entity}", response = BoardMessage.class)
    @ResponseBody
    public BoardMessage Delete${entity}(@RequestParam("id") int id){

        // 验证用户信息
        var tempVal=TokenUse.verificationTokenInfo(request);
        if(tempVal==null){
            return new BoardMessage(ErrorCode.getTokenId(),"Token无效,请重新登入",tempVal);
        }

        BoardMessage message;
        try{
            if(i${entity}Service.removeById(id)){
                return new BoardMessage(ErrorCode.getSuccess(),"Delete${entity}",tempVal);
            }else{
                return new BoardMessage(ErrorCode.getFail(),"Delete${entity}",tempVal);
            }
        }catch(Exception e){
            message=new BoardMessage(ErrorCode.getException(),e.toString(),"Delete${entity}",tempVal);
        }
        return message;
    }

    /**
     * 启用/禁用${entity}
     * @param vue${entity} 请求参数对象 IsEnable,Id 为必要参数
     * @return  BoardMessage
     */
    @PostMapping(value = "Enable${entity}")
    @ApiOperation(value = " 启用/禁用${entity}", notes = "启用/禁用${entity}", response = BoardMessage.class)
    @ResponseBody
    public BoardMessage Enable${entity}(@RequestBody Vue${entity} vue${entity}) {

        // 验证用户信息
        var tempVal = TokenUse.verificationTokenInfo(request);
        if (tempVal == null) {
            return new BoardMessage(ErrorCode.getTokenId(), "Token无效,请重新登入", tempVal);
        }

        BoardMessage message;
        try {
            ${entity} demo${entity} = new ${entity}();
            demo${entity}.setIsEnable(vue${entity}.getIsEnable());
            demo${entity}.setId(vue${entity}.getId());

            if (i${entity}Service.updateById(demo${entity})) {
                message = new BoardMessage(ErrorCode.getSuccess(), "", "Enable${entity}", tempVal);
            } else {
                message = new BoardMessage(ErrorCode.getFail(), "", "Enable${entity}", tempVal);
            }
        } catch (Exception e) {
            message = new BoardMessage(ErrorCode.getException(), e.toString(), "Enable${entity}", tempVal);
        }
        return message;
    }

}

2. entity.java.vm

package ${package.Entity};

#if(${activeRecord})
import java.io.Serializable;

#end
#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${entityLombokModel})
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#end
#if(${swagger2})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end

/**
 * @author ${author}
 * @since ${date}
 */
#if(${entityLombokModel})
@Data
@NoArgsConstructor
@AllArgsConstructor
#end
#if(${swagger2})
@ApiModel(value="${entity}对象", description="$!{table.comment}")
#end
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#else
public class ${entity} implements Serializable {
#end
## private static final long serialVersionUID = 1L;
## ----------  BEGIN 字段循环遍历  ----------
#foreach($field in ${table.fields})
    #if(${field.keyFlag})
    #set($keyPropertyName=${field.propertyName})
    #end
    #if(${field.keyFlag})
    ## 主键
    #if(${field.keyIdentityFlag})
@TableId(value="${field.name}", type= IdType.AUTO)
    #elseif(${field.convert})
@TableId("${field.name}")
    #end
    ## 普通字段
    #elseif(${field.fill})
    ## -----   存在字段填充设置   -----
        #if(${field.convert})
    @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
        #else
    @TableField(fill = FieldFill.${field.fill})
        #end
    #elseif(${field.convert})
    @TableField("${field.name}")
    #end
## 乐观锁注解
    #if(${versionFieldName}==${field.name})
    @Version
    #end
## 逻辑删除注解
    #if(${logicDeleteFieldName}==${field.name})
    @TableLogic
    #end
## 主键
    #if(${field.keyIdentityFlag})
private ${field.propertyType} ${field.propertyName};
## 非主键
    #elseif(${field.convert})
        #if(${swagger2})
    @ApiModelProperty(value = "${field.comment}")
        #else
    /**
     * ${field.comment}
     */
        #end
    private ${field.propertyType} ${field.propertyName};
        #end

#end

    @TableField(exist = false)
    private String AddTimeStr;

## ----------  END 字段循环遍历  ----------
#if(!${entityLombokModel})
    #foreach($field in ${table.fields})
        #if(${field.propertyType.equals("boolean")})
            #set($getprefix="is")
        #else
            #set($getprefix="get")
        #end

    public ${field.propertyType} ${getprefix}${field.capitalName}() {
            return ${field.propertyName};
            }

        #if(${entityBuilderModel})
        public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
        #else
        public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
        #end
            this.${field.propertyName} = ${field.propertyName};
        #if(${entityBuilderModel})
                return this;
        #end
            }
    #end
#end
#if(${entityColumnConstant})
    #foreach($field in ${table.fields})
    public static final String ${field.name.toUpperCase()} = "${field.name}";

    #end
#end
#if(${activeRecord})
@Override
protected Serializable pkVal() {
    #if(${keyPropertyName})
            return this.${keyPropertyName};
    #else
            return this.id;
    #end
        }

#end
#if(!${entityLombokModel})
@Override
public String toString() {
        return "${entity}{" +
    #foreach($field in ${table.fields})
        #if($!{velocityCount}==1)
                "${field.propertyName}=" + ${field.propertyName} +
        #else
                ", ${field.propertyName}=" + ${field.propertyName} +
        #end
    #end
        "}";
        }
#end
}

3. mapper.java.vm

package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;

/**
 * <p>
 * $!{table.comment} Mapper 接口
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Repository
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
    List<${entity}> find${entity}PageList(Page<${entity}> page,String fuzzySearchStr);
}

4.mapper.xml.vm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">

    #if(${enableCache})
        <!-- 开启二级缓存 -->
        <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>

    #end
    #if(${baseResultMap})
        <!-- 通用查询映射结果 -->
        <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
            #foreach($field in ${table.fields})
                #if(${field.keyFlag})##生成主键排在第一位
                    <id column="${field.name}" property="${field.propertyName}" />
                #end
            #end
            #foreach($field in ${table.commonFields})##生成公共字段
                <result column="${field.name}" property="${field.propertyName}" />
            #end
            #foreach($field in ${table.fields})
                #if(!${field.keyFlag})##生成普通字段
                    <result column="${field.name}" property="${field.propertyName}" />
                #end
            #end
        </resultMap>

    #end
    #if(${baseColumnList})
        <!-- 通用查询结果列 -->
        <sql id="Base_Column_List">
                #foreach($field in ${table.commonFields})
                    #if(${field.name} == ${field.propertyName})${field.name}#else${field.name} AS ${field.propertyName}#end
                #end
                ${table.fieldNames}
        </sql>
    #end

    <select id="find${entity}PageList" resultType="${package.Entity}.${entity}">
        SELECT
        *
        FROM
        ${table.name}
        WHERE
        <if test="fuzzySearchStr != null and fuzzySearchStr != '' ">
            FuzzySearch LIKE CONCAT(CONCAT('%',#{fuzzySearchStr},'%')) AND
        </if>
        IsDel = 0
    </select>
</mapper>

5. service.java.vm

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.List;

/**
 * <p>
 * $!{table.comment} 服务类
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

        /**
         *  分页查询
         * @param pageQuery 必须要有 page 和 row
         * @return
         */
        Page<${entity}> select${entity}Page(PageQuery pageQuery);

        boolean IsNameExists(String name, Integer id);
}

6. serviceImpl.java.vm

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.text.SimpleDateFormat;
import java.util.List;
/**
 * <p>
 * $!{table.comment} 服务实现类
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Service
@Transactional
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
        @Autowired
        private ${table.mapperName} ${table.entityPath}Mapper;

        @Override
        public Page<${entity}> select${entity}Page(PageQuery pageQuery) {
                String fuzzySearchStr = ""; // 模糊查询字段
                Page<${entity}> page = new Page<>(pageQuery.getPage(),pageQuery.getRow());
                List<${entity}> list = ${table.entityPath}Mapper.find${entity}PageList(page,fuzzySearchStr);
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                list.forEach(item->{
                item.setAddTimeStr(simpleDateFormat.format(item.getAddTime()));
                });
                page.setRecords(list);
                return page;
        }

        /**
        * 查询名称是否存在
        * @param name 名称
        * @param id 主键
        * @return
        */
        @Override
        public boolean IsNameExists(String name, Integer id) {
                QueryWrapper<${entity}> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().and(c->c.eq(${entity}::getName,name));
                if (0 != id) {
                queryWrapper.lambda().and(c->c.ne(${entity}::getId, id));
                }
                return ${table.entityPath}Mapper.selectCount(queryWrapper)>0;
        }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值