Add pause/resume functionality for active profiles in AccountSettingsWindow and improve automation scripts with OCR-based transaction ID extraction, card balance waits, and absolute value handling in event parsing.
This commit is contained in:
parent
58513eb15a
commit
41bb5e33fd
@ -133,6 +133,10 @@ void GetCardInfoScript::doStart() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ждём загрузки баланса (может быть 0 пока данные подтягиваются)
|
||||||
|
QThread::msleep(1500);
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
|
||||||
QString fullNumber = xmlScreenParser.parseFullCardNumber();
|
QString fullNumber = xmlScreenParser.parseFullCardNumber();
|
||||||
const double cardBalance = xmlScreenParser.parseCardDetailBalance();
|
const double cardBalance = xmlScreenParser.parseCardDetailBalance();
|
||||||
const QString holder = xmlScreenParser.parseCardDetailHolder();
|
const QString holder = xmlScreenParser.parseCardDetailHolder();
|
||||||
|
|||||||
@ -260,6 +260,45 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
<< "amount=" << parsed.amount << "time=" << dtStr
|
<< "amount=" << parsed.amount << "time=" << dtStr
|
||||||
<< "name=" << detail.name;
|
<< "name=" << detail.name;
|
||||||
|
|
||||||
|
// Пробуем получить ID через "Документы" → OCR
|
||||||
|
QString externalId = detail.bankTrExternalId;
|
||||||
|
if (externalId.isEmpty()) {
|
||||||
|
Node docBtn = xmlScreenParser.findButtonNode("Документы", false);
|
||||||
|
if (!docBtn.isEmpty()) {
|
||||||
|
qDebug() << "[FetchTransactions] Tapping 'Документы'...";
|
||||||
|
AdbUtils::makeTap(m_deviceId, docBtn.x(), docBtn.y());
|
||||||
|
QThread::msleep(2000);
|
||||||
|
|
||||||
|
bool docLoaded = false;
|
||||||
|
for (int da = 0; da < 15; ++da) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
if (!xmlScreenParser.findNodeByContentDesc("Поделиться").isEmpty()) {
|
||||||
|
docLoaded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QThread::msleep(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (docLoaded) {
|
||||||
|
QThread::msleep(500);
|
||||||
|
const QByteArray screenshot = AdbUtils::captureScreenshotBytes(m_deviceId);
|
||||||
|
if (!screenshot.isEmpty()) {
|
||||||
|
const QString ocrText = recognizeTextFromImage(screenshot);
|
||||||
|
if (!ocrText.isEmpty()) {
|
||||||
|
qDebug() << "[FetchTransactions] OCR result:" << ocrText;
|
||||||
|
externalId = extractTransactionId(ocrText);
|
||||||
|
if (!externalId.isEmpty()) {
|
||||||
|
qDebug() << "[FetchTransactions] Extracted ID:" << externalId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AdbUtils::goBack(m_deviceId);
|
||||||
|
QThread::msleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Сохраняем
|
// Сохраняем
|
||||||
if (accountId != -1) {
|
if (accountId != -1) {
|
||||||
TransactionInfo tx;
|
TransactionInfo tx;
|
||||||
@ -267,6 +306,7 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
tx.amount = parsed.amount;
|
tx.amount = parsed.amount;
|
||||||
tx.bankName = m_appCode;
|
tx.bankName = m_appCode;
|
||||||
tx.bankTime = dtStr;
|
tx.bankTime = dtStr;
|
||||||
|
tx.bankTrExternalId = externalId;
|
||||||
tx.status = TransactionStatus::Complete;
|
tx.status = TransactionStatus::Complete;
|
||||||
tx.timestamp = DateUtils::getUtcNow();
|
tx.timestamp = DateUtils::getUtcNow();
|
||||||
if (txTime.isValid()) tx.completeTime = txTime;
|
if (txTime.isValid()) tx.completeTime = txTime;
|
||||||
@ -352,6 +392,7 @@ void GetLastTransactionsScript::scanRecentTransactions(const DeviceInfo &device,
|
|||||||
|
|
||||||
tx.bankName = m_appCode;
|
tx.bankName = m_appCode;
|
||||||
tx.bankTime = detail.bankTime;
|
tx.bankTime = detail.bankTime;
|
||||||
|
tx.bankTrExternalId = detail.bankTrExternalId;
|
||||||
tx.status = TransactionStatus::Complete;
|
tx.status = TransactionStatus::Complete;
|
||||||
tx.timestamp = DateUtils::getUtcNow();
|
tx.timestamp = DateUtils::getUtcNow();
|
||||||
if (!detail.name.isEmpty()) tx.name = detail.name;
|
if (!detail.name.isEmpty()) tx.name = detail.name;
|
||||||
|
|||||||
@ -373,14 +373,10 @@ void DeviceScreener::start() {
|
|||||||
qDebug() << "Cant update device";
|
qDebug() << "Cant update device";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isChecked) {
|
// Проверяем установленные приложения каждый цикл
|
||||||
// Новое устройство — проверяем приложения (после upsert, чтобы FK не падал)
|
QSet<QString> apps = AdbUtils::getListApps(adbSerial);
|
||||||
QSet<QString> apps = AdbUtils::getListApps(adbSerial);
|
if (!BankProfileDAO::checkInstalledApps(device.id, apps)) {
|
||||||
if (!BankProfileDAO::checkInstalledApps(device.id, apps)) {
|
qWarning() << "Cant check installed apps";
|
||||||
qWarning() << "Cant check installed apps";
|
|
||||||
} else {
|
|
||||||
qDebug() << "Apps checked:" << device.id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -447,7 +447,7 @@ void EventHandler::startThreadForTask(const MaterialInfo &account, const EventIn
|
|||||||
// Парсим amount и created_at из body задачи
|
// Парсим amount и created_at из body задачи
|
||||||
const QJsonObject taskJson = QJsonDocument::fromJson(event.json.toUtf8()).object();
|
const QJsonObject taskJson = QJsonDocument::fromJson(event.json.toUtf8()).object();
|
||||||
const QJsonObject body = taskJson["body"].toObject();
|
const QJsonObject body = taskJson["body"].toObject();
|
||||||
const double searchAmount = body["amount"].toDouble() / 100.0; // копейки → рубли
|
const double searchAmount = qAbs(body["amount"].toDouble()) / 100.0; // копейки → рубли (абс. значение)
|
||||||
const QDateTime searchTime = QDateTime::fromString(body["created_at"].toString(), Qt::ISODate);
|
const QDateTime searchTime = QDateTime::fromString(body["created_at"].toString(), Qt::ISODate);
|
||||||
|
|
||||||
if (appCode == "ozon")
|
if (appCode == "ozon")
|
||||||
|
|||||||
@ -292,6 +292,7 @@ void AccountSettingsWindow::startCheckPinCode() {
|
|||||||
void AccountSettingsWindow::startGetProfileInfo() {
|
void AccountSettingsWindow::startGetProfileInfo() {
|
||||||
m_profileBtn->setEnabled(false);
|
m_profileBtn->setEnabled(false);
|
||||||
m_cardsBtn->setEnabled(false);
|
m_cardsBtn->setEnabled(false);
|
||||||
|
pauseActiveProfiles();
|
||||||
|
|
||||||
auto *thread = new QThread(nullptr);
|
auto *thread = new QThread(nullptr);
|
||||||
const QString deviceId = m_deviceId;
|
const QString deviceId = m_deviceId;
|
||||||
@ -301,6 +302,7 @@ void AccountSettingsWindow::startGetProfileInfo() {
|
|||||||
QMetaObject::invokeMethod(this, [this, appCode]() {
|
QMetaObject::invokeMethod(this, [this, appCode]() {
|
||||||
m_profileBtn->setEnabled(true);
|
m_profileBtn->setEnabled(true);
|
||||||
m_cardsBtn->setEnabled(true);
|
m_cardsBtn->setEnabled(true);
|
||||||
|
resumePausedProfiles();
|
||||||
m_app = BankProfileDAO::getApplication(m_deviceId, appCode);
|
m_app = BankProfileDAO::getApplication(m_deviceId, appCode);
|
||||||
updateStatusUI();
|
updateStatusUI();
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
@ -343,6 +345,7 @@ void AccountSettingsWindow::startGetProfileInfo() {
|
|||||||
void AccountSettingsWindow::startGetCardInfo() {
|
void AccountSettingsWindow::startGetCardInfo() {
|
||||||
m_profileBtn->setEnabled(false);
|
m_profileBtn->setEnabled(false);
|
||||||
m_cardsBtn->setEnabled(false);
|
m_cardsBtn->setEnabled(false);
|
||||||
|
pauseActiveProfiles();
|
||||||
|
|
||||||
auto *thread = new QThread(nullptr);
|
auto *thread = new QThread(nullptr);
|
||||||
const QString deviceId = m_deviceId;
|
const QString deviceId = m_deviceId;
|
||||||
@ -352,6 +355,7 @@ void AccountSettingsWindow::startGetCardInfo() {
|
|||||||
QMetaObject::invokeMethod(this, [this]() {
|
QMetaObject::invokeMethod(this, [this]() {
|
||||||
m_profileBtn->setEnabled(true);
|
m_profileBtn->setEnabled(true);
|
||||||
m_cardsBtn->setEnabled(true);
|
m_cardsBtn->setEnabled(true);
|
||||||
|
resumePausedProfiles();
|
||||||
reloadCards();
|
reloadCards();
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
};
|
};
|
||||||
@ -537,3 +541,43 @@ void AccountSettingsWindow::reloadCards() {
|
|||||||
m_cardsTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
|
m_cardsTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
|
||||||
m_cardsTable->resizeRowsToContents();
|
m_cardsTable->resizeRowsToContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Pause/Resume active profiles ───────────────────────────────────────────
|
||||||
|
|
||||||
|
static void toggleProfileOnServer(const BankProfileInfo &app, bool enable) {
|
||||||
|
if (app.bankProfileId.isEmpty()) return;
|
||||||
|
auto *thread = new QThread;
|
||||||
|
auto *net = new NetworkService;
|
||||||
|
net->moveToThread(thread);
|
||||||
|
net->addExtra("bank_profile_id", app.bankProfileId);
|
||||||
|
net->addExtra("enable", enable);
|
||||||
|
QObject::connect(thread, &QThread::started, net, &NetworkService::toggleBankProfile);
|
||||||
|
QObject::connect(net, &NetworkService::finished, thread, &QThread::quit);
|
||||||
|
QObject::connect(net, &NetworkService::finished, net, &QObject::deleteLater);
|
||||||
|
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||||
|
thread->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountSettingsWindow::pauseActiveProfiles() {
|
||||||
|
const QList<BankProfileInfo> apps = BankProfileDAO::getApplicationsByDeviceId(m_deviceId);
|
||||||
|
for (const BankProfileInfo &app : apps) {
|
||||||
|
if (app.status == "active") {
|
||||||
|
m_pausedProfiles.append(app.code);
|
||||||
|
BankProfileDAO::update(app.id, app.pinCode, app.comment, "off");
|
||||||
|
toggleProfileOnServer(app, false);
|
||||||
|
qDebug() << "[AccountSettings] Paused profile:" << app.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountSettingsWindow::resumePausedProfiles() {
|
||||||
|
for (const QString &code : m_pausedProfiles) {
|
||||||
|
const BankProfileInfo app = BankProfileDAO::getApplication(m_deviceId, code);
|
||||||
|
if (app.id >= 0 && app.status == "off") {
|
||||||
|
BankProfileDAO::update(app.id, app.pinCode, app.comment, "active");
|
||||||
|
toggleProfileOnServer(app, true);
|
||||||
|
qDebug() << "[AccountSettings] Resumed profile:" << app.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_pausedProfiles.clear();
|
||||||
|
}
|
||||||
|
|||||||
@ -47,6 +47,10 @@ private:
|
|||||||
void toggleMaterialStatus(const MaterialInfo &account);
|
void toggleMaterialStatus(const MaterialInfo &account);
|
||||||
void reloadCards();
|
void reloadCards();
|
||||||
|
|
||||||
|
QStringList m_pausedProfiles;
|
||||||
|
void pauseActiveProfiles();
|
||||||
|
void resumePausedProfiles();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user