C++图书管理系统1.0

一、项目需求

(一)、用户登录(可选择后台管理员或前台管理员)
(二)、后台管理员身份
1、书籍录入(存入书籍文件)
2、借阅人信息录入(存入借阅人信息文件)
(三)、前台管理员身份
1、记录借书(存入借书信息文件)
2、记录还书(存入还书信息文件)

二、方案

1、设计一个登录菜单
2、设计两个界面(前台、后台)
3、进入前台或后台之后显示一个子菜单
4、设计三个类
4.1、书籍类Book
4.2、人类People
4.3、初始化类Init

三、框架

在这里插入图片描述

四、源代码

1、主程序

#include<Windows.h>
#include<iostream>
#include"Book.h"
#include"People.h"
#include"FUNS.h"
#include"Init.h"
using namespace std;

int main(void)
{
	WinSize(WIN_WIDTH, WIN_HEIGHT);
	system("color B1");

	Init init;//初始化
	init.Initfrombookfile();
	init.Initfrompeoplefile();

	People people;

	bool choice = Menu();
	while (1)
	{
		while (choice == true)//进入后台
		{
			Login(choice);//登录
			int tag = SecondMenu(choice);//二级菜单
			while (tag == BOOKINPUT || tag == PEOPLEINPUT)
			{
				if (tag == BOOKINPUT)
				{
					init.Initbookfile();//书籍录入
				}
				else
				{
					init.Initpeoplefile();//借书人信息录入
				}
				tag = SecondMenu(choice);//退出循环之后重新显示二级菜单
			}
			choice = Menu();//,退出后台操作后,重新显示主菜单
		}

		while (choice == false)//进入前台
		{
			Login(choice);//登录
			int tag = SecondMenu(choice);//二级菜单
			while (tag != RETURN_FROM_FRONT)
			{
				switch (tag)
				{
				case BORBOOK://借书
				{
					cout << "请输入姓名:";
					string name;
					cin >> name;
					cout << "请输入id:";
					int id=0;
					CheckCin(id);
					People people(name, id);
					if (people.BorrowBook()) 
					{
						cout << "借书成功!\n";
						system("pause");
					}
					else 
					{
						cout << "书籍不存在或库存不足或等级不够!\n";
						system("pause");
					}
					break;
				}
				case GIVEBOOK://还书
				{
					cout << "请输入姓名:";
					string name;
					cin >> name;
					cout << "请输入id:";
					int id=0;
					CheckCin(id);
					People people(name, id);
					if (people.Giveback())
					{
						cout << "还书成功!\n";
						system("pause");
					}
					else
					{
						cout << "你没有借这本书!\n";
						system("pause");
					}
					break;
				}
				case QUERY: //查询
				{
					people.Query();
					break;
				}
				}
				tag = SecondMenu(choice);
			}
			choice = Menu();
		}
	}
	system("pause");
	return 0;
}

2、函数声明和一些常量

#pragma once
#include<string>
using namespace std;

//常量
const int WIN_WIDTH = 80;//窗口宽度
const int WIN_HEIGHT = 30;//窗口高度

enum { BOOKINPUT = 1, PEOPLEINPUT, RETURN_FROM_BACK};
enum { BORBOOK = 1, GIVEBOOK, QUERY, RETURN_FROM_FRONT };

#define BOOKFILE "书籍信息.txt"
#define PEOPLEFILE "借书人信息.txt"
#define BORROWFILE "借书信息.txt"
#define GIVEBOOKFILE "还书信息.txt"

const string BACK_ADMINISTRATOR_ACCOUNT = "abcdefg123";  //后台管理员账号
const string BACK_ADMINISTRATOR_PASSWORD = "123456";     //后台管理员密码

const string FRONT_ADMINISTRATOR_ACCOUNT = "abcdefg";  //前台管理员账号
const string FRONT_ADMINISTRATOR_PASSWORD = "654321";     //前台管理员密码

//函数声明
void WinSize(int cols, int lines);//设置窗口
void CheckCin(int& NUM);//检查输入流
bool Menu();//true进入后台界面,false进入前台界面
void Login(bool bl);//登录
int SecondMenu(bool bl);//二级菜单
void IfNoOpen(ofstream& fout);//处理文件打开失败的情况
void IfNoOpen(ifstream& fin);

3、实现

#include<iostream>
#include<fstream>
#include<conio.h>
#include<vector>
#include<Windows.h>
#include"FUNS.h"
#include"Book.h"

void WinSize(int cols, int lines)
{
	char ch[255];
	sprintf_s(ch, "mode con cols=%d lines=%d", cols, lines);
	system(ch);
}

void CheckCin(int& NUM)
{
	cin >> NUM;
	while (!cin)
	{
		cin.clear();//重置输入流
		while (cin.get() != '\n')
		{
			//显示一个空白,再退格
			//cout << "\b \b";
			continue;
		}
		cin >> NUM;
	}
}

bool Menu()
{
	while (1)
	{
		system("cls");
		cout << "1.后台管理员登录\n2.前台管理员登录\n3.退出\n";
		cout << "请选择:";
		int choice;
		//cin >> choice;
		CheckCin(choice);
		switch (choice)
		{
		case 1:
		{
			system("cls");
			cin.get();//读取输入流中留下的换行符,防止它影响接下来的输入
			return true;
		}
		case 2:
		{
			system("cls");
			cin.get();
			return false;
		}
		case 3:exit(0);
		default:break;
		}
	}
}

void Login(bool bl)
{
	int count = 3;//最大输入次数
	while (count != 0)
	{
		bl ? cout << "后台管理员登陆界面\n" : cout << "前台管理员登陆界面\n";
		cout << "请输入账号:";
		string name;
		getline(cin, name);
		cout << "请输入密码:";
		string pwd = "";
		while (1)//逐字符输入密码
		{
			char c;
			c = _getch();
			if (c != 13)//按下回车结束输入
			{
				if (c == 8)//8是退格键的字符编码
				{
					if (pwd.length() > 0)//如果有输入
					{
						pwd = pwd.substr(0, pwd.length() - 1);//删除字符串末尾的一个字符
						cout << "\b \b";//退格输出空格再退格(覆盖原来的*)
						continue;
					}
					continue;//如果字符串本来就是空的,则按下退格键不做任何操作
				}
				pwd += c;
				_putch('*');//如果输入正确,用*隐藏密码
			}
			else
			{
				cout << endl;
				break;
			}
		}
		count--;
		if (name == (bl ? BACK_ADMINISTRATOR_ACCOUNT : FRONT_ADMINISTRATOR_ACCOUNT) &&
			pwd == (bl ? BACK_ADMINISTRATOR_PASSWORD : FRONT_ADMINISTRATOR_PASSWORD))
		{
			system("cls");
			break;
		}
		else
		{
			cout << "账号或密码错误,请重新输入!\n";
			cout << "剩余输入次数" << count << "次\n";
			if (count == 0)
			{
				system("pause");
				system("cls");
				cout << "今日次数已用完,请明日再试!\n";
				exit(EXIT_FAILURE);//终止程序
			}
			system("pause");
			system("cls");
		}
	}
}

int SecondMenu(bool bl)
{
	system("cls");
	if (bl)//后台选项
	{
		while (1)
		{
			system("cls");
			cout << "1.书籍录入\n2.借阅人信息录入\n3.返回\n";
			cout << "请选择:";
			int choice;
			//cin >> choice;
			CheckCin(choice);
			switch (choice)
			{
			case BOOKINPUT:
			{
				system("cls");
				cin.get();//读取输入流中留下的换行符,防止它影响接下来的输入
				return BOOKINPUT;
			}
			case PEOPLEINPUT:
			{
				system("cls");
				cin.get();
				return PEOPLEINPUT;
			}
			case RETURN_FROM_BACK:
			{
				system("cls");
				cin.get();
				return RETURN_FROM_BACK;
			}
			default:break;
			}
		}
	}
	else//前台选项
	{
		while (1)
		{
			system("cls");
			cout << "1.借书\n2.还书\n3.查询\n4.返回\n";
			cout << "请选择:";
			int choice;
			//cin >> choice;
			CheckCin(choice);
			switch (choice)
			{
			case BORBOOK:
			{
				system("cls");
				cin.get();//读取输入流中留下的换行符,防止它影响接下来的输入
				return BORBOOK;
			}
			case GIVEBOOK:
			{
				system("cls");
				cin.get();
				return GIVEBOOK;
			}
			case QUERY:
			{
				system("cls");
				cin.get();
				return QUERY;
			}
			case RETURN_FROM_FRONT:
			{
				system("cls");
				cin.get();
				return RETURN_FROM_FRONT;
			}
			default:break;
			}
		}
	}
}

void IfNoOpen(ofstream& fout)
{
	if (!fout.is_open())
	{
		cout << "文件打开失败!\n";
		exit(1);
	}
}

void IfNoOpen(ifstream& fin)
{
	if (!fin.is_open())
	{
		cout << "文件打开失败!\n";
		exit(1);
	}
}

4、Book类

#pragma once
#include<string>
using namespace std;
class Book
{
public:
	Book();
	Book(string bookname, int sernum, string category, unsigned inventory);
	~Book();

	string GetBookname()const;//查看书名
	int GetSernum()const;//查看编号
	string GetCategory()const;//查看类别
	unsigned GetInventory()const;//查看库存

	bool Addbook();//库存+1(还书)
	bool Subbook();//库存-1(借书)

	friend class People;
	friend ostream& operator<<(ostream& os, const Book& book);//重载<<输出到控制台
	friend ofstream& operator<<(ofstream& fout, const Book& book);//重载<<输出到文件
private:
	string bookname;//书名
	int sernum;//编号
	string category;//类别
	unsigned inventory;//库存
};
#include "Book.h"
#include<iostream>
#include<fstream>

Book::Book()
{
	bookname = "空";
	sernum = 0;
	category = "空";
	inventory = 0;
}

Book::Book(string bookname, int sernum, string category, unsigned inventory)
{
	this->bookname = bookname;
	this->sernum = sernum;
	this->category = category;
	this->inventory = inventory;
}

Book::~Book()
{
}

string Book::GetBookname() const
{
	return bookname;
}

int Book::GetSernum() const
{
	return sernum;
}

string Book::GetCategory() const
{
	return category;
}

unsigned Book::GetInventory() const
{
	return inventory;
}

bool Book::Addbook()
{
	inventory++;
	return true;
}

bool Book::Subbook()
{
	if (inventory == 0)
	{
		cout << "库存不足!\n";
		return false;
	}
	inventory--;
	return true;
}

ostream& operator<<(ostream& os, const Book& book)
{
	os << "书名:" << book.bookname << " 编号:" << book.sernum << " 类别:" << book.category << " 库存:" << book.inventory << endl;
	return os;
}

ofstream& operator<<(ofstream& fout, const Book& book)
{
	fout << "书名:" << book.bookname << " 编号:" << book.sernum << " 类别:" << book.category << " 库存:" << book.inventory << endl;
	return fout;
}

5、People类

#pragma once
#include<string>
#include<vector>
#include"Book.h"
using namespace std;

class People
{
public:
	People();
	People(string name, int id, unsigned booknums=0, int level = 1);
	~People();

	string GetName()const;
	int GetId()const;
	int GetLevel()const;
	unsigned GetBooknums()const;

	vector<Book>havebooks;//保存借到的书
	string GetTime()const;//获取时间
	unsigned MaxBooks();//当前等级最大借书数量

	bool BorrowBook();//借书
	bool Giveback();//还书

	void Query();//查询

	friend ostream& operator<<(ostream& os, const People& people);//重载<<输出到控制台
	friend ofstream& operator<<(ofstream& fout, const People& people);//重载<<输出到文件
private:
	string name;
	int id;
	unsigned booknums;
	int level;
};
#include<iostream>
#include<fstream>
#include<sstream>
#include<ctime>
#include<Windows.h>
#include "People.h"
#include"FUNS.h"
#include"Init.h"

People::People()
{
	name = "空";
	id = 0;
	level = 0;
	booknums = 0;
}

People::People(string name, int id, unsigned booknums, int level)
{
	this->name = name;
	this->id = id;
	this->level = level;
	this->booknums = booknums;
}

People::~People()
{
}

string People::GetName() const
{
	return name;
}

int People::GetId() const
{
	return id;
}

int People::GetLevel() const
{
	return level;
}

unsigned People::GetBooknums() const
{
	return booknums;
}

string People::GetTime() const
{
	stringstream str;
	time_t t = time(NULL);//当前时间戳
	tm localt;//保存本地时间戳
	localtime_s(&localt, &t);//将当前时间戳转换成本地时间戳
	str << localt.tm_year + 1900 << "年 "
		<< localt.tm_mon + 1 << "月 "
		<< localt.tm_mday << "日 "
		<< localt.tm_hour << "时 "
		<< localt.tm_min << "分 "
		<< localt.tm_sec << "秒" << endl;
	return str.str();
}

unsigned People::MaxBooks()
{
	unsigned maxbooks;
	maxbooks = level * 3;
	return maxbooks;
}

bool People::BorrowBook()//借书
{
	int sernum = 0;
	cout << "请输入编号:";
	//cin >> sernum; 
	CheckCin(sernum);
	//判断是否有这个编号
	Init init;
	init.Initfrombookfile();//筛选编号和修改书籍信息会用到这个初始化
	init.Initfrompeoplefile();//修改借书人信息会用到这个初始化
	for (auto book = (init.books).begin(); book != (init.books).end(); book++)//从所有书籍中筛选
	{
		if (sernum == book->sernum)//编号相同
		{
			if (book->Subbook()&& booknums<MaxBooks())//能否借书(考虑库存和等级),如果能借书Subbook()方法会把库存-1
			{
				//添加借书记录
				ofstream foutborrow;
				foutborrow.open(BORROWFILE, ios::out | ios::app);//打开文件,只追加
				IfNoOpen(foutborrow);
				//把这本书的信息,借书时间,借书人输入到借书信息
				string line(100, '-');
				foutborrow << "书名:" << (*book).bookname << endl << GetTime() << "借书人:" << name << endl << line << endl;
				foutborrow.close();

				//修改书籍信息
				//待优化:要改的只是库存,不需要把所有数据都覆盖*******************************************优化:只修改指定数据
				ofstream foutbook;
				foutbook.open(BOOKFILE, ios::out | ios::trunc);//打开文件,截短
				IfNoOpen(foutbook);
				for (auto it = (init.books).begin(); it != (init.books).end(); it++)
				{
					foutbook << (*it);
				}
				foutbook.close();

				//修改借书人信息
				ofstream foutpeople;
				foutpeople.open(PEOPLEFILE, ios::out | ios::trunc);//打开文件,截短
				IfNoOpen(foutpeople);
				bool tag = false;//一个临时标记
				for (auto it = (init.people).begin(); it != (init.people).end(); it++)
				{
					if (id == it->id)//如果有这个人(借过书)
					{
						//保存已借到的书
						(it->havebooks).push_back(*book);//这里的Book类库存已经改了

						(it->booknums)++;
						tag = true;
					}
					foutpeople << (*it);
				}
				if (!tag)
				{
					//进入这里说明遍历了容器没找到这个人
					//把这个人添加进去
					booknums++;
					havebooks.push_back(*book);
					(init.people).push_back(*this);
					foutpeople << *this;
				}
				foutpeople.close();

				return true;
			}
		}
	}
	//5.是否可升级**********************************************还没添加升级功能
	return false;
}

bool People::Giveback()//还书
{
	int sernum = 0;
	cout << "请输入编号:";
	//cin >> sernum;
	CheckCin(sernum);
	//判断是否有这个编号
	Init init;
	init.Initfrombookfile();//筛选编号和修改书籍信息会用到这个初始化
	init.Initfrompeoplefile();//修改借书人信息会用到这个初始化
	//for (auto it = havebooks.begin(); it != havebooks.end(); it++)//从已借到的书里面筛选
	for (auto it = init.people.begin(); it != init.people.end(); it++)//从借书人里面筛选
	{
		if (id == it->id)//找到这个人
		{
			for (auto book = it->havebooks.begin(); book != it->havebooks.end(); book++)
			{
				if (sernum == book->sernum)//编号相同
				{
					

					//添加还书记录
					ofstream foutgive;
					foutgive.open(GIVEBOOKFILE, ios::out | ios::app);//打开文件,只追加
					IfNoOpen(foutgive);
					//把这本书的信息,还书时间,还书人输入到还书信息
					string line(100, '-');
					foutgive << "还书人:" << name << endl << "还书:" << book->bookname << endl << GetTime() << line << endl;
					foutgive.close();

					//修改书籍信息
					ofstream foutbook;
					foutbook.open(BOOKFILE, ios::out | ios::trunc);//打开文件,截短
					IfNoOpen(foutbook);
					for (auto it = (init.books).begin(); it != (init.books).end(); it++)
					{
						if (sernum == it->sernum)//找到这本书(一定有!)
						{
							it->Addbook();//库存+1
						}
						foutbook << (*it);
					}
					foutbook.close();


					//修改已借到的书
					it->havebooks.erase(book);//删除
					it->booknums--;

					//修改借书人信息
					ofstream foutpeople;
					foutpeople.open(PEOPLEFILE, ios::out | ios::trunc);//打开文件,截短
					IfNoOpen(foutpeople);
					for (auto it = (init.people).begin(); it != (init.people).end(); it++)
					{
						//if (id == it->id)//找到这个人(一定有!)
						//{
						//	(it->booknums)--;
						//}
						foutpeople << (*it);
					}
					foutpeople.close();

					return true;
				}
			}
		}
	}
	return false;
}

void People::Query()
{
	Init init;
	init.Initfrombookfile();
	while (1)
	{
		system("cls");
		cout << "1.按书名查找\n2.按编号查找\n3.返回\n";
		cout << "请选择:";
		int choice;
		//cin >> choice;
		CheckCin(choice);
		switch (choice)
		{
		case 1:
		{
			system("cls");
			cout << "请输入书名:";
			string bookname;
			cin >> bookname;
			for (auto it = init.books.begin(); it != init.books.end(); it++)
			{
				if (bookname == (*it).bookname)
				{
					system("cls");
					cout << (*it);
				}
			}
			system("pause");
			break;
		}
		case 2:
		{
			system("cls");
			cout << "请输入编号:";
			int serialnum;
			cin >> serialnum;
			for (auto it = init.books.begin(); it != init.books.end(); it++)
			{
				if (serialnum == (*it).sernum)
				{
					system("cls");
					cout << (*it);
				}
			}
			system("pause");
			break;
		}
		case 3:return;
		default:break;
		}
	}
}

ostream& operator<<(ostream& os, const People& people)
{
	os << "姓名:" << people.name << " id:" << people.id << " 已借书数量:" << people.booknums << " 等级:" << people.level << endl;
	return os;
}

ofstream& operator<<(ofstream& fout, const People& people)
{
	fout << "姓名:" << people.name << " id:" << people.id << " 已借书数量:" << people.booknums << " 等级:" << people.level << endl;
	fout << "已借到的书:\n";
	for (auto it = people.havebooks.begin(); it != people.havebooks.end(); it++)
	{
		fout << *it;
	}
	string line(100, '-');
	fout << line << endl;
	return fout;
}

6、Init类

#pragma once
#include<vector>
#include"Book.h"
#include"People.h"

class Init
{
public:
	friend class People;
	void Initfrombookfile();//从文件导出书籍信息
	void Initfrompeoplefile();//从文件导出借书人信息

	void Initbookfile();//初始化书籍信息
	void Initpeoplefile();//初始化借书人信息

	vector<Book> books;
	vector<People> people;
};

#include<fstream>
#include<Windows.h>
#include<iostream>
#include<conio.h>
#include"FUNS.h"
#include "Init.h"
using namespace std;

void Init::Initfrombookfile()
{
	//从书籍信息中导出数据
	ifstream finbook;
	finbook.open(BOOKFILE);
	if (!finbook.is_open())
	{
		//cout << "书籍不存在!\n";
		return;
	}

	while (1)
	{
		string line;
		getline(finbook, line);

		if (finbook.eof())
		{
			break;
		}
		//解析这一行数据
		char bookname[256];//书名
		int sernum;//编号
		char category[256];//类别
		unsigned inventory;//库存
		sscanf_s(line.c_str(), "书名:%s 编号:%d 类别:%s 库存:%d", bookname, sizeof(bookname), &sernum, category, sizeof(category), &inventory);
		Book book(bookname, sernum, category, inventory);
		books.push_back(book);
	}
}

void Init::Initfrompeoplefile()
{
	//从借书人信息中导出数据
	ifstream finpeople;
	finpeople.open(PEOPLEFILE);
	if (!finpeople.is_open())
	{
		//cout << "没有借书人!\n";
		return;
	}

	while (1)
	{
		string line;
		getline(finpeople, line);

		if (finpeople.eof())
		{
			break;
		}
		//解析这一行数据
		char name[256];//姓名
		int id;
		unsigned booknums;//已借书数量
		int level;
		sscanf_s(line.c_str(), "姓名:%s id:%d 已借书数量:%d 等级:%d", name, sizeof(name), &id, &booknums, &level);
		People peo(name, id, booknums, level);

		getline(finpeople, line);//读取无用行(“已借到的书:”)

		for (int i = 0; i < booknums; i++)
		{
			string line;
			getline(finpeople, line);
			char name[256];//书名
			int sernum;//编号
			char category[256];//类别
			unsigned inventory;//库存
			sscanf_s(line.c_str(), "书名:%s 编号:%d 类别:%s 库存:%d", name, sizeof(name), &sernum, category, sizeof(category), &inventory);
			Book book(name, sernum, category, inventory);
			peo.havebooks.push_back(book);
		}
		people.push_back(peo);

		getline(finpeople, line);//读取无用行:分割线
	}
}

void Init::Initbookfile()
{
	//将信息保存到books容器
	char key = 0;//保存按键
	while (key != VK_RETURN)
	{
		system("cls");
		cout << "书籍录入\n";
		string bookname;//书名
		int sernum = 0;//编号
		string category;//书籍类别
		int nums = 0;//库存
		cout << "请输入书名:";
		cin >> bookname;
		cout << "请输入编号:";
		cin >> sernum;
		cout << "请输入书籍类别:";
		cin >> category;
		cout << "请输入书籍数量:";
		cin >> nums;

		Book tempbook(bookname, sernum, category, nums);//创建一个临时书籍对象
		//考虑重复添加
		bool tag = false;//临时标记
		for (auto it = books.begin(); it != books.end(); it++)
		{
			if (sernum == it->GetSernum())
			{
				cout << "书籍已存在!\n";
				tag = true;
			}
		}

		if (!tag)
		{
			books.push_back(tempbook);//把对象添加到容器中
			//写入文件
			ofstream fout;
			fout.open(BOOKFILE, ios::out | ios::app);//打开文件,只追加
			IfNoOpen(fout);
			fout.seekp(0, ios::end);//定位到文件尾
			fout << tempbook;

			fout.close();
		}

		cout << "按任意键继续(回车键结束)\n";
		key = _getch();
	}
}

void Init::Initpeoplefile()
{
	//将信息保存到people容器
	char key = 0;//保存按键
	while (key != VK_RETURN)
	{
		system("cls");
		cout << "借书人录入\n";
		string name;//姓名
		int id = 0;
		cout << "请输入姓名:";
		cin >> name;
		cout << "请输入id:";
		//cin >> id; 
		CheckCin(id);

		People temppeople(name, id);//创建一个临时借书人对象
		//考虑重复添加
		bool tag = false;//临时标记
		for (auto it = people.begin(); it != people.end(); it++)
		{
			if (id == it->GetId())
			{
				cout << "借书人已存在!\n";
				tag = true;
			}
		}

		if (!tag)
		{
			people.push_back(temppeople);//把对象添加到容器中
			//写入文件
			ofstream fout;
			fout.open(PEOPLEFILE, ios::out | ios::app);//打开文件,只追加
			IfNoOpen(fout);
			fout << temppeople;

			fout.close();
		}
		cout << "按任意键继续(回车键结束)\n";
		key = _getch();
	}
}

五、其他

还有一些地方可以优化:
1、修改文件的时候应该只修改指定数据,覆盖所有数据并不合理。
2、借书/还书的时候输入了姓名和id,但是后面的判断语句只用到了id,这样会导致一个问题:张三借了书,还书的时候输入李四也能完成还书,因为只判断了id。
3、People类还有一个增加等级的功能没实现。

可能还有其他的问题,1.0版本先这样吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值