perf:【IoT 物联网】场景联动触发器优化

This commit is contained in:
puhui999
2025-08-01 16:14:11 +08:00
parent c740da02b9
commit a554bc5309
11 changed files with 551 additions and 315 deletions

View File

@ -1,47 +1,97 @@
<template>
<el-card class="border border-[var(--el-border-color-light)] rounded-8px" shadow="never">
<!-- TODO @puhui999触发器还是多个每个触发器里面有事件类型 + 附加条件组最好文案上和阿里 iot 保持相对一致 -->
<el-card class="border border-[var(--el-border-color-light)] rounded-8px mb-10px" shadow="never">
<template #header>
<div class="flex items-center gap-8px">
<Icon icon="ep:lightning" class="text-[var(--el-color-primary)] text-18px" />
<span class="text-16px font-600 text-[var(--el-text-color-primary)]">触发器配置</span>
<el-tag size="small" type="info">场景触发器</el-tag>
<div class="flex items-center justify-between">
<div class="flex items-center gap-8px">
<Icon icon="ep:lightning" class="text-[var(--el-color-primary)] text-18px" />
<span class="text-16px font-600 text-[var(--el-text-color-primary)]">触发器配置</span>
<el-tag size="small" type="info">{{ triggers.length }} 个触发器</el-tag>
</div>
<el-button type="primary" size="small" @click="addTrigger">
<Icon icon="ep:plus" />
添加触发器
</el-button>
</div>
</template>
<div class="p-16px space-y-16px">
<!-- 触发事件类型选择 -->
<el-form-item label="触发事件类型" required>
<el-select
:model-value="trigger.type"
@update:model-value="(value) => updateTriggerType(value)"
@change="onTriggerTypeChange"
placeholder="请选择触发事件类型"
class="w-full"
<div class="p-16px space-y-24px">
<!-- 触发器列表 -->
<div v-if="triggers.length > 0" class="space-y-24px">
<div
v-for="(triggerItem, index) in triggers"
:key="`trigger-${index}`"
class="border border-[var(--el-border-color-light)] rounded-8px p-16px relative"
>
<el-option
v-for="option in triggerTypeOptions"
:key="option.value"
:label="option.label"
:value="option.value"
<!-- 触发器头部 -->
<div class="flex items-center justify-between mb-16px">
<div class="flex items-center gap-8px">
<span class="text-14px font-500 text-[var(--el-text-color-primary)]">
触发器 {{ index + 1 }}
</span>
<el-tag size="small" :type="getTriggerTagType(triggerItem.type)">
{{ getTriggerTypeLabel(triggerItem.type) }}
</el-tag>
</div>
<div class="flex items-center gap-8px">
<el-button
v-if="triggers.length > 1"
type="danger"
size="small"
text
@click="removeTrigger(index)"
>
<Icon icon="ep:delete" />
删除
</el-button>
</div>
</div>
<!-- 触发事件类型选择 -->
<el-form-item label="触发事件类型" required>
<el-select
:model-value="triggerItem.type"
@update:model-value="(value) => updateTriggerType(index, value)"
placeholder="请选择触发事件类型"
class="w-full"
>
<el-option
v-for="option in triggerTypeOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<!-- 设备触发配置 -->
<DeviceTriggerConfig
v-if="isDeviceTrigger(triggerItem.type)"
:model-value="triggerItem"
@update:model-value="(value) => updateTriggerDeviceConfig(index, value)"
/>
</el-select>
</el-form-item>
<!-- 设备触发配置 -->
<DeviceTriggerConfig
v-if="isDeviceTrigger(trigger.type)"
:model-value="trigger"
@update:model-value="updateTrigger"
/>
<!-- 定时触发配置 -->
<TimerTriggerConfig
v-else-if="triggerItem.type === TriggerTypeEnum.TIMER"
:model-value="triggerItem.cronExpression"
@update:model-value="(value) => updateTriggerCronConfig(index, value)"
/>
</div>
</div>
<!-- 定时触发配置 -->
<!-- TODO @puhui999这里要不 v-else 好了? -->
<TimerTriggerConfig
v-if="trigger.type === TriggerTypeEnum.TIMER"
:model-value="trigger.cronExpression"
@update:model-value="updateTriggerCronExpression"
/>
<!-- 空状态 -->
<div v-else class="py-40px text-center">
<el-empty description="暂无触发器">
<template #description>
<div class="space-y-8px">
<p class="text-[var(--el-text-color-secondary)]">暂无触发器配置</p>
<p class="text-12px text-[var(--el-text-color-placeholder)]">
请使用上方的"添加触发器"按钮来设置触发规则
</p>
</div>
</template>
</el-empty>
</div>
</div>
</el-card>
</template>
@ -50,108 +100,115 @@
import { useVModel } from '@vueuse/core'
import DeviceTriggerConfig from '../configs/DeviceTriggerConfig.vue'
import TimerTriggerConfig from '../configs/TimerTriggerConfig.vue'
import { TriggerFormData } from '@/api/iot/rule/scene/scene.types'
import {
TriggerFormData,
IotRuleSceneTriggerTypeEnum as TriggerTypeEnum
} from '@/api/iot/rule/scene/scene.types'
getTriggerTypeOptions,
IotRuleSceneTriggerTypeEnum as TriggerTypeEnum,
IotRuleSceneTriggerTypeEnum,
isDeviceTrigger
} from '@/views/iot/utils/constants'
/** 触发器配置组件 */
defineOptions({ name: 'TriggerSection' })
// TODO @puhui999下面的 PropsEmits 可以合并到变量那;
interface Props {
trigger: TriggerFormData
}
// PropsEmits 定义
const props = defineProps<{
triggers: TriggerFormData[]
}>()
interface Emits {
(e: 'update:trigger', value: TriggerFormData): void
}
const emit = defineEmits<{
'update:triggers': [value: TriggerFormData[]]
}>()
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
const triggers = useVModel(props, 'triggers', emit)
const trigger = useVModel(props, 'trigger', emit)
// 触发器类型选项
// TODO @puhui999/Users/yunai/Java/yudao-ui-admin-vue3/src/views/iot/utils/constants.ts
const triggerTypeOptions = [
{
value: TriggerTypeEnum.DEVICE_STATE_UPDATE,
label: '设备状态变更'
},
{
value: TriggerTypeEnum.DEVICE_PROPERTY_POST,
label: '设备属性上报'
},
{
value: TriggerTypeEnum.DEVICE_EVENT_POST,
label: '设备事件上报'
},
{
value: TriggerTypeEnum.DEVICE_SERVICE_INVOKE,
label: '设备服务调用'
},
{
value: TriggerTypeEnum.TIMER,
label: '定时触发'
}
]
// 触发器类型选项(从 constants 中获取)
const triggerTypeOptions = getTriggerTypeOptions()
// 工具函数
// TODO @puhui999/Users/yunai/Java/yudao-ui-admin-vue3/src/views/iot/utils/constants.ts
const isDeviceTrigger = (type: number) => {
const deviceTriggerTypes = [
TriggerTypeEnum.DEVICE_STATE_UPDATE,
TriggerTypeEnum.DEVICE_PROPERTY_POST,
TriggerTypeEnum.DEVICE_EVENT_POST,
TriggerTypeEnum.DEVICE_SERVICE_INVOKE
] as number[]
return deviceTriggerTypes.includes(type)
const getTriggerTypeLabel = (type: number): string => {
const option = triggerTypeOptions.find((opt) => opt.value === type)
return option?.label || '未知类型'
}
// 事件处理
const updateTriggerType = (type: number) => {
trigger.value.type = type
onTriggerTypeChange(type)
const getTriggerTagType = (type: number): string => {
if (type === IotRuleSceneTriggerTypeEnum.TIMER) {
return 'warning'
}
return isDeviceTrigger(type) ? 'success' : 'info'
}
// TODO @puhui999updateTriggerDeviceConfig
const updateTrigger = (newTrigger: TriggerFormData) => {
trigger.value = newTrigger
// 事件处理函数
const addTrigger = () => {
const newTrigger: TriggerFormData = {
type: TriggerTypeEnum.DEVICE_STATE_UPDATE,
productId: undefined,
deviceId: undefined,
identifier: undefined,
operator: undefined,
value: undefined,
cronExpression: undefined,
mainCondition: undefined,
conditionGroup: undefined
}
triggers.value.push(newTrigger)
}
// TODO @puhui999updateTriggerCronConfig
const updateTriggerCronExpression = (cronExpression?: string) => {
trigger.value.cronExpression = cronExpression
const removeTrigger = (index: number) => {
if (triggers.value.length > 1) {
triggers.value.splice(index, 1)
}
}
const onTriggerTypeChange = (type: number) => {
const updateTriggerType = (index: number, type: number) => {
triggers.value[index].type = type
onTriggerTypeChange(index, type)
}
const updateTriggerDeviceConfig = (index: number, newTrigger: TriggerFormData) => {
triggers.value[index] = newTrigger
}
const updateTriggerCronConfig = (index: number, cronExpression?: string) => {
triggers.value[index].cronExpression = cronExpression
}
const onTriggerTypeChange = (index: number, type: number) => {
const triggerItem = triggers.value[index]
// 清理不相关的配置
if (type === TriggerTypeEnum.TIMER) {
trigger.value.productId = undefined
trigger.value.deviceId = undefined
trigger.value.identifier = undefined
trigger.value.operator = undefined
trigger.value.value = undefined
trigger.value.mainCondition = undefined
trigger.value.conditionGroup = undefined
if (!trigger.value.cronExpression) {
trigger.value.cronExpression = '0 0 12 * * ?'
triggerItem.productId = undefined
triggerItem.deviceId = undefined
triggerItem.identifier = undefined
triggerItem.operator = undefined
triggerItem.value = undefined
triggerItem.mainCondition = undefined
triggerItem.conditionGroup = undefined
if (!triggerItem.cronExpression) {
triggerItem.cronExpression = '0 0 12 * * ?'
}
} else {
trigger.value.cronExpression = undefined
triggerItem.cronExpression = undefined
if (type === TriggerTypeEnum.DEVICE_STATE_UPDATE) {
trigger.value.mainCondition = undefined
trigger.value.conditionGroup = undefined
triggerItem.mainCondition = undefined
triggerItem.conditionGroup = undefined
} else {
// 设备属性、事件、服务触发需要条件配置
if (!trigger.value.mainCondition) {
trigger.value.mainCondition = undefined // 等待用户配置
if (!triggerItem.mainCondition) {
triggerItem.mainCondition = undefined // 等待用户配置
}
if (!trigger.value.conditionGroup) {
trigger.value.conditionGroup = undefined // 可选的条件组
if (!triggerItem.conditionGroup) {
triggerItem.conditionGroup = undefined // 可选的条件组
}
}
}
}
// 初始化:确保至少有一个触发器
onMounted(() => {
if (triggers.value.length === 0) {
addTrigger()
}
})
</script>