mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-09 15:04:06 +08:00
重构 OutputEditor:提取可重用组件并改进变量验证
This commit is contained in:
parent
365964fc02
commit
40f1e1d7f7
@ -4,26 +4,25 @@
|
|||||||
<div class="row justify-center q-px-sm q-pt-md">
|
<div class="row justify-center q-px-sm q-pt-md">
|
||||||
{{ commandName }}
|
{{ commandName }}
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-output q-px-sm">
|
|
||||||
<q-badge color="primary" class="q-mb-sm q-pa-xs">完整结果</q-badge>
|
<!-- 完整结果部分 -->
|
||||||
<q-input v-model="simpleOutputVar" filled dense autofocus>
|
<SectionBlock title="完整结果">
|
||||||
<template v-slot:prepend>
|
<OutputField
|
||||||
<div class="variable-label">
|
v-model="simpleOutputVar"
|
||||||
{{ currentOutputs?.label || "输出变量名" }}
|
:label="currentOutputs?.label || '输出变量名'"
|
||||||
</div>
|
autofocus
|
||||||
</template>
|
class="q-px-sm"
|
||||||
</q-input>
|
/>
|
||||||
</div>
|
</SectionBlock>
|
||||||
<div v-if="currentOutputs?.structure">
|
|
||||||
<div class="row items-center">
|
<!-- 详细输出部分 -->
|
||||||
<q-badge color="primary" class="q-ma-sm q-pa-xs">详细输出</q-badge>
|
<template v-if="currentOutputs?.structure">
|
||||||
<div
|
<SectionBlock
|
||||||
v-if="Array.isArray(currentOutputs.structure)"
|
title="详细输出"
|
||||||
class="text-caption text-grey-5"
|
:subtitle="
|
||||||
|
Array.isArray(currentOutputs.structure) ? '数组中第一个元素' : ''
|
||||||
|
"
|
||||||
>
|
>
|
||||||
数组中第一个元素
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<q-scroll-area
|
<q-scroll-area
|
||||||
style="height: 200px"
|
style="height: 200px"
|
||||||
:thumb-style="{
|
:thumb-style="{
|
||||||
@ -31,147 +30,56 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="detail-output column q-col-gutter-sm q-px-sm">
|
<div class="detail-output column q-col-gutter-sm q-px-sm">
|
||||||
<!-- 处理数组类型的structure -->
|
|
||||||
<template v-if="Array.isArray(currentOutputs.structure)">
|
<template v-if="Array.isArray(currentOutputs.structure)">
|
||||||
<div
|
<template
|
||||||
v-for="(output, key) in currentOutputs.structure[0]"
|
v-for="(output, key) in currentOutputs.structure[0]"
|
||||||
:key="key"
|
:key="key"
|
||||||
>
|
>
|
||||||
<!-- 如果是嵌套对象 -->
|
<OutputStructure
|
||||||
<div v-if="hasNestedFields(output)">
|
:output="output"
|
||||||
<BorderLabel
|
:output-key="key"
|
||||||
:label="output.label || key"
|
:is-array="true"
|
||||||
:model-value="false"
|
v-model="outputVars"
|
||||||
>
|
/>
|
||||||
<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>
|
</template>
|
||||||
</q-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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>
|
</template>
|
||||||
</q-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<!-- 处理对象类型的structure -->
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div
|
<template
|
||||||
v-for="(output, key) in currentOutputs?.structure"
|
v-for="(output, key) in currentOutputs?.structure"
|
||||||
:key="key"
|
:key="key"
|
||||||
>
|
>
|
||||||
<!-- 如果是嵌套对象 -->
|
<OutputStructure
|
||||||
<div v-if="hasNestedFields(output)">
|
:output="output"
|
||||||
<BorderLabel
|
:output-key="key"
|
||||||
:label="output.label || key"
|
v-model="outputVars"
|
||||||
: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>
|
</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>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</q-scroll-area>
|
</q-scroll-area>
|
||||||
</div>
|
</SectionBlock>
|
||||||
|
</template>
|
||||||
<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">
|
<template v-if="!!asyncMode">
|
||||||
<q-select
|
<SectionBlock title="运行模式">
|
||||||
v-model="asyncMode"
|
<div class="row q-col-gutter-sm q-px-sm">
|
||||||
:options="asyncModeOptions"
|
<OutputField
|
||||||
filled
|
v-model="asyncMode"
|
||||||
dense
|
class="col"
|
||||||
autofocus
|
:options="asyncModeOptions"
|
||||||
emit-value
|
/>
|
||||||
map-options
|
<template v-if="asyncMode === 'then'">
|
||||||
class="col"
|
<OutputField
|
||||||
>
|
v-model="callbackFunc"
|
||||||
</q-select>
|
label="回调函数"
|
||||||
<q-input
|
placeholder="新函数名则自动创建"
|
||||||
v-model="callbackFunc"
|
class="col-8"
|
||||||
filled
|
/>
|
||||||
dense
|
|
||||||
autofocus
|
|
||||||
class="col-8"
|
|
||||||
v-if="asyncMode === 'then'"
|
|
||||||
placeholder="新函数名则自动创建"
|
|
||||||
>
|
|
||||||
<template v-slot:prepend>
|
|
||||||
<div class="variable-label">回调函数</div>
|
|
||||||
</template>
|
</template>
|
||||||
</q-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</SectionBlock>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="row justify-end q-px-sm q-py-sm">
|
<div class="row justify-end q-px-sm q-py-sm">
|
||||||
<q-btn flat label="取消" color="primary" v-close-popup />
|
<q-btn flat label="取消" color="primary" v-close-popup />
|
||||||
@ -183,12 +91,17 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent } from "vue";
|
||||||
import BorderLabel from "components/composer/common/BorderLabel.vue";
|
import { validateVariableName } from "js/common/variableValidator";
|
||||||
|
import OutputField from "./output/OutputField.vue";
|
||||||
|
import SectionBlock from "./output/SectionBlock.vue";
|
||||||
|
import OutputStructure from "./output/OutputStructure.vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "OutputEditor",
|
name: "OutputEditor",
|
||||||
components: {
|
components: {
|
||||||
BorderLabel,
|
OutputField,
|
||||||
|
SectionBlock,
|
||||||
|
OutputStructure,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@ -263,39 +176,6 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
hasNestedFields(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]) => {
|
|
||||||
if (key !== "label" && key !== "placeholder") {
|
|
||||||
fields[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return fields;
|
|
||||||
},
|
|
||||||
initOutputVars(outputVariable) {
|
initOutputVars(outputVariable) {
|
||||||
// 初始化完整输出变量名
|
// 初始化完整输出变量名
|
||||||
if (!outputVariable) return;
|
if (!outputVariable) return;
|
||||||
@ -338,6 +218,25 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查变量名是否合法
|
||||||
|
const varNames = [
|
||||||
|
outputVariable.name,
|
||||||
|
...Object.keys(outputVariable.details || {}),
|
||||||
|
result.callbackFunc,
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
|
const invalidVars = varNames.filter((name) => {
|
||||||
|
return !validateVariableName(name).isValid;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (invalidVars.length > 0) {
|
||||||
|
quickcommand.showMessageBox(
|
||||||
|
`变量名/函数名 ${invalidVars.join(", ")} 包含无效字符,请修改`,
|
||||||
|
"error"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.$emit("confirm", result);
|
this.$emit("confirm", result);
|
||||||
this.isOpen = false;
|
this.isOpen = false;
|
||||||
},
|
},
|
||||||
@ -349,44 +248,4 @@ export default defineComponent({
|
|||||||
.output-editor {
|
.output-editor {
|
||||||
width: 450px;
|
width: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.output-item {
|
|
||||||
border-radius: 8px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.output-item:hover {
|
|
||||||
background: rgba(0, 0, 0, 0.02);
|
|
||||||
}
|
|
||||||
|
|
||||||
.variable-label {
|
|
||||||
font-size: 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding-right: 10px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body--dark .output-item:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.02);
|
|
||||||
}
|
|
||||||
|
|
||||||
.output-editor :deep(.q-field--filled .q-field__control),
|
|
||||||
.output-editor :deep(.q-field--filled .q-field__control > *),
|
|
||||||
.output-editor :deep(.q-field--filled .q-field__native) {
|
|
||||||
max-height: 36px;
|
|
||||||
min-height: 36px;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 去除filled输入框边框 */
|
|
||||||
.output-editor :deep(.q-field__control:before) {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 去除filled输入框下划线 */
|
|
||||||
.output-editor :deep(.q-field__control:after) {
|
|
||||||
height: 0;
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
86
src/components/composer/card/output/OutputField.vue
Normal file
86
src/components/composer/card/output/OutputField.vue
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<q-input
|
||||||
|
v-if="!options"
|
||||||
|
:model-value="modelValue"
|
||||||
|
@update:model-value="$emit('update:modelValue', $event)"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
class="output-field"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:autofocus="autofocus"
|
||||||
|
>
|
||||||
|
<template v-slot:prepend>
|
||||||
|
<div class="variable-label">{{ label }}</div>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<q-select
|
||||||
|
v-else
|
||||||
|
:model-value="modelValue"
|
||||||
|
:options="options"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
class="output-field"
|
||||||
|
@update:model-value="$emit('update:modelValue', $event)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "OutputField",
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
autofocus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: null,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ["update:modelValue"],
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.variable-label {
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-right: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-field :deep(.q-field__control),
|
||||||
|
.output-field :deep(.q-field__control > *),
|
||||||
|
.output-field :deep(.q-field__native) {
|
||||||
|
max-height: 36px;
|
||||||
|
min-height: 36px;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 去除filled输入框边框 */
|
||||||
|
.output-field :deep(.q-field__control:before) {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 去除filled输入框下划线 */
|
||||||
|
.output-field :deep(.q-field__control:after) {
|
||||||
|
height: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
</style>
|
127
src/components/composer/card/output/OutputStructure.vue
Normal file
127
src/components/composer/card/output/OutputStructure.vue
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 如果是嵌套对象 -->
|
||||||
|
<div v-if="hasNestedFields">
|
||||||
|
<BorderLabel :label="output.label || outputKey" :model-value="false">
|
||||||
|
<div class="column q-col-gutter-sm">
|
||||||
|
<div v-for="(subOutput, subKey) in getNestedFields" :key="subKey">
|
||||||
|
<div class="output-item">
|
||||||
|
<OutputField
|
||||||
|
:model-value="modelValue[getFieldPath(subKey)]"
|
||||||
|
@update:model-value="updateField(subKey, $event)"
|
||||||
|
:label="subOutput.label"
|
||||||
|
:placeholder="subOutput.placeholder"
|
||||||
|
autofocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</BorderLabel>
|
||||||
|
</div>
|
||||||
|
<!-- 如果是普通字段 -->
|
||||||
|
<div v-else class="output-item">
|
||||||
|
<OutputField
|
||||||
|
:model-value="modelValue[getFieldPath()]"
|
||||||
|
@update:model-value="updateField('', $event)"
|
||||||
|
:label="output.label"
|
||||||
|
:placeholder="output.placeholder"
|
||||||
|
autofocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 只处理一层嵌套,手动在配置文件中控制outputs结构不要太复杂
|
||||||
|
* 第二层嵌套只嵌套对象,不嵌套数组
|
||||||
|
* 最复杂的情况:
|
||||||
|
* outputs: {
|
||||||
|
* label: "测试",
|
||||||
|
* structure: [
|
||||||
|
* {
|
||||||
|
* position: { label: "位置", {
|
||||||
|
* x: { label: "X坐标" },
|
||||||
|
* y: { label: "Y坐标" }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import BorderLabel from "components/composer/common/BorderLabel.vue";
|
||||||
|
import OutputField from "./OutputField.vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "OutputStructure",
|
||||||
|
components: {
|
||||||
|
BorderLabel,
|
||||||
|
OutputField,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
output: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
outputKey: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
isArray: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ["update:modelValue"],
|
||||||
|
computed: {
|
||||||
|
hasNestedFields() {
|
||||||
|
if (!this.output) return false;
|
||||||
|
return Object.keys(this.output).some(
|
||||||
|
(key) => key !== "label" && key !== "placeholder"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
getNestedFields() {
|
||||||
|
const fields = {};
|
||||||
|
Object.entries(this.output).forEach(([key, value]) => {
|
||||||
|
if (key !== "label" && key !== "placeholder") {
|
||||||
|
fields[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return fields;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getFieldPath(subKey = "") {
|
||||||
|
const base = this.isArray ? `[0].${this.outputKey}` : this.outputKey;
|
||||||
|
return subKey ? `${base}.${subKey}` : base;
|
||||||
|
},
|
||||||
|
updateField(subKey, value) {
|
||||||
|
const path = this.getFieldPath(subKey);
|
||||||
|
const newValue = { ...this.modelValue };
|
||||||
|
newValue[path] = value;
|
||||||
|
this.$emit("update:modelValue", newValue);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.output-item {
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-item:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.body--dark .output-item:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.02);
|
||||||
|
}
|
||||||
|
</style>
|
29
src/components/composer/card/output/SectionBlock.vue
Normal file
29
src/components/composer/card/output/SectionBlock.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="row items-center">
|
||||||
|
<q-badge color="primary" class="q-ma-sm q-pa-xs">{{ title }}</q-badge>
|
||||||
|
<div v-if="subtitle" class="text-caption text-grey-5">
|
||||||
|
{{ subtitle }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "SectionBlock",
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
subtitle: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@ -35,6 +35,7 @@
|
|||||||
dense
|
dense
|
||||||
borderless
|
borderless
|
||||||
class="var-input"
|
class="var-input"
|
||||||
|
@blur="validateVariable(localFlow)"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<div class="var-label">标识</div>
|
<div class="var-label">标识</div>
|
||||||
@ -76,8 +77,8 @@
|
|||||||
dense
|
dense
|
||||||
borderless
|
borderless
|
||||||
class="var-input"
|
class="var-input"
|
||||||
@blur="validateVariable(variable, 'param')"
|
@blur="validateVariable(variable)"
|
||||||
@keydown.enter="validateVariable(variable, 'param')"
|
@keydown.enter="validateVariable(variable)"
|
||||||
/>
|
/>
|
||||||
<q-btn
|
<q-btn
|
||||||
flat
|
flat
|
||||||
@ -125,8 +126,8 @@
|
|||||||
borderless
|
borderless
|
||||||
class="var-input"
|
class="var-input"
|
||||||
placeholder="变量名"
|
placeholder="变量名"
|
||||||
@blur="validateVariable(variable, 'var')"
|
@blur="validateVariable(variable)"
|
||||||
@keydown.enter="validateVariable(variable, 'var')"
|
@keydown.enter="validateVariable(variable)"
|
||||||
/>
|
/>
|
||||||
<q-separator vertical />
|
<q-separator vertical />
|
||||||
<q-input
|
<q-input
|
||||||
@ -174,6 +175,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
import { validateVariableName } from "js/common/variableValidator";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "FlowManager",
|
name: "FlowManager",
|
||||||
@ -242,14 +244,14 @@ export default defineComponent({
|
|||||||
this.localFlow.customVariables = newVars;
|
this.localFlow.customVariables = newVars;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validateVariable(variable, type) {
|
validateVariable(variable) {
|
||||||
if (!variable.name) {
|
if (validateVariableName(variable.name).isValid) {
|
||||||
const prefix = type === "param" ? "param_" : "var_";
|
return;
|
||||||
const count = this.localFlow.customVariables.filter(
|
|
||||||
(v) => v.type === type
|
|
||||||
).length;
|
|
||||||
variable.name = prefix + count;
|
|
||||||
}
|
}
|
||||||
|
quickcommand.showMessageBox(
|
||||||
|
`变量/函数名 ${variable.name} 包含无效字符,请修改`,
|
||||||
|
"error"
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,9 @@ export function generateCode(flow) {
|
|||||||
return `${varName} = ${varValue};`;
|
return `${varName} = ${varValue};`;
|
||||||
}
|
}
|
||||||
usedVarNames[funcName].push(varName);
|
usedVarNames[funcName].push(varName);
|
||||||
|
if (!varValue) {
|
||||||
|
return `let ${varName};`;
|
||||||
|
}
|
||||||
return `let ${varName} = ${varValue};`;
|
return `let ${varName} = ${varValue};`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user