
#include <QFileDialog>
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "TcpClient.h"

#define DEBUG_HTTP 1

MainWindow::MainWindow(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    this->statusBar = new QStatusBar();
    this->statusInfo = new QLabel("初始化完成",this);
    this->statusBar->addPermanentWidget(this->statusInfo);//显示正常信息
    QLabel* statusVersion = new QLabel("开启时间:" + QDateTime::currentDateTime().toString("yy.MM.dd.hh.mm"),this);
    this->statusBar->addWidget(statusVersion);

    layout()->addWidget(this->statusBar);

    this->setWindowTitle("Matrix_RFID 车号识别程序(勿关！！)");
    this->configPath_ = "./config/config.ini";

    if (!this->mkLogDir())
    {
        this->logError("创建Log目录失败！");
    }

    // 配置文件读取
    QString errorMessage = "";
    if (!ConfigUtil::readBaseConfig(this->configPath_, errorMessage, this->baseConfig_))
    {
        this->logError(errorMessage);
    }
    if (!ConfigUtil::readInterfaceConfig(this->configPath_, errorMessage, this->interfaceConfig_))
    {
        this->logError(errorMessage);
    }
    if (!ConfigUtil::readSocketServerConfig(this->configPath_, errorMessage, this->socketServerConfig_))
    {
        this->logError(errorMessage);
    }

    // 获取本机串口列表
    this->getComList();

    // 初始化界面上的串口打开参数
    this->initComboBox();

    this->serial_ = new QSerialPort;


    m_pSystemTray=new QSystemTrayIcon(this);

    connect(this->ui->openComButton, &QPushButton::clicked, this, &MainWindow::openComClicked);

    connect(this, &MainWindow::getRfid_signals, this, &MainWindow::getQueueDataThread);

    connect(this, &MainWindow::upRfid_signals, this, &MainWindow::upRfid);

    connect(this->ui->testButton, &QPushButton::clicked, this, &MainWindow::readTestInfo);
    // 识别状态改变
    connect(this, &MainWindow::IdentifyType, this, &MainWindow::IdentifyTypeUpdate);
    //最小化信号槽
    connect(m_pSystemTray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason)));

    this->logRfidRecvName = "./Logs/rfid_data.txt";
    this->recvLog.setFileName(logRfidRecvName);
    this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append);

    //初始最小化
    //this->showMinimized();//最小化
    // 设置最大展示数据行数
    this->ui->textBrowser->document()->setMaximumBlockCount(1000);

    getStandardItemModel();
    this->ui->resultTable->setModel(this->resultTableModel_);
    this->ui->resultTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    this->ui->resultTable->verticalHeader()->setMinimumWidth(50);

    if (!this->baseConfig_.upResult)
    {
        QIcon icon("./Fail.ico");
        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
        this->ui->upflagLabel->setPixmap(m_pic);
    }else{
        QIcon icon("./Succ.ico");
        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
        this->ui->upflagLabel->setPixmap(m_pic);
    }

    if (this->baseConfig_.useSocketServer)
    {
        // 创建线程
        QThread *threadWork = new QThread;   // 任务线程

        this->tcpClient = new TcpClient(this);
        this->tcpClient->moveToThread(threadWork);

        connect(this, &MainWindow::connect_socket, this->tcpClient, &TcpClient::connectToServer);

        // 子线程反馈 socket 到主线程
        connect(this->tcpClient, &TcpClient::socketComplete, this, [=](QTcpSocket* tcp, QString ip, quint16 port){
            this->tcp_ = tcp;
        });

        // 接收子线程的消息提示
        connect(this->tcpClient, &TcpClient::sendTcpInfoSignals, this, [=](const QString& info){
            this->logInfo(info);
            this->statusInfo->setText(info);
            if (info == "链接服务端超时"
            || info == "未连接Socket服务器"
            || info == "链接服务端失败"
            || info == "服务端断开连接"
            || info == "链接服务端失败")
            {
                this->videoHasTrain = false;
            }
        });
        // 接收子线程的TCP消息内容展示
        connect(this->tcpClient, &TcpClient::getTcpInfoSignals, this, [=](const QString& info){
            this->logInfo(info);
        });

        emit connect_socket(this->socketServerConfig_.server_ip, this->socketServerConfig_.server_port);

        connect(this->tcpClient, &TcpClient::comeTrainSignals, this, [=](bool type) {
            if (type)
            {
                this->logInfo("视频车号识别-来车了");
                this->videoHasTrain = true;
                emit IdentifyType();
            }
            else
            {
                this->logInfo("视频车号识别-火车离开了");
                this->videoHasTrain = false;
                if (this->needIdentify)
                    emit IdentifyType();
            }
        });
        connect(this->tcpClient, &TcpClient::getDirectionSignals, this, [=](int direction) {
            if (this->iDirection == 0)
            {
                this->logInfo("获得方向判定：" + QString(direction > -1 ? (direction > 0 ? "需识别" : "待定") : "无需上传"));
                this->iDirection = direction;
            }
        });
    }

    ui->openComButton->click();

    this->upResultThread = new UpResultThread(&this->queueTrainInfo_, &this->iDirection, this);
    this->upResultThread->start();

    connect(this->upResultThread, &UpResultThread::DebugSignals, this, &MainWindow::DebugSlots);
    connect(this->upResultThread, &UpResultThread::InfoSignals, this, &MainWindow::InfoSlots);
    connect(this->upResultThread, &UpResultThread::WarnSignals, this, &MainWindow::WarnSlots);
    connect(this->upResultThread, &UpResultThread::ErrorSignals, this, &MainWindow::ErrorSlots);
}

MainWindow::~MainWindow()
{
    this->logInfo("-- 程序退出 --");
    this->initParam();
    delete ui;
}

void MainWindow::logDebug(const QString& message) {
    LogDebug << message.toStdString();
    ui->textBrowser->append(QString("[Debug] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}
void MainWindow::logInfo(const QString& message) {
    LogInfo << message.toStdString();
    ui->textBrowser->append(QString("[Info] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}
void MainWindow::logWarn(const QString& message) {
    LogWarn << message.toStdString();
    ui->textBrowser->append(QString("[Warn] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}
void MainWindow::logError(const QString& message) {
    LogError << message.toStdString();
    ui->textBrowser->append(QString("[Error] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}

void MainWindow::initParam() {
    this->rfidSourceInfo = "";
    this->trainTime = "";
    if (this->recvLog.isOpen()) this->recvLog.close();
    this->vecTrain.clear();
    this->needIdentify = false;
    this->rnameRfidLog();
    this->queue_.clear();
    this->iDirection = 0;
}

/**
 * 创建日志目录
 * @return bool
 */
bool MainWindow::mkLogDir()
{
    if (_access("Logs", 0) == -1) {				//判断是否存在日志的文件夹，没有则创建
        std::string folderPath = "Logs";
        if (0 != _mkdir(folderPath.c_str()))
        {
            return false;
        }
    }
    return true;
}

bool MainWindow::mkRfidLog()
{
    try {
        QFileInfo fileInfo(this->logRfidRecvName);
        if(fileInfo.isFile())
        {
            return true;
        }
        this->recvLog.setFileName(this->logRfidRecvName);
        if (!this->recvLog.isOpen())
        {
            this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append);
        }
        return true;
    } catch (const std::exception &e) {
        this->logError("创建、打开RFID原始数据日志文件失败,详细：");
        this->logError(e.what());
    }
    return false;
}

void MainWindow::deleteOldFiles(const QString &path, int days)
{
    QDir dir(path);
    foreach(QFileInfo fi, dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot))
    {
        if((fi.lastModified().addDays(days) < QDateTime::currentDateTime()))
        {
            QFile::remove(fi.absoluteFilePath());
        }
    }
}

bool MainWindow::rnameRfidLog()
{
    try {
        this->recvLog.close();
        QFile logFile(this->logRfidRecvName);
        QFileInfo fileInfo(logFile);
        if (fileInfo.size() == 0) return false;

        QString newLogFileName = fileInfo.path() + "/";
        newLogFileName.append(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss"));
        newLogFileName.append(".txt");

        if (!logFile.rename(newLogFileName))
        {
            this->logError("读取RFID原始数据，存储重命名失败！");
            return false;
        }

        this->deleteOldFiles(fileInfo.path(), 3);
    } catch (const std::exception &e) {
        this->logError("读取RFID原始数据，存储重命名失败！");
        return false;
    }
    return true;
}

void MainWindow::saveRfidLog(const QString &value)
{
    try {
        QString logValue = value + "\n";
        if (!this->recvLog.isOpen())
        {
            this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append);
        }
        this->recvLog.write(logValue.toUtf8());
        this->recvLog.flush();
    } catch (const std::exception &e) {
        this->logError("保存RFID原数据失败");
    }
}

/**
 * 获取本地所有串口
 * @return
 */
QList<QString> MainWindow::getComList() {
    // 获取系统所有串口信息
    QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts();
    for (const auto & availablePort : availablePorts) {
        this->comList.append(availablePort.portName());
    }
    return this->comList;
}

/**
 * 初始化 comboxBox 组件的值
 */
void MainWindow::initComboBox() {
//    ui->BTBox->setEditable(true);
    ui->BTBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(225, 225, 225);}");
    ui->BTBox->setView(new QListView());
    ui->comBox->setEditable(true);
    ui->comBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(225, 225, 225);}");
    ui->comBox->setMaxVisibleItems(5);
    ui->comBox->setView(new QListView());
    ui->comBox->addItems(this->comList);
    if (this->baseConfig_.comName != "") {
        if (ui->comBox->findText(this->baseConfig_.comName) == -1)
        {
            ui->comBox->addItem(this->baseConfig_.comName);
        }
        ui->comBox->setCurrentText(this->baseConfig_.comName);
    }
    if (ui->BTBox->findText(QString::number(this->baseConfig_.baud)) == -1)
    {
        ui->BTBox->addItem(QString::number(this->baseConfig_.baud));
    }
    ui->BTBox->setCurrentText(QString::number(this->baseConfig_.baud));

    ui->truckEdit->setText(QString::number(this->baseConfig_.trackName));

    this->rfidHasTrain = false;
    this->videoHasTrain = false;
}

/**
 * @brief:获取系统时间
 * @param：
 * @return:空
 */
QString MainWindow::getSystemTime()
{
    return QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
}

/**
 * 获取结果框的ItemModel
 * @return
 */
QStandardItemModel* MainWindow::getStandardItemModel()
{
    if (this->resultTableModel_== nullptr) this->resultTableModel_ = new QStandardItemModel();
    this->resultTableModel_->setColumnCount(1);
    this->resultTableModel_->setHeaderData(0,Qt::Horizontal, "车号");
    return this->resultTableModel_;
}

QStandardItem* MainWindow::getStandardItem(const QString &value)
{
    QStandardItem *resultTableItem = new QStandardItem();
    resultTableItem->setTextAlignment(Qt::AlignCenter);
    resultTableItem->setText(value);
    return resultTableItem;
}

/***************************最小化相关****************************************/
/**
 * @brief:接收最小化信号
 * @param：
 * @return:空
 */
void MainWindow::changeEvent(QEvent *event)
{
    if((event->type()==QEvent::WindowStateChange)&&isMinimized())
    {
        this->hide();
        m_pSystemTray->setIcon(QIcon("./logo.ico"));     // 托盘时显示的图片
        m_pSystemTray->setToolTip("Rfid车号识别-股道号:" + QString::number(this->baseConfig_.trackName));                                             // 鼠标在托盘图片时的提示
        m_pSystemTray->showMessage("Rfid车号识别","已隐藏至托盘",QSystemTrayIcon::Information,10000);
        event->ignore();
        //建立托盘操作的菜单
        creat_action();
        creat_menu();
        m_pSystemTray->show();   // 显示图片图标
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    // 弹出对话框要求用户输入账号和密码
    QString password = QInputDialog::getText(this, "密码验证", "请输入密码：", QLineEdit::Password);

    // 验证账号和密码是否正确
    if (password == "matrix") {
        this->initParam();
        this->tcp_->close();
        event->accept();  // 关闭窗口
        exit(0);
    } else {
        QMessageBox::warning(this, "验证失败", "密码不正确！");
        event->ignore();  // 阻止关闭窗口
    }
}

void MainWindow::creat_action()
{
    m_pActionShow = new QAction("主界面", this);
    connect(m_pActionShow, &QAction::triggered, this,&MainWindow::on_ShowMainAction);
//    m_pActionQuit = new QAction("退出", this);
//    connect(m_pActionQuit, &QAction::triggered, this, &MainWindow::on_ExitAppAction);
}

void MainWindow::creat_menu()
{
    m_pTrayMennu = new QMenu(this);
    //新增菜单项---显示主界面
    m_pTrayMennu->addAction(m_pActionShow);
    //增加分隔符
//    m_pTrayMennu->addSeparator();
//    //新增菜单项---退出程序
//    m_pTrayMennu->addAction(m_pActionQuit);
    //把QMenu赋给QSystemTrayIcon对象
    m_pSystemTray->setContextMenu(m_pTrayMennu);
}

/**
* @brief:显示
* @param：
* @return:空
*/
void MainWindow::on_ShowMainAction()
{
    this->show();
    this->showNormal();
    this->activateWindow();
}

void MainWindow::on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason reason)
{
    switch(reason){
        case QSystemTrayIcon::Trigger:
            //单击托盘图标
            this->showNormal();
            break;
        case QSystemTrayIcon::DoubleClick:
            //双击托盘图标
            //双击后显示主程序窗口
            this->showNormal();
            this->activateWindow();
            break;
        default:
            break;
    }
}

/********************************串口操作*************************************/
bool MainWindow::connectCom()
{
    this->serial_ = this->comDetect_.openCom(ui->comBox->currentText(), ui->BTBox->currentText().toInt());

    if (this->serial_ != nullptr) {
        QString logs;
        logs.append("串口打开成功\n");
        logs.append("串口号:" + ui->comBox->currentText() + "\n");
        logs.append("波特率:" + ui->BTBox->currentText() + "\n");
        if (this->baseConfig_.havaMagnetSteel)
            logs.append("磁钢顺序:" + this->baseConfig_.magnetSteelOrder);
        this->isOpenCom = true;
        this->logInfo(logs);
        this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
                                          "background-color: rgba(74, 221, 108, 225);\ "
                                          "border:1px solid rgba(168, 168, 168, 105);");
        connect(this->serial_, &QSerialPort::readyRead, this, &MainWindow::readCom); //

        connect(this->serial_, &QSerialPort::errorOccurred, this, &MainWindow::serialPort_error);
        return true;
    }
    else
    {
        return false;
    }
}

/**
 * 打开串口
 */
void MainWindow::openComClicked()
{
    if (ui->openComButton->text() == "打开串口")
    {
        this->auto_reconnect_serial_ = true;
        this->ui->openComButton->setText("关闭串口");
        QtConcurrent::run([=](){
            while (this->auto_reconnect_serial_ && !this->isOpenCom) {
                if (!this->connectCom())
                {
                    this->isOpenCom = false;
                    this->comDetect_.closeCom();
                    this->logInfo("串口打开失败！10秒钟后将会重连...");
                } else {
                    return ;
                }
                QThread::sleep(10);
            }
        });



//        this->serial_ = this->comDetect_.openCom(ui->comBox->currentText(), ui->BTBox->currentText().toInt());
//
//        if (this->serial_ != nullptr)
//        {
//            QString logs;
//            logs.append("串口打开成功\n");
//            logs.append("串口号:" + ui->comBox->currentText() + "\n");
//            logs.append("波特率:" + ui->BTBox->currentText() + "\n");
//            if (this->baseConfig_.havaMagnetSteel)
//                logs.append("磁钢顺序:" + this->baseConfig_.magnetSteelOrder);
//            this->isOpenCom = true;
//            this->logInfo(logs);
////            this->ui->openComButton->setText("关闭串口");
//            this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
//                                              "background-color: rgba(74, 221, 108, 225);\ "
//                                              "border:1px solid rgba(168, 168, 168, 105);");
//            connect(this->serial_,&QSerialPort::readyRead,this,&MainWindow::readCom); //
//
//            connect(this->serial_, &QSerialPort::errorOccurred, this, &MainWindow::serialPort_error);
//
//        }
//        else
//        {
//            this->isOpenCom = false;
//            this->comDetect_.closeCom();
//            this->logInfo("串口打开失败！10秒钟后将会重连...");
//            this->ui->openComButton->setText("关闭串口");
//
//            QtConcurrent::run([=](){
//                QThread::sleep(10);
//                if (this->auto_reconnect_serial_ && !this->isOpenCom) {
//                    ui->openComButton->click();
//                }
//            });
//        }
    }
    else
    {
        this->auto_reconnect_serial_ = false;
        if (this->isOpenCom)
        {
            // 弹出对话框要求用户输入密码
            QString password = QInputDialog::getText(this, "密码验证", "请输入密码：", QLineEdit::Password);

            // 验证账号和密码是否正确
            if (password == "matrix") {
                if (this->comDetect_.closeCom())
                {
                    if (this->needIdentify == true) this->needIdentify = false;
                    this->isOpenCom = false;
                    this->logInfo("串口已关闭！");
                    this->initParam();
                    this->ui->openComButton->setText("打开串口");
                    this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
                                                      "background-color: red;\ "
                                                      "border:1px solid rgba(168, 168, 168, 105);");
                }
            } else {
                QMessageBox::warning(this, "验证失败", "密码不正确！");
            }
        }
        else
        {
            this->logInfo("串口已停止访问！");
            this->ui->openComButton->setText("打开串口");
        }
    }
}

/**
 * 串口异常退出的槽函数
 * @param error
 */
void MainWindow::serialPort_error(QSerialPort::SerialPortError error)
{
    if (error != QSerialPort::NoError)
    {
        //关闭串口
        this->serial_->close();
        this->ui->openComButton->setText("打开串口");
        this->logError("串口异常退出，疑似接口松动");
        this->ui->LEDlabel->setStyleSheet("border-radius: 16px; \ "
                                          "background-color: red;\ "
                                          "border:1px solid rgba(168, 168, 168, 105);");
        QtConcurrent::run([=](){
            QThread::sleep(10);
            if (this->auto_reconnect_serial_ && !this->isOpenCom) {
                this->connectCom();
            }
        });
    }
}

void MainWindow::readCom()
{
    try {
        if (this->serial_->waitForReadyRead(10)) {
            QByteArray data = this->serial_->readAll(); // 读取数据
            if(!data.isEmpty())
            {
                this->queue_.push(QString(data));
                emit getRfid_signals();
            }
//            this->serial_->clear();
            data.clear();
        }
        else
        {
            this->logError("等待读取超时");
        }
    } catch(...) {
        this->logError("读取串口数据异常！");
    }
}

/**
 * @brief:从queue中获取数据
 * @param:空
 * @return:空
 */
void MainWindow::getQueueDataThread()
{
    if (this->queue_.isEmpty()) return;

    QString strRfidInfo = this->queue_.getTop();
    this->queue_.pop();
    this->saveRfidLog(strRfidInfo);
    this->tmpRfid.append(strRfidInfo);
    if (this->tmpRfid.right(1) != "&")
    {
        return;
    }

    this->tmpRfid = this->tmpRfid.replace("&", "");
    QStringList rfidSubList = this->tmpRfid.split("@");
    this->tmpRfid = "";

    auto split_lambda = [=](QString strFirst, QString strOther){
        if (strFirst == "0")
        {
            this->rfidHasTrain = false;
            this->logInfo("RFID-火车离开了");
            // 关功放信号
            // 需要结合 “来车状态”广播消息，确认是否真的车离开了;  TODO:没有真离开，则向串口发送 @on& 避免关功放
            emit IdentifyType();
        }
        else
        {
            // TODO: 此处按照4个磁钢来配置，可能存在一定限制; 另外逻辑需要优化
            if (strOther == "000000"  // 第一次检测来车时（前提是上一次功放已关闭）
                && (strFirst == this->baseConfig_.magnetSteelOrder.left(1)
                    || strFirst == this->baseConfig_.magnetSteelOrder.mid(1, 1)))
            {
                this->rfidHasTrain = true;
                this->logInfo("RFID-来车了");
                emit IdentifyType();
            }
        }
    };

    for (const auto & i : rfidSubList)
    {
        if (i.size() == 26 || i.size() == 24)
        {
            // 车厢信息
            QString strTrainInfo = i.left(14);

            if (vecTrain.empty() || !vecTrain.contains(strTrainInfo))
            {
                bool isNoCarriage = false;
                int carT = strTrainInfo.mid(3, 2).simplified().toInt(&isNoCarriage);
                if (isNoCarriage && carT >= 10) continue;
                // 因信号不稳定 增加一行过滤  出现文字中带有字母及数字以外的字符时，过滤
                if (!strTrainInfo.contains(QRegExp("^[A-Z0-9\\s]+$"))) continue;
                // 因信号不稳定 增加一行过滤  出现读到的数据里 空格替代了实际字符的情况
                if (strTrainInfo.mid(7, 7).simplified().size() < 7) continue;
                vecTrain.append(strTrainInfo);
                int train_order = vecTrain.size();
                this->resultTableModel_->setItem(train_order - 1, 0, new QStandardItem(strTrainInfo));
                this->logInfo(QString("第%1节 %2").arg(train_order).arg(strTrainInfo));
                // 将接收到的RFID使用@符拼接起来，以待后续上传web
                this->rfidSourceInfo.append("@" + i);
                QString rfidinfo = this->rfidSourceInfo;
                this->rfidSourceInfo = "";
                emit upRfid_signals(rfidinfo);

            }
        }
        else if (i.size() == 7)
        {
            // 不使用磁钢的情况下 过滤掉磁钢信号
            if (!this->baseConfig_.havaMagnetSteel) continue;
            // 磁钢信号
            QString strFirst = i.left(1);
            QString strOther = i.mid(1, i.size() - 1);
            // 将接收到的RFID使用@符拼接起来，以待后续上传web
            this->rfidSourceInfo.append("@" + i);
            split_lambda(strFirst, strOther);
        }
        else if (i.size() == 14) // 特殊情况，来车信号少了&符
        {
            // 不使用磁钢的情况下 过滤掉磁钢信号
            if (!this->baseConfig_.havaMagnetSteel) continue;
            for (int j = 0; j < i.size(); j+=7) {
                QString rfid_cg = i.mid(j, 7);
                QString strFirst = rfid_cg.left(1);
                QString strOther = rfid_cg.mid(1, 6);
                // 将接收到的RFID使用@符拼接起来，以待后续上传web
                this->rfidSourceInfo.append("@" + rfid_cg);
                split_lambda(strFirst, strOther);
            }
        }
    }
}

void MainWindow::upRfid(QString rfidInfo)
{
    if (!this->baseConfig_.upResult) return;
    if (!this->needIdentify && this->baseConfig_.havaMagnetSteel)
    {
        QIcon icon("./Fail.ico");
        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
        this->ui->upflagLabel->setPixmap(m_pic);
        return;
    }else{
        QIcon icon("./Succ.ico");
        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
        this->ui->upflagLabel->setPixmap(m_pic);
    }

    QString info = this->vecTrain.back();
    int order = this->vecTrain.size();

    if (order > this->socketServerConfig_.delayed_upload && this->iDirection == 0)
    {
        this->iDirection = 1;
    }
    if (!this->baseConfig_.useSocketServer) this->iDirection = 1;

    info = info.mid(1,info.size() - 1);

    TrainInfo trainInfo;
    trainInfo.carriageType = info.left(6).simplified().toStdString();
    trainInfo.carriageNum = info.mid(6, info.size() - 6).simplified().toStdString();
    trainInfo.strOrder = QString::number(order).toStdString();
    trainInfo.trainTime = this->trainTime.toStdString();
    trainInfo.collectTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz").toStdString();
    trainInfo.strRfidInfo = rfidInfo.toStdString();

    this->queueTmpTrainInfo_.push(trainInfo);

    if (this->iDirection < 0)
    {
        this->queueTmpTrainInfo_.clear();
        return;
    }
    if (this->iDirection > 0)
    {
        while (!this->queueTmpTrainInfo_.isEmpty())
        {
            this->queueTrainInfo_.push(this->queueTmpTrainInfo_.pop());
        }
    }
}

void MainWindow::IdentifyTypeUpdate() {
    if (this->rfidHasTrain || this->videoHasTrain)
    {
        if (!this->needIdentify)
        {
            this->logInfo("来车了");
            this->mkRfidLog();
            this->vecTrain.clear();
            this->needIdentify = true;
            this->trainTime = this->getSystemTime();
            this->resultTableModel_->clear();
            this->resultTableModel_ = this->getStandardItemModel();
        }
    }
    else if (!this->rfidHasTrain && !this->videoHasTrain)
    {
        this->initParam();
        this->logInfo("火车离开了");
    }
}

void MainWindow::DebugSlots(const QString &info) {
    this->logDebug(info);
}

void MainWindow::InfoSlots(const QString &info) {
    this->logInfo(info);
}

void MainWindow::WarnSlots(const QString &info) {
    this->logWarn(info);
}

void MainWindow::ErrorSlots(const QString &info) {
    this->logError(info);
}

// ============================= 测试 ====================================

void MainWindow::readTestInfo()
{

    if (this->isOpenCom || ui->openComButton->text() == "关闭串口")
    {
        logWarn("请先关闭串口后进行测试操作！");
        return;
    }
    QString filePath = QFileDialog::getOpenFileName(this, "选择一个文件", QDir::currentPath(), "(*.*)");
    if(filePath.isEmpty()){
        QMessageBox::warning(this, "打开文件", "选择文件不能为空");
        return;
    }
    // 创建一个QFile对象并打开要读取的文本文件
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        logError("无法打开测试文件:" + filePath);
        return;
    }
    logInfo("开始读取测试数据...");
    // 将文件内容读入到QStringList中
    QTextStream in(&file);
    while(!in.atEnd()) {
        QString line = in.readLine();
        this->queue_.push(line);
        emit getRfid_signals();
    }
    // 关闭文件
    file.close();
    logInfo("---读取测试数据完毕---");
}