From 1be9103412bc1cb2836f8d9fc00298f47d9a3045 Mon Sep 17 00:00:00 2001 From: zhuzichu Date: Thu, 31 Aug 2023 18:06:05 +0800 Subject: [PATCH 1/5] update --- src/FluTheme.cpp | 2 +- .../FluentUI/Controls/FluNavigationView.qml | 7 ++++- src/Qt5/imports/FluentUI/Controls/FluTour.qml | 26 +++++++++---------- .../FluentUI/Controls/FluNavigationView.qml | 7 ++++- src/Qt6/imports/FluentUI/Controls/FluTour.qml | 23 ++++++++-------- 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/FluTheme.cpp b/src/FluTheme.cpp index 17892aa5..343f6662 100644 --- a/src/FluTheme.cpp +++ b/src/FluTheme.cpp @@ -31,7 +31,7 @@ FluTheme::FluTheme(QObject *parent) }); primaryColor(FluColors::getInstance()->Blue()); nativeText(false); - enableAnimation(false); + enableAnimation(true); darkMode(FluThemeType::DarkMode::Light); _systemDark = systemDark(); qApp->installEventFilter(this); diff --git a/src/Qt5/imports/FluentUI/Controls/FluNavigationView.qml b/src/Qt5/imports/FluentUI/Controls/FluNavigationView.qml index 1a3f2625..24bdbaf3 100644 --- a/src/Qt5/imports/FluentUI/Controls/FluNavigationView.qml +++ b/src/Qt5/imports/FluentUI/Controls/FluNavigationView.qml @@ -752,7 +752,12 @@ Item { id:nav_stack2 anchors.fill: nav_stack clip: true - visible: FluPageType.SingleInstance === nav_stack.currentItem.launchMode + visible: { + if(!nav_stack.currentItem){ + return false + } + return FluPageType.SingleInstance === nav_stack.currentItem.launchMode + } } function navStack(){ return nav_stack diff --git a/src/Qt5/imports/FluentUI/Controls/FluTour.qml b/src/Qt5/imports/FluentUI/Controls/FluTour.qml index 4f4bb4f3..4287548f 100644 --- a/src/Qt5/imports/FluentUI/Controls/FluTour.qml +++ b/src/Qt5/imports/FluentUI/Controls/FluTour.qml @@ -96,24 +96,22 @@ Popup{ ctx.globalCompositeOperation = 'destination-out' ctx.fillStyle = 'black' var rect = Qt.rect(d.pos.x-control.targetMargins,d.pos.y-control.targetMargins, d.target.width+control.targetMargins*2, d.target.height+control.targetMargins*2) - ctx.fillRect(rect.x,rect.y,rect.width,rect.height) + drawRoundedRect(rect,2,ctx) ctx.restore() } - //Todo function drawRoundedRect(rect, r, ctx) { - var ptA = Qt.point(rect.x + r, rect.y) - var ptB = Qt.point(rect.x + rect.width, rect.y) - var ptC = Qt.point(rect.x + rect.width, rect.y + rect.height) - var ptD = Qt.point(rect.x, rect.y + rect.height) - var ptE = Qt.point(rect.x, rect.y) - ctx.beginPath() - ctx.moveTo(ptA.x, ptA.y) - ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r) - ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r) - ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r) - ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r) + ctx.beginPath(); + ctx.moveTo(rect.x + r, rect.y); + ctx.lineTo(rect.x + rect.width - r, rect.y); + ctx.arcTo(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + r, r); + ctx.lineTo(rect.x + rect.width, rect.y + rect.height - r); + ctx.arcTo(rect.x + rect.width, rect.y + rect.height, rect.x + rect.width - r, rect.y + rect.height, r); + ctx.lineTo(rect.x + r, rect.y + rect.height); + ctx.arcTo(rect.x, rect.y + rect.height, rect.x, rect.y + rect.height - r, r); + ctx.lineTo(rect.x, rect.y + r); + ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r); + ctx.closePath(); ctx.fill() - ctx.closePath() } } FluArea{ diff --git a/src/Qt6/imports/FluentUI/Controls/FluNavigationView.qml b/src/Qt6/imports/FluentUI/Controls/FluNavigationView.qml index 56490cbe..682ee717 100644 --- a/src/Qt6/imports/FluentUI/Controls/FluNavigationView.qml +++ b/src/Qt6/imports/FluentUI/Controls/FluNavigationView.qml @@ -753,7 +753,12 @@ Item { id:nav_stack2 anchors.fill: nav_stack clip: true - visible: FluPageType.SingleInstance === nav_stack.currentItem.launchMode + visible: { + if(!nav_stack.currentItem){ + return false + } + return FluPageType.SingleInstance === nav_stack.currentItem.launchMode + } } function navStack(){ return nav_stack diff --git a/src/Qt6/imports/FluentUI/Controls/FluTour.qml b/src/Qt6/imports/FluentUI/Controls/FluTour.qml index 27768f5b..b92732a6 100644 --- a/src/Qt6/imports/FluentUI/Controls/FluTour.qml +++ b/src/Qt6/imports/FluentUI/Controls/FluTour.qml @@ -89,19 +89,18 @@ Popup{ ctx.restore() } function drawRoundedRect(rect, r, ctx) { - var ptA = Qt.point(rect.x + r, rect.y) - var ptB = Qt.point(rect.x + rect.width, rect.y) - var ptC = Qt.point(rect.x + rect.width, rect.y + rect.height) - var ptD = Qt.point(rect.x, rect.y + rect.height) - var ptE = Qt.point(rect.x, rect.y) - ctx.beginPath() - ctx.moveTo(ptA.x, ptA.y) - ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r) - ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r) - ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r) - ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r) + ctx.beginPath(); + ctx.moveTo(rect.x + r, rect.y); + ctx.lineTo(rect.x + rect.width - r, rect.y); + ctx.arcTo(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + r, r); + ctx.lineTo(rect.x + rect.width, rect.y + rect.height - r); + ctx.arcTo(rect.x + rect.width, rect.y + rect.height, rect.x + rect.width - r, rect.y + rect.height, r); + ctx.lineTo(rect.x + r, rect.y + rect.height); + ctx.arcTo(rect.x, rect.y + rect.height, rect.x, rect.y + rect.height - r, r); + ctx.lineTo(rect.x, rect.y + r); + ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r); + ctx.closePath(); ctx.fill() - ctx.closePath() } } FluArea{ From e29150ca52dd550ef0e9c70d32917ec6e0fe91ca Mon Sep 17 00:00:00 2001 From: huangkangfa <1664724081@qq.com> Date: Fri, 1 Sep 2023 09:37:07 +0800 Subject: [PATCH 2/5] update THIRD_PARTY_COPYRIGHT --- THIRD_PARTY_COPYRIGHT.txt | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/THIRD_PARTY_COPYRIGHT.txt b/THIRD_PARTY_COPYRIGHT.txt index 851e19bf..e7b2da58 100644 --- a/THIRD_PARTY_COPYRIGHT.txt +++ b/THIRD_PARTY_COPYRIGHT.txt @@ -262,4 +262,29 @@ zxing-cpp distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. + +************************************************************************************ +ChartJs2QML + +MIT License + +Copyright (c) 2020 ChartJs2QML contributors (starting with Elypson, Michael A. Voelkel, https://github.com/Elypson) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 08c4f784546fe84ba4917e3e5083e60cb1dc8619 Mon Sep 17 00:00:00 2001 From: zhuzichu Date: Fri, 1 Sep 2023 18:38:21 +0800 Subject: [PATCH 3/5] update --- src/Def.h | 18 ++++++++++ src/FluHttp.cpp | 90 ++++++++++++++++++++++++++++++++++-------------- src/FluHttp.h | 8 +++-- src/FluTools.cpp | 17 +++++++++ src/FluTools.h | 21 +++++++++++ 5 files changed, 127 insertions(+), 27 deletions(-) diff --git a/src/Def.h b/src/Def.h index a77e8fd2..812adb82 100644 --- a/src/Def.h +++ b/src/Def.h @@ -4,6 +4,24 @@ #include #include +namespace FluHttpType { +Q_NAMESPACE +enum CacheMode { + /** 不使用缓存 */ + NoCache = 0x0000, + + /** 请求网络失败后,读取缓存 */ + RequestFailedReadCache = 0x0001, + + /** 如果缓存不存在才请求网络,否则使用缓存 */ + IfNoneCacheRequest = 0x0002, + + /** 先使用缓存,不管是否存在,仍然请求网络 */ + FirstCacheThenRequest = 0x0004, +}; +Q_ENUM_NS(CacheMode) +QML_NAMED_ELEMENT(FluHttpType) +} namespace FluScreenshotType { Q_NAMESPACE diff --git a/src/FluHttp.cpp b/src/FluHttp.cpp index 7ada2796..2f9a8fda 100644 --- a/src/FluHttp.cpp +++ b/src/FluHttp.cpp @@ -6,14 +6,20 @@ #include #include #include +#include +#include +#include "Def.h" #include "MainThread.h" #include "FluApp.h" +#include "FluTools.h" FluHttp::FluHttp(QObject *parent) : QObject{parent} { retry(3); timeout(15000); + cacheMode(FluHttpType::CacheMode::RequestFailedReadCache); + cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/httpcache"); } FluHttp::~FluHttp(){ @@ -21,7 +27,7 @@ FluHttp::~FluHttp(){ } void FluHttp::cancel(){ - foreach (QPointer item, _cache) { + foreach (QPointer item, _cacheReply) { if(item){ item->abort(); } @@ -29,11 +35,12 @@ void FluHttp::cancel(){ } void FluHttp::handleReply(QNetworkReply* reply){ - _cache.append(reply); + _cacheReply.append(reply); } void FluHttp::post(QString url,QJSValue callable,QMap params,QMap headers){ - QMap data = invokeIntercept(params,headers,"post").toMap(); + auto requestMap = toRequest(url,params,headers,"post"); + QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); for (int i = 0; i < retry(); ++i) { @@ -55,7 +62,7 @@ void FluHttp::post(QString url,QJSValue callable,QMap params, } QEventLoop loop; QNetworkReply* reply = manager.post(request,&multiPart); - _cache.append(reply); + _cacheReply.append(reply); connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){ loop.quit(); }); @@ -64,10 +71,11 @@ void FluHttp::post(QString url,QJSValue callable,QMap params, int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QString errorString = reply->errorString(); bool isSuccess = reply->error() == QNetworkReply::NoError; - _cache.removeOne(reply); + _cacheReply.removeOne(reply); reply->deleteLater(); reply = nullptr; if (isSuccess) { + handleCache(requestMap,result); onSuccess(callable,result); break; }else{ @@ -81,7 +89,8 @@ void FluHttp::post(QString url,QJSValue callable,QMap params, } void FluHttp::postString(QString url,QJSValue callable,QString params,QMap headers){ - QMap data = invokeIntercept(params,headers,"postString").toMap(); + auto requestMap = toRequest(url,params,headers,"post"); + QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); for (int i = 0; i < retry(); ++i) { @@ -94,7 +103,7 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QMapattribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QString errorString = reply->errorString(); bool isSuccess = reply->error() == QNetworkReply::NoError; - _cache.removeOne(reply); + _cacheReply.removeOne(reply); reply->deleteLater(); reply = nullptr; if (isSuccess) { + handleCache(requestMap,result); onSuccess(callable,result); break; }else{ @@ -120,7 +130,8 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QMap params,QMap headers){ - QMap data = invokeIntercept(params,headers,"postJson").toMap(); + auto requestMap = toRequest(url,params,headers,"post"); + QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); for (int i = 0; i < retry(); ++i) { @@ -133,7 +144,7 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap par request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); QEventLoop loop; QNetworkReply* reply = manager.post(request,QJsonDocument::fromVariant(data["params"]).toJson()); - _cache.append(reply); + _cacheReply.append(reply); connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){ loop.quit(); }); @@ -142,10 +153,11 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap par int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QString errorString = reply->errorString(); bool isSuccess = reply->error() == QNetworkReply::NoError; - _cache.removeOne(reply); + _cacheReply.removeOne(reply); reply->deleteLater(); reply = nullptr; if (isSuccess) { + handleCache(requestMap,result); onSuccess(callable,result); break; }else{ @@ -159,7 +171,8 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap par } void FluHttp::get(QString url,QJSValue callable,QMap params,QMap headers){ - QMap data = invokeIntercept(params,headers,"get").toMap(); + auto requestMap = toRequest(url,params,headers,"post"); + QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ for (int i = 0; i < retry(); ++i) { onStart(callable); @@ -171,7 +184,7 @@ void FluHttp::get(QString url,QJSValue callable,QMap params,Q addHeaders(&request,data["headers"].toMap()); QEventLoop loop; QNetworkReply* reply = manager.get(request); - _cache.append(reply); + _cacheReply.append(reply); connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){ loop.quit(); }); @@ -180,10 +193,11 @@ void FluHttp::get(QString url,QJSValue callable,QMap params,Q int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QString errorString = reply->errorString(); bool isSuccess = reply->error() == QNetworkReply::NoError; - _cache.removeOne(reply); + _cacheReply.removeOne(reply); reply->deleteLater(); reply = nullptr; if (isSuccess) { + handleCache(requestMap,result); onSuccess(callable,result); break; }else{ @@ -197,7 +211,8 @@ void FluHttp::get(QString url,QJSValue callable,QMap params,Q } void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap params,QMap headers){ - QMap data = invokeIntercept(params,headers,"download").toMap(); + auto requestMap = toRequest(url,params,headers,"post"); + QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); QNetworkAccessManager manager; @@ -218,7 +233,7 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap reply = manager.get(request); - _cache.append(reply); + _cacheReply.append(reply); connect(reply,&QNetworkReply::downloadProgress,this,[=](qint64 bytesReceived, qint64 bytesTotal){ onDownloadProgress(callable,bytesReceived,bytesTotal); }); @@ -229,7 +244,7 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMapattribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),""); } - _cache.removeOne(reply); + _cacheReply.removeOne(reply); reply->deleteLater(); reply = nullptr; onFinish(callable); @@ -237,7 +252,8 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap params,QMap headers){ - QMap data = invokeIntercept(params,headers,"upload").toMap(); + auto requestMap = toRequest(url,params,headers,"post"); + QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); QNetworkAccessManager manager; @@ -262,7 +278,7 @@ void FluHttp::upload(QString url,QJSValue callable,QMap param } QEventLoop loop; QNetworkReply* reply = manager.post(request,&multiPart); - _cache.append(reply); + _cacheReply.append(reply); connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){ loop.quit(); }); @@ -274,7 +290,7 @@ void FluHttp::upload(QString url,QJSValue callable,QMap param int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QString errorString = reply->errorString(); bool isSuccess = reply->error() == QNetworkReply::NoError; - _cache.removeOne(reply); + _cacheReply.removeOne(reply); reply->deleteLater(); reply = nullptr; if (isSuccess) { @@ -286,17 +302,22 @@ void FluHttp::upload(QString url,QJSValue callable,QMap param }); } -QVariant FluHttp::invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method){ - QMap requet = { +QMap FluHttp::toRequest(const QString& url,const QVariant& params,const QVariant& headers,const QString& method){ + QMap request = { + {"url",url}, {"params",params}, {"headers",headers}, - {"method",method} + {"method","upload"} }; + return request; +} + +QVariant FluHttp::invokeIntercept(QMap request){ if(!FluApp::getInstance()->httpInterceptor()){ - return requet; + return request; } QVariant target; - QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, requet)); + QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, request)); return target; } @@ -371,3 +392,22 @@ void FluHttp::onUploadProgress(const QJSValue& callable,qint64 sent, qint64 tota onUploadProgress.call(args); }); } + +void FluHttp::handleCache(QMap request,const QString& result){ + if(_cacheMode==FluHttpType::CacheMode::NoCache){ + return; + } + auto fileName = FluTools::getInstance()->md5(QJsonDocument::fromVariant(QVariant(request)).toJson()); + QDir dir = _cacheDir; + if (!dir.exists(_cacheDir)){ + dir.mkpath(_cacheDir); + } + auto filePath = _cacheDir+"/"+fileName; + QSharedPointer file(new QFile(filePath)); + QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate; + if (!file->open(mode)) + { + return; + } + file->write(FluTools::getInstance()->toBase64(result).toUtf8()); +} diff --git a/src/FluHttp.h b/src/FluHttp.h index c003c848..dacfc2be 100644 --- a/src/FluHttp.h +++ b/src/FluHttp.h @@ -12,9 +12,12 @@ class FluHttp : public QObject Q_OBJECT Q_PROPERTY_AUTO(int,retry); Q_PROPERTY_AUTO(int,timeout) + Q_PROPERTY_AUTO(int,cacheMode); + Q_PROPERTY_AUTO(QString,cacheDir); QML_NAMED_ELEMENT(FluHttp) private: - QVariant invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method); + QVariant invokeIntercept(QMap request); + QMap toRequest(const QString& url,const QVariant& params,const QVariant& headers,const QString& method); void handleReply(QNetworkReply* reply); void addQueryParam(QUrl* url,const QMap& params); void addHeaders(QNetworkRequest* request,const QMap& params); @@ -24,6 +27,7 @@ private: void onSuccess(const QJSValue& callable,QString result); void onDownloadProgress(const QJSValue& callable,qint64 recv, qint64 total); void onUploadProgress(const QJSValue& callable,qint64 recv, qint64 total); + void handleCache(QMap request, const QString& result); public: explicit FluHttp(QObject *parent = nullptr); ~FluHttp(); @@ -36,7 +40,7 @@ public: Q_INVOKABLE void upload(QString url,QJSValue callable,QMap params = {},QMap headers = {}); Q_INVOKABLE void cancel(); private: - QList> _cache; + QList> _cacheReply; }; #endif // FLUHTTP_H diff --git a/src/FluTools.cpp b/src/FluTools.cpp index 0decf35d..a09e585c 100644 --- a/src/FluTools.cpp +++ b/src/FluTools.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include FluTools* FluTools::m_instance = nullptr; @@ -128,3 +129,19 @@ QUrl FluTools::getUrlByFilePath(const QString& path){ QColor FluTools::colorAlpha(const QColor& color,qreal alpha){ return QColor(color.red(),color.green(),color.blue(),255*alpha); } + +QString FluTools::md5(QString text) +{ + return QCryptographicHash::hash(text.toUtf8(), QCryptographicHash::Md5).toHex(); +} + +QString FluTools::toBase64(QString text) +{ + return text.toUtf8().toBase64(); +} + +QString FluTools::fromBase64(QString text) +{ + return QByteArray::fromBase64(text.toUtf8()); +} + diff --git a/src/FluTools.h b/src/FluTools.h index 1da83f5a..bb2a525b 100644 --- a/src/FluTools.h +++ b/src/FluTools.h @@ -144,6 +144,27 @@ public: */ Q_INVOKABLE QColor colorAlpha(const QColor&,qreal alpha); + /** + * @brief md5 + * @param text + * @return + */ + QString md5(QString text); + + /** + * @brief toBase64 + * @param text + * @return + */ + QString toBase64(QString text); + + /** + * @brief fromBase64 + * @param text + * @return + */ + QString fromBase64(QString text); + }; #endif // FLUTOOLS_H From ba32c9213393e54970396a2fef6aaddb74588725 Mon Sep 17 00:00:00 2001 From: zhuzichu Date: Mon, 4 Sep 2023 11:29:15 +0800 Subject: [PATCH 4/5] update --- example/qml-Qt6/page/T_Http.qml | 16 ++++++ src/FluHttp.cpp | 99 +++++++++++++++++++++++++++++---- src/FluHttp.h | 4 ++ 3 files changed, 108 insertions(+), 11 deletions(-) diff --git a/example/qml-Qt6/page/T_Http.qml b/example/qml-Qt6/page/T_Http.qml index 58942ade..4c1d03a0 100644 --- a/example/qml-Qt6/page/T_Http.qml +++ b/example/qml-Qt6/page/T_Http.qml @@ -47,6 +47,10 @@ FluContentPage{ text_info.text = result console.debug(result) } + callable.onCache = function(result){ + text_info.text = result + console.debug(result) + } callable.onError = function(status,errorString){ console.debug(status+";"+errorString) } @@ -69,6 +73,10 @@ FluContentPage{ text_info.text = result console.debug(result) } + callable.onCache = function(result){ + text_info.text = result + console.debug(result) + } callable.onError = function(status,errorString){ console.debug(status+";"+errorString) } @@ -95,6 +103,10 @@ FluContentPage{ text_info.text = result console.debug(result) } + callable.onCache = function(result){ + text_info.text = result + console.debug(result) + } callable.onError = function(status,errorString){ console.debug(status+";"+errorString) } @@ -121,6 +133,10 @@ FluContentPage{ text_info.text = result console.debug(result) } + callable.onCache = function(result){ + text_info.text = result + console.debug(result) + } callable.onError = function(status,errorString){ console.debug(status+";"+errorString) } diff --git a/src/FluHttp.cpp b/src/FluHttp.cpp index 2f9a8fda..e8ab346d 100644 --- a/src/FluHttp.cpp +++ b/src/FluHttp.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "Def.h" #include "MainThread.h" @@ -18,7 +19,7 @@ FluHttp::FluHttp(QObject *parent) { retry(3); timeout(15000); - cacheMode(FluHttpType::CacheMode::RequestFailedReadCache); + cacheMode(FluHttpType::CacheMode::NoCache); cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/httpcache"); } @@ -43,6 +44,14 @@ void FluHttp::post(QString url,QJSValue callable,QMap params, QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ + onCache(callable,readCache(requestMap)); + onFinish(callable); + return; + } + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ + onCache(callable,readCache(requestMap)); + } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; manager.setTransferTimeout(timeout()); @@ -80,6 +89,9 @@ void FluHttp::post(QString url,QJSValue callable,QMap params, break; }else{ if(i == retry()-1){ + if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){ + onCache(callable,readCache(requestMap)); + } onError(callable,status,errorString,result); } } @@ -89,10 +101,18 @@ void FluHttp::post(QString url,QJSValue callable,QMap params, } void FluHttp::postString(QString url,QJSValue callable,QString params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"post"); + auto requestMap = toRequest(url,params,headers,"postString"); QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ + onCache(callable,readCache(requestMap)); + onFinish(callable); + return; + } + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ + onCache(callable,readCache(requestMap)); + } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; manager.setTransferTimeout(timeout()); @@ -121,6 +141,9 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"post"); + auto requestMap = toRequest(url,params,headers,"postJson"); QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ + onCache(callable,readCache(requestMap)); + onFinish(callable); + return; + } + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ + onCache(callable,readCache(requestMap)); + } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; manager.setTransferTimeout(timeout()); @@ -162,6 +193,9 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap par break; }else{ if(i == retry()-1){ + if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){ + onCache(callable,readCache(requestMap)); + } onError(callable,status,errorString,result); } } @@ -171,11 +205,19 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap par } void FluHttp::get(QString url,QJSValue callable,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"post"); + auto requestMap = toRequest(url,params,headers,"get"); QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ + onStart(callable); + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ + onCache(callable,readCache(requestMap)); + } + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ + onCache(callable,readCache(requestMap)); + onFinish(callable); + return; + } for (int i = 0; i < retry(); ++i) { - onStart(callable); QNetworkAccessManager manager; manager.setTransferTimeout(timeout()); QUrl _url(url); @@ -202,6 +244,9 @@ void FluHttp::get(QString url,QJSValue callable,QMap params,Q break; }else{ if(i == retry()-1){ + if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){ + onCache(callable,readCache(requestMap)); + } onError(callable,status,errorString,result); } } @@ -211,7 +256,7 @@ void FluHttp::get(QString url,QJSValue callable,QMap params,Q } void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"post"); + auto requestMap = toRequest(url,params,headers,"download"); QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); @@ -252,7 +297,7 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"post"); + auto requestMap = toRequest(url,params,headers,"upload"); QMap data = invokeIntercept(requestMap).toMap(); QThreadPool::globalInstance()->start([=](){ onStart(callable); @@ -307,7 +352,7 @@ QMap FluHttp::toRequest(const QString& url,const QVariant& pa {"url",url}, {"params",params}, {"headers",headers}, - {"method","upload"} + {"method",method} }; return request; } @@ -373,6 +418,15 @@ void FluHttp::onSuccess(const QJSValue& callable,QString result){ }); } +void FluHttp::onCache(const QJSValue& callable,QString result){ + MainThread::post([=](){ + QJSValueList args; + args< request,const QString& result){ - if(_cacheMode==FluHttpType::CacheMode::NoCache){ - return; +QString FluHttp::readCache(const QMap& request){ + auto filePath = getCacheFilePath(request); + QString result; + QFile file(filePath); + if(!file.exists()){ + return result; } + if (file.open(QIODevice::ReadOnly)) { + QTextStream stream(&file); + result = FluTools::getInstance()->fromBase64(stream.readAll().toUtf8()); + } + return result; +} + +bool FluHttp::cacheExists(const QMap& request){ + return QFile(getCacheFilePath(request)).exists(); +} + +QString FluHttp::getCacheFilePath(const QMap& request){ auto fileName = FluTools::getInstance()->md5(QJsonDocument::fromVariant(QVariant(request)).toJson()); QDir dir = _cacheDir; if (!dir.exists(_cacheDir)){ dir.mkpath(_cacheDir); } auto filePath = _cacheDir+"/"+fileName; + return filePath; +} + +void FluHttp::handleCache(QMap request,const QString& result){ + if(_cacheMode==FluHttpType::CacheMode::NoCache){ + return; + } + auto filePath = getCacheFilePath(request); QSharedPointer file(new QFile(filePath)); QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate; if (!file->open(mode)) diff --git a/src/FluHttp.h b/src/FluHttp.h index dacfc2be..0747aaa4 100644 --- a/src/FluHttp.h +++ b/src/FluHttp.h @@ -25,9 +25,13 @@ private: void onFinish(const QJSValue& callable); void onError(const QJSValue& callable,int status,QString errorString,QString result); void onSuccess(const QJSValue& callable,QString result); + void onCache(const QJSValue& callable,QString result); void onDownloadProgress(const QJSValue& callable,qint64 recv, qint64 total); void onUploadProgress(const QJSValue& callable,qint64 recv, qint64 total); void handleCache(QMap request, const QString& result); + QString readCache(const QMap& request); + bool cacheExists(const QMap& request); + QString getCacheFilePath(const QMap& request); public: explicit FluHttp(QObject *parent = nullptr); ~FluHttp(); From f7b7d30a6f2e329ce0dca2e63f4ebf5ad43bf3da Mon Sep 17 00:00:00 2001 From: zhuzichu Date: Mon, 4 Sep 2023 18:37:55 +0800 Subject: [PATCH 5/5] update --- example/qml-Qt6/page/T_Http.qml | 268 ++++++++++++++------------ example/qml-Qt6/window/MainWindow.qml | 38 ++-- example/qml/page/T_Http.qml | 252 ++++++++++++++---------- example/qml/window/MainWindow.qml | 37 ++-- src/FluHttp.cpp | 195 +++++++------------ src/FluHttp.h | 34 ++-- src/FluTools.cpp | 5 + src/FluTools.h | 14 +- src/fluentuiplugin.cpp | 1 + 9 files changed, 447 insertions(+), 397 deletions(-) diff --git a/example/qml-Qt6/page/T_Http.qml b/example/qml-Qt6/page/T_Http.qml index 4c1d03a0..19ae6d9e 100644 --- a/example/qml-Qt6/page/T_Http.qml +++ b/example/qml-Qt6/page/T_Http.qml @@ -10,14 +10,57 @@ import "qrc:///example/qml/component" FluContentPage{ title:"Http" + property string cacheDirPath: FluTools.getApplicationDirPath() + "/cache/http" FluHttp{ id:http } + FluHttp{ + id:http_cache_ifnonecacherequest + cacheMode:FluHttpType.IfNoneCacheRequest + cacheDir:cacheDirPath + } + + FluHttp{ + id:http_cache_requestfailedreadcache + cacheMode:FluHttpType.RequestFailedReadCache + cacheDir:cacheDirPath + } + + FluHttp{ + id:http_cache_firstcachethenrequest + cacheMode:FluHttpType.FirstCacheThenRequest + cacheDir:cacheDirPath + } + + HttpCallable{ + id:callable + onStart: { + showLoading() + } + onFinish: { + hideLoading() + } + onError: + (status,errorString,result)=>{ + console.debug(status+";"+errorString+";"+result) + } + onSuccess: + (result)=>{ + text_info.text = result + console.debug(result) + } + onCache: + (result)=>{ + text_info.text = result + console.debug(result) + } + } + Flickable{ id:layout_flick - width: 160 + width: 200 clip: true anchors{ top: parent.top @@ -36,24 +79,6 @@ FluContentPage{ implicitHeight: 36 text: "Get请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onCache = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } http.get("https://httpbingo.org/get",callable) } } @@ -62,24 +87,6 @@ FluContentPage{ implicitHeight: 36 text: "Post表单请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onCache = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } var param = {} param.custname = "朱子楚" param.custtel = "1234567890" @@ -92,24 +99,6 @@ FluContentPage{ implicitHeight: 36 text: "Post Json请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onCache = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } var param = {} param.custname = "朱子楚" param.custtel = "1234567890" @@ -122,24 +111,6 @@ FluContentPage{ implicitHeight: 36 text: "Post String请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onCache = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } var param = "我命由我不由天" http.postString("https://httpbingo.org/post",callable,param) } @@ -162,9 +133,86 @@ FluContentPage{ file_dialog.open() } } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "FirstCacheThenRequest缓存" + onClicked: { + var param = {} + param.cacheMode = "FirstCacheThenRequest" + http_cache_firstcachethenrequest.post("https://httpbingo.org/post",callable,param) + } + } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "RequestFailedReadCache缓存" + onClicked: { + var param = {} + param.cacheMode = "RequestFailedReadCache" + http_cache_requestfailedreadcache.post("https://httpbingo.org/post",callable,param) + } + } + + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "IfNoneCacheRequest缓存" + onClicked: { + var param = {} + param.cacheMode = "IfNoneCacheRequest" + http_cache_ifnonecacherequest.post("https://httpbingo.org/post",callable,param) + } + } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "删除缓存" + onClicked: { + console.debug(FluTools.removeDir(cacheDirPath)) + } + } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "清空右边数据" + onClicked: { + text_info.text = "" + } + } } } + HttpCallable{ + id:callable_upload + onStart: { + btn_upload.disabled = true + } + onFinish: { + btn_upload.disabled = false + btn_upload.text = "上传文件" + layout_upload_file_size.visible = false + text_upload_file_size.text = "" + } + onError: + (status,errorString,result)=>{ + text_info.text = result + console.debug(result) + } + onSuccess: + (result)=>{ + text_info.text = result + } + onUploadProgress: + (sent,total)=>{ + var locale = Qt.locale() + var precent = (sent/total * 100).toFixed(0) + "%" + btn_upload.text = "上传中..."+precent + text_upload_file_size.text = "%1/%2".arg(locale.formattedDataSize(sent)).arg(locale.formattedDataSize(total)) + layout_upload_file_size.visible = true + } + } + FileDialog { id: file_dialog onAccepted: { @@ -175,65 +223,46 @@ FluContentPage{ var filePath = FluTools.toLocalPath(fileUrl) param[fileName] = filePath } - console.debug(JSON.stringify(param)) - var callable = {} - callable.onStart = function(){ - btn_upload.disabled = true - } - callable.onFinish = function(){ - btn_upload.disabled = false - btn_upload.text = "上传文件" - layout_upload_file_size.visible = false - text_upload_file_size.text = "" - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString,result){ - text_info.text = result - console.debug(result) - } - callable.onUploadProgress = function(sent,total){ - var locale = Qt.locale() - var precent = (sent/total * 100).toFixed(0) + "%" - btn_upload.text = "上传中..."+precent - text_upload_file_size.text = "%1/%2".arg(locale.formattedDataSize(sent)).arg(locale.formattedDataSize(total)) - layout_upload_file_size.visible = true - } - http.upload("https://httpbingo.org/post",callable,param) + http.upload("https://httpbingo.org/post",callable_upload,param) } } - FolderDialog { - id: folder_dialog - currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0] - onAccepted: { - var callable = {} - callable.onStart = function(){ - btn_download.disabled = true + HttpCallable{ + id:callable_download + onStart: { + btn_download.disabled = true + } + onFinish: { + btn_download.disabled = false + btn_download.text = "下载文件" + layout_download_file_size.visible = false + text_download_file_size.text = "" + } + onError: + (status,errorString,result)=>{ + showError(errorString) + console.debug(status+";"+errorString+";"+result) } - callable.onFinish = function(){ - btn_download.disabled = false - btn_download.text = "下载文件" - layout_download_file_size.visible = false - text_download_file_size.text = "" - } - callable.onSuccess = function(result){ + onSuccess: + (result)=>{ showSuccess(result) } - callable.onError = function(status,errorString){ - showError(errorString) - } - callable.onDownloadProgress = function(recv,total){ + onDownloadProgress: + (recv,total)=>{ var locale = Qt.locale() var precent = (recv/total * 100).toFixed(0) + "%" btn_download.text = "下载中..."+precent text_download_file_size.text = "%1/%2".arg(locale.formattedDataSize(recv)).arg(locale.formattedDataSize(total)) layout_download_file_size.visible = true } + } + + FolderDialog { + id: folder_dialog + currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0] + onAccepted: { var path = FluTools.toLocalPath(currentFolder)+ "/big_buck_bunny.mp4" - http.download("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",callable,path) + http.download("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",callable_download,path) } } @@ -277,7 +306,6 @@ FluContentPage{ } } - FluRectangle{ id:layout_upload_file_size radius: [4,4,4,4] diff --git a/example/qml-Qt6/window/MainWindow.qml b/example/qml-Qt6/window/MainWindow.qml index 89c6a9c1..a0159a4c 100644 --- a/example/qml-Qt6/window/MainWindow.qml +++ b/example/qml-Qt6/window/MainWindow.qml @@ -309,27 +309,33 @@ CustomWindow { } } - function checkUpdate(){ - var callable = {} - callable.onStart = function(){ + + HttpCallable{ + id:callable + onStart: { console.debug("satrt check update...") } - callable.onFinish = function(){ + onFinish: { console.debug("check update finish") } - callable.onSuccess = function(result){ - var data = JSON.parse(result) - console.debug("current version "+appInfo.version) - console.debug("new version "+data.tag_name) - if(data.tag_name !== appInfo.version){ - dialog_update.newVerson = data.tag_name - dialog_update.body = data.body - dialog_update.open() + onSuccess: + (result)=>{ + var data = JSON.parse(result) + console.debug("current version "+appInfo.version) + console.debug("new version "+data.tag_name) + if(data.tag_name !== appInfo.version){ + dialog_update.newVerson = data.tag_name + dialog_update.body = data.body + dialog_update.open() + } } - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } + onError: + (status,errorString)=>{ + console.debug(status+";"+errorString) + } + } + + function checkUpdate(){ http.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest",callable) } diff --git a/example/qml/page/T_Http.qml b/example/qml/page/T_Http.qml index 0a1c5e66..88ce5eb7 100644 --- a/example/qml/page/T_Http.qml +++ b/example/qml/page/T_Http.qml @@ -11,14 +11,57 @@ import "../component" FluContentPage{ title:"Http" + property string cacheDirPath: FluTools.getApplicationDirPath() + "/cache/http" FluHttp{ id:http } + FluHttp{ + id:http_cache_ifnonecacherequest + cacheMode:FluHttpType.IfNoneCacheRequest + cacheDir:cacheDirPath + } + + FluHttp{ + id:http_cache_requestfailedreadcache + cacheMode:FluHttpType.RequestFailedReadCache + cacheDir:cacheDirPath + } + + FluHttp{ + id:http_cache_firstcachethenrequest + cacheMode:FluHttpType.FirstCacheThenRequest + cacheDir:cacheDirPath + } + + HttpCallable{ + id:callable + onStart: { + showLoading() + } + onFinish: { + hideLoading() + } + onError: + (status,errorString,result)=>{ + console.debug(status+";"+errorString+";"+result) + } + onSuccess: + (result)=>{ + text_info.text = result + console.debug(result) + } + onCache: + (result)=>{ + text_info.text = result + console.debug(result) + } + } + Flickable{ id:layout_flick - width: 160 + width: 200 clip: true anchors{ top: parent.top @@ -37,20 +80,6 @@ FluContentPage{ implicitHeight: 36 text: "Get请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } http.get("https://httpbingo.org/get",callable) } } @@ -59,20 +88,6 @@ FluContentPage{ implicitHeight: 36 text: "Post表单请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } var param = {} param.custname = "朱子楚" param.custtel = "1234567890" @@ -85,20 +100,6 @@ FluContentPage{ implicitHeight: 36 text: "Post Json请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } var param = {} param.custname = "朱子楚" param.custtel = "1234567890" @@ -111,20 +112,6 @@ FluContentPage{ implicitHeight: 36 text: "Post String请求" onClicked: { - var callable = {} - callable.onStart = function(){ - showLoading() - } - callable.onFinish = function(){ - hideLoading() - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } var param = "我命由我不由天" http.postString("https://httpbingo.org/post",callable,param) } @@ -147,9 +134,86 @@ FluContentPage{ file_dialog.open() } } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "FirstCacheThenRequest缓存" + onClicked: { + var param = {} + param.cacheMode = "FirstCacheThenRequest" + http_cache_firstcachethenrequest.post("https://httpbingo.org/post",callable,param) + } + } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "RequestFailedReadCache缓存" + onClicked: { + var param = {} + param.cacheMode = "RequestFailedReadCache" + http_cache_requestfailedreadcache.post("https://httpbingo.org/post",callable,param) + } + } + + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "IfNoneCacheRequest缓存" + onClicked: { + var param = {} + param.cacheMode = "IfNoneCacheRequest" + http_cache_ifnonecacherequest.post("https://httpbingo.org/post",callable,param) + } + } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "删除缓存" + onClicked: { + console.debug(FluTools.removeDir(cacheDirPath)) + } + } + FluButton{ + implicitWidth: parent.width + implicitHeight: 36 + text: "清空右边数据" + onClicked: { + text_info.text = "" + } + } } } + HttpCallable{ + id:callable_upload + onStart: { + btn_upload.disabled = true + } + onFinish: { + btn_upload.disabled = false + btn_upload.text = "上传文件" + layout_upload_file_size.visible = false + text_upload_file_size.text = "" + } + onError: + (status,errorString,result)=>{ + text_info.text = result + console.debug(result) + } + onSuccess: + (result)=>{ + text_info.text = result + } + onUploadProgress: + (sent,total)=>{ + var locale = Qt.locale() + var precent = (sent/total * 100).toFixed(0) + "%" + btn_upload.text = "上传中..."+precent + text_upload_file_size.text = "%1/%2".arg(locale.formattedDataSize(sent)).arg(locale.formattedDataSize(total)) + layout_upload_file_size.visible = true + } + } + FileDialog { id: file_dialog onAccepted: { @@ -160,65 +224,46 @@ FluContentPage{ var filePath = FluTools.toLocalPath(fileUrl) param[fileName] = filePath } - console.debug(JSON.stringify(param)) - var callable = {} - callable.onStart = function(){ - btn_upload.disabled = true - } - callable.onFinish = function(){ - btn_upload.disabled = false - btn_upload.text = "上传文件" - layout_upload_file_size.visible = false - text_upload_file_size.text = "" - } - callable.onSuccess = function(result){ - text_info.text = result - console.debug(result) - } - callable.onError = function(status,errorString,result){ - text_info.text = result - console.debug(result) - } - callable.onUploadProgress = function(sent,total){ - var locale = Qt.locale() - var precent = (sent/total * 100).toFixed(0) + "%" - btn_upload.text = "上传中..."+precent - text_upload_file_size.text = "%1/%2".arg(locale.formattedDataSize(sent)).arg(locale.formattedDataSize(total)) - layout_upload_file_size.visible = true - } - http.upload("https://httpbingo.org/post",callable,param) + http.upload("https://httpbingo.org/post",callable_upload,param) } } - FolderDialog { - id: folder_dialog - currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0] - onAccepted: { - var callable = {} - callable.onStart = function(){ - btn_download.disabled = true + HttpCallable{ + id:callable_download + onStart: { + btn_download.disabled = true + } + onFinish: { + btn_download.disabled = false + btn_download.text = "下载文件" + layout_download_file_size.visible = false + text_download_file_size.text = "" + } + onError: + (status,errorString,result)=>{ + showError(errorString) + console.debug(status+";"+errorString+";"+result) } - callable.onFinish = function(){ - btn_download.disabled = false - btn_download.text = "下载文件" - layout_download_file_size.visible = false - text_download_file_size.text = "" - } - callable.onSuccess = function(result){ + onSuccess: + (result)=>{ showSuccess(result) } - callable.onError = function(status,errorString){ - showError(errorString) - } - callable.onDownloadProgress = function(recv,total){ + onDownloadProgress: + (recv,total)=>{ var locale = Qt.locale() var precent = (recv/total * 100).toFixed(0) + "%" btn_download.text = "下载中..."+precent text_download_file_size.text = "%1/%2".arg(locale.formattedDataSize(recv)).arg(locale.formattedDataSize(total)) layout_download_file_size.visible = true } + } + + FolderDialog { + id: folder_dialog + currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0] + onAccepted: { var path = FluTools.toLocalPath(currentFolder)+ "/big_buck_bunny.mp4" - http.download("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",callable,path) + http.download("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",callable_download,path) } } @@ -262,7 +307,6 @@ FluContentPage{ } } - FluRectangle{ id:layout_upload_file_size radius: [4,4,4,4] diff --git a/example/qml/window/MainWindow.qml b/example/qml/window/MainWindow.qml index 95831a8b..5db84342 100644 --- a/example/qml/window/MainWindow.qml +++ b/example/qml/window/MainWindow.qml @@ -310,27 +310,32 @@ CustomWindow { } } - function checkUpdate(){ - var callable = {} - callable.onStart = function(){ + HttpCallable{ + id:callable + onStart: { console.debug("satrt check update...") } - callable.onFinish = function(){ + onFinish: { console.debug("check update finish") } - callable.onSuccess = function(result){ - var data = JSON.parse(result) - console.debug("current version "+appInfo.version) - console.debug("new version "+data.tag_name) - if(data.tag_name !== appInfo.version){ - dialog_update.newVerson = data.tag_name - dialog_update.body = data.body - dialog_update.open() + onSuccess: + (result)=>{ + var data = JSON.parse(result) + console.debug("current version "+appInfo.version) + console.debug("new version "+data.tag_name) + if(data.tag_name !== appInfo.version){ + dialog_update.newVerson = data.tag_name + dialog_update.body = data.body + dialog_update.open() + } } - } - callable.onError = function(status,errorString){ - console.debug(status+";"+errorString) - } + onError: + (status,errorString)=>{ + console.debug(status+";"+errorString) + } + } + + function checkUpdate(){ http.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest",callable) } diff --git a/src/FluHttp.cpp b/src/FluHttp.cpp index e8ab346d..e5e5f99d 100644 --- a/src/FluHttp.cpp +++ b/src/FluHttp.cpp @@ -14,6 +14,11 @@ #include "FluApp.h" #include "FluTools.h" +HttpCallable::HttpCallable(QObject *parent) + : QObject{parent} +{ +} + FluHttp::FluHttp(QObject *parent) : QObject{parent} { @@ -39,18 +44,18 @@ void FluHttp::handleReply(QNetworkReply* reply){ _cacheReply.append(reply); } -void FluHttp::post(QString url,QJSValue callable,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"post"); - QMap data = invokeIntercept(requestMap).toMap(); +void FluHttp::post(QString url,HttpCallable* callable,QMap params,QMap headers){ QThreadPool::globalInstance()->start([=](){ - onStart(callable); + auto requestMap = toRequest(url,params,headers,"post"); + QMap data = invokeIntercept(requestMap).toMap(); + Q_EMIT callable->start(); if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - onCache(callable,readCache(requestMap)); - onFinish(callable); + Q_EMIT callable->cache(readCache(requestMap)); + Q_EMIT callable->finish(); return; } if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; @@ -85,33 +90,34 @@ void FluHttp::post(QString url,QJSValue callable,QMap params, reply = nullptr; if (isSuccess) { handleCache(requestMap,result); - onSuccess(callable,result); + Q_EMIT callable->success(result); break; }else{ if(i == retry()-1){ if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } - onError(callable,status,errorString,result); + Q_EMIT callable->error(status,errorString,result); } } } - onFinish(callable); + Q_EMIT callable->finish(); + // Q_EMIT callable->finish(); }); } -void FluHttp::postString(QString url,QJSValue callable,QString params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"postString"); - QMap data = invokeIntercept(requestMap).toMap(); +void FluHttp::postString(QString url,HttpCallable* callable,QString params,QMap headers){ QThreadPool::globalInstance()->start([=](){ - onStart(callable); + auto requestMap = toRequest(url,params,headers,"postString"); + QMap data = invokeIntercept(requestMap).toMap(); + Q_EMIT callable->start(); if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - onCache(callable,readCache(requestMap)); - onFinish(callable); + Q_EMIT callable->cache(readCache(requestMap)); + Q_EMIT callable->finish(); return; } if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; @@ -137,33 +143,33 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QMapsuccess(result); break; }else{ if(i == retry()-1){ if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } - onError(callable,status,errorString,result); + Q_EMIT callable->error(status,errorString,result); } } } - onFinish(callable); + Q_EMIT callable->finish(); }); } -void FluHttp::postJson(QString url,QJSValue callable,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"postJson"); - QMap data = invokeIntercept(requestMap).toMap(); +void FluHttp::postJson(QString url,HttpCallable* callable,QMap params,QMap headers){ QThreadPool::globalInstance()->start([=](){ - onStart(callable); + auto requestMap = toRequest(url,params,headers,"postJson"); + QMap data = invokeIntercept(requestMap).toMap(); + Q_EMIT callable->start(); if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - onCache(callable,readCache(requestMap)); - onFinish(callable); + Q_EMIT callable->cache(readCache(requestMap)); + Q_EMIT callable->finish(); return; } if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; @@ -189,32 +195,32 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap par reply = nullptr; if (isSuccess) { handleCache(requestMap,result); - onSuccess(callable,result); + Q_EMIT callable->success(result); break; }else{ if(i == retry()-1){ if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } - onError(callable,status,errorString,result); + Q_EMIT callable->error(status,errorString,result); } } } - onFinish(callable); + Q_EMIT callable->finish(); }); } -void FluHttp::get(QString url,QJSValue callable,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"get"); - QMap data = invokeIntercept(requestMap).toMap(); - QThreadPool::globalInstance()->start([=](){ - onStart(callable); +void FluHttp::get(QString url,HttpCallable* callable,QMap params,QMap headers){ + QThreadPool::globalInstance()->start([=](){ + auto requestMap = toRequest(url,params,headers,"get"); + QMap data = invokeIntercept(requestMap).toMap(); + Q_EMIT callable->start(); if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - onCache(callable,readCache(requestMap)); - onFinish(callable); + Q_EMIT callable->cache(readCache(requestMap)); + Q_EMIT callable->finish(); return; } for (int i = 0; i < retry(); ++i) { @@ -240,26 +246,26 @@ void FluHttp::get(QString url,QJSValue callable,QMap params,Q reply = nullptr; if (isSuccess) { handleCache(requestMap,result); - onSuccess(callable,result); + Q_EMIT callable->success(result); break; }else{ if(i == retry()-1){ if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){ - onCache(callable,readCache(requestMap)); + Q_EMIT callable->cache(readCache(requestMap)); } - onError(callable,status,errorString,result); + Q_EMIT callable->error(status,errorString,result); } } } - onFinish(callable); + Q_EMIT callable->finish(); }); } -void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"download"); - QMap data = invokeIntercept(requestMap).toMap(); +void FluHttp::download(QString url,HttpCallable* callable,QString filePath,QMap params,QMap headers){ QThreadPool::globalInstance()->start([=](){ - onStart(callable); + auto requestMap = toRequest(url,params,headers,"download"); + QMap data = invokeIntercept(requestMap).toMap(); + Q_EMIT callable->start(); QNetworkAccessManager manager; QUrl _url(url); addQueryParam(&_url,data["params"].toMap()); @@ -269,8 +275,8 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMapopen(mode)) { - onError(callable,-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()),""); - onFinish(callable); + Q_EMIT callable->error(-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()),""); + Q_EMIT callable->finish(); return; } QEventLoop loop; @@ -280,27 +286,27 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap reply = manager.get(request); _cacheReply.append(reply); connect(reply,&QNetworkReply::downloadProgress,this,[=](qint64 bytesReceived, qint64 bytesTotal){ - onDownloadProgress(callable,bytesReceived,bytesTotal); + Q_EMIT callable->downloadProgress(bytesReceived,bytesTotal); }); loop.exec(); if (reply->error() == QNetworkReply::NoError) { file->write(reply->readAll()); - onSuccess(callable,filePath); + Q_EMIT callable->success(filePath); }else{ - onError(callable,reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),""); + Q_EMIT callable->error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),""); } _cacheReply.removeOne(reply); reply->deleteLater(); reply = nullptr; - onFinish(callable); + Q_EMIT callable->finish(); }); } -void FluHttp::upload(QString url,QJSValue callable,QMap params,QMap headers){ - auto requestMap = toRequest(url,params,headers,"upload"); - QMap data = invokeIntercept(requestMap).toMap(); +void FluHttp::upload(QString url,HttpCallable* callable,QMap params,QMap headers){ QThreadPool::globalInstance()->start([=](){ - onStart(callable); + auto requestMap = toRequest(url,params,headers,"upload"); + QMap data = invokeIntercept(requestMap).toMap(); + Q_EMIT callable->start(); QNetworkAccessManager manager; manager.setTransferTimeout(timeout()); QUrl _url(url); @@ -328,7 +334,7 @@ void FluHttp::upload(QString url,QJSValue callable,QMap param loop.quit(); }); connect(reply,&QNetworkReply::uploadProgress,this,[=](qint64 bytesSent, qint64 bytesTotal){ - onUploadProgress(callable,bytesSent,bytesTotal); + Q_EMIT callable->uploadProgress(bytesSent,bytesTotal); }); loop.exec(); QString result = QString::fromUtf8(reply->readAll()); @@ -339,11 +345,11 @@ void FluHttp::upload(QString url,QJSValue callable,QMap param reply->deleteLater(); reply = nullptr; if (isSuccess) { - onSuccess(callable,result); + Q_EMIT callable->success(result); }else{ - onError(callable,status,errorString,result); + Q_EMIT callable->error(status,errorString,result); } - onFinish(callable); + Q_EMIT callable->finish(); }); } @@ -362,7 +368,7 @@ QVariant FluHttp::invokeIntercept(QMap request){ return request; } QVariant target; - QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, request)); + QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Qt::BlockingQueuedConnection,Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, request)); return target; } @@ -386,67 +392,6 @@ void FluHttp::addHeaders(QNetworkRequest* request,const QMap& } } -void FluHttp::onStart(const QJSValue& callable){ - MainThread::post([=](){ - QJSValue onStart = callable.property("onStart"); - onStart.call(); - }); -} - -void FluHttp::onFinish(const QJSValue& callable){ - MainThread::post([=](){ - QJSValue onFinish = callable.property("onFinish"); - onFinish.call(); - }); -} - -void FluHttp::onError(const QJSValue& callable,int status,QString errorString,QString result){ - MainThread::post([=](){ - QJSValue onError = callable.property("onError"); - QJSValueList args; - args<(recv); - args<(total); - QJSValue onDownloadProgress = callable.property("onDownloadProgress"); - onDownloadProgress.call(args); - }); -} - -void FluHttp::onUploadProgress(const QJSValue& callable,qint64 sent, qint64 total){ - MainThread::post([=](){ - QJSValueList args; - args<(sent); - args<(total); - QJSValue onUploadProgress = callable.property("onUploadProgress"); - onUploadProgress.call(args); - }); -} - QString FluHttp::readCache(const QMap& request){ auto filePath = getCacheFilePath(request); QString result; diff --git a/src/FluHttp.h b/src/FluHttp.h index 0747aaa4..af19e36f 100644 --- a/src/FluHttp.h +++ b/src/FluHttp.h @@ -6,6 +6,21 @@ #include #include #include "stdafx.h" +#include + +class HttpCallable : public QObject{ + Q_OBJECT + QML_NAMED_ELEMENT(HttpCallable) +public: + explicit HttpCallable(QObject *parent = nullptr); + Q_SIGNAL void start(); + Q_SIGNAL void finish(); + 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 downloadProgress(qint64 recv, qint64 total); + Q_SIGNAL void uploadProgress(qint64 recv, qint64 total); +}; class FluHttp : public QObject { @@ -21,13 +36,6 @@ private: void handleReply(QNetworkReply* reply); void addQueryParam(QUrl* url,const QMap& params); void addHeaders(QNetworkRequest* request,const QMap& params); - void onStart(const QJSValue& callable); - void onFinish(const QJSValue& callable); - void onError(const QJSValue& callable,int status,QString errorString,QString result); - void onSuccess(const QJSValue& callable,QString result); - void onCache(const QJSValue& callable,QString result); - void onDownloadProgress(const QJSValue& callable,qint64 recv, qint64 total); - void onUploadProgress(const QJSValue& callable,qint64 recv, qint64 total); void handleCache(QMap request, const QString& result); QString readCache(const QMap& request); bool cacheExists(const QMap& request); @@ -36,12 +44,12 @@ public: explicit FluHttp(QObject *parent = nullptr); ~FluHttp(); //神坑!!! 如果参数使用QVariantMap会有问题,在6.4.3版本中QML一调用就会编译失败。所以改用QMap - Q_INVOKABLE void get(QString url,QJSValue callable,QMap params= {},QMap headers = {}); - Q_INVOKABLE void post(QString url,QJSValue callable,QMap params= {},QMap headers = {}); - Q_INVOKABLE void postString(QString url,QJSValue callable,QString params = "",QMap headers = {}); - Q_INVOKABLE void postJson(QString url,QJSValue callable,QMap params = {},QMap headers = {}); - Q_INVOKABLE void download(QString url,QJSValue callable,QString filePath,QMap params = {},QMap headers = {}); - Q_INVOKABLE void upload(QString url,QJSValue callable,QMap params = {},QMap headers = {}); + Q_INVOKABLE void get(QString url,HttpCallable* callable,QMap params= {},QMap headers = {}); + Q_INVOKABLE void post(QString url,HttpCallable* callable,QMap params= {},QMap headers = {}); + Q_INVOKABLE void postString(QString url,HttpCallable* callable,QString params = "",QMap headers = {}); + Q_INVOKABLE void postJson(QString url,HttpCallable* callable,QMap params = {},QMap headers = {}); + Q_INVOKABLE void download(QString url,HttpCallable* callable,QString filePath,QMap params = {},QMap headers = {}); + Q_INVOKABLE void upload(QString url,HttpCallable* callable,QMap params = {},QMap headers = {}); Q_INVOKABLE void cancel(); private: QList> _cacheReply; diff --git a/src/FluTools.cpp b/src/FluTools.cpp index a09e585c..1067a402 100644 --- a/src/FluTools.cpp +++ b/src/FluTools.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -145,3 +146,7 @@ QString FluTools::fromBase64(QString text) return QByteArray::fromBase64(text.toUtf8()); } +bool FluTools::removeDir(QString dirPath){ + QDir qDir(dirPath); + return qDir.removeRecursively(); +} diff --git a/src/FluTools.h b/src/FluTools.h index bb2a525b..9df087f4 100644 --- a/src/FluTools.h +++ b/src/FluTools.h @@ -149,21 +149,29 @@ public: * @param text * @return */ - QString md5(QString text); + Q_INVOKABLE QString md5(QString text); /** * @brief toBase64 * @param text * @return */ - QString toBase64(QString text); + Q_INVOKABLE QString toBase64(QString text); /** * @brief fromBase64 * @param text * @return */ - QString fromBase64(QString text); + Q_INVOKABLE QString fromBase64(QString text); + + + /** + * @brief removeDir + * @param dirPath + * @return + */ + Q_INVOKABLE bool removeDir(QString dirPath); }; diff --git a/src/fluentuiplugin.cpp b/src/fluentuiplugin.cpp index 013b1b0d..986d62f2 100644 --- a/src/fluentuiplugin.cpp +++ b/src/fluentuiplugin.cpp @@ -38,6 +38,7 @@ void FluentUIPlugin::registerTypes(const char *uri) qmlRegisterType(uri,major,minor,"FluColorSet"); qmlRegisterType(uri,major,minor,"FluHttpInterceptor"); qmlRegisterType(uri,major,minor,"FluHttp"); + qmlRegisterType(uri,major,minor,"HttpCallable"); qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluThemeType::staticMetaObject, uri,major,minor,"FluThemeType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluPageType::staticMetaObject, uri,major,minor,"FluPageType", "Access to enums & flags only");