perf: 【IoT 物联网】场景联动优化 DeviceStatusConditionConfig 的内容直接内联在主组件中, 移除自定义校验

pull/808/head
puhui999 2025-08-07 15:44:05 +08:00
parent 18b4775e98
commit 09be0a10b1
2 changed files with 90 additions and 316 deletions

View File

@ -23,39 +23,75 @@
</el-col>
</el-row>
<!-- 设备状态条件配置 -->
<DeviceStatusConditionConfig
v-if="condition.type === ConditionTypeEnum.DEVICE_STATUS"
:model-value="condition"
@update:model-value="updateCondition"
@validate="handleValidate"
/>
<!-- 产品设备选择 - 设备相关条件的公共部分 -->
<el-row v-if="isDeviceCondition" :gutter="16">
<el-col :span="12">
<el-form-item label="产品" required>
<ProductSelector
:model-value="condition.productId"
@update:model-value="(value) => updateConditionField('productId', value)"
@change="handleProductChange"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备" required>
<DeviceSelector
:model-value="condition.deviceId"
@update:model-value="(value) => updateConditionField('deviceId', value)"
:product-id="condition.productId"
@change="handleDeviceChange"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 设备属性条件配置 -->
<div v-else-if="condition.type === ConditionTypeEnum.DEVICE_PROPERTY" class="space-y-16px">
<!-- 产品设备选择 -->
<!-- 设备状态条件配置 -->
<div v-if="condition.type === ConditionTypeEnum.DEVICE_STATUS" class="flex flex-col gap-16px">
<!-- 状态和操作符选择 -->
<el-row :gutter="16">
<!-- 操作符选择 -->
<el-col :span="12">
<el-form-item label="产品" required>
<ProductSelector
:model-value="condition.productId"
@update:model-value="(value) => updateConditionField('productId', value)"
@change="handleProductChange"
/>
<el-form-item label="操作符" required>
<el-select
:model-value="condition.operator"
@update:model-value="(value) => updateConditionField('operator', value)"
placeholder="请选择操作符"
class="w-full"
>
<el-option
v-for="option in statusOperatorOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
</el-col>
<!-- 状态选择 -->
<el-col :span="12">
<el-form-item label="设备" required>
<DeviceSelector
:model-value="condition.deviceId"
@update:model-value="(value) => updateConditionField('deviceId', value)"
:product-id="condition.productId"
@change="handleDeviceChange"
/>
<el-form-item label="设备状态" required>
<el-select
:model-value="condition.param"
@update:model-value="(value) => updateConditionField('param', value)"
placeholder="请选择设备状态"
class="w-full"
>
<el-option
v-for="option in deviceStatusOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 设备属性条件配置 -->
<div v-else-if="condition.type === ConditionTypeEnum.DEVICE_PROPERTY" class="space-y-16px">
<!-- 属性配置 -->
<el-row :gutter="16">
<!-- 属性/事件/服务选择 -->
@ -94,7 +130,6 @@
:property-type="propertyType"
:operator="condition.operator"
:property-config="propertyConfig"
@validate="handleValueValidate"
/>
</el-form-item>
</el-col>
@ -106,24 +141,12 @@
v-else-if="condition.type === ConditionTypeEnum.CURRENT_TIME"
:model-value="condition"
@update:model-value="updateCondition"
@validate="handleValidate"
/>
<!-- 验证结果 -->
<div v-if="validationMessage" class="mt-8px">
<el-alert
:title="validationMessage"
:type="isValid ? 'success' : 'error'"
:closable="false"
show-icon
/>
</div>
</div>
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import DeviceStatusConditionConfig from './DeviceStatusConditionConfig.vue'
import CurrentTimeConditionConfig from './CurrentTimeConditionConfig.vue'
import ProductSelector from '../selectors/ProductSelector.vue'
import DeviceSelector from '../selectors/DeviceSelector.vue'
@ -146,7 +169,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)
@ -170,12 +192,40 @@ const conditionTypeOptions = [
}
]
//
const deviceStatusOptions = [
{
value: 'online',
label: '在线'
},
{
value: 'offline',
label: '离线'
}
]
//
const statusOperatorOptions = [
{
value: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value,
label: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.name
},
{
value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.value,
label: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.name
}
]
//
const propertyType = ref<string>('string')
const propertyConfig = ref<any>(null)
const validationMessage = ref('')
const isValid = ref(true)
const valueValidation = ref({ valid: true, message: '' })
//
const isDeviceCondition = computed(() => {
return (
condition.value.type === ConditionTypeEnum.DEVICE_STATUS ||
condition.value.type === ConditionTypeEnum.DEVICE_PROPERTY
)
})
//
const updateConditionField = (field: keyof TriggerCondition, value: any) => {
@ -216,27 +266,17 @@ const handleConditionTypeChange = (type: number) => {
// 使
condition.value.operator = IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value
condition.value.param = ''
updateValidationResult()
}
const handleValidate = (result: { valid: boolean; message: string }) => {
isValid.value = result.valid
validationMessage.value = result.message
emit('validate', result)
}
const handleProductChange = (_: number) => {
//
condition.value.deviceId = undefined
condition.value.identifier = ''
updateValidationResult()
}
const handleDeviceChange = (_: number) => {
//
condition.value.identifier = ''
updateValidationResult()
}
const handlePropertyChange = (propertyInfo: { type: string; config: any }) => {
@ -246,71 +286,12 @@ const handlePropertyChange = (propertyInfo: { type: string; config: any }) => {
//
condition.value.operator = '='
condition.value.param = ''
updateValidationResult()
}
const handleOperatorChange = () => {
//
condition.value.param = ''
updateValidationResult()
}
const handleValueValidate = (result: { valid: boolean; message: string }) => {
valueValidation.value = result
updateValidationResult()
}
const updateValidationResult = () => {
//
if (!condition.value.identifier) {
isValid.value = false
validationMessage.value = '请选择监控项'
emit('validate', { valid: false, message: validationMessage.value })
return
}
if (!condition.value.operator) {
isValid.value = false
validationMessage.value = '请选择操作符'
emit('validate', { valid: false, message: validationMessage.value })
return
}
if (!condition.value.param) {
isValid.value = false
validationMessage.value = '请输入比较值'
emit('validate', { valid: false, message: validationMessage.value })
return
}
//
if (!valueValidation.value.valid) {
isValid.value = false
validationMessage.value = valueValidation.value.message
emit('validate', { valid: false, message: validationMessage.value })
return
}
//
isValid.value = true
validationMessage.value = '条件配置验证通过'
emit('validate', { valid: true, message: validationMessage.value })
}
//
watch(
() => [condition.value.identifier, condition.value.operator, condition.value.param],
() => {
updateValidationResult()
},
{ deep: true }
)
//
onMounted(() => {
updateValidationResult()
})
</script>
<style scoped>

View File

@ -1,207 +0,0 @@
<!-- 设备状态条件配置组件 -->
<template>
<div class="flex flex-col gap-16px">
<!-- 产品设备选择 -->
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="产品" required>
<ProductSelector
:model-value="condition.productId"
@update:model-value="(value) => updateConditionField('productId', value)"
@change="handleProductChange"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备" required>
<DeviceSelector
:model-value="condition.deviceId"
@update:model-value="(value) => updateConditionField('deviceId', value)"
:product-id="condition.productId"
@change="handleDeviceChange"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 状态和操作符选择 -->
<el-row :gutter="16">
<!-- 操作符选择 -->
<el-col :span="12">
<el-form-item label="操作符" required>
<el-select
:model-value="condition.operator"
@update:model-value="(value) => updateConditionField('operator', value)"
placeholder="请选择操作符"
class="w-full"
>
<el-option
v-for="option in statusOperatorOptions"
:key="option.value"
:label="option.label"
:value="option.value"
>
<div class="flex items-center justify-between w-full">
<span>{{ option.label }}</span>
<span class="text-12px text-[var(--el-text-color-secondary)]">
{{ option.description }}
</span>
</div>
</el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 状态选择 -->
<el-col :span="12">
<el-form-item label="设备状态" required>
<el-select
:model-value="condition.param"
@update:model-value="(value) => updateConditionField('param', value)"
placeholder="请选择设备状态"
class="w-full"
>
<el-option
v-for="option in deviceStatusOptions"
:key="option.value"
:label="option.label"
:value="option.value"
>
<div class="flex items-center gap-8px">
<Icon :icon="option.icon" :class="option.iconClass" />
<span>{{ option.label }}</span>
<el-tag :type="option.tag" size="small">{{ option.description }}</el-tag>
</div>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import ProductSelector from '../selectors/ProductSelector.vue'
import DeviceSelector from '../selectors/DeviceSelector.vue'
import type { TriggerCondition } from '@/api/iot/rule/scene'
/** 设备状态条件配置组件 */
defineOptions({ name: 'DeviceStatusConditionConfig' })
const props = defineProps<{
modelValue: TriggerCondition
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: TriggerCondition): void
(e: 'validate', result: { valid: boolean; message: string }): void
}>()
const condition = useVModel(props, 'modelValue', emit)
//
// TODO @puhui999
const deviceStatusOptions = [
{
value: 'online',
label: '在线',
description: '设备已连接',
icon: 'ep:circle-check',
iconClass: 'text-green-500',
tag: 'success'
},
{
value: 'offline',
label: '离线',
description: '设备已断开',
icon: 'ep:circle-close',
iconClass: 'text-red-500',
tag: 'danger'
}
]
//
// TODO @puhui999valuelabel
const statusOperatorOptions = [
{
value: '=',
label: '等于',
description: '状态完全匹配时触发'
},
{
value: '!=',
label: '不等于',
description: '状态不匹配时触发'
}
]
//
const validationMessage = ref('')
const isValid = ref(true)
//
const updateConditionField = (field: any, value: any) => {
condition.value[field] = value
updateValidationResult()
}
const handleProductChange = (_: number) => {
//
condition.value.deviceId = undefined
updateValidationResult()
}
const handleDeviceChange = (_: number) => {
//
updateValidationResult()
}
const updateValidationResult = () => {
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.param) {
isValid.value = false
validationMessage.value = '请选择设备状态'
emit('validate', { valid: false, message: validationMessage.value })
return
}
if (!condition.value.operator) {
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.param,
condition.value.operator
],
() => {
updateValidationResult()
},
{ immediate: true }
)
</script>