1
0
forked from BRT/arc

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:
slava 2026-04-06 17:02:52 +07:00
parent 58513eb15a
commit 41bb5e33fd
6 changed files with 98 additions and 9 deletions

View File

@ -133,6 +133,10 @@ void GetCardInfoScript::doStart() {
continue;
}
// Ждём загрузки баланса (может быть 0 пока данные подтягиваются)
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
QString fullNumber = xmlScreenParser.parseFullCardNumber();
const double cardBalance = xmlScreenParser.parseCardDetailBalance();
const QString holder = xmlScreenParser.parseCardDetailHolder();

View File

@ -260,6 +260,45 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
<< "amount=" << parsed.amount << "time=" << dtStr
<< "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) {
TransactionInfo tx;
@ -267,6 +306,7 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
tx.amount = parsed.amount;
tx.bankName = m_appCode;
tx.bankTime = dtStr;
tx.bankTrExternalId = externalId;
tx.status = TransactionStatus::Complete;
tx.timestamp = DateUtils::getUtcNow();
if (txTime.isValid()) tx.completeTime = txTime;
@ -352,6 +392,7 @@ void GetLastTransactionsScript::scanRecentTransactions(const DeviceInfo &device,
tx.bankName = m_appCode;
tx.bankTime = detail.bankTime;
tx.bankTrExternalId = detail.bankTrExternalId;
tx.status = TransactionStatus::Complete;
tx.timestamp = DateUtils::getUtcNow();
if (!detail.name.isEmpty()) tx.name = detail.name;

View File

@ -373,14 +373,10 @@ void DeviceScreener::start() {
qDebug() << "Cant update device";
}
if (!isChecked) {
// Новое устройство — проверяем приложения (после upsert, чтобы FK не падал)
QSet<QString> apps = AdbUtils::getListApps(adbSerial);
if (!BankProfileDAO::checkInstalledApps(device.id, apps)) {
qWarning() << "Cant check installed apps";
} else {
qDebug() << "Apps checked:" << device.id;
}
// Проверяем установленные приложения каждый цикл
QSet<QString> apps = AdbUtils::getListApps(adbSerial);
if (!BankProfileDAO::checkInstalledApps(device.id, apps)) {
qWarning() << "Cant check installed apps";
}
}

View File

@ -447,7 +447,7 @@ void EventHandler::startThreadForTask(const MaterialInfo &account, const EventIn
// Парсим amount и created_at из body задачи
const QJsonObject taskJson = QJsonDocument::fromJson(event.json.toUtf8()).object();
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);
if (appCode == "ozon")

View File

@ -292,6 +292,7 @@ void AccountSettingsWindow::startCheckPinCode() {
void AccountSettingsWindow::startGetProfileInfo() {
m_profileBtn->setEnabled(false);
m_cardsBtn->setEnabled(false);
pauseActiveProfiles();
auto *thread = new QThread(nullptr);
const QString deviceId = m_deviceId;
@ -301,6 +302,7 @@ void AccountSettingsWindow::startGetProfileInfo() {
QMetaObject::invokeMethod(this, [this, appCode]() {
m_profileBtn->setEnabled(true);
m_cardsBtn->setEnabled(true);
resumePausedProfiles();
m_app = BankProfileDAO::getApplication(m_deviceId, appCode);
updateStatusUI();
}, Qt::QueuedConnection);
@ -343,6 +345,7 @@ void AccountSettingsWindow::startGetProfileInfo() {
void AccountSettingsWindow::startGetCardInfo() {
m_profileBtn->setEnabled(false);
m_cardsBtn->setEnabled(false);
pauseActiveProfiles();
auto *thread = new QThread(nullptr);
const QString deviceId = m_deviceId;
@ -352,6 +355,7 @@ void AccountSettingsWindow::startGetCardInfo() {
QMetaObject::invokeMethod(this, [this]() {
m_profileBtn->setEnabled(true);
m_cardsBtn->setEnabled(true);
resumePausedProfiles();
reloadCards();
}, Qt::QueuedConnection);
};
@ -537,3 +541,43 @@ void AccountSettingsWindow::reloadCards() {
m_cardsTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
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();
}

View File

@ -47,6 +47,10 @@ private:
void toggleMaterialStatus(const MaterialInfo &account);
void reloadCards();
QStringList m_pausedProfiles;
void pauseActiveProfiles();
void resumePausedProfiles();
protected:
void resizeEvent(QResizeEvent *event) override;
};