diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e2b7d4..06427b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,21 @@ endif() target_link_libraries(Satellite PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Charts Qt${QT_VERSION_MAJOR}::Network) +#spdlog +target_include_directories(Satellite PRIVATE ${CMAKE_CURRENT_LIST_DIR}/3rdparty/spdlog_x64-windows/include) +target_link_libraries(Satellite PRIVATE ${CMAKE_CURRENT_LIST_DIR}/3rdparty/spdlog_x64-windows/lib/spdlog.lib) +#fmt +target_include_directories(Satellite PRIVATE ${CMAKE_CURRENT_LIST_DIR}/3rdparty/fmt_x64-windows/include) +target_link_libraries(Satellite PRIVATE ${CMAKE_CURRENT_LIST_DIR}/3rdparty/fmt_x64-windows/lib/fmt.lib) +#sqlite3 +target_include_directories(Satellite PRIVATE ${CMAKE_CURRENT_LIST_DIR}/3rdparty/sqlite3_x64-windows/include) +target_link_libraries(Satellite PRIVATE ${CMAKE_CURRENT_LIST_DIR}/3rdparty/sqlite3_x64-windows/lib/sqlite3.lib) +#sqlite-orm +target_include_directories(Satellite PRIVATE ${CMAKE_CURRENT_LIST_DIR}/3rdparty/sqlite-orm_x64-windows/include) + +target_compile_definitions(Satellite PRIVATE _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) + + # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # If you are developing for iOS or macOS you should consider setting an # explicit, fixed bundle identifier manually though. diff --git a/LoggerWidget.cpp b/LoggerWidget.cpp index eaf1c50..2333312 100644 --- a/LoggerWidget.cpp +++ b/LoggerWidget.cpp @@ -1,4 +1,7 @@ #include "LoggerWidget.h" +#include "spdlog/sinks/qt_sinks.h" +#include "spdlog/sinks/basic_file_sink.h" + #include "ui_LoggerWidget.h" LoggerWidget::LoggerWidget(QWidget *parent) @@ -6,9 +9,19 @@ LoggerWidget::LoggerWidget(QWidget *parent) , ui(new Ui::LoggerWidget) { ui->setupUi(this); + + m_logger = spdlog::qt_color_logger_mt("logger", ui->txtLogger, 500); + m_logger->set_level(spdlog::level::info); + } LoggerWidget::~LoggerWidget() { delete ui; } + +void LoggerWidget::on_btnClear_clicked() +{ + ui->txtLogger->clear(); +} + diff --git a/LoggerWidget.h b/LoggerWidget.h index 8c358d0..322c9d6 100644 --- a/LoggerWidget.h +++ b/LoggerWidget.h @@ -2,6 +2,8 @@ #define LOGGERWIDGET_H #include +#include "spdlog/spdlog.h" +#include namespace Ui { class LoggerWidget; @@ -15,8 +17,13 @@ public: explicit LoggerWidget(QWidget *parent = nullptr); ~LoggerWidget(); +private slots: + void on_btnClear_clicked(); + private: Ui::LoggerWidget *ui; + + std::shared_ptr m_logger; }; #endif // LOGGERWIDGET_H diff --git a/LoggerWidget.ui b/LoggerWidget.ui index dcd5e07..b4ebdbc 100644 --- a/LoggerWidget.ui +++ b/LoggerWidget.ui @@ -6,8 +6,8 @@ 0 0 - 584 - 495 + 1026 + 614 @@ -15,7 +15,7 @@ - + @@ -33,7 +33,7 @@ - + 清空 diff --git a/RecordQuery.cpp b/RecordQuery.cpp index 557ff37..c6dddb5 100644 --- a/RecordQuery.cpp +++ b/RecordQuery.cpp @@ -1,14 +1,230 @@ #include "RecordQuery.h" + +#include + #include "ui_RecordQuery.h" +using namespace sqlite_orm; + RecordQuery::RecordQuery(QWidget *parent) : QWidget(parent) , ui(new Ui::RecordQuery) { ui->setupUi(this); + InitDatabase(); + m_logger = spdlog::get("logger"); } RecordQuery::~RecordQuery() { delete ui; } +static auto& GetRecordStorage() { + std::string db_path = QCoreApplication::applicationDirPath().toStdString() + "/record.db"; + static auto storage = make_storage(db_path, + make_table("record", + make_column("id", &DbRecord::id, primary_key().autoincrement()), + make_column("begin_time", &DbRecord::beginTime), + make_column("channel", &DbRecord::channel), + make_column("type", &DbRecord::type), + make_column("direction", &DbRecord::direction), + make_column("number", &DbRecord::number), + make_column("content", &DbRecord::content)) + ); + return storage; +} +void RecordQuery::InitDatabase(){ + auto& storage = GetRecordStorage(); + storage.sync_schema(); +} +void RecordQuery::InsertRecord(const Record& record) { + DbRecord r; + r.beginTime = record.beginTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(); + r.channel = int(record.channel); + r.type = int(record.type); + r.direction = int(record.type); + r.number = record.number.toStdString(); + r.content = record.content.toStdString(); + r.callDuration = record.callDuration; + try { + auto& storage = GetRecordStorage(); + storage.insert(r);//uint64_t id = + } + catch (std::exception& e) { + m_logger->error("向数据库插入记录数据错误: {}", e.what()); + } +} +void RecordQuery::InsertRecords(const std::vector& data){ + for(const auto& r : data){ + InsertRecord(r); + } +} + +void RecordQuery::UpdateRecordList(const std::vector& records){ + ui->tblRecordList->clear(); + QStringList column_labels; + column_labels << "开始时间" + << "通道" + << "通信类型" + << "方向" + << "号码" + << "通话时长" + << "消息内容"; + // 设置列表行数和列数 + int rowCount = records.size(); + ui->tblRecordList->setRowCount(rowCount); // 设置行数 + ui->tblRecordList->setColumnCount(column_labels.size()); // 设置列数 + // 设置水平表头 + ui->tblRecordList->setHorizontalHeaderLabels(column_labels); + // 设置垂直表头 + // self.ui.tblTestList.setVerticalHeaderLabels([str(v) for v in + // range(1,len(self.test_list)+1)]) 设置列宽 + int column_index = 0; + ui->tblRecordList->setColumnWidth(column_index, 180); // 开始时间 + column_index = column_index + 1; + ui->tblRecordList->setColumnWidth(column_index, 60); // 通道 + column_index = column_index + 1; + ui->tblRecordList->setColumnWidth(column_index, 80); // 通信类型 + column_index = column_index + 1; + ui->tblRecordList->setColumnWidth(column_index, 60); // 方向 + column_index = column_index + 1; + ui->tblRecordList->setColumnWidth(column_index, 120); // 号码 + column_index = column_index + 1; + ui->tblRecordList->setColumnWidth(column_index, 80); // 通话时长 + column_index = column_index + 1; + ui->tblRecordList->setColumnWidth(column_index, 400); // 消息内容 + column_index = column_index + 1; + + //插入所有项 + int rowIndex = 0; + for (int index = 0; index < records.size(); index++) { + const DbRecord& r = records[index]; + int column_index = 0; + // 开始时间 + auto item = new QTableWidgetItem(QString::fromStdString(r.beginTime)); + item->setTextAlignment(Qt::AlignCenter); + ui->tblRecordList->setItem(rowIndex, column_index, item); + column_index = column_index + 1; + // 通道 + item = new QTableWidgetItem(r.channel == int(Channel::Uhf)?"UHF":(r.channel== int(Channel::S)?"S":"北斗")); + item->setTextAlignment(Qt::AlignCenter); + ui->tblRecordList->setItem(rowIndex, column_index, item); + column_index = column_index + 1; + // 通信类型 + item = new QTableWidgetItem(r.type == int(CommType::Call) ? "通话" : "短信息"); + item->setTextAlignment(Qt::AlignCenter); + ui->tblRecordList->setItem(rowIndex, column_index, item); + column_index = column_index + 1; + // 方向 + item = new QTableWidgetItem(r.direction==int(CommDirection::Receive)?"接收":"发送"); + item->setTextAlignment(Qt::AlignCenter); + ui->tblRecordList->setItem(rowIndex, column_index, item); + column_index = column_index + 1; + // 号码 + item = new QTableWidgetItem(QString::fromStdString(r.number)); + item->setTextAlignment(Qt::AlignCenter); + ui->tblRecordList->setItem(rowIndex, column_index, item); + column_index = column_index + 1; + // 通话时长 + item = new QTableWidgetItem(QString::asprintf("%d s",r.callDuration)); + item->setTextAlignment(Qt::AlignCenter); + ui->tblRecordList->setItem(rowIndex, column_index, item); + column_index = column_index + 1; + // 消息内容 + item = new QTableWidgetItem(QString::fromStdString(r.content)); + ui->tblRecordList->setItem(rowIndex, column_index, item); + column_index = column_index + 1; + + rowIndex++; + } +} +//-------------------------------------------------------------------------------------- +// 槽函数 +//-------------------------------------------------------------------------------------- + +void RecordQuery::on_btnQuery_clicked() +{ + std::string begin_date_time = ui->dteBeginTime->dateTime().toString("yyyy-MM-dd hh:mm:ss").toStdString(); + std::string end_date_time = ui->dteEndTime->dateTime().toString("yyyy-MM-dd hh:mm:ss").toStdString(); + auto& storage = GetRecordStorage(); + auto timeCond = c(&DbRecord::beginTime) >= begin_date_time and c(&DbRecord::beginTime) <= end_date_time; + std::vector v = storage.get_all();//where(timeCond) + + UpdateRecordList(v); +} + +void RecordQuery::on_btnFirstPage_clicked() +{ + +} + + +void RecordQuery::on_btnPreviousPage_clicked() +{ + +} + + +void RecordQuery::on_btnNextPage_clicked() +{ + +} + + +void RecordQuery::on_btnLastPage_2_clicked() +{ + +} + + +void RecordQuery::on_spbGoToPage_valueChanged(int arg1) +{ + +} + + +void RecordQuery::on_tblRecordList_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous) +{ + int currentRow = ui->tblRecordList->currentRow(); + if(currentRow == -1){ + ui->txtCurrentItemMessageContent->clear(); + }else{ + ui->txtCurrentItemMessageContent->setText(ui->tblRecordList->item(currentRow,6)->text());//NOTE:注意此处的列数 + } +} + + +void RecordQuery::on_chbTime_stateChanged(int arg1) +{ + ui->dteBeginTime->setEnabled(arg1 == Qt::CheckState::Checked); + ui->dteEndTime->setEnabled(arg1 == Qt::CheckState::Checked); +} + + +void RecordQuery::on_chbChannel_stateChanged(int arg1) +{ + ui->chbChannelUHF->setEnabled(arg1 == Qt::CheckState::Checked); + ui->chbChannelS->setEnabled(arg1 == Qt::CheckState::Checked); + ui->chbChannelBeiDou->setEnabled(arg1 == Qt::CheckState::Checked); +} + + +void RecordQuery::on_chbType_stateChanged(int arg1) +{ + ui->chbCall->setEnabled(arg1 == Qt::CheckState::Checked); + ui->chbMessage->setEnabled(arg1 == Qt::CheckState::Checked); +} + + +void RecordQuery::on_chbDirection_stateChanged(int arg1) +{ + ui->chbSend->setEnabled(arg1 == Qt::CheckState::Checked); + ui->chbReceive->setEnabled(arg1 == Qt::CheckState::Checked); +} + + +void RecordQuery::on_chbNumber_stateChanged(int arg1) +{ + ui->cmbNumber->setEnabled(arg1 == Qt::CheckState::Checked); +} + diff --git a/RecordQuery.h b/RecordQuery.h index a6239ab..b1f4530 100644 --- a/RecordQuery.h +++ b/RecordQuery.h @@ -3,6 +3,11 @@ #include #include +#include +#include + +#include +#include "spdlog/spdlog.h" enum class Channel{ Uhf, @@ -28,6 +33,17 @@ struct Record{ QString number; QString content; bool isUnread; + uint32_t callDuration;//s +}; +struct DbRecord{ + uint64_t id; + std::string beginTime; + int channel; + int type; + int direction; + std::string number; + std::string content; + uint32_t callDuration;//s }; @@ -35,6 +51,7 @@ namespace Ui { class RecordQuery; } +class QTableWidgetItem; class RecordQuery : public QWidget { Q_OBJECT @@ -42,9 +59,40 @@ class RecordQuery : public QWidget public: explicit RecordQuery(QWidget *parent = nullptr); ~RecordQuery(); + void InsertRecord(const Record& data); + void InsertRecords(const std::vector& data); +private slots: + void on_btnQuery_clicked(); + + void on_btnFirstPage_clicked(); + + void on_btnPreviousPage_clicked(); + + void on_btnNextPage_clicked(); + + void on_btnLastPage_2_clicked(); + + void on_spbGoToPage_valueChanged(int arg1); + + void on_tblRecordList_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous); + + void on_chbTime_stateChanged(int arg1); + + void on_chbChannel_stateChanged(int arg1); + + void on_chbType_stateChanged(int arg1); + + void on_chbDirection_stateChanged(int arg1); + + void on_chbNumber_stateChanged(int arg1); private: Ui::RecordQuery *ui; + + std::shared_ptr m_logger; + + void InitDatabase(); + void UpdateRecordList(const std::vector& r); }; #endif // RECORDQUERY_H diff --git a/RecordQuery.ui b/RecordQuery.ui index 2f7a481..961b681 100644 --- a/RecordQuery.ui +++ b/RecordQuery.ui @@ -19,7 +19,7 @@ 记录查询 - + @@ -31,63 +31,7 @@ - - - - 通话 - - - - - - - 接收 - - - - - - - 北斗 - - - - - - - 发送 - - - - - - - 开始时间: - - - - - - - 短消息 - - - - - - - 方向: - - - - - - - 通道: - - - - + 结束时间: @@ -95,41 +39,166 @@ - + 类型: + + false + + + + + + + + + + 时间: + + + false + + + + + + + 通道: + + + false + + + + + + + false + + + + + + + false + + + + + + + 方向: + + + false + - + 号码: + + false + - - + + - S + 开始时间: + + false + UHF - - + + + + false + + + S + + + false + + - - + + + + false + + + 北斗 + + - + + + + false + + + 通话 + + + + + + + false + + + 短消息 + + + true + + + + + + + false + + + 发送 + + + false + + + + + + + false + + + 接收 + + + true + + + + + + false + true @@ -143,6 +212,30 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 查询 + + + + + @@ -154,6 +247,15 @@ + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + 开始时间 @@ -207,7 +309,7 @@ - + ... @@ -227,7 +329,7 @@ - + ... @@ -244,7 +346,7 @@ - + 80 @@ -254,7 +356,7 @@ - + ... @@ -271,7 +373,7 @@ - + ... diff --git a/mainwindow.cpp b/mainwindow.cpp index 7285620..b588658 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -23,16 +23,24 @@ qreal get_rand(qreal maxValue) { return rand() * 1.0 / RAND_MAX * maxValue; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); + + m_loggerWidget = std::make_shared();//需要在RecordQuery创建前 + m_loggerWidget->hide(); + + m_recordQueryWidget = std::make_shared(); + m_recordQueryWidget->hide(); + + createBeiDouSignalStrengthChart(); createAzimuthMapChart(); ui->btnCallReject->hide(); - m_udpSocket = std::make_shared(); - m_recordQueryWidget = std::make_shared(); - m_recordQueryWidget->hide(); - m_loggerWidget = std::make_shared(); - m_loggerWidget->hide(); + m_udpSocket = std::make_shared(); + m_udpServerSocket = std::make_shared(); + connect(&*m_udpServerSocket, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams); + + m_logger = spdlog::get("logger"); test(); } @@ -47,6 +55,23 @@ void MainWindow::keyPressEvent(QKeyEvent* event){ } } +void MainWindow::readPendingDatagrams(){ + while (m_udpServerSocket->hasPendingDatagrams()) { + QByteArray datagram; + datagram.resize(m_udpServerSocket->pendingDatagramSize()); + + QHostAddress sender; + quint16 senderPort; + + // 读取数据报 + m_udpServerSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); + + //TODO:处理数据包 + //qDebug() << "Received datagram from" << sender.toString() << ":" << senderPort; + //qDebug() << "Data:" << datagram; + } +} + void MainWindow::test() { // 随机生成信号能量数据 @@ -70,6 +95,7 @@ void MainWindow::test() { r1.number = "10001"; r1.content = "地阿斯顿发射点发大水发大水发"; r1.isUnread = true; + r1.callDuration = 0; Record r2; r2.beginTime = QDateTime::currentDateTime(); @@ -79,6 +105,7 @@ void MainWindow::test() { r2.number = "10002"; r2.content = "dsfgdsfgsdfgsdfgdfsgdsfgdsfg"; r2.isUnread = false; + r1.callDuration = 0; Record r3; r3.beginTime = QDateTime::currentDateTime(); @@ -88,11 +115,17 @@ void MainWindow::test() { r3.number = "10003"; r3.content = "fdghfgdhfghdfghdfghdfghf"; r3.isUnread = true; + r1.callDuration = 30; m_msgList.push_back(r1); m_msgList.push_back(r2); m_msgList.push_back(r3); UpdateMessageList(); + + m_recordQueryWidget->InsertRecords(m_msgList); + + + m_logger->info("{}---{}---{}",1,"22",30); } //-------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- @@ -204,7 +237,7 @@ void MainWindow::UpdateMessageList() { //插入所有项 int rowIndex = 0; for (int index = 0; index < m_msgList.size(); index++) { - Record r = m_msgList[index]; + Record& r = m_msgList[index]; int column_index = 0; // 读取状态 auto item = new QTableWidgetItem(r.isUnread ? "未读" : "已读"); @@ -335,6 +368,10 @@ void MainWindow::on_tblMessageList_currentItemChanged(QTableWidgetItem *current, ui->txtCurrentItemMessageContent->clear(); }else{ ui->txtCurrentItemMessageContent->setText(m_msgList[currentRow].content); + if(m_msgList[currentRow].isUnread){ + m_msgList[currentRow].isUnread = true; + ui->tblMessageList->item(currentRow,0)->setText("已读"); + } } } diff --git a/mainwindow.h b/mainwindow.h index d513ed6..6600f7a 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -9,6 +9,8 @@ #include "RecordQuery.h" #include "LoggerWidget.h" +#include "spdlog/spdlog.h" + QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; @@ -53,6 +55,8 @@ private slots: void on_btnRecordQuery_clicked(); + void readPendingDatagrams(); + void on_tblMessageList_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous); protected: void keyPressEvent(QKeyEvent* event) override; @@ -80,6 +84,7 @@ private: Ui::MainWindow *ui; CallStatus m_callStatus = CallStatus::Idle; std::shared_ptr m_udpSocket; + std::shared_ptr m_udpServerSocket; std::shared_ptr m_recordQueryWidget; std::shared_ptr m_loggerWidget; QChart* m_signalStrengthChart; @@ -87,6 +92,8 @@ private: QBarCategoryAxis* m_signalStrengthChartXAxis; QValueAxis* m_signalStrengthChartYAxis; + std::shared_ptr m_logger; + std::vector m_msgList; }; #endif // MAINWINDOW_H diff --git a/res/first_page.png b/res/first_page.png index b118b2e..e37d231 100644 Binary files a/res/first_page.png and b/res/first_page.png differ diff --git a/res/last_page.png b/res/last_page.png index 8462c1b..4603769 100644 Binary files a/res/last_page.png and b/res/last_page.png differ diff --git a/res/next_page.png b/res/next_page.png index 1b998f7..fe23ac1 100644 Binary files a/res/next_page.png and b/res/next_page.png differ diff --git a/res/previous_page.png b/res/previous_page.png index 4b2fda0..cbdd866 100644 Binary files a/res/previous_page.png and b/res/previous_page.png differ