admin-vue3/src/views/iot/rule/scene/form/configs/ConditionConfig.vue

302 lines
9.2 KiB
Vue

<!-- 单个条件配置组件 -->
<template>
<div class="flex flex-col gap-16px">
<!-- 条件类型选择 -->
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="条件类型" required>
<el-select
:model-value="condition.type"
@update:model-value="(value) => updateConditionField('type', value)"
@change="handleConditionTypeChange"
placeholder="请选择条件类型"
class="w-full"
>
<el-option
v-for="option in getConditionTypeOptions()"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 产品设备选择 - 设备相关条件的公共部分 -->
<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-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS"
class="flex flex-col gap-16px"
>
<!-- 状态和操作符选择 -->
<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"
/>
</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"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 设备属性条件配置 -->
<div
v-else-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY"
class="space-y-16px"
>
<!-- 属性配置 -->
<el-row :gutter="16">
<!-- 属性/事件/服务选择 -->
<el-col :span="6">
<el-form-item label="监控项" required>
<PropertySelector
:model-value="condition.identifier"
@update:model-value="(value) => updateConditionField('identifier', value)"
:trigger-type="triggerType"
:product-id="condition.productId"
:device-id="condition.deviceId"
@change="handlePropertyChange"
/>
</el-form-item>
</el-col>
<!-- 操作符选择 -->
<el-col :span="6">
<el-form-item label="操作符" required>
<OperatorSelector
:model-value="condition.operator"
@update:model-value="(value) => updateConditionField('operator', value)"
:property-type="propertyType"
@change="handleOperatorChange"
/>
</el-form-item>
</el-col>
<!-- 值输入 -->
<el-col :span="12">
<el-form-item label="比较值" required>
<ValueInput
:model-value="condition.param"
@update:model-value="(value) => updateConditionField('param', value)"
:property-type="propertyType"
:operator="condition.operator"
:property-config="propertyConfig"
/>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 当前时间条件配置 -->
<CurrentTimeConditionConfig
v-else-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME"
:model-value="condition"
@update:model-value="updateCondition"
/>
</div>
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import CurrentTimeConditionConfig from './CurrentTimeConditionConfig.vue'
import ProductSelector from '../selectors/ProductSelector.vue'
import DeviceSelector from '../selectors/DeviceSelector.vue'
import PropertySelector from '../selectors/PropertySelector.vue'
import OperatorSelector from '../selectors/OperatorSelector.vue'
import ValueInput from '../inputs/ValueInput.vue'
import type { TriggerCondition } from '@/api/iot/rule/scene'
import {
IotRuleSceneTriggerConditionTypeEnum,
IotRuleSceneTriggerConditionParameterOperatorEnum,
getConditionTypeOptions,
IoTDeviceStatusEnum
} from '@/views/iot/utils/constants'
/** 单个条件配置组件 */
defineOptions({ name: 'ConditionConfig' })
const props = defineProps<{
modelValue: TriggerCondition
triggerType: number
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: TriggerCondition): void
}>()
/** 获取设备状态选项 */
const deviceStatusOptions = [
{
value: IoTDeviceStatusEnum.ONLINE.value,
label: IoTDeviceStatusEnum.ONLINE.label
},
{
value: IoTDeviceStatusEnum.OFFLINE.value,
label: IoTDeviceStatusEnum.OFFLINE.label
}
]
/** 获取状态操作符选项 */
const statusOperatorOptions = [
{
value: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value,
label: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.name
},
{
value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.value,
label: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.name
}
]
const condition = useVModel(props, 'modelValue', emit)
const propertyType = ref<string>('string') // 属性类型
const propertyConfig = ref<any>(null) // 属性配置
const isDeviceCondition = computed(() => {
return (
condition.value.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS ||
condition.value.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY
)
}) // 计算属性:判断是否为设备相关条件
/**
* 更新条件字段
* @param field 字段名
* @param value 字段值
*/
const updateConditionField = (field: any, value: any) => {
;(condition.value as any)[field] = value
emit('update:modelValue', condition.value)
}
/**
* 更新整个条件对象
* @param newCondition 新的条件对象
*/
const updateCondition = (newCondition: TriggerCondition) => {
condition.value = newCondition
emit('update:modelValue', condition.value)
}
/**
* 处理条件类型变化事件
* @param type 条件类型
*/
const handleConditionTypeChange = (type: number) => {
// 根据条件类型清理字段
const isCurrentTime = type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME
const isDeviceStatus = type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS
// 清理标识符字段(时间条件和设备状态条件都不需要)
if (isCurrentTime || isDeviceStatus) {
condition.value.identifier = undefined
}
// 清理设备相关字段(仅时间条件需要)
if (isCurrentTime) {
condition.value.productId = undefined
condition.value.deviceId = undefined
}
// 设置默认操作符
condition.value.operator = isCurrentTime
? 'at_time'
: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value
// 清空参数值
condition.value.param = ''
}
/** 处理产品变化事件 */
const handleProductChange = (_: number) => {
// 产品变化时清空设备和属性
condition.value.deviceId = undefined
condition.value.identifier = ''
}
/** 处理设备变化事件 */
const handleDeviceChange = (_: number) => {
// 设备变化时清空属性
condition.value.identifier = ''
}
/**
* 处理属性变化事件
* @param propertyInfo 属性信息对象
*/
const handlePropertyChange = (propertyInfo: { type: string; config: any }) => {
propertyType.value = propertyInfo.type
propertyConfig.value = propertyInfo.config
// 重置操作符和值
condition.value.operator = IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value
condition.value.param = ''
}
/** 处理操作符变化事件 */
const handleOperatorChange = () => {
// 重置值
condition.value.param = ''
}
</script>
<style scoped>
:deep(.el-form-item) {
margin-bottom: 0;
}
</style>