Include androidId in TaskDumpMeta and update related scripts for improved device identification and tracking.
This commit is contained in:
parent
35b2b3bcaa
commit
5c2aba0505
@ -37,7 +37,7 @@ void GetCardInfoScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("black", "FETCH_CARDS", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("black", "FETCH_CARDS", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
// Читаем текущий экран
|
// Читаем текущий экран
|
||||||
|
|||||||
@ -35,7 +35,7 @@ void GetProfileInfoScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("black", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("black", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
// Читаем текущий экран
|
// Читаем текущий экран
|
||||||
|
|||||||
@ -36,7 +36,7 @@ void LoginAndCheckAccountsScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("black", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("black", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
|||||||
@ -180,6 +180,8 @@ QString TaskDumpRecorder::buildCaption(const QString &errorMessage) const {
|
|||||||
if (!desktopId.isEmpty())
|
if (!desktopId.isEmpty())
|
||||||
body += QStringLiteral("Desktop: %1\n").arg(desktopId.toHtmlEscaped());
|
body += QStringLiteral("Desktop: %1\n").arg(desktopId.toHtmlEscaped());
|
||||||
body += QStringLiteral("Device: %1").arg(m_adbDeviceIdRaw.toHtmlEscaped());
|
body += QStringLiteral("Device: %1").arg(m_adbDeviceIdRaw.toHtmlEscaped());
|
||||||
|
if (!m_meta.androidId.isEmpty())
|
||||||
|
body += QStringLiteral("\nAndroidId: %1").arg(m_meta.androidId.toHtmlEscaped());
|
||||||
if (!m_meta.bankProfileId.isEmpty())
|
if (!m_meta.bankProfileId.isEmpty())
|
||||||
body += QStringLiteral("\nProfile: %1").arg(m_meta.bankProfileId.toHtmlEscaped());
|
body += QStringLiteral("\nProfile: %1").arg(m_meta.bankProfileId.toHtmlEscaped());
|
||||||
if (!m_meta.materialId.isEmpty())
|
if (!m_meta.materialId.isEmpty())
|
||||||
@ -251,6 +253,7 @@ void TaskDumpRecorder::finishInternal(const QString &errorMessage) {
|
|||||||
ts << "bank: " << m_bank << "\n"
|
ts << "bank: " << m_bank << "\n"
|
||||||
<< "task: " << m_taskKind << "\n"
|
<< "task: " << m_taskKind << "\n"
|
||||||
<< "device: " << m_adbDeviceIdRaw << "\n";
|
<< "device: " << m_adbDeviceIdRaw << "\n";
|
||||||
|
if (!m_meta.androidId.isEmpty()) ts << "android_id: " << m_meta.androidId << "\n";
|
||||||
if (!m_meta.bankProfileId.isEmpty()) ts << "profile_id: " << m_meta.bankProfileId << "\n";
|
if (!m_meta.bankProfileId.isEmpty()) ts << "profile_id: " << m_meta.bankProfileId << "\n";
|
||||||
if (!m_meta.profilePhone.isEmpty()) ts << "profile_phone: " << m_meta.profilePhone << "\n";
|
if (!m_meta.profilePhone.isEmpty()) ts << "profile_phone: " << m_meta.profilePhone << "\n";
|
||||||
if (!m_meta.materialId.isEmpty()) ts << "material_id: " << m_meta.materialId << "\n";
|
if (!m_meta.materialId.isEmpty()) ts << "material_id: " << m_meta.materialId << "\n";
|
||||||
|
|||||||
@ -13,6 +13,7 @@ struct TaskDumpMeta {
|
|||||||
QString card; // пусто = нет
|
QString card; // пусто = нет
|
||||||
QString bankProfileId; // серверный UUID банковского профиля (детект в общих логах)
|
QString bankProfileId; // серверный UUID банковского профиля (детект в общих логах)
|
||||||
QString profilePhone; // телефон банковского профиля (не получателя)
|
QString profilePhone; // телефон банковского профиля (не получателя)
|
||||||
|
QString androidId; // стабильный android_id устройства (в отличие от adbSerial не меняется)
|
||||||
};
|
};
|
||||||
|
|
||||||
class TaskDumpRecorder {
|
class TaskDumpRecorder {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ void GetCardInfoScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_CARDS", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_CARDS", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
// Душанбе показывает суммы как "100,50", "100.50 TJS", "1 000,50",
|
// Душанбе показывает суммы как "100,50", "100.50 TJS", "1 000,50",
|
||||||
// "1 000.50 TJS" и т.п. Голый QString::toDouble на таком вернёт 0,
|
// "1 000.50 TJS" и т.п. Голый QString::toDouble на таком вернёт 0,
|
||||||
// потому что требует, чтобы вся строка была валидным числом.
|
// потому что требует, чтобы вся строка была валидным числом.
|
||||||
@ -276,7 +278,7 @@ void GetLastTransactionsScript::doStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const double firstAmount = m_targets.isEmpty() ? 0.0 : m_targets.first().first;
|
const double firstAmount = m_targets.isEmpty() ? 0.0 : m_targets.first().first;
|
||||||
const TaskDumpMeta dumpMeta{m_materialId, firstAmount, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{m_materialId, firstAmount, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_TRANSACTIONS", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_TRANSACTIONS", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
@ -386,16 +388,31 @@ void GetLastTransactionsScript::doStart() {
|
|||||||
qWarning() << "[Dushanbe::GetLastTransactions] No account found";
|
qWarning() << "[Dushanbe::GetLastTransactions] No account found";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// История отсортирована сверху-вниз: новые операции выше старых. Ищем цели
|
||||||
|
// в том же порядке (по времени, от новых к старым) — тогда один непрерывный
|
||||||
|
// проход вниз находит все, и возвращаться к началу между целями не нужно.
|
||||||
|
QList<QPair<double, QDateTime>> targets = m_targets;
|
||||||
|
std::sort(targets.begin(), targets.end(),
|
||||||
|
[](const QPair<double, QDateTime> &a, const QPair<double, QDateTime> &b) {
|
||||||
|
return a.second > b.second; // по убыванию времени (новые первыми)
|
||||||
|
});
|
||||||
|
|
||||||
// Ищем каждую цель из списка. Найденные отдаём сразу через transactionParsed;
|
// Ищем каждую цель из списка. Найденные отдаём сразу через transactionParsed;
|
||||||
// ненайденные копим и репортим одной агрегированной ошибкой в конце.
|
// ненайденные копим и репортим одной агрегированной ошибкой в конце.
|
||||||
QStringList notFound;
|
QStringList notFound;
|
||||||
for (int i = 0; i < m_targets.size(); ++i) {
|
for (int i = 0; i < targets.size(); ++i) {
|
||||||
if (QThread::currentThread()->isInterruptionRequested()) { m_error = "Interrupted"; break; }
|
if (QThread::currentThread()->isInterruptionRequested()) { m_error = "Interrupted"; break; }
|
||||||
const double amount = m_targets[i].first;
|
const double amount = targets[i].first;
|
||||||
const QDateTime time = m_targets[i].second;
|
const QDateTime time = targets[i].second;
|
||||||
// Перед каждой целью (кроме первой) возвращаемся к началу Выписки.
|
// Проход идёт вниз от текущей позиции. Если цель не нашлась — возможно,
|
||||||
if (i > 0) scrollHistoryToTop(device);
|
// предыдущая (более новая) цель отсутствовала и увела список вниз, а эта
|
||||||
if (!searchOne(device, accountId, amount, time)) {
|
// лежит выше. Тогда надёжно возвращаемся к началу Выписки и пробуем ещё раз.
|
||||||
|
bool found = searchOne(device, accountId, amount, time);
|
||||||
|
if (!found && m_error != "Interrupted") {
|
||||||
|
scrollHistoryToTop(device);
|
||||||
|
found = searchOne(device, accountId, amount, time);
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
if (m_error == "Interrupted") break;
|
if (m_error == "Interrupted") break;
|
||||||
notFound << QString("amount=%1 time=%2")
|
notFound << QString("amount=%1 time=%2")
|
||||||
.arg(QString::number(amount, 'f', 2), time.toString(Qt::ISODate));
|
.arg(QString::number(amount, 'f', 2), time.toString(Qt::ISODate));
|
||||||
@ -423,16 +440,48 @@ void GetLastTransactionsScript::doStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GetLastTransactionsScript::scrollHistoryToTop(const DeviceInfo &device) {
|
void GetLastTransactionsScript::scrollHistoryToTop(const DeviceInfo &device) {
|
||||||
// Свайпы сверху-вниз поднимают список Выписки к началу.
|
// Свайпы сверху-вниз поднимают список Выписки к началу. Поиск ОДНОЙ цели
|
||||||
for (int i = 0; i < 4; ++i) {
|
// (searchOne) мог проскроллить вниз до maxScrolls(=10) раз, поэтому
|
||||||
|
// фиксированного числа свайпов вверх не хватает — крутим, пока верх списка
|
||||||
|
// не перестанет меняться (значит достигли начала), с запасом по итерациям.
|
||||||
|
static const QRegularExpression reTime(R"(\d{2}:\d{2}:\d{2})");
|
||||||
|
|
||||||
|
// Сигнатура верха списка: content-desc самой верхней View-строки операции
|
||||||
|
// (last line — время HH:MM:SS). Пустая строка — список не распознан/пуст.
|
||||||
|
auto topSignature = [&]() -> QString {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
QString best;
|
||||||
|
int bestY = device.screenHeight + 1;
|
||||||
|
for (const Node &n : xmlScreenParser.findAllNodes()) {
|
||||||
|
if (n.className != "android.view.View") continue;
|
||||||
|
const QStringList lines = n.contentDesc.split('\n');
|
||||||
|
if (lines.size() < 5) continue;
|
||||||
|
if (!reTime.match(lines.last().trimmed()).hasMatch()) continue;
|
||||||
|
if (n.y1() < bestY) { bestY = n.y1(); best = n.contentDesc; }
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
};
|
||||||
|
|
||||||
|
const int x = device.screenWidth / 2;
|
||||||
|
const int fromY = device.screenHeight / 3; // ниже шапки — без pull-to-refresh
|
||||||
|
const int toY = device.screenHeight * 3 / 4; // длинный бросок вниз → контент вверх
|
||||||
|
const int maxUpSwipes = 14; // > maxScrolls(10) с запасом
|
||||||
|
|
||||||
|
QString prevTop = topSignature();
|
||||||
|
int stable = 0;
|
||||||
|
for (int i = 0; i < maxUpSwipes; ++i) {
|
||||||
if (QThread::currentThread()->isInterruptionRequested()) return;
|
if (QThread::currentThread()->isInterruptionRequested()) return;
|
||||||
AdbUtils::makeSwipe(m_deviceId, device.screenWidth / 2,
|
AdbUtils::makeSwipe(m_deviceId, x, fromY, x, toY, 500);
|
||||||
device.screenHeight / 3,
|
QThread::msleep(700);
|
||||||
device.screenWidth / 2,
|
const QString curTop = topSignature();
|
||||||
device.screenHeight * 2 / 3, 300);
|
if (!curTop.isEmpty() && curTop == prevTop) {
|
||||||
QThread::msleep(500);
|
if (++stable >= 2) break; // верх не меняется два свайпа подряд → начало списка
|
||||||
|
} else {
|
||||||
|
stable = 0;
|
||||||
|
prevTop = curTop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QThread::msleep(800);
|
QThread::msleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetLastTransactionsScript::searchOne(const DeviceInfo &device, int accountId,
|
bool GetLastTransactionsScript::searchOne(const DeviceInfo &device, int accountId,
|
||||||
|
|||||||
@ -39,7 +39,7 @@ void GetProfileInfoScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
|||||||
@ -41,7 +41,7 @@ void LoginAndCheckAccountsScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
|||||||
@ -123,7 +123,7 @@ void PayByCardScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, {}, m_cardNumber, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, {}, m_cardNumber, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("dushanbe", "CREATE_TRANSACTION_CARD", device.adbSerial, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("dushanbe", "CREATE_TRANSACTION_CARD", device.adbSerial, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.adbSerial, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.adbSerial, ++m_counter));
|
||||||
|
|||||||
@ -120,7 +120,7 @@ void PayByPhoneScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, m_phone, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, m_phone, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("dushanbe", "CREATE_TRANSACTION_PHONE", device.adbSerial, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("dushanbe", "CREATE_TRANSACTION_PHONE", device.adbSerial, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.adbSerial, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.adbSerial, ++m_counter));
|
||||||
|
|||||||
@ -42,7 +42,7 @@ void GetCardInfoScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_CARDS", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_CARDS", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
// Читаем текущий экран
|
// Читаем текущий экран
|
||||||
|
|||||||
@ -109,7 +109,7 @@ void GetLastTransactionsScript::doStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const double firstAmount = m_targets.isEmpty() ? 0.0 : m_targets.first().first;
|
const double firstAmount = m_targets.isEmpty() ? 0.0 : m_targets.first().first;
|
||||||
const TaskDumpMeta dumpMeta{m_materialId, firstAmount, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{m_materialId, firstAmount, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_TRANSACTIONS", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_TRANSACTIONS", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
if (!navigateToTransactionList(device, app)) {
|
if (!navigateToTransactionList(device, app)) {
|
||||||
|
|||||||
@ -37,7 +37,7 @@ void GetProfileInfoScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
// Читаем текущий экран
|
// Читаем текущий экран
|
||||||
|
|||||||
@ -40,7 +40,7 @@ void LoginAndCheckAccountsScript::doStart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("ozon", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
|||||||
@ -91,7 +91,7 @@ void PayByCardScript::doStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QString &adbId = device.adbSerial;
|
const QString &adbId = device.adbSerial;
|
||||||
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, {}, m_cardNumber, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, {}, m_cardNumber, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("ozon", "CREATE_TRANSACTION_CARD", adbId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("ozon", "CREATE_TRANSACTION_CARD", adbId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(adbId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(adbId, ++m_counter));
|
||||||
|
|||||||
@ -100,7 +100,7 @@ void PayByPhoneScript::doStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QString &adbId = device.adbSerial;
|
const QString &adbId = device.adbSerial;
|
||||||
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, m_phone, {}, app.bankProfileId, app.phone};
|
const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, m_phone, {}, app.bankProfileId, app.phone, device.id};
|
||||||
TaskDumpRecorder::Scope dumpScope("ozon", "CREATE_TRANSACTION_PHONE", adbId, dumpMeta, &m_error);
|
TaskDumpRecorder::Scope dumpScope("ozon", "CREATE_TRANSACTION_PHONE", adbId, dumpMeta, &m_error);
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(adbId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(adbId, ++m_counter));
|
||||||
|
|||||||
@ -348,11 +348,12 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
|
|||||||
// ещё не отправлено: при частичном успехе (часть списка найдена и уже
|
// ещё не отправлено: при частичном успехе (часть списка найдена и уже
|
||||||
// улетела на сервер) ретрай бессмыслен — переотправит дубли, поэтому
|
// улетела на сервер) ретрай бессмыслен — переотправит дубли, поэтому
|
||||||
// ненайденные просто репортим ошибкой ниже.
|
// ненайденные просто репортим ошибкой ниже.
|
||||||
if (!result.isEmpty() && event.type == EventType::FetchTransactions
|
// Ретраи отключены: при ошибке сразу репортим как Error без повторов.
|
||||||
&& m_parsedTxCount.value(key, 0) == 0
|
// if (!result.isEmpty() && event.type == EventType::FetchTransactions
|
||||||
&& tryRetry(key, event, result)) {
|
// && m_parsedTxCount.value(key, 0) == 0
|
||||||
return;
|
// && tryRetry(key, event, result)) {
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
const EventStatus newStatus = result.isEmpty() ? EventStatus::Complete : EventStatus::Error;
|
const EventStatus newStatus = result.isEmpty() ? EventStatus::Complete : EventStatus::Error;
|
||||||
|
|
||||||
@ -757,11 +758,12 @@ void EventHandler::startThreadForTask(const MaterialInfo &account, const EventIn
|
|||||||
|
|
||||||
// Поиск транзакции: таймаут тоже ретраим (ещё до 2 раз), но только если
|
// Поиск транзакции: таймаут тоже ретраим (ещё до 2 раз), но только если
|
||||||
// ещё ни одной транзакции не отправлено (иначе ретрай переотправит дубли).
|
// ещё ни одной транзакции не отправлено (иначе ретрай переотправит дубли).
|
||||||
if (event.type == EventType::FetchTransactions
|
// Ретраи отключены: при таймауте сразу репортим как Error без повторов.
|
||||||
&& m_parsedTxCount.value(key, 0) == 0
|
// if (event.type == EventType::FetchTransactions
|
||||||
&& tryRetry(key, event, "Script timeout (5 min)")) {
|
// && m_parsedTxCount.value(key, 0) == 0
|
||||||
return;
|
// && tryRetry(key, event, "Script timeout (5 min)")) {
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
// Помечаем событие как ошибку
|
// Помечаем событие как ошибку
|
||||||
EventDAO::updateEvent(event.id, EventStatus::Error, "Script timeout (5 min)");
|
EventDAO::updateEvent(event.id, EventStatus::Error, "Script timeout (5 min)");
|
||||||
|
|||||||
@ -40,7 +40,14 @@ DesktopSelectionWindow::DesktopSelectionWindow(const QJsonArray &desktops, QWidg
|
|||||||
|
|
||||||
const QStringList devices = deviceNamesOf(d);
|
const QStringList devices = deviceNamesOf(d);
|
||||||
QString text = title;
|
QString text = title;
|
||||||
if (!devices.isEmpty()) text += "\n" + devices.join("\n");
|
if (!devices.isEmpty()) {
|
||||||
|
// При длинном списке показываем только первые 3 устройства,
|
||||||
|
// а в следующей строке — сколько ещё осталось.
|
||||||
|
const int kMaxShown = 3;
|
||||||
|
text += "\n" + devices.mid(0, kMaxShown).join("\n");
|
||||||
|
if (devices.size() > kMaxShown)
|
||||||
|
text += QString("\n… ещё %1").arg(devices.size() - kMaxShown);
|
||||||
|
}
|
||||||
|
|
||||||
auto *btn = new QPushButton(text);
|
auto *btn = new QPushButton(text);
|
||||||
btn->setStyleSheet("text-align: left; padding: 8px;");
|
btn->setStyleSheet("text-align: left; padding: 8px;");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user