Bläddra i källkod

perf: 【IoT 物联网】场景联动移除自定义校验规则简化校验逻辑

puhui999 9 månader sedan
förälder
incheckning
9684857174

+ 2 - 53
src/views/iot/rule/scene/form/configs/CurrentTimeConditionConfig.vue

@@ -106,7 +106,6 @@ const props = defineProps<{
 
 const emit = defineEmits<{
   (e: 'update:modelValue', value: TriggerCondition): void
-  (e: 'validate', result: { valid: boolean; message: string }): void
 }>()
 
 const condition = useVModel(props, 'modelValue', emit)
@@ -155,10 +154,6 @@ const timeOperatorOptions = [
   }
 ]
 
-// 状态
-const validationMessage = ref('')
-const isValid = ref(true)
-
 // 计算属性
 const needsTimeInput = computed(() => {
   const timeOnlyOperators = [
@@ -181,62 +176,16 @@ const needsSecondTimeInput = computed(() => {
 // 事件处理
 const updateConditionField = (field: keyof TriggerCondition, value: any) => {
   condition.value[field] = value
-  updateValidationResult()
 }
 
-const updateValidationResult = () => {
-  if (!condition.value.operator) {
-    isValid.value = false
-    validationMessage.value = '请选择时间条件'
-    emit('validate', { valid: false, message: validationMessage.value })
-    return
-  }
-
-  // 今日条件不需要时间值
-  if (condition.value.operator === IotRuleSceneTriggerTimeOperatorEnum.TODAY.value) {
-    isValid.value = true
-    validationMessage.value = '当前时间条件配置验证通过'
-    emit('validate', { valid: true, message: validationMessage.value })
-    return
-  }
-
-  if (needsTimeInput.value && !condition.value.timeValue) {
-    isValid.value = false
-    validationMessage.value = '请设置时间值'
-    emit('validate', { valid: false, message: validationMessage.value })
-    return
-  }
-
-  if (needsSecondTimeInput.value && !condition.value.timeValue2) {
-    isValid.value = false
-    validationMessage.value = '请设置结束时间'
-    emit('validate', { valid: false, message: validationMessage.value })
-    return
-  }
-
-  isValid.value = true
-  validationMessage.value = '当前时间条件配置验证通过'
-  emit('validate', { valid: true, message: validationMessage.value })
-}
-
-// 监听变化
-watch(
-  () => [condition.value.operator, condition.value.timeValue, condition.value.timeValue2],
-  () => {
-    updateValidationResult()
-  },
-  { immediate: true }
-)
-
 // 监听操作符变化,清理不相关的时间值
 watch(
   () => condition.value.operator,
   (newOperator) => {
     if (newOperator === IotRuleSceneTriggerTimeOperatorEnum.TODAY.value) {
-      condition.value.timeValue = undefined
-      condition.value.timeValue2 = undefined
+      ;(condition.value as any).timeValue = undefined(condition.value as any).timeValue2 = undefined
     } else if (!needsSecondTimeInput.value) {
-      condition.value.timeValue2 = undefined
+      ;(condition.value as any).timeValue2 = undefined
     }
   }
 )

+ 8 - 15
src/views/iot/rule/scene/form/configs/DeviceControlConfig.vue

@@ -55,7 +55,6 @@
             type="service"
             :config="{ service: selectedService }"
             placeholder="请输入JSON格式的服务参数"
-            @validate="handleParamsValidate"
           />
         </el-form-item>
       </div>
@@ -70,7 +69,6 @@
           type="property"
           :config="{ properties: thingModelProperties }"
           placeholder="请输入JSON格式的控制参数"
-          @validate="handleParamsValidate"
         />
       </el-form-item>
     </div>
@@ -86,7 +84,8 @@ import type { Action } from '@/api/iot/rule/scene'
 import type { ThingModelProperty, ThingModelService } from '@/api/iot/thingmodel'
 import {
   IotRuleSceneActionTypeEnum,
-  IoTThingModelAccessModeEnum
+  IoTThingModelAccessModeEnum,
+  IoTDataSpecsDataTypeEnum
 } from '@/views/iot/utils/constants'
 import { ThingModelApi } from '@/api/iot/thingmodel'
 
@@ -126,12 +125,6 @@ const paramsValue = computed({
   }
 })
 
-// 参数验证处理
-const handleParamsValidate = (result: { valid: boolean; message: string }) => {
-  // 可以在这里处理验证结果,比如显示错误信息
-  console.log('参数验证结果:', result)
-}
-
 const isPropertySetAction = computed(() => {
   // 是否为属性设置类型
   return action.value.type === IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET
@@ -301,16 +294,16 @@ const loadServiceFromTSL = async (productId: number, serviceIdentifier: string)
  */
 const getDefaultValueForParam = (param: any) => {
   switch (param.dataType) {
-    case 'int':
+    case IoTDataSpecsDataTypeEnum.INT:
       return 0
-    case 'float':
-    case 'double':
+    case IoTDataSpecsDataTypeEnum.FLOAT:
+    case IoTDataSpecsDataTypeEnum.DOUBLE:
       return 0.0
-    case 'bool':
+    case IoTDataSpecsDataTypeEnum.BOOL:
       return false
-    case 'text':
+    case IoTDataSpecsDataTypeEnum.TEXT:
       return ''
-    case 'enum':
+    case IoTDataSpecsDataTypeEnum.ENUM:
       // 如果有枚举值,使用第一个
       if (param.dataSpecs?.dataSpecsList && param.dataSpecs.dataSpecsList.length > 0) {
         return param.dataSpecs.dataSpecsList[0].value

+ 0 - 56
src/views/iot/rule/scene/form/configs/DeviceTriggerConfig.vue

@@ -29,7 +29,6 @@
             :model-value="trigger"
             @update:model-value="updateCondition"
             :trigger-type="trigger.type"
-            @validate="handleValidate"
             @trigger-type-change="handleTriggerTypeChange"
           />
         </div>
@@ -123,7 +122,6 @@
                   @update:model-value="(value) => updateSubGroup(subGroupIndex, value)"
                   :trigger-type="trigger.type"
                   :max-conditions="maxConditionsPerGroup"
-                  @validate="(result) => handleSubGroupValidate(subGroupIndex, result)"
                 />
               </div>
 
@@ -182,7 +180,6 @@ const props = defineProps<{
 
 const emit = defineEmits<{
   (e: 'update:modelValue', value: Trigger): void
-  (e: 'validate', value: { valid: boolean; message: string }): void
   (e: 'trigger-type-change', type: number): void
 }>()
 
@@ -192,18 +189,11 @@ const trigger = useVModel(props, 'modelValue', emit)
 const maxSubGroups = 3 // 最多 3 个子条件组
 const maxConditionsPerGroup = 3 // 每组最多 3 个条件
 
-// 验证状态
-const subGroupValidations = ref<{ [key: number]: { valid: boolean; message: string } }>({})
-
 // 事件处理
 const updateCondition = (condition: Trigger) => {
   trigger.value = condition
 }
 
-const handleValidate = (result: { valid: boolean; message: string }) => {
-  emit('validate', result)
-}
-
 const handleTriggerTypeChange = (type: number) => {
   trigger.value.type = type
   emit('trigger-type-change', type)
@@ -231,21 +221,6 @@ const addSubGroup = () => {
 const removeSubGroup = (index: number) => {
   if (trigger.value.conditionGroups) {
     trigger.value.conditionGroups.splice(index, 1)
-    delete subGroupValidations.value[index]
-
-    // 重新索引验证结果
-    const newValidations: { [key: number]: { valid: boolean; message: string } } = {}
-    Object.keys(subGroupValidations.value).forEach((key) => {
-      const numKey = parseInt(key)
-      if (numKey > index) {
-        newValidations[numKey - 1] = subGroupValidations.value[numKey]
-      } else if (numKey < index) {
-        newValidations[numKey] = subGroupValidations.value[numKey]
-      }
-    })
-    subGroupValidations.value = newValidations
-
-    updateValidationResult()
   }
 }
 
@@ -258,35 +233,4 @@ const updateSubGroup = (index: number, subGroup: any) => {
 const removeConditionGroup = () => {
   trigger.value.conditionGroups = undefined
 }
-
-const handleSubGroupValidate = (index: number, result: { valid: boolean; message: string }) => {
-  subGroupValidations.value[index] = result
-  updateValidationResult()
-}
-
-const updateValidationResult = () => {
-  if (!trigger.value.conditionGroups || trigger.value.conditionGroups.length === 0) {
-    emit('validate', { valid: true, message: '条件组容器为空,验证通过' })
-    return
-  }
-
-  const validations = Object.values(subGroupValidations.value)
-  const allValid = validations.every((v: any) => v.valid)
-
-  if (allValid) {
-    emit('validate', { valid: true, message: '条件组容器配置验证通过' })
-  } else {
-    const errorMessages = validations.filter((v: any) => !v.valid).map((v: any) => v.message)
-    emit('validate', { valid: false, message: `子条件组配置错误: ${errorMessages.join('; ')}` })
-  }
-}
-
-// 监听变化
-watch(
-  () => trigger.value.conditionGroups,
-  () => {
-    updateValidationResult()
-  },
-  { deep: true, immediate: true }
-)
 </script>

+ 1 - 90
src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue

@@ -100,7 +100,6 @@
               type="service"
               :config="serviceConfig"
               placeholder="请输入JSON格式的服务参数"
-              @validate="handleValueValidate"
             />
             <!-- 事件上报参数配置 -->
             <JsonParamsInput
@@ -109,7 +108,6 @@
               type="event"
               :config="eventConfig"
               placeholder="请输入JSON格式的事件参数"
-              @validate="handleValueValidate"
             />
             <!-- 普通值输入 -->
             <ValueInput
@@ -119,7 +117,6 @@
               :property-type="propertyType"
               :operator="condition.operator"
               :property-config="propertyConfig"
-              @validate="handleValueValidate"
             />
           </el-form-item>
         </el-col>
@@ -202,15 +199,11 @@ const props = defineProps<{
 
 const emit = defineEmits<{
   (e: 'update:modelValue', value: Trigger): void
-  (e: 'validate', result: { valid: boolean; message: string }): void
   (e: 'trigger-type-change', value: number): void
 }>()
 
 // 响应式数据
 const condition = useVModel(props, 'modelValue', emit)
-// TODO @puhui999:是不是 validationMessage 非空,就是不通过哈;
-const isValid = ref(true)
-const validationMessage = ref('')
 const propertyType = ref('')
 const propertyConfig = ref<any>(null)
 
@@ -279,7 +272,6 @@ const triggerTypeOptions = getTriggerTypeOptions()
 // 事件处理
 const updateConditionField = (field: keyof Trigger, value: any) => {
   ;(condition.value as any)[field] = value
-  updateValidationResult()
 }
 
 const handleTriggerTypeChange = (type: number) => {
@@ -290,13 +282,11 @@ const handleProductChange = () => {
   // 产品变化时清空设备和属性
   condition.value.deviceId = undefined
   condition.value.identifier = ''
-  updateValidationResult()
 }
 
 const handleDeviceChange = () => {
   // 设备变化时清空属性
   condition.value.identifier = ''
-  updateValidationResult()
 }
 
 const handlePropertyChange = (propertyInfo: any) => {
@@ -312,88 +302,9 @@ const handlePropertyChange = (propertyInfo: any) => {
       condition.value.operator = '='
     }
   }
-  updateValidationResult()
 }
 
 const handleOperatorChange = () => {
-  updateValidationResult()
+  // 操作符变化处理
 }
-
-// 处理参数验证结果
-const handleValueValidate = (result: { valid: boolean; message: string }) => {
-  isValid.value = result.valid
-  validationMessage.value = result.message
-  emit('validate', result)
-  updateValidationResult()
-}
-
-// 验证逻辑
-// TODO @puhui999:这个校验,是不是用更原生的 validator 哈。项目风格更统一点。
-const updateValidationResult = () => {
-  if (isDevicePropertyTrigger.value) {
-    // 设备属性触发验证
-    if (!condition.value.productId) {
-      isValid.value = false
-      validationMessage.value = '请选择产品'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-
-    if (!condition.value.deviceId) {
-      isValid.value = false
-      validationMessage.value = '请选择设备'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-
-    if (!condition.value.identifier) {
-      isValid.value = false
-      validationMessage.value = '请选择监控项'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-
-    // 服务调用和事件上报不需要操作符
-    if (
-      props.triggerType !== IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE &&
-      props.triggerType !== IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST &&
-      !condition.value.operator
-    ) {
-      isValid.value = false
-      validationMessage.value = '请选择操作符'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-
-    if (!condition.value.value) {
-      isValid.value = false
-      validationMessage.value = '请输入比较值'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-  }
-
-  isValid.value = true
-  validationMessage.value = '主条件配置验证通过'
-  emit('validate', { valid: true, message: validationMessage.value })
-}
-
-// 监听变化
-watch(
-  () => [
-    condition.value.productId,
-    condition.value.deviceId,
-    condition.value.identifier,
-    // 服务调用和事件上报不需要监听操作符
-    props.triggerType !== IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE &&
-    props.triggerType !== IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST
-      ? condition.value.operator
-      : null,
-    condition.value.value
-  ],
-  () => {
-    updateValidationResult()
-  },
-  { immediate: true }
-)
 </script>

+ 0 - 51
src/views/iot/rule/scene/form/configs/SubConditionGroupConfig.vue

@@ -56,7 +56,6 @@
               :model-value="condition"
               @update:model-value="(value) => updateCondition(conditionIndex, value)"
               :trigger-type="triggerType"
-              @validate="(result) => handleConditionValidate(conditionIndex, result)"
             />
           </div>
         </div>
@@ -100,7 +99,6 @@ const props = defineProps<{
 
 const emit = defineEmits<{
   (e: 'update:modelValue', value: TriggerCondition[]): void
-  (e: 'validate', result: { valid: boolean; message: string }): void
 }>()
 
 const subGroup = useVModel(props, 'modelValue', emit)
@@ -108,9 +106,6 @@ const subGroup = useVModel(props, 'modelValue', emit)
 // 配置常量
 const maxConditions = computed(() => props.maxConditions || 3)
 
-// 验证状态
-const conditionValidations = ref<{ [key: number]: { valid: boolean; message: string } }>({})
-
 // 事件处理
 const addCondition = () => {
   // 确保 subGroup.value 是一个数组
@@ -143,21 +138,6 @@ const addCondition = () => {
 const removeCondition = (index: number) => {
   if (subGroup.value) {
     subGroup.value.splice(index, 1)
-    delete conditionValidations.value[index]
-
-    // 重新索引验证结果
-    const newValidations: { [key: number]: { valid: boolean; message: string } } = {}
-    Object.keys(conditionValidations.value).forEach((key) => {
-      const numKey = parseInt(key)
-      if (numKey > index) {
-        newValidations[numKey - 1] = conditionValidations.value[numKey]
-      } else if (numKey < index) {
-        newValidations[numKey] = conditionValidations.value[numKey]
-      }
-    })
-    conditionValidations.value = newValidations
-
-    updateValidationResult()
   }
 }
 
@@ -166,35 +146,4 @@ const updateCondition = (index: number, condition: TriggerCondition) => {
     subGroup.value[index] = condition
   }
 }
-
-const handleConditionValidate = (index: number, result: { valid: boolean; message: string }) => {
-  conditionValidations.value[index] = result
-  updateValidationResult()
-}
-
-const updateValidationResult = () => {
-  if (!subGroup.value || subGroup.value.length === 0) {
-    emit('validate', { valid: false, message: '子条件组至少需要一个条件' })
-    return
-  }
-
-  const validations = Object.values(conditionValidations.value)
-  const allValid = validations.every((v: any) => v.valid)
-
-  if (allValid) {
-    emit('validate', { valid: true, message: '子条件组配置验证通过' })
-  } else {
-    const errorMessages = validations.filter((v: any) => !v.valid).map((v: any) => v.message)
-    emit('validate', { valid: false, message: `条件配置错误: ${errorMessages.join('; ')}` })
-  }
-}
-
-// 监听变化
-watch(
-  () => subGroup.value,
-  () => {
-    updateValidationResult()
-  },
-  { deep: true, immediate: true }
-)
 </script>

+ 19 - 23
src/views/iot/rule/scene/form/inputs/JsonParamsInput.vue

@@ -136,6 +136,7 @@
 <script setup lang="ts">
 import { useVModel } from '@vueuse/core'
 import { InfoFilled } from '@element-plus/icons-vue'
+import { IoTDataSpecsDataTypeEnum } from '@/views/iot/utils/constants'
 
 /** JSON参数输入组件 - 通用版本 */
 defineOptions({ name: 'JsonParamsInput' })
@@ -169,7 +170,6 @@ interface Props {
 
 interface Emits {
   (e: 'update:modelValue', value: string): void
-  (e: 'validate', result: { valid: boolean; message: string }): void
 }
 
 const props = withDefaults(defineProps<Props>(), {
@@ -317,7 +317,6 @@ const handleParamsChange = () => {
       // 额外的参数验证
       if (typeof parsed !== 'object' || parsed === null) {
         jsonError.value = '参数必须是一个有效的 JSON 对象'
-        emit('validate', { valid: false, message: jsonError.value })
         return
       }
 
@@ -325,7 +324,6 @@ const handleParamsChange = () => {
       for (const param of paramsList.value) {
         if (param.required && (!parsed[param.identifier] || parsed[param.identifier] === '')) {
           jsonError.value = `参数 ${param.name} 为必填项`
-          emit('validate', { valid: false, message: jsonError.value })
           return
         }
       }
@@ -334,10 +332,9 @@ const handleParamsChange = () => {
     }
 
     // 验证通过
-    emit('validate', { valid: true, message: 'JSON格式正确' })
+    jsonError.value = ''
   } catch (error) {
     jsonError.value = `JSON格式错误: ${error instanceof Error ? error.message : '未知错误'}`
-    emit('validate', { valid: false, message: jsonError.value })
   }
 }
 
@@ -352,7 +349,6 @@ const clearParams = () => {
   paramsJson.value = ''
   localValue.value = ''
   jsonError.value = ''
-  emit('validate', { valid: true, message: '' })
 }
 
 // 工具函数
@@ -373,35 +369,35 @@ const getParamTypeName = (dataType: string) => {
 
 const getParamTypeTag = (dataType: string) => {
   const tagMap = {
-    int: 'primary',
-    float: 'success',
-    double: 'success',
-    text: 'info',
-    bool: 'warning',
-    enum: 'danger',
-    date: 'primary',
-    struct: 'info',
-    array: 'warning'
+    [IoTDataSpecsDataTypeEnum.INT]: 'primary',
+    [IoTDataSpecsDataTypeEnum.FLOAT]: 'success',
+    [IoTDataSpecsDataTypeEnum.DOUBLE]: 'success',
+    [IoTDataSpecsDataTypeEnum.TEXT]: 'info',
+    [IoTDataSpecsDataTypeEnum.BOOL]: 'warning',
+    [IoTDataSpecsDataTypeEnum.ENUM]: 'danger',
+    [IoTDataSpecsDataTypeEnum.DATE]: 'primary',
+    [IoTDataSpecsDataTypeEnum.STRUCT]: 'info',
+    [IoTDataSpecsDataTypeEnum.ARRAY]: 'warning'
   }
   return tagMap[dataType] || 'info'
 }
 
 const getExampleValue = (param: any) => {
   switch (param.dataType) {
-    case 'int':
+    case IoTDataSpecsDataTypeEnum.INT:
       return '25'
-    case 'float':
-    case 'double':
+    case IoTDataSpecsDataTypeEnum.FLOAT:
+    case IoTDataSpecsDataTypeEnum.DOUBLE:
       return '25.5'
-    case 'bool':
+    case IoTDataSpecsDataTypeEnum.BOOL:
       return 'false'
-    case 'text':
+    case IoTDataSpecsDataTypeEnum.TEXT:
       return '"auto"'
-    case 'enum':
+    case IoTDataSpecsDataTypeEnum.ENUM:
       return '"option1"'
-    case 'struct':
+    case IoTDataSpecsDataTypeEnum.STRUCT:
       return '{}'
-    case 'array':
+    case IoTDataSpecsDataTypeEnum.ARRAY:
       return '[]'
     default:
       return '""'

+ 18 - 121
src/views/iot/rule/scene/form/inputs/ValueInput.vue

@@ -132,19 +132,12 @@
         </el-tooltip>
       </template>
     </el-input>
-
-    <!-- 验证提示 -->
-    <div v-if="validationMessage" class="mt-4px">
-      <el-text :type="isValid ? 'success' : 'danger'" size="small">
-        <Icon :icon="isValid ? 'ep:check' : 'ep:warning-filled'" />
-        {{ validationMessage }}
-      </el-text>
-    </div>
   </div>
 </template>
 
 <script setup lang="ts">
 import { useVModel } from '@vueuse/core'
+import { IoTDataSpecsDataTypeEnum } from '@/views/iot/utils/constants'
 
 /** 值输入组件 */
 defineOptions({ name: 'ValueInput' })
@@ -158,7 +151,6 @@ interface Props {
 
 interface Emits {
   (e: 'update:modelValue', value: string): void
-  (e: 'validate', result: { valid: boolean; message: string }): void
 }
 
 const props = defineProps<Props>()
@@ -173,8 +165,6 @@ const rangeStart = ref('')
 const rangeEnd = ref('')
 const dateValue = ref('')
 const numberValue = ref<number>()
-const validationMessage = ref('')
-const isValid = ref(true)
 
 // 计算属性
 const enumOptions = computed(() => {
@@ -199,14 +189,18 @@ const listPreview = computed(() => {
 
 // 工具函数
 const isNumericType = () => {
-  return ['int', 'float', 'double'].includes(props.propertyType || '')
+  return [
+    IoTDataSpecsDataTypeEnum.INT,
+    IoTDataSpecsDataTypeEnum.FLOAT,
+    IoTDataSpecsDataTypeEnum.DOUBLE
+  ].includes(props.propertyType || '')
 }
 
 const getInputType = () => {
   switch (props.propertyType) {
-    case 'int':
-    case 'float':
-    case 'double':
+    case IoTDataSpecsDataTypeEnum.INT:
+    case IoTDataSpecsDataTypeEnum.FLOAT:
+    case IoTDataSpecsDataTypeEnum.DOUBLE:
       return 'number'
     default:
       return 'text'
@@ -215,22 +209,22 @@ const getInputType = () => {
 
 const getPlaceholder = () => {
   const typeMap = {
-    string: '请输入字符串',
-    int: '请输入整数',
-    float: '请输入浮点数',
-    double: '请输入双精度数',
-    struct: '请输入JSON格式数据',
-    array: '请输入数组格式数据'
+    [IoTDataSpecsDataTypeEnum.TEXT]: '请输入字符串',
+    [IoTDataSpecsDataTypeEnum.INT]: '请输入整数',
+    [IoTDataSpecsDataTypeEnum.FLOAT]: '请输入浮点数',
+    [IoTDataSpecsDataTypeEnum.DOUBLE]: '请输入双精度数',
+    [IoTDataSpecsDataTypeEnum.STRUCT]: '请输入JSON格式数据',
+    [IoTDataSpecsDataTypeEnum.ARRAY]: '请输入数组格式数据'
   }
   return typeMap[props.propertyType || ''] || '请输入值'
 }
 
 const getPrecision = () => {
-  return props.propertyType === 'int' ? 0 : 2
+  return props.propertyType === IoTDataSpecsDataTypeEnum.INT ? 0 : 2
 }
 
 const getStep = () => {
-  return props.propertyType === 'int' ? 1 : 0.1
+  return props.propertyType === IoTDataSpecsDataTypeEnum.INT ? 1 : 0.1
 }
 
 const getMin = () => {
@@ -243,7 +237,7 @@ const getMax = () => {
 
 // 事件处理
 const handleChange = () => {
-  validateValue()
+  // 值变化处理
 }
 
 const handleRangeChange = () => {
@@ -252,106 +246,16 @@ const handleRangeChange = () => {
   } else {
     localValue.value = ''
   }
-  validateValue()
 }
 
 const handleDateChange = (value: string) => {
   localValue.value = value || ''
-  validateValue()
 }
 
 const handleNumberChange = (value: number | undefined) => {
   localValue.value = value?.toString() || ''
-  validateValue()
 }
 
-// 验证函数
-const validateValue = () => {
-  if (!localValue.value) {
-    isValid.value = false
-    validationMessage.value = '请输入值'
-    emit('validate', { valid: false, message: validationMessage.value })
-    return
-  }
-
-  // 数字类型验证
-  if (isNumericType()) {
-    const num = parseFloat(localValue.value)
-    if (isNaN(num)) {
-      isValid.value = false
-      validationMessage.value = '请输入有效的数字'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-
-    // 范围验证
-    const min = getMin()
-    const max = getMax()
-    if (min !== undefined && num < min) {
-      isValid.value = false
-      validationMessage.value = `值不能小于 ${min}`
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-    if (max !== undefined && num > max) {
-      isValid.value = false
-      validationMessage.value = `值不能大于 ${max}`
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-  }
-
-  // 范围输入验证
-  if (props.operator === 'between') {
-    const parts = localValue.value.split(',')
-    if (parts.length !== 2) {
-      isValid.value = false
-      validationMessage.value = '范围格式错误'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-
-    const start = parseFloat(parts[0])
-    const end = parseFloat(parts[1])
-    if (isNaN(start) || isNaN(end)) {
-      isValid.value = false
-      validationMessage.value = '范围值必须是数字'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-
-    if (start >= end) {
-      isValid.value = false
-      validationMessage.value = '起始值必须小于结束值'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-  }
-
-  // 列表输入验证
-  if (props.operator === 'in') {
-    if (listPreview.value.length === 0) {
-      isValid.value = false
-      validationMessage.value = '请输入至少一个值'
-      emit('validate', { valid: false, message: validationMessage.value })
-      return
-    }
-  }
-
-  // 验证通过
-  isValid.value = true
-  validationMessage.value = '输入值验证通过'
-  emit('validate', { valid: true, message: validationMessage.value })
-}
-
-// 监听值变化
-watch(
-  () => localValue.value,
-  () => {
-    validateValue()
-  }
-)
-
 // 监听操作符变化
 watch(
   () => props.operator,
@@ -363,11 +267,4 @@ watch(
     numberValue.value = undefined
   }
 )
-
-// 初始化
-onMounted(() => {
-  if (localValue.value) {
-    validateValue()
-  }
-})
 </script>

+ 78 - 13
src/views/iot/rule/scene/form/selectors/OperatorSelector.vue

@@ -35,7 +35,10 @@
 
 <script setup lang="ts">
 import { useVModel } from '@vueuse/core'
-import { IotRuleSceneTriggerConditionParameterOperatorEnum } from '@/views/iot/utils/constants'
+import {
+  IotRuleSceneTriggerConditionParameterOperatorEnum,
+  IoTDataSpecsDataTypeEnum
+} from '@/views/iot/utils/constants'
 
 /** 操作符选择器组件 */
 defineOptions({ name: 'OperatorSelector' })
@@ -60,7 +63,14 @@ const allOperators = [
     symbol: '=',
     description: '值完全相等时触发',
     example: 'temperature = 25',
-    supportedTypes: ['int', 'float', 'double', 'string', 'bool', 'enum']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.TEXT,
+      IoTDataSpecsDataTypeEnum.BOOL,
+      IoTDataSpecsDataTypeEnum.ENUM
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.value,
@@ -68,7 +78,14 @@ const allOperators = [
     symbol: '≠',
     description: '值不相等时触发',
     example: 'power != false',
-    supportedTypes: ['int', 'float', 'double', 'string', 'bool', 'enum']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.TEXT,
+      IoTDataSpecsDataTypeEnum.BOOL,
+      IoTDataSpecsDataTypeEnum.ENUM
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.value,
@@ -76,7 +93,12 @@ const allOperators = [
     symbol: '>',
     description: '值大于指定值时触发',
     example: 'temperature > 30',
-    supportedTypes: ['int', 'float', 'double', 'date']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.DATE
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.value,
@@ -84,7 +106,12 @@ const allOperators = [
     symbol: '≥',
     description: '值大于或等于指定值时触发',
     example: 'humidity >= 80',
-    supportedTypes: ['int', 'float', 'double', 'date']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.DATE
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.value,
@@ -92,7 +119,12 @@ const allOperators = [
     symbol: '<',
     description: '值小于指定值时触发',
     example: 'temperature < 10',
-    supportedTypes: ['int', 'float', 'double', 'date']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.DATE
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.value,
@@ -100,7 +132,12 @@ const allOperators = [
     symbol: '≤',
     description: '值小于或等于指定值时触发',
     example: 'battery <= 20',
-    supportedTypes: ['int', 'float', 'double', 'date']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.DATE
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.IN.value,
@@ -108,7 +145,12 @@ const allOperators = [
     symbol: '∈',
     description: '值在指定列表中时触发',
     example: 'status in [1,2,3]',
-    supportedTypes: ['int', 'float', 'string', 'enum']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.TEXT,
+      IoTDataSpecsDataTypeEnum.ENUM
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.value,
@@ -116,7 +158,12 @@ const allOperators = [
     symbol: '∉',
     description: '值不在指定列表中时触发',
     example: 'status not in [1,2,3]',
-    supportedTypes: ['int', 'float', 'string', 'enum']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.TEXT,
+      IoTDataSpecsDataTypeEnum.ENUM
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.value,
@@ -124,7 +171,12 @@ const allOperators = [
     symbol: '⊆',
     description: '值在指定范围内时触发',
     example: 'temperature between 20,30',
-    supportedTypes: ['int', 'float', 'double', 'date']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.DATE
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.value,
@@ -132,7 +184,12 @@ const allOperators = [
     symbol: '⊄',
     description: '值不在指定范围内时触发',
     example: 'temperature not between 20,30',
-    supportedTypes: ['int', 'float', 'double', 'date']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.DATE
+    ]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.LIKE.value,
@@ -140,7 +197,7 @@ const allOperators = [
     symbol: '≈',
     description: '字符串匹配指定模式时触发',
     example: 'message like "%error%"',
-    supportedTypes: ['string']
+    supportedTypes: [IoTDataSpecsDataTypeEnum.TEXT]
   },
   {
     value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_NULL.value,
@@ -148,7 +205,15 @@ const allOperators = [
     symbol: '≠∅',
     description: '值非空时触发',
     example: 'data not null',
-    supportedTypes: ['int', 'float', 'double', 'string', 'bool', 'enum', 'date']
+    supportedTypes: [
+      IoTDataSpecsDataTypeEnum.INT,
+      IoTDataSpecsDataTypeEnum.FLOAT,
+      IoTDataSpecsDataTypeEnum.DOUBLE,
+      IoTDataSpecsDataTypeEnum.TEXT,
+      IoTDataSpecsDataTypeEnum.BOOL,
+      IoTDataSpecsDataTypeEnum.ENUM,
+      IoTDataSpecsDataTypeEnum.DATE
+    ]
   }
 ]
 

+ 23 - 19
src/views/iot/rule/scene/form/selectors/PropertySelector.vue

@@ -159,7 +159,11 @@
 <script setup lang="ts">
 import { useVModel } from '@vueuse/core'
 import { InfoFilled } from '@element-plus/icons-vue'
-import { IotRuleSceneTriggerTypeEnum, IoTThingModelTypeEnum } from '@/views/iot/utils/constants'
+import {
+  IotRuleSceneTriggerTypeEnum,
+  IoTThingModelTypeEnum,
+  IoTDataSpecsDataTypeEnum
+} from '@/views/iot/utils/constants'
 import type {
   IotThingModelTSLResp,
   ThingModelEvent,
@@ -246,30 +250,30 @@ const selectedProperty = computed(() => {
 // 工具函数
 const getPropertyTypeName = (dataType: string) => {
   const typeMap = {
-    int: '整数',
-    float: '浮点数',
-    double: '双精度',
-    text: '字符串',
-    bool: '布尔值',
-    enum: '枚举',
-    date: '日期',
-    struct: '结构体',
-    array: '数组'
+    [IoTDataSpecsDataTypeEnum.INT]: '整数',
+    [IoTDataSpecsDataTypeEnum.FLOAT]: '浮点数',
+    [IoTDataSpecsDataTypeEnum.DOUBLE]: '双精度',
+    [IoTDataSpecsDataTypeEnum.TEXT]: '字符串',
+    [IoTDataSpecsDataTypeEnum.BOOL]: '布尔值',
+    [IoTDataSpecsDataTypeEnum.ENUM]: '枚举',
+    [IoTDataSpecsDataTypeEnum.DATE]: '日期',
+    [IoTDataSpecsDataTypeEnum.STRUCT]: '结构体',
+    [IoTDataSpecsDataTypeEnum.ARRAY]: '数组'
   }
   return typeMap[dataType] || dataType
 }
 
 const getPropertyTypeTag = (dataType: string) => {
   const tagMap = {
-    int: 'primary',
-    float: 'success',
-    double: 'success',
-    text: 'info',
-    bool: 'warning',
-    enum: 'danger',
-    date: 'primary',
-    struct: 'info',
-    array: 'warning'
+    [IoTDataSpecsDataTypeEnum.INT]: 'primary',
+    [IoTDataSpecsDataTypeEnum.FLOAT]: 'success',
+    [IoTDataSpecsDataTypeEnum.DOUBLE]: 'success',
+    [IoTDataSpecsDataTypeEnum.TEXT]: 'info',
+    [IoTDataSpecsDataTypeEnum.BOOL]: 'warning',
+    [IoTDataSpecsDataTypeEnum.ENUM]: 'danger',
+    [IoTDataSpecsDataTypeEnum.DATE]: 'primary',
+    [IoTDataSpecsDataTypeEnum.STRUCT]: 'info',
+    [IoTDataSpecsDataTypeEnum.ARRAY]: 'warning'
   }
   return tagMap[dataType] || 'info'
 }