Skip to content

Commit 2485f2f

Browse files
authored
[1008] 统一模板打开器重构 (#3366)
1 parent b64c6f9 commit 2485f2f

7 files changed

Lines changed: 403 additions & 150 deletions

File tree

devel/1008.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# [1008] 统一模板打开器重构
2+
3+
## 1 相关文档
4+
- [dddd.md](dddd.md) - 任务文档模板
5+
6+
## 2 任务相关的代码文件
7+
- `src/Plugins/Qt/QTMTemplateOpener.hpp`
8+
- `src/Plugins/Qt/QTMTemplateOpener.cpp`
9+
- `src/Plugins/Qt/QTMHomePage.cpp`
10+
- `src/Plugins/Qt/QTMHomePage.hpp`
11+
- `src/Plugins/Qt/QTMTemplatePage.cpp`
12+
- `src/Plugins/Qt/QTMTemplatePage.hpp`
13+
- `src/Plugins/Qt/qt_template_utils.hpp`
14+
- `src/Plugins/Qt/qt_template_utils.cpp`
15+
16+
## 3 如何测试
17+
18+
### 非确定性测试(文档验证)
19+
20+
启动应用并验证以下功能:
21+
1. HomePage 点击模板卡片能否正常打开模板
22+
2. TemplatePage 预览后点击打开能否正常工作
23+
3. 本地模板和远程模板的打开流程是否正确
24+
4. 下载进度对话框是否正常显示
25+
5. 取消下载后是否无错误提示
26+
27+
28+
## 4 如何提交
29+
30+
提交前执行以下最少步骤:
31+
32+
```bash
33+
# 代码格式化
34+
./bin/format
35+
36+
# 编译验证
37+
xmake build
38+
```
39+
40+
## 5 What
41+
42+
`QTMHomePage``QTMTemplatePage` 中分散的模板打开逻辑抽取为独立的 `QTMTemplateOpener` 类,实现统一的模板打开流程。
43+
44+
1. 新增 `QTMTemplateOpener` 类(`QTMTemplateOpener.hpp/cpp`
45+
- 封装本地模板打开逻辑:复制到 Documents 并加载
46+
- 封装远程模板下载逻辑:显示进度对话框、同步下载、错误处理
47+
- 提供信号:`completed``failed``downloadProgress`
48+
49+
2. 重构 `QTMHomePage`
50+
- 删除 `createDocumentFromTemplate` 方法
51+
- 使用 `QTMTemplateOpener` 打开模板
52+
53+
3. 重构 `QTMTemplatePage`
54+
- 删除重复的模板打开代码
55+
- 使用 `QTMTemplateOpener` 打开模板
56+
57+
4. 清理冗余 include
58+
-`QTMHomePage.cpp``QTMTemplatePage.cpp` 中移除不再需要的 `qt_template_utils.hpp`
59+
60+
## 6 Why
61+
62+
`QTMHomePage``QTMTemplatePage` 中各自维护了一套几乎相同的模板打开逻辑,存在以下问题:
63+
64+
- **代码重复**:下载进度对话框、错误处理、本地/远程判断逻辑在两个类中重复实现
65+
- **维护困难**:修改模板打开流程需要在两个地方同步修改
66+
- **职责不单一**:页面类既负责 UI 展示又负责业务逻辑
67+
68+
通过抽取 `QTMTemplateOpener` 类,实现单一职责原则,提高代码复用性和可维护性。
69+
70+
## 7 How
71+
72+
### 7.1 设计思路
73+
74+
采用 QObject 子类封装模板打开逻辑,通过信号通知调用方结果:
75+
76+
```
77+
QTMTemplateOpener (QObject)
78+
├── openTemplate(templateId) // 主入口
79+
├── isAvailableLocally(templateId) // 本地检查
80+
├── openLocalTemplate_() // 本地打开(私有)
81+
├── startDownload_() // 远程下载(私有)
82+
└── 信号: completed / failed / downloadProgress
83+
```
84+
85+
### 7.2 同步下载处理
86+
87+
由于模板打开需要阻塞等待下载完成(同时保持 UI 响应),采用 `QProgressDialog` + `downloadTemplateSync` 的同步风格:
88+
89+
1. 显示模态进度对话框
90+
2. 调用 `TemplateManager::downloadTemplateSync` 阻塞下载
91+
3. 通过信号更新进度对话框
92+
4. 下载完成后关闭对话框并打开模板
93+
94+
### 7.3 错误处理策略
95+
96+
- 本地模板不存在 → 显示错误 Toast,发射 `failed` 信号
97+
- 下载失败 → 显示错误 Toast(非用户取消时),发射 `failed` 信号
98+
- 用户取消下载 → 静默失败,发射空的 `failed` 信号
99+
100+
### 7.4 使用方式
101+
102+
```cpp
103+
QTMTemplateOpener opener(this);
104+
opener.openTemplate("template-id");
105+
```
106+
107+
调用方可以选择连接信号处理结果,也可以直接调用(同步风格,结果在返回前已确定)。

src/Plugins/Qt/QTMHomePage.cpp

Lines changed: 3 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,16 @@
2727
#include <QMouseEvent>
2828
#include <QPainter>
2929
#include <QPointer>
30-
#include <QProgressDialog>
3130
#include <QPushButton>
3231
#include <QResizeEvent>
3332
#include <QStringList>
3433
#include <QStyleOption>
3534
#include <QTimer>
3635
#include <QVBoxLayout>
3736

37+
#include "QTMTemplateOpener.hpp"
3838
#include "qt_dpi_utils.hpp"
3939
#include "qt_floating_toast.hpp"
40-
#include "qt_template_utils.hpp"
4140
#include "qt_utilities.hpp"
4241
#include "s7_tm.hpp"
4342
#include "sys_utils.hpp"
@@ -761,83 +760,15 @@ QTMHomePage::createDocumentWithStyle (const QString& styleId) {
761760

762761
for (const auto& style : styles_) {
763762
if (style.id == styleId) {
764-
createDocumentFromTemplate (style.templateId);
763+
QTMTemplateOpener opener (this);
764+
opener.openTemplate (style.templateId);
765765
return;
766766
}
767767
}
768768

769769
qWarning () << "Invalid style ID:" << styleId;
770770
}
771771

772-
void
773-
QTMHomePage::createDocumentFromTemplate (const QString& templateId) {
774-
TemplateManager* mgr= TemplateManager::instance ();
775-
if (!mgr) return;
776-
777-
if (mgr->isTemplateAvailableLocally (templateId)) {
778-
auto meta= mgr->templateById (templateId);
779-
if (!meta) {
780-
QtFloatingToast::showToast (this,
781-
qt_translate ("Template metadata not found"),
782-
3000, QtFloatingToast::Error);
783-
return;
784-
}
785-
QString localPath= mgr->localTemplatePath (templateId);
786-
if (localPath.isEmpty ()) {
787-
QtFloatingToast::showToast (
788-
this, qt_translate ("Local template file is missing"), 3000,
789-
QtFloatingToast::Error);
790-
return;
791-
}
792-
qt_copy_template_and_load (this, localPath, meta->name);
793-
return;
794-
}
795-
796-
QProgressDialog dialog (qt_translate ("Downloading template..."),
797-
qt_translate ("Cancel"), 0, 100, this);
798-
dialog.setWindowModality (Qt::WindowModal);
799-
dialog.setAutoClose (true);
800-
801-
bool cancelledByUser= false;
802-
connect (&dialog, &QProgressDialog::canceled, [&] () {
803-
cancelledByUser= true;
804-
mgr->cancelDownload (templateId);
805-
});
806-
807-
connect (mgr, &TemplateManager::downloadProgress, &dialog,
808-
[&dialog] (const QString&, qint64 received, qint64 total) {
809-
if (total <= 0) return;
810-
dialog.setMaximum (static_cast<int> (total));
811-
dialog.setValue (static_cast<int> (received));
812-
});
813-
814-
dialog.show ();
815-
816-
QString errorMsg;
817-
QString localPath= mgr->downloadTemplateSync (templateId, 30000, &errorMsg);
818-
819-
dialog.hide ();
820-
821-
if (localPath.isEmpty ()) {
822-
if (!cancelledByUser) {
823-
QtFloatingToast::showToast (
824-
this,
825-
errorMsg.isEmpty () ? qt_translate ("Download failed") : errorMsg,
826-
3000, QtFloatingToast::Error);
827-
}
828-
return;
829-
}
830-
831-
auto meta= mgr->templateById (templateId);
832-
if (!meta) {
833-
QtFloatingToast::showToast (this,
834-
qt_translate ("Template metadata not found"),
835-
3000, QtFloatingToast::Error);
836-
return;
837-
}
838-
qt_copy_template_and_load (this, localPath, meta->name);
839-
}
840-
841772
void
842773
QTMHomePage::refreshTemplateThumbnails () {
843774
TemplateManager* mgr= TemplateManager::instance ();

src/Plugins/Qt/QTMHomePage.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ class QTMHomePage : public QWidget {
119119
void removeRecentDoc (const QString& path);
120120
void clearAllRecentDocs ();
121121
void createDocumentWithStyle (const QString& styleId);
122-
void createDocumentFromTemplate (const QString& templateId);
123122
void refreshTemplateThumbnails ();
124123

125124
// 样式卡片相关

0 commit comments

Comments
 (0)