index.vue
3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<script setup lang="ts">
import { Card } from 'ant-design-vue'
import { computed, nextTick, reactive, unref, watch } from 'vue'
import type { ComponentExposeType } from '../PublicForm'
import { getFormSchemas } from './config'
import { ThingsModelForm } from '.'
import type { StructJSON } from '@/api/device/model'
import { BasicForm, useForm } from '@/components/Form'
import { DataTypeEnum } from '@/enums/datasource'
import { FormLabelAlignEnum, FormLayoutEnum } from '@/components/Form/src/enum'
const props = withDefaults(defineProps<{
value: Recordable
inputData?: StructJSON[]
required?: boolean
title?: string
transportType?: string
}>(), {
inputData: () => [],
required: true,
})
const thingsModelFormListElMap = reactive<Record<string, { el: InstanceType<typeof ThingsModelForm>; structJSON: StructJSON }>>({})
// const getLabelWidth = () => {
// return Math.max(...((props.inputData || [])?.map(item => item?.functionName?.length))) * 12
// }
const [register, formActionType] = useForm({
schemas: getFormSchemas({ structJSON: props.inputData || [], required: props.required, transportType: props.transportType }),
showActionButtonGroup: false,
// labelWidth: getLabelWidth() || 80,
labelAlign: FormLabelAlignEnum.RIGHT,
layout: FormLayoutEnum.HORIZONTAL,
})
const getStructFormItem = computed(() => {
const { inputData } = props
return inputData.filter(item => item.dataType?.type === DataTypeEnum.STRUCT)
})
const setFormElRef = (el: InstanceType<typeof ThingsModelForm>, structJSON: StructJSON) => {
const _structJSON = unref(getStructFormItem).find(item => item.identifier === structJSON.identifier)
if (_structJSON)
thingsModelFormListElMap[structJSON.identifier] = { el, structJSON }
}
const getFieldsValue = () => {
const basicValue = formActionType.getFieldsValue()
const structValue: Recordable = {}
for (const key of Object.keys(thingsModelFormListElMap)) {
const item = thingsModelFormListElMap[key]
const { el } = item
structValue[key] = el.getFieldsValue() || {}
}
return {
...basicValue,
...structValue,
}
}
const setFieldsValue = (value: Recordable) => {
return formActionType.setFieldsValue(value)
}
const validate = async () => {
await formActionType.validate()
for (const key of Object.keys(thingsModelFormListElMap))
await thingsModelFormListElMap[key].el.validate()
}
const updateSchema = (value: Recordable) => {
return formActionType.updateSchema(value)
}
watch(() => props.value,
async (value) => {
await nextTick()
formActionType.setFieldsValue(value || {})
},
{ immediate: true },
)
watch(
() => props.inputData,
(value) => {
if (value && value.length) {
const schemas = getFormSchemas({ structJSON: props.inputData || [], required: props.required, transportType: props.transportType })
formActionType.setProps({ schemas })
}
})
defineExpose<ComponentExposeType>({
getFieldsValue,
setFieldsValue,
validate,
updateSchema,
})
</script>
<template>
<Card class="!border-2 !border-dashed" :title="title">
<BasicForm class="things-model-form" @register="register">
<template v-for="item in getStructFormItem" #[item.identifier]="{ model, field }" :key="item.identifier">
<ThingsModelForm :ref="(el) => setFormElRef(el as InstanceType<typeof ThingsModelForm>, item) " v-model:value="model[field]" :input-data="(item.dataType?.specs as StructJSON[]) || []" :title="item.functionName" />
</template>
</BasicForm>
</Card>
</template>
<style lang="less" scoped>
.things-model-form {
:deep(.ant-input-number) {
width: 100%;
}
}
:deep(.ant-form-item-control){
margin-left: 6px;
}
</style>