1
0
forked from BRT/arc

Refine transaction filtering logic by adjusting time-based pre-filtering with wraparound midnight support and improving detail parsing for extracting transaction metadata.

This commit is contained in:
slava 2026-04-10 19:03:35 +07:00
parent ffb206303e
commit d79dd93514

View File

@ -429,15 +429,16 @@ void GetLastTransactionsScript::doStart() {
qDebug() << "[Dushanbe::GetLastTransactions] Amount match:" << tx.amount qDebug() << "[Dushanbe::GetLastTransactions] Amount match:" << tx.amount
<< "date:" << tx.date << "time:" << tx.time; << "date:" << tx.date << "time:" << tx.time;
// Проверка даты+времени (±1 час) // Проверка времени по HH:MM:SS (±1 час, с учётом wraparound полуночи)
if (m_searchTime.isValid() && !tx.date.isEmpty() && !tx.time.isEmpty()) { if (m_searchTime.isValid() && !tx.time.isEmpty()) {
QDateTime txDt = QDateTime::fromString(tx.date + " " + tx.time, const QTime listTime = QTime::fromString(tx.time, "HH:mm:ss");
"dd.MM.yyyy HH:mm:ss"); const QTime searchLocalTime = m_searchTime.toTimeZone(tjTz).time();
if (txDt.isValid()) { if (listTime.isValid() && searchLocalTime.isValid()) {
txDt.setTimeZone(tjTz); const int diffSecs = qAbs(listTime.secsTo(searchLocalTime));
const qint64 diffSecs = qAbs(txDt.toUTC().secsTo(m_searchTime.toUTC())); if (diffSecs > 3600 && diffSecs < 82800) { // 82800 = 23h
if (diffSecs > 3600) { qDebug() << "[Dushanbe::GetLastTransactions] Time pre-filter skip:"
qDebug() << "[Dushanbe::GetLastTransactions] Time diff too big:" << diffSecs << "sec, skipping"; << tx.time << "vs" << searchLocalTime.toString("HH:mm:ss")
<< "diff=" << diffSecs << "sec";
continue; continue;
} }
} }
@ -453,15 +454,36 @@ void GetLastTransactionsScript::doStart() {
AdbUtils::makeTap(m_deviceId, txNode.x(), txNode.y()); AdbUtils::makeTap(m_deviceId, txNode.x(), txNode.y());
QThread::msleep(3000); QThread::msleep(3000);
// Ждём экран деталей — ищем кнопку "Назад" (признак экрана детали) // Ждём экран деталей Выписки — ImageView с content-desc начинающимся с "Успешный платеж"
OcrTransactionDetail detail;
bool detailLoaded = false; bool detailLoaded = false;
for (int attempt = 0; attempt < 10; ++attempt) { for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter)); xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (!xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Назад")).isEmpty() || for (const Node &n : xmlScreenParser.findAllNodes()) {
!xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Поделиться")).isEmpty()) { if (!n.contentDesc.contains(QString::fromUtf8("Успешный платеж"))) continue;
if (!n.contentDesc.contains(QString::fromUtf8("Дата:"))) continue;
const QStringList lines = n.contentDesc.split('\n');
for (int i = 0; i < lines.size(); ++i) {
const QString key = lines[i].trimmed();
if (i + 1 >= lines.size()) continue;
const QString val = lines[i + 1].trimmed();
if (key == QString::fromUtf8("Получатель:")) {
detail.receiverAccount = val;
} else if (key == QString::fromUtf8("Сумма:")) {
detail.amount = val.toDouble();
} else if (key == QString::fromUtf8("Дата:")) {
detail.date = val;
} else if (key == QString::fromUtf8("Время:")) {
detail.time = val;
}
}
if (n.contentDesc.contains(QString::fromUtf8("Успешный"))) {
detail.status = QString::fromUtf8("Успешный");
}
detailLoaded = true; detailLoaded = true;
break; break;
} }
if (detailLoaded) break;
QThread::msleep(1500); QThread::msleep(1500);
} }
@ -471,19 +493,9 @@ void GetLastTransactionsScript::doStart() {
QThread::msleep(1000); QThread::msleep(1000);
continue; continue;
} }
qDebug() << "[Dushanbe::GetLastTransactions] Detail parsed:"
// OCR скриншота деталей << "date=" << detail.date << "time=" << detail.time
const QByteArray detailScreenshot = AdbUtils::captureScreenshotBytes(m_deviceId); << "amount=" << detail.amount << "receiver=" << detail.receiverAccount;
const QString ocrText = recognizeTextFromImage(detailScreenshot);
qDebug() << "[Dushanbe::GetLastTransactions] OCR result:" << ocrText;
OcrTransactionDetail detail = parseDetailFromOcr(ocrText);
// Точечный OCR для номера операции (кроп + только цифры)
const QString preciseOpId = recognizeOperationId(detailScreenshot);
if (!preciseOpId.isEmpty()) {
detail.operationId = preciseOpId;
}
// Проверяем время ±1 час // Проверяем время ±1 час
if (m_searchTime.isValid() && !detail.date.isEmpty() && !detail.time.isEmpty()) { if (m_searchTime.isValid() && !detail.date.isEmpty() && !detail.time.isEmpty()) {