Qt实现图书管理系统(C++)

news2024/11/30 2:52:17

文章目录

  • 数据库表的实现
      • 创建表
      • 将powerDesigner里面的表导出成xxx.sql脚本
      • 将SQL文件导入数据库创建表
  • 图书管理系统思维导图
  • 创建工程
  • 开发阶段
        • 创建Dlg_login登录页面
        • login页面样式
        • 主页页面布局
        • 主函数测试login
        • 设置logo
        • 打包程序
        • 子页面的样子
        • 将子页面放到StackedWidget里面
        • 按钮直接形成互斥效果
      • 用属性选择器来改变样式
        • 设置user页面的标头和设置文本不可编辑
  • 创建SqlMgr类进行SQL操作
      • 初始化数据库
    • 登录功能login
    • 用户功能
      • getUsers功能
      • 导入用户(导入文件里面的数据到数据库)
      • 删除用户(del)
      • 搜索用户
    • 图书管理功能
      • 获取图书
      • 添加图书
      • 修改图书
      • 删除图书
        • 遇到的错误
      • 借阅图书
      • 搜索图书
    • 借阅记录管理功能
      • 获取借阅记录
      • 模糊查询记录
      • 归还图书
        • 出现的问题
      • 清空借阅记录
      • 登录功能
      • 页面展示

数据库表的实现

使用powerdesigner工具

创建表

在这里插入图片描述

创建三个表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

将powerDesigner里面的表导出成xxx.sql脚本

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时就会生成文件在桌面了
在这里插入图片描述

将SQL文件导入数据库创建表

在这里插入图片描述

在这里插入图片描述
运行sql文件
在这里插入图片描述
设置主键自增

图书管理系统思维导图

在这里插入图片描述

创建工程

在qt上创建一个工程项目

在这里插入图片描述

把这个四个文件发到controller文件夹下,在创建一个dao文件夹

在这里插入图片描述

controller文件夹下面是一些界面类和逻辑类,dao文件夹下就是和数据库交互的

在这里插入图片描述

进入项目

在这里插入图片描述
在这里插入图片描述

加上这一句话

include($$PWD/controller/controller.pri)
正在右键项目执行qmake
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加一句这个以后生成的目标文件都在这里(当前文件目录的上一级创建一个bin 文件夹

在这里插入图片描述

开发阶段

创建Dlg_login登录页面

在这里插入图片描述

在这里插入图片描述

login页面样式

QLabel#le_title{font:38px '方正姚体';}
QLabel#name,QLabel#pwd{font: 18px '楷体';}
QLineEdit{border-radius:4px;min-height:25px;border:1px solid gray;}
QPushButton{border-radius:4px;background-color:#409eff;color:white;font-size:18px;}
QWidget#bg{background:white;}

主页页面布局

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

主函数测试login

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //实现登录
    Dlg_login dlg;
    int ret=dlg.exec();
    if(1==ret){
        Cell_main w;
        w.show();
        return a.exec();
    }
    if(0==ret){
        exit(0);
        return 0;
    }
    return 0;

}

实现Dlg_login函数

void Dlg_login::on_btn_login_clicked()
{
    setResult(1);
    this->hide();
}


void Dlg_login::on_btn_exit_clicked()
{
    setResult(0);
    this->hide();
}

设置logo

在这里插入图片描述
在资源文件中添加一个app.rc文件,在打开这个app.rc文件 添加一句话:

IDI_ICON1 ICON DISCARDABLE “tubiao.ico”
再把这个ico图标放到这个资源文件里

在这里插入图片描述

打包程序

在这里插入图片描述
如果还 运行不了,可能是有些库没有权限没靠过来,手动考
在这里插入图片描述

子页面的样子

用户管理界面
图书管理页面
借阅管理

将子页面放到StackedWidget里面

在这里插入图片描述

#include "cell_main.h"
#include "ui_cell_main.h"
#include"dlg_login.h"
#include"QPushButton"
#include"QDebug"

Cell_main::Cell_main(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Cell_main),
    m_bookPage(nullptr),
    m_recordPage(nullptr),
    m_userPage(nullptr)
{
    ui->setupUi(this);

    //初始化栈窗口
    initPage();

}
void Cell_main::initPage()
{
    m_bookPage=new cell_BookMgr(this);
    m_userPage=new cell_UserMgr(this);
    m_recordPage=new cell_Record(this);
    //把页面放到栈窗口
    ui->stackedWidget->addWidget(m_userPage);
    ui->stackedWidget->addWidget(m_bookPage);
    ui->stackedWidget->addWidget(m_recordPage);
    //设置首页是用户管理
    ui->stackedWidget->setCurrentIndex(0);
    qDebug()<<"helloworld";

    auto l=ui->tool->children();//获得子控件
    for(auto it:l){
       //为每个页面进行绑定槽函数
        if(it->objectName().contains("btn"))
        {
            connect(static_cast<QPushButton*>(it),&QPushButton::clicked,this,&Cell_main::DealMenu);
        }
    }
    //主页初始化一下
   // m_userPage->initPage();

}

void Cell_main::DealMenu()
{
    auto str=sender()->objectName();

    //切换页面
    do{
        if("btn_user"==str){
            //m_userPage->initPage();
            ui->stackedWidget->setCurrentIndex(0);
            break;
        }

        if("btn_book"==str){
            //m_bookPage->initPage();
            ui->stackedWidget->setCurrentIndex(1);
            break;
        }

        if("btn_his"==str){
            //m_recordPage->initPage();
            ui->stackedWidget->setCurrentIndex(2);
            break;
        }

    }while(false);

}



Cell_main::~Cell_main()
{
    delete ui;
}


在添加完之后在进行切换操作,页面之间切换
在这里插入图片描述

按钮直接形成互斥效果

在这里插入图片描述

用属性选择器来改变样式

在这里插入图片描述
在这里插入图片描述

设置user页面的标头和设置文本不可编辑

  ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);//一次选中一行
    ui->tableView->setModel(&m_model);
    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置不可编辑
    m_model.setHorizontalHeaderLabels(QStringList{"用户id","年级","部门","权限","人物类型","密码","用户名"});

