feat:【iot 物联网】优化场景联动的界面
parent
be964a6287
commit
3686b58dbb
|
|
@ -150,7 +150,6 @@ const authDialogVisible = ref(false) // 定义设备认证信息弹框的可见
|
||||||
const authPasswordVisible = ref(false) // 定义密码可见性状态
|
const authPasswordVisible = ref(false) // 定义密码可见性状态
|
||||||
const authInfo = ref<IotDeviceAuthInfoVO>({} as IotDeviceAuthInfoVO) // 定义设备认证信息对象
|
const authInfo = ref<IotDeviceAuthInfoVO>({} as IotDeviceAuthInfoVO) // 定义设备认证信息对象
|
||||||
|
|
||||||
// TODO @AI:注释使用 /** */ 风格,方法注释;
|
|
||||||
/** 控制地图显示的标志 */
|
/** 控制地图显示的标志 */
|
||||||
const showMap = computed(() => {
|
const showMap = computed(() => {
|
||||||
return !!(device.longitude && device.latitude)
|
return !!(device.longitude && device.latitude)
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
<!-- 值输入组件 -->
|
<!-- 值输入组件 -->
|
||||||
<!-- TODO @yunai:这个需要在看看。。。 -->
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full min-w-0">
|
<div class="w-full min-w-0">
|
||||||
<!-- 布尔值选择 -->
|
<!-- 布尔值选择 -->
|
||||||
<el-select
|
<el-select
|
||||||
v-if="propertyType === 'bool'"
|
v-if="propertyType === IoTDataSpecsDataTypeEnum.BOOL"
|
||||||
v-model="localValue"
|
v-model="localValue"
|
||||||
placeholder="请选择布尔值"
|
placeholder="请选择布尔值"
|
||||||
@change="handleChange"
|
|
||||||
class="w-full!"
|
class="w-full!"
|
||||||
style="width: 100% !important"
|
|
||||||
>
|
>
|
||||||
<el-option label="真 (true)" value="true" />
|
<el-option label="真 (true)" value="true" />
|
||||||
<el-option label="假 (false)" value="false" />
|
<el-option label="假 (false)" value="false" />
|
||||||
|
|
@ -17,12 +14,10 @@
|
||||||
|
|
||||||
<!-- 枚举值选择 -->
|
<!-- 枚举值选择 -->
|
||||||
<el-select
|
<el-select
|
||||||
v-else-if="propertyType === 'enum' && enumOptions.length > 0"
|
v-else-if="propertyType === IoTDataSpecsDataTypeEnum.ENUM && enumOptions.length > 0"
|
||||||
v-model="localValue"
|
v-model="localValue"
|
||||||
placeholder="请选择枚举值"
|
placeholder="请选择枚举值"
|
||||||
@change="handleChange"
|
|
||||||
class="w-full!"
|
class="w-full!"
|
||||||
style="width: 100% !important"
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="option in enumOptions"
|
v-for="option in enumOptions"
|
||||||
|
|
@ -34,9 +29,8 @@
|
||||||
|
|
||||||
<!-- 范围输入 (between 操作符) -->
|
<!-- 范围输入 (between 操作符) -->
|
||||||
<div
|
<div
|
||||||
v-else-if="operator === 'between'"
|
v-else-if="operator === IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.value"
|
||||||
class="w-full! flex items-center gap-8px"
|
class="w-full! flex items-center gap-8px"
|
||||||
style="width: 100% !important"
|
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="rangeStart"
|
v-model="rangeStart"
|
||||||
|
|
@ -53,19 +47,15 @@
|
||||||
placeholder="最大值"
|
placeholder="最大值"
|
||||||
@input="handleRangeChange"
|
@input="handleRangeChange"
|
||||||
class="flex-1 min-w-0"
|
class="flex-1 min-w-0"
|
||||||
style="width: auto !important"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 列表输入 (in 操作符) -->
|
<!-- 列表输入 (in 操作符) -->
|
||||||
<div v-else-if="operator === 'in'" class="w-full!" style="width: 100% !important">
|
<div
|
||||||
<el-input
|
v-else-if="operator === IotRuleSceneTriggerConditionParameterOperatorEnum.IN.value"
|
||||||
v-model="localValue"
|
class="w-full!"
|
||||||
placeholder="请输入值列表,用逗号分隔"
|
>
|
||||||
@input="handleChange"
|
<el-input v-model="localValue" placeholder="请输入值列表,用逗号分隔" class="w-full!">
|
||||||
class="w-full!"
|
|
||||||
style="width: 100% !important"
|
|
||||||
>
|
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<el-tooltip content="多个值用逗号分隔,如:1,2,3" placement="top">
|
<el-tooltip content="多个值用逗号分隔,如:1,2,3" placement="top">
|
||||||
<Icon
|
<Icon
|
||||||
|
|
@ -85,7 +75,7 @@
|
||||||
|
|
||||||
<!-- 日期时间输入 -->
|
<!-- 日期时间输入 -->
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-else-if="propertyType === 'date'"
|
v-else-if="propertyType === IoTDataSpecsDataTypeEnum.DATE"
|
||||||
v-model="dateValue"
|
v-model="dateValue"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder="请选择日期时间"
|
placeholder="请选择日期时间"
|
||||||
|
|
@ -93,7 +83,6 @@
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
@change="handleDateChange"
|
@change="handleDateChange"
|
||||||
class="w-full!"
|
class="w-full!"
|
||||||
style="width: 100% !important"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 数字输入 -->
|
<!-- 数字输入 -->
|
||||||
|
|
@ -107,7 +96,6 @@
|
||||||
placeholder="请输入数值"
|
placeholder="请输入数值"
|
||||||
@change="handleNumberChange"
|
@change="handleNumberChange"
|
||||||
class="w-full!"
|
class="w-full!"
|
||||||
style="width: 100% !important"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 文本输入 -->
|
<!-- 文本输入 -->
|
||||||
|
|
@ -116,9 +104,7 @@
|
||||||
v-model="localValue"
|
v-model="localValue"
|
||||||
:type="getInputType()"
|
:type="getInputType()"
|
||||||
:placeholder="getPlaceholder()"
|
:placeholder="getPlaceholder()"
|
||||||
@input="handleChange"
|
|
||||||
class="w-full!"
|
class="w-full!"
|
||||||
style="width: 100% !important"
|
|
||||||
>
|
>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
|
|
@ -126,9 +112,9 @@
|
||||||
:content="`单位:${propertyConfig.unit}`"
|
:content="`单位:${propertyConfig.unit}`"
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<span class="text-12px text-[var(--el-text-color-secondary)] px-4px">{{
|
<span class="text-12px text-[var(--el-text-color-secondary)] px-4px">
|
||||||
propertyConfig.unit
|
{{ propertyConfig.unit }}
|
||||||
}}</span>
|
</span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
|
@ -137,7 +123,10 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useVModel } from '@vueuse/core'
|
import { useVModel } from '@vueuse/core'
|
||||||
import { IoTDataSpecsDataTypeEnum } from '@/views/iot/utils/constants'
|
import {
|
||||||
|
IoTDataSpecsDataTypeEnum,
|
||||||
|
IotRuleSceneTriggerConditionParameterOperatorEnum
|
||||||
|
} from '@/views/iot/utils/constants'
|
||||||
|
|
||||||
/** 值输入组件 */
|
/** 值输入组件 */
|
||||||
defineOptions({ name: 'ValueInput' })
|
defineOptions({ name: 'ValueInput' })
|
||||||
|
|
@ -165,7 +154,7 @@ const rangeEnd = ref('') // 范围结束值
|
||||||
const dateValue = ref('') // 日期值
|
const dateValue = ref('') // 日期值
|
||||||
const numberValue = ref<number>() // 数字值
|
const numberValue = ref<number>() // 数字值
|
||||||
|
|
||||||
// 计算属性:枚举选项
|
/** 计算属性:枚举选项 */
|
||||||
const enumOptions = computed(() => {
|
const enumOptions = computed(() => {
|
||||||
if (props.propertyConfig?.enum) {
|
if (props.propertyConfig?.enum) {
|
||||||
return props.propertyConfig.enum.map((item: any) => ({
|
return props.propertyConfig.enum.map((item: any) => ({
|
||||||
|
|
@ -176,9 +165,12 @@ const enumOptions = computed(() => {
|
||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
|
|
||||||
// 计算属性:列表预览
|
/** 计算属性:列表预览 */
|
||||||
const listPreview = computed(() => {
|
const listPreview = computed(() => {
|
||||||
if (props.operator === 'in' && localValue.value) {
|
if (
|
||||||
|
props.operator === IotRuleSceneTriggerConditionParameterOperatorEnum.IN.value &&
|
||||||
|
localValue.value
|
||||||
|
) {
|
||||||
return localValue.value
|
return localValue.value
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((item) => item.trim())
|
.map((item) => item.trim())
|
||||||
|
|
@ -187,10 +179,7 @@ const listPreview = computed(() => {
|
||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/** 判断是否为数字类型 */
|
||||||
* 判断是否为数字类型
|
|
||||||
* @returns 是否为数字类型
|
|
||||||
*/
|
|
||||||
const isNumericType = () => {
|
const isNumericType = () => {
|
||||||
return [
|
return [
|
||||||
IoTDataSpecsDataTypeEnum.INT,
|
IoTDataSpecsDataTypeEnum.INT,
|
||||||
|
|
@ -199,10 +188,7 @@ const isNumericType = () => {
|
||||||
].includes((props.propertyType || '') as any)
|
].includes((props.propertyType || '') as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 获取输入框类型 */
|
||||||
* 获取输入框类型
|
|
||||||
* @returns 输入框类型
|
|
||||||
*/
|
|
||||||
const getInputType = () => {
|
const getInputType = () => {
|
||||||
switch (props.propertyType) {
|
switch (props.propertyType) {
|
||||||
case IoTDataSpecsDataTypeEnum.INT:
|
case IoTDataSpecsDataTypeEnum.INT:
|
||||||
|
|
@ -214,10 +200,7 @@ const getInputType = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 获取占位符文本 */
|
||||||
* 获取占位符文本
|
|
||||||
* @returns 占位符文本
|
|
||||||
*/
|
|
||||||
const getPlaceholder = () => {
|
const getPlaceholder = () => {
|
||||||
const typeMap = {
|
const typeMap = {
|
||||||
[IoTDataSpecsDataTypeEnum.TEXT]: '请输入字符串',
|
[IoTDataSpecsDataTypeEnum.TEXT]: '请输入字符串',
|
||||||
|
|
@ -230,48 +213,27 @@ const getPlaceholder = () => {
|
||||||
return typeMap[props.propertyType || ''] || '请输入值'
|
return typeMap[props.propertyType || ''] || '请输入值'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 获取数字精度 */
|
||||||
* 获取数字精度
|
|
||||||
* @returns 数字精度
|
|
||||||
*/
|
|
||||||
const getPrecision = () => {
|
const getPrecision = () => {
|
||||||
return props.propertyType === IoTDataSpecsDataTypeEnum.INT ? 0 : 2
|
return props.propertyType === IoTDataSpecsDataTypeEnum.INT ? 0 : 2
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 获取数字步长 */
|
||||||
* 获取数字步长
|
|
||||||
* @returns 数字步长
|
|
||||||
*/
|
|
||||||
const getStep = () => {
|
const getStep = () => {
|
||||||
return props.propertyType === IoTDataSpecsDataTypeEnum.INT ? 1 : 0.1
|
return props.propertyType === IoTDataSpecsDataTypeEnum.INT ? 1 : 0.1
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 获取最小值 */
|
||||||
* 获取最小值
|
|
||||||
* @returns 最小值
|
|
||||||
*/
|
|
||||||
const getMin = () => {
|
const getMin = () => {
|
||||||
return props.propertyConfig?.min || undefined
|
return props.propertyConfig?.min || undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 获取最大值 */
|
||||||
* 获取最大值
|
|
||||||
* @returns 最大值
|
|
||||||
*/
|
|
||||||
const getMax = () => {
|
const getMax = () => {
|
||||||
return props.propertyConfig?.max || undefined
|
return props.propertyConfig?.max || undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 处理范围变化事件 */
|
||||||
* 处理值变化事件
|
|
||||||
*/
|
|
||||||
const handleChange = () => {
|
|
||||||
// 值变化处理
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理范围变化事件
|
|
||||||
*/
|
|
||||||
const handleRangeChange = () => {
|
const handleRangeChange = () => {
|
||||||
if (rangeStart.value && rangeEnd.value) {
|
if (rangeStart.value && rangeEnd.value) {
|
||||||
localValue.value = `${rangeStart.value},${rangeEnd.value}`
|
localValue.value = `${rangeStart.value},${rangeEnd.value}`
|
||||||
|
|
@ -280,23 +242,17 @@ const handleRangeChange = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 处理日期变化事件 */
|
||||||
* 处理日期变化事件
|
|
||||||
* @param value 日期值
|
|
||||||
*/
|
|
||||||
const handleDateChange = (value: string) => {
|
const handleDateChange = (value: string) => {
|
||||||
localValue.value = value || ''
|
localValue.value = value || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 处理数字变化事件 */
|
||||||
* 处理数字变化事件
|
|
||||||
* @param value 数字值
|
|
||||||
*/
|
|
||||||
const handleNumberChange = (value: number | undefined) => {
|
const handleNumberChange = (value: number | undefined) => {
|
||||||
localValue.value = value?.toString() || ''
|
localValue.value = value?.toString() || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听操作符变化
|
/** 监听操作符变化 */
|
||||||
watch(
|
watch(
|
||||||
() => props.operator,
|
() => props.operator,
|
||||||
() => {
|
() => {
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@
|
||||||
<el-tag size="small" type="warning">自动执行</el-tag>
|
<el-tag size="small" type="warning">自动执行</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-12px text-[var(--el-text-color-secondary)] leading-relaxed">
|
<div class="text-12px text-[var(--el-text-color-secondary)] leading-relaxed">
|
||||||
当触发条件满足时,系统将自动发送告警通知,无需额外配置。
|
当触发条件满足时,系统将自动发送告警通知,可在菜单 [告警中心 -> 告警配置] 管理。
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -79,9 +79,9 @@
|
||||||
<Icon icon="ep:document" />
|
<Icon icon="ep:document" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-24px font-600 text-[#303133] leading-none">{{
|
<div class="text-24px font-600 text-[#303133] leading-none">
|
||||||
statistics.total
|
{{ statistics.total }}
|
||||||
}}</div>
|
</div>
|
||||||
<div class="text-14px text-[#909399] mt-4px">总规则数</div>
|
<div class="text-14px text-[#909399] mt-4px">总规则数</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -99,9 +99,9 @@
|
||||||
<Icon icon="ep:check" />
|
<Icon icon="ep:check" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-24px font-600 text-[#303133] leading-none">{{
|
<div class="text-24px font-600 text-[#303133] leading-none">
|
||||||
statistics.enabled
|
{{ statistics.enabled }}
|
||||||
}}</div>
|
</div>
|
||||||
<div class="text-14px text-[#909399] mt-4px">启用规则</div>
|
<div class="text-14px text-[#909399] mt-4px">启用规则</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -119,9 +119,9 @@
|
||||||
<Icon icon="ep:close" />
|
<Icon icon="ep:close" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-24px font-600 text-[#303133] leading-none">{{
|
<div class="text-24px font-600 text-[#303133] leading-none">
|
||||||
statistics.disabled
|
{{ statistics.disabled }}
|
||||||
}}</div>
|
</div>
|
||||||
<div class="text-14px text-[#909399] mt-4px">禁用规则</div>
|
<div class="text-14px text-[#909399] mt-4px">禁用规则</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -139,9 +139,9 @@
|
||||||
<Icon icon="ep:timer" />
|
<Icon icon="ep:timer" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-24px font-600 text-[#303133] leading-none">{{
|
<div class="text-24px font-600 text-[#303133] leading-none">
|
||||||
statistics.timerRules
|
{{ statistics.timerRules }}
|
||||||
}}</div>
|
</div>
|
||||||
<div class="text-14px text-[#909399] mt-4px">定时规则</div>
|
<div class="text-14px text-[#909399] mt-4px">定时规则</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -214,7 +214,7 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="210" fixed="right">
|
<el-table-column label="操作" width="210" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex gap-8px">
|
<div>
|
||||||
<el-button type="primary" link @click="handleEdit(row)">
|
<el-button type="primary" link @click="handleEdit(row)">
|
||||||
<Icon icon="ep:edit" />
|
<Icon icon="ep:edit" />
|
||||||
编辑
|
编辑
|
||||||
|
|
@ -293,7 +293,6 @@ const statistics = ref({
|
||||||
total: 0,
|
total: 0,
|
||||||
enabled: 0,
|
enabled: 0,
|
||||||
disabled: 0,
|
disabled: 0,
|
||||||
triggered: 0, // 已触发的规则数量 (暂时使用启用状态的规则数量)
|
|
||||||
timerRules: 0 // 定时规则数量
|
timerRules: 0 // 定时规则数量
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -321,9 +320,9 @@ const getRuleSceneSummary = (rule: IotSceneRule) => {
|
||||||
}
|
}
|
||||||
// 添加设备信息(如果有)
|
// 添加设备信息(如果有)
|
||||||
if (trigger.deviceId) {
|
if (trigger.deviceId) {
|
||||||
description += ` [设备ID: ${trigger.deviceId}]`
|
description += ` [设备 ID: ${trigger.deviceId}]`
|
||||||
} else if (trigger.productId) {
|
} else if (trigger.productId) {
|
||||||
description += ` [产品ID: ${trigger.productId}]`
|
description += ` [产品 ID: ${trigger.productId}]`
|
||||||
}
|
}
|
||||||
return description
|
return description
|
||||||
}) || []
|
}) || []
|
||||||
|
|
@ -334,13 +333,13 @@ const getRuleSceneSummary = (rule: IotSceneRule) => {
|
||||||
let description = getActionTypeLabel(action.type)
|
let description = getActionTypeLabel(action.type)
|
||||||
// 添加设备信息(如果有)
|
// 添加设备信息(如果有)
|
||||||
if (action.deviceId) {
|
if (action.deviceId) {
|
||||||
description += ` [设备ID: ${action.deviceId}]`
|
description += ` [设备 ID: ${action.deviceId}]`
|
||||||
} else if (action.productId) {
|
} else if (action.productId) {
|
||||||
description += ` [产品ID: ${action.productId}]`
|
description += ` [产品 ID: ${action.productId}]`
|
||||||
}
|
}
|
||||||
// 添加告警配置信息(如果有)
|
// 添加告警配置信息(如果有)
|
||||||
if (action.alertConfigId) {
|
if (action.alertConfigId) {
|
||||||
description += ` [告警配置ID: ${action.alertConfigId}]`
|
description += ` [告警配置 ID: ${action.alertConfigId}]`
|
||||||
}
|
}
|
||||||
return description
|
return description
|
||||||
}) || []
|
}) || []
|
||||||
|
|
@ -371,7 +370,6 @@ const updateStatistics = () => {
|
||||||
total: list.value.length,
|
total: list.value.length,
|
||||||
enabled: list.value.filter((item) => item.status === CommonStatusEnum.ENABLE).length,
|
enabled: list.value.filter((item) => item.status === CommonStatusEnum.ENABLE).length,
|
||||||
disabled: list.value.filter((item) => item.status === CommonStatusEnum.DISABLE).length,
|
disabled: list.value.filter((item) => item.status === CommonStatusEnum.DISABLE).length,
|
||||||
triggered: list.value.filter((item) => item.status === CommonStatusEnum.ENABLE).length,
|
|
||||||
timerRules: list.value.filter((item) => hasTimerTrigger(item)).length
|
timerRules: list.value.filter((item) => hasTimerTrigger(item)).length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue