diff --git a/example/qml-Qt6/page/T_Network.qml b/example/qml-Qt6/page/T_Network.qml index c198574e..6e4fedb3 100644 --- a/example/qml-Qt6/page/T_Network.qml +++ b/example/qml-Qt6/page/T_Network.qml @@ -1,5 +1,4 @@ import QtQuick -import Qt.labs.platform import QtQuick.Layouts import QtQuick.Window import QtQuick.Controls @@ -340,6 +339,50 @@ FluContentPage{ .go(callable) } } + FluProgressButton{ + id:btn_upload + implicitWidth: parent.width + implicitHeight: 36 + text: "Upload File" + onClicked: { + file_dialog.open() + } + } + } + } + + FluNetworkCallable{ + id:callable_upload_file + onStart: { + btn_upload.disabled = true + } + onFinish: { + btn_upload.disabled = false + } + onError: + (status,errorString,result)=>{ + btn_upload.progress = 0 + text_info.text = result + console.debug(result) + } + onSuccess: + (result)=>{ + text_info.text = result + } + onUploadProgress: + (sent,total)=>{ + btn_upload.progress = sent/total + } + } + + FileDialog { + id: file_dialog + onAccepted: { + FluNetwork.postForm("https://httpbingo.org/post") + .setRetry(0)//请求失败后不重复请求 + .add("accessToken","12345678") + .addFile("file",FluTools.toLocalPath(file_dialog.selectedFile)) + .go(callable_upload_file) } } diff --git a/src/FluNetwork.cpp b/src/FluNetwork.cpp index f1535d50..61b6dc73 100644 --- a/src/FluNetwork.cpp +++ b/src/FluNetwork.cpp @@ -15,7 +15,6 @@ NetworkCallable::NetworkCallable(QObject *parent):QObject{parent}{ } - QString NetworkParams::method2String(){ switch (_method) { case METHOD_GET: @@ -49,6 +48,18 @@ int NetworkParams::getRetry(){ return FluNetwork::getInstance()->retry(); } +DownloadParam::DownloadParam(QObject *parent) + : QObject{parent} +{ +} + +DownloadParam::DownloadParam(QString destPath,bool append,QObject *parent) + : QObject{parent} +{ + this->_destPath = destPath; + this->_append = append; +} + NetworkParams::NetworkParams(QObject *parent) : QObject{parent} { @@ -102,6 +113,11 @@ NetworkParams* NetworkParams::setCacheMode(int val){ return this; } +NetworkParams* NetworkParams::toDownload(QString destPath,bool append){ + _downloadParam = new DownloadParam(destPath,append,this); + return this; +} + QString NetworkParams::buildCacheKey(){ QJsonObject obj; obj.insert("url",_url); @@ -110,12 +126,17 @@ QString NetworkParams::buildCacheKey(){ obj.insert("query",QString(QJsonDocument::fromVariant(_queryMap).toJson(QJsonDocument::Compact))); obj.insert("param",QString(QJsonDocument::fromVariant(_paramMap).toJson(QJsonDocument::Compact))); obj.insert("header",QString(QJsonDocument::fromVariant(_headerMap).toJson(QJsonDocument::Compact))); + obj.insert("file",QString(QJsonDocument::fromVariant(_fileMap).toJson(QJsonDocument::Compact))); QByteArray data = QJsonDocument(obj).toJson(QJsonDocument::Compact); return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex(); } void NetworkParams::go(NetworkCallable* callable){ - FluNetwork::getInstance()->handle(this,callable); + if(_downloadParam){ + FluNetwork::getInstance()->handleDownload(this,callable); + }else{ + FluNetwork::getInstance()->handle(this,callable); + } } void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){ @@ -148,7 +169,7 @@ void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){ connect(manager,&QNetworkAccessManager::finished,this,[this,params,request,callable,manager,times,cacheKey](QNetworkReply *reply){ if(reply->error() != QNetworkReply::NoError && *times < params->getRetry()) { (*times)++; - sendRequest(manager,request,params,reply); + sendRequest(manager,request,params,reply,callable); } else { QString response = QString::fromUtf8(reply->readAll()); QNetworkReply::NetworkError error = reply->error(); @@ -178,7 +199,11 @@ void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){ } } }); - sendRequest(manager,request,params,reply); + sendRequest(manager,request,params,reply,callable); +} + +void FluNetwork::handleDownload(NetworkParams* params,NetworkCallable* result){ + } QString FluNetwork::readCache(const QString& key){ @@ -207,7 +232,7 @@ QString FluNetwork::getCacheFilePath(const QString& key){ return cacheDir.absoluteFilePath(key); } -void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply){ +void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,QPointer callable){ if(reply){ reply->deleteLater(); } @@ -223,8 +248,28 @@ void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest requ part.setBody(each.second.toByteArray()); multiPart->append(part); } + for (const auto& each : params->_fileMap.toStdMap()) + { + QString filePath = each.second.toString(); + QString name = each.first; + QFile *file = new QFile(filePath); + QString fileName = QFileInfo(filePath).fileName(); + file->open(QIODevice::ReadOnly); + file->setParent(multiPart); + QHttpPart part; + part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"; filename=\"%2\"").arg(name,fileName)); + part.setBodyDevice(file); + multiPart->append(part); + } reply = manager->sendCustomRequest(request,verb,multiPart); multiPart->setParent(reply); + if(!params->_fileMap.isEmpty()){ + connect(reply,&QNetworkReply::uploadProgress,reply,[callable](qint64 bytesSent, qint64 bytesTotal){ + if(!callable.isNull() && bytesSent!=0 && bytesTotal!=0){ + callable->uploadProgress(bytesSent,bytesTotal); + } + }); + } break; } case NetworkParams::TYPE_JSON:{ diff --git a/src/FluNetwork.h b/src/FluNetwork.h index f1070e9d..6d680320 100644 --- a/src/FluNetwork.h +++ b/src/FluNetwork.h @@ -10,7 +10,6 @@ #include "stdafx.h" #include "singleton.h" - class NetworkCallable : public QObject{ Q_OBJECT QML_NAMED_ELEMENT(FluNetworkCallable) @@ -21,6 +20,18 @@ public: Q_SIGNAL void error(int status,QString errorString,QString result); Q_SIGNAL void success(QString result); Q_SIGNAL void cache(QString result); + Q_SIGNAL void uploadProgress(qint64 sent, qint64 total); + Q_SIGNAL void downloadProgress(qint64 recv, qint64 total); +}; + +class DownloadParam : public QObject{ + Q_OBJECT +public: + explicit DownloadParam(QObject *parent = nullptr); + DownloadParam(QString destPath,bool append,QObject *parent = nullptr); +public: + QString _destPath; + bool _append; }; class NetworkParams : public QObject @@ -53,12 +64,14 @@ public: Q_INVOKABLE NetworkParams* setTimeout(int val); Q_INVOKABLE NetworkParams* setRetry(int val); Q_INVOKABLE NetworkParams* setCacheMode(int val); + Q_INVOKABLE NetworkParams* toDownload(QString destPath,bool append); Q_INVOKABLE void go(NetworkCallable* result); QString buildCacheKey(); QString method2String(); int getTimeout(); int getRetry(); public: + DownloadParam* _downloadParam = nullptr; Method _method; Type _type; QString _url; @@ -104,8 +117,9 @@ public: Q_INVOKABLE NetworkParams* patchJsonArray(const QString& url); Q_INVOKABLE NetworkParams* deleteJsonArray(const QString& url); void handle(NetworkParams* params,NetworkCallable* result); + void handleDownload(NetworkParams* params,NetworkCallable* result); private: - void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply); + void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,QPointer callable); void addQueryParam(QUrl* url,const QMap& params); void addHeaders(QNetworkRequest* request,const QMap& headers); void saveResponse(QString key,QString response);