一个简单的web项目,网站文章管理(二)

年底因为各种事情比较忙,很久没有更新,最近在家宅着顺便填下之前的坑。

后端部分:

一、创建maven工程导入依赖(在上一篇中可以找到pom文件)和配置spring及整合springMVC、Mybatis

  • 我用的是IDEA,创建maven-web工程的教程有很多,我就不多废话了;
  • web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>article</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <!-- 启动spring容器 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- springMVC前端控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 取消过滤html页面 -->
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

  <!-- 过滤字符编码 -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- 将页面普通的请求转为rest风格的请求 -->
  <filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
  • applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
	
	<context:component-scan base-package="com.luofc">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	
	<!-- 配置连接池 -->
	<context:property-placeholder location="classpath:dbconfig.properties"/>
	<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>
	
	<!-- 配置整合mybatis -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 指定mybatis全局配置文件位置 -->
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
		<property name="dataSource" ref="pooledDataSource"></property>
		<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
	</bean>
	
	<!-- 配置可以執行批量操作的sqlsession -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
		<constructor-arg name="executorType" value="BATCH"></constructor-arg>
	</bean>
	
	<!-- 配置扫描器,把mybatis的接口实现类加入IOC容器中 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!-- 扫描所有dao接口的实现,加入IOC -->
		<property name="basePackage" value="com.luofc.article"></property>
	</bean>
	
	<!-- 配置事务控制 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="pooledDataSource"></property>
	</bean>
	
	<!-- 开启基于XML配置的事务 -->
	<aop:config>
		<aop:pointcut expression="execution(* com.jiafu.article.service..*(..))" id="txPoint"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
	</aop:config>
	
	<!-- 配置事务的增强 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="*" propagation="REQUIRED" read-only="false"/>
			<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
		</tx:attributes>
	</tx:advice>
</beans>

  • 连接池配置文件:dbconfig.properties,大家根据自己数据库的库名和用域名及密码配置,我的如下:
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/luofc
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=root
  • 配置springMVC
    • 配置视图解析器时要注意,使用jsp页面和html页面的配置有很大区别,我把两种配置都写出来了,大家可以根据自己的需要配置(我使用的是html页面,jsp页面的配置我注释掉了)
    • 另外,此配置文件的位置需要注意;它不能放在resources中,而需要放在WEB-INF下,与web.xml在同一目录下。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc 
						http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
						http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/context 
						http://www.springframework.org/schema/context/spring-context-4.3.xsd">
  
	<!-- springMVC配置 -->
	<context:component-scan base-package="com.luofc" use-default-filters="false">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	<!-- 配置html视图解析器 -->
	<bean id="freemarkerConfiguration"
		  class="org.springframework.beans.factory.config.PropertiesFactoryBean">
		<property name="location" value="classpath:freemarker.properties" />
	</bean>

	<bean id="freemarkerConfig"
		  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="freemarkerSettings" ref="freemarkerConfiguration"/>
		<property name="templateLoaderPath" value="/WEB-INF/views/"/>
	</bean>
	<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<property name="suffix" value=".html"/>
		<property name="order" value="0"/>
		<property name="contentType" value="text/html;charset=UTF-8"/>
	</bean>
	
	<!-- 配置JSP视图解析器
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"/>
		<property name="suffix" value=".jsp"/>
		<property name="order" value="1"/>
	</bean>-->

	<!--配置文件上传解析器-->
	<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="defaultEncoding">
			<value>UTF-8</value>
		</property>
		<property name="maxUploadSize">
			<value>32505856</value><!-- 上传文件大小限制为31M,31*1024*1024 -->
		</property>
		<property name="maxInMemorySize">
			<value>4096</value>
		</property>
	</bean>
	
	<!-- 将springMVC不能处理的请求交给tomcat -->
	<mvc:default-servlet-handler/>
	
	<!-- 支持springMVC高级应用,如JSR303校验、快捷ajax -->
	<mvc:annotation-driven/>
	
	<!-- 配置springMvc拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->   
            <mvc:mapping path="/**" />     
            <!-- 不需要拦截的地址 --> 
            <!-- <mvc:exclude-mapping path="/" />           
            <mvc:exclude-mapping path="/timeout" />            
            <mvc:exclude-mapping path="/template/**" /> -->
            <mvc:exclude-mapping path="/login" />
            <mvc:exclude-mapping path="/static/**" />
            <mvc:exclude-mapping path="/bin/**" />
            <mvc:exclude-mapping path="/lib/**" />
            <mvc:exclude-mapping path="/temp/**" />
            <bean class="com.jiafu.article.utils.loginInterceptor"/>
		</mvc:interceptor>
	</mvc:interceptors>
</beans>
  • 配置Mybatis
<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
  
<configuration>
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
	
	<typeAliases>
		<package name="com.luofc.article.bean"/>
	</typeAliases>
	
	<plugins>
		<plugin interceptor="com.github.pagehelper.PageInterceptor">
			<!-- 分页合理化参数配置,该配置用于解决后期导航条页数显示出现负数的bug -->
			<property name="reasonable" value="true"/>
		</plugin>
	</plugins>
