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:
parent
d7c296ba42
commit
8ec9f37160
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {};
|
||||||
|
|||||||
@ -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 {};
|
||||||
|
|||||||
@ -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 {};
|
||||||
|
|||||||
@ -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 задачи
|
||||||
|
|||||||
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user