执行正常,保存导出错误

This commit is contained in:
2025-08-22 14:24:23 +08:00
parent 6351c038b5
commit fc2e48c6b0
12 changed files with 13448 additions and 13058 deletions

View File

@@ -75,3 +75,25 @@
- Add proper z-index and pointer-events handling - Add proper z-index and pointer-events handling
- Improve visual feedback for buttons and drag handle - Improve visual feedback for buttons and drag handle
- _Requirements: 1.3, 2.2, 4.3_ - _Requirements: 1.3, 2.2, 4.3_
- [x] 12. Implement Tauri-based file operations for import/export
- Configure Tauri permissions for fs and dialog plugins
- Replace web-based file operations with native Tauri APIs
- Implement save dialog for workflow export
- Implement open dialog for workflow import
- Add proper error handling and user feedback
- _Requirements: 2.1, 2.2, 3.1, 3.2_
- [x] 13. Enhance workflow execution and JSON output
- Improve startTask function to output detailed JSON to console
- Add metadata like creation time and version to exported workflows
- Implement proper workflow validation during import
- Add comprehensive logging for debugging and monitoring
- _Requirements: 1.5, 2.1, 2.2_
- [x] 14. Fix Tauri plugin configuration and dependencies
- Correct Tauri 2.0 plugin configuration format in tauri.conf.json
- Add dialog plugin dependency to Cargo.toml
- Initialize dialog plugin in lib.rs
- Remove invalid configuration fields that caused startup errors
- _Requirements: 2.1, 3.1_

View File

@@ -266,6 +266,8 @@
getNodesByCategory, getNodesByCategory,
nodeDefinitions nodeDefinitions
} from "~/components/flow-nodes/nodes"; } from "~/components/flow-nodes/nodes";
import { save, open } from '@tauri-apps/plugin-dialog';
import { writeTextFile, readTextFile } from '@tauri-apps/plugin-fs';
const router = useRouter(); const router = useRouter();
const workflowNodes = ref<FlowNode[]>([]); const workflowNodes = ref<FlowNode[]>([]);
@@ -380,6 +382,7 @@
const taskData = { const taskData = {
name: `任务_${new Date().toLocaleTimeString()}`, name: `任务_${new Date().toLocaleTimeString()}`,
createdAt: new Date().toISOString(),
nodes: workflowNodes.value.map((node) => ({ nodes: workflowNodes.value.map((node) => ({
id: node.id, id: node.id,
name: node.name, name: node.name,
@@ -389,13 +392,25 @@
})) }))
}; };
console.log("执行", taskData); console.log("=== 工作流执行 ===");
console.log("任务已开始,请查看控制台"); console.log("任务名称:", taskData.name);
console.log("创建时间:", taskData.createdAt);
console.log("节点数量:", taskData.nodes.length);
console.log("完整JSON数据:");
console.log(JSON.stringify(taskData, null, 2));
console.log("=== 执行完成 ===");
}; };
const saveTask = () => { const saveTask = async () => {
if (workflowNodes.value.length === 0) {
console.log("工作流为空,无法保存");
return;
}
const taskData = { const taskData = {
name: `任务_${new Date().toLocaleTimeString()}`, name: `任务_${new Date().toLocaleTimeString()}`,
createdAt: new Date().toISOString(),
version: "1.0",
nodes: workflowNodes.value.map((node) => ({ nodes: workflowNodes.value.map((node) => ({
id: node.id, id: node.id,
name: node.name, name: node.name,
@@ -405,50 +420,71 @@
})) }))
}; };
const blob = new Blob([JSON.stringify(taskData, null, 2)], { try {
type: "application/json" const filePath = await save({
}); filters: [{
const url = URL.createObjectURL(blob); name: 'JSON',
const a = document.createElement("a"); extensions: ['json']
a.href = url; }],
a.download = `任务_${Date.now()}.json`; defaultPath: `workflow_${Date.now()}.json`
a.click(); });
URL.revokeObjectURL(url);
};
const exportTask = () => { if (filePath) {
saveTask(); await writeTextFile(filePath, JSON.stringify(taskData, null, 2));
}; console.log("工作流已保存到:", filePath);
const importTask = () => {
const input = document.createElement("input");
input.type = "file";
input.accept = "application/json";
input.onchange = (e) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
try {
const data = JSON.parse(e.target?.result as string);
if (data.nodes && Array.isArray(data.nodes)) {
workflowNodes.value = data.nodes.map((node: any) => {
const definition = nodeDefinitions[node.id.replace(/-\d+$/, "")];
return {
...definition,
id: node.id,
config: node.config || {}
};
});
}
} catch (error) {
console.error("文件格式错误", error);
}
};
reader.readAsText(file);
} }
}; } catch (error) {
input.click(); console.error("保存工作流失败:", error);
}
};
const exportTask = async () => {
await saveTask();
};
const importTask = async () => {
try {
const selected = await open({
multiple: false,
filters: [{
name: 'JSON',
extensions: ['json']
}]
});
if (selected) {
const content = await readTextFile(selected as string);
const data = JSON.parse(content);
if (data.nodes && Array.isArray(data.nodes)) {
// 验证并重建节点
const importedNodes = data.nodes.map((node: any) => {
// 提取原始节点ID去除时间戳后缀
const originalId = node.id.replace(/-\d+-[a-z0-9]+$/, '');
const definition = nodeDefinitions[originalId];
if (!definition) {
console.warn(`未找到节点定义: ${originalId}`);
return null;
}
return {
...definition,
id: node.id, // 保持导入的ID
config: node.config || definition.config || {}
};
}).filter(Boolean); // 过滤掉null值
workflowNodes.value = importedNodes as FlowNode[];
console.log(`成功导入 ${importedNodes.length} 个节点`);
console.log("导入的工作流数据:", data);
} else {
console.error("无效的工作流文件格式");
}
}
} catch (error) {
console.error("导入工作流失败:", error);
}
}; };
</script> </script>

