优化参数值为空和传递空参数的逻辑

This commit is contained in:
fofolee 2025-01-07 17:50:13 +08:00
parent 5c2d9a5d89
commit a13580d53f
7 changed files with 275 additions and 199 deletions

View File

@ -4,7 +4,7 @@
v-if="hasFunctionSelector" v-if="hasFunctionSelector"
:model-value="funcName" :model-value="funcName"
@update:model-value="funcName = $event" @update:model-value="funcName = $event"
:options="localCommand.functionSelector?.options" :options="localCommand.functionSelector"
/> />
<ParamInput :configs="localConfig" :values="argvs" @update="updateArgv" /> <ParamInput :configs="localConfig" :values="argvs" @update="updateArgv" />
</div> </div>
@ -40,17 +40,22 @@ export default defineComponent({
}, },
// //
functionConfig() { functionConfig() {
return ( return this.getSelectFunction()?.config || [];
this.modelValue.functionSelector?.options.find(
(item) => item.value === this.funcName
)?.config || []
);
}, },
localConfig() { localConfig() {
return [...this.commonConfig, ...this.functionConfig].map((item) => { return [...this.commonConfig, ...this.functionConfig].map((item) => {
const value =
item.type === "varInput"
? item.defaultValue || {
value: "",
isString: true,
__varInputVal__: true,
}
: // undefined
item.defaultValue;
return { return {
...item, ...item,
value: item.defaultValue, value,
}; };
}); });
}, },
@ -62,7 +67,20 @@ export default defineComponent({
return this.modelValue.value; return this.modelValue.value;
}, },
set(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() { argvs() {
@ -75,6 +93,11 @@ export default defineComponent({
}, },
}, },
methods: { methods: {
getSelectFunction(funcName = this.funcName) {
return this.modelValue.functionSelector?.find(
(item) => item.value === funcName
);
},
updateArgv(index, value) { updateArgv(index, value) {
const newArgvs = [...this.argvs]; const newArgvs = [...this.argvs];
newArgvs[index] = value; newArgvs[index] = value;
@ -82,10 +105,41 @@ export default defineComponent({
this.updateModelValue(this.funcName, newArgvs); this.updateModelValue(this.funcName, newArgvs);
}, },
generateCode(funcName, argvs) { generateCode(funcName, argvs) {
const newArgvs = argvs console.log("argvs", argvs);
.map((argv) => stringifyArgv(argv)) /**
.filter((item) => item != null && item !== ""); * 字符串模式stringfiy后null会变成'"null"', ''变成'""'
return `${funcName}(${newArgvs.join(",")})`; * 变量模式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) { parseCodeToArgvs(code) {
let argvs = window.lodashM.cloneDeep(this.defaultArgvs); let argvs = window.lodashM.cloneDeep(this.defaultArgvs);
@ -110,9 +164,7 @@ export default defineComponent({
}, },
getSummary(argvs) { getSummary(argvs) {
// header // header
const funcNameLabel = this.localCommand.functionSelector?.options.find( const funcNameLabel = this.getSelectFunction()?.label;
(option) => option.value === this.funcName
)?.label;
const subFeature = funcNameLabel ? `${funcNameLabel} ` : ""; const subFeature = funcNameLabel ? `${funcNameLabel} ` : "";
const allArgvs = argvs const allArgvs = argvs
.filter((item) => item != null && item != "") .filter((item) => item != null && item != "")

View File

@ -67,13 +67,17 @@ export default defineComponent({
return this.modelValue; return this.modelValue;
}, },
set(value) { 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: { methods: {
updateNumber(delta) { updateNumber(delta) {
this.$emit("update:modelValue", this.localValue + delta); this.$emit("update:modelValue", (this.localValue || 0) + delta);
}, },
}, },
}); });

View File

@ -43,6 +43,8 @@
<q-select <q-select
v-else-if="config.type === 'select'" v-else-if="config.type === 'select'"
filled filled
emit-value
map-options
:model-value="values[index]" :model-value="values[index]"
@update:model-value="$emit('update', index, $event)" @update:model-value="$emit('update', index, $event)"
:options="config.options" :options="config.options"
@ -113,9 +115,16 @@ export default defineComponent({
emits: ["update"], emits: ["update"],
methods: { methods: {
getColumnStyle(width = 12) { getColumnStyle(width = 12) {
if (width === "auto") {
return {
flex: "1 1 0%",
minWidth: "0",
};
}
const columnWidth = (width / 12) * 100; const columnWidth = (width / 12) * 100;
return { return {
width: `calc(${columnWidth}% - var(--grid-gap))`, width: `calc(${columnWidth}% - var(--grid-gap))`,
flex: "0 0 auto",
}; };
}, },
}, },
@ -134,11 +143,18 @@ export default defineComponent({
.grid-item { .grid-item {
min-width: 50px; min-width: 50px;
margin-bottom: 0; margin-bottom: 0;
display: flex;
}
.grid-item > * {
flex: 1;
min-width: 0;
} }
@media (max-width: 600px) { @media (max-width: 600px) {
.grid-item { .grid-item {
width: 100% !important; width: 100% !important;
flex: 1 1 100% !important;
} }
} }
</style> </style>

View File

@ -17,50 +17,48 @@ export const dataCommands = {
type: "varInput", type: "varInput",
}, },
], ],
functionSelector: { functionSelector: [
options: [ {
{ label: "Base64编码",
label: "Base64编码", value: "quickcomposer.data.base64Encode",
value: "quickcomposer.data.base64Encode", icon: "title",
icon: "title", },
}, {
{ label: "Base64解码",
label: "Base64解码", value: "quickcomposer.data.base64Decode",
value: "quickcomposer.data.base64Decode", icon: "title",
icon: "title", },
}, {
{ label: "十六进制编码",
label: "十六进制编码", value: "quickcomposer.data.hexEncode",
value: "quickcomposer.data.hexEncode", icon: "code",
icon: "code", },
}, {
{ label: "十六进制解码",
label: "十六进制解码", value: "quickcomposer.data.hexDecode",
value: "quickcomposer.data.hexDecode", icon: "code",
icon: "code", },
}, {
{ label: "URL编码",
label: "URL编码", value: "quickcomposer.data.urlEncode",
value: "quickcomposer.data.urlEncode", icon: "link",
icon: "link", },
}, {
{ label: "URL解码",
label: "URL解码", value: "quickcomposer.data.urlDecode",
value: "quickcomposer.data.urlDecode", icon: "link",
icon: "link", },
}, {
{ label: "HTML编码",
label: "HTML编码", value: "quickcomposer.data.htmlEncode",
value: "quickcomposer.data.htmlEncode", icon: "html",
icon: "html", },
}, {
{ label: "HTML解码",
label: "HTML解码", value: "quickcomposer.data.htmlDecode",
value: "quickcomposer.data.htmlDecode", icon: "html",
icon: "html", },
}, ],
],
},
}, },
{ {
value: "quickcomposer.data.symmetricCrypto", value: "quickcomposer.data.symmetricCrypto",
@ -90,35 +88,33 @@ export const dataCommands = {
type: "varInput", type: "varInput",
}, },
], ],
functionSelector: { functionSelector: [
options: [ {
{ label: "MD5",
label: "MD5", value: "quickcomposer.data.md5Hash",
value: "quickcomposer.data.md5Hash", icon: "functions",
icon: "functions", },
}, {
{ label: "SHA1",
label: "SHA1", value: "quickcomposer.data.sha1Hash",
value: "quickcomposer.data.sha1Hash", icon: "functions",
icon: "functions", },
}, {
{ label: "SHA256",
label: "SHA256", value: "quickcomposer.data.sha256Hash",
value: "quickcomposer.data.sha256Hash", icon: "functions",
icon: "functions", },
}, {
{ label: "SHA512",
label: "SHA512", value: "quickcomposer.data.sha512Hash",
value: "quickcomposer.data.sha512Hash", icon: "functions",
icon: "functions", },
}, {
{ label: "SM3",
label: "SM3", value: "quickcomposer.data.sm3Hash",
value: "quickcomposer.data.sm3Hash", icon: "functions",
icon: "functions", },
}, ],
],
},
}, },
{ {
value: "Math.sin", value: "Math.sin",
@ -134,80 +130,78 @@ export const dataCommands = {
type: "numInput", type: "numInput",
}, },
], ],
functionSelector: { functionSelector: [
options: [ {
{ label: "正弦(sin)",
label: "正弦(sin)", value: "Math.sin",
value: "Math.sin", icon: "functions",
icon: "functions", },
}, {
{ label: "余弦(cos)",
label: "余弦(cos)", value: "Math.cos",
value: "Math.cos", icon: "functions",
icon: "functions", },
}, {
{ label: "正切(tan)",
label: "正切(tan)", value: "Math.tan",
value: "Math.tan", icon: "functions",
icon: "functions", },
}, {
{ label: "反正弦(asin)",
label: "反正弦(asin)", value: "Math.asin",
value: "Math.asin", icon: "functions",
icon: "functions", },
}, {
{ label: "反余弦(acos)",
label: "反余弦(acos)", value: "Math.acos",
value: "Math.acos", icon: "functions",
icon: "functions", },
}, {
{ label: "反正切(atan)",
label: "反正切(atan)", value: "Math.atan",
value: "Math.atan", icon: "functions",
icon: "functions", },
}, {
{ label: "平方根(sqrt)",
label: "平方根(sqrt)", value: "Math.sqrt",
value: "Math.sqrt", icon: "functions",
icon: "functions", },
}, {
{ label: "自然对数(ln)",
label: "自然对数(ln)", value: "Math.log",
value: "Math.log", icon: "functions",
icon: "functions", },
}, {
{ label: "10对数(log10)",
label: "10对数(log10)", value: "Math.log10",
value: "Math.log10", icon: "functions",
icon: "functions", },
}, {
{ label: "绝对值(abs)",
label: "绝对值(abs)", value: "Math.abs",
value: "Math.abs", icon: "functions",
icon: "functions", },
}, {
{ label: "向上取整(ceil)",
label: "向上取整(ceil)", value: "Math.ceil",
value: "Math.ceil", icon: "functions",
icon: "functions", },
}, {
{ label: "向下取整(floor)",
label: "向下取整(floor)", value: "Math.floor",
value: "Math.floor", icon: "functions",
icon: "functions", },
}, {
{ label: "四舍五入(round)",
label: "四舍五入(round)", value: "Math.round",
value: "Math.round", icon: "functions",
icon: "functions", },
}, {
{ label: "幂运算(pow)",
label: "幂运算(pow)", value: "Math.pow",
value: "Math.pow", icon: "functions",
icon: "functions", },
}, ],
],
},
}, },
{ {
value: "quickcomposer.data.random", value: "quickcomposer.data.random",

View File

@ -27,26 +27,23 @@ export const simulateCommands = {
width: 6, width: 6,
}, },
], ],
functionSelector: { functionSelector: [
options: [ {
{ label: "单击",
label: "单击", value: "utools.simulateMouseClick",
value: "utools.simulateMouseClick", icon: "mouse",
icon: "mouse", },
}, {
{ label: "右击",
label: "右击", value: "utools.simulateMouseRightClick",
value: "utools.simulateMouseRightClick", icon: "mouse",
icon: "mouse", },
}, {
{ label: "双击",
label: "双击", value: "utools.simulateMouseDoubleClick",
value: "utools.simulateMouseDoubleClick", icon: "mouse",
icon: "mouse", },
}, ],
],
allowEmptyArgv: true,
},
}, },
{ {
value: "utools.simulateMouseMove", value: "utools.simulateMouseMove",

View File

@ -103,15 +103,19 @@ const stringifyObject = (jsonObj) => {
* @returns {string} 格式化后的字符串 * @returns {string} 格式化后的字符串
*/ */
export const stringifyArgv = (argv) => { export const stringifyArgv = (argv) => {
// 处理普通字符串 // 普通字符串加上引号
if (typeof argv === "string") { if (typeof argv === "string") {
return `"${argv}"`; return `"${argv}"`;
} }
// 处理对象 // null类型是Object需要单独处理返回原值
if (argv === null) {
return null;
}
// 对象通过stringifyObject处理
if (typeof argv === "object") { if (typeof argv === "object") {
return stringifyObject(argv); return stringifyObject(argv);
} }
// 处理其他类型 // 其他类型返回原值
return argv; return argv;
}; };
@ -270,12 +274,25 @@ export const parseFunction = (functionStr, options = {}) => {
return shouldUseVariableFormat return shouldUseVariableFormat
? { value: node.value, isString: true, __varInputVal__: true } ? { value: node.value, isString: true, __varInputVal__: true }
: node.value; : node.value;
// 数字、布尔
case "NumericLiteral": case "NumericLiteral":
return node.value;
case "BooleanLiteral": case "BooleanLiteral":
return node.value; return shouldUseVariableFormat
? {
value: JSON.stringify(node.value),
isString: false,
__varInputVal__: true,
}
: node.value;
// null
case "NullLiteral": case "NullLiteral":
return null; return shouldUseVariableFormat
? {
value: "null",
isString: false,
__varInputVal__: true,
}
: null;
case "Identifier": case "Identifier":
// 标识符(变量)总是不带引号的 // 标识符(变量)总是不带引号的
return shouldUseVariableFormat return shouldUseVariableFormat

View File

@ -28,15 +28,11 @@
} }
}, },
"functionSelector": { "functionSelector": {
"描述": "可选函数选择器用于选择函数如果存在则使用MultiParams组件用于一类参数类似但函数名不同的命令", "配置项属性": {
"options": { "label": "必选,显示的名称",
"描述": "必选,选项,一个数组,每个元素是一个对象,包含以下属性:", "value": "必选,生成代码时使用的函数名",
"配置项属性": { "icon": "可选,图标",
"label": "必选,显示的名称", "config": "可选特定函数独有参数配置和MultiParams组件的config一样"
"value": "必选,生成代码时使用的函数名",
"icon": "可选,图标",
"config": "可选特定函数独有参数配置和MultiParams组件的config一样"
}
}, },
"value": "必选,默认值" "value": "必选,默认值"
} }