当前位置:   article > 正文

简单的图书馆管理系统_图书管理系统

图书管理系统

简单的图书馆管理系统

一、概要

1、题目意义

为更好管理图书馆,制作一个简易的图书管理系统,实现新书录入、图书资料查询、显示所有图书信息等功能。通过这个案例可以系统地了解类以及文件的输入输出流。

2、设计思想

①能够借阅图书;
②能够归还图书;
③能够对图书信息进行集中管理。可以设置二级菜单,能够对图书信息实现增、删、改、查操作;
④能够对用户信息进行集中管理。可以设置二级菜单,对用户信息实现增、删、改、查操作。

二、整体架构流程

  1. 总设计框架图

​​​​总设计框架图

  1. 功能设计功能

根据案例需求,可以定义一个图书类,图书的基本信息有书名和作者(其实还可以添加其他信息,例如出版社、价格等,这里只选用最重要的两条信息为代表)。对图书的管理包括设置书名、设置作者名、查询书名等功能,这些功能需要调用图书类的成员函数实现。

由于需要对图书资料进行读入和存储,在程序中需要文件的输入输出操作。先从相应的文件中读入图书资料,用户在对资料进行处理后,在退出系统时将已修改的资料重新存储到原文件中。

  1. 功能模块介绍

主要分为四大模块:借阅图书、归还图书、图书管理模块和用户管理模块。管理员便可以对图书的信 息进行增加、删除、修改、查询以及统计等的功能。下面就来详细介绍:

  1. 借阅图书:输入学号及想借阅的书号,就能借阅图书,在图书管理页面可以查到这本书是否被借阅。

  2. 归还图书:输入学号及想借阅的书号,就能归还图书,在图书管理页面可以查到这本书是否被借阅。

  3. 图书管理模块
    (1)增加图书信息:输入书号和书名,即可实现图书信息的增加。
    (2)更改图书信息:输入书号和书名,即可实现图书信息的更改。
    (3)删除图书信息:输入书号,即可实现图书信息的删除,删除后该图书信息将不存在图书管理系统中。
    (4)查找图书信息:输入书号,即可显示要查找图书的信息,可以显示图书的名称和状态(是否在架)。
    (5)显示图书信息:可显示所有图书的信息,包括书号、书名和图书状态(是否在架)。
    (6)返回主菜单:可以返回主菜单,进行其他操作。

  4. 用户管理模块
    (1)增加用户信息:输入学号和姓名,即可实现用户信息的增加。
    (2)更改用户信息:输入学号和姓名,即可实现用户信息的更改。
    (3)删除用户信息:输入学号,即可实现用户信息的删除,删除后该用户信息将不存在图书管理系统中。
    (4)查找用户信息:输入学号,即可显示要查找用户的信息,可以显示用户的姓名和是否借书。
    (5)显示用户信息:可显示所有用户的信息,包括学号、书名和姓名和是否借书。
    (6)返回主菜单:可以返回主菜单,进行其他操作。

三、技术细节

功能模块分析

1.类的设计

Book 类的设计
Book的成员示例图
2.数据成员设计

(1)char name[StrNum];用来存放书名。

(2)char writer[StrNum];用来存放作者姓名。
3.函数成员设计
(1)Book();无参构造函数,用于为书名和作者姓名设置默认值。

(2)Book(const char *Name,const char *Writer)带参构造函数,按照入口参数设置书名和作者姓名。

(3)char *get_name();用于获取书名。

(2) char *get_writer();用于获取作者姓名。

(5)void changeName(const char *newName);用于设置书名。

(6)void changeWriter(const char *newWriter);用于设置作者姓名。

(7)int cmpName(const char *Name);用于比较查询词和书名,如果相等则返回“1”。
4.主程序设计
(1)函数的设计

  • void showBook(Book book)——用于输出一册图书的书名。
  • void showAll(Book *book,int Num)——用于输出 Num 册图书的书名。

(2)主函数的设计

  • 在主函数中创建了一个 Book 类的对象数组,对图书资料的操作都将通过该类所创建对象的函数成员完成。
  • 在主函数中通过调用两个函数 showBook()和 showAll()实现图书资料的显示功能。
    图书管理系统主程序流程

四、详细代码

头文件

//图书管理模块
//图书类头文件

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class book
{
public:
	int no;//图书编号
	char name[20];//图书名称
	int b_flag;//1 为在架,2 为借出
	int b_del;//1 为存在, 2 为删除
public:
	book();//构造函数
	void setno(int n);
	int getno();
	void setname(char na[]);
	char* getname();
	void borbook();
	void delbook();
	void addbook(int no, char na[]);//增加图书功能
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
//图书数据库类
//图书数据库类头文件
#include"book.h"
const int BMAX = 50;//书最多个数
class bdatabase
{
public:
	book btarray[BMAX];//图书集合
	int top;
public:
	bdatabase();
	~bdatabase();
	void addbooks();
	int findbooks(int suffix);
	int findbooks();
	void editbooks();
	void delbooks();
	void listbooks();
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
//读者管理模块
//读者类头文件
#include "book.h" 
class reader{
public:
	int no;
	char name[20];
	int r_del;//1 存在,2 删除
	int r_bor;//1 借过书,2 没有借书
    book brbook; 
public:
	void addreader(int id, char na[]);//增加读者
	void setbrbook(book bt);//设置借书标记
	book getbrbook();
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
//读者数据库类
//读者数据库类头文件
#include"reader.h"
const int RMAX = 50;//书最多个数
class rdatabase
{
public:
	reader rdarray[RMAX];
	int top;
public:
	rdatabase();
	~rdatabase();
	void addreaders();
	int findreaders(int suffix);
	int findreaders();
	void editreaders();
	void delreaders();
	void listreaders();
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

源文件

//主函数源文件
#include<string>
#include<fstream>
#include<iostream>
#include "bdatabase.h"
#include "rdatabase.h"
void bookjiemain()//图书维护子菜单
{
	cout<<"______________________"<<endl;
	cout << "|    图书维护     |" << endl;
	cout << "|    (1)增加      |" << endl;
	cout << "|    (2)更改      |" << endl;
	cout << "|    (3)删除      |" << endl;
	cout << "|    (4)查找      |" << endl;
	cout << "|    (5)显示      |" << endl;
	cout << "| (6)返回上一层   |" << endl;
	cout<<"______________________"<<endl;
}
void readerjiemian()//读者维护子菜单
{
	cout << "______________________" << endl;
	cout << "|    读者维护     |" << endl;
	cout << "|    (1)增加      |" << endl;
	cout << "|    (2)更改      |" << endl;
	cout << "|    (3)删除      |" << endl;
	cout << "|    (4)查找      |" << endl;
	cout << "|    (5)显示      |" << endl;
	cout << "| (6)返回上一层   |" << endl;
	cout << "______________________" << endl;
}
void mainjiemian()//主界面
{
	cout << "***********************" << endl;
	cout << "*     图书管理系统    *" << endl;
	cout << "*      (1)借书        *" << endl;
	cout << "*      (2)还书        *" << endl;
	cout << "*      (3)图书管理    *" << endl;
	cout << "*      (4)用户管理    *" << endl;
	cout << "*      (0)退出        *" << endl;
	cout << "***********************" << endl;
}
void borrowtoreturn(char br)//借书还书函数.参数 br 用来判断是“借书”还是“还书”.1 为“借书”,2 为“还书”
{
	int rdid = 0;
	int bkid = 0;
	int rsuffix, bsuffix;
	bdatabase t_bd;
	rdatabase t_rd;
	if (br == '1')
	{
		rsuffix = t_rd.findreaders(rdid);
		bsuffix = t_bd.findbooks(bkid);
		if (rsuffix == -1 || bsuffix == -1)
			return;
		if (t_bd.btarray[bsuffix].b_flag == 2)
		{
			cout << "图书已经借出,请选择其他图书" << endl;
			return;
		}
		if (t_rd.rdarray[rsuffix].r_bor == 1)
		{
			cout << "你已经借过图书,请先归还其他图书" << endl;
			return;
		}
		t_bd.btarray[bsuffix].b_flag = 2;
		t_rd.rdarray[rsuffix].r_bor = 1;
		t_rd.rdarray[rsuffix].brbook = t_bd.btarray[bsuffix];
		return;
	}
	if (br == '2')
	{
		rsuffix = t_rd.findreaders(rdid);
		bsuffix = t_bd.findbooks(bkid);
		if (rsuffix == -1 || bsuffix == -1)
			return;
		if (t_rd.rdarray[rsuffix].brbook.no == t_bd.btarray[bsuffix].no)
		{
			t_bd.btarray[bsuffix].b_flag = 1;
			t_rd.rdarray[rsuffix].r_bor = 2;
			t_rd.rdarray[rsuffix].brbook = t_bd.btarray[bsuffix];
		}
		else
		{
			cout << "请重新输入,读者借的图书号不正确" << endl;
			return;
		}
		return;
	}
}
void booksmange()
{
	char in;
	bdatabase bd;
	do {
		bookjiemain();
		cin >> in;
		switch (in)
		{
		case'1':
			bd.addbooks();
			break;
		case'2':
			bd.editbooks();
			break;
		case'3':
			bd.delbooks();
			break;
		case'4':
			bd.findbooks();
			break;
		case'5':
			bd.listbooks();
			break;
		case'6':
			break;
		default:cout << "输入错误,请重新输入" << endl;;
		}
	} while (in != '6');
	return;
}
void readersmange()
{
	char in;
	rdatabase bd;
	do {
		readerjiemian();
		cin >> in;
		switch (in)
		{
		case'1':
			bd.addreaders();
			break;
		case'2':
			bd.editreaders();
			break;
		case'3':
			bd.delreaders();
			break;
		case'4':
			bd.findreaders();
			break;
		case'5':
			bd.listreaders();
			break;
		case'6':
			break;
		default:cout << "输入错误,请重新输入" << endl;
		}
	} while (in != '6');
		return;
}
int main()
{
	char in;
	do {
		mainjiemian();
		cin >> in;
		switch (in)
		{
		case'1':
			borrowtoreturn(in);
			break;
		case'2':
			borrowtoreturn(in);
			break;
		case'3':
			booksmange();
			break;
		case'4':
			readersmange();
			break;
		case'0':
			break;
		default:cout << "输入错误,请重新输入" << endl;
		}
	} while (in != '0');
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
//图书类源文件
#include"book.h"
book::book()
{

}//构造函数
void book::setno(int n)
{
	no = n;//图书编号取值
}
int book::getno()
{
	return no;//返回图书编号值
}
void book::setname(char na[])
{
	strcpy_s(name, na);//字符串复制
}
char* book::getname()
{
	return name;//返回图书名称
}
void book::borbook()
{
	b_flag = 2;//借书标志
}
void book::delbook()
{
	b_del = 2;//删除标志
}
void book::addbook(int no, char na[])//增加图书功能
{
	setno(no);
	setname(na);
	b_flag = 1;
	b_del = 1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
//图书数据库类源文件
#include "bdatabase.h" 
bdatabase::bdatabase()
{	book b;
    top = -1;
    fstream file("book.txt", ios::in);//打开文件
	while(1)
    {
	file.read((char*)&b, sizeof(b)); 
	if (!file) 
		break;
	top++; btarray[top] = b;
    }
    file.close();//关闭文件

}
bdatabase::~bdatabase()
{
	fstream file("book.txt", ios::out);
	for (int i = 0; i <= top; i++)
	{
		if (btarray[i].b_del == 1)
			file.write((char*)&btarray[i], sizeof(btarray[i]));
	}
	file.close();

}
void bdatabase::addbooks()//往图书数据库中加图书
{

	book bk; int no;
	char bname[20]; cout << "请输入书号: "; cin >> no;
	cout << endl << "请输入书名: ";
	cin >> bname; cout << endl; bk.b_flag = 1; bk.addbook(no, bname); top++;
	btarray[top] = bk; return;
}
int bdatabase::findbooks(int suffix)//查找图书,这个函数用于借书这书操作,suffix 是数组下标
{
	int no;
	cout << "请输入书号: "; cin >> no;
	for (int i = 0; i <= top; i++)
	{
		if (btarray[i].no == no && btarray[i].b_del == 1)
		{
			return i;
		}
	}
	return -1;
}
int bdatabase::findbooks()//查找图书,这个函数用于图书维护
{
	int no;
	char value[6];
	cout << "请输入书号: "; cin >> no;
	for (int i = 0; i <= top; i++)
	{
		if (btarray[i].no == no && btarray[i].b_del == 1)
		{
			if (btarray[i].b_flag == 1) strcpy_s(value, "在架"); 
			if (btarray[i].b_flag == 2) strcpy_s(value, "借出");
			cout << "书号: " << btarray[i].no << "  书的名称: " << btarray[i].name << " 图书状态 :" << value << endl;
			return i;
		}
	}
	return -1;

}
void bdatabase::editbooks()	//编辑图书
{
	int cur;
	cur = findbooks(); if (cur == -1)
	{
		cout << "没有这本书" << endl;
		return;
	}
	cout << "书号: " << btarray[cur].no << " 书的名称: " << btarray[cur].name << endl; cout << "请修改数据:" << endl;
	cout << endl << "书的名称: ";
	cin >> btarray[cur].name; return;
}
void bdatabase::delbooks()//删除图书
{
	int cur;
	cur = findbooks(); if (cur == -1)
	{
		return;
	}
	if (btarray[cur].b_flag == 2)//删除时判断图书是否借出
	{
		cout << "该图书已经借出,请在归还后再删除。" << endl;
		return;
	}
	btarray[cur].b_del = 2; return;
}
void bdatabase::listbooks()//显示全部图书
{
	char value[6];
	for (int i = 0; i <= top; i++)
	{

		if (btarray[i].b_del == 1)
		{
			if (btarray[i].b_flag == 1) strcpy_s(value, "在架"); 
			if (btarray[i].b_flag == 2) strcpy_s(value, "借出");
			cout << "书号: " << btarray[i].no << "  书的名称: " << btarray[i].name << " 图书状态 :" << value << endl;
		}
	}
	return;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
//读者类源文件
#include "reader.h"
void reader::addreader(int id, char na[])//增加读者
{
	no = id; 
	strcpy_s(name, na); 
	r_del = 1;
}
void reader::setbrbook(book bt)//设置借书标记
{
	brbook = bt;
}
book reader::getbrbook()
{
	return brbook;//返回借书信息
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
//读者数据库类源文件
#include "rdatabase.h" 
rdatabase::rdatabase()
{
	reader rd;
	top = -1;
	fstream file("reader.txt", ios::in);//打开文件
	while (1)
	{
		file.read((char*)&rd, sizeof(rd));
		if (!file) break;
		top++;
		rdarray[top] = rd;
	}
	file.close();//关闭文件
}
rdatabase::~rdatabase()
{
	fstream file("reader.txt", ios::out); 
	for (int i = 0; i <= top; i++)
	{
		if (rdarray[i].r_del == 1)
			file.write((char*)&rdarray[i], sizeof(rdarray[i]));
	}
	file.close();
}
void rdatabase::addreaders()//添加读者
{
	reader rd; int no;
	char rname[20]; cout << "请输入学号: "; cin >> no;
	cout << endl << "请输入姓名: ";
	cin >> rname; cout << endl;

	rd.addreader(no, rname); rd.r_bor = 2;
	top++; rdarray[top] = rd; return;
}
int rdatabase::findreaders(int suffix)	//查找读者,这个函数用于借书还书操作。
{
	int no;
	cout << "请输入学号: "; cin >> no;
	for (int i = 0; i <= top; i++)
	{
		if (rdarray[i].no == no && rdarray[i].r_del == 1)
		{
			return i;
		}
	}
	return -1;
}
int rdatabase::findreaders()//查找读者,这个函数用于读者维护操作
{
	int no;
	char value[3];
	cout << "请输入学号: "; cin >> no;
	for (int i = 0; i <= top; i++)
	{
		if (rdarray[i].no == no && rdarray[i].r_del == 1)
		{
			if (rdarray[i].r_bor == 1) strcpy_s(value, "借"); 
			if (rdarray[i].r_bor == 2) strcpy_s(value, "无");
			cout << "学号: " << rdarray[i].no << " 姓名: " << rdarray[i].name << " 是否借书: " << value << endl;
			return i;
		}
	}
	return -1;
}
void rdatabase::editreaders()	//编辑读者信息
{
	int cur;
	cur = findreaders(); if (cur == -1)
	{
		cout << "没有该学生" << endl;
		return;

	}
	cout << "请修改数据:" << endl; cout << endl << " 姓名: ";
	cin >> rdarray[cur].name; return;
}
void rdatabase::delreaders()	//删除读者,读者如果借书要还书后才能删除
{
	int cur;
	cur = findreaders(); if (cur == -1)
	{
		return;
	}
	if (rdarray[cur].r_bor == 1)
	{
		cout << "该用户借了图书,请还书后再删除" << endl;
		return;
	}
	rdarray[cur].r_del = 2; return;
}
void rdatabase::listreaders()//显示所有读者
{
	char value[3];
	for (int i = 0; i <= top; i++)
	{

		if (rdarray[i].r_del == 1)
		{
			if (rdarray[i].r_bor == 1) strcpy_s(value, "借"); 
			if (rdarray[i].r_bor == 2) strcpy_s(value, "无");
			cout << "学号: " << rdarray[i].no << " 姓名: " << rdarray[i].name << " 是否借书: " << value << endl;
		}
	}
	return;
}




  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111

五、项目总结

本案例只是完成了图书管理系统中的一部分基础功能,需求相对简单,采用数组和链表也可以实现。 案例涉及到了对象数组及文件的操作,这些知识点并不难理解,读者需要注意的是类结构的设计。除此以外,读者还需要注意以下几点:
1.C++是一门过程语言,无法在源程序中实现数据的存储,必须将数据存储在外部文件中,在必要时可以读入和输出。

2.在不使用文件时要及时关闭,且文件的打开和关闭都要作异常处理。

本系统只是完成了图书管理系统中的一部分基础功能,还有很多功能没有实现,可以在以下方面继续完善本案例:
1.增加图书信息,例如出版社、价格、摘要等。

2.提供多样化的查询和预览方式。

3.提供删除、借还书等功能。

4.改用链表形式制作图书管理系统也是很好的选择。

5.用 MFC 结合数据库可以制作出理想而优秀的图书管理系统。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/744144
推荐阅读
相关标签
  

闽ICP备14008679号