View File

@@ -25,6 +25,7 @@
"dependencies": { "dependencies": {
"@nuxt/ui-pro": "^3.2.0", "@nuxt/ui-pro": "^3.2.0",
"@tauri-apps/api": "^2.6.0", "@tauri-apps/api": "^2.6.0",
"@tauri-apps/plugin-dialog": "^2.3.0",
"@tauri-apps/plugin-fs": "^2.4.0", "@tauri-apps/plugin-fs": "^2.4.0",
"@tauri-apps/plugin-notification": "^2.3.0", "@tauri-apps/plugin-notification": "^2.3.0",
"@tauri-apps/plugin-os": "^2.3.0", "@tauri-apps/plugin-os": "^2.3.0",

15
pnpm-lock.yaml generated
View File

@@ -17,6 +17,9 @@ importers:
'@tauri-apps/api': '@tauri-apps/api':
specifier: ^2.6.0 specifier: ^2.6.0
version: 2.6.0 version: 2.6.0
'@tauri-apps/plugin-dialog':
specifier: ^2.3.0
version: 2.3.3
'@tauri-apps/plugin-fs': '@tauri-apps/plugin-fs':
specifier: ^2.4.0 specifier: ^2.4.0
version: 2.4.0 version: 2.4.0
@@ -1754,6 +1757,9 @@ packages:
'@tauri-apps/api@2.6.0': '@tauri-apps/api@2.6.0':
resolution: {integrity: sha512-hRNcdercfgpzgFrMXWwNDBN0B7vNzOzRepy6ZAmhxi5mDLVPNrTpo9MGg2tN/F7JRugj4d2aF7E1rtPXAHaetg==} resolution: {integrity: sha512-hRNcdercfgpzgFrMXWwNDBN0B7vNzOzRepy6ZAmhxi5mDLVPNrTpo9MGg2tN/F7JRugj4d2aF7E1rtPXAHaetg==}
'@tauri-apps/api@2.8.0':
resolution: {integrity: sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw==}
'@tauri-apps/cli-darwin-arm64@2.6.2': '@tauri-apps/cli-darwin-arm64@2.6.2':
resolution: {integrity: sha512-YlvT+Yb7u2HplyN2Cf/nBplCQARC/I4uedlYHlgtxg6rV7xbo9BvG1jLOo29IFhqA2rOp5w1LtgvVGwsOf2kxw==} resolution: {integrity: sha512-YlvT+Yb7u2HplyN2Cf/nBplCQARC/I4uedlYHlgtxg6rV7xbo9BvG1jLOo29IFhqA2rOp5w1LtgvVGwsOf2kxw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
@@ -1830,6 +1836,9 @@ packages:
engines: {node: '>= 10'} engines: {node: '>= 10'}
hasBin: true hasBin: true
'@tauri-apps/plugin-dialog@2.3.3':
resolution: {integrity: sha512-cWXB9QJDbLIA0v7I5QY183awazBEQNPhp19iPvrMZoJRX8SbFkhWFx1/q7zy7xGpXXzxz29qtq6z21Ho7W5Iew==}
'@tauri-apps/plugin-fs@2.4.0': '@tauri-apps/plugin-fs@2.4.0':
resolution: {integrity: sha512-Sp8AdDcbyXyk6LD6Pmdx44SH3LPeNAvxR2TFfq/8CwqzfO1yOyV+RzT8fov0NNN7d9nvW7O7MtMAptJ42YXA5g==} resolution: {integrity: sha512-Sp8AdDcbyXyk6LD6Pmdx44SH3LPeNAvxR2TFfq/8CwqzfO1yOyV+RzT8fov0NNN7d9nvW7O7MtMAptJ42YXA5g==}
@@ -7664,6 +7673,8 @@ snapshots:
'@tauri-apps/api@2.6.0': {} '@tauri-apps/api@2.6.0': {}
'@tauri-apps/api@2.8.0': {}
'@tauri-apps/cli-darwin-arm64@2.6.2': '@tauri-apps/cli-darwin-arm64@2.6.2':
optional: true optional: true
@@ -7711,6 +7722,10 @@ snapshots:
'@tauri-apps/cli-win32-ia32-msvc': 2.6.2 '@tauri-apps/cli-win32-ia32-msvc': 2.6.2
'@tauri-apps/cli-win32-x64-msvc': 2.6.2 '@tauri-apps/cli-win32-x64-msvc': 2.6.2
'@tauri-apps/plugin-dialog@2.3.3':
dependencies:
'@tauri-apps/api': 2.8.0
'@tauri-apps/plugin-fs@2.4.0': '@tauri-apps/plugin-fs@2.4.0':
dependencies: dependencies:
'@tauri-apps/api': 2.6.0 '@tauri-apps/api': 2.6.0

181
src-tauri/Cargo.lock generated
View File

@@ -62,6 +62,27 @@ version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "ashpd"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
dependencies = [
"enumflags2",
"futures-channel",
"futures-util",
"rand 0.9.2",
"raw-window-handle",
"serde",
"serde_repr",
"tokio",
"url",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"zbus",
]
[[package]] [[package]]
name = "async-broadcast" name = "async-broadcast"
version = "0.7.2" version = "0.7.2"
@@ -745,6 +766,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
dependencies = [ dependencies = [
"bitflags 2.9.1", "bitflags 2.9.1",
"block2 0.6.1",
"libc",
"objc2 0.6.1", "objc2 0.6.1",
] ]
@@ -759,6 +782,15 @@ dependencies = [
"syn 2.0.104", "syn 2.0.104",
] ]
[[package]]
name = "dlib"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading",
]
[[package]] [[package]]
name = "dlopen2" name = "dlopen2"
version = "0.7.0" version = "0.7.0"
@@ -782,6 +814,12 @@ dependencies = [
"syn 2.0.104", "syn 2.0.104",
] ]
[[package]]
name = "downcast-rs"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]] [[package]]
name = "dpi" name = "dpi"
version = "0.1.2" version = "0.1.2"
@@ -2180,6 +2218,7 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-build", "tauri-build",
"tauri-plugin-dialog",
"tauri-plugin-fs", "tauri-plugin-fs",
"tauri-plugin-notification", "tauri-plugin-notification",
"tauri-plugin-os", "tauri-plugin-os",
@@ -2891,6 +2930,16 @@ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
] ]
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
]
[[package]] [[package]]
name = "rand_chacha" name = "rand_chacha"
version = "0.2.2" version = "0.2.2"
@@ -2911,6 +2960,16 @@ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
] ]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.5.1" version = "0.5.1"
@@ -2929,6 +2988,15 @@ dependencies = [
"getrandom 0.2.16", "getrandom 0.2.16",
] ]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.3",
]
[[package]] [[package]]
name = "rand_hc" name = "rand_hc"
version = "0.2.0" version = "0.2.0"
@@ -3057,6 +3125,31 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "rfd"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
dependencies = [
"ashpd",
"block2 0.6.1",
"dispatch2",
"glib-sys",
"gobject-sys",
"gtk-sys",
"js-sys",
"log",
"objc2 0.6.1",
"objc2-app-kit",
"objc2-core-foundation",
"objc2-foundation 0.3.1",
"raw-window-handle",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.25" version = "0.1.25"
@@ -3157,6 +3250,12 @@ dependencies = [
"syn 2.0.104", "syn 2.0.104",
] ]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@@ -3799,6 +3898,24 @@ dependencies = [
"walkdir", "walkdir",
] ]
[[package]]
name = "tauri-plugin-dialog"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aefb14219b492afb30b12647b5b1247cadd2c0603467310c36e0f7ae1698c28"
dependencies = [
"log",
"raw-window-handle",
"rfd",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"tauri-plugin-fs",
"thiserror 2.0.12",
"url",
]
[[package]] [[package]]
name = "tauri-plugin-fs" name = "tauri-plugin-fs"
version = "2.4.0" version = "2.4.0"
@@ -4122,9 +4239,11 @@ dependencies = [
"libc", "libc",
"mio", "mio",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry",
"slab", "slab",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"tracing",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@@ -4638,6 +4757,66 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "wayland-backend"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
dependencies = [
"cc",
"downcast-rs",
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-client"
version = "0.31.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
dependencies = [
"bitflags 2.9.1",
"rustix",
"wayland-backend",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols"
version = "0.32.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901"
dependencies = [
"bitflags 2.9.1",
"wayland-backend",
"wayland-client",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.31.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3"
dependencies = [
"proc-macro2",
"quick-xml 0.37.5",
"quote",
]
[[package]]
name = "wayland-sys"
version = "0.31.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142"
dependencies = [
"dlib",
"log",
"pkg-config",
]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.77" version = "0.3.77"
@@ -5271,6 +5450,7 @@ dependencies = [
"ordered-stream", "ordered-stream",
"serde", "serde",
"serde_repr", "serde_repr",
"tokio",
"tracing", "tracing",
"uds_windows", "uds_windows",
"windows-sys 0.59.0", "windows-sys 0.59.0",
@@ -5390,6 +5570,7 @@ dependencies = [
"endi", "endi",
"enumflags2", "enumflags2",
"serde", "serde",
"url",
"winnow 0.7.12", "winnow 0.7.12",
"zvariant_derive", "zvariant_derive",
"zvariant_utils", "zvariant_utils",

View File

@@ -24,6 +24,7 @@ tauri-plugin-shell = "2.3.0"
tauri-plugin-notification = "2.3.0" tauri-plugin-notification = "2.3.0"
tauri-plugin-os = "2.3.0" tauri-plugin-os = "2.3.0"
tauri-plugin-fs = "2.4.0" tauri-plugin-fs = "2.4.0"
tauri-plugin-dialog = "2.3.0"
tauri-plugin-store = "2.3.0" tauri-plugin-store = "2.3.0"
serde_json = "1" serde_json = "1"

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{ "main": { "identifier": "main", "description": "Capabilities for the app window", "local": true, "windows": ["main", "secondary"], "permissions": ["core:path:default", "core:event:default", "core:window:default", "core:app:default", "core:resources:default", "core:menu:default", "core:tray:default", "shell:allow-open", { "identifier": "shell:allow-execute", "allow": [{ "args": ["-c", { "validator": "\\S+" }], "cmd": "sh", "name": "exec-sh", "sidecar": false }] }, "notification:default", "os:allow-platform", "os:allow-arch", "os:allow-family", "os:allow-version", "os:allow-locale", "fs:allow-document-read", "fs:allow-document-write", "store:default", "core:webview:allow-create-webview", "core:webview:allow-create-webview-window"] } } {"main":{"identifier":"main","description":"Capabilities for the app window","local":true,"windows":["main","secondary"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":["-c",{"validator":"\\S+"}],"cmd":"sh","name":"exec-sh","sidecar":false}]},"notification:default","os:allow-platform","os:allow-arch","os:allow-family","os:allow-version","os:allow-locale","fs:allow-document-read","fs:allow-document-write","store:default","core:webview:allow-create-webview","core:webview:allow-create-webview-window"]}}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@ pub fn run() {
.plugin(tauri_plugin_notification::init()) .plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_store::Builder::new().build()) .plugin(tauri_plugin_store::Builder::new().build())
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");

View File

@@ -49,6 +49,7 @@
], ],
"security": { "security": {
"csp": null "csp": null
} },
"withGlobalTauri": false
} }
} }