图书管理系统(三)——借书还书
- 需求分析
- 视图
- 借书
- 还书
本项目以及配套数据库已经上传到CSDN,大家可根据需要下载:
- 项目
- 数据库
需求分析
- 若用户有超期未归还书籍的行为则不准再借书
- 用户要借的这本书需在馆
- 假定一条数据是一本书(也可以加一个字段用于描述书本的数量,这里我简略操作了)
- 用户还的书,必须是TA已经借出去的书
- 如果还书时发现有超期行为,则需要提示用户超期了多少天
上面说了那么多,说白了就是要符合实际情况,满足数据库的基本性质。大家也可以自行增加更多需求。
分析完上面的需求后,我们发现,在用户端需要有一个表格用户显示“我借的书”,其中的字段包括了书籍的基本信息、借书时间、应归时间、是否归还,用户id这些字段。而在我们的数据库设计中,并没有一个表格完全包含了这些字段,我们要怎么显示呢?
使用视图可以帮助我们解决这个问题。
视图
- 在navicat中右击视图,点击新建。
- 看到这个“视图创建工具”,打开以后,就可以勾选我们所需要的字段了,注意这里不能勾选表的主键。同时要特别注意你的勾选顺序,生成的视图中的字段顺序就是勾选顺序。如果发现顺序有误,还可以通过下面框进行拖动调整。我将这个视图命名为mybooks。
借书
- 在程序启动时首先检查数据库里的借书记录,是否随着时间的推移出现了超期未归还的行为。
void checkwarning1(){
//在程序启动时检查,随着时间的推移,用户是否有超期记录,如果有,则将warning字段设置为yes
QSqlQuery query;
QString sql=QString("select user_id from userbooks where is_return='否' and return_date-now()<0");//未归还且超期了
query.exec(sql);
if(query.size()!=0){//存在超期的用户
while(query.next()){
QString sql1=QString("update users set warning='yes' where id=%0").arg(query.value(0).toInt());//将这些用户的warning改为yes
query.exec(sql1);
}
}
}
我们就只需要把对应的数据进行修改,其他的东西都是一环扣一环。把上面这个checkwarning1()放到main函数里面,就可以实现在程序启动时检查用户超期行为这个功能了。
- 借书成功的话,userbooks中需要增加一条信息,books中对应的书籍需要更改状态。
参考界面:
用户登录进去将看到以下界面,查询部分和管理员端是差不多的,可以直接套用。至于其他按钮的实现方法,都很简单,看了前两章后就可以掌握。
这个界面需要新建ui文件,我命名为“userinterface”
点击“我的”按钮,进入个人空间,下面表中显示的就是“我借的书”。
这个界面需要新建ui文件,我命名为“myinformation”
void myinformation::on_borrowButton_clicked()//对应借书按钮
{
ui->label_9->clear();
QString id=ui->lineEdit->text();
int int_id=id.toInt();
QSqlQuery query;
QString status;
if(isid(int_id)){//判断用户输入的确实是个数据库中存在的id
QString sql0=QString("select * from books where id=%0").arg(int_id);
query.exec(sql0);
while(query.next())
{
status=query.value(7).toString();
}//找到该书的状态
if(status=="未借出"){
QString sql=QString("select warning from users where number='%1'").arg(login::number);
//和上面的checkwarning1扣起来了,这里就在检查warning的情况
query.exec(sql);
while(query.next())
{
if(query.value(0).toString()!="yes"){
QString sql1=QString("insert into userbooks(user_id,book_id,borrow_date,return_date,is_return) values(%1,%2,now(),date_add(now(),interval 1 month),'否')").arg(login::id).arg(int_id);
//往userbooks中插入一条记录,注意日期的用户,这里设置归还书籍的时间间隔为一个月
QString sql2=QString("update books set status='已借出' where id=%0").arg(int_id);
//修改书籍的状态
if(query.exec(sql1)&&query.exec(sql2)){//执行上面这些sql语句
model->submitAll();
model->setTable("mybooks");//显示我们更改新建的视图
setTitle();
model->select();
model->removeColumn(10);
QMessageBox::information(NULL,"借书成功","借书成功!");
}
else{
QMessageBox::warning(NULL,"数据库出错","数据库出错!");
}
}
else{
QMessageBox::warning(NULL,"借书失败","您有超期的图书还未归还,不能借书!");
}
}
}
else{
QMessageBox::warning(NULL,"借书失败","该图书已被借出!");
}
}
else{
QMessageBox::warning(NULL,"借书失败","填写的id不符合规定!");
}
}
//检查输入id确实是存在于数据库里面
bool myinformation::isid(int id)
{
bool res=false;
QString sql=QString("select id from books");
QSqlQuery query;
query.exec(sql);
while(query.next())
{
if(id==query.value(0).toInt()){
res= true;
break;
}
}
return res;
}
还书
- 还书后,userbooks中的记录并不会被删除,只需将其中is_return字段修改为‘是’。书籍的状态需要修改。用户的warning状态可能会被修改。
void myinformation::on_returnButton_clicked()
{
QString id=ui->lineEdit_2->text();
int int_id=id.toInt();//书的id
QSqlQuery query;
QString sql=QString("update userbooks set is_return='是' where book_id=%2").arg(int_id);
QString sql2=QString("update books set status='未借出' where id=%0").arg(int_id);
if(isid2(int_id)){//检查输入的合理性
QDateTime current_date_time =QDateTime::currentDateTime();
int timeT = current_date_time.toTime_t();
int ndaysec = 24*60*60;
QString sql3=QString("select * from userbooks where book_id=%2 and return_date-now()<0 and is_return='否'").arg(int_id);
//找出即将操作的那一条记录
query.exec(sql3);
while(query.next())
{
if(query.size()==1){
QDateTime return_date=query.value(4).toDateTime();//获取应归还日期,算出超期天数
int timeT2=return_date.toTime_t();
int day=(timeT-timeT2)/(ndaysec)+((timeT-timeT2)%(ndaysec)+(ndaysec-1))/(ndaysec)-1;
QString str_day=QString::number(day);
ui->label_9->setText("本书归还时间已超期"+str_day+"天!");
break;
}
}
if(query.exec(sql)&&query.exec(sql2)){
checkwarning2();//在还书后进行的check
model->submitAll();
model->setTable("mybooks");
setTitle();
model->select();
model->removeColumn(10);
QMessageBox::information(NULL,"还书成功","还书成功!");
}
else
QMessageBox::warning(NULL,"数据库出错","数据库出错!");
}
else{
QMessageBox::warning(NULL,"还书失败","所填写的id不符合规定!");
}
}
void myinformation::checkwarning2(){
//在用户还书完成后检查,看此时,用户的warning是否将改动为no
QSqlQuery query;
QString sql=QString("select * from userbooks where user_id=%1 and is_return='否' and return_date-now()<0").arg(login::id);
query.exec(sql);
if(query.size()==0){
QString sql1=QString("update users set warning ='no' where id=%0").arg(login::id);
query.exec(sql1);
}
}
//判断用户输入的id确实是TA借出的书,并且还没有归还
bool myinformation::isid2(int id)
{
bool res=false;
QString sql=QString("select book_id from userbooks where user_id=%1 and is_return='否'").arg(login::id);
QSqlQuery query;
query.exec(sql);
while(query.next()){
if(id==query.value(0).toInt()){
res= true;
break;
}
}
return res;
}
至此,我们就实现了用户借书还书的过程。整个系统已经可以跑通。
当然,系统依然存在很多其他的需求:
- 用户要查看、修改自己的个人信息或密码
- 注册时对证号和密码有格式要求
- 在注册添加学院字段时,使用下拉框的样式
- 在管理员添加书籍的“借还状态”等字段时,需要使用下拉框的样式;添加用户的“性别”等字段时,也需要使用下拉框的样式
- 表格的形式看着不舒服,特别是当书籍摘要部分很多时看着更不方便,我想要双击这一行就能看到该行数据的详情
- 我还想直接在表格中添加按钮来操作这一行
- 在用户界面加一个按钮筛选出用户没有还的书
- 在用户界面高亮或用红色颜色标出TA没有还的书
…
还有很多的需求都可以被提出并且实现,今后的章节我将挑选其中几点进行更新。当然,能看到这里的你,相信已经具备了完成以上功能的能力。有任何问题欢迎评论~ 如果觉得这篇文章有帮到你的话,不妨点个赞哦~