diff --git a/src/components/composer/MultiParams.vue b/src/components/composer/MultiParams.vue
index c0324b6..7904ba6 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 4645d97..17a74d3 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 29fbf95..9f9ba04 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 41f72f0..10678d7 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 f793065..646661c 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 ba79214..6360239 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/项目说明.json b/项目说明.json
index a3daf46..3db461b 100644
--- a/项目说明.json
+++ b/项目说明.json
@@ -28,15 +28,11 @@
}
},
"functionSelector": {
- "描述": "可选,函数选择器,用于选择函数,如果存在则使用MultiParams组件,用于一类参数类似,但函数名不同的命令",
- "options": {
- "描述": "必选,选项,一个数组,每个元素是一个对象,包含以下属性:",
- "配置项属性": {
- "label": "必选,显示的名称",
- "value": "必选,生成代码时使用的函数名",
- "icon": "可选,图标",
- "config": "可选,特定函数独有参数配置,和MultiParams组件的config一样"
- }
+ "配置项属性": {
+ "label": "必选,显示的名称",
+ "value": "必选,生成代码时使用的函数名",
+ "icon": "可选,图标",
+ "config": "可选,特定函数独有参数配置,和MultiParams组件的config一样"
},
"value": "必选,默认值"
}