diff --git a/database/dao/DeviceDAO.cpp b/database/dao/DeviceDAO.cpp index 4f4c76c..e55ae65 100644 --- a/database/dao/DeviceDAO.cpp +++ b/database/dao/DeviceDAO.cpp @@ -154,6 +154,11 @@ DeviceInfo DeviceDAO::findUnmatchedDevice() { } bool DeviceDAO::upsertDevice(const DeviceInfo &device) { + if (device.id.isEmpty() || device.name.isEmpty()) { + qWarning() << "[DeviceDAO] upsertDevice skipped: empty id or name"; + return false; + } + QSqlQuery query(DatabaseManager::instance().database()); // Проверка: существует ли запись diff --git a/services/net/NetworkService.cpp b/services/net/NetworkService.cpp index f8ce951..d66319c 100644 --- a/services/net/NetworkService.cpp +++ b/services/net/NetworkService.cpp @@ -760,6 +760,7 @@ void NetworkService::syncDevicesFromServer(const QString &desktopId) { } const QJsonArray devicesArray = devicesResult.toArray(); + const QList allDevices = DeviceDAO::getAllDevices(false); QSet processedNames; // защита от дублей с сервера for (const QJsonValue &devVal : devicesArray) { @@ -775,7 +776,13 @@ void NetworkService::syncDevicesFromServer(const QString &desktopId) { } processedNames.insert(name); - // Проверяем: есть ли уже устройство с таким name в локальной БД + // Проверяем: есть ли уже устройство с таким apiId в локальной БД + bool apiIdExists = false; + for (const DeviceInfo &d : allDevices) { + if (d.apiId == apiId) { apiIdExists = true; break; } + } + if (apiIdExists) continue; + const DeviceInfo existing = DeviceDAO::findByName(name); if (!existing.id.isEmpty() && !existing.apiId.isEmpty()) { continue; diff --git a/views/bank/AccountSettingsWindow.cpp b/views/bank/AccountSettingsWindow.cpp index 5a9635e..b73af98 100644 --- a/views/bank/AccountSettingsWindow.cpp +++ b/views/bank/AccountSettingsWindow.cpp @@ -16,6 +16,8 @@ #include "black/LoginAndCheckAccountsScript.h" #include "black/GetProfileInfoScript.h" #include "black/GetCardInfoScript.h" +#include "dushanbe/GetProfileInfoScript.h" +#include "dushanbe/GetCardInfoScript.h" #include "dao/BankProfileDAO.h" #include "dao/MaterialDAO.h" #include "net/NetworkService.h" @@ -86,15 +88,15 @@ AccountSettingsWindow::AccountSettingsWindow( // ── Кнопки обновления ────────────────────────────────────────────── auto *actionsRow = new QHBoxLayout; - auto *profileBtn = new QPushButton("Обновить профиль"); - profileBtn->setStyleSheet("background-color: #1565C0; color: white; padding: 4px 12px;"); - connect(profileBtn, &QPushButton::clicked, this, &AccountSettingsWindow::startGetProfileInfo); - actionsRow->addWidget(profileBtn); + m_profileBtn = new QPushButton("Обновить профиль"); + m_profileBtn->setStyleSheet("background-color: #1565C0; color: white; padding: 4px 12px;"); + connect(m_profileBtn, &QPushButton::clicked, this, &AccountSettingsWindow::startGetProfileInfo); + actionsRow->addWidget(m_profileBtn); - auto *cardsBtn = new QPushButton("Проверить аккаунты"); - cardsBtn->setStyleSheet("background-color: #1565C0; color: white; padding: 4px 12px;"); - connect(cardsBtn, &QPushButton::clicked, this, &AccountSettingsWindow::startGetCardInfo); - actionsRow->addWidget(cardsBtn); + m_cardsBtn = new QPushButton("Проверить аккаунты"); + m_cardsBtn->setStyleSheet("background-color: #1565C0; color: white; padding: 4px 12px;"); + connect(m_cardsBtn, &QPushButton::clicked, this, &AccountSettingsWindow::startGetCardInfo); + actionsRow->addWidget(m_cardsBtn); actionsRow->addStretch(); layout->addLayout(actionsRow); @@ -288,12 +290,17 @@ void AccountSettingsWindow::startCheckPinCode() { // ── Get Profile ──────────────────────────────────────────────────────────── void AccountSettingsWindow::startGetProfileInfo() { + m_profileBtn->setEnabled(false); + m_cardsBtn->setEnabled(false); + auto *thread = new QThread(nullptr); const QString deviceId = m_deviceId; const QString appCode = m_app.code; auto onDone = [this, appCode]() { QMetaObject::invokeMethod(this, [this, appCode]() { + m_profileBtn->setEnabled(true); + m_cardsBtn->setEnabled(true); m_app = BankProfileDAO::getApplication(m_deviceId, appCode); updateStatusUI(); }, Qt::QueuedConnection); @@ -315,6 +322,14 @@ void AccountSettingsWindow::startGetProfileInfo() { connect(worker, &Black::GetProfileInfoScript::finished, thread, &QThread::quit); connect(worker, &Black::GetProfileInfoScript::finished, worker, &QObject::deleteLater); connect(thread, &QThread::finished, thread, &QObject::deleteLater); + } else if (appCode == "dushanbe_city_bank") { + auto *worker = new Dushanbe::GetProfileInfoScript(deviceId, appCode, nullptr); + worker->moveToThread(thread); + connect(thread, &QThread::started, worker, &Dushanbe::GetProfileInfoScript::start); + connect(worker, &Dushanbe::GetProfileInfoScript::finished, this, onDone, Qt::QueuedConnection); + connect(worker, &Dushanbe::GetProfileInfoScript::finished, thread, &QThread::quit); + connect(worker, &Dushanbe::GetProfileInfoScript::finished, worker, &QObject::deleteLater); + connect(thread, &QThread::finished, thread, &QObject::deleteLater); } else { thread->deleteLater(); return; @@ -326,12 +341,19 @@ void AccountSettingsWindow::startGetProfileInfo() { // ── Get Cards ────────────────────────────────────────────────────────────── void AccountSettingsWindow::startGetCardInfo() { + m_profileBtn->setEnabled(false); + m_cardsBtn->setEnabled(false); + auto *thread = new QThread(nullptr); const QString deviceId = m_deviceId; const QString appCode = m_app.code; auto onDone = [this]() { - QMetaObject::invokeMethod(this, [this]() { reloadCards(); }, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, [this]() { + m_profileBtn->setEnabled(true); + m_cardsBtn->setEnabled(true); + reloadCards(); + }, Qt::QueuedConnection); }; if (appCode == "ozon") { @@ -350,6 +372,14 @@ void AccountSettingsWindow::startGetCardInfo() { connect(worker, &Black::GetCardInfoScript::finished, thread, &QThread::quit); connect(worker, &Black::GetCardInfoScript::finished, worker, &QObject::deleteLater); connect(thread, &QThread::finished, thread, &QObject::deleteLater); + } else if (appCode == "dushanbe_city_bank") { + auto *worker = new Dushanbe::GetCardInfoScript(deviceId, appCode, nullptr); + worker->moveToThread(thread); + connect(thread, &QThread::started, worker, &Dushanbe::GetCardInfoScript::start); + connect(worker, &Dushanbe::GetCardInfoScript::finished, this, onDone, Qt::QueuedConnection); + connect(worker, &Dushanbe::GetCardInfoScript::finished, thread, &QThread::quit); + connect(worker, &Dushanbe::GetCardInfoScript::finished, worker, &QObject::deleteLater); + connect(thread, &QThread::finished, thread, &QObject::deleteLater); } else { thread->deleteLater(); return; diff --git a/views/bank/AccountSettingsWindow.h b/views/bank/AccountSettingsWindow.h index 13386da..b2509e1 100644 --- a/views/bank/AccountSettingsWindow.h +++ b/views/bank/AccountSettingsWindow.h @@ -25,6 +25,8 @@ private: QLabel *m_pinLabel; QLabel *m_profileLabel; QPushButton *m_toggleBtn; + QPushButton *m_profileBtn; + QPushButton *m_cardsBtn; QTableWidget *m_cardsTable; // Overlay