mirror of
https://github.com/yudaocode/yudao-ui-admin-vue3.git
synced 2026-03-29 23:25:52 +00:00
feat(iot):【场景联动】定时触发,增加条件组
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
<!-- 定时触发器条件组配置组件 -->
|
||||
<template>
|
||||
<div class="space-y-16px">
|
||||
<!-- 条件组容器头部 -->
|
||||
<div
|
||||
class="flex items-center justify-between p-16px bg-gradient-to-r from-blue-50 to-cyan-50 border border-blue-200 rounded-8px"
|
||||
>
|
||||
<div class="flex items-center gap-12px">
|
||||
<div class="flex items-center gap-8px text-16px font-600 text-blue-700">
|
||||
<div
|
||||
class="w-24px h-24px bg-blue-500 text-white rounded-full flex items-center justify-center text-12px font-bold"
|
||||
>
|
||||
组
|
||||
</div>
|
||||
<span>附加条件组</span>
|
||||
</div>
|
||||
<el-tag size="small" type="info">定时触发时需满足以下条件</el-tag>
|
||||
<el-tag size="small" type="warning">
|
||||
{{ conditionGroups?.length || 0 }} 个子条件组
|
||||
</el-tag>
|
||||
</div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="addConditionGroup"
|
||||
:disabled="(conditionGroups?.length || 0) >= maxGroups"
|
||||
>
|
||||
<Icon icon="ep:plus" />
|
||||
添加条件组
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 条件组列表 -->
|
||||
<div v-if="conditionGroups && conditionGroups.length > 0" class="space-y-16px">
|
||||
<div
|
||||
v-for="(group, groupIndex) in conditionGroups"
|
||||
:key="`group-${groupIndex}`"
|
||||
class="relative"
|
||||
>
|
||||
<!-- 条件组容器 -->
|
||||
<div
|
||||
class="border-2 border-orange-200 rounded-8px bg-orange-50 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-between p-16px bg-gradient-to-r from-orange-50 to-yellow-50 border-b border-orange-200 rounded-t-6px"
|
||||
>
|
||||
<div class="flex items-center gap-12px">
|
||||
<div class="flex items-center gap-8px text-16px font-600 text-orange-700">
|
||||
<div
|
||||
class="w-24px h-24px bg-orange-500 text-white rounded-full flex items-center justify-center text-12px font-bold"
|
||||
>
|
||||
{{ groupIndex + 1 }}
|
||||
</div>
|
||||
<span>子条件组 {{ groupIndex + 1 }}</span>
|
||||
</div>
|
||||
<el-tag size="small" type="warning" class="font-500">组内条件为"且"关系</el-tag>
|
||||
<el-tag size="small" type="info"> {{ group?.length || 0 }}个条件 </el-tag>
|
||||
</div>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
text
|
||||
@click="removeConditionGroup(groupIndex)"
|
||||
class="hover:bg-red-50"
|
||||
>
|
||||
<Icon icon="ep:delete" />
|
||||
删除组
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<SubConditionGroupConfig
|
||||
:model-value="group"
|
||||
@update:model-value="(value) => updateConditionGroup(groupIndex, value)"
|
||||
:trigger-type="IotRuleSceneTriggerTypeEnum.TIMER"
|
||||
:max-conditions="maxConditionsPerGroup"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 条件组间的"或"连接符 -->
|
||||
<div
|
||||
v-if="groupIndex < conditionGroups.length - 1"
|
||||
class="flex items-center justify-center py-12px"
|
||||
>
|
||||
<div class="flex items-center gap-8px">
|
||||
<!-- 连接线 -->
|
||||
<div class="w-32px h-1px bg-orange-300"></div>
|
||||
<!-- 或标签 -->
|
||||
<div class="px-16px py-6px bg-orange-100 border-2 border-orange-300 rounded-full">
|
||||
<span class="text-14px font-600 text-orange-600">或</span>
|
||||
</div>
|
||||
<!-- 连接线 -->
|
||||
<div class="w-32px h-1px bg-orange-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div
|
||||
v-else
|
||||
class="p-24px border-2 border-dashed border-blue-200 rounded-8px text-center bg-blue-50"
|
||||
>
|
||||
<div class="flex flex-col items-center gap-12px">
|
||||
<Icon icon="ep:plus" class="text-32px text-blue-400" />
|
||||
<div class="text-blue-600">
|
||||
<p class="text-14px font-500 mb-4px">暂无附加条件</p>
|
||||
<p class="text-12px">定时触发时将直接执行动作</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useVModel } from '@vueuse/core'
|
||||
import SubConditionGroupConfig from './SubConditionGroupConfig.vue'
|
||||
import type { TriggerCondition } from '@/api/iot/rule/scene'
|
||||
import { IotRuleSceneTriggerTypeEnum } from '@/views/iot/utils/constants'
|
||||
|
||||
/** 定时触发器条件组配置组件 */
|
||||
defineOptions({ name: 'TimerConditionGroupConfig' })
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: TriggerCondition[][]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: TriggerCondition[][]): void
|
||||
}>()
|
||||
|
||||
const conditionGroups = useVModel(props, 'modelValue', emit)
|
||||
|
||||
const maxGroups = 3 // 最多 3 个条件组
|
||||
const maxConditionsPerGroup = 3 // 每组最多 3 个条件
|
||||
|
||||
/** 添加条件组 */
|
||||
const addConditionGroup = async () => {
|
||||
if (!conditionGroups.value) {
|
||||
conditionGroups.value = []
|
||||
}
|
||||
|
||||
// 检查是否达到最大条件组数量限制
|
||||
if (conditionGroups.value.length >= maxGroups) {
|
||||
return
|
||||
}
|
||||
|
||||
// 使用 nextTick 确保响应式更新完成后再添加新的条件组
|
||||
await nextTick()
|
||||
if (conditionGroups.value) {
|
||||
conditionGroups.value.push([])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除条件组
|
||||
* @param index 条件组索引
|
||||
*/
|
||||
const removeConditionGroup = (index: number) => {
|
||||
if (conditionGroups.value) {
|
||||
conditionGroups.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新条件组
|
||||
* @param index 条件组索引
|
||||
* @param group 条件组数据
|
||||
*/
|
||||
const updateConditionGroup = (index: number, group: TriggerCondition[]) => {
|
||||
if (conditionGroups.value) {
|
||||
conditionGroups.value[index] = group
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -90,6 +90,12 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<!-- 附加条件组配置 -->
|
||||
<TimerConditionGroupConfig
|
||||
:model-value="triggerItem.conditionGroups"
|
||||
@update:model-value="(value) => updateTriggerConditionGroups(index, value)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -115,8 +121,9 @@
|
||||
<script setup lang="ts">
|
||||
import { useVModel } from '@vueuse/core'
|
||||
import DeviceTriggerConfig from '../configs/DeviceTriggerConfig.vue'
|
||||
import TimerConditionGroupConfig from '../configs/TimerConditionGroupConfig.vue'
|
||||
import { Crontab } from '@/components/Crontab'
|
||||
import type { Trigger } from '@/api/iot/rule/scene'
|
||||
import type { Trigger, TriggerCondition } from '@/api/iot/rule/scene'
|
||||
import {
|
||||
getTriggerTypeLabel,
|
||||
IotRuleSceneTriggerTypeEnum,
|
||||
@@ -197,6 +204,15 @@ const updateTriggerCronConfig = (index: number, cronExpression?: string) => {
|
||||
triggers.value[index].cronExpression = cronExpression
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新触发器条件组配置
|
||||
* @param index 触发器索引
|
||||
* @param conditionGroups 条件组数组
|
||||
*/
|
||||
const updateTriggerConditionGroups = (index: number, conditionGroups: TriggerCondition[][]) => {
|
||||
triggers.value[index].conditionGroups = conditionGroups
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理触发器类型变化事件
|
||||
* @param index 触发器索引
|
||||
|
||||
@@ -219,13 +219,23 @@ const thingModelTSL = ref<IotThingModelTSLResp | null>(null) // 物模型TSL数
|
||||
const propertyGroups = computed(() => {
|
||||
const groups: { label: string; options: any[] }[] = []
|
||||
|
||||
if (props.triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST) {
|
||||
groups.push({
|
||||
label: THING_MODEL_GROUP_LABELS.PROPERTY,
|
||||
options: propertyList.value.filter((p) => p.type === IoTThingModelTypeEnum.PROPERTY)
|
||||
})
|
||||
// 设备属性上报触发器 或 定时触发器(条件组中的设备属性条件)
|
||||
if (
|
||||
props.triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST ||
|
||||
props.triggerType === IotRuleSceneTriggerTypeEnum.TIMER
|
||||
) {
|
||||
const propertyOptions = propertyList.value.filter(
|
||||
(p) => p.type === IoTThingModelTypeEnum.PROPERTY
|
||||
)
|
||||
if (propertyOptions.length > 0) {
|
||||
groups.push({
|
||||
label: THING_MODEL_GROUP_LABELS.PROPERTY,
|
||||
options: propertyOptions
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 设备事件上报触发器
|
||||
if (props.triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST) {
|
||||
groups.push({
|
||||
label: THING_MODEL_GROUP_LABELS.EVENT,
|
||||
@@ -233,6 +243,7 @@ const propertyGroups = computed(() => {
|
||||
})
|
||||
}
|
||||
|
||||
// 设备服务调用触发器
|
||||
if (props.triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE) {
|
||||
groups.push({
|
||||
label: THING_MODEL_GROUP_LABELS.SERVICE,
|
||||
|
||||
Reference in New Issue
Block a user