From b9a89c8db755ab8e5eb9030c11dc62a72b12a4fe Mon Sep 17 00:00:00 2001 From: wuyize Date: Fri, 7 Jul 2023 00:48:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8F=E8=A7=88=E8=AE=B0=E5=BD=95=E3=80=81?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AicsKnowledgeBase/qml/MainWindow.qml | 1 + .../qml/component/TransferListPopup.qml | 96 ++++++++++++------ AicsKnowledgeBase/qml/global/UserData.qml | 2 + AicsKnowledgeBase/res/download.png | Bin 0 -> 3104 bytes AicsKnowledgeBase/res/upload.png | Bin 0 -> 3017 bytes .../src/FileTransferListModel.cpp | 2 + AicsKnowledgeBase/src/FileTransferManager.cpp | 14 +-- AicsKnowledgeBase/src/FileTransferManager.h | 1 + 8 files changed, 80 insertions(+), 36 deletions(-) create mode 100644 AicsKnowledgeBase/res/download.png create mode 100644 AicsKnowledgeBase/res/upload.png diff --git a/AicsKnowledgeBase/qml/MainWindow.qml b/AicsKnowledgeBase/qml/MainWindow.qml index be9e4dc..9763a23 100644 --- a/AicsKnowledgeBase/qml/MainWindow.qml +++ b/AicsKnowledgeBase/qml/MainWindow.qml @@ -102,6 +102,7 @@ FluWindow { target: SignalFileOperation function onOpen(file) { stack_view.clear() + UserData.viewHistory.push(file) stack_view.push(file_view, { "knowledgeFileId": file }) diff --git a/AicsKnowledgeBase/qml/component/TransferListPopup.qml b/AicsKnowledgeBase/qml/component/TransferListPopup.qml index 7c13c78..b5a990c 100644 --- a/AicsKnowledgeBase/qml/component/TransferListPopup.qml +++ b/AicsKnowledgeBase/qml/component/TransferListPopup.qml @@ -5,6 +5,7 @@ import QtQuick.Layouts import Qt5Compat.GraphicalEffects import FluentUI import AicsKB.FileTransferManager +import "qrc:///AicsKnowledgeBase/qml/global" Popup { id: transfer_popup @@ -18,6 +19,15 @@ Popup { FluShadow {} } + Connections { + target: FileTransferManager + onTransferComplete: (download, fileId, fileName) => { + console.log("onTransferComplete") + UserData.downloadedFiles.push(fileId) + console.log(UserData.downloadedFiles) + } + } + contentItem: FluScrollablePage { anchors.fill: parent anchors.topMargin: 10 @@ -30,42 +40,65 @@ Popup { Layout.fillWidth: true height: 50 - ColumnLayout { + Item { anchors.fill: parent - anchors.margins: 5 - spacing: 2 - Text { - text: name + anchors.topMargin: 5 + anchors.bottomMargin: 5 + anchors.leftMargin: 0 + Image { + id: icon + anchors.verticalCenter: parent.verticalCenter + width: 32 + height: 32 + source: download ? "qrc:/AicsKnowledgeBase/res/download.png" : "qrc:/AicsKnowledgeBase/res/upload.png" } - FluProgressBar { - Layout.fillWidth: true - progress: completedSize / totalSize - indeterminate: false - } + ColumnLayout { + anchors.left: icon.right + anchors.right: parent.right + anchors.leftMargin: 5 + spacing: 2 + Text { + text: name + } + Text { + visible: completedSize >= totalSize + text: "已完成" + color: FluColors.Grey130 + } + FluProgressBar { + Layout.fillWidth: true + progress: completedSize / totalSize + indeterminate: false + visible: completedSize < totalSize + } - Text { - color: FluColors.Grey130 - text: formatSize(speed) + "/s - " + formatSize( - completedSize) + "/" + formatSize( - totalSize) + Text { + visible: completedSize < totalSize + color: FluColors.Grey130 + text: formatSize(speed) + "/s - " + formatSize( + completedSize) + "/" + formatSize( + totalSize) - /** - * 格式化文件大小, 输出成带单位的字符串 - * @param {Number} size 文件大小 - * @param {Number} [pointLength=1] 精确到的小数点数。 - * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节,到千字节,一直往上指定。 - * 如果单位数组里面只指定了到了K(千字节),同时文件大小大于M, 此方法的输出将还是显示成多少K. - */ - function formatSize(size, pointLength, units) { - var unit - units = units || ['B', 'KB', 'MB', 'GB', 'TB'] - while ((unit = units.shift()) && size > 1024) { - size = size / 1024 + /** + * 格式化文件大小, 输出成带单位的字符串 + * @param {Number} size 文件大小 + * @param {Number} [pointLength=1] 精确到的小数点数。 + * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节,到千字节,一直往上指定。 + * 如果单位数组里面只指定了到了K(千字节),同时文件大小大于M, 此方法的输出将还是显示成多少K. + */ + function formatSize(size, pointLength, units) { + var unit + units = units + || ['B', 'KB', 'MB', 'GB', 'TB'] + while ((unit = units.shift()) + && size > 1024) { + size = size / 1024 + } + return (unit === 'B' ? size : size.toFixed( + pointLength === undefined ? 1 : pointLength)) + ' ' + unit } - return (unit === 'B' ? size : size.toFixed( - pointLength === undefined ? 1 : pointLength)) + ' ' + unit } } } @@ -73,7 +106,10 @@ Popup { MouseArea { anchors.fill: parent hoverEnabled: true - onEntered: file_buttons.visible = true + onEntered: { + if (completedSize < totalSize) + file_buttons.visible = true + } onExited: file_buttons.visible = false LinearGradient { diff --git a/AicsKnowledgeBase/qml/global/UserData.qml b/AicsKnowledgeBase/qml/global/UserData.qml index 771ac90..4d7845f 100644 --- a/AicsKnowledgeBase/qml/global/UserData.qml +++ b/AicsKnowledgeBase/qml/global/UserData.qml @@ -5,4 +5,6 @@ import QtQuick QtObject { property string username property string userId + property var viewHistory: [] + property var downloadedFiles: [] } diff --git a/AicsKnowledgeBase/res/download.png b/AicsKnowledgeBase/res/download.png new file mode 100644 index 0000000000000000000000000000000000000000..3bd31e82d1543fd60bcb039cc4ca32ed4c6401ca GIT binary patch literal 3104 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 literal 0 HcmV?d00001 diff --git a/AicsKnowledgeBase/res/upload.png b/AicsKnowledgeBase/res/upload.png new file mode 100644 index 0000000000000000000000000000000000000000..136a60ff815c7a9a03ebb47c66d7a64d2a0b0f2c GIT binary patch literal 3017 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 += dlnow; fileTrans->speed = speed; - qDebug() << std::format("Downloading: {} / {}, Speed: {}", fileTrans->completedSize, fileTrans->totalSize, - speed).c_str(); + //qDebug() << std::format("Downloading: {} / {}, Speed: {}", fileTrans->completedSize, fileTrans->totalSize, + // speed).c_str(); auto item = static_cast(*fileTrans); QTimer::singleShot(0, qApp, [item]() { @@ -96,8 +96,8 @@ static int uploadInfo(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t curl_easy_getinfo(fileTrans->curlHandle, CURLINFO_SPEED_UPLOAD_T, &speed); fileTrans->completedSize += ulnow; fileTrans->speed = speed; - qDebug() << std::format("Uploading: {} / {}, Speed: {}", fileTrans->completedSize, fileTrans->totalSize, - speed).c_str(); + //qDebug() << std::format("Uploading: {} / {}, Speed: {}", fileTrans->completedSize, fileTrans->totalSize, + // speed).c_str(); auto item = static_cast(*fileTrans); QTimer::singleShot(0, qApp, [item]() { @@ -359,6 +359,10 @@ void FileTransferManager::download(const QString &fileId, const QString &fileNam auto fileUrl = std::format("File/{}?rangeStart={}&rangeEnd={}", fileId.toStdString(), completedSize, size); auto res = httpDownload(fileUrl, savePath, item); + + if (QFileInfo(QString::fromLocal8Bit(savePath.c_str())).size() == size) + emit transferComplete(true, fileId, fileName); + qDebug() << "End Get" << res; }); } @@ -398,8 +402,6 @@ QString FileTransferManager::getFileName(const QUrl &fileUrl) } - - void FileTransferManager::getMarkdown(const QString &fileId) { QtConcurrent::run([fileId, this] { diff --git a/AicsKnowledgeBase/src/FileTransferManager.h b/AicsKnowledgeBase/src/FileTransferManager.h index 0e1c3ad..571e693 100644 --- a/AicsKnowledgeBase/src/FileTransferManager.h +++ b/AicsKnowledgeBase/src/FileTransferManager.h @@ -33,6 +33,7 @@ public: Q_INVOKABLE void getMarkdown(const QString &fileId); signals: + void transferComplete(bool download, QString fileId, QString fileName); void markdownData(QString data); private: