CRM客户关系管理系统开发第二讲——实现用户的注册和登录功能

实现用户注册功能

创建用户表

首先创建一个数据库(例如crm),并在该数据库下新建一张用户表,笔者这里使用的数据库是MySQL。

create database crm;
use crm;

CREATE TABLE `sys_user` (
	`user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
	`user_code` varchar(32) NOT NULL COMMENT '用户账号',
	`user_name` varchar(64) NOT NULL COMMENT '用户名称',
	`user_password` varchar(32) NOT NULL COMMENT '用户密码',
	`user_state` char(1) NOT NULL COMMENT '1:正常,0:暂停',
	PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

创建User实体类及其对应的映射配置文件

在com.meimeixia.crm.domain包下创建一个User实体类及其相对应的映射配置文件。

  • User实体类

    package com.meimeixia.crm.domain;
    
    /**
     * 用户的实体
     * @author liayun
     *
     */
    public class User {
    	
    	private Long user_id;
    	private String user_code;//用户名
    	private String user_name;//真实姓名
    	private String user_password;
    	private String user_state;
    	public Long getUser_id() {
    		return user_id;
    	}
    	public void setUser_id(Long user_id) {
    		this.user_id = user_id;
    	}
    	public String getUser_code() {
    		return user_code;
    	}
    	public void setUser_code(String user_code) {
    		this.user_code = user_code;
    	}
    	public String getUser_name() {
    		return user_name;
    	}
    	public void setUser_name(String user_name) {
    		this.user_name = user_name;
    	}
    	public String getUser_password() {
    		return user_password;
    	}
    	public void setUser_password(String user_password) {
    		this.user_password = user_password;
    	}
    	public String getUser_state() {
    		return user_state;
    	}
    	public void setUser_state(String user_state) {
    		this.user_state = user_state;
    	}
    	
    }
    
  • User.hbm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        
    <hibernate-mapping>
    	<class name="com.meimeixia.crm.domain.User" table="sys_user">
    		<id name="user_id" column="user_id">
    			<generator class="native"></generator>
    		</id>
    		
    		<property name="user_code" column="user_code" />
    		<property name="user_name" column="user_name" />
    		<property name="user_password" column="user_password" />
    		<property name="user_state" column="user_state" />
    	</class>
    </hibernate-mapping>
    

编写web层

首先,在com.meimeixia.crm.web.action包下创建一个UserAction类,并在里面写一个用户注册的方法。

package com.meimeixia.crm.web.action;

import com.meimeixia.crm.domain.User;
import com.meimeixia.crm.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 用户管理的Action类
 * @author liayun
 *
 */
public class UserAction extends ActionSupport implements ModelDriven<User> {
	//模型驱动使用的对象
	private User user = new User();

	@Override
	public User getModel() {
		return user;
	}
	
	//注入service
	private UserService userService;
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	/*
	 * 用户注册的方法(regist)
	 */
	public String regist() {
		userService.regist(user);
		return LOGIN;
	}
	
}

在UserAction类中,我们注入了service。然后,将UserAction交给Spring来管理。

<?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.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">
	
	<!-- 引入外部属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 配置C3P0连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
	<!-- 配置UserAction -->
	<bean id="userAction" class="com.meimeixia.crm.web.action.UserAction" scope="prototype">
		<property name="userService" ref="userService"></property>
	</bean>
	
</beans>

配置UserAction时,需要注意两个地方,一是该Action需要配置为多例的,二是需要自己手动注入service。
最后,我们还要记得在Struts2配置文件中(即struts.xml)对UserAction进行配置,就像下面这样:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<!-- 配置Strust2的一些常量 -->
	<constant name="struts.action.extension" value="action" />
	
	<package name="crm" extends="struts-default" namespace="/">
		<action name="user_*" class="userAction" method="{1}">
			<result name="login">/login.jsp</result>
		</action>
	</package>
	
</struts>

编写service层

首先,在com.meimeixia.crm.service包下创建一个UserService接口,在该接口中添加一个用户注册的方法声明,如下:

package com.meimeixia.crm.service;

import com.meimeixia.crm.domain.User;

/**
 * 用户管理的业务层的接口
 * @author liayun
 *
 */
public interface UserService {

	void regist(User user);

}

然后,在com.meimeixia.crm.service.impl包下编写以上接口的一个实现类——UserServiceImpl.java。

package com.meimeixia.crm.service.impl;

import com.meimeixia.crm.dao.UserDao;
import com.meimeixia.crm.domain.User;
import com.meimeixia.crm.service.UserService;
import com.meimeixia.crm.utils.MD5Utils;

/**
 * 用户管理的业务层的实现类
 * @author liayun
 *
 */
public class UserServiceImpl implements UserService {
	
	//注入dao
	private UserDao userDao;
	
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	//业务层注册用户的方法
	@Override
	public void regist(User user) {
		//对密码进行加密的处理
		user.setUser_password(MD5Utils.md5(user.getUser_password()));
		user.setUser_state("1");//1代表正常状态
		//调用dao
		userDao.save(user);
	}
	
}

在以上实现类中,我们注入了dao,并且对密码进行了简单的加密处理。其中,MD5Utils工具类的具体代码如下:

package com.meimeixia.crm.utils;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 用的是比较简单的一个加密算法(md5加密算法)
 * @author liayun
 *
 */
public class MD5Utils {
	/**
	 * 使用md5的算法进行加密
	 */
	public static String md5(String plainText) {
		byte[] secretBytes = null;
		try {
			secretBytes = MessageDigest.getInstance("md5").digest(
					plainText.getBytes());
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException("没有md5这个算法!");
		}
		String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
		// 如果生成数字未满32位,需要前面补0
		for (int i = 0; i < 32 - md5code.length(); i++) {
			md5code = "0" + md5code;
		}
		return md5code;
	}

	public static void main(String[] args) {
		System.out.println(md5("123"));
	}

}

像这样的工具类,公司一般都会提供的,我们直接拿过来用就可以了,但有时候,我们难免要自己去编写一些工具类。
最后,将以上实现类交给Spring来管理。

<?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.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">
	
	<!-- 引入外部属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 配置C3P0连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
	<!-- 配置UserAction -->
	<bean id="userAction" class="com.meimeixia.crm.web.action.UserAction" scope="prototype">
		<property name="userService" ref="userService"></property>
	</bean>
	<!-- 配置service -->
	<bean id="userService" class="com.meimeixia.crm.service.impl.UserServiceImpl">
		<property name="userDao" ref="userDao"></property>
	</bean>
	
</beans>

编写dao层

Spring整合Hibernate框架的时候,虽然可以不用创建Hibernate的核心配置文件,但还是要把Hibernate核心配置文件中的基本信息配置和映射文件的引入放到Spring配置文件中进行配置。所以,这时Spring配置文件的内容就应修改为下面这个样子。

<?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.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">

	<!-- Spring整合Hibernate~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
	<!-- 引入Hibernate的配置信息。Spring通过加载这些Hibernate的配置信息,帮我们生成SessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<!-- 注入连接池 -->
		<property name="dataSource" ref="dataSource" />
		<!-- 配置Hibernate的相关属性 -->
		<property name="hibernateProperties">
			<props>
				<!-- 配置Hibernate的方言 -->
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<!-- 打印sql语句 -->
				<prop key="hibernate.show_sql">true</prop>
				<!-- 格式化sql语句 -->
				<prop key="hibernate.format_sql">true</prop>
				<!-- 自动创建表 -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		
		<!-- 引入映射文件 -->
		<property name="mappingResources">
			<list>
				<value>com/meimeixia/crm/domain/User.hbm.xml</value>
			</list>
		</property>
	</bean>
	
	<!-- 引入外部属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 配置C3P0连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
	<!-- 配置UserAction -->
	<bean id="userAction" class="com.meimeixia.crm.web.action.UserAction" scope="prototype">
		<property name="userService" ref="userService"></property>
	</bean>
	<!-- 配置service -->
	<bean id="userService" class="com.meimeixia.crm.service.impl.UserServiceImpl">
		<property name="userDao" ref="userDao"></property>
	</bean>
	
</beans>

然后,在com.meimeixia.crm.dao包下创建一个UserDao接口,并在该接口中添加一个用户注册的方法声明,如下:

package com.meimeixia.crm.dao;

import com.meimeixia.crm.domain.User;

/**
 * 用户管理的dao的接口
 * @author liayun
 *
 */
public interface UserDao {

	void save(User user);

}

接着,在com.meimeixia.crm.dao.impl包下编写以上接口的一个实现类(UserDaoImpl.java)。

package com.meimeixia.crm.dao.impl;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.meimeixia.crm.dao.UserDao;
import com.meimeixia.crm.domain.User;

/**
 * 用户管理的dao的实现类
 * @author liayun
 *
 */
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

	//dao中保存用户的方法
	@Override
	public void save(User user) {
		this.getHibernateTemplate().save(user);
	}

}

从以上UserDaoImpl实现类的代码中,我们可以看出它继承了HibernateDaoSupport类,继承该类有什么好处呢?查看该类的源代码,可以发现在它的源代码里面,提供了一个setSessionFactory(SessionFactory sessionFactory)方法,如果你给它注入了一个SessionFactory对象的话,那么它便会使用这个SessionFactory对象帮你创建一个Hibernate模板类的对象。所以,在将以上UserDaoImpl实现类交给Spring来管理时,应该使用property标签注入sessionFactory属性。

<?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.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">

	<!-- Spring整合Hibernate~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
	<!-- 引入Hibernate的配置信息。Spring通过加载这些Hibernate的配置信息,帮我们生成SessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<!-- 注入连接池 -->
		<property name="dataSource" ref="dataSource" />
		<!-- 配置Hibernate的相关属性 -->
		<property name="hibernateProperties">
			<props>
				<!-- 配置Hibernate的方言 -->
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<!-- 打印sql语句 -->
				<prop key="hibernate.show_sql">true</prop>
				<!-- 格式化sql语句 -->
				<prop key="hibernate.format_sql">true</prop>
				<!-- 自动创建表 -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		
		<!-- 引入映射文件 -->
		<property name="mappingResources">
			<list>
				<value>com/meimeixia/crm/domain/User.hbm.xml</value>
			</list>
		</property>
	</bean>
	
	<!-- 引入外部属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 配置C3P0连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
	<!-- 配置UserAction -->
	<bean id="userAction" class="com.meimeixia.crm.web.action.UserAction" scope="prototype">
		<property name="userService" ref="userService"></property>
	</bean>
	<!-- 配置service -->
	<bean id="userService" class="com.meimeixia.crm.service.impl.UserServiceImpl">
		<property name="userDao" ref="userDao"></property>
	</bean>
	<!-- 配置dao -->
	<bean id="userDao" class="com.meimeixia.crm.dao.impl.UserDaoImpl">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	
</beans>

配置Spring的事务管理

这里,我们会使用Spring基于注解方式的声明式事务管理,因为写起来更加简单。

  • 第一步,配置事务管理器。
    在这里插入图片描述
  • 第二步,开启事务注解。
    在这里插入图片描述
  • 第三步,在业务层中的实现类(UserDaoImpl)上添加@Transactional注解。
    在这里插入图片描述

至此,用户注册功能就算是开发好了,接下来,便来测试开发好的用户注册功能。

测试用户注册功能

发布我们的项目到Tomcat服务器并启动,然后访问该项目的登录页面,点击注册按钮,跳转到用户注册页面,紧接着填写完相关用户注册信息,点击注册系统按钮即可完成用户的注册。
在这里插入图片描述

实现用户登录功能

在登录页面(login.jsp)中修改提交路径

在这里插入图片描述

编写web层

首先,在UserAction类里面编写一个用户登录的方法。

package com.meimeixia.crm.web.action;

import com.meimeixia.crm.domain.User;
import com.meimeixia.crm.service.UserService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 用户管理的Action类
 * @author liayun
 *
 */
public class UserAction extends ActionSupport implements ModelDriven<User> {
	//模型驱动使用的对象
	private User user = new User();

	@Override
	public User getModel() {
		return user;
	}
	
	//注入Service
	private UserService userService;
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	/*
	 * 用户注册的方法(regist)
	 */
	public String regist() {
		userService.regist(user);
		return LOGIN;
	}
	
	/*
	 * 用户登录的方法(login)
	 */
	public String login() {
		//调用业务层查询用户
		User existUser = userService.login(user);
		if (existUser == null) {
			//登录失败
			//添加错误信息
			this.addActionError("用户名或密码错误!");
			return LOGIN;
		} else {
			//登录成功
//			ServletActionContext.getRequest().getSession().setAttribute("existUser", existUser);
			//或者写成下面这样:
			ActionContext.getContext().getSession().put("existUser", existUser);
			return SUCCESS;
		}
	}
	
}

然后,我们还得在Struts2配置文件中(即struts.xml)对UserAction进行如下的配置,即配置页面的跳转:当用户登录成功之后,重定向到项目的首页,而当用户登录失败后,还是跳转回登录页面。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<!-- 配置Strust2的一些常量 -->
	<constant name="struts.action.extension" value="action" />
	
	<package name="crm" extends="struts-default" namespace="/">
		<action name="user_*" class="userAction" method="{1}">
			<result name="login">/login.jsp</result>
			<result name="success" type="redirect">/index.jsp</result>
		</action>
	</package>
	
</struts>

编写service层

首先,在UserService接口中添加一个用户登录的方法声明,如下:

package com.meimeixia.crm.service;

import com.meimeixia.crm.domain.User;

/**
 * 用户管理的业务层的接口
 * @author liayun
 *
 */
public interface UserService {

	void regist(User user);

	User login(User user);

}

然后,在以上接口的一个实现类(UserServiceImpl.java)中去实现用户登录的方法。

package com.meimeixia.crm.service.impl;

import org.springframework.transaction.annotation.Transactional;

import com.meimeixia.crm.dao.UserDao;
import com.meimeixia.crm.domain.User;
import com.meimeixia.crm.service.UserService;
import com.meimeixia.crm.utils.MD5Utils;

/**
 * 用户管理的业务层的实现类
 * @author liayun
 *
 */
@Transactional
public class UserServiceImpl implements UserService {
	
	//注入dao
	private UserDao userDao;
	
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	//业务层注册用户的方法
	@Override
	public void regist(User user) {
		//对密码进行加密的处理
		user.setUser_password(MD5Utils.md5(user.getUser_password()));
		user.setUser_state("1");//1代表正常状态
		//调用dao
		userDao.save(user);
	}

	//业务层用户登录的方法
	@Override
	public User login(User user) {
		user.setUser_password(MD5Utils.md5(user.getUser_password()));
		//调用dao
		return userDao.login(user);
	}

}

编写dao层

首先,在UserDao接口中添加一个用户登录的方法声明,如下:

package com.meimeixia.crm.dao;

import com.meimeixia.crm.domain.User;

/**
 * 用户管理的dao的接口
 * @author liayun
 *
 */
public interface UserDao {

	void save(User user);

	User login(User user);

}

然后,在以上接口的一个实现类(UserDaoImpl.java)中去实现用户登录的方法。

package com.meimeixia.crm.dao.impl;

import java.util.List;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.meimeixia.crm.dao.UserDao;
import com.meimeixia.crm.domain.User;

/**
 * 用户管理的dao的实现类
 * @author liayun
 *
 */
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

	//dao中保存用户的方法
	@Override
	public void save(User user) {
		this.getHibernateTemplate().save(user);
	}

	//dao中根据用户名和密码进行查询的方法
	@Override
	public User login(User user) {
		List<User> list = (List<User>) this.getHibernateTemplate().find("from User where user_code = ? and user_password = ?", 
				user.getUser_code(), user.getUser_password());
		//判断一下
		if (list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

}

在页面中显示数据

用户登录成功之后,在首页显示用户信息

当用户登录成功之后,我们要在首页(也即top.jsp页面)上显示其用户信息。
在这里插入图片描述

用户登录失败之后,在登录页面上显示错误信息

当用户登录失败之后,我们要在登录页面上显示错误信息。
在这里插入图片描述
至此,用户登录的功能,我们就已经实现了,至于测试的话,我就不再这里测试了(偷懒了),反正是好使的!

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李阿昀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值