create project
This commit is contained in:
commit
b16661ac91
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
配置模块
|
||||
"""
|
||||
from .styles import DARK_THEME
|
||||
|
||||
__all__ = ['DARK_THEME']
|
||||
|
|
@ -0,0 +1,363 @@
|
|||
# """
|
||||
# 样式定义模块
|
||||
# 包含深色主题样式
|
||||
# """
|
||||
#
|
||||
DARK_THEME = """"""
|
||||
# DARK_THEME = """
|
||||
# /* ==================== 全局样式 ==================== */
|
||||
# QMainWindow, QDialog {
|
||||
# background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
|
||||
# stop:0 #0a0e27, stop:1 #1a1f3a);
|
||||
# color: #e0e6ed;
|
||||
# }
|
||||
#
|
||||
# QWidget {
|
||||
# background-color: transparent;
|
||||
# color: #e0e6ed;
|
||||
# font-family: "Microsoft YaHei", "SimHei", Arial;
|
||||
# font-size: 13px;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 面板样式 ==================== */
|
||||
# QFrame[frameShape="4"],
|
||||
# QFrame[frameShape="5"] {
|
||||
# background: rgba(30, 41, 59, 0.6);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-radius: 12px;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 按钮样式 ==================== */
|
||||
# QPushButton {
|
||||
# background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
# stop:0 #3b82f6, stop:1 #2563eb);
|
||||
# color: white;
|
||||
# border: none;
|
||||
# border-radius: 6px;
|
||||
# padding: 8px 16px;
|
||||
# font-weight: bold;
|
||||
# min-height: 30px;
|
||||
# }
|
||||
#
|
||||
# QPushButton:hover {
|
||||
# background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
# stop:0 #60a5fa, stop:1 #3b82f6);
|
||||
# }
|
||||
#
|
||||
# QPushButton:pressed {
|
||||
# background: #2563eb;
|
||||
# }
|
||||
#
|
||||
# QPushButton:disabled {
|
||||
# background: rgba(51, 65, 85, 0.5);
|
||||
# color: #64748b;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 输入框样式 ==================== */
|
||||
# QLineEdit, QTextEdit, QPlainTextEdit {
|
||||
# background: rgba(51, 65, 85, 0.5);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-radius: 6px;
|
||||
# padding: 8px;
|
||||
# color: #e0e6ed;
|
||||
# selection-background-color: #3b82f6;
|
||||
# }
|
||||
#
|
||||
# QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {
|
||||
# border: 1px solid #3b82f6;
|
||||
# background: rgba(51, 65, 85, 0.7);
|
||||
# }
|
||||
#
|
||||
# /* ==================== 下拉框样式 ==================== */
|
||||
# QComboBox {
|
||||
# background: rgba(51, 65, 85, 0.5);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-radius: 6px;
|
||||
# padding: 6px;
|
||||
# color: #e0e6ed;
|
||||
# min-height: 30px;
|
||||
# }
|
||||
#
|
||||
# QComboBox:hover {
|
||||
# border: 1px solid rgba(59, 130, 246, 0.4);
|
||||
# }
|
||||
#
|
||||
# QComboBox::drop-down {
|
||||
# border: none;
|
||||
# width: 30px;
|
||||
# }
|
||||
#
|
||||
# QComboBox QAbstractItemView {
|
||||
# background: rgba(30, 41, 59, 0.95);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
# border-radius: 6px;
|
||||
# selection-background-color: rgba(59, 130, 246, 0.3);
|
||||
# color: #e0e6ed;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 列表样式 ==================== */
|
||||
# QListWidget, QTreeWidget {
|
||||
# background: rgba(30, 41, 59, 0.4);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-radius: 8px;
|
||||
# color: #e0e6ed;
|
||||
# outline: none;
|
||||
# }
|
||||
#
|
||||
# QListWidget::item, QTreeWidget::item {
|
||||
# padding: 8px;
|
||||
# border-radius: 4px;
|
||||
# border: none;
|
||||
# }
|
||||
#
|
||||
# QListWidget::item:hover, QTreeWidget::item:hover {
|
||||
# background: rgba(59, 130, 246, 0.15);
|
||||
# }
|
||||
#
|
||||
# QListWidget::item:selected, QTreeWidget::item:selected {
|
||||
# background: rgba(59, 130, 246, 0.3);
|
||||
# border-left: 3px solid #3b82f6;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 标签页样式 ==================== */
|
||||
# QTabWidget::pane {
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-radius: 8px;
|
||||
# background: rgba(30, 41, 59, 0.4);
|
||||
# top: -1px;
|
||||
# }
|
||||
#
|
||||
# QTabBar::tab {
|
||||
# background: rgba(51, 65, 85, 0.4);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-bottom: none;
|
||||
# border-radius: 6px 6px 0 0;
|
||||
# padding: 8px 16px;
|
||||
# margin-right: 4px;
|
||||
# color: #94a3b8;
|
||||
# min-width: 80px;
|
||||
# }
|
||||
#
|
||||
# QTabBar::tab:hover {
|
||||
# background: rgba(59, 130, 246, 0.15);
|
||||
# color: #e0e6ed;
|
||||
# }
|
||||
#
|
||||
# QTabBar::tab:selected {
|
||||
# background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
# stop:0 #3b82f6, stop:1 #2563eb);
|
||||
# color: white;
|
||||
# border-color: #3b82f6;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 进度条样式 ==================== */
|
||||
# QProgressBar {
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-radius: 4px;
|
||||
# background: rgba(51, 65, 85, 0.5);
|
||||
# text-align: center;
|
||||
# color: #e0e6ed;
|
||||
# height: 20px;
|
||||
# }
|
||||
#
|
||||
# QProgressBar::chunk {
|
||||
# background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
|
||||
# stop:0 #3b82f6, stop:1 #06b6d4);
|
||||
# border-radius: 3px;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 复选框样式 ==================== */
|
||||
# QCheckBox {
|
||||
# color: #e0e6ed;
|
||||
# spacing: 8px;
|
||||
# }
|
||||
#
|
||||
# QCheckBox::indicator {
|
||||
# width: 18px;
|
||||
# height: 18px;
|
||||
# border: 2px solid rgba(59, 130, 246, 0.4);
|
||||
# border-radius: 4px;
|
||||
# background: rgba(51, 65, 85, 0.5);
|
||||
# }
|
||||
#
|
||||
# QCheckBox::indicator:hover {
|
||||
# border-color: rgba(59, 130, 246, 0.6);
|
||||
# }
|
||||
#
|
||||
# QCheckBox::indicator:checked {
|
||||
# background: #3b82f6;
|
||||
# border-color: #3b82f6;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 单选框样式 ==================== */
|
||||
# QRadioButton {
|
||||
# color: #e0e6ed;
|
||||
# spacing: 8px;
|
||||
# }
|
||||
#
|
||||
# QRadioButton::indicator {
|
||||
# width: 18px;
|
||||
# height: 18px;
|
||||
# border: 2px solid rgba(59, 130, 246, 0.4);
|
||||
# border-radius: 9px;
|
||||
# background: rgba(51, 65, 85, 0.5);
|
||||
# }
|
||||
#
|
||||
# QRadioButton::indicator:hover {
|
||||
# border-color: rgba(59, 130, 246, 0.6);
|
||||
# }
|
||||
#
|
||||
# QRadioButton::indicator:checked {
|
||||
# background: #3b82f6;
|
||||
# border-color: #3b82f6;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 滚动条样式 ==================== */
|
||||
# QScrollBar:vertical {
|
||||
# border: none;
|
||||
# background: rgba(30, 41, 59, 0.3);
|
||||
# width: 10px;
|
||||
# border-radius: 5px;
|
||||
# margin: 0;
|
||||
# }
|
||||
#
|
||||
# QScrollBar::handle:vertical {
|
||||
# background: rgba(59, 130, 246, 0.4);
|
||||
# border-radius: 5px;
|
||||
# min-height: 30px;
|
||||
# }
|
||||
#
|
||||
# QScrollBar::handle:vertical:hover {
|
||||
# background: rgba(59, 130, 246, 0.6);
|
||||
# }
|
||||
#
|
||||
# QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
|
||||
# height: 0px;
|
||||
# }
|
||||
#
|
||||
# QScrollBar:horizontal {
|
||||
# border: none;
|
||||
# background: rgba(30, 41, 59, 0.3);
|
||||
# height: 10px;
|
||||
# border-radius: 5px;
|
||||
# margin: 0;
|
||||
# }
|
||||
#
|
||||
# QScrollBar::handle:horizontal {
|
||||
# background: rgba(59, 130, 246, 0.4);
|
||||
# border-radius: 5px;
|
||||
# min-width: 30px;
|
||||
# }
|
||||
#
|
||||
# QScrollBar::handle:horizontal:hover {
|
||||
# background: rgba(59, 130, 246, 0.6);
|
||||
# }
|
||||
#
|
||||
# QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal {
|
||||
# width: 0px;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 分组框样式 ==================== */
|
||||
# QGroupBox {
|
||||
# border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# border-radius: 8px;
|
||||
# margin-top: 12px;
|
||||
# padding-top: 12px;
|
||||
# color: #60a5fa;
|
||||
# font-weight: bold;
|
||||
# }
|
||||
#
|
||||
# QGroupBox::title {
|
||||
# subcontrol-origin: margin;
|
||||
# subcontrol-position: top left;
|
||||
# padding: 0 8px;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 工具栏样式 ==================== */
|
||||
# QToolBar {
|
||||
# background: rgba(15, 23, 42, 0.8);
|
||||
# border: none;
|
||||
# border-bottom: 2px solid rgba(59, 130, 246, 0.3);
|
||||
# spacing: 8px;
|
||||
# padding: 8px;
|
||||
# }
|
||||
#
|
||||
# QToolBar::separator {
|
||||
# background: rgba(59, 130, 246, 0.3);
|
||||
# width: 1px;
|
||||
# margin: 0 8px;
|
||||
# }
|
||||
#
|
||||
# QToolButton {
|
||||
# background: transparent;
|
||||
# border: none;
|
||||
# border-radius: 4px;
|
||||
# padding: 6px;
|
||||
# color: #e0e6ed;
|
||||
# }
|
||||
#
|
||||
# QToolButton:hover {
|
||||
# background: rgba(59, 130, 246, 0.2);
|
||||
# }
|
||||
#
|
||||
# QToolButton:pressed {
|
||||
# background: rgba(59, 130, 246, 0.3);
|
||||
# }
|
||||
#
|
||||
# /* ==================== 状态栏样式 ==================== */
|
||||
# QStatusBar {
|
||||
# background: rgba(15, 23, 42, 0.8);
|
||||
# border-top: 1px solid rgba(59, 130, 246, 0.2);
|
||||
# color: #94a3b8;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 菜单样式 ==================== */
|
||||
# QMenu {
|
||||
# background: rgba(30, 41, 59, 0.95);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
# border-radius: 8px;
|
||||
# padding: 5px;
|
||||
# }
|
||||
#
|
||||
# QMenu::item {
|
||||
# padding: 8px 30px 8px 20px;
|
||||
# border-radius: 4px;
|
||||
# color: #e0e6ed;
|
||||
# }
|
||||
#
|
||||
# QMenu::item:selected {
|
||||
# background: rgba(59, 130, 246, 0.3);
|
||||
# }
|
||||
#
|
||||
# QMenu::separator {
|
||||
# height: 1px;
|
||||
# background: rgba(59, 130, 246, 0.2);
|
||||
# margin: 5px 10px;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 分割器样式 ==================== */
|
||||
# QSplitter::handle {
|
||||
# background: rgba(59, 130, 246, 0.2);
|
||||
# }
|
||||
#
|
||||
# QSplitter::handle:hover {
|
||||
# background: rgba(59, 130, 246, 0.4);
|
||||
# }
|
||||
#
|
||||
# QSplitter::handle:horizontal {
|
||||
# width: 2px;
|
||||
# }
|
||||
#
|
||||
# QSplitter::handle:vertical {
|
||||
# height: 2px;
|
||||
# }
|
||||
#
|
||||
# /* ==================== 工具提示样式 ==================== */
|
||||
# QToolTip {
|
||||
# background: rgba(30, 41, 59, 0.95);
|
||||
# border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
# border-radius: 6px;
|
||||
# padding: 5px;
|
||||
# color: #e0e6ed;
|
||||
# }
|
||||
# """
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
"""
|
||||
对话框模块
|
||||
"""
|
||||
from .new_project_dialog import NewProjectDialog
|
||||
from .code_view_dialog import CodeViewDialog
|
||||
from .module_detail_dialog import ModuleDetailDialog
|
||||
from .pipeline_dialog import PipelineDialog
|
||||
|
||||
__all__ = [
|
||||
'NewProjectDialog',
|
||||
'CodeViewDialog',
|
||||
'ModuleDetailDialog',
|
||||
'PipelineDialog'
|
||||
]
|
||||
|
|
@ -0,0 +1,351 @@
|
|||
"""
|
||||
代码查看对话框
|
||||
"""
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QTextEdit, QPushButton, QMessageBox, QFileDialog, QApplication
|
||||
)
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
|
||||
class CodeViewDialog(QDialog):
|
||||
"""代码查看对话框"""
|
||||
|
||||
def __init__(self, file_name: str, parent=None):
|
||||
"""
|
||||
初始化对话框
|
||||
|
||||
Args:
|
||||
file_name: 文件名
|
||||
parent: 父窗口
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.file_name = file_name
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
self.setWindowTitle(f"代码查看 - {self.file_name}")
|
||||
self.resize(900, 600)
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSpacing(10)
|
||||
|
||||
# 工具栏
|
||||
toolbar = QHBoxLayout()
|
||||
|
||||
file_label = QLabel(f"📄 {self.file_name}")
|
||||
file_label.setStyleSheet("""
|
||||
font-weight: bold;
|
||||
color: #60a5fa;
|
||||
font-size: 14px;
|
||||
""")
|
||||
toolbar.addWidget(file_label)
|
||||
|
||||
toolbar.addStretch()
|
||||
|
||||
copy_btn = QPushButton("📋 复制代码")
|
||||
copy_btn.clicked.connect(self._copy_code)
|
||||
toolbar.addWidget(copy_btn)
|
||||
|
||||
download_btn = QPushButton("⬇ 下载")
|
||||
download_btn.clicked.connect(self._download_code)
|
||||
toolbar.addWidget(download_btn)
|
||||
|
||||
layout.addLayout(toolbar)
|
||||
|
||||
# 代码编辑器
|
||||
self.code_editor = QTextEdit()
|
||||
self.code_editor.setReadOnly(True)
|
||||
self.code_editor.setStyleSheet("""
|
||||
QTextEdit {
|
||||
background: #1e293b;
|
||||
color: #e0e6ed;
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
""")
|
||||
|
||||
# 生成示例代码
|
||||
sample_code = self._generate_sample_code()
|
||||
self.code_editor.setPlainText(sample_code)
|
||||
|
||||
layout.addWidget(self.code_editor)
|
||||
|
||||
# 关闭按钮
|
||||
close_btn = QPushButton("关闭")
|
||||
close_btn.clicked.connect(self.accept)
|
||||
layout.addWidget(close_btn)
|
||||
|
||||
def _generate_sample_code(self) -> str:
|
||||
"""生成示例代码"""
|
||||
if self.file_name.endswith('.java'):
|
||||
return self._get_java_sample()
|
||||
elif self.file_name.endswith('.py'):
|
||||
return self._get_python_sample()
|
||||
elif self.file_name.endswith('.xml'):
|
||||
return self._get_xml_sample()
|
||||
else:
|
||||
return f"# {self.file_name}\n\n这是一个示例文件的内容。"
|
||||
|
||||
def _get_java_sample(self) -> str:
|
||||
"""获取Java示例代码"""
|
||||
return '''package com.example.project;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
/**
|
||||
* 示例控制器
|
||||
*
|
||||
* @author AI Generator
|
||||
* @version 1.0
|
||||
* @date 2024-01-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1")
|
||||
public class ExampleController {
|
||||
|
||||
@Autowired
|
||||
private ExampleService exampleService;
|
||||
|
||||
/**
|
||||
* 获取数据
|
||||
*
|
||||
* @param id 数据ID
|
||||
* @return 响应结果
|
||||
*/
|
||||
@GetMapping("/data/{id}")
|
||||
public ResponseEntity<DataResponse> getData(@PathVariable Long id) {
|
||||
try {
|
||||
DataResponse data = exampleService.getDataById(id);
|
||||
return ResponseEntity.ok(data);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.internalServerError().build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 响应结果
|
||||
*/
|
||||
@PostMapping("/data")
|
||||
public ResponseEntity<DataResponse> createData(@RequestBody DataRequest request) {
|
||||
DataResponse data = exampleService.createData(request);
|
||||
return ResponseEntity.ok(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据
|
||||
*
|
||||
* @param id 数据ID
|
||||
* @param request 请求参数
|
||||
* @return 响应结果
|
||||
*/
|
||||
@PutMapping("/data/{id}")
|
||||
public ResponseEntity<DataResponse> updateData(
|
||||
@PathVariable Long id,
|
||||
@RequestBody DataRequest request) {
|
||||
DataResponse data = exampleService.updateData(id, request);
|
||||
return ResponseEntity.ok(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*
|
||||
* @param id 数据ID
|
||||
* @return 响应结果
|
||||
*/
|
||||
@DeleteMapping("/data/{id}")
|
||||
public ResponseEntity<Void> deleteData(@PathVariable Long id) {
|
||||
exampleService.deleteData(id);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
}'''
|
||||
|
||||
def _get_python_sample(self) -> str:
|
||||
"""获取Python示例代码"""
|
||||
return '''#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
示例模块
|
||||
|
||||
Author: AI Generator
|
||||
Version: 1.0
|
||||
Date: 2024-01-15
|
||||
"""
|
||||
|
||||
from flask import Flask, jsonify, request
|
||||
from typing import Dict, Any
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route('/api/v1/data/<int:data_id>', methods=['GET'])
|
||||
def get_data(data_id: int) -> Dict[str, Any]:
|
||||
"""
|
||||
获取数据
|
||||
|
||||
Args:
|
||||
data_id: 数据ID
|
||||
|
||||
Returns:
|
||||
响应数据
|
||||
"""
|
||||
try:
|
||||
# 实现逻辑
|
||||
return jsonify({
|
||||
'id': data_id,
|
||||
'status': 'success',
|
||||
'data': {}
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@app.route('/api/v1/data', methods=['POST'])
|
||||
def create_data() -> Dict[str, Any]:
|
||||
"""
|
||||
创建数据
|
||||
|
||||
Returns:
|
||||
响应数据
|
||||
"""
|
||||
data = request.get_json()
|
||||
|
||||
# 实现逻辑
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'data': data
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/v1/data/<int:data_id>', methods=['PUT'])
|
||||
def update_data(data_id: int) -> Dict[str, Any]:
|
||||
"""
|
||||
更新数据
|
||||
|
||||
Args:
|
||||
data_id: 数据ID
|
||||
|
||||
Returns:
|
||||
响应数据
|
||||
"""
|
||||
data = request.get_json()
|
||||
|
||||
# 实现逻辑
|
||||
return jsonify({
|
||||
'id': data_id,
|
||||
'status': 'success',
|
||||
'data': data
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/v1/data/<int:data_id>', methods=['DELETE'])
|
||||
def delete_data(data_id: int) -> Dict[str, Any]:
|
||||
"""
|
||||
删除数据
|
||||
|
||||
Args:
|
||||
data_id: 数据ID
|
||||
|
||||
Returns:
|
||||
响应数据
|
||||
"""
|
||||
# 实现逻辑
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'message': 'Data deleted'
|
||||
})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)'''
|
||||
|
||||
def _get_xml_sample(self) -> str:
|
||||
"""获取XML示例代码"""
|
||||
return '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>lowcode-project</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>LowCode Project</name>
|
||||
<description>AI Generated Project</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>'''
|
||||
|
||||
def _copy_code(self):
|
||||
"""复制代码"""
|
||||
clipboard = QApplication.clipboard()
|
||||
clipboard.setText(self.code_editor.toPlainText())
|
||||
QMessageBox.information(self, "复制", "代码已复制到剪贴板")
|
||||
|
||||
def _download_code(self):
|
||||
"""下载代码"""
|
||||
file_path, _ = QFileDialog.getSaveFileName(
|
||||
self,
|
||||
"保存代码",
|
||||
self.file_name
|
||||
)
|
||||
|
||||
if file_path:
|
||||
try:
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
f.write(self.code_editor.toPlainText())
|
||||
QMessageBox.information(self, "下载", f"代码已保存到:\n{file_path}")
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "错误", f"保存失败:\n{str(e)}")
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
"""
|
||||
模块详情对话框
|
||||
"""
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QPushButton, QProgressBar, QGroupBox
|
||||
)
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
|
||||
class ModuleDetailDialog(QDialog):
|
||||
"""模块详情对话框"""
|
||||
|
||||
def __init__(self, module, parent=None):
|
||||
"""
|
||||
初始化对话框
|
||||
|
||||
Args:
|
||||
module: 模块对象
|
||||
parent: 父窗口
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.module = module
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
self.setWindowTitle(f"模块详情 - {self.module.name}")
|
||||
self.resize(600, 500)
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSpacing(20)
|
||||
|
||||
# 模块标题
|
||||
title_label = QLabel(f"<h2>{self.module.icon} {self.module.name}</h2>")
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 基本信息组
|
||||
basic_group = self._create_basic_info_group()
|
||||
layout.addWidget(basic_group)
|
||||
|
||||
# 关联需求组
|
||||
req_group = self._create_requirements_group()
|
||||
layout.addWidget(req_group)
|
||||
|
||||
# 技术栈组
|
||||
tech_group = self._create_tech_stack_group()
|
||||
layout.addWidget(tech_group)
|
||||
|
||||
# 开发进度组
|
||||
progress_group = self._create_progress_group()
|
||||
layout.addWidget(progress_group)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# 关闭按钮
|
||||
button_layout = QHBoxLayout()
|
||||
button_layout.addStretch()
|
||||
|
||||
close_btn = QPushButton("关闭")
|
||||
close_btn.setMinimumWidth(100)
|
||||
close_btn.clicked.connect(self.accept)
|
||||
button_layout.addWidget(close_btn)
|
||||
|
||||
layout.addLayout(button_layout)
|
||||
|
||||
def _create_basic_info_group(self) -> QGroupBox:
|
||||
"""创建基本信息组"""
|
||||
group = QGroupBox("基本信息")
|
||||
layout = QVBoxLayout(group)
|
||||
|
||||
# 描述
|
||||
desc_label = QLabel(f"<b>描述:</b><br>{self.module.description}")
|
||||
desc_label.setWordWrap(True)
|
||||
desc_label.setStyleSheet("color: #e0e6ed; padding: 5px;")
|
||||
layout.addWidget(desc_label)
|
||||
|
||||
return group
|
||||
|
||||
def _create_requirements_group(self) -> QGroupBox:
|
||||
"""创建关联需求组"""
|
||||
group = QGroupBox("关联需求")
|
||||
layout = QVBoxLayout(group)
|
||||
|
||||
if self.module.requirements:
|
||||
req_layout = QHBoxLayout()
|
||||
req_layout.setSpacing(8)
|
||||
|
||||
for req_id in self.module.requirements:
|
||||
req_label = QLabel(req_id)
|
||||
req_label.setStyleSheet("""
|
||||
background: #3b82f633;
|
||||
color: #3b82f6;
|
||||
border: 1px solid #3b82f6;
|
||||
border-radius: 4px;
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
""")
|
||||
req_layout.addWidget(req_label)
|
||||
|
||||
req_layout.addStretch()
|
||||
layout.addLayout(req_layout)
|
||||
else:
|
||||
no_req_label = QLabel("暂无关联需求")
|
||||
no_req_label.setStyleSheet("color: #94a3b8;")
|
||||
layout.addWidget(no_req_label)
|
||||
|
||||
return group
|
||||
|
||||
def _create_tech_stack_group(self) -> QGroupBox:
|
||||
"""创建技术栈组"""
|
||||
group = QGroupBox("技术栈")
|
||||
layout = QVBoxLayout(group)
|
||||
|
||||
if self.module.tech_stack:
|
||||
tech_layout = QHBoxLayout()
|
||||
tech_layout.setSpacing(8)
|
||||
|
||||
for tech in self.module.tech_stack:
|
||||
tech_label = QLabel(tech)
|
||||
tech_label.setStyleSheet("""
|
||||
background: rgba(100, 116, 139, 0.3);
|
||||
color: #94a3b8;
|
||||
border: 1px solid rgba(100, 116, 139, 0.5);
|
||||
border-radius: 4px;
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
""")
|
||||
tech_layout.addWidget(tech_label)
|
||||
|
||||
tech_layout.addStretch()
|
||||
layout.addLayout(tech_layout)
|
||||
else:
|
||||
no_tech_label = QLabel("暂无技术栈信息")
|
||||
no_tech_label.setStyleSheet("color: #94a3b8;")
|
||||
layout.addWidget(no_tech_label)
|
||||
|
||||
return group
|
||||
|
||||
def _create_progress_group(self) -> QGroupBox:
|
||||
"""创建开发进度组"""
|
||||
group = QGroupBox("开发进度")
|
||||
layout = QVBoxLayout(group)
|
||||
|
||||
# 进度条
|
||||
progress = QProgressBar()
|
||||
progress.setValue(self.module.progress)
|
||||
progress.setTextVisible(True)
|
||||
progress.setFormat(f"{self.module.progress}%")
|
||||
layout.addWidget(progress)
|
||||
|
||||
# 状态说明
|
||||
if self.module.progress == 0:
|
||||
status_text = "尚未开始"
|
||||
status_color = "#94a3b8"
|
||||
elif self.module.progress < 100:
|
||||
status_text = "开发中"
|
||||
status_color = "#3b82f6"
|
||||
else:
|
||||
status_text = "已完成"
|
||||
status_color = "#10b981"
|
||||
|
||||
status_label = QLabel(f"状态: {status_text}")
|
||||
status_label.setStyleSheet(f"color: {status_color}; font-weight: bold;")
|
||||
layout.addWidget(status_label)
|
||||
|
||||
return group
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
"""
|
||||
新建项目对话框
|
||||
"""
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QLineEdit, QTextEdit, QPushButton, QMessageBox
|
||||
)
|
||||
from PyQt5.QtCore import Qt
|
||||
from models import Project, Requirement, Module, Document
|
||||
|
||||
|
||||
class NewProjectDialog(QDialog):
|
||||
"""新建项目对话框"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
初始化对话框
|
||||
|
||||
Args:
|
||||
parent: 父窗口
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.project = None
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
self.setWindowTitle("新建项目")
|
||||
self.setModal(True)
|
||||
self.resize(700, 500)
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSpacing(15)
|
||||
|
||||
# 标题
|
||||
title_label = QLabel("<h2>📁 新建项目</h2>")
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 项目名称
|
||||
layout.addWidget(QLabel("项目名称 *"))
|
||||
self.name_edit = QLineEdit()
|
||||
self.name_edit.setPlaceholderText("请输入项目名称")
|
||||
layout.addWidget(self.name_edit)
|
||||
|
||||
# 项目描述
|
||||
layout.addWidget(QLabel("项目描述"))
|
||||
self.desc_edit = QTextEdit()
|
||||
self.desc_edit.setPlaceholderText("请输入项目描述(可选)")
|
||||
self.desc_edit.setMaximumHeight(80)
|
||||
layout.addWidget(self.desc_edit)
|
||||
|
||||
# 需求描述
|
||||
layout.addWidget(QLabel("需求描述 *"))
|
||||
self.req_edit = QTextEdit()
|
||||
self.req_edit.setPlaceholderText(
|
||||
"请输入项目需求...\n\n"
|
||||
"建议格式:\n"
|
||||
"1. 功能描述\n"
|
||||
"2. 性能要求\n"
|
||||
"3. 安全要求"
|
||||
)
|
||||
layout.addWidget(self.req_edit)
|
||||
|
||||
# 按钮区域
|
||||
button_layout = QHBoxLayout()
|
||||
button_layout.addStretch()
|
||||
|
||||
cancel_btn = QPushButton("取消")
|
||||
cancel_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background: rgba(51, 65, 85, 0.5);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
""")
|
||||
cancel_btn.clicked.connect(self.reject)
|
||||
button_layout.addWidget(cancel_btn)
|
||||
|
||||
create_btn = QPushButton("创建项目")
|
||||
create_btn.clicked.connect(self._create_project)
|
||||
button_layout.addWidget(create_btn)
|
||||
|
||||
layout.addLayout(button_layout)
|
||||
|
||||
def _create_project(self):
|
||||
"""创建项目"""
|
||||
# 验证输入
|
||||
name = self.name_edit.text().strip()
|
||||
if not name:
|
||||
QMessageBox.warning(self, "提示", "请输入项目名称")
|
||||
return
|
||||
|
||||
req_text = self.req_edit.toPlainText().strip()
|
||||
if not req_text:
|
||||
QMessageBox.warning(self, "提示", "请输入需求描述")
|
||||
return
|
||||
|
||||
# 创建项目对象
|
||||
self.project = Project(
|
||||
name=name,
|
||||
description=self.desc_edit.toPlainText().strip()
|
||||
)
|
||||
self.project.original_requirement = req_text
|
||||
|
||||
# 模拟生成需求
|
||||
self._generate_requirements()
|
||||
|
||||
# 模拟生成模块
|
||||
self._generate_modules()
|
||||
|
||||
# 模拟生成文档
|
||||
self._generate_documents()
|
||||
|
||||
self.accept()
|
||||
|
||||
def _generate_requirements(self):
|
||||
"""生成需求(模拟AI分析)"""
|
||||
requirements = [
|
||||
Requirement("REQ-001", "核心功能", "从需求文本提取的核心功能", 90, "高"),
|
||||
Requirement("REQ-002", "数据管理", "数据的增删改查功能", 85, "中"),
|
||||
Requirement("REQ-003", "用户管理", "用户认证和权限管理", 88, "高")
|
||||
]
|
||||
|
||||
for req in requirements:
|
||||
self.project.add_requirement(req)
|
||||
|
||||
def _generate_modules(self):
|
||||
"""生成模块(模拟AI生成)"""
|
||||
modules = [
|
||||
Module("核心业务模块", "实现主要业务逻辑", ["REQ-001"]),
|
||||
Module("数据管理模块", "数据存储和查询", ["REQ-002"]),
|
||||
Module("用户认证模块", "用户登录和权限控制", ["REQ-003"])
|
||||
]
|
||||
|
||||
for module in modules:
|
||||
module.add_tech("Spring Boot")
|
||||
module.add_tech("MySQL")
|
||||
module.add_tech("Redis")
|
||||
self.project.add_module(module)
|
||||
|
||||
def _generate_documents(self):
|
||||
"""生成文档"""
|
||||
documents = [
|
||||
Document("需求规格说明书.docx", "SRS", "1.5 MB"),
|
||||
Document("功能设计文档.docx", "功能设计", "1.2 MB"),
|
||||
Document("接口文档.pdf", "API", "800 KB")
|
||||
]
|
||||
|
||||
for doc in documents:
|
||||
self.project.add_document(doc)
|
||||
|
||||
def get_project(self):
|
||||
"""获取创建的项目"""
|
||||
return self.project
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
"""
|
||||
流水线执行对话框
|
||||
"""
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QTextEdit, QPushButton, QProgressBar, QFrame, QMessageBox
|
||||
)
|
||||
from PyQt5.QtCore import Qt, QTimer
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class PipelineDialog(QDialog):
|
||||
"""流水线执行对话框"""
|
||||
|
||||
def __init__(self, project, parent=None):
|
||||
"""
|
||||
初始化对话框
|
||||
|
||||
Args:
|
||||
project: 项目对象
|
||||
parent: 父窗口
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.project = project
|
||||
self.current_step = 0
|
||||
self.timer = None
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
self.setWindowTitle(f"流水线 - {self.project.name}")
|
||||
self.resize(1000, 600)
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSpacing(15)
|
||||
|
||||
# 标题
|
||||
title_label = QLabel(f"<h2>🚀 项目流水线 - {self.project.name}</h2>")
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 流水线步骤
|
||||
steps_layout = QHBoxLayout()
|
||||
steps_layout.setSpacing(10)
|
||||
|
||||
self.step_widgets = []
|
||||
steps = [
|
||||
("🔍", "静态扫描", "SonarQube"),
|
||||
("🔨", "编译构建", "Maven"),
|
||||
("📦", "打包", "JAR"),
|
||||
("🚀", "部署", "测试环境"),
|
||||
("✅", "验证测试", "JUnit")
|
||||
]
|
||||
|
||||
for icon, name, tool in steps:
|
||||
step_widget = self._create_step_widget(icon, name, tool)
|
||||
self.step_widgets.append(step_widget)
|
||||
steps_layout.addWidget(step_widget)
|
||||
|
||||
layout.addLayout(steps_layout)
|
||||
|
||||
# 日志输出区域
|
||||
log_label = QLabel("<b>执行日志:</b>")
|
||||
layout.addWidget(log_label)
|
||||
|
||||
self.log_text = QTextEdit()
|
||||
self.log_text.setReadOnly(True)
|
||||
self.log_text.setStyleSheet("""
|
||||
QTextEdit {
|
||||
background: #1e293b;
|
||||
color: #10b981;
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 12px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
}
|
||||
""")
|
||||
layout.addWidget(self.log_text)
|
||||
|
||||
# 总体进度条
|
||||
self.progress = QProgressBar()
|
||||
self.progress.setTextVisible(True)
|
||||
self.progress.setFormat("%p%")
|
||||
layout.addWidget(self.progress)
|
||||
|
||||
# 按钮区域
|
||||
button_layout = QHBoxLayout()
|
||||
button_layout.addStretch()
|
||||
|
||||
self.start_btn = QPushButton("▶ 启动流水线")
|
||||
self.start_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
stop:0 #10b981, stop:1 #059669);
|
||||
}
|
||||
""")
|
||||
self.start_btn.setMinimumWidth(120)
|
||||
self.start_btn.clicked.connect(self._start_pipeline)
|
||||
button_layout.addWidget(self.start_btn)
|
||||
|
||||
self.stop_btn = QPushButton("⏹ 停止")
|
||||
self.stop_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
stop:0 #ef4444, stop:1 #dc2626);
|
||||
}
|
||||
""")
|
||||
self.stop_btn.setMinimumWidth(120)
|
||||
self.stop_btn.setEnabled(False)
|
||||
self.stop_btn.clicked.connect(self._stop_pipeline)
|
||||
button_layout.addWidget(self.stop_btn)
|
||||
|
||||
close_btn = QPushButton("关闭")
|
||||
close_btn.setMinimumWidth(120)
|
||||
close_btn.clicked.connect(self.accept)
|
||||
button_layout.addWidget(close_btn)
|
||||
|
||||
layout.addLayout(button_layout)
|
||||
|
||||
def _create_step_widget(self, icon: str, name: str, tool: str) -> QFrame:
|
||||
"""创建步骤组件"""
|
||||
widget = QFrame()
|
||||
widget.setFrameShape(QFrame.StyledPanel)
|
||||
widget.setStyleSheet("""
|
||||
QFrame {
|
||||
background: rgba(51, 65, 85, 0.4);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
}
|
||||
""")
|
||||
|
||||
layout = QVBoxLayout(widget)
|
||||
layout.setAlignment(Qt.AlignCenter)
|
||||
layout.setSpacing(8)
|
||||
|
||||
# 图标
|
||||
icon_label = QLabel(icon)
|
||||
icon_label.setStyleSheet("font-size: 36px;")
|
||||
icon_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(icon_label)
|
||||
|
||||
# 步骤名称
|
||||
name_label = QLabel(name)
|
||||
name_label.setStyleSheet("""
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #e0e6ed;
|
||||
""")
|
||||
name_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(name_label)
|
||||
|
||||
# 工具名称
|
||||
tool_label = QLabel(tool)
|
||||
tool_label.setStyleSheet("""
|
||||
color: #94a3b8;
|
||||
font-size: 11px;
|
||||
""")
|
||||
tool_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(tool_label)
|
||||
|
||||
# 状态标签
|
||||
status_label = QLabel("就绪")
|
||||
status_label.setObjectName("status_label")
|
||||
status_label.setStyleSheet("""
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
""")
|
||||
status_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(status_label)
|
||||
|
||||
return widget
|
||||
|
||||
def _start_pipeline(self):
|
||||
"""启动流水线"""
|
||||
self.start_btn.setEnabled(False)
|
||||
self.stop_btn.setEnabled(True)
|
||||
self.current_step = 0
|
||||
self.progress.setValue(0)
|
||||
self.log_text.clear()
|
||||
|
||||
self._add_log("[INFO] ========================================")
|
||||
self._add_log(f"[INFO] 流水线启动 - 项目: {self.project.name}")
|
||||
self._add_log("[INFO] ========================================")
|
||||
|
||||
# 使用定时器模拟流水线执行
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self._update_pipeline)
|
||||
self.timer.start(1500) # 每1.5秒执行一步
|
||||
|
||||
def _update_pipeline(self):
|
||||
"""更新流水线状态"""
|
||||
if self.current_step < len(self.step_widgets):
|
||||
widget = self.step_widgets[self.current_step]
|
||||
|
||||
# 更新为进行中状态
|
||||
widget.setStyleSheet("""
|
||||
QFrame {
|
||||
background: rgba(59, 130, 246, 0.3);
|
||||
border: 2px solid #3b82f6;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
}
|
||||
""")
|
||||
|
||||
# 更新状态标签
|
||||
status_label = widget.findChild(QLabel, "status_label")
|
||||
if status_label:
|
||||
status_label.setText("进行中...")
|
||||
status_label.setStyleSheet("""
|
||||
color: #3b82f6;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
""")
|
||||
|
||||
# 添加日志
|
||||
step_names = ["静态扫描", "编译构建", "打包", "部署", "验证测试"]
|
||||
self._add_log(f"[INFO] 开始执行: {step_names[self.current_step]}")
|
||||
self._add_log(f"[INFO] 步骤 {self.current_step + 1}/{len(self.step_widgets)}")
|
||||
|
||||
# 更新进度条
|
||||
progress_value = int((self.current_step + 1) / len(self.step_widgets) * 100)
|
||||
self.progress.setValue(progress_value)
|
||||
|
||||
# 延迟标记为完成
|
||||
QTimer.singleShot(1000, lambda: self._complete_step(self.current_step))
|
||||
|
||||
self.current_step += 1
|
||||
else:
|
||||
self.timer.stop()
|
||||
self._finish_pipeline()
|
||||
|
||||
def _complete_step(self, step_index: int):
|
||||
"""完成步骤"""
|
||||
if step_index < len(self.step_widgets):
|
||||
widget = self.step_widgets[step_index]
|
||||
|
||||
# 更新为完成状态
|
||||
widget.setStyleSheet("""
|
||||
QFrame {
|
||||
background: rgba(16, 185, 129, 0.2);
|
||||
border: 2px solid #10b981;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
}
|
||||
""")
|
||||
|
||||
# 更新状态标签
|
||||
status_label = widget.findChild(QLabel, "status_label")
|
||||
if status_label:
|
||||
status_label.setText("✓ 完成")
|
||||
status_label.setStyleSheet("""
|
||||
color: #10b981;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
""")
|
||||
|
||||
# 添加完成日志
|
||||
step_names = ["静态扫描", "编译构建", "打包", "部署", "验证测试"]
|
||||
self._add_log(f"[SUCCESS] {step_names[step_index]} 完成")
|
||||
self._add_log("")
|
||||
|
||||
def _finish_pipeline(self):
|
||||
"""完成流水线"""
|
||||
self._add_log("[INFO] ========================================")
|
||||
self._add_log("[SUCCESS] 流水线执行完成!")
|
||||
self._add_log(f"[INFO] 项目: {self.project.name}")
|
||||
self._add_log("[INFO] 所有步骤已成功执行")
|
||||
self._add_log("[INFO] ========================================")
|
||||
|
||||
self.start_btn.setEnabled(True)
|
||||
self.stop_btn.setEnabled(False)
|
||||
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"完成",
|
||||
f"流水线执行完成!\n\n项目: {self.project.name}\n所有步骤已成功执行。"
|
||||
)
|
||||
|
||||
def _stop_pipeline(self):
|
||||
"""停止流水线"""
|
||||
if self.timer:
|
||||
self.timer.stop()
|
||||
|
||||
self._add_log("")
|
||||
self._add_log("[WARNING] ========================================")
|
||||
self._add_log("[WARNING] 流水线已被用户停止")
|
||||
self._add_log("[WARNING] ========================================")
|
||||
|
||||
self.start_btn.setEnabled(True)
|
||||
self.stop_btn.setEnabled(False)
|
||||
|
||||
def _add_log(self, message: str):
|
||||
"""添加日志"""
|
||||
timestamp = datetime.now().strftime("%H:%M:%S")
|
||||
self.log_text.append(f"[{timestamp}] {message}")
|
||||
|
||||
# 自动滚动到底部
|
||||
scrollbar = self.log_text.verticalScrollBar()
|
||||
scrollbar.setValue(scrollbar.maximum())
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,53 @@
|
|||
"""
|
||||
智能低代码开发平台 - 主程序入口
|
||||
|
||||
使用方法:
|
||||
python main.py
|
||||
|
||||
依赖:
|
||||
pip install PyQt5
|
||||
"""
|
||||
|
||||
import sys
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtGui import QFont
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from config import DARK_THEME
|
||||
from windows import MainWindow
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 创建应用程序
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# 设置应用程序信息
|
||||
app.setApplicationName("智能低代码开发平台")
|
||||
app.setApplicationVersion("1.0.0")
|
||||
app.setOrganizationName("AI Development Team")
|
||||
|
||||
# 设置样式
|
||||
app.setStyle("Fusion")
|
||||
|
||||
# 应用深色主题
|
||||
app.setStyleSheet(DARK_THEME)
|
||||
|
||||
# 设置默认字体
|
||||
font = QFont("Microsoft YaHei", 10)
|
||||
app.setFont(font)
|
||||
|
||||
# 启用高DPI支持
|
||||
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
|
||||
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
|
||||
|
||||
# 创建并显示主窗口
|
||||
window = MainWindow()
|
||||
window.show()
|
||||
|
||||
# 运行应用程序
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
"""
|
||||
数据模型模块
|
||||
"""
|
||||
from .project import Project
|
||||
from .requirement import Requirement
|
||||
from .module import Module
|
||||
from .document import Document
|
||||
|
||||
__all__ = ['Project', 'Requirement', 'Module', 'Document']
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
"""
|
||||
文档模型
|
||||
"""
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any
|
||||
|
||||
|
||||
class Document:
|
||||
"""文档数据模型"""
|
||||
|
||||
def __init__(self, name: str, doc_type: str, size: str = "0 KB"):
|
||||
"""
|
||||
初始化文档
|
||||
|
||||
Args:
|
||||
name: 文档名称
|
||||
doc_type: 文档类型
|
||||
size: 文件大小
|
||||
"""
|
||||
self.name = name
|
||||
self.doc_type = doc_type
|
||||
self.size = size
|
||||
self.created_at = datetime.now()
|
||||
self.icon = self._get_icon()
|
||||
|
||||
def _get_icon(self) -> str:
|
||||
"""根据文档类型获取图标"""
|
||||
icon_map = {
|
||||
'SRS': '📄',
|
||||
'功能设计': '📋',
|
||||
'概要设计': '🏗️',
|
||||
'详细设计': '📐',
|
||||
'API': '📖',
|
||||
'数据库': '🗄️',
|
||||
'测试': '✅',
|
||||
'用户手册': '📚'
|
||||
}
|
||||
return icon_map.get(self.doc_type, '📄')
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""转换为字典"""
|
||||
return {
|
||||
'name': self.name,
|
||||
'type': self.doc_type,
|
||||
'size': self.size,
|
||||
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M')
|
||||
}
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.icon} {self.name}"
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
"""
|
||||
功能模块模型
|
||||
"""
|
||||
from typing import List, Dict, Any
|
||||
|
||||
|
||||
class Module:
|
||||
"""功能模块数据模型"""
|
||||
|
||||
def __init__(self, name: str, description: str, requirements: List[str] = None):
|
||||
"""
|
||||
初始化模块
|
||||
|
||||
Args:
|
||||
name: 模块名称
|
||||
description: 模块描述
|
||||
requirements: 关联的需求ID列表
|
||||
"""
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.requirements = requirements or []
|
||||
self.tech_stack = []
|
||||
self.progress = 0
|
||||
self.icon = "🔧"
|
||||
|
||||
def add_requirement(self, req_id: str):
|
||||
"""添加关联需求"""
|
||||
if req_id not in self.requirements:
|
||||
self.requirements.append(req_id)
|
||||
|
||||
def add_tech(self, tech: str):
|
||||
"""添加技术栈"""
|
||||
if tech not in self.tech_stack:
|
||||
self.tech_stack.append(tech)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""转换为字典"""
|
||||
return {
|
||||
'name': self.name,
|
||||
'description': self.description,
|
||||
'requirements': self.requirements,
|
||||
'tech_stack': self.tech_stack,
|
||||
'progress': self.progress
|
||||
}
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.icon} {self.name}"
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
"""
|
||||
项目模型
|
||||
"""
|
||||
from datetime import datetime
|
||||
from typing import List, Dict, Any
|
||||
from .requirement import Requirement
|
||||
from .module import Module
|
||||
from .document import Document
|
||||
|
||||
|
||||
class Project:
|
||||
"""项目数据模型"""
|
||||
|
||||
def __init__(self, name: str, description: str = "", status: str = "进行中"):
|
||||
"""
|
||||
初始化项目
|
||||
|
||||
Args:
|
||||
name: 项目名称
|
||||
description: 项目描述
|
||||
status: 项目状态 (进行中/已完成/已暂停)
|
||||
"""
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.status = status
|
||||
self.created_at = datetime.now()
|
||||
self.requirements: List[Requirement] = []
|
||||
self.modules: List[Module] = []
|
||||
self.documents: List[Document] = []
|
||||
self.original_requirement = ""
|
||||
self.project_type = "Java Spring Boot"
|
||||
|
||||
def add_requirement(self, requirement: Requirement):
|
||||
"""添加需求"""
|
||||
self.requirements.append(requirement)
|
||||
|
||||
def add_module(self, module: Module):
|
||||
"""添加模块"""
|
||||
self.modules.append(module)
|
||||
|
||||
def add_document(self, document: Document):
|
||||
"""添加文档"""
|
||||
self.documents.append(document)
|
||||
|
||||
def get_requirement_count(self) -> int:
|
||||
"""获取需求数量"""
|
||||
return len(self.requirements)
|
||||
|
||||
def get_module_count(self) -> int:
|
||||
"""获取模块数量"""
|
||||
return len(self.modules)
|
||||
|
||||
def get_document_count(self) -> int:
|
||||
"""获取文档数量"""
|
||||
return len(self.documents)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""转换为字典"""
|
||||
return {
|
||||
'name': self.name,
|
||||
'description': self.description,
|
||||
'status': self.status,
|
||||
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M'),
|
||||
'requirements': [r.to_dict() for r in self.requirements],
|
||||
'modules': [m.to_dict() for m in self.modules],
|
||||
'documents': [d.to_dict() for d in self.documents],
|
||||
'project_type': self.project_type
|
||||
}
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Project: {self.name} ({self.status})"
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
"""
|
||||
需求模型
|
||||
"""
|
||||
from typing import Dict, Any
|
||||
|
||||
|
||||
class Requirement:
|
||||
"""需求数据模型"""
|
||||
|
||||
def __init__(self, req_id: str, title: str, description: str,
|
||||
confidence: int = 0, priority: str = "中"):
|
||||
"""
|
||||
初始化需求
|
||||
|
||||
Args:
|
||||
req_id: 需求ID
|
||||
title: 需求标题
|
||||
description: 需求描述
|
||||
confidence: 置信度 (0-100)
|
||||
priority: 优先级 (高/中/低)
|
||||
"""
|
||||
self.req_id = req_id
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.confidence = confidence
|
||||
self.priority = priority
|
||||
self.checked = True
|
||||
self.req_type = "功能性"
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""转换为字典"""
|
||||
return {
|
||||
'req_id': self.req_id,
|
||||
'title': self.title,
|
||||
'description': self.description,
|
||||
'confidence': self.confidence,
|
||||
'priority': self.priority,
|
||||
'type': self.req_type
|
||||
}
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.req_id}: {self.title}"
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
"""
|
||||
自定义组件模块
|
||||
"""
|
||||
from .panel_widget import PanelWidget
|
||||
from .project_item import ProjectItemWidget
|
||||
from .requirement_item import RequirementItemWidget
|
||||
from .module_item import ModuleItemWidget
|
||||
|
||||
__all__ = [
|
||||
'PanelWidget',
|
||||
'ProjectItemWidget',
|
||||
'RequirementItemWidget',
|
||||
'ModuleItemWidget'
|
||||
]
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
"""
|
||||
模块列表项组件
|
||||
"""
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
|
||||
class ModuleItemWidget(QWidget):
|
||||
"""模块列表项组件"""
|
||||
|
||||
def __init__(self, module, parent=None):
|
||||
"""
|
||||
初始化模块列表项
|
||||
|
||||
Args:
|
||||
module: 模块对象
|
||||
parent: 父组件
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.module = module
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(15, 15, 15, 15)
|
||||
layout.setSpacing(10)
|
||||
|
||||
# 模块标题
|
||||
title_label = QLabel(f"{self.module.icon} {self.module.name}")
|
||||
title_label.setStyleSheet("""
|
||||
font-weight: bold;
|
||||
color: #60a5fa;
|
||||
font-size: 14px;
|
||||
""")
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 模块描述
|
||||
desc_label = QLabel(self.module.description)
|
||||
desc_label.setStyleSheet("""
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
""")
|
||||
desc_label.setWordWrap(True)
|
||||
layout.addWidget(desc_label)
|
||||
|
||||
# 需求标签
|
||||
if self.module.requirements:
|
||||
req_layout = QHBoxLayout()
|
||||
req_layout.setSpacing(5)
|
||||
|
||||
for req_id in self.module.requirements[:3]: # 最多显示3个
|
||||
req_label = QLabel(req_id)
|
||||
req_label.setStyleSheet("""
|
||||
background: #3b82f633;
|
||||
color: #3b82f6;
|
||||
border: 1px solid #3b82f6;
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
""")
|
||||
req_layout.addWidget(req_label)
|
||||
|
||||
req_layout.addStretch()
|
||||
layout.addLayout(req_layout)
|
||||
|
||||
# 技术栈标签
|
||||
if self.module.tech_stack:
|
||||
tech_layout = QHBoxLayout()
|
||||
tech_layout.setSpacing(5)
|
||||
|
||||
for tech in self.module.tech_stack[:3]: # 最多显示3个
|
||||
tech_label = QLabel(tech)
|
||||
tech_label.setStyleSheet("""
|
||||
background: rgba(100, 116, 139, 0.3);
|
||||
color: #94a3b8;
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
""")
|
||||
tech_layout.addWidget(tech_label)
|
||||
|
||||
tech_layout.addStretch()
|
||||
layout.addLayout(tech_layout)
|
||||
|
||||
# 设置整体样式
|
||||
self.setStyleSheet("""
|
||||
QWidget {
|
||||
background: rgba(51, 65, 85, 0.3);
|
||||
border: 1px solid rgba(59, 130, 246, 0.15);
|
||||
border-radius: 8px;
|
||||
}
|
||||
QWidget:hover {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
""")
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
"""
|
||||
面板组件
|
||||
"""
|
||||
from PyQt5.QtWidgets import QFrame, QVBoxLayout, QLabel
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
|
||||
class PanelWidget(QFrame):
|
||||
"""面板组件 - 带标题的容器"""
|
||||
|
||||
def __init__(self, title: str = "", parent=None):
|
||||
"""
|
||||
初始化面板
|
||||
|
||||
Args:
|
||||
title: 面板标题
|
||||
parent: 父组件
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.title = title
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
# 设置框架样式
|
||||
self.setFrameShape(QFrame.StyledPanel)
|
||||
|
||||
# 创建布局
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(15, 15, 15, 15)
|
||||
layout.setSpacing(10)
|
||||
|
||||
# 添加标题
|
||||
if self.title:
|
||||
title_label = QLabel(self.title)
|
||||
title_label.setStyleSheet("""
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #60a5fa;
|
||||
margin-bottom: 5px;
|
||||
""")
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 添加分隔线
|
||||
line = QFrame()
|
||||
line.setFrameShape(QFrame.HLine)
|
||||
line.setStyleSheet("""
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
max-height: 1px;
|
||||
margin-bottom: 10px;
|
||||
""")
|
||||
layout.addWidget(line)
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
"""
|
||||
项目列表项组件
|
||||
"""
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel
|
||||
from PyQt5.QtCore import pyqtSignal, Qt
|
||||
|
||||
|
||||
class ProjectItemWidget(QWidget):
|
||||
"""项目列表项组件"""
|
||||
|
||||
clicked = pyqtSignal(object) # 点击信号
|
||||
|
||||
def __init__(self, project, parent=None):
|
||||
"""
|
||||
初始化项目列表项
|
||||
|
||||
Args:
|
||||
project: 项目对象
|
||||
parent: 父组件
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.project = project
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(12, 12, 12, 12)
|
||||
layout.setSpacing(8)
|
||||
|
||||
# 项目名称
|
||||
name_label = QLabel(self.project.name)
|
||||
name_label.setStyleSheet("""
|
||||
font-weight: bold;
|
||||
color: #60a5fa;
|
||||
font-size: 14px;
|
||||
""")
|
||||
layout.addWidget(name_label)
|
||||
|
||||
# 项目描述
|
||||
desc_label = QLabel(self.project.description or "暂无描述")
|
||||
desc_label.setStyleSheet("""
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
""")
|
||||
desc_label.setWordWrap(True)
|
||||
layout.addWidget(desc_label)
|
||||
|
||||
# 底部信息
|
||||
bottom_layout = QHBoxLayout()
|
||||
bottom_layout.setSpacing(10)
|
||||
|
||||
# 创建时间
|
||||
time_label = QLabel(self.project.created_at.strftime('%Y-%m-%d'))
|
||||
time_label.setStyleSheet("""
|
||||
color: #64748b;
|
||||
font-size: 11px;
|
||||
""")
|
||||
bottom_layout.addWidget(time_label)
|
||||
|
||||
bottom_layout.addStretch()
|
||||
|
||||
# 状态标签
|
||||
status_label = self._create_status_label()
|
||||
bottom_layout.addWidget(status_label)
|
||||
|
||||
layout.addLayout(bottom_layout)
|
||||
|
||||
# 设置整体样式
|
||||
self.setStyleSheet("""
|
||||
QWidget {
|
||||
background: rgba(51, 65, 85, 0.4);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
border-radius: 8px;
|
||||
}
|
||||
QWidget:hover {
|
||||
background: rgba(59, 130, 246, 0.15);
|
||||
border-color: rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
""")
|
||||
|
||||
def _create_status_label(self) -> QLabel:
|
||||
"""创建状态标签"""
|
||||
status_colors = {
|
||||
"进行中": "#10b981",
|
||||
"已完成": "#3b82f6",
|
||||
"已暂停": "#f59e0b"
|
||||
}
|
||||
color = status_colors.get(self.project.status, "#94a3b8")
|
||||
|
||||
status_label = QLabel(self.project.status)
|
||||
status_label.setStyleSheet(f"""
|
||||
background: {color}33;
|
||||
color: {color};
|
||||
border: 1px solid {color};
|
||||
border-radius: 4px;
|
||||
padding: 2px 8px;
|
||||
font-size: 10px;
|
||||
""")
|
||||
|
||||
return status_label
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
"""鼠标点击事件"""
|
||||
self.clicked.emit(self.project)
|
||||
super().mousePressEvent(event)
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
"""
|
||||
需求列表项组件
|
||||
"""
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel, QCheckBox
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
|
||||
class RequirementItemWidget(QWidget):
|
||||
"""需求列表项组件"""
|
||||
|
||||
def __init__(self, requirement, parent=None):
|
||||
"""
|
||||
初始化需求列表项
|
||||
|
||||
Args:
|
||||
requirement: 需求对象
|
||||
parent: 父组件
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.requirement = requirement
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI"""
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 10, 10, 10)
|
||||
layout.setSpacing(10)
|
||||
|
||||
# 复选框
|
||||
checkbox = QCheckBox()
|
||||
checkbox.setChecked(self.requirement.checked)
|
||||
checkbox.stateChanged.connect(
|
||||
lambda state: setattr(self.requirement, 'checked', state == Qt.Checked)
|
||||
)
|
||||
layout.addWidget(checkbox)
|
||||
|
||||
# 内容区域
|
||||
content_layout = QVBoxLayout()
|
||||
content_layout.setSpacing(5)
|
||||
|
||||
# 标题行
|
||||
title_layout = QHBoxLayout()
|
||||
title_layout.setSpacing(10)
|
||||
|
||||
# 需求标题
|
||||
title_label = QLabel(f"{self.requirement.req_id} {self.requirement.title}")
|
||||
title_label.setStyleSheet("""
|
||||
font-weight: bold;
|
||||
color: #60a5fa;
|
||||
""")
|
||||
title_layout.addWidget(title_label)
|
||||
|
||||
title_layout.addStretch()
|
||||
|
||||
# 置信度标签
|
||||
confidence_label = self._create_confidence_label()
|
||||
title_layout.addWidget(confidence_label)
|
||||
|
||||
# 优先级标签
|
||||
priority_label = self._create_priority_label()
|
||||
title_layout.addWidget(priority_label)
|
||||
|
||||
content_layout.addLayout(title_layout)
|
||||
|
||||
# 需求描述
|
||||
desc_label = QLabel(self.requirement.description)
|
||||
desc_label.setStyleSheet("""
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
""")
|
||||
desc_label.setWordWrap(True)
|
||||
content_layout.addWidget(desc_label)
|
||||
|
||||
layout.addLayout(content_layout)
|
||||
|
||||
# 设置整体样式
|
||||
self.setStyleSheet("""
|
||||
QWidget {
|
||||
background: rgba(51, 65, 85, 0.3);
|
||||
border: 1px solid rgba(59, 130, 246, 0.15);
|
||||
border-radius: 6px;
|
||||
}
|
||||
""")
|
||||
|
||||
def _create_confidence_label(self) -> QLabel:
|
||||
"""创建置信度标签"""
|
||||
confidence = self.requirement.confidence
|
||||
|
||||
if confidence >= 90:
|
||||
color = "#10b981"
|
||||
elif confidence >= 70:
|
||||
color = "#f59e0b"
|
||||
else:
|
||||
color = "#ef4444"
|
||||
|
||||
label = QLabel(f"{confidence}%")
|
||||
label.setStyleSheet(f"""
|
||||
background: {color}33;
|
||||
color: {color};
|
||||
border: 1px solid {color};
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
""")
|
||||
|
||||
return label
|
||||
|
||||
def _create_priority_label(self) -> QLabel:
|
||||
"""创建优先级标签"""
|
||||
priority = self.requirement.priority
|
||||
color = "#f59e0b" if priority == "高" else "#3b82f6"
|
||||
|
||||
label = QLabel(f"{priority}优先级")
|
||||
label.setStyleSheet(f"""
|
||||
background: {color}33;
|
||||
color: {color};
|
||||
border: 1px solid {color};
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
""")
|
||||
|
||||
return label
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
窗口模块
|
||||
"""
|
||||
from .main_window import MainWindow
|
||||
|
||||
__all__ = ['MainWindow']
|
||||
|
|
@ -0,0 +1,680 @@
|
|||
"""
|
||||
主窗口
|
||||
"""
|
||||
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 models import Project, Requirement, Module, Document
|
||||
from widgets import PanelWidget, ProjectItemWidget, RequirementItemWidget, ModuleItemWidget
|
||||
from 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
|
||||
)
|
||||
Loading…
Reference in New Issue