Add database migration, DAO enhancements, and OCR-based transaction handling updates
Implemented database migration for adding new fields (`json`, `sent_to_server`) in `events` table. Updated DAO methods to support the new fields and introduced `markSentToServer`. Enhanced Ozon transaction workflows with OCR-based extraction, event error handling improvements, and result reporting. Refactored `EventHandler` for streamlined task processing and stale event cleanup.
This commit is contained in:
parent
832fb03aac
commit
8eedd07ffd
@ -45,8 +45,8 @@ static QString recognizeTextFromImage(const QByteArray &pngData) {
|
||||
}
|
||||
|
||||
static QString extractTransactionId(const QString &ocrText) {
|
||||
// "ID операции A60130542076330K0000040011670301"
|
||||
QRegularExpression reId(R"(ID\s+операции\s+([A-Za-z0-9]+))");
|
||||
// "ID операции A60130542076330K0000040011670301" или "ID операции = Аб60650..."
|
||||
QRegularExpression reId(R"(ID\s+операции\s*=?\s*([A-Za-zА-Яа-я0-9]+))");
|
||||
if (auto m = reId.match(ocrText); m.hasMatch()) return m.captured(1);
|
||||
|
||||
// "№ Ф-2026-25235663"
|
||||
@ -270,6 +270,17 @@ void GetLastTransactionsScript::doStart() {
|
||||
<< "phone:" << tx.phone
|
||||
<< "amount:" << (tx.amount >= 0 ? "+" : "") + QString::number(tx.amount, 'f', 2);
|
||||
|
||||
// Если транзакция старше 24 часов — прекращаем
|
||||
if (tx.completeTime.isValid()) {
|
||||
const qint64 ageSecs = tx.completeTime.toUTC().secsTo(QDateTime::currentDateTimeUtc());
|
||||
if (ageSecs > 24 * 3600) {
|
||||
qDebug() << "[GetLastTransactions] Transaction older than 24h, stopping";
|
||||
AdbUtils::goBack(m_deviceId);
|
||||
QThread::msleep(1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Сохраняем в БД если не существует
|
||||
// Берём первый аккаунт для этого устройства и приложения
|
||||
if (accountId != -1) {
|
||||
@ -286,14 +297,14 @@ void GetLastTransactionsScript::doStart() {
|
||||
|
||||
// Ждём появления кнопки "Поделиться"
|
||||
bool docLoaded = false;
|
||||
for (int da = 0; da < 10; ++da) {
|
||||
for (int da = 0; da < 20; ++da) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
Node shareBtn = xmlScreenParser.findNodeByContentDesc("Поделиться");
|
||||
if (!shareBtn.isEmpty()) {
|
||||
docLoaded = true;
|
||||
break;
|
||||
}
|
||||
qDebug() << "[GetLastTransactions] Waiting for 'Поделиться', attempt" << da + 1 << "/ 10";
|
||||
qDebug() << "[GetLastTransactions] Waiting for 'Поделиться', attempt" << da + 1 << "/ 20";
|
||||
QThread::msleep(1500);
|
||||
}
|
||||
|
||||
|
||||
@ -3,13 +3,58 @@
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QThread>
|
||||
#include <QTimeZone>
|
||||
#include <utility>
|
||||
|
||||
#include <tesseract/baseapi.h>
|
||||
#include <leptonica/allheaders.h>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "dao/TransactionDAO.h"
|
||||
#include "time/DateUtils.h"
|
||||
|
||||
static QString recognizeTextFromImage(const QByteArray &pngData) {
|
||||
auto *api = new tesseract::TessBaseAPI();
|
||||
if (api->Init(nullptr, "rus+eng")) {
|
||||
qWarning() << "[OCR] Failed to init Tesseract";
|
||||
delete api;
|
||||
return {};
|
||||
}
|
||||
|
||||
Pix *pix = pixReadMem(reinterpret_cast<const l_uint8 *>(pngData.constData()),
|
||||
static_cast<size_t>(pngData.size()));
|
||||
if (!pix) {
|
||||
qWarning() << "[OCR] Failed to read image";
|
||||
api->End();
|
||||
delete api;
|
||||
return {};
|
||||
}
|
||||
|
||||
api->SetImage(pix);
|
||||
char *text = api->GetUTF8Text();
|
||||
QString result = QString::fromUtf8(text).trimmed();
|
||||
delete[] text;
|
||||
pixDestroy(&pix);
|
||||
api->End();
|
||||
delete api;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static QString extractTransactionId(const QString &ocrText) {
|
||||
// "ID операции A60130542076330K0000040011670301" или "ID операции = Аб60650..."
|
||||
QRegularExpression reId(R"(ID\s+операции\s*=?\s*([A-Za-zА-Яа-я0-9]+))");
|
||||
if (auto m = reId.match(ocrText); m.hasMatch()) return m.captured(1);
|
||||
|
||||
// "№ Ф-2026-25235663"
|
||||
QRegularExpression reRef(R"(№\s*(Ф-[\d-]+))");
|
||||
if (auto m = reRef.match(ocrText); m.hasMatch()) return m.captured(1);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
namespace Ozon {
|
||||
|
||||
@ -329,7 +374,106 @@ void PayByPhoneScript::makePayment(
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[PayByPhone] Confirm screen loaded, stopping before confirmation";
|
||||
// 8. Нажимаем "Перевести ..." (ищем по первому слову)
|
||||
Node transferConfirmBtn = xmlScreenParser.findButtonNode("Перевести", true);
|
||||
if (transferConfirmBtn.isEmpty()) {
|
||||
m_error = "Кнопка 'Перевести ...' не найдена на экране подтверждения";
|
||||
qWarning() << "[PayByPhone]" << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[PayByPhone] Tapping confirm button:" << transferConfirmBtn.text;
|
||||
AdbUtils::makeTap(deviceId, transferConfirmBtn.x(), transferConfirmBtn.y());
|
||||
QThread::msleep(3000);
|
||||
|
||||
// 9. Ждём результат: "Успешно" или "Не удалось"
|
||||
for (int attempt = 0; attempt < 15; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
|
||||
if (!xmlScreenParser.findTextNode("Успешно").isEmpty()) {
|
||||
qDebug() << "[PayByPhone] Payment successful!";
|
||||
m_error.clear();
|
||||
|
||||
// Сохраняем транзакцию в БД
|
||||
TransactionInfo tx;
|
||||
tx.accountId = m_account.id;
|
||||
tx.amount = -m_amount;
|
||||
tx.phone = m_phone;
|
||||
tx.bankName = "ozon";
|
||||
tx.type = TransactionType::Phone;
|
||||
tx.status = TransactionStatus::Complete;
|
||||
tx.timestamp = DateUtils::getUtcNow();
|
||||
tx.completeTime = QDateTime::currentDateTime().toTimeZone(QTimeZone("Europe/Moscow"));
|
||||
tx.bankTime = tx.completeTime.toString("dd.MM.yyyy, HH:mm");
|
||||
const int txId = TransactionDAO::insertTransaction(tx);
|
||||
qDebug() << "[PayByPhone] Saved transaction to DB, id:" << txId;
|
||||
|
||||
// Ищем кнопку "Документы" и достаём ID операции
|
||||
Node docBtn = xmlScreenParser.findButtonNode("Документы", false);
|
||||
if (!docBtn.isEmpty() && txId != -1) {
|
||||
qDebug() << "[PayByPhone] Tapping 'Документы'...";
|
||||
AdbUtils::makeTap(deviceId, docBtn.x(), docBtn.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// Ждём появления кнопки "Поделиться"
|
||||
bool docLoaded = false;
|
||||
for (int da = 0; da < 20; ++da) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
Node shareBtn = xmlScreenParser.findNodeByContentDesc("Поделиться");
|
||||
if (!shareBtn.isEmpty()) {
|
||||
docLoaded = true;
|
||||
break;
|
||||
}
|
||||
qDebug() << "[PayByPhone] Waiting for 'Поделиться', attempt" << da + 1 << "/ 20";
|
||||
QThread::msleep(1500);
|
||||
}
|
||||
|
||||
if (docLoaded) {
|
||||
QThread::msleep(500);
|
||||
const QByteArray screenshot = AdbUtils::captureScreenshotBytes(deviceId);
|
||||
if (!screenshot.isEmpty()) {
|
||||
TransactionDAO::updateReceiptImage(txId, screenshot);
|
||||
qDebug() << "[PayByPhone] Receipt saved to DB, txId:" << txId;
|
||||
|
||||
const QString ocrText = recognizeTextFromImage(screenshot);
|
||||
if (!ocrText.isEmpty()) {
|
||||
qDebug() << "[PayByPhone] OCR result:\n" << ocrText;
|
||||
const QString externalId = extractTransactionId(ocrText);
|
||||
if (!externalId.isEmpty()) {
|
||||
TransactionDAO::updateBankTrExternalId(txId, externalId);
|
||||
qDebug() << "[PayByPhone] Extracted transaction ID:" << externalId;
|
||||
} else {
|
||||
qWarning() << "[PayByPhone] Could not extract transaction ID from OCR text";
|
||||
}
|
||||
} else {
|
||||
qWarning() << "[PayByPhone] OCR returned empty text";
|
||||
}
|
||||
} else {
|
||||
qWarning() << "[PayByPhone] Screenshot is empty";
|
||||
}
|
||||
} else {
|
||||
qWarning() << "[PayByPhone] 'Поделиться' not found, skipping receipt";
|
||||
}
|
||||
|
||||
AdbUtils::goBack(deviceId);
|
||||
QThread::msleep(1000);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xmlScreenParser.findTextNode("Не удалось").isEmpty()) {
|
||||
m_error = "Перевод не удался (экран 'Не удалось')";
|
||||
qWarning() << "[PayByPhone]" << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[PayByPhone] Waiting for payment result, attempt" << attempt + 1 << "/ 15";
|
||||
QThread::msleep(2000);
|
||||
}
|
||||
|
||||
m_error = "Не дождались результата перевода";
|
||||
qWarning() << "[PayByPhone]" << m_error;
|
||||
}
|
||||
|
||||
} // namespace Ozon
|
||||
|
||||
@ -388,38 +388,54 @@ QString ScreenXmlParser::parseProfilePhone() {
|
||||
}
|
||||
|
||||
QList<Node> ScreenXmlParser::findPinCodeNodes(const QString &pinCode) {
|
||||
// Ozon PIN кнопки — анонимные FrameLayout без text/content-desc.
|
||||
// Алгоритм не зависит от разрешения: ищем строки из ровно 3 кликабельных узлов.
|
||||
|
||||
// 1. Собираем все кликабельные узлы с ненулевым размером
|
||||
QList<Node> clickable;
|
||||
for (const Node &node: m_nodes) {
|
||||
if (node.clickable && node.width() > 0 && node.height() > 0) {
|
||||
clickable.append(node);
|
||||
// Способ 1: ищем кликабельные ноды с текстом-цифрой (0-9)
|
||||
QMap<QString, Node> digitMap;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (!node.clickable || node.width() <= 0 || node.height() <= 0) continue;
|
||||
const QString t = node.text.trimmed();
|
||||
if (t.size() == 1 && t.at(0).isDigit()) {
|
||||
digitMap[t] = node;
|
||||
}
|
||||
}
|
||||
|
||||
if (digitMap.size() >= 10) {
|
||||
QList<Node> result;
|
||||
for (const QChar &c : pinCode) {
|
||||
const QString d = QString(c);
|
||||
if (digitMap.contains(d)) {
|
||||
result.append(digitMap[d]);
|
||||
} else {
|
||||
qWarning() << "[findPinCodeNodes] digit not found:" << d;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Способ 2 (fallback): анонимные FrameLayout — ищем сетку 4x3
|
||||
QList<Node> clickable;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.clickable && node.width() > 0 && node.height() > 0)
|
||||
clickable.append(node);
|
||||
}
|
||||
if (clickable.isEmpty()) return {};
|
||||
|
||||
// 2. Находим минимальную высоту — это примерный размер одной кнопки.
|
||||
// Исключаем полноэкранные элементы (WebView и т.п.) фильтром height <= minH * 3.
|
||||
int minH = INT_MAX;
|
||||
for (const Node &n: clickable) minH = std::min(minH, n.height());
|
||||
for (const Node &n : clickable) minH = std::min(minH, n.height());
|
||||
|
||||
QList<Node> candidates;
|
||||
for (const Node &n: clickable) {
|
||||
for (const Node &n : clickable) {
|
||||
if (n.height() <= minH * 3) candidates.append(n);
|
||||
}
|
||||
|
||||
// 3. Сортируем по y
|
||||
std::sort(candidates.begin(), candidates.end(), [](const Node &a, const Node &b) {
|
||||
return a.y() < b.y();
|
||||
});
|
||||
|
||||
// 4. Группируем в строки: узлы с разницей y < height первого узла строки — одна строка
|
||||
QList<QList<Node>> rows;
|
||||
for (const Node &node: candidates) {
|
||||
for (const Node &node : candidates) {
|
||||
bool placed = false;
|
||||
for (QList<Node> &row: rows) {
|
||||
for (QList<Node> &row : rows) {
|
||||
if (std::abs(node.y() - row.first().y()) < row.first().height()) {
|
||||
row.append(node);
|
||||
placed = true;
|
||||
@ -429,45 +445,35 @@ QList<Node> ScreenXmlParser::findPinCodeNodes(const QString &pinCode) {
|
||||
if (!placed) rows.append({node});
|
||||
}
|
||||
|
||||
// 5. Внутри каждой строки сортируем по x (слева направо)
|
||||
for (QList<Node> &row: rows) {
|
||||
for (QList<Node> &row : rows) {
|
||||
std::sort(row.begin(), row.end(), [](const Node &a, const Node &b) {
|
||||
return a.x() < b.x();
|
||||
});
|
||||
}
|
||||
|
||||
// 6. PIN-сетка — строки ровно с 3 узлами (3 столбца)
|
||||
// Строки 1-3: цифры 1-9
|
||||
// Строка 4: (биометрия) [0] (backspace) → берём средний элемент
|
||||
qDebug() << "[findPinCodeNodes] clickable:" << clickable.size()
|
||||
<< "minH:" << minH << "candidates:" << candidates.size() << "rows:" << rows.size();
|
||||
for (int i = 0; i < rows.size(); ++i) {
|
||||
QStringList info;
|
||||
for (const Node &n : rows[i])
|
||||
info << QString("(%1,%2 %3x%4 '%5')").arg(n.x()).arg(n.y()).arg(n.width()).arg(n.height()).arg(n.text.left(15));
|
||||
qDebug() << "[findPinCodeNodes] row" << i << "size:" << rows[i].size() << info.join(" | ");
|
||||
}
|
||||
|
||||
QList<QList<Node>> gridRows;
|
||||
for (const QList<Node> &row: rows) {
|
||||
for (const QList<Node> &row : rows) {
|
||||
if (row.size() == 3) gridRows.append(row);
|
||||
}
|
||||
qDebug() << "[findPinCodeNodes] gridRows:" << gridRows.size() << "pinCode len:" << pinCode.size();
|
||||
|
||||
QMap<QString, Node> digitMap;
|
||||
if (gridRows.size() < 4) {
|
||||
qWarning() << "[findPinCodeNodes] grid not found: gridRows=" << gridRows.size();
|
||||
return {};
|
||||
}
|
||||
|
||||
const QStringList digits19 = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
|
||||
int idx = 0;
|
||||
for (int r = 0; r < gridRows.size() - 1 && idx < digits19.size(); ++r) {
|
||||
for (const Node &n: gridRows[r]) {
|
||||
for (const Node &n : gridRows[r]) {
|
||||
if (idx < digits19.size()) digitMap[digits19[idx++]] = n;
|
||||
}
|
||||
}
|
||||
if (!gridRows.isEmpty() && gridRows.last().size() >= 2) {
|
||||
digitMap["0"] = gridRows.last()[1]; // средний столбец последней строки
|
||||
if (gridRows.last().size() >= 2) {
|
||||
digitMap["0"] = gridRows.last()[1];
|
||||
}
|
||||
|
||||
QList<Node> result;
|
||||
for (const QChar &c: pinCode) {
|
||||
for (const QChar &c : pinCode) {
|
||||
if (const QString d = QString(c); digitMap.contains(d)) {
|
||||
result.append(digitMap[d]);
|
||||
}
|
||||
|
||||
BIN
assets/error.png
Normal file
BIN
assets/error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
assets/ozon/pay/confirm_payment.png
Normal file
BIN
assets/ozon/pay/confirm_payment.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
539
assets/ozon/pay/confirm_payment.xml
Normal file
539
assets/ozon/pay/confirm_payment.xml
Normal file
@ -0,0 +1,539 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/action_bar_root"
|
||||
class="android.widget.LinearLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/main_activity_top"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="1" text="" resource-id="ru.ozon.fintech.finance:id/over_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="4" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/over_fragment_top"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="1"
|
||||
hint=""/>
|
||||
</node>
|
||||
<node index="3" text="" resource-id="" class="android.view.ViewGroup"
|
||||
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="3" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2"
|
||||
hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/web_view_top"
|
||||
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/web_view_holder"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.FrameLayout"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.webkit.WebView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]" drawing-order="0"
|
||||
hint="">
|
||||
<node index="0" text="⠀" resource-id=""
|
||||
class="android.webkit.WebView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="true"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false"
|
||||
scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="svelte"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="MFC2C@sbp"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,0][1080,252]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="base-go-back-button"
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="true"
|
||||
enabled="true"
|
||||
focusable="true"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[44,149][133,236]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text=""
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="native-toolbar-close-button"
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="true"
|
||||
enabled="true"
|
||||
focusable="true"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[1021,191][1080,252]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1"
|
||||
text="Подтвердите перевод"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[42,312][1039,430]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2"
|
||||
text="Владислав Николаевич К."
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,490][777,556]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3"
|
||||
text="+7 (985) 553-28-96"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,569][496,627]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="4" text=""
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[501,574][546,619]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[858,490][976,609]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[926,559][987,619]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.widget.Image"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[937,569][976,609]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
<node index="6" text="Банк получателя"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,693][976,742]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="7" text="Альфа-Банк"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,750][976,816]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="8" text="Счёт списания"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,855][976,905]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="9" text="Основной счёт"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,913][976,979]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="10" text="1 251,50 ₽"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,987][249,1031]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="11" text="Сумма списания"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,1071][976,1120]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="12" text="100 ₽"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,1128][976,1194]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="13" text="Без комисcии"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[105,1202][976,1246]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="14" text="Перевести 100 ₽"
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[42,2079][1039,2228]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="15"
|
||||
text="Система быстрых платежей"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[267,2247][763,2296]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="modal-container"
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,2336][1080,2336]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="⠀"
|
||||
resource-id="svelte-announcer"
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][5,5]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="3" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/web_view_toolbar"
|
||||
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,147]" drawing-order="1" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_bottom_navigation_holder"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,2201][1080,2400]" drawing-order="3"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[818,0][1080,262]" drawing-order="2" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/ozon/pay/confirm_payment_error.png
Normal file
BIN
assets/ozon/pay/confirm_payment_error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 572 KiB |
698
assets/ozon/pay/confirm_payment_error.xml
Normal file
698
assets/ozon/pay/confirm_payment_error.xml
Normal file
@ -0,0 +1,698 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/action_bar_root"
|
||||
class="android.widget.LinearLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/main_activity_top"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="1" text="" resource-id="ru.ozon.fintech.finance:id/over_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="4" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/over_fragment_top"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="1"
|
||||
hint=""/>
|
||||
</node>
|
||||
<node index="3" text="" resource-id="" class="android.view.ViewGroup"
|
||||
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="3" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2"
|
||||
hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/web_view_top"
|
||||
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/web_view_holder"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.FrameLayout"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.webkit.WebView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]" drawing-order="0"
|
||||
hint="">
|
||||
<node index="0" text="⠀" resource-id=""
|
||||
class="android.webkit.WebView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="true"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false"
|
||||
scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="svelte"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="MFC2C@sbp"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="modal-container"
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,2336][1080,2336]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="⠀"
|
||||
resource-id="svelte-announcer"
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][5,5]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="3" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="4" text="" resource-id=""
|
||||
class="android.app.AlertDialog"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,1569]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,133][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[42,165][105,231]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="Система быстрых платежей"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[291,173][787,223]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="2" text=""
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[952,154][1039,241]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3" text=""
|
||||
resource-id="payment-result-body"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[0,259][1080,2170]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="payment-result-body-center"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[86,777][992,1653]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[86,777][992,1653]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[433,672][645,887]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[433,672][645,887]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[580,819][666,908]"
|
||||
drawing-order="0"
|
||||
hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[580,819][666,908]"
|
||||
drawing-order="0"
|
||||
hint="">
|
||||
<node index="0"
|
||||
text=""
|
||||
resource-id=""
|
||||
class="android.widget.Image"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[580,819][666,908]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,777][992,1653]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="payment-result-ticket-top"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,779][992,1336]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0"
|
||||
text="Не удалось"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,926][929,994]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="1"
|
||||
text="− 100 ₽"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1000][929,1084]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="2"
|
||||
text="Технические неполадки у СБП. Попробуйте снова"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1120][929,1294]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="3" text=""
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,1288][992,1336]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,1330][992,1375]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="2"
|
||||
text="Альфа-Банк"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1372][929,1422]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="3"
|
||||
text="Владислав Николаевич К."
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1438][929,1506]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="4"
|
||||
text="+7 (985) 553-28-96"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1522][929,1590]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="4" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[42,2168][1039,2296]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="Готово" resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[42,2168][1039,2296]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/web_view_toolbar"
|
||||
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,147]" drawing-order="1" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_bottom_navigation_holder"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,2201][1080,2400]" drawing-order="3"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[818,0][1080,262]" drawing-order="2" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/ozon/pay/confirm_payment_success.png
Normal file
BIN
assets/ozon/pay/confirm_payment_success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 665 KiB |
780
assets/ozon/pay/confirm_payment_success.xml
Normal file
780
assets/ozon/pay/confirm_payment_success.xml
Normal file
@ -0,0 +1,780 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/action_bar_root"
|
||||
class="android.widget.LinearLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/main_activity_top"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="1" text="" resource-id="ru.ozon.fintech.finance:id/over_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="4" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/over_fragment_top"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="1"
|
||||
hint=""/>
|
||||
</node>
|
||||
<node index="3" text="" resource-id="" class="android.view.ViewGroup"
|
||||
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="3" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2"
|
||||
hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/web_view_top"
|
||||
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/web_view_holder"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.FrameLayout"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.webkit.WebView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]" drawing-order="0"
|
||||
hint="">
|
||||
<node index="0" text="⠀" resource-id=""
|
||||
class="android.webkit.WebView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="true"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false"
|
||||
scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="svelte"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="MFC2C@sbp"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="modal-container"
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,2336][1080,2336]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="⠀"
|
||||
resource-id="svelte-announcer"
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][5,5]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="3" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="4" text="" resource-id=""
|
||||
class="android.app.AlertDialog"
|
||||
package="ru.ozon.fintech.finance" content-desc=""
|
||||
checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2337]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,15][1080,1596]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,133][1080,2337]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[42,165][105,231]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="Система быстрых платежей"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[291,173][787,223]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="2" text=""
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[952,154][1039,241]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3" text=""
|
||||
resource-id="payment-result-body"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[0,259][1080,2170]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="payment-result-body-center"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[86,805][992,1627]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[86,805][992,1627]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[422,685][640,903]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[422,685][640,903]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[572,832][661,921]"
|
||||
drawing-order="0"
|
||||
hint="">
|
||||
<node index="0" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[572,832][661,921]"
|
||||
drawing-order="0"
|
||||
hint="">
|
||||
<node index="0"
|
||||
text=""
|
||||
resource-id=""
|
||||
class="android.widget.Image"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[572,832][661,921]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,805][992,1470]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="payment-result-ticket-top"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[78,779][992,1149]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0"
|
||||
text="Успешно"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[147,929][924,1015]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="1"
|
||||
text="− 100 ₽"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[147,1002][926,1105]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="2" text=""
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,1078][992,1149]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,1144][992,1191]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="2"
|
||||
text="Альфа-Банк"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1186][929,1239]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="3"
|
||||
text="Владислав Николаевич К."
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1254][929,1323]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="4"
|
||||
text="+7 (985) 553-28-96"
|
||||
resource-id=""
|
||||
class="android.widget.TextView"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[149,1338][929,1407]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
<node index="2" text=""
|
||||
resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[86,1464][992,1627]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text=""
|
||||
resource-id="MFPromoBanners@promo"
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="false"
|
||||
enabled="true"
|
||||
focusable="false"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[128,1464][950,1596]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0"
|
||||
text="Banner Получайте ежедневный доход со ставкой 12,5% годовых"
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc=""
|
||||
checkable="false"
|
||||
checked="false"
|
||||
clickable="true"
|
||||
enabled="true"
|
||||
focusable="true"
|
||||
focused="false"
|
||||
scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false"
|
||||
selected="false"
|
||||
bounds="[128,1498][950,1596]"
|
||||
drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text="Повторить"
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[149,1687][330,1869]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="Документы"
|
||||
resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[349,1687][530,1869]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3" text="Шаблон" resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[548,1687][729,1869]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="4" text="Помощь" resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[748,1687][929,1869]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="4" text="" resource-id=""
|
||||
class="android.view.View"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="false"
|
||||
enabled="true" focusable="false"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false" password="false"
|
||||
selected="false"
|
||||
bounds="[42,2168][1039,2296]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="Готово" resource-id=""
|
||||
class="android.widget.Button"
|
||||
package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false"
|
||||
checked="false" clickable="true"
|
||||
enabled="true" focusable="true"
|
||||
focused="false" scrollable="false"
|
||||
long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[42,2168][1039,2296]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/web_view_toolbar"
|
||||
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,147]" drawing-order="1" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text=""
|
||||
resource-id="ru.ozon.fintech.finance:id/main_activity_bottom_navigation_holder"
|
||||
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,2201][1080,2400]" drawing-order="3"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View" package="ru.ozon.fintech.finance"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[818,0][1080,262]" drawing-order="2" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
@ -2,13 +2,13 @@
|
||||
list=ozon
|
||||
|
||||
[common]
|
||||
access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjNDU1MjE1Ni1kMTc5LTRhNzktOWU5MS01ODcwMzhjOTVjZjAiLCJ0eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzcyNzE0MTQyfQ.-074b8eEWeLgzoxxpq5o54G1npivuC_VWvu4NLEz_gY
|
||||
access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjNDU1MjE1Ni1kMTc5LTRhNzktOWU5MS01ODcwMzhjOTVjZjAiLCJ0eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzcyODg4MjU2fQ.5WF3EQobCOQpuQr5wcCeYOJW1ER0RJG506WRhEB_Y5E
|
||||
api_key=0eee77b62013253e02e1a69bc6a505bb37757fb7
|
||||
currencies=USD, KRW, AZN, RUB
|
||||
desktop_id=b86eac8e-dc89-4a9e-a5e8-7f85db011391
|
||||
profile_id=c4552156-d179-4a79-9e91-587038c95cf0
|
||||
refresh_token=def3036b-b62d-4550-8971-94d7ef57eba2
|
||||
token_expires_at=1772714142
|
||||
refresh_token=4c78f097-d70b-4bdb-b351-c839fa9eb442
|
||||
token_expires_at=1772888256
|
||||
version=0.0.1
|
||||
|
||||
[db]
|
||||
|
||||
@ -361,6 +361,16 @@ void DatabaseManager::initSchema() {
|
||||
q.exec("PRAGMA user_version = 11");
|
||||
qDebug() << "[DB] Migration 11 applied";
|
||||
}
|
||||
|
||||
// ── Версия 12: json и sent_to_server в events ────────────────────────────
|
||||
if (version < 12) {
|
||||
db.transaction();
|
||||
q.exec("ALTER TABLE events ADD COLUMN json TEXT DEFAULT ''");
|
||||
q.exec("ALTER TABLE events ADD COLUMN sent_to_server INTEGER DEFAULT 0");
|
||||
db.commit();
|
||||
q.exec("PRAGMA user_version = 12");
|
||||
qDebug() << "[DB] Migration 12 applied";
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseManager::closeConnection() {
|
||||
|
||||
Binary file not shown.
@ -224,8 +224,10 @@ QStringList AccountDAO::getActiveMaterialIds() {
|
||||
SELECT a.material_id
|
||||
FROM accounts a
|
||||
JOIN applications app ON a.device_id = app.device_id AND a.app_code = app.code
|
||||
JOIN devices d ON a.device_id = d.id
|
||||
WHERE app.status = 'active'
|
||||
AND a.material_id IS NOT NULL AND a.material_id != ''
|
||||
AND d.status = 'device' AND d.image IS NOT NULL
|
||||
)");
|
||||
|
||||
if (!query.exec()) {
|
||||
|
||||
@ -29,6 +29,19 @@ QList<BankInfo> BankDAO::getAll() {
|
||||
return list;
|
||||
}
|
||||
|
||||
BankInfo BankDAO::findByAlias(const QString &alias) {
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
query.prepare("SELECT * FROM banks WHERE alias = :alias LIMIT 1");
|
||||
query.bindValue(":alias", alias);
|
||||
if (!query.exec() || !query.next()) return {};
|
||||
BankInfo bank;
|
||||
bank.id = query.value("id").toInt();
|
||||
bank.alias = query.value("alias").toString();
|
||||
bank.name = query.value("name").toString();
|
||||
bank.nspkName = query.value("nspk_name").toString();
|
||||
return bank;
|
||||
}
|
||||
|
||||
void BankDAO::replaceAll(const QList<BankInfo> &banks) {
|
||||
QSqlDatabase db = DatabaseManager::instance().database();
|
||||
QSqlQuery query(db);
|
||||
|
||||
@ -7,5 +7,7 @@ class BankDAO {
|
||||
public:
|
||||
[[nodiscard]] static QList<BankInfo> getAll();
|
||||
|
||||
[[nodiscard]] static BankInfo findByAlias(const QString &alias);
|
||||
|
||||
static void replaceAll(const QList<BankInfo> &banks);
|
||||
};
|
||||
|
||||
@ -18,6 +18,8 @@ EventInfo parseEvent(const QSqlQuery &query) {
|
||||
event.phone = query.value("phone").toString();
|
||||
event.bankName = query.value("bank_name").toString();
|
||||
event.comment = query.value("comment").toString();
|
||||
event.json = query.value("json").toString();
|
||||
event.sentToServer = query.value("sent_to_server").toBool();
|
||||
event.timestamp = DateUtils::fromUtcString(query.value("timestamp").toString());
|
||||
event.updateTime = DateUtils::fromUtcString(query.value("update_time").toString());
|
||||
event.completeTime = DateUtils::fromUtcString(query.value("complete_time").toString());
|
||||
@ -29,9 +31,9 @@ int EventDAO::insertEvent(const EventInfo &event) {
|
||||
|
||||
query.prepare(R"(
|
||||
INSERT INTO events (
|
||||
status, external_id, account_id, amount, phone, bank_name, timestamp, device_id, type
|
||||
status, external_id, account_id, amount, phone, bank_name, comment, json, timestamp, device_id, type
|
||||
) VALUES (
|
||||
:status, :external_id, :account_id, :amount, :phone, :bank_name, :timestamp, :device_id, :type
|
||||
:status, :external_id, :account_id, :amount, :phone, :bank_name, :comment, :json, :timestamp, :device_id, :type
|
||||
)
|
||||
)");
|
||||
|
||||
@ -43,6 +45,8 @@ int EventDAO::insertEvent(const EventInfo &event) {
|
||||
query.bindValue(":amount", event.amount);
|
||||
query.bindValue(":phone", event.phone);
|
||||
query.bindValue(":bank_name", event.bankName);
|
||||
query.bindValue(":comment", event.comment);
|
||||
query.bindValue(":json", event.json);
|
||||
query.bindValue(":timestamp", DateUtils::toUtcString(event.timestamp));
|
||||
|
||||
if (!query.exec()) {
|
||||
@ -114,12 +118,24 @@ bool EventDAO::updateEventAmount(int id, double amount) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EventDAO::markSentToServer(int id) {
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
query.prepare("UPDATE events SET sent_to_server = 1 WHERE id = :id");
|
||||
query.bindValue(":id", id);
|
||||
if (!query.exec()) {
|
||||
qWarning() << "Ошибка markSentToServer:" << query.lastError().text();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<EventInfo> EventDAO::getAllEvents(const EventStatus &status) {
|
||||
QList<EventInfo> events;
|
||||
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
query.prepare(R"(
|
||||
SELECT id, account_id, device_id, external_id, amount, phone, bank_name, status, update_time, complete_time, timestamp, type
|
||||
SELECT id, account_id, device_id, external_id, amount, phone, bank_name,
|
||||
status, type, comment, json, sent_to_server, update_time, complete_time, timestamp
|
||||
FROM events
|
||||
WHERE status = :status
|
||||
)");
|
||||
@ -141,7 +157,7 @@ EventInfo EventDAO::getFirstWaitEventByDeviceId(const QString &key) {
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
query.prepare(R"(
|
||||
SELECT id, account_id, device_id, external_id, amount, phone, bank_name,
|
||||
status, type, comment, update_time, complete_time, timestamp
|
||||
status, type, comment, json, sent_to_server, update_time, complete_time, timestamp
|
||||
FROM events
|
||||
WHERE status = :status AND device_id = :device_id
|
||||
ORDER BY timestamp ASC
|
||||
@ -166,7 +182,7 @@ QList<EventInfo> EventDAO::getEvents(int page, int pageSize) {
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
query.prepare(R"(
|
||||
SELECT id, account_id, device_id, external_id, amount, phone, bank_name,
|
||||
status, type, comment, update_time, complete_time, timestamp
|
||||
status, type, comment, json, sent_to_server, update_time, complete_time, timestamp
|
||||
FROM events
|
||||
ORDER BY id DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
|
||||
@ -20,6 +20,8 @@ public:
|
||||
|
||||
[[nodiscard]] static bool updateEventAmount(int id, double amount);
|
||||
|
||||
[[nodiscard]] static bool markSentToServer(int id);
|
||||
|
||||
[[nodiscard]] static QList<EventInfo> getEvents(int page, int pageSize);
|
||||
|
||||
[[nodiscard]] static int getTotalCount();
|
||||
|
||||
@ -67,6 +67,7 @@ bool TransactionDAO::insertTransactionIfNotExists(const TransactionInfo &info) {
|
||||
query.bindValue(":bank_tr_external_id", info.bankTrExternalId);
|
||||
query.bindValue(":update_time", DateUtils::toUtcString(info.updateTime));
|
||||
query.bindValue(":complete_time", DateUtils::toUtcString(info.completeTime));
|
||||
query.bindValue(":timestamp", DateUtils::toUtcString(info.timestamp));
|
||||
|
||||
if (!query.exec()) {
|
||||
qWarning() << "Ошибка при вставке transaction:" << query.lastError().text();
|
||||
|
||||
@ -67,6 +67,9 @@ struct EventInfo {
|
||||
EventStatus status = EventStatus::Unknown;
|
||||
EventType type = EventType::Unknown;
|
||||
|
||||
QString json;
|
||||
bool sentToServer = false;
|
||||
|
||||
QByteArray screenshot;
|
||||
|
||||
QDateTime updateTime;
|
||||
|
||||
@ -203,7 +203,7 @@ void DeviceScreener::postScreenshotToApi(const QString &apiId, const QByteArray
|
||||
} else {
|
||||
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
|
||||
if (doc.isObject() && doc.object()["success"].toBool()) {
|
||||
qDebug() << "postScreenshotToApi done for device" << apiId;
|
||||
// ok
|
||||
} else {
|
||||
qWarning() << "postScreenshotToApi failed for device" << apiId << ":" << doc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
@ -229,7 +229,6 @@ void DeviceScreener::toggleBankProfilesOnApi(const QString &deviceId, bool enabl
|
||||
|
||||
const QString enableStr = enable ? "true" : "false";
|
||||
const QString path = "/api/v1/profile/bank_profile/" + app.bankProfileId + "/" + enableStr;
|
||||
qDebug() << "[DeviceScreener] toggleBankProfile:" << app.code << app.bankProfileId << "enable=" << enable;
|
||||
apiPatch(path, QJsonObject());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,23 @@
|
||||
#include "EventHandler.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QMap>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QTimeZone>
|
||||
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/BankDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "dao/EventDAO.h"
|
||||
#include "dao/TransactionDAO.h"
|
||||
#include "db/ApplicationInfo.h"
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "net/NetworkService.h"
|
||||
#include "birbank/GetLastDaysHistoryBirbankScript.h"
|
||||
#include "birbank/LoginAndCheckAccountsBirbankScript.h"
|
||||
@ -24,8 +29,11 @@
|
||||
#include "toss/LoginAndCheckAccountsTossScript.h"
|
||||
#include "ziraat/GetLastDaysHistoryZiraatScript.h"
|
||||
#include "ziraat/LoginAndCheckAccountsZiraatScript.h"
|
||||
#include "ozon/PayByPhoneScript.h"
|
||||
#include "rshb/PayByPhoneScript.h"
|
||||
|
||||
static void sendTaskResult(const QString &type, const QString &materialId, const QString &bankName, const QJsonValue &data);
|
||||
static void sendTaskError(const QString &type, const QString &materialId, const QString &bankName, const QString &description);
|
||||
|
||||
EventHandler::EventHandler(QObject *parent) : QObject(parent) {}
|
||||
|
||||
@ -41,6 +49,18 @@ void EventHandler::start() {
|
||||
connect(m_pollTimer, &QTimer::timeout, m_network, &NetworkService::getTasks);
|
||||
m_pollTimer->start();
|
||||
|
||||
// Закрываем зависшие события с прошлого запуска (только не отправленные на сервер)
|
||||
for (const EventStatus st : {EventStatus::Wait, EventStatus::InProgress}) {
|
||||
const QList<EventInfo> stale = EventDAO::getAllEvents(st);
|
||||
for (const EventInfo &e : stale) {
|
||||
if (e.sentToServer) continue;
|
||||
EventDAO::updateEvent(e.id, EventStatus::Error, "App restarted");
|
||||
EventDAO::markSentToServer(e.id);
|
||||
sendTaskError(eventTypeToString(e.type), e.externalId, e.bankName, "App restarted, event was pending");
|
||||
qDebug() << "[EventHandler] Closed stale event id:" << e.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Первый запрос сразу при старте
|
||||
qDebug() << "[EventHandler] starting first getTasks()";
|
||||
m_network->getTasks();
|
||||
@ -74,10 +94,7 @@ void EventHandler::onTasksReceived(const QJsonArray &tasks) {
|
||||
const AccountInfo account = AccountDAO::findByMaterialId(materialId);
|
||||
if (account.id == -1) {
|
||||
qWarning() << "[EventHandler] Account not found for bank:" << bankName << "material_id:" << materialId;
|
||||
QJsonObject data;
|
||||
data["status"] = "error";
|
||||
data["description"] = "Account not found for material_id: " + materialId;
|
||||
sendTaskResult(typeStr, materialId, bankName, QJsonValue(data));
|
||||
sendTaskError(typeStr, materialId, bankName, "Account not found for material_id: " + materialId);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -89,11 +106,19 @@ void EventHandler::onTasksReceived(const QJsonArray &tasks) {
|
||||
event.deviceId = account.deviceId;
|
||||
event.bankName = bankName;
|
||||
event.timestamp = QDateTime::currentDateTimeUtc();
|
||||
event.json = QJsonDocument(task).toJson(QJsonDocument::Compact);
|
||||
|
||||
const QJsonObject body = task["body"].toObject();
|
||||
if (eventType == EventType::CreateTransaction) {
|
||||
event.amount = body["amount"].toDouble();
|
||||
event.amount = body["amount"].toDouble() / 100.0;
|
||||
event.phone = body["bank_participator_id"].toString();
|
||||
|
||||
// Резолвим название банка-получателя по алиасу
|
||||
const QString bankAlias = body["extra"].toObject()["bank_participator_name"].toString();
|
||||
if (!bankAlias.isEmpty()) {
|
||||
const BankInfo bank = BankDAO::findByAlias(bankAlias);
|
||||
event.comment = !bank.nspkName.isEmpty() ? bank.nspkName : bank.name;
|
||||
}
|
||||
}
|
||||
|
||||
const int eventId = EventDAO::insertEvent(event);
|
||||
@ -106,10 +131,7 @@ void EventHandler::onTasksReceived(const QJsonArray &tasks) {
|
||||
if (!onlineDevices.contains(account.deviceId)) {
|
||||
qWarning() << "[EventHandler] Device offline for material_id:" << materialId << "device:" << account.deviceId;
|
||||
EventDAO::updateEvent(eventId, EventStatus::Error, "Device is offline");
|
||||
QJsonObject errData;
|
||||
errData["status"] = "error";
|
||||
errData["description"] = "Device is offline";
|
||||
sendTaskResult(typeStr, materialId, bankName, QJsonValue(errData));
|
||||
sendTaskError(typeStr, materialId, bankName, "Device is offline");
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,10 +147,7 @@ void EventHandler::onTasksReceived(const QJsonArray &tasks) {
|
||||
if (waitSecs > 5 * 60) {
|
||||
qWarning() << "[EventHandler] Task expired after" << waitSecs << "s, event id:" << event.id;
|
||||
EventDAO::updateEvent(event.id, EventStatus::Error, "Task expired: waited " + QString::number(waitSecs) + "s");
|
||||
QJsonObject errData;
|
||||
errData["status"] = "error";
|
||||
errData["description"] = "Task expired: not started within 5 minutes";
|
||||
sendTaskResult(eventTypeToString(event.type), event.externalId, event.bankName, QJsonValue(errData));
|
||||
sendTaskError(eventTypeToString(event.type), event.externalId, event.bankName, "Task expired: not started within 5 minutes");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -146,7 +165,7 @@ void EventHandler::onTasksReceived(const QJsonArray &tasks) {
|
||||
}
|
||||
|
||||
static void sendTaskResult(const QString &type, const QString &materialId, const QString &bankName,
|
||||
const QJsonValue &data) {
|
||||
const QJsonValue &data, int eventId = -1) {
|
||||
QJsonObject obj;
|
||||
obj["type"] = type;
|
||||
obj["material_id"] = materialId; // UUID string
|
||||
@ -157,13 +176,51 @@ static void sendTaskResult(const QString &type, const QString &materialId, const
|
||||
auto *networkService = new NetworkService;
|
||||
networkService->moveToThread(thread);
|
||||
networkService->setPayload(QJsonDocument(obj).toJson());
|
||||
QObject::connect(thread, &QThread::started, networkService, &NetworkService::postTaskResult);
|
||||
QObject::connect(thread, &QThread::started, networkService, [networkService, eventId]() {
|
||||
networkService->postTaskResult();
|
||||
if (eventId != -1) {
|
||||
EventDAO::markSentToServer(eventId);
|
||||
}
|
||||
});
|
||||
QObject::connect(networkService, &NetworkService::finished, thread, &QThread::quit);
|
||||
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
|
||||
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
|
||||
static void sendTaskError(const QString &type, const QString &materialId, const QString &bankName,
|
||||
const QString &description) {
|
||||
const QString message = QStringLiteral("[%1] bank=%2 material=%3: %4")
|
||||
.arg(type, bankName, materialId, description);
|
||||
|
||||
auto *thread = new QThread;
|
||||
auto *networkService = new NetworkService;
|
||||
networkService->moveToThread(thread);
|
||||
QObject::connect(thread, &QThread::started, networkService, [networkService, message]() {
|
||||
networkService->postMonitoringLog("error", "task_error", message, {});
|
||||
emit networkService->finished();
|
||||
});
|
||||
QObject::connect(networkService, &NetworkService::finished, thread, &QThread::quit);
|
||||
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
|
||||
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
|
||||
static void sendMonitoringLog(const QString &type, const QString &event, const QString &message,
|
||||
const QByteArray &image = {}) {
|
||||
auto *thread = new QThread;
|
||||
auto *networkService = new NetworkService;
|
||||
networkService->moveToThread(thread);
|
||||
QObject::connect(thread, &QThread::started, networkService, [networkService, type, event, message, image]() {
|
||||
networkService->postMonitoringLog(type, event, message, image);
|
||||
emit networkService->finished();
|
||||
});
|
||||
QObject::connect(networkService, &NetworkService::finished, thread, &QThread::quit);
|
||||
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
|
||||
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
|
||||
static void sendEventStatus(const QString &deviceId, const QString &externalId, const int eventId,
|
||||
const QString &status, const QString &error) {
|
||||
QJsonObject obj;
|
||||
@ -190,58 +247,98 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
|
||||
if (!EventDAO::updateEvent(event.id, newStatus, result)) {
|
||||
qCritical() << "[EventHandler] Failed to update event:" << event.id;
|
||||
} else {
|
||||
QJsonValue taskData;
|
||||
if (newStatus == EventStatus::Error) {
|
||||
QJsonObject errObj;
|
||||
errObj["status"] = "error";
|
||||
errObj["description"] = result;
|
||||
taskData = errObj;
|
||||
} else if (event.type == EventType::FetchProfile) {
|
||||
const AccountInfo account = AccountDAO::getAccountById(event.accountId);
|
||||
EventDAO::updateEventAmount(event.id, account.amount);
|
||||
QJsonObject obj;
|
||||
obj["bank_account_id"] = QString();
|
||||
obj["amount"] = static_cast<int>(account.amount);
|
||||
obj["currency"] = 643; // RUB
|
||||
taskData = obj;
|
||||
} else if (event.type == EventType::FetchTransactions) {
|
||||
QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 24);
|
||||
if (txList.isEmpty()) {
|
||||
txList = TransactionDAO::getLastTransactions(event.accountId, 10);
|
||||
}
|
||||
QJsonArray arr;
|
||||
for (const auto &tx : txList) {
|
||||
QJsonObject txObj;
|
||||
txObj["bank_transaction_id"] = tx.bankTrExternalId.isEmpty() ? QJsonValue(QJsonValue::Null) : QJsonValue(tx.bankTrExternalId);
|
||||
txObj["amount"] = static_cast<int>(tx.amount);
|
||||
txObj["currency"] = 643; // RUB
|
||||
txObj["transaction_type"] = (tx.type == TransactionType::Phone) ? "top-up" : "bank";
|
||||
txObj["bank_participator_id"]= tx.phone;
|
||||
txObj["status"] = tx.status == TransactionStatus::Complete ? "completed" : (tx.status == TransactionStatus::Wait ? "progress" : "completed");
|
||||
txObj["extra"] = QJsonObject();
|
||||
if (tx.timestamp.isValid()) {
|
||||
txObj["created_at"] = tx.timestamp.toString(Qt::ISODate);
|
||||
} else if (!tx.bankTime.isEmpty()) {
|
||||
QDateTime dt = QDateTime::fromString(tx.bankTime, "dd.MM.yyyy, HH:mm");
|
||||
if (!dt.isValid()) dt = QDateTime::fromString(tx.bankTime, "dd.MM.yyyy HH:mm");
|
||||
txObj["created_at"] = dt.isValid() ? dt.toString(Qt::ISODate) : QJsonValue(QJsonValue::Null);
|
||||
} else {
|
||||
txObj["created_at"] = QJsonValue(QJsonValue::Null);
|
||||
}
|
||||
arr.append(txObj);
|
||||
}
|
||||
taskData = arr;
|
||||
} else {
|
||||
QJsonObject obj;
|
||||
obj["status"] = "completed";
|
||||
taskData = obj;
|
||||
sendTaskError(eventTypeToString(event.type), event.externalId, event.bankName, result);
|
||||
EventDAO::markSentToServer(event.id);
|
||||
}
|
||||
|
||||
if (newStatus != EventStatus::Error) {
|
||||
QJsonValue taskData;
|
||||
if (event.type == EventType::FetchProfile) {
|
||||
const AccountInfo account = AccountDAO::getAccountById(event.accountId);
|
||||
EventDAO::updateEventAmount(event.id, account.amount);
|
||||
QJsonObject obj;
|
||||
obj["bank_account_id"] = QString();
|
||||
obj["amount"] = static_cast<int>(account.amount * 100);
|
||||
obj["currency"] = 643; // RUB
|
||||
taskData = obj;
|
||||
} else if (event.type == EventType::FetchTransactions) {
|
||||
QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 24);
|
||||
QJsonArray arr;
|
||||
for (const auto &tx : txList) {
|
||||
QJsonObject txObj;
|
||||
txObj["bank_transaction_id"] = tx.bankTrExternalId.isEmpty() ? QJsonValue(QJsonValue::Null) : QJsonValue(tx.bankTrExternalId);
|
||||
txObj["amount"] = static_cast<int>(tx.amount * 100);
|
||||
txObj["currency"] = 643; // RUB
|
||||
txObj["transaction_type"] = (tx.type == TransactionType::Phone) ? "top-up" : "bank";
|
||||
txObj["bank_participator_id"]= tx.phone;
|
||||
txObj["status"] = tx.status == TransactionStatus::Complete ? "completed" : (tx.status == TransactionStatus::Wait ? "progress" : "completed");
|
||||
txObj["extra"] = QJsonObject();
|
||||
if (tx.timestamp.isValid()) {
|
||||
txObj["created_at"] = tx.timestamp.toTimeZone(QTimeZone("Europe/Moscow")).toString(Qt::ISODateWithMs);
|
||||
} else if (!tx.bankTime.isEmpty()) {
|
||||
QDateTime dt = QDateTime::fromString(tx.bankTime, "dd.MM.yyyy, HH:mm");
|
||||
if (!dt.isValid()) dt = QDateTime::fromString(tx.bankTime, "dd.MM.yyyy HH:mm");
|
||||
if (dt.isValid()) {
|
||||
dt.setTimeZone(QTimeZone("Europe/Moscow"));
|
||||
txObj["created_at"] = dt.toString(Qt::ISODateWithMs);
|
||||
} else {
|
||||
txObj["created_at"] = QJsonValue(QJsonValue::Null);
|
||||
}
|
||||
} else {
|
||||
txObj["created_at"] = QJsonValue(QJsonValue::Null);
|
||||
}
|
||||
arr.append(txObj);
|
||||
}
|
||||
taskData = arr;
|
||||
} else if (event.type == EventType::CreateTransaction) {
|
||||
QJsonObject obj;
|
||||
obj["amount"] = -static_cast<int>(event.amount * 100);
|
||||
obj["currency"] = 643;
|
||||
obj["transaction_type"] = "top-up";
|
||||
obj["bank_participator_id"]= event.phone;
|
||||
obj["status"] = "completed";
|
||||
obj["created_at"] = QDateTime::currentDateTime().toTimeZone(QTimeZone("Europe/Moscow")).toString(Qt::ISODateWithMs);
|
||||
|
||||
// Берём bank_transaction_id из последней сохранённой транзакции
|
||||
QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 1);
|
||||
for (const auto &tx : txList) {
|
||||
if (!tx.bankTrExternalId.isEmpty() && qAbs(tx.amount) == event.amount && tx.phone == event.phone) {
|
||||
obj["bank_transaction_id"] = tx.bankTrExternalId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
taskData = obj;
|
||||
} else {
|
||||
QJsonObject obj;
|
||||
obj["status"] = "completed";
|
||||
taskData = obj;
|
||||
}
|
||||
sendTaskResult(
|
||||
eventTypeToString(event.type),
|
||||
event.externalId,
|
||||
event.bankName,
|
||||
taskData,
|
||||
event.id
|
||||
);
|
||||
}
|
||||
|
||||
if (newStatus == EventStatus::Complete && event.type == EventType::CreateTransaction) {
|
||||
const QString msg = QStringLiteral("[CREATE_TRANSACTION] bank=%1 material=%2 amount=%3 phone=%4")
|
||||
.arg(event.bankName, event.externalId, QString::number(event.amount, 'f', 2), event.phone);
|
||||
QByteArray screenshot;
|
||||
const QString tmpPath = QDir::tempPath() + "/arc_tx_" + QString::number(event.id);
|
||||
if (AdbUtils::takeScreenshot(event.deviceId, tmpPath)) {
|
||||
QFile f(tmpPath + ".png");
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
screenshot = f.readAll();
|
||||
f.close();
|
||||
}
|
||||
f.remove();
|
||||
}
|
||||
sendMonitoringLog("info", "task_success", msg, screenshot);
|
||||
}
|
||||
sendTaskResult(
|
||||
eventTypeToString(event.type),
|
||||
event.externalId,
|
||||
event.bankName,
|
||||
taskData
|
||||
);
|
||||
}
|
||||
|
||||
if (const auto tm = m_timers.take(key)) {
|
||||
@ -292,32 +389,35 @@ void EventHandler::startThreadForTask(const AccountInfo &account, const EventInf
|
||||
}
|
||||
|
||||
if (event.type == EventType::CreateTransaction) {
|
||||
// TODO: реализовать CREATE_TRANSACTION
|
||||
const QString recipientBank = event.comment; // резолвленное имя банка-получателя
|
||||
if (appCode == "ozon") setup(new Ozon::PayByPhoneScript(account, event.phone, recipientBank, event.amount));
|
||||
else if (appCode == "rshb") setup(new Rshb::PayByPhoneScript(account, event.phone, recipientBank, event.amount));
|
||||
else qWarning() << "[EventHandler] CREATE_TRANSACTION: unknown appCode:" << appCode;
|
||||
}
|
||||
|
||||
// Watchdog-таймер: 5 минут — убиваем зависший поток
|
||||
const auto timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
connect(timer, &QTimer::timeout, this, [this, key]() {
|
||||
qWarning() << "[EventHandler] Timeout for key" << key << "- killing stuck thread.";
|
||||
if (QThread *thread = m_threads.value(key); thread && thread->isRunning()) {
|
||||
thread->requestInterruption();
|
||||
if (!thread->wait(500)) {
|
||||
qWarning() << "[EventHandler] Hard terminate for key" << key;
|
||||
thread->terminate();
|
||||
thread->wait();
|
||||
}
|
||||
}
|
||||
if (const auto tm = m_timers.take(key)) {
|
||||
tm->deleteLater();
|
||||
}
|
||||
m_threads.remove(key);
|
||||
});
|
||||
// // Watchdog-таймер: 5 минут — убиваем зависший поток
|
||||
// const auto timer = new QTimer(this);
|
||||
// timer->setSingleShot(true);
|
||||
// connect(timer, &QTimer::timeout, this, [this, key]() {
|
||||
// qWarning() << "[EventHandler] Timeout for key" << key << "- killing stuck thread.";
|
||||
// if (QThread *thread = m_threads.value(key); thread && thread->isRunning()) {
|
||||
// thread->requestInterruption();
|
||||
// if (!thread->wait(500)) {
|
||||
// qWarning() << "[EventHandler] Hard terminate for key" << key;
|
||||
// thread->terminate();
|
||||
// thread->wait();
|
||||
// }
|
||||
// }
|
||||
// if (const auto tm = m_timers.take(key)) {
|
||||
// tm->deleteLater();
|
||||
// }
|
||||
// m_threads.remove(key);
|
||||
// });
|
||||
|
||||
m_threads[key] = thr;
|
||||
m_timers[key] = timer;
|
||||
// m_timers[key] = timer;
|
||||
|
||||
timer->start(5 * 60 * 1000);
|
||||
// timer->start(5 * 60 * 1000);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "NetworkService.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QUrlQuery>
|
||||
#include <QHttpPart>
|
||||
#include <QNetworkReply>
|
||||
@ -626,6 +627,10 @@ void NetworkService::getTasks() {
|
||||
QUrl url(m_apiBase + m_pathGetTasks);
|
||||
QUrlQuery urlQuery;
|
||||
const QStringList materialIds = AccountDAO::getActiveMaterialIds();
|
||||
if (materialIds.isEmpty()) {
|
||||
m_fetchingTasks = false;
|
||||
return;
|
||||
}
|
||||
for (const QString &mid : materialIds) {
|
||||
urlQuery.addQueryItem("materials_id", mid);
|
||||
}
|
||||
@ -665,7 +670,7 @@ void NetworkService::getTasks() {
|
||||
void NetworkService::postTaskResult() {
|
||||
const QJsonObject body = QJsonDocument::fromJson(m_json).object();
|
||||
const QJsonValue result = postJson(m_apiBase + m_pathTaskResult, body, true);
|
||||
if (result.isNull() || result.isUndefined()) {
|
||||
if (result.isUndefined()) {
|
||||
qWarning() << "[NetworkService] postTaskResult failed, body:" << QJsonDocument(body).toJson(QJsonDocument::Compact);
|
||||
}
|
||||
emit finished();
|
||||
@ -675,18 +680,20 @@ void NetworkService::postMonitoringLog(const QString &type, const QString &event
|
||||
const QString &message, const QByteArray &image) {
|
||||
auto *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||
|
||||
addFormField(multiPart, "type", type);
|
||||
addFormField(multiPart, "type", type.toUpper());
|
||||
addFormField(multiPart, "event", event);
|
||||
addFormField(multiPart, "message", message);
|
||||
|
||||
QHttpPart imagePart;
|
||||
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
|
||||
imagePart.setHeader(
|
||||
QNetworkRequest::ContentDispositionHeader,
|
||||
QStringLiteral("form-data; name=\"image\"; filename=\"screenshot.png\"")
|
||||
);
|
||||
imagePart.setBody(image.isEmpty() ? QByteArray(1, '\0') : image);
|
||||
multiPart->append(imagePart);
|
||||
if (!image.isEmpty()) {
|
||||
QHttpPart imagePart;
|
||||
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
|
||||
imagePart.setHeader(
|
||||
QNetworkRequest::ContentDispositionHeader,
|
||||
QStringLiteral("form-data; name=\"image\"; filename=\"screenshot.png\"")
|
||||
);
|
||||
imagePart.setBody(image);
|
||||
multiPart->append(imagePart);
|
||||
}
|
||||
|
||||
const QUrl url(m_apiBase + m_pathMonitoringLog);
|
||||
QNetworkRequest request(url);
|
||||
@ -694,12 +701,15 @@ void NetworkService::postMonitoringLog(const QString &type, const QString &event
|
||||
QNetworkReply *reply = m_manager->post(request, multiPart);
|
||||
multiPart->setParent(reply);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, reply, [reply]() {
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qWarning() << "[NetworkService] postMonitoringLog failed:" << reply->errorString();
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
QEventLoop loop;
|
||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qWarning() << "[NetworkService] postMonitoringLog failed:" << reply->errorString()
|
||||
<< "\n response body:" << reply->readAll();
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void NetworkService::start() {
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
#include "EventWindow.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QThread>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@ -18,7 +20,9 @@ static constexpr int COL_DEVICE = 4;
|
||||
static constexpr int COL_STATUS = 5;
|
||||
static constexpr int COL_AMOUNT = 6;
|
||||
static constexpr int COL_COMMENT = 7;
|
||||
static constexpr int COL_ACTION = 8;
|
||||
static constexpr int COL_JSON = 8;
|
||||
static constexpr int COL_SENT = 9;
|
||||
static constexpr int COL_ACTION = 10;
|
||||
|
||||
static void sendErrorToServer(const QString &type, const QString &materialId, const QString &bankName) {
|
||||
QJsonObject errData;
|
||||
@ -63,13 +67,13 @@ static QString typeDisplayName(EventType t) {
|
||||
|
||||
EventWindow::EventWindow(QWidget *parent) : QDialog(parent) {
|
||||
setWindowTitle("События");
|
||||
resize(1100, 600);
|
||||
resize(1400, 600);
|
||||
|
||||
// ── Таблица ───────────────────────────────────────────────────────────────
|
||||
m_table = new QTableWidget(this);
|
||||
m_table->setColumnCount(9);
|
||||
m_table->setColumnCount(11);
|
||||
m_table->setHorizontalHeaderLabels({
|
||||
"#", "Время", "Тип", "Банк", "Устройство", "Статус", "Сумма", "Комментарий", ""
|
||||
"#", "Время", "Тип", "Банк", "Устройство", "Статус", "Сумма", "Комментарий", "JSON", "Отпр.", ""
|
||||
});
|
||||
m_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
@ -83,6 +87,8 @@ EventWindow::EventWindow(QWidget *parent) : QDialog(parent) {
|
||||
m_table->setColumnWidth(COL_DEVICE, 120);
|
||||
m_table->setColumnWidth(COL_STATUS, 100);
|
||||
m_table->setColumnWidth(COL_AMOUNT, 80);
|
||||
m_table->setColumnWidth(COL_JSON, 200);
|
||||
m_table->setColumnWidth(COL_SENT, 45);
|
||||
m_table->setColumnWidth(COL_ACTION, 80);
|
||||
|
||||
// ── Пагинация ─────────────────────────────────────────────────────────────
|
||||
@ -116,6 +122,24 @@ EventWindow::EventWindow(QWidget *parent) : QDialog(parent) {
|
||||
m_page = 0;
|
||||
loadPage();
|
||||
});
|
||||
connect(m_table, &QTableWidget::cellDoubleClicked, this, [this](int row, int col) {
|
||||
if (col != COL_JSON) return;
|
||||
auto *item = m_table->item(row, col);
|
||||
if (!item) return;
|
||||
const QString json = item->toolTip();
|
||||
if (json.isEmpty()) return;
|
||||
|
||||
auto *dlg = new QDialog(this);
|
||||
dlg->setWindowTitle("JSON");
|
||||
dlg->resize(600, 400);
|
||||
auto *edit = new QPlainTextEdit(dlg);
|
||||
edit->setReadOnly(true);
|
||||
edit->setPlainText(QJsonDocument::fromJson(json.toUtf8()).toJson(QJsonDocument::Indented));
|
||||
auto *layout = new QVBoxLayout(dlg);
|
||||
layout->addWidget(edit);
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dlg->show();
|
||||
});
|
||||
|
||||
loadPage();
|
||||
}
|
||||
@ -141,6 +165,12 @@ void EventWindow::loadPage() {
|
||||
e.amount > 0 ? QString::number(e.amount, 'f', 2) : "—"));
|
||||
m_table->setItem(i, COL_COMMENT, new QTableWidgetItem(e.comment));
|
||||
|
||||
auto *jsonItem = new QTableWidgetItem(e.json.left(80));
|
||||
jsonItem->setToolTip(e.json);
|
||||
m_table->setItem(i, COL_JSON, jsonItem);
|
||||
|
||||
m_table->setItem(i, COL_SENT, new QTableWidgetItem(e.sentToServer ? "+" : ""));
|
||||
|
||||
// Подсветка строки по статусу
|
||||
QColor bg;
|
||||
switch (e.status) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user