diff --git a/src/views/iot/rule/scene/form/RuleSceneForm.vue b/src/views/iot/rule/scene/form/RuleSceneForm.vue index 8fc3e26d..2adc9f50 100644 --- a/src/views/iot/rule/scene/form/RuleSceneForm.vue +++ b/src/views/iot/rule/scene/form/RuleSceneForm.vue @@ -26,13 +26,6 @@ - - - @@ -48,11 +41,16 @@ import { useVModel } from '@vueuse/core' import BasicInfoSection from './sections/BasicInfoSection.vue' import TriggerSection from './sections/TriggerSection.vue' import ActionSection from './sections/ActionSection.vue' -import PreviewSection from './sections/PreviewSection.vue' -import { RuleSceneFormData, IotRuleScene } from '@/api/iot/rule/scene/scene.types' +import { + RuleSceneFormData, + IotRuleScene, + IotRuleSceneTriggerTypeEnum, + IotRuleSceneActionTypeEnum, + CommonStatusEnum +} from '@/api/iot/rule/scene/scene.types' import { getBaseValidationRules } from '../utils/validation' -import { transformFormToApi, transformApiToForm, createDefaultFormData } from '../utils/transform' import { ElMessage } from 'element-plus' +import { generateUUID } from '@/utils' /** IoT 场景联动规则表单 - 主表单组件 */ defineOptions({ name: 'RuleSceneForm' }) @@ -72,12 +70,93 @@ const emit = defineEmits() const drawerVisible = useVModel(props, 'modelValue', emit) +/** + * 创建默认的表单数据 + */ +const createDefaultFormData = (): RuleSceneFormData => { + return { + name: '', + description: '', + status: CommonStatusEnum.ENABLE, // 默认启用状态 + triggers: [], + actions: [] + } +} + +/** + * 将表单数据转换为API请求格式 + */ +const transformFormToApi = (formData: RuleSceneFormData): IotRuleScene => { + return { + id: formData.id, + name: formData.name, + description: formData.description, + status: Number(formData.status), + 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: + trigger.conditionGroups?.map((group) => ({ + type: 'property', + identifier: trigger.identifier || '', + parameters: group.conditions.map((condition) => ({ + identifier: condition.identifier, + operator: condition.operator, + value: condition.param + })) + })) || [] + })) || [], + actions: + formData.actions?.map((action) => ({ + type: action.type, + alertConfigId: action.alertConfigId, + deviceControl: + action.type === IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET || + action.type === IotRuleSceneActionTypeEnum.DEVICE_SERVICE_INVOKE + ? { + productKey: action.productId ? `product_${action.productId}` : '', + deviceNames: action.deviceId ? [`device_${action.deviceId}`] : [], + type: 'property', + identifier: 'set', + params: action.params || {} + } + : undefined + })) || [] + } as IotRuleScene +} + +/** + * 将 API 响应数据转换为表单格式 + */ +const transformApiToForm = (apiData: IotRuleScene): RuleSceneFormData => { + return { + ...apiData, + status: Number(apiData.status), // 确保状态为数字类型 + triggers: + apiData.triggers?.map((trigger) => ({ + ...trigger, + type: Number(trigger.type), + // 为每个触发器添加唯一标识符,解决组件索引重用问题 + key: generateUUID() + })) || [], + actions: + apiData.actions?.map((action) => ({ + ...action, + type: Number(action.type), + // 为每个执行器添加唯一标识符,解决组件索引重用问题 + key: generateUUID() + })) || [] + } +} + // 表单数据和状态 const formRef = ref() const formData = ref(createDefaultFormData()) const formRules = getBaseValidationRules() const submitLoading = ref(false) -const validationResult = ref<{ valid: boolean; message?: string } | null>(null) // 验证状态 const triggerValidation = ref({ valid: true, message: '' }) @@ -87,16 +166,6 @@ const actionValidation = ref({ valid: true, message: '' }) const isEdit = computed(() => !!props.ruleScene?.id) const drawerTitle = computed(() => (isEdit.value ? '编辑场景联动规则' : '新增场景联动规则')) -const canSubmit = computed(() => { - return ( - formData.value.name && - formData.value.triggers.length > 0 && - formData.value.actions.length > 0 && - triggerValidation.value.valid && - actionValidation.value.valid - ) -}) - // 事件处理 const handleTriggerValidate = (result: { valid: boolean; message: string }) => { triggerValidation.value = result @@ -106,29 +175,6 @@ const handleActionValidate = (result: { valid: boolean; message: string }) => { actionValidation.value = result } -const handleValidate = async () => { - try { - await formRef.value?.validate() - - if (!triggerValidation.value.valid) { - throw new Error(triggerValidation.value.message) - } - - if (!actionValidation.value.valid) { - throw new Error(actionValidation.value.message) - } - - validationResult.value = { valid: true, message: '验证通过' } - ElMessage.success('规则验证通过') - return true - } catch (error: any) { - const message = error.message || '表单验证失败' - validationResult.value = { valid: false, message } - ElMessage.error(message) - return false - } -} - const handleSubmit = async () => { // 校验表单 if (!formRef.value) return @@ -167,7 +213,6 @@ const handleSubmit = async () => { const handleClose = () => { drawerVisible.value = false - validationResult.value = null } // 初始化表单数据 diff --git a/src/views/iot/rule/scene/form/previews/ActionPreview.vue b/src/views/iot/rule/scene/form/previews/ActionPreview.vue deleted file mode 100644 index a977173b..00000000 --- a/src/views/iot/rule/scene/form/previews/ActionPreview.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - - - 暂无执行器配置 - - - - - - 执行器 {{ index + 1 }} - - {{ getActionTypeName(action.type) }} - - - - - {{ getActionSummary(action) }} - - - - - - - - - - diff --git a/src/views/iot/rule/scene/form/previews/ConfigPreview.vue b/src/views/iot/rule/scene/form/previews/ConfigPreview.vue deleted file mode 100644 index 3f7a690f..00000000 --- a/src/views/iot/rule/scene/form/previews/ConfigPreview.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - 场景名称: - {{ formData.name || '未设置' }} - - - 场景状态: - - {{ formData.status === 0 ? '启用' : '禁用' }} - - - - 场景描述: - {{ formData.description }} - - - - - - - - diff --git a/src/views/iot/rule/scene/form/previews/NextExecutionPreview.vue b/src/views/iot/rule/scene/form/previews/NextExecutionPreview.vue deleted file mode 100644 index 2e79929b..00000000 --- a/src/views/iot/rule/scene/form/previews/NextExecutionPreview.vue +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - 执行时间预览 - - - - - CRON表达式: - {{ cronExpression }} - - - - 执行规律: - {{ cronDescription }} - - - - 接下来5次执行时间: - - - - {{ time }} - - - - - - - - - - - - - - diff --git a/src/views/iot/rule/scene/form/previews/TriggerPreview.vue b/src/views/iot/rule/scene/form/previews/TriggerPreview.vue deleted file mode 100644 index 2e255166..00000000 --- a/src/views/iot/rule/scene/form/previews/TriggerPreview.vue +++ /dev/null @@ -1,80 +0,0 @@ - - - - - 暂无触发器配置 - - - - - - 触发器 {{ index + 1 }} - - {{ getTriggerTypeName(trigger.type) }} - - - - - {{ getTriggerSummary(trigger) }} - - - - - - - - - - diff --git a/src/views/iot/rule/scene/form/previews/ValidationResult.vue b/src/views/iot/rule/scene/form/previews/ValidationResult.vue deleted file mode 100644 index f83739f9..00000000 --- a/src/views/iot/rule/scene/form/previews/ValidationResult.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - 点击"验证配置"按钮检查规则配置 - - - - - - - {{ validationResult.message || '所有配置项验证通过,规则可以正常运行' }} - - - 规则配置完整且有效 - - - - {{ validationResult.message || '配置验证失败,请检查以下问题' }} - - - - 请确保所有必填项都已配置 - - - - 请检查触发器和执行器配置是否正确 - - - - - - - - - - - - diff --git a/src/views/iot/rule/scene/form/sections/ActionSection.vue b/src/views/iot/rule/scene/form/sections/ActionSection.vue index 7d3fe8d6..c2707816 100644 --- a/src/views/iot/rule/scene/form/sections/ActionSection.vue +++ b/src/views/iot/rule/scene/form/sections/ActionSection.vue @@ -117,7 +117,6 @@ import { ActionFormData, IotRuleSceneActionTypeEnum as ActionTypeEnum } from '@/api/iot/rule/scene/scene.types' -import { createDefaultActionData } from '../../utils/transform' /** 执行器配置组件 */ defineOptions({ name: 'ActionSection' }) @@ -136,6 +135,19 @@ const emit = defineEmits() const actions = useVModel(props, 'actions', emit) +/** + * 创建默认的执行器数据 + */ +const createDefaultActionData = (): ActionFormData => { + return { + type: ActionTypeEnum.DEVICE_PROPERTY_SET, // 默认为设备属性设置 + productId: undefined, + deviceId: undefined, + params: {}, + alertConfigId: undefined + } +} + // 配置常量 const maxActions = 5 diff --git a/src/views/iot/rule/scene/form/sections/PreviewSection.vue b/src/views/iot/rule/scene/form/sections/PreviewSection.vue deleted file mode 100644 index d57fa046..00000000 --- a/src/views/iot/rule/scene/form/sections/PreviewSection.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - 配置预览 - - - - - 验证配置 - - - - - - - - - - - 基础信息 - - - - - - - - - - - 触发器配置 - {{ formData.triggers.length }} - - - - - - - - - - - 执行器配置 - {{ formData.actions.length }} - - - - - - - - - - - 验证结果 - - - - - - - - - - - - diff --git a/src/views/iot/rule/scene/form/sections/TriggerSection.vue b/src/views/iot/rule/scene/form/sections/TriggerSection.vue index e16d702e..3f05ff6e 100644 --- a/src/views/iot/rule/scene/form/sections/TriggerSection.vue +++ b/src/views/iot/rule/scene/form/sections/TriggerSection.vue @@ -119,7 +119,6 @@ import { TriggerFormData, IotRuleSceneTriggerTypeEnum as TriggerTypeEnum } from '@/api/iot/rule/scene/scene.types' -import { createDefaultTriggerData } from '../../utils/transform' /** 触发器配置组件 */ defineOptions({ name: 'TriggerSection' }) @@ -138,6 +137,22 @@ const emit = defineEmits() const triggers = useVModel(props, 'triggers', emit) +/** + * 创建默认的触发器数据 + */ +const createDefaultTriggerData = (): TriggerFormData => { + return { + type: TriggerTypeEnum.DEVICE_PROPERTY_POST, // 默认为设备属性上报 + productId: undefined, + deviceId: undefined, + identifier: undefined, + operator: undefined, + value: undefined, + cronExpression: undefined, + conditionGroups: [] + } +} + // 配置常量 const maxTriggers = 5 diff --git a/src/views/iot/rule/scene/index.vue b/src/views/iot/rule/scene/index.vue index 3f6e175a..551e64f3 100644 --- a/src/views/iot/rule/scene/index.vue +++ b/src/views/iot/rule/scene/index.vue @@ -35,7 +35,6 @@ class="!w-240px" /> - - - + @@ -61,7 +64,6 @@ - @@ -125,14 +127,7 @@ {{ row.name }} - - - {{ row.status === 0 ? '启用' : '禁用' }} - + {{ row.description }} @@ -169,7 +164,6 @@ - @@ -185,7 +179,6 @@ - @@ -197,10 +190,9 @@ @click="handleToggleStatus(row)" > - {{ row.status === 0 ? '禁用' : '启用' }} - + 删除 @@ -247,17 +239,17 @@
{{ cronExpression }}
{{ validationResult.message || '所有配置项验证通过,规则可以正常运行' }}
{{ validationResult.message || '配置验证失败,请检查以下问题' }}