一个很简单的demo来演示一个账号只能同时被一个人使用(Java实现)

怎么实现同一账号只能在一台设备登录 同一账号只能在一台设备登录实现思路。 注意:登录是在白名单(直接放行的接口)。生成的token携带账号信息。 1.用户每次登录生成token时,将账号当成key,token当成value,以token的过期时间存入redis中。 2.用户访问的时候,在拦截器解析token,获取账号,拿账号去redis中获取value,如果是value的token与当前用户携带过来的token一致就放行。如果不一致,则告诉前端重复登录,让前端清除token,跳转到登录页面。 3.用户在另一台设备登录时,也是存入redis,这 阅读详情

大家在登陆qq的时候,电脑上登陆了qq,如果另一台机器上也登陆该qq账号,那么之前的qq账号会被挤下去。

我们现在用web的方式来做一个非常简单的演示。

先简单的说一下功能吧,

用户只有一个User,这个entity设置成账号为hello,密码world


这样做为了简化不到数据库里面去查用户的账号信息。

首先,我们看一看我们的web.xml


  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2. <web-app xmlns=“http://xmlns.jcp.org/xml/ns/javaee”  
  3.          xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”  
  4.          xsi:schemaLocation=“http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd”  
  5.          version=“3.1”>  
  6.   
  7.     <listener>  
  8.         <listener-class>SessionListener</listener-class>  
  9.     </listener>  
  10. </web-app>  
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <listener>
        <listener-class>SessionListener</listener-class>
    </listener>
</web-app>
web.xml里面就配置了一个HttpSessionListener


类SessionListener的实现如下

  1. import javax.servlet.http.HttpSession;  
  2. import javax.servlet.http.HttpSessionEvent;  
  3. import javax.servlet.http.HttpSessionListener;  
  4. import java.util.HashMap;  
  5.   
  6. /**  
  7.  * Created by HuLuo on 2016/8/20.  
  8.  */  
  9. public class SessionListener implements HttpSessionListener  
  10. {  
  11.     /**  
  12.      * 该HashMap以用户名-HttpSession对象存储一个账号只能被一个人登陆的信息。  
  13.      */  
  14.     public static HashMap<String,HttpSession> sessionMap = new HashMap<String,HttpSession>();  
  15.   
  16.     @Override  
  17.     public void sessionCreated(HttpSessionEvent httpSessionEvent)  
  18.     {  
  19.         HttpSession session = httpSessionEvent.getSession();  
  20.     }  
  21.   
  22.     @Override  
  23.     public void sessionDestroyed(HttpSessionEvent httpSessionEvent)  
  24.     {  
  25.   
  26.         HttpSession session = httpSessionEvent.getSession();  
  27.   
  28.         delSession( session );  
  29.     }  
  30.   
  31.     public static synchronized void delSession(HttpSession session)  
  32.     {  
  33.         if(session != null)  
  34.         {  
  35.   
  36.             // 删除单一登录中记录的变量  
  37.             if(session.getAttribute( “users” ) != null)  
  38.             {  
  39.                 User user = (User) session.getAttribute( “users” );  
  40.                 SessionListener.sessionMap.remove( user.getUsername() );  
  41.             }  
  42.         }  
  43.     }  
  44.   
  45. }  
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.HashMap;

/**
 * Created by HuLuo on 2016/8/20.
 */
public class SessionListener implements HttpSessionListener
{
    /**
     * 该HashMap以用户名-HttpSession对象存储一个账号只能被一个人登陆的信息。
     */
    public static HashMap<String,HttpSession> sessionMap = new HashMap<String,HttpSession>();

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent)
    {
        HttpSession session = httpSessionEvent.getSession();
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent)
    {

        HttpSession session = httpSessionEvent.getSession();

        delSession( session );
    }

    public static synchronized void delSession(HttpSession session)
    {
        if(session != null)
        {

            // 删除单一登录中记录的变量
            if(session.getAttribute( "users" ) != null)
            {
                User user = (User) session.getAttribute( "users" );
                SessionListener.sessionMap.remove( user.getUsername() );
            }
        }
    }

}

public static HashMap<String,HttpSession> sessionMap = new HashMap<String,HttpSession>();

这个HashMap是用来存储用户的登陆信息,一个账户同时只能被一个人使用。


接着是demo的首页面,里面很简单,只有一个超链接,让其访问到 

${pageContext.request.contextPath}/login


这边笔者也是简化的不能再简化了,直接连账户名密码也不用填。直接登陆上。。。。。。

再来我们看LoginServlet.java ——————————>判断这个账号是否被其他人登陆的逻辑判断


代码如下

  1. import javax.servlet.ServletException;  
  2. import javax.servlet.annotation.WebServlet;  
  3. import javax.servlet.http.HttpServlet;  
  4. import javax.servlet.http.HttpServletRequest;  
  5. import javax.servlet.http.HttpServletResponse;  
  6. import javax.servlet.http.HttpSession;  
  7. import java.io.IOException;  
  8.   
  9. /** 
  10.  * Created by HuLuo on 2016/8/20. 
  11.  */  
  12. @WebServlet(urlPatterns = “/login”)  
  13. public class LoginServlet extends HttpServlet  
  14. {  
  15.     @Override  
  16.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException  
  17.     {  
  18.         User user = new User();  
  19.         HttpSession session = req.getSession();  
  20.         /** 
  21.          * 该账号已经被登陆 
  22.          */  
  23.         if(null != SessionListener.sessionMap.get( user.getUsername() ))  
  24.         {  
  25.             /** 
  26.              * 将已经登陆的信息拿掉,将新的用户登录信息放进去 
  27.              */  
  28.             ForceLogoutUtils.forceUserLogout( user.getUsername() );  
  29.   
  30.             SessionListener.sessionMap.put( user.getUsername(), session );  
  31.         }  
  32.         /** 
  33.          * 该账号未被登陆 
  34.          */  
  35.         else  
  36.         {  
  37.             SessionListener.sessionMap.put( user.getUsername(), session );  
  38.         }  
  39.         session.setAttribute( ”users”, user );  
  40.         req.getRequestDispatcher( ”result.jsp” ).forward( req,resp );  
  41.     }  
  42. }  
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * Created by HuLuo on 2016/8/20.
 */
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        User user = new User();
        HttpSession session = req.getSession();
        /**
         * 该账号已经被登陆
         */
        if(null != SessionListener.sessionMap.get( user.getUsername() ))
        {
            /**
             * 将已经登陆的信息拿掉,将新的用户登录信息放进去
             */
            ForceLogoutUtils.forceUserLogout( user.getUsername() );

            SessionListener.sessionMap.put( user.getUsername(), session );
        }
        /**
         * 该账号未被登陆
         */
        else
        {
            SessionListener.sessionMap.put( user.getUsername(), session );
        }
        session.setAttribute( "users", user );
        req.getRequestDispatcher( "result.jsp" ).forward( req,resp );
    }
}

然后我们接着讲ForceLogoutUtils.java

这个类呢是用来,当发现账号已经被人登陆了,就将这个已经登陆上的人的Session从SessionListener.java中的HashMap里给拿到,并且移除在此HashMap中的记录

并将session  invalidate掉。



  1. import javax.servlet.http.HttpSession;  
  2. import java.util.Enumeration;  
  3.   
  4. /**  
  5.  * Created by HuLuo on 2016/8/20.  
  6.  */  
  7. public class ForceLogoutUtils  
  8. {  
  9.     public static void forceUserLogout(String username)  
  10.     {  
  11.         if(SessionListener.sessionMap.get( username ) != null)  
  12.         {  
  13.             HttpSession session = SessionListener.sessionMap.get( username );  
  14.   
  15.             SessionListener.sessionMap.remove( username );  
  16.   
  17.             Enumeration e = session.getAttributeNames();  
  18.   
  19.             while(e.hasMoreElements())  
  20.             {  
  21.                 String sessionName = (String) e.nextElement();  
  22.   
  23.                 session.removeAttribute( sessionName );  
  24.             }  
  25.   
  26.             session.invalidate();  
  27.         }  
  28.     }  
  29. }  
import javax.servlet.http.HttpSession;
import java.util.Enumeration;

/**
 * Created by HuLuo on 2016/8/20.
 */
public class ForceLogoutUtils
{
    public static void forceUserLogout(String username)
    {
        if(SessionListener.sessionMap.get( username ) != null)
        {
            HttpSession session = SessionListener.sessionMap.get( username );

            SessionListener.sessionMap.remove( username );

            Enumeration e = session.getAttributeNames();

            while(e.hasMoreElements())
            {
                String sessionName = (String) e.nextElement();

                session.removeAttribute( sessionName );
            }

            session.invalidate();
        }
    }
}
在LoginServlet.java处理的结果出来之后,跳转到一个result.jsp这个页面


页面内容也是只有一个超链接。检查自己是否被踢下

<%--           以下的超链接用于检验自己登陆的被踢下,被踢下了返回到index.jsp页面        --%>
    <a href="${pageContext.request.contextPath}/check">检验</a>

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2016/8/20
  Time: 11:24
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>


<body>


<%--           以下的超链接用于检验自己登陆的被踢下,被踢下了返回到index.jsp页面        --%>
    <a href="${pageContext.request.contextPath}/check">检验</a>
</body>
</html>


如果被踢下返回到index.jsp页面,如果没有被踢下,就继续留在result.jsp

是否被踢下


最后我们来看CheckServlet.java里面的逻辑判断


  1. import javax.servlet.ServletException;  
  2. import javax.servlet.annotation.WebServlet;  
  3. import javax.servlet.http.HttpServlet;  
  4. import javax.servlet.http.HttpServletRequest;  
  5. import javax.servlet.http.HttpServletResponse;  
  6. import java.io.IOException;  
  7.   
  8. /** 
  9.  * Created by HuLuo on 2016/8/20. 
  10.  */  
  11. @WebServlet(urlPatterns = “/check”)  
  12. public class CheckServlet extends HttpServlet  
  13. {  
  14.     @Override  
  15.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException  
  16.     {  
  17.         User user = (User) req.getSession().getAttribute( ”users” );  
  18.   
  19.         if(null == user)  
  20.         {  
  21.   
  22.             resp.sendRedirect( ”index.jsp” );  
  23.         }  
  24.         else  
  25.         {  
  26.             resp.sendRedirect( ”result.jsp” );  
  27.         }  
  28.   
  29.     }  
  30. }  
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by HuLuo on 2016/8/20.
 */
@WebServlet(urlPatterns = "/check")
public class CheckServlet extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        User user = (User) req.getSession().getAttribute( "users" );

        if(null == user)
        {

            resp.sendRedirect( "index.jsp" );
        }
        else
        {
            resp.sendRedirect( "result.jsp" );
        }

    }
}

判断从Session中拿到,是否有users信息,如果有继续留在result.jsp页面,如果没有重定向到index.jsp


Eclipse下的Springboot 整合Mybatis,并实现登录demo 这里Eclipse下的Springboot 整合Mybatis,并实现登录demodemo实现思路后端项目搭建前置条件搭建数据库开始springboot项目搭建修改配置文件创建demo包下的类mapper层:service层:controller层:entity层:在resources下的mapper包下创建UserMapper.xml编写主程序入口Api测试文件解释层级解释UserMapper.java 解释UserMapper.xml 解释UserService.java 解释UserServiceim 阅读详情

相关推荐

Java接入PayPal教程,Spring boot Demo源码,企业账号注册,支付,回调,退款全流程,最新PayPal SDK

一、环境准备 1. 注册 2.创建沙箱测试账号 3. Client ID及Secret 二、核心代码 1. 官方github sdk 2. pom引用 3. 代码讲解 4. 支付代码demo流程 5. 退款 6. 支付回调 一、环境准备 1. 注册 注册:创建PayPal账户 - PayPal中国https://www.paypal.com/c2/webapps/mpp/account-selection1.1 选择企业账户 1.2开发者中心: ...

hhhlkkk的博客 4337

异步简单实现一人一单

简单实现一下异步线程执行同一业务,提高访问效率

ws_please的博客 588

31、Java——JDBC实现账号密码登录

JDBC实现账号密码登录

不迁怒,不贰过。小知识,大智慧。 4178

使用java 如何保证每次添加数据的时候 只有一个用户操作

