perf:【IoT 物联网】场景联动触发器优化
This commit is contained in:
@ -0,0 +1,80 @@
|
||||
<!-- 条件类型选择器组件 -->
|
||||
<template>
|
||||
<el-select
|
||||
:model-value="modelValue"
|
||||
@update:model-value="handleChange"
|
||||
placeholder="请选择条件类型"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in conditionTypeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
>
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div class="flex items-center gap-8px">
|
||||
<Icon :icon="option.icon" :class="option.iconClass" />
|
||||
<span>{{ option.label }}</span>
|
||||
</div>
|
||||
<el-tag :type="option.tag" size="small">{{ option.category }}</el-tag>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { IotRuleSceneTriggerConditionTypeEnum } from '@/api/iot/rule/scene/scene.types'
|
||||
|
||||
/** 条件类型选择器组件 */
|
||||
defineOptions({ name: 'ConditionTypeSelector' })
|
||||
|
||||
interface Props {
|
||||
modelValue?: number
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: number): void
|
||||
(e: 'change', value: number): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
// 条件类型选项
|
||||
const conditionTypeOptions = [
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS,
|
||||
label: '设备状态',
|
||||
description: '监控设备的在线/离线状态变化',
|
||||
icon: 'ep:connection',
|
||||
iconClass: 'text-blue-500',
|
||||
tag: 'primary',
|
||||
category: '设备'
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY,
|
||||
label: '设备属性',
|
||||
description: '监控设备属性值的变化',
|
||||
icon: 'ep:data-analysis',
|
||||
iconClass: 'text-green-500',
|
||||
tag: 'success',
|
||||
category: '属性'
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME,
|
||||
label: '当前时间',
|
||||
description: '基于当前时间的条件判断',
|
||||
icon: 'ep:timer',
|
||||
iconClass: 'text-orange-500',
|
||||
tag: 'warning',
|
||||
category: '时间'
|
||||
}
|
||||
]
|
||||
|
||||
// 事件处理
|
||||
const handleChange = (value: number) => {
|
||||
emit('update:modelValue', value)
|
||||
emit('change', value)
|
||||
}
|
||||
</script>
|
||||
127
src/views/iot/rule/scene/form/selectors/DeviceSelector.vue
Normal file
127
src/views/iot/rule/scene/form/selectors/DeviceSelector.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<!-- 设备选择器组件 -->
|
||||
<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">
|
||||
<el-tag size="small" :type="getStatusType(device.status)">
|
||||
{{ getStatusText(device.status) }}
|
||||
</el-tag>
|
||||
<el-tag size="small" :type="device.activeTime ? 'success' : 'info'">
|
||||
{{ device.activeTime ? '已激活' : '未激活' }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DeviceApi } from '@/api/iot/device/device'
|
||||
|
||||
/** 设备选择器组件 */
|
||||
defineOptions({ name: 'DeviceSelector' })
|
||||
|
||||
interface Props {
|
||||
modelValue?: number
|
||||
productId?: number
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value?: number): void
|
||||
(e: 'change', value?: number): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
// 状态
|
||||
const deviceLoading = ref(false)
|
||||
const deviceList = ref<any[]>([])
|
||||
|
||||
// 事件处理
|
||||
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 {
|
||||
deviceLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 设备状态映射
|
||||
const getStatusType = (status: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return 'success' // 正常
|
||||
case 1:
|
||||
return 'danger' // 禁用
|
||||
default:
|
||||
return 'info'
|
||||
}
|
||||
}
|
||||
|
||||
const getStatusText = (status: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return '正常'
|
||||
case 1:
|
||||
return '禁用'
|
||||
default:
|
||||
return '未知'
|
||||
}
|
||||
}
|
||||
|
||||
// 监听产品变化
|
||||
watch(
|
||||
() => props.productId,
|
||||
(newProductId) => {
|
||||
if (newProductId) {
|
||||
getDeviceList()
|
||||
} else {
|
||||
deviceList.value = []
|
||||
// 清空当前选择的设备
|
||||
if (props.modelValue) {
|
||||
emit('update:modelValue', undefined)
|
||||
emit('change', undefined)
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
81
src/views/iot/rule/scene/form/selectors/ProductSelector.vue
Normal file
81
src/views/iot/rule/scene/form/selectors/ProductSelector.vue
Normal file
@ -0,0 +1,81 @@
|
||||
<!-- 产品选择器组件 -->
|
||||
<template>
|
||||
<el-select
|
||||
:model-value="modelValue"
|
||||
@update:model-value="handleChange"
|
||||
placeholder="请选择产品"
|
||||
filterable
|
||||
clearable
|
||||
class="w-full"
|
||||
:loading="productLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="product in productList"
|
||||
:key="product.id"
|
||||
:label="product.name"
|
||||
:value="product.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">{{
|
||||
product.name
|
||||
}}</div>
|
||||
<div class="text-12px text-[var(--el-text-color-secondary)]">{{
|
||||
product.productKey
|
||||
}}</div>
|
||||
</div>
|
||||
<el-tag size="small" :type="product.status === 0 ? 'success' : 'danger'">
|
||||
{{ product.status === 0 ? '正常' : '禁用' }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ProductApi } from '@/api/iot/product/product'
|
||||
|
||||
/** 产品选择器组件 */
|
||||
defineOptions({ name: 'ProductSelector' })
|
||||
|
||||
interface Props {
|
||||
modelValue?: number
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value?: number): void
|
||||
(e: 'change', value?: number): void
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
// 状态
|
||||
const productLoading = ref(false)
|
||||
const productList = ref<any[]>([])
|
||||
|
||||
// 事件处理
|
||||
const handleChange = (value?: number) => {
|
||||
emit('update:modelValue', value)
|
||||
emit('change', value)
|
||||
}
|
||||
|
||||
// 获取产品列表
|
||||
const getProductList = async () => {
|
||||
try {
|
||||
productLoading.value = true
|
||||
const res = await ProductApi.getSimpleProductList()
|
||||
productList.value = res || []
|
||||
} catch (error) {
|
||||
console.error('获取产品列表失败:', error)
|
||||
productList.value = []
|
||||
} finally {
|
||||
productLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 组件挂载时获取产品列表
|
||||
onMounted(() => {
|
||||
getProductList()
|
||||
})
|
||||
</script>
|
||||
@ -130,41 +130,3 @@ export interface PropertySelectorItem {
|
||||
event?: ThingModelEvent
|
||||
service?: ThingModelService
|
||||
}
|
||||
|
||||
/** 数据类型枚举 */
|
||||
export enum DataTypeEnum {
|
||||
INT = 'int',
|
||||
FLOAT = 'float',
|
||||
DOUBLE = 'double',
|
||||
ENUM = 'enum',
|
||||
BOOL = 'bool',
|
||||
TEXT = 'text',
|
||||
DATE = 'date',
|
||||
STRUCT = 'struct',
|
||||
ARRAY = 'array'
|
||||
}
|
||||
|
||||
/** 访问模式枚举 */
|
||||
export enum AccessModeEnum {
|
||||
READ = 'r',
|
||||
READ_write = 'rw'
|
||||
}
|
||||
|
||||
/** 事件类型枚举 */
|
||||
export enum EventTypeEnum {
|
||||
INFO = 'info',
|
||||
ALERT = 'alert',
|
||||
ERROR = 'error'
|
||||
}
|
||||
|
||||
/** 调用类型枚举 */
|
||||
export enum CallTypeEnum {
|
||||
ASYNC = 'async',
|
||||
SYNC = 'sync'
|
||||
}
|
||||
|
||||
/** 参数方向枚举 */
|
||||
export enum ParamDirectionEnum {
|
||||
INPUT = 'input',
|
||||
OUTPUT = 'output'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user