fix: 添加JSON文本框

This commit is contained in:
shaohuzhang1 2024-10-24 19:06:50 +08:00 committed by shaohuzhang1
parent 823bd9f779
commit a0ad4c911c
5 changed files with 193 additions and 6 deletions

View File

@ -22,6 +22,7 @@ import type { Dict } from '@/api/type/common'
const damo_data: Array<FormField> = [
{ field: 'name', input_type: 'PasswordInput', label: '用戶名', required: false },
{ field: 'json_text', input_type: 'JsonInput', label: 'aa', required: false },
{
field: 'array_object_card_field',
input_type: 'ArrayObjectCard',

View File

@ -107,13 +107,23 @@ const errMsg = computed(() => {
? props.formfield.label + '不能为空'
: props.formfield.label.label + '不能为空'
})
/**
* 反序列化
* @param rule
*/
const to_rule = (rule: any) => {
if (rule.validator) {
let validator = (rule: any, value: string, callback: any) => {}
return { ...rule, validator }
}
return rule
}
/**
* 校验
*/
const rules = computed(() => {
return props_info.value.rules
? props_info.value.rules
? props_info.value.rules.map(to_rule)
: {
message: errMsg.value,
trigger: 'blur',

View File

@ -52,7 +52,8 @@ const props = withDefaults(
{ label: '滑块', value: 'SliderConstructor' },
{ label: '开关', value: 'SwitchInputConstructor' },
{ label: '单选框', value: 'SingleSelectConstructor' },
{ label: '日期', value: 'DatePickerConstructor' }
{ label: '日期', value: 'DatePickerConstructor' },
{ label: 'JSON文本框', value: 'JsonInputConstructor' }
]
}
)
@ -69,8 +70,8 @@ const form_data = ref<any>({
input_type: ''
})
const rules = {
label: [{ required: true, message: '参数 为必填属性' }],
field: [{ required: true, message: '显示名称 为必填属性' }],
label: [{ required: true, message: '显示名称 为必填属性' }],
field: [{ required: true, message: '参数 为必填属性' }],
required: [{ required: true, message: '是否必填 为必填属性' }],
input_type: [{ required: true, message: '组建类型 为必填属性' }]
}
@ -108,7 +109,10 @@ onMounted(() => {
const rander = (data: any) => {
form_data.value.required = data.required ? data.required : false
form_data.value.field = data.field
form_data.value.input_type = data.input_type + 'Constructor'
if (data.input_type) {
form_data.value.input_type = data.input_type + 'Constructor'
}
if (data.label && data.label.input_type === 'TooltipLabel') {
form_data.value.tooltip = data.label.attrs.tooltip
form_data.value.label = data.label.label

View File

@ -0,0 +1,71 @@
<template>
<el-form-item
label="默认值"
:required="formValue.required"
prop="default_value"
:rules="[default_value_rule]"
>
<JsonInput v-model="formValue.default_value"> </JsonInput>
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onMounted } from 'vue'
import JsonInput from '@/components/dynamics-form/items/JsonInput.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: 'JsonInput',
attrs: {},
props_info: {
rules: [
{
required: true,
validator: `validator = (rule, value, callback) => {
try {
JSON.parse(value)
} catch (e) {
callback(new Error('JSON格式不正确'))
}
}`,
trigger: 'blur'
}
]
},
default_value: formValue.value.default_value
}
}
const default_value_rule = {
required: true,
validator: (rule: any, value: any, callback: any) => {
try {
JSON.parse(value)
} catch (e) {
callback(new Error('JSON格式不正确'))
}
return true
},
trigger: 'blur'
}
const rander = (form_data: any) => {
formValue.value.default_value = form_data.default_value
}
defineExpose({ getData, rander })
onMounted(() => {
formValue.value.default_value = '{}'
})
</script>
<style lang="scss"></style>

View File

@ -0,0 +1,101 @@
<template>
<div style="width: 100%" class="function-CodemirrorEditor">
<Codemirror
v-bind="$attrs"
ref="cmRef"
v-model="model_value"
:extensions="extensions"
:style="codemirrorStyle"
:tab-size="4"
:autofocus="true"
/>
<div class="function-CodemirrorEditor__format">
<el-button text type="info" @click="format" class="magnify">
<el-icon><DocumentChecked /></el-icon
></el-button>
</div>
<div class="function-CodemirrorEditor__footer">
<el-button text type="info" @click="openCodemirrorDialog" class="magnify">
<AppIcon iconName="app-magnify" style="font-size: 16px"></AppIcon>
</el-button>
</div>
<!-- Codemirror 弹出层 -->
<el-dialog v-model="dialogVisible" title="Python 代码" append-to-body>
<Codemirror
v-model="cloneContent"
:extensions="extensions"
:style="codemirrorStyle"
:tab-size="4"
:autofocus="true"
style="height: 300px !important; border: 1px solid #bbbfc4; border-radius: 4px"
/>
<template #footer>
<div class="dialog-footer mt-24">
<el-button type="primary" @click="submitDialog"> 确认</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { json, jsonParseLinter } from '@codemirror/lang-json'
import { oneDark } from '@codemirror/theme-one-dark'
import { Codemirror } from 'vue-codemirror'
import { linter } from '@codemirror/lint'
import { computed, ref } from 'vue'
const props = withDefaults(defineProps<{ modelValue?: string }>(), { modelValue: '{}' })
const emit = defineEmits(['update:modelValue'])
const model_value = computed({
get: () => {
if (!props.modelValue) {
emit('update:modelValue', '{}')
}
return props.modelValue
},
set: (v: string) => {
if (!v) {
emit('update:modelValue', '{}')
} else {
emit('update:modelValue', v)
}
}
})
const extensions = [json(), linter(jsonParseLinter()), oneDark]
const codemirrorStyle = {
height: '210px!important',
width: '100%'
}
//
const dialogVisible = ref<boolean>(false)
const cloneContent = ref<string>('')
const openCodemirrorDialog = () => {
cloneContent.value = model_value.value
dialogVisible.value = true
}
const format = () => {
try {
const json_str = JSON.parse(model_value.value)
model_value.value = JSON.stringify(json_str, null, 4)
} catch (e) {}
}
function submitDialog() {
model_value.value = cloneContent.value
dialogVisible.value = false
}
</script>
<style lang="scss">
.function-CodemirrorEditor__footer {
position: absolute;
bottom: 10px;
right: 10px;
}
.function-CodemirrorEditor {
position: relative;
}
.function-CodemirrorEditor__format {
position: absolute;
top: 10px;
right: 10px;
}
</style>