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 | 7 | unit: string; |
| 8 | 8 | unitName: string; |
| 9 | 9 | |
| 10 | + dataType?: string; | |
| 11 | + name?: string; | |
| 12 | + value?: string; | |
| 10 | 13 | step: string; |
| 11 | 14 | length: string; |
| 12 | 15 | boolOpen: string; |
| ... | ... | @@ -20,6 +23,7 @@ export interface Specs { |
| 20 | 23 | export interface DataType { |
| 21 | 24 | type: DataTypeEnum; |
| 22 | 25 | specs?: Partial<Specs> | StructJSON[]; |
| 26 | + specsList?: Specs[]; | |
| 23 | 27 | } |
| 24 | 28 | |
| 25 | 29 | export interface StructJSON { | ... | ... |
| ... | ... | @@ -42,6 +42,7 @@ import InputGroup from './components/InputGroup.vue'; |
| 42 | 42 | import RegisterAddressInput from '/@/views/task/center/components/PollCommandInput/RegisterAddressInput.vue'; |
| 43 | 43 | import ExtendDesc from '/@/components/Form/src/externalCompns/components/ExtendDesc/index.vue'; |
| 44 | 44 | import DeviceProfileForm from '/@/components/Form/src/externalCompns/components/DeviceProfileForm/index.vue'; |
| 45 | +import EnumList from './externalCompns/components/StructForm/EnumList.vue'; | |
| 45 | 46 | |
| 46 | 47 | const componentMap = new Map<ComponentType, Component>(); |
| 47 | 48 | |
| ... | ... | @@ -90,6 +91,7 @@ componentMap.set('ApiSelectScrollLoad', ApiSelectScrollLoad); |
| 90 | 91 | componentMap.set('InputGroup', InputGroup); |
| 91 | 92 | componentMap.set('RegisterAddressInput', RegisterAddressInput); |
| 92 | 93 | componentMap.set('ExtendDesc', ExtendDesc); |
| 94 | +componentMap.set('EnumList', EnumList); | |
| 93 | 95 | componentMap.set('DeviceProfileForm', DeviceProfileForm); |
| 94 | 96 | |
| 95 | 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 | 14 | import { DataType, StructJSON } from '/@/api/device/model/modelOfMatterModel'; |
| 15 | 15 | import { isArray } from '/@/utils/is'; |
| 16 | 16 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 17 | + import EnumList from './EnumList.vue'; | |
| 18 | + import { DataTypeEnum } from '/@/enums/objectModelEnum'; | |
| 17 | 19 | |
| 18 | 20 | const modalReceiveRecord = ref<OpenModalParams>({ |
| 19 | 21 | mode: OpenModalMode.CREATE, |
| ... | ... | @@ -26,6 +28,8 @@ |
| 26 | 28 | hiddenAccessMode: boolean; |
| 27 | 29 | }>(); |
| 28 | 30 | |
| 31 | + const enumListRef = ref<InstanceType<typeof EnumList>>(); | |
| 32 | + | |
| 29 | 33 | const emit = defineEmits(['register', 'submit']); |
| 30 | 34 | |
| 31 | 35 | const { createMessage } = useMessage(); |
| ... | ... | @@ -53,13 +57,14 @@ |
| 53 | 57 | modalReceiveRecord.value = record; |
| 54 | 58 | const data = record.record || {}; |
| 55 | 59 | const { dataType = {} } = data! as StructJSON; |
| 56 | - const { specs = {}, type } = dataType as DataType; | |
| 60 | + const { specs = {}, type, specsList } = dataType as DataType; | |
| 57 | 61 | |
| 58 | 62 | if (record.record) { |
| 59 | 63 | const value = { |
| 60 | 64 | type, |
| 61 | 65 | ...data, |
| 62 | 66 | ...(isArray(specs) ? { specs } : { ...specs }), |
| 67 | + enumList: type === DataTypeEnum.ENUM ? specsList : [], | |
| 63 | 68 | }; |
| 64 | 69 | |
| 65 | 70 | setFieldsValue(value); |
| ... | ... | @@ -74,7 +79,8 @@ |
| 74 | 79 | const handleSubmit = async () => { |
| 75 | 80 | try { |
| 76 | 81 | const _value = await validate(); |
| 77 | - let structJSON = transfromToStructJSON(_value); | |
| 82 | + await unref(enumListRef)?.validate?.(); | |
| 83 | + let structJSON = transfromToStructJSON(_value, unref(enumListRef)?.getFieldsValue?.() || []); | |
| 78 | 84 | const value = { |
| 79 | 85 | ...structJSON, |
| 80 | 86 | ...(unref(modalReceiveRecord)?.record?.id |
| ... | ... | @@ -104,7 +110,11 @@ |
| 104 | 110 | destroy-on-close |
| 105 | 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 | 118 | </BasicModal> |
| 109 | 119 | </template> |
| 110 | 120 | ... | ... |
| ... | ... | @@ -37,7 +37,7 @@ const validateExcludeComma = (field: string, errorName: string): Rule[] => { |
| 37 | 37 | validator: () => { |
| 38 | 38 | const reg = /[,,]+/; |
| 39 | 39 | if (reg.test(field)) { |
| 40 | - return Promise.reject(errorName); | |
| 40 | + return Promise.reject(`${errorName}不能包含逗号`); | |
| 41 | 41 | } |
| 42 | 42 | return Promise.resolve(); |
| 43 | 43 | }, |
| ... | ... | @@ -64,7 +64,10 @@ export const formSchemas = ({ |
| 64 | 64 | placeholder: '请输入功能名称', |
| 65 | 65 | }, |
| 66 | 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 | 83 | placeholder: '请输入标识符', |
| 81 | 84 | }, |
| 82 | 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 | 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 | 146 | field: FormField.VALUE_RANGE, |
| 131 | 147 | label: '取值范围', |
| 132 | 148 | component: 'CustomMinMaxInput', | ... | ... |
| 1 | 1 | import { cloneDeep } from 'lodash-es'; |
| 2 | 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 | 9 | import { isArray } from '/@/utils/is'; |
| 5 | 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 | 13 | const { |
| 9 | 14 | type, |
| 10 | 15 | valueRange, |
| ... | ... | @@ -55,6 +60,13 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { |
| 55 | 60 | }; |
| 56 | 61 | break; |
| 57 | 62 | |
| 63 | + case DataTypeEnum.ENUM: | |
| 64 | + dataType = { | |
| 65 | + type, | |
| 66 | + specsList: enumList, | |
| 67 | + }; | |
| 68 | + break; | |
| 69 | + | |
| 58 | 70 | case DataTypeEnum.STRUCT: |
| 59 | 71 | dataType = { |
| 60 | 72 | type, |
| ... | ... | @@ -62,12 +74,13 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { |
| 62 | 74 | }; |
| 63 | 75 | break; |
| 64 | 76 | } |
| 65 | - return { ...basic, dataType }; | |
| 77 | + return { ...basic, dataType } as StructJSON; | |
| 66 | 78 | } |
| 67 | 79 | |
| 68 | 80 | export const excludeIdInStructJSON = (struct: DataType) => { |
| 69 | 81 | const _value = cloneDeep(struct); |
| 70 | 82 | const { specs } = _value; |
| 83 | + if (!specs) return _value; | |
| 71 | 84 | const list = [specs]; |
| 72 | 85 | |
| 73 | 86 | while (list.length) { |
| ... | ... | @@ -77,10 +90,10 @@ export const excludeIdInStructJSON = (struct: DataType) => { |
| 77 | 90 | if (temp.dataType?.specs) { |
| 78 | 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 | 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 | 98 | list.shift(); |
| 86 | 99 | } | ... | ... |
| ... | ... | @@ -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 | 124 | const createStructJson = ({ identifier, functionName, dataType }: StructJSON): FormSchema => { |
| 105 | 125 | return { |
| 106 | 126 | field: identifier, |
| ... | ... | @@ -140,6 +160,7 @@ export const getFormSchemas = ({ |
| 140 | 160 | } |
| 141 | 161 | |
| 142 | 162 | if (type === DataTypeEnum.BOOL) schemas.push(createSelect(item)); |
| 163 | + else if (type === DataTypeEnum.ENUM) schemas.push(createEnumsSelect(item)); | |
| 143 | 164 | else if (type === DataTypeEnum.NUMBER_INT) schemas.push(createInputNumber(item)); |
| 144 | 165 | else if (type === DataTypeEnum.NUMBER_DOUBLE) schemas.push(createInputNumber(item)); |
| 145 | 166 | else if (type === DataTypeEnum.STRING) schemas.push(createInput(item)); | ... | ... |
| ... | ... | @@ -27,16 +27,26 @@ export interface SocketInfoDataSourceItemType extends BaseAdditionalInfo { |
| 27 | 27 | expand?: boolean; |
| 28 | 28 | showHistoryDataButton?: boolean; |
| 29 | 29 | rawValue?: any; |
| 30 | + enum?: Record<string, string>; | |
| 30 | 31 | } |
| 31 | 32 | |
| 32 | 33 | export function buildTableDataSourceByObjectModel( |
| 33 | 34 | models: DeviceModelOfMatterAttrs[] |
| 34 | 35 | ): SocketInfoDataSourceItemType[] { |
| 35 | 36 | function getAdditionalInfoByDataType(dataType?: DataType) { |
| 36 | - const { specs } = dataType || {}; | |
| 37 | + const { specs, specsList, type } = dataType || {}; | |
| 37 | 38 | if (isArray(specs)) return {}; |
| 38 | 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 | 52 | return models.map((item) => { |
| ... | ... | @@ -72,7 +82,6 @@ export function buildTableDataSourceByObjectModel( |
| 72 | 82 | } else { |
| 73 | 83 | Object.assign(res, getAdditionalInfoByDataType(dataType)); |
| 74 | 84 | } |
| 75 | - | |
| 76 | 85 | return res; |
| 77 | 86 | }); |
| 78 | 87 | } | ... | ... |
| ... | ... | @@ -284,13 +284,15 @@ |
| 284 | 284 | }); |
| 285 | 285 | |
| 286 | 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 | 298 | const [register, { openModal: openSendCommandModal }] = useModal(); | ... | ... |
| ... | ... | @@ -81,7 +81,7 @@ export const useGenDynamicForm = () => { |
| 81 | 81 | type: 'string', |
| 82 | 82 | trigger: 'change', |
| 83 | 83 | validator: (_rule, value) => { |
| 84 | - if (value.length > length) { | |
| 84 | + if (value?.length > length) { | |
| 85 | 85 | return Promise.reject(`${functionName}数据长度应该小于${length}`); |
| 86 | 86 | } |
| 87 | 87 | return Promise.resolve(value); |
| ... | ... | @@ -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 | 138 | const createInputJson = ({ identifier, functionName }: BasicCreateFormParams): FormSchema => { |
| 121 | 139 | return { |
| 122 | 140 | field: identifier, |
| ... | ... | @@ -144,6 +162,7 @@ export const useGenDynamicForm = () => { |
| 144 | 162 | [DataTypeEnum.NUMBER_INT]: createInputNumber, |
| 145 | 163 | [DataTypeEnum.STRING]: createInput, |
| 146 | 164 | [DataTypeEnum.STRUCT]: createInputJson, |
| 165 | + [DataTypeEnum.ENUM]: createEnumSelect, | |
| 147 | 166 | }; |
| 148 | 167 | |
| 149 | 168 | const fieldTypeMap = new Map<string, DataTypeEnum>(); | ... | ... |
| 1 | -<template> | |
| 2 | - <BasicForm @register="register" /> | |
| 3 | -</template> | |
| 4 | 1 | <script lang="ts" setup> |
| 5 | 2 | import { BasicForm, useForm } from '/@/components/Form'; |
| 6 | 3 | import { DataType, ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; |
| ... | ... | @@ -15,34 +12,38 @@ |
| 15 | 12 | import { formSchemas } from '/@/components/Form/src/externalCompns/components/StructForm/config'; |
| 16 | 13 | import { TransportTypeEnum } from '../../../../components/TransportDescript/const'; |
| 17 | 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 | 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 | 23 | labelWidth: 100, |
| 23 | 24 | schemas: formSchemas({ |
| 24 | 25 | hasStructForm: false, |
| 25 | 26 | hiddenAccessMode: false, |
| 26 | 27 | isTcp: props.transportType === TransportTypeEnum.TCP, |
| 27 | 28 | }), |
| 28 | - actionColOptions: { | |
| 29 | - span: 14, | |
| 30 | - }, | |
| 31 | - showResetButton: false, | |
| 32 | - submitOnReset: false, | |
| 33 | 29 | showActionButtonGroup: false, |
| 34 | 30 | }); |
| 35 | 31 | |
| 32 | + const disabled = ref(false); | |
| 36 | 33 | const setDisable = (flag: boolean) => { |
| 37 | - setProps({ disabled: flag }); | |
| 34 | + disabled.value = flag; | |
| 38 | 35 | }; |
| 39 | 36 | |
| 40 | 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 | 42 | const { functionName, remark, identifier, accessMode } = _values; |
| 44 | - const structJSON = transfromToStructJSON(_values); | |
| 43 | + const structJSON = transfromToStructJSON(_values, unref(enumListRef)?.getFieldsValue?.()); | |
| 44 | + | |
| 45 | 45 | const dataType = excludeIdInStructJSON(structJSON.dataType!); |
| 46 | + | |
| 46 | 47 | const value = { |
| 47 | 48 | functionName, |
| 48 | 49 | functionType: FunctionType.PROPERTIES, |
| ... | ... | @@ -54,6 +55,7 @@ |
| 54 | 55 | dataType: dataType, |
| 55 | 56 | }, |
| 56 | 57 | } as ModelOfMatterParams; |
| 58 | + | |
| 57 | 59 | return value; |
| 58 | 60 | } |
| 59 | 61 | |
| ... | ... | @@ -63,18 +65,21 @@ |
| 63 | 65 | |
| 64 | 66 | const setFormData = (record: ModelOfMatterParams) => { |
| 65 | 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 | 72 | const value = { |
| 71 | 73 | ...record, |
| 72 | 74 | ...functionJson, |
| 73 | 75 | ...dataType, |
| 74 | 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 | 83 | setFieldsValue(value); |
| 79 | 84 | }; |
| 80 | 85 | |
| ... | ... | @@ -85,4 +90,13 @@ |
| 85 | 90 | setDisable, |
| 86 | 91 | }); |
| 87 | 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 | 102 | <style lang="less" scoped></style> | ... | ... |