681 lines
24 KiB
Python
681 lines
24 KiB
Python
|
|
"""
|
|||
|
|
主窗口
|
|||
|
|
"""
|
|||
|
|
from PyQt5.QtWidgets import (
|
|||
|
|
QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
|||
|
|
QListWidget, QListWidgetItem, QTabWidget, QTextEdit,
|
|||
|
|
QTreeWidget, QTreeWidgetItem, QPushButton, QLineEdit,
|
|||
|
|
QAction, QMenu, QMessageBox, QFileDialog, QInputDialog, QLabel
|
|||
|
|
)
|
|||
|
|
from PyQt5.QtCore import Qt, QTimer, QSize
|
|||
|
|
from PyQt5.QtGui import QFont
|
|||
|
|
|
|||
|
|
from gui_ai_developer.models import Project, Requirement, Module, Document
|
|||
|
|
from gui_ai_developer.widgets import PanelWidget, ProjectItemWidget, RequirementItemWidget, ModuleItemWidget
|
|||
|
|
from gui_ai_developer.dialogs import NewProjectDialog, CodeViewDialog, ModuleDetailDialog, PipelineDialog
|
|||
|
|
|
|||
|
|
|
|||
|
|
class MainWindow(QMainWindow):
|
|||
|
|
"""主窗口类"""
|
|||
|
|
|
|||
|
|
def __init__(self):
|
|||
|
|
"""初始化主窗口"""
|
|||
|
|
super().__init__()
|
|||
|
|
self.projects = []
|
|||
|
|
self.current_project = None
|
|||
|
|
|
|||
|
|
self._setup_window()
|
|||
|
|
self._setup_toolbar()
|
|||
|
|
self._setup_ui()
|
|||
|
|
self._setup_statusbar()
|
|||
|
|
|
|||
|
|
# 加载示例数据
|
|||
|
|
self._load_sample_data()
|
|||
|
|
|
|||
|
|
# 显示欢迎消息
|
|||
|
|
QTimer.singleShot(500, self._show_welcome)
|
|||
|
|
|
|||
|
|
def _setup_window(self):
|
|||
|
|
"""设置窗口属性"""
|
|||
|
|
self.setWindowTitle("智能低代码开发平台 v1.0")
|
|||
|
|
self.setMinimumSize(1400, 900)
|
|||
|
|
|
|||
|
|
def _setup_toolbar(self):
|
|||
|
|
"""设置工具栏"""
|
|||
|
|
toolbar = self.addToolBar("主工具栏")
|
|||
|
|
toolbar.setMovable(False)
|
|||
|
|
toolbar.setIconSize(QSize(24, 24))
|
|||
|
|
|
|||
|
|
# 新建项目
|
|||
|
|
new_action = QAction("📁 新建项目", self)
|
|||
|
|
new_action.setShortcut("Ctrl+N")
|
|||
|
|
new_action.setToolTip("创建新项目 (Ctrl+N)")
|
|||
|
|
new_action.triggered.connect(self._create_new_project)
|
|||
|
|
toolbar.addAction(new_action)
|
|||
|
|
|
|||
|
|
toolbar.addSeparator()
|
|||
|
|
|
|||
|
|
# 保存
|
|||
|
|
save_action = QAction("💾 保存", self)
|
|||
|
|
save_action.setShortcut("Ctrl+S")
|
|||
|
|
save_action.setToolTip("保存项目 (Ctrl+S)")
|
|||
|
|
save_action.triggered.connect(self._save_project)
|
|||
|
|
toolbar.addAction(save_action)
|
|||
|
|
|
|||
|
|
# 导出
|
|||
|
|
export_action = QAction("📤 导出", self)
|
|||
|
|
export_action.setToolTip("导出项目")
|
|||
|
|
export_action.triggered.connect(self._export_project)
|
|||
|
|
toolbar.addAction(export_action)
|
|||
|
|
|
|||
|
|
toolbar.addSeparator()
|
|||
|
|
|
|||
|
|
# 运行流水线
|
|||
|
|
run_action = QAction("▶ 运行流水线", self)
|
|||
|
|
run_action.setToolTip("运行CI/CD流水线")
|
|||
|
|
run_action.triggered.connect(self._run_pipeline)
|
|||
|
|
toolbar.addAction(run_action)
|
|||
|
|
|
|||
|
|
toolbar.addSeparator()
|
|||
|
|
|
|||
|
|
# 设置
|
|||
|
|
settings_action = QAction("⚙ 设置", self)
|
|||
|
|
settings_action.setToolTip("系统设置")
|
|||
|
|
settings_action.triggered.connect(self._show_settings)
|
|||
|
|
toolbar.addAction(settings_action)
|
|||
|
|
|
|||
|
|
# 帮助
|
|||
|
|
help_action = QAction("❓ 帮助", self)
|
|||
|
|
help_action.setToolTip("帮助文档")
|
|||
|
|
help_action.triggered.connect(self._show_help)
|
|||
|
|
toolbar.addAction(help_action)
|
|||
|
|
|
|||
|
|
def _setup_ui(self):
|
|||
|
|
"""设置UI"""
|
|||
|
|
# 创建中心部件
|
|||
|
|
central = QWidget()
|
|||
|
|
self.setCentralWidget(central)
|
|||
|
|
|
|||
|
|
main_layout = QHBoxLayout(central)
|
|||
|
|
main_layout.setContentsMargins(10, 10, 10, 10)
|
|||
|
|
main_layout.setSpacing(10)
|
|||
|
|
|
|||
|
|
# 左侧面板 - 项目列表
|
|||
|
|
self._create_left_panel(main_layout)
|
|||
|
|
|
|||
|
|
# 中间面板 - 需求和功能
|
|||
|
|
self._create_center_panel(main_layout)
|
|||
|
|
|
|||
|
|
# 右侧面板 - 文档和代码
|
|||
|
|
self._create_right_panel(main_layout)
|
|||
|
|
|
|||
|
|
def _create_left_panel(self, parent_layout):
|
|||
|
|
"""创建左侧面板"""
|
|||
|
|
left_panel = PanelWidget("📁 项目列表")
|
|||
|
|
left_panel.setMaximumWidth(320)
|
|||
|
|
|
|||
|
|
layout = QVBoxLayout()
|
|||
|
|
|
|||
|
|
# 新建项目按钮
|
|||
|
|
new_btn = QPushButton("+ 新建项目")
|
|||
|
|
new_btn.setMinimumHeight(40)
|
|||
|
|
new_btn.clicked.connect(self._create_new_project)
|
|||
|
|
layout.addWidget(new_btn)
|
|||
|
|
|
|||
|
|
# 搜索框
|
|||
|
|
self.search_edit = QLineEdit()
|
|||
|
|
self.search_edit.setPlaceholderText("🔍 搜索项目...")
|
|||
|
|
self.search_edit.textChanged.connect(self._filter_projects)
|
|||
|
|
layout.addWidget(self.search_edit)
|
|||
|
|
|
|||
|
|
# 项目列表
|
|||
|
|
self.project_list = QListWidget()
|
|||
|
|
self.project_list.itemClicked.connect(self._on_project_clicked)
|
|||
|
|
self.project_list.setContextMenuPolicy(Qt.CustomContextMenu)
|
|||
|
|
self.project_list.customContextMenuRequested.connect(self._show_project_context_menu)
|
|||
|
|
layout.addWidget(self.project_list)
|
|||
|
|
|
|||
|
|
left_panel.layout().addLayout(layout)
|
|||
|
|
parent_layout.addWidget(left_panel, 2)
|
|||
|
|
|
|||
|
|
def _create_center_panel(self, parent_layout):
|
|||
|
|
"""创建中间面板"""
|
|||
|
|
center_widget = QWidget()
|
|||
|
|
layout = QVBoxLayout(center_widget)
|
|||
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|||
|
|
layout.setSpacing(10)
|
|||
|
|
|
|||
|
|
# 需求面板
|
|||
|
|
req_panel = PanelWidget("📋 需求管理")
|
|||
|
|
req_layout = QVBoxLayout()
|
|||
|
|
|
|||
|
|
self.req_tabs = QTabWidget()
|
|||
|
|
|
|||
|
|
# 原始需求标签页
|
|||
|
|
self.original_req_text = QTextEdit()
|
|||
|
|
self.original_req_text.setPlaceholderText("原始需求内容将显示在这里...")
|
|||
|
|
self.original_req_text.setReadOnly(True)
|
|||
|
|
self.req_tabs.addTab(self.original_req_text, "原始需求")
|
|||
|
|
|
|||
|
|
# 需求列表标签页
|
|||
|
|
self.req_list = QListWidget()
|
|||
|
|
self.req_tabs.addTab(self.req_list, "需求列表")
|
|||
|
|
|
|||
|
|
req_layout.addWidget(self.req_tabs)
|
|||
|
|
req_panel.layout().addLayout(req_layout)
|
|||
|
|
layout.addWidget(req_panel)
|
|||
|
|
|
|||
|
|
# 功能模块面板
|
|||
|
|
func_panel = PanelWidget("⚙️ 功能模块")
|
|||
|
|
func_layout = QVBoxLayout()
|
|||
|
|
|
|||
|
|
self.module_list = QListWidget()
|
|||
|
|
self.module_list.itemDoubleClicked.connect(self._show_module_detail)
|
|||
|
|
func_layout.addWidget(self.module_list)
|
|||
|
|
|
|||
|
|
func_panel.layout().addLayout(func_layout)
|
|||
|
|
layout.addWidget(func_panel)
|
|||
|
|
|
|||
|
|
parent_layout.addWidget(center_widget, 3)
|
|||
|
|
|
|||
|
|
def _create_right_panel(self, parent_layout):
|
|||
|
|
"""创建右侧面板"""
|
|||
|
|
right_widget = QWidget()
|
|||
|
|
layout = QVBoxLayout(right_widget)
|
|||
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|||
|
|
layout.setSpacing(10)
|
|||
|
|
|
|||
|
|
# 文档面板
|
|||
|
|
doc_panel = PanelWidget("📚 项目文档")
|
|||
|
|
doc_layout = QVBoxLayout()
|
|||
|
|
|
|||
|
|
# 文档工具栏
|
|||
|
|
doc_toolbar = QHBoxLayout()
|
|||
|
|
doc_toolbar.addStretch()
|
|||
|
|
|
|||
|
|
download_all_btn = QPushButton("⬇ 全部下载")
|
|||
|
|
download_all_btn.setStyleSheet("""
|
|||
|
|
QPushButton {
|
|||
|
|
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
|||
|
|
stop:0 #10b981, stop:1 #059669);
|
|||
|
|
}
|
|||
|
|
""")
|
|||
|
|
download_all_btn.clicked.connect(self._download_all_documents)
|
|||
|
|
doc_toolbar.addWidget(download_all_btn)
|
|||
|
|
|
|||
|
|
doc_layout.addLayout(doc_toolbar)
|
|||
|
|
|
|||
|
|
self.doc_list = QListWidget()
|
|||
|
|
self.doc_list.itemDoubleClicked.connect(self._open_document)
|
|||
|
|
self.doc_list.setContextMenuPolicy(Qt.CustomContextMenu)
|
|||
|
|
self.doc_list.customContextMenuRequested.connect(self._show_doc_context_menu)
|
|||
|
|
doc_layout.addWidget(self.doc_list)
|
|||
|
|
|
|||
|
|
doc_panel.layout().addLayout(doc_layout)
|
|||
|
|
layout.addWidget(doc_panel)
|
|||
|
|
|
|||
|
|
# 代码结构面板
|
|||
|
|
code_panel = PanelWidget("💻 代码结构")
|
|||
|
|
code_layout = QVBoxLayout()
|
|||
|
|
|
|||
|
|
# 代码工具栏
|
|||
|
|
code_toolbar = QHBoxLayout()
|
|||
|
|
code_toolbar.addStretch()
|
|||
|
|
|
|||
|
|
download_code_btn = QPushButton("⬇ 下载代码")
|
|||
|
|
download_code_btn.setStyleSheet("""
|
|||
|
|
QPushButton {
|
|||
|
|
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
|||
|
|
stop:0 #10b981, stop:1 #059669);
|
|||
|
|
}
|
|||
|
|
""")
|
|||
|
|
download_code_btn.clicked.connect(self._download_all_code)
|
|||
|
|
code_toolbar.addWidget(download_code_btn)
|
|||
|
|
|
|||
|
|
code_layout.addLayout(code_toolbar)
|
|||
|
|
|
|||
|
|
self.code_tree = QTreeWidget()
|
|||
|
|
self.code_tree.setHeaderLabel("文件")
|
|||
|
|
self.code_tree.itemDoubleClicked.connect(self._open_code_file)
|
|||
|
|
self.code_tree.setContextMenuPolicy(Qt.CustomContextMenu)
|
|||
|
|
self.code_tree.customContextMenuRequested.connect(self._show_code_context_menu)
|
|||
|
|
code_layout.addWidget(self.code_tree)
|
|||
|
|
|
|||
|
|
code_panel.layout().addLayout(code_layout)
|
|||
|
|
layout.addWidget(code_panel)
|
|||
|
|
|
|||
|
|
parent_layout.addWidget(right_widget, 2)
|
|||
|
|
|
|||
|
|
def _setup_statusbar(self):
|
|||
|
|
"""设置状态栏"""
|
|||
|
|
self.statusBar().showMessage("就绪")
|
|||
|
|
|
|||
|
|
# 添加永久部件
|
|||
|
|
self.status_label = QLabel("无项目")
|
|||
|
|
self.statusBar().addPermanentWidget(self.status_label)
|
|||
|
|
|
|||
|
|
def _load_sample_data(self):
|
|||
|
|
"""加载示例数据"""
|
|||
|
|
# 项目1
|
|||
|
|
p1 = Project("智能监控系统", "基于AI的实时监控平台", "进行中")
|
|||
|
|
p1.original_requirement = """需要开发一个智能监控系统,包含以下功能:
|
|||
|
|
1. 用户登录认证:支持用户名密码登录,集成多因素认证
|
|||
|
|
2. 实时数据监控:实时采集设备数据,可视化展示
|
|||
|
|
3. 数据导出:支持导出Excel、CSV格式
|
|||
|
|
4. 系统日志:记录所有操作日志"""
|
|||
|
|
|
|||
|
|
p1.add_requirement(Requirement("REQ-001", "用户登录认证", "支持用户名密码登录,集成MFA", 95, "高"))
|
|||
|
|
p1.add_requirement(Requirement("REQ-002", "实时数据监控", "实时采集设备数据并可视化", 92, "高"))
|
|||
|
|
p1.add_requirement(Requirement("REQ-003", "数据导出功能", "支持导出Excel、CSV格式", 88, "中"))
|
|||
|
|
p1.add_requirement(Requirement("REQ-004", "系统日志管理", "记录所有操作日志", 85, "中"))
|
|||
|
|
|
|||
|
|
m1 = Module("用户认证模块", "实现登录、注册、权限管理", ["REQ-001"])
|
|||
|
|
m1.add_tech("Spring Boot")
|
|||
|
|
m1.add_tech("Spring Security")
|
|||
|
|
m1.add_tech("JWT")
|
|||
|
|
m1.progress = 60
|
|||
|
|
p1.add_module(m1)
|
|||
|
|
|
|||
|
|
m2 = Module("数据监控模块", "实时数据采集和可视化", ["REQ-002"])
|
|||
|
|
m2.add_tech("WebSocket")
|
|||
|
|
m2.add_tech("ECharts")
|
|||
|
|
m2.add_tech("Redis")
|
|||
|
|
m2.progress = 40
|
|||
|
|
p1.add_module(m2)
|
|||
|
|
|
|||
|
|
m3 = Module("数据管理模块", "数据查询、导出、备份", ["REQ-003"])
|
|||
|
|
m3.add_tech("MyBatis")
|
|||
|
|
m3.add_tech("POI")
|
|||
|
|
m3.add_tech("MySQL")
|
|||
|
|
m3.progress = 30
|
|||
|
|
p1.add_module(m3)
|
|||
|
|
|
|||
|
|
p1.add_document(Document("需求规格说明书.docx", "SRS", "2.3 MB"))
|
|||
|
|
p1.add_document(Document("功能设计文档.docx", "功能设计", "1.8 MB"))
|
|||
|
|
p1.add_document(Document("软件概要设计文档.docx", "概要设计", "3.1 MB"))
|
|||
|
|
p1.add_document(Document("接口文档.pdf", "API", "1.2 MB"))
|
|||
|
|
|
|||
|
|
# 项目2
|
|||
|
|
p2 = Project("数据分析平台", "大数据可视化分析工具", "已完成")
|
|||
|
|
|
|||
|
|
# 项目3
|
|||
|
|
p3 = Project("物联网管理系统", "设备管理与数据采集", "进行中")
|
|||
|
|
|
|||
|
|
self.projects = [p1, p2, p3]
|
|||
|
|
self._refresh_project_list()
|
|||
|
|
|
|||
|
|
def _refresh_project_list(self):
|
|||
|
|
"""刷新项目列表"""
|
|||
|
|
self.project_list.clear()
|
|||
|
|
|
|||
|
|
for project in self.projects:
|
|||
|
|
item = QListWidgetItem()
|
|||
|
|
item_widget = ProjectItemWidget(project)
|
|||
|
|
item_widget.clicked.connect(self._load_project)
|
|||
|
|
|
|||
|
|
item.setSizeHint(item_widget.sizeHint())
|
|||
|
|
item.setData(Qt.UserRole, project)
|
|||
|
|
|
|||
|
|
self.project_list.addItem(item)
|
|||
|
|
self.project_list.setItemWidget(item, item_widget)
|
|||
|
|
|
|||
|
|
def _on_project_clicked(self, item):
|
|||
|
|
"""项目点击事件"""
|
|||
|
|
project = item.data(Qt.UserRole)
|
|||
|
|
if project:
|
|||
|
|
self._load_project(project)
|
|||
|
|
|
|||
|
|
def _load_project(self, project):
|
|||
|
|
"""加载项目"""
|
|||
|
|
self.current_project = project
|
|||
|
|
self.status_label.setText(f"当前项目: {project.name}")
|
|||
|
|
self.statusBar().showMessage(f"已加载项目: {project.name}")
|
|||
|
|
|
|||
|
|
# 加载原始需求
|
|||
|
|
self.original_req_text.setText(project.original_requirement)
|
|||
|
|
|
|||
|
|
# 加载需求列表
|
|||
|
|
self.req_list.clear()
|
|||
|
|
for req in project.requirements:
|
|||
|
|
item = QListWidgetItem()
|
|||
|
|
item_widget = RequirementItemWidget(req)
|
|||
|
|
|
|||
|
|
item.setSizeHint(item_widget.sizeHint())
|
|||
|
|
self.req_list.addItem(item)
|
|||
|
|
self.req_list.setItemWidget(item, item_widget)
|
|||
|
|
|
|||
|
|
# 加载功能模块
|
|||
|
|
self.module_list.clear()
|
|||
|
|
for module in project.modules:
|
|||
|
|
item = QListWidgetItem()
|
|||
|
|
item_widget = ModuleItemWidget(module)
|
|||
|
|
|
|||
|
|
item.setSizeHint(item_widget.sizeHint())
|
|||
|
|
item.setData(Qt.UserRole, module)
|
|||
|
|
self.module_list.addItem(item)
|
|||
|
|
self.module_list.setItemWidget(item, item_widget)
|
|||
|
|
|
|||
|
|
# 加载文档列表
|
|||
|
|
self.doc_list.clear()
|
|||
|
|
for doc in project.documents:
|
|||
|
|
item = QListWidgetItem(f"{doc.icon} {doc.name}")
|
|||
|
|
item.setData(Qt.UserRole, doc)
|
|||
|
|
self.doc_list.addItem(item)
|
|||
|
|
|
|||
|
|
# 加载代码树
|
|||
|
|
self._load_code_tree(project)
|
|||
|
|
|
|||
|
|
def _load_code_tree(self, project):
|
|||
|
|
"""加载代码树"""
|
|||
|
|
self.code_tree.clear()
|
|||
|
|
root = QTreeWidgetItem(self.code_tree, [f"📁 {project.name}"])
|
|||
|
|
|
|||
|
|
# src目录
|
|||
|
|
src = QTreeWidgetItem(root, ["📁 src"])
|
|||
|
|
QTreeWidgetItem(src, ["📄 Application.java"])
|
|||
|
|
|
|||
|
|
# modules目录
|
|||
|
|
modules = QTreeWidgetItem(src, ["📁 modules"])
|
|||
|
|
for module in project.modules:
|
|||
|
|
module_name = module.name.replace("模块", "Module").replace(" ", "")
|
|||
|
|
QTreeWidgetItem(modules, [f"☕ {module_name}.java"])
|
|||
|
|
|
|||
|
|
# utils目录
|
|||
|
|
utils = QTreeWidgetItem(src, ["📁 utils"])
|
|||
|
|
QTreeWidgetItem(utils, ["📄 HttpUtil.java"])
|
|||
|
|
QTreeWidgetItem(utils, ["📄 DateUtil.java"])
|
|||
|
|
QTreeWidgetItem(utils, ["📄 StringUtil.java"])
|
|||
|
|
|
|||
|
|
# 配置文件
|
|||
|
|
QTreeWidgetItem(root, ["📋 pom.xml"])
|
|||
|
|
QTreeWidgetItem(root, ["📋 application.yml"])
|
|||
|
|
QTreeWidgetItem(root, ["📝 README.md"])
|
|||
|
|
|
|||
|
|
self.code_tree.expandAll()
|
|||
|
|
|
|||
|
|
def _create_new_project(self):
|
|||
|
|
"""创建新项目"""
|
|||
|
|
dialog = NewProjectDialog(self)
|
|||
|
|
if dialog.exec_() == dialog.Accepted:
|
|||
|
|
project = dialog.get_project()
|
|||
|
|
if project:
|
|||
|
|
self.projects.insert(0, project)
|
|||
|
|
self._refresh_project_list()
|
|||
|
|
self._load_project(project)
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"成功",
|
|||
|
|
f"项目 '{project.name}' 创建成功!"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
def _filter_projects(self, text):
|
|||
|
|
"""过滤项目"""
|
|||
|
|
for i in range(self.project_list.count()):
|
|||
|
|
item = self.project_list.item(i)
|
|||
|
|
project = item.data(Qt.UserRole)
|
|||
|
|
if project:
|
|||
|
|
visible = (
|
|||
|
|
text.lower() in project.name.lower() or
|
|||
|
|
text.lower() in project.description.lower()
|
|||
|
|
)
|
|||
|
|
item.setHidden(not visible)
|
|||
|
|
|
|||
|
|
def _show_project_context_menu(self, pos):
|
|||
|
|
"""显示项目右键菜单"""
|
|||
|
|
item = self.project_list.itemAt(pos)
|
|||
|
|
if not item:
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
menu = QMenu(self)
|
|||
|
|
|
|||
|
|
open_action = menu.addAction("📂 打开项目")
|
|||
|
|
open_action.triggered.connect(lambda: self._on_project_clicked(item))
|
|||
|
|
|
|||
|
|
menu.addSeparator()
|
|||
|
|
|
|||
|
|
rename_action = menu.addAction("✏ 重命名")
|
|||
|
|
rename_action.triggered.connect(lambda: self._rename_project(item))
|
|||
|
|
|
|||
|
|
export_action = menu.addAction("📤 导出项目")
|
|||
|
|
export_action.triggered.connect(self._export_project)
|
|||
|
|
|
|||
|
|
menu.addSeparator()
|
|||
|
|
|
|||
|
|
delete_action = menu.addAction("🗑 删除项目")
|
|||
|
|
delete_action.triggered.connect(lambda: self._delete_project(item))
|
|||
|
|
|
|||
|
|
menu.exec_(self.project_list.mapToGlobal(pos))
|
|||
|
|
|
|||
|
|
def _show_doc_context_menu(self, pos):
|
|||
|
|
"""显示文档右键菜单"""
|
|||
|
|
item = self.doc_list.itemAt(pos)
|
|||
|
|
if not item:
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
menu = QMenu(self)
|
|||
|
|
|
|||
|
|
open_action = menu.addAction("👁 预览")
|
|||
|
|
open_action.triggered.connect(lambda: self._open_document(item))
|
|||
|
|
|
|||
|
|
download_action = menu.addAction("⬇ 下载")
|
|||
|
|
download_action.triggered.connect(lambda: self._download_document(item))
|
|||
|
|
|
|||
|
|
menu.exec_(self.doc_list.mapToGlobal(pos))
|
|||
|
|
|
|||
|
|
def _show_code_context_menu(self, pos):
|
|||
|
|
"""显示代码右键菜单"""
|
|||
|
|
item = self.code_tree.itemAt(pos)
|
|||
|
|
if not item:
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
menu = QMenu(self)
|
|||
|
|
|
|||
|
|
open_action = menu.addAction("👁 查看代码")
|
|||
|
|
open_action.triggered.connect(lambda: self._open_code_file(item, 0))
|
|||
|
|
|
|||
|
|
download_action = menu.addAction("⬇ 下载文件")
|
|||
|
|
download_action.triggered.connect(lambda: self._download_code_file(item))
|
|||
|
|
|
|||
|
|
menu.exec_(self.code_tree.mapToGlobal(pos))
|
|||
|
|
|
|||
|
|
def _show_module_detail(self, item):
|
|||
|
|
"""显示模块详情"""
|
|||
|
|
module = item.data(Qt.UserRole)
|
|||
|
|
if module:
|
|||
|
|
dialog = ModuleDetailDialog(module, self)
|
|||
|
|
dialog.exec_()
|
|||
|
|
|
|||
|
|
def _open_document(self, item):
|
|||
|
|
"""打开文档"""
|
|||
|
|
doc = item.data(Qt.UserRole)
|
|||
|
|
if doc:
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"文档预览",
|
|||
|
|
f"正在打开文档: {doc.name}\n\n"
|
|||
|
|
f"类型: {doc.doc_type}\n"
|
|||
|
|
f"大小: {doc.size}"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
def _download_document(self, item):
|
|||
|
|
"""下载文档"""
|
|||
|
|
doc = item.data(Qt.UserRole)
|
|||
|
|
if doc:
|
|||
|
|
file_path, _ = QFileDialog.getSaveFileName(
|
|||
|
|
self,
|
|||
|
|
"保存文档",
|
|||
|
|
doc.name
|
|||
|
|
)
|
|||
|
|
if file_path:
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"下载",
|
|||
|
|
f"文档已保存到:\n{file_path}"
|
|||
|
|
)
|
|||
|
|
self.statusBar().showMessage(f"已下载: {doc.name}", 3000)
|
|||
|
|
|
|||
|
|
def _download_all_documents(self):
|
|||
|
|
"""下载所有文档"""
|
|||
|
|
if not self.current_project:
|
|||
|
|
QMessageBox.warning(self, "提示", "请先选择一个项目")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
folder = QFileDialog.getExistingDirectory(self, "选择保存目录")
|
|||
|
|
if folder:
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"下载",
|
|||
|
|
f"所有文档已保存到:\n{folder}"
|
|||
|
|
)
|
|||
|
|
self.statusBar().showMessage("文档批量下载完成", 3000)
|
|||
|
|
|
|||
|
|
def _open_code_file(self, item, column):
|
|||
|
|
"""打开代码文件"""
|
|||
|
|
file_name = item.text(0)
|
|||
|
|
if "📄" in file_name or "☕" in file_name or "📋" in file_name or "📝" in file_name:
|
|||
|
|
file_name = file_name.replace("📄 ", "").replace("☕ ", "").replace("📋 ", "").replace("📝 ", "")
|
|||
|
|
dialog = CodeViewDialog(file_name, self)
|
|||
|
|
dialog.exec_()
|
|||
|
|
|
|||
|
|
def _download_code_file(self, item):
|
|||
|
|
"""下载代码文件"""
|
|||
|
|
file_name = item.text(0).replace("📄 ", "").replace("📁 ", "").replace("☕ ", "").replace("📋 ", "").replace(
|
|||
|
|
"📝 ", "")
|
|||
|
|
file_path, _ = QFileDialog.getSaveFileName(
|
|||
|
|
self,
|
|||
|
|
"保存代码文件",
|
|||
|
|
file_name
|
|||
|
|
)
|
|||
|
|
if file_path:
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"下载",
|
|||
|
|
f"文件已保存到:\n{file_path}"
|
|||
|
|
)
|
|||
|
|
self.statusBar().showMessage(f"已下载: {file_name}", 3000)
|
|||
|
|
|
|||
|
|
def _download_all_code(self):
|
|||
|
|
"""下载所有代码"""
|
|||
|
|
if not self.current_project:
|
|||
|
|
QMessageBox.warning(self, "提示", "请先选择一个项目")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
folder = QFileDialog.getExistingDirectory(self, "选择保存目录")
|
|||
|
|
if folder:
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"下载",
|
|||
|
|
f"项目代码已打包保存到:\n{folder}"
|
|||
|
|
)
|
|||
|
|
self.statusBar().showMessage("代码下载完成", 3000)
|
|||
|
|
|
|||
|
|
def _rename_project(self, item):
|
|||
|
|
"""重命名项目"""
|
|||
|
|
project = item.data(Qt.UserRole)
|
|||
|
|
if project:
|
|||
|
|
new_name, ok = QInputDialog.getText(
|
|||
|
|
self,
|
|||
|
|
"重命名项目",
|
|||
|
|
"新项目名称:",
|
|||
|
|
text=project.name
|
|||
|
|
)
|
|||
|
|
if ok and new_name:
|
|||
|
|
project.name = new_name
|
|||
|
|
self._refresh_project_list()
|
|||
|
|
self.statusBar().showMessage(f"项目已重命名为: {new_name}", 3000)
|
|||
|
|
|
|||
|
|
def _delete_project(self, item):
|
|||
|
|
"""删除项目"""
|
|||
|
|
project = item.data(Qt.UserRole)
|
|||
|
|
if project:
|
|||
|
|
reply = QMessageBox.question(
|
|||
|
|
self,
|
|||
|
|
"确认删除",
|
|||
|
|
f"确定要删除项目 '{project.name}' 吗?\n此操作不可恢复!",
|
|||
|
|
QMessageBox.Yes | QMessageBox.No
|
|||
|
|
)
|
|||
|
|
if reply == QMessageBox.Yes:
|
|||
|
|
self.projects.remove(project)
|
|||
|
|
self._refresh_project_list()
|
|||
|
|
if self.current_project == project:
|
|||
|
|
self.current_project = None
|
|||
|
|
self.status_label.setText("无项目")
|
|||
|
|
self.statusBar().showMessage(f"已删除项目: {project.name}", 3000)
|
|||
|
|
|
|||
|
|
def _save_project(self):
|
|||
|
|
"""保存项目"""
|
|||
|
|
if self.current_project:
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"保存",
|
|||
|
|
f"项目 '{self.current_project.name}' 已保存"
|
|||
|
|
)
|
|||
|
|
self.statusBar().showMessage("项目已保存", 3000)
|
|||
|
|
else:
|
|||
|
|
QMessageBox.warning(self, "提示", "没有打开的项目")
|
|||
|
|
|
|||
|
|
def _export_project(self):
|
|||
|
|
"""导出项目"""
|
|||
|
|
if not self.current_project:
|
|||
|
|
QMessageBox.warning(self, "提示", "请先选择一个项目")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
file_path, _ = QFileDialog.getSaveFileName(
|
|||
|
|
self,
|
|||
|
|
"导出项目",
|
|||
|
|
f"{self.current_project.name}.zip",
|
|||
|
|
"ZIP文件 (*.zip)"
|
|||
|
|
)
|
|||
|
|
if file_path:
|
|||
|
|
QMessageBox.information(
|
|||
|
|
self,
|
|||
|
|
"导出",
|
|||
|
|
f"项目已导出到:\n{file_path}"
|
|||
|
|
)
|
|||
|
|
self.statusBar().showMessage("项目导出完成", 3000)
|
|||
|
|
|
|||
|
|
def _run_pipeline(self):
|
|||
|
|
"""运行流水线"""
|
|||
|
|
if not self.current_project:
|
|||
|
|
QMessageBox.warning(self, "提示", "请先选择一个项目")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
dialog = PipelineDialog(self.current_project, self)
|
|||
|
|
dialog.exec_()
|
|||
|
|
|
|||
|
|
def _show_settings(self):
|
|||
|
|
"""显示设置"""
|
|||
|
|
QMessageBox.information(self, "设置", "设置功能开发中...")
|
|||
|
|
|
|||
|
|
def _show_help(self):
|
|||
|
|
"""显示帮助"""
|
|||
|
|
help_text = """
|
|||
|
|
<h2>智能低代码开发平台 v1.0</h2>
|
|||
|
|
<h3>快捷键:</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li><b>Ctrl+N</b> - 新建项目</li>
|
|||
|
|
<li><b>Ctrl+S</b> - 保存项目</li>
|
|||
|
|
</ul>
|
|||
|
|
<h3>功能说明:</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li>支持基于AI的需求分析和功能生成</li>
|
|||
|
|
<li>自动生成项目文档和代码结构</li>
|
|||
|
|
<li>集成流水线进行编译、打包、部署</li>
|
|||
|
|
<li>支持多种项目类型和技术栈</li>
|
|||
|
|
</ul>
|
|||
|
|
<h3>使用提示:</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li>双击模块查看详细信息</li>
|
|||
|
|
<li>右键点击项目/文档/代码可查看更多操作</li>
|
|||
|
|
<li>使用搜索框快速定位项目</li>
|
|||
|
|
</ul>
|
|||
|
|
"""
|
|||
|
|
QMessageBox.about(self, "帮助", help_text)
|
|||
|
|
|
|||
|
|
def _show_welcome(self):
|
|||
|
|
"""显示欢迎消息"""
|
|||
|
|
self.statusBar().showMessage(
|
|||
|
|
"欢迎使用智能低代码开发平台!按 Ctrl+N 创建新项目",
|
|||
|
|
5000
|
|||
|
|
)
|