From 365964fc029cfc2df654b965c3736b260192825e Mon Sep 17 00:00:00 2001 From: fofolee Date: Sun, 26 Jan 2025 12:05:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E5=96=84=E7=94=9F=E6=88=90=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=80=BB=E8=BE=91=EF=BC=8C=E8=A6=86=E7=9B=96=E5=90=84?= =?UTF-8?q?=E7=A7=8D=E6=83=85=E5=86=B5=EF=BC=8C=E6=94=B9=E7=94=A8asyncMode?= =?UTF-8?q?=E5=AD=98=E5=82=A8promise=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/composer/ComposerCard.vue | 38 ++- src/components/composer/ComposerFlow.vue | 1 - src/components/composer/FlowTabs.vue | 30 +-- .../composer/card/CommandButtons.vue | 4 +- src/components/composer/card/OutputEditor.vue | 254 +++++++++++------- src/js/composer/commands/audioCommands.js | 8 +- src/js/composer/commands/browserCommands.js | 24 +- src/js/composer/commands/dataCommands.js | 2 +- src/js/composer/commands/fileCommands.js | 4 +- src/js/composer/commands/imageCommands.js | 12 +- src/js/composer/commands/macosCommands.js | 53 ++-- src/js/composer/commands/networkCommands.js | 12 +- src/js/composer/commands/scriptCommands.js | 2 +- src/js/composer/commands/simulateCommands.js | 6 +- src/js/composer/commands/statusCommands.js | 10 +- src/js/composer/commands/systemCommands.js | 2 +- src/js/composer/commands/uiCommands.js | 14 +- src/js/composer/commands/windowsCommands.js | 36 ++- src/js/composer/commonComponentGuide.js | 2 +- src/js/composer/customComponentGuide.js | 2 +- src/js/composer/generateCode.js | 97 +++++-- src/js/composer/variableManager.js | 11 +- 22 files changed, 387 insertions(+), 237 deletions(-) diff --git a/src/components/composer/ComposerCard.vue b/src/components/composer/ComposerCard.vue index eb95031..baa6a31 100644 --- a/src/components/composer/ComposerCard.vue +++ b/src/components/composer/ComposerCard.vue @@ -155,27 +155,37 @@ export default defineComponent({ }, methods: { handleOutputVariableUpdate(result) { - const { outputVariable, mode, functionInfo } = result; + const { outputVariable, asyncMode, callbackFunc } = result; if (outputVariable.name || outputVariable.details) { this.localCommand.outputVariable = { ...outputVariable }; + } else { + delete this.localCommand.outputVariable; + } + + if (asyncMode) { + this.localCommand.asyncMode = asyncMode; // 如果是回调模式,添加 callbackFunc 属性 - if (mode === "callback") { - this.localCommand.callbackFunc = functionInfo.name; + if (callbackFunc) { + this.localCommand.callbackFunc = callbackFunc; + let params = []; + if (outputVariable?.name) { + params.push(outputVariable.name); + } + if (outputVariable?.details) { + params.push(...Object.values(outputVariable.details)); + } + this.$emit("add-command", { + command: { + name: callbackFunc, + params, + silent: true, + }, + type: "function", + }); } else { delete this.localCommand.callbackFunc; } - - // 如果是回调函数模式,创建新函数 - if (mode === "callback" && functionInfo) { - this.$emit("add-command", { - command: functionInfo, - type: "function", - }); - } - } else { - delete this.localCommand.outputVariable; - delete this.localCommand.callbackFunc; } }, runCommand() { diff --git a/src/components/composer/ComposerFlow.vue b/src/components/composer/ComposerFlow.vue index aeff041..ee01eca 100644 --- a/src/components/composer/ComposerFlow.vue +++ b/src/components/composer/ComposerFlow.vue @@ -63,7 +63,6 @@ import ComposerCard from "./ComposerCard.vue"; import ChainStyles from "./flow/ChainStyles.vue"; import DropArea from "./flow/DropArea.vue"; import { findCommandByValue } from "js/composer/composerConfig"; -import { processVariable } from "js/composer/variableManager"; // 拖拽前的命令列表,非响应式 let commandsBeforeDrag = []; diff --git a/src/components/composer/FlowTabs.vue b/src/components/composer/FlowTabs.vue index e68fa23..e301be4 100644 --- a/src/components/composer/FlowTabs.vue +++ b/src/components/composer/FlowTabs.vue @@ -252,19 +252,9 @@ export default defineComponent({ }); } - // 添加局部变量 - if (options.localVars && options.localVars.length > 0) { - options.localVars.forEach((varInfo) => { - newFlow.customVariables.push({ - name: varInfo.name, - type: "var", - value: varInfo.value, - }); - }); - } - this.subFlows.push(newFlow); - if (options.params || options.localVars) { + + if (options.silent) { return; } @@ -281,12 +271,17 @@ export default defineComponent({ } }, updateSubFlow(index, payload) { - const { params, localVars } = payload; + const { params } = payload; + const newParams = params.map((param) => ({ + name: param, + type: "param", + })); + const localVars = this.subFlows[index].customVariables.filter( + (v) => v.type === "var" + ); + // 完全更新参数 this.subFlows[index].customVariables = [ - ...params.map((param) => ({ - name: param, - type: "param", - })), + ...newParams, ...localVars, ]; }, @@ -355,7 +350,6 @@ export default defineComponent({ "icon", "width", "placeholder", - "isAsync", "summary", "type", ]; diff --git a/src/components/composer/card/CommandButtons.vue b/src/components/composer/card/CommandButtons.vue index 2ee7036..cd163cc 100644 --- a/src/components/composer/card/CommandButtons.vue +++ b/src/components/composer/card/CommandButtons.vue @@ -15,9 +15,9 @@ @click="showOutputEditor = true" > -
配置命令输出变量
+
输出配置
- 将命令的输出保存为变量以供后续使用 + 配置输出变量、是否等待执行完毕等
diff --git a/src/components/composer/card/OutputEditor.vue b/src/components/composer/card/OutputEditor.vue index 7703a74..e94b879 100644 --- a/src/components/composer/card/OutputEditor.vue +++ b/src/components/composer/card/OutputEditor.vue @@ -14,8 +14,16 @@ -
- 详细输出 +
+
+ 详细输出 +
+ 数组中第一个元素 +
+
-
- -
- -
-
-
- - - + + + +
-
- 输出模式 +
+ 运行模式
@@ -147,64 +219,74 @@ export default defineComponent({ commandName() { return this.currentSubCommand.label || this.command.label; }, - isAsyncCommand() { - return this.currentSubCommand.isAsync || this.command.isAsync; - }, currentOutputs() { return this.currentSubCommand.outputs || this.command.outputs; }, - detailOutputs() { - let outputs = { ...this.currentOutputs }; - delete outputs.label; - delete outputs.placeholder; - return outputs; - }, }, data() { return { simpleOutputVar: "", outputVars: {}, - outputMode: "wait", - outputModeOptions: [ + asyncMode: "await", + callbackFunc: "", + asyncModeOptions: [ { label: "等待运行完毕", - value: "wait", + value: "await", }, { - label: "输出到回调函数", - value: "callback", + label: "不等待运行完毕", + value: "then", }, ], - callbackFunc: "", }; }, watch: { "command.outputVariable": { immediate: true, deep: true, - handler(outputVariable) { - this.initOutputVars(outputVariable); + handler(newValue) { + this.initOutputVars(newValue); + }, + }, + "command.asyncMode": { + immediate: true, + handler(newValue) { + this.asyncMode = newValue; }, }, "command.callbackFunc": { immediate: true, - handler(callbackFunc) { - if (callbackFunc) { - this.outputMode = "callback"; - this.callbackFunc = callbackFunc; - } else { - this.outputMode = "wait"; - } + handler(newValue) { + this.callbackFunc = newValue; }, }, }, methods: { hasNestedFields(output) { - console.log(output); + if (!output) return false; return Object.keys(output).some( (key) => key !== "label" && key !== "placeholder" ); }, + /** + * 只处理一层嵌套,手动在配置文件中控制outputs结构不要太复杂 + * 第二层嵌套只嵌套对象,不嵌套数组 + * 最复杂的情况: + * outputs: { + * label: "测试", + * structure: [ + * { + * position: { label: "位置", { + * x: { label: "X坐标" }, + * y: { label: "Y坐标" } + * } + * } + * ] + * } + * + * + */ getNestedFields(output) { const fields = {}; Object.entries(output).forEach(([key, value]) => { @@ -243,25 +325,17 @@ export default defineComponent({ } // 根据输出模式处理 - const result = { + let result = { outputVariable, - mode: this.outputMode, }; - // 如果是回调函数模式,添加回调函数名和参数信息 - if (this.outputMode === "callback" && this.callbackFunc) { - // 添加函数参数和本地变量信息 - result.functionInfo = { - name: this.callbackFunc, - params: [outputVariable.name], - localVars: outputVariable.details - ? Object.entries(outputVariable.details).map(([path, varName]) => ({ - name: varName, - type: "var", - value: `${outputVariable.name}.${path}`, - })) - : [], - }; + // async模式 + if (this.asyncMode) { + result.asyncMode = this.asyncMode; + // 如果是回调函数模式,添加回调函数名和参数信息 + if (this.asyncMode === "then" && this.callbackFunc) { + result.callbackFunc = this.callbackFunc; + } } this.$emit("confirm", result); diff --git a/src/js/composer/commands/audioCommands.js b/src/js/composer/commands/audioCommands.js index c5d1502..4309475 100644 --- a/src/js/composer/commands/audioCommands.js +++ b/src/js/composer/commands/audioCommands.js @@ -133,7 +133,7 @@ export const audioCommands = { value: "quickcomposer.audio.media.play", label: "音频播放", icon: "music_note", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.audio.media.play", @@ -175,7 +175,7 @@ export const audioCommands = { value: "quickcomposer.audio.record", label: "音频录制", icon: "mic", - isAsync: true, + asyncMode: "await", config: [ { label: "录制时长(ms)", @@ -211,7 +211,7 @@ export const audioCommands = { { value: "quickcomposer.audio.media.beep", label: "系统音效", - isAsync: true, + asyncMode: "await", icon: "notifications_active", config: [ { @@ -238,7 +238,7 @@ export const audioCommands = { value: "quickcomposer.audio.media.analyze", label: "音频信息", icon: "analytics", - isAsync: true, + asyncMode: "await", config: [ { label: "音频文件", diff --git a/src/js/composer/commands/browserCommands.js b/src/js/composer/commands/browserCommands.js index 0c390f0..53ac94f 100644 --- a/src/js/composer/commands/browserCommands.js +++ b/src/js/composer/commands/browserCommands.js @@ -36,7 +36,7 @@ export const browserCommands = { value: "quickcomposer.browser.startClient", label: "浏览器实例管理", icon: "launch", - isAsync: true, + asyncMode: "await", config: [], subCommands: [ { @@ -168,7 +168,7 @@ export const browserCommands = { value: "quickcomposer.browser.getUrl", label: "获取/设置网址", icon: "link", - isAsync: true, + asyncMode: "await", config: [tabConfig], subCommands: [ { @@ -196,7 +196,7 @@ export const browserCommands = { value: "quickcomposer.browser.getTabs", label: "标签操作", icon: "tab", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.browser.getTabs", @@ -240,7 +240,7 @@ export const browserCommands = { value: "quickcomposer.browser.captureScreenshot", label: "捕获截图", icon: "screenshot", - isAsync: true, + asyncMode: "await", config: [ tabConfig, { @@ -305,7 +305,7 @@ export const browserCommands = { value: "quickcomposer.browser.executeScript", label: "执行脚本", icon: "code", - isAsync: true, + asyncMode: "await", config: [ tabConfig, { @@ -328,7 +328,7 @@ export const browserCommands = { value: "quickcomposer.browser.injectRemoteScript", label: "注入脚本/样式", icon: "style", - isAsync: true, + asyncMode: "await", config: [tabConfig], subCommands: [ { @@ -396,7 +396,7 @@ export const browserCommands = { value: "quickcomposer.browser.setCookie", label: "Cookie操作", icon: "cookie", - isAsync: true, + asyncMode: "await", config: [tabConfig], subCommands: [ { @@ -486,7 +486,7 @@ export const browserCommands = { value: "quickcomposer.browser.clickElement", label: "元素操作", icon: "web", - isAsync: true, + asyncMode: "await", config: [ tabConfig, { @@ -591,7 +591,7 @@ export const browserCommands = { value: "quickcomposer.browser.scrollTo", label: "滚动及页面尺寸", icon: "open_in_full", - isAsync: true, + asyncMode: "await", config: [tabConfig], subCommands: [ { @@ -631,8 +631,8 @@ export const browserCommands = { value: "quickcomposer.browser.network.setRequestInterception", label: "修改请求/响应", icon: "network", - isAsync: true, - isAsync: true, + asyncMode: "await", + asyncMode: "await", subCommands: [ { value: "quickcomposer.browser.network.setRequestInterception", @@ -753,7 +753,7 @@ export const browserCommands = { value: "quickcomposer.browser.device.setDevice", label: "设备模拟", icon: "devices", - isAsync: true, + asyncMode: "await", config: [tabConfig], subCommands: [ { diff --git a/src/js/composer/commands/dataCommands.js b/src/js/composer/commands/dataCommands.js index ef7a9c7..5dc51ad 100644 --- a/src/js/composer/commands/dataCommands.js +++ b/src/js/composer/commands/dataCommands.js @@ -709,7 +709,7 @@ export const dataCommands = { label: "数据压缩解压", component: "ZlibEditor", icon: "compress", - isAsync: true, + asyncMode: "await", }, { value: "quickcomposer.data.htmlParser", diff --git a/src/js/composer/commands/fileCommands.js b/src/js/composer/commands/fileCommands.js index 40555ef..78869e6 100644 --- a/src/js/composer/commands/fileCommands.js +++ b/src/js/composer/commands/fileCommands.js @@ -7,7 +7,7 @@ export const fileCommands = { value: "quickcomposer.file.operation", label: "文件/文件夹操作", component: "FileOperationEditor", - isAsync: true, + asyncMode: "await", }, { value: "utools.shellOpenItem", @@ -67,7 +67,7 @@ export const fileCommands = { value: "quickcomposer.file.archive", label: "文件归档", icon: "archive", - isAsync: true, + asyncMode: "await", config: [ { label: "操作类型", diff --git a/src/js/composer/commands/imageCommands.js b/src/js/composer/commands/imageCommands.js index 300508b..f71fcaf 100644 --- a/src/js/composer/commands/imageCommands.js +++ b/src/js/composer/commands/imageCommands.js @@ -25,7 +25,7 @@ export const imageCommands = { value: "quickcomposer.image.analyze", label: "图片信息", icon: "analytics", - isAsync: true, + asyncMode: "await", config: [ { label: "图片文件", @@ -54,7 +54,7 @@ export const imageCommands = { value: "quickcomposer.image.resize", label: "调整大小", icon: "aspect_ratio", - isAsync: true, + asyncMode: "await", config: [ { label: "输入文件", @@ -140,7 +140,7 @@ export const imageCommands = { value: "quickcomposer.image.rotate", label: "旋转图片", icon: "rotate_right", - isAsync: true, + asyncMode: "await", config: [ { label: "输入文件", @@ -207,7 +207,7 @@ export const imageCommands = { value: "quickcomposer.image.crop", label: "裁剪图片", icon: "crop", - isAsync: true, + asyncMode: "await", config: [ { label: "输入文件", @@ -302,7 +302,7 @@ export const imageCommands = { value: "quickcomposer.image.watermark", label: "添加水印", icon: "format_color_text", - isAsync: true, + asyncMode: "await", config: [ { label: "输入文件", @@ -409,7 +409,7 @@ export const imageCommands = { value: "quickcomposer.image.convert", label: "格式转换", icon: "transform", - isAsync: true, + asyncMode: "await", config: [ { label: "输入文件", diff --git a/src/js/composer/commands/macosCommands.js b/src/js/composer/commands/macosCommands.js index 1673266..c66e66e 100644 --- a/src/js/composer/commands/macosCommands.js +++ b/src/js/composer/commands/macosCommands.js @@ -7,7 +7,7 @@ export const macosCommands = { value: "quickcomposer.macos.app.getFrontmost", label: "应用及窗口控制", icon: "apps", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.macos.app.getFrontmost", @@ -15,29 +15,32 @@ export const macosCommands = { icon: "front_hand", outputs: { label: "前台应用信息", - name: { label: "应用名称" }, - displayedName: { label: "应用显示名称" }, - path: { label: "应用路径" }, - version: { label: "应用版本" }, - pid: { label: "应用进程ID" }, - backgroundOnly: { label: "是否后台运行" }, - visible: { label: "是否可见" }, - frontmost: { label: "是否前台运行" }, - window: { - label: "窗口信息", - name: { label: "窗口名称" }, - title: { label: "窗口标题" }, - index: { label: "窗口索引" }, - position: { - label: "窗口位置", - placeholder: "数组, 第一个元素是 x 坐标,第二个元素是 y 坐标", + structure: { + name: { label: "应用名称" }, + displayedName: { label: "应用显示名称" }, + path: { label: "应用路径" }, + version: { label: "应用版本" }, + pid: { label: "应用进程ID" }, + backgroundOnly: { label: "是否后台运行" }, + visible: { label: "是否可见" }, + frontmost: { label: "是否前台运行" }, + window: { + label: "窗口信息", + name: { label: "窗口名称" }, + title: { label: "窗口标题" }, + index: { label: "窗口索引" }, + position: { + label: "窗口位置", + placeholder: + "数组, 第一个元素是 x 坐标,第二个元素是 y 坐标", + }, + size: { + label: "窗口大小", + placeholder: "数组, 第一个元素是宽度,第二个元素是高度", + }, + minimized: { label: "是否最小化" }, + fullscreen: { label: "是否全屏" }, }, - size: { - label: "窗口大小", - placeholder: "数组, 第一个元素是宽度,第二个元素是高度", - }, - minimized: { label: "是否最小化" }, - fullscreen: { label: "是否全屏" }, }, }, }, @@ -164,7 +167,7 @@ export const macosCommands = { value: "quickcomposer.macos.system.setVolume", label: "系统管理", icon: "settings", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.macos.system.setVolume", @@ -284,7 +287,7 @@ export const macosCommands = { value: "quickcomposer.macos.finder.getSelection", label: "访达管理", icon: "folder", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.macos.finder.getSelection", diff --git a/src/js/composer/commands/networkCommands.js b/src/js/composer/commands/networkCommands.js index ef004cf..b8aa5a5 100644 --- a/src/js/composer/commands/networkCommands.js +++ b/src/js/composer/commands/networkCommands.js @@ -26,14 +26,14 @@ export const networkCommands = { icon: "public", }, ], - isAsync: true, + asyncMode: "await", }, { value: "ubrowser", label: "ubrowser浏览器操作", config: [], component: "UBrowserEditor", - isAsync: true, + asyncMode: "await", icon: "public", }, { @@ -41,7 +41,7 @@ export const networkCommands = { label: "HTTP请求(Axios)", config: [], component: "AxiosConfigEditor", - isAsync: true, + asyncMode: "await", icon: "http", }, { @@ -246,7 +246,7 @@ export const networkCommands = { value: "quickcomposer.network.dns.lookupHost", label: "DNS操作", icon: "dns", - isAsync: true, + asyncMode: "await", config: [], subCommands: [ { @@ -389,7 +389,7 @@ export const networkCommands = { value: "quickcommand.downloadFile", label: "下载文件", icon: "file_download", - isAsync: true, + asyncMode: "await", config: [ { label: "文件URL", @@ -411,7 +411,7 @@ export const networkCommands = { value: "quickcommand.uploadFile", label: "上传文件", icon: "file_upload", - isAsync: true, + asyncMode: "await", config: [ { label: "上传接口地址", diff --git a/src/js/composer/commands/scriptCommands.js b/src/js/composer/commands/scriptCommands.js index 5c2ad5a..3429eb8 100644 --- a/src/js/composer/commands/scriptCommands.js +++ b/src/js/composer/commands/scriptCommands.js @@ -24,7 +24,7 @@ export const scriptCommands = { label: "运行脚本", component: "ScriptEditor", desc: "运行各种编程语言的代码", - isAsync: true, + asyncMode: "await", }, { value: "return", diff --git a/src/js/composer/commands/simulateCommands.js b/src/js/composer/commands/simulateCommands.js index f3e32f9..9199b48 100644 --- a/src/js/composer/commands/simulateCommands.js +++ b/src/js/composer/commands/simulateCommands.js @@ -216,19 +216,19 @@ export const simulateCommands = { label: "屏幕找图", component: "ImageSearchEditor", config: [], - isAsync: true, + asyncMode: "await", }, { value: "quickcomposer.simulate.screenColorPick", label: "屏幕取色", icon: "colorize", - isAsync: true, + asyncMode: "await", }, { value: "quickcomposer.simulate.captureScreen", label: "屏幕截图", icon: "screenshot_monitor", - isAsync: true, + asyncMode: "await", config: [ { label: "截图范围", diff --git a/src/js/composer/commands/statusCommands.js b/src/js/composer/commands/statusCommands.js index 21fde82..ebaa823 100644 --- a/src/js/composer/commands/statusCommands.js +++ b/src/js/composer/commands/statusCommands.js @@ -6,31 +6,31 @@ export const statusCommands = { value: "utools.readCurrentFolderPath", label: "获取当前文件管理器路径", icon: "folder", - isAsync: true, + asyncMode: "await", }, { value: "utools.readCurrentBrowserUrl", label: "获取当前浏览器地址", icon: "language", - isAsync: true, + asyncMode: "await", }, { value: "quickcomposer.status.getSelectedText", label: "获取选中文本", icon: "text_fields", - isAsync: true, + asyncMode: "await", }, { value: "quickcomposer.status.getSelectedImage", label: "获取选中的图片", icon: "image", - isAsync: true, + asyncMode: "await", }, { value: "quickcomposer.status.getSelectedFiles", label: "获取选中的文件", icon: "file_present", - isAsync: true, + asyncMode: "await", }, ], }; diff --git a/src/js/composer/commands/systemCommands.js b/src/js/composer/commands/systemCommands.js index dd5a71f..e7c8eb6 100644 --- a/src/js/composer/commands/systemCommands.js +++ b/src/js/composer/commands/systemCommands.js @@ -105,7 +105,7 @@ export const systemCommands = { label: "执行系统命令", component: "SystemCommandEditor", icon: "terminal", - isAsync: true, + asyncMode: "await", }, { value: "utools.getPath", diff --git a/src/js/composer/commands/uiCommands.js b/src/js/composer/commands/uiCommands.js index 168c5fb..93074d2 100644 --- a/src/js/composer/commands/uiCommands.js +++ b/src/js/composer/commands/uiCommands.js @@ -111,7 +111,7 @@ export const uiCommands = { { value: "quickcommand.showMessageBox", label: "消息提示", - isAsync: true, + asyncMode: "await", config: [ { label: "提示内容", @@ -168,7 +168,7 @@ export const uiCommands = { { value: "quickcommand.showConfirmBox", label: "确认框", - isAsync: true, + asyncMode: "await", outputs: { label: "是否确认", }, @@ -219,7 +219,7 @@ export const uiCommands = { { value: "quickcommand.showButtonBox", label: "按钮组", - isAsync: true, + asyncMode: "await", width: 12, config: [ { @@ -254,7 +254,7 @@ export const uiCommands = { { value: "quickcommand.showInputBox", label: "输入框", - isAsync: true, + asyncMode: "await", config: [ { label: "输入框", @@ -293,12 +293,12 @@ export const uiCommands = { value: "quickcommand.showSelectList", label: "选择列表", component: "SelectListEditor", - isAsync: true, + asyncMode: "await", }, { value: "quickcommand.showTextArea", label: "文本框", - isAsync: true, + asyncMode: "await", config: [ { label: "文本框占位符", @@ -329,7 +329,7 @@ export const uiCommands = { { value: "quickcommand.showSystemWaitButton", label: "等待操作按钮", - isAsync: true, + asyncMode: "await", config: [ { component: "OptionEditor", diff --git a/src/js/composer/commands/windowsCommands.js b/src/js/composer/commands/windowsCommands.js index 5b23e1a..5bdcb40 100644 --- a/src/js/composer/commands/windowsCommands.js +++ b/src/js/composer/commands/windowsCommands.js @@ -199,7 +199,7 @@ export const windowsCommands = { value: "quickcomposer.windows.window.getWindowInfo", label: "搜索/选择窗口", icon: "window", - isAsync: true, + asyncMode: "await", config: [], subCommands: [ { @@ -207,6 +207,22 @@ export const windowsCommands = { value: "quickcomposer.windows.window.getWindowInfo", label: "搜索窗口", icon: "search", + outputs: { + label: "窗口信息(数组)", + structure: [ + { + handle: { label: "窗口句柄" }, + title: { label: "窗口标题" }, + class: { label: "窗口类名" }, + x: { label: "窗口X坐标" }, + y: { label: "窗口Y坐标" }, + width: { label: "窗口宽度" }, + height: { label: "窗口高度" }, + processName: { label: "窗口进程名" }, + processPath: { label: "窗口进程路径" }, + }, + ], + }, }, { value: "quickcomposer.windows.automation.inspect", @@ -381,14 +397,14 @@ export const windowsCommands = { ], }, ], - isAsync: true, + asyncMode: "await", }, // automation { value: "quickcomposer.windows.automation.click", label: "界面自动化", icon: "smart_button", - isAsync: true, + asyncMode: "await", config: searchElementConfig, subCommands: [ { @@ -611,7 +627,7 @@ export const windowsCommands = { value: "quickcomposer.windows.sendmessage.listControls", label: "发送控制消息", icon: "smart_button", - isAsync: true, + asyncMode: "await", config: windowHandleConfig, subCommands: [ { @@ -804,7 +820,7 @@ export const windowsCommands = { value: "quickcomposer.windows.monitor.watchClipboard", label: "剪贴板/文件监控", icon: "monitor_heart", - isAsync: true, + asyncMode: "await", showLoading: true, subCommands: [ { @@ -866,7 +882,7 @@ export const windowsCommands = { value: "quickcomposer.windows.process.listProcesses", label: "进程管理", icon: "memory", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.windows.process.listProcesses", @@ -928,7 +944,7 @@ export const windowsCommands = { value: "quickcomposer.windows.registry.listKeys", label: "注册表管理", icon: "settings", - isAsync: true, + asyncMode: "await", config: [ { label: "注册表路径", @@ -1053,7 +1069,7 @@ export const windowsCommands = { value: "quickcomposer.windows.service.listServices", label: "服务管理", icon: "miscellaneous_services", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.windows.service.listServices", @@ -1095,7 +1111,7 @@ export const windowsCommands = { value: "quickcomposer.windows.software.listSoftware", label: "软件管理", icon: "apps", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.windows.software.listSoftware", @@ -1124,7 +1140,7 @@ export const windowsCommands = { value: "quickcomposer.windows.utils.setWallpaper", label: "系统工具", icon: "build", - isAsync: true, + asyncMode: "await", subCommands: [ { value: "quickcomposer.windows.utils.setWallpaper", diff --git a/src/js/composer/commonComponentGuide.js b/src/js/composer/commonComponentGuide.js index 12fbc41..915c6ae 100644 --- a/src/js/composer/commonComponentGuide.js +++ b/src/js/composer/commonComponentGuide.js @@ -103,7 +103,7 @@ const commonComponentGuide = { }, optionalFields: { desc: "命令描述", - isAsync: "是否异步命令", + asyncMode: "async模式,可选值为await/then", icon: "命令图标", }, }, diff --git a/src/js/composer/customComponentGuide.js b/src/js/composer/customComponentGuide.js index ce8ad4c..676783c 100644 --- a/src/js/composer/customComponentGuide.js +++ b/src/js/composer/customComponentGuide.js @@ -270,7 +270,7 @@ const customComponentGuide = { }, optionalFields: { desc: "命令描述", - isAsync: "是否异步命令", + asyncMode: "async模式,可选值为await/then", isControlFlow: "是否控制流命令", }, }, diff --git a/src/js/composer/generateCode.js b/src/js/composer/generateCode.js index 599cd2e..b4f375a 100644 --- a/src/js/composer/generateCode.js +++ b/src/js/composer/generateCode.js @@ -1,10 +1,28 @@ export function generateCode(flow) { + let usedVarNames = {}; + + // 获取变量赋值代码,如果变量已经存在,则直接赋值,否则声明并赋值 + const getVarAssignCode = (varName, varValue, funcName) => { + if (!usedVarNames[funcName]) { + usedVarNames[funcName] = []; + } + if (usedVarNames[funcName].includes(varName)) { + return `${varName} = ${varValue};`; + } + usedVarNames[funcName].push(varName); + return `let ${varName} = ${varValue};`; + }; + + const getVarByPath = (name, path) => { + return `${name}${path.startsWith("[") ? "" : "."}${path}`; + }; + const { commands, name, label, customVariables = [] } = flow; const params = customVariables.filter((v) => v.type === "param") || []; const manualVars = customVariables.filter((v) => v.type === "var") || []; // 检查是否包含异步函数 - const hasAsyncFunction = commands.some((cmd) => cmd.isAsync); + const hasAsyncFunction = commands.some((cmd) => cmd.asyncMode); let code = []; const funcName = name || "func_" + new Date().getTime(); @@ -17,9 +35,13 @@ export function generateCode(flow) { .join(", ")}) {` ); - code.push(manualVars.map((v) => ` let ${v.name} = ${v.value};`).join("\n")); const indent = " "; + // 局部变量赋值 + manualVars.forEach((v) => { + code.push(indent + getVarAssignCode(v.name, v.value, flow.name)); + }); + commands.forEach((cmd) => { // 跳过禁用的命令 if (cmd.disabled) return; @@ -29,36 +51,71 @@ export function generateCode(flow) { // 处理输出变量 if (cmd.outputVariable) { const { name, details } = cmd.outputVariable; - if (cmd.isAsync) { + if (cmd.asyncMode === "then") { + // 使用回调函数模式 if (cmd.callbackFunc) { - // 使用回调函数模式 - cmdCode = `${cmdCode}.then(${cmd.callbackFunc})`; - } else { - // 使用 await 模式 - cmdCode = `const ${name} = await ${cmdCode}`; - code.push(indent + cmdCode); - // 处理详细变量 - if (details) { - Object.entries(details).forEach(([path, varName]) => { - code.push(`${indent}let ${varName} = ${name}.${path};`); - }); + // 如果回调函数存在,则使用回调函数模式,否则保持原样 + if (!details) { + cmdCode = `${cmdCode}.then(${cmd.callbackFunc})`; + } else { + // 如果输出变量有详细变量,则需要为每个变量赋值 + const promiseName = name || "result"; + + const extractVarCode = Object.entries(details) + .map( + ([path, varName]) => + `let ${varName} = ${getVarByPath(promiseName, path)}` + ) + .join("\n"); + + const funcName = cmd.callbackFunc; + + const funcParams = + (name ? `${name},` : "") + Object.values(details).join(","); + + cmdCode = `${cmdCode}.then((${promiseName})=>{ + ${extractVarCode} + ${funcName}(${funcParams}) + })`; } - return; } - } else { - cmdCode = `const ${name} = ${cmdCode}`; + code.push(indent + cmdCode); + } else if (cmd.asyncMode === "await") { + // 使用 await 模式 + const promiseName = name || "result"; + cmdCode = getVarAssignCode(promiseName, `await ${cmdCode}`); code.push(indent + cmdCode); // 处理详细变量 if (details) { Object.entries(details).forEach(([path, varName]) => { - code.push(`${indent}let ${varName} = ${name}.${path};`); + code.push( + `${indent}${getVarAssignCode( + varName, + getVarByPath(promiseName, path) + )}` + ); + }); + } + } else { + // 非Async命令 + cmdCode = getVarAssignCode(name, `${cmdCode}`); + code.push(indent + cmdCode); + // 处理详细变量 + if (details) { + Object.entries(details).forEach(([path, varName]) => { + code.push( + `${indent}${getVarAssignCode(varName, getVarByPath(name, path))}` + ); }); } return; } + } else { + if (cmd.asyncMode === "await") { + cmdCode = `await ${cmdCode}`; + } + code.push(indent + cmdCode); } - - code.push(indent + cmdCode); }); code.push("}"); // Close the function diff --git a/src/js/composer/variableManager.js b/src/js/composer/variableManager.js index 48dd674..90f6646 100644 --- a/src/js/composer/variableManager.js +++ b/src/js/composer/variableManager.js @@ -7,12 +7,7 @@ import { validateVariableName } from "js/common/variableValidator"; */ function generateRandomSuffix(varCount, withPrefix = true) { // 根据变量数量决定后缀长度 - let length = 1; // 默认1位 - if (varCount >= 100) { - length = 3; - } else if (varCount >= 10) { - length = 2; - } + let length = varCount > 100 ? 3 : 2; return ( (withPrefix ? "_" : "") + @@ -100,7 +95,9 @@ export function processVariable({ value, existingVars, baseName = "var" }) { isValid: true, processedValue: processedVar, warning: - processedVar !== value ? `输入值非法,已被修改为: ${processedVar}` : null, + processedVar !== value + ? `输入值非法,已被修改为: ${processedVar}` + : null, }; }