</configuration>

二、使用Mybatis逆向工程生成基础类

创建基础类

  • 在第一篇中说到因为想偷个懒,用的是mybatis的逆向生成实体类、Dao层接口和对应mapper,所以第一步就是先创建数据库,数据库结构如下:
    • article表
      此表为原有表,用于在网站展现
    • article_1表
      此表为通过审核带发布上线的文章
    • article_2表
      此表格为待审核文章
    • user表
      在这里插入图片描述
  • 配置Mybatis逆向工程
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<!-- Mybatis逆向工程的配置文件 -->
<generatorConfiguration>

    <context id="DB2Tables" targetRuntime="MyBatis3">

        <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!-- 数据库连接 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/hztyhz"
                        userId="root"
                        password="root">
        </jdbcConnection>

        <javaTypeResolver >
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- 指定javabean生成的位置 -->
        <javaModelGenerator targetPackage="com.jiafu.article.bean" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!-- 指定sql映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="mapper"  targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!-- 指定Dao接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.jiafu.article.dao" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!-- 指定数据库中每一个表的生成策略;tableName后写需要读取的表名,domainObjectName后写生成的类名-->
        <table tableName="user" domainObjectName="User" ></table>
        <table tableName="article" domainObjectName="Article" ></table>
        <table tableName="article_1" domainObjectName="ArticleFa" ></table>
		<table tableName="article_2" domainObjectName="ArticleWei" ></table>
    </context>
</generatorConfiguration>
  • Mybatis逆向工程运行主程序
package com.luofc.article.test;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author:luoFc
 * @date:2019/10/22-18:55
 * @emal:523232622@qq.com
 * @Description:(运行Mybatis逆向工程的方法)
 */
public class MBGRun {

    public static void main(String[] args) throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("./src/main/resources/MBG.xml"); //指定逆向工程配置文件路径
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
}

直接运行main方法后可自动生成实体类、Dao层接口和mapper。

三、编写service层

  • UserService
package com.luofc.article.service;

import com.luofc.article.bean.User;
import com.luofc.article.dao.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author:luoFc
 * @date:2019/10/22-19:28
 * @emal:523232622@qq.com
 * @Description:(用户管理的业务层)
 */

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    //通过用户名查找一个用户(用于登陆查询)
    public User findByUserName(String username) {

        return userMapper.selectByName(username);

    }

    //查询所有用户(用于后期用户管理功能)
    public List<User> findAllUser(){

        return userMapper.selectByExample(null);
    }

    //添加用户(用于后期用户管理功能)
    public void insertUser(User user){

        userMapper.insert(user);
    }

    //通过ID删除用户(用于后期用户管理功能)
    public void deleteUser(Integer id){
        userMapper.deleteByPrimaryKey(id);
    }
}
  • ArticleService
  • MyBatis逆向工程生成的Dao层接口和mapper有一定的局限性,通过作者名查询文章这一方法并没有相关Dao层和mapper支持,所以我们后续还要完善这部分;
package com.luofc.article.service;

import com.luofc.article.bean.Article;
import com.luofc.article.bean.ArticleExample;
import com.luofc.article.dao.ArticleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author:luoFc
 * @date:2019/10/22-19:27
 * @emal:523232622@qq.com
 * @Description:(文章处理的业务层)
 */

@Service
public class ArticleService {

    //自动装配文章的Mapper
    @Autowired
    ArticleMapper articleMapper;

    @Autowired
    ArticleExample articleExample;

    //保存文章
    public boolean addArticle(Article article) {
        Integer num = articleMapper.insertSelective(article);

        if (num == 0){
            return false;
        }
        return true;
    }

    //通过ID删除一篇文章
    public boolean deleteArticleById(Integer id) {
        Integer num = articleMapper.deleteByPrimaryKey(id);

        if (num == 0){
            return false;
        }
        return true;
    }

    //查询所有文章
    public List<Article> getAllArticle() {
        articleExample.setOrderByClause("id DESC");

        return articleMapper.selectByExample(articleExample);
    }

    //通过作者查询文章(用于对不同的写作用户进行分类展示)
    public List<Article> getArticleByZuozhe(String zuozhe){

        if (zuozhe != null){
            List<Article> list = articleMapper.selectByZuozhe(zuozhe);
            return list;
        }

        return null;
    }

    //通过id查询已发布文章
    public Article getArticleById(Integer id){
        return articleMapper.selectByPrimaryKey(id);
    }
}

  • ArticleFaService
  • 同样根据需要,通过作者名查询待发布文章这一方法也没有Dao层和mapper支持,后面一起完善;
package com.luofc.article.service;

import com.luofc.article.bean.ArticleFa;
import com.luofc.article.dao.ArticleFaMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author:luoFc
 * @date:2019/10/24-18:52
 * @emal:523232622@qq.com
 * @Description:(待发布文章的业务层)
 */

@Service
public class ArticleFaService {

    @Autowired
    ArticleFaMapper articleFaMapper;

    //增加一篇待发布文章
    public boolean addArticleFa(ArticleFa articleFa){
        Integer i = articleFaMapper.insert(articleFa);

        if (i == 0){
            return false;
        }
        return true;
    }

    //根据id删除待发布文章
    public boolean deleteArticleFaById(Integer fid){
        Integer i = articleFaMapper.deleteByPrimaryKey(fid);

        if (i == 0){
            return false;
        }

        return true;
    }

    //根据主键修改一篇未发布文章
    public boolean updateArticleFaById(ArticleFa articleFa){
        Integer i = articleFaMapper.updateByPrimaryKeySelective(articleFa);

        if (i == 0){
            return false;
        }

        return true;
    }

    //查询所有的待发布文章
    public List<ArticleFa> getAllArticleFas(){

        return articleFaMapper.selectByExample(null);
    }

	//根据作者名查询所有待发布文章
	public List<ArticleFa> getArticleFasByZuozhew(String zuozhe){
        if (zuozhe != null){
            return articleFaMapper.selectByZuozhe(zuozhe);
        }
        return null;
    }

    //根据id查询一篇待发布文章
    public ArticleFa getArticleFaById(Integer fid){

        return articleFaMapper.selectByPrimaryKey(fid);
    }
}

  • ArticleWeiService
  • 同样根据需要,通过作者名查询未审核文章这一方法也没有Dao层和mapper支持,后面一起完善;
package com.luofc.article.service;

import com.luofc.article.bean.ArticleWei;
import com.luofc.article.dao.ArticleWeiMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author:luoFc
 * @date:2019/10/23-16:49
 * @emal:523232622@qq.com
 * @Description:(未审核文章的业务层)
 */

@Service
public class ArticleWeiService {

    @Autowired
    ArticleWeiMapper articleWeiMapper;

    //增加一篇未审核文章
    public boolean addArticleWei(ArticleWei articleWei){
        Integer i = articleWeiMapper.insertSelective(articleWei);

        if (i == 0){
            return false;
        }

        return true;
    }

    //根据id删除未审核文章
    public boolean deleteArticleWeiById(Integer wid){
        Integer i = articleWeiMapper.deleteByPrimaryKey(wid);

        if (i == 0){
            return false;
        }

        return true;
    }

    //根据主键更新未审核文章
    public boolean updateArticleWeiById(ArticleWei articleWei){
        int i = articleWeiMapper.updateByPrimaryKeySelective(articleWei);

        if (i == 0){
            return false;
        }
        return true;
    }

    //查询所有未审核文章
    public List<ArticleWei> getAllArticleWeis(){
        return articleWeiMapper.selectByExample(null);
    }

    //通过作者查询所有未审核文章
    public List<ArticleWei> getArticleWeisByZuozhew(String zuozhe){
        if (zuozhe != null){
            return articleWeiMapper.selectByZuozhe(zuozhe);
        }
        return null;
    }

    //通过id查询未审核文章
    public ArticleWei getArticleWeiById(Integer wid){

        return articleWeiMapper.selectByPrimaryKey(wid);
    }
}

四、根据需求完善逆向工程生成的Dao层接口、mapper

  • 在Dao层ArticleMapper接口中添加:
//基于mybatis逆向工程新添加,用于查找不同写作用户的文章
    List<Article> selectByZuozhe(String zuozhe);
  • 在resource文件夹下mapper包中的ArticleMapper里面添加:
<!--用于查询不同写作用户的文章,注意jdbcType=VARCHAR中的类型为mysql数据库中的类型-->
  <select id="selectByZuozhe" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
    select
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from article
    where zuozhe = #{zuozhe,jdbcType=VARCHAR}
  </select>
  • 在Dao层接口ArticleFaMapper中添加:
//luoFc增加根据用户查询待发布文章
    List<ArticleFa> selectByZuozhe(String zuozhe);
  • 在resource文件夹下mapper包中的ArticleFa里面添加:
<!--根据用户查询待发布文章-->
  <select id="selectByZuozhe" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
    select
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from article_1
    where fzuozhe = #{fzuozhe,jdbcType=VARCHAR}
  </select>
  • 在Dao层接口ArticleWeiMapper中添加:
//luoFc添加,用于通过作者查询未审核文章
    List<ArticleWei> selectByZuozhe(String zuozhe);
  • 在resource文件夹下mapper包中的ArticleWei里面添加:
<select id="selectByZuozhe" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
    select
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from aritcle_2
    where wzuozhe = #{wzuozhe,jdbcType=VARCHAR}
  </select>

到目前为止,所有的业务逻辑和后端的基础部分已经完成,接下来就是导入前端页面和编写各种controller了。如果有任何疑问可以加我QQ或者给我写邮件。
PS:如果是新手,我建议在整合spring+springMVC+Mybatis的时候应该分步测试,详细教程可以去网上找找,我自己看的是heima的整合教程。对新人来说多了解各个框架的基础和底层实现原理非常有用。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

琪琪的饭团子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值