Java提供了一些同步工具来保证线程安全。其中一种常用的方法是使用synchronized关键字。可以在方法上使用它,也可以在代码块上使用它。 例如,在一个类中,如果有一个方法需要保证只有一个线程可以访问它,可以这样写: public class MyClass { public synchronized void addData() { // code to add da...

weixin_42576804的博客 380

Java Web 实现QQ登录功能一个帐号同一时间只能一个人登录

对于一个帐号在同一时间只能一个人登录,下文给大家介绍的非常详细,对java web qq 登录功能感兴趣的朋友一起看看吧

第五章 PCIe介绍 5.1-5.7

为什么SSD要用PCIe接口?因为它快,比SATA快。通道,PCIe最多可以有32个通道。两个设备之间的PCIe连接,叫做一个Link。如下图,设备A和设备B是个双向连接,两个PCIe设备之间,有专门的发送和接收通道,数据可以同时往两个方向传输,PCIe Spec称这种工作模式为,可以理解为。和PCIe一样,SATA有独立的发送和接收通道。但与PCIe工作模式不一样,同一时间,SATA只有一条通道可以进行数据传输。这种工作模式称为。与SATA单通道不同,PCIe连接可以通过增加通道数扩展带宽。

fengbaobaola的博客 2968

Java IO ——实例操作:单人信息管理程序

数据输入类: import java.io.* ; import java.util.* ; import java.text.* ; public class InputData{ private BufferedReader buf = null ; public In

韩世雷 程序员专栏 1082

TCNOpen实现TRDP通信协议(源码编译运行测试)

概述 本文介绍了通过TCNOpen开源源码实现TRDP通信,包括源码下载,开发环境搭建,编译运行,测试。 Linux环境下编译运行TRDP (一) 下载CANOpen源码。 下载地址:https://sourceforge.net/p/tcnopen/trdp/HEAD/tree/ (二) 源码编译 下载源码解压过后,在根目录文件readme-makefile.txt有介绍源码的配置和编译方法。 在trdp/config目录下可以看到包含在linux环境下的编译配置文件LINUX_config;执行”m

fengweibo112的博客 9630

idea,datagrip正版账号,如有需要欢迎咨询

idea,datagrip正版账号,如有需要欢迎咨询

realmname的专栏 1869

无人机精准降落辅助系统核心技术解析

接近地面时(<10米)切换至基于图像的视觉伺服(IBVS),依据图像特征点偏移(如靶标图案、LED标记)微调姿态,消除位置累积误差。通过SRUKF(平方根无迹卡尔曼滤波) 算法融合三类数据,输出6自由度位姿估计(精度达厘米级),抑制单一传感器噪声。权值根据信噪比动态调整。模型预测控制(MPC):针对斜坡降落,构建包含平台倾角、风扰的动力学方程,滚动求解最优油门序列。动态照明适配:针对夜间或低光照场景,系统向降落平台发送亮度调节指令,如增强红外信标强度或调整可见光LED阵列,确保特征识别鲁棒性。

YUNZHUO666的博客 1695

Halcon工业相机开发全流程:从SDK配置到实时图像采集(C++版)

本文详细介绍了使用C++进行Halcon工业相机开发的完整流程,从SDK配置到实时图像采集的实现。涵盖环境搭建、设备初始化、回调机制、参数控制等关键环节,并提供异常处理和实战案例,帮助开发者快速掌握工业视觉系统的开发技巧。

weixin_33728268的博客 512

java实现只能有一个相同用户登录的功能

需求:使用相同用户名登录系统,确保同名用户登录顶掉之前用户登录或者返回登录的功能。 实现效果图: java实现: 首先 1.web.xml中配置监听器&lt;listener&gt;&lt;listener-class&gt;com.bes.enterprise.console.viewer.system.action.userHttpListener&lt;/listener-class...

qq_35076190的博客 3825

AI辅助Android开发:从传统到智能化的技术演进

AI辅助开发的核心在于利用算法模型自动化或优化传统任务。在Android开发中,AI可应用于需求分析、设计、编码、测试和维护各阶段。需求分析:AI工具如基于NLP的模型(例如GPT系列)可解析用户需求文档,自动生成用户故事和原型设计。假设产品需求为“开发一个航班查询应用”,AI能提取关键词,输出UML图或伪代码。代码生成:使用AI代码助手(如GitHub Copilot),工程师输入自然语言描述,AI生成Java/Kotlin代码片段。

郑伟强dev的专栏 137

java简单演示程序_一个很简单的demo来演示一个账号只能同时被一个人使用(Java实现)...

大家在登陆qq的时候,电脑上登陆了qq,如果另一台机器上也登陆该qq账号,那么之前的qq账号会被挤下去。我们现在用web的方式来做一个非常简单的演示。先简单的说一下功能吧,用户只有一个User,这个entity设置成账号为hello,密码world 这样做为了简化不到数据库里面去查用户的账号信息。首先,我们看一看我们的web.xmlxmlns:xsi="http://www.w3.org/2001...

weixin_34378126的博客 537

朱长江《偏微分方程简明教程》答案第一章部分

偏微分方程简明教程第一章习题1.1 第一章 习题1.1 1、指出下列方程的阶,并判断它是线性的还是非线性的。如果是线性的,说明它还是其次的: (1)ut−(uxx+uyy)+1=0;(2)ut−uxx+xu=0;(3)ut−uxxt+uux=0;(4)ux2+uuy=0;(5)utt−uxx+t2+x2=0;(6)ux+eyuy=0;(7)ut+uxxxx+1+u=0;(8)ux(1+ux2)−12+uy(1+uy2)−12=0;(9)∂4u∂x4+2∂4u∂x2∂y2+∂4u∂y4=0;(10)∂3u∂x

ymengm的博客 6760

Python爬虫实战:基于Scrapy与Playwright高效爬取人民网新闻数据

本文将详细介绍如何使用Python最新技术栈(Scrapy框架结合Playwright浏览器自动化工具)高效爬取人民网新闻数据。文章包含完整项目搭建、反反爬策略、数据解析存储以及性能优化等核心内容,提供可直接运行的代码示例,适合中高级Python开发者学习现代网络爬虫开发技术。python# 去除特殊空白字符。

2201_76125261的博客 1118

java实现简单的银行账号系统

任务:编写一个银行用户现金业务办理程序,模拟新用户到银行办理业务,可以模拟出银行对用户到来的欢迎动作,对用户离开的提醒动作以及“存款”、“取款”、“查询余额”和“显示账号信息”等功能。编写一测试类,创建两个不同的账户类的对象,并分别完成存款、取款、查询余额、显示账号等操作。 //定义People类,作为父类,属性为name和money class People{ public String na...

胖大xian 3408

华为od 面试八股文_Python语言_01_含答案

华为od 面试八股文_Python语言_01_含答案

MISAYAONE的博客 9092

同一个账号,同一时刻,只能使用一个IP.登陆。

同一个账号,同一时刻,只能使用一个IP.登陆。 分享一些本人在开发项目中得到的一点心得。 首先,大家在登录账号的时候如果在其他地方已经登录该账号,那么会遇到该账户已登录这种情况,在下写了一个非常简单的demo来实现这个功能,这就给大家做一个非常简单的演示。 首先说下大概流程: 每次登录将当前的session,与登录的邮箱(账号),放到一个map容器中,即:Map &lt; Stri...

Haust_S_J_F的博客 4041

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

java jsp demo_JSP简单示例

前提假设你已经搭建好环境 Java开发工具(JDK) 以及 Web服务器:Tomcat尚未搭建环境 请查看 该文章 自行搭建 JSP 配置环境问题首先我们创建一个 Dynamic Web Project, 项目名为 JSPDemo1.png然后在WebContent 鼠标右键 新建一个demo2.jsp 文件2.jpg代码如下pageEncoding="UTF-8"%>Insert titl...

weixin_28759829的博客 1066

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java 实现一个用户的登陆认证

初略的功能: 需要一个小数据库(存储用户真实的账号和密码) 用户输入自己登录的账号和密码 提示用户输入账号和密码 进行校验 import java.util.Scanner; public class Demo { private String[][] userBox = {{"zgh","666"},{"xy","111"},{"hq","222"},{"lcw","000"}};...

Zhangguohao666的博客 5035

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java使用mongodb实现增删改查的一个小demo案例

1、MongoDB的3.x版本java驱动相对2.x做了全新的设计,类库和使用方法上有很大区别。例如用Document替换BasicDBObject本文整理了基于3.2版本的常用增删改查操作的使用方法。 1、先导入jar包 mongo-java-driver-3.2.2.jar 如下图所示: 2、测试类 import java.net.UnknownHostException; /** *...

小白轩的博客 2270

Pulsar简单实现demo

Pulsar简单实现demo

super_chenzhou 1861

springboot mongodb 账号密码认证连接 源码demo

之前介绍 过 springboot mongodb无认证连接 + 连接池 源码demo 实际项目中肯定是会有认证的,下面介绍 springboot mongodb 账号密码认证连接 源码demo 下一章介绍 在本章基础上增加 连接池配置 testdb数据库的集合user测试数据 在user集合添加一条数据用于测试 db.createCollection('user') db.user.inser...

a704397849的博客 5951
上一篇: 当启动tomcat时出现tomcat setting should be set in tomcat preference page
下一篇: mysql千万级大数据SQL查询优化
半盏清风
博客等级 码龄9年 7粉丝 11原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值