From d5a848e308b798ec7d3238244e6e9a5f490aa73f Mon Sep 17 00:00:00 2001 From: zhangtingan Date: Mon, 24 Aug 2026 01:50:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=20JSON=20=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E5=8C=96=E5=BA=8F=E5=88=97=E5=8C=96=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=A4=E7=AB=AF=E8=BF=81=E7=A7=BB=E5=AE=8C=E6=88=90=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E4=B8=8D=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PMS bug #246975: 数据传输完成后两端迁移完成列表不一致 根因: add_result 与 transfer_content 通道以空格作为字段分隔符, 而 name/reason/filepath 均为含空格的翻译文本或文件路径,导致接收端 按 split(" ") 严格校验字段数时丢弃全部条目,接收端列表为空/缺失, 与发送端完整列表不一致。 修复方案 (方案 A): 改用 QJsonDocument 结构化序列化,两端格式严格同步。 - add_result 发送端 resultdisplay.cpp: 以 QJsonArray 累积结果, QJsonDocument 序列化后发送,替代 processText 空格拼接 - add_result 接收端 transferworker.cpp: 解析 JSON 数组取字段, 替代 split(";")/split(" ") + size()==3 校验 - transfer_content 发送端 transferringwidget.cpp: 以 QJsonObject 序列化单条进度消息,替代空格拼接 - transfer_content 接收端 transferworker.cpp: 解析 JSON 对象取字段, 替代 split(";")/split(" ") + size()==4 校验 边界情况: 空字段、含空格/特殊字符的 name/reason/filepath、空列表、 异步应用安装结果在发送前已包含等,均由 JSON 转义自动处理。 基线: release/v20 @ 570cb50b4f7bb810b9483e3277e2e5199add58c5 --- .../core/gui/transfer/resultdisplay.cpp | 15 ++++++--- .../core/gui/transfer/resultdisplay.h | 3 +- .../core/gui/transfer/transferringwidget.cpp | 13 ++++++-- .../core/utils/transferworker.cpp | 31 +++++++++++++------ 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/plugins/data-transfer/core/gui/transfer/resultdisplay.cpp b/src/plugins/data-transfer/core/gui/transfer/resultdisplay.cpp index 8db67a77f..dcd562069 100644 --- a/src/plugins/data-transfer/core/gui/transfer/resultdisplay.cpp +++ b/src/plugins/data-transfer/core/gui/transfer/resultdisplay.cpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include ResultDisplayWidget::ResultDisplayWidget(QWidget *parent) @@ -67,7 +70,8 @@ void ResultDisplayWidget::initUI() &ResultDisplayWidget::addResult); #ifdef linux connect(TransferHelper::instance(), &TransferHelper::transferFinished, this, [this] { - TransferHelper::instance()->sendMessage("add_result", processText); + QJsonDocument doc(resultArray); + TransferHelper::instance()->sendMessage("add_result", QString::fromUtf8(doc.toJson(QJsonDocument::Compact))); }); #endif } @@ -107,14 +111,17 @@ void ResultDisplayWidget::addResult(QString name, bool success, QString reason) setStatus(false); resultWindow->updateContent(name, reason, success); - QString res = success ? "true" : "false"; - processText.append(name + " " + res + " " + reason + ";"); + QJsonObject resultObj; + resultObj["name"] = name; + resultObj["success"] = success; + resultObj["reason"] = reason; + resultArray.append(resultObj); } void ResultDisplayWidget::clear() { resultWindow->clear(); - processText.clear(); + resultArray = QJsonArray(); setStatus(true); } diff --git a/src/plugins/data-transfer/core/gui/transfer/resultdisplay.h b/src/plugins/data-transfer/core/gui/transfer/resultdisplay.h index c21ed2ade..358bb751a 100644 --- a/src/plugins/data-transfer/core/gui/transfer/resultdisplay.h +++ b/src/plugins/data-transfer/core/gui/transfer/resultdisplay.h @@ -2,6 +2,7 @@ #define RESULTDISPLAYWIDGET_H #include +#include #include "../type_defines.h" class QTextBrowser; class QLabel; @@ -37,7 +38,7 @@ public slots: private: ResultWindow *resultWindow { nullptr }; - QString processText; + QJsonArray resultArray; QLabel *iconLabel { nullptr }; QLabel *titileLabel { nullptr }; QLabel *tiptextlabel { nullptr }; diff --git a/src/plugins/data-transfer/core/gui/transfer/transferringwidget.cpp b/src/plugins/data-transfer/core/gui/transfer/transferringwidget.cpp index a84483a86..4c0bf00ae 100644 --- a/src/plugins/data-transfer/core/gui/transfer/transferringwidget.cpp +++ b/src/plugins/data-transfer/core/gui/transfer/transferringwidget.cpp @@ -17,6 +17,9 @@ #include #include +#include +#include + TransferringWidget::TransferringWidget(QWidget *parent) : QFrame(parent) { @@ -202,9 +205,13 @@ void TransferringWidget::updateProcess(const QString &tpye, const QString &conte timeLabel->setText(QString(tr("Transfer will be completed in --"))); #ifdef linux //通知对方进程情况 - QString mes = tpye + " " + content + " " + QString::number(progressbar) + " " - + QString::number(estimatedtime) + ";"; - TransferHelper::instance()->sendMessage("transfer_content", mes); + QJsonObject contentObj; + contentObj["type"] = tpye; + contentObj["content"] = content; + contentObj["progressbar"] = progressbar; + contentObj["estimatedtime"] = estimatedtime; + QJsonDocument doc(contentObj); + TransferHelper::instance()->sendMessage("transfer_content", QString::fromUtf8(doc.toJson(QJsonDocument::Compact))); #endif } } diff --git a/src/plugins/data-transfer/core/utils/transferworker.cpp b/src/plugins/data-transfer/core/utils/transferworker.cpp index acfce1a6d..30d457fac 100644 --- a/src/plugins/data-transfer/core/utils/transferworker.cpp +++ b/src/plugins/data-transfer/core/utils/transferworker.cpp @@ -17,6 +17,10 @@ #include #include #include +#include +#include +#include +#include #pragma execution_character_set("utf-8") TransferHandle::TransferHandle() @@ -350,11 +354,15 @@ void TransferHandle::handleMiscMessage(QString jsonmsg) if (miscJson.has_member("add_result")) { QString result = miscJson.get("add_result").as_c_str(); LOG << "add_result" << result.data(); - for (QString str : result.split(";")) { - auto res = str.split(" "); - if (res.size() != 3) - continue; - emit TransferHelper::instance()->addResult(res.at(0), res.at(1) == "true", res.at(2)); + QJsonParseError parseError; + QJsonDocument doc = QJsonDocument::fromJson(result.toUtf8(), &parseError); + if (parseError.error == QJsonParseError::NoError && doc.isArray()) { + for (const QJsonValue &val : doc.array()) { + QJsonObject obj = val.toObject(); + emit TransferHelper::instance()->addResult(obj.value("name").toString(), + obj.value("success").toBool(), + obj.value("reason").toString()); + } } emit TransferHelper::instance()->transferFinished(); } @@ -376,11 +384,14 @@ void TransferHandle::handleMiscMessage(QString jsonmsg) if (miscJson.has_member("transfer_content")) { QString result = miscJson.get("transfer_content").as_c_str(); - for (QString str : result.split(";")) { - auto res = str.split(" "); - if (res.size() != 4) - continue; - emit TransferHelper::instance()->transferContent(res.at(0), res.at(1), res.at(2).toInt(), res.at(3).toInt()); + QJsonParseError parseError; + QJsonDocument doc = QJsonDocument::fromJson(result.toUtf8(), &parseError); + if (parseError.error == QJsonParseError::NoError && doc.isObject()) { + QJsonObject obj = doc.object(); + emit TransferHelper::instance()->transferContent(obj.value("type").toString(), + obj.value("content").toString(), + obj.value("progressbar").toInt(), + obj.value("estimatedtime").toInt()); } } }