From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/iot/rule/scene/form/sections/TriggerSection.vue |  222 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 222 insertions(+), 0 deletions(-)

diff --git a/src/views/iot/rule/scene/form/sections/TriggerSection.vue b/src/views/iot/rule/scene/form/sections/TriggerSection.vue
new file mode 100644
index 0000000..144d53c
--- /dev/null
+++ b/src/views/iot/rule/scene/form/sections/TriggerSection.vue
@@ -0,0 +1,222 @@
+<template>
+  <el-card class="border border-[var(--el-border-color-light)] rounded-8px mb-10px" shadow="never">
+    <template #header>
+      <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-24px">
+      <!-- 瑙﹀彂鍣ㄥ垪琛� -->
+      <div v-if="triggers.length > 0" class="space-y-24px">
+        <div
+          v-for="(triggerItem, index) in triggers"
+          :key="`trigger-${index}`"
+          class="border-2 border-green-200 rounded-8px bg-green-50 shadow-sm hover:shadow-md transition-shadow"
+        >
+          <!-- 瑙﹀彂鍣ㄥご閮� - 缁胯壊涓婚 -->
+          <div
+            class="flex items-center justify-between p-16px bg-gradient-to-r from-green-50 to-emerald-50 border-b border-green-200 rounded-t-6px"
+          >
+            <div class="flex items-center gap-12px">
+              <div class="flex items-center gap-8px text-16px font-600 text-green-700">
+                <div
+                  class="w-24px h-24px bg-green-500 text-white rounded-full flex items-center justify-center text-12px font-bold"
+                >
+                  {{ index + 1 }}
+                </div>
+                <span>瑙﹀彂鍣� {{ index + 1 }}</span>
+              </div>
+              <el-tag size="small" :type="getTriggerTagType(triggerItem.type)" class="font-500">
+                {{ 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)"
+                class="hover:bg-red-50"
+              >
+                <Icon icon="ep:delete" />
+                鍒犻櫎
+              </el-button>
+            </div>
+          </div>
+
+          <!-- 瑙﹀彂鍣ㄥ唴瀹瑰尯鍩� -->
+          <div class="p-16px space-y-16px">
+            <!-- 璁惧瑙﹀彂閰嶇疆 -->
+            <DeviceTriggerConfig
+              v-if="isDeviceTrigger(triggerItem.type)"
+              :model-value="triggerItem"
+              :index="index"
+              @update:model-value="(value) => updateTriggerDeviceConfig(index, value)"
+              @trigger-type-change="(type) => updateTriggerType(index, type)"
+            />
+
+            <!-- 瀹氭椂瑙﹀彂閰嶇疆 -->
+            <div
+              v-else-if="triggerItem.type === IotRuleSceneTriggerTypeEnum.TIMER"
+              class="flex flex-col gap-16px"
+            >
+              <div
+                class="flex items-center gap-8px p-12px px-16px bg-[var(--el-fill-color-light)] rounded-6px border border-[var(--el-border-color-lighter)]"
+              >
+                <Icon icon="ep:timer" class="text-[var(--el-color-danger)] text-18px" />
+                <span class="text-14px font-500 text-[var(--el-text-color-primary)]"
+                  >瀹氭椂瑙﹀彂閰嶇疆</span
+                >
+              </div>
+
+              <!-- CRON 琛ㄨ揪寮忛厤缃� -->
+              <div
+                class="p-16px border border-[var(--el-border-color-lighter)] rounded-6px bg-[var(--el-fill-color-blank)]"
+              >
+                <el-form-item label="CRON琛ㄨ揪寮�" required>
+                  <Crontab
+                    :model-value="triggerItem.cronExpression || '0 0 12 * * ?'"
+                    @update:model-value="(value) => updateTriggerCronConfig(index, value)"
+                  />
+                </el-form-item>
+              </div>
+            </div>
+          </div>
+        </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>
+  </el-card>
+</template>
+
+<script setup lang="ts">
+import { useVModel } from '@vueuse/core'
+import DeviceTriggerConfig from '../configs/DeviceTriggerConfig.vue'
+import { Crontab } from '@/components/Crontab'
+import type { Trigger } from '@/api/iot/rule/scene'
+import {
+  getTriggerTypeLabel,
+  IotRuleSceneTriggerTypeEnum,
+  isDeviceTrigger
+} from '@/views/iot/utils/constants'
+
+/** 瑙﹀彂鍣ㄩ厤缃粍浠� */
+defineOptions({ name: 'TriggerSection' })
+
+const props = defineProps<{
+  triggers: Trigger[]
+}>()
+
+const emit = defineEmits<{
+  (e: 'update:triggers', value: Trigger[]): void
+}>()
+
+const triggers = useVModel(props, 'triggers', emit)
+
+/** 鑾峰彇瑙﹀彂鍣ㄦ爣绛剧被鍨嬶紙鐢ㄤ簬 el-tag 鐨� type 灞炴�э級 */
+const getTriggerTagType = (type: number): 'primary' | 'success' | 'info' | 'warning' | 'danger' => {
+  if (type === IotRuleSceneTriggerTypeEnum.TIMER) {
+    return 'warning'
+  }
+  return isDeviceTrigger(type) ? 'success' : 'info'
+}
+
+/** 娣诲姞瑙﹀彂鍣� */
+const addTrigger = () => {
+  const newTrigger: Trigger = {
+    type: IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE,
+    productId: undefined,
+    deviceId: undefined,
+    identifier: undefined,
+    operator: undefined,
+    value: undefined,
+    cronExpression: undefined,
+    conditionGroups: [] // 绌虹殑鏉′欢缁勬暟缁�
+  }
+  triggers.value.push(newTrigger)
+}
+
+/**
+ * 鍒犻櫎瑙﹀彂鍣�
+ * @param index 瑙﹀彂鍣ㄧ储寮�
+ */
+const removeTrigger = (index: number) => {
+  if (triggers.value.length > 1) {
+    triggers.value.splice(index, 1)
+  }
+}
+
+/**
+ * 鏇存柊瑙﹀彂鍣ㄧ被鍨�
+ * @param index 瑙﹀彂鍣ㄧ储寮�
+ * @param type 瑙﹀彂鍣ㄧ被鍨�
+ */
+const updateTriggerType = (index: number, type: number) => {
+  triggers.value[index].type = type
+  onTriggerTypeChange(index, type)
+}
+
+/**
+ * 鏇存柊瑙﹀彂鍣ㄨ澶囬厤缃�
+ * @param index 瑙﹀彂鍣ㄧ储寮�
+ * @param newTrigger 鏂扮殑瑙﹀彂鍣ㄥ璞�
+ */
+const updateTriggerDeviceConfig = (index: number, newTrigger: Trigger) => {
+  triggers.value[index] = newTrigger
+}
+
+/**
+ * 鏇存柊瑙﹀彂鍣� CRON 閰嶇疆
+ * @param index 瑙﹀彂鍣ㄧ储寮�
+ * @param cronExpression CRON 琛ㄨ揪寮�
+ */
+const updateTriggerCronConfig = (index: number, cronExpression?: string) => {
+  triggers.value[index].cronExpression = cronExpression
+}
+
+/**
+ * 澶勭悊瑙﹀彂鍣ㄧ被鍨嬪彉鍖栦簨浠�
+ * @param index 瑙﹀彂鍣ㄧ储寮�
+ * @param _ 瑙﹀彂鍣ㄧ被鍨嬶紙鏈娇鐢級
+ */
+const onTriggerTypeChange = (index: number, _: number) => {
+  const triggerItem = triggers.value[index]
+  triggerItem.productId = undefined
+  triggerItem.deviceId = undefined
+  triggerItem.identifier = undefined
+  triggerItem.operator = undefined
+  triggerItem.value = undefined
+  triggerItem.cronExpression = undefined
+  triggerItem.conditionGroups = []
+}
+
+/** 鍒濆鍖栵細纭繚鑷冲皯鏈変竴涓Е鍙戝櫒 */
+onMounted(() => {
+  if (triggers.value.length === 0) {
+    addTrigger()
+  }
+})
+</script>

--
Gitblit v1.8.0