2025-09-25 19:20:25 +08:00
|
|
|
|
#include "QWHome.h"
|
|
|
|
|
|
#include "common/Spdlogger.h"
|
|
|
|
|
|
#include "app/Config.h"
|
|
|
|
|
|
#include "common/Utils.h"
|
|
|
|
|
|
#include "app/Application.h"
|
|
|
|
|
|
#include "app/AppData.h"
|
|
|
|
|
|
#include "app/Station.h"
|
|
|
|
|
|
#include "protocol/MqttEntity.h"
|
|
|
|
|
|
|
2025-09-29 18:31:44 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-25 19:20:25 +08:00
|
|
|
|
QWHome::QWHome(QWidget* parent) : MyWidget(parent)
|
|
|
|
|
|
{
|
2025-09-29 18:31:44 +08:00
|
|
|
|
this->setObjectName("home");
|
|
|
|
|
|
this->setStyleSheet("#home { background-color:rgba(100,100,100,50); }");
|
2025-09-25 19:20:25 +08:00
|
|
|
|
|
2025-09-29 18:31:44 +08:00
|
|
|
|
int x = 10, y = 0;
|
2025-09-25 19:20:25 +08:00
|
|
|
|
{
|
|
|
|
|
|
this->groupSys = MyQUI::GroupBox(this, x, y, 1190, 120, "系统");
|
|
|
|
|
|
auto pw = groupSys.get();
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
x = 10, y += 130;
|
|
|
|
|
|
this->groupHttp = MyQUI::GroupBox(this, x, y, 390, 120, "HTTP");
|
|
|
|
|
|
auto pw = groupHttp.get();
|
2025-09-29 18:31:44 +08:00
|
|
|
|
this->addPair("http-t", pw, 20, 20, "服务类型: ", "服务端");
|
|
|
|
|
|
this->addPair("http-p", pw, 20, 50, "服务端口: ", Utils::toStr(Config::option.http.port));
|
|
|
|
|
|
this->addPair("http-s", pw, 20, 80, "服务状态: ", "运行");
|
2025-09-25 19:20:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
x += 400;
|
|
|
|
|
|
this->groupMqtt = MyQUI::GroupBox(this, x, y, 390, 120, "MQTT");
|
|
|
|
|
|
auto pw = groupMqtt.get();
|
2025-09-29 18:31:44 +08:00
|
|
|
|
this->addPair("mqtt-t", pw, 20, 20, "服务类型: ", "客户端");
|
|
|
|
|
|
this->addPair("mqtt-h", pw, 20, 50, "服务地址: ", Config::option.mqtt.host);
|
|
|
|
|
|
this->addPair("mqtt-s", pw, 20, 80, "服务状态: ", "---");
|
2025-09-25 19:20:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
x += 400;
|
|
|
|
|
|
this->groupDB = MyQUI::GroupBox(this, x, y, 390, 120, "数据库");
|
|
|
|
|
|
auto pw = groupDB.get();
|
2025-09-29 18:31:44 +08:00
|
|
|
|
this->addPair("db-n", pw, 20, 20, "数据库名: ", Config::option.database.dbname);
|
|
|
|
|
|
this->addPair("db-h", pw, 20, 50, "主机地址: ", Config::option.database.host);
|
|
|
|
|
|
this->addPair("db-u", pw, 20, 80, "用 户 名: ", Config::option.database.user);
|
|
|
|
|
|
|
2025-09-25 19:20:25 +08:00
|
|
|
|
|
|
|
|
|
|
table = std::make_shared<QTableWidget>(this);
|
2025-09-29 18:31:44 +08:00
|
|
|
|
table->setGeometry(10, y += 130, 1190, 265);
|
2025-09-25 19:20:25 +08:00
|
|
|
|
table->setStyleSheet(QSS_TABLE.c_str());
|
|
|
|
|
|
table->horizontalHeader()->setStretchLastSection(true); // 最后一列占满
|
|
|
|
|
|
table->verticalHeader()->setVisible(false); // 不显示垂直表头
|
|
|
|
|
|
table->setEditTriggers(QAbstractItemView::NoEditTriggers); // 单元格不可编辑
|
|
|
|
|
|
table->setSelectionMode(QAbstractItemView::SingleSelection); // 设置为单选模式
|
|
|
|
|
|
table->setSelectionBehavior(QAbstractItemView::SelectRows); // 设置为整行选中
|
|
|
|
|
|
table->horizontalHeader()->setFixedHeight(50);
|
|
|
|
|
|
table->horizontalHeader()->setDefaultSectionSize(60);
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem* headerItem;
|
|
|
|
|
|
QStringList headerText_Row, headerText_Col;
|
|
|
|
|
|
headerText_Row << "ID" << "站名" << "编号" << "状态" << "MQTT状态" << "召测(秒)"
|
|
|
|
|
|
<< "日充电\n电量" << "日放电\n电量" << "总充电\n电量" << "总放电\n电量"
|
|
|
|
|
|
<< "日充电\n费用" << "日放电\n费用" << "总充电\n费用" << "总放电\n费用"
|
|
|
|
|
|
<< "日收益" << "总收益" << "--";
|
|
|
|
|
|
|
|
|
|
|
|
// 设置为水平表头
|
|
|
|
|
|
table->setColumnCount(headerText_Row.size());
|
|
|
|
|
|
table->setHorizontalHeaderLabels(headerText_Row);
|
|
|
|
|
|
table->setColumnWidth(0, 50);
|
|
|
|
|
|
table->setColumnWidth(1, 120);
|
|
|
|
|
|
table->setColumnWidth(2, 50);
|
|
|
|
|
|
table->setColumnWidth(4, 80);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-29 18:31:44 +08:00
|
|
|
|
logFilter = MyQUI::PairLine(this, 10, y += 270, "日志过滤: ", "", false);
|
|
|
|
|
|
btnLogClean = std::make_shared<QPushButton>("清除", this);
|
|
|
|
|
|
btnLogClean->setGeometry(400, y, 80, 26);
|
|
|
|
|
|
connect(btnLogClean.get(), &QPushButton::clicked, this, [=]() { texteditLog->clear(); });
|
|
|
|
|
|
|
|
|
|
|
|
texteditLog = std::make_shared<QTextEdit>(this);
|
|
|
|
|
|
texteditLog->setGeometry(10, y += 30, 1190, 280);
|
|
|
|
|
|
texteditLog->setStyleSheet("background-color: transparent; border: 1px solid gray; font-weight: 400;");
|
|
|
|
|
|
texteditLog->setReadOnly(true);
|
2025-09-25 19:20:25 +08:00
|
|
|
|
|
|
|
|
|
|
{
|
2025-09-29 18:31:44 +08:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// QT显示spdlog: 方法一
|
2025-09-25 19:20:25 +08:00
|
|
|
|
// 第二个参数是方法函数名称,即调用 QTextEdit的appeng函数;
|
2025-09-29 18:31:44 +08:00
|
|
|
|
//auto qtSink = std::make_shared<spdlog::sinks::qt_sink_mt>(textLog.get(), "append");
|
|
|
|
|
|
//spdlog::default_logger()->sinks().push_back(qtSink);
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// QT显示spdlog: 方法二, 自定义实现 QtLogSink
|
|
|
|
|
|
myqtSink = std::make_shared<QtLogSink>(this);
|
|
|
|
|
|
spdlog::default_logger()->sinks().push_back(myqtSink);
|
|
|
|
|
|
//auto logger = std::make_shared<spdlog::logger>("custom_logger", myqtSink);
|
|
|
|
|
|
//spdlog::register_logger(logger);
|
|
|
|
|
|
|
|
|
|
|
|
// 连接信号和槽,使用Qt::QueuedConnection确保线程安全
|
|
|
|
|
|
connect(myqtSink.get(), &QtLogSink::logMessageReceived, this, &QWHome::onLogMessageReceived, Qt::QueuedConnection);
|
2025-09-25 19:20:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-29 18:31:44 +08:00
|
|
|
|
QWHome::~QWHome()
|
2025-09-25 19:20:25 +08:00
|
|
|
|
{
|
2025-09-29 18:31:44 +08:00
|
|
|
|
table->clear();
|
|
|
|
|
|
mapPairs.clear();
|
2025-09-25 19:20:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-29 18:31:44 +08:00
|
|
|
|
void QWHome::addPair(string name, QWidget* parent, int x, int y, string k, string v, bool readonly /*= true*/)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (name.empty()) name = k;
|
|
|
|
|
|
mapPairs[name] = MyQUI::PairLine(parent, x, y, k, v);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-25 19:20:25 +08:00
|
|
|
|
void QWHome::onTimer()
|
|
|
|
|
|
{
|
2025-09-29 18:31:44 +08:00
|
|
|
|
if (!this->isVisible()) { return; }
|
|
|
|
|
|
|
2025-09-25 19:20:25 +08:00
|
|
|
|
auto& appdata = Application().data();
|
|
|
|
|
|
int rowNo = 0;
|
|
|
|
|
|
int tsNow = Utils::time();
|
|
|
|
|
|
for (auto& item : appdata.mapStation)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& station = item.second;
|
|
|
|
|
|
if (rowNo >= table->rowCount())
|
|
|
|
|
|
{
|
|
|
|
|
|
table->insertRow(rowNo);
|
|
|
|
|
|
}
|
|
|
|
|
|
bool isOpen = station->status > 0;
|
|
|
|
|
|
bool isConnected = station->mqttCli->isConnected;
|
|
|
|
|
|
|
2025-09-29 18:31:44 +08:00
|
|
|
|
MyQUI::setTableCell(table, rowNo, 0, std::to_string(station->stationId));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 1, station->name);
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 2, station->code);
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 3, isOpen ? "启用" : "未启用", isOpen ? "OK" : "ERR");
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 4, isConnected ? "连接成功" : "未连接", isConnected ? "OK" : "ERR");
|
2025-09-25 19:20:25 +08:00
|
|
|
|
|
|
|
|
|
|
int tsPolling = station->getPollingTS();
|
2025-09-29 18:31:44 +08:00
|
|
|
|
MyQUI::setTableCell(table, rowNo, 5, tsPolling > 0 ? std::to_string(tsNow - tsPolling) + "/" + std::to_string(Config::option.mqtt.interval) : "--");
|
|
|
|
|
|
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 6, Utils::toStr(station->statData.dayElectIn, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 7, Utils::toStr(station->statData.dayElectOut, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 8, Utils::toStr(station->statData.totalElectIn, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 9, Utils::toStr(station->statData.totalElectOut, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 10, Utils::toStr(station->statData.dayFeeIn, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 11, Utils::toStr(station->statData.dayFeeOut, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 12, Utils::toStr(station->statData.totalFeeIn, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 13, Utils::toStr(station->statData.totalFeeOut, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 14, Utils::toStr(station->statData.dayIncome, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 15, Utils::toStr(station->statData.totalIncome, 0));
|
|
|
|
|
|
MyQUI::setTableCell(table, rowNo, 16, station->statData.ts > 0 ? Utils::timeStr(station->statData.ts) : "--");
|
2025-09-25 19:20:25 +08:00
|
|
|
|
|
|
|
|
|
|
rowNo++;
|
|
|
|
|
|
}
|
2025-09-29 18:31:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void QWHome::onLogMessageReceived(const QString& message)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!this->isVisible()) { return; }
|
|
|
|
|
|
|
|
|
|
|
|
bool show = true;
|
|
|
|
|
|
if (logFilter.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto filter = logFilter.second->text();
|
|
|
|
|
|
if (!filter.isEmpty() && !message.contains(filter))
|
|
|
|
|
|
{
|
|
|
|
|
|
show = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (show)
|
|
|
|
|
|
{
|
|
|
|
|
|
texteditLog->append(message.trimmed());
|
|
|
|
|
|
}
|
2025-09-25 19:20:25 +08:00
|
|
|
|
}
|