183 lines
7.7 KiB
C++
183 lines
7.7 KiB
C++
#include "GetProfileInfoScript.h"
|
|
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QMap>
|
|
#include <QtGlobal>
|
|
#include <QThread>
|
|
|
|
#include "adb/AdbUtils.h"
|
|
#include "dao/MaterialDAO.h"
|
|
#include "dao/BankProfileDAO.h"
|
|
#include "dao/DeviceDAO.h"
|
|
#include "net/NetworkService.h"
|
|
#include "AppLogger.h"
|
|
|
|
namespace Ozon {
|
|
|
|
GetProfileInfoScript::GetProfileInfoScript(
|
|
QString deviceId,
|
|
QString appCode,
|
|
QObject *parent
|
|
) : CommonScript(parent),
|
|
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
|
|
}
|
|
|
|
GetProfileInfoScript::~GetProfileInfoScript() = default;
|
|
|
|
void GetProfileInfoScript::doStart() {
|
|
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;
|
|
}
|
|
|
|
// Читаем текущий экран
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
|
|
// Закрываем рекламный bottom sheet, если открыт (home_ad_1)
|
|
if (Node adNode = xmlScreenParser.tryToFindAdBanner(); !adNode.isEmpty()) {
|
|
qDebug() << "[GetProfileInfo] Ad banner detected, closing...";
|
|
AdbUtils::makeTap(m_deviceId, adNode.x(), adNode.y());
|
|
QThread::msleep(1000);
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
}
|
|
|
|
// Свежий дамп перед проверкой домашнего экрана
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
|
|
// Если мы не на домашнем экране — перезапускаем приложение и вводим пин-код
|
|
if (!xmlScreenParser.isHomeScreen()) {
|
|
qDebug() << "[GetProfileInfo] Not on home screen, restarting app...";
|
|
if (!runAppAndGoToHomeScreen(m_deviceId, app.package, app.pinCode,
|
|
device.screenWidth, device.screenHeight)) {
|
|
m_error = "Cannot reach home screen: " + m_deviceId + " " + m_appCode;
|
|
qWarning() << m_error;
|
|
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
emit finishedWithResult(m_error);
|
|
return;
|
|
}
|
|
// После runAppAndGoToHomeScreen xml уже обновлён внутри метода,
|
|
// но делаем свежий дамп, чтобы убедиться
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
}
|
|
|
|
// Закрываем баннеры на главной, если есть
|
|
tryToCloseAllBannersOnHomePage(m_deviceId, device.screenWidth, device.screenHeight);
|
|
QThread::msleep(500);
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
|
|
// Находим имя пользователя в верхней части домашнего экрана и тапаем по нему
|
|
Node userNameNode = xmlScreenParser.findUserNameOnHomeScreen(device.screenHeight);
|
|
if (userNameNode.isEmpty()) {
|
|
m_error = "Cannot find user name on home screen: " + m_deviceId;
|
|
qWarning() << m_error;
|
|
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
emit finishedWithResult(m_error);
|
|
return;
|
|
}
|
|
|
|
qDebug() << "[GetProfileInfo] Tapping on user name:" << userNameNode.text
|
|
<< "at" << userNameNode.x() << userNameNode.y();
|
|
AdbUtils::makeTap(m_deviceId, userNameNode.x(), userNameNode.y());
|
|
|
|
// Ждём загрузки страницы профиля
|
|
QThread::msleep(2500);
|
|
|
|
// Читаем XML профиля и проверяем что мы действительно там
|
|
for (int attempt = 0; attempt < 5; ++attempt) {
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
if (xmlScreenParser.isProfileScreen()) {
|
|
break;
|
|
}
|
|
QThread::msleep(1000);
|
|
}
|
|
|
|
if (!xmlScreenParser.isProfileScreen()) {
|
|
m_error = "Profile screen not detected after tap: " + m_deviceId;
|
|
qWarning() << m_error;
|
|
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
emit finishedWithResult(m_error);
|
|
return;
|
|
}
|
|
|
|
// Извлекаем полное имя и телефон
|
|
const QString fullName = xmlScreenParser.parseProfileFullName();
|
|
QString phone = xmlScreenParser.parseProfilePhone();
|
|
phone.remove(QRegularExpression(R"(\s+)")); // убираем все виды пробелов (включая \u00A0)
|
|
|
|
qDebug() << "[GetProfileInfo] fullName:" << fullName << "phone:" << phone;
|
|
|
|
if (!BankProfileDAO::updateProfileInfo(app.id, fullName, phone)) {
|
|
m_error = "Failed to save profile info to DB: " + m_deviceId;
|
|
qWarning() << m_error;
|
|
}
|
|
|
|
// Отправляем bank_profile на сервер
|
|
const BankProfileInfo freshApp = BankProfileDAO::getApplication(device.id, m_appCode);
|
|
|
|
const QMap<QString, int> currencyCodes = {
|
|
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}, {"TJS", 972}
|
|
};
|
|
const int currencyCode = currencyCodes.value(freshApp.currency.toUpper(), 643);
|
|
|
|
const QStringList parts = fullName.split(' ', Qt::SkipEmptyParts);
|
|
QJsonObject profileBody;
|
|
profileBody["first_name"] = parts.value(0);
|
|
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : "";
|
|
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
|
profileBody["bank_name"] = m_appCode;
|
|
profileBody["phone_number"] = phone;
|
|
profileBody["balance"] = QString::number(qRound64(freshApp.amount * 100));
|
|
profileBody["state"] = (freshApp.status == "active") ? "enabled" : "disabled";
|
|
profileBody["device_id"] = device.apiId;
|
|
profileBody["currency"] = currencyCode;
|
|
|
|
NetworkService ns;
|
|
ns.setDeviceId(m_deviceId);
|
|
ns.setPayload(QJsonDocument(profileBody).toJson());
|
|
|
|
if (freshApp.bankProfileId.isEmpty()) {
|
|
ns.addExtra("app_id", freshApp.id);
|
|
ns.postBankProfile();
|
|
const BankProfileInfo afterPost = BankProfileDAO::getApplication(device.id, m_appCode);
|
|
if (afterPost.bankProfileId.isEmpty()) {
|
|
const QString err = "postBankProfile failed for " + m_deviceId;
|
|
qWarning() << "[GetProfileInfo]" << err;
|
|
AppLogger::log("ozon/GetProfileInfo", m_deviceId, err,
|
|
AdbUtils::captureScreenshotBytes(m_deviceId),
|
|
"FETCH_PROFILE");
|
|
} else {
|
|
qDebug() << "[GetProfileInfo] postBankProfile done";
|
|
}
|
|
} else {
|
|
ns.addExtra("bank_profile_id", freshApp.bankProfileId);
|
|
ns.patchBankProfile();
|
|
qDebug() << "[GetProfileInfo] patchBankProfile done";
|
|
}
|
|
|
|
// Отправляем данные аккаунтов на сервер если нет material_id
|
|
const QList<MaterialInfo> allAccounts = MaterialDAO::getAccounts(device.id, m_appCode);
|
|
QList<QPair<MaterialInfo, Node>> accountsToPost;
|
|
for (const auto &acc : allAccounts) {
|
|
if (acc.materialId.isEmpty()) {
|
|
accountsToPost.append({acc, Node()});
|
|
}
|
|
}
|
|
if (!accountsToPost.isEmpty()) {
|
|
postAccountsData(accountsToPost);
|
|
}
|
|
|
|
// Возвращаемся на домашний экран
|
|
AdbUtils::goBack(m_deviceId);
|
|
QThread::msleep(1000);
|
|
|
|
emit finishedWithResult(m_error);
|
|
}
|
|
|
|
} // namespace Ozon
|