mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-10-10 23:53:29 +08:00
改善生成代码逻辑,覆盖各种情况,改用asyncMode存储promise状态
This commit is contained in:
@@ -155,27 +155,37 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
handleOutputVariableUpdate(result) {
|
||||
const { outputVariable, mode, functionInfo } = result;
|
||||
const { outputVariable, asyncMode, callbackFunc } = result;
|
||||
|
||||
if (outputVariable.name || outputVariable.details) {
|
||||
this.localCommand.outputVariable = { ...outputVariable };
|
||||
} else {
|
||||
delete this.localCommand.outputVariable;
|
||||
}
|
||||
|
||||
if (asyncMode) {
|
||||
this.localCommand.asyncMode = asyncMode;
|
||||
// 如果是回调模式,添加 callbackFunc 属性
|
||||
if (mode === "callback") {
|
||||
this.localCommand.callbackFunc = functionInfo.name;
|
||||
if (callbackFunc) {
|
||||
this.localCommand.callbackFunc = callbackFunc;
|
||||
let params = [];
|
||||
if (outputVariable?.name) {
|
||||
params.push(outputVariable.name);
|
||||
}
|
||||
if (outputVariable?.details) {
|
||||
params.push(...Object.values(outputVariable.details));
|
||||
}
|
||||
this.$emit("add-command", {
|
||||
command: {
|
||||
name: callbackFunc,
|
||||
params,
|
||||
silent: true,
|
||||
},
|
||||
type: "function",
|
||||
});
|
||||
} else {
|
||||
delete this.localCommand.callbackFunc;
|
||||
}
|
||||
|
||||
// 如果是回调函数模式,创建新函数
|
||||
if (mode === "callback" && functionInfo) {
|
||||
this.$emit("add-command", {
|
||||
command: functionInfo,
|
||||
type: "function",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
delete this.localCommand.outputVariable;
|
||||
delete this.localCommand.callbackFunc;
|
||||
}
|
||||
},
|
||||
runCommand() {
|
||||
|
@@ -63,7 +63,6 @@ import ComposerCard from "./ComposerCard.vue";
|
||||
import ChainStyles from "./flow/ChainStyles.vue";
|
||||
import DropArea from "./flow/DropArea.vue";
|
||||
import { findCommandByValue } from "js/composer/composerConfig";
|
||||
import { processVariable } from "js/composer/variableManager";
|
||||
|
||||
// 拖拽前的命令列表,非响应式
|
||||
let commandsBeforeDrag = [];
|
||||
|
@@ -252,19 +252,9 @@ export default defineComponent({
|
||||
});
|
||||
}
|
||||
|
||||
// 添加局部变量
|
||||
if (options.localVars && options.localVars.length > 0) {
|
||||
options.localVars.forEach((varInfo) => {
|
||||
newFlow.customVariables.push({
|
||||
name: varInfo.name,
|
||||
type: "var",
|
||||
value: varInfo.value,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.subFlows.push(newFlow);
|
||||
if (options.params || options.localVars) {
|
||||
|
||||
if (options.silent) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -281,12 +271,17 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
updateSubFlow(index, payload) {
|
||||
const { params, localVars } = payload;
|
||||
const { params } = payload;
|
||||
const newParams = params.map((param) => ({
|
||||
name: param,
|
||||
type: "param",
|
||||
}));
|
||||
const localVars = this.subFlows[index].customVariables.filter(
|
||||
(v) => v.type === "var"
|
||||
);
|
||||
// 完全更新参数
|
||||
this.subFlows[index].customVariables = [
|
||||
...params.map((param) => ({
|
||||
name: param,
|
||||
type: "param",
|
||||
})),
|
||||
...newParams,
|
||||
...localVars,
|
||||
];
|
||||
},
|
||||
@@ -355,7 +350,6 @@ export default defineComponent({
|
||||
"icon",
|
||||
"width",
|
||||
"placeholder",
|
||||
"isAsync",
|
||||
"summary",
|
||||
"type",
|
||||
];
|
||||
|
@@ -15,9 +15,9 @@
|
||||
@click="showOutputEditor = true"
|
||||
>
|
||||
<q-tooltip>
|
||||
<div class="text-body2">配置命令输出变量</div>
|
||||
<div class="text-body2">输出配置</div>
|
||||
<div class="text-caption text-grey-5">
|
||||
将命令的输出保存为变量以供后续使用
|
||||
配置输出变量、是否等待执行完毕等
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
|
@@ -14,8 +14,16 @@
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
<div v-if="hasNestedFields(currentOutputs)">
|
||||
<q-badge color="primary" class="q-ma-sm q-pa-xs">详细输出</q-badge>
|
||||
<div v-if="currentOutputs?.structure">
|
||||
<div class="row items-center">
|
||||
<q-badge color="primary" class="q-ma-sm q-pa-xs">详细输出</q-badge>
|
||||
<div
|
||||
v-if="Array.isArray(currentOutputs.structure)"
|
||||
class="text-caption text-grey-5"
|
||||
>
|
||||
数组中第一个元素
|
||||
</div>
|
||||
</div>
|
||||
<q-scroll-area
|
||||
style="height: 200px"
|
||||
:thumb-style="{
|
||||
@@ -23,61 +31,124 @@
|
||||
}"
|
||||
>
|
||||
<div class="detail-output column q-col-gutter-sm q-px-sm">
|
||||
<div v-for="(output, key) in detailOutputs" :key="key">
|
||||
<!-- 如果是嵌套对象 -->
|
||||
<div v-if="hasNestedFields(output)">
|
||||
<BorderLabel :label="output.label || key" :model-value="false">
|
||||
<div class="column q-col-gutter-sm">
|
||||
<div
|
||||
v-for="(subOutput, subKey) in getNestedFields(output)"
|
||||
:key="subKey"
|
||||
>
|
||||
<div class="output-item">
|
||||
<q-input
|
||||
v-model="outputVars[`${key}.${subKey}`]"
|
||||
filled
|
||||
dense
|
||||
autofocus
|
||||
class="col"
|
||||
:placeholder="subOutput.placeholder"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<div class="variable-label">
|
||||
{{ subOutput.label }}
|
||||
</div>
|
||||
</template>
|
||||
</q-input>
|
||||
<!-- 处理数组类型的structure -->
|
||||
<template v-if="Array.isArray(currentOutputs.structure)">
|
||||
<div
|
||||
v-for="(output, key) in currentOutputs.structure[0]"
|
||||
:key="key"
|
||||
>
|
||||
<!-- 如果是嵌套对象 -->
|
||||
<div v-if="hasNestedFields(output)">
|
||||
<BorderLabel
|
||||
:label="output.label || key"
|
||||
:model-value="false"
|
||||
>
|
||||
<div class="column q-col-gutter-sm">
|
||||
<div
|
||||
v-for="(subOutput, subKey) in getNestedFields(output)"
|
||||
:key="subKey"
|
||||
>
|
||||
<div class="output-item">
|
||||
<q-input
|
||||
v-model="outputVars[`[0].${key}.${subKey}`]"
|
||||
filled
|
||||
dense
|
||||
autofocus
|
||||
class="col"
|
||||
:placeholder="subOutput.placeholder"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<div class="variable-label">
|
||||
{{ subOutput.label }}
|
||||
</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BorderLabel>
|
||||
</BorderLabel>
|
||||
</div>
|
||||
<!-- 如果是普通字段 -->
|
||||
<div v-else class="output-item">
|
||||
<q-input
|
||||
v-model="outputVars[`[0].${key}`]"
|
||||
filled
|
||||
dense
|
||||
class="col"
|
||||
:placeholder="output.placeholder"
|
||||
autofocus
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<div class="variable-label">{{ output.label }}</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 如果是普通字段 -->
|
||||
<div v-else class="output-item">
|
||||
<q-input
|
||||
v-model="outputVars[key]"
|
||||
filled
|
||||
dense
|
||||
class="col"
|
||||
:placeholder="output.placeholder"
|
||||
autofocus
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<div class="variable-label">{{ output.label }}</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
<!-- 处理对象类型的structure -->
|
||||
<template v-else>
|
||||
<div
|
||||
v-for="(output, key) in currentOutputs?.structure"
|
||||
:key="key"
|
||||
>
|
||||
<!-- 如果是嵌套对象 -->
|
||||
<div v-if="hasNestedFields(output)">
|
||||
<BorderLabel
|
||||
:label="output.label || key"
|
||||
:model-value="false"
|
||||
>
|
||||
<div class="column q-col-gutter-sm">
|
||||
<div
|
||||
v-for="(subOutput, subKey) in getNestedFields(output)"
|
||||
:key="subKey"
|
||||
>
|
||||
<div class="output-item">
|
||||
<q-input
|
||||
v-model="outputVars[`${key}.${subKey}`]"
|
||||
filled
|
||||
dense
|
||||
autofocus
|
||||
class="col"
|
||||
:placeholder="subOutput.placeholder"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<div class="variable-label">
|
||||
{{ subOutput.label }}
|
||||
</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BorderLabel>
|
||||
</div>
|
||||
<!-- 如果是普通字段 -->
|
||||
<div v-else class="output-item">
|
||||
<q-input
|
||||
v-model="outputVars[key]"
|
||||
filled
|
||||
dense
|
||||
class="col"
|
||||
:placeholder="output.placeholder"
|
||||
autofocus
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<div class="variable-label">{{ output.label }}</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
</div>
|
||||
|
||||
<div v-if="isAsyncCommand">
|
||||
<q-badge color="primary" class="q-ma-sm q-pa-xs">输出模式</q-badge>
|
||||
<div v-if="!!asyncMode">
|
||||
<q-badge color="primary" class="q-ma-sm q-pa-xs">运行模式</q-badge>
|
||||
<div class="row q-col-gutter-sm q-px-sm">
|
||||
<q-select
|
||||
v-model="outputMode"
|
||||
:options="outputModeOptions"
|
||||
v-model="asyncMode"
|
||||
:options="asyncModeOptions"
|
||||
filled
|
||||
dense
|
||||
autofocus
|
||||
@@ -92,10 +163,11 @@
|
||||
dense
|
||||
autofocus
|
||||
class="col-8"
|
||||
v-if="outputMode === 'callback'"
|
||||
v-if="asyncMode === 'then'"
|
||||
placeholder="新函数名则自动创建"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<div class="variable-label">回调函数名</div>
|
||||
<div class="variable-label">回调函数</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
@@ -147,64 +219,74 @@ export default defineComponent({
|
||||
commandName() {
|
||||
return this.currentSubCommand.label || this.command.label;
|
||||
},
|
||||
isAsyncCommand() {
|
||||
return this.currentSubCommand.isAsync || this.command.isAsync;
|
||||
},
|
||||
currentOutputs() {
|
||||
return this.currentSubCommand.outputs || this.command.outputs;
|
||||
},
|
||||
detailOutputs() {
|
||||
let outputs = { ...this.currentOutputs };
|
||||
delete outputs.label;
|
||||
delete outputs.placeholder;
|
||||
return outputs;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
simpleOutputVar: "",
|
||||
outputVars: {},
|
||||
outputMode: "wait",
|
||||
outputModeOptions: [
|
||||
asyncMode: "await",
|
||||
callbackFunc: "",
|
||||
asyncModeOptions: [
|
||||
{
|
||||
label: "等待运行完毕",
|
||||
value: "wait",
|
||||
value: "await",
|
||||
},
|
||||
{
|
||||
label: "输出到回调函数",
|
||||
value: "callback",
|
||||
label: "不等待运行完毕",
|
||||
value: "then",
|
||||
},
|
||||
],
|
||||
callbackFunc: "",
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
"command.outputVariable": {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler(outputVariable) {
|
||||
this.initOutputVars(outputVariable);
|
||||
handler(newValue) {
|
||||
this.initOutputVars(newValue);
|
||||
},
|
||||
},
|
||||
"command.asyncMode": {
|
||||
immediate: true,
|
||||
handler(newValue) {
|
||||
this.asyncMode = newValue;
|
||||
},
|
||||
},
|
||||
"command.callbackFunc": {
|
||||
immediate: true,
|
||||
handler(callbackFunc) {
|
||||
if (callbackFunc) {
|
||||
this.outputMode = "callback";
|
||||
this.callbackFunc = callbackFunc;
|
||||
} else {
|
||||
this.outputMode = "wait";
|
||||
}
|
||||
handler(newValue) {
|
||||
this.callbackFunc = newValue;
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hasNestedFields(output) {
|
||||
console.log(output);
|
||||
if (!output) return false;
|
||||
return Object.keys(output).some(
|
||||
(key) => key !== "label" && key !== "placeholder"
|
||||
);
|
||||
},
|
||||
/**
|
||||
* 只处理一层嵌套,手动在配置文件中控制outputs结构不要太复杂
|
||||
* 第二层嵌套只嵌套对象,不嵌套数组
|
||||
* 最复杂的情况:
|
||||
* outputs: {
|
||||
* label: "测试",
|
||||
* structure: [
|
||||
* {
|
||||
* position: { label: "位置", {
|
||||
* x: { label: "X坐标" },
|
||||
* y: { label: "Y坐标" }
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
*
|
||||
*/
|
||||
getNestedFields(output) {
|
||||
const fields = {};
|
||||
Object.entries(output).forEach(([key, value]) => {
|
||||
@@ -243,25 +325,17 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
// 根据输出模式处理
|
||||
const result = {
|
||||
let result = {
|
||||
outputVariable,
|
||||
mode: this.outputMode,
|
||||
};
|
||||
|
||||
// 如果是回调函数模式,添加回调函数名和参数信息
|
||||
if (this.outputMode === "callback" && this.callbackFunc) {
|
||||
// 添加函数参数和本地变量信息
|
||||
result.functionInfo = {
|
||||
name: this.callbackFunc,
|
||||
params: [outputVariable.name],
|
||||
localVars: outputVariable.details
|
||||
? Object.entries(outputVariable.details).map(([path, varName]) => ({
|
||||
name: varName,
|
||||
type: "var",
|
||||
value: `${outputVariable.name}.${path}`,
|
||||
}))
|
||||
: [],
|
||||
};
|
||||
// async模式
|
||||
if (this.asyncMode) {
|
||||
result.asyncMode = this.asyncMode;
|
||||
// 如果是回调函数模式,添加回调函数名和参数信息
|
||||
if (this.asyncMode === "then" && this.callbackFunc) {
|
||||
result.callbackFunc = this.callbackFunc;
|
||||
}
|
||||
}
|
||||
|
||||
this.$emit("confirm", result);
|
||||
|
Reference in New Issue
Block a user