1
0
forked from BRT/arc

- Add buttons for profile and card operations to AccountSettingsWindow with threading integration and UI state management.

- Implement `Dushanbe` automation for `GetProfileInfoScript` and `GetCardInfoScript`.
- Add device validation in `DeviceDAO` and enhance duplicate checks in `NetworkService` during synchronization.
This commit is contained in:
trnsmkot 2026-04-06 14:59:00 +07:00
parent 78a038ad19
commit 40cfcff92d
4 changed files with 54 additions and 10 deletions

View File

@ -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());
// Проверка: существует ли запись

View File

@ -760,6 +760,7 @@ void NetworkService::syncDevicesFromServer(const QString &desktopId) {
}
const QJsonArray devicesArray = devicesResult.toArray();
const QList<DeviceInfo> allDevices = DeviceDAO::getAllDevices(false);
QSet<QString> 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;

View File

@ -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;

View File

@ -25,6 +25,8 @@ private:
QLabel *m_pinLabel;
QLabel *m_profileLabel;
QPushButton *m_toggleBtn;
QPushButton *m_profileBtn;
QPushButton *m_cardsBtn;
QTableWidget *m_cardsTable;
// Overlay