diff --git a/android/rshb/GetLastDaysHistoryScript.cpp b/android/rshb/GetLastDaysHistoryScript.cpp index e639950..24635b9 100644 --- a/android/rshb/GetLastDaysHistoryScript.cpp +++ b/android/rshb/GetLastDaysHistoryScript.cpp @@ -137,9 +137,6 @@ bool GetLastDaysHistoryScript::openAndSaveDitailInfo(TransactionInfo &transactio void GetLastDaysHistoryScript::doStart() { // берем все транзакции из БД QList localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48); - // for (const TransactionInfo& transaction: transactions) { - // qDebug().noquote().nospace() << convertTransactionToString(transaction); - // } const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId); xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter)); @@ -149,124 +146,202 @@ void GetLastDaysHistoryScript::doStart() { findAndTapOnAccount(device.id, m_account.lastNumbers); xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter)); - Node filterBtn = xmlScreenParser.findButtonNode("РСХБ Онлайн", false); - if (!filterBtn.isEmpty()) { - AdbUtils::makeTap(m_account.deviceId, filterBtn.x(), filterBtn.y()); - QThread::msleep(1000); + Node actionBtn = xmlScreenParser.findButtonNode("Действия", false); + if (!actionBtn.isEmpty()) { + AdbUtils::makeTap(m_account.deviceId, actionBtn.x(), actionBtn.y()); + QThread::msleep(200); } else { - qWarning() << "--- filterBtn not found"; + qWarning() << "--- actionBtn not found"; + } + Node reportButton = swipeToButton(m_account.deviceId, "Выписка", m_counter, device.screenWidth, + device.screenHeight); + + if (!reportButton.isEmpty()) { + AdbUtils::makeTap(m_account.deviceId, reportButton.x(), reportButton.y()); + QThread::msleep(1000); } xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter)); - Node allTransactionFilerBtn = xmlScreenParser.findButtonNode("Все операции", false); - if (!allTransactionFilerBtn.isEmpty()) { - AdbUtils::makeTap(m_account.deviceId, allTransactionFilerBtn.x(), allTransactionFilerBtn.y()); - QThread::msleep(1000); - } else { - qWarning() << "--- allTransactionFilerBtn not found"; - } - QList parsedTransactions; - xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter)); - for (int i = 0; i < 5; ++i) { - parsedTransactions = xmlScreenParser.parseTodayAndYesterdayHistory(); - if (!parsedTransactions.empty()) { - break; - } + Node reportTitle = xmlScreenParser.findTextNode("Выписка"); + if (!reportTitle.isEmpty() && reportTitle.y() < 300) { + QDate beforeYesterday = DateUtils::getMoscowNow().date().addDays(-2); + QString beforeYesterdayTitle = beforeYesterday.toString("dd.MM.yyyy"); - QThread::msleep(1000); - xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter)); - } - - - qDebug() << "--- parsedTransactions: " << parsedTransactions.length(); - // localTransactions - QList updatedTransactions; - for (TransactionInfo &transaction: parsedTransactions) { - // если shortDescription + сумма + день и Complete совпадает и одна - int cSimilar = countSimilar(transaction, parsedTransactions); - QList txs = findSavedTransaction(localTransactions, transaction); - - if (cSimilar == 1 && txs.length() < 2) { - if (txs.length() == 1) { - // смотрим, надо ли обновление - if (txs[0].status != TransactionStatus::Complete || txs[0].shortDescription.isEmpty()) { - txs[0].shortDescription = transaction.shortDescription; - openAndSaveDitailInfo(txs[0], device.screenWidth, device.screenHeight); - updatedTransactions.append(txs[0]); - } - } else { - // создаем новую - openAndSaveDitailInfo(transaction, device.screenWidth, device.screenHeight); + for (int i = 0; i < 5; ++i) { + Node byDayTitle = xmlScreenParser.findTextNode(beforeYesterdayTitle); + if (!byDayTitle.isEmpty()) { + qWarning() << "--- beforeYesterdayTitle found!"; + break; } - } else { - if (cSimilar == txs.length()) { - // одинаковые транзакции (2 - 2) - for (TransactionInfo &tx: txs) { - if (!updatedTransactions.contains(tx)) { - openAndSaveDitailInfo(tx, device.screenWidth, device.screenHeight); - updatedTransactions.append(tx); + AdbUtils::makeSwipe( + m_account.deviceId, + device.screenWidth / 2, device.screenHeight / 4 * 3, + device.screenWidth / 2, device.screenHeight / 4 + ); + QThread::msleep(1000); + xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter)); + } + } else { + qWarning() << "--- reportTitle not found"; + } + + // все поддвержденные + QList parsedTransactions = xmlScreenParser.parseTodayAndYesterdayReportHistory(); + QSet parsedTransactionIds; + qDebug() << "--- parsedTransactions: " << parsedTransactions.length(); + qDebug() << "--- localTransactions: " << localTransactions.length(); + for (const TransactionInfo &transaction: parsedTransactions) { + bool updated = false; + + for (const TransactionInfo &saved: localTransactions) { + if (parsedTransactionIds.contains(saved.id)) { + continue; + } + QDate sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy HH:mm:ss").date(); + if (!sDate.isValid()) { + sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy").date(); + } + QDate pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy HH:mm:ss").date(); + if (!pDate.isValid()) { + pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy").date(); + } + // Если сумма и дата совпадают + if (saved.amount == transaction.amount && sDate == pDate) { + if (transaction.description.startsWith("Перевод")) { + // Перевод по номеру + if (saved.bankName == transaction.bankName && saved.phone == transaction.phone) { + parsedTransactionIds.insert(saved.id); + updated = true; + if (saved.status != TransactionStatus::Complete || saved.description.isEmpty()) { + if (!TransactionDAO::updateTransaction( + saved.id, + TransactionStatus::Complete, + saved.description, + transaction.description + )) { + qDebug().noquote().nospace() << "--- updated+phone failed" << + convertTransactionToString(transaction);; + } + } break; } - } - } else if (cSimilar < txs.length()) { - // Дубликаты транзакций или название изменилось (1 - 2) - qDebug() << "--- Дубликаты транзакций или название изменилось (1 - 2)!!!!!!!!!!!!"; - // FIXME alert!!! - } else { - // нужно создать новую транзакцию, которой не было (2 - 1) - bool updated = false; - for (TransactionInfo &tx: txs) { - if (!updatedTransactions.contains(tx)) { - openAndSaveDitailInfo(tx, device.screenWidth, device.screenHeight); - updatedTransactions.append(tx); + } else { + // перевод по карте + // перезаписать saved.description -> updatedDescription если не равны + if (!saved.description.isEmpty()) { + if (saved.description == transaction.description) { + // описания совпадают + if (saved.status != TransactionStatus::Complete) { + if (!TransactionDAO::updateTransaction( + saved.id, + TransactionStatus::Complete, + saved.description, + transaction.description + )) { + qDebug().noquote().nospace() << "--- updated+card[description same] failed" + << + convertTransactionToString(transaction);; + } + } + parsedTransactionIds.insert(saved.id); + updated = true; + break; + } else { + // описания не совпадают, то пробуем найти такое же, если не находим то это новая + bool findWithSameName = false; + for (const TransactionInfo &saved2: localTransactions) { + if (saved2.description == transaction.description && !parsedTransactionIds. + contains( + saved2.id)) { + // мы нашли с одинаковым описанием и еще не обработанную + if (saved2.status != TransactionStatus::Complete) { + if (!TransactionDAO::updateTransaction( + saved2.id, + TransactionStatus::Complete, + saved2.description, + transaction.description + )) { + qDebug().noquote().nospace() << + "--- updated+card2[description same] failed" + << + convertTransactionToString(transaction);; + } + } + parsedTransactionIds.insert(saved2.id); + updated = true; + findWithSameName = true; + break; + } + } + if (!findWithSameName) { + // обновляем описание + if (!TransactionDAO::updateTransaction( + saved.id, + TransactionStatus::Complete, + saved.description, + transaction.description + )) { + qDebug().noquote().nospace() << + "--- updated+card2+new desc[description same] failed" << + convertTransactionToString(transaction);; + } + } + parsedTransactionIds.insert(saved.id); + updated = true; + break; + } + } else { + // пустой описание + if (!TransactionDAO::updateTransaction( + saved.id, + TransactionStatus::Complete, + saved.description, + transaction.description + )) { + qDebug().noquote().nospace() << + "--- updated+card[empty description]" << + convertTransactionToString(transaction);; + } + parsedTransactionIds.insert(saved.id); updated = true; break; } } - if (!updated) { - // создаем новую, так как у нас появилась одинаковая транзакция - openAndSaveDitailInfo(transaction, device.screenWidth, device.screenHeight); - } + } + } + if (!updated) { + qDebug() << "--- insert: " << transaction.description; + // не нашлась транзакция + TransactionInfo tr; + tr.accountId = m_account.id; + tr.description = transaction.description; + tr.bankTime = transaction.bankTime; + tr.bankName = transaction.bankName; + tr.amount = transaction.amount; + tr.phone = transaction.phone; + tr.updateTime = DateUtils::getUtcNow(); + tr.fee = transaction.fee; + tr.name = transaction.name; + tr.trExternalId = transaction.trExternalId; + tr.status = TransactionStatus::Complete; + tr.type = transaction.description.startsWith("Перевод") + ? TransactionType::Phone + : TransactionType::Card; + tr.completeTime = DateUtils::getUtcNow(); + if (TransactionDAO::insertTransaction(tr) == -1) { + qDebug() << "--- not inserted: " << transaction.description; } } - xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter)); + // Если это перевод + // Если совпадает по сумме + телефон + банк дата (без времени) + банк + + // Если по карте, мы знаем ток дату + сумма } - // сначала обработаем + } } else { qDebug() << "--- home screen not found"; } } - -/** - amount: -250 - shortDescription: Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +7964181514... - bankTime: 08.05.2025 - - amount: -305 - shortDescription: Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815... - bankTime: 08.05.2025 - - - amount: -250 - shortDescription: Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815... - bankTime: 07.05.2025 - - amount: -250 - shortDescription: Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +7964181514... - bankTime: 07.05.2025 - - amount: -250 - shortDescription: Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815... - bankTime: 07.05.2025 - - amount: 2100 - shortDescription: Перевод через СБП от Надежда Юрьевна К (+7(964)-181-51-46) из Альфа-Банк на 4081... - bankTime: 07.05.2025 - - amount: 250 - shortDescription: Перевод через СБП от Надежда Юрьевна К (+7(964)-181-51-46) из Сбербанк на 408178... - bankTime: 07.05.2025 - */ diff --git a/android/rshb/ScreenXmlParser.cpp b/android/rshb/ScreenXmlParser.cpp index b8a8a64..0a58a3e 100644 --- a/android/rshb/ScreenXmlParser.cpp +++ b/android/rshb/ScreenXmlParser.cpp @@ -300,6 +300,23 @@ bool hasTimeComponent(const QString &datetimeStr) { return dt.time() != QTime(0, 0, 0); // Проверка, что время не равно 00:00:00 } +QString transformBankDateTime(const QString &date) { + QDateTime dt; + if (date.contains(",")) { + // 10.05.2025, 15:03 + dt = QDateTime::fromString(date, "dd.MM.yyyy, HH:mm"); + } else { + dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm:ss"); + } + if (!dt.isValid()) { + dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm"); + } + if (!dt.isValid()) { + return date; // не распарсили + } + return dt.toString("dd.MM.yyyy HH:mm:ss"); +} + void parseTransferInfo(const QString &text, TransactionInfo &info) { if (const auto m = reSender.match(text); m.hasMatch()) { info.name = m.captured(1).trimmed(); @@ -330,9 +347,9 @@ void parseTransferInfo(const QString &text, TransactionInfo &info) { if (const auto m = reDate.match(text); m.hasMatch()) { const QString date = m.captured(1); // если не пустая и дата у нас с 00:00 - if (hasTimeComponent(date)) { - info.bankTime = date; - } + // if (hasTimeComponent(date)) { + info.bankTime = transformBankDateTime(date); + // } } } @@ -491,6 +508,103 @@ QString beforeAmount(const QString &text) { return text; // если не найдено — вернуть всю строку } +double parseAmount(const QString &amountAsString) { + QString numberString = amountAsString; + numberString.remove(QRegularExpression(R"([^\dточка])")); + numberString.replace("точка", "."); + double amount = numberString.toDouble(); + + if (amountAsString.startsWith("-")) { + amount *= -1; + } + + return amount; +} + +QDomElement findElementWithListView(const QDomElement &parent) { + QDomElement element = parent.firstChildElement(); + while (!element.isNull()) { + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.hasAttribute("class") && child.attribute("class") == "android.widget.ListView") { + return child; + } + child = child.nextSiblingElement(); + } + + QDomElement found = findElementWithListView(element); + if (!found.isNull()) { + return found; + } + element = element.nextSiblingElement(); + } + return {}; +} + +QList ScreenXmlParser::parseTodayAndYesterdayReportHistory() { + QList transactions; + + QDomElement child = findElementWithListView(m_xml); + QDomNodeList listView = findElementWithListView(m_xml).childNodes(); + qDebug() << listView.count(); + if (!listView.isEmpty()) { + QString date; + for (QDomNode node: listView) { + if (node.hasChildNodes()) { + QString text; + if (node.childNodes().count() > 1) { + date = node.firstChildElement().attribute("text"); + text = node.lastChildElement().attribute("text"); + } else if (node.childNodes().count() == 1) { + text = node.firstChildElement().attribute("text"); + } + + TransactionInfo transaction; + if (text.startsWith("Перевод")) { + QRegularExpression re(R"([+-] \d{1,3}(?: \d{3})* точка \d{2} Рубль$)"); + QRegularExpressionMatch match = re.match(text); + if (match.hasMatch()) { + QString amount = match.captured(0); + transaction.amount = parseAmount(amount.trimmed()); + text.chop(amount.length()); + } + transaction.description = text.trimmed(); + parseTransferInfo(text, transaction); + if (transaction.bankTime.isEmpty()) { + transaction.bankTime = transformBankDateTime(date); + } + } else { + // карта + if (text.contains("без учета комиссии")) { + QRegularExpression re(R"( без учета комиссии -\d{1,3}(?: \d{3})* точка \d{2} Рубль$)"); + QRegularExpressionMatch match = re.match(text); + if (match.hasMatch()) { + QString fee = match.captured(0); + text.chop(fee.length()); + transaction.fee = parseAmount(fee.replace("без учета комиссии", "").trimmed()); + } + } + QRegularExpression re(R"([+-] \d{1,3}(?: \d{3})* точка \d{2} Рубль$)"); + QRegularExpressionMatch match = re.match(text); + if (match.hasMatch()) { + QString amount = match.captured(0); + transaction.amount = parseAmount(amount.trimmed()); + text.chop(amount.length()); + } + transaction.description = text.trimmed(); + if (transaction.bankTime.isEmpty()) { + transaction.bankTime = transformBankDateTime(date); + } + } + transactions.append(transaction); + } + } + } else { + qDebug() << "ListView is empty"; + } + return transactions; +} + QList ScreenXmlParser::parseTodayAndYesterdayHistory() { QDate today = DateUtils::getMoscowNow().date(); QDate yesterday = today.addDays(-1); @@ -668,7 +782,7 @@ TransactionInfo parseExpandedInfoHistory(const QDomElement &root) { switch (QDomElement e = info.toElement(); e.attribute("index").toInt()) { case 2: // Дата операции - transaction.bankTime = findSubInfo(e, "1"); + transaction.bankTime = transformBankDateTime(findSubInfo(e, "1")); break; case 5: transaction.description = findSubInfo(e, "1"); @@ -732,7 +846,7 @@ TransactionInfo parseExpandedInfo(const QDomElement &root) { QDomElement ee; switch (index.toInt()) { case 3: - transaction.bankTime = findSubInfo(infoElement, "1"); + transaction.bankTime = transformBankDateTime(findSubInfo(infoElement, "1")); break; case 4: ee = findSubElement(infoElement, "0"); @@ -786,7 +900,6 @@ TransactionInfo ScreenXmlParser::parseTransactionInfo(int screenWidth, int scree } - QList > ScreenXmlParser::parseAccountsInfo() { QList > accounts; for (const Node &node: m_nodes) { @@ -835,7 +948,7 @@ void ScreenXmlParser::test() { QDomElement root = doc.documentElement(); parseAndSaveXml(doc.toString()); // for (const AccountInfo &info: parseAccountsInfo()) { - // qDebug().noquote().nospace() << convertAccountToString(info); + // qDebug().noquote().nospace() << convertAccountToString(info); // } // TransactionInfo info = parseExpandedInfo(root); // qDebug().noquote().nospace() << convertTransactionToString(info); diff --git a/android/rshb/ScreenXmlParser.h b/android/rshb/ScreenXmlParser.h index b7e15d8..de942f2 100644 --- a/android/rshb/ScreenXmlParser.h +++ b/android/rshb/ScreenXmlParser.h @@ -38,6 +38,8 @@ public: TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight); TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight); + QList parseTodayAndYesterdayReportHistory(); + QList parseTodayAndYesterdayHistory(); diff --git a/assets/rshb/card_report_complete.png b/assets/rshb/card_report_complete.png new file mode 100644 index 0000000..3317f6e Binary files /dev/null and b/assets/rshb/card_report_complete.png differ diff --git a/assets/rshb/card_report_complete.xml b/assets/rshb/card_report_complete.xml new file mode 100644 index 0000000..b0732ea --- /dev/null +++ b/assets/rshb/card_report_complete.xml @@ -0,0 +1,430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/rshb/card_report_complete_0.png b/assets/rshb/card_report_complete_0.png new file mode 100644 index 0000000..6d5a527 Binary files /dev/null and b/assets/rshb/card_report_complete_0.png differ diff --git a/assets/rshb/card_report_complete_0.xml b/assets/rshb/card_report_complete_0.xml new file mode 100644 index 0000000..248e542 --- /dev/null +++ b/assets/rshb/card_report_complete_0.xml @@ -0,0 +1,1068 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/rshb/card_screen_actions.png b/assets/rshb/card_screen_actions.png new file mode 100644 index 0000000..c6069a4 Binary files /dev/null and b/assets/rshb/card_screen_actions.png differ diff --git a/assets/rshb/card_screen_actions.xml b/assets/rshb/card_screen_actions.xml new file mode 100644 index 0000000..298c077 --- /dev/null +++ b/assets/rshb/card_screen_actions.xml @@ -0,0 +1,869 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/database/app_data.db b/database/app_data.db index fdec5d7..cef29f6 100644 Binary files a/database/app_data.db and b/database/app_data.db differ diff --git a/database/dao/TransactionDAO.cpp b/database/dao/TransactionDAO.cpp index ab1182b..a089185 100644 --- a/database/dao/TransactionDAO.cpp +++ b/database/dao/TransactionDAO.cpp @@ -292,3 +292,46 @@ QList TransactionDAO::getTransactionsWithinHours(const int acco } return list; } + +bool TransactionDAO::updateTransaction( + const int id, + const TransactionStatus status, + const QString &oldDesc, + const QString &newDesc +) { + QSqlQuery query(DatabaseManager::instance().database()); + + query.prepare(R"( + UPDATE transactions SET + status = :status, + update_time = :update_time, + complete_time = :complete_time, + description = :description, + updated_description = :updated_description + WHERE id = :id + )"); + + query.bindValue(":id", id); + query.bindValue(":status", transactionStatusToString(status)); + query.bindValue(":update_time", DateUtils::toUtcString(DateUtils::getUtcNow())); + + if (oldDesc.isEmpty() || oldDesc != newDesc) { + query.bindValue(":description", newDesc); + query.bindValue(":updated_description", oldDesc); + } else { + query.bindValue(":description", newDesc); + query.bindValue(":updated_description", ""); + } + + if (status == TransactionStatus::Complete) { + query.bindValue(":complete_time", DateUtils::toUtcString(DateUtils::getUtcNow())); + } else { + query.bindValue(":complete_time", QVariant(QMetaType(QMetaType::QString))); + } + + if (!query.exec()) { + qWarning() << "Ошибка при обновлении transaction:" << query.lastError().text(); + return false; + } + return true; +} diff --git a/database/dao/TransactionDAO.h b/database/dao/TransactionDAO.h index cd805a1..5b4ca56 100644 --- a/database/dao/TransactionDAO.h +++ b/database/dao/TransactionDAO.h @@ -19,4 +19,10 @@ public: [[nodiscard]] static TransactionInfo getTransactionById(int id); [[nodiscard]] static QList getTransactionsWithinHours(int accountId, int hours); + + [[nodiscard]] static bool updateTransaction( + int id, TransactionStatus status, + const QString &oldDesc, + const QString &newDesc + ); }; diff --git a/database/time/DateUtils.cpp b/database/time/DateUtils.cpp index 0c35890..15703c7 100644 --- a/database/time/DateUtils.cpp +++ b/database/time/DateUtils.cpp @@ -13,7 +13,7 @@ QDateTime DateUtils::getUtcNow() { } QDateTime DateUtils::fromUtcString(const QString ×tamp) { - QDateTime dateTime = QDateTime::fromString(timestamp, "dd.MM.yyyy HH:mm:ss"); + QDateTime dateTime = QDateTime::fromString(timestamp, "yyyy-MM-dd HH:mm:ss"); if (dateTime.isValid()) { dateTime.setTimeZone(QTimeZone::utc()); } @@ -21,5 +21,5 @@ QDateTime DateUtils::fromUtcString(const QString ×tamp) { } QString DateUtils::toUtcString(const QDateTime &dateTime) { - return dateTime.toString("dd.MM.yyyy HH:mm:ss"); + return dateTime.toString("yyyy-MM-dd HH:mm:ss"); } diff --git a/main.cpp b/main.cpp index 2c83275..5627b25 100644 --- a/main.cpp +++ b/main.cpp @@ -49,6 +49,25 @@ void setupWorkerAndThread(QCoreApplication &app) { thread->start(); } +void setupWorkerAndThreadHistory(QCoreApplication &app) { + const QString appName = "rshb"; + const QString cardNumber = "2200380317107183"; + AccountInfo account = AccountDAO::findAppAccount(appName, cardNumber); + auto *thread = new QThread; + auto *deviceScreenerWorker = new GetLastDaysHistoryScript(account); + + deviceScreenerWorker->moveToThread(thread); + QObject::connect(thread, &QThread::started, deviceScreenerWorker, &GetLastDaysHistoryScript::start); + QObject::connect(deviceScreenerWorker, &GetLastDaysHistoryScript::finished, thread, &QThread::quit); + QObject::connect(deviceScreenerWorker, &GetLastDaysHistoryScript::finished, deviceScreenerWorker, &QObject::deleteLater); + QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater); + QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() { + deviceScreenerWorker->stop(); + }); + + thread->start(); +} + void setupScriptAutoPaymentAndThread(QCoreApplication &app) { const QString appName = "rshb"; const QString cardNumber = "2200380317107183"; @@ -56,15 +75,21 @@ void setupScriptAutoPaymentAndThread(QCoreApplication &app) { const QString phoneNumber = "79641815146"; const QString bankName = "Альфа-Банк"; // const QString bankName = "Сбербанк"; - const double amount = 310; + const double amount = 440; - AccountInfo account = AccountDAO::findAppAccount(appName, cardNumber); + const AccountInfo account = AccountDAO::findAppAccount(appName, cardNumber); if (account.id != -1) { // Функция для подключения потоков к завершению приложения auto connectStopOnQuit = [&](QObject *worker, QThread *thread) { - QObject::connect(&app, &QCoreApplication::aboutToQuit, worker, &QObject::deleteLater); - QObject::connect(&app, &QCoreApplication::aboutToQuit, thread, &QThread::quit); - QObject::connect(&app, &QCoreApplication::aboutToQuit, thread, &QThread::deleteLater); + QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() { + if (thread->isRunning()) { + qDebug() << "Завершаем поток:" << thread; + thread->quit(); + thread->wait(); // Ожидаем завершения потока + } + worker->deleteLater(); + thread->deleteLater(); + }); }; // Первый поток @@ -79,7 +104,7 @@ void setupScriptAutoPaymentAndThread(QCoreApplication &app) { QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater); // Обработка результата первого потока - QObject::connect(scriptWorker, &PayByPhoneScript::finishedWithResult, &app, [&](const QString &result) { + QObject::connect(scriptWorker, &PayByPhoneScript::finishedWithResult, &app, [account, connectStopOnQuit](const QString &result) { qDebug() << "Получен результат: [" << result << "]"; // Создаем второй поток после завершения первого diff --git a/migrations.sql b/migrations.sql index c66c44f..e1a190f 100644 --- a/migrations.sql +++ b/migrations.sql @@ -8,7 +8,7 @@ CREATE TABLE IF NOT EXISTS devices screen_height INTEGER, battery INTEGER, update_time DATETIME, - timestamp DATETIME DEFAULT (strftime('%d.%m.%Y %H:%M:%S', 'now')), + timestamp DATETIME DEFAULT (strftime('%d.%m.%Y %H:%M:%S', 'now')), image BLOB ); @@ -35,7 +35,7 @@ CREATE TABLE IF NOT EXISTS accounts last_numbers TEXT, description TEXT, amount REAL, - update_time DATETIME DEFAULT (strftime('%d.%m.%Y %H:%M:%S', 'now')), + update_time DATETIME DEFAULT (strftime('%d.%m.%Y %H:%M:%S', 'now')), status TEXT, FOREIGN KEY (device_id) REFERENCES devices (id) ON DELETE CASCADE, UNIQUE (device_id, app_name, last_numbers) @@ -66,7 +66,6 @@ CREATE TABLE IF NOT EXISTS transactions update_time DATETIME, complete_time DATETIME, - timestamp DATETIME DEFAULT (strftime('%d.%m.%Y %H:%M:%S', 'now')), - FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE, - UNIQUE (amount, timestamp) + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE ); \ No newline at end of file