| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- #include "tapi.h"
- #include "appevent.h"
- #include "qcoreapplication.h"
- #include "qglobal.h"
- #include "qjsonobject.h"
- #include "qobject.h"
- #include <functional>
- #include <optional>
- #include <QApplication>
- #include <QFile>
- #include <QFileInfo>
- #include <QHttpMultiPart>
- #include <QJsonArray>
- #include <QJsonDocument>
- #include <QJsonObject>
- #include <QNetworkReply>
- #include <QUrlQuery>
- #include <QMessageBox>
- #include <QCoreApplication>
- struct Tr
- {
- Q_DECLARE_TR_FUNCTIONS(TeacherServer)
- };
- #include "api/tloginapi.h"
- namespace TC {
- // 创建一个映射来存储错误码和对应的信息
- static QMap<RequestCode, QString> errorMessages
- = {{RequestCode::OK, Tr::tr("OK")},
- {RequestCode::GeneralServerError, Tr::tr("General Server Error")},
- {RequestCode::InvalidRequest, Tr::tr("Invalid Request")},
- {RequestCode::TokenExpired, Tr::tr("Token Expired")},
- {RequestCode::DatabaseError, Tr::tr("Database Error")},
- {RequestCode::UsernameError, Tr::tr("Username Error")},
- {RequestCode::InvalidPhoneFormat, Tr::tr("Invalid Phone Format")},
- {RequestCode::PasswordRequirementsNotMet, Tr::tr("Password Requirements Not Met")},
- {RequestCode::PhoneAlreadyRegistered, Tr::tr("Phone Already Registered")},
- {RequestCode::IncorrectCredentials, Tr::tr("Incorrect Credentials")},
- {RequestCode::GetPhoneCodeError, Tr::tr("Get Phone Code Error")},
- {RequestCode::PhoneCodeExists, Tr::tr("Phone Code Exists")},
- {RequestCode::PhoneCodeNotFound, Tr::tr("Phone Code Not Found")},
- {RequestCode::CorrectVerificationCode, Tr::tr("Correct Verification Code")},
- {RequestCode::UpdateLoginPasswordFailed, Tr::tr("Update Login Password Failed")},
- {RequestCode::RealNameVerificationFailed, Tr::tr("Real Name Verification Failed")},
- {RequestCode::VIPExpirationTimeFailed, Tr::tr("VIP Expiration Time Failed")}};
- static QString base_url("http://exam.stem993.cn");
- static const QLatin1String scCode("code");
- static const QLatin1String scMessage("message");
- static const QLatin1String scData("data");
- // 响应拦截
- static bool InterceptorsResponse(QNetworkReply *reply, QJsonValue &data)
- {
- if (reply->error() == QNetworkReply::NoError) {
- const QByteArray allData = reply->readAll();
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(allData, &jsonError);
- if (jsonError.error != QJsonParseError::NoError) {
- qDebug() << data;
- return false;
- }
- #ifdef QT_DEBUG
- qDebug() << QString::fromUtf8(jsonDoc.toJson());
- #endif
- if (jsonDoc.isObject()) {
- const QJsonObject &object = jsonDoc.object();
- if (object.contains(scCode)) {
- int code = object.value(scCode).toInt();
- if (code != 0) {
- // RequestCode requestCode = static_cast<RequestCode>(code);
- const QWidgetList widgetList = QApplication::topLevelWidgets();
- QWidget *parentWidget = nullptr;
- if (!widgetList.isEmpty()) {
- parentWidget = widgetList.first();
- }
- // 获取当前活动窗口
- QMessageBox::critical(parentWidget,
- Tr::tr("Error"),
- object[scMessage].toString());
- // if (errorMessages.contains(requestCode)) {
- // //Core::MessageManager::writeFlashing(errorMessages[requestCode]);
- // } else {
- // //Core::MessageManager::writeFlashing(Tr::tr("unknown error"));
- // }
- return false;
- }
- }
- if (object.contains(scMessage)) {
- const QString &message = object.value(scMessage).toString();
- // Core::MessageManager::writeFlashing(message);
- }
- if (object.contains(scData)) {
- data = object.value(scData);
- }
- }
- return true;
- } else if (reply->error() == QNetworkReply::InternalServerError) { //权限错误
- qDebug() << "0" << reply->error();
- AppEvent::instance()->setJwtToken(QString());
- QWidget *parentWidget = QApplication::topLevelWidgets().first();
- QMessageBox::critical(parentWidget, Tr::tr("Server Error"), reply->errorString());
- return false;
- } else { //其他错误
- AppEvent::instance()->setJwtToken(QString());
- qDebug() << "1" << reply->error();
- QWidget *parentWidget = QApplication::topLevelWidgets().first();
- // 获取当前活动窗口
- QMessageBox::critical(parentWidget, Tr::tr("Server Error"), reply->errorString());
- // Core::MessageManager::writeFlashing(reply->errorString());
- return false;
- }
- return false;
- }
- static bool InterceptorsResponse2(QNetworkReply *reply, QJsonValue &data)
- {
- if (reply->error() == QNetworkReply::NoError) {
- const QByteArray allData = reply->readAll();
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(allData, &jsonError);
- if (jsonError.error != QJsonParseError::NoError) {
- qDebug() << data;
- return false;
- }
- #ifdef QT_DEBUG
- qDebug() << QString::fromUtf8(jsonDoc.toJson());
- #endif
- if (jsonDoc.isObject()) {
- const QJsonObject &object = jsonDoc.object();
- data = object;
- // if (object.contains(scCode)) {
- // int code = object.value(scCode).toInt();
- // if (code != 0) {
- // return false;
- // }
- // }
- // if (object.contains(scMessage)) {
- // const QString &message = object.value(scMessage).toString();
- // // Core::MessageManager::writeFlashing(message);
- // }
- // if (object.contains(scData)) {
- // data = object.value(scData);
- // }
- }
- return true;
- } else if (reply->error() == QNetworkReply::InternalServerError) { //权限错误
- qDebug() << "0" << reply->error();
- AppEvent::instance()->setJwtToken(QString());
- return false;
- } else { //其他错误
- qDebug() << reply->error() << reply->errorString();
- AppEvent::instance()->setJwtToken(QString());
- return false;
- }
- return false;
- }
- }; // namespace TC
- namespace TC {
- static NetworkAccessManager *namInstance = nullptr;
- void cleanupNetworkAccessManager()
- {
- delete namInstance;
- namInstance = nullptr;
- }
- NetworkAccessManager *NetworkAccessManager::instance()
- {
- if (!namInstance) {
- namInstance = new NetworkAccessManager;
- qAddPostRoutine(cleanupNetworkAccessManager);
- }
- return namInstance;
- }
- NetworkAccessManager::NetworkAccessManager(QObject *parent)
- : QNetworkAccessManager(parent)
- {
- // const QString ip = AppEvent::instance()->configValue("serverIP").toString();
- // const QString port = AppEvent::instance()->configValue("serverPort").toString();
- // base_url = QString("http://%1:%2").arg(ip).arg(port);
- }
- QNetworkReply *NetworkAccessManager::createRequest(Operation op,
- const QNetworkRequest &request,
- QIODevice *outgoingData)
- {
- QString agentStr = QString::fromLatin1("%1/%2 (QNetworkAccessManager %3; %4; %5; %6 bit)")
- .arg(QCoreApplication::applicationName(),
- QCoreApplication::applicationVersion(),
- QLatin1String(qVersion()),
- QSysInfo::prettyProductName(),
- QLocale::system().name())
- .arg(QSysInfo::WordSize);
- QNetworkRequest req(request);
- req.setRawHeader("User-Agent", agentStr.toLatin1());
- // QHttpMultiPartIODevice *multiPart = dynamic_cast<QHttpMultiPartIODevice *>(outgoingData);
- // if (multiPart) {
- // // req.setHeader(QNetworkRequest::ContentTypeHeader, "multipart");
- // } else
- {
- req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- }
- const QUrl &url = request.url();
- const QString urlPath = url.path();
- qDebug() << url;
- //设置白名单
- if (urlPath.indexOf(RefreshToken().url) >= 0 || urlPath.indexOf(Login().url) >= 0) {
- } else {
- //需要刷新token
- // qDebug() << "RefreshToken" << urlPath;
- if (AppEvent::instance()->isRefreshToken()) {
- RefreshToken().get();
- }
- }
- //这里考虑处理 JWT 数据
- const QString &token = AppEvent::instance()->jwtToken();
- // 加个事件校验 防止token 失效导致异常
- if (!token.isEmpty()) {
- req.setRawHeader("Authorization", "Bearer " + token.toUtf8());
- }
- return QNetworkAccessManager::createRequest(op, req, outgoingData);
- }
- //
- std::optional<QJsonValue> sendRequest(QNetworkAccessManager::Operation op,
- const QString &url,
- const QByteArray &postData = QByteArray())
- {
- QNetworkAccessManager *manager = NetworkAccessManager::instance();
- manager->setTransferTimeout(3000);
- QNetworkReply *reply = nullptr;
- QUrl fullUrl(QString(base_url).append(url));
- switch (op) {
- case QNetworkAccessManager::HeadOperation:
- reply = manager->head(QNetworkRequest(fullUrl));
- break;
- case QNetworkAccessManager::GetOperation:
- reply = manager->get(QNetworkRequest(fullUrl));
- break;
- case QNetworkAccessManager::PutOperation:
- reply = manager->put(QNetworkRequest(fullUrl), postData);
- break;
- case QNetworkAccessManager::PostOperation:
- reply = manager->post(QNetworkRequest(fullUrl), postData);
- break;
- case QNetworkAccessManager::DeleteOperation:
- reply = manager->deleteResource(QNetworkRequest(fullUrl));
- break;
- case QNetworkAccessManager::CustomOperation:
- break;
- default:
- break;
- }
- if (!reply) {
- qDebug() << "sendRequest Operation error";
- }
- //等待请求结束
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
- QJsonValue data;
- if (!InterceptorsResponse(reply, data)) {
- return std::nullopt;
- }
- return data;
- }
- std::optional<QJsonValue> sendRawRequest(QNetworkAccessManager::Operation op,
- const QString &url,
- const QByteArray &postData = QByteArray())
- {
- QNetworkAccessManager *manager = NetworkAccessManager::instance();
- manager->setTransferTimeout(3000);
- QNetworkReply *reply = nullptr;
- QUrl fullUrl(QString(base_url).append(url));
- switch (op) {
- case QNetworkAccessManager::HeadOperation:
- reply = manager->head(QNetworkRequest(fullUrl));
- break;
- case QNetworkAccessManager::GetOperation:
- reply = manager->get(QNetworkRequest(fullUrl));
- break;
- case QNetworkAccessManager::PutOperation:
- reply = manager->put(QNetworkRequest(fullUrl), postData);
- break;
- case QNetworkAccessManager::PostOperation:
- reply = manager->post(QNetworkRequest(fullUrl), postData);
- break;
- case QNetworkAccessManager::DeleteOperation:
- reply = manager->deleteResource(QNetworkRequest(fullUrl));
- break;
- case QNetworkAccessManager::CustomOperation:
- break;
- default:
- break;
- }
- if (!reply) {
- qDebug() << "sendRequest Operation error";
- }
- //等待请求结束
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
- QJsonValue data;
- if (!InterceptorsResponse2(reply, data)) {
- return std::nullopt;
- }
- return data;
- }
- bool downRequest(const QString &url,
- const QByteArray &fileName,
- std::function<bool(QNetworkReply *)> callback)
- {
- QNetworkAccessManager *manager = NetworkAccessManager::instance();
- manager->setTransferTimeout(30000);
- QUrl fullUrl(QString(base_url).append(url));
- QUrlQuery query;
- query.addQueryItem("file", fileName);
- fullUrl.setQuery(query);
- QNetworkReply *reply = manager->get(QNetworkRequest(fullUrl));
- if (!reply) {
- qDebug() << "sendRequest Operation error";
- }
- //等待请求结束
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
- return callback(reply);
- }
- std::optional<QJsonValue> uploaderRequest(const QString &url, const QStringList &fileList)
- {
- QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
- // Create a file part
- for (const QString &filePath : fileList) {
- QFile *file = new QFile(filePath);
- if (!file->open(QIODevice::ReadOnly)) {
- qWarning() << "Cannot open file:" << file->errorString();
- return false;
- }
- QHttpPart filePart;
- filePart.setBodyDevice(file);
- filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
- filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
- QString("form-data; name=\"file\"; filename=\"%1\"")
- .arg(QFileInfo(filePath).fileName()));
- file->setParent(multiPart); // Ensure file is deleted with multiPart
- multiPart->append(filePart);
- }
- QNetworkAccessManager *manager = NetworkAccessManager::instance();
- QUrl fullUrl(QString(base_url).append(url));
- QNetworkReply *reply = manager->post(QNetworkRequest(fullUrl), multiPart);
- if (!reply) {
- qDebug() << "sendRequest Operation error";
- }
- //等待请求结束
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
- QJsonValue data;
- if (!InterceptorsResponse(reply, data)) {
- return std::nullopt;
- }
- return data;
- }
- } // namespace TC
|