From 2c8b0a546ee188be8e57330b6511fb0152a29c6c Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Tue, 12 Aug 2025 08:40:02 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix=20(core):=20=E4=BF=AE=E5=A4=8D=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=97=A5=E5=BF=97=E6=9C=AA=E9=80=82=E9=85=8D=E5=A4=9A?= =?UTF-8?q?=20level=20=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + src-tauri/src/utils/logger.rs | 63 +++++++++++++++++++++++++----- src/components/setting/General.vue | 1 + 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 061d4fc..1df3867 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -10,6 +10,7 @@ dependencies = [ "dirs", "fern", "log", + "regex", "serde", "serde_json", "tauri", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a85cfa1..73e1847 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -27,3 +27,4 @@ chrono = { version = "0.4", features = ["serde"] } log = "0.4" fern = "0.7.1" dirs = "6.0.0" +regex = "1.11.1" diff --git a/src-tauri/src/utils/logger.rs b/src-tauri/src/utils/logger.rs index 230ab15..145951a 100644 --- a/src-tauri/src/utils/logger.rs +++ b/src-tauri/src/utils/logger.rs @@ -1,3 +1,4 @@ +use chrono::{Duration, Local}; use log::{error, info, warn}; use std::path::PathBuf; use std::sync::Mutex; @@ -156,8 +157,6 @@ pub async fn get_log_files(app: AppHandle) -> Result, String> { // 清除日志 #[command] pub async fn clear_logs(app: AppHandle, keep_days: u32) -> Result { - use chrono::{Duration, Local}; - let log_dir = { let guard = LOG_DIRECTORY.lock().unwrap(); match &*guard { @@ -176,13 +175,54 @@ pub async fn clear_logs(app: AppHandle, keep_days: u32) -> Result { if let Some(filename) = entry.file_name().to_str() { if filename.ends_with(".log") && filename.starts_with("codeforge-") { scanned_count += 1; - // 从文件名提取日期 codeforge-2024-08-09.log - if let Some(date_str) = filename - .strip_prefix("codeforge-") - .and_then(|s| s.strip_suffix(".log")) - { + + // 提取日期的函数 + let extract_date = |filename: &str| -> Option { + // 支持的日志文件格式: + // 1. codeforge-2025-08-12.log + // 2. codeforge-info-2025-08-12.log + // 3. codeforge-warn-2025-08-12.log + // 4. codeforge-error-2025-08-12.log + // 5. codeforge-debug-2025-08-12.log + + if let Some(without_prefix) = filename.strip_prefix("codeforge-") { + if let Some(without_suffix) = without_prefix.strip_suffix(".log") { + // 使用正则表达式匹配日期部分 + // 匹配模式:可选的级别前缀 + 日期 + let date_patterns = [ + // 直接日期格式:codeforge-2025-08-12.log + r"^(\d{4}-\d{2}-\d{2})$", + // 带级别前缀:codeforge-info-2025-08-12.log + r"^(?:info|warn|error|debug)-(\d{4}-\d{2}-\d{2})$", + ]; + + for pattern in &date_patterns { + if let Ok(re) = regex::Regex::new(pattern) { + if let Some(captures) = re.captures(without_suffix) { + if let Some(date_match) = captures.get(1) { + return Some(date_match.as_str().to_string()); + } + } + } + } + + // 如果正则匹配失败,尝试简单的字符串处理 + // 检查是否以日期结尾(最后10个字符应该是日期格式) + if without_suffix.len() >= 10 { + let potential_date = + &without_suffix[without_suffix.len() - 10..]; + if potential_date.matches('-').count() == 2 { + return Some(potential_date.to_string()); + } + } + } + } + None + }; + + if let Some(date_str) = extract_date(filename) { if let Ok(file_date) = - chrono::NaiveDate::parse_from_str(date_str, "%Y-%m-%d") + chrono::NaiveDate::parse_from_str(&date_str, "%Y-%m-%d") { if file_date < cutoff_date.date_naive() { if let Err(e) = std::fs::remove_file(entry.path()) { @@ -192,14 +232,19 @@ pub async fn clear_logs(app: AppHandle, keep_days: u32) -> Result { deleted_count += 1; } } else { - info!("清理日志 -> 日志文件文件未到期,将被保留: {}", filename); + info!("清理日志 -> 日志文件未到期,将被保留: {}", filename); } + } else { + warn!("清理日志 -> 无法解析日期格式 {}: {}", filename, date_str); } + } else { + warn!("清理日志 -> 无法从文件名提取日期: {}", filename); } } } } } + info!( "清理日志 -> 扫描 {} 个日志文件,删除 {} 个", scanned_count, deleted_count diff --git a/src/components/setting/General.vue b/src/components/setting/General.vue index b064011..48bb989 100644 --- a/src/components/setting/General.vue +++ b/src/components/setting/General.vue @@ -122,6 +122,7 @@ const logFiles = ref([]) const keepDays = ref(30) const keepDaysOptions = [ + { label: '保留 1 天', value: 1 }, { label: '保留 7 天', value: 7 }, { label: '保留 14 天', value: 14 }, { label: '保留 30 天', value: 30 }, From 201c4a29964aaf2f826a2c846e94a764c18bebad Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Tue, 12 Aug 2025 08:55:45 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat=20(language):=20=E6=94=AF=E6=8C=81=20G?= =?UTF-8?q?o=20=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + public/icons/go.svg | 41 ++++++ src-tauri/src/plugins/go.rs | 54 ++++++++ src-tauri/src/plugins/manager.rs | 3 +- src-tauri/src/plugins/mod.rs | 1 + src/utils/highlighter/languages/go.ts | 176 ++++++++++++++++++++++++++ src/utils/highlighter/manager.ts | 2 + 7 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 public/icons/go.svg create mode 100644 src-tauri/src/plugins/go.rs create mode 100644 src/utils/highlighter/languages/go.ts diff --git a/.gitignore b/.gitignore index 1b41949..1c1c5de 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ pnpm-lock.yaml *.csv *.json !config*.json +go.mod diff --git a/public/icons/go.svg b/public/icons/go.svg new file mode 100644 index 0000000..6acca81 --- /dev/null +++ b/public/icons/go.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src-tauri/src/plugins/go.rs b/src-tauri/src/plugins/go.rs new file mode 100644 index 0000000..36d51e0 --- /dev/null +++ b/src-tauri/src/plugins/go.rs @@ -0,0 +1,54 @@ +use super::{LanguagePlugin, PluginConfig}; + +pub struct GoPlugin; + +impl LanguagePlugin for GoPlugin { + fn get_order(&self) -> i32 { + 4 + } + + fn get_language_name(&self) -> &'static str { + "Go" + } + + fn get_language_key(&self) -> &'static str { + "go" + } + + fn get_version_args(&self) -> Vec<&'static str> { + vec!["version"] + } + + fn get_path_command(&self) -> String { + "package main\nimport (\"fmt\"\n\"runtime\")\nfunc main() { fmt.Println(runtime.GOROOT()) }" + .to_string() + } + + fn get_default_config(&self) -> PluginConfig { + PluginConfig { + enabled: true, + language: String::from("go"), + before_compile: Some(String::from("go mod init temp 2>/dev/null || true")), + extension: String::from("go"), + execute_home: None, + run_command: Some(String::from("go run $filename")), + after_compile: None, + template: Some(String::from( + "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Your code here\n\tfmt.Println(\"Hello, Go!\")\n}\n", + )), + timeout: Some(30), + } + } + + fn get_default_command(&self) -> String { + self.get_config() + .and_then(|config| config.run_command) + .unwrap_or_else(|| "go run".to_string()) + } + + fn get_file_extension(&self) -> String { + self.get_config() + .map(|config| config.extension.clone()) + .unwrap_or_else(|| "go".to_string()) + } +} diff --git a/src-tauri/src/plugins/manager.rs b/src-tauri/src/plugins/manager.rs index fce254c..a55c180 100644 --- a/src-tauri/src/plugins/manager.rs +++ b/src-tauri/src/plugins/manager.rs @@ -1,5 +1,5 @@ use super::{ - LanguagePlugin, PluginConfig, nodejs::NodeJSPlugin, python2::Python2Plugin, + LanguagePlugin, PluginConfig, go::GoPlugin, nodejs::NodeJSPlugin, python2::Python2Plugin, python3::Python3Plugin, }; use std::collections::HashMap; @@ -15,6 +15,7 @@ impl PluginManager { plugins.insert("python2".to_string(), Box::new(Python2Plugin)); plugins.insert("python3".to_string(), Box::new(Python3Plugin)); plugins.insert("nodejs".to_string(), Box::new(NodeJSPlugin)); + plugins.insert("go".to_string(), Box::new(GoPlugin)); Self { plugins } } diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index c6c0fbf..c11069a 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -316,5 +316,6 @@ pub mod manager; pub mod nodejs; pub mod python2; pub mod python3; +pub mod go; pub use manager::PluginManager; diff --git a/src/utils/highlighter/languages/go.ts b/src/utils/highlighter/languages/go.ts new file mode 100644 index 0000000..c1ebb6b --- /dev/null +++ b/src/utils/highlighter/languages/go.ts @@ -0,0 +1,176 @@ +import type { HighlightRule, LanguageHighlighter } from '../types' + +export class GoHighlighter + implements LanguageHighlighter +{ + getLanguageName(): string + { + return 'go' + } + + getDisplayName(): string + { + return 'Go' + } + + getOrder(): number + { + return 4 + } + + getRules(): HighlightRule[] + { + return [ + // 1. 注释 (最高优先级) + { + pattern: /\/\/.*$/gm, + className: 'text-gray-500 italic', + priority: 1 + }, + { + pattern: /\/\*[\s\S]*?\*\//g, + className: 'text-gray-500 italic', + priority: 1 + }, + + // 2. 字符串 (高优先级) + { + pattern: /`(?:[^`\\]|\\.)*`/g, + className: 'text-green-600', + priority: 2 + }, + { + pattern: /"(?:[^"\\]|\\.)*"/g, + className: 'text-green-600', + priority: 2 + }, + { + pattern: /'(?:[^'\\]|\\.)*'/g, + className: 'text-green-600', + priority: 2 + }, + + // 3. Go 关键字 + { + pattern: /\b(package|import|func|var|const|type|struct|interface|map|chan|select|go|defer|return|break|continue|fallthrough|if|else|switch|case|default|for|range|goto|true|false|nil|iota)\b/g, + className: 'text-purple-600 font-semibold', + priority: 3 + }, + + // 4. Go 内置类型 + { + pattern: /\b(bool|byte|complex64|complex128|error|float32|float64|int|int8|int16|int32|int64|rune|string|uint|uint8|uint16|uint32|uint64|uintptr)\b/g, + className: 'text-blue-600 font-semibold', + priority: 4 + }, + + // 5. 数字 + { + pattern: /\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?[fFlL]?\b/g, + className: 'text-blue-600', + priority: 5 + }, + + // 6. 十六进制、八进制、二进制数字 + { + pattern: /\b0[xX][0-9a-fA-F]+\b|\b0[0-7]+\b|\b0[bB][01]+\b/g, + className: 'text-blue-600', + priority: 5 + }, + + // 7. 函数定义 + { + pattern: /\bfunc\s+([a-zA-Z_]\w*)/g, + className: 'text-orange-600 font-semibold', + priority: 6 + }, + + // 8. 函数调用 + { + pattern: /\b([a-zA-Z_]\w*)(?=\s*\()/g, + className: 'text-orange-600', + priority: 7 + }, + + // 9. 类型定义 + { + pattern: /\btype\s+([A-Z]\w*)/g, + className: 'text-yellow-600 font-semibold', + priority: 8 + }, + + // 10. 结构体字段 + { + pattern: /\b([a-zA-Z_]\w*)\s*:/g, + className: 'text-cyan-600', + priority: 9 + }, + + // 11. 包名 + { + pattern: /\bpackage\s+([a-zA-Z_]\w*)/g, + className: 'text-indigo-600 font-semibold', + priority: 10 + }, + + // 12. import 语句 + { + pattern: /\bimport\s*\(\s*[\s\S]*?\)/g, + className: 'text-emerald-600', + priority: 11 + }, + { + pattern: /\bimport\s+"[^"]+"/g, + className: 'text-emerald-600', + priority: 11 + }, + + // 13. 常见的 Go 内置函数 + { + pattern: /\b(make|new|len|cap|append|copy|delete|close|panic|recover|print|println)\b/g, + className: 'text-pink-600 font-medium', + priority: 12 + }, + + // 14. 指针操作符 + { + pattern: /[*&]/g, + className: 'text-red-600 font-bold', + priority: 13 + }, + + // 15. 通道操作符 + { + pattern: /<-/g, + className: 'text-violet-600 font-bold', + priority: 14 + }, + + // 16. 结构体标签 + { + pattern: /`[^`]*`/g, + className: 'text-teal-600 bg-gray-100', + priority: 15 + }, + + // 17. 大写开头的导出标识符 + { + pattern: /\b[A-Z]\w*/g, + className: 'text-amber-600', + priority: 16 + } + ] + } + + preProcess(code: string): string + { + // Go 特定的预处理 + return code + } + + postProcess(highlighted: string): string + { + // Go 特定的后处理 + return highlighted + } +} diff --git a/src/utils/highlighter/manager.ts b/src/utils/highlighter/manager.ts index 6b1a2ce..7a5a458 100644 --- a/src/utils/highlighter/manager.ts +++ b/src/utils/highlighter/manager.ts @@ -2,6 +2,7 @@ import type { HighlightMatch, LanguageHighlighter } from './types' import { Python2Highlighter } from './languages/python2' import { Python3Highlighter } from './languages/python3' import { NodeJSHighlighter } from './languages/nodejs.ts' +import { GoHighlighter } from './languages/go.ts' export class HighlightManager { @@ -20,6 +21,7 @@ export class HighlightManager this.register(new Python2Highlighter()) this.register(new Python3Highlighter()) this.register(new NodeJSHighlighter()) + this.register(new GoHighlighter()) } /** From e0cda52a70e63cfe99a55705bb3a6409c39b6374 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Tue, 12 Aug 2025 12:02:45 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat=20(language):=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.json | 40 +++++++++++++++-- src-tauri/src/plugins/mod.rs | 2 +- src/App.vue | 83 +++++++++++------------------------- 3 files changed, 63 insertions(+), 62 deletions(-) diff --git a/config/config.json b/config/config.json index faa0113..c319f20 100644 --- a/config/config.json +++ b/config/config.json @@ -7,12 +7,46 @@ { "enabled": true, "execute_home": null, - "extensions": [], + "extension": "py", + "language": "python3", + "before_compile": null, + "after_compile": null, + "run_command": "python3 $filename", + "template": "# -*- coding: utf-8 -*-\n# Python 3 示例代码 - CodeForge 代码执行环境\n\nprint(\"🎉 欢迎使用 CodeForge!\")\nprint(\"Welcome to CodeForge!\")\nprint()\n\nprint(\"=========================================\")\nprint(\" CodeForge Python 3 \")\nprint(\"=========================================\")\nprint()\n\n# 基本输出示例\nprint(\"✅ Python 3 运行成功! (Python 3 is working!)\")\nprint(\"🐍 这是 Python 3.x 版本 (This is Python 3.x)\")\nprint()\n\n# 简单计算\nnumber1 = 10\nnumber2 = 20\nresult = number1 + number2\n\nprint(\"🔢 简单计算 (Simple calculation):\")\nprint(f\"{number1} + {number2} = {result}\")\nprint()\n\n# 字符串操作\nname = \"CodeForge\"\nversion = \"Python 3\"\n\nprint(\"📝 字符串操作 (String operations):\")\nprint(\"平台名称 (Platform):\", name)\nprint(\"语言版本 (Language):\", version)\nprint(f\"完整信息 (Full info): {name} - {version}\")\nprint()\n\n# 循环示例\nprint(\"🔄 循环输出 (Loop output):\")\nfor i in range(1, 6):\n print(f\"第 {i} 次输出 (Output #{i}): Hello from CodeForge!\")\n\nprint()\n\n# 列表操作\nfruits = [\"苹果\", \"香蕉\", \"橙子\", \"葡萄\"]\nprint(\"🍎 水果列表 (Fruit list):\")\nfor index, fruit in enumerate(fruits, 1):\n print(f\"{index}. {fruit}\")\n\nprint()\n\n# 条件判断\nscore = 85\nprint(\"📊 成绩评估 (Score evaluation):\")\nif score >= 90:\n print(\"优秀! (Excellent!)\")\nelif score >= 80:\n print(\"良好! (Good!)\")\nelif score >= 60:\n print(\"及格 (Pass)\")\nelse:\n print(\"需要努力 (Need improvement)\")\n\nprint()\n\n# Python 3 特性展示\nprint(\"🆕 Python 3 特性 (Python 3 features):\")\ndata = {\"name\": \"CodeForge\", \"language\": \"Python 3\", \"status\": \"运行中\"}\nprint(\"字典操作 (Dictionary):\", data)\n\n# 列表推导式\nsquares = [x**2 for x in range(1, 6)]\nprint(\"列表推导式 (List comprehension):\", squares)\n\nprint()\nprint(\"🎯 CodeForge Python 3 代码执行完成!\")\nprint(\"🎯 CodeForge Python 3 execution completed!\")\nprint()\nprint(\"感谢使用 CodeForge 代码执行环境! 🚀\")\nprint(\"Thank you for using CodeForge! 🚀\")", + "timeout": 30 + }, + { + "enabled": true, + "execute_home": null, + "extension": "js", + "language": "nodejs", + "before_compile": null, + "after_compile": null, + "run_command": "node $filename", + "template": "// Node.js 示例代码 - CodeForge 代码执行环境\n\nconsole.log(\"🎉 欢迎使用 CodeForge!\");\nconsole.log(\"Welcome to CodeForge!\");\nconsole.log(\"\");\n\nconsole.log(\"=========================================\");\nconsole.log(\" CodeForge Node.js \");\nconsole.log(\"=========================================\");\nconsole.log(\"\");\n\n// 基本输出示例\nconsole.log(\"✅ Node.js 运行成功! (Node.js is working!)\");\nconsole.log(`🟢 Node.js 版本 (Version): ${process.version}`);\nconsole.log(\"\");\n\n// 简单计算\nconst number1 = 10;\nconst number2 = 20;\nconst result = number1 + number2;\n\nconsole.log(\"🔢 简单计算 (Simple calculation):\");\nconsole.log(`${number1} + ${number2} = ${result}`);\nconsole.log(\"\");\n\n// 字符串操作\nconst name = \"CodeForge\";\nconst platform = \"Node.js\";\n\nconsole.log(\"📝 字符串操作 (String operations):\");\nconsole.log(\"平台名称 (Platform):\", name);\nconsole.log(\"运行环境 (Runtime):\", platform);\nconsole.log(`完整信息 (Full info): ${name} - ${platform}`);\nconsole.log(\"\");\n\n// 循环示例\nconsole.log(\"🔄 循环输出 (Loop output):\");\nfor (let i = 1; i <= 5; i++) {\n console.log(`第 ${i} 次输出 (Output #${i}): Hello from CodeForge!`);\n}\n\nconsole.log(\"\");\n\n// 数组操作\nconst fruits = [\"苹果\", \"香蕉\", \"橙子\", \"葡萄\"];\nconsole.log(\"🍎 水果列表 (Fruit list):\");\nfruits.forEach((fruit, index) => {\n console.log(`${index + 1}. ${fruit}`);\n});\n\nconsole.log(\"\");\n\n// 条件判断\nconst score = 85;\nconsole.log(\"📊 成绩评估 (Score evaluation):\");\nif (score >= 90) {\n console.log(\"优秀! (Excellent!)\");\n} else if (score >= 80) {\n console.log(\"良好! (Good!)\");\n} else if (score >= 60) {\n console.log(\"及格 (Pass)\");\n} else {\n console.log(\"需要努力 (Need improvement)\");\n}\n\nconsole.log(\"\");\n\n// JavaScript/Node.js 特性展示\nconsole.log(\"🆕 JavaScript 特性 (JavaScript features):\");\nconst data = { name: \"CodeForge\", platform: \"Node.js\", status: \"运行中\" };\nconsole.log(\"对象操作 (Object):\", JSON.stringify(data, null, 2));\n\n// 箭头函数和数组方法\nconst squares = [1, 2, 3, 4, 5].map(x => x ** 2);\nconsole.log(\"数组映射 (Array mapping):\", squares);\n\n// 异步操作示例\nconsole.log(\"⏰ 异步操作 (Async operation):\");\nsetTimeout(() => {\n console.log(\"⏱️ 1秒后执行 (Executed after 1 second)\");\n}, 1000);\n\nconsole.log(\"\");\nconsole.log(\"🎯 CodeForge Node.js 代码执行完成!\");\nconsole.log(\"🎯 CodeForge Node.js execution completed!\");\nconsole.log(\"\");\nconsole.log(\"感谢使用 CodeForge 代码执行环境! 🚀\");\nconsole.log(\"Thank you for using CodeForge! 🚀\");", + "timeout": 30 + }, + { + "enabled": true, + "execute_home": null, + "extension": "py", "language": "python2", "before_compile": null, "after_compile": null, - "run_command": null, - "template": null + "run_command": "python2 $filename", + "template": "# -*- coding: utf-8 -*-\n# Python 2 示例代码 - CodeForge 代码执行环境\n\nprint \"🎉 欢迎使用 CodeForge!\"\nprint \"Welcome to CodeForge!\"\nprint \"\"\n\nprint \"=========================================\"\nprint \" CodeForge Python 2 \"\nprint \"=========================================\"\nprint \"\"\n\n# 基本输出示例\nprint \"✅ Python 2 运行成功! (Python 2 is working!)\"\nprint \"🐍 这是 Python 2.x 版本 (This is Python 2.x)\"\nprint \"\"\n\n# 简单计算\nnumber1 = 10\nnumber2 = 20\nresult = number1 + number2\n\nprint \"🔢 简单计算 (Simple calculation):\"\nprint \"%d + %d = %d\" % (number1, number2, result)\nprint \"\"\n\n# 字符串操作\nname = \"CodeForge\"\nversion = \"Python 2\"\n\nprint \"📝 字符串操作 (String operations):\"\nprint \"平台名称 (Platform): \" + name\nprint \"语言版本 (Language): \" + version\nprint \"完整信息 (Full info): %s - %s\" % (name, version)\nprint \"\"\n\n# 循环示例\nprint \"🔄 循环输出 (Loop output):\"\nfor i in range(1, 6):\n print \"第 %d 次输出 (Output #%d): Hello from CodeForge!\" % (i, i)\n\nprint \"\"\n\n# 列表操作\nfruits = [u\"苹果\", u\"香蕉\", u\"橙子\", u\"葡萄\"]\nprint \"🍎 水果列表 (Fruit list):\"\nfor index, fruit in enumerate(fruits, 1):\n print \"%d. %s\" % (index, fruit.encode('utf-8'))\n\nprint \"\"\n\n# 条件判断\nscore = 85\nprint \"📊 成绩评估 (Score evaluation):\"\nif score >= 90:\n print \"优秀! (Excellent!)\"\nelif score >= 80:\n print \"良好! (Good!)\"\nelif score >= 60:\n print \"及格 (Pass)\"\nelse:\n print \"需要努力 (Need improvement)\"\n\nprint \"\"\nprint \"🎯 CodeForge Python 2 代码执行完成!\"\nprint \"🎯 CodeForge Python 2 execution completed!\"\nprint \"\"\nprint \"感谢使用 CodeForge 代码执行环境! 🚀\"\nprint \"Thank you for using CodeForge! 🚀\"", + "timeout": 30 + }, + { + "enabled": true, + "execute_home": null, + "extension": "go", + "language": "go", + "before_compile": "go mod init temp 2>/dev/null || true", + "after_compile": null, + "run_command": "go run $filename", + "template": "package main\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n\t\"time\"\n)\n\nfunc main() {\n\tfmt.Println(\"🎉 欢迎使用 CodeForge!\")\n\tfmt.Println(\"Welcome to CodeForge!\")\n\tfmt.Println()\n\n\tfmt.Println(\"=========================================\")\n\tfmt.Println(\" CodeForge Go \")\n\tfmt.Println(\"=========================================\")\n\tfmt.Println()\n\n\t// 基本输出示例\n\tfmt.Println(\"✅ Go 运行成功! (Go is working!)\")\n\tfmt.Printf(\"🔷 Go 版本 (Version): %s\\n\", runtime.Version())\n\tfmt.Println()\n\n\t// 简单计算\n\tnumber1 := 10\n\tnumber2 := 20\n\tresult := number1 + number2\n\n\tfmt.Println(\"🔢 简单计算 (Simple calculation):\")\n\tfmt.Printf(\"%d + %d = %d\\n\", number1, number2, result)\n\tfmt.Println()\n\n\t// 字符串操作\n\tname := \"CodeForge\"\n\tlanguage := \"Go\"\n\n\tfmt.Println(\"📝 字符串操作 (String operations):\")\n\tfmt.Println(\"平台名称 (Platform):\", name)\n\tfmt.Println(\"编程语言 (Language):\", language)\n\tfmt.Printf(\"完整信息 (Full info): %s - %s\\n\", name, language)\n\tfmt.Println()\n\n\t// 循环示例\n\tfmt.Println(\"🔄 循环输出 (Loop output):\")\n\tfor i := 1; i <= 5; i++ {\n\t\tfmt.Printf(\"第 %d 次输出 (Output #%d): Hello from CodeForge!\\n\", i, i)\n\t}\n\n\tfmt.Println()\n\n\t// 切片操作\n\tfruits := []string{\"苹果\", \"香蕉\", \"橙子\", \"葡萄\"}\n\tfmt.Println(\"🍎 水果列表 (Fruit list):\")\n\tfor index, fruit := range fruits {\n\t\tfmt.Printf(\"%d. %s\\n\", index+1, fruit)\n\t}\n\n\tfmt.Println()\n\n\t// 条件判断\n\tscore := 85\n\tfmt.Println(\"📊 成绩评估 (Score evaluation):\")\n\tswitch {\n\tcase score >= 90:\n\t\tfmt.Println(\"优秀! (Excellent!)\")\n\tcase score >= 80:\n\t\tfmt.Println(\"良好! (Good!)\")\n\tcase score >= 60:\n\t\tfmt.Println(\"及格 (Pass)\")\n\tdefault:\n\t\tfmt.Println(\"需要努力 (Need improvement)\")\n\t}\n\n\tfmt.Println()\n\n\t// Go 特性展示\n\tfmt.Println(\"🆕 Go 特性 (Go features):\")\n\t\n\t// 结构体\n\ttype Info struct {\n\t\tName string\n\t\tLanguage string\n\t\tStatus string\n\t}\n\t\n\tdata := Info{\n\t\tName: \"CodeForge\",\n\t\tLanguage: \"Go\",\n\t\tStatus: \"运行中\",\n\t}\n\tfmt.Printf(\"结构体 (Struct): %+v\\n\", data)\n\n\t// 映射 (Map)\n\tlanguages := map[string]string{\n\t\t\"Go\": \"编译型\",\n\t\t\"Python\": \"解释型\",\n\t\t\"JavaScript\": \"解释型\",\n\t}\n\tfmt.Println(\"映射 (Map):\", languages)\n\n\t// 协程示例 (简单展示)\n\tfmt.Println(\"⚡ 协程示例 (Goroutine example):\")\n\tdone := make(chan bool)\n\t\n\tgo func() {\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\tfmt.Println(\"🔥 协程执行完成! (Goroutine completed!)\")\n\t\tdone <- true\n\t}()\n\t\n\t<-done // 等待协程完成\n\n\tfmt.Println()\n\tfmt.Println(\"🎯 CodeForge Go 代码执行完成!\")\n\tfmt.Println(\"🎯 CodeForge Go execution completed!\")\n\tfmt.Println()\n\tfmt.Println(\"感谢使用 CodeForge 代码执行环境! 🚀\")\n\tfmt.Println(\"Thank you for using CodeForge! 🚀\")\n}", + "timeout": 30 } ] } \ No newline at end of file diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index c11069a..d208f3d 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -312,10 +312,10 @@ pub trait LanguagePlugin: Send + Sync { } // 重新导出子模块 +pub mod go; pub mod manager; pub mod nodejs; pub mod python2; pub mod python3; -pub mod go; pub use manager::PluginManager; diff --git a/src/App.vue b/src/App.vue index 5dd671f..ebca0f1 100644 --- a/src/App.vue +++ b/src/App.vue @@ -103,60 +103,6 @@ interface CodeOutputEvent language: string } -// 代码模板 -const codeTemplates: Record = { - python: `# Welcome to CodeForge! -# Write your Python code here and click Run to execute - -print("Hello, CodeForge!") - -# Example: Simple calculation -x = 10 -y = 20 -result = x + y -print(f"The result of {x} + {y} = {result}") - -# Example: List operations -numbers = [1, 2, 3, 4, 5] -squared = [n**2 for n in numbers] -print(f"Original: {numbers}") -print(f"Squared: {squared}")`, - - python2: `# Welcome to CodeForge - Python 2! -# Write your Python 2 code here and click Run to execute - -print "Hello, CodeForge from Python 2!" - -# Example: Simple calculation -x = 10 -y = 20 -result = x + y -print "The result of %d + %d = %d" % (x, y, result) - -# Example: List operations -numbers = [1, 2, 3, 4, 5] -squared = [n**2 for n in numbers] -print "Original:", numbers -print "Squared:", squared`, - - python3: `# Welcome to CodeForge - Python 3! -# Write your Python 3 code here and click Run to execute - -print("Hello, CodeForge from Python 3!") - -# Example: Simple calculation -x = 10 -y = 20 -result = x + y -print(f"The result of {x} + {y} = {result}") - -# Example: List operations -numbers = [1, 2, 3, 4, 5] -squared = [n**2 for n in numbers] -print(f"Original: {numbers}") -print(f"Squared: {squared}")` -} - const toast = useToast() const code = ref('') const currentLanguage = ref('python2') @@ -168,6 +114,7 @@ const activeTab = ref('output') const supportedLanguages = ref([]) const showAbout = ref(false) const showSettings = ref(false) +const globalConfig = ref(null as any) // 实时输出相关 const realTimeOutput = ref('') @@ -250,8 +197,7 @@ const handleLanguageChange = async (newLanguage: string) => { currentLanguage.value = newLanguage // 更新代码模板 - code.value = codeTemplates[newLanguage] || `# ${ getLanguageDisplayName(newLanguage) } Code -# Write your code here...` + code.value = filterPluginTemplate(newLanguage) // 清空输出 clearOutput() @@ -413,20 +359,41 @@ const handleExecutionError = (event: any) => { } } +const getConfigure = async () => { + try { + globalConfig.value = await invoke('get_app_config') + } + catch (error) { + toast.error('获取配置失败 - 错误信息: ' + error) + } +} + +const filterPluginTemplate = (plugin: any) => { + if (globalConfig.value && globalConfig.value.plugins) { + return globalConfig.value.plugins.find((p: any) => p.language === plugin).template + } + + return null +} + // 禁用右键菜单 window.addEventListener('contextmenu', (e) => e.preventDefault(), false) onMounted(async () => { await getSupportedLanguages() await refreshEnvInfo() + await getConfigure() // 设置初始代码模板 if (supportedLanguages.value.length > 0) { currentLanguage.value = supportedLanguages.value[0].value - code.value = codeTemplates[currentLanguage.value] || codeTemplates.python + console.log('当前语言:', currentLanguage.value) + const template = filterPluginTemplate(currentLanguage.value) + console.log('使用的模板:', template) + code.value = template } else { - code.value = codeTemplates.python + code.value = 'No supported languages found' } // 监听来自 Rust 的各种事件 From 047f997fe7917938d8f17ae33016bce4d28cfd23 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Tue, 12 Aug 2025 12:31:36 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix=20(core):=20=E4=BF=AE=E5=A4=8D=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E7=9B=AE=E5=BD=95=E5=90=8E=E6=89=A7=E8=A1=8C=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E4=BD=8D=E7=BD=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/plugins/mod.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index d208f3d..b9d191a 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -77,15 +77,32 @@ pub trait LanguagePlugin: Send + Sync { fn get_command(&self, file_path: Option<&str>) -> String { if let Some(config) = self.get_config() { if let Some(run_cmd) = &config.run_command { - if let Some(path) = file_path { - return run_cmd.replace("$filename", path); + return if let Some(path) = file_path { + let final_cmd = if self.get_execute_home().is_some() { + // 如果有执行主目录,在整个命令前面加 ./ + let cmd_with_file = run_cmd.replace("$filename", path); + if cmd_with_file.starts_with("./") { + cmd_with_file + } else { + format!("./{}", cmd_with_file) + } + } else { + run_cmd.replace("$filename", path) + }; + final_cmd } else { - return run_cmd + let base_cmd = run_cmd .split_whitespace() .next() .unwrap_or(&config.language) .to_string(); - } + + if self.get_execute_home().is_some() && !base_cmd.starts_with("./") { + format!("./{}", base_cmd) + } else { + base_cmd + } + }; } } self.get_default_command() From 06a6e6a7d5f69950db224d6233b380c2b329d869 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Tue, 12 Aug 2025 12:43:25 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix=20(core):=20=E4=BF=AE=E5=A4=8D=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=91=BD=E4=BB=A4=E4=BB=A3=E7=A0=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/plugins/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index b9d191a..7c9ee40 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -78,7 +78,7 @@ pub trait LanguagePlugin: Send + Sync { if let Some(config) = self.get_config() { if let Some(run_cmd) = &config.run_command { return if let Some(path) = file_path { - let final_cmd = if self.get_execute_home().is_some() { + if self.get_execute_home().is_some() { // 如果有执行主目录,在整个命令前面加 ./ let cmd_with_file = run_cmd.replace("$filename", path); if cmd_with_file.starts_with("./") { @@ -88,8 +88,7 @@ pub trait LanguagePlugin: Send + Sync { } } else { run_cmd.replace("$filename", path) - }; - final_cmd + } } else { let base_cmd = run_cmd .split_whitespace()