安卓登陆注册功能实现 mvvm模式 jetback(包含后端)

所有app第一步都是登陆注册

如果你想做一个app,那么登陆注册功能是最基本的功能之一,简单介绍一下Android app登陆注册功能,客户端使用mvvm模式,jetpack全家桶,数据库用sqlite。后端用的springboot框架,数据库为mysql。

布局

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=".MainActivity">

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.07" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.27" />

<EditText
    android:id="@+id/editTextNumberPassword"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="72dp"
    android:ems="10"
    android:hint="密码"
    android:inputType="numberPassword"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.343"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline2" />

<EditText
    android:id="@+id/editTextTextPersonName"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="60dp"
    android:ems="10"
    android:hint="账号"
    android:inputType="textPersonName"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.35"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.54" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.6538988" />

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    android:text="登陆"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline3" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.7619699" />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:text="注册"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline4" />

</androidx.constraintlayout.widget.ConstraintLayout>

还有注册界面的布局

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=".LoginActivity">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline6"
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:orientation=“horizontal”
app:layout_constraintGuide_percent=“0.07” />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline7"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.27" />

<EditText
    android:id="@+id/editTextTextPersonName2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="40dp"
    android:ems="10"
    android:hint="account"
    android:inputType="textPersonName"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline6" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline8"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.54" />

<EditText
    android:id="@+id/editTextNumberPassword2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="60dp"
    android:ems="10"
    android:hint="password"
    android:inputType="numberPassword"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline7" />

<Button
    android:id="@+id/button3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="48dp"
    android:text="Register"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline8" />

</androidx.constraintlayout.widget.ConstraintLayout>

登陆

运用jetback首先要对账号登陆做一个数据类Account

package com.example.chiditan.shuchu;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity
public class Account {
    @PrimaryKey(autoGenerate = true)
    int id;

    @ColumnInfo
    private int account;
    @ColumnInfo
    private String password;

    public Account(int account, String password) {
        this.account = account;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAccount() {
        return account;
    }

    public void setAccount(int account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

随后创建一个dao接口,用于处理sqlite

package com.example.chiditan.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;


import com.example.chiditan.shuchu.Account;

import java.util.List;

import javax.sql.DataSource;
@Dao
public interface Accountdao {
    @Update
    void updataAccount(Account...accounts);
    @Insert
    void insertAccount(Account...accounts);

    @Query("select * from Account where account = :account1")
    List<Account> queryAccount(int account1);

    @Query("select * from Account  where account = :password & account =:account")
    List<Account> queryPassword(int account,String password);
    @Query("select * from Account  where id =1")
    LiveData<Account> getAccountlive();
}

创建viewmodel类

package com.example.chiditan.ViewModel;
import android.app.Application;
import android.content.Context;
import android.os.AsyncTask;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.room.Update;

import com.example.chiditan.dao.Accountdao;
import com.example.chiditan.database.Accountdatabase;
import com.example.chiditan.shuchu.Account;


public class AccountViewModel extends AndroidViewModel{
    private Accountdao accountdao;
    private LiveData<Account> accountlive;

    public LiveData<Account> getAccountlive() {
        return accountlive;
    }

    public AccountViewModel(@NonNull Application application)
    {
        super(application);
        Accountdatabase accountdatabase=Accountdatabase.getAccountdatabase(application);
        accountdao=accountdatabase.getAccountdao();
        accountlive=accountdao.getAccountlive();
    }
    static class InsterAsyncTask extends AsyncTask<Account,Void,Void>
    {
        private Accountdao accountdao;

        public InsterAsyncTask(Accountdao accountdao) {
            this.accountdao = accountdao;
        }



        @Override
        protected Void doInBackground(Account... accounts) {
            accountdao.insertAccount(accounts);
            return null;
        }
    }
    static class UpdataAsyncTask extends AsyncTask<Account,Void,Void>
    {
        private Accountdao accountdao;

        public UpdataAsyncTask(Accountdao accountdao) {
            this.accountdao = accountdao;
        }

        @Override
        protected Void doInBackground(Account... accounts) {
            accountdao.updataAccount(accounts);
            return null;
        }
    }
    public   void InsertAccount(Account...accounts)
    {
        new InsterAsyncTask(accountdao).execute(accounts);
    }
    public   void UpdataAccount(Account...accounts)
    {
        new UpdataAsyncTask(accountdao).execute(accounts);
    }
}

创建database

package com.example.chiditan.database;
import android.content.Context;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.DatabaseConfiguration;
import androidx.room.InvalidationTracker;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteOpenHelper;

import com.example.chiditan.dao.Accountdao;
import com.example.chiditan.shuchu.Account;

@Database(entities = {Account.class},version = 1,exportSchema = false)
public abstract class Accountdatabase extends RoomDatabase {
    private static Accountdatabase INSTANCE;
    public static synchronized Accountdatabase getAccountdatabase(Context context)
    {
        if(INSTANCE==null)
        {
            INSTANCE = Room.databaseBuilder(context.getApplicationContext(),Accountdatabase.class,"account_database")
                    .allowMainThreadQueries()
                    .build();
        }
        return INSTANCE;
    }
    public abstract Accountdao getAccountdao();
}

最后登录activit

package com.example.chiditan;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;
import androidx.room.DatabaseConfiguration;
import androidx.room.InvalidationTracker;
import androidx.room.Room;
import androidx.sqlite.db.SupportSQLiteOpenHelper;

import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


import com.example.chiditan.ViewModel.AccountViewModel;
import com.example.chiditan.dao.Accountdao;
import com.example.chiditan.shuchu.Account;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.List;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity
{
    private Button login_but, register_but;
    private TextView user_text, password_text;
    LiveData<Account> accountlive;
    AccountViewModel accountViewModel;
    public Response response;
    public String account1 = null;
    Accountdao accountdao;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        password_text = findViewById(R.id.editTextNumberPassword);
        user_text = findViewById(R.id.editTextTextPersonName);
        login_but = findViewById(R.id.button);
        register_but = findViewById(R.id.button2);


        accountViewModel = ViewModelProviders.of(this).get(AccountViewModel.class);


        accountViewModel.getAccountlive().observe(this, new Observer<Account>()
        {
        //时刻更新数据,自动显示上次注册成功的账号密码
            @Override
            public void onChanged(Account account)
            {
                if (account != null)
                {
                    int account_text = 0;
                    String password1_text = "";
                    account_text = account.getAccount();
                    password1_text = account.getPassword();
                    password_text.setText(password1_text);
                    user_text.setText(String.valueOf(account_text));

                }
            }
        });
//点击跳转到登陆界面
        register_but.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, LoginActivity.class);
              
                startActivity(intent);
            }
        });

//点击登陆按钮
        login_but.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                new Thread(new Runnable()
               {
                    @Override
                    public void run()

                   {

                       try
                        {
                           RequestBody formBody = new FormBody.Builder()
                                   .add("account", user_text.getText().toString())
                                   .add("password", password_text.getText().toString())
                                   .build();
                            OkHttpClient client = new OkHttpClient();
             //发送账号信息
                           Request request = new Request.Builder()
                                    .url("http://10.0.2.2:8080/Login")
                                   .post(formBody)
                                    .build();
                           Response response = null;
                           response = client.newCall(request).execute();
                           String s = response.body().string();
                           int res = Integer.valueOf(s);
                           Log.d(s, "获取返回值");
                          //根据后端反应确定是否登陆成功
                           if (res == 1)
                           {
                               runOnUiThread(new Runnable()
                                {
                                  @Override
                                   public void run()
                                   {
                                       Toast.makeText(getApplicationContext(), "未注册账号",
                                                Toast.LENGTH_SHORT).show();
                                    }
                              });
                           } else
                           {
                               if (res == 2)
                               {
                                  runOnUiThread(new Runnable()
                                   {
                                       @Override
                                      public void run()
                                      {
                                           Toast.makeText(getApplicationContext(), "密码错误",
                                                    Toast.LENGTH_SHORT).show();
                                       }
                                  });

                                }
                                //登陆成功跳转到主页面
                               if (res == 3)
                              {
                                   Intent intent = new Intent();
                                  intent.setClass(MainActivity.this, MainActivity2.class);
                                   Bundle bundle = new Bundle();
                                   startActivity(intent);
                                   runOnUiThread(new Runnable()
                                   {
                                       @Override
                                       public void run()
                                      {
                                            Toast.makeText(getApplicationContext(), "登陆成功",
                                                   Toast.LENGTH_LONG).show();
                                           ;

                                    }
                                  });
                              }

                           }
                        } catch (IOException e)
                       {
                          e.printStackTrace();
                     }

                 }
             }).start();

      
            }
        });

注册页面

package com.example.chiditan;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;

import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProviders;


import com.example.chiditan.ViewModel.AccountViewModel;
import com.example.chiditan.dao.Accountdao;
import com.example.chiditan.database.Accountdatabase;
import com.example.chiditan.shuchu.Account;

import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.json.JSONObject;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class LoginActivity extends AppCompatActivity {
     Accountdatabase accountdatabase;
    Accountdao accountdao;
    private Button register_but2;
    private TextView user_text,password_text;
    AccountViewModel accountViewModel;
    
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
        }
        return true;

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        password_text =findViewById(R.id.editTextNumberPassword2);
        user_text =findViewById(R.id.editTextTextPersonName2);
        register_but2 = findViewById(R.id.button3);
        accountViewModel = ViewModelProviders.of(this).get(AccountViewModel.class);
       

//点击注册按钮

 register_but2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            RequestBody formBody = new FormBody.Builder()
                                    .add("account", user_text.getText().toString())
                                    .add("password", password_text.getText().toString())
                                    .build();
                            OkHttpClient client = new OkHttpClient();

                            Request request = new Request.Builder()
                                    .url("http://10.0.2.2:8080/Register")
                                    .post(formBody)
                                    .build();
                            Response response = client.newCall(request).execute();
                            String s = response.body().string();
                           int res= Integer.valueOf(s);
                            Log.d(s, "获取返回值");
                            //根据后端的回应发送确定下一步动作
                            if(res==1)
                            {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(getApplicationContext(),"该账号已注册,请使用此账号直接登录或使用其他账号注册",Toast.LENGTH_SHORT).show();
                                    }
                                });
                            }
                            else
                            {
                                if(res==3)
                                {
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            Toast.makeText(getApplicationContext(),"密码错误",Toast.LENGTH_SHORT).show();
                                        }
                                    });

                                }
                                else
                                //注册成功将本地的数据库进行更新
                                    {
                                        Account account=new Account(Integer.valueOf(user_text.getText().toString()).intValue(),password_text.getText().toString());
                                        if(accountViewModel.getAccountlive().getValue()==null)
                                        {
                                                   accountViewModel.InsertAccount(account);

                                        }
                                               else
                                                   {
                                                   account.setId(1);
                                                    accountViewModel.UpdataAccount(account);

                                               }
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                Toast.makeText(getApplicationContext(),"注册成功",Toast.LENGTH_LONG).show();;

                                            }
                                        });
                                    }
                                }

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });


    }
}

后端

登陆

package com.example.ditanbao.Controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@RestController
@org.springframework.stereotype.Controller


public class LoginController
{
    private static final long serialVersionUID = 1L;
    @Autowired
    private JdbcTemplate jdbcTemplate;
  public LoginController()
  {
    super();
  }
    @ResponseBody
    @PostMapping("Login")
    public int doPost(@RequestParam("account") String account, @RequestParam("password") String password)
    {

        System.out.println("account:" + account + "\npassword:" + password); // 打印出来看一看

        String result = "";
        int res=0;
        Map result1=null;
        Map result2=null;

        String sqlQuery = "select * from table_user_password where userName=" + account;
        try
        {
            result1 = (Map) jdbcTemplate.queryForMap(sqlQuery); // 先查询同样的账号(比如手机号)是否存在
        }catch (Exception e)
        { };

        if (result1==null)
        { // 模拟登陆账号、密码验证
           result="账号不存在";
           System.out.println(result);
           res=1;
        } else
        {
            String sqlQuery1 = "select * from table_user_password where username= '"+account+"' and userpassword= '" + password+"'";
            try
            {
                result2=(Map) jdbcTemplate.queryForMap(sqlQuery1);
            }catch (Exception e)
            { };


            if (result2==null)
            {
                result="密码不对";
                res=2;
                System.out.println(result);
            }else
            {
                res=3;
                result="登录成功";
                System.out.println(result);
            }
        }
      return res;
    }


}


注册

package com.example.ditanbao.Controller;



import com.example.ditanbao.domain.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.server.PathParam;
import java.util.Map;

@RestController
@org.springframework.stereotype.Controller


public class RegisterController
{

    @Autowired
    private JdbcTemplate jdbcTemplate;
    private static final long serialVersionUID = 1L;

    public RegisterController()
    {
        super();
    }
    @ResponseBody
    @PostMapping("Register")

    public int doPost(@RequestParam("account") String account,@RequestParam("password") String password)
    {

    //String account=account1.getAccount();
    //String password=account1.getPassword();
        System.out.println("account:" + account + "\npassword:" + password); // 打印出来看一看


        String resMsg = "";



        /* 这里我们做一个最简单的注册逻辑,当然,你的实际业务可以相当复杂 */

        int res=0;
        Map result = null;
        Map result2 =null;
        int[] result1;


        String sqlQuery = "select * from table_user_password where userName=" + account;

        // 查询类操作返回一个ResultSet集合,没有查到结果时ResultSet的长度为0
        try
        {
            result = (Map) jdbcTemplate.queryForMap(sqlQuery); // 先查询同样的账号(比如手机号)是否存在
        }catch (Exception e)
        { };


        if (result!=null)
        { // 已存在
            res=1;
            resMsg = "该账号已注册,请使用此账号直接登录或使用其他账号注册";
            System.out.println(resMsg);
        }
        else
        { // 不存在
            String sqlInsertPass = "insert into " + "table_user_password" + "(userName,userPassword) values('" + account + "','" + password + "')";

            result1 = jdbcTemplate.batchUpdate(sqlInsertPass); // 插入帐号密码
            if (result1.length > 0)
            {
                String sqlQueryId = "select userId from " + "table_user_password" + " where userName='" + account + "'";
                try
                {
                    result2 = (Map) jdbcTemplate.queryForMap(sqlQueryId); // 查询新增记录的userId

                }catch (Exception e)
                { };

                if (result2!=null)
                {
                    res=2;
                    resMsg = "注册成功";
                    System.out.println(resMsg);
                }else {
                    res=3;
                    resMsg="注册失败";
                }
            }
        }




        return res;



    }


}

  • 7
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值