From a554bc53098d4494f3a0fa4f834c10169840d222 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 1 Aug 2025 16:14:11 +0800 Subject: [PATCH] =?UTF-8?q?perf=EF=BC=9A=E3=80=90IoT=20=E7=89=A9=E8=81=94?= =?UTF-8?q?=E7=BD=91=E3=80=91=E5=9C=BA=E6=99=AF=E8=81=94=E5=8A=A8=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=99=A8=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/iot/rule/scene/scene.types.ts | 51 +--- .../iot/rule/scene/form/RuleSceneForm.vue | 109 +++---- .../form/configs/ConditionGroupConfig.vue | 8 +- .../form/configs/DeviceTriggerConfig.vue | 23 +- .../form/configs/MainConditionConfig.vue | 26 +- .../form/configs/MainConditionInnerConfig.vue | 9 +- .../scene/form/sections/BasicInfoSection.vue | 23 +- .../scene/form/sections/TriggerSection.vue | 275 +++++++++++------- .../scene/form/selectors/OperatorSelector.vue | 28 +- .../scene/form/selectors/PropertySelector.vue | 268 +++++++++++++++-- src/views/iot/utils/constants.ts | 46 +++ 11 files changed, 551 insertions(+), 315 deletions(-) diff --git a/src/api/iot/rule/scene/scene.types.ts b/src/api/iot/rule/scene/scene.types.ts index a9ba63b9c..29fc5f533 100644 --- a/src/api/iot/rule/scene/scene.types.ts +++ b/src/api/iot/rule/scene/scene.types.ts @@ -2,15 +2,7 @@ * IoT 场景联动接口定义 */ -// TODO @puhui999:枚举挪到 views/iot/utils/constants.ts 里 -// 枚举定义 -const IotRuleSceneTriggerTypeEnum = { - DEVICE_STATE_UPDATE: 1, // 设备上下线变更 - DEVICE_PROPERTY_POST: 2, // 物模型属性上报 - DEVICE_EVENT_POST: 3, // 设备事件上报 - DEVICE_SERVICE_INVOKE: 4, // 设备服务调用 - TIMER: 100 // 定时触发 -} as const +// 枚举定义已迁移到 constants.ts,这里不再重复导出 const IotRuleSceneActionTypeEnum = { DEVICE_PROPERTY_SET: 1, // 设备属性设置, @@ -25,11 +17,7 @@ const IotDeviceMessageTypeEnum = { EVENT: 'event' // 事件 } as const -// TODO @puhui999:这个貌似可以不要? -const IotDeviceMessageIdentifierEnum = { - PROPERTY_SET: 'set', // 属性设置 - SERVICE_INVOKE: '${identifier}' // 服务调用 -} as const +// 已删除不需要的 IotDeviceMessageIdentifierEnum const IotRuleSceneTriggerConditionParameterOperatorEnum = { EQUALS: { name: '等于', value: '=' }, // 等于 @@ -64,29 +52,10 @@ const IotRuleSceneTriggerTimeOperatorEnum = { TODAY: { name: '在今日之间', value: 'today' } // 在今日之间 } as const -// TODO @puhui999:下面 IotAlertConfigReceiveTypeEnum、DeviceStateEnum 没用到,貌似可以删除下? -const IotAlertConfigReceiveTypeEnum = { - SMS: 1, // 短信 - MAIL: 2, // 邮箱 - NOTIFY: 3 // 通知 -} as const +// 已删除未使用的枚举:IotAlertConfigReceiveTypeEnum、DeviceStateEnum +// CommonStatusEnum 已在全局定义,这里不再重复定义 -// 设备状态枚举 -const DeviceStateEnum = { - INACTIVE: 0, // 未激活 - ONLINE: 1, // 在线 - OFFLINE: 2 // 离线 -} as const - -// TODO @puhui999:这个全局已经有啦 -// 通用状态枚举 -const CommonStatusEnum = { - ENABLE: 0, // 开启 - DISABLE: 1 // 关闭 -} as const - -// 基础接口 -// TODO @puhui999:这个貌似可以不要? +// 基础接口(如果项目中有全局的 BaseDO,可以使用全局的) interface TenantBaseDO { createTime?: Date // 创建时间 updateTime?: Date // 更新时间 @@ -144,7 +113,7 @@ interface RuleSceneFormData { name: string description?: string status: number - trigger: TriggerFormData + triggers: TriggerFormData[] // 支持多个触发器 actions: ActionFormData[] } @@ -209,8 +178,7 @@ interface IotRuleScene extends TenantBaseDO { } // 工具类型 - 从枚举中提取类型 -export type TriggerType = - (typeof IotRuleSceneTriggerTypeEnum)[keyof typeof IotRuleSceneTriggerTypeEnum] +// TriggerType 现在从 constants.ts 中的枚举提取 export type ActionType = (typeof IotRuleSceneActionTypeEnum)[keyof typeof IotRuleSceneActionTypeEnum] export type MessageType = (typeof IotDeviceMessageTypeEnum)[keyof typeof IotDeviceMessageTypeEnum] @@ -246,16 +214,11 @@ export { ConditionGroupContainerFormData, SubConditionGroupFormData, ConditionFormData, - IotRuleSceneTriggerTypeEnum, IotRuleSceneActionTypeEnum, IotDeviceMessageTypeEnum, - IotDeviceMessageIdentifierEnum, IotRuleSceneTriggerConditionParameterOperatorEnum, IotRuleSceneTriggerConditionTypeEnum, IotRuleSceneTriggerTimeOperatorEnum, - IotAlertConfigReceiveTypeEnum, - DeviceStateEnum, - CommonStatusEnum, ValidationRule, FormValidationRules } diff --git a/src/views/iot/rule/scene/form/RuleSceneForm.vue b/src/views/iot/rule/scene/form/RuleSceneForm.vue index 6c4a96859..57437196d 100644 --- a/src/views/iot/rule/scene/form/RuleSceneForm.vue +++ b/src/views/iot/rule/scene/form/RuleSceneForm.vue @@ -9,12 +9,12 @@ :close-on-press-escape="false" @close="handleClose" > - + - + @@ -40,15 +40,21 @@ import BasicInfoSection from './sections/BasicInfoSection.vue' import TriggerSection from './sections/TriggerSection.vue' import ActionSection from './sections/ActionSection.vue' import { - CommonStatusEnum, IotRuleScene, IotRuleSceneActionTypeEnum, - IotRuleSceneTriggerTypeEnum, - RuleSceneFormData + RuleSceneFormData, + TriggerFormData } from '@/api/iot/rule/scene/scene.types' +import { IotRuleSceneTriggerTypeEnum } from '@/views/iot/utils/constants' import { ElMessage } from 'element-plus' import { generateUUID } from '@/utils' +// 导入全局的 CommonStatusEnum +const CommonStatusEnum = { + ENABLE: 0, // 开启 + DISABLE: 1 // 关闭 +} as const + /** IoT 场景联动规则表单 - 主表单组件 */ defineOptions({ name: 'RuleSceneForm' }) @@ -76,17 +82,19 @@ const createDefaultFormData = (): RuleSceneFormData => { name: '', description: '', status: CommonStatusEnum.ENABLE, // 默认启用状态 - trigger: { - type: IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST, - productId: undefined, - deviceId: undefined, - identifier: undefined, - operator: undefined, - value: undefined, - cronExpression: undefined, - mainCondition: undefined, - conditionGroup: undefined - }, + triggers: [ + { + type: IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST, + productId: undefined, + deviceId: undefined, + identifier: undefined, + operator: undefined, + value: undefined, + cronExpression: undefined, + mainCondition: undefined, + conditionGroup: undefined + } + ], actions: [] } } @@ -95,13 +103,13 @@ const createDefaultFormData = (): RuleSceneFormData => { * 将表单数据转换为 API 请求格式 */ const convertFormToVO = (formData: RuleSceneFormData): IotRuleScene => { - // 构建触发器条件 - const buildTriggerConditions = () => { + // 构建单个触发器的条件 + const buildTriggerConditions = (trigger: TriggerFormData) => { const conditions: any[] = [] // 处理主条件 - if (formData.trigger.mainCondition) { - const mainCondition = formData.trigger.mainCondition + if (trigger.mainCondition) { + const mainCondition = trigger.mainCondition conditions.push({ type: mainCondition.type === 2 ? 'property' : 'event', identifier: mainCondition.identifier || '', @@ -115,8 +123,8 @@ const convertFormToVO = (formData: RuleSceneFormData): IotRuleScene => { } // 处理条件组 - if (formData.trigger.conditionGroup?.subGroups) { - formData.trigger.conditionGroup.subGroups.forEach((subGroup) => { + if (trigger.conditionGroup?.subGroups) { + trigger.conditionGroup.subGroups.forEach((subGroup) => { subGroup.conditions.forEach((condition) => { conditions.push({ type: condition.type === 2 ? 'property' : 'event', @@ -140,19 +148,13 @@ const convertFormToVO = (formData: RuleSceneFormData): IotRuleScene => { name: formData.name, description: formData.description, status: Number(formData.status), - triggers: [ - { - type: formData.trigger.type, - productKey: formData.trigger.productId - ? `product_${formData.trigger.productId}` - : undefined, - deviceNames: formData.trigger.deviceId - ? [`device_${formData.trigger.deviceId}`] - : undefined, - cronExpression: formData.trigger.cronExpression, - conditions: buildTriggerConditions() - } - ], + triggers: formData.triggers.map((trigger) => ({ + type: trigger.type, + productKey: trigger.productId ? `product_${trigger.productId}` : undefined, + deviceNames: trigger.deviceId ? [`device_${trigger.deviceId}`] : undefined, + cronExpression: trigger.cronExpression, + conditions: buildTriggerConditions(trigger) + })), actions: formData.actions?.map((action) => ({ type: action.type, @@ -180,9 +182,7 @@ const convertFormToVO = (formData: RuleSceneFormData): IotRuleScene => { * 将 API 响应数据转换为表单格式 */ const convertVOToForm = (apiData: IotRuleScene): RuleSceneFormData => { - const firstTrigger = apiData.triggers?.[0] - - // 解析触发器条件 + // 解析单个触发器的条件 const parseConditions = (trigger: any) => { if (!trigger?.conditions?.length) { return { @@ -208,28 +208,23 @@ const convertVOToForm = (apiData: IotRuleScene): RuleSceneFormData => { } } - const conditionData = firstTrigger - ? parseConditions(firstTrigger) - : { - mainCondition: undefined, - conditionGroup: undefined - } - - return { - ...apiData, - status: Number(apiData.status), - trigger: firstTrigger - ? { - type: Number(firstTrigger.type), + // 转换所有触发器 + const triggers = apiData.triggers?.length + ? apiData.triggers.map((trigger) => { + const conditionData = parseConditions(trigger) + return { + type: Number(trigger.type), productId: undefined, // 需要从 productKey 解析 deviceId: undefined, // 需要从 deviceNames 解析 identifier: undefined, operator: undefined, value: undefined, - cronExpression: firstTrigger.cronExpression, + cronExpression: trigger.cronExpression, ...conditionData } - : { + }) + : [ + { type: IotRuleSceneTriggerTypeEnum.DEVICE_PROPERTY_POST, productId: undefined, deviceId: undefined, @@ -239,7 +234,13 @@ const convertVOToForm = (apiData: IotRuleScene): RuleSceneFormData => { cronExpression: undefined, mainCondition: undefined, conditionGroup: undefined - }, + } + ] + + return { + ...apiData, + status: Number(apiData.status), + triggers, actions: apiData.actions?.map((action) => ({ ...action, diff --git a/src/views/iot/rule/scene/form/configs/ConditionGroupConfig.vue b/src/views/iot/rule/scene/form/configs/ConditionGroupConfig.vue index dff6fe598..6aad617fa 100644 --- a/src/views/iot/rule/scene/form/configs/ConditionGroupConfig.vue +++ b/src/views/iot/rule/scene/form/configs/ConditionGroupConfig.vue @@ -114,11 +114,8 @@ diff --git a/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue b/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue index c054ae737..23c492a91 100644 --- a/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue +++ b/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue @@ -1,11 +1,5 @@