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/selectors/DeviceSelector.vue |  103 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/src/views/iot/rule/scene/form/selectors/DeviceSelector.vue b/src/views/iot/rule/scene/form/selectors/DeviceSelector.vue
new file mode 100644
index 0000000..0aa9cdd
--- /dev/null
+++ b/src/views/iot/rule/scene/form/selectors/DeviceSelector.vue
@@ -0,0 +1,103 @@
+<!-- 璁惧閫夋嫨鍣ㄧ粍浠� -->
+<template>
+  <el-select
+    :model-value="modelValue"
+    @update:model-value="handleChange"
+    placeholder="璇烽�夋嫨璁惧"
+    filterable
+    clearable
+    class="w-full"
+    :loading="deviceLoading"
+    :disabled="!productId"
+  >
+    <el-option
+      v-for="device in deviceList"
+      :key="device.id"
+      :label="device.deviceName"
+      :value="device.id"
+    >
+      <div class="flex items-center justify-between w-full py-4px">
+        <div class="flex-1">
+          <div class="text-14px font-500 text-[var(--el-text-color-primary)] mb-2px">
+            {{ device.deviceName }}
+          </div>
+          <div class="text-12px text-[var(--el-text-color-secondary)]">{{ device.deviceKey }}</div>
+        </div>
+        <div class="flex items-center gap-4px" v-if="device.id > 0">
+          <dict-tag :type="DICT_TYPE.IOT_DEVICE_STATE" :value="device.state" />
+        </div>
+      </div>
+    </el-option>
+  </el-select>
+</template>
+
+<script setup lang="ts">
+import { DeviceApi } from '@/api/iot/device/device'
+import { DEVICE_SELECTOR_OPTIONS } from '@/views/iot/utils/constants'
+import { DICT_TYPE } from '@/utils/dict'
+
+/** 璁惧閫夋嫨鍣ㄧ粍浠� */
+defineOptions({ name: 'DeviceSelector' })
+
+const props = defineProps<{
+  modelValue?: number
+  productId?: number
+}>()
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value?: number): void
+  (e: 'change', value?: number): void
+}>()
+
+const deviceLoading = ref(false) // 璁惧鍔犺浇鐘舵��
+const deviceList = ref<any[]>([]) // 璁惧鍒楄〃
+
+/**
+ * 澶勭悊閫夋嫨鍙樺寲浜嬩欢
+ * @param value 閫変腑鐨勮澶嘔D
+ */
+const handleChange = (value?: number) => {
+  emit('update:modelValue', value)
+  emit('change', value)
+}
+
+/**
+ * 鑾峰彇璁惧鍒楄〃
+ */
+const getDeviceList = async () => {
+  if (!props.productId) {
+    deviceList.value = []
+    return
+  }
+
+  try {
+    deviceLoading.value = true
+    const res = await DeviceApi.getDeviceListByProductId(props.productId)
+    deviceList.value = res || []
+  } catch (error) {
+    console.error('鑾峰彇璁惧鍒楄〃澶辫触:', error)
+    deviceList.value = []
+  } finally {
+    deviceList.value.unshift(DEVICE_SELECTOR_OPTIONS.ALL_DEVICES)
+    deviceLoading.value = false
+  }
+}
+
+// 鐩戝惉浜у搧鍙樺寲
+watch(
+  () => props.productId,
+  (newProductId) => {
+    if (newProductId) {
+      getDeviceList()
+    } else {
+      deviceList.value = []
+      // 娓呯┖褰撳墠閫夋嫨鐨勮澶�
+      if (props.modelValue) {
+        emit('update:modelValue', undefined)
+        emit('change', undefined)
+      }
+    }
+  },
+  { immediate: true }
+)
+</script>

--
Gitblit v1.8.0