#include "NetworkService.h" #include #include #include #include #include #include #include "dao/AccountDAO.h" #include "dao/EventDAO.h" #include "dao/TransactionDAO.h" #include "db/EventInfo.h" NetworkService::NetworkService(QObject *parent) : QObject(parent) { } NetworkService::~NetworkService() = default; // FIXME доделать работу с экстра void NetworkService::addExtra(const QString &key, const QVariant &value) { m_extraData[key] = value; } void addFormField(QHttpMultiPart *multiPart, const QString &fieldName, const QString &fieldValue) { QHttpPart formField; formField.setHeader( QNetworkRequest::ContentDispositionHeader,QStringLiteral("form-data; name=\"%1\"").arg(fieldName) ); formField.setBody(fieldValue.toUtf8()); multiPart->append(formField); } void addFormMetadata(QHttpMultiPart *multiPart, const QByteArray &fieldValue) { QHttpPart jsonPart; jsonPart.setHeader(QNetworkRequest::ContentTypeHeader, "application/json; charset=UTF-8"); jsonPart.setHeader(QNetworkRequest::ContentDispositionHeader, R"(form-data; name="metadata")"); jsonPart.setBody(fieldValue); multiPart->append(jsonPart); } QJsonValue NetworkService::post(QHttpMultiPart *multiPart, const QString &path) { QNetworkAccessManager manager; // создаём внутри потока const QUrl url(path); const QNetworkRequest request(url); QNetworkReply *reply = manager.post(request, multiPart); multiPart->setParent(reply); QEventLoop loop; connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); connect(reply, &QNetworkReply::errorOccurred, [&loop](QNetworkReply::NetworkError) { loop.quit(); }); loop.exec(); // <- здесь и запускается event-loop потока QJsonValue result; if (reply->error() == QNetworkReply::NoError) { const QByteArray raw = reply->readAll(); QJsonParseError err; const QJsonDocument doc = QJsonDocument::fromJson(raw, &err); if (err.error == QJsonParseError::NoError && doc.isObject()) { const QJsonObject root = doc.object(); if (root.value("success").toBool()) { result = root.value("data"); } else { qWarning() << "Ошибка:" << root; } } } else { qWarning() << "Ошибка:" << reply->errorString(); } reply->deleteLater(); return result; } QJsonArray NetworkService::get(const QString &path, const QMap ¶ms) { QNetworkAccessManager manager; // создаём внутри потока QUrl url(path); QUrlQuery query; for (auto it = params.constBegin(); it != params.constEnd(); ++it) { query.addQueryItem(it.key(), it.value()); } url.setQuery(query); const QNetworkRequest request(url); QNetworkReply *reply = manager.get(request); QEventLoop loop; connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); connect(reply, &QNetworkReply::errorOccurred, [&loop](QNetworkReply::NetworkError) { loop.quit(); }); loop.exec(); // <- здесь и запускается event-loop потока QJsonArray result; if (reply->error() == QNetworkReply::NoError) { const QByteArray raw = reply->readAll(); QJsonParseError err; const QJsonDocument doc = QJsonDocument::fromJson(raw, &err); if (err.error == QJsonParseError::NoError && doc.isObject()) { const QJsonObject root = doc.object(); if (root.value("success").toBool()) { result = root.value("data").toArray(); } else { qWarning() << "Ошибка:" << root; } } } else { qWarning() << "Ошибка:" << reply->errorString(); } reply->deleteLater(); return result; } void NetworkService::postAccountsData() { QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); addFormMetadata(multiPart, m_json); addFormField(multiPart, "desktopUniqueName", m_desktopId); addFormField(multiPart, "androidUniqueName", m_deviceId); const bool isSuccess = post(multiPart, "http://localhost:9999/api/v1/account/update").toBool(); if (!isSuccess) { qDebug() << "Cant post accounts data"; } emit finished(); } void NetworkService::getPayments() { QMap params; params["desktopUniqueName"] = m_desktopId; const QJsonArray data = get("http://localhost:9999/api/v1/payments", params); for (QJsonValue item: data) { QJsonObject obj = item.toObject(); EventInfo eventInfo; eventInfo.status = EventStatus::Wait; eventInfo.externalId = obj["id"].toInt(); eventInfo.amount = obj["amount"].toDouble(); eventInfo.bankName = obj["bankName"].toString(); eventInfo.phone = obj["phone"].toString(); QString deviceId = obj["deviceId"].toString(); QString appName = obj["appName"].toString(); QString lastNumbers = obj["lastNumbers"].toString(); AccountInfo account = AccountDAO::findAppAccount(deviceId, appName, lastNumbers); eventInfo.accountId = account.id; int id = EventDAO::insertEvent(eventInfo); if (id == -1) { qDebug() << "Cant insert event"; } else { if (!EventDAO::updateEvent(id, EventStatus::Wait)) { qDebug() << "Cant update event"; } } } emit finished(); } void NetworkService::updateTransactionData() { QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); addFormMetadata(multiPart, m_json); addFormField(multiPart, "desktopUniqueName", m_desktopId); addFormField(multiPart, "androidUniqueName", m_deviceId); addFormField(multiPart, "lastNumbers", m_extraData["lastNumbers"].toString()); const bool isSuccess = post(multiPart, "http://localhost:9999/api/v1/transaction/update").toBool(); if (!isSuccess) { qDebug() << "Cant update transaction"; } emit finished(); } void NetworkService::insertTransactionData() { QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); addFormMetadata(multiPart, m_json); addFormField(multiPart, "desktopUniqueName", m_desktopId); addFormField(multiPart, "androidUniqueName", m_deviceId); addFormField(multiPart, "lastNumbers", m_extraData["lastNumbers"].toString()); const int id = post(multiPart, "http://localhost:9999/api/v1/transaction/insert").toInt(); if (id > 0) { const int transactionId = m_extraData["transactionId"].toInt(); if (!TransactionDAO::updateExternalTransactionId(transactionId, id)) { qDebug() << "Cant update transaction id"; } } emit finished(); } void NetworkService::stop() { m_running = false; }