commit
c427031e5a
|
|
@ -4,13 +4,18 @@
|
||||||
|
|
||||||
// 枚举定义
|
// 枚举定义
|
||||||
const IotRuleSceneTriggerTypeEnum = {
|
const IotRuleSceneTriggerTypeEnum = {
|
||||||
DEVICE: 1, // 设备触发
|
DEVICE_STATE_UPDATE: 1, // 设备上下线变更
|
||||||
TIMER: 2 // 定时触发
|
DEVICE_PROPERTY_POST: 2, // 物模型属性上报
|
||||||
|
DEVICE_EVENT_POST: 3, // 设备事件上报
|
||||||
|
DEVICE_SERVICE_INVOKE: 4, // 设备服务调用
|
||||||
|
TIMER: 100 // 定时触发
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
const IotRuleSceneActionTypeEnum = {
|
const IotRuleSceneActionTypeEnum = {
|
||||||
DEVICE_CONTROL: 1, // 设备执行
|
DEVICE_PROPERTY_SET: 1, // 设备属性设置,
|
||||||
ALERT: 2 // 告警执行
|
DEVICE_SERVICE_INVOKE: 2, // 设备服务调用
|
||||||
|
ALERT_TRIGGER: 100, // 告警触发
|
||||||
|
ALERT_RECOVER: 101 // 告警恢复
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
const IotDeviceMessageTypeEnum = {
|
const IotDeviceMessageTypeEnum = {
|
||||||
|
|
@ -89,20 +94,12 @@ interface ActionDeviceControl {
|
||||||
data: Record<string, any> // 具体数据
|
data: Record<string, any> // 具体数据
|
||||||
}
|
}
|
||||||
|
|
||||||
// 告警执行配置
|
|
||||||
interface ActionAlert {
|
|
||||||
receiveType: number // 接收方式
|
|
||||||
phoneNumbers?: string[] // 手机号列表
|
|
||||||
emails?: string[] // 邮箱列表
|
|
||||||
content: string // 通知内容
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行器配置
|
// 执行器配置
|
||||||
interface ActionConfig {
|
interface ActionConfig {
|
||||||
key: any // 解决组件索引重用 TODO @puhui999:看看有没更好的解决方案呢。
|
key: any // 解决组件索引重用 TODO @puhui999:看看有没更好的解决方案呢。
|
||||||
type: number // 执行类型
|
type: number // 执行类型
|
||||||
deviceControl?: ActionDeviceControl // 设备控制
|
deviceControl?: ActionDeviceControl // 设备控制
|
||||||
alert?: ActionAlert // 告警执行
|
alertConfigId?: number // 告警配置ID(告警恢复时需要)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 主接口
|
// 主接口
|
||||||
|
|
@ -122,7 +119,6 @@ export {
|
||||||
TriggerConditionParameter,
|
TriggerConditionParameter,
|
||||||
ActionConfig,
|
ActionConfig,
|
||||||
ActionDeviceControl,
|
ActionDeviceControl,
|
||||||
ActionAlert,
|
|
||||||
IotRuleSceneTriggerTypeEnum,
|
IotRuleSceneTriggerTypeEnum,
|
||||||
IotRuleSceneActionTypeEnum,
|
IotRuleSceneActionTypeEnum,
|
||||||
IotDeviceMessageTypeEnum,
|
IotDeviceMessageTypeEnum,
|
||||||
|
|
|
||||||
|
|
@ -33,17 +33,36 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-divider content-position="left">触发器配置</el-divider>
|
<el-divider content-position="left">触发器配置</el-divider>
|
||||||
<device-listener
|
<!-- 根据触发类型选择不同的监听器组件 -->
|
||||||
v-for="(trigger, index) in formData.triggers"
|
<template v-for="(trigger, index) in formData.triggers" :key="trigger.key">
|
||||||
:key="trigger.key"
|
<!-- 设备状态变更和定时触发使用简化的监听器 -->
|
||||||
:model-value="trigger"
|
<device-state-listener
|
||||||
@update:model-value="(val) => (formData.triggers[index] = val)"
|
v-if="
|
||||||
class="mb-10px"
|
trigger.type === IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE ||
|
||||||
>
|
trigger.type === IotRuleSceneTriggerTypeEnum.TIMER
|
||||||
<el-button type="danger" round size="small" @click="removeTrigger(index)">
|
"
|
||||||
<Icon icon="ep:delete" />
|
:model-value="trigger"
|
||||||
</el-button>
|
@update:model-value="(val) => (formData.triggers[index] = val)"
|
||||||
</device-listener>
|
class="mb-10px"
|
||||||
|
>
|
||||||
|
<el-button type="danger" round size="small" @click="removeTrigger(index)">
|
||||||
|
<Icon icon="ep:delete" />
|
||||||
|
</el-button>
|
||||||
|
</device-state-listener>
|
||||||
|
|
||||||
|
<!-- 其他设备触发类型使用完整的监听器 -->
|
||||||
|
<device-listener
|
||||||
|
v-else
|
||||||
|
:model-value="trigger"
|
||||||
|
@update:model-value="(val) => (formData.triggers[index] = val)"
|
||||||
|
class="mb-10px"
|
||||||
|
>
|
||||||
|
<el-button type="danger" round size="small" @click="removeTrigger(index)">
|
||||||
|
<Icon icon="ep:delete" />
|
||||||
|
</el-button>
|
||||||
|
</device-listener>
|
||||||
|
</template>
|
||||||
|
|
||||||
<el-button class="ml-10px!" type="primary" size="small" @click="addTrigger">
|
<el-button class="ml-10px!" type="primary" size="small" @click="addTrigger">
|
||||||
添加触发器
|
添加触发器
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -77,6 +96,7 @@
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { RuleSceneApi } from '@/api/iot/rule/scene'
|
import { RuleSceneApi } from '@/api/iot/rule/scene'
|
||||||
import DeviceListener from './components/listener/DeviceListener.vue'
|
import DeviceListener from './components/listener/DeviceListener.vue'
|
||||||
|
import DeviceStateListener from './components/listener/DeviceStateListener.vue'
|
||||||
import { CommonStatusEnum } from '@/utils/constants'
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
import {
|
import {
|
||||||
ActionConfig,
|
ActionConfig,
|
||||||
|
|
@ -117,7 +137,7 @@ const formRef = ref() // 表单 Ref
|
||||||
const addTrigger = () => {
|
const addTrigger = () => {
|
||||||
formData.value.triggers.push({
|
formData.value.triggers.push({
|
||||||
key: generateUUID(), // 解决组件索引重用
|
key: generateUUID(), // 解决组件索引重用
|
||||||
type: IotRuleSceneTriggerTypeEnum.DEVICE,
|
type: IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST, // 默认为物模型属性上报
|
||||||
productKey: '',
|
productKey: '',
|
||||||
deviceNames: [],
|
deviceNames: [],
|
||||||
conditions: [
|
conditions: [
|
||||||
|
|
@ -138,7 +158,7 @@ const removeTrigger = (index: number) => {
|
||||||
const addAction = () => {
|
const addAction = () => {
|
||||||
formData.value.actions.push({
|
formData.value.actions.push({
|
||||||
key: generateUUID(), // 解决组件索引重用
|
key: generateUUID(), // 解决组件索引重用
|
||||||
type: IotRuleSceneActionTypeEnum.DEVICE_CONTROL
|
type: IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET
|
||||||
} as ActionConfig)
|
} as ActionConfig)
|
||||||
}
|
}
|
||||||
/** 移除执行器 */
|
/** 移除执行器 */
|
||||||
|
|
|
||||||
|
|
@ -19,19 +19,13 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="isDeviceAction" class="flex items-center mr-60px">
|
||||||
v-if="actionConfig.type === IotRuleSceneActionTypeEnum.DEVICE_CONTROL"
|
|
||||||
class="flex items-center mr-60px"
|
|
||||||
>
|
|
||||||
<span class="mr-10px">产品</span>
|
<span class="mr-10px">产品</span>
|
||||||
<el-button type="primary" @click="handleSelectProduct" size="small" plain>
|
<el-button type="primary" @click="handleSelectProduct" size="small" plain>
|
||||||
{{ product ? product.name : '选择产品' }}
|
{{ product ? product.name : '选择产品' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="isDeviceAction" class="flex items-center mr-60px">
|
||||||
v-if="actionConfig.type === IotRuleSceneActionTypeEnum.DEVICE_CONTROL"
|
|
||||||
class="flex items-center mr-60px"
|
|
||||||
>
|
|
||||||
<span class="mr-10px">设备</span>
|
<span class="mr-10px">设备</span>
|
||||||
<el-button type="primary" @click="handleSelectDevice" size="small" plain>
|
<el-button type="primary" @click="handleSelectDevice" size="small" plain>
|
||||||
{{ isEmpty(deviceList) ? '选择设备' : deviceList.map((d) => d.deviceName).join(',') }}
|
{{ isEmpty(deviceList) ? '选择设备' : deviceList.map((d) => d.deviceName).join(',') }}
|
||||||
|
|
@ -47,7 +41,8 @@
|
||||||
|
|
||||||
<!-- 设备控制执行器 -->
|
<!-- 设备控制执行器 -->
|
||||||
<DeviceControlAction
|
<DeviceControlAction
|
||||||
v-if="actionConfig.type === IotRuleSceneActionTypeEnum.DEVICE_CONTROL"
|
v-if="isDeviceAction"
|
||||||
|
:action-type="actionConfig.type"
|
||||||
:model-value="actionConfig.deviceControl"
|
:model-value="actionConfig.deviceControl"
|
||||||
:product-id="product?.id"
|
:product-id="product?.id"
|
||||||
:product-key="product?.productKey"
|
:product-key="product?.productKey"
|
||||||
|
|
@ -55,11 +50,42 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 告警执行器 -->
|
<!-- 告警执行器 -->
|
||||||
<AlertAction
|
<div v-else-if="isAlertAction">
|
||||||
v-else-if="actionConfig.type === IotRuleSceneActionTypeEnum.ALERT"
|
<!-- 告警触发 - 无需额外配置 -->
|
||||||
:model-value="actionConfig.alert"
|
<div
|
||||||
@update:model-value="(val) => (actionConfig.alert = val)"
|
v-if="actionConfig.type === IotRuleSceneActionTypeEnum.ALERT_TRIGGER"
|
||||||
/>
|
class="bg-[#dbe5f6] flex items-center justify-center p-10px"
|
||||||
|
>
|
||||||
|
<el-icon class="mr-5px text-blue-500"><Icon icon="ep:info-filled" /></el-icon>
|
||||||
|
<span class="text-gray-600">触发告警通知,系统将自动发送告警信息</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 告警恢复 - 需要选择告警配置 -->
|
||||||
|
<div v-else-if="actionConfig.type === IotRuleSceneActionTypeEnum.ALERT_RECOVER">
|
||||||
|
<div class="bg-[#dbe5f6] flex items-center justify-center p-10px mb-10px">
|
||||||
|
<el-icon class="mr-5px text-blue-500"><Icon icon="ep:info-filled" /></el-icon>
|
||||||
|
<span class="text-gray-600">恢复指定的告警配置状态</span>
|
||||||
|
</div>
|
||||||
|
<div class="p-10px">
|
||||||
|
<el-form-item label="选择告警配置" required>
|
||||||
|
<el-select
|
||||||
|
v-model="actionConfig.alertConfigId"
|
||||||
|
class="!w-240px"
|
||||||
|
clearable
|
||||||
|
placeholder="请选择要恢复的告警配置"
|
||||||
|
:loading="alertConfigLoading"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="config in alertConfigList"
|
||||||
|
:key="config.id"
|
||||||
|
:label="config.name"
|
||||||
|
:value="config.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 产品、设备的选择 -->
|
<!-- 产品、设备的选择 -->
|
||||||
|
|
@ -80,11 +106,10 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import ProductTableSelect from '@/views/iot/product/product/components/ProductTableSelect.vue'
|
import ProductTableSelect from '@/views/iot/product/product/components/ProductTableSelect.vue'
|
||||||
import DeviceTableSelect from '@/views/iot/device/device/components/DeviceTableSelect.vue'
|
import DeviceTableSelect from '@/views/iot/device/device/components/DeviceTableSelect.vue'
|
||||||
import DeviceControlAction from './DeviceControlAction.vue'
|
import DeviceControlAction from './DeviceControlAction.vue'
|
||||||
import AlertAction from './AlertAction.vue'
|
|
||||||
import { ProductApi, ProductVO } from '@/api/iot/product/product'
|
import { ProductApi, ProductVO } from '@/api/iot/product/product'
|
||||||
import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
|
import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
|
||||||
|
import { AlertConfigApi, AlertConfig } from '@/api/iot/alert/config'
|
||||||
import {
|
import {
|
||||||
ActionAlert,
|
|
||||||
ActionConfig,
|
ActionConfig,
|
||||||
ActionDeviceControl,
|
ActionDeviceControl,
|
||||||
IotDeviceMessageIdentifierEnum,
|
IotDeviceMessageIdentifierEnum,
|
||||||
|
|
@ -101,29 +126,56 @@ const actionConfig = useVModel(props, 'modelValue', emits) as Ref<ActionConfig>
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
|
/** 计算属性:判断是否为设备相关执行类型 */
|
||||||
|
const isDeviceAction = computed(() => {
|
||||||
|
return [
|
||||||
|
IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET,
|
||||||
|
IotRuleSceneActionTypeEnum.DEVICE_SERVICE_INVOKE
|
||||||
|
].includes(actionConfig.value.type as any)
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 计算属性:判断是否为告警相关执行类型 */
|
||||||
|
const isAlertAction = computed(() => {
|
||||||
|
return [
|
||||||
|
IotRuleSceneActionTypeEnum.ALERT_TRIGGER,
|
||||||
|
IotRuleSceneActionTypeEnum.ALERT_RECOVER
|
||||||
|
].includes(actionConfig.value.type as any)
|
||||||
|
})
|
||||||
|
|
||||||
/** 初始化执行器结构 */
|
/** 初始化执行器结构 */
|
||||||
const initActionConfig = () => {
|
const initActionConfig = () => {
|
||||||
if (!actionConfig.value) {
|
if (!actionConfig.value) {
|
||||||
actionConfig.value = { type: IotRuleSceneActionTypeEnum.DEVICE_CONTROL } as ActionConfig
|
actionConfig.value = { type: IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET } as ActionConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设备控制执行器初始化
|
// 设备控制执行器初始化
|
||||||
if (
|
if (isDeviceAction.value && !actionConfig.value.deviceControl) {
|
||||||
actionConfig.value.type === IotRuleSceneActionTypeEnum.DEVICE_CONTROL &&
|
|
||||||
!actionConfig.value.deviceControl
|
|
||||||
) {
|
|
||||||
actionConfig.value.deviceControl = {
|
actionConfig.value.deviceControl = {
|
||||||
productKey: '',
|
productKey: '',
|
||||||
deviceNames: [],
|
deviceNames: [],
|
||||||
type: IotDeviceMessageTypeEnum.PROPERTY,
|
type:
|
||||||
identifier: IotDeviceMessageIdentifierEnum.PROPERTY_SET,
|
actionConfig.value.type === IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET
|
||||||
|
? IotDeviceMessageTypeEnum.PROPERTY
|
||||||
|
: IotDeviceMessageTypeEnum.SERVICE,
|
||||||
|
identifier:
|
||||||
|
actionConfig.value.type === IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET
|
||||||
|
? IotDeviceMessageIdentifierEnum.PROPERTY_SET
|
||||||
|
: IotDeviceMessageIdentifierEnum.SERVICE_INVOKE,
|
||||||
data: {}
|
data: {}
|
||||||
} as ActionDeviceControl
|
} as ActionDeviceControl
|
||||||
}
|
}
|
||||||
|
|
||||||
// 告警执行器初始化
|
// 告警执行器初始化
|
||||||
if (actionConfig.value.type === IotRuleSceneActionTypeEnum.ALERT && !actionConfig.value.alert) {
|
if (isAlertAction.value) {
|
||||||
actionConfig.value.alert = {} as ActionAlert
|
if (actionConfig.value.type === IotRuleSceneActionTypeEnum.ALERT_TRIGGER) {
|
||||||
|
// 告警触发 - 无需额外配置
|
||||||
|
actionConfig.value.alertConfigId = undefined
|
||||||
|
} else if (actionConfig.value.type === IotRuleSceneActionTypeEnum.ALERT_RECOVER) {
|
||||||
|
// 告警恢复 - 需要选择告警配置
|
||||||
|
if (!actionConfig.value.alertConfigId) {
|
||||||
|
actionConfig.value.alertConfigId = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,6 +185,10 @@ const deviceTableSelectRef = ref<InstanceType<typeof DeviceTableSelect>>()
|
||||||
const product = ref<ProductVO>()
|
const product = ref<ProductVO>()
|
||||||
const deviceList = ref<DeviceVO[]>([])
|
const deviceList = ref<DeviceVO[]>([])
|
||||||
|
|
||||||
|
/** 告警配置相关 */
|
||||||
|
const alertConfigList = ref<AlertConfig[]>([])
|
||||||
|
const alertConfigLoading = ref(false)
|
||||||
|
|
||||||
/** 处理选择产品 */
|
/** 处理选择产品 */
|
||||||
const handleSelectProduct = () => {
|
const handleSelectProduct = () => {
|
||||||
productTableSelectRef.value?.open()
|
productTableSelectRef.value?.open()
|
||||||
|
|
@ -168,11 +224,27 @@ const handleDeviceSelect = (val: DeviceVO[]) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 获取告警配置列表 */
|
||||||
|
const getAlertConfigList = async () => {
|
||||||
|
try {
|
||||||
|
alertConfigLoading.value = true
|
||||||
|
alertConfigList.value = await AlertConfigApi.getSimpleAlertConfigList()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取告警配置列表失败:', error)
|
||||||
|
} finally {
|
||||||
|
alertConfigLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 监听执行类型变化,初始化对应配置 */
|
/** 监听执行类型变化,初始化对应配置 */
|
||||||
watch(
|
watch(
|
||||||
() => actionConfig.value.type,
|
() => actionConfig.value.type,
|
||||||
() => {
|
(newType) => {
|
||||||
initActionConfig()
|
initActionConfig()
|
||||||
|
// 如果是告警恢复类型,需要加载告警配置列表
|
||||||
|
if (newType === IotRuleSceneActionTypeEnum.ALERT_RECOVER) {
|
||||||
|
getAlertConfigList()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="bg-[#dbe5f6] p-10px">
|
|
||||||
<div class="flex items-center mb-10px">
|
|
||||||
<span class="mr-10px w-80px">接收方式</span>
|
|
||||||
<el-select
|
|
||||||
v-model="alertConfig.receiveType"
|
|
||||||
class="!w-160px"
|
|
||||||
clearable
|
|
||||||
placeholder="选择接收方式"
|
|
||||||
>
|
|
||||||
<!-- TODO @芋艿:后续搞成字典 -->
|
|
||||||
<!-- TODO @puhui999:这里好像是 1、/2、/3 哈 -->
|
|
||||||
<el-option
|
|
||||||
v-for="(value, key) in IotAlertConfigReceiveTypeEnum"
|
|
||||||
:key="value"
|
|
||||||
:label="key === 'SMS' ? '短信' : key === 'MAIL' ? '邮箱' : '通知'"
|
|
||||||
:value="value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="alertConfig.receiveType === IotAlertConfigReceiveTypeEnum.SMS"
|
|
||||||
class="flex items-center mb-10px"
|
|
||||||
>
|
|
||||||
<span class="mr-10px w-80px">手机号码</span>
|
|
||||||
<el-select
|
|
||||||
v-model="alertConfig.phoneNumbers"
|
|
||||||
class="!w-360px"
|
|
||||||
multiple
|
|
||||||
filterable
|
|
||||||
allow-create
|
|
||||||
default-first-option
|
|
||||||
placeholder="请输入手机号码"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="alertConfig.receiveType === IotAlertConfigReceiveTypeEnum.MAIL"
|
|
||||||
class="flex items-center mb-10px"
|
|
||||||
>
|
|
||||||
<span class="mr-10px w-80px">邮箱地址</span>
|
|
||||||
<el-select
|
|
||||||
v-model="alertConfig.emails"
|
|
||||||
class="!w-360px"
|
|
||||||
multiple
|
|
||||||
filterable
|
|
||||||
allow-create
|
|
||||||
default-first-option
|
|
||||||
placeholder="请输入邮箱地址"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<span class="mr-10px w-80px align-self-start">通知内容</span>
|
|
||||||
<el-input
|
|
||||||
v-model="alertConfig.content"
|
|
||||||
type="textarea"
|
|
||||||
:rows="4"
|
|
||||||
class="!w-360px"
|
|
||||||
placeholder="请输入通知内容"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { useVModel } from '@vueuse/core'
|
|
||||||
import { ActionAlert, IotAlertConfigReceiveTypeEnum } from '@/api/iot/rule/scene/scene.types'
|
|
||||||
|
|
||||||
/** 告警执行器组件 */
|
|
||||||
defineOptions({ name: 'AlertAction' })
|
|
||||||
|
|
||||||
const props = defineProps<{ modelValue: any }>()
|
|
||||||
const emits = defineEmits(['update:modelValue'])
|
|
||||||
const alertConfig = useVModel(props, 'modelValue', emits) as Ref<ActionAlert>
|
|
||||||
|
|
||||||
/** 初始化告警执行器结构 */
|
|
||||||
const initAlertConfig = () => {
|
|
||||||
if (!alertConfig.value) {
|
|
||||||
alertConfig.value = {
|
|
||||||
receiveType: IotAlertConfigReceiveTypeEnum.NOTIFY,
|
|
||||||
phoneNumbers: [],
|
|
||||||
emails: [],
|
|
||||||
content: ''
|
|
||||||
} as ActionAlert
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 初始化 */
|
|
||||||
onMounted(() => {
|
|
||||||
initAlertConfig()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="bg-[#dbe5f6] flex p-10px">
|
<div class="bg-[#dbe5f6] flex p-10px">
|
||||||
<div class="flex flex-col items-center justify-center mr-10px h-a">
|
|
||||||
<el-select v-model="deviceControlConfig.type" class="!w-160px" clearable placeholder="">
|
|
||||||
<el-option label="属性" :value="IotDeviceMessageTypeEnum.PROPERTY" />
|
|
||||||
<el-option label="服务" :value="IotDeviceMessageTypeEnum.SERVICE" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<div
|
<div
|
||||||
class="flex items-center justify-around mb-10px last:mb-0"
|
class="flex items-center justify-around mb-10px last:mb-0"
|
||||||
|
|
@ -74,7 +68,8 @@ import { ThingModelApi } from '@/api/iot/thingmodel'
|
||||||
import {
|
import {
|
||||||
ActionDeviceControl,
|
ActionDeviceControl,
|
||||||
IotDeviceMessageIdentifierEnum,
|
IotDeviceMessageIdentifierEnum,
|
||||||
IotDeviceMessageTypeEnum
|
IotDeviceMessageTypeEnum,
|
||||||
|
IotRuleSceneActionTypeEnum
|
||||||
} from '@/api/iot/rule/scene/scene.types'
|
} from '@/api/iot/rule/scene/scene.types'
|
||||||
import ThingModelParamInput from '../ThingModelParamInput.vue'
|
import ThingModelParamInput from '../ThingModelParamInput.vue'
|
||||||
|
|
||||||
|
|
@ -83,6 +78,7 @@ defineOptions({ name: 'DeviceControlAction' })
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: any
|
modelValue: any
|
||||||
|
actionType: number
|
||||||
productId?: number
|
productId?: number
|
||||||
productKey?: string
|
productKey?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -98,10 +94,6 @@ const addParameter = () => {
|
||||||
message.warning('请先选择一个产品')
|
message.warning('请先选择一个产品')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (parameters.value.length >= thingModels.value().length) {
|
|
||||||
message.warning(`该产品只有${thingModels.value().length}个物模型!!!`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
parameters.value.push({ identifier: '', value: undefined })
|
parameters.value.push({ identifier: '', value: undefined })
|
||||||
}
|
}
|
||||||
const removeParameter = (index: number) => {
|
const removeParameter = (index: number) => {
|
||||||
|
|
@ -140,8 +132,14 @@ const initDeviceControlConfig = () => {
|
||||||
deviceControlConfig.value = {
|
deviceControlConfig.value = {
|
||||||
productKey: '',
|
productKey: '',
|
||||||
deviceNames: [],
|
deviceNames: [],
|
||||||
type: IotDeviceMessageTypeEnum.PROPERTY,
|
type:
|
||||||
identifier: IotDeviceMessageIdentifierEnum.PROPERTY_SET,
|
props.actionType === IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET
|
||||||
|
? IotDeviceMessageTypeEnum.PROPERTY
|
||||||
|
: IotDeviceMessageTypeEnum.SERVICE,
|
||||||
|
identifier:
|
||||||
|
props.actionType === IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET
|
||||||
|
? IotDeviceMessageIdentifierEnum.PROPERTY_SET
|
||||||
|
: IotDeviceMessageIdentifierEnum.SERVICE_INVOKE,
|
||||||
data: {}
|
data: {}
|
||||||
} as ActionDeviceControl
|
} as ActionDeviceControl
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -208,6 +206,26 @@ watch(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** 监听执行类型变化 */
|
||||||
|
watch(
|
||||||
|
() => props.actionType,
|
||||||
|
(val: any) => {
|
||||||
|
if (!val) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 切换执行类型时清空参数
|
||||||
|
deviceControlConfig.value.data = {}
|
||||||
|
parameters.value = []
|
||||||
|
if (val === IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET) {
|
||||||
|
deviceControlConfig.value.type = IotDeviceMessageTypeEnum.PROPERTY
|
||||||
|
deviceControlConfig.value.identifier = IotDeviceMessageIdentifierEnum.PROPERTY_SET
|
||||||
|
} else if (val === IotRuleSceneActionTypeEnum.DEVICE_SERVICE_INVOKE) {
|
||||||
|
deviceControlConfig.value.type = IotDeviceMessageTypeEnum.SERVICE
|
||||||
|
deviceControlConfig.value.identifier = IotDeviceMessageIdentifierEnum.SERVICE_INVOKE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
/** 监听消息类型变化 */
|
/** 监听消息类型变化 */
|
||||||
watch(
|
watch(
|
||||||
() => deviceControlConfig.value.type,
|
() => deviceControlConfig.value.type,
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,13 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="isDeviceTrigger" class="flex items-center mr-60px">
|
||||||
v-if="triggerConfig.type === IotRuleSceneTriggerTypeEnum.DEVICE"
|
|
||||||
class="flex items-center mr-60px"
|
|
||||||
>
|
|
||||||
<span class="mr-10px">产品</span>
|
<span class="mr-10px">产品</span>
|
||||||
<el-button type="primary" @click="productTableSelectRef?.open()" size="small" plain>
|
<el-button type="primary" @click="productTableSelectRef?.open()" size="small" plain>
|
||||||
{{ product ? product.name : '选择产品' }}
|
{{ product ? product.name : '选择产品' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="isDeviceTrigger" class="flex items-center mr-60px">
|
||||||
v-if="triggerConfig.type === IotRuleSceneTriggerTypeEnum.DEVICE"
|
|
||||||
class="flex items-center mr-60px"
|
|
||||||
>
|
|
||||||
<span class="mr-10px">设备</span>
|
<span class="mr-10px">设备</span>
|
||||||
<el-button type="primary" @click="openDeviceSelect" size="small" plain>
|
<el-button type="primary" @click="openDeviceSelect" size="small" plain>
|
||||||
{{ isEmpty(deviceList) ? '选择设备' : triggerConfig.deviceNames.join(',') }}
|
{{ isEmpty(deviceList) ? '选择设备' : triggerConfig.deviceNames.join(',') }}
|
||||||
|
|
@ -44,25 +38,22 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 设备触发器条件 -->
|
<!-- 设备触发器条件 -->
|
||||||
<template v-if="triggerConfig.type === IotRuleSceneTriggerTypeEnum.DEVICE">
|
<template v-if="isDeviceTrigger">
|
||||||
|
<!-- 设备上下线变更 - 无需额外配置 -->
|
||||||
<div
|
<div
|
||||||
|
v-if="triggerConfig.type === IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE"
|
||||||
|
class="bg-[#dbe5f6] flex items-center justify-center p-10px"
|
||||||
|
>
|
||||||
|
<span class="text-gray-600">设备上下线状态变更时触发,无需额外配置</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 物模型属性上报、设备事件上报、设备服务调用 - 需要配置条件 -->
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
class="bg-[#dbe5f6] flex p-10px"
|
class="bg-[#dbe5f6] flex p-10px"
|
||||||
v-for="(condition, index) in triggerConfig.conditions"
|
v-for="(condition, index) in triggerConfig.conditions"
|
||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col items-center justify-center mr-10px h-a">
|
|
||||||
<el-select
|
|
||||||
v-model="condition.type"
|
|
||||||
@change="condition.parameters = []"
|
|
||||||
class="!w-160px"
|
|
||||||
clearable
|
|
||||||
placeholder=""
|
|
||||||
>
|
|
||||||
<el-option label="属性" :value="IotDeviceMessageTypeEnum.PROPERTY" />
|
|
||||||
<el-option label="服务" :value="IotDeviceMessageTypeEnum.SERVICE" />
|
|
||||||
<el-option label="事件" :value="IotDeviceMessageTypeEnum.EVENT" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="w-70%">
|
<div class="w-70%">
|
||||||
<DeviceListenerCondition
|
<DeviceListenerCondition
|
||||||
v-for="(parameter, index2) in condition.parameters"
|
v-for="(parameter, index2) in condition.parameters"
|
||||||
|
|
@ -118,9 +109,11 @@
|
||||||
<span class="w-120px">CRON 表达式</span>
|
<span class="w-120px">CRON 表达式</span>
|
||||||
<crontab v-model="triggerConfig.cronExpression" />
|
<crontab v-model="triggerConfig.cronExpression" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 设备触发才可以设置多个触发条件 -->
|
<!-- 除了设备上下线变更,其他设备触发类型都可以设置多个触发条件 -->
|
||||||
<el-text
|
<el-text
|
||||||
v-if="triggerConfig.type === IotRuleSceneTriggerTypeEnum.DEVICE"
|
v-if="
|
||||||
|
isDeviceTrigger && triggerConfig.type !== IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE
|
||||||
|
"
|
||||||
class="ml-10px!"
|
class="ml-10px!"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="addCondition"
|
@click="addCondition"
|
||||||
|
|
@ -158,6 +151,7 @@ import {
|
||||||
TriggerConditionParameter,
|
TriggerConditionParameter,
|
||||||
TriggerConfig
|
TriggerConfig
|
||||||
} from '@/api/iot/rule/scene/scene.types'
|
} from '@/api/iot/rule/scene/scene.types'
|
||||||
|
import { Crontab } from '@/components/Crontab'
|
||||||
|
|
||||||
/** 场景联动之监听器组件 */
|
/** 场景联动之监听器组件 */
|
||||||
defineOptions({ name: 'DeviceListener' })
|
defineOptions({ name: 'DeviceListener' })
|
||||||
|
|
@ -168,10 +162,35 @@ const triggerConfig = useVModel(props, 'modelValue', emits) as Ref<TriggerConfig
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
|
/** 计算属性:判断是否为设备触发类型 */
|
||||||
|
const isDeviceTrigger = computed(() => {
|
||||||
|
return [
|
||||||
|
IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE,
|
||||||
|
IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST,
|
||||||
|
IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST,
|
||||||
|
IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE
|
||||||
|
].includes(triggerConfig.value.type as any)
|
||||||
|
})
|
||||||
|
|
||||||
/** 添加触发条件 */
|
/** 添加触发条件 */
|
||||||
const addCondition = () => {
|
const addCondition = () => {
|
||||||
|
// 根据触发类型设置默认的条件类型
|
||||||
|
let defaultConditionType: string = IotDeviceMessageTypeEnum.PROPERTY
|
||||||
|
|
||||||
|
switch (triggerConfig.value.type) {
|
||||||
|
case IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST:
|
||||||
|
defaultConditionType = IotDeviceMessageTypeEnum.PROPERTY
|
||||||
|
break
|
||||||
|
case IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST:
|
||||||
|
defaultConditionType = IotDeviceMessageTypeEnum.EVENT
|
||||||
|
break
|
||||||
|
case IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE:
|
||||||
|
defaultConditionType = IotDeviceMessageTypeEnum.SERVICE
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
triggerConfig.value.conditions?.push({
|
triggerConfig.value.conditions?.push({
|
||||||
type: IotDeviceMessageTypeEnum.PROPERTY,
|
type: defaultConditionType,
|
||||||
identifier: IotDeviceMessageIdentifierEnum.PROPERTY_SET,
|
identifier: IotDeviceMessageIdentifierEnum.PROPERTY_SET,
|
||||||
parameters: []
|
parameters: []
|
||||||
})
|
})
|
||||||
|
|
@ -187,6 +206,10 @@ const addConditionParameter = (conditionParameters: TriggerConditionParameter[])
|
||||||
message.warning('请先选择一个产品')
|
message.warning('请先选择一个产品')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (conditionParameters.length >= 1) {
|
||||||
|
message.warning('只允许添加一个参数')
|
||||||
|
return
|
||||||
|
}
|
||||||
conditionParameters.push({} as TriggerConditionParameter)
|
conditionParameters.push({} as TriggerConditionParameter)
|
||||||
}
|
}
|
||||||
/** 移除参数 */
|
/** 移除参数 */
|
||||||
|
|
@ -290,12 +313,48 @@ const getThingModelTSL = async () => {
|
||||||
thingModelTSL.value = await ThingModelApi.getThingModelTSLByProductId(product.value.id)
|
thingModelTSL.value = await ThingModelApi.getThingModelTSLByProductId(product.value.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 监听触发类型变化,自动设置条件类型 */
|
||||||
|
watch(
|
||||||
|
() => triggerConfig.value.type,
|
||||||
|
(newType) => {
|
||||||
|
if (!newType || newType === IotRuleSceneTriggerTypeEnum.TIMER) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备上下线变更不需要条件配置
|
||||||
|
if (newType === IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE) {
|
||||||
|
triggerConfig.value.conditions = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为其他设备触发类型设置默认条件
|
||||||
|
if (triggerConfig.value.conditions && triggerConfig.value.conditions.length > 0) {
|
||||||
|
triggerConfig.value.conditions.forEach((condition) => {
|
||||||
|
switch (newType) {
|
||||||
|
case IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST:
|
||||||
|
condition.type = IotDeviceMessageTypeEnum.PROPERTY
|
||||||
|
break
|
||||||
|
case IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST:
|
||||||
|
condition.type = IotDeviceMessageTypeEnum.EVENT
|
||||||
|
break
|
||||||
|
case IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE:
|
||||||
|
condition.type = IotDeviceMessageTypeEnum.SERVICE
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 初始化产品和设备回显
|
// 初始化产品和设备回显
|
||||||
if (triggerConfig.value) {
|
if (triggerConfig.value) {
|
||||||
// 初始化conditions数组,如果不存在
|
// 初始化conditions数组,如果不存在且不是设备上下线变更类型
|
||||||
if (!triggerConfig.value.conditions) {
|
if (
|
||||||
|
!triggerConfig.value.conditions &&
|
||||||
|
triggerConfig.value.type !== IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE
|
||||||
|
) {
|
||||||
triggerConfig.value.conditions = []
|
triggerConfig.value.conditions = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,166 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="m-10px">
|
||||||
|
<div class="relative bg-[#eff3f7] h-50px flex items-center px-10px">
|
||||||
|
<div class="flex items-center mr-60px">
|
||||||
|
<span class="mr-10px">触发条件</span>
|
||||||
|
<el-select
|
||||||
|
v-model="triggerConfig.type"
|
||||||
|
class="!w-240px"
|
||||||
|
clearable
|
||||||
|
placeholder="请选择触发条件"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.IOT_RULE_SCENE_TRIGGER_TYPE_ENUM)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mr-60px">
|
||||||
|
<span class="mr-10px">产品</span>
|
||||||
|
<el-button type="primary" @click="productTableSelectRef?.open()" size="small" plain>
|
||||||
|
{{ product ? product.name : '选择产品' }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mr-60px">
|
||||||
|
<span class="mr-10px">设备</span>
|
||||||
|
<el-button type="primary" @click="openDeviceSelect" size="small" plain>
|
||||||
|
{{ isEmpty(deviceList) ? '选择设备' : triggerConfig.deviceNames.join(',') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<!-- 删除触发器 -->
|
||||||
|
<div class="absolute top-auto right-16px bottom-auto">
|
||||||
|
<el-tooltip content="删除触发器" placement="top">
|
||||||
|
<slot></slot>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 设备状态变更说明 -->
|
||||||
|
<div
|
||||||
|
v-if="triggerConfig.type === IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE"
|
||||||
|
class="bg-[#dbe5f6] flex items-center justify-center p-10px"
|
||||||
|
>
|
||||||
|
<el-icon class="mr-5px text-blue-500"><Icon icon="ep:info-filled" /></el-icon>
|
||||||
|
<span class="text-gray-600">当选中的设备上线或下线时触发场景联动</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 定时触发 -->
|
||||||
|
<div
|
||||||
|
v-if="triggerConfig.type === IotRuleSceneTriggerTypeEnum.TIMER"
|
||||||
|
class="bg-[#dbe5f6] flex items-center justify-between p-10px"
|
||||||
|
>
|
||||||
|
<span class="w-120px">CRON 表达式</span>
|
||||||
|
<crontab v-model="triggerConfig.cronExpression" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 产品、设备的选择 -->
|
||||||
|
<ProductTableSelect ref="productTableSelectRef" @success="handleProductSelect" />
|
||||||
|
<DeviceTableSelect
|
||||||
|
ref="deviceTableSelectRef"
|
||||||
|
multiple
|
||||||
|
:product-id="product?.id"
|
||||||
|
@success="handleDeviceSelect"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useVModel } from '@vueuse/core'
|
||||||
|
import { isEmpty } from '@/utils/is'
|
||||||
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
import ProductTableSelect from '@/views/iot/product/product/components/ProductTableSelect.vue'
|
||||||
|
import DeviceTableSelect from '@/views/iot/device/device/components/DeviceTableSelect.vue'
|
||||||
|
import { ProductApi, ProductVO } from '@/api/iot/product/product'
|
||||||
|
import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
|
||||||
|
import { IotRuleSceneTriggerTypeEnum, TriggerConfig } from '@/api/iot/rule/scene/scene.types'
|
||||||
|
import { Crontab } from '@/components/Crontab'
|
||||||
|
|
||||||
|
/** 设备状态监听器组件 */
|
||||||
|
defineOptions({ name: 'DeviceStateListener' })
|
||||||
|
|
||||||
|
const props = defineProps<{ modelValue: any }>()
|
||||||
|
const emits = defineEmits(['update:modelValue'])
|
||||||
|
const triggerConfig = useVModel(props, 'modelValue', emits) as Ref<TriggerConfig>
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
/** 产品和设备选择引用 */
|
||||||
|
const productTableSelectRef = ref<InstanceType<typeof ProductTableSelect>>()
|
||||||
|
const deviceTableSelectRef = ref<InstanceType<typeof DeviceTableSelect>>()
|
||||||
|
const product = ref<ProductVO>()
|
||||||
|
const deviceList = ref<DeviceVO[]>([])
|
||||||
|
|
||||||
|
/** 处理产品选择 */
|
||||||
|
const handleProductSelect = (val: ProductVO) => {
|
||||||
|
product.value = val
|
||||||
|
triggerConfig.value.productKey = val.productKey
|
||||||
|
deviceList.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 处理设备选择 */
|
||||||
|
const handleDeviceSelect = (val: DeviceVO[]) => {
|
||||||
|
deviceList.value = val
|
||||||
|
triggerConfig.value.deviceNames = val.map((item) => item.deviceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 打开设备选择器 */
|
||||||
|
const openDeviceSelect = () => {
|
||||||
|
if (!product.value) {
|
||||||
|
message.warning('请先选择一个产品')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deviceTableSelectRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化产品回显信息
|
||||||
|
*/
|
||||||
|
const initProductInfo = async () => {
|
||||||
|
if (!triggerConfig.value.productKey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productData = await ProductApi.getProductByKey(triggerConfig.value.productKey)
|
||||||
|
if (productData) {
|
||||||
|
product.value = productData
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取产品信息失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化设备回显信息
|
||||||
|
*/
|
||||||
|
const initDeviceInfo = async () => {
|
||||||
|
if (!triggerConfig.value.productKey || !triggerConfig.value.deviceNames?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const deviceData = await DeviceApi.getDevicesByProductKeyAndNames(
|
||||||
|
triggerConfig.value.productKey,
|
||||||
|
triggerConfig.value.deviceNames
|
||||||
|
)
|
||||||
|
|
||||||
|
if (deviceData && deviceData.length > 0) {
|
||||||
|
deviceList.value = deviceData
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取设备信息失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 */
|
||||||
|
onMounted(async () => {
|
||||||
|
if (triggerConfig.value) {
|
||||||
|
await initProductInfo()
|
||||||
|
await initDeviceInfo()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue