perf: 【IoT 物联网】场景联动收拢常量定义
parent
9684857174
commit
93311f8bd7
|
@ -148,18 +148,6 @@ export const DeviceApi = {
|
|||
return await request.get({ url: `/iot/device/get-auth-info`, params: { id } })
|
||||
},
|
||||
|
||||
// 根据 ProductKey 和 DeviceNames 获取设备列表
|
||||
// TODO @puhui999:有没可能搞成基于 id 的查询哈?
|
||||
getDevicesByProductKeyAndNames: async (productKey: string, deviceNames: string[]) => {
|
||||
return await request.get({
|
||||
url: `/iot/device/list-by-product-key-and-names`,
|
||||
params: {
|
||||
productKey,
|
||||
deviceNames: deviceNames.join(',')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 查询设备消息分页
|
||||
getDeviceMessagePage: async (params: any) => {
|
||||
return await request.get({ url: `/iot/device/message/page`, params })
|
||||
|
|
|
@ -58,7 +58,6 @@ const updateModelValue = () => {
|
|||
emit('update:modelValue', result)
|
||||
}
|
||||
|
||||
// TODO @puhui999:有告警的地方,尽量用 cursor 处理下
|
||||
/** 监听项目变化 */
|
||||
watch(items, updateModelValue, { deep: true })
|
||||
watch(
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in conditionTypeOptions"
|
||||
v-for="option in getConditionTypeOptions()"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
|
@ -47,7 +47,10 @@
|
|||
</el-row>
|
||||
|
||||
<!-- 设备状态条件配置 -->
|
||||
<div v-if="condition.type === ConditionTypeEnum.DEVICE_STATUS" class="flex flex-col gap-16px">
|
||||
<div
|
||||
v-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS"
|
||||
class="flex flex-col gap-16px"
|
||||
>
|
||||
<!-- 状态和操作符选择 -->
|
||||
<el-row :gutter="16">
|
||||
<!-- 操作符选择 -->
|
||||
|
@ -60,7 +63,7 @@
|
|||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in statusOperatorOptions"
|
||||
v-for="option in getStatusOperatorOptions()"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
|
@ -79,7 +82,7 @@
|
|||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in deviceStatusOptions"
|
||||
v-for="option in getDeviceStatusOptions()"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
|
@ -91,13 +94,15 @@
|
|||
</div>
|
||||
|
||||
<!-- 设备属性条件配置 -->
|
||||
<div v-else-if="condition.type === ConditionTypeEnum.DEVICE_PROPERTY" class="space-y-16px">
|
||||
<div
|
||||
v-else-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY"
|
||||
class="space-y-16px"
|
||||
>
|
||||
<!-- 属性配置 -->
|
||||
<el-row :gutter="16">
|
||||
<!-- 属性/事件/服务选择 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item label="监控项" required>
|
||||
<!-- TODO @puhui999:是不是不展示“整数”、“小数”这个类型,一行,只展示属性名 + 标识,更简洁一点;然后标识是 tag;因为已经有个 ? tip 了 -->
|
||||
<PropertySelector
|
||||
:model-value="condition.identifier"
|
||||
@update:model-value="(value) => updateConditionField('identifier', value)"
|
||||
|
@ -138,7 +143,7 @@
|
|||
|
||||
<!-- 当前时间条件配置 -->
|
||||
<CurrentTimeConditionConfig
|
||||
v-else-if="condition.type === ConditionTypeEnum.CURRENT_TIME"
|
||||
v-else-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME"
|
||||
:model-value="condition"
|
||||
@update:model-value="updateCondition"
|
||||
/>
|
||||
|
@ -156,7 +161,10 @@ import ValueInput from '../inputs/ValueInput.vue'
|
|||
import type { TriggerCondition } from '@/api/iot/rule/scene'
|
||||
import {
|
||||
IotRuleSceneTriggerConditionTypeEnum,
|
||||
IotRuleSceneTriggerConditionParameterOperatorEnum
|
||||
IotRuleSceneTriggerConditionParameterOperatorEnum,
|
||||
getConditionTypeOptions,
|
||||
getDeviceStatusOptions,
|
||||
getStatusOperatorOptions
|
||||
} from '@/views/iot/utils/constants'
|
||||
|
||||
/** 单个条件配置组件 */
|
||||
|
@ -173,48 +181,6 @@ const emit = defineEmits<{
|
|||
|
||||
const condition = useVModel(props, 'modelValue', emit)
|
||||
|
||||
// 常量定义
|
||||
const ConditionTypeEnum = IotRuleSceneTriggerConditionTypeEnum
|
||||
|
||||
// 条件类型选项
|
||||
const conditionTypeOptions = [
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS,
|
||||
label: '设备状态'
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY,
|
||||
label: '设备属性'
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME,
|
||||
label: '当前时间'
|
||||
}
|
||||
]
|
||||
|
||||
// 设备状态选项
|
||||
const deviceStatusOptions = [
|
||||
{
|
||||
value: 'online',
|
||||
label: '在线'
|
||||
},
|
||||
{
|
||||
value: 'offline',
|
||||
label: '离线'
|
||||
}
|
||||
]
|
||||
// 状态操作符选项
|
||||
const statusOperatorOptions = [
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value,
|
||||
label: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.name
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.value,
|
||||
label: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.name
|
||||
}
|
||||
]
|
||||
|
||||
// 状态
|
||||
const propertyType = ref<string>('string')
|
||||
const propertyConfig = ref<any>(null)
|
||||
|
@ -222,8 +188,8 @@ const propertyConfig = ref<any>(null)
|
|||
// 计算属性:判断是否为设备相关条件
|
||||
const isDeviceCondition = computed(() => {
|
||||
return (
|
||||
condition.value.type === ConditionTypeEnum.DEVICE_STATUS ||
|
||||
condition.value.type === ConditionTypeEnum.DEVICE_PROPERTY
|
||||
condition.value.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS ||
|
||||
condition.value.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -240,7 +206,7 @@ const updateCondition = (newCondition: TriggerCondition) => {
|
|||
|
||||
const handleConditionTypeChange = (type: number) => {
|
||||
// 清理不相关的字段
|
||||
if (type === ConditionTypeEnum.DEVICE_STATUS) {
|
||||
if (type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS) {
|
||||
condition.value.identifier = undefined
|
||||
// 清理时间相关字段(如果存在)
|
||||
if ('timeValue' in condition.value) {
|
||||
|
@ -249,11 +215,11 @@ const handleConditionTypeChange = (type: number) => {
|
|||
if ('timeValue2' in condition.value) {
|
||||
delete (condition.value as any).timeValue2
|
||||
}
|
||||
} else if (type === ConditionTypeEnum.CURRENT_TIME) {
|
||||
} else if (type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME) {
|
||||
condition.value.identifier = undefined
|
||||
condition.value.productId = undefined
|
||||
condition.value.deviceId = undefined
|
||||
} else if (type === ConditionTypeEnum.DEVICE_PROPERTY) {
|
||||
} else if (type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY) {
|
||||
// 清理时间相关字段(如果存在)
|
||||
if ('timeValue' in condition.value) {
|
||||
delete (condition.value as any).timeValue
|
||||
|
|
|
@ -157,8 +157,12 @@
|
|||
placeholder="请选择操作符"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option label="变为在线" value="online" />
|
||||
<el-option label="变为离线" value="offline" />
|
||||
<el-option
|
||||
v-for="option in deviceStatusChangeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -168,7 +172,7 @@
|
|||
<!-- 其他触发类型的提示 -->
|
||||
<div v-else class="text-center py-20px">
|
||||
<p class="text-14px text-[var(--el-text-color-secondary)] mb-4px">
|
||||
当前触发事件类型:{{ getTriggerTypeText(triggerType) }}
|
||||
当前触发事件类型:{{ getTriggerTypeLabel(triggerType) }}
|
||||
</p>
|
||||
<p class="text-12px text-[var(--el-text-color-placeholder)]">
|
||||
此触发类型暂不需要配置额外条件
|
||||
|
@ -186,7 +190,12 @@ import ValueInput from '../inputs/ValueInput.vue'
|
|||
import JsonParamsInput from '../inputs/JsonParamsInput.vue'
|
||||
|
||||
import type { Trigger } from '@/api/iot/rule/scene'
|
||||
import { IotRuleSceneTriggerTypeEnum, getTriggerTypeOptions } from '@/views/iot/utils/constants'
|
||||
import {
|
||||
IotRuleSceneTriggerTypeEnum,
|
||||
getTriggerTypeOptions,
|
||||
getTriggerTypeLabel,
|
||||
getDeviceStatusChangeOptions
|
||||
} from '@/views/iot/utils/constants'
|
||||
import { useVModel } from '@vueuse/core'
|
||||
|
||||
/** 主条件内部配置组件 */
|
||||
|
@ -249,25 +258,9 @@ const eventConfig = computed(() => {
|
|||
return undefined
|
||||
})
|
||||
|
||||
// 获取触发类型文本
|
||||
// TODO @puhui999:是不是有枚举可以服用哈;
|
||||
const getTriggerTypeText = (type: number) => {
|
||||
switch (type) {
|
||||
case IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST:
|
||||
return '设备属性上报'
|
||||
case IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST:
|
||||
return '设备事件上报'
|
||||
case IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE:
|
||||
return '设备服务调用'
|
||||
case IotRuleSceneTriggerTypeEnum.DEVICE_STATE_UPDATE:
|
||||
return '设备状态变化'
|
||||
default:
|
||||
return '未知类型'
|
||||
}
|
||||
}
|
||||
|
||||
// 触发器类型选项
|
||||
// 使用标准化的选项获取函数
|
||||
const triggerTypeOptions = getTriggerTypeOptions()
|
||||
const deviceStatusChangeOptions = getDeviceStatusChangeOptions()
|
||||
|
||||
// 事件处理
|
||||
const updateConditionField = (field: keyof Trigger, value: any) => {
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<Icon icon="ep:setting" class="text-[var(--el-color-success)] text-16px" />
|
||||
<span>执行器 {{ index + 1 }}</span>
|
||||
<el-tag :type="getActionTypeTag(action.type)" size="small">
|
||||
{{ getActionTypeName(action.type) }}
|
||||
{{ getActionTypeLabel(action.type) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -139,7 +139,9 @@ import {
|
|||
isDeviceAction,
|
||||
isAlertAction,
|
||||
getActionTypeLabel,
|
||||
getActionTypeOptions
|
||||
getActionTypeOptions,
|
||||
getActionTypeTag,
|
||||
SCENE_RULE_CONFIG
|
||||
} from '@/views/iot/utils/constants'
|
||||
|
||||
/** 执行器配置组件 */
|
||||
|
@ -169,22 +171,8 @@ const createDefaultActionData = (): Action => {
|
|||
}
|
||||
}
|
||||
|
||||
const maxActions = 5 // 最大执行器数量
|
||||
|
||||
// 工具函数
|
||||
const getActionTypeName = (type: number) => {
|
||||
return getActionTypeLabel(type)
|
||||
}
|
||||
|
||||
const getActionTypeTag = (type: number) => {
|
||||
const actionTypeTags = {
|
||||
[ActionTypeEnum.DEVICE_PROPERTY_SET]: 'primary',
|
||||
[ActionTypeEnum.DEVICE_SERVICE_INVOKE]: 'success',
|
||||
[ActionTypeEnum.ALERT_TRIGGER]: 'danger',
|
||||
[ActionTypeEnum.ALERT_RECOVER]: 'warning'
|
||||
}
|
||||
return actionTypeTags[type] || 'info'
|
||||
}
|
||||
// 使用标准化的常量和函数
|
||||
const maxActions = SCENE_RULE_CONFIG.MAX_ACTIONS
|
||||
|
||||
/** 添加执行器 */
|
||||
const addAction = () => {
|
||||
|
|
|
@ -118,9 +118,9 @@ import DeviceTriggerConfig from '../configs/DeviceTriggerConfig.vue'
|
|||
import { Crontab } from '@/components/Crontab'
|
||||
import type { Trigger } from '@/api/iot/rule/scene'
|
||||
import {
|
||||
getTriggerTypeOptions,
|
||||
getTriggerTypeLabel,
|
||||
getTriggerTagType,
|
||||
IotRuleSceneTriggerTypeEnum as TriggerTypeEnum,
|
||||
IotRuleSceneTriggerTypeEnum,
|
||||
isDeviceTrigger
|
||||
} from '@/views/iot/utils/constants'
|
||||
|
||||
|
@ -137,23 +137,6 @@ const emit = defineEmits<{
|
|||
|
||||
const triggers = useVModel(props, 'triggers', emit)
|
||||
|
||||
// 触发器类型选项(从 constants 中获取)
|
||||
const triggerTypeOptions = getTriggerTypeOptions()
|
||||
|
||||
// 工具函数
|
||||
// TODO @puhui999:这里是不是重复了哈;
|
||||
const getTriggerTypeLabel = (type: number): string => {
|
||||
const option = triggerTypeOptions.find((opt) => opt.value === type)
|
||||
return option?.label || '未知类型'
|
||||
}
|
||||
|
||||
const getTriggerTagType = (type: number): string => {
|
||||
if (type === IotRuleSceneTriggerTypeEnum.TIMER) {
|
||||
return 'warning'
|
||||
}
|
||||
return isDeviceTrigger(type) ? 'success' : 'info'
|
||||
}
|
||||
|
||||
// 事件处理函数
|
||||
const addTrigger = () => {
|
||||
const newTrigger: Trigger = {
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
<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 size="small" :type="getDeviceEnableStatusTagType(device.status)">
|
||||
{{ getDeviceEnableStatusText(device.status) }}
|
||||
</el-tag>
|
||||
<el-tag size="small" :type="device.activeTime ? 'success' : 'info'">
|
||||
{{ device.activeTime ? '已激活' : '未激活' }}
|
||||
<el-tag size="small" :type="getDeviceActiveStatus(device.activeTime).tagType">
|
||||
{{ getDeviceActiveStatus(device.activeTime).text }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -38,6 +38,12 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { DeviceApi } from '@/api/iot/device/device'
|
||||
import {
|
||||
getDeviceEnableStatusText,
|
||||
getDeviceEnableStatusTagType,
|
||||
getDeviceActiveStatus,
|
||||
DEVICE_SELECTOR_OPTIONS
|
||||
} from '@/views/iot/utils/constants'
|
||||
|
||||
/** 设备选择器组件 */
|
||||
defineOptions({ name: 'DeviceSelector' })
|
||||
|
@ -77,33 +83,12 @@ const getDeviceList = async () => {
|
|||
console.error('获取设备列表失败:', error)
|
||||
deviceList.value = []
|
||||
} finally {
|
||||
deviceList.value.push({ id: 0, deviceName: '全部设备' })
|
||||
deviceList.value.push(DEVICE_SELECTOR_OPTIONS.ALL_DEVICES)
|
||||
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 '未知'
|
||||
}
|
||||
}
|
||||
// 设备状态处理函数已从 constants.ts 中导入
|
||||
|
||||
// 监听产品变化
|
||||
watch(
|
||||
|
|
|
@ -18,20 +18,17 @@
|
|||
:label="property.name"
|
||||
:value="property.identifier"
|
||||
>
|
||||
<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">
|
||||
{{ property.name }}
|
||||
</div>
|
||||
<div class="text-12px text-[var(--el-text-color-secondary)]">
|
||||
{{ property.identifier }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-shrink-0">
|
||||
<el-tag :type="getPropertyTypeTag(property.dataType)" size="small">
|
||||
{{ getPropertyTypeName(property.dataType) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="flex items-center justify-between w-full py-2px">
|
||||
<span class="text-14px font-500 text-[var(--el-text-color-primary)] flex-1 truncate">
|
||||
{{ property.name }}
|
||||
</span>
|
||||
<el-tag
|
||||
:type="getDataTypeTagType(property.dataType)"
|
||||
size="small"
|
||||
class="ml-8px flex-shrink-0"
|
||||
>
|
||||
{{ property.identifier }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
|
@ -65,8 +62,8 @@
|
|||
<span class="text-14px font-500 text-[var(--el-text-color-primary)]">
|
||||
{{ selectedProperty.name }}
|
||||
</span>
|
||||
<el-tag :type="getPropertyTypeTag(selectedProperty.dataType)" size="small">
|
||||
{{ getPropertyTypeName(selectedProperty.dataType) }}
|
||||
<el-tag :type="getDataTypeTagType(selectedProperty.dataType)" size="small">
|
||||
{{ getDataTypeName(selectedProperty.dataType) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
|
||||
|
@ -119,7 +116,7 @@
|
|||
访问模式:
|
||||
</span>
|
||||
<span class="text-12px text-[var(--el-text-color-primary)] flex-1">
|
||||
{{ getAccessModeText(selectedProperty.accessMode) }}
|
||||
{{ getAccessModeLabel(selectedProperty.accessMode) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
@ -133,7 +130,7 @@
|
|||
事件类型:
|
||||
</span>
|
||||
<span class="text-12px text-[var(--el-text-color-primary)] flex-1">
|
||||
{{ getEventTypeText(selectedProperty.eventType) }}
|
||||
{{ getEventTypeLabel(selectedProperty.eventType) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
@ -147,7 +144,7 @@
|
|||
调用类型:
|
||||
</span>
|
||||
<span class="text-12px text-[var(--el-text-color-primary)] flex-1">
|
||||
{{ getCallTypeText(selectedProperty.callType) }}
|
||||
{{ getThingModelServiceCallTypeLabel(selectedProperty.callType) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -162,7 +159,12 @@ import { InfoFilled } from '@element-plus/icons-vue'
|
|||
import {
|
||||
IotRuleSceneTriggerTypeEnum,
|
||||
IoTThingModelTypeEnum,
|
||||
IoTDataSpecsDataTypeEnum
|
||||
getAccessModeLabel,
|
||||
getEventTypeLabel,
|
||||
getThingModelServiceCallTypeLabel,
|
||||
getDataTypeName,
|
||||
getDataTypeTagType,
|
||||
THING_MODEL_GROUP_LABELS
|
||||
} from '@/views/iot/utils/constants'
|
||||
import type {
|
||||
IotThingModelTSLResp,
|
||||
|
@ -177,7 +179,7 @@ import { ThingModelApi } from '@/api/iot/thingmodel'
|
|||
defineOptions({ name: 'PropertySelector' })
|
||||
|
||||
/** 属性选择器内部使用的统一数据结构 */
|
||||
export interface PropertySelectorItem {
|
||||
interface PropertySelectorItem {
|
||||
identifier: string
|
||||
name: string
|
||||
description?: string
|
||||
|
@ -221,21 +223,21 @@ const propertyGroups = computed(() => {
|
|||
|
||||
if (props.triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST) {
|
||||
groups.push({
|
||||
label: '设备属性',
|
||||
label: THING_MODEL_GROUP_LABELS.PROPERTY,
|
||||
options: propertyList.value.filter((p) => p.type === IoTThingModelTypeEnum.PROPERTY)
|
||||
})
|
||||
}
|
||||
|
||||
if (props.triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST) {
|
||||
groups.push({
|
||||
label: '设备事件',
|
||||
label: THING_MODEL_GROUP_LABELS.EVENT,
|
||||
options: propertyList.value.filter((p) => p.type === IoTThingModelTypeEnum.EVENT)
|
||||
})
|
||||
}
|
||||
|
||||
if (props.triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_SERVICE_INVOKE) {
|
||||
groups.push({
|
||||
label: '设备服务',
|
||||
label: THING_MODEL_GROUP_LABELS.SERVICE,
|
||||
options: propertyList.value.filter((p) => p.type === IoTThingModelTypeEnum.SERVICE)
|
||||
})
|
||||
}
|
||||
|
@ -247,66 +249,6 @@ const selectedProperty = computed(() => {
|
|||
return propertyList.value.find((p) => p.identifier === localValue.value)
|
||||
})
|
||||
|
||||
// 工具函数
|
||||
const getPropertyTypeName = (dataType: string) => {
|
||||
const typeMap = {
|
||||
[IoTDataSpecsDataTypeEnum.INT]: '整数',
|
||||
[IoTDataSpecsDataTypeEnum.FLOAT]: '浮点数',
|
||||
[IoTDataSpecsDataTypeEnum.DOUBLE]: '双精度',
|
||||
[IoTDataSpecsDataTypeEnum.TEXT]: '字符串',
|
||||
[IoTDataSpecsDataTypeEnum.BOOL]: '布尔值',
|
||||
[IoTDataSpecsDataTypeEnum.ENUM]: '枚举',
|
||||
[IoTDataSpecsDataTypeEnum.DATE]: '日期',
|
||||
[IoTDataSpecsDataTypeEnum.STRUCT]: '结构体',
|
||||
[IoTDataSpecsDataTypeEnum.ARRAY]: '数组'
|
||||
}
|
||||
return typeMap[dataType] || dataType
|
||||
}
|
||||
|
||||
const getPropertyTypeTag = (dataType: string) => {
|
||||
const tagMap = {
|
||||
[IoTDataSpecsDataTypeEnum.INT]: 'primary',
|
||||
[IoTDataSpecsDataTypeEnum.FLOAT]: 'success',
|
||||
[IoTDataSpecsDataTypeEnum.DOUBLE]: 'success',
|
||||
[IoTDataSpecsDataTypeEnum.TEXT]: 'info',
|
||||
[IoTDataSpecsDataTypeEnum.BOOL]: 'warning',
|
||||
[IoTDataSpecsDataTypeEnum.ENUM]: 'danger',
|
||||
[IoTDataSpecsDataTypeEnum.DATE]: 'primary',
|
||||
[IoTDataSpecsDataTypeEnum.STRUCT]: 'info',
|
||||
[IoTDataSpecsDataTypeEnum.ARRAY]: 'warning'
|
||||
}
|
||||
return tagMap[dataType] || 'info'
|
||||
}
|
||||
|
||||
// 工具函数 - 获取访问模式文本
|
||||
const getAccessModeText = (accessMode: string) => {
|
||||
const modeMap = {
|
||||
r: '只读',
|
||||
w: '只写',
|
||||
rw: '读写'
|
||||
}
|
||||
return modeMap[accessMode] || accessMode
|
||||
}
|
||||
|
||||
// 工具函数 - 获取事件类型文本
|
||||
const getEventTypeText = (eventType: string) => {
|
||||
const typeMap = {
|
||||
info: '信息',
|
||||
alert: '告警',
|
||||
error: '故障'
|
||||
}
|
||||
return typeMap[eventType] || eventType
|
||||
}
|
||||
|
||||
// 工具函数 - 获取调用类型文本
|
||||
const getCallTypeText = (callType: string) => {
|
||||
const typeMap = {
|
||||
sync: '同步',
|
||||
async: '异步'
|
||||
}
|
||||
return typeMap[callType] || callType
|
||||
}
|
||||
|
||||
// 事件处理
|
||||
const handleChange = (value: string) => {
|
||||
const property = propertyList.value.find((p) => p.identifier === value)
|
||||
|
@ -336,36 +278,17 @@ const getThingModelTSL = async () => {
|
|||
thingModelTSL.value = tslData
|
||||
parseThingModelData()
|
||||
} else {
|
||||
// 如果TSL获取失败,尝试获取物模型列表
|
||||
await getThingModelList()
|
||||
console.error('获取物模型TSL失败: 返回数据为空')
|
||||
propertyList.value = []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取物模型TSL失败:', error)
|
||||
// 如果TSL获取失败,尝试获取物模型列表
|
||||
await getThingModelList()
|
||||
propertyList.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物模型列表(备用方案)
|
||||
*/
|
||||
const getThingModelList = async () => {
|
||||
if (!props.productId) {
|
||||
propertyList.value = []
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await ThingModelApi.getThingModelList({ productId: props.productId })
|
||||
propertyList.value = data || []
|
||||
} catch (error) {
|
||||
console.error('获取物模型列表失败:', error)
|
||||
propertyList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 解析物模型TSL数据
|
||||
const parseThingModelData = () => {
|
||||
const tsl = thingModelTSL.value
|
||||
|
@ -484,7 +407,7 @@ watch(
|
|||
/* 下拉选项样式 */
|
||||
:deep(.el-select-dropdown__item) {
|
||||
height: auto;
|
||||
padding: 8px 20px;
|
||||
padding: 6px 20px;
|
||||
}
|
||||
|
||||
/* 弹出层内容样式 */
|
||||
|
|
|
@ -158,6 +158,47 @@ export const getDataTypeOptionsLabel = (value: string) => {
|
|||
return dataType && `${dataType.value}(${dataType.label})`
|
||||
}
|
||||
|
||||
/** 获取数据类型显示名称(用于属性选择器) */
|
||||
export const getDataTypeName = (dataType: string): string => {
|
||||
const typeMap = {
|
||||
[IoTDataSpecsDataTypeEnum.INT]: '整数',
|
||||
[IoTDataSpecsDataTypeEnum.FLOAT]: '浮点数',
|
||||
[IoTDataSpecsDataTypeEnum.DOUBLE]: '双精度',
|
||||
[IoTDataSpecsDataTypeEnum.TEXT]: '字符串',
|
||||
[IoTDataSpecsDataTypeEnum.BOOL]: '布尔值',
|
||||
[IoTDataSpecsDataTypeEnum.ENUM]: '枚举',
|
||||
[IoTDataSpecsDataTypeEnum.DATE]: '日期',
|
||||
[IoTDataSpecsDataTypeEnum.STRUCT]: '结构体',
|
||||
[IoTDataSpecsDataTypeEnum.ARRAY]: '数组'
|
||||
}
|
||||
return typeMap[dataType] || dataType
|
||||
}
|
||||
|
||||
/** 获取数据类型标签类型(用于 el-tag 的 type 属性) */
|
||||
export const getDataTypeTagType = (
|
||||
dataType: string
|
||||
): 'primary' | 'success' | 'info' | 'warning' | 'danger' => {
|
||||
const tagMap = {
|
||||
[IoTDataSpecsDataTypeEnum.INT]: 'primary',
|
||||
[IoTDataSpecsDataTypeEnum.FLOAT]: 'success',
|
||||
[IoTDataSpecsDataTypeEnum.DOUBLE]: 'success',
|
||||
[IoTDataSpecsDataTypeEnum.TEXT]: 'info',
|
||||
[IoTDataSpecsDataTypeEnum.BOOL]: 'warning',
|
||||
[IoTDataSpecsDataTypeEnum.ENUM]: 'danger',
|
||||
[IoTDataSpecsDataTypeEnum.DATE]: 'primary',
|
||||
[IoTDataSpecsDataTypeEnum.STRUCT]: 'info',
|
||||
[IoTDataSpecsDataTypeEnum.ARRAY]: 'warning'
|
||||
} as const
|
||||
return tagMap[dataType] || 'info'
|
||||
}
|
||||
|
||||
/** 物模型组标签常量 */
|
||||
export const THING_MODEL_GROUP_LABELS = {
|
||||
PROPERTY: '设备属性',
|
||||
EVENT: '设备事件',
|
||||
SERVICE: '设备服务'
|
||||
} as const
|
||||
|
||||
// IoT OTA 任务设备范围枚举
|
||||
export const IoTOtaTaskDeviceScopeEnum = {
|
||||
ALL: {
|
||||
|
@ -314,6 +355,26 @@ export const getActionTypeLabel = (type: number): string => {
|
|||
return option?.label || '未知类型'
|
||||
}
|
||||
|
||||
/** 获取执行器标签类型(用于 el-tag 的 type 属性) */
|
||||
export const getActionTypeTag = (
|
||||
type: number
|
||||
): 'primary' | 'success' | 'info' | 'warning' | 'danger' => {
|
||||
const actionTypeTags = {
|
||||
[IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET]: 'primary',
|
||||
[IotRuleSceneActionTypeEnum.DEVICE_SERVICE_INVOKE]: 'success',
|
||||
[IotRuleSceneActionTypeEnum.ALERT_TRIGGER]: 'danger',
|
||||
[IotRuleSceneActionTypeEnum.ALERT_RECOVER]: 'warning'
|
||||
} as const
|
||||
return actionTypeTags[type] || 'info'
|
||||
}
|
||||
|
||||
/** 场景联动规则配置常量 */
|
||||
export const SCENE_RULE_CONFIG = {
|
||||
MAX_ACTIONS: 5, // 最大执行器数量
|
||||
MAX_TRIGGERS: 10, // 最大触发器数量
|
||||
MAX_CONDITIONS: 20 // 最大条件数量
|
||||
} as const
|
||||
|
||||
/** IoT 设备消息类型枚举 */
|
||||
export const IotDeviceMessageTypeEnum = {
|
||||
PROPERTY: 'property', // 属性
|
||||
|
@ -344,6 +405,131 @@ export const IotRuleSceneTriggerConditionTypeEnum = {
|
|||
CURRENT_TIME: 3 // 当前时间
|
||||
} as const
|
||||
|
||||
/** 获取条件类型选项 */
|
||||
export const getConditionTypeOptions = () => [
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS,
|
||||
label: '设备状态'
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY,
|
||||
label: '设备属性'
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME,
|
||||
label: '当前时间'
|
||||
}
|
||||
]
|
||||
|
||||
/** 设备状态枚举 */
|
||||
export const IoTDeviceStatusEnum = {
|
||||
ONLINE: {
|
||||
label: '在线',
|
||||
value: 'online'
|
||||
},
|
||||
OFFLINE: {
|
||||
label: '离线',
|
||||
value: 'offline'
|
||||
}
|
||||
} as const
|
||||
|
||||
/** 设备启用状态枚举 */
|
||||
export const IoTDeviceEnableStatusEnum = {
|
||||
ENABLED: {
|
||||
label: '正常',
|
||||
value: 0,
|
||||
tagType: 'success'
|
||||
},
|
||||
DISABLED: {
|
||||
label: '禁用',
|
||||
value: 1,
|
||||
tagType: 'danger'
|
||||
}
|
||||
} as const
|
||||
|
||||
/** 设备激活状态枚举 */
|
||||
export const IoTDeviceActiveStatusEnum = {
|
||||
ACTIVATED: {
|
||||
label: '已激活',
|
||||
tagType: 'success'
|
||||
},
|
||||
NOT_ACTIVATED: {
|
||||
label: '未激活',
|
||||
tagType: 'info'
|
||||
}
|
||||
} as const
|
||||
|
||||
/** 设备选择器特殊选项 */
|
||||
export const DEVICE_SELECTOR_OPTIONS = {
|
||||
ALL_DEVICES: {
|
||||
id: 0,
|
||||
deviceName: '全部设备'
|
||||
}
|
||||
} as const
|
||||
|
||||
/** 获取设备状态选项 */
|
||||
export const getDeviceStatusOptions = () => [
|
||||
{
|
||||
value: IoTDeviceStatusEnum.ONLINE.value,
|
||||
label: IoTDeviceStatusEnum.ONLINE.label
|
||||
},
|
||||
{
|
||||
value: IoTDeviceStatusEnum.OFFLINE.value,
|
||||
label: IoTDeviceStatusEnum.OFFLINE.label
|
||||
}
|
||||
]
|
||||
|
||||
/** 获取状态操作符选项 */
|
||||
export const getStatusOperatorOptions = () => [
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value,
|
||||
label: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.name
|
||||
},
|
||||
{
|
||||
value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.value,
|
||||
label: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.name
|
||||
}
|
||||
]
|
||||
|
||||
/** 获取设备状态变更选项(用于触发器配置) */
|
||||
export const getDeviceStatusChangeOptions = () => [
|
||||
{
|
||||
label: '变为在线',
|
||||
value: IoTDeviceStatusEnum.ONLINE.value
|
||||
},
|
||||
{
|
||||
label: '变为离线',
|
||||
value: IoTDeviceStatusEnum.OFFLINE.value
|
||||
}
|
||||
]
|
||||
|
||||
/** 获取设备启用状态文本 */
|
||||
export const getDeviceEnableStatusText = (status: number): string => {
|
||||
const statusItem = Object.values(IoTDeviceEnableStatusEnum).find((item) => item.value === status)
|
||||
return statusItem?.label || '未知'
|
||||
}
|
||||
|
||||
/** 获取设备启用状态标签类型 */
|
||||
export const getDeviceEnableStatusTagType = (
|
||||
status: number
|
||||
): 'primary' | 'success' | 'info' | 'warning' | 'danger' => {
|
||||
const statusItem = Object.values(IoTDeviceEnableStatusEnum).find((item) => item.value === status)
|
||||
return statusItem?.tagType || 'info'
|
||||
}
|
||||
|
||||
/** 获取设备激活状态文本和标签类型 */
|
||||
export const getDeviceActiveStatus = (activeTime?: string | null) => {
|
||||
const isActivated = !!activeTime
|
||||
return {
|
||||
text: isActivated
|
||||
? IoTDeviceActiveStatusEnum.ACTIVATED.label
|
||||
: IoTDeviceActiveStatusEnum.NOT_ACTIVATED.label,
|
||||
tagType: isActivated
|
||||
? IoTDeviceActiveStatusEnum.ACTIVATED.tagType
|
||||
: IoTDeviceActiveStatusEnum.NOT_ACTIVATED.tagType
|
||||
}
|
||||
}
|
||||
|
||||
/** IoT 场景联动触发时间操作符枚举 */
|
||||
export const IotRuleSceneTriggerTimeOperatorEnum = {
|
||||
BEFORE_TIME: { name: '在时间之前', value: 'before_time' }, // 在时间之前
|
||||
|
@ -363,3 +549,13 @@ export const getTriggerTypeLabel = (type: number): string => {
|
|||
const option = options.find((item) => item.value === type)
|
||||
return option?.label || '未知类型'
|
||||
}
|
||||
|
||||
/** 获取触发器标签类型(用于 el-tag 的 type 属性) */
|
||||
export const getTriggerTagType = (
|
||||
type: number
|
||||
): 'primary' | 'success' | 'info' | 'warning' | 'danger' => {
|
||||
if (type === IotRuleSceneTriggerTypeEnum.TIMER) {
|
||||
return 'warning'
|
||||
}
|
||||
return isDeviceTrigger(type) ? 'success' : 'info'
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue