PYQT5手写一个简单好用的密码管理系统

初学了PYQT,试着自己写了一个关于密码存储的管理系统。这套系统可以很好的解决我在日常工作中记不住密码的问题,使用非对称算法生成的秘钥文件,非常的安全。借此与大家一起分享。

系统用到的工具主要有QT设计师软件(Qt Designer),VsCode编辑器。

一、设计Qt界面

因为学得还不是很深入,使用的都是软件自带的一些配色。

1.登录界面

新用户注册界面

 

重置登录密码界面

 

当输入密码错误超过5次,将锁定键盘60秒

 

密码管理的主界面

查看密码的界面

 

 排好界面后将ui文件保存到自定义的目录,并用pyuic5的命令将ui文件转换成py文件。

接下来就可以用编辑器敲代码了。

这里我就偷下懒,直接把代码粘出来分享给大家一起学习。

1.登录页面代码

from PyQt5.QtWidgets import (

    QApplication,QDialog,QMessageBox

)

from login import Ui_login_pwd_manager

from Pwd_Manager_main import PwdManager

from set_passwd_main import Reset_Passwd

from sign_page_main import RegisterAccount

from lock_keyboard_main import LockKeyboard

import sys

import pymysql

import os

class LoginManager(Ui_login_pwd_manager,QDialog):

    def __init__(self) -> None:

        super().__init__()

        self.setupUi(self)

        self.show()

        if os.path.exists('./error.txt'):

            os.remove('./error.txt')

        self.pushButton_login.clicked.connect(self.show_manager_window)

        self.pushButton_sign_account.clicked.connect(self.show_sign_window)

        self.pushButton_find_passwd.clicked.connect(self.show_find_passwd)

        self.pushButton_quit.clicked.connect(self.close)

    def show_msg(self,msg):

        msgs = QMessageBox.warning(

            self,

            "信息提示",

            msg

        )

        return msgs

    def show_manager_window(self):

        try:

           host = '主机名或IP地址'

            user = self.lineEdit_user.text()

            pwd = self.lineEdit_pwd.text()

            db = '数据库名'

            port = 端口号

            conn = pymysql.connect(host=host,user=user,password=pwd,db=db,port=port)

            cur = conn.cursor()

            if os.path.exists('./error.txt'):

                os.remove('./error.txt')

            pwd_manager = PwdManager(engine=conn,object=cur,user=user)

            pwd_manager.exec()

        except:

            with open('./error.txt','a+') as fin:

                fin.write('error\n')

            self.error_msg()

    def error_msg(self):

        count_set = 6

        if os.path.exists('./error.txt'):

            with open('./error.txt','r') as fout:

                error = fout.readlines()

            count_now = count_set - len(error)

            self.show_msg(f"用户名或密码错误还有{count_now}次机会,键盘将锁定!")

        if count_now == 1:

            lock = LockKeyboard()

            lock.exec()




    def show_sign_window(self):

        sign_window = RegisterAccount()

        sign_window.exec()



    def show_find_passwd(self):

        reset_pwd = Reset_Passwd()

        reset_pwd.exec()

2.注册页面代码

from distutils.log import error
from PyQt5.QtWidgets import (
    QDialog,QMessageBox
)
from sign_page import Ui_sign
import pymysql
import base64



class RegisterAccount(Ui_sign,QDialog):

    def __init__(self) -> None:
        super().__init__()
        self.setupUi(self)
        self.show()

        try:
            host = '主机名或IP地址'
            user = '用户名'
            pwd = '密码'
            db = '数据库名'
            port = 端口号
            self.conn = pymysql.connect(host=host,user=user,password=pwd,db=db,port=port)
            self.cur = self.conn.cursor()
        except Exception as e:
            QMessageBox.warning(
                self,
                "错误信息",
                f"连接服务器失败!{e}"
            )

        self.pushButton_sign.clicked.connect(self.sign)
        self.pushButton_close.clicked.connect(self.close)

    def show_msg(self,msg):
        msgs = QMessageBox.warning(self,"信息提示",msg)
        return msgs

    def sign(self):
        user = self.lineEdit_user.text()
        pwd = self.lineEdit_pwd.text()
        pwd_again = self.lineEdit_pwd_again.text()
        phone = self.lineEdit_phone.text()
        try:
            check_sql = f"""
                    SELECT user FROM mysql.user WHERE user="{user}"
                """
            self.cur.execute(check_sql)
            get_user = self.cur.fetchall()
            if get_user:
                self.show_msg('用户名已存在!')
            else:
                if pwd == "" or pwd_again == "":
                    self.show_msg("密码不能为空")
                elif pwd != pwd_again:
                    self.show_msg("两次输入的密码不一致,请重新输入!")
                else:
                    if 0 < len(phone) < 11:
                        self.show_msg("手机号码格式错误!")
                    elif len(phone) == 11:
                        phone = str(base64.b64encode(phone.encode()))[2:-2]

                        sqls_user = []
                        create_user_local_sql = f"""
                            CREATE USER "{user}"@'localhost' IDENTIFIED BY "{pwd}"
                        """
                        create_user_any_sql = f"""
                            CREATE USER "{user}"@'%' IDENTIFIED BY "{pwd}"
                        """
                        sqls_user.append([[create_user_local_sql],[create_user_any_sql]])

                        for i in sqls_user[0]:
                            sql = ''.join(i).replace('\n','')
                            self.cur.execute(sql)
                            self.conn.commit()

                        sqls_set_table = []
                        create_table_sql = f"""
                            CREATE TABLE {user}_table(
                                account_name varchar(50),
                                user_name varchar(50),
                                pwd varchar(200) DEFAULT '1234'
                            )
                        """
                        unique_account_sql = f"""
                            ALTER TABLE {user}_table
                            ADD UNIQUE (account_name)
                        """
                        unique_user_sql = f"""
                            ALTER TABLE {user}_table
                            ADD UNIQUE (user_name)
                        """
                        grant_local_sql = f"""
                            GRANT ALL ON 数据库名.{user}_table TO "{user}"@'localhost' IDENTIFIED BY "{pwd}" 
                        """
                        grant_any_sql = f"""
                            GRANT ALL ON 数据库名.{user}_table TO "{user}"@'%' IDENTIFIED BY "{pwd}"
                        """
                        user_info_sql = f"""
                            INSERT INTO user_info VALUES("{user}","{phone}")
                        """
                        sqls_set_table.append([[create_table_sql],[unique_account_sql],[unique_user_sql],[grant_local_sql],[grant_any_sql],[user_info_sql]])

                        for i in sqls_set_table[0]:
                            sql = ''.join(i).replace('\n','')
                            self.cur.execute(sql)
                            self.conn.commit()
                        self.show_msg(f"恭喜你,注册成功!\n快点儿登录试试吧!")
                    else:
                        self.show_msg("请填写您的手机号码,便于您找回密码!")
        except pymysql.err.OperationalError as e:
            self.show_msg(f"用户名已存在!{e}")

3.重置密码页面

 # coding=utf-8
from distutils.log import info
import urllib
import urllib.request
import hashlib
from PyQt5.QtWidgets import (
    QDialog,QMessageBox
)
from reset_pwd import Ui_reset_passwd
import pymysql
import string
import random
import base64


class Reset_Passwd(Ui_reset_passwd,QDialog):

    def __init__(self) -> None:
        super().__init__()
        self.setupUi(self)
        self.show()

        try:
            host = '主机名或IP地址'
            user = '用户名'
            pwd = '密码'
            db = '数据库名'
            port = 端口号
            self.conn = pymysql.connect(host=host,user=user,password=pwd,db=db,port=port)
            self.cur = self.conn.cursor()
        except Exception as e:
            QMessageBox.warning(
                self,
                "错误信息",
                f"连接服务器失败!{e}"
            )

        self.statusStr = {
            '0': '短信发送成功',
            '-1': '参数不全',
            '-2': '服务器空间不支持,请确认支持curl或者fsocket,联系您的空间商解决或者更换空间',
            '30': '密码错误',
            '40': '账号不存在',
            '41': '余额不足',
            '42': '账户已过期',
            '43': 'IP地址限制',
            '50': '内容含有敏感词'
        }

        chars = string.digits*10
        self.code = ''.join(random.sample(chars,4))

        self.pushButton_get_check_num.clicked.connect(self.send_msg)
        self.pushButton_set_pwd.clicked.connect(self.set_pwd)
        self.pushButton_close.clicked.connect(self.close)

    def show_msg(self,msg):
        msgs = QMessageBox.warning(self,"信息提示",msg)
        return msgs

    def md5(self,str):
        m = hashlib.md5()
        m.update(str.encode("utf8"))
        return m.hexdigest()

    def send_msg(self):
        smsapi = "https://api.smsbao.com/sms?"
        self.username = self.lineEdit_user_name.text()
        if not self.username:
            self.show_msg("用户名不能为空!")

        user_sql = f"""
                SELECT user FROM mysql.user WHERE user="{self.username}"
            """
        self.cur.execute(user_sql)
        get_user = self.cur.fetchall()
        
        if get_user:
            # 短信平台账号
            user = '短信平台账号'
            # 短信平台密码
            password = self.md5('短信平台密码')

            # 要发送的短信内容
            content = f"【密码管理系统】您的验证码是{self.code}。请妥善保管好您的验证码并在5分钟内输入。如非本人操作,请忽略本短信"
            # 要发送短信的手机号码
            info_sql = f"""
            SELECT info FROM user_info WHERE user="{self.username}"
            """
            self.cur.execute(info_sql)
            user_info = self.cur.fetchall()
            if user_info:
                info = f"'{user_info[0][0]}='"
                info = str(base64.b64decode(info))[2:-1]

                self.label_set_info.setText(f"给手机号码{info[:3]}****{info[-4:]}发送验证信息")
                data = urllib.parse.urlencode({'u': user, 'p': password, 'm': info, 'c': content})
                send_url = f"{smsapi}{data}"
                response = urllib.request.urlopen(send_url)
                the_page = response.read().decode('utf-8')
                self.show_msg(f"{self.statusStr[the_page]},请注意查收!")
            else:
                self.show_msg("请输入接收验证码的手机号码!")
        else:
            self.show_msg(f"用户不存在!")
        

    def set_pwd(self):
        msgs = []
        get_code = self.lineEdit_check_num.text()
        pwd = self.lineEdit_pwd.text()
        pwd_again = self.lineEdit_pwd_again.text()

        if get_code == self.code:
            if pwd == pwd_again:
                if pwd and pwd_again:
                    reset_sql1 = f"""
                        ALTER USER "{self.username}"@'localhost' IDENTIFIED BY "{pwd}"
                    """
                    reset_sql2 = f"""
                        ALTER USER "{self.username}"@'%' IDENTIFIED BY "{pwd}"
                    """
                    sqls = [[reset_sql1],[reset_sql2]]
                    for i in sqls:
                        sql = ''.join(i)
                        self.cur.execute(sql)
                        self.conn.commit()
                    msgs.append("重置密码成功!\n快去登录系统试试吧!")
                else:
                    msgs.append("密码不能为空!")
            else:
                msgs.append("两次输入的密码不一致!")
        else:
            msgs.append("验证码不正确!")

        if msgs:
            self.show_msg(''.join(msgs))

4.键盘锁页面

from PyQt5.QtWidgets import (
    QApplication,QDialog
)
from lock_keyboard import Ui_lock_keyboard
import time
import os
from ctypes import windll

class LockKeyboard(Ui_lock_keyboard,QDialog):
    def __init__(self) -> None:
        super().__init__()
        self.setupUi(self)
        self.show()

        self.lock()
        self.pushButton_close.clicked.connect(self.close)

    def lock(self):
        user32 = windll.LoadLibrary('user32.dll')
        user32.BlockInput(True)
        countdown = 60
        count = 0
        while count < countdown:
            count_now = countdown -count
            self.label_lock.setText(f"键盘已锁定!   {count_now}秒后解锁")
            QApplication.processEvents()
            time.sleep(1)
            count += 1
            if count_now == 1:
                self.label_lock.setText("解锁")
                QApplication.processEvents()
                user32.BlockInput(False)
                if os.path.exists('./error.txt'):
                    os.remove('./error.txt')

5.密码管理主页面

from PyQt5.QtWidgets import (
    QDialog,QMessageBox,QTableWidgetItem
)
from pwd_manager import Ui_pwd_manager
from view_pwd_main import ViewPwd
import pymysql
import random
import string
import base64
import rsa
import os



class PwdManager(Ui_pwd_manager,QDialog):

    def __init__(self,engine,object,user) -> None:
        super().__init__()
        self.setupUi(self)
        self.show()

        self.conn = engine
        self.cur = object
        self.user = user
        (pubkey,privkey) = rsa.newkeys(512)
        pubkey_file = pubkey.save_pkcs1()
        privkey_file = privkey.save_pkcs1()

        pubkey_path = r"./pubkey.pem"
        privkey_path = r"./privkey.pem"
        if not os.path.exists(pubkey_path):
            with open(pubkey_path,'wb') as fin:
                fin.write(pubkey_file)

        if not os.path.exists(privkey_path):
            with open(privkey_path,'wb') as fin1:
                fin1.write(privkey_file)

        with open(pubkey_path,'r') as fout:
            self.pubkey = rsa.PublicKey.load_pkcs1(fout.read())

        self.pushButton_query_pwd.clicked.connect(self.query_one_pwd)
        self.pushButton_query_pwd_all.clicked.connect(self.query_all_pwd)
        self.pushButton_create_pwd.clicked.connect(self.create_pwd)
        self.pushButton_add_pwd.clicked.connect(self.add_pwd)
        self.pushButton_refresh_pwd.clicked.connect(self.refresh_pwd_window)
        self.pushButton_del_pwd.clicked.connect(self.del_pwd)
        self.pushButton_del_all_pwd.clicked.connect(self.del_all_pwd)


    def show_msg(self,msg):
        msgs = QMessageBox.warning(self,"信息提示",msg)
        return msgs
     
    def query_one_pwd(self):
        try:
            account_name = self.lineEdit_get_account_name.text()
            if  account_name:
                sql = f"""
                    SELECT * FROM  {self.user}_table  WHERE account_name="{account_name}"
                """
            self.cur.execute(sql)
            results = self.cur.fetchall()
            print(results[0][2])
            print(len(results[0][2]))
            if results:
                row = self.cur.rowcount
                col = len(results[0])
                self.tableWidget_show_pwd.setRowCount(row)
                self.tableWidget_show_pwd.setColumnCount(col)
                pwd = base64.b64decode(f"{results[0][2]}==")
                print(pwd)
                print(type(pwd))
                for i in range(row):
                    for j in range(col):
                        self.tableWidget_show_pwd.setItem(
                            i,j,
                            QTableWidgetItem(str(results[i][j]))
                        )
                reply = QMessageBox.question(self,"信息提示","是否查看密码?",QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
                if reply == QMessageBox.Yes:
                    view_pwd = ViewPwd(pwd)
                    view_pwd.exec()
            else:
                self.show_msg("没有找到对应账号类别的相关信息,确认账号类别输入正确后再试试哦!")
        except Exception as e:
            self.show_msg(f"请先输入要查询的账号类别{e}")


    def query_all_pwd(self):
        try:
            sql = f"""
                SELECT * FROM {self.user}_table
            """
            self.cur.execute(sql)
            results = self.cur.fetchall()
            if results:
                row = self.cur.rowcount
                col = len(results[0])
                self.tableWidget_show_pwd.setRowCount(row)
                self.tableWidget_show_pwd.setColumnCount(col)
                
                for i in range(row):
                    for j in range(col):
                        self.tableWidget_show_pwd.setItem(
                            i,j,
                            QTableWidgetItem(str(results[i][j]))
                        )
            else:
                self.show_msg("数据空空如也,快点儿存入你的第一个密码试试吧!")
        except AttributeError as e:
            self.show_msg(f"请先连接数据库!{e}")
    
    #加密
    def rsaEncrypt(self,str,pubkey):
        content = str.encode('utf-8')
        crypto = rsa.encrypt(content,pubkey)
        return crypto

    def create_pwd(self):
        pwd_length = int(self.spinBox_pwd_length.text())
        if pwd_length == 0:
            self.show_msg("密码位数不能小于1")
        elif pwd_length > 53:
            self.show_msg("密码位数不能大于53")
        else:
            chars = []
            if self.checkBox_letters.isChecked():
                chars.append(string.ascii_letters*10)
            if self.checkBox_digits.isChecked():
                chars.append(string.digits*10)
            if self.checkBox_punctuation.isChecked():
                chars.append(string.punctuation*10)
            if not chars:
                chars = f"""
                {string.ascii_letters},{string.digits},{string.punctuation}
                """
            else:
                chars = "".join(chars)
            chars_list = random.sample(chars,pwd_length)

            self.pwd = "".join(chars_list)
            self.lineEdit_new_pwd.setText(self.pwd)

            self.pwd = self.rsaEncrypt(self.pwd,self.pubkey)
            print(self.pwd)
            self.pwd = str(base64.b64encode(self.pwd))[2:-3]
            print(self.pwd)
            print(type(self.pwd))
            print(len(','.join(self.pwd)))



    def add_pwd(self):
        msgs = []
        try:
            account_name = self.lineEdit_add_account_name.text()
            if not account_name:
                msgs.append("账号类别不能为空\n")
            user_name = self.lineEdit_add_user_name.text()
            if not user_name:
                msgs.append("用户名不能为空\n")
            sql = f"""
                    INSERT INTO {self.user}_table VALUES("{account_name}","{user_name}","{self.pwd}")
            """
            self.cur.execute(sql)
            self.conn.commit()
            self.query_all_pwd()
            #清空输入框数据
            self.lineEdit_add_account_name.clear()
            self.lineEdit_add_user_name.clear()
            self.spinBox_pwd_length.clear()
            self.lineEdit_new_pwd.clear()
        except pymysql.err.IntegrityError as e:
            msgs.append(f"账号类别/用户名已存在:{e}\n")
        except pymysql.err.ProgrammingError as e:
            msgs.append(f"自动生成的密码格式错误:{e}\n")
        except AttributeError as e:
            msgs.append(f"密码不能为空{e}\n")

        if msgs:
            self.show_msg("".join(msgs))

    def refresh_pwd_window(self):
        try:
            for i in self.tableWidget_show_pwd.selectedItems():
                if i.column() == 0:
                    text = self.tableWidget_show_pwd.item(i.row(),i.column()+1).text()
                    sql = f"""
                        UPDATE {self.user}_table SET account_name="{i.text()}" WHERE user_name="{text}"
                    """
                elif i.column() == 1:
                    text = self.tableWidget_show_pwd.item(i.row(),i.column()-1).text()
                    sql = f"""
                        UPDATE {self.user}_table SET user_name="{i.text()}" WHERE account_name="{text}"
                    """
                elif i.column() == 2:
                    text = self.tableWidget_show_pwd.item(i.row(),i.column()-1).text()
                    pwd = self.rsaEncrypt(i.text(),self.pubkey)
                    pwd = str(base64.b64encode(pwd))[2:-3]
                    sql = f"""
                        UPDATE {self.user}_table SET pwd="{pwd}" WHERE user_name="{text}"
                    """
            self.cur.execute(sql)
            self.conn.commit()
            self.query_all_pwd()
        except Exception as e:
            self.show_msg(f"请先选择要修改的数据!{e}")


    def del_pwd(self):
        try:
            for i in self.tableWidget_show_pwd.selectedItems():
                if i.column() == 0:
                    sql = f"""
                        DELETE FROM {self.user}_table WHERE account_name="{i.text()}"
                    """
                elif i.column() == 1:
                    sql = f"""
                        DELETE FROM {self.user}_table WHERE user_name="{i.text()}"
                    """
                elif i.column() == 2:
                    sql = f"""
                        DELETE FROM {self.user}_table WHERE pwd="{i.text()}"
                    """
            self.cur.execute(sql)
            self.conn.commit()
            self.query_all_pwd()
        except Exception as e:
            self.show_msg(f"请先选择要删除的账号类别或用户名!{e}")

    def del_all_pwd(self):
        sql = f"""
            DELETE FROM {self.user}_table
        """
        select_box = QMessageBox.question(
            self,
            "警告提示",
            "你确定要删除所有数据吗?三思而后行!",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        if select_box == QMessageBox.Yes:
            self.cur.execute(sql)
            self.conn.commit()
            self.query_all_pwd()

6.创建新密码

from http import server
from PyQt5.QtWidgets import (
    QApplication,QDialog,QMessageBox
)
from add_pwd import Ui_add_pwd
import sys
import pymysql
import random
import string



class AddPwd(Ui_add_pwd,QDialog):
    def __init__(self) -> None:
        super().__init__()
        self.setupUi(self)
        self.show()

        self.host = '主机名或IP地址'
        self.user = '用户名'
        self.pwd = '密码'
        self.db = '数据库名'
        self.port = 端口号
        try:
            self.conn = pymysql.connect(host=self.host,user=self.user,password=self.pwd,db=self.db,port=self.port)
            server_info = self.conn.get_server_info()
            self.cur = self.conn.cursor()
        except Exception as e:
            self.show_msg(f"连接错误:{e}")

        self.pushButton_create_pwd.clicked.connect(self.create_pwd)
        self.pushButton_add_pwd.clicked.connect(self.add_pwd)

    def create_pwd(self):
        pwd_length = int(self.spinBox_pwd_length.text())
        chars = []
        if self.checkBox_letters.isChecked():
            chars.append(string.ascii_letters*10)
        if self.checkBox_digits.isChecked():
            chars.append(string.digits*10)
        if self.checkBox_punctuation.isChecked():
            chars.append(string.punctuation*10)
        if not chars:
            chars = f"""
            {string.ascii_letters},{string.digits},{string.punctuation}
            """
        else:
            chars = "".join(chars)
        print(type(chars))
        chars_list = random.sample(chars,pwd_length)
        print(chars_list)
        self.pwd = "".join(chars_list)
        self.label_show_pwd.setText(f"新密码:{self.pwd}")

    def add_pwd(self):
        msgs = []
        try:
            cur = self.conn.cursor()
            account_name = self.lineEdit_get_name1.text()
            user_name = self.lineEdit_get_name2.text()
            sql = f"""
            insert into pwd values("{account_name}","{user_name}","{self.pwd}")
            """
            cur.execute(sql)
            self.conn.commit()
        except pymysql.err.IntegrityError as e:
            msgs.append(f"账号名称已存在:{e}")
        except AttributeError as e:
            msgs.append(f"数据库未连接,请退出窗口重新打开!{e}")
        print(msgs)
        if msgs:
            QMessageBox.warning(
                self,
                "错误信息",
                "".join(msgs)
            )
        else:
            QMessageBox.information(self,"信息提示","新增密码成功!")

7.查看密码页面

from PyQt5.QtWidgets import (
    QApplication,QDialog,QMessageBox,
    QFileDialog
)
from view_pwd import Ui_view_pwd
import sys
import rsa
import os



class ViewPwd(Ui_view_pwd,QDialog):
    def __init__(self,pwd) -> None:
        super().__init__()
        self.setupUi(self)
        self.show()
        self.str_pwd = pwd
        self.pushButton_select_privkey.clicked.connect(self.select_file)
        self.pushButton_view_pwd.clicked.connect(self.view_pwd)
        self.pushButton_close.clicked.connect(self.close)


    def select_file(self):
        self.privkey = QFileDialog.getOpenFileName(self,"请选择您的私钥文件",os.getcwd())[0]
        print(self.privkey)
        self.lineEdit_select_privkey.setText(self.privkey)

    def rsaDecrypt(self,str,pk):
        with open(self.privkey,'rb') as fout:
            pk = rsa.PrivateKey.load_pkcs1(fout.read())
        content = rsa.decrypt(str,pk)
        con = content.decode('utf-8')
        return con

    def view_pwd(self):
        try:
            pwd = self.rsaDecrypt(self.str_pwd,self.privkey)
            self.lineEdit_get_pwd.setText(pwd)
        except:
            QMessageBox.warning(self,"错误提示","查看密码失败,您的私钥文件不匹配!")

最后,可以在网上找一张漂亮的图片做程序的logo,使用【pyinstaller -F -w 文件名 --noconsole --icon=ico图片名 】命令打包成exe文件,就可以在任意一台电脑上面运行了!

最最后,展示下效果图

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值