admin-vben/apps/web-antd/src/views/iot/thingmodel/modules/ThingModelProperty.vue

224 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 产品的物模型表单property -->
<script lang="ts" setup>
import type { Ref } from 'vue';
import type { ThingModelProperty } from '#/api/iot/thingmodel';
import { computed, watch } from 'vue';
import { isEmpty } from '@vben/utils';
import { useVModel } from '@vueuse/core';
import { Form, Input, Radio, Select } from 'ant-design-vue';
import { validateBoolName } from '#/api/iot/thingmodel';
import {
getDataTypeOptions,
IoTDataSpecsDataTypeEnum,
IoTThingModelAccessModeEnum,
} from '#/views/iot/utils/constants';
import {
ThingModelArrayDataSpecs,
ThingModelEnumDataSpecs,
ThingModelNumberDataSpecs,
ThingModelStructDataSpecs,
} from './dataSpecs';
/** IoT 物模型属性 */
defineOptions({ name: 'ThingModelProperty' });
const props = defineProps<{
isParams?: boolean;
isStructDataSpecs?: boolean;
modelValue: any;
}>();
const emits = defineEmits(['update:modelValue']);
const property = useVModel(
props,
'modelValue',
emits,
) as Ref<ThingModelProperty>;
const getDataTypeOptions2 = computed(() => {
if (!props.isStructDataSpecs) {
return getDataTypeOptions();
}
const excludedTypes = new Set([
IoTDataSpecsDataTypeEnum.ARRAY,
IoTDataSpecsDataTypeEnum.STRUCT,
]);
return getDataTypeOptions().filter(
(item: any) => !excludedTypes.has(item.value),
);
}); // 获得数据类型列表
/** 属性值的数据类型切换时初始化相关数据 */
function handleChange(dataType: any) {
property.value.dataSpecs = {};
property.value.dataSpecsList = [];
// 不是列表型数据才设置 dataSpecs.dataType
![
IoTDataSpecsDataTypeEnum.BOOL,
IoTDataSpecsDataTypeEnum.ENUM,
IoTDataSpecsDataTypeEnum.STRUCT,
].includes(dataType) && (property.value.dataSpecs.dataType = dataType);
switch (dataType) {
case IoTDataSpecsDataTypeEnum.BOOL: {
for (let i = 0; i < 2; i++) {
property.value.dataSpecsList.push({
dataType: IoTDataSpecsDataTypeEnum.BOOL,
name: '', // 布尔值的名称
value: i, // 布尔值
});
}
break;
}
case IoTDataSpecsDataTypeEnum.ENUM: {
property.value.dataSpecsList.push({
dataType: IoTDataSpecsDataTypeEnum.ENUM,
name: '', // 枚举项的名称
value: undefined, // 枚举值
});
break;
}
}
}
/** 默认选中读写 */
watch(
() => property.value.accessMode,
(val: string | undefined) => {
if (props.isStructDataSpecs || props.isParams) {
return;
}
isEmpty(val) &&
(property.value.accessMode =
IoTThingModelAccessModeEnum.READ_WRITE.value);
},
{ immediate: true },
);
</script>
<template>
<Form.Item
:rules="[{ required: true, message: '请选择数据类型', trigger: 'change' }]"
label="数据类型"
prop="property.dataType"
>
<Select
v-model="property.dataType"
placeholder="请选择数据类型"
@change="handleChange"
>
<!-- ARRAY 和 STRUCT 类型数据相互嵌套时,最多支持递归嵌套 2 层(父和子) -->
<Select.Option
v-for="option in getDataTypeOptions2"
:key="option.value"
:label="`${option.value}(${option.label})`"
:value="option.value"
/>
</Select>
</Form.Item>
<!-- 数值型配置 -->
<ThingModelNumberDataSpecs
v-if="
[
IoTDataSpecsDataTypeEnum.INT,
IoTDataSpecsDataTypeEnum.DOUBLE,
IoTDataSpecsDataTypeEnum.FLOAT,
].includes(property.dataType || '')
"
v-model="property.dataSpecs"
/>
<!-- 枚举型配置 -->
<ThingModelEnumDataSpecs
v-if="property.dataType === IoTDataSpecsDataTypeEnum.ENUM"
v-model="property.dataSpecsList"
/>
<!-- 布尔型配置 -->
<Form.Item
v-if="property.dataType === IoTDataSpecsDataTypeEnum.BOOL"
label="布尔值"
>
<template v-for="(item, index) in property.dataSpecsList" :key="item.value">
<div class="w-1/1 mb-5px flex items-center justify-start">
<span>{{ item.value }}</span>
<span class="mx-2">-</span>
<Form.Item
:prop="`property.dataSpecsList[${index}].name`"
:rules="[
{ required: true, message: '枚举描述不能为空' },
{ validator: validateBoolName, trigger: 'blur' },
]"
class="mb-0 flex-1"
>
<Input
v-model="item.name"
:placeholder="`如:${item.value === 0 ? '关' : '开'}`"
class="w-255px!"
/>
</Form.Item>
</div>
</template>
</Form.Item>
<!-- 文本型配置 -->
<Form.Item
v-if="property.dataType === IoTDataSpecsDataTypeEnum.TEXT"
label="数据长度"
prop="property.dataSpecs.length"
>
<Input
v-model="property.dataSpecs.length"
class="w-255px!"
placeholder="请输入文本字节长度"
>
<template #append>字节</template>
</Input>
</Form.Item>
<!-- 时间型配置 -->
<Form.Item
v-if="property.dataType === IoTDataSpecsDataTypeEnum.DATE"
label="时间格式"
prop="date"
>
<Input
class="w-255px!"
disabled
placeholder="String 类型的 UTC 时间戳(毫秒)"
/>
</Form.Item>
<!-- 数组型配置-->
<ThingModelArrayDataSpecs
v-if="property.dataType === IoTDataSpecsDataTypeEnum.ARRAY"
v-model="property.dataSpecs"
/>
<!-- Struct 型配置-->
<ThingModelStructDataSpecs
v-if="property.dataType === IoTDataSpecsDataTypeEnum.STRUCT"
v-model="property.dataSpecsList"
/>
<Form.Item
v-if="!isStructDataSpecs && !isParams"
label="读写类型"
prop="property.accessMode"
>
<Radio.Group v-model="property.accessMode">
<Radio
v-for="accessMode in Object.values(IoTThingModelAccessModeEnum)"
:key="accessMode.value"
:label="accessMode.value"
>
{{ accessMode.label }}
</Radio>
</Radio.Group>
</Form.Item>
</template>
<style lang="scss" scoped>
:deep(.ant-form-item) {
.ant-form-item {
margin-bottom: 0;
}
}
</style>