在这里插入图片描述

创建SqlMgr类进行SQL操作

涉及到的函数函数和变量

class SqlMgr
{
public:
    SqlMgr();

    //设置单例模式
    static SqlMgr*  instance;
    static SqlMgr*  getInstance(){
        if(nullptr==instance){
            instance=new SqlMgr();
        }
        return instance;
    }
    void test1();


    void init();//初始化数据库


    //登录
    bool login(QString username,QString password,int &userId);

    //获取所有用户
    QVector<QStringList> getUsers(QString StrCondition="");

    //添加用户
    void addUsers(QVector<QStringList> );

    //删除用户
    void delUser(QString userId);

    //获取所有图书
    QVector<QStringList> getBooks(QString StrCondition="");

    //添加图书
    void addBooks(QVector<QStringList> );

    //修改图书
    void updateBook(QStringList);

    //删除图书
    QString delBook(QString bookId);

    //归还图书
    QString returnBook(QString userId,QString bookId);

    //图书借阅
    QString borrowBook(QString userId,QString bookId);

    //获取借阅记录
    QVector <QStringList> getRecord(QString strCondition="");

    //清除借阅记录
    void clearRecord();
    //

private:
    QSqlDatabase m_db;

初始化数据库

void SqlMgr::init()
{
    m_db=QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName(QCoreApplication::applicationDirPath()+"/db/WpcBook.db");
    qDebug()<<m_db.open();
}

在这里插入图片描述
失败啦!!!
在这里插入图片描述
成功啦,失败原因是之前把一些文件打包到bin目录下了,所以就不走系统的了缺少一些文件就会报错,把bin目录下的文件删除就走系统的了
在这里插入图片描述

m_db.setDatabaseName(QCoreApplication::applicationDirPath()

app目录是这个路径

这里是引用

登录功能login

先不实现键盘输入登录功能,先测试一下,查询数据库里面是否有这个用户,有就返回true

//返回      true登录成功
bool SqlMgr::login(QString username, QString password)
{
    QSqlQuery q(m_db);
    QString sql=QString("select *from user where username='%1' and password='%2'").arg(username).arg(password);
    bool ret=q.exec(sql);//执行查询语句 执行成功返回true
    if(ret==false){
        qDebug()<<q.lastError();
    }

    return ret;
}

用户功能

getUsers功能

(数据库层)SqlMgr代码:

//获取所有用户
QVector<QStringList> SqlMgr::getUsers(QString StrCondition){

    QSqlQuery q(m_db);
    //StrCondition里可以写模糊查询的东西
    QString sql=QString("select *from user %1").arg(StrCondition);
    //获取到的数据可能是多行
    QVector<QStringList> vec;
    bool ret=q.exec(sql);
    if(ret==false){
        qDebug()<<q.lastError();
    }else{
        //读取返回来的数据
        //获取这个数据是几行
        int col =q.record().count();
        QStringList temp;
        while(q.next()){//向下读
            temp.clear();
            for(int i=0;i<col;i++){
                //将这一行数据转换为QString放到
                temp<<q.value(i).toString();
            }
            vec.push_back(temp);

        }
        qDebug()<<"sqlMgr getuser被执行";

    }

    return vec;

}

(控制层代码)cell_UserMgr:

//初始化用户管理页面
void cell_UserMgr::initPage(QString strCondition){
    qDebug()<<"initUSer被执行";
    //调用数据库进行查询
    QVector<QStringList>vec= SqlMgr::getInstance()->getUsers(strCondition);
    m_model.clear();//在设置一次头
    m_model.setHorizontalHeaderLabels(QStringList{"用户id","年级","部门","权限","人物类型","密码","用户名"});
     QList <QStandardItem*>items;//添加到页面
    //获取每一个QStringList
    for(QStringList tempList:vec){
         items.clear();//清理
        for(int i=0;i<tempList.size();i++){
             //追加每一个元素
             items.append(new QStandardItem(tempList[i]));
        }
        //追加到一行上面
        m_model.appendRow(items);
    }

}

在这里插入图片描述

导入用户(导入文件里面的数据到数据库)

使用: QFileDialog::getOpenFileName(nullptr,“输入文件路径”);会出现弹窗

**dao代码(SqlMgr) **

//导入用户(.txt类型 是GBK编码)
void SqlMgr::addUsers(QVector<QStringList> vec){
    QSqlQuery q(m_db);
    //StrCondition里可以写模糊查询的东西

    //一个个拿出来
    for(auto tempList:vec){
            QString sql=QString("insert into user VALUES(NULL,'%1','%2','%3','%4','%5','%6')")
                              .arg(tempList[0])
                              .arg(tempList[1])
                              .arg(tempList[2])
                              .arg(tempList[3])
                              .arg(tempList[4])
                              .arg(tempList[5]);
        bool ret=q.exec(sql);
            if(ret==false){
            qDebug()<<q.lastError();
        }
    }

}

控制层代码:

//导入用户
void cell_UserMgr::on_btn_UserAdd_clicked()
{
    //会弹出页面窗口
    auto strPath=QFileDialog::getOpenFileName(nullptr,"输入文件路径");
    QVector<QStringList>vec;

    if(strPath.isEmpty()!=true){
        QFile f(strPath);//读这个文件
        qDebug()<<"路径: "<<strPath;
        f.open(QFile::ReadOnly);

        while(!f.atEnd()){
        QByteArray bytes= f.readLine();//一次读一行
        //转换为QString 里面的数据类型是 : xxx,xxx,xxx,xxx用,分割
        QString str(bytes);
        qDebug()<<"str = "<<str;
        //分割
        QStringList  strList=str.split(",");
        //判断
        if(strList.size()!=6){
             QMessageBox::information(nullptr,"信息","导入失败",QMessageBox::Ok);
                return;
             }

             //把一行数据的最后的元素的最后两个字节去掉\n\r去掉
       strList[strList.size()-1]=strList[strList.size()-1].chopped(2);
        //存
         vec.push_back(strList);

        }
        //调用数据库
        SqlMgr::getInstance()->addUsers(vec);
        f.close();
        //刷新页面
        //ui->le_search->clear();
        initPage();
    }
}

在这里插入图片描述
先写数据层库层

效果:
在这里插入图片描述

删除用户(del)

数据库:

void SqlMgr::delUser(QString userId){
    QSqlQuery q(m_db);
    QString sql=QString("delete from user where id= %1").arg(userId);

    bool ret=q.exec(sql);
    if(!ret){
        qDebug()<<q.lastError().text();
    }


}

控制层:

//删除用户
void cell_UserMgr::on_btn_UserDel_clicked()
{
    //获取鼠标点击到的哪一行的
    //第一列的数据
    int r=ui->tableView->currentIndex().row();//获取当前行号
    if(r<0){
        QMessageBox::information(nullptr,"提示","请选中一行...",QMessageBox::Ok);

    }else{
    //获取r行 的0列
    auto id=m_model.item(r,0)->text();
    SqlMgr::getInstance()->delUser(id);

        //刷新页面
    initPage();
    }
}

搜索用户

控制层:(直接调用initPage函数)

    void cell_UserMgr::on_le_search_textChanged(const QString &arg1)
    {
        QString sql=QString("where username like '%%1%' or department like '%%1%'").arg(arg1);
    
        initPage(sql);
    }

在这里插入图片描述

图书管理功能

获取图书

数据库:

//获取图书
QVector<QStringList> SqlMgr::getBooks(QString StrCondition)
{
    QSqlQuery q(m_db);
    QString sql=QString("select *from book %1").arg(StrCondition);
     QVector<QStringList> vec;
    //执行
    bool ret=q.exec(sql);
    if(!ret){
        qDebug()<<q.lastError().text();

    }else{

        QStringList strList;

        //获取这些数据有几列
        int col=q.record().count();
        //从q里面获取数据
        while(q.next()){
            strList.clear();
            for(int i=0;i<col;i++){
                //把这一行数据放进去
                strList<<q.value(i).toString();
            }
            vec.push_back(strList);
        }
    }
    return vec;

}

//添加图书
void SqlMgr::addBooks(QVector<QStringList> vec ){
    //添加图书是一次添加一本

    QSqlQuery q(m_db);
    auto data= vec[0];
    QString sql=QString("insert into Wbook values(null,'%1','%2','%3','%4','%5',%6,'');")
                      .arg(data[1])
                      .arg(data[2])
                      .arg(data[3])
                      .arg(data[4])
                      .arg(data[5])
                      .arg(data[6]);
    bool ret=q.exec(sql);//执行查询语句
    if(ret==false){
        qDebug()<<q.lastError();
        return;
    }
}

控制层:

//初始化图书管理页面
void cell_BookMgr::initPage(QString condition){
    //调用dao的getbooks
    auto vec=SqlMgr::getInstance()->getBooks(condition);
    //拿数据显示到页面
    m_model.clear();//在设置一次头
    m_model.setHorizontalHeaderLabels(QStringList{"图书id","图书名称","价格","类型1","类型2","类型3","数量","图片"});

    for(QStringList tlist:vec){//拿出一行QStringList
        QList<QStandardItem*> items;
        for(int i=0;i<tlist.size();i++){
            //追加到items
            items.append(new QStandardItem(tlist[i]));
        }
        qDebug()<<"图书被调用";
        //加到model
        m_model.appendRow(items);
    }


}

添加图书

添加图书要弹出一个页面Dlg_addOrUp

在这里插入图片描述
数据库层:

//添加图书
void SqlMgr::addBooks(QStringList data ){
    //添加图书是一次添加一本

    QSqlQuery q(m_db);

    QString sql=QString("insert into book values(null,'%1','%2','%3','%4','%5',%6,'');")
                      .arg(data[0])
                      .arg(data[1])
                      .arg(data[3])
                      .arg(data[4])
                      .arg(data[5])
                      .arg(data[2]);
    bool ret=q.exec(sql);//执行查询语句
    if(ret==false){
        qDebug()<<q.lastError().text();

    }
}

控制层:

void cell_BookMgr::on_btn_bookAdd_clicked()
{
    //调用子窗口
    Dlg_addOrUp dlg;
    dlg.setFlag(-1);//添加就设置为-1
    dlg.exec();



}

Dlg_addOrUp类

#include "dlg_addorup.h"
#include "ui_dlg_addorup.h"
#include"dao/sqlmgr.h"
#include"QDebug"
Dlg_addOrUp::Dlg_addOrUp(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dlg_addOrUp)
{
    ui->setupUi(this);

}

Dlg_addOrUp::~Dlg_addOrUp()
{
    delete ui;
}

void Dlg_addOrUp::addOrUp()
{
    QStringList strList;
    //添加
    if(m_flag==-1){
      //获取页面输入
        strList<<ui->le_name->text();
        strList<<ui->le_press->text();
        strList<<ui->le_count->text();
        strList<<ui->cb1->currentText();
        strList<<ui->cb2->currentText();
        strList<<ui->cb3->currentText();
        qDebug()<<"==== "<<strList;
        //调用数据添加函数
        SqlMgr::getInstance()->addBooks(strList);
    }
}

void Dlg_addOrUp::setFlag(int flag)
{
    m_flag=flag;
}

void Dlg_addOrUp::on_btn_ok_clicked()
{
    addOrUp();
    //隐藏页面
    this->hide();
}


void Dlg_addOrUp::on_btn_cancel_clicked()
{
    this->hide();
}


这个Dlg_addOrUp既是添加页面又是修改页面里面m_flag=-1时是添加,非-1时是修改

修改图书

dao层:

//修改图书
void SqlMgr::updateBook(QStringList data){
    QSqlQuery q(m_db);
    QString sql=QString("update book set"
                          " name='%1',press='%2',type1='%3',type2='%4',"
                          "type3='%5',cnt='%6' where bookid='%7';")
                      .arg(data[1])
                      .arg(data[2])
                      .arg(data[4])
                      .arg(data[5])
                      .arg(data[6])
                      .arg(data[3])
                      .arg(data[0]);
    bool ret=q.exec(sql);//执行查询语句
    if(ret==false){
        qDebug()<<q.lastError();
    }
}

控制层:


void cell_BookMgr::on_btn_bookUpdate_clicked()
{
    //判断有没有选中一行将要修改的数据
    //要知道鼠标点中哪一行
    int r=ui->tableView->currentIndex().row();

    if(r<0){
        QMessageBox::information(nullptr,"信息","请选中要更新的一行",QMessageBox::Ok);

    }
    else{
        qDebug()<<"update被调用...";
        //获得选中的一行的id拿出来
        auto it= m_model.item(r,0)->text();
        Dlg_addOrUp dlg;
        dlg.setFlag(it.toInt());//修改
        dlg.showDetial(it.toInt());//显示要修改的信息
        dlg.exec();
        initPage();
    }
}

显示到页面上信息(Dlg_addOrUp):

void Dlg_addOrUp::showDetial(int id)
{
    QString sql=QString("where bookid= %1").arg(id);
    //先查询信息显示到页面上
    QVector<QStringList> vec =SqlMgr::getInstance()->getBooks(sql);
    QStringList data=vec[0];//查出来的是一条数据
    ui->le_name->setText(data[1]);
    ui->le_press->setText(data[2]);
    ui->cb1->setCurrentText(data[3]);
    ui->cb2->setCurrentText(data[4]);
    ui->cb3->setCurrentText(data[5]);
    ui->le_count->setText(data[6]);
}

更新:

void Dlg_addOrUp::addOrUp()
{
    QStringList strList;
    //添加
    if(m_flag==-1){
      //获取页面输入
        strList<<ui->le_name->text();
        strList<<ui->le_press->text();
        strList<<ui->le_count->text();
        strList<<ui->cb1->currentText();
        strList<<ui->cb2->currentText();
        strList<<ui->cb3->currentText();
        qDebug()<<"==== "<<strList;
        //调用数据添加函数
        SqlMgr::getInstance()->addBooks(strList);
    }else{//修改
        strList.clear();

        strList<<QString::number(m_flag);//把bookid拿进去
        //获取页面输入
        strList<<ui->le_name->text();
        strList<<ui->le_press->text();
        strList<<ui->le_count->text();
        strList<<ui->cb1->currentText();
        strList<<ui->cb2->currentText();
        strList<<ui->cb3->currentText();
        SqlMgr::getInstance()->updateBook(strList);
    }
}

在这里插入图片描述
在这里插入图片描述

删除图书

遇到的错误

在这里插入图片描述

//删除图书
QString SqlMgr:: delBook(QString bookId){
    QSqlQuery q(m_db);
    QString sql=QString("delete from book where bookid= %1").arg(bookId);

    bool ret=q.exec(sql);
    if(!ret){
        qDebug()<<q.lastError().text();
        return "fail";
    }
    return "success";
}
void cell_BookMgr::on_btn_bookDel_clicked()
{
    //获取鼠标点击到哪一行了
    int r=ui->tableView->currentIndex().row();
    if(r<0){
        QMessageBox::information(nullptr,"信息","请选中要删除的一行",QMessageBox::Ok);
    }else{
        auto  id =m_model.item(r,0)->text();
        QString str=SqlMgr::getInstance()->delBook(id);
        QMessageBox::information(nullptr,"信息",str=="success"?"删除成功":"删除失败",QMessageBox::Ok);
        initPage();
    }
}

借阅图书

创建一个窗口类
在这里插入图片描述
Dlg_getsetbook

#include "dlg_getsetbook.h"
#include "ui_dlg_getsetbook.h"
#include"dao/sqlmgr.h"
#include"QMessageBox"
Dlg_getSetBook::Dlg_getSetBook(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dlg_getSetBook)
{
    ui->setupUi(this);
}

Dlg_getSetBook::~Dlg_getSetBook()
{
    delete ui;
}

void Dlg_getSetBook::showBorrowBook(QString bookName)
{
    //在页面上显示图书
    ui->le_bookname->setText(bookName);
}

void Dlg_getSetBook::setBookId(QString bookid)
{
    m_bookid=bookid;
}

void Dlg_getSetBook::on_btn_ok_clicked()
{
    //点击确定之后获取页面上的数据进行调用数据库
    auto userName=ui->le_username->text();
    auto pwd=ui->le_pwd->text();
    //判断用户是否存在
   bool ret=SqlMgr::getInstance()->login(userName,pwd);
    if(ret==false){
       QMessageBox::information(nullptr,"提示","该用户不存在",QMessageBox::Ok);
        return;
   }
   //  图书借阅   QString borrowBook(QString userId,QString bookId);
        //获取用户id
  QString userid =  SqlMgr::getInstance()->getUserid(userName,pwd);
   m_userid=userid;
  if(m_userid==""&&m_bookid==""){
    QMessageBox::information(nullptr,"提示","用户id或图书id为null",QMessageBox::Ok);
        return;
   }
  QString str=SqlMgr::getInstance()->borrowBook(m_userid,m_bookid);
 QMessageBox::information(nullptr,"提示",str=="借阅成功"?"借阅成功":"借阅失败",QMessageBox::Ok);
  //隐藏窗口
  this->hide();
}


#ifndef DLG_GETSETBOOK_H
#define DLG_GETSETBOOK_H

#include <QDialog>

namespace Ui {
class Dlg_getSetBook;
}

class Dlg_getSetBook : public QDialog
{
    Q_OBJECT

public:
    explicit Dlg_getSetBook(QWidget *parent = nullptr);
    ~Dlg_getSetBook();
    //显示你借的那一本书
    void showBorrowBook(QString bookName);
    void setBookId(QString bookid);

private slots:
    void on_btn_ok_clicked();

private:
    Ui::Dlg_getSetBook *ui;
    QString m_bookid;
    QString m_userid;
};

#endif // DLG_GETSETBOOK_H


dao:

//图书借阅
QString SqlMgr::borrowBook(QString userId,QString bookId){
    QSqlQuery q(m_db);
    QString sql=QString("update book set cnt=cnt-1 where bookid = %1").arg(bookId);
    bool ret=q.exec(sql);//执行查询语句
    if(ret==false){
        qDebug()<<q.lastError().text();
        return "借阅失败";
    }
    //QDateTime::currentSecsSinceEpoch()
    QString start =secondsToDateString(QDateTime::currentSecsSinceEpoch());
    QString end =secondsToDateString(QDateTime::currentSecsSinceEpoch()+3600*24*10);
    sql=QString("insert into record values(null,%1,%2,'%3','%4')")
              .arg(userId)
              .arg(bookId)
              .arg(start)
              .arg(end);
    ret=q.exec(sql);//执行查询语句
    if(ret==false){
        qDebug()<<q.lastError().text();
        return "借阅失败";
    }
    return "借阅成功";

}

dao:(getuserid)


QString SqlMgr::getUserid(QString userName, QString pwd)
{
    QSqlQuery q(m_db);
    QString sql=QString("select id from user where username = '%1' and password = '%2' ")
                      .arg(userName)
                      .arg(pwd);
    bool ret=q.exec(sql);//执行查询语句
    if(ret==false){
        qDebug()<<q.lastError().text();
        return "";
    }

    QString userid = "";
    if (q.next()) { // 移动到结果集中的第一条记录
        userid = q.value(0).toString();
    }
    return userid;
}
QString SqlMgr::secondsToDateString(qint64 seconds)
{
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(seconds);
    QString dateString = dateTime.toString("yyyy-MM-dd");
    return dateString;
}

控制层:

//借阅图书
void cell_BookMgr::on_btn_BookRecord_clicked()
{
    //判断点击了哪一行数据
    int r=ui->tableView->currentIndex().row();
    if(r<0){
        QMessageBox::information(nullptr,"信息","请选中要借阅的图书",QMessageBox::Ok);
    }else{
        auto bookid =m_model.item(r,0)->text();
        //获得cnt cnt<=0 库存没了不能借 r行的6列
        auto cnt =m_model.item(r,6)->text();
        if(cnt<="0"){
           QMessageBox::information(nullptr,"信息","该书没有库存了,嗷了个嗷~",QMessageBox::Ok);
            return;
        }
        //否则向下执行 要进行登记是谁借了这本书调用子页面
        Dlg_getSetBook dlg;
        //获得书的名字
        auto bookName =m_model.item(r,1)->text();
        dlg.setBookId(bookid);//设置图书id
        dlg.showBorrowBook(bookName);
        dlg.exec();
        initPage();
    }

搜索图书

控制层:(直接调用initPage函数)

void cell_BookMgr::on_le_search_textChanged(const QString &arg1)
{
    QString sql=QString("where name like '%%1%' or type1 = '%1' or type2 = '%1' or type3 = '%1' ").arg(arg1);

    initPage(sql);
}

借阅记录管理功能

获取借阅记录

在这里插入图片描述
dao:

//获取借阅记录
QVector <QStringList> SqlMgr::getRecord(QString strCondition){
    QSqlQuery q(m_db);
    QString sql=QString("select * from record %1").arg(strCondition);
    QVector<QStringList> vec;
    //执行
    bool ret=q.exec(sql);
    if(!ret){
        qDebug()<<q.lastError().text();

    }else{

        QStringList strList;

        //获取这些数据有几列
        int col=q.record().count();
        //从q里面获取数据
        while(q.next()){
            strList.clear();
            for(int i=0;i<col;i++){
                //把这一行数据放进去
                strList<<q.value(i).toString();
            }
            vec.push_back(strList);
        }
    }
    return vec;
}

控制层:

void cell_Record::initPage(QString condition){

    auto vec=SqlMgr::getInstance()->getRecord(condition);
    //拿数据显示到页面
    m_model.clear();//在设置一次头
    m_model.setHorizontalHeaderLabels(QStringList{"图书id","图书名称","价格","类型1","类型2","类型3","数量","图片"});
    for(QStringList strList:vec){
        QList<QStandardItem*> items;
        for(int i=0;i<strList.size();i++){
            items.append(new QStandardItem(strList[i]));
        }
        m_model.appendRow(items);
    }

}

void cell_Record::on_le_search_textChanged(const QString &arg1)
{
    QString sql=QString("where start like '%%1%' or end like '%%1%' or userid = %1 or bookid = %1").arg(arg1);

    initPage(sql);
}

模糊查询记录

通过开始时间和结束时间与用户名和密码进行查询

void cell_Record::on_le_search_textChanged(const QString &arg1)
{
    //同过开始时间和结束时间与用户名和密码进行查询
    QString sql=QString("where start like '%%1%' or end like '%%1%' or user.username = '%1' or book.name= '%1'").arg(arg1);

    initPage(sql);
}

归还图书

数据库层:

//归还图书
QString SqlMgr::returnBook(QString userId,QString bookId){
    //根据userid==bookid删除记录 在根据bookid为本书cnt(库存+1)
    QSqlQuery q(m_db);
//    qDebug()<<"bookid= "<<bookId<<" userid = "<<userId;
    /*
     * 假如a(id=1)借西游记(bookid=6) b(id=2)借了西游记(bookid=6)
     * 登录b还a借的书也是会成功的 b(id=2) a借的书(bookid=6)
*/
    QString sql=QString("delete from record where userid = %1 and bookid = %2")
                      .arg(userId)
                      .arg(bookId);
    bool ret=q.exec(sql);
    if(ret==false){
        qDebug()<<q.lastError().text();
        return "归还失败";
    }

    sql=QString("update book set cnt = cnt+1 where bookid = %1")
              .arg(bookId);

//    qDebug()<<"bookid= ======"<<bookId;
     ret=q.exec(sql);
    if(ret==false){
        qDebug()<<q.lastError().text();
        return "归还失败";
    }
    return "归还成功";
}

控制层:


//归还图书
void cell_Record::on_btn_return_clicked()
{
    //获取鼠标点中的哪一行
    int r=ui->tableView->currentIndex().row();
    if(r<0){
        QMessageBox::information(nullptr,"信息","请选中要归还的图书",QMessageBox::Ok);
    }else{
        //弹出子页面用户登录之后在删除
        Dlg_getSetBook dlg;
        //获得书的名字
        QString tempBookid=m_model.item(r,2)->text();
        QString bookName=getBookName(tempBookid.toInt());
        //获取图书id
        auto bookid = m_model.item(r,2)->text();
        //获取userid
        auto userid = m_model.item(r,1)->text();
        dlg.setBookId(bookid);
        dlg.setUserId(userid);
        dlg.setFlag(true);
        dlg.showBorrowBook(bookName);//设置到页面上
        dlg.exec();
        initPage();

    }
}

QString cell_Record::getBookName(int bookid)
{
    QString bookName;
    bookName=SqlMgr::getInstance()->getBookName(bookid);
    return bookName;
}

Dlg_setgetBook

void Dlg_getSetBook::on_btn_ok_clicked()
{
    //点击确定之后获取页面上的数据进行调用数据库
    auto userName=ui->le_username->text();
    auto pwd=ui->le_pwd->text();
    //判断用户是否存在
   bool ret=SqlMgr::getInstance()->login(userName,pwd);
    if(ret==false){
       QMessageBox::information(nullptr,"提示","该用户不存在",QMessageBox::Ok);
        return;
   }

        //获取当前登录在Dlg_getsetbook窗口的用户id
  QString CurUserid =  SqlMgr::getInstance()->getUserid(userName,pwd);

  if(m_userid==""&&m_bookid==""){
    QMessageBox::information(nullptr,"提示","用户id或图书id为null",QMessageBox::Ok);
        return;
   }
  if(m_flag==false){//借阅
        //借阅图书的时候用当前登录的用户的用户id借阅
        m_userid=CurUserid;
        QString str=SqlMgr::getInstance()->borrowBook(m_userid,m_bookid);
        QMessageBox::information(nullptr,"提示",str=="借阅成功"?"借阅成功":"借阅失败",QMessageBox::Ok);
  }else{//归还
        if(CurUserid==m_userid){
        QString str=SqlMgr::getInstance()->returnBook(m_userid,m_bookid);
        QMessageBox::information(nullptr,"提示",str=="归还成功"?"归还成功":"归还失败",QMessageBox::Ok);
        }
        else{
        QMessageBox::information(nullptr,"提示","用户: "+userName+" 未借此书",QMessageBox::Ok);
        }
  }
  //隐藏窗口
  this->hide();
}



出现的问题

在这里插入图片描述
改造一下归还函数

//归还图书
QString SqlMgr::returnBook(QString userId,QString bookId,QString recordId){
    //根据userid==bookid删除记录 在根据bookid为本书cnt(库存+1)
    QSqlQuery q(m_db);
//    qDebug()<<"bookid= "<<bookId<<" userid = "<<userId;
    /*
     * 假如a(id=1)借西游记(bookid=6) b(id=2)借了西游记(bookid=6)
     * 登录b还a借的书也是会成功的 b(id=2) a借的书(bookid=6)
*/
    QString sql=QString("delete from record where userid = %1 and bookid = %2 and id= %3")
                      .arg(userId)
                      .arg(bookId)
                      .arg(recordId);
    bool ret=q.exec(sql);
    if(ret==false){
        qDebug()<<q.lastError().text();
        return "归还失败";
    }

    sql=QString("update book set cnt = cnt+1 where bookid = %1")
              .arg(bookId);

//    qDebug()<<"bookid= ======"<<bookId;
     ret=q.exec(sql);
    if(ret==false){
        qDebug()<<q.lastError().text();
        return "归还失败";
    }
    return "归还成功";
}




//转换日期格式
QString SqlMgr::secondsToDateString(qint64 seconds)
{
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(seconds);
    QString dateString = dateTime.toString("yyyy-MM-dd");
    return dateString;
}

QString SqlMgr::getBookName(int bookid)
{
    QSqlQuery q(m_db);
    QString sql=QString("select name from book where bookid = %1").arg(bookid);
    bool ret =q.exec(sql);
    if(!ret){
        qDebug()<<q.lastError().text();
        return "";
    }
    QString bookName="";
    if(q.next()){
        bookName= q.value(0).toString();
        return bookName;
    }
    return bookName;
}

添加一下这个函数
在这里插入图片描述
在这里插入图片描述

#include "dlg_getsetbook.h"
#include "ui_dlg_getsetbook.h"
#include"dao/sqlmgr.h"
#include"QMessageBox"
Dlg_getSetBook::Dlg_getSetBook(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dlg_getSetBook)
{
    ui->setupUi(this);
}

Dlg_getSetBook::~Dlg_getSetBook()
{
    delete ui;
}

void Dlg_getSetBook::showBorrowBook(QString bookName)
{
    //在页面上显示图书
    ui->le_bookname->setText(bookName);
}

void Dlg_getSetBook::setBookId(QString bookid)
{
    m_bookid=bookid;
}

void Dlg_getSetBook::setFlag(bool flag)
{
    m_flag=flag;
}

void Dlg_getSetBook::setUserId(QString userid)
{
    m_userid=userid;
}

void Dlg_getSetBook::setRecordId(QString recordid)
{
    m_recordid=recordid;
}

void Dlg_getSetBook::on_btn_ok_clicked()
{
    //点击确定之后获取页面上的数据进行调用数据库
    auto userName=ui->le_username->text();
    auto pwd=ui->le_pwd->text();
    //判断用户是否存在
   bool ret=SqlMgr::getInstance()->login(userName,pwd);
    if(ret==false){
       QMessageBox::information(nullptr,"提示","该用户不存在",QMessageBox::Ok);
        return;
   }

        //获取当前登录在Dlg_getsetbook窗口的用户id
  QString CurUserid =  SqlMgr::getInstance()->getUserid(userName,pwd);

  if(m_userid==""&&m_bookid==""){
    QMessageBox::information(nullptr,"提示","用户id或图书id为null",QMessageBox::Ok);
        return;
   }
  if(m_flag==false){//借阅
        //借阅图书的时候用当前登录的用户的用户id借阅
        m_userid=CurUserid;
        QString str=SqlMgr::getInstance()->borrowBook(m_userid,m_bookid);
        QMessageBox::information(nullptr,"提示",str=="借阅成功"?"借阅成功":"借阅失败",QMessageBox::Ok);
  }else{//归还
        if(CurUserid==m_userid){
         //归还的时候还要用到记录id
        QString str=SqlMgr::getInstance()->returnBook(m_userid,m_bookid,m_recordid);
        QMessageBox::information(nullptr,"提示",str=="归还成功"?"归还成功":"归还失败",QMessageBox::Ok);
        }
        else{
        QMessageBox::information(nullptr,"提示","用户: "+userName+" 未借此书",QMessageBox::Ok);
        }
  }
  //隐藏窗口
  this->hide();
}



清空借阅记录

dao:


void SqlMgr::clearRecord()
{
    //删除所有图书
        QSqlQuery q(m_db);
        QString sql=QString("delete from record;");
        bool ret=q.exec(sql);//执行查询语句
        if(ret==false){
            qDebug()<<q.lastError();
            return;
        }


        sql=QString("delete from sqlite_sequence where name= 'record';");
        ret=q.exec(sql);//执行查询语句
        if(ret==false){
            qDebug()<<q.lastError();
            return;
        }

        qDebug()<<"clearRecord()成功.......";


}

控制层:

void cell_Record::on_btn_clear_clicked()
{
    SqlMgr::getInstance()->clearRecord();
    initPage();
}

登录功能

控制层:

void Dlg_login::on_btn_login_clicked()
{
    auto username=ui->username->text();
    auto pwd=ui->password->text();
    if(username==""||pwd==""){
        QMessageBox::information(nullptr,"提示","用户名或密码不能为空",QMessageBox::Ok);
        return;
    }
    bool ret=SqlMgr::getInstance()->login(username,pwd);
    if(ret){

        setResult(1);
        hide();
    }else{

    QMessageBox::information(nullptr,"提示","用户名或密码错误",QMessageBox::Ok);
    }
}

dao:

//返回      true登录成功
bool SqlMgr::login(QString username, QString password)
{
    QSqlQuery q(m_db);
    QString sql=QString("select *from user where username='%1' and password='%2'").arg(username).arg(password);
    bool ret=q.exec(sql);//执行查询语句 执行成功返回true
    if(ret==false){

        qDebug()<<q.lastError().text();
    }

    //执行这个q.next()判断是否还有可以执行成功
    ret=q.next();
    return ret;
}

在这里插入图片描述

页面展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/986771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot MongoDB 主从 多数据源

上一篇&#xff0c;我写了关于用一个map管理mongodb多个数据源&#xff08;每个数据源&#xff0c;只有单例&#xff09;的内容。 springboot mongodb 配置多数据源 临到部署到阿里云的测试环境&#xff0c;发现还需要考虑一下主从的问题&#xff0c;阿里云买的数据库&#x…

C语言——指针完全版

一、指针的运算 1.1指针 - 整数 总结&#xff1a;指针的类型决定了指针向前或者向后走一步有多大&#xff08;距离&#xff09;。 1.2指针 - 指针 int main() {int arr[10] { 0 };printf("%d\n", &arr[9] - &arr[0]);return 0; } 当我们想用两个指针相减时…

【100天精通Python】Day57:Python 数据分析_Pandas数据描述性统计,分组聚合,数据透视表和相关性分析

目录 1 描述性统计&#xff08;Descriptive Statistics&#xff09; 2 数据分组和聚合 3 数据透视表 4 相关性分析 1 描述性统计&#xff08;Descriptive Statistics&#xff09; 描述性统计是一种用于汇总和理解数据集的方法&#xff0c;它提供了关于数据分布、集中趋势和…

怎么把pdf转换成jpg图片?

怎么把pdf转换成jpg图片&#xff1f;在工作中&#xff0c;如果我们收到无法修改编辑的PDF文件&#xff0c;可能会遇到一些困难。尤其是当平台或网站只支持JPG图片格式&#xff0c;而领导又要求我们将pdf文件改为JPG格式时&#xff0c;情况就更为棘手了。这对于我们打工一族来说…

二、模型驱动测试设计

如果能够提升抽象层级&#xff0c;测试设计师会更加有效和有效率。 完全改正软件是不可能到达的&#xff0c;其原因是可以以形式化的方式来表述的而且是富有哲理的。聪明的软件工程师不再追求软件的完全正确&#xff0c;而是试着评判软件的行为来决定其是否为可接受的。**包括可…

Linux之SELinux

目录 概述 定义 作用 SELinux与传统的权限区别 SELinux工作原理 名词解释 主体&#xff08;Subject&#xff09; 目标&#xff08;Object&#xff09; 策略&#xff08;Policy&#xff09; 安全上下文&#xff08;Security Context&#xff09; 文件安全上下文查看 …

【MySQL基础】事务隔离03

目录 隔离性与隔离级别事务隔离的实现事务的启动方式MySQL事务代码示例 在MySQL中&#xff0c;事务支持是在引擎层实现的。MySQL是一个支持多引擎的系统&#xff0c;但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务&#xff0c;这也是 MyISAM 被 Inn…

永安通配符和多域名SSL证书的区别

随着互联网的快速发展&#xff0c;现在大多数人都已经习惯在网上交流、购物、学习&#xff0c;因此互联网上的各种类型的网站越来越多&#xff0c;不仅是企事业单位创建各种类型的网站&#xff0c;个人开发者创建的网站也越来越多&#xff0c;一张单域名SSL就不能满足个人或者企…

Windows云服务器 PHP搭建网站外网无法访问的问题

前言&#xff1a;本人在华为云上租了一台windows的云主机&#xff0c;可以远程访问桌面的那种&#xff0c;然后想搭个网站&#xff0c;最开始想到的是IIS&#xff0c;测试了下用html的文件&#xff0c;没有问题。但是&#xff0c;php文件却不能用&#xff0c;因为少了PHP环境。…

【LeetCode - 每日一题】2594. 修车的最少时间(23.09.07)

2594. 修车的最少时间 题意 给定每个师傅修车的时间和需要修的车辆总数&#xff0c;计算修理所有汽车需要的最少时间。师傅可以同时修车。 解法 二分 看到题目没有任何头绪&#xff0c;直接查看题解。 至于为什么用二分做呢&#xff0c;讨论区有个友友这么说到&#xff1a…

【Linux】LVM原理及核心概念

LVM是什么&#xff1f;LVM核心概念LVM的优势在Linux上使用LVM感谢 &#x1f496; LVM是什么&#xff1f; LVM是一种高级的磁盘管理工具&#xff0c;用于在Linux和其他类Unix操作系统中管理磁盘存储。它的核心思想是将底层物理存储抽象为逻辑存储单元&#xff0c;从而提供了更大…

如何使用HTTP代理爬虫,防止对网站造成负面影响

在当今大数据时代&#xff0c;爬虫技术已经成为了获取数据的重要手段之一。但是&#xff0c;由于爬虫程序的高频访问容易对目标网站造成负面影响&#xff0c;如增加服务器负载、影响网站性能等&#xff0c;因此&#xff0c;如何使用HTTP代理爬虫防止对网站造成负面影响成为了一…

idea中mapper直接跳转到xml的插件

一.点击File | Settings | Plugins&#xff0c;下载插件 二、重启idea

Shopify电子邮件营销方法?邮件营销的技巧?

Shopify电子邮件营销怎么操作&#xff1f;独立站如何做邮件营销? Shopify电子邮件营销是一种强大的工具&#xff0c;可帮助电商企业与其客户建立联系并提高销售。蜂邮EDM将探讨一些有效的Shopify电子邮件营销方法&#xff0c;以帮助您最大限度地利用这一策略。 Shopify电子邮…

suning苏宁API接入说明(苏宁商品详情+关键词搜索商品列表)

API地址:https://o0b.cn/anzexi 调用示例&#xff1a;https://api-gw.onebound.cn/suning/item_get/?keytest_api_key& &num_iid0070134261/703410301&&langzh-CN&secret 参数说明 通用参数说明 version:API版本key:调用key,测试key:test_api_keyapi_na…

攻防世界-WEB-ics-05

打开靶机 只有设备维护中心可以点开 点标签得到新的url pageindex 想到文件包含漏洞&#xff08;URL中出现path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼 利用php伪协议查看源码 出现一段base64源码&#xff0c;进行转码得出源码 ?pagephp://filter…

Java-day13(IO流)

IO流 凡是与输入&#xff0c;输出相关的类&#xff0c;接口等都定义在java.io包下 1.File类的使用 File类可以有构造器创建其对象&#xff0c;此对象对应着一个文件(.txt,.avi,.doc,.mp3等)或文件目录 File类对象是与平台无关的 File中的方法仅涉及到如何创建&#xff0c;…

数据挖掘的学习路径

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

DGIOT-Modbus-RTU控制指令05、06的配置与下发

[小 迪 导 读]&#xff1a;伴随工业物联网在实际应用中普及&#xff0c;Modbus-RTU作为行业内的标准化通讯协议。在为物联网起到采集作用的同时&#xff0c;设备的控制也是一个密不可分的环节。 场景解析&#xff1a;在使用Modbus对设备进行采集后&#xff0c;可以通过自动控制…

nested exception is java.io.FileNotFoundException

完整的错误信息&#xff1a; [main] ERROR o.s.boot.SpringApplication - Application run failed org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.heima.article.ArticleApplication]; nested exception is java…