图书管理系统(三)——借书还书

  • 需求分析
  • 视图
  • 借书
  • 还书


本项目以及配套数据库已经上传到CSDN,大家可根据需要下载:

  1. 项目
  2. 数据库

需求分析

  1. 若用户有超期未归还书籍的行为则不准再借书
  2. 用户要借的这本书需在馆
  3. 假定一条数据是一本书(也可以加一个字段用于描述书本的数量,这里我简略操作了)
  4. 用户还的书,必须是TA已经借出去的书
  5. 如果还书时发现有超期行为,则需要提示用户超期了多少天

上面说了那么多,说白了就是要符合实际情况,满足数据库的基本性质。大家也可以自行增加更多需求。
分析完上面的需求后,我们发现,在用户端需要有一个表格用户显示“我借的书”,其中的字段包括了书籍的基本信息、借书时间、应归时间、是否归还,用户id这些字段。而在我们的数据库设计中,并没有一个表格完全包含了这些字段,我们要怎么显示呢?
使用视图可以帮助我们解决这个问题。

视图

  1. 在navicat中右击视图,点击新建。
  2. 看到这个“视图创建工具”,打开以后,就可以勾选我们所需要的字段了,注意这里不能勾选表的主键。同时要特别注意你的勾选顺序,生成的视图中的字段顺序就是勾选顺序。如果发现顺序有误,还可以通过下面框进行拖动调整。我将这个视图命名为mybooks。

借书

  1. 在程序启动时首先检查数据库里的借书记录,是否随着时间的推移出现了超期未归还的行为。
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函数里面,就可以实现在程序启动时检查用户超期行为这个功能了。

  1. 借书成功的话,userbooks中需要增加一条信息,books中对应的书籍需要更改状态。

参考界面:

用户登录进去将看到以下界面,查询部分和管理员端是差不多的,可以直接套用。至于其他按钮的实现方法,都很简单,看了前两章后就可以掌握。

这个界面需要新建ui文件,我命名为“userinterface”

mysql 书籍借还表设计 借书还书数据流程图_数据库


点击“我的”按钮,进入个人空间,下面表中显示的就是“我借的书”。

这个界面需要新建ui文件,我命名为“myinformation”

mysql 书籍借还表设计 借书还书数据流程图_sql_02

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;
}

还书

  1. 还书后,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;
}

至此,我们就实现了用户借书还书的过程。整个系统已经可以跑通。
当然,系统依然存在很多其他的需求:

  1. 用户要查看、修改自己的个人信息或密码
  2. 注册时对证号和密码有格式要求
  3. 在注册添加学院字段时,使用下拉框的样式
  4. 在管理员添加书籍的“借还状态”等字段时,需要使用下拉框的样式;添加用户的“性别”等字段时,也需要使用下拉框的样式
  5. 表格的形式看着不舒服,特别是当书籍摘要部分很多时看着更不方便,我想要双击这一行就能看到该行数据的详情
  6. 我还想直接在表格中添加按钮来操作这一行
  7. 在用户界面加一个按钮筛选出用户没有还的书
  8. 在用户界面高亮或用红色颜色标出TA没有还的书

    还有很多的需求都可以被提出并且实现,今后的章节我将挑选其中几点进行更新。当然,能看到这里的你,相信已经具备了完成以上功能的能力。有任何问题欢迎评论~ 如果觉得这篇文章有帮到你的话,不妨点个赞哦~