fix: 修复表单构造器相关bug

This commit is contained in:
shaohuzhang1 2024-10-28 12:09:17 +08:00 committed by shaohuzhang1
parent ba37e62428
commit a7b85143a1
10 changed files with 217 additions and 84 deletions

View File

@ -0,0 +1,27 @@
const input_type_list = [
{
label: '文本框',
value: 'TextInput'
},
{
label: '滑块',
value: 'Slider'
},
{
label: '开关',
value: 'SwitchInput'
},
{
label: '单选框',
value: 'SingleSelect'
},
{
label: '日期',
value: 'DatePicker'
},
{
label: 'JSON文本框',
value: 'JsonInput'
}
]
export { input_type_list }

View File

@ -41,20 +41,15 @@
import { onMounted, ref, nextTick } from 'vue'
import type { FormInstance } from 'element-plus'
import _ from 'lodash'
import { input_type_list as input_type_list_data } from '@/components/dynamics-form/constructor/data'
const props = withDefaults(
defineProps<{
modelValue?: any
input_type_list?: Array<{ label: string; value: string }>
}>(),
{
input_type_list: () => [
{ label: '文本框', value: 'TextInputConstructor' },
{ label: '滑块', value: 'SliderConstructor' },
{ label: '开关', value: 'SwitchInputConstructor' },
{ label: '单选框', value: 'SingleSelectConstructor' },
{ label: '日期', value: 'DatePickerConstructor' },
{ label: 'JSON文本框', value: 'JsonInputConstructor' }
]
input_type_list: () =>
input_type_list_data.map((item) => ({ label: item.label, value: item.value + 'Constructor' }))
}
)
const emit = defineEmits(['update:modelValue'])

View File

@ -41,7 +41,7 @@
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { computed, onBeforeMount } from 'vue'
const type_list = [
{
label: '年',
@ -97,10 +97,10 @@ const getData = () => {
const rander = (form_data: any) => {
formValue.value.type = form_data.attrs.type
formValue.value.format = form_data.attrs?.format
formValue.value.default_value = form_data.default_value
formValue.value.default_value = form_data.default_value || ''
}
defineExpose({ getData, rander })
onMounted(() => {
onBeforeMount(() => {
formValue.value.type = 'datetime'
formValue.value.format = 'YYYY-MM-DD HH:mm:ss'
formValue.value.default_value = ''

View File

@ -26,7 +26,6 @@ const formValue = computed({
})
const jsonInputRef = ref<InstanceType<typeof JsonInput>>()
const getData = () => {
console.log('xx')
return {
input_type: 'JsonInput',
attrs: {},

View File

@ -62,6 +62,10 @@ const addOption = () => {
}
const delOption = (index: number) => {
const option = formValue.value.option_list[index]
if (option.value && formValue.value.default_value == option.value) {
formValue.value.default_value = ''
}
formValue.value.option_list.splice(index, 1)
}
@ -70,13 +74,13 @@ const getData = () => {
input_type: 'SingleSelect',
attrs: {},
default_value: formValue.value.default_value,
text_field: formValue.value.text_field,
value_field: formValue.value.value_field,
text_field: 'value',
value_field: 'value',
option_list: formValue.value.option_list
}
}
const rander = (form_data: any) => {
formValue.value.option_list = form_data.option_list
formValue.value.option_list = form_data.option_list || []
formValue.value.default_value = form_data.default_value
}

View File

@ -1,16 +1,45 @@
<template>
<el-form-item label="取值范围" required>
<el-form-item label="是否带输入框" required prop="showInput">
<el-switch v-model="formValue.showInput" />
</el-form-item>
<el-form-item label="取值范围" required prop="min">
<el-col :span="11" style="padding-left: 0">
<el-input-number style="width: 100%" v-model="formValue.min" controls-position="right" />
<el-form-item
:rules="[
{
required: true,
message: '最小值必填',
trigger: 'change'
}
]"
prop="min"
>
<el-input-number style="width: 100%" v-model="formValue.min" controls-position="right"
/></el-form-item>
</el-col>
<el-col :span="2" class="text-center">
<span class="text-gray-500">-</span>
</el-col>
<el-col :span="11">
<el-input-number style="width: 100%" v-model="formValue.max" controls-position="right" />
<el-form-item
:rules="[
{
required: true,
message: '最大值必填',
trigger: 'change'
}
]"
prop="max"
><el-input-number
prop="max"
style="width: 100%"
v-model="formValue.max"
:min="formValue.min > formValue.max ? formValue.min : undefined"
controls-position="right"
/></el-form-item>
</el-col>
</el-form-item>
<el-form-item label="步长值" required>
<el-form-item label="步长值" required prop="step">
<el-input-number v-model="formValue.step" :min="0" controls-position="right" />
</el-form-item>
@ -22,7 +51,7 @@
>
<el-slider
v-model="formValue.default_value"
show-input
:show-input="formValue.showInput"
:show-input-controls="false"
:max="formValue.max"
:min="formValue.min"
@ -32,7 +61,7 @@
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onBeforeMount } from 'vue'
import { computed, onBeforeMount, watch } from 'vue'
const props = defineProps<{
modelValue: any
@ -56,18 +85,26 @@ const getData = () => {
step: formValue.value.step,
precision: formValue.value.precision,
'show-input-controls': false,
'show-input': true
'show-input': formValue.value.showInput
},
default_value: formValue.value.default_value
}
}
watch(
() => formValue.value.min,
() => {
if (formValue.value.min > formValue.value.max) {
formValue.value.max = formValue.value.min
}
}
)
const rander = (form_data: any) => {
const attrs = form_data.attrs
formValue.value.option_list = form_data.option_list
formValue.value.min = attrs.min
formValue.value.max = attrs.max
formValue.value.step = attrs.step
formValue.value.showInput = attrs['show-input']
formValue.value.default_value = form_data.default_value
}
@ -77,6 +114,7 @@ onBeforeMount(() => {
formValue.value.max = 20
formValue.value.step = 0.1
formValue.value.default_value = 1
formValue.value.showInput = true
})
</script>
<style lang="scss"></style>

View File

@ -33,7 +33,7 @@ const getData = () => {
}
const rander = (form_data: any) => {
formValue.value.default_value = form_data.default_value
formValue.value.default_value = form_data.default_value || false
}
defineExpose({ getData, rander })
onMounted(() => {

View File

@ -1,21 +1,48 @@
<template>
<el-form-item label="取值范围" required>
<el-form-item label="文本长度" required>
<el-col :span="11" style="padding-left: 0">
<el-input-number
style="width: 100%"
v-model="formValue.minlength"
controls-position="right"
/>
<el-form-item
:rules="[
{
required: true,
message: '最小长度必填',
trigger: 'change'
}
]"
prop="minlength"
>
<el-input-number
style="width: 100%"
:min="1"
:step="1"
step-strictly
v-model="formValue.minlength"
controls-position="right"
/>
</el-form-item>
</el-col>
<el-col :span="2" class="text-center">
<span class="text-gray-500">-</span>
</el-col>
<el-col :span="11">
<el-input-number
style="width: 100%"
v-model="formValue.maxlength"
controls-position="right"
/>
<el-form-item
:rules="[
{
required: true,
message: '最大长度必填',
trigger: 'change'
}
]"
prop="maxlength"
>
<el-input-number
style="width: 100%"
:min="formValue.minlength > formValue.maxlength ? formValue.minlength : 1"
step-strictly
:step="1"
v-model="formValue.maxlength"
controls-position="right"
/></el-form-item>
</el-col>
</el-form-item>
@ -23,7 +50,9 @@
label="默认值"
:required="formValue.required"
prop="default_value"
:rules="formValue.required ? [{ required: true, message: '默认值 为必填属性' }] : []"
:rules="
formValue.required ? [{ required: true, message: '默认值 为必填属性' }, ...rules] : rules
"
>
<el-input
v-model="formValue.default_value"
@ -36,7 +65,7 @@
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { computed, onMounted, watch } from 'vue'
const props = defineProps<{
modelValue: any
@ -50,7 +79,14 @@ const formValue = computed({
return props.modelValue
}
})
watch(
() => formValue.value.minlength,
() => {
if (formValue.value.minlength > formValue.value.maxlength) {
formValue.value.maxlength = formValue.value.minlength
}
}
)
const getData = () => {
return {
input_type: 'TextInput',
@ -59,7 +95,27 @@ const getData = () => {
minlength: formValue.value.minlength,
'show-word-limit': true
},
default_value: formValue.value.default_value
default_value: formValue.value.default_value,
props_info: {
rules: formValue.value.required
? [
{ required: true, message: `${formValue.value.label} 为必填属性` },
{
min: formValue.value.minlength,
max: formValue.value.maxlength,
message: `${formValue.value.label}长度在 ${formValue.value.minlength}${formValue.value.maxlength} 个字符`,
trigger: 'blur'
}
]
: [
{
min: formValue.value.minlength,
max: formValue.value.maxlength,
message: `${formValue.value.label}长度在 ${formValue.value.minlength}${formValue.value.maxlength} 个字符`,
trigger: 'blur'
}
]
}
}
}
const rander = (form_data: any) => {
@ -68,6 +124,30 @@ const rander = (form_data: any) => {
formValue.value.maxlength = attrs.maxlength
formValue.value.default_value = form_data.default_value
}
const rangeRules = [
{
required: true,
validator: (rule: any, value: any, callback: any) => {
if (!formValue.value.minlength) {
callback(new Error('文本长度为必填参数'))
}
if (!formValue.value.maxlength) {
callback(new Error('文本长度为必填参数'))
}
return true
},
message: `${formValue.value.label} 为必填属性`
}
]
const rules = computed(() => [
{
min: formValue.value.minlength,
max: formValue.value.maxlength,
message: `长度在 ${formValue.value.minlength}${formValue.value.maxlength} 个字符`,
trigger: 'blur'
}
])
defineExpose({ getData, rander })
onMounted(() => {
formValue.value.minlength = 0

View File

@ -1,5 +1,11 @@
<template>
<el-drawer v-model="drawer" :direction="direction" size="600" :destroy-on-close="true" :before-close="cancelClick">
<el-drawer
v-model="drawer"
:direction="direction"
size="600"
:destroy-on-close="true"
:before-close="cancelClick"
>
<template #header>
<h4>{{ isEdit ? '编辑参数' : '添加参数' }}</h4>
</template>
@ -67,10 +73,6 @@ function confirmClick() {
}
defineExpose({ open })
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>

View File

@ -8,26 +8,22 @@
:destroy-on-close="true"
:before-close="close"
>
<el-button type="primary" @click="openAddDrawer()" class="mb-12">
添加参数
</el-button>
<el-table
:data="modelParamsForm"
class="mb-16"
>
<el-button type="primary" @click="openAddDrawer()" class="mb-12"> 添加参数 </el-button>
<el-table :data="modelParamsForm" class="mb-16">
<el-table-column prop="label" label="显示名称">
<template #default="{ row }">
<span v-if="row.label && row.label.input_type === 'TooltipLabel'">{{ row.label.label }}</span>
<span v-if="row.label && row.label.input_type === 'TooltipLabel'">{{
row.label.label
}}</span>
<span v-else>{{ row.label }}</span>
</template>
</el-table-column>
<el-table-column prop="field" label="参数" />
<el-table-column label="组件类型">
<el-table-column label="组件类型" width="100px">
<template #default="{ row }">
<el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'">文本框</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'">滑块</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SwitchInput'">开关</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SingleSelect'">单选框</el-tag>
<el-tag type="info" class="info-tag">{{
input_type_list.find((item) => item.value === row.input_type)?.label
}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="default_value" label="默认值" />
@ -41,13 +37,13 @@
<el-table-column label="操作" align="left" width="80">
<template #default="{ row, $index }">
<span class="mr-4">
<el-tooltip effect="dark" content="修改" placement="top">
<el-button type="primary" text @click.stop="openAddDrawer(row, $index)">
<el-icon><EditPen /></el-icon>
</el-button>
</el-tooltip>
</span>
<span class="mr-4">
<el-tooltip effect="dark" content="修改" placement="top">
<el-button type="primary" text @click.stop="openAddDrawer(row, $index)">
<el-icon><EditPen /></el-icon>
</el-button>
</el-tooltip>
</span>
<el-tooltip effect="dark" content="删除" placement="top">
<el-button type="primary" text @click="deleteParam($index)">
<el-icon>
@ -74,7 +70,7 @@ import { ref } from 'vue'
import AddParamDrawer from './AddParamDrawer.vue'
import { MsgError, MsgSuccess } from '@/utils/message'
import ModelApi from '@/api/model'
import { input_type_list } from '@/components/dynamics-form/constructor/data'
const props = defineProps<{
model: Model
@ -88,22 +84,20 @@ const AddParamRef = ref()
const open = () => {
dialogVisible.value = true
loading.value = true
ModelApi.getModelParamsForm(
props.model.id,
loading
).then((ok) => {
loading.value = false
modelParamsForm.value = ok.data
}).catch(() => {
loading.value = false
})
ModelApi.getModelParamsForm(props.model.id, loading)
.then((ok) => {
loading.value = false
modelParamsForm.value = ok.data
})
.catch(() => {
loading.value = false
})
}
const close = () => {
dialogVisible.value = false
}
function openAddDrawer(data?: any, index?: any) {
AddParamRef.value?.open(data, index)
}
@ -143,11 +137,7 @@ function refresh(data: any, index: any) {
function submit() {
// console.log('submit: ', modelParamsForm.value)
ModelApi.updateModelParamsForm(
props.model.id,
modelParamsForm.value,
loading
).then((ok) => {
ModelApi.updateModelParamsForm(props.model.id, modelParamsForm.value, loading).then((ok) => {
MsgSuccess('模型参数保存成功')
close()
// emit('submit')
@ -157,6 +147,4 @@ function submit() {
defineExpose({ open, close })
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>