|
@@ -1,47 +1,97 @@
|
|
|
<template>
|
|
<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>
|
|
<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>
|
|
</div>
|
|
|
</template>
|
|
</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"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <!-- 定时触发配置 -->
|
|
|
|
|
- <!-- TODO @puhui999:这里要不 v-else 好了? -->
|
|
|
|
|
- <TimerTriggerConfig
|
|
|
|
|
- v-if="trigger.type === TriggerTypeEnum.TIMER"
|
|
|
|
|
- :model-value="trigger.cronExpression"
|
|
|
|
|
- @update:model-value="updateTriggerCronExpression"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 定时触发配置 -->
|
|
|
|
|
+ <TimerTriggerConfig
|
|
|
|
|
+ v-else-if="triggerItem.type === TriggerTypeEnum.TIMER"
|
|
|
|
|
+ :model-value="triggerItem.cronExpression"
|
|
|
|
|
+ @update:model-value="(value) => updateTriggerCronConfig(index, value)"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 空状态 -->
|
|
|
|
|
+ <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>
|
|
</div>
|
|
|
</el-card>
|
|
</el-card>
|
|
|
</template>
|
|
</template>
|
|
@@ -50,108 +100,115 @@
|
|
|
import { useVModel } from '@vueuse/core'
|
|
import { useVModel } from '@vueuse/core'
|
|
|
import DeviceTriggerConfig from '../configs/DeviceTriggerConfig.vue'
|
|
import DeviceTriggerConfig from '../configs/DeviceTriggerConfig.vue'
|
|
|
import TimerTriggerConfig from '../configs/TimerTriggerConfig.vue'
|
|
import TimerTriggerConfig from '../configs/TimerTriggerConfig.vue'
|
|
|
|
|
+import { TriggerFormData } from '@/api/iot/rule/scene/scene.types'
|
|
|
import {
|
|
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' })
|
|
defineOptions({ name: 'TriggerSection' })
|
|
|
|
|
|
|
|
-// TODO @puhui999:下面的 Props、Emits 可以合并到变量那;
|
|
|
|
|
-interface Props {
|
|
|
|
|
- trigger: TriggerFormData
|
|
|
|
|
|
|
+// Props 和 Emits 定义
|
|
|
|
|
+const props = defineProps<{
|
|
|
|
|
+ triggers: TriggerFormData[]
|
|
|
|
|
+}>()
|
|
|
|
|
+
|
|
|
|
|
+const emit = defineEmits<{
|
|
|
|
|
+ 'update:triggers': [value: TriggerFormData[]]
|
|
|
|
|
+}>()
|
|
|
|
|
+
|
|
|
|
|
+const triggers = useVModel(props, 'triggers', emit)
|
|
|
|
|
+
|
|
|
|
|
+// 触发器类型选项(从 constants 中获取)
|
|
|
|
|
+const triggerTypeOptions = getTriggerTypeOptions()
|
|
|
|
|
+
|
|
|
|
|
+// 工具函数
|
|
|
|
|
+const getTriggerTypeLabel = (type: number): string => {
|
|
|
|
|
+ const option = triggerTypeOptions.find((opt) => opt.value === type)
|
|
|
|
|
+ return option?.label || '未知类型'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-interface Emits {
|
|
|
|
|
- (e: 'update:trigger', value: TriggerFormData): void
|
|
|
|
|
|
|
+const getTriggerTagType = (type: number): string => {
|
|
|
|
|
+ if (type === IotRuleSceneTriggerTypeEnum.TIMER) {
|
|
|
|
|
+ return 'warning'
|
|
|
|
|
+ }
|
|
|
|
|
+ return isDeviceTrigger(type) ? 'success' : 'info'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const props = defineProps<Props>()
|
|
|
|
|
-const emit = defineEmits<Emits>()
|
|
|
|
|
-
|
|
|
|
|
-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: '定时触发'
|
|
|
|
|
|
|
+// 事件处理函数
|
|
|
|
|
+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 @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 removeTrigger = (index: number) => {
|
|
|
|
|
+ if (triggers.value.length > 1) {
|
|
|
|
|
+ triggers.value.splice(index, 1)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 事件处理
|
|
|
|
|
-const updateTriggerType = (type: number) => {
|
|
|
|
|
- trigger.value.type = type
|
|
|
|
|
- onTriggerTypeChange(type)
|
|
|
|
|
|
|
+const updateTriggerType = (index: number, type: number) => {
|
|
|
|
|
+ triggers.value[index].type = type
|
|
|
|
|
+ onTriggerTypeChange(index, type)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// TODO @puhui999:updateTriggerDeviceConfig
|
|
|
|
|
-const updateTrigger = (newTrigger: TriggerFormData) => {
|
|
|
|
|
- trigger.value = newTrigger
|
|
|
|
|
|
|
+const updateTriggerDeviceConfig = (index: number, newTrigger: TriggerFormData) => {
|
|
|
|
|
+ triggers.value[index] = newTrigger
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// TODO @puhui999:updateTriggerCronConfig
|
|
|
|
|
-const updateTriggerCronExpression = (cronExpression?: string) => {
|
|
|
|
|
- trigger.value.cronExpression = cronExpression
|
|
|
|
|
|
|
+const updateTriggerCronConfig = (index: number, cronExpression?: string) => {
|
|
|
|
|
+ triggers.value[index].cronExpression = cronExpression
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const onTriggerTypeChange = (type: number) => {
|
|
|
|
|
|
|
+const onTriggerTypeChange = (index: number, type: number) => {
|
|
|
|
|
+ const triggerItem = triggers.value[index]
|
|
|
|
|
+
|
|
|
// 清理不相关的配置
|
|
// 清理不相关的配置
|
|
|
if (type === TriggerTypeEnum.TIMER) {
|
|
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 {
|
|
} else {
|
|
|
- trigger.value.cronExpression = undefined
|
|
|
|
|
|
|
+ triggerItem.cronExpression = undefined
|
|
|
if (type === TriggerTypeEnum.DEVICE_STATE_UPDATE) {
|
|
if (type === TriggerTypeEnum.DEVICE_STATE_UPDATE) {
|
|
|
- trigger.value.mainCondition = undefined
|
|
|
|
|
- trigger.value.conditionGroup = undefined
|
|
|
|
|
|
|
+ triggerItem.mainCondition = undefined
|
|
|
|
|
+ triggerItem.conditionGroup = undefined
|
|
|
} else {
|
|
} 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>
|
|
</script>
|