图书管理系统


一, 前言:

随着对 Javaweb 的学习,想要尝试做一些项目,该文档是为了指导开发图书管理系统编写的.该文档是对图书管理系统涉及的功能,用户等级,界面,以及技术进行了明确.为项目开发提供明确的思路.

项目仓库:

二,系统分析:

2.1,系统可行性分析:

可行性分析是在进行初步调查后所尽心的对系统开发必要性和可行性的研究,所以也叫做可行性研究.信息系统也应从技术可行性,经济可行性和社会可行性三方面来论证.通过对javaweb练手项目的观察,我认为图书管理系统的可行性分析如下:

2.1.1,经济可行性分析:

该项目是为了验证在学习中编程技术的检验情况而开发的,对于经济要求不高,可忽略.

2.1.2,技术可行性分析:

技术上的可行性分析主要分析享有技术条件能否顺利完成开发工作,硬件,软件配置能否满足开发者的需要,图书管理系统的工作主要是便于读者与图书馆之间架起一座桥梁,能相互沟通信息和处理问题,这一特点非常适合计算机特点,通过网络 Internet 技术,发挥计算机的信息传输速度快,准确度高的有事.计算机硬件和软件技术的飞速发展,为系统的建设提供了技术条件.

2.1.3,社会可行性分析:

社会可行性分析有时也称操作可行性,主要论证新系统开发和运行的可能性以及运行后对企业或机构的影响,通过对多数javawe项目的挑选,我选择该系统进行技术检验,

2.2,系统需求分析:

该项目的图书管理系统设置图书信息,系统用户信息,读者信息,图书 节约等多种数据管理,从管理的角度可将系统分为三类:图书信息管理,系统用户管理,读者数据管理.图书嘻嘻管理包括图书征订,借还,查询等操作,系统用户管理包括系统用户类别,和用户数据管理,读者数据管理包括读者类别和个人数据的录入,修改和删除.

图书借阅者的需求是查询图书馆所存图书,个人节约情况及个人信息的修改;图书馆工作人员对图书借阅者的借阅及幻术要求进行操作,同时想成结束或还书报表给借阅者查看确认;图书管理人员的功能最为复杂,包括对工作人员,图书借阅者,图书进行管理和维护,及系统状态的查看,维护等.图书借阅者可直接查看图书馆图书情况,如果图书借阅者根据本人借书证号和密码登录系统,还可以进行本人结束情况的查询和维护部分个人信息,一般情况下,图书借阅者只应该查询和维护本人的结束情况和个人信息.图书馆工作人员有修改图书借阅者借书和还书记录的权限,所以需对工作人员登录本模块进行更多的考虑,在此模块中,图书馆工作人员可以为图书借阅者加入借书记录或是还书记录,并打印生成相应的报表给用户查看和确认,图书管理人员功能的信息量最大,数据安全性和保密性要求最高,本功能实现对图书信息,借阅者信息,总体借阅情况信息的管理和同届,工作人员和管理人员信息查看及维护.图书管理员可以以浏览,查询添加,删除,修改,统计图书的基本信息:浏览,查询,统计,添加,删除和修改借阅者的基本信息,浏览、查询、统计图书馆的借阅信息,但不能添加、删除和修改借阅信息,这部分功能应该由图书馆工作人员执行,但是,删除某条图书借阅者基本信息记录时,应实现对该图书借阅者借阅记录的级联删除。并且还应具有生成催还图书报表,并打印输出的功能。

2.3,系统的功能需求:

在本系统中,对读者来说,它们关心的问题其实是如何方便的查询到图书馆中的书籍以及自己正在借阅或是已经借阅过些什么书,所街的书是否到期等,由此可以得出系统在面向读者方面应该至少做到如下几点:

1,图书查询.

2,读者信息查询,读者信息查询的内容应包括以下几个方面:

​ 读者信息—对读者的基本信息进行显示.

​ 书刊借阅—对该读者借阅过的所有书籍进行查询.

​ 借阅历史—查询该读者借阅过的所有书籍

​ 违规信息—该读者的违规信息

​ 读者规则—读者所应用的规则.

对系统管理员来说,应该注意的是:

1,图书馆中有哪些书,它们存放的位置,是否可以被借阅;

2,对本图书馆发放的读者证有哪些,如何管理这些读书证;

3,这些读书证都借阅着哪些书;

4,如何确定这些读书证是否可用,以及借书的患期等.

从以上问题出发,可以得出本系统应该具有的功能:

1,图书查询—对管呃逆的图书进行查询

2,借阅管理—对读者的每次借阅,还书进行登记和管理

3,图书管理—对图书的书籍进行管理

4,借阅证管理—对读者的借阅证进行管理

5,读者规则管理—设置和管理读者规则

2.4,设计模式:

设计模式是面向对象的程序设计人员用来解决编程问题的一种形式化表示.本系统开发采用目前一种广泛流行的软件设计模式,MVC应用程序结构被用来分析分布式应用程序的特征.这种抽象结构有助于应用程序分割成若干逻辑部件,是程序设计变得更加容易.把一个应用的输入,处理,输出流程按照model,view,controller的方式进行分离.

三,系统设计:

3.1,系统概要:

本图书管理系统总体上分为前台页面显示,和后台管理.前台页面(即本图书管理系统的首页)实现了公告的显示图书查询,留言简易三大功能.而后台的页面则集成了图书管理重所需的功能和录入新书到库,办公图书,借还手续,查询图书等等,平时如数管理人员的工作都是在后台中完成的,前台是为用户显示的,用户可以看到图书管理人员发布的最新公告信息;并可以查询自己感兴趣的图书,也可以给管理人员留言简易.相应的后台针对的是管理人员,后台的页面都加密,如果不正常登录是进入不了后台管理页面的,后台工鞥能具体包括:发布首页公告,添加新书到库等等

3.2,功能模块:

本系统的功能模块的设计如图所示,整个系统包含图书信息管理,添加,删除,修改,查询图书信息管理,用户信息设置,图书借阅管理.

功能模块

3.3,设计思想:

利用软件开发现有软硬件环境,及先进的管理信息系统开发方案,从而达到充分利用现有资源提高系统开发水平和应用想过的目的.

系统应该符合软件功能开发的理论,开发方法等开发依据.

系统应满足图书馆管理工作需要,到操作过程中的直观,方便,使用,安全等要求.

系统具备数据库维护功能,及时根据用户需求进行数据库的各种操作.

系统采用圆形,使用模块化程序设计方法,便于系统功能的各种组合和修改,以及系统的测试与维护.

3.4,模块设计及功能:

3.4.1,图书查询:

读者可以通过网络访问图书管理系统,并对管内图书进行查询,对查到的在馆图书可以进行借阅,如图:

图书查询流程图

3.4.2,借阅管理:

这一部分对图书借阅,书籍归还的管理,当用户借书时,图书管理员把书籍的编号和读者的借阅证号输入系统,当此次借阅方盒借阅规则的时候,借阅成功.并将结果写入到数据库中.读者归还书籍时,将图书交给图书管理员,管理员把书籍的编号和读者的借阅证号输入系统,系统核对借阅规则,对违规(如超期)的读者进行罚款之类的,如图:

图书借阅流程图

3.4.3,图书管理:

图书管理主要实现的功能是对新购的图书进行入库和废书记录从库中删除,当新书被放入图书馆时,管理员登录进入系统,把图书的信息添加到图书馆管理系统中,并指定是放到哪一个位置,这时图书可以被用户查询到,并可以借阅.当要把一本废书删除时,图书管理员登录进入系统,查找到这一本书,并将其删除.这时,这一本图书不再能被查询到

图书管理流程图

3.4.4,借阅管理:

本部分是对借阅凭证进行管理,并对用户的一些基本信息进行维护,提供增,删,改等功能.每一个借阅凭证都要符合用户规则巨鼎可以借阅书籍的等级,如:借书时间,种类等.当读者借阅凭证丢失时,可以进行挂失处理,持失之后借阅凭证失效,如图:

借阅凭证管理流程图

3.4.5,借阅规则管理:

借阅规则包括借阅时间,可借阅的图书数目等.这一部分可以对借阅规则进行管理,主要是增,删,改,操作,如图:

借阅规则管理流程图

3.4.6,借还图书功能流程图:

借阅还功能流程图

3.5,数据库设计:

表一:书籍信息:

E-R图: 创建四张表,bookinfo,bookno,species和status

书籍E-R图
bookinfo表创建代码:
CREATE TABLE `bookinfo` (
  `id` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT 'id',
  `bookname` char(24) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '书名',
  `author` char(24) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '作者',
  `speciesno` int NOT NULL COMMENT '种类编号',
  `describe` varchar(250) NOT NULL COMMENT '描述',
  `price` int NOT NULL COMMENT '单价',
  `place` char(24) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '位置',
  `statusno` int NOT NULL COMMENT '状态编号',
  PRIMARY KEY (`id`),
  KEY `statusno` (`statusno`),
  KEY `speciesno` (`speciesno`),
  CONSTRAINT `speciesno` FOREIGN KEY (`speciesno`) REFERENCES `species` (`speciesno`),
  CONSTRAINT `statusno` FOREIGN KEY (`statusno`) REFERENCES `status` (`statusno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+———–+—————————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———–+—————————+——+—–+———+—————-+
| id | int(10) unsigned zerofill | NO | PRI | NULL | auto_increment |
| bookname | char(24) | NO | | NULL | |
| author | char(24) | NO | | NULL | |
| speciesno | int | NO | MUL | NULL | |
| describe | varchar(250) | NO | | NULL | |
| price | int | NO | | NULL | |
| place | char(24) | NO | | NULL | |
| statusno | int | NO | MUL | NULL | |
+———–+—————————+——+—–+———+—————-+

bookno表创建代码:
CREATE TABLE `bookno` (
  `bookno` char(24) NOT NULL,
  `statusno` int NOT NULL,
  `id` int(10) unsigned zerofill NOT NULL,
  PRIMARY KEY (`bookno`),
  KEY `id` (`id`),
  KEY `status` (`statusno`),
  CONSTRAINT `id` FOREIGN KEY (`id`) REFERENCES `bookinfo` (`id`),
  CONSTRAINT `status` FOREIGN KEY (`statusno`) REFERENCES `status` (`statusno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+———-+—————————+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+———-+—————————+——+—–+———+——-+
| bookno | char(24) | NO | PRI | NULL | |
| statusno | int | NO | MUL | NULL | |
| id | int(10) unsigned zerofill | NO | MUL | NULL | |
+———-+—————————+——+—–+———+——-+

species表创建代码:
CREATE TABLE `species` (
  `speciesno` int NOT NULL AUTO_INCREMENT COMMENT '种类编号',
  `species` char(24) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '种类',
  PRIMARY KEY (`speciesno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+———–+———+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———–+———+——+—–+———+—————-+
| speciesno | int | NO | PRI | NULL | auto_increment |
| species | char(24) | NO | | NULL | |
+———–+———+——+—–+———+—————-+

status表创建代码:
CREATE TABLE `status` (
  `statusno` int NOT NULL AUTO_INCREMENT COMMENT '状态编号',
  `status` char(24) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '状态',
  PRIMARY KEY (`statusno`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
表结构:

+———-+———+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———-+———+——+—–+———+—————-+
| statusno | int | NO | PRI | NULL | auto_increment |
| status | char(24) | NO | | NULL | |
+———-+———+——+—–+———+—————-+

表二:租书信息:

E-R图: 创建三个表orders表和penalty表以及type表

租书e-r图
orders表:
CREATE TABLE `orders` (
  `ordernum` char(16) NOT NULL COMMENT '订单编号',
  `code` char(24) NOT NULL COMMENT '账号',
  `typeno` int NOT NULL COMMENT '账号类型编号',
  `bookname` char(24) NOT NULL COMMENT '书名',
  `bookno` char(24) NOT NULL COMMENT '书籍编号',
  `lendtiem` date NOT NULL COMMENT '借书时间',
  `repaytime` date NOT NULL COMMENT '还书时间',
  `overdue` int NOT NULL COMMENT '逾期',
  `penalty` int NOT NULL COMMENT '罚款',
  `penaltystatusno` int NOT NULL COMMENT '罚款状态编号',
  `statusno` int NOT NULL COMMENT '状态编号',
  `operator` char(24) NOT NULL COMMENT '操作员',
  PRIMARY KEY (`ordernum`),
  KEY `statusid` (`statusno`),
  KEY `bookno` (`bookno`),
  KEY `typeno` (`typeno`),
  KEY `penalty` (`penaltystatusno`),
  CONSTRAINT `bookno` FOREIGN KEY (`bookno`) REFERENCES `bookno` (`bookno`),
  CONSTRAINT `penalty` FOREIGN KEY (`penaltystatusno`) REFERENCES `penalty` (`penaltystatusno`),
  CONSTRAINT `statusid` FOREIGN KEY (`statusno`) REFERENCES `status` (`statusno`),
  CONSTRAINT `typeno` FOREIGN KEY (`typeno`) REFERENCES `type` (`typeno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+—————–+———-+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+—————–+———-+——+—–+———+——-+
| ordernum | char(16) | NO | PRI | NULL | |
| code | char(24) | NO | | NULL | |
| typeno | int | NO | MUL | NULL | |
| bookname | char(24) | NO | | NULL | |
| bookno | char(24) | NO | MUL | NULL | |
| lendtiem | date | NO | | NULL | |
| repaytime | date | NO | | NULL | |
| overdue | int | NO | | NULL | |
| penalty | int | NO | | NULL | |
| penaltystatusno | int | NO | MUL | NULL | |
| statusno | int | NO | MUL | NULL | |
| operator | char(24) | NO | | NULL | |
+—————–+———-+——+—–+———+——-+

penalty表 :
CREATE TABLE `penalty` (
  `penaltystatusno` int NOT NULL AUTO_INCREMENT COMMENT '罚款状态编号',
  `penaltystatus` char(24) NOT NULL COMMENT '罚款状态',
  PRIMARY KEY (`penaltystatusno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+—————–+———-+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+—————–+———-+——+—–+———+—————-+
| penaltystatusno | int | NO | PRI | NULL | auto_increment |
| penaltystatus | char(24) | NO | | NULL | |
+—————–+———-+——+—–+———+—————-+

type表:
CREATE TABLE `type` (
  `typeno` int NOT NULL AUTO_INCREMENT COMMENT '类型编号',
  `type` char(24) NOT NULL COMMENT '账号类型',
  PRIMARY KEY (`typeno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+——–+———-+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+——–+———-+——+—–+———+—————-+
| typeno | int | NO | PRI | NULL | auto_increment |
| type | char(24) | NO | | NULL | |
+——–+———-+——+—–+———+—————-+

表三:工作人员表:

E-R图: 创建三个表employee表,department表和post表

员工E-R图
employee表:
CREATE TABLE `employee` (
  `no` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '员工编号',
  `name` char(16) NOT NULL COMMENT '姓名',
  `sex` char(4) NOT NULL COMMENT '性别',
  `age` int NOT NULL COMMENT '年龄',
  `postno` int NOT NULL COMMENT '职位编号',
  `departmentno` int NOT NULL COMMENT '部门编号',
  `entrytime` date NOT NULL COMMENT '入职时间',
  `quittime` date DEFAULT NULL COMMENT '离职时间',
  PRIMARY KEY (`no`),
  KEY `department` (`departmentno`),
  KEY `post` (`postno`),
  CONSTRAINT `department` FOREIGN KEY (`departmentno`) REFERENCES `department` (`departmentno`),
  CONSTRAINT `post` FOREIGN KEY (`postno`) REFERENCES `post` (`postno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+————–+—————————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————–+—————————+——+—–+———+—————-+
| no | int(10) unsigned zerofill | NO | PRI | NULL | auto_increment |
| name | char(16) | NO | | NULL | |
| sex | char(4) | NO | | NULL | |
| age | int | NO | | NULL | |
| postno | int | NO | MUL | NULL | |
| departmentno | int | NO | MUL | NULL | |
| entrytime | date | NO | | NULL | |
| quittime | date | YES | | NULL | |
+————–+—————————+——+—–+———+—————-+

department表:
CREATE TABLE `department` (
  `departmentno` int NOT NULL AUTO_INCREMENT COMMENT '部门编号',
  `department` char(24) NOT NULL COMMENT '部门',
  `postno` int NOT NULL COMMENT '职位编号',
  PRIMARY KEY (`departmentno`),
  KEY `postid` (`postno`),
  CONSTRAINT `postid` FOREIGN KEY (`postno`) REFERENCES `post` (`postno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+————–+———-+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————–+———-+——+—–+———+—————-+
| departmentno | int | NO | PRI | NULL | auto_increment |
| department | char(24) | NO | | NULL | |
| postno | int | NO | MUL | NULL | |
+————–+———-+——+—–+———+—————-+

post表:
CREATE TABLE `post` (
  `postno` int NOT NULL AUTO_INCREMENT COMMENT '部门编号',
  `post` char(24) NOT NULL COMMENT '职位',
  PRIMARY KEY (`postno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+——–+———-+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+——–+———-+——+—–+———+—————-+
| postno | int | NO | PRI | NULL | auto_increment |
| post | char(24) | NO | | NULL | |
+——–+———-+——+—–+———+—————-+

表四:管理员表:

E-R图: 创建两张表operate表和admin表

管理员E-R图
admin表:
CREATE TABLE `admin` (
  `username` char(16) NOT NULL COMMENT '用户名',
  `password` char(16) NOT NULL COMMENT '密码',
  `grade` int NOT NULL COMMENT '等级',
  `logintime` datetime NOT NULL COMMENT '登录时间',
  `operateno` bigint NOT NULL COMMENT '操作记录编号',
  PRIMARY KEY (`username`),
  KEY `operate` (`operateno`),
  CONSTRAINT `operate` FOREIGN KEY (`operateno`) REFERENCES `operate` (`operateno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+———–+———-+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+———–+———-+——+—–+———+——-+
| username | char(16) | NO | PRI | NULL | |
| password | char(16) | NO | | NULL | |
| grade | int | NO | | NULL | |
| logintime | datetime | NO | | NULL | |
| operateno | bigint | NO | MUL | NULL | |
+———–+———-+——+—–+———+——-+

operate表:
CREATE TABLE `operate` (
  `operateno` bigint NOT NULL COMMENT '操作记录编号',
  `operate` char(24) NOT NULL COMMENT '操作',
  `operatetime` datetime NOT NULL COMMENT '操作时间',
  PRIMARY KEY (`operateno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+————-+———-+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+————-+———-+——+—–+———+——-+
| operateno | bigint | NO | PRI | NULL | |
| operate | char(24) | NO | | NULL | |
| operatetime | datetime | NO | | NULL | |
+————-+———-+——+—–+———+——-+

表五:用户表

E-R图: 创建两张表bookcart和account表

用户E-R图
account表:
CREATE TABLE `account` (
  `username` char(16) NOT NULL COMMENT '用户名',
  `password` char(16) NOT NULL COMMENT '密码',
  `age` int NOT NULL COMMENT '年龄',
  `sex` char(4) NOT NULL COMMENT '性别',
  `phone` char(11) NOT NULL COMMENT '电话',
  `balance` double NOT NULL DEFAULT '0' COMMENT '余额',
  `statusno` int NOT NULL COMMENT '状态',
  `code` char(16) NOT NULL COMMENT '卡号',
  PRIMARY KEY (`username`),
  KEY `code` (`code`),
  CONSTRAINT `code` FOREIGN KEY (`code`) REFERENCES `bookcart` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+———-+———-+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+———-+———-+——+—–+———+——-+
| username | char(16) | NO | PRI | NULL | |
| password | char(16) | NO | | NULL | |
| age | int | NO | | NULL | |
| sex | char(4) | NO | | NULL | |
| phone | char(11) | NO | | NULL | |
| balance | double | NO | | 0 | |
| statusno | int | NO | | NULL | |
| code | char(16) | NO | MUL | NULL | |
+———-+———-+——+—–+———+——-+

bookcart表:
CREATE TABLE `bookcart` (
  `code` char(16) NOT NULL COMMENT '卡号',
  `name` char(16) NOT NULL COMMENT '姓名',
  `phone` char(16) NOT NULL COMMENT '电话',
  `balance` double NOT NULL DEFAULT '0' COMMENT '余额',
  `statusno` int NOT NULL COMMENT '状态',
  `username` char(16) DEFAULT NULL COMMENT '用户名',
  PRIMARY KEY (`code`),
  KEY `username` (`username`),
  CONSTRAINT `username` FOREIGN KEY (`username`) REFERENCES `account` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构:

+———-+———-+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+———-+———-+——+—–+———+——-+
| code | char(16) | NO | PRI | NULL | |
| name | char(16) | NO | | NULL | |
| phone | char(16) | NO | | NULL | |
| balance | double | NO | | 0 | |
| statusno | int | NO | | NULL | |
| username | char(16) | YES | MUL | NULL | |
+———-+———-+——+—–+———+——-+

四,程序设计与编码:

4.1 ,系统注册界面

系统注册界面分为三个页面用来对应不同的用户,这样可以实现用户与管理者的分流.

这是进入系统时的身份资格的获取,只有通过了申请的用户才能登录使用系统

customer用户:

customer用户注册界面

流程图:

customer用户注册流程图

核心代码:

员工:不支持直接访问,需要在具有相应权限的管理员账户页面进入

employee用户注册界面

流程图:

employee用户注册路程图

核心代码:

管理员:不支持非管理员低级用户直接访问,需要在相应权限的管理员账户的页面进入

admin用户注册界面

流程图:

admin用户注册流程图

核心代码:

4.2 ,系统登录界面:

系统登录界面分为三个页面用来对应不同的用户,这样可以实现用户与管理者的分流.

这是进入系统时的身份验证,用户首先要申请用户名和密码,才可以进入.

customer用户:

customer用户登录界面

流程图:

customer用户登录流程图

核心代码:

员工:

employee用户登录界面

流程图:

employee用户登录流程图

核心代码:

管理员:

admin用户登录界面

流程图:

admin用户登录流程图

核心代码:


文章作者: 火乐
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 火乐 !
  目录