#include "LoginAndCheckAccountsScript.h" #include #include "adb/AdbUtils.h" #include "dao/MaterialDAO.h" #include "dao/BankProfileDAO.h" #include "dao/DeviceDAO.h" #include "dump/TaskDumpRecorder.h" #include "scripting/ScriptRuntime.h" #include "scripting/ScriptingConfig.h" #include "AppLogger.h" #include "GetCardInfoScript.h" namespace Ozon { LoginAndCheckAccountsScript::LoginAndCheckAccountsScript( QString deviceId, QString appCode, QObject *parent, bool fetchProfileOnly, bool pinCheckOnly ) : CommonScript(parent), m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)), m_fetchProfileOnly(fetchProfileOnly), m_pinCheckOnly(pinCheckOnly) { } LoginAndCheckAccountsScript::~LoginAndCheckAccountsScript() = default; void LoginAndCheckAccountsScript::doStart() { // Удалённый JS-скрипт: пробуем JS-версию. JS отвечает ТОЛЬКО за свою часть // (логин + сбор/постинг аккаунтов). Финальный вызов GetCardInfoScript // оставлен в C++ снаружи блока — когда get_card тоже уедет на JS, // его собственный doStart() сам подхватит JS-путь. if (Scripting::ScriptingConfig::isEnabled() && Scripting::ScriptingConfig::isJsEnabledFor("ozon/login_and_check_accounts")) { QString jsOut; const QVariantMap params{ {"deviceId", m_deviceId}, {"appCode", m_appCode}, {"fetchProfileOnly", m_fetchProfileOnly}, {"pinCheckOnly", m_pinCheckOnly}, }; const auto status = Scripting::ScriptRuntime::run( "ozon", "login_and_check_accounts", params, &jsOut); if (status == Scripting::ScriptRuntime::Result::Completed) { m_error = jsOut; // pinCheckOnly: вышли сразу после успешного логина — карты не сканировались. // fetchProfileOnly: профиль сохранён, карты обновлять не надо. if (m_error.isEmpty() && !m_fetchProfileOnly && !m_pinCheckOnly) { GetCardInfoScript cardScript(m_deviceId, m_appCode, ""); cardScript.start(); } emit finishedWithResult(m_error); return; } qWarning() << "[Ozon::LoginAndCheck] JS path failed (" << jsOut << ") — fallback to C++ implementation"; } // m_deviceId = ADB serial, device.id = android_id (для БД) DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId); if (device.id.isEmpty()) device = DeviceDAO::findByAdbSerial(m_deviceId); if (!device.adbSerial.isEmpty()) m_deviceId = device.adbSerial; const BankProfileInfo app = BankProfileDAO::getApplication(device.id, m_appCode); if (device.id.isEmpty() || app.id == -1) { m_error = "Device or app not found: " + m_deviceId + " " + m_appCode; qCritical() << m_error; emit finishedWithResult(m_error); return; } const TaskDumpMeta dumpMeta{}; TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error); xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter)); if (!runAppAndGoToHomeScreen(m_deviceId, app.package, app.pinCode, device.screenWidth, device.screenHeight)) { m_error = "Cant open the home screen: " + device.name + " (" + m_deviceId + ") " + m_appCode; qWarning() << m_error; m_resultScreenshot = AdbUtils::captureScreenshotBytes(m_deviceId); if (!m_resultScreenshot.isEmpty()) emit screenshotReady(m_resultScreenshot); BankProfileDAO::updateComment(app.id, "Не прошла проверка " + QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm:ss")); AdbUtils::tryToKillApplication(m_deviceId, app.package); emit finishedWithResult(m_error); return; } else { if (m_pinCheckOnly) { emit finishedWithResult(m_error); return; } // Скриншот домашнего экрана m_resultScreenshot = AdbUtils::captureScreenshotBytes(m_deviceId); if (!m_resultScreenshot.isEmpty()) emit screenshotReady(m_resultScreenshot); // Парсим баланс с домашнего экрана xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter)); const QList parsedCards = xmlScreenParser.parseCardsOnHomeScreen(); double parsedBalance = parsedCards.isEmpty() ? 0.0 : parsedCards[0].amount; qDebug() << "[LoginAndCheck] Parsed balance:" << parsedBalance << "cards:" << parsedCards.size(); if (parsedBalance > 0.0) { BankProfileDAO::updateAmount(app.id, parsedBalance); } // Создаём/обновляем bank profile на сервере createBankProfileIfNeeded(device.id, m_appCode, parsedBalance); if (goToAllProducts(m_deviceId, device.screenWidth, device.screenHeight)) { QList > accounts = xmlScreenParser.parseAccountsInfo(); for (auto &[account, node]: accounts) { account.deviceId = device.id; account.appCode = m_appCode; if (!MaterialDAO::upsertAccount(account)) { m_error = "Not updated: " + account.lastNumbers; qCritical() << m_error; } } if (!m_fetchProfileOnly) { postAccountsData(accounts); } } else { qWarning() << "Cant go to all products: " << m_deviceId << " " << m_appCode; } if (!m_fetchProfileOnly) { // Запускаем сканирование баланса, данных карт и отправку на сервер (синхронно) GetCardInfoScript cardScript(m_deviceId, m_appCode, ""); cardScript.start(); } } emit finishedWithResult(m_error); } } // namespace Ozon