Library Manage System
It is suggested that you can directly look at my github. The pictures here do not support
https://github.com/interval-package/Library_Manage_System.git
Article directory
- Library Manage System
- 1. Demand analysis
- 2. Overall design
- 3. Detailed design
- 4. Test and analysis of program running results
- 5. Conclusion and experience
1. Demand analysis
Mobile Internet technology is widely used in the process of library digitization with remarkable effects. This not only makes up for the inefficiency and difficulty in management of the traditional library management model, but also facilitates many readers and users. The overall digitization of libraries is also the future development trend.
The library information management system database is used to collect and store book information, people (readers, librarians) information, book borrowing information and accident processing information, and record and store information changes in various links in a timely manner for management, query, display, and output. While saving a lot of manpower and material resources, people are freed from the complicated manual recording methods, and at the same time, it effectively guarantees the efficient operation of the library's daily affairs.
The library management system can greatly improve the daily operation efficiency of the library. Librarians and readers use this system to perform functions such as book management, reader management, book borrowing, book search, and viewing borrowing records, which can enhance the user experience of all parties. Free users from complicated data processing.
This article starts from the actual needs of library management, analyzes the specific needs, designs each module, realizes the humanization and intelligence of book lending management, makes book management more standardized, convenient and fast, and is closer to people's lives.
This paper uses the 4+1 view method to design the architecture according to different requirements. The "4+1" view model is a very general model, which can define various components of the architecture in each view, and can also choose different architectural styles for different views.
In this paper, the "4+1" model adopts UML as the expression and interpretation environment of each view, and unifies the modeling description language of each part, which is conducive to cooperative development and communication between developers at all levels and links, and establishes a realistic The model balances the contradiction between software quality and development cycle, and accelerates software development and promotion. The combination of "4+1" architecture description method and Unified Modeling Language UML can overcome the current dilemma of software development and improve the efficiency of software development and component reuse.
In this course design, based on the task requirements, we designed a library management system. Considering various aspects, we believe that our system has the following basic requirements:
interface requirements
User interface is the medium between human and computer. The user exchanges information with the computer through the user interface. Therefore, the quality of the user interface is directly related to whether the performance of the application system can be fully utilized, and whether users can work accurately, efficiently, easily and happily. Therefore, the friendliness and ease of use of software are very important to the software system.
For our library management system, we have summarized the following basic requirements for user interaction experience:
interface elements
Usually, the elements of a user interface include the main color of the interface, font color, font size, interface layout, interface interaction mode, interface function distribution, and interface input and output modes. Among them, elements that have a significant impact on user work efficiency include: input and output methods, interaction methods, and function distribution.
As a whole, the software interface as a whole, any element in it that does not conform to the user's habits and requirements will reduce the user's recognition of the software system, and even affect the user's work efficiency, so that the user will eventually give up using the system.
For our library management system:
- The interface should be concise yet able to cover all functional requirements.
- Each corresponding function needs to be managed by paging.
- The page jump function should be comprehensive.
- Users can freely make choices for each item on the interface, and all choices are reversible. Informing users when they make risky choices is an effective way to reduce user error.
user role
Think what they think, do what they do. Users always understand and use it in their own way. User-centered design ( User Centered Design ) is adopted in the interface design to allow users to truly participate in the interface design. Reflecting the user's thoughts in the final interface design is the key to designing a user interface that satisfies the user.
For our library management system, we mainly face:
- student user
- teacher user
- librarian user
- For admin users, we want to allow advanced actions
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-HkOpRQWW-1653025184570)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Process_pic\UserRole.png)]
Functional Requirements
For our system, our functional requirements can be basically divided into the following categories:
basic functional elements
It mainly includes managing the inventory information of books, the borrowing information of each book, and the borrowing information of each person.
- The inventory information of each book includes number, title, author, publishing house, publication date, amount, category, total storage quantity, current inventory, number of books that have been lent, etc.
- Each borrowed book includes the following information: serial number, book title, amount, library card number, borrowing date, due date, fine amount, etc.
- Each person's borrowing information includes library card number, name, class, student number, etc.
Borrowing materials management
Books, periodicals, and newspapers are required to be classified and managed. In this way, the operation will be more flexible and convenient, and related materials can be added, deleted, modified, and inquired at any time.
Borrowing management
(1) Lending operation: the user can retrieve, query, and select the target book through the interface.
(2) Book return operation: the user can return the selected book type or perform the amount compensation operation on the target interface in the operation interface.
(3) Renewal processing: For books that have reached the deadline, the user can renew the loan through the amount compensation in the interface.
reader management
Reader level: Classify the readers, for example, teachers and students. And define the number of books that can be borrowed for each type of readers and the related borrowing time and other information.
Reader management: Reader information can be entered, and readers can be reported for loss or logout, query and other services.
In this book management system, the end users are librarians and borrowers. Among them, the borrowers can only query the book bibliography, and the librarian can perform all operations, so the librarian is required to fully grasp the system. Readers can check the library bibliography and check their own borrowing information through the library card. Administrators can register books for lending, add/delete new books, query bibliographic information, and query borrowing information through this system.
Statistical Analysis
Statistical analysis can be carried out at any time, so as to keep abreast of the current borrowing situation and the status of related materials. Statistical analysis includes borrowing rankings, data status statistics and borrowing statistics, and functional analysis such as displaying information on all books that are due and not returned within the current day.
System parameter setting
You can set related system server parameters such as the amount of fines and the maximum number of borrowing days.
Extended functional elements
Information export
For super users, it is allowed to directly query the data, and the data of the query results can be exported to the excel table by selecting the path.
Migrating Functional Elements
local and cloud
It should be designed to be able to use multiple database methods, which can be connected to the local built-in server, and should also be able to connect to the cloud server through the address.
Safety Functional Elements
Ensure that only superusers can modify the data in detail.
Ensure that only superusers can enter the authority management interface, or directly modify the database.
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-lkxhTdZq-1653025184572)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Process_pic\Safety.png)]
performance requirements
Data Accuracy
The recall rate and precision rate of the query are guaranteed to be 100%. All records containing the query keyword in the corresponding field can be found, and all records not containing the query keyword in the corresponding field cannot be found.
system response time
-
n Single record query time is less than 3 seconds
-
n multiple record query time is less than 6 seconds
-
n update/save record time is less than 2 seconds
adaptability
Satisfy the requirements of the operating environment to allow safe transition between operating systems and independent operation with other application software
operational requirements
need | |
---|---|
User Interface | Using the browser interface structure and adopting the navigation bar interface method, try to bring convenience and user-friendliness to the operating users; support the mouse and keyboard separately. |
hardware interface | This software needs to be supported by the Internet, and the user's hardware platform should be able to connect to the Internet. |
software interface | Run on Windows98 and higher versions of the Windows operating system, or other systems. |
Troubleshooting | There should be no errors during normal use. If an unrecoverable system error is encountered during operation, the database must also be kept intact |
2. Overall design
Logic flow design
Login logic flow
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-lolqqX6f-1653025184573)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Process_pic\login_logic.png)]
Borrowing process logic
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-75mZsths-1653025184574) (D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Process_pic\rentting_logic.png)]
Administrator rights process
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-Dr2ODJac-1653025184574) (D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Process_pic\superpage_logic.png)]
Page logic design
In this practice, the pyqt framework is mainly used for development.
PyQt
Implements a Python module set. It has more than 300 classes and nearly 6000 functions and methods. It is a multi-platform toolkit that runs on all major operating systems, including UNIX, Windows and Mac. PyQt
With dual licenses, developers can choose between GPL and commercial licenses. Prior to this, the GPL version could only be used on Unix, PyQt
starting from version 4 of the GPL license can be used on all supported platforms.
UI logic flow
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-yucevw5C-1653025184575) (D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Process_pic\user_page_logic.png)]
object design
In this practice, we are basically divided into three categories of objects:
- Function class object
- interface class object
- exception class object
Function class object:
Mainly responsible for data storage and data interaction with the database.
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-2C8q79FF-1653025184575) (D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\obj_pic\basic_util_class.png)]
interface object:
Since we are using the Qt framework, each interface is defined in the form of a class. Between different classes and objects, there is a relationship of nesting and inheritance. The basic relationship is shown in the relationship diagram below.
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-lqrucjCq-1653025184576)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\obj_pic\page_objs.png)]
exception object:
In the process of program design, due to the user's unsafe operation, or some normal operations that do not meet the requirements and are rejected, the program will cause abnormalities.
At the same time, we pass the request failure information through exceptions, and form error pop-up windows through exception handling. Mainly use the qt native error family and the sql error family.
Database Design
local database structure
The sqlite lightweight database is built in the source code of this project, which can be used directly by users.
SQLite, a lightweight database, is an ACID-compliant relational database management system contained in a relatively small C library. It is D.RichardHipp
an established public domain project. Its design target is embedded, and it has been used in many embedded products. It occupies very low resources. In embedded devices, only a few hundred K of memory may be enough. It can support mainstream operating systems such as Windows/Linux/Unix, and can be combined with many programming languages, such as Tcl
C#, PHP, Java, etc., and has an ODBC interface Mysql
. As far as the database management system is concerned, its processing speed is faster than them. The first Alpha version of SQLite was born in May 2000. It has been nearly 21 years since 2021, and SQLite has also ushered in a version SQLite 3 has been released.
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-BOsWSF3W-1653025184576)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Outter\sqlite.png)]
remote database structure
This system supports SQL server database at the same time, and supports remote connection.
SQL Server is a relational database management system launched by Microsoft Corporation. With the advantages of ease of use, good scalability and high degree of integration of related software, it can be used across a variety of platforms from laptops running Microsoft Windows 98 to large multi-processor servers running Microsoft Windows 2012.
Microsoft SQL Server is a comprehensive database platform that provides enterprise-class data management with integrated business intelligence (BI) tools. The Microsoft SQL Server database engine provides a more secure and reliable storage function for relational data and structured data, enabling you to build and manage highly available and high-performance data applications for business.
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-ToRV16t3-1653025184577)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\Outter\sql_server.png)]
3. Detailed design
basic object
overview
## 基本功能对象
class DataLoader(object)
class LoginUserDataLoader(DataLoader):
def __init__(self, user, password)
class BasicUser(object):
def __init__(self, user_id, user_name, role, password)
## 界面显示对象
# 主界面
class Ui_MainWindow(object)
class MainWindow(QMainWindow, Ui_MainWindow)
# 登录界面
class Ui_LoginPage(object)
class LoginPage(QtWidgets.QWidget, Ui_LoginPage)
# 注册界面
class Ui_SignUpPage(object)
class SignUpPage(QtWidgets.QWidget, Ui_SignUpPage)
# 用户界面
class Ui_Form(object)
class UserPage(QtWidgets.QWidget, Ui_Form)
# 借书界面
class Ui_RentingPage(object)
class RentingPage(QtWidgets.QWidget, Ui_RentingPage)
# 归还界面
class Ui_ReturnPage(object)
class ReturnPage(QtWidgets.QWidget, Ui_ReturnPage)
detailed introduction
basic function object
DataLoader
Initialize the database for importing data. Encapsulate the database access interface and adapt to cloud and local services.
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-ZADHPc8i-1653025184577)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\obj_pic\dataloader.png)]
BasicUser
User object model:
field | |
---|---|
user info | Basic User Information |
user rent history | User's Borrowing Information |
interface display object
For each interface, we have two interface classes, responsible for different functions.
UI_Page
负责界面内容ui的绘制与初始化。
Page_Wrapper
时UI_Page的子类,在UI_Page初始化ui的前提下,实现逻辑功能与转跳。
Main interface
class Ui_MainWindow(object)
class MainWindow(QMainWindow, Ui_MainWindow)
def __init__(self)
The initialization function is responsible for undertaking the content initialization of the UI class.
param | type | description |
---|---|---|
returns | none | no return |
def setIcon(self)
set label function, set the label of our function
param | type | description |
---|---|---|
returns | none | no return |
def switchPage(self, index)
The page switching function performs conversion and loading of the first-level main interface.
Use class QStackedWidget(QFrame)
to switch, and all page content is mounted on it.
param | type | description |
---|---|---|
index | int | Page number to switch |
throws | index error | |
returns | none |
def LoginPage_Login(self)
The main logic of the login interface.
Call self.LoginPage.Login()
to perform user login logic.
Pass parameters to other pages.
param | type | description |
---|---|---|
returns | none | Obtain input information through the text box of the graphical interface |
def SuperUserAction(self)
When the user tries to access the super control, it is judged whether he has the authority to access the management page.
param | type | description |
---|---|---|
returns | none | |
throws | none | When accessing illegally, a pop-up window will pop up |
error function
def Echo_Fail_Authority(self)
The echo function is called when an attempt to perform a superuser operation is rejected.
An error pop-up window pops up to inform the user of the information.
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-zENF5sqJ-1653025184577) (D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\pop up\super fail.png) ]
param | type | description |
---|---|---|
returns | none | |
pop up | error | |
throws | printing | no exception throws, but printing. |
def SignUpPage_SignUpAction_Bind(self)
Binding function, the registration operation is performed on the registration interface. Access the text input box in the interface, get information, and access the database to add data.
param | type | description |
---|---|---|
returns | none | Bind the login logic to the target structure, initialize the login logic. |
login interface
class Ui_LoginPage(object)
class LoginPage(QtWidgets.QWidget, Ui_LoginPage)
def Login(self)
def LoginResult(self, user_id: str, password: str)
error function
-
def Echo_Login_Failed(self)
-
def Echo_Login_Empty(self)
-
def Echo_Login_Success(self)
-
def MultiUserErrorFind(self)
param | type | description |
---|---|---|
returns | none | |
pop up | Call the standard error prompt window to display the current error message |
Registration interface
class Ui_SignUpPage(object)
class SignUpPage(QtWidgets.QWidget, Ui_SignUpPage)
def SignUp_Action(self)
Get information from the text box, for registration access.
param | type | description |
---|---|---|
returns | none |
def Echo_Empty_Input(self)
Called when the registration fails, and the relevant content of the registration failure will pop up.
param | type | description |
---|---|---|
returns | none | Make a pop-up window, display an error, or a success message |
User Interface
class Ui_Form(object)
class UserPage(QtWidgets.QWidget, Ui_Form)
def SetUser(self, user)
The external parameter passing function is used to initialize the internal user object.
def updatePage(self)
Refresh the page function, call other component refresh functions, and update the content of the page input block diagram.
def updateUserInfoList(self)
To update the display of user information on the page, the following function will be called
-
def updateRentedBookInfoList(self)
-
def updateBookRankPage(self)
-
def updateUserRankPage(self)
For all functions there are:
param | type | description |
---|---|---|
returns | none | No return, but modify the page content |
def CallPayPage(self)
Call the page that pays everything owed.
Borrowing interface
class Ui_RentingPage(object)
class RentingPage(QtWidgets.QWidget, Ui_RentingPage)
def setUser(self, User)
The external parameter passing function is used to initialize the internal user object.
def SetBookType(self)
Initializes the option box, providing matching of book type name to id.
def updateRentedBookInfoList(self)
According to the query result, update the book information that has been borrowed.
Core function
def Query(self)
def Rent(self)
param | type | description |
---|---|---|
returns | none | Perform pop-up windows, display error or success information, and modify the visual interface. |
query | will access the database |
The core function function is responsible for the realization of the core function of the page, that is, the borrowing function.
The basic logic flow is as follows.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LVyZ8vba-1653025184578)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\obj_pic\rentAndQuery.png)]
报错函数
def Echo_Empty_Input(self, ms=None)
def Echo_Success_Not(self, flag)
def Echo_Fail_To_Rent(self)
param | type | description |
---|---|---|
returns | none | 进行弹窗,显示错误,或者成功信息 |
归还界面
class Ui_ReturnPage(object)
class ReturnPage(QtWidgets.QWidget, Ui_ReturnPage)
def SetUser(self, User)
设置用户数据。
def updatePage(self) -> None
更新页面信息。
def updateRentedBookInfoList(self) -> None
- 更新已经借阅信息表格。
def ReturnBook(self)
param | type | description |
---|---|---|
returns | none | |
inputs | none | 从表格中获取信息 |
权限界面
class Ui_SuperPage(object)
class SuperPage(QtWidgets.QWidget, Ui_SuperPage)
def switchPage(self, index)
进行挂载页面的切换。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xRuWViep-1653025184579)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\obj_pic\superpage.png)]
信息查询界面
class Ui_CheckInfoPage(object)
class CheckInfoPage(QtWidgets.QWidget, Ui_CheckInfoPage)
def SetTypeListDict(self)
进行类型的绑定。将可选择进行的功能与目标函数进行绑定。
页面刷新函数
-
def RefreshPageInfo(self)
- 总刷新函数,刷新页面所有内容
-
def RefreshUserList(self)
- 刷新用户列表信息
-
def RefreshBookList(self)
- 刷新图书列表信息
-
def updateBookRankPage(self) -> None
- 刷新排名页
-
def SetBookType(self)
此类函数负责页面的刷新内容
param | type | description |
---|---|---|
returns | none | |
inputs | none | 从表格中获取信息 |
def MessageOfGettingPath(self, Filepath=None)
调用内置功能模块,获取用户选择路径。
param | type | description |
---|---|---|
returns | str | 目标路径 |
inputs | none | 从表格中获取信息 |
核心功能函数
def SaveQuery(self)
保存函数,调用pandas的data frame,将目标结构保存到目标地址。创建一个新的excel文件。
def Query(self)
查询函数
def Query_User(self)
修改用户界面
class Ui_UserEditPage(object)
class UserEditPage(QtWidgets.QWidget, Ui_UserEditPage)
def CommandCommit(self)
def RefreshViews(self)
更新页面函数
def UpdateRoleView(self)
def UpdateUserView(self)
def SetBookType(self)
param | type | description |
---|---|---|
returns | none | |
inputs | none | 从表格中获取信息 |
action | 刷新多个页面 |
核心功能函数
def ChangeUserInfoAction(self)
- 修改用户信息
def AddUserAction(self)
- 添加用户
param | type | description |
---|---|---|
returns | none | |
inputs | none | 从表格中获取信息 |
核心函数调用逻辑如下:
报错函数
-
def Echo_Empty_Input(self, ms=None)
-
def Echo_Fail(self, ms)
-
def Echo_Success(self)
param | type | description |
---|---|---|
returns | none | |
inputs | none | 从表格中获取信息 |
修改书籍界面
class Ui_BookEditPage(object)
class BookEditPage(QtWidgets.QWidget, Ui_BookEditPage)
基本刷新函数
def RefreshViews(self)
def SetBookType(self)
param | type | description |
---|---|---|
returns | none | |
inputs | none | 从表格中获取信息 |
核心功能函数
def AddBookType(self)
def ChangeBookAction(self)
def AddBookAction(self)
param | type | description |
---|---|---|
returns | none | |
inputs | none | 从表格中获取信息 |
action | 访问数据库,修改信息 |
报错函数
def Echo_Empty_Input(self, ms=None)
def Echo_Fail(self, ms)
def Echo_Success(self)
param | type | description |
---|---|---|
returns | none | |
action | 调用标准报错弹窗 |
基本功能函数
概览
Query
def Query_UserRentingHis(user_id)
def Query_BookRank()
def Query_UserRank()
def Query_BookType()
def Query_BookType_Id()
def Query_Book(TypeName, BookInfo)
def Query_UnReturned_Book(UserId)
def Query_Price_Remain(UserId, BookId=None, RentDate=None)
def Modify_Return(tar)
def RentCertification(UserId, BookId) -> bool
def Add_RentHis(UserId, BookId)
def Add_Book(BookId, BookName, stock, price, BookType)
def Add_BookType(Id, Name)
def Add_User(UserId, UserName, Role, Password)
def Update_UserInfo(pack)
def Update_RentDate(UserId, BookId, RentDate)
def Update_BookInfo(pack)
def FetchAllBooks()
def FetchAllBookType()
def FetchAllRoleTypes()
def FetchAllUser()
2.详细介绍
数据库访问函数
数据库访问函数状态控制:
QueryMethod = 'sqlite'
# QueryMethod = 'sql_server'
if QueryMethod == 'sqlite':
from kernel.QueryInfoSite.QueryInfo_sqlite import *
elif QueryMethod == 'sql_server':
from kernel.QueryInfoSite.QueryInfo_MsSql import *
双内核处理方式,支持多种数据库类型访问。在修改参数后,会修改数据库访问函数的细节调用。
按照条件查询
def Query_UserRentingHis(user_id)
该函数通过调用user_id,对数据库进行访问。会被User对象调用。
返回Book.BookId, Book.BookName, BookType.TypeName, RentHistory.RentDay, RentHistory.ReturnDate
每一条记录代表着某个用户的借阅历史记录。
param | type | description |
---|---|---|
user_id | str | 用户的账号 |
returns | list | 一个两层的list结构,第一层每个元素为一个数据元组。 |
throws | none | 不会抛出异常,但是当访问出错时,会打印异常状况 |
def Query_BookRank()
该函数对数据库内容进行标准化访问。
返回查询结果结构:Book.BookId, BookName, times, Stock, Price, TypeName
按照借阅次数降序排序。
param | type | description |
---|---|---|
None | None | 无传入参数 |
returns | list | 一个两层的list结构,第一层每个元素为一个数据元组。 |
throws | none | 不会抛出异常,但是当访问出错时,会打印异常状况 |
def Query_UserRank()
该函数对数据库内容进行标准化访问,与Query_BookRank
类似。
返回查询结果结构:UserName, User.UserId, times
按照借阅次数降序排序。
param | type | description |
---|---|---|
None | None | 无传入参数 |
returns | list | 一个两层的list结构,第一层每个元素为一个数据元组。尚未进行Dict 封装。 |
throws | none | 不会抛出异常,但是当访问出错时,会打印异常状况 |
def Query_BookType()
同族类似功能函数有:
def Query_BookType_Id()
def FetchAllBookType()
获取Type信息。
param | type | description |
---|---|---|
None | None | 无传入参数 |
returns | list | 一个两层的list结构,第一层每个元素为一个数据元组。尚未进行Dict封装。 |
throws | none | 不会抛出异常,但是当访问出错时,会打印异常状况 |
def Query_Book(TypeName, BookInfo)
该函数用于查询书本列表,按照书本的类型以及书本名称(可以不用完全相等)来查找书籍。
param | type | description |
---|---|---|
TypeName |
str | 书本类型名称 |
BookInfo |
str | 书本名称部分切片 |
returns | list | 一个两层的list结构,第一层每个元素为一个数据元组。尚未进行Dict 封装。 |
throws | none | 不会抛出异常,但是当访问出错时,会打印异常状况。 |
def Query_UnReturned_Book(UserId)
按照UserId
从数据库中查询用户尚未归还的书籍。
param | type | description |
---|---|---|
UserId |
str | 读者号 |
returns | list | 一个两层的list结构,第一层每个元素为一个数据元组。尚未进行Dict 封装。 |
throws | none | 不会抛出异常,但是当访问出错时,会打印异常状况。 |
def Query_Price_Remain(UserId, BookId=None, RentDate=None)
借阅的记录由UserId
,BookId
以及借阅日期决定。
该函数有可选性功能,当未传入BookId
时,会搜索数据库中该用户所有的未归还记录,并且获得欠款数据。
当传入了BookId
数据,则指定了目标条目所带来的数据欠款数据。
req = """
select * from UnreturnPrice
where UserId = {}
""".format(str(UserId))
if BookId is not None:
req += " and BookId = '{}".format(str(BookId))
if RentDate is not None:
req += " and RentDay = '{}'".format(str(RentDate))
param | type | description |
---|---|---|
UserId |
str | 读者的id |
BookId |
str,default:none | 对应的图书id |
RentDate |
str,在数据库中会自动转换为date类型 | 借阅日期 |
returns | list | 一个两层的list结构,第一层每个元素为一个数据元组。尚未进行Dict 封装。 |
throws | none | 打印发生的异常状态 |
def Modify_Return(tar)
UserId, BookId, RentDate = tar
该函数通过
param | type | description |
---|---|---|
tar | tuple 或者list | 输入参数,必须为三元组或者是长度为3的列表,内容分别为UserId , BookId , RentDate |
returns | none | 打印借阅成功信息 |
throws | ReturnRefuse | 异常,表示传入数据包不符合要求 |
throws | sql.DatabaseError |
数据库访问异常,需要在外部捕获,表示访问失败 |
def RentCertification(UserId, BookId) -> bool
本地数据库使用,由于sqlite不支持复杂的触发器操作,则使用函数进行详细约束。
该函数进行借阅验证,测试当前用户是否还有借阅量剩余,是否有过期图书。
两次验证失败时均会抛出拒绝借阅异常。
param | type | description |
---|---|---|
UserId |
str | 读者id |
BookId |
str | 书本id |
returns | bool | 是否有效 |
throws | RentRefuse("too many books") |
借阅验证失败,超出借阅额度 |
throws | RentRefuse("no book remain") |
借阅验证失败,图书馆没有剩余书目 |
throws | sql.DatabaseError |
数据库访问异常,在外部抓取 |
添加数据类
def Add_RentHis(UserId, BookId)
该函数实现借阅功能,会调用RentCertification
进行借阅有效性的验证。
param | type | description |
---|---|---|
UserId |
str | 读者id |
BookId |
str | 书本id |
returns | none | |
throws | sql.DatabaseError |
数据库访问异常,在外部抓取 |
def Add_Book(BookId, BookName, stock, price, BookType)
由超级用户使用,用于添加书本。
param | type | description |
---|---|---|
args |
str | 一系列书本相关数据 |
returns | none | |
throws | sql.DatabaseError |
数据库访问异常,在外部抓取 |
def Add_BookType(Id, Name)
由超级用户使用,用于创建新的书本类型。
param | type | description |
---|---|---|
Id | str | 书本id |
Name | str | 书本名称 |
returns | none | none |
throws | sql.DatabaseError |
` |
def Add_User(UserId, UserName, Role, Password)
可以被超级用户,或者是读者进行注册操作的时候调用。创建新用户。
为了保护数据库安全性,该方式调用时具有限定性,只能创建老师或者是学生用户,不能创建超级用户。
param | type | description |
---|---|---|
args |
str | 读者的id,姓名,权限以及密码 |
returns | none | |
throws | sql.DatabaseError |
` |
def Update_UserInfo(pack)
超级用户使用,用于修改已有的用户的属性。
pack = dict()
for i, title in zip(self.UserView.selectionModel().selectedIndexes(), self.UserInfoHeader):
pack[title] = i.data()
Update_UserInfo(pack)
param | type | description |
---|---|---|
pack | dict |
数据包,装载格式化的传入数据参数 |
returns | none | |
throws | RentRefuse(repr(e)) |
拒绝借阅异常 |
对于打包内容需要有以下关键字:
pack['name'], pack['password'], pack['role'], pack['id']
def Update_RentDate(UserId, BookId, RentDate)
通过传入参数,查询借阅记录。同时更新借阅记录的借阅日期为当前时间。
param | type | description |
---|---|---|
UserId | str | 用户id |
BookId | str | 借阅书本id |
RentDate | str | 借阅日期 |
def Update_BookInfo(pack)
pack['name'], pack['stock'], pack['price'], pack['type id'], pack['id']
param | type | description |
---|---|---|
pack | dict | 字典包,字典结构如图所示 |
returns | none |
update Book set BookName = '{}',
Stock = '{}',
Price = '{}',
TypeId = '{}'
where BookId = '{}'
直接获取类
def FetchAllBooks()
def FetchAllRoleTypes()
def FetchAllUser()
- 获取所有用户权限信息。
- 获取所有书本的信息。
- 用于获取用户数据,该方法下获取所有用户的数据。
param | type | description |
---|---|---|
input | list | 输出查询结果 |
returns | none | 无返回 |
数据库结构详解
内置数据库
表结构
Book
CREATE TABLE Book (
BookId CHAR PRIMARY KEY
NOT NULL,
BookName CHAR,
Stock INTEGER DEFAULT (0)
CHECK (Stock >= 0)
NOT NULL,
Price INTEGER DEFAULT (0)
CHECK (Price > 0)
NOT NULL,
TypeId REFERENCES BookType (TypeId)
);
书本表,存储书本的基本数据。每一本书对应一条唯一的书本id,同时对应一条该表内的记录。
Name | Data Type | PK | FK | Unique | Check | Default |
---|---|---|---|---|---|---|
BookId |
char | true | ||||
BookName |
char | |||||
Stock |
int | 0 | ||||
Price |
int | 0 | ||||
TypeId |
char | REFERENCES BookType (TypeId) ,参照BookType表 |
not null |
BookType
CREATE TABLE BookType (
TypeId CHAR PRIMARY KEY
NOT NULL,
TypeName CHAR
);
书本类型,将书本按照不同类型分类的表,存放书本的类型。每一条记录记录一种书本类型。
Name | Data Type | PK | FK | Unique | Check | Default |
---|---|---|---|---|---|---|
TypeId |
CHAR | true | not null | |||
TypeName |
CHAR |
User
CREATE TABLE User (
UserId CHAR PRIMARY KEY
NOT NULL,
UserName CHAR,
Role REFERENCES UserRole (RoleId)
NOT NULL,
Password CHAR NOT NULL
DEFAULT (0)
);
User表存储所有的读者与管理人员信息。
Name | Data Type | PK | FK | Unique | Check | Default |
---|---|---|---|---|---|---|
UserId |
CHAR | true | ||||
UserName |
CHAR | not null | ||||
Role |
REFERENCES UserRole (RoleId ) |
not null | ||||
Password |
CHAR | not null |
UserRole
CREATE TABLE UserRole (
RoleId NUMERIC PRIMARY KEY ASC,
RoleName CHAR NOT NULL,
Duration TIME NOT NULL,
LendingTimes INT NOT NULL
);
读者类型与权限记录表,记录读者权限。
Name | Data Type | PK | FK | Unique | Check | Default |
---|---|---|---|---|---|---|
RoleId |
char | true | ||||
RoleName |
char | true | ||||
Duration |
num | check positive | 10 | |||
LendingTimes |
num | check positive | 10 |
该表正常情况下,不允许添加新项目,固定信息如下:
Role | RoleId |
Duration | LendingTimes |
---|---|---|---|
Super User |
0 | 365 | 100 |
Teacher |
1 | 30 | 10 |
Students |
2 | 10 | 5 |
系统借阅的基本参数,由该表决定,后续修改依照该表。
RentHistory
CREATE TABLE RentHistory (
UserId REFERENCES User (UserId)
NOT NULL,
BookId REFERENCES Book (BookId)
NOT NULL,
RentDay DATETIME NOT NULL,
ReturnDate DATETIME,
PRIMARY KEY (
UserId,
BookId,
RentDay
)
);
借阅记录表,该表负责记录所有的借阅与归还信息。
每次借阅都会插入一条数据,并且设置ReturnDate
的初始值为null。
对于归还了的记录,returnDate
将为非null,可以用于后续判断。
Name | Data Type | PK | FK | Unique | Check | Default |
---|---|---|---|---|---|---|
UserId |
char | true | true REFERENCES User (UserId) |
not null | ||
BookId |
char | true | true REFERENCES Book (BookId) |
not null | ||
RentDay |
Date | not null | getdate() |
|||
ReturnDate |
Date | null |
视图设计
为了方便编程,以及快速查询与修改,在设计设计库的时候,设计了一系列的视图,为后续的功能提供支持。
BookRemain
设计视图用于快速查询剩余的书本数量,用于限制借阅次数。
Select Book.BookId, Book.Stock-temp.num remain from Book
inner join
(
select BookId, count(*) num
from RentHistory
where ReturnDate is null
group by BookId
)as temp
on temp.BookId = Book.BookId
UnreturnPrice
统计所有用户目前所欠金额。
select User.UserId, Book.BookId,Book.BookName, Book.Price, RentHistory.RentDay
from Book, RentHistory, User, UserRole
where Book.BookId = RentHistory.BookId
and User.UserId = RentHistory.UserId
and USer.Role = UserRole.RoleId
and RentHistory.ReturnDate is null
and
date(RentHistory.RentDay, '+'||cast(UserRole.Duration as string)|| ' day') < date('now')
UserUnReturn_Count
统计所有用户目前未归还书本的数目。
select User.UserId, temp.times, UserRole.LendingTimes from User, UserRole,
(
select UserId, count(*) as times
from RentHistory
where ReturnDate is null
group by UserID
) as temp
where User.Role = UserRole.RoleId
and User.UserId = temp.UserId
触发器设计
sqlite无法支持复杂的触发器结构,但是我们在云端部署的SQL server数据库中,使用触发器,对于我们图书馆管理系统的完整性进行约束。
借阅有效性判断
判读是否还有剩余的书本,以及用户是否还有剩余的借阅限额。
USE [LibraryManageSystem]
GO
/****** Object: Trigger [dbo].[UserRentConstrain] Script Date: 2022/5/16 10:28:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER trigger [dbo].[UserRentConstrain]
on [dbo].[RentHistory] for insert
as
begin
declare @tempNum int
declare @boundNum int
select @tempNum = times, @boundNum = LendingTimes
from UserUnReturn_Count, inserted
where
UserUnReturn_Count.UserId = inserted.UserId
if @tempNum >= @boundNum
begin
rollback
end
end
远程链接数据库
同本地数据库结构。
四、程序运行结果测试与分析
GUI展示
普通用户流程展示
登录界面
登录成功
日历界面
注册界面
用户界面
基本用户信息界面
用户排行榜
图书排行榜
借阅界面
归还界面
初始
归还操作
续借界面
未有过期书目:
有过期书目:
尝试访问管理权限
超级用户流程展示
用户界面
权限界面
查询信息界面
修改读者信息界面
修改书本信息界面
数据输出展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fTH9hOzR-1653025184580)(D:\Coding\PythonProjects\Library_Manage_System\DisplayPics\SuperUser\SaveUserRes.png)]
五、结论与心得
任务负责
在本次的课程实践中,我负责该管理系统的全部的设计与实现工作。包括但不限于以下工作:
- 数据库ER模型设计
- 数据库模型编码实现
- UI界面设计
- UI界面前端绘制
- 业务逻辑设计
- 业务逻辑编码实现
- 成果测试检验
收获
概念收获
在本次的程序设计课程设计中,我收获了许多。首先是更加了解了软件工程的实际含义,与在实际工程中所需要的思考方式与想法。
同时更加深入地了解数据库的设计与创建过程。
了解数据库各级的形成过程:
数据库各级模式的形成过程需求分析阶段:综合各个用户的应用需求。
概念设计阶段:形成独立于机器特点,独立于各个DBMS产品的概念模式(E-R图)。
逻辑设计阶段:首先将E-R图转换成具体DBMS支持的数据模型,如关系模型,形成数据库逻辑模式;然后根据用户处理的要求、安全性的考虑,在基本表的基础上再建立必要的视图(View),形成数据的外模式。
物理设计阶段:根据DBMS特点和处理的需要,进行物理存储安排,建立索引,形成数据库内模式。
技术收获
在本次的项目中其实收获到的最大的好处就是,将之前学习到的很多内容,进行了一个梳理,同时也对知识点有了更深的印象。使得自己对于哪些python以及sql基础知识有了一个更好的理解,同时对其会产生的问题有了一个具体的了解,当我在遇到的时候就会懂得如何去修改,以及能及时发现其中的错误。
前端技术收获
深入了解学习python qt前端的框架体系。了解了前端可视化界面的总体结构。
数据库技术收获
在学习数据库和数据表创建和修改时,了解到表是建立关系数据库的基本结构,用来存储数据具有已定义的属性,在表的操作过程中,有查看表信息、查看表属性、修改表中的数据、删除表中的数据及修改表和删除表的操作。
从实践中让我更明白一些知识,表是数据最重要的一个数据对象,表的创建好坏直接关系到数数据库的成败,表的内容是越具体越好,但是也不能太繁琐,对表的规划和理解更加深刻。
同时更加深刻地了解到了不同数据库之间的不同,以及对应工作环境下的区别。
遇到困难
技术困难
- qt表格类的使用
- qt整个框架是基于c++构建的,移植到python下实际上底层内核还是使用c++编译的,无法直接查看源代码。对于部分功能的理解会有一点障碍。
- qt表格类较为复杂,是多个对象以及方法的嵌套,了解起来有点困难。
- 数据库触发设计
- sqlite作为轻量级数据库,实际上数据的管理功能是有限的。
- 在内置的功能里,不支持复杂的触发结构,需要程序员自行设计。
未实现功能
用户交互层面
用户交互设计依旧不够友好,对于部分操作还是分开进行。
例如:
- 对于修改用户权限,需要用户手动输入。对于用户权限的选择是具有局限性的选择,应当使用下拉式进行修改。
- 查询与修改操作是分开的,在修改是不能查询,查询时不能修改。
对于用户的可视化界面还不够美观。
数据库信息存储层面
- 目前而言数据模型还没有完善,对于用户只存储了基本信息,对于对书籍内容只存储了基本信息,需要后续进行拓展。
- 数据库数据的修改具有局限性,只允许管理员进行数据的修改,而用户无法对于自己的信息,进行直接修改。使得操作有时不够人性化。
网络连接层面
个DBMS产品的概念模式(E-R图)。
逻辑设计阶段:首先将E-R图转换成具体DBMS支持的数据模型,如关系模型,形成数据库逻辑模式;然后根据用户处理的要求、安全性的考虑,在基本表的基础上再建立必要的视图(View),形成数据的外模式。
物理设计阶段:根据DBMS特点和处理的需要,进行物理存储安排,建立索引,形成数据库内模式。
技术收获
在本次的项目中其实收获到的最大的好处就是,将之前学习到的很多内容,进行了一个梳理,同时也对知识点有了更深的印象。使得自己对于哪些python以及sql基础知识有了一个更好的理解,同时对其会产生的问题有了一个具体的了解,当我在遇到的时候就会懂得如何去修改,以及能及时发现其中的错误。
前端技术收获
深入了解学习python qt前端的框架体系。了解了前端可视化界面的总体结构。
数据库技术收获
在学习数据库和数据表创建和修改时,了解到表是建立关系数据库的基本结构,用来存储数据具有已定义的属性,在表的操作过程中,有查看表信息、查看表属性、修改表中的数据、删除表中的数据及修改表和删除表的操作。
从实践中让我更明白一些知识,表是数据最重要的一个数据对象,表的创建好坏直接关系到数数据库的成败,表的内容是越具体越好,但是也不能太繁琐,对表的规划和理解更加深刻。
同时更加深刻地了解到了不同数据库之间的不同,以及对应工作环境下的区别。
遇到困难
技术困难
- qt表格类的使用
- qt整个框架是基于c++构建的,移植到python下实际上底层内核还是使用c++编译的,无法直接查看源代码。对于部分功能的理解会有一点障碍。
- qt表格类较为复杂,是多个对象以及方法的嵌套,了解起来有点困难。
- 数据库触发设计
- sqlite作为轻量级数据库,实际上数据的管理功能是有限的。
- 在内置的功能里,不支持复杂的触发结构,需要程序员自行设计。
未实现功能
用户交互层面
用户交互设计依旧不够友好,对于部分操作还是分开进行。
例如:
- 对于修改用户权限,需要用户手动输入。对于用户权限的选择是具有局限性的选择,应当使用下拉式进行修改。
- 查询与修改操作是分开的,在修改是不能查询,查询时不能修改。
对于用户的可视化界面还不够美观。
数据库信息存储层面
- 目前而言数据模型还没有完善,对于用户只存储了基本信息,对于对书籍内容只存储了基本信息,需要后续进行拓展。
- 数据库数据的修改具有局限性,只允许管理员进行数据的修改,而用户无法对于自己的信息,进行直接修改。使得操作有时不够人性化。
网络连接层面
目前远程数据库只是有个雏形,目前只使用了local服务端进行模拟,总体功能还有待提升。