ThingModelProperty.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <el-form-item
  3. :rules="[{ required: true, message: '请选择数据类型', trigger: 'change' }]"
  4. label="数据类型"
  5. prop="property.dataType"
  6. >
  7. <el-select v-model="property.dataType" placeholder="请选择数据类型" @change="handleChange">
  8. <!-- ARRAY 和 STRUCT 类型数据相互嵌套时,最多支持递归嵌套2层(父和子) -->
  9. <el-option
  10. v-for="option in getDataTypeOptions"
  11. :key="option.value"
  12. :label="option.label"
  13. :value="option.value"
  14. />
  15. </el-select>
  16. </el-form-item>
  17. <!-- 数值型配置 -->
  18. <ThingModelNumberDataSpecs
  19. v-if="
  20. [DataSpecsDataType.INT, DataSpecsDataType.DOUBLE, DataSpecsDataType.FLOAT].includes(
  21. property.dataType || ''
  22. )
  23. "
  24. v-model="property.dataSpecs"
  25. />
  26. <!-- 枚举型配置 -->
  27. <ThingModelEnumDataSpecs
  28. v-if="property.dataType === DataSpecsDataType.ENUM"
  29. v-model="property.dataSpecsList"
  30. />
  31. <!-- 布尔型配置 -->
  32. <el-form-item v-if="property.dataType === DataSpecsDataType.BOOL" label="布尔值">
  33. <template v-for="(item, index) in property.dataSpecsList" :key="item.value">
  34. <div class="flex items-center justify-start w-1/1 mb-5px">
  35. <span>{{ item.value }}</span>
  36. <span class="mx-2">-</span>
  37. <el-form-item
  38. :prop="`property.dataSpecsList[${index}].name`"
  39. :rules="[
  40. { required: true, message: '枚举描述不能为空' },
  41. { validator: validateBoolName, trigger: 'blur' }
  42. ]"
  43. class="flex-1 mb-0"
  44. >
  45. <el-input
  46. v-model="item.name"
  47. :placeholder="`如:${item.value === 0 ? '关' : '开'}`"
  48. class="w-255px!"
  49. />
  50. </el-form-item>
  51. </div>
  52. </template>
  53. </el-form-item>
  54. <!-- 文本型配置 -->
  55. <el-form-item
  56. v-if="property.dataType === DataSpecsDataType.TEXT"
  57. label="数据长度"
  58. prop="property.dataSpecs.length"
  59. >
  60. <el-input v-model="property.dataSpecs.length" class="w-255px!" placeholder="请输入文本字节长度">
  61. <template #append>字节</template>
  62. </el-input>
  63. </el-form-item>
  64. <!-- 时间型配置 -->
  65. <el-form-item v-if="property.dataType === DataSpecsDataType.DATE" label="时间格式" prop="date">
  66. <el-input class="w-255px!" disabled placeholder="String类型的UTC时间戳(毫秒)" />
  67. </el-form-item>
  68. <!-- 数组型配置-->
  69. <ThingModelArrayDataSpecs
  70. v-if="property.dataType === DataSpecsDataType.ARRAY"
  71. v-model="property.dataSpecs"
  72. />
  73. <!-- Struct 型配置-->
  74. <ThingModelStructDataSpecs
  75. v-if="property.dataType === DataSpecsDataType.STRUCT"
  76. v-model="property.dataSpecsList"
  77. />
  78. <el-form-item v-if="!isStructDataSpecs && !isParams" label="读写类型" prop="property.accessMode">
  79. <el-radio-group v-model="property.accessMode">
  80. <el-radio :label="ThingModelAccessMode.READ_WRITE.value">
  81. {{ ThingModelAccessMode.READ_WRITE.label }}
  82. </el-radio>
  83. <el-radio :label="ThingModelAccessMode.READ_ONLY.value">
  84. {{ ThingModelAccessMode.READ_ONLY.label }}
  85. </el-radio>
  86. </el-radio-group>
  87. </el-form-item>
  88. </template>
  89. <script lang="ts" setup>
  90. import { useVModel } from '@vueuse/core'
  91. import {
  92. DataSpecsDataType,
  93. dataTypeOptions,
  94. ThingModelAccessMode,
  95. validateBoolName
  96. } from './config'
  97. import {
  98. ThingModelArrayDataSpecs,
  99. ThingModelEnumDataSpecs,
  100. ThingModelNumberDataSpecs,
  101. ThingModelStructDataSpecs
  102. } from './dataSpecs'
  103. import { ThingModelProperty } from '@/api/iot/thingmodel'
  104. /** IoT 物模型属性 */
  105. defineOptions({ name: 'ThingModelProperty' })
  106. const props = defineProps<{ modelValue: any; isStructDataSpecs?: boolean; isParams?: boolean }>()
  107. const emits = defineEmits(['update:modelValue'])
  108. const property = useVModel(props, 'modelValue', emits) as Ref<ThingModelProperty>
  109. const getDataTypeOptions = computed(() => {
  110. return !props.isStructDataSpecs
  111. ? dataTypeOptions
  112. : dataTypeOptions.filter(
  113. (item) =>
  114. !([DataSpecsDataType.STRUCT, DataSpecsDataType.ARRAY] as any[]).includes(item.value)
  115. )
  116. }) // 获得数据类型列表
  117. /** 属性值的数据类型切换时初始化相关数据 */
  118. const handleChange = (dataType: any) => {
  119. property.value.dataSpecsList = []
  120. property.value.dataSpecs = {}
  121. // 不是列表型数据才设置 dataSpecs.dataType
  122. ![DataSpecsDataType.ENUM, DataSpecsDataType.BOOL, DataSpecsDataType.STRUCT].includes(dataType) &&
  123. (property.value.dataSpecs.dataType = dataType)
  124. switch (dataType) {
  125. case DataSpecsDataType.ENUM:
  126. property.value.dataSpecsList.push({
  127. dataType: DataSpecsDataType.ENUM,
  128. name: '', // 枚举项的名称
  129. value: undefined // 枚举值
  130. })
  131. break
  132. case DataSpecsDataType.BOOL:
  133. for (let i = 0; i < 2; i++) {
  134. property.value.dataSpecsList.push({
  135. dataType: DataSpecsDataType.BOOL,
  136. name: '', // 布尔值的名称
  137. value: i // 布尔值
  138. })
  139. }
  140. break
  141. }
  142. }
  143. </script>
  144. <style lang="scss" scoped>
  145. :deep(.el-form-item) {
  146. .el-form-item {
  147. margin-bottom: 0;
  148. }
  149. }
  150. </style>