编排新增HTML解析、上传、下载

This commit is contained in:
fofolee
2025-01-08 17:35:27 +08:00
parent ebbc7b7661
commit 01183d06e8
10 changed files with 346 additions and 180 deletions

View File

@@ -1,82 +1,89 @@
<template>
<div class="array-editor">
<div v-for="(item, index) in items" :key="index" class="row items-center">
<template v-if="optionsKeys.length">
<div
v-for="key in optionsKeys"
:key="key.value"
:class="[
key.width ? `col-${key.width}` : 'col',
optionsKeys.length > 1 ? 'q-pr-sm' : '',
]"
>
<VariableInput
:model-value="item[key.value]"
:label="key.label"
:no-icon="true"
@update:model-value="
(val) => updateItemKeyValue(index, key.value, val)
"
/>
</div>
</template>
<template v-else>
<div class="col">
<VariableInput
:model-value="item"
:label="`${label || '项目'} ${index + 1}`"
:icon="icon || 'code'"
:options="{
items: options.items,
}"
@update:model-value="(val) => updateItemValue(index, val)"
/>
</div>
</template>
<div class="col-auto">
<div class="btn-container">
<template v-if="items.length === 1">
<q-btn
flat
dense
size="sm"
icon="add"
class="center-btn"
@click="addItem"
<component
:is="!!label ? 'BorderLabel' : 'div'"
:label="label"
:icon="icon"
:model-value="isCollapse"
>
<div class="array-editor">
<div v-for="(item, index) in items" :key="index" class="row items-center">
<template v-if="optionsKeys.length">
<div
v-for="key in optionsKeys"
:key="key.value"
:class="[
key.width ? `col-${key.width}` : 'col',
optionsKeys.length > 1 ? 'q-pr-sm' : '',
]"
>
<VariableInput
:model-value="item[key.value]"
:label="key.label"
:no-icon="true"
@update:model-value="
(val) => updateItemKeyValue(index, key.value, val)
"
/>
</template>
<template v-else-if="index === items.length - 1">
<q-btn
flat
dense
size="sm"
icon="remove"
class="top-btn"
@click="removeItem(index)"
</div>
</template>
<template v-else>
<div class="col">
<VariableInput
:model-value="item"
:label="`${label || '项目'} ${index + 1}`"
:icon="icon || 'code'"
:options="{
items: options.items,
}"
@update:model-value="(val) => updateItemValue(index, val)"
/>
<q-btn
flat
dense
size="sm"
icon="add"
class="bottom-btn"
@click="addItem"
/>
</template>
<template v-else>
<q-btn
flat
dense
size="sm"
icon="remove"
class="center-btn"
@click="removeItem(index)"
/>
</template>
</div>
</template>
<div class="col-auto">
<div class="btn-container">
<template v-if="items.length === 1">
<q-btn
flat
dense
size="sm"
icon="add"
class="center-btn"
@click="addItem"
/>
</template>
<template v-else-if="index === items.length - 1">
<q-btn
flat
dense
size="sm"
icon="remove"
class="top-btn"
@click="removeItem(index)"
/>
<q-btn
flat
dense
size="sm"
icon="add"
class="bottom-btn"
@click="addItem"
/>
</template>
<template v-else>
<q-btn
flat
dense
size="sm"
icon="remove"
class="center-btn"
@click="removeItem(index)"
/>
</template>
</div>
</div>
</div>
</div>
</div>
</component>
</template>
<script>
@@ -118,16 +125,19 @@
import { defineComponent } from "vue";
import VariableInput from "components/composer/common/VariableInput.vue";
import { newVarInputVal } from "js/composer/varInputValManager";
import BorderLabel from "components/composer/common/BorderLabel.vue";
export default defineComponent({
name: "ArrayEditor",
components: {
VariableInput,
BorderLabel,
},
props: {
modelValue: {
type: Array,
required: true,
default: () => [],
},
label: {
type: String,
@@ -137,6 +147,10 @@ export default defineComponent({
type: String,
default: "",
},
isCollapse: {
type: Boolean,
default: true,
},
options: {
type: Object,
default: () => ({}),

View File

@@ -1,12 +1,20 @@
<template>
<div class="border-label" :class="{ collapsed }" :data-label="label">
<div class="label-header" @click="toggleCollapse">
<div class="label-header row items-center" @click="toggleCollapse">
<q-icon
:name="collapsed ? 'expand_more' : 'expand_less'"
size="16px"
class="collapse-icon"
/>
<span class="label-text">{{ label }}</span>
<div class="label-text row items-center">
<q-icon
v-if="icon"
:name="icon"
size="16px"
class="collapse-icon q-pl-sm"
/>
<div class="label-text">{{ label }}</div>
</div>
</div>
<div class="content" :class="{ collapsed }">
<slot></slot>
@@ -33,6 +41,10 @@ export default {
type: Boolean,
default: true,
},
icon: {
type: String,
default: "",
},
},
emits: ["update:modelValue"],
data() {

View File

@@ -1,102 +1,110 @@
<template>
<div class="dict-editor">
<div
v-for="(item, index) in items"
:key="index"
class="row q-col-gutter-sm items-center"
>
<div class="col-4">
<q-select
v-if="options?.items"
:model-value="item.key"
:options="options.items"
label="名称"
dense
filled
use-input
input-debounce="0"
:hide-selected="!!inputValue"
@filter="filterFn"
@update:model-value="(val) => handleSelect(val, index)"
@input-value="(val) => handleInput(val, index)"
@blur="handleBlur"
>
<template v-slot:prepend>
<q-icon name="code" />
</template>
</q-select>
<q-input
v-else
:model-value="item.key"
label="名称"
dense
filled
@update:model-value="(val) => updateItemKey(val, index)"
>
<template v-slot:prepend>
<q-icon name="code" />
</template>
</q-input>
</div>
<div class="col">
<VariableInput
:model-value="item.value"
label=""
icon="code"
class="col-grow"
@update:model-value="(val) => updateItemValue(val, index)"
/>
</div>
<div class="col-auto">
<div class="btn-container">
<template v-if="items.length === 1">
<q-btn
flat
dense
size="sm"
icon="add"
class="center-btn"
@click="addItem"
/>
</template>
<template v-else-if="index === items.length - 1">
<q-btn
flat
dense
size="sm"
icon="remove"
class="top-btn"
@click="removeItem(index)"
/>
<q-btn
flat
dense
size="sm"
icon="add"
class="bottom-btn"
@click="addItem"
/>
</template>
<template v-else>
<q-btn
flat
dense
size="sm"
icon="remove"
class="center-btn"
@click="removeItem(index)"
/>
</template>
<component
:is="!!label ? 'BorderLabel' : 'div'"
:label="label"
:icon="icon"
:model-value="isCollapse"
>
<div class="dict-editor">
<div
v-for="(item, index) in items"
:key="index"
class="row q-col-gutter-sm items-center"
>
<div class="col-4">
<q-select
v-if="options?.items"
:model-value="item.key"
:options="options.items"
label="名称"
dense
filled
use-input
input-debounce="0"
:hide-selected="!!inputValue"
@filter="filterFn"
@update:model-value="(val) => handleSelect(val, index)"
@input-value="(val) => handleInput(val, index)"
@blur="handleBlur"
>
<template v-slot:prepend>
<q-icon name="code" />
</template>
</q-select>
<q-input
v-else
:model-value="item.key"
label="名称"
dense
filled
@update:model-value="(val) => updateItemKey(val, index)"
>
<template v-slot:prepend>
<q-icon name="code" />
</template>
</q-input>
</div>
<div class="col">
<VariableInput
:model-value="item.value"
label=""
icon="code"
class="col-grow"
@update:model-value="(val) => updateItemValue(val, index)"
/>
</div>
<div class="col-auto">
<div class="btn-container">
<template v-if="items.length === 1">
<q-btn
flat
dense
size="sm"
icon="add"
class="center-btn"
@click="addItem"
/>
</template>
<template v-else-if="index === items.length - 1">
<q-btn
flat
dense
size="sm"
icon="remove"
class="top-btn"
@click="removeItem(index)"
/>
<q-btn
flat
dense
size="sm"
icon="add"
class="bottom-btn"
@click="addItem"
/>
</template>
<template v-else>
<q-btn
flat
dense
size="sm"
icon="remove"
class="center-btn"
@click="removeItem(index)"
/>
</template>
</div>
</div>
</div>
</div>
</div>
</component>
</template>
<script>
import { defineComponent } from "vue";
import { newVarInputVal } from "js/composer/varInputValManager";
import VariableInput from "components/composer/common/VariableInput.vue";
import BorderLabel from "components/composer/common/BorderLabel.vue";
/**
* 字典编辑器组件
@@ -124,16 +132,30 @@ export default defineComponent({
name: "DictEditor",
components: {
VariableInput,
BorderLabel,
},
props: {
modelValue: {
type: Object,
required: true,
default: () => ({}),
},
options: {
type: Object,
default: () => ({}),
},
label: {
type: String,
default: "",
},
icon: {
type: String,
default: "",
},
isCollapse: {
type: Boolean,
default: true,
},
},
emits: ["update:modelValue"],
data() {

View File

@@ -29,12 +29,17 @@
@update:model-value="$emit('update', index, $event)"
:label="config.label"
:options="config.options"
:icon="config.icon"
:is-collapse="config.isCollapse"
/>
<DictEditor
v-else-if="config.type === 'dictEditor'"
:model-value="values[index]"
@update:model-value="$emit('update', index, $event)"
:label="config.label"
:options="config.options"
:icon="config.icon"
:is-collapse="config.isCollapse"
/>
<q-toggle
v-else-if="config.type === 'switch'"

View File

@@ -116,12 +116,12 @@
<!-- 环境变量 -->
<div class="col-12">
<BorderLabel label="环境变量">
<DictEditor
:model-value="argvs.options.env"
@update:model-value="(val) => updateArgvs('options.env', val)"
/>
</BorderLabel>
<DictEditor
:model-value="argvs.options.env"
@update:model-value="(val) => updateArgvs('options.env', val)"
label="环境变量"
icon="environment"
/>
</div>
</div>
</q-slide-transition>
@@ -136,7 +136,6 @@ import { newVarInputVal } from "js/composer/varInputValManager";
import VariableInput from "components/composer/common/VariableInput.vue";
import NumberInput from "components/composer/common/NumberInput.vue";
import DictEditor from "components/composer/common/DictEditor.vue";
import BorderLabel from "components/composer/common/BorderLabel.vue";
export default defineComponent({
name: "SystemCommandEditor",
@@ -144,7 +143,6 @@ export default defineComponent({
VariableInput,
NumberInput,
DictEditor,
BorderLabel,
},
props: {
modelValue: {
@@ -166,7 +164,6 @@ export default defineComponent({
],
defaultArgvs: {
command: newVarInputVal("str"),
},
options: {
cwd: newVarInputVal("str"),
env: {},
@@ -174,9 +171,10 @@ export default defineComponent({
encoding: "buffer",
timeout: 0,
maxBuffer: 1024 * 1024, // 1MB
shell: newVarInputVal("str"),
windowsHide: true,
},
shell: newVarInputVal("str"),
windowsHide: true,
},
},
};
},
computed: {