feat: 新增动态表单收集器
Some checks are pending
sync2gitee / repo-sync (push) Waiting to run
Typos Check / Spell Check with Typos (push) Waiting to run

This commit is contained in:
zhangshaohu 2024-10-13 20:03:32 +08:00 committed by shaohuzhang1
parent 2e331dcf56
commit 2e7b31dc3c
7 changed files with 339 additions and 0 deletions

View File

@ -0,0 +1,33 @@
"""
@project: MaxKB
@Author
@file switch_field.py
@date2024/10/13 19:43
@desc:
"""
from typing import Dict
from common.forms import BaseField, TriggerType, BaseLabel
class SwitchField(BaseField):
"""
滑块输入框
"""
def __init__(self, label: str or BaseLabel,
required: bool = False,
default_value=None,
relation_show_field_dict: Dict = None,
attrs=None, props_info=None):
"""
@param required: 是否必填
@param default_value: 默认值
@param relation_show_field_dict:
@param attrs:
@param props_info:
"""
super().__init__('Switch', label, required, default_value, relation_show_field_dict,
{},
TriggerType.OPTION_LIST, attrs, props_info)

View File

@ -0,0 +1,43 @@
<template>
<el-row :gutter="12">
<el-col :span="12">
<el-card shadow="never">
<DynamicsFormConstructor
label-position="top"
require-asterisk-position="right"
ref="DynamicsFormConstructorRef"
></DynamicsFormConstructor>
<el-button @click="add_field">添加</el-button>
</el-card></el-col
>
<el-col :span="12">
<el-card shadow="never">
<DynamicsForm
label-position="top"
require-asterisk-position="right"
v-model="form_data"
:model="form_data"
:render_data="form_item_list"
ref="dynamicsFormRef"
>
</DynamicsForm> </el-card
></el-col>
</el-row>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue'
import DynamicsForm from '@/components/dynamics-form/index.vue'
const DynamicsFormConstructorRef = ref<InstanceType<typeof DynamicsFormConstructor>>()
const form_item_list = ref<Array<any>>([])
const add_field = () => {
if (DynamicsFormConstructorRef.value) {
DynamicsFormConstructorRef.value.validate().then(() => {
form_item_list.value.push(DynamicsFormConstructorRef.value?.getData())
})
}
}
const form_data = ref({})
const dynamicsFormRef = ref<InstanceType<typeof DynamicsForm>>()
</script>
<style lang="scss"></style>

View File

@ -0,0 +1,89 @@
<template>
<el-form
@submit.prevent
ref="ruleFormRef"
class="mb-24"
label-width="auto"
:model="form_data"
v-bind="$attrs"
>
<el-form-item label="参数" :required="true" prop="label" :rules="rules.label">
<el-input v-model="form_data.label" placeholder="请输入参数" />
</el-form-item>
<el-form-item label="显示名称" :required="true" prop="field" :rules="rules.field">
<el-input v-model="form_data.field" placeholder="请输入显示名称" />
</el-form-item>
<el-form-item label="参数提示说明">
<el-input v-model="form_data.tooltip" placeholder="请输入参数提示说明" />
</el-form-item>
<el-form-item label="是否必填" :required="true" prop="required" :rules="rules.required">
<el-switch v-model="form_data.required" />
</el-form-item>
<el-form-item label="组建类型" :required="true" prop="input_type" :rules="rules.input_type">
<el-select v-model="form_data.input_type" placeholder="请选择组建类型">
<el-option
v-for="input_type in input_type_list"
:key="input_type.value"
:label="input_type.label"
:value="input_type.value"
/>
</el-select>
</el-form-item>
<component
v-if="form_data.input_type"
ref="componentFormRef"
v-model="form_data"
:is="form_data.input_type"
></component>
</el-form>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { FormInstance } from 'element-plus'
const ruleFormRef = ref<FormInstance>()
const input_type_list = [
{ label: '文本框', value: 'TextInputConstructor' },
{ label: '滑块', value: 'SliderConstructor' },
{label: '开关',value:'SwitchInputConstructor'}
]
const componentFormRef = ref<any>()
const form_data = ref<any>({
label: '',
field: '',
tooltip: '',
required: false,
input_type: ''
})
const rules = {
label: [{ required: true, message: '参数 为必填属性' }],
field: [{ required: true, message: '显示名称 为必填属性' }],
required: [{ required: true, message: '是否必填 为必填属性' }],
input_type: [{ required: true, message: '组建类型 为必填属性' }]
}
const getData = () => {
let label: string | any = form_data.value.label
if (form_data.value.tooltip) {
label = {
input_type: 'TooltipLabel',
label: form_data.value.label,
attrs: { tooltip: form_data.value.tooltip },
props_info: {}
}
}
return {
label: label,
required: form_data.value.required,
field: form_data.value.field,
default_value: form_data.value.default_value,
...componentFormRef.value.getData()
}
}
const validate = () => {
if (ruleFormRef.value) {
return ruleFormRef.value?.validate()
}
return Promise.resolve()
}
defineExpose({ getData, validate })
</script>
<style lang="scss"></style>

View File

@ -0,0 +1,70 @@
<template>
<el-form-item label="最小值" required>
<el-input-number v-model="formValue.min" :min="0" controls-position="right" />
</el-form-item>
<el-form-item label="最大值" required>
<el-input-number v-model="formValue.max" :min="0" controls-position="right" />
</el-form-item>
<el-form-item label="步长值" required>
<el-input-number v-model="formValue.step" :min="0" controls-position="right" />
</el-form-item>
<el-form-item label="精确值" required>
<el-input-number v-model="formValue.precision" :min="0" controls-position="right" />
</el-form-item>
<el-form-item
label="默认值"
:required="formValue.required"
prop="default_value"
:rules="formValue.required ? [{ required: true, message: '默认值 为必填属性' }] : []"
>
<el-slider
v-model="formValue.default_value"
show-input
:show-input-controls="false"
:max="formValue.max"
:min="formValue.min"
:step="formValue.step"
:precision="formValue.precision"
/>
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onBeforeMount } from 'vue'
const props = defineProps<{
modelValue: any
}>()
const emit = defineEmits(['update:modelValue'])
const formValue = computed({
set: (item) => {
emit('update:modelValue', item)
},
get: () => {
return props.modelValue
}
})
const getData = () => {
return {
input_type: 'Slider',
attrs: {
min: formValue.value.min,
max: formValue.value.max,
step: formValue.value.step,
precision: formValue.value.precision,
'show-input-controls': false,
'show-input': true
},
default_value: formValue.value.default_value
}
}
defineExpose({ getData })
onBeforeMount(() => {
formValue.value.min = 0
formValue.value.max = 20
formValue.value.step = 0.1
formValue.value.precision = 1
formValue.value.default_value = 1
})
</script>
<style lang="scss"></style>

View File

@ -0,0 +1,39 @@
<template>
<el-form-item
label="默认值"
:required="formValue.required"
prop="default_value"
:rules="formValue.required ? [{ required: true, message: '默认值 为必填属性' }] : []"
>
<el-switch v-model="formValue.default_value" />
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onMounted } from 'vue'
const props = defineProps<{
modelValue: any
}>()
const emit = defineEmits(['update:modelValue'])
const formValue = computed({
set: (item) => {
emit('update:modelValue', item)
},
get: () => {
return props.modelValue
}
})
const getData = () => {
return {
input_type: 'SwitchInput',
attrs: {},
default_value: formValue.value.default_value
}
}
defineExpose({ getData })
onMounted(() => {
formValue.value.default_value = false
})
</script>
<style lang="scss"></style>

View File

@ -0,0 +1,58 @@
<template>
<el-form-item label="最小长度" required>
<el-input-number v-model="formValue.min_length" :min="0" controls-position="right" />
</el-form-item>
<el-form-item label="最大长度" required>
<el-input-number v-model="formValue.max_length" :min="0" controls-position="right" />
</el-form-item>
<el-form-item
label="默认值"
:required="formValue.required"
prop="default_value"
:rules="formValue.required ? [{ required: true, message: '默认值 为必填属性' }] : []"
>
<el-input
v-model="formValue.default_value"
:maxlength="formValue.max_length"
:minlength="formValue.min_length"
placeholder="请输入默认值"
show-word-limit
type="text"
/>
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onMounted } from 'vue'
const props = defineProps<{
modelValue: any
}>()
const emit = defineEmits(['update:modelValue'])
const formValue = computed({
set: (item) => {
emit('update:modelValue', item)
},
get: () => {
return props.modelValue
}
})
const getData = () => {
return {
input_type: 'TextInput',
attrs: {
maxlength: formValue.value.max_length,
minlength: formValue.value.min_length,
'show-word-limit': true
},
default_value: formValue.value.default_value
}
}
defineExpose({ getData })
onMounted(() => {
formValue.value.min_length = 0
formValue.value.max_length = 20
formValue.value.default_value = ''
})
</script>
<style lang="scss"></style>

View File

@ -0,0 +1,7 @@
<template>
<el-switch v-bind="$attrs" />
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped>
</style>