1
0
forked from BRT/arc

Replace nullptr with QCoreApplication::applicationDirPath() in OCR initialization across automation scripts to ensure correct Tesseract setup paths. Add UI overlay updates in AccountSettingsWindow for better progress visibility and enhance error handling in EventHandler for transactions missing bank_transaction_id.

This commit is contained in:
slava 2026-04-06 19:45:51 +07:00
parent d7c296ba42
commit 8ec9f37160
8 changed files with 38 additions and 11 deletions

View File

@ -14,9 +14,10 @@
#include "dao/TransactionDAO.h" #include "dao/TransactionDAO.h"
#include "AppLogger.h" #include "AppLogger.h"
#include <QCoreApplication>
static QString recognizeTextFromImage(const QByteArray &pngData) { static QString recognizeTextFromImage(const QByteArray &pngData) {
auto *api = new tesseract::TessBaseAPI(); auto *api = new tesseract::TessBaseAPI();
if (api->Init(nullptr, "rus+eng")) { if (api->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "rus+eng")) {
qWarning() << "[Dushanbe::OCR] Failed to init Tesseract"; qWarning() << "[Dushanbe::OCR] Failed to init Tesseract";
delete api; delete api;
return {}; return {};
@ -49,7 +50,7 @@ static QString recognizeOperationId(const QByteArray &pngData) {
// 1. Полный OCR с координатами слов — ищем "операции" // 1. Полный OCR с координатами слов — ищем "операции"
auto *api = new tesseract::TessBaseAPI(); auto *api = new tesseract::TessBaseAPI();
if (api->Init(nullptr, "rus+eng")) { if (api->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "rus+eng")) {
pixDestroy(&pix); delete api; pixDestroy(&pix); delete api;
return {}; return {};
} }
@ -103,7 +104,7 @@ static QString recognizeOperationId(const QByteArray &pngData) {
if (!cropped) return {}; if (!cropped) return {};
auto *api2 = new tesseract::TessBaseAPI(); auto *api2 = new tesseract::TessBaseAPI();
if (api2->Init(nullptr, "eng")) { if (api2->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "eng")) {
pixDestroy(&cropped); delete api2; pixDestroy(&cropped); delete api2;
return {}; return {};
} }

View File

@ -12,6 +12,7 @@
#include "dao/TransactionDAO.h" #include "dao/TransactionDAO.h"
#include "AppLogger.h" #include "AppLogger.h"
#include <QCoreApplication>
// Точечный OCR: находит строку "операции" и кропает правую часть для digit-only OCR // Точечный OCR: находит строку "операции" и кропает правую часть для digit-only OCR
static QString recognizeOperationId(const QByteArray &pngData) { static QString recognizeOperationId(const QByteArray &pngData) {
Pix *pix = pixReadMem(reinterpret_cast<const l_uint8 *>(pngData.constData()), Pix *pix = pixReadMem(reinterpret_cast<const l_uint8 *>(pngData.constData()),
@ -22,7 +23,7 @@ static QString recognizeOperationId(const QByteArray &pngData) {
const int h = pixGetHeight(pix); const int h = pixGetHeight(pix);
auto *api = new tesseract::TessBaseAPI(); auto *api = new tesseract::TessBaseAPI();
if (api->Init(nullptr, "rus+eng")) { if (api->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "rus+eng")) {
pixDestroy(&pix); delete api; pixDestroy(&pix); delete api;
return {}; return {};
} }
@ -72,7 +73,7 @@ static QString recognizeOperationId(const QByteArray &pngData) {
if (!cropped) return {}; if (!cropped) return {};
auto *api2 = new tesseract::TessBaseAPI(); auto *api2 = new tesseract::TessBaseAPI();
if (api2->Init(nullptr, "eng")) { if (api2->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "eng")) {
pixDestroy(&cropped); delete api2; pixDestroy(&cropped); delete api2;
return {}; return {};
} }

View File

@ -12,6 +12,7 @@
#include "dao/TransactionDAO.h" #include "dao/TransactionDAO.h"
#include "AppLogger.h" #include "AppLogger.h"
#include <QCoreApplication>
static QString recognizeOperationId(const QByteArray &pngData) { static QString recognizeOperationId(const QByteArray &pngData) {
Pix *pix = pixReadMem(reinterpret_cast<const l_uint8 *>(pngData.constData()), Pix *pix = pixReadMem(reinterpret_cast<const l_uint8 *>(pngData.constData()),
static_cast<size_t>(pngData.size())); static_cast<size_t>(pngData.size()));
@ -21,7 +22,7 @@ static QString recognizeOperationId(const QByteArray &pngData) {
const int h = pixGetHeight(pix); const int h = pixGetHeight(pix);
auto *api = new tesseract::TessBaseAPI(); auto *api = new tesseract::TessBaseAPI();
if (api->Init(nullptr, "rus+eng")) { if (api->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "rus+eng")) {
pixDestroy(&pix); delete api; pixDestroy(&pix); delete api;
return {}; return {};
} }
@ -69,7 +70,7 @@ static QString recognizeOperationId(const QByteArray &pngData) {
if (!cropped) return {}; if (!cropped) return {};
auto *api2 = new tesseract::TessBaseAPI(); auto *api2 = new tesseract::TessBaseAPI();
if (api2->Init(nullptr, "eng")) { if (api2->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "eng")) {
pixDestroy(&cropped); delete api2; pixDestroy(&cropped); delete api2;
return {}; return {};
} }

View File

@ -16,9 +16,10 @@
#include "time/DateUtils.h" #include "time/DateUtils.h"
#include "AppLogger.h" #include "AppLogger.h"
#include <QCoreApplication>
static QString recognizeTextFromImage(const QByteArray &pngData) { static QString recognizeTextFromImage(const QByteArray &pngData) {
auto *api = new tesseract::TessBaseAPI(); auto *api = new tesseract::TessBaseAPI();
if (api->Init(nullptr, "rus+eng")) { if (api->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "rus+eng")) {
qWarning() << "[OCR] Failed to init Tesseract"; qWarning() << "[OCR] Failed to init Tesseract";
delete api; delete api;
return {}; return {};

View File

@ -1,5 +1,6 @@
#include "PayByCardScript.h" #include "PayByCardScript.h"
#include <QCoreApplication>
#include <QProcess> #include <QProcess>
#include <QRegularExpression> #include <QRegularExpression>
#include <QThread> #include <QThread>
@ -18,7 +19,7 @@
static QString recognizeTextFromImage(const QByteArray &pngData) { static QString recognizeTextFromImage(const QByteArray &pngData) {
auto *api = new tesseract::TessBaseAPI(); auto *api = new tesseract::TessBaseAPI();
if (api->Init(nullptr, "rus+eng")) { if (api->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "rus+eng")) {
qWarning() << "[OCR] Failed to init Tesseract"; qWarning() << "[OCR] Failed to init Tesseract";
delete api; delete api;
return {}; return {};

View File

@ -16,9 +16,10 @@
#include "dao/TransactionDAO.h" #include "dao/TransactionDAO.h"
#include "time/DateUtils.h" #include "time/DateUtils.h"
#include <QCoreApplication>
static QString recognizeTextFromImage(const QByteArray &pngData) { static QString recognizeTextFromImage(const QByteArray &pngData) {
auto *api = new tesseract::TessBaseAPI(); auto *api = new tesseract::TessBaseAPI();
if (api->Init(nullptr, "rus+eng")) { if (api->Init(QCoreApplication::applicationDirPath().toUtf8().constData(), "rus+eng")) {
qWarning() << "[OCR] Failed to init Tesseract"; qWarning() << "[OCR] Failed to init Tesseract";
delete api; delete api;
return {}; return {};

View File

@ -305,10 +305,16 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
taskData = obj; taskData = obj;
} else if (event.type == EventType::FetchTransactions) { } else if (event.type == EventType::FetchTransactions) {
QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 24); QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 24);
// Фильтруем: отправляем только транзакции с bank_transaction_id
bool hasWithoutId = false;
QJsonArray arr; QJsonArray arr;
for (const auto &tx : txList) { for (const auto &tx : txList) {
if (tx.bankTrExternalId.isEmpty()) {
hasWithoutId = true;
continue;
}
QJsonObject txObj; QJsonObject txObj;
txObj["bank_transaction_id"] = tx.bankTrExternalId.isEmpty() ? QJsonValue(QJsonValue::Null) : QJsonValue(tx.bankTrExternalId); txObj["bank_transaction_id"] = tx.bankTrExternalId;
txObj["amount"] = static_cast<int>(tx.amount * 100); txObj["amount"] = static_cast<int>(tx.amount * 100);
txObj["currency"] = currencyCode; txObj["currency"] = currencyCode;
txObj["transaction_type"] = (tx.type == TransactionType::Phone) ? "top-up" : "bank"; txObj["transaction_type"] = (tx.type == TransactionType::Phone) ? "top-up" : "bank";
@ -341,6 +347,17 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
} }
arr.append(txObj); arr.append(txObj);
} }
if (arr.isEmpty() && hasWithoutId) {
// Транзакция найдена но без bank_transaction_id — ошибка
qWarning() << "[EventHandler] FETCH_TRANSACTIONS: tx found but no bank_transaction_id";
sendTaskError(eventTypeToString(event.type), event.externalId, event.bankName,
"Transaction found but bank_transaction_id is empty");
EventDAO::updateEvent(event.id, EventStatus::Error,
"Transaction found but bank_transaction_id is empty (OCR failed)");
EventDAO::markSentToServer(event.id);
m_threads.remove(key);
return;
}
taskData = arr; taskData = arr;
} else if (event.type == EventType::CreateTransaction) { } else if (event.type == EventType::CreateTransaction) {
// Определяем тип транзакции из JSON задачи // Определяем тип транзакции из JSON задачи

View File

@ -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);
showOverlay("Обновление профиля...");
pauseActiveProfiles(); pauseActiveProfiles();
auto *thread = new QThread(nullptr); auto *thread = new QThread(nullptr);
@ -305,6 +306,7 @@ void AccountSettingsWindow::startGetProfileInfo() {
resumePausedProfiles(); resumePausedProfiles();
m_app = BankProfileDAO::getApplication(m_deviceId, appCode); m_app = BankProfileDAO::getApplication(m_deviceId, appCode);
updateStatusUI(); updateStatusUI();
hideOverlay(true, "Профиль обновлён");
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
}; };
@ -345,6 +347,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);
showOverlay("Проверка аккаунтов...");
pauseActiveProfiles(); pauseActiveProfiles();
auto *thread = new QThread(nullptr); auto *thread = new QThread(nullptr);
@ -357,6 +360,7 @@ void AccountSettingsWindow::startGetCardInfo() {
m_cardsBtn->setEnabled(true); m_cardsBtn->setEnabled(true);
resumePausedProfiles(); resumePausedProfiles();
reloadCards(); reloadCards();
hideOverlay(true, "Аккаунты обновлены");
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
}; };