From bfa0f58956db25d70fdf089bddf7fbcc0cc29a29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Dec 2024 04:28:25 +0000 Subject: [PATCH 001/332] Bump braces from 3.0.2 to 3.0.3 Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d7375ee..b92d00aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3174,12 +3174,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -5316,9 +5316,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -13528,12 +13528,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -15136,9 +15136,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" From a13580d53f5c8ef44a5a18c970eece91c26fdd5f Mon Sep 17 00:00:00 2001 From: fofolee Date: Tue, 7 Jan 2025 17:50:13 +0800 Subject: [PATCH 002/332] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=80=BC=E4=B8=BA=E7=A9=BA=E5=92=8C=E4=BC=A0=E9=80=92=E7=A9=BA?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/composer/MultiParams.vue | 82 ++++- .../composer/common/NumberInput.vue | 8 +- src/components/composer/common/ParamInput.vue | 16 + src/js/composer/commands/dataCommands.js | 288 +++++++++--------- src/js/composer/commands/simulateCommands.js | 37 ++- src/js/composer/formatString.js | 29 +- ...\347\233\256\350\257\264\346\230\216.json" | 14 +- 7 files changed, 275 insertions(+), 199 deletions(-) diff --git a/src/components/composer/MultiParams.vue b/src/components/composer/MultiParams.vue index c0324b68..7904ba67 100644 --- a/src/components/composer/MultiParams.vue +++ b/src/components/composer/MultiParams.vue @@ -4,7 +4,7 @@ v-if="hasFunctionSelector" :model-value="funcName" @update:model-value="funcName = $event" - :options="localCommand.functionSelector?.options" + :options="localCommand.functionSelector" /> @@ -40,17 +40,22 @@ export default defineComponent({ }, // 特定函数独有参数配置 functionConfig() { - return ( - this.modelValue.functionSelector?.options.find( - (item) => item.value === this.funcName - )?.config || [] - ); + return this.getSelectFunction()?.config || []; }, localConfig() { return [...this.commonConfig, ...this.functionConfig].map((item) => { + const value = + item.type === "varInput" + ? item.defaultValue || { + value: "", + isString: true, + __varInputVal__: true, + } + : // 其他类型情况复杂,不做判断,没有默认值返回undefined + item.defaultValue; return { ...item, - value: item.defaultValue, + value, }; }); }, @@ -62,7 +67,20 @@ export default defineComponent({ return this.modelValue.value; }, set(value) { - this.updateModelValue(value, this.defaultArgvs); + // 构建新的参数数组 + const newArgvs = []; + + // 保留通用配置的参数值 + this.commonConfig.forEach((_, index) => { + newArgvs[index] = this.argvs[index]; + }); + + // 使用新选择的函数独有配置的默认值 + this.getSelectFunction(value)?.config?.forEach((config, index) => { + newArgvs[this.commonConfig.length + index] = config.defaultValue; + }); + + this.updateModelValue(value, newArgvs); }, }, argvs() { @@ -75,6 +93,11 @@ export default defineComponent({ }, }, methods: { + getSelectFunction(funcName = this.funcName) { + return this.modelValue.functionSelector?.find( + (item) => item.value === funcName + ); + }, updateArgv(index, value) { const newArgvs = [...this.argvs]; newArgvs[index] = value; @@ -82,10 +105,41 @@ export default defineComponent({ this.updateModelValue(this.funcName, newArgvs); }, generateCode(funcName, argvs) { - const newArgvs = argvs - .map((argv) => stringifyArgv(argv)) - .filter((item) => item != null && item !== ""); - return `${funcName}(${newArgvs.join(",")})`; + console.log("argvs", argvs); + /** + * 字符串模式stringfiy后,null会变成'"null"', ''变成'""' + * 变量模式stringify后,null变成'null', ''保持'' + */ + const stringifiedArgvs = argvs.map((argv) => stringifyArgv(argv)); + + /* 空值处理: + * 1. 去掉 undefined,'', null + * 2. varInput在字符串模式下,留空为'""',所以不会被处理 + * 3. 变量模式下,留空是'', 会被过滤 + * 4. 如果想传递空字符串,将varInput切为字符串模式并留空 + * 5. 如果不想传递对应参数,将varInput切为变量模式并留空 + * 6. 如果想传递空参数,将varInput切为变量模式并设置为null或undefined + + * [undefined, undefined] -> funcName() + * [undefined, 1] -> '' + * [1, undefined] -> funcName(1) + * [null, 1] -> funcName(null, 1) + * [1, 字符串模式下varInput留空] -> funcName(1, "") + * [1, 变量模式下varInput留空] -> funcName(1) + * [1, 变量模式下varInput设置为null] -> funcName(1, null) + */ + // 空参数后面跟着非空参数,不生成代码 + const isEmpty = (v) => v === undefined || v === "" || v === null; + for (let i = 0; i < stringifiedArgvs.length - 1; i++) { + if (isEmpty(stringifiedArgvs[i]) && !isEmpty(stringifiedArgvs[i + 1])) { + return ""; + } + } + + // 过滤空参数,由于前面已经对处于非空参数中间的空参数做了处理,这里直接过滤空参数不会对参数顺序造成影响 + const finalArgvs = stringifiedArgvs.filter((v) => !isEmpty(v)); + + return `${funcName}(${finalArgvs.join(",")})`; }, parseCodeToArgvs(code) { let argvs = window.lodashM.cloneDeep(this.defaultArgvs); @@ -110,9 +164,7 @@ export default defineComponent({ }, getSummary(argvs) { // 虽然header里对溢出做了处理,但是这里截断主要是为了节省存储空间 - const funcNameLabel = this.localCommand.functionSelector?.options.find( - (option) => option.value === this.funcName - )?.label; + const funcNameLabel = this.getSelectFunction()?.label; const subFeature = funcNameLabel ? `${funcNameLabel} ` : ""; const allArgvs = argvs .filter((item) => item != null && item != "") diff --git a/src/components/composer/common/NumberInput.vue b/src/components/composer/common/NumberInput.vue index 4645d973..17a74d3c 100644 --- a/src/components/composer/common/NumberInput.vue +++ b/src/components/composer/common/NumberInput.vue @@ -67,13 +67,17 @@ export default defineComponent({ return this.modelValue; }, set(value) { - this.$emit("update:modelValue", value); + if (value === null || value === undefined || value === "") { + this.$emit("update:modelValue", null); + } else { + this.$emit("update:modelValue", value); + } }, }, }, methods: { updateNumber(delta) { - this.$emit("update:modelValue", this.localValue + delta); + this.$emit("update:modelValue", (this.localValue || 0) + delta); }, }, }); diff --git a/src/components/composer/common/ParamInput.vue b/src/components/composer/common/ParamInput.vue index 29fbf954..9f9ba04b 100644 --- a/src/components/composer/common/ParamInput.vue +++ b/src/components/composer/common/ParamInput.vue @@ -43,6 +43,8 @@ * { + flex: 1; + min-width: 0; } @media (max-width: 600px) { .grid-item { width: 100% !important; + flex: 1 1 100% !important; } } diff --git a/src/js/composer/commands/dataCommands.js b/src/js/composer/commands/dataCommands.js index 41f72f0d..10678d71 100644 --- a/src/js/composer/commands/dataCommands.js +++ b/src/js/composer/commands/dataCommands.js @@ -17,50 +17,48 @@ export const dataCommands = { type: "varInput", }, ], - functionSelector: { - options: [ - { - label: "Base64编码", - value: "quickcomposer.data.base64Encode", - icon: "title", - }, - { - label: "Base64解码", - value: "quickcomposer.data.base64Decode", - icon: "title", - }, - { - label: "十六进制编码", - value: "quickcomposer.data.hexEncode", - icon: "code", - }, - { - label: "十六进制解码", - value: "quickcomposer.data.hexDecode", - icon: "code", - }, - { - label: "URL编码", - value: "quickcomposer.data.urlEncode", - icon: "link", - }, - { - label: "URL解码", - value: "quickcomposer.data.urlDecode", - icon: "link", - }, - { - label: "HTML编码", - value: "quickcomposer.data.htmlEncode", - icon: "html", - }, - { - label: "HTML解码", - value: "quickcomposer.data.htmlDecode", - icon: "html", - }, - ], - }, + functionSelector: [ + { + label: "Base64编码", + value: "quickcomposer.data.base64Encode", + icon: "title", + }, + { + label: "Base64解码", + value: "quickcomposer.data.base64Decode", + icon: "title", + }, + { + label: "十六进制编码", + value: "quickcomposer.data.hexEncode", + icon: "code", + }, + { + label: "十六进制解码", + value: "quickcomposer.data.hexDecode", + icon: "code", + }, + { + label: "URL编码", + value: "quickcomposer.data.urlEncode", + icon: "link", + }, + { + label: "URL解码", + value: "quickcomposer.data.urlDecode", + icon: "link", + }, + { + label: "HTML编码", + value: "quickcomposer.data.htmlEncode", + icon: "html", + }, + { + label: "HTML解码", + value: "quickcomposer.data.htmlDecode", + icon: "html", + }, + ], }, { value: "quickcomposer.data.symmetricCrypto", @@ -90,35 +88,33 @@ export const dataCommands = { type: "varInput", }, ], - functionSelector: { - options: [ - { - label: "MD5", - value: "quickcomposer.data.md5Hash", - icon: "functions", - }, - { - label: "SHA1", - value: "quickcomposer.data.sha1Hash", - icon: "functions", - }, - { - label: "SHA256", - value: "quickcomposer.data.sha256Hash", - icon: "functions", - }, - { - label: "SHA512", - value: "quickcomposer.data.sha512Hash", - icon: "functions", - }, - { - label: "SM3", - value: "quickcomposer.data.sm3Hash", - icon: "functions", - }, - ], - }, + functionSelector: [ + { + label: "MD5", + value: "quickcomposer.data.md5Hash", + icon: "functions", + }, + { + label: "SHA1", + value: "quickcomposer.data.sha1Hash", + icon: "functions", + }, + { + label: "SHA256", + value: "quickcomposer.data.sha256Hash", + icon: "functions", + }, + { + label: "SHA512", + value: "quickcomposer.data.sha512Hash", + icon: "functions", + }, + { + label: "SM3", + value: "quickcomposer.data.sm3Hash", + icon: "functions", + }, + ], }, { value: "Math.sin", @@ -134,80 +130,78 @@ export const dataCommands = { type: "numInput", }, ], - functionSelector: { - options: [ - { - label: "正弦(sin)", - value: "Math.sin", - icon: "functions", - }, - { - label: "余弦(cos)", - value: "Math.cos", - icon: "functions", - }, - { - label: "正切(tan)", - value: "Math.tan", - icon: "functions", - }, - { - label: "反正弦(asin)", - value: "Math.asin", - icon: "functions", - }, - { - label: "反余弦(acos)", - value: "Math.acos", - icon: "functions", - }, - { - label: "反正切(atan)", - value: "Math.atan", - icon: "functions", - }, - { - label: "平方根(sqrt)", - value: "Math.sqrt", - icon: "functions", - }, - { - label: "自然对数(ln)", - value: "Math.log", - icon: "functions", - }, - { - label: "10对数(log10)", - value: "Math.log10", - icon: "functions", - }, - { - label: "绝对值(abs)", - value: "Math.abs", - icon: "functions", - }, - { - label: "向上取整(ceil)", - value: "Math.ceil", - icon: "functions", - }, - { - label: "向下取整(floor)", - value: "Math.floor", - icon: "functions", - }, - { - label: "四舍五入(round)", - value: "Math.round", - icon: "functions", - }, - { - label: "幂运算(pow)", - value: "Math.pow", - icon: "functions", - }, - ], - }, + functionSelector: [ + { + label: "正弦(sin)", + value: "Math.sin", + icon: "functions", + }, + { + label: "余弦(cos)", + value: "Math.cos", + icon: "functions", + }, + { + label: "正切(tan)", + value: "Math.tan", + icon: "functions", + }, + { + label: "反正弦(asin)", + value: "Math.asin", + icon: "functions", + }, + { + label: "反余弦(acos)", + value: "Math.acos", + icon: "functions", + }, + { + label: "反正切(atan)", + value: "Math.atan", + icon: "functions", + }, + { + label: "平方根(sqrt)", + value: "Math.sqrt", + icon: "functions", + }, + { + label: "自然对数(ln)", + value: "Math.log", + icon: "functions", + }, + { + label: "10对数(log10)", + value: "Math.log10", + icon: "functions", + }, + { + label: "绝对值(abs)", + value: "Math.abs", + icon: "functions", + }, + { + label: "向上取整(ceil)", + value: "Math.ceil", + icon: "functions", + }, + { + label: "向下取整(floor)", + value: "Math.floor", + icon: "functions", + }, + { + label: "四舍五入(round)", + value: "Math.round", + icon: "functions", + }, + { + label: "幂运算(pow)", + value: "Math.pow", + icon: "functions", + }, + ], }, { value: "quickcomposer.data.random", diff --git a/src/js/composer/commands/simulateCommands.js b/src/js/composer/commands/simulateCommands.js index f7930658..646661c7 100644 --- a/src/js/composer/commands/simulateCommands.js +++ b/src/js/composer/commands/simulateCommands.js @@ -27,26 +27,23 @@ export const simulateCommands = { width: 6, }, ], - functionSelector: { - options: [ - { - label: "单击", - value: "utools.simulateMouseClick", - icon: "mouse", - }, - { - label: "右击", - value: "utools.simulateMouseRightClick", - icon: "mouse", - }, - { - label: "双击", - value: "utools.simulateMouseDoubleClick", - icon: "mouse", - }, - ], - allowEmptyArgv: true, - }, + functionSelector: [ + { + label: "单击", + value: "utools.simulateMouseClick", + icon: "mouse", + }, + { + label: "右击", + value: "utools.simulateMouseRightClick", + icon: "mouse", + }, + { + label: "双击", + value: "utools.simulateMouseDoubleClick", + icon: "mouse", + }, + ], }, { value: "utools.simulateMouseMove", diff --git a/src/js/composer/formatString.js b/src/js/composer/formatString.js index ba792140..63602390 100644 --- a/src/js/composer/formatString.js +++ b/src/js/composer/formatString.js @@ -103,15 +103,19 @@ const stringifyObject = (jsonObj) => { * @returns {string} 格式化后的字符串 */ export const stringifyArgv = (argv) => { - // 处理普通字符串 + // 普通字符串加上引号 if (typeof argv === "string") { return `"${argv}"`; } - // 处理对象 + // null类型是Object,需要单独处理,返回原值 + if (argv === null) { + return null; + } + // 对象通过stringifyObject处理 if (typeof argv === "object") { return stringifyObject(argv); } - // 处理其他类型 + // 其他类型返回原值 return argv; }; @@ -270,12 +274,25 @@ export const parseFunction = (functionStr, options = {}) => { return shouldUseVariableFormat ? { value: node.value, isString: true, __varInputVal__: true } : node.value; + // 数字、布尔 case "NumericLiteral": - return node.value; case "BooleanLiteral": - return node.value; + return shouldUseVariableFormat + ? { + value: JSON.stringify(node.value), + isString: false, + __varInputVal__: true, + } + : node.value; + // null case "NullLiteral": - return null; + return shouldUseVariableFormat + ? { + value: "null", + isString: false, + __varInputVal__: true, + } + : null; case "Identifier": // 标识符(变量)总是不带引号的 return shouldUseVariableFormat diff --git "a/\351\241\271\347\233\256\350\257\264\346\230\216.json" "b/\351\241\271\347\233\256\350\257\264\346\230\216.json" index a3daf465..3db461b2 100644 --- "a/\351\241\271\347\233\256\350\257\264\346\230\216.json" +++ "b/\351\241\271\347\233\256\350\257\264\346\230\216.json" @@ -28,15 +28,11 @@ } }, "functionSelector": { - "描述": "可选,函数选择器,用于选择函数,如果存在则使用MultiParams组件,用于一类参数类似,但函数名不同的命令", - "options": { - "描述": "必选,选项,一个数组,每个元素是一个对象,包含以下属性:", - "配置项属性": { - "label": "必选,显示的名称", - "value": "必选,生成代码时使用的函数名", - "icon": "可选,图标", - "config": "可选,特定函数独有参数配置,和MultiParams组件的config一样" - } + "配置项属性": { + "label": "必选,显示的名称", + "value": "必选,生成代码时使用的函数名", + "icon": "可选,图标", + "config": "可选,特定函数独有参数配置,和MultiParams组件的config一样" }, "value": "必选,默认值" } From 807da38e2eb18d03ce3f6a2402e793cdeec8d172 Mon Sep 17 00:00:00 2001 From: fofolee Date: Tue, 7 Jan 2025 18:19:25 +0800 Subject: [PATCH 003/332] =?UTF-8?q?=E4=BF=AE=E6=94=B9DNS=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/lib/quickcomposer/network/dns.js | 4 +- src/components/composer/MultiParams.vue | 10 +- src/components/composer/network/DnsEditor.vue | 241 ------------------ src/js/composer/cardComponents.js | 3 - src/js/composer/commands/networkCommands.js | 86 ++++++- src/js/composer/commonComponentGuide.js | 127 +++++++++ src/js/composer/customComponentGuide.js | 1 - 7 files changed, 221 insertions(+), 251 deletions(-) delete mode 100644 src/components/composer/network/DnsEditor.vue create mode 100644 src/js/composer/commonComponentGuide.js diff --git a/plugin/lib/quickcomposer/network/dns.js b/plugin/lib/quickcomposer/network/dns.js index 8e00ad23..46e91ba6 100644 --- a/plugin/lib/quickcomposer/network/dns.js +++ b/plugin/lib/quickcomposer/network/dns.js @@ -13,9 +13,9 @@ const resolveCname = promisify(dns.resolveCname); const reverse = promisify(dns.reverse); // 解析主机名 -async function lookupHost(hostname, options = {}) { +async function lookupHost(hostname, family = 0, all = false) { try { - return await lookup(hostname, options); + return await lookup(hostname, { family, all }); } catch (error) { throw new Error(`DNS查询失败: ${error.message}`); } diff --git a/src/components/composer/MultiParams.vue b/src/components/composer/MultiParams.vue index 7904ba67..40a7b893 100644 --- a/src/components/composer/MultiParams.vue +++ b/src/components/composer/MultiParams.vue @@ -36,9 +36,15 @@ export default defineComponent({ }, // 通用参数配置 commonConfig() { - return this.modelValue.config || []; + return ( + // 过滤掉特定函数排除的参数, excludeConfig格式为[要排除的参数索引] + this.modelValue.config?.filter( + (_, index) => + !this.getSelectFunction()?.excludeConfig?.includes(index) + ) || [] + ); }, - // 特定函数独有参数配置 + // 特定函数独有参数配置,config格式和通用的config一致 functionConfig() { return this.getSelectFunction()?.config || []; }, diff --git a/src/components/composer/network/DnsEditor.vue b/src/components/composer/network/DnsEditor.vue deleted file mode 100644 index ecc35dac..00000000 --- a/src/components/composer/network/DnsEditor.vue +++ /dev/null @@ -1,241 +0,0 @@ - - - - - diff --git a/src/js/composer/cardComponents.js b/src/js/composer/cardComponents.js index fe998217..f6fa48af 100644 --- a/src/js/composer/cardComponents.js +++ b/src/js/composer/cardComponents.js @@ -73,9 +73,6 @@ export const ZlibEditor = defineAsyncComponent(() => export const UrlEditor = defineAsyncComponent(() => import("components/composer/network/UrlEditor.vue") ); -export const DnsEditor = defineAsyncComponent(() => - import("components/composer/network/DnsEditor.vue") -); export const BufferEditor = defineAsyncComponent(() => import("src/components/composer/data/BufferEditor.vue") ); diff --git a/src/js/composer/commands/networkCommands.js b/src/js/composer/commands/networkCommands.js index 94b2f9af..a9ac8ca7 100644 --- a/src/js/composer/commands/networkCommands.js +++ b/src/js/composer/commands/networkCommands.js @@ -54,12 +54,94 @@ export const networkCommands = { icon: "link", }, { - value: "quickcomposer.network.dns", + value: "quickcomposer.network.dns.lookupHost", label: "DNS操作", desc: "DNS解析和查询", - component: "DnsEditor", icon: "dns", isAsync: true, + config: [ + { + label: "要查询的域名", + icon: "dns", + type: "varInput", + width: "auto", + }, + ], + functionSelector: [ + { + label: "DNS查询", + value: "quickcomposer.network.dns.lookupHost", + icon: "search", + config: [ + { + label: "IP版本", + icon: "settings_ethernet", + type: "select", + options: [ + { label: "自动", value: 0 }, + { label: "IPv4", value: 4 }, + { label: "IPv6", value: 6 }, + ], + defaultValue: 0, + width: 2.5, + }, + { + label: "返回所有地址", + type: "checkbox", + defaultValue: false, + width: 2.5, + }, + ], + }, + { + value: "quickcomposer.network.dns.resolveAll", + label: "解析所有记录", + icon: "all_inclusive", + }, + { + value: "quickcomposer.network.dns.resolveIpv4", + label: "解析IPv4", + icon: "filter_4", + }, + { + value: "quickcomposer.network.dns.resolveIpv6", + label: "解析IPv6", + icon: "filter_6", + }, + { + value: "quickcomposer.network.dns.resolveMxRecords", + label: "解析MX记录", + icon: "mail", + }, + { + value: "quickcomposer.network.dns.resolveTxtRecords", + label: "解析TXT记录", + icon: "text_fields", + }, + { + value: "quickcomposer.network.dns.resolveNsRecords", + label: "解析NS记录", + icon: "dns", + }, + { + value: "quickcomposer.network.dns.resolveCnameRecords", + label: "解析CNAME记录", + icon: "link", + }, + { + value: "quickcomposer.network.dns.reverseResolve", + label: "反向解析", + icon: "swap_horiz", + excludeConfig: [0], + config: [ + { + label: "IP地址", + icon: "router", + type: "varInput", + }, + ], + }, + ], }, ], }; diff --git a/src/js/composer/commonComponentGuide.js b/src/js/composer/commonComponentGuide.js new file mode 100644 index 00000000..fb1c8503 --- /dev/null +++ b/src/js/composer/commonComponentGuide.js @@ -0,0 +1,127 @@ +/** + * Common Component Creation Guide + * 通用组件创建指南 - 使用 MultiParams 组件 + */ +const commonComponentGuide = { + description: "创建使用 MultiParams 组件的命令的完整流程", + important: "创建过程中严禁删除、修改任何已有的函数或对象", + steps: { + "1. Backend Interface": { + location: "plugin/lib/quickcomposer/xxx/yyy.js", + description: "创建具体功能实现", + requirements: { + functionDefinition: "使用独立函数而非对象方法", + asyncHandling: "使用 async/await 处理异步操作", + errorHandling: "合理的错误捕获和提示", + paramValidation: "检查必要参数是否存在", + }, + }, + "2. Interface Export": { + location: "plugin/lib/quickcomposer/xxx/index.js", + description: "导出接口给quickcomposer使用", + examples: { + singleFunction: "module.exports = { operation }", + multipleFunctions: "module.exports = { ...encoder, ...hash }", + }, + }, + "3. Interface Registration": { + location: "plugin/lib/quickcomposer.js", + description: "将接口注册到quickcomposer对象", + format: "quickcomposer.xxx = require('./quickcomposer/xxx')", + }, + "4. Command Configuration": { + location: "src/js/composer/commands/xxxCommands.js", + description: "配置命令参数,使用 MultiParams 组件", + requiredFields: { + value: "必选,生成代码时使用的函数名,如 quickcomposer.xxx.yyy", + label: "必选,命令的显示名称", + config: { + description: "必选,通用参数配置数组,每个元素是一个对象", + properties: { + label: "必选,参数标签", + type: "必选,参数类型(varInput/numInput/select/checkbox等)", + icon: "必选,参数图标", + width: "可选,参数占用宽度(1-12或auto)", + defaultValue: "可选,参数默认值", + options: "可选,select等类型的选项", + }, + example: ` + config: [ + { + label: "域名", + type: "varInput", + icon: "dns", + width: "auto" + } + ] + `, + }, + functionSelector: { + description: + "可选,函数选择器配置,用于一个命令包含多个相关函数的情况", + properties: { + value: "必选,函数名", + label: "必选,显示名称", + icon: "可选,图标", + config: "可选,函数特有的参数配置,格式同通用config", + excludeConfig: "可选,要排除的通用参数索引数组", + }, + example: ` + functionSelector: [ + { + label: "DNS查询", + value: "quickcomposer.network.dns.lookupHost", + icon: "search", + config: [ + { + label: "IP版本", + type: "select", + options: [ + { label: "自动", value: 0 }, + { label: "IPv4", value: 4 } + ], + defaultValue: 0 + } + ] + }, + { + value: "quickcomposer.network.dns.reverseResolve", + label: "反向解析", + icon: "swap_horiz", + excludeConfig: [0], // 排除第一个通用参数 + config: [ + { + label: "IP地址", + type: "varInput", + icon: "router" + } + ] + } + ] + `, + }, + }, + optionalFields: { + desc: "命令描述", + isAsync: "是否异步命令", + icon: "命令图标", + }, + }, + }, + notes: { + bestPractices: { + description: "最佳实践", + tips: [ + "合理使用 width 属性布局参数", + "相关参数尽量放在同一行", + "使用 excludeConfig 禁用掉不需要的参数配置", + "合理设置 defaultValue", + "使用语义化的图标", + "保持参数标签简洁明了", + ], + }, + }, + examples: { + multiFunctionCommand: "多函数命令,如DNS操作", + }, +}; diff --git a/src/js/composer/customComponentGuide.js b/src/js/composer/customComponentGuide.js index 4c0e5b24..cf61a53b 100644 --- a/src/js/composer/customComponentGuide.js +++ b/src/js/composer/customComponentGuide.js @@ -272,7 +272,6 @@ const customComponentGuide = { desc: "命令描述", isAsync: "是否异步命令", isControlFlow: "是否控制流命令", - allowEmptyArgv: "是否允许空参数", }, }, }, From e23d3e5e11d56d96098193d0f6193d1e9fcb826e Mon Sep 17 00:00:00 2001 From: fofolee Date: Tue, 7 Jan 2025 19:28:14 +0800 Subject: [PATCH 004/332] =?UTF-8?q?OS/URL/PATH/BUFFER=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/lib/quickcomposer/network/url.js | 57 +- plugin/lib/quickcomposer/system/os.js | 8 +- plugin/lib/quickcomposer/system/path.js | 27 +- src/components/composer/ComposerCard.vue | 6 +- src/components/composer/MultiParams.vue | 1 - .../composer/common/ButtonGroup.vue | 70 ++ src/components/composer/common/ParamInput.vue | 8 + src/components/composer/data/BufferEditor.vue | 695 ------------------ src/components/composer/network/UrlEditor.vue | 455 ------------ src/components/composer/system/OsEditor.vue | 368 ---------- src/components/composer/system/PathEditor.vue | 438 ----------- src/js/composer/cardComponents.js | 12 - src/js/composer/commands/dataCommands.js | 348 ++++++++- src/js/composer/commands/networkCommands.js | 174 ++++- src/js/composer/commands/systemCommands.js | 248 ++++++- 15 files changed, 902 insertions(+), 2013 deletions(-) create mode 100644 src/components/composer/common/ButtonGroup.vue delete mode 100644 src/components/composer/data/BufferEditor.vue delete mode 100644 src/components/composer/network/UrlEditor.vue delete mode 100644 src/components/composer/system/OsEditor.vue delete mode 100644 src/components/composer/system/PathEditor.vue diff --git a/plugin/lib/quickcomposer/network/url.js b/plugin/lib/quickcomposer/network/url.js index f9174805..bef341d3 100644 --- a/plugin/lib/quickcomposer/network/url.js +++ b/plugin/lib/quickcomposer/network/url.js @@ -1,32 +1,57 @@ const url = require("url"); // URL 解析 -function parse(urlString, parseQueryString = false) { - return url.parse(urlString, parseQueryString); +function parse(urlString) { + try { + return url.parse(urlString, false); + } catch (error) { + throw new Error(`URL解析失败: ${error.message}`); + } } -// URL 格式化 -function format(urlObject) { - return url.format(urlObject); +// 格式化 URL +function format(protocol, auth, hostname, port, pathname, search, hash) { + try { + const urlObject = { + protocol, + auth, + hostname, + port, + pathname, + search, + hash, + }; + return url.format(urlObject); + } catch (error) { + throw new Error(`URL格式化失败: ${error.message}`); + } } // 解析查询字符串 -function parseQuery(query) { - const searchParams = new URLSearchParams(query); - const result = {}; - for (const [key, value] of searchParams) { - result[key] = value; +function parseQuery(queryString) { + try { + const searchParams = new URLSearchParams(queryString); + const result = {}; + for (const [key, value] of searchParams) { + result[key] = value; + } + return result; + } catch (error) { + throw new Error(`查询字符串解析失败: ${error.message}`); } - return result; } // 格式化查询字符串 -function formatQuery(queryObject) { - const searchParams = new URLSearchParams(); - for (const [key, value] of Object.entries(queryObject)) { - searchParams.append(key, value); +function formatQuery(queryParams) { + try { + const searchParams = new URLSearchParams(); + for (const [key, value] of Object.entries(queryParams)) { + searchParams.append(key, value); + } + return searchParams.toString(); + } catch (error) { + throw new Error(`查询字符串格式化失败: ${error.message}`); } - return searchParams.toString(); } // 解析路径名 diff --git a/plugin/lib/quickcomposer/system/os.js b/plugin/lib/quickcomposer/system/os.js index 83f390e7..2260c2da 100644 --- a/plugin/lib/quickcomposer/system/os.js +++ b/plugin/lib/quickcomposer/system/os.js @@ -6,7 +6,7 @@ function arch() { } // 获取CPU信息 -function cpus({ format = "full" } = {}) { +function cpus(format = "full") { const cpuInfo = os.cpus(); if (format === "simple") { return cpuInfo.map(({ model, speed }) => ({ model, speed })); @@ -15,7 +15,7 @@ function cpus({ format = "full" } = {}) { } // 获取内存信息 -function memory({ type = "totalmem" } = {}) { +function memory(type = "totalmem") { switch (type) { case "totalmem": return os.totalmem(); @@ -27,7 +27,7 @@ function memory({ type = "totalmem" } = {}) { } // 获取网络信息 -function network({ type = "hostname", internal = false } = {}) { +function network(type = "hostname", internal = false) { switch (type) { case "hostname": return os.hostname(); @@ -50,7 +50,7 @@ function network({ type = "hostname", internal = false } = {}) { } // 获取平台信息 -function platform({ type = "platform" } = {}) { +function platform(type = "platform") { switch (type) { case "platform": return os.platform(); diff --git a/plugin/lib/quickcomposer/system/path.js b/plugin/lib/quickcomposer/system/path.js index b30a1c6a..7c59cc57 100644 --- a/plugin/lib/quickcomposer/system/path.js +++ b/plugin/lib/quickcomposer/system/path.js @@ -5,7 +5,7 @@ const path = require("path"); * @param {string} p 要规范化的路径 * @returns {string} 规范化后的路径 */ -async function normalize(p) { +function normalize(p) { try { return path.normalize(p); } catch (error) { @@ -18,7 +18,7 @@ async function normalize(p) { * @param {...string} paths 路径片段 * @returns {string} 连接后的路径 */ -async function join(...paths) { +function join(...paths) { try { return path.join(...paths); } catch (error) { @@ -31,7 +31,7 @@ async function join(...paths) { * @param {string} p 要解析的路径 * @returns {Object} 解析结果,包含 root, dir, base, ext, name */ -async function parse(p) { +function parse(p) { try { return path.parse(p); } catch (error) { @@ -44,7 +44,7 @@ async function parse(p) { * @param {string} p 路径 * @returns {string} 目录名 */ -async function dirname(p) { +function dirname(p) { try { return path.dirname(p); } catch (error) { @@ -58,7 +58,7 @@ async function dirname(p) { * @param {string} [ext] 可选的扩展名,如果提供则从结果中移除 * @returns {string} 文件名 */ -async function basename(p, ext) { +function basename(p, ext = undefined) { try { return path.basename(p, ext); } catch (error) { @@ -71,7 +71,7 @@ async function basename(p, ext) { * @param {string} p 路径 * @returns {string} 扩展名 */ -async function extname(p) { +function extname(p) { try { return path.extname(p); } catch (error) { @@ -84,7 +84,7 @@ async function extname(p) { * @param {string} p 路径 * @returns {boolean} 是否为绝对路径 */ -async function isAbsolute(p) { +function isAbsolute(p) { try { return path.isAbsolute(p); } catch (error) { @@ -98,7 +98,7 @@ async function isAbsolute(p) { * @param {string} to 目标路径 * @returns {string} 相对路径 */ -async function relative(from, to) { +function relative(from, to) { try { return path.relative(from, to); } catch (error) { @@ -111,7 +111,7 @@ async function relative(from, to) { * @param {...string} paths 路径片段 * @returns {string} 解析后的绝对路径 */ -async function resolve(...paths) { +function resolve(...paths) { try { return path.resolve(...paths); } catch (error) { @@ -121,11 +121,16 @@ async function resolve(...paths) { /** * 格式化路径对象为路径字符串 - * @param {Object} pathObject 路径对象,包含 dir, root, base, name, ext + * @param {string} root 根路径 + * @param {string} dir 目录 + * @param {string} base 基本名称 + * @param {string} name 文件名 + * @param {string} ext 扩展名 * @returns {string} 格式化后的路径 */ -async function format(pathObject) { +function format(root, dir, base, name, ext) { try { + const pathObject = { root, dir, base, name, ext }; return path.format(pathObject); } catch (error) { throw new Error(`格式化路径失败: ${error.message}`); diff --git a/src/components/composer/ComposerCard.vue b/src/components/composer/ComposerCard.vue index 67622410..9c3bc993 100644 --- a/src/components/composer/ComposerCard.vue +++ b/src/components/composer/ComposerCard.vue @@ -55,7 +55,11 @@ diff --git a/src/components/composer/MultiParams.vue b/src/components/composer/MultiParams.vue index 40a7b893..19c8ddb0 100644 --- a/src/components/composer/MultiParams.vue +++ b/src/components/composer/MultiParams.vue @@ -111,7 +111,6 @@ export default defineComponent({ this.updateModelValue(this.funcName, newArgvs); }, generateCode(funcName, argvs) { - console.log("argvs", argvs); /** * 字符串模式stringfiy后,null会变成'"null"', ''变成'""' * 变量模式stringify后,null变成'null', ''保持'' diff --git a/src/components/composer/common/ButtonGroup.vue b/src/components/composer/common/ButtonGroup.vue new file mode 100644 index 00000000..c2b406fe --- /dev/null +++ b/src/components/composer/common/ButtonGroup.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/components/composer/common/ParamInput.vue b/src/components/composer/common/ParamInput.vue index 9f9ba04b..2324960b 100644 --- a/src/components/composer/common/ParamInput.vue +++ b/src/components/composer/common/ParamInput.vue @@ -72,6 +72,12 @@ :label="config.label" :icon="config.icon" /> + @@ -82,6 +88,7 @@ import VariableInput from "./VariableInput.vue"; import NumberInput from "./NumberInput.vue"; import ArrayEditor from "./ArrayEditor.vue"; import DictEditor from "./DictEditor.vue"; +import ButtonGroup from "./ButtonGroup.vue"; /** * 参数输入组件 @@ -101,6 +108,7 @@ export default defineComponent({ NumberInput, ArrayEditor, DictEditor, + ButtonGroup, }, props: { configs: { diff --git a/src/components/composer/data/BufferEditor.vue b/src/components/composer/data/BufferEditor.vue deleted file mode 100644 index cd3c9dd8..00000000 --- a/src/components/composer/data/BufferEditor.vue +++ /dev/null @@ -1,695 +0,0 @@ - - - - - diff --git a/src/components/composer/network/UrlEditor.vue b/src/components/composer/network/UrlEditor.vue deleted file mode 100644 index 1422f340..00000000 --- a/src/components/composer/network/UrlEditor.vue +++ /dev/null @@ -1,455 +0,0 @@ - - - - - diff --git a/src/components/composer/system/OsEditor.vue b/src/components/composer/system/OsEditor.vue deleted file mode 100644 index 6ece904c..00000000 --- a/src/components/composer/system/OsEditor.vue +++ /dev/null @@ -1,368 +0,0 @@ - - - - - diff --git a/src/components/composer/system/PathEditor.vue b/src/components/composer/system/PathEditor.vue deleted file mode 100644 index 649b07f2..00000000 --- a/src/components/composer/system/PathEditor.vue +++ /dev/null @@ -1,438 +0,0 @@ - - - - - diff --git a/src/js/composer/cardComponents.js b/src/js/composer/cardComponents.js index f6fa48af..fc0da7cf 100644 --- a/src/js/composer/cardComponents.js +++ b/src/js/composer/cardComponents.js @@ -60,19 +60,7 @@ export const SystemCommandEditor = defineAsyncComponent(() => import("components/composer/system/SystemCommandEditor.vue") ); -export const OsEditor = defineAsyncComponent(() => - import("components/composer/system/OsEditor.vue") -); -export const PathEditor = defineAsyncComponent(() => - import("components/composer/system/PathEditor.vue") -); export const ZlibEditor = defineAsyncComponent(() => import("src/components/composer/data/ZlibEditor.vue") ); -export const UrlEditor = defineAsyncComponent(() => - import("components/composer/network/UrlEditor.vue") -); -export const BufferEditor = defineAsyncComponent(() => - import("src/components/composer/data/BufferEditor.vue") -); diff --git a/src/js/composer/commands/dataCommands.js b/src/js/composer/commands/dataCommands.js index 10678d71..864b13da 100644 --- a/src/js/composer/commands/dataCommands.js +++ b/src/js/composer/commands/dataCommands.js @@ -312,11 +312,355 @@ export const dataCommands = { saveOutput: true, }, { - value: "quickcomposer.data.buffer", + value: "quickcomposer.data.buffer.from", label: "Buffer操作", desc: "Buffer创建、转换和操作", - component: "BufferEditor", + config: [], icon: "memory", + functionSelector: [ + { + value: "quickcomposer.data.buffer.from", + label: "创建Buffer", + icon: "add_box", + config: [ + { + label: "数据", + type: "varInput", + icon: "text_fields", + width: 9, + }, + { + label: "编码", + type: "select", + icon: "code", + options: [ + { label: "UTF-8", value: "utf8" }, + { label: "UTF-16LE", value: "utf16le" }, + { label: "Latin1", value: "latin1" }, + { label: "Base64", value: "base64" }, + { label: "Hex", value: "hex" }, + { label: "ASCII", value: "ascii" }, + { label: "Binary", value: "binary" }, + { label: "UCS-2", value: "ucs2" }, + ], + defaultValue: "utf8", + width: 3, + }, + ], + }, + { + value: "quickcomposer.data.buffer.toString", + label: "转换字符串", + icon: "text_fields", + config: [ + { + label: "Buffer", + type: "varInput", + icon: "memory", + width: 12, + }, + { + label: "编码", + type: "select", + icon: "code", + options: [ + { label: "UTF-8", value: "utf8" }, + { label: "UTF-16LE", value: "utf16le" }, + { label: "Latin1", value: "latin1" }, + { label: "Base64", value: "base64" }, + { label: "Hex", value: "hex" }, + { label: "ASCII", value: "ascii" }, + { label: "Binary", value: "binary" }, + { label: "UCS-2", value: "ucs2" }, + ], + defaultValue: "utf8", + width: 4, + }, + { + label: "起始位置", + type: "numInput", + icon: "first_page", + width: 4, + }, + { + label: "结束位置", + type: "numInput", + icon: "last_page", + width: 4, + }, + ], + }, + { + value: "quickcomposer.data.buffer.write", + label: "写入数据", + icon: "edit", + config: [ + { + label: "Buffer", + type: "varInput", + icon: "memory", + width: 6, + }, + { + label: "要写入的字符串", + type: "varInput", + icon: "edit", + width: 6, + }, + { + label: "偏移量", + type: "numInput", + icon: "first_page", + width: 4, + }, + { + label: "长度", + type: "numInput", + icon: "straighten", + width: 4, + }, + { + label: "编码", + type: "select", + icon: "code", + options: [ + { label: "UTF-8", value: "utf8" }, + { label: "UTF-16LE", value: "utf16le" }, + { label: "Latin1", value: "latin1" }, + { label: "Base64", value: "base64" }, + { label: "Hex", value: "hex" }, + { label: "ASCII", value: "ascii" }, + { label: "Binary", value: "binary" }, + { label: "UCS-2", value: "ucs2" }, + ], + defaultValue: "utf8", + width: 4, + }, + ], + }, + { + value: "quickcomposer.data.buffer.fill", + label: "填充数据", + icon: "format_color_fill", + config: [ + { + label: "Buffer", + type: "varInput", + icon: "memory", + width: 6, + }, + { + label: "填充值", + type: "varInput", + icon: "format_color_fill", + width: 6, + }, + { + label: "起始位置", + type: "numInput", + icon: "first_page", + width: 4, + }, + { + label: "结束位置", + type: "numInput", + icon: "last_page", + width: 4, + }, + { + label: "编码", + type: "select", + icon: "code", + options: [ + { label: "UTF-8", value: "utf8" }, + { label: "UTF-16LE", value: "utf16le" }, + { label: "Latin1", value: "latin1" }, + { label: "Base64", value: "base64" }, + { label: "Hex", value: "hex" }, + { label: "ASCII", value: "ascii" }, + { label: "Binary", value: "binary" }, + { label: "UCS-2", value: "ucs2" }, + ], + defaultValue: "utf8", + width: 4, + }, + ], + }, + { + value: "quickcomposer.data.buffer.copy", + label: "复制数据", + icon: "content_copy", + config: [ + { + label: "源Buffer", + type: "varInput", + icon: "content_copy", + width: 6, + }, + { + label: "目标Buffer", + type: "varInput", + icon: "save", + width: 6, + }, + { + label: "目标起始位置", + type: "numInput", + icon: "first_page", + width: 4, + }, + { + label: "源起始位置", + type: "numInput", + icon: "first_page", + width: 4, + }, + { + label: "源结束位置", + type: "numInput", + icon: "last_page", + width: 4, + }, + ], + }, + { + value: "quickcomposer.data.buffer.compare", + label: "比较数据", + icon: "compare", + config: [ + { + label: "Buffer 1", + type: "varInput", + icon: "memory", + width: 6, + }, + { + label: "Buffer 2", + type: "varInput", + icon: "memory", + width: 6, + }, + ], + }, + { + value: "quickcomposer.data.buffer.concat", + label: "连接Buffer", + icon: "merge", + config: [ + { + label: "Buffer列表", + type: "arrayEditor", + icon: "memory", + width: 12, + defaultValue: [ + { + value: "", + isString: false, + __varInputVal__: true, + }, + ], + }, + { + label: "总长度(可选)", + type: "numInput", + icon: "straighten", + width: 12, + }, + ], + }, + { + value: "quickcomposer.data.buffer.slice", + label: "切片数据", + icon: "content_cut", + config: [ + { + label: "Buffer", + type: "varInput", + icon: "memory", + width: 12, + }, + { + label: "起始位置", + type: "numInput", + icon: "first_page", + width: 6, + }, + { + label: "结束位置", + type: "numInput", + icon: "last_page", + width: 6, + }, + ], + }, + { + value: "quickcomposer.data.buffer.indexOf", + label: "查找数据", + icon: "search", + config: [ + { + label: "Buffer", + type: "varInput", + icon: "memory", + width: 12, + }, + { + label: "要查找的值", + type: "varInput", + icon: "search", + width: 4, + }, + { + label: "起始位置", + type: "numInput", + icon: "first_page", + width: 4, + }, + { + label: "编码", + type: "select", + icon: "code", + options: [ + { label: "UTF-8", value: "utf8" }, + { label: "UTF-16LE", value: "utf16le" }, + { label: "Latin1", value: "latin1" }, + { label: "Base64", value: "base64" }, + { label: "Hex", value: "hex" }, + { label: "ASCII", value: "ascii" }, + { label: "Binary", value: "binary" }, + { label: "UCS-2", value: "ucs2" }, + ], + defaultValue: "utf8", + width: 4, + }, + ], + }, + { + value: "quickcomposer.data.buffer.swap", + label: "交换字节序", + icon: "swap_horiz", + config: [ + { + label: "Buffer", + type: "varInput", + icon: "memory", + width: 9, + }, + { + label: "字节大小", + type: "select", + icon: "memory", + options: [ + { label: "16位", value: 16 }, + { label: "32位", value: 32 }, + { label: "64位", value: 64 }, + ], + defaultValue: 16, + width: 3, + }, + ], + }, + ], }, { value: "quickcomposer.data.zlib", diff --git a/src/js/composer/commands/networkCommands.js b/src/js/composer/commands/networkCommands.js index a9ac8ca7..ab7dd501 100644 --- a/src/js/composer/commands/networkCommands.js +++ b/src/js/composer/commands/networkCommands.js @@ -47,11 +47,181 @@ export const networkCommands = { saveOutput: true, }, { - value: "quickcomposer.network.url", + value: "quickcomposer.network.url.parse", label: "URL操作", desc: "URL解析、格式化和参数处理", - component: "UrlEditor", icon: "link", + config: [ + { + label: "URL", + type: "varInput", + icon: "link", + width: "auto", + }, + ], + functionSelector: [ + { + value: "quickcomposer.network.url.parse", + label: "解析URL", + icon: "link_off", + }, + { + value: "quickcomposer.network.url.format", + label: "格式化URL", + icon: "link", + excludeConfig: [0], + config: [ + { + label: "协议", + type: "varInput", + icon: "security", + width: 6, + }, + { + label: "认证信息", + type: "varInput", + icon: "person", + width: 6, + }, + { + label: "主机名", + type: "varInput", + icon: "dns", + width: 6, + }, + { + label: "端口", + type: "varInput", + icon: "settings_ethernet", + width: 6, + }, + { + label: "路径", + type: "varInput", + icon: "folder", + }, + { + label: "查询字符串", + type: "varInput", + icon: "search", + width: 6, + }, + { + label: "锚点", + type: "varInput", + icon: "tag", + width: 6, + }, + ], + }, + { + value: "quickcomposer.network.url.parseQuery", + label: "解析查询字符串", + icon: "search", + excludeConfig: [0], + config: [ + { + label: "查询字符串", + type: "varInput", + icon: "search", + }, + ], + }, + { + value: "quickcomposer.network.url.formatQuery", + label: "格式化查询字符串", + icon: "edit", + excludeConfig: [0], + config: [ + { + label: "参数", + type: "dictEditor", + icon: "edit", + }, + ], + }, + { + value: "quickcomposer.network.url.parsePath", + label: "解析路径", + icon: "folder_open", + excludeConfig: [0], + config: [ + { + label: "路径", + type: "varInput", + icon: "folder", + }, + ], + }, + { + value: "quickcomposer.network.url.parseHost", + label: "解析主机名", + icon: "dns", + excludeConfig: [0], + config: [ + { + label: "主机名", + type: "varInput", + icon: "dns", + }, + ], + }, + { + value: "quickcomposer.network.url.getQueryParam", + label: "获取参数", + icon: "find_in_page", + config: [ + { + label: "参数名", + type: "varInput", + icon: "key", + width: "auto", + }, + ], + }, + { + value: "quickcomposer.network.url.addQueryParam", + label: "添加参数", + icon: "add_circle", + config: [ + { + label: "参数名", + type: "varInput", + icon: "key", + width: "auto", + }, + { + label: "参数值", + type: "varInput", + icon: "text_fields", + width: "auto", + }, + ], + }, + { + value: "quickcomposer.network.url.removeQueryParam", + label: "移除参数", + icon: "remove_circle", + config: [ + { + label: "参数名", + type: "varInput", + icon: "key", + width: "auto", + }, + ], + }, + { + value: "quickcomposer.network.url.isAbsolute", + label: "检查绝对URL", + icon: "check_circle", + }, + { + value: "quickcomposer.network.url.parseComponents", + label: "解析组成部分", + icon: "category", + }, + ], }, { value: "quickcomposer.network.dns.lookupHost", diff --git a/src/js/composer/commands/systemCommands.js b/src/js/composer/commands/systemCommands.js index cb6a6251..9e4caf4f 100644 --- a/src/js/composer/commands/systemCommands.js +++ b/src/js/composer/commands/systemCommands.js @@ -32,20 +32,252 @@ export const systemCommands = { isAsync: true, }, { - value: "quickcomposer.system.os", + value: "quickcomposer.system.os.arch", label: "系统信息", desc: "获取操作系统相关信息", - component: "OsEditor", icon: "computer", - isAsync: true, + config: [], + functionSelector: [ + { + value: "quickcomposer.system.os.arch", + label: "系统架构", + icon: "memory", + }, + { + value: "quickcomposer.system.os.cpus", + label: "CPU信息", + icon: "developer_board", + config: [ + { + label: "信息格式", + type: "buttonGroup", + options: [ + { label: "完整信息", value: "full" }, + { label: "仅型号和速度", value: "simple" }, + ], + defaultValue: "full", + width: 12, + }, + ], + }, + { + value: "quickcomposer.system.os.memory", + label: "内存信息", + icon: "storage", + config: [ + { + label: "内存类型", + type: "buttonGroup", + options: [ + { label: "总内存", value: "totalmem" }, + { label: "空闲内存", value: "freemem" }, + ], + defaultValue: "totalmem", + width: 12, + }, + ], + }, + { + value: "quickcomposer.system.os.network", + label: "网络信息", + icon: "wifi", + config: [ + { + label: "网络信息类型", + type: "buttonGroup", + options: [ + { label: "主机名", value: "hostname" }, + { label: "网络接口", value: "networkInterfaces" }, + ], + defaultValue: "hostname", + width: 12, + }, + { + label: "包含内部接口", + type: "checkbox", + defaultValue: false, + width: 12, + condition: "values[0] === 'networkInterfaces'", + }, + ], + }, + { + value: "quickcomposer.system.os.platform", + label: "平台信息", + icon: "computer", + config: [ + { + label: "平台信息类型", + type: "buttonGroup", + options: [ + { label: "操作系统名称", value: "platform" }, + { label: "操作系统类型", value: "type" }, + { label: "操作系统版本", value: "release" }, + { label: "操作系统架构", value: "arch" }, + { label: "CPU字节序", value: "endianness" }, + { label: "系统临时目录", value: "tmpdir" }, + { label: "主目录", value: "homedir" }, + { label: "系统正常运行时间", value: "uptime" }, + { label: "用户信息", value: "userInfo" }, + ], + defaultValue: "platform", + width: 12, + }, + ], + }, + ], }, { - value: "quickcomposer.system.path", + value: "quickcomposer.system.path.normalize", label: "路径操作", - desc: "路径操作", - component: "PathEditor", - icon: "folder_path", - isAsync: true, + desc: "路径解析和处理", + icon: "folder", + config: [ + { + label: "路径", + type: "varInput", + icon: "folder", + width: "auto", + }, + ], + functionSelector: [ + { + value: "quickcomposer.system.path.normalize", + label: "规范化路径", + icon: "straighten", + }, + { + value: "quickcomposer.system.path.parse", + label: "解析路径", + icon: "account_tree", + }, + { + value: "quickcomposer.system.path.dirname", + label: "获取目录名", + icon: "folder", + }, + { + value: "quickcomposer.system.path.basename", + label: "获取文件名", + icon: "description", + config: [ + { + label: "要移除的扩展名", + type: "varInput", + icon: "extension", + width: "auto", + }, + ], + }, + { + value: "quickcomposer.system.path.extname", + label: "获取扩展名", + icon: "extension", + }, + { + value: "quickcomposer.system.path.isAbsolute", + label: "判断绝对路径", + icon: "check_circle", + }, + { + value: "quickcomposer.system.path.join", + label: "连接路径", + icon: "add_link", + excludeConfig: [0], + config: [ + { + label: "路径片段", + type: "varInput", + icon: "folder", + width: "auto", + }, + { + label: "路径片段", + type: "varInput", + icon: "folder", + width: "auto", + }, + ], + }, + { + value: "quickcomposer.system.path.resolve", + label: "解析绝对路径", + icon: "assistant_direction", + excludeConfig: [0], + config: [ + { + label: "路径片段", + type: "varInput", + icon: "folder", + width: "auto", + }, + { + label: "路径片段", + type: "varInput", + icon: "folder", + width: "auto", + }, + ], + }, + { + value: "quickcomposer.system.path.relative", + label: "计算相对路径", + icon: "compare_arrows", + excludeConfig: [0], + config: [ + { + label: "起始路径", + type: "varInput", + icon: "folder", + width: 6, + }, + { + label: "目标路径", + type: "varInput", + icon: "folder", + width: 6, + }, + ], + }, + { + value: "quickcomposer.system.path.format", + label: "格式化路径", + icon: "format_shapes", + excludeConfig: [0], + config: [ + { + label: "根路径", + type: "varInput", + icon: "folder", + width: 6, + }, + { + label: "目录", + type: "varInput", + icon: "folder", + width: 6, + }, + { + label: "基本名称", + type: "varInput", + icon: "description", + width: 6, + }, + { + label: "文件名", + type: "varInput", + icon: "insert_drive_file", + width: 6, + }, + { + label: "扩展名", + type: "varInput", + icon: "extension", + width: 6, + }, + ], + }, + ], }, ], }; From f742e6f121583e548fe47164ec640bdcb8c5b6ae Mon Sep 17 00:00:00 2001 From: fofolee Date: Wed, 8 Jan 2025 00:54:51 +0800 Subject: [PATCH 005/332] =?UTF-8?q?=E7=BC=96=E6=8E=92=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=88=97=E8=A1=A8=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../composer/common/ArrayEditor.vue | 42 ++- .../composer/common/OperationCard.vue | 12 +- src/components/composer/common/ParamInput.vue | 1 + .../composer/ui/SelectListEditor.vue | 346 ++++++++++++++++++ src/js/composer/cardComponents.js | 5 +- src/js/composer/commands/dataCommands.js | 2 +- src/js/composer/commands/index.js | 2 +- .../commands/{uiCommand.js => uiCommands.js} | 7 + 8 files changed, 398 insertions(+), 19 deletions(-) create mode 100644 src/components/composer/ui/SelectListEditor.vue rename src/js/composer/commands/{uiCommand.js => uiCommands.js} (87%) diff --git a/src/components/composer/common/ArrayEditor.vue b/src/components/composer/common/ArrayEditor.vue index ea6d64c6..71683a69 100644 --- a/src/components/composer/common/ArrayEditor.vue +++ b/src/components/composer/common/ArrayEditor.vue @@ -1,17 +1,19 @@ @@ -187,6 +187,7 @@ export default defineComponent({ }, label: String, icon: String, + noIcon: Boolean, options: { type: Object, default: () => ({}), diff --git a/src/components/composer/ui/SelectListEditor.vue b/src/components/composer/ui/SelectListEditor.vue index 2d4f0ebc..15a2ab59 100644 --- a/src/components/composer/ui/SelectListEditor.vue +++ b/src/components/composer/ui/SelectListEditor.vue @@ -6,7 +6,7 @@
@@ -22,7 +22,7 @@
{ + if (typeof val !== "string") val = JSON.stringify(val); + return { + value: val, + isString: type === "str", __varInputVal__: true, - }), + }; }; +const jsonDefaultSelects = new Array(3).fill().map((_, index) => ({ + id: newVarInputVal("var", index), + title: newVarInputVal("str"), + description: newVarInputVal("str"), +})); + +const textDefaultSelects = new Array(3).fill(newVarInputVal("str")); + const defaultSelects = { json: jsonDefaultSelects, plaintext: textDefaultSelects, @@ -248,12 +247,25 @@ export default defineComponent({ }, }, methods: { - updateArgvs(key, value) { + /** + * 更新参数 + * @param {string|string[]} keys - 键名 + * @param {string|string[]} values - 值 + */ + updateArgvs(keys, values) { + if (typeof keys === "string") { + keys = [keys]; + values = [values]; + } const argvs = { ...this.argvs }; - const keys = key.split("."); - const lastKey = keys.pop(); - const target = keys.reduce((obj, key) => obj[key], argvs); - target[lastKey] = value; + // 更新每一个键 + keys.forEach((key, index) => { + // 支持嵌套对象的键值 + const subKeys = key.split("."); + const lastKey = subKeys.pop(); + const target = subKeys.reduce((obj, key) => obj[key], argvs); + target[lastKey] = values[index]; + }); this.updateModelValue(argvs); }, generateCode(argvs = this.argvs) { @@ -285,13 +297,16 @@ export default defineComponent({ try { const result = parseFunction(code, { - variableFormatPaths: ["arg0", "arg1.placeholder"], + variableFormatPaths: ["arg0", "arg0[*]", "arg1.placeholder"], }); + if (!result) return this.defaultArgvs; const [selects, options = {}] = result.argvs; + const inputMode = selects.__varInputVal__ ? "variable" : "manual"; return { ...this.defaultArgvs, + inputMode, selects, ...options, }; @@ -318,20 +333,46 @@ export default defineComponent({ argvs, }); }, + handleOptionTypeChange(newOptionType) { + const oldOptionType = this.argvs.optionType; + // 原地点击不处理 + if (oldOptionType === newOptionType) return; + // 变量输入模式不需要处理 selects + if (this.argvs.inputMode === "variable") { + this.updateArgvs("optionType", newOptionType); + return; + } + const oldSelects = this.argvs.selects; + let newSelects = oldSelects; + // 从JSON转换为非JSON时,取title或description + if (oldOptionType === "json") { + newSelects = oldSelects.map( + (item) => item.title || item.description || newVarInputVal("str") + ); + } else if (newOptionType === "json") { + // 从非JSON转换为JSON时,添加title和description + newSelects = oldSelects.map((item) => ({ + title: item, + description: item, + })); + } + this.updateArgvs(["optionType", "selects"], [newOptionType, newSelects]); + }, + handleInputModeChange(newInputMode) { + let newSelects = this.argvs.selects; + if (newInputMode === "variable") { + newSelects = newVarInputVal("var"); + } else { + newSelects = defaultSelects[this.argvs.optionType]; + } + this.updateArgvs(["inputMode", "selects"], [newInputMode, newSelects]); + }, }, mounted() { if (!this.modelValue.argvs && !this.modelValue.code) { this.updateModelValue(this.defaultArgvs); } }, - watch: { - "argvs.optionType": { - immediate: true, - handler(newVal) { - this.argvs.selects = defaultSelects[newVal]; - }, - }, - }, }); diff --git a/src/js/composer/formatString.js b/src/js/composer/formatString.js index 63602390..1f531cdf 100644 --- a/src/js/composer/formatString.js +++ b/src/js/composer/formatString.js @@ -306,9 +306,37 @@ export const parseFunction = (functionStr, options = {}) => { return obj; }, {}); case "ArrayExpression": - return node.elements.map((element, index) => - processNode(element, `${currentPath}[${index}]`) - ); + return node.elements.map((element, index) => { + const elementPath = `${currentPath}[${index}]`; + const processedElement = processNode(element, elementPath); + + if ( + shouldUseVariableFormat && + typeof processedElement === "object" + ) { + return Object.entries(processedElement).reduce( + (acc, [key, value]) => { + // 如果值已经是 varInputVal 格式,直接使用 + if (value?.__varInputVal__) { + acc[key] = value; + } else { + // 否则转换为 varInputVal 格式 + acc[key] = { + value: + typeof value === "string" + ? value + : JSON.stringify(value), + isString: typeof value === "string", + __varInputVal__: true, + }; + } + return acc; + }, + {} + ); + } + return processedElement; + }); case "ObjectProperty": return processNode(node.value, currentPath); case "MemberExpression": From 7a43695e2d280eca05e60ee65dfcf9dd810a047c Mon Sep 17 00:00:00 2001 From: fofolee Date: Wed, 8 Jan 2025 14:39:08 +0800 Subject: [PATCH 007/332] =?UTF-8?q?=E7=BB=9F=E4=B8=80VarInput=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E7=9A=84=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/composer/MultiParams.vue | 7 +- .../composer/common/ArrayEditor.vue | 62 ++----- src/components/composer/common/DictEditor.vue | 25 +-- .../composer/common/VariableInput.vue | 44 +---- .../composer/data/AsymmetricCryptoEditor.vue | 8 +- .../composer/data/SymmetricCryptoEditor.vue | 7 +- src/components/composer/data/ZlibEditor.vue | 8 +- .../composer/data/regex/RegexEditor.vue | 13 +- .../composer/data/regex/RegexTester.vue | 13 +- .../composer/file/FileOperationEditor.vue | 7 +- .../composer/network/AxiosConfigEditor.vue | 61 ++----- .../composer/system/SystemCommandEditor.vue | 23 +-- .../composer/ubrowser/UBrowserBasic.vue | 8 +- .../operations/UBrowserCookieList.vue | 38 +--- .../operations/UBrowserDeviceName.vue | 8 +- .../ubrowser/operations/UBrowserFileList.vue | 8 +- .../operations/UBrowserNamedParamList.vue | 29 +--- .../composer/ui/SelectListEditor.vue | 17 +- src/js/composer/commands/dataCommands.js | 10 +- src/js/composer/commands/uiCommands.js | 26 +-- src/js/composer/customComponentGuide.js | 5 +- src/js/composer/formatString.js | 74 +++----- src/js/composer/ubrowserConfig.js | 164 ++++-------------- src/js/composer/varInputValManager.js | 41 +++++ 24 files changed, 190 insertions(+), 516 deletions(-) create mode 100644 src/js/composer/varInputValManager.js diff --git a/src/components/composer/MultiParams.vue b/src/components/composer/MultiParams.vue index 19c8ddb0..08d6d6d3 100644 --- a/src/components/composer/MultiParams.vue +++ b/src/components/composer/MultiParams.vue @@ -15,6 +15,7 @@ import { defineComponent } from "vue"; import OperationCard from "components/composer/common/OperationCard.vue"; import ParamInput from "components/composer/common/ParamInput.vue"; import { stringifyArgv, parseFunction } from "js/composer/formatString"; +import { newVarInputVal } from "js/composer/varInputValManager"; export default defineComponent({ name: "MultiParams", @@ -52,11 +53,7 @@ export default defineComponent({ return [...this.commonConfig, ...this.functionConfig].map((item) => { const value = item.type === "varInput" - ? item.defaultValue || { - value: "", - isString: true, - __varInputVal__: true, - } + ? item.defaultValue || newVarInputVal("str") : // 其他类型情况复杂,不做判断,没有默认值返回undefined item.defaultValue; return { diff --git a/src/components/composer/common/ArrayEditor.vue b/src/components/composer/common/ArrayEditor.vue index a11b71e1..c5f536e6 100644 --- a/src/components/composer/common/ArrayEditor.vue +++ b/src/components/composer/common/ArrayEditor.vue @@ -94,35 +94,30 @@ * @example * // 基础数组 * [ - * { - * value: "张三", - * isString: true, - * __varInputVal__: true - * } + * newVarInputVal("str", "张三") * ] * * // 多键对象数组 * options.keys = ['name', 'age', 'email'] * [ * { - * name: { value: "张三", isString: true, __varInputVal__: true }, - * age: { value: "18", isString: false, __varInputVal__: true }, - * email: { value: "zhangsan@example.com", isString: true, __varInputVal__: true } + * name: newVarInputVal("str", "张三"), + * age: newVarInputVal("str", "18"), + * email: newVarInputVal("str", "zhangsan@example.com") * } * ] * * // 下拉选择模式 * options.items = ['选项1', '选项2', '选项3'] * [ - * { - * value: "选项1", - * isString: true, - * __varInputVal__: true - * } + * newVarInputVal("str", "选项1"), + * newVarInputVal("str", "选项2"), + * newVarInputVal("str", "选项3") * ] */ import { defineComponent } from "vue"; import VariableInput from "components/composer/common/VariableInput.vue"; +import { newVarInputVal } from "js/composer/varInputValManager"; export default defineComponent({ name: "ArrayEditor", @@ -169,22 +164,12 @@ export default defineComponent({ if (this.optionsKeys?.length) { const item = {}; this.optionsKeys.forEach((key) => { - item[key] = { - value: "", - isString: true, - __varInputVal__: true, - }; + item[key] = newVarInputVal("str"); }); return [item]; } - return [ - { - value: "", - isString: true, - __varInputVal__: true, - }, - ]; + return [newVarInputVal("str")]; }, /** * 添加新的数组项 @@ -195,22 +180,11 @@ export default defineComponent({ if (this.options.keys) { const newItem = {}; this.options.keys.forEach((key) => { - newItem[key] = { - value: "", - isString: true, - __varInputVal__: true, - }; + newItem[key] = newVarInputVal("str"); }); newItems = [...this.items, newItem]; } else { - newItems = [ - ...this.items, - { - value: "", - isString: true, - __varInputVal__: true, - }, - ]; + newItems = [...this.items, newVarInputVal("str")]; } this.$emit("update:modelValue", newItems); }, @@ -225,19 +199,11 @@ export default defineComponent({ if (this.options.keys) { const newItem = {}; this.options.keys.forEach((key) => { - newItem[key] = { - value: "", - isString: true, - __varInputVal__: true, - }; + newItem[key] = newVarInputVal("str"); }); newItems.push(newItem); } else { - newItems.push({ - value: "", - isString: true, - __varInputVal__: true, - }); + newItems.push(newVarInputVal("str")); } } this.$emit("update:modelValue", newItems); diff --git a/src/components/composer/common/DictEditor.vue b/src/components/composer/common/DictEditor.vue index ce513056..2514b7aa 100644 --- a/src/components/composer/common/DictEditor.vue +++ b/src/components/composer/common/DictEditor.vue @@ -95,6 +95,7 @@ diff --git a/src/js/composer/cardComponents.js b/src/js/composer/cardComponents.js index 1ed87326..c919a921 100644 --- a/src/js/composer/cardComponents.js +++ b/src/js/composer/cardComponents.js @@ -1,14 +1,17 @@ import { defineAsyncComponent } from "vue"; -// UI Components +// 模拟操作组件 export const KeyEditor = defineAsyncComponent(() => import("src/components/composer/simulate/KeyEditor.vue") ); export const ImageSearchEditor = defineAsyncComponent(() => import("components/composer/simulate/ImageSearchEditor.vue") ); +export const KeySequenceEditor = defineAsyncComponent(() => + import("src/components/composer/simulate/KeySequenceEditor.vue") +); -// Control Flow Components +// 控制流组件 export const ConditionalJudgment = defineAsyncComponent(() => import("components/composer/control/ConditionalJudgment.vue") ); @@ -31,18 +34,24 @@ export const TryCatchControl = defineAsyncComponent(() => import("components/composer/control/TryCatchControl.vue") ); -// Editor Components +// 网络组件 export const UBrowserEditor = defineAsyncComponent(() => import("components/composer/ubrowser/UBrowserEditor.vue") ); export const AxiosConfigEditor = defineAsyncComponent(() => import("src/components/composer/network/AxiosConfigEditor.vue") ); + +// 数据组件 export const RegexEditor = defineAsyncComponent(() => import("components/composer/data/regex/RegexEditor.vue") ); -// Crypto Components +export const ZlibEditor = defineAsyncComponent(() => + import("src/components/composer/data/ZlibEditor.vue") +); + +// 加密组件 export const SymmetricCryptoEditor = defineAsyncComponent(() => import("src/components/composer/coding/SymmetricCryptoEditor.vue") ); @@ -50,20 +59,17 @@ export const AsymmetricCryptoEditor = defineAsyncComponent(() => import("src/components/composer/coding/AsymmetricCryptoEditor.vue") ); -// File Components +// 文件组件 export const FileOperationEditor = defineAsyncComponent(() => import("components/composer/file/FileOperationEditor.vue") ); -// System Components +// 系统组件 export const SystemCommandEditor = defineAsyncComponent(() => import("components/composer/system/SystemCommandEditor.vue") ); -export const ZlibEditor = defineAsyncComponent(() => - import("src/components/composer/data/ZlibEditor.vue") -); - +// UI组件 export const SelectListEditor = defineAsyncComponent(() => import("components/composer/ui/SelectListEditor.vue") ); diff --git a/src/js/composer/commands/index.js b/src/js/composer/commands/index.js index c2f1fe8d..41d362d4 100644 --- a/src/js/composer/commands/index.js +++ b/src/js/composer/commands/index.js @@ -10,12 +10,14 @@ import { uiCommands } from "./uiCommands"; import { codingCommands } from "./codingCommand"; import { mathCommands } from "./mathCommands"; import { userdataCommands } from "./userdataCommands"; +import { utoolsCommands } from "./utoolsCommand"; export const commandCategories = [ fileCommands, networkCommands, systemCommands, notifyCommands, + utoolsCommands, dataCommands, codingCommands, controlCommands, diff --git a/src/js/composer/commands/otherCommands.js b/src/js/composer/commands/otherCommands.js index 510066f5..b7edf869 100644 --- a/src/js/composer/commands/otherCommands.js +++ b/src/js/composer/commands/otherCommands.js @@ -3,18 +3,6 @@ export const otherCommands = { icon: "more_horiz", defaultOpened: false, commands: [ - { - value: "utools.redirect", - label: "转至指定插件", - config: [ - { - key: "pluginName", - label: "要跳转至的插件名称", - type: "varInput", - icon: "alt_route", - }, - ], - }, { value: "quickcommand.sleep", label: "添加延时", diff --git a/src/js/composer/commands/simulateCommands.js b/src/js/composer/commands/simulateCommands.js index 2eb3e524..e3dc6835 100644 --- a/src/js/composer/commands/simulateCommands.js +++ b/src/js/composer/commands/simulateCommands.js @@ -4,11 +4,34 @@ export const simulateCommands = { defaultOpened: false, commands: [ { - value: "utools.simulateKeyboardTap", + value: "quickcomposer.simulate.keyboardTap", label: "模拟按键", config: [], component: "KeyEditor", }, + { + value: "quickcomposer.simulate.keySequence", + label: "按键序列", + description: "按顺序执行多个按键操作", + component: "KeySequenceEditor", + }, + { + value: "quickcommand.simulateCopy", + label: "模拟复制粘贴", + config: [], + functionSelector: [ + { + value: "quickcommand.simulateCopy", + label: "复制", + icon: "content_copy", + }, + { + value: "quickcommand.simulatePaste", + label: "粘贴", + icon: "content_paste", + }, + ], + }, { value: "quickcomposer.simulate.sendText", label: "发送文本", diff --git a/src/js/composer/commands/systemCommands.js b/src/js/composer/commands/systemCommands.js index 62b321a7..64b1b4ab 100644 --- a/src/js/composer/commands/systemCommands.js +++ b/src/js/composer/commands/systemCommands.js @@ -1,3 +1,5 @@ +import { newVarInputVal } from "js/composer/varInputValManager"; + export const systemCommands = { label: "系统操作", icon: "computer", @@ -299,5 +301,26 @@ export const systemCommands = { }, ], }, + { + value: "quickcommand.kill", + label: "关闭进程", + desc: "关闭指定进程", + icon: "dangerous", + config: [ + { + label: "进程ID", + type: "numInput", + icon: "developer_board", + width: 6, + }, + { + label: "信号", + type: "varInput", + icon: "signal_cellular_alt", + defaultValue: newVarInputVal("str", "SIGTERM"), + width: 6, + }, + ], + }, ], }; diff --git a/src/js/composer/commands/utoolsCommand.js b/src/js/composer/commands/utoolsCommand.js new file mode 100644 index 00000000..518afcf5 --- /dev/null +++ b/src/js/composer/commands/utoolsCommand.js @@ -0,0 +1,87 @@ +export const utoolsCommands = { + label: "uTools功能", + icon: "insights", + commands: [ + { + value: "utools.hideMainWindow", + label: "隐藏主窗口", + desc: "隐藏主窗口", + icon: "visibility_off", + }, + { + value: "quickcommand.wakeUtools", + label: "唤醒uTools", + desc: "唤醒uTools", + icon: "visibility", + }, + { + value: "utools.setExpendHeight", + label: "设置uTools高度", + desc: "设置uTools高度", + icon: "height", + config: [ + { + key: "height", + label: "高度", + type: "numInput", + icon: "straighten", + width: 12, + }, + ], + }, + { + value: "utools.outPlugin", + label: "退出插件", + desc: "退出插件", + icon: "exit_to_app", + config: [ + { + key: "isKill", + type: "select", + options: [ + { label: "杀死插件进程", value: true }, + { label: "插件隐藏到后台", value: false }, + ], + defaultValue: false, + icon: "logout", + }, + ], + }, + { + value: "utools.isDarkColors", + label: "是否深色模式", + desc: "是否深色模式", + icon: "dark_mode", + outputVariable: "isDark", + saveOutput: true, + }, + { + value: "utools.getUser", + label: "获取用户信息", + desc: "获取用户信息", + icon: "person", + outputVariable: "{avatar,nickname,type}", + saveOutput: true, + }, + { + value: "utools.redirect", + label: "转至指定插件", + config: [ + { + key: "pluginName", + label: "要跳转至的插件名称", + type: "varInput", + icon: "alt_route", + width: 6, + }, + { + key: "payload", + label: "传递给插件的文本", + type: "varInput", + icon: "alt_route", + width: 6, + }, + ], + }, + ], +}; From f50bad59abfe9e6f725080a6356db05f34a6be29 Mon Sep 17 00:00:00 2001 From: fofolee Date: Thu, 9 Jan 2025 10:11:39 +0800 Subject: [PATCH 016/332] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=9E=84=E9=80=A0=E6=8E=A7=E5=88=B6=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E5=91=BD=E4=BB=A4=EF=BC=8C=E8=A7=84=E8=8C=83=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E5=AD=97=E6=AE=B5=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/composer/ComposerCard.vue | 7 +- src/components/composer/MultiParams.vue | 10 +- src/components/composer/card/CommandHead.vue | 3 +- src/components/composer/common/ParamInput.vue | 12 +- .../composer/control/ConditionalJudgment.vue | 211 ---------- .../composer/control/ControlCommand.vue | 262 +++++++++++++ .../composer/control/ForEachControl.vue | 226 ----------- .../composer/control/ForInControl.vue | 223 ----------- .../composer/control/LoopControl.vue | 230 ----------- .../composer/control/SwitchControl.vue | 219 ----------- .../composer/control/TryCatchControl.vue | 203 ---------- .../composer/control/WhileControl.vue | 205 ---------- src/js/composer/cardComponents.js | 23 -- src/js/composer/commands/codingCommand.js | 4 +- src/js/composer/commands/controlCommands.js | 321 ++++++++++++++- src/js/composer/commands/dataCommands.js | 2 +- src/js/composer/commands/mathCommands.js | 2 +- src/js/composer/commands/networkCommands.js | 4 +- src/js/composer/commands/simulateCommands.js | 6 +- src/js/composer/commands/systemCommands.js | 6 +- src/js/composer/commonComponentGuide.js | 4 +- ...\347\233\256\350\257\264\346\230\216.json" | 369 ------------------ 22 files changed, 612 insertions(+), 1940 deletions(-) delete mode 100644 src/components/composer/control/ConditionalJudgment.vue create mode 100644 src/components/composer/control/ControlCommand.vue delete mode 100644 src/components/composer/control/ForEachControl.vue delete mode 100644 src/components/composer/control/ForInControl.vue delete mode 100644 src/components/composer/control/LoopControl.vue delete mode 100644 src/components/composer/control/SwitchControl.vue delete mode 100644 src/components/composer/control/TryCatchControl.vue delete mode 100644 src/components/composer/control/WhileControl.vue delete mode 100644 "\351\241\271\347\233\256\350\257\264\346\230\216.json" diff --git a/src/components/composer/ComposerCard.vue b/src/components/composer/ComposerCard.vue index 9069eb4b..bd06483c 100644 --- a/src/components/composer/ComposerCard.vue +++ b/src/components/composer/ComposerCard.vue @@ -23,8 +23,7 @@ > - - - - diff --git a/src/components/composer/control/ControlCommand.vue b/src/components/composer/control/ControlCommand.vue new file mode 100644 index 00000000..ab97d8b6 --- /dev/null +++ b/src/components/composer/control/ControlCommand.vue @@ -0,0 +1,262 @@ + + + + + diff --git a/src/components/composer/control/ForEachControl.vue b/src/components/composer/control/ForEachControl.vue deleted file mode 100644 index 652272f2..00000000 --- a/src/components/composer/control/ForEachControl.vue +++ /dev/null @@ -1,226 +0,0 @@ - - - - - diff --git a/src/components/composer/control/ForInControl.vue b/src/components/composer/control/ForInControl.vue deleted file mode 100644 index e6511909..00000000 --- a/src/components/composer/control/ForInControl.vue +++ /dev/null @@ -1,223 +0,0 @@ - - - - - diff --git a/src/components/composer/control/LoopControl.vue b/src/components/composer/control/LoopControl.vue deleted file mode 100644 index b2f42f5f..00000000 --- a/src/components/composer/control/LoopControl.vue +++ /dev/null @@ -1,230 +0,0 @@ - - - - - diff --git a/src/components/composer/control/SwitchControl.vue b/src/components/composer/control/SwitchControl.vue deleted file mode 100644 index fadcf733..00000000 --- a/src/components/composer/control/SwitchControl.vue +++ /dev/null @@ -1,219 +0,0 @@ - - - - - diff --git a/src/components/composer/control/TryCatchControl.vue b/src/components/composer/control/TryCatchControl.vue deleted file mode 100644 index fb508ab1..00000000 --- a/src/components/composer/control/TryCatchControl.vue +++ /dev/null @@ -1,203 +0,0 @@ - - - - - diff --git a/src/components/composer/control/WhileControl.vue b/src/components/composer/control/WhileControl.vue deleted file mode 100644 index 6c129c70..00000000 --- a/src/components/composer/control/WhileControl.vue +++ /dev/null @@ -1,205 +0,0 @@ - - - - - diff --git a/src/js/composer/cardComponents.js b/src/js/composer/cardComponents.js index c919a921..d9f8933c 100644 --- a/src/js/composer/cardComponents.js +++ b/src/js/composer/cardComponents.js @@ -11,29 +11,6 @@ export const KeySequenceEditor = defineAsyncComponent(() => import("src/components/composer/simulate/KeySequenceEditor.vue") ); -// 控制流组件 -export const ConditionalJudgment = defineAsyncComponent(() => - import("components/composer/control/ConditionalJudgment.vue") -); -export const LoopControl = defineAsyncComponent(() => - import("components/composer/control/LoopControl.vue") -); -export const ForEachControl = defineAsyncComponent(() => - import("components/composer/control/ForEachControl.vue") -); -export const ForInControl = defineAsyncComponent(() => - import("components/composer/control/ForInControl.vue") -); -export const WhileControl = defineAsyncComponent(() => - import("components/composer/control/WhileControl.vue") -); -export const SwitchControl = defineAsyncComponent(() => - import("components/composer/control/SwitchControl.vue") -); -export const TryCatchControl = defineAsyncComponent(() => - import("components/composer/control/TryCatchControl.vue") -); - // 网络组件 export const UBrowserEditor = defineAsyncComponent(() => import("components/composer/ubrowser/UBrowserEditor.vue") diff --git a/src/js/composer/commands/codingCommand.js b/src/js/composer/commands/codingCommand.js index 40a699a8..f75a7820 100644 --- a/src/js/composer/commands/codingCommand.js +++ b/src/js/composer/commands/codingCommand.js @@ -17,7 +17,7 @@ export const codingCommands = { type: "varInput", }, ], - functionSelector: [ + subCommands: [ { label: "Base64编码", value: "quickcomposer.coding.base64Encode", @@ -88,7 +88,7 @@ export const codingCommands = { type: "varInput", }, ], - functionSelector: [ + subCommands: [ { label: "MD5", value: "quickcomposer.coding.md5Hash", diff --git a/src/js/composer/commands/controlCommands.js b/src/js/composer/commands/controlCommands.js index 5735e860..191f532e 100644 --- a/src/js/composer/commands/controlCommands.js +++ b/src/js/composer/commands/controlCommands.js @@ -5,51 +5,358 @@ export const controlCommands = { { value: "condition", label: "条件判断", - component: "ConditionalJudgment", + component: "ControlCommand", isControlFlow: true, commandChain: ["if", "end"], + subCommands: [ + { + label: "如果满足", + value: "if", + codeTemplate: "if (${condition}) {", + config: [ + { + key: "condition", + label: "条件", + type: "controlInput", + placeholder: "表达式", + defaultValue: "true", + }, + ], + }, + { + label: "否则", + value: "else", + icon: "fork_left", + codeTemplate: "} else {", + }, + { + label: "否则满足", + value: "else if", + icon: "fork_left", + codeTemplate: "} else if (${condition}) {", + config: [ + { + key: "condition", + label: "条件", + type: "controlInput", + placeholder: "表达式", + }, + ], + }, + { + label: "结束", + value: "end", + codeTemplate: "}", + }, + ], }, { value: "loop", label: "循环执行", - component: "LoopControl", + component: "ControlCommand", isControlFlow: true, commandChain: ["loop", "end"], + subCommands: [ + { + label: "循环执行", + value: "loop", + icon: "loop", + codeTemplate: + "for (let ${indexVar} = ${startValue}; ${indexVar} <= ${endValue}; ${indexVar} += ${stepValue}) {", + config: [ + { + key: "indexVar", + label: "变量", + type: "controlInput", + defaultValue: "i", + width: 3, + }, + { + key: "startValue", + label: "从", + type: "controlInput", + icon: "first_page", + defaultValue: "0", + width: 3, + }, + { + key: "endValue", + label: "到", + type: "controlInput", + icon: "last_page", + defaultValue: "10", + width: 3, + }, + { + key: "stepValue", + label: "步进", + type: "controlInput", + icon: "trending_up", + defaultValue: "1", + width: 3, + }, + ], + }, + { + label: "继续循环", + value: "continue", + icon: "skip_next", + codeTemplate: "continue;", + }, + { + label: "终止循环", + value: "break", + icon: "stop", + codeTemplate: "break;", + }, + { + label: "结束", + value: "end", + codeTemplate: "}", + }, + ], }, { value: "forEach", label: "遍历数组", - component: "ForEachControl", + component: "ControlCommand", isControlFlow: true, commandChain: ["forEach", "end"], + subCommands: [ + { + label: "遍历数组", + value: "forEach", + icon: "list", + codeTemplate: + "for (let [${indexVar}, ${itemVar}] of ${arrayVar}.entries()) {", + config: [ + { + key: "itemVar", + label: "元素", + type: "controlInput", + defaultValue: "item", + width: 4, + }, + { + key: "indexVar", + label: "索引", + type: "controlInput", + defaultValue: "i", + width: 4, + }, + { + key: "arrayVar", + label: "数组", + type: "controlInput", + icon: "list", + defaultValue: "array", + width: 4, + }, + ], + }, + { + label: "继续循环", + value: "continue", + icon: "skip_next", + codeTemplate: "continue;", + }, + { + label: "终止循环", + value: "break", + icon: "stop", + codeTemplate: "break;", + }, + { + label: "结束", + value: "end", + codeTemplate: "}", + }, + ], }, { value: "forIn", label: "遍历对象", - component: "ForInControl", + component: "ControlCommand", isControlFlow: true, commandChain: ["forIn", "end"], + subCommands: [ + { + label: "遍历对象", + value: "forIn", + icon: "data_object", + codeTemplate: + "for (const ${keyVar} in ${objectVar}) { const ${valueVar} = ${objectVar}[${keyVar}];", + config: [ + { + key: "keyVar", + label: "键名", + type: "controlInput", + defaultValue: "key", + width: 4, + }, + { + key: "valueVar", + label: "值", + type: "controlInput", + defaultValue: "value", + width: 4, + }, + { + key: "objectVar", + label: "对象", + type: "controlInput", + defaultValue: "object", + width: 4, + }, + ], + }, + { + label: "继续循环", + value: "continue", + icon: "skip_next", + codeTemplate: "continue;", + }, + { + label: "终止循环", + value: "break", + icon: "stop", + codeTemplate: "break;", + }, + { + label: "结束", + value: "end", + codeTemplate: "}", + }, + ], }, { value: "while", label: "条件循环", - component: "WhileControl", + component: "ControlCommand", isControlFlow: true, commandChain: ["while", "end"], + subCommands: [ + { + label: "条件循环", + value: "while", + icon: "loop", + codeTemplate: "while (${condition}) {", + config: [ + { + key: "condition", + label: "条件", + type: "controlInput", + placeholder: "表达式", + defaultValue: "true", + }, + ], + }, + { + label: "继续循环", + value: "continue", + icon: "skip_next", + codeTemplate: "continue;", + }, + { + label: "终止循环", + value: "break", + icon: "stop", + codeTemplate: "break;", + }, + { + label: "结束", + value: "end", + codeTemplate: "}", + }, + ], }, { value: "switch", label: "条件分支", - component: "SwitchControl", + component: "ControlCommand", isControlFlow: true, commandChain: ["switch", "case", "end"], + subCommands: [ + { + label: "条件分支", + value: "switch", + icon: "call_split", + codeTemplate: "switch (${expression}) {", + config: [ + { + key: "expression", + label: "变量", + type: "controlInput", + placeholder: "变量或表达式", + defaultValue: "expression", + }, + ], + }, + { + label: "匹配分支", + value: "case", + icon: "check", + codeTemplate: "case ${value}:", + config: [ + { + key: "value", + label: "值", + type: "controlInput", + }, + ], + }, + { + label: "默认分支", + value: "default", + icon: "last_page", + codeTemplate: "default:", + }, + { + label: "结束", + value: "end", + codeTemplate: "}", + }, + ], }, { value: "tryCatch", label: "异常处理", - component: "TryCatchControl", + component: "ControlCommand", isControlFlow: true, commandChain: ["try", "catch", "end"], + subCommands: [ + { + label: "尝试执行", + value: "try", + icon: "play_circle", + codeTemplate: "try {", + }, + { + label: "捕获异常", + value: "catch", + icon: "error", + codeTemplate: "} catch (${errorVar}) {", + config: [ + { + key: "errorVar", + label: "错误", + type: "controlInput", + defaultValue: "error", + }, + ], + }, + { + label: "最后执行", + value: "finally", + icon: "done_all", + codeTemplate: "} finally {", + }, + { + label: "结束", + value: "end", + codeTemplate: "}", + }, + ], }, ], }; diff --git a/src/js/composer/commands/dataCommands.js b/src/js/composer/commands/dataCommands.js index 67783957..c269fd70 100644 --- a/src/js/composer/commands/dataCommands.js +++ b/src/js/composer/commands/dataCommands.js @@ -93,7 +93,7 @@ export const dataCommands = { desc: "Buffer创建、转换和操作", config: [], icon: "memory", - functionSelector: [ + subCommands: [ { value: "quickcomposer.data.buffer.from", label: "创建Buffer", diff --git a/src/js/composer/commands/mathCommands.js b/src/js/composer/commands/mathCommands.js index 6ec7dcae..550d0a22 100644 --- a/src/js/composer/commands/mathCommands.js +++ b/src/js/composer/commands/mathCommands.js @@ -17,7 +17,7 @@ export const mathCommands = { type: "numInput", }, ], - functionSelector: [ + subCommands: [ { label: "正弦(sin)", value: "Math.sin", diff --git a/src/js/composer/commands/networkCommands.js b/src/js/composer/commands/networkCommands.js index f59b7901..7933b393 100644 --- a/src/js/composer/commands/networkCommands.js +++ b/src/js/composer/commands/networkCommands.js @@ -61,7 +61,7 @@ export const networkCommands = { width: "auto", }, ], - functionSelector: [ + subCommands: [ { value: "quickcomposer.network.url.parse", label: "解析URL", @@ -239,7 +239,7 @@ export const networkCommands = { width: "auto", }, ], - functionSelector: [ + subCommands: [ { label: "DNS查询", value: "quickcomposer.network.dns.lookupHost", diff --git a/src/js/composer/commands/simulateCommands.js b/src/js/composer/commands/simulateCommands.js index e3dc6835..aeecd195 100644 --- a/src/js/composer/commands/simulateCommands.js +++ b/src/js/composer/commands/simulateCommands.js @@ -19,7 +19,7 @@ export const simulateCommands = { value: "quickcommand.simulateCopy", label: "模拟复制粘贴", config: [], - functionSelector: [ + subCommands: [ { value: "quickcommand.simulateCopy", label: "复制", @@ -73,7 +73,7 @@ export const simulateCommands = { width: 6, }, ], - functionSelector: [ + subCommands: [ { label: "单击", value: "utools.simulateMouseClick", @@ -94,7 +94,7 @@ export const simulateCommands = { { value: "utools.simulateMouseMove", label: "鼠标位置", - functionSelector: [ + subCommands: [ { label: "移动到坐标", value: "utools.simulateMouseMove", diff --git a/src/js/composer/commands/systemCommands.js b/src/js/composer/commands/systemCommands.js index 64b1b4ab..138fa21f 100644 --- a/src/js/composer/commands/systemCommands.js +++ b/src/js/composer/commands/systemCommands.js @@ -22,7 +22,7 @@ export const systemCommands = { label: "获取剪贴板内容", outputVariable: "clipboardContent", saveOutput: true, - functionSelector: [ + subCommands: [ { value: "electron.clipboard.readText", label: "剪贴板文本", @@ -59,7 +59,7 @@ export const systemCommands = { desc: "获取操作系统相关信息", icon: "computer", config: [], - functionSelector: [ + subCommands: [ { value: "quickcomposer.system.os.arch", label: "系统架构", @@ -162,7 +162,7 @@ export const systemCommands = { width: "auto", }, ], - functionSelector: [ + subCommands: [ { value: "quickcomposer.system.path.normalize", label: "规范化路径", diff --git a/src/js/composer/commonComponentGuide.js b/src/js/composer/commonComponentGuide.js index fb1c8503..ad7dca71 100644 --- a/src/js/composer/commonComponentGuide.js +++ b/src/js/composer/commonComponentGuide.js @@ -56,7 +56,7 @@ const commonComponentGuide = { ] `, }, - functionSelector: { + subCommands: { description: "可选,函数选择器配置,用于一个命令包含多个相关函数的情况", properties: { @@ -67,7 +67,7 @@ const commonComponentGuide = { excludeConfig: "可选,要排除的通用参数索引数组", }, example: ` - functionSelector: [ + subCommands: [ { label: "DNS查询", value: "quickcomposer.network.dns.lookupHost", diff --git "a/\351\241\271\347\233\256\350\257\264\346\230\216.json" "b/\351\241\271\347\233\256\350\257\264\346\230\216.json" deleted file mode 100644 index 3db461b2..00000000 --- "a/\351\241\271\347\233\256\350\257\264\346\230\216.json" +++ /dev/null @@ -1,369 +0,0 @@ -{ - "项目结构说明": { - "src": { - "描述": "源代码目录", - "js": { - "描述": "存放JS代码", - "composer": { - "描述": "存放可视化编排相关的JS代码", - "commands": { - "描述": "存放生成组件的配置文件,一个分类一个文件", - "命令配置字段说明": { - "value": "必选,当使用MultiParams组件且未启用functionSelector时,表示生成代码时使用的函数名", - "label": "必选,命令的显示的名称", - "component": "可选,存在则表示使用自定义组件,否则根据config使用MultiParams组件", - "isControlFlow": "可选,是否是流程控制命令", - "commandChain": "可选,命令链,流程控制命令使用", - "allowEmptyArgv": "可选,是否允许空参数", - "isAsync": "可选,是否是异步命令", - "config": { - "描述": "可选,命令的配置,用来在MultiParams组件中显示,是一个数组,每个元素是一个对象", - "配置项属性": { - "key": "必选,键", - "label": "必选,标签", - "type": "必选,类型,varInput则使用VariableInput组件,numInput则使用NumberInput组件,其他类型则使用qurasr对应组件", - "defaultValue": "可选,默认值", - "icon": "必选,图标", - "width": "可选,flex布局的相对比例" - } - }, - "functionSelector": { - "配置项属性": { - "label": "必选,显示的名称", - "value": "必选,生成代码时使用的函数名", - "icon": "可选,图标", - "config": "可选,特定函数独有参数配置,和MultiParams组件的config一样" - }, - "value": "必选,默认值" - } - } - }, - "cardComponents.js": { - "描述": "自定义的组件要在这里导入", - "主要功能": { - "导入组件": "导入并注册自定义的命令卡片组件", - "导出组件": "导出所有注册的组件供CommandComposer使用" - } - }, - "customComponentGuide.js": { - "描述": "自定义组件创建指南" - }, - "formatString.js": { - "描述": "处理字符串格式化的工具函数,主要用于处理对象序列化和类型转换", - "主要功能": { - "parseFunction": "解析函数字符串,返回函数名和参数", - "stringifyArgv": "格式化参数为字符串,根据值的类型决定是否添加引号" - } - } - } - }, - "components": { - "描述": "存放Vue组件", - "composer": { - "描述": "存放可视化编排相关的组件", - "file": { - "描述": "存放文件操作相关的组件", - "组件列表": { - "FileOperationEditor.vue": { - "描述": "文件操作编辑器组件", - "主要功能": { - "文件读取": { - "编码支持": "UTF-8、ASCII、Base64、二进制、十六进制", - "读取模式": "全部读取、指定位置读取", - "参数配置": "起始位置、读取长度" - }, - "文件写入": { - "编码支持": "UTF-8、ASCII、Base64、二进制、十六进制", - "写入模式": "覆盖写入、追加写入", - "内容输入": "支持变量和文本输入" - }, - "文件删除": { - "删除选项": "递归删除、强制删除" - }, - "文件管理": { - "重命名/移动": "支持文件重命名和移动", - "权限管理": "支持修改文件权限,支持递归修改", - "所有者管理": "支持修改文件所有者和组,支持递归修改" - } - } - } - } - }, - "ui": { - "描述": "基础UI组件", - "组件列表": { - "VariableInput.vue": { - "描述": "统一处理变量输入和输出组件", - "主要功能": { - "变量输入": "支持各种类型的变量输入", - "引号处理": "自动处理返回值的引号", - "类型转换": "支持不同类型间的转换" - } - }, - "MultiParams.vue": { - "描述": "统一处理多参数输入和输出组件", - "主要功能": { - "参数配置": "根据config配置显示不同的参数输入", - "代码生成": "生成完整的命令代码", - "参数验证": "验证参数的完整性和正确性" - } - }, - "DictionaryEditor.vue": { - "描述": "统一处理字典输入和输出组件", - "主要功能": { - "键值对编辑": "支持编辑字典的键值对", - "对象转换": "自动处理对象的序列化和反序列化" - } - } - } - }, - "control": { - "描述": "存放控制流程的组件", - "ConditionalJudgment.vue": "条件判断组件,用于if/else等流程控制", - "LoopControl.vue": "循环控制组件,用于for/while等循环控制", - "ForEachControl.vue": "foreach循环控制组件,用于foreach循环控制", - "ForInControl.vue": "forin循环控制组件,用于forin循环控制", - "WhileControl.vue": "while循环控制组件,用于while循环控制", - "SwitchControl.vue": "switch控制组件,用于switch控制" - }, - "simulate": { - "描述": "存放模拟操作的组件", - "ImageSearchEditor.vue": "图片搜索组件,用于搜索图片" - }, - "crypto": { - "描述": "存放加解密的组件", - "SymmetricCryptoEditor.vue": "对称加解密组件,用于对称加解密", - "AsymmetricCryptoEditor.vue": "非对称加解密组件,用于非对称加解密" - }, - "card": { - "描述": "存放ComposerCard子组件", - "CommandHead.vue": "命令卡片的头部组件,包含命令名称、折叠、删除等功能", - "CommandButtons.vue": "命令卡片的按钮组件,包含运行、保存等功能" - }, - "flow": { - "描述": "存放ComposerFlow子组件", - "ComposerButtons.vue": "流程操作按钮组件,包含运行、保存等功能", - "ChainStyles.vue": "控制流程链样式组件", - "DropArea.vue": "在命令流程下面显示一个拖拽区域,用于拖拽命令到流程编辑器", - "EmptyFlow.vue": "没有流程时显示的组件" - }, - "http": { - "描述": "存放http请求的组件", - "AxiosConfigEditor.vue": "Axios请求配置编辑器" - }, - "regex": { - "描述": "存放正则相关的组件" - }, - "CommandComposer.vue": { - "描述": "命令编辑器主组件", - "主要功能": { - "变量管理": "管理命令间的变量传递", - "命令流程": "管理命令的执行顺序", - "代码生成": "生成最终的执行代码" - }, - "子组件": { - "ComposerList": "左侧命令列表", - "ComposerFlow": "右侧流程编辑器" - } - }, - "ComposerCard.vue": { - "描述": "命令卡片组件,用于显示和编辑单个命令", - "主要功能": { - "参数编辑": "根据命令配置显示不同的参数编辑器", - "变量输出": "管理命令的输出变量", - "折叠控制": "控制命令卡片的折叠状态" - } - }, - "ComposerFlow.vue": { - "描述": "命令流程编辑器,管理命令的执行顺序", - "主要功能": { - "拖拽排序": "通过拖拽调整命令顺序", - "链式命令": "管理if/else等控制流程命令", - "折叠管理": "控制命令链的折叠状态" - } - }, - "ComposerList.vue": { - "描述": "命令列表组件,显示可用的命令", - "主要功能": { - "命令分类": "按类别显示命令", - "搜索过滤": "支持拼音搜索命令", - "拖拽添加": "拖拽命令到流程编辑器" - } - } - }, - "quickcommandUI": { - "描述": "存放quickcommand的UI组件,提供各种交互界面", - "组件列表": { - "QuickCommand.vue": { - "描述": "UI组件的主入口", - "主要功能": { - "对话框管理": { - "showInputBox": "显示输入框对话框,支持多个输入框", - "showButtonBox": "显示按钮对话框,支持多个按钮", - "showConfirmBox": "显示确认对话框,支持HTML内容", - "showMessageBox": "显示消息提示框,支持不同图标和位置", - "showTextArea": "显示文本编辑框,支持大段文本输入", - "showSelectList": "显示选择列表,支持搜索和快捷键" - }, - "按钮管理": { - "showWaitButton": "显示等待按钮", - "closeWaitButton": "关闭等待按钮" - }, - "事件管理": { - "listenKeydown": "添加键盘事件监听", - "removeListener": "移除键盘事件监听" - } - } - }, - "子组件": { - "InputBox.vue": { - "描述": "输入框对话框组件", - "功能": { - "多输入框": "支持显示多个输入框", - "提示文本": "支持设置标签和提示文本", - "默认值": "支持设置默认值" - } - }, - "ButtonBox.vue": { - "描述": "按钮对话框组件", - "功能": { - "多按钮": "支持显示多个按钮", - "返回值": "返回点击的按钮索引和文本" - } - }, - "ConfirmBox.vue": { - "描述": "确认对话框组件", - "功能": { - "HTML内容": "支持显示HTML格式的内容", - "自定义宽度": "支持设置对话框宽度" - } - }, - "TextArea.vue": { - "描述": "文本编辑框组件", - "功能": { - "大文本输入": "支持输入和编辑大段文本", - "占位文本": "支持设置占位文本", - "默认值": "支持设置默认值" - } - }, - "SelectList.vue": { - "描述": "选择列表组件", - "功能": { - "虚拟滚动": "使用虚拟滚动优化大量数据的显示", - "拼音搜索": "支持拼音搜索过滤", - "键盘导航": "支持键盘上下键导航", - "快捷键选择": "支持Alt/Command+数字快速选择", - "多种显示模式": { - "plaintext": "纯文本模式", - "json": "带图标和描述的JSON模式", - "html": "HTML内容模式" - } - } - } - } - } - } - } - }, - "plugin": { - "描述": "插件相关代码", - "lib": { - "描述": "存放核心功能代码", - "文件列表": { - "quickcomposer": { - "描述": "命令生成器的核心功能", - "命名规则": "quickcomposer.xxx.yyy.js 对应 quickcomposer.xxx.yyy 接口,xxx 为分类,和src/js/composer/commands里分类对应", - "功能分类": { - "系统命令": "系统相关的命令", - "控制命令": "流程控制相关的命令", - "模拟命令": "模拟操作相关的命令" - } - }, - "quickcommand.js": { - "描述": "定义preload.js中quickcommand的接口,UI相关的接口在src/components/quickcommandUI中", - "主要功能": { - "模拟操作": { - "simulateCopy": "模拟复制操作", - "simulatePaste": "模拟粘贴操作" - }, - "剪贴板": { - "readClipboard": "读取剪贴板文本", - "writeClipboard": "写入剪贴板文本", - "readClipboardImage": "读取剪贴板图片" - }, - "文件操作": { - "downloadFile": "下载文件", - "uploadFile": "上传文件", - "loadRemoteScript": "载入在线资源" - }, - "系统操作": { - "sleep": "同步延时", - "setTimeout": "异步延时", - "kill": "关闭进程", - "wakeUtools": "唤醒uTools", - "runInTerminal": "在终端中执行命令(非Linux)" - }, - "平台特定": { - "Windows": { - "runVbs": "运行VBS脚本", - "runPowerShell": "运行PowerShell脚本", - "runCsharp": "运行C#脚本" - }, - "MacOS": { - "runAppleScript": "运行AppleScript脚本" - } - } - } - }, - "getQuickcommandTempFile.js": { - "描述": "获取临时文件路径", - "参数": { - "ext": "文件扩展名", - "name": "可选,文件名,默认为时间戳", - "dir": "可选,临时目录名,默认为quickcommandTempDir" - } - }, - "lodashMini.js": { - "描述": "lodash的精简版,提供常用的工具函数", - "主要函数": { - "数组操作": { - "concat": "连接数组", - "pull": "移除数组中的指定值", - "union": "创建去重数组", - "without": "创建不包含指定值的数组" - }, - "对象操作": { - "cloneDeep": "深拷贝", - "pick": "选取对象属性", - "omitBy": "过滤对象属性", - "values": "获取对象的所有值" - }, - "集合操作": { - "filter": "过滤集合", - "forIn": "遍历对象的可枚举属性" - }, - "类型判断": { - "isArray": "是否为数组", - "isBuffer": "是否为Buffer", - "isEmpty": "是否为空", - "isNil": "是否为null或undefined", - "isObject": "是否为对象" - }, - "字符串操作": { - "truncate": "截断字符串" - } - } - } - } - }, - "preload.js": { - "描述": "预加载脚本", - "主要功能": { - "接口暴露": "暴露接口给渲染进程", - "沙箱环境": "提供安全的代码执行环境", - "全局变量": "管理全局变量和工具函数" - } - } - } - } -} From fe26f98809b98c80e27d98101b63a9bd4f2a7201 Mon Sep 17 00:00:00 2001 From: fofolee Date: Thu, 9 Jan 2025 11:01:25 +0800 Subject: [PATCH 017/332] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8C=89=E9=94=AE?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=9C=A8windows=E4=B8=8B=E7=9A=84=E6=95=88?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../composer/simulate/KeySequenceEditor.vue | 239 +++++++++++------- 1 file changed, 152 insertions(+), 87 deletions(-) diff --git a/src/components/composer/simulate/KeySequenceEditor.vue b/src/components/composer/simulate/KeySequenceEditor.vue index afe683b6..645a02a9 100644 --- a/src/components/composer/simulate/KeySequenceEditor.vue +++ b/src/components/composer/simulate/KeySequenceEditor.vue @@ -143,21 +143,23 @@
-
- - +
@@ -215,52 +222,64 @@ import { defineComponent } from "vue"; import NumberInput from "../common/NumberInput.vue"; import draggable from "vuedraggable"; -import { parseFunction } from "js/composer/formatString"; // 检测操作系统 const isMac = window.utools.isMacOs(); -// 通用快捷键 +// 通用修饰键配置 +const getDefaultModifier = (extraModifiers = {}) => { + const baseModifiers = isMac ? { command: true } : { control: true }; + return { ...baseModifiers, ...extraModifiers }; +}; + +// 通用快捷键 - 根据操作系统设置不同的快捷键 const commonShortcuts = [ { label: "复制", - sequence: [{ mainKey: "c", modifiers: { command: true } }], + sequence: [{ mainKey: "c", modifiers: getDefaultModifier() }], }, { label: "粘贴", - sequence: [{ mainKey: "v", modifiers: { command: true } }], + sequence: [{ mainKey: "v", modifiers: getDefaultModifier() }], }, { label: "剪切", - sequence: [{ mainKey: "x", modifiers: { command: true } }], + sequence: [{ mainKey: "x", modifiers: getDefaultModifier() }], }, { label: "全选", - sequence: [{ mainKey: "a", modifiers: { command: true } }], + sequence: [{ mainKey: "a", modifiers: getDefaultModifier() }], }, { label: "撤销", - sequence: [{ mainKey: "z", modifiers: { command: true } }], + sequence: [{ mainKey: "z", modifiers: getDefaultModifier() }], }, { label: "重做", - sequence: [{ mainKey: "z", modifiers: { command: true, shift: true } }], + sequence: [ + { mainKey: "z", modifiers: getDefaultModifier({ shift: true }) }, + ], }, { label: "保存", - sequence: [{ mainKey: "s", modifiers: { command: true } }], + sequence: [{ mainKey: "s", modifiers: getDefaultModifier() }], }, { label: "查找", - sequence: [{ mainKey: "f", modifiers: { command: true } }], + sequence: [{ mainKey: "f", modifiers: getDefaultModifier() }], }, { label: "替换", - sequence: [{ mainKey: "h", modifiers: { command: true } }], + sequence: [{ mainKey: "h", modifiers: getDefaultModifier() }], }, { label: "关闭窗口", - sequence: [{ mainKey: "w", modifiers: { command: true } }], + sequence: [ + { + mainKey: isMac ? "w" : "f4", + modifiers: isMac ? { command: true } : { alt: true }, + }, + ], }, ]; @@ -565,11 +584,11 @@ export default defineComponent({ : key.charAt(0).toUpperCase() + key.slice(1)) ); }, - generateCode() { - if (this.argvs.sequence.length === 0) return; + generateCode(argvs = this.argvs) { + if (!argvs.sequence.length) return; // 将每个按键记录转换为按键数组 - const keySequence = this.argvs.sequence.map((item) => { + const keySequence = argvs.sequence.map((item) => { const activeModifiers = Object.entries(item.modifiers) .filter(([_, active]) => active) .map(([key]) => key) @@ -581,7 +600,7 @@ export default defineComponent({ // 生成代码 const options = - this.argvs.sequence.length > 1 ? { interval: this.argvs.interval } : {}; + argvs.sequence.length > 1 ? { interval: argvs.interval } : {}; if (Object.keys(options).length > 0) { return `${this.modelValue.value}(${JSON.stringify( keySequence @@ -589,12 +608,14 @@ export default defineComponent({ } return `${this.modelValue.value}(${JSON.stringify(keySequence)})`; }, - updateValue() { - this.$emit("update:modelValue", { + updateValue(newArgvs) { + const updatedModelValue = { ...this.modelValue, - argvs: this.argvs, - code: this.generateCode(), - }); + argvs: newArgvs || this.argvs, + code: this.generateCode(newArgvs || this.argvs), + }; + + this.$emit("update:modelValue", updatedModelValue); }, appendSequence(newSequence) { const startId = Date.now(); @@ -637,6 +658,24 @@ export default defineComponent({ } return argvs; }, + toggleModifier(index, key) { + // 创建新的 argvs 对象 + const newArgvs = { + sequence: [...this.argvs.sequence], + interval: this.argvs.interval, + }; + + // 修改对应按键的修饰键状态 + newArgvs.sequence[index] = { + ...newArgvs.sequence[index], + modifiers: { + ...newArgvs.sequence[index].modifiers, + [key]: !newArgvs.sequence[index].modifiers[key], + }, + }; + // 更新 modelValue + this.updateValue(newArgvs); + }, }, mounted() { if (!this.modelValue.code && !this.modelValue.argvs) { @@ -648,7 +687,7 @@ export default defineComponent({ From 036b6fa934af047592b271650a609b996a3bae64 Mon Sep 17 00:00:00 2001 From: fofolee Date: Thu, 9 Jan 2025 16:37:41 +0800 Subject: [PATCH 018/332] =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=89=E6=8B=A9=E5=AF=B9=E8=AF=9D=E6=A1=86?= =?UTF-8?q?=EF=BC=8CVarInput=E6=94=AF=E6=8C=81=E5=A4=9A=E9=80=89=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9ECheckGroup=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/lib/quickcomposer.js | 1 + plugin/lib/quickcomposer/ui/dialog.js | 50 +++++ plugin/lib/quickcomposer/ui/index.js | 6 + src/components/composer/ComposerCard.vue | 1 - src/components/composer/MultiParams.vue | 1 - .../composer/common/ArrayEditor.vue | 33 +++- .../composer/common/BorderLabel.vue | 16 +- src/components/composer/common/CheckGroup.vue | 181 ++++++++++++++++++ src/components/composer/common/DictEditor.vue | 4 + src/components/composer/common/ParamInput.vue | 45 ++--- .../composer/common/VariableInput.vue | 118 ++++++++++-- .../composer/system/SystemCommandEditor.vue | 2 +- src/js/composer/commands/uiCommands.js | 105 ++++++++++ src/js/composer/formatString.js | 2 +- 14 files changed, 506 insertions(+), 59 deletions(-) create mode 100644 plugin/lib/quickcomposer/ui/dialog.js create mode 100644 plugin/lib/quickcomposer/ui/index.js create mode 100644 src/components/composer/common/CheckGroup.vue diff --git a/plugin/lib/quickcomposer.js b/plugin/lib/quickcomposer.js index bec8553f..3c3d6508 100644 --- a/plugin/lib/quickcomposer.js +++ b/plugin/lib/quickcomposer.js @@ -6,6 +6,7 @@ const quickcomposer = { network: require("./quickcomposer/network"), coding: require("./quickcomposer/coding"), math: require("./quickcomposer/math"), + ui: require("./quickcomposer/ui"), }; module.exports = quickcomposer; diff --git a/plugin/lib/quickcomposer/ui/dialog.js b/plugin/lib/quickcomposer/ui/dialog.js new file mode 100644 index 00000000..f7e5f093 --- /dev/null +++ b/plugin/lib/quickcomposer/ui/dialog.js @@ -0,0 +1,50 @@ +const showSaveDialog = ( + title, + defaultPath, + buttonLabel, + message, + extensions, + properties +) => { + return window.utools.showSaveDialog({ + title, + defaultPath, + buttonLabel, + message, + properties, + filters: [ + { + name: "文件", + extensions, + }, + ], + }); +}; + +const showOpenDialog = ( + title, + defaultPath, + buttonLabel, + message, + extensions, + properties +) => { + return window.utools.showOpenDialog({ + title, + defaultPath, + buttonLabel, + message, + properties, + filters: [ + { + name: "文件", + extensions, + }, + ], + }); +}; + +module.exports = { + showSaveDialog, + showOpenDialog, +}; diff --git a/plugin/lib/quickcomposer/ui/index.js b/plugin/lib/quickcomposer/ui/index.js new file mode 100644 index 00000000..6f9a8113 --- /dev/null +++ b/plugin/lib/quickcomposer/ui/index.js @@ -0,0 +1,6 @@ +const { showSaveDialog, showOpenDialog } = require("./dialog"); + +module.exports = { + showSaveDialog, + showOpenDialog, +}; diff --git a/src/components/composer/ComposerCard.vue b/src/components/composer/ComposerCard.vue index bd06483c..d24de261 100644 --- a/src/components/composer/ComposerCard.vue +++ b/src/components/composer/ComposerCard.vue @@ -197,7 +197,6 @@ export default defineComponent({ .composer-card .command-item { transition: none !important; transform: none !important; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05) !important; } .command-item { diff --git a/src/components/composer/MultiParams.vue b/src/components/composer/MultiParams.vue index 9e169d86..b0d0de6f 100644 --- a/src/components/composer/MultiParams.vue +++ b/src/components/composer/MultiParams.vue @@ -113,7 +113,6 @@ export default defineComponent({ * 变量模式stringify后,null变成'null', ''保持'' */ const stringifiedArgvs = argvs.map((argv) => stringifyArgv(argv)); - /* 空值处理: * 1. 去掉 undefined,'', null * 2. varInput在字符串模式下,留空为'""',所以不会被处理 diff --git a/src/components/composer/common/ArrayEditor.vue b/src/components/composer/common/ArrayEditor.vue index e44639b0..d5e27c87 100644 --- a/src/components/composer/common/ArrayEditor.vue +++ b/src/components/composer/common/ArrayEditor.vue @@ -17,9 +17,11 @@ ]" > ({}), }, + placeholder: { + type: String, + default: "", + }, }, emits: ["update:modelValue"], computed: { @@ -169,9 +196,9 @@ export default defineComponent({ return ( this.options?.keys?.map((key) => { return { + ...key, value: key.value || key, label: key.label || key, - width: key.width, }; }) || [] ); diff --git a/src/components/composer/common/BorderLabel.vue b/src/components/composer/common/BorderLabel.vue index bf053286..3bbc9b84 100644 --- a/src/components/composer/common/BorderLabel.vue +++ b/src/components/composer/common/BorderLabel.vue @@ -1,20 +1,18 @@