Browse Source

【功能完善】IoT: 场景联动物模型属性参数输入组件

puhui999 1 year ago
parent
commit
4eb7188ecf

+ 118 - 0
src/views/iot/rule/scene/components/ThingModelParamInput.vue

@@ -0,0 +1,118 @@
+<template>
+  <div class="flex items-center">
+    <!-- 数值类型输入框 -->
+    <template v-if="isNumeric">
+      <el-input
+        v-model="value"
+        class="w-1/1!"
+        :placeholder="`请输入${dataSpecs.unitName ? dataSpecs.unitName : '数值'}`"
+      >
+        <template #append> {{ dataSpecs.unit }} </template>
+      </el-input>
+    </template>
+
+    <!-- 布尔类型使用开关 -->
+    <template v-else-if="isBool">
+      <el-switch
+        v-model="value"
+        size="large"
+        :active-text="dataSpecsList[1].name"
+        :active-value="dataSpecsList[1].value"
+        :inactive-text="dataSpecsList[0].name"
+        :inactive-value="dataSpecsList[0].value"
+      />
+    </template>
+
+    <!-- 枚举类型使用下拉选择 -->
+    <template v-else-if="isEnum">
+      <el-select class="w-1/1!" v-model="value">
+        <el-option
+          v-for="(item, index) in dataSpecsList"
+          :key="index"
+          :label="item.name"
+          :value="item.value"
+        />
+      </el-select>
+    </template>
+
+    <!-- 时间类型使用时间选择器 -->
+    <template v-else-if="isDate">
+      <el-date-picker
+        class="w-1/1!"
+        v-model="value"
+        type="datetime"
+        value-format="YYYY-MM-DD HH:mm:ss"
+        placeholder="选择日期时间"
+      />
+    </template>
+
+    <!-- 文本类型使用文本输入框 -->
+    <template v-else-if="isText">
+      <el-input
+        class="w-1/1!"
+        v-model="value"
+        :maxlength="dataSpecs?.length"
+        :show-word-limit="true"
+        placeholder="请输入文本"
+      />
+    </template>
+
+    <!-- array、struct 直接输入 -->
+    <template v-else>
+      <el-input class="w-1/1!" v-model="value" placeholder="请输入值" />
+    </template>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { computed } from 'vue'
+import { useVModel } from '@vueuse/core'
+import { DataSpecsDataType } from '@/views/iot/thingmodel/config'
+
+/** 物模型属性参数输入组件 */
+defineOptions({ name: 'ThingModelParamInput' })
+
+const props = defineProps<{
+  modelValue: any // 物模型的值
+  thingModel: any // 物模型
+}>()
+
+const emits = defineEmits(['update:modelValue', 'change'])
+const value = useVModel(props, 'modelValue', emits)
+
+/** 计算属性:判断数据类型 */
+const isNumeric = computed(() =>
+  [DataSpecsDataType.INT, DataSpecsDataType.FLOAT, DataSpecsDataType.DOUBLE].includes(
+    props.thingModel?.dataType as any
+  )
+)
+const isBool = computed(() => props.thingModel?.dataType === DataSpecsDataType.BOOL)
+const isEnum = computed(() => props.thingModel?.dataType === DataSpecsDataType.ENUM)
+const isDate = computed(() => props.thingModel?.dataType === DataSpecsDataType.DATE)
+const isText = computed(() => props.thingModel?.dataType === DataSpecsDataType.TEXT)
+/** 获取数据规格 */
+const dataSpecs = computed(() => {
+  if (isNumeric.value || isDate.value || isText.value) {
+    return props.thingModel?.dataSpecs
+  }
+  return {}
+})
+const dataSpecsList = computed(() => {
+  if (isBool.value || isEnum.value) {
+    return props.thingModel?.dataSpecsList
+  }
+  return []
+})
+
+/** 物模型切换重置值 */
+watch(
+  () => props.thingModel?.dataType,
+  (_, oldValue) => {
+    if (!oldValue) {
+      return
+    }
+    value.value = undefined
+  },
+  { deep: true }
+)
+</script>

+ 13 - 19
src/views/iot/rule/scene/components/action/DeviceControlAction.vue

@@ -40,12 +40,15 @@
             :value="thingModel.identifier"
           />
         </el-select>
-        <!-- TODO puhui999: 输入框调整,数值型使用数字输入框校验边界,bool 值使用开关,枚举值使用下拉选择,时间值使用时间选择器 -->
-        <el-input v-model="parameter.value" class="!w-240px mr-10px" placeholder="请输入值">
-          <template v-if="getUnitName(parameter.identifier)" #append>
-            {{ getUnitName(parameter.identifier) }}
-          </template>
-        </el-input>
+        <ThingModelParamInput
+          class="!w-240px mr-10px"
+          v-model="parameter.value"
+          :thing-model="
+            thingModels(parameter?.identifier0)?.find(
+              (item) => item.identifier === parameter.identifier
+            )
+          "
+        />
         <el-tooltip content="删除参数" placement="top">
           <el-button type="danger" circle size="small" @click="removeParameter(index)">
             <Icon icon="ep:delete" />
@@ -66,13 +69,14 @@
 
 <script setup lang="ts">
 import { useVModel } from '@vueuse/core'
+import { isEmpty } from '@/utils/is'
 import { ThingModelApi } from '@/api/iot/thingmodel'
 import {
   ActionDeviceControl,
   IotDeviceMessageIdentifierEnum,
   IotDeviceMessageTypeEnum
 } from '@/api/iot/rule/scene/scene.types'
-import { isEmpty } from '@/utils/is'
+import ThingModelParamInput from '../ThingModelParamInput.vue'
 
 /** 设备控制执行器组件 */
 defineOptions({ name: 'DeviceControlAction' })
@@ -94,8 +98,8 @@ const addParameter = () => {
     message.warning('请先选择一个产品')
     return
   }
-  if (parameters.value.length >= thingModels.value.length) {
-    message.warning(`该产品只有${thingModels.value.length}个物模型!!!`)
+  if (parameters.value.length >= thingModels.value().length) {
+    message.warning(`该产品只有${thingModels.value().length}个物模型!!!`)
     return
   }
   parameters.value.push({ identifier: '', value: undefined })
@@ -189,16 +193,6 @@ const thingModels = computed(() => (identifier?: string): any[] => {
 })
 /** 获取物模型服务 */
 const getThingModelTSLServices = computed(() => thingModelTSL.value?.services || [])
-/** 获得属性单位 */
-const getUnitName = computed(() => (identifier: string) => {
-  const model = thingModels.value().find((item: any) => item.identifier === identifier)
-  // 属性
-  if (model?.dataSpecs) {
-    return model.dataSpecs.unitName
-  }
-  // TODO puhui999: enum、bool、struct 类型数据处理
-  return ''
-})
 
 /** 监听 productId 变化 */
 watch(