Commit 9594836d630aefdecae90db9513e9fceb59ad4b8
Merge branch 'feat/object-model-enums-type' into 'main_dev'
feat: 物模型新增枚举类型 See merge request yunteng/thingskit-front!1133
Showing
15 changed files
with
348 additions
and
40 deletions
@@ -7,6 +7,9 @@ export interface Specs { | @@ -7,6 +7,9 @@ export interface Specs { | ||
7 | unit: string; | 7 | unit: string; |
8 | unitName: string; | 8 | unitName: string; |
9 | 9 | ||
10 | + dataType?: string; | ||
11 | + name?: string; | ||
12 | + value?: string; | ||
10 | step: string; | 13 | step: string; |
11 | length: string; | 14 | length: string; |
12 | boolOpen: string; | 15 | boolOpen: string; |
@@ -20,6 +23,7 @@ export interface Specs { | @@ -20,6 +23,7 @@ export interface Specs { | ||
20 | export interface DataType { | 23 | export interface DataType { |
21 | type: DataTypeEnum; | 24 | type: DataTypeEnum; |
22 | specs?: Partial<Specs> | StructJSON[]; | 25 | specs?: Partial<Specs> | StructJSON[]; |
26 | + specsList?: Specs[]; | ||
23 | } | 27 | } |
24 | 28 | ||
25 | export interface StructJSON { | 29 | export interface StructJSON { |
@@ -42,6 +42,7 @@ import InputGroup from './components/InputGroup.vue'; | @@ -42,6 +42,7 @@ import InputGroup from './components/InputGroup.vue'; | ||
42 | import RegisterAddressInput from '/@/views/task/center/components/PollCommandInput/RegisterAddressInput.vue'; | 42 | import RegisterAddressInput from '/@/views/task/center/components/PollCommandInput/RegisterAddressInput.vue'; |
43 | import ExtendDesc from '/@/components/Form/src/externalCompns/components/ExtendDesc/index.vue'; | 43 | import ExtendDesc from '/@/components/Form/src/externalCompns/components/ExtendDesc/index.vue'; |
44 | import DeviceProfileForm from '/@/components/Form/src/externalCompns/components/DeviceProfileForm/index.vue'; | 44 | import DeviceProfileForm from '/@/components/Form/src/externalCompns/components/DeviceProfileForm/index.vue'; |
45 | +import EnumList from './externalCompns/components/StructForm/EnumList.vue'; | ||
45 | 46 | ||
46 | const componentMap = new Map<ComponentType, Component>(); | 47 | const componentMap = new Map<ComponentType, Component>(); |
47 | 48 | ||
@@ -90,6 +91,7 @@ componentMap.set('ApiSelectScrollLoad', ApiSelectScrollLoad); | @@ -90,6 +91,7 @@ componentMap.set('ApiSelectScrollLoad', ApiSelectScrollLoad); | ||
90 | componentMap.set('InputGroup', InputGroup); | 91 | componentMap.set('InputGroup', InputGroup); |
91 | componentMap.set('RegisterAddressInput', RegisterAddressInput); | 92 | componentMap.set('RegisterAddressInput', RegisterAddressInput); |
92 | componentMap.set('ExtendDesc', ExtendDesc); | 93 | componentMap.set('ExtendDesc', ExtendDesc); |
94 | +componentMap.set('EnumList', EnumList); | ||
93 | componentMap.set('DeviceProfileForm', DeviceProfileForm); | 95 | componentMap.set('DeviceProfileForm', DeviceProfileForm); |
94 | 96 | ||
95 | export function add(compName: ComponentType, component: Component) { | 97 | export function add(compName: ComponentType, component: Component) { |
1 | +import { FormSchema } from '/@/components/Table'; | ||
2 | + | ||
3 | +export enum FormFieldsEnum { | ||
4 | + VALUE = 'value', | ||
5 | + NAME = 'name', | ||
6 | + DATA_TYPE = 'dataType', | ||
7 | +} | ||
8 | + | ||
9 | +export const getFormSchemas = (): FormSchema[] => { | ||
10 | + return [ | ||
11 | + { | ||
12 | + field: FormFieldsEnum.VALUE, | ||
13 | + label: '', | ||
14 | + component: 'InputNumber', | ||
15 | + rules: [ | ||
16 | + { required: true, message: `支持整型,取值范围:-2147483648 ~ 2147483647`, type: 'number' }, | ||
17 | + ], | ||
18 | + componentProps: () => { | ||
19 | + return { | ||
20 | + placeholder: '编号如"0"', | ||
21 | + min: -2147483648, | ||
22 | + max: 2147483647, | ||
23 | + }; | ||
24 | + }, | ||
25 | + colProps: { | ||
26 | + span: 11, | ||
27 | + }, | ||
28 | + }, | ||
29 | + { | ||
30 | + field: 'division', | ||
31 | + label: '', | ||
32 | + component: 'Input', | ||
33 | + slot: 'division', | ||
34 | + colProps: { | ||
35 | + span: 1, | ||
36 | + }, | ||
37 | + }, | ||
38 | + { | ||
39 | + field: FormFieldsEnum.NAME, | ||
40 | + label: '', | ||
41 | + component: 'Input', | ||
42 | + rules: [{ required: true, message: `参数描述不能为空`, type: 'string' }], | ||
43 | + componentProps: () => { | ||
44 | + return { | ||
45 | + placeholder: '对该枚举项的描述', | ||
46 | + maxLength: 20, | ||
47 | + }; | ||
48 | + }, | ||
49 | + colProps: { | ||
50 | + span: 11, | ||
51 | + }, | ||
52 | + }, | ||
53 | + ]; | ||
54 | +}; |
1 | +<script setup lang="ts"> | ||
2 | + import { Button, Tooltip } from 'ant-design-vue'; | ||
3 | + import { nextTick, ref, unref, watch } from 'vue'; | ||
4 | + import { useForm, BasicForm } from '/@/components/Form'; | ||
5 | + import { Specs } from '/@/api/device/model/modelOfMatterModel'; | ||
6 | + import { Icon } from '/@/components/Icon'; | ||
7 | + import { getFormSchemas } from './EnumList.config'; | ||
8 | + import { FormActionType } from '../../../types/form'; | ||
9 | + import { buildUUID } from '/@/utils/uuid'; | ||
10 | + import { DataTypeEnum } from '/@/enums/objectModelEnum'; | ||
11 | + | ||
12 | + const props = defineProps<{ disabled?: boolean; value?: Specs[] }>(); | ||
13 | + | ||
14 | + interface EnumElItemType { | ||
15 | + uuid: string; | ||
16 | + formActionType?: FormActionType; | ||
17 | + dataSource?: Recordable; | ||
18 | + } | ||
19 | + | ||
20 | + const [registerForm] = useForm({ | ||
21 | + schemas: getFormSchemas(), | ||
22 | + showActionButtonGroup: false, | ||
23 | + layout: 'inline', | ||
24 | + }); | ||
25 | + | ||
26 | + const enumsListElRef = ref<EnumElItemType[]>([{ uuid: buildUUID() }]); | ||
27 | + | ||
28 | + const setFormActionType = (item: EnumElItemType, el: any) => { | ||
29 | + item.formActionType = el as unknown as FormActionType; | ||
30 | + }; | ||
31 | + | ||
32 | + const validate = async () => { | ||
33 | + for (const enumElItem of unref(enumsListElRef)) { | ||
34 | + await enumElItem.formActionType?.validate?.(); | ||
35 | + } | ||
36 | + }; | ||
37 | + | ||
38 | + const getFieldsValue = () => { | ||
39 | + return unref(enumsListElRef).map( | ||
40 | + (item) => | ||
41 | + ({ | ||
42 | + ...(item.formActionType?.getFieldsValue?.() || {}), | ||
43 | + dataType: DataTypeEnum.ENUM, | ||
44 | + } as Specs) | ||
45 | + ); | ||
46 | + }; | ||
47 | + | ||
48 | + const setFieldsValue = (spaceList: Specs[]) => { | ||
49 | + enumsListElRef.value = spaceList.map((item) => ({ uuid: buildUUID(), dataSource: item })); | ||
50 | + | ||
51 | + nextTick(() => { | ||
52 | + unref(enumsListElRef).forEach((item) => | ||
53 | + item.formActionType?.setFieldsValue?.(item.dataSource) | ||
54 | + ); | ||
55 | + }); | ||
56 | + }; | ||
57 | + | ||
58 | + const handleDeleteEnums = (item: EnumElItemType) => { | ||
59 | + const index = unref(enumsListElRef).findIndex((temp) => item.uuid === temp.uuid); | ||
60 | + | ||
61 | + ~index && enumsListElRef.value.splice(index, 1); | ||
62 | + }; | ||
63 | + | ||
64 | + const handleAddEnums = () => { | ||
65 | + unref(enumsListElRef).push({ uuid: buildUUID() }); | ||
66 | + }; | ||
67 | + | ||
68 | + watch( | ||
69 | + () => props.value, | ||
70 | + (target) => { | ||
71 | + setFieldsValue(target || [{} as Specs]); | ||
72 | + }, | ||
73 | + { | ||
74 | + immediate: true, | ||
75 | + } | ||
76 | + ); | ||
77 | + | ||
78 | + defineExpose({ | ||
79 | + validate, | ||
80 | + getFieldsValue, | ||
81 | + setFieldsValue, | ||
82 | + }); | ||
83 | +</script> | ||
84 | + | ||
85 | +<template> | ||
86 | + <section class="w-full"> | ||
87 | + <header class="flex h-8 items-center"> | ||
88 | + <div class="w-1/2"> | ||
89 | + <span>参考值</span> | ||
90 | + <Tooltip title="支持整型,取值范围:-2147483648 ~ 2147483647"> | ||
91 | + <Icon icon="ant-design:question-circle-outlined" class="cursor-pointer ml-1" /> | ||
92 | + </Tooltip> | ||
93 | + </div> | ||
94 | + <div class="w-1/2"> | ||
95 | + <span>参考描述</span> | ||
96 | + <Tooltip | ||
97 | + title="支持中文、英文大小写、日文、数字、下划线和短划线,必须以中文、英文或数字开头,不超过20个字符" | ||
98 | + > | ||
99 | + <Icon icon="ant-design:question-circle-outlined" class="cursor-pointer ml-1" /> | ||
100 | + </Tooltip> | ||
101 | + </div> | ||
102 | + </header> | ||
103 | + <main class="w-full"> | ||
104 | + <section class="w-full flex" v-for="item in enumsListElRef" :key="item.uuid"> | ||
105 | + <BasicForm | ||
106 | + :ref="(el) => setFormActionType(item, el)" | ||
107 | + @register="registerForm" | ||
108 | + class="enums-form" | ||
109 | + :disabled="disabled" | ||
110 | + > | ||
111 | + <template #division> | ||
112 | + <div>~</div> | ||
113 | + </template> | ||
114 | + </BasicForm> | ||
115 | + <Button | ||
116 | + type="link" | ||
117 | + class="relative -left-6" | ||
118 | + :disabled="disabled" | ||
119 | + @click="handleDeleteEnums(item)" | ||
120 | + > | ||
121 | + 删除 | ||
122 | + </Button> | ||
123 | + </section> | ||
124 | + </main> | ||
125 | + <Button type="link" @click="handleAddEnums" :disabled="disabled">+添加枚举项</Button> | ||
126 | + </section> | ||
127 | +</template> | ||
128 | + | ||
129 | +<style scoped lang="less"> | ||
130 | + .enums-form { | ||
131 | + @apply w-full; | ||
132 | + | ||
133 | + > :deep(.ant-row) { | ||
134 | + @apply w-full; | ||
135 | + | ||
136 | + .ant-input-number { | ||
137 | + width: 100%; | ||
138 | + } | ||
139 | + } | ||
140 | + } | ||
141 | +</style> |
@@ -14,6 +14,8 @@ | @@ -14,6 +14,8 @@ | ||
14 | import { DataType, StructJSON } from '/@/api/device/model/modelOfMatterModel'; | 14 | import { DataType, StructJSON } from '/@/api/device/model/modelOfMatterModel'; |
15 | import { isArray } from '/@/utils/is'; | 15 | import { isArray } from '/@/utils/is'; |
16 | import { useMessage } from '/@/hooks/web/useMessage'; | 16 | import { useMessage } from '/@/hooks/web/useMessage'; |
17 | + import EnumList from './EnumList.vue'; | ||
18 | + import { DataTypeEnum } from '/@/enums/objectModelEnum'; | ||
17 | 19 | ||
18 | const modalReceiveRecord = ref<OpenModalParams>({ | 20 | const modalReceiveRecord = ref<OpenModalParams>({ |
19 | mode: OpenModalMode.CREATE, | 21 | mode: OpenModalMode.CREATE, |
@@ -26,6 +28,8 @@ | @@ -26,6 +28,8 @@ | ||
26 | hiddenAccessMode: boolean; | 28 | hiddenAccessMode: boolean; |
27 | }>(); | 29 | }>(); |
28 | 30 | ||
31 | + const enumListRef = ref<InstanceType<typeof EnumList>>(); | ||
32 | + | ||
29 | const emit = defineEmits(['register', 'submit']); | 33 | const emit = defineEmits(['register', 'submit']); |
30 | 34 | ||
31 | const { createMessage } = useMessage(); | 35 | const { createMessage } = useMessage(); |
@@ -53,13 +57,14 @@ | @@ -53,13 +57,14 @@ | ||
53 | modalReceiveRecord.value = record; | 57 | modalReceiveRecord.value = record; |
54 | const data = record.record || {}; | 58 | const data = record.record || {}; |
55 | const { dataType = {} } = data! as StructJSON; | 59 | const { dataType = {} } = data! as StructJSON; |
56 | - const { specs = {}, type } = dataType as DataType; | 60 | + const { specs = {}, type, specsList } = dataType as DataType; |
57 | 61 | ||
58 | if (record.record) { | 62 | if (record.record) { |
59 | const value = { | 63 | const value = { |
60 | type, | 64 | type, |
61 | ...data, | 65 | ...data, |
62 | ...(isArray(specs) ? { specs } : { ...specs }), | 66 | ...(isArray(specs) ? { specs } : { ...specs }), |
67 | + enumList: type === DataTypeEnum.ENUM ? specsList : [], | ||
63 | }; | 68 | }; |
64 | 69 | ||
65 | setFieldsValue(value); | 70 | setFieldsValue(value); |
@@ -74,7 +79,8 @@ | @@ -74,7 +79,8 @@ | ||
74 | const handleSubmit = async () => { | 79 | const handleSubmit = async () => { |
75 | try { | 80 | try { |
76 | const _value = await validate(); | 81 | const _value = await validate(); |
77 | - let structJSON = transfromToStructJSON(_value); | 82 | + await unref(enumListRef)?.validate?.(); |
83 | + let structJSON = transfromToStructJSON(_value, unref(enumListRef)?.getFieldsValue?.() || []); | ||
78 | const value = { | 84 | const value = { |
79 | ...structJSON, | 85 | ...structJSON, |
80 | ...(unref(modalReceiveRecord)?.record?.id | 86 | ...(unref(modalReceiveRecord)?.record?.id |
@@ -104,7 +110,11 @@ | @@ -104,7 +110,11 @@ | ||
104 | destroy-on-close | 110 | destroy-on-close |
105 | :show-ok-btn="!$props.disabled" | 111 | :show-ok-btn="!$props.disabled" |
106 | > | 112 | > |
107 | - <BasicForm @register="register" :schemas="getFormSchemas" /> | 113 | + <BasicForm @register="register" :schemas="getFormSchemas"> |
114 | + <template #EnumList="{ field, model }"> | ||
115 | + <EnumList ref="enumListRef" :value="model[field]" :disabled="disabled" /> | ||
116 | + </template> | ||
117 | + </BasicForm> | ||
108 | </BasicModal> | 118 | </BasicModal> |
109 | </template> | 119 | </template> |
110 | 120 |
@@ -37,7 +37,7 @@ const validateExcludeComma = (field: string, errorName: string): Rule[] => { | @@ -37,7 +37,7 @@ const validateExcludeComma = (field: string, errorName: string): Rule[] => { | ||
37 | validator: () => { | 37 | validator: () => { |
38 | const reg = /[,,]+/; | 38 | const reg = /[,,]+/; |
39 | if (reg.test(field)) { | 39 | if (reg.test(field)) { |
40 | - return Promise.reject(errorName); | 40 | + return Promise.reject(`${errorName}不能包含逗号`); |
41 | } | 41 | } |
42 | return Promise.resolve(); | 42 | return Promise.resolve(); |
43 | }, | 43 | }, |
@@ -64,7 +64,10 @@ export const formSchemas = ({ | @@ -64,7 +64,10 @@ export const formSchemas = ({ | ||
64 | placeholder: '请输入功能名称', | 64 | placeholder: '请输入功能名称', |
65 | }, | 65 | }, |
66 | dynamicRules: ({ values }) => { | 66 | dynamicRules: ({ values }) => { |
67 | - return validateExcludeComma(values[FormField.FUNCTION_NAME], '功能名称不能包含逗号'); | 67 | + return [ |
68 | + { required: true, message: '请输入功能名称' }, | ||
69 | + ...validateExcludeComma(values[FormField.FUNCTION_NAME], '功能名称'), | ||
70 | + ]; | ||
68 | }, | 71 | }, |
69 | }, | 72 | }, |
70 | { | 73 | { |
@@ -80,7 +83,10 @@ export const formSchemas = ({ | @@ -80,7 +83,10 @@ export const formSchemas = ({ | ||
80 | placeholder: '请输入标识符', | 83 | placeholder: '请输入标识符', |
81 | }, | 84 | }, |
82 | dynamicRules: ({ values }) => { | 85 | dynamicRules: ({ values }) => { |
83 | - return validateExcludeComma(values[FormField.IDENTIFIER], '标识符不能包含逗号'); | 86 | + return [ |
87 | + { required: true, message: '请输入标识符' }, | ||
88 | + ...validateExcludeComma(values[FormField.IDENTIFIER], '标识符'), | ||
89 | + ]; | ||
84 | }, | 90 | }, |
85 | }, | 91 | }, |
86 | { | 92 | { |
@@ -127,6 +133,16 @@ export const formSchemas = ({ | @@ -127,6 +133,16 @@ export const formSchemas = ({ | ||
127 | }, | 133 | }, |
128 | }, | 134 | }, |
129 | { | 135 | { |
136 | + field: FormField.ENUM_LIST, | ||
137 | + component: 'Input', | ||
138 | + label: '枚举', | ||
139 | + ifShow: ({ values }) => values[FormField.TYPE] === DataTypeEnum.ENUM, | ||
140 | + slot: 'EnumList', | ||
141 | + colProps: { | ||
142 | + span: 24, | ||
143 | + }, | ||
144 | + }, | ||
145 | + { | ||
130 | field: FormField.VALUE_RANGE, | 146 | field: FormField.VALUE_RANGE, |
131 | label: '取值范围', | 147 | label: '取值范围', |
132 | component: 'CustomMinMaxInput', | 148 | component: 'CustomMinMaxInput', |
1 | import { cloneDeep } from 'lodash-es'; | 1 | import { cloneDeep } from 'lodash-es'; |
2 | import { StructFormValue } from './type'; | 2 | import { StructFormValue } from './type'; |
3 | -import { DataType, ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel'; | 3 | +import { |
4 | + DataType, | ||
5 | + ModelOfMatterParams, | ||
6 | + Specs, | ||
7 | + StructJSON, | ||
8 | +} from '/@/api/device/model/modelOfMatterModel'; | ||
4 | import { isArray } from '/@/utils/is'; | 9 | import { isArray } from '/@/utils/is'; |
5 | import { DataTypeEnum } from '/@/enums/objectModelEnum'; | 10 | import { DataTypeEnum } from '/@/enums/objectModelEnum'; |
6 | 11 | ||
7 | -export function transfromToStructJSON(value: StructFormValue): StructJSON { | 12 | +export function transfromToStructJSON(value: StructFormValue, enumList: Specs[] = []): StructJSON { |
8 | const { | 13 | const { |
9 | type, | 14 | type, |
10 | valueRange, | 15 | valueRange, |
@@ -55,6 +60,13 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { | @@ -55,6 +60,13 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { | ||
55 | }; | 60 | }; |
56 | break; | 61 | break; |
57 | 62 | ||
63 | + case DataTypeEnum.ENUM: | ||
64 | + dataType = { | ||
65 | + type, | ||
66 | + specsList: enumList, | ||
67 | + }; | ||
68 | + break; | ||
69 | + | ||
58 | case DataTypeEnum.STRUCT: | 70 | case DataTypeEnum.STRUCT: |
59 | dataType = { | 71 | dataType = { |
60 | type, | 72 | type, |
@@ -62,12 +74,13 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { | @@ -62,12 +74,13 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { | ||
62 | }; | 74 | }; |
63 | break; | 75 | break; |
64 | } | 76 | } |
65 | - return { ...basic, dataType }; | 77 | + return { ...basic, dataType } as StructJSON; |
66 | } | 78 | } |
67 | 79 | ||
68 | export const excludeIdInStructJSON = (struct: DataType) => { | 80 | export const excludeIdInStructJSON = (struct: DataType) => { |
69 | const _value = cloneDeep(struct); | 81 | const _value = cloneDeep(struct); |
70 | const { specs } = _value; | 82 | const { specs } = _value; |
83 | + if (!specs) return _value; | ||
71 | const list = [specs]; | 84 | const list = [specs]; |
72 | 85 | ||
73 | while (list.length) { | 86 | while (list.length) { |
@@ -77,10 +90,10 @@ export const excludeIdInStructJSON = (struct: DataType) => { | @@ -77,10 +90,10 @@ export const excludeIdInStructJSON = (struct: DataType) => { | ||
77 | if (temp.dataType?.specs) { | 90 | if (temp.dataType?.specs) { |
78 | list.push(temp.dataType.specs); | 91 | list.push(temp.dataType.specs); |
79 | } | 92 | } |
80 | - Reflect.deleteProperty(temp, 'id'); | 93 | + Reflect.has(temp, 'id') && Reflect.deleteProperty(temp, 'id'); |
81 | }); | 94 | }); |
82 | } else { | 95 | } else { |
83 | - Reflect.deleteProperty(item as Recordable, 'id'); | 96 | + Reflect.has(item as Recordable, 'id') && Reflect.deleteProperty(item as Recordable, 'id'); |
84 | } | 97 | } |
85 | list.shift(); | 98 | list.shift(); |
86 | } | 99 | } |
@@ -101,6 +101,26 @@ export const getFormSchemas = ({ | @@ -101,6 +101,26 @@ export const getFormSchemas = ({ | ||
101 | }; | 101 | }; |
102 | }; | 102 | }; |
103 | 103 | ||
104 | + const createEnumsSelect = ({ identifier, functionName, dataType }: StructJSON): FormSchema => { | ||
105 | + const { specsList } = dataType || {}; | ||
106 | + return { | ||
107 | + field: identifier, | ||
108 | + label: functionName!, | ||
109 | + component: 'Select', | ||
110 | + rules: [ | ||
111 | + { | ||
112 | + required, | ||
113 | + message: `${functionName}是必填项`, | ||
114 | + type: 'number', | ||
115 | + }, | ||
116 | + ], | ||
117 | + componentProps: { | ||
118 | + options: specsList?.map((item) => ({ label: item.name, value: item.value })), | ||
119 | + placeholder: `请选择${functionName}`, | ||
120 | + }, | ||
121 | + }; | ||
122 | + }; | ||
123 | + | ||
104 | const createStructJson = ({ identifier, functionName, dataType }: StructJSON): FormSchema => { | 124 | const createStructJson = ({ identifier, functionName, dataType }: StructJSON): FormSchema => { |
105 | return { | 125 | return { |
106 | field: identifier, | 126 | field: identifier, |
@@ -140,6 +160,7 @@ export const getFormSchemas = ({ | @@ -140,6 +160,7 @@ export const getFormSchemas = ({ | ||
140 | } | 160 | } |
141 | 161 | ||
142 | if (type === DataTypeEnum.BOOL) schemas.push(createSelect(item)); | 162 | if (type === DataTypeEnum.BOOL) schemas.push(createSelect(item)); |
163 | + else if (type === DataTypeEnum.ENUM) schemas.push(createEnumsSelect(item)); | ||
143 | else if (type === DataTypeEnum.NUMBER_INT) schemas.push(createInputNumber(item)); | 164 | else if (type === DataTypeEnum.NUMBER_INT) schemas.push(createInputNumber(item)); |
144 | else if (type === DataTypeEnum.NUMBER_DOUBLE) schemas.push(createInputNumber(item)); | 165 | else if (type === DataTypeEnum.NUMBER_DOUBLE) schemas.push(createInputNumber(item)); |
145 | else if (type === DataTypeEnum.STRING) schemas.push(createInput(item)); | 166 | else if (type === DataTypeEnum.STRING) schemas.push(createInput(item)); |
@@ -144,4 +144,5 @@ export type ComponentType = | @@ -144,4 +144,5 @@ export type ComponentType = | ||
144 | | 'TimeRangePicker' | 144 | | 'TimeRangePicker' |
145 | | 'TriggerDurationInput' | 145 | | 'TriggerDurationInput' |
146 | | 'AlarmProfileSelect' | 146 | | 'AlarmProfileSelect' |
147 | - | 'LockControlGroup'; | 147 | + | 'LockControlGroup' |
148 | + | 'EnumList'; |
@@ -27,16 +27,26 @@ export interface SocketInfoDataSourceItemType extends BaseAdditionalInfo { | @@ -27,16 +27,26 @@ export interface SocketInfoDataSourceItemType extends BaseAdditionalInfo { | ||
27 | expand?: boolean; | 27 | expand?: boolean; |
28 | showHistoryDataButton?: boolean; | 28 | showHistoryDataButton?: boolean; |
29 | rawValue?: any; | 29 | rawValue?: any; |
30 | + enum?: Record<string, string>; | ||
30 | } | 31 | } |
31 | 32 | ||
32 | export function buildTableDataSourceByObjectModel( | 33 | export function buildTableDataSourceByObjectModel( |
33 | models: DeviceModelOfMatterAttrs[] | 34 | models: DeviceModelOfMatterAttrs[] |
34 | ): SocketInfoDataSourceItemType[] { | 35 | ): SocketInfoDataSourceItemType[] { |
35 | function getAdditionalInfoByDataType(dataType?: DataType) { | 36 | function getAdditionalInfoByDataType(dataType?: DataType) { |
36 | - const { specs } = dataType || {}; | 37 | + const { specs, specsList, type } = dataType || {}; |
37 | if (isArray(specs)) return {}; | 38 | if (isArray(specs)) return {}; |
38 | const { unit, boolClose, boolOpen, unitName } = (specs as Partial<Specs>) || {}; | 39 | const { unit, boolClose, boolOpen, unitName } = (specs as Partial<Specs>) || {}; |
39 | - return { unit, boolClose, boolOpen, unitName }; | 40 | + const result = { unit, boolClose, boolOpen, unitName }; |
41 | + if (type == DataTypeEnum.ENUM && specsList && specsList.length) { | ||
42 | + Reflect.set( | ||
43 | + result, | ||
44 | + 'enum', | ||
45 | + specsList.reduce((prev, next) => ({ ...prev, [next.value!]: next.name }), {}) | ||
46 | + ); | ||
47 | + } | ||
48 | + | ||
49 | + return result; | ||
40 | } | 50 | } |
41 | 51 | ||
42 | return models.map((item) => { | 52 | return models.map((item) => { |
@@ -72,7 +82,6 @@ export function buildTableDataSourceByObjectModel( | @@ -72,7 +82,6 @@ export function buildTableDataSourceByObjectModel( | ||
72 | } else { | 82 | } else { |
73 | Object.assign(res, getAdditionalInfoByDataType(dataType)); | 83 | Object.assign(res, getAdditionalInfoByDataType(dataType)); |
74 | } | 84 | } |
75 | - | ||
76 | return res; | 85 | return res; |
77 | }); | 86 | }); |
78 | } | 87 | } |
@@ -284,13 +284,15 @@ | @@ -284,13 +284,15 @@ | ||
284 | }); | 284 | }); |
285 | 285 | ||
286 | const formatValue = (item: SocketInfoDataSourceItemType) => { | 286 | const formatValue = (item: SocketInfoDataSourceItemType) => { |
287 | - return item.type === DataTypeEnum.BOOL | ||
288 | - ? !isNullOrUnDef(item.value) | ||
289 | - ? !!Number(item.value) | ||
290 | - ? item.boolOpen | ||
291 | - : item.boolClose | ||
292 | - : '--' | ||
293 | - : (item.value as string) || '--'; | 287 | + if (isNullOrUnDef(item)) return '--'; |
288 | + switch (item.type) { | ||
289 | + case DataTypeEnum.BOOL: | ||
290 | + return !!Number(item.value) ? item.boolOpen : item.boolClose; | ||
291 | + case DataTypeEnum.ENUM: | ||
292 | + return item.enum?.[item.value as string]; | ||
293 | + default: | ||
294 | + return item.value || '--'; | ||
295 | + } | ||
294 | }; | 296 | }; |
295 | 297 | ||
296 | const [register, { openModal: openSendCommandModal }] = useModal(); | 298 | const [register, { openModal: openSendCommandModal }] = useModal(); |
@@ -81,7 +81,7 @@ export const useGenDynamicForm = () => { | @@ -81,7 +81,7 @@ export const useGenDynamicForm = () => { | ||
81 | type: 'string', | 81 | type: 'string', |
82 | trigger: 'change', | 82 | trigger: 'change', |
83 | validator: (_rule, value) => { | 83 | validator: (_rule, value) => { |
84 | - if (value.length > length) { | 84 | + if (value?.length > length) { |
85 | return Promise.reject(`${functionName}数据长度应该小于${length}`); | 85 | return Promise.reject(`${functionName}数据长度应该小于${length}`); |
86 | } | 86 | } |
87 | return Promise.resolve(value); | 87 | return Promise.resolve(value); |
@@ -117,6 +117,24 @@ export const useGenDynamicForm = () => { | @@ -117,6 +117,24 @@ export const useGenDynamicForm = () => { | ||
117 | }; | 117 | }; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | + const createEnumSelect = ({ | ||
121 | + identifier, | ||
122 | + functionName, | ||
123 | + dataType, | ||
124 | + }: BasicCreateFormParams): FormSchema => { | ||
125 | + const { specsList } = dataType; | ||
126 | + return { | ||
127 | + field: identifier, | ||
128 | + label: functionName, | ||
129 | + component: 'Select', | ||
130 | + componentProps: { | ||
131 | + options: specsList?.map((item) => ({ label: item.name, value: item.value })), | ||
132 | + placeholder: `请选择${functionName}`, | ||
133 | + getPopupContainer: () => document.body, | ||
134 | + }, | ||
135 | + }; | ||
136 | + }; | ||
137 | + | ||
120 | const createInputJson = ({ identifier, functionName }: BasicCreateFormParams): FormSchema => { | 138 | const createInputJson = ({ identifier, functionName }: BasicCreateFormParams): FormSchema => { |
121 | return { | 139 | return { |
122 | field: identifier, | 140 | field: identifier, |
@@ -144,6 +162,7 @@ export const useGenDynamicForm = () => { | @@ -144,6 +162,7 @@ export const useGenDynamicForm = () => { | ||
144 | [DataTypeEnum.NUMBER_INT]: createInputNumber, | 162 | [DataTypeEnum.NUMBER_INT]: createInputNumber, |
145 | [DataTypeEnum.STRING]: createInput, | 163 | [DataTypeEnum.STRING]: createInput, |
146 | [DataTypeEnum.STRUCT]: createInputJson, | 164 | [DataTypeEnum.STRUCT]: createInputJson, |
165 | + [DataTypeEnum.ENUM]: createEnumSelect, | ||
147 | }; | 166 | }; |
148 | 167 | ||
149 | const fieldTypeMap = new Map<string, DataTypeEnum>(); | 168 | const fieldTypeMap = new Map<string, DataTypeEnum>(); |
1 | -<template> | ||
2 | - <BasicForm @register="register" /> | ||
3 | -</template> | ||
4 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
5 | import { BasicForm, useForm } from '/@/components/Form'; | 2 | import { BasicForm, useForm } from '/@/components/Form'; |
6 | import { DataType, ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; | 3 | import { DataType, ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; |
@@ -15,34 +12,38 @@ | @@ -15,34 +12,38 @@ | ||
15 | import { formSchemas } from '/@/components/Form/src/externalCompns/components/StructForm/config'; | 12 | import { formSchemas } from '/@/components/Form/src/externalCompns/components/StructForm/config'; |
16 | import { TransportTypeEnum } from '../../../../components/TransportDescript/const'; | 13 | import { TransportTypeEnum } from '../../../../components/TransportDescript/const'; |
17 | import { DataTypeEnum } from '/@/enums/objectModelEnum'; | 14 | import { DataTypeEnum } from '/@/enums/objectModelEnum'; |
15 | + import { ref, unref } from 'vue'; | ||
16 | + import EnumList from '/@/components/Form/src/externalCompns/components/StructForm/EnumList.vue'; | ||
18 | 17 | ||
19 | const props = defineProps<{ openModalMode: OpenModelMode; transportType?: string | undefined }>(); | 18 | const props = defineProps<{ openModalMode: OpenModelMode; transportType?: string | undefined }>(); |
20 | 19 | ||
21 | - const [register, { validate, resetFields, setFieldsValue, setProps }] = useForm({ | 20 | + const enumListRef = ref<InstanceType<typeof EnumList>>(); |
21 | + | ||
22 | + const [register, { validate, getFieldsValue, resetFields, setFieldsValue }] = useForm({ | ||
22 | labelWidth: 100, | 23 | labelWidth: 100, |
23 | schemas: formSchemas({ | 24 | schemas: formSchemas({ |
24 | hasStructForm: false, | 25 | hasStructForm: false, |
25 | hiddenAccessMode: false, | 26 | hiddenAccessMode: false, |
26 | isTcp: props.transportType === TransportTypeEnum.TCP, | 27 | isTcp: props.transportType === TransportTypeEnum.TCP, |
27 | }), | 28 | }), |
28 | - actionColOptions: { | ||
29 | - span: 14, | ||
30 | - }, | ||
31 | - showResetButton: false, | ||
32 | - submitOnReset: false, | ||
33 | showActionButtonGroup: false, | 29 | showActionButtonGroup: false, |
34 | }); | 30 | }); |
35 | 31 | ||
32 | + const disabled = ref(false); | ||
36 | const setDisable = (flag: boolean) => { | 33 | const setDisable = (flag: boolean) => { |
37 | - setProps({ disabled: flag }); | 34 | + disabled.value = flag; |
38 | }; | 35 | }; |
39 | 36 | ||
40 | async function getFormData(): Promise<Partial<ModelOfMatterParams>> { | 37 | async function getFormData(): Promise<Partial<ModelOfMatterParams>> { |
41 | - const _values = (await validate()) as StructFormValue; | ||
42 | - if (!_values) return {}; | 38 | + await validate(); |
39 | + await unref(enumListRef)?.validate?.(); | ||
40 | + | ||
41 | + const _values = getFieldsValue() as StructFormValue; | ||
43 | const { functionName, remark, identifier, accessMode } = _values; | 42 | const { functionName, remark, identifier, accessMode } = _values; |
44 | - const structJSON = transfromToStructJSON(_values); | 43 | + const structJSON = transfromToStructJSON(_values, unref(enumListRef)?.getFieldsValue?.()); |
44 | + | ||
45 | const dataType = excludeIdInStructJSON(structJSON.dataType!); | 45 | const dataType = excludeIdInStructJSON(structJSON.dataType!); |
46 | + | ||
46 | const value = { | 47 | const value = { |
47 | functionName, | 48 | functionName, |
48 | functionType: FunctionType.PROPERTIES, | 49 | functionType: FunctionType.PROPERTIES, |
@@ -54,6 +55,7 @@ | @@ -54,6 +55,7 @@ | ||
54 | dataType: dataType, | 55 | dataType: dataType, |
55 | }, | 56 | }, |
56 | } as ModelOfMatterParams; | 57 | } as ModelOfMatterParams; |
58 | + | ||
57 | return value; | 59 | return value; |
58 | } | 60 | } |
59 | 61 | ||
@@ -63,18 +65,21 @@ | @@ -63,18 +65,21 @@ | ||
63 | 65 | ||
64 | const setFormData = (record: ModelOfMatterParams) => { | 66 | const setFormData = (record: ModelOfMatterParams) => { |
65 | const { functionJson } = record; | 67 | const { functionJson } = record; |
66 | - const { dataType = {} } = functionJson!; | 68 | + const { dataType } = functionJson!; |
67 | 69 | ||
68 | - const { specs } = dataType! as DataType; | 70 | + const { specs } = (dataType! || {}) as DataType; |
69 | 71 | ||
70 | const value = { | 72 | const value = { |
71 | ...record, | 73 | ...record, |
72 | ...functionJson, | 74 | ...functionJson, |
73 | ...dataType, | 75 | ...dataType, |
74 | ...(isArray(specs) ? specs : { ...specs }), | 76 | ...(isArray(specs) ? specs : { ...specs }), |
75 | - hasStructForm: (record?.functionJson?.dataType as DataType)?.type === DataTypeEnum.STRUCT, | 77 | + hasStructForm: (dataType as DataType)?.type === DataTypeEnum.STRUCT, |
78 | + enumList: | ||
79 | + (dataType as DataType)?.type === DataTypeEnum.ENUM | ||
80 | + ? unref((dataType as DataType).specsList) | ||
81 | + : [], | ||
76 | }; | 82 | }; |
77 | - | ||
78 | setFieldsValue(value); | 83 | setFieldsValue(value); |
79 | }; | 84 | }; |
80 | 85 | ||
@@ -85,4 +90,13 @@ | @@ -85,4 +90,13 @@ | ||
85 | setDisable, | 90 | setDisable, |
86 | }); | 91 | }); |
87 | </script> | 92 | </script> |
93 | + | ||
94 | +<template> | ||
95 | + <BasicForm @register="register" :disabled="disabled"> | ||
96 | + <template #EnumList="{ field, model }"> | ||
97 | + <EnumList ref="enumListRef" :value="model[field]" :disabled="disabled" /> | ||
98 | + </template> | ||
99 | + </BasicForm> | ||
100 | +</template> | ||
101 | + | ||
88 | <style lang="less" scoped></style> | 102 | <style lang="less" scoped></style> |
@@ -28,6 +28,7 @@ export enum FormField { | @@ -28,6 +28,7 @@ export enum FormField { | ||
28 | REGISTER_ADDRESS = 'registerAddress', | 28 | REGISTER_ADDRESS = 'registerAddress', |
29 | EXTENSION_DESC = 'extensionDesc', | 29 | EXTENSION_DESC = 'extensionDesc', |
30 | STRUCT = 'struct', | 30 | STRUCT = 'struct', |
31 | + ENUM_LIST = 'enumList', | ||
31 | 32 | ||
32 | HAS_STRUCT_FROM = 'hasStructForm', | 33 | HAS_STRUCT_FROM = 'hasStructForm', |
33 | } | 34 | } |