perf:【IoT 物联网】场景联动优化数据结构对齐后端
parent
858f1cdb0b
commit
d06835ae7f
|
|
@ -39,14 +39,7 @@ import { useVModel } from '@vueuse/core'
|
||||||
import BasicInfoSection from './sections/BasicInfoSection.vue'
|
import BasicInfoSection from './sections/BasicInfoSection.vue'
|
||||||
import TriggerSection from './sections/TriggerSection.vue'
|
import TriggerSection from './sections/TriggerSection.vue'
|
||||||
import ActionSection from './sections/ActionSection.vue'
|
import ActionSection from './sections/ActionSection.vue'
|
||||||
import {
|
import { IotRuleSceneDO, RuleSceneFormData } from '@/api/iot/rule/scene/scene.types'
|
||||||
IotRuleScene,
|
|
||||||
IotRuleSceneDO,
|
|
||||||
IotRuleSceneActionTypeEnum,
|
|
||||||
RuleSceneFormData,
|
|
||||||
TriggerFormData,
|
|
||||||
TriggerConditionFormData
|
|
||||||
} from '@/api/iot/rule/scene/scene.types'
|
|
||||||
import { IotRuleSceneTriggerTypeEnum } from '@/views/iot/utils/constants'
|
import { IotRuleSceneTriggerTypeEnum } from '@/views/iot/utils/constants'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { generateUUID } from '@/utils'
|
import { generateUUID } from '@/utils'
|
||||||
|
|
@ -64,16 +57,12 @@ defineOptions({ name: 'RuleSceneForm' })
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
/** 抽屉显示状态 */
|
/** 抽屉显示状态 */
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
/** 编辑的规则数据(新增时为空) */
|
|
||||||
ruleScene?: IotRuleScene
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
/** 组件事件定义 */
|
/** 组件事件定义 */
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
/** 更新抽屉显示状态 */
|
(e: 'update:modelValue', value: boolean): void
|
||||||
'update:modelValue': [value: boolean]
|
(e: 'success'): void
|
||||||
/** 操作成功事件 */
|
|
||||||
success: []
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const drawerVisible = useVModel(props, 'modelValue', emit) // 是否可见
|
const drawerVisible = useVModel(props, 'modelValue', emit) // 是否可见
|
||||||
|
|
@ -120,13 +109,14 @@ const convertFormToVO = (formData: RuleSceneFormData): IotRuleSceneDO => {
|
||||||
cronExpression: trigger.cronExpression,
|
cronExpression: trigger.cronExpression,
|
||||||
conditionGroups: trigger.conditionGroups || []
|
conditionGroups: trigger.conditionGroups || []
|
||||||
})),
|
})),
|
||||||
actions: formData.actions?.map((action) => ({
|
actions:
|
||||||
type: action.type,
|
formData.actions?.map((action) => ({
|
||||||
productId: action.productId,
|
type: action.type,
|
||||||
deviceId: action.deviceId,
|
productId: action.productId,
|
||||||
params: action.params,
|
deviceId: action.deviceId,
|
||||||
alertConfigId: action.alertConfigId
|
params: action.params,
|
||||||
})) || []
|
alertConfigId: action.alertConfigId
|
||||||
|
})) || []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,7 +206,7 @@ const triggerValidation = ref({ valid: true, message: '' })
|
||||||
const actionValidation = ref({ valid: true, message: '' })
|
const actionValidation = ref({ valid: true, message: '' })
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const isEdit = computed(() => !!props.ruleScene?.id)
|
const isEdit = ref(false)
|
||||||
const drawerTitle = computed(() => (isEdit.value ? '编辑场景联动规则' : '新增场景联动规则'))
|
const drawerTitle = computed(() => (isEdit.value ? '编辑场景联动规则' : '新增场景联动规则'))
|
||||||
|
|
||||||
// 事件处理
|
// 事件处理
|
||||||
|
|
@ -284,30 +274,28 @@ const handleClose = () => {
|
||||||
|
|
||||||
/** 初始化表单数据 */
|
/** 初始化表单数据 */
|
||||||
const initFormData = () => {
|
const initFormData = () => {
|
||||||
if (props.ruleScene) {
|
// TODO @puhui999: 编辑的情况后面实现
|
||||||
formData.value = convertVOToForm(props.ruleScene)
|
formData.value = createDefaultFormData()
|
||||||
} else {
|
|
||||||
formData.value = createDefaultFormData()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听抽屉显示
|
// 监听抽屉显示
|
||||||
watch(drawerVisible, (visible) => {
|
watch(drawerVisible, (visible) => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
initFormData()
|
initFormData()
|
||||||
nextTick(() => {
|
// TODO @puhui999: 重置表单的情况
|
||||||
formRef.value?.clearValidate()
|
// nextTick(() => {
|
||||||
})
|
// formRef.value?.clearValidate()
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听 props 变化
|
// 监听 props 变化
|
||||||
watch(
|
// watch(
|
||||||
() => props.ruleScene,
|
// () => props.ruleScene,
|
||||||
() => {
|
// () => {
|
||||||
if (drawerVisible.value) {
|
// if (drawerVisible.value) {
|
||||||
initFormData()
|
// initFormData()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ import PropertySelector from '../selectors/PropertySelector.vue'
|
||||||
import OperatorSelector from '../selectors/OperatorSelector.vue'
|
import OperatorSelector from '../selectors/OperatorSelector.vue'
|
||||||
import ValueInput from '../inputs/ValueInput.vue'
|
import ValueInput from '../inputs/ValueInput.vue'
|
||||||
import {
|
import {
|
||||||
ConditionFormData,
|
TriggerConditionFormData,
|
||||||
IotRuleSceneTriggerConditionTypeEnum
|
IotRuleSceneTriggerConditionTypeEnum
|
||||||
} from '@/api/iot/rule/scene/scene.types'
|
} from '@/api/iot/rule/scene/scene.types'
|
||||||
|
|
||||||
|
|
@ -130,12 +130,12 @@ import {
|
||||||
defineOptions({ name: 'ConditionConfig' })
|
defineOptions({ name: 'ConditionConfig' })
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: ConditionFormData
|
modelValue: TriggerConditionFormData
|
||||||
triggerType: number
|
triggerType: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: ConditionFormData): void
|
(e: 'update:modelValue', value: TriggerConditionFormData): void
|
||||||
(e: 'validate', result: { valid: boolean; message: string }): void
|
(e: 'validate', result: { valid: boolean; message: string }): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
|
@ -152,12 +152,12 @@ const isValid = ref(true)
|
||||||
const valueValidation = ref({ valid: true, message: '' })
|
const valueValidation = ref({ valid: true, message: '' })
|
||||||
|
|
||||||
// 事件处理
|
// 事件处理
|
||||||
const updateConditionField = (field: keyof ConditionFormData, value: any) => {
|
const updateConditionField = (field: keyof TriggerConditionFormData, value: any) => {
|
||||||
;(condition.value as any)[field] = value
|
;(condition.value as any)[field] = value
|
||||||
emit('update:modelValue', condition.value)
|
emit('update:modelValue', condition.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateCondition = (newCondition: ConditionFormData) => {
|
const updateCondition = (newCondition: TriggerConditionFormData) => {
|
||||||
condition.value = newCondition
|
condition.value = newCondition
|
||||||
emit('update:modelValue', condition.value)
|
emit('update:modelValue', condition.value)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,14 @@
|
||||||
<span>附加条件组</span>
|
<span>附加条件组</span>
|
||||||
</div>
|
</div>
|
||||||
<el-tag size="small" type="success">与主条件为且关系</el-tag>
|
<el-tag size="small" type="success">与主条件为且关系</el-tag>
|
||||||
<el-tag size="small" type="info">
|
<el-tag size="small" type="info"> {{ modelValue?.length || 0 }}个子条件组 </el-tag>
|
||||||
{{ modelValue.subGroups?.length || 0 }}个子条件组
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-8px">
|
<div class="flex items-center gap-8px">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
@click="addSubGroup"
|
@click="addSubGroup"
|
||||||
:disabled="(modelValue.subGroups?.length || 0) >= maxSubGroups"
|
:disabled="(modelValue?.length || 0) >= maxSubGroups"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:plus" />
|
<Icon icon="ep:plus" />
|
||||||
添加子条件组
|
添加子条件组
|
||||||
|
|
@ -36,11 +34,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 子条件组列表 -->
|
<!-- 子条件组列表 -->
|
||||||
<div v-if="modelValue.subGroups && modelValue.subGroups.length > 0" class="space-y-16px">
|
<div v-if="modelValue && modelValue.length > 0" class="space-y-16px">
|
||||||
<!-- 逻辑关系说明 -->
|
<!-- 逻辑关系说明 -->
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
v-for="(subGroup, subGroupIndex) in modelValue.subGroups"
|
v-for="(subGroup, subGroupIndex) in modelValue"
|
||||||
:key="`sub-group-${subGroupIndex}`"
|
:key="`sub-group-${subGroupIndex}`"
|
||||||
class="relative"
|
class="relative"
|
||||||
>
|
>
|
||||||
|
|
@ -88,7 +86,7 @@
|
||||||
|
|
||||||
<!-- 子条件组间的"或"连接符 -->
|
<!-- 子条件组间的"或"连接符 -->
|
||||||
<div
|
<div
|
||||||
v-if="subGroupIndex < modelValue.subGroups!.length - 1"
|
v-if="subGroupIndex < modelValue!.length - 1"
|
||||||
class="flex items-center justify-center py-12px"
|
class="flex items-center justify-center py-12px"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-8px">
|
<div class="flex items-center gap-8px">
|
||||||
|
|
@ -125,21 +123,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useVModel } from '@vueuse/core'
|
import { useVModel } from '@vueuse/core'
|
||||||
import SubConditionGroupConfig from './SubConditionGroupConfig.vue'
|
import SubConditionGroupConfig from './SubConditionGroupConfig.vue'
|
||||||
import {
|
|
||||||
ConditionGroupContainerFormData,
|
|
||||||
SubConditionGroupFormData
|
|
||||||
} from '@/api/iot/rule/scene/scene.types'
|
|
||||||
|
|
||||||
/** 条件组容器配置组件 */
|
/** 条件组容器配置组件 */
|
||||||
defineOptions({ name: 'ConditionGroupContainerConfig' })
|
defineOptions({ name: 'ConditionGroupContainerConfig' })
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: ConditionGroupContainerFormData
|
modelValue: any
|
||||||
triggerType: number
|
triggerType: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: ConditionGroupContainerFormData): void
|
(e: 'update:modelValue', value: any): void
|
||||||
(e: 'validate', result: { valid: boolean; message: string }): void
|
(e: 'validate', result: { valid: boolean; message: string }): void
|
||||||
(e: 'remove'): void
|
(e: 'remove'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -155,24 +149,20 @@ const subGroupValidations = ref<{ [key: number]: { valid: boolean; message: stri
|
||||||
|
|
||||||
// 事件处理
|
// 事件处理
|
||||||
const addSubGroup = () => {
|
const addSubGroup = () => {
|
||||||
if (!container.value.subGroups) {
|
if (!container.value) {
|
||||||
container.value.subGroups = []
|
container.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container.value.subGroups.length >= maxSubGroups) {
|
if (container.value.length >= maxSubGroups) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const newSubGroup: SubConditionGroupFormData = {
|
container.value.push([])
|
||||||
conditions: []
|
|
||||||
}
|
|
||||||
|
|
||||||
container.value.subGroups.push(newSubGroup)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeSubGroup = (index: number) => {
|
const removeSubGroup = (index: number) => {
|
||||||
if (container.value.subGroups) {
|
if (container.value) {
|
||||||
container.value.subGroups.splice(index, 1)
|
container.value.splice(index, 1)
|
||||||
delete subGroupValidations.value[index]
|
delete subGroupValidations.value[index]
|
||||||
|
|
||||||
// 重新索引验证结果
|
// 重新索引验证结果
|
||||||
|
|
@ -191,9 +181,9 @@ const removeSubGroup = (index: number) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateSubGroup = (index: number, subGroup: SubConditionGroupFormData) => {
|
const updateSubGroup = (index: number, subGroup: any) => {
|
||||||
if (container.value.subGroups) {
|
if (container.value) {
|
||||||
container.value.subGroups[index] = subGroup
|
container.value[index] = subGroup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,7 +197,7 @@ const handleSubGroupValidate = (index: number, result: { valid: boolean; message
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateValidationResult = () => {
|
const updateValidationResult = () => {
|
||||||
if (!container.value.subGroups || container.value.subGroups.length === 0) {
|
if (!container.value || container.value.length === 0) {
|
||||||
emit('validate', { valid: true, message: '条件组容器为空,验证通过' })
|
emit('validate', { valid: true, message: '条件组容器为空,验证通过' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +215,7 @@ const updateValidationResult = () => {
|
||||||
|
|
||||||
// 监听变化
|
// 监听变化
|
||||||
watch(
|
watch(
|
||||||
() => container.value.subGroups,
|
() => container.value,
|
||||||
() => {
|
() => {
|
||||||
updateValidationResult()
|
updateValidationResult()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -84,17 +84,17 @@
|
||||||
import { useVModel } from '@vueuse/core'
|
import { useVModel } from '@vueuse/core'
|
||||||
import ProductSelector from '../selectors/ProductSelector.vue'
|
import ProductSelector from '../selectors/ProductSelector.vue'
|
||||||
import DeviceSelector from '../selectors/DeviceSelector.vue'
|
import DeviceSelector from '../selectors/DeviceSelector.vue'
|
||||||
import { ConditionFormData } from '@/api/iot/rule/scene/scene.types'
|
import { TriggerConditionFormData } from '@/api/iot/rule/scene/scene.types'
|
||||||
|
|
||||||
/** 设备状态条件配置组件 */
|
/** 设备状态条件配置组件 */
|
||||||
defineOptions({ name: 'DeviceStatusConditionConfig' })
|
defineOptions({ name: 'DeviceStatusConditionConfig' })
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: ConditionFormData
|
modelValue: TriggerConditionFormData
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: ConditionFormData): void
|
(e: 'update:modelValue', value: TriggerConditionFormData): void
|
||||||
(e: 'validate', result: { valid: boolean; message: string }): void
|
(e: 'validate', result: { valid: boolean; message: string }): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
|
@ -139,18 +139,18 @@ const validationMessage = ref('')
|
||||||
const isValid = ref(true)
|
const isValid = ref(true)
|
||||||
|
|
||||||
// 事件处理
|
// 事件处理
|
||||||
const updateConditionField = (field: keyof ConditionFormData, value: any) => {
|
const updateConditionField = (field: any, value: any) => {
|
||||||
condition.value[field] = value
|
condition.value[field] = value
|
||||||
updateValidationResult()
|
updateValidationResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleProductChange = (productId: number) => {
|
const handleProductChange = (_: number) => {
|
||||||
// 产品变化时清空设备
|
// 产品变化时清空设备
|
||||||
condition.value.deviceId = undefined
|
condition.value.deviceId = undefined
|
||||||
updateValidationResult()
|
updateValidationResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDeviceChange = (deviceId: number) => {
|
const handleDeviceChange = (_: number) => {
|
||||||
// 设备变化时可以进行其他处理
|
// 设备变化时可以进行其他处理
|
||||||
updateValidationResult()
|
updateValidationResult()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,48 +11,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 条件组配置 -->
|
<!-- 条件组配置 -->
|
||||||
<div v-if="trigger.mainCondition" class="space-y-16px">
|
<div class="space-y-16px">
|
||||||
<div v-if="!trigger.conditionGroup" class="flex items-center justify-between">
|
|
||||||
<div class="flex items-center gap-8px">
|
|
||||||
<span class="text-14px font-500 text-[var(--el-text-color-primary)]">附加条件组</span>
|
|
||||||
<el-tag size="small" type="success">与主条件为且关系</el-tag>
|
|
||||||
<el-tag size="small" type="info">
|
|
||||||
{{ trigger.conditionGroup?.subGroups?.length || 0 }} 个子条件组
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
@click="addConditionGroup"
|
|
||||||
v-if="!trigger.conditionGroup"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:plus" />
|
|
||||||
添加条件组
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 条件组配置 -->
|
<!-- 条件组配置 -->
|
||||||
<ConditionGroupContainerConfig
|
<ConditionGroupContainerConfig
|
||||||
v-if="trigger.conditionGroup"
|
v-model="trigger.conditionGroups"
|
||||||
v-model="trigger.conditionGroup"
|
|
||||||
:trigger-type="trigger.type"
|
:trigger-type="trigger.type"
|
||||||
@validate="handleConditionGroupValidate"
|
@validate="handleConditionGroupValidate"
|
||||||
@remove="removeConditionGroup"
|
@remove="removeConditionGroup"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 空状态 -->
|
|
||||||
<div v-else class="py-40px text-center">
|
|
||||||
<el-empty description="暂无触发条件">
|
|
||||||
<template #description>
|
|
||||||
<div class="space-y-8px">
|
|
||||||
<p class="text-[var(--el-text-color-secondary)]">暂无触发条件</p>
|
|
||||||
<p class="text-12px text-[var(--el-text-color-placeholder)]">
|
|
||||||
请使用上方的"添加条件组"按钮来设置触发规则
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-empty>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -70,6 +36,7 @@ defineOptions({ name: 'DeviceTriggerConfig' })
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: TriggerFormData
|
modelValue: TriggerFormData
|
||||||
|
index: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|
@ -89,16 +56,17 @@ const isValid = ref(true)
|
||||||
|
|
||||||
// 初始化主条件
|
// 初始化主条件
|
||||||
const initMainCondition = () => {
|
const initMainCondition = () => {
|
||||||
if (!trigger.value.mainCondition) {
|
// TODO @puhui999: 等到编辑回显时联调
|
||||||
trigger.value.mainCondition = {
|
// if (!trigger.value.mainCondition) {
|
||||||
type: trigger.value.type, // 使用触发事件类型作为条件类型
|
// trigger.value = {
|
||||||
productId: undefined,
|
// type: trigger.value.type, // 使用触发事件类型作为条件类型
|
||||||
deviceId: undefined,
|
// productId: undefined,
|
||||||
identifier: '',
|
// deviceId: undefined,
|
||||||
operator: '=',
|
// identifier: '',
|
||||||
param: ''
|
// operator: '=',
|
||||||
}
|
// param: ''
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听触发器类型变化,自动初始化主条件
|
// 监听触发器类型变化,自动初始化主条件
|
||||||
|
|
@ -110,18 +78,16 @@ watch(
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 新的事件处理函数
|
|
||||||
const handleMainConditionValidate = (result: { valid: boolean; message: string }) => {
|
const handleMainConditionValidate = (result: { valid: boolean; message: string }) => {
|
||||||
mainConditionValidation.value = result
|
mainConditionValidation.value = result
|
||||||
updateValidationResult()
|
updateValidationResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
const addConditionGroup = () => {
|
const addConditionGroup = () => {
|
||||||
if (!trigger.value.conditionGroup) {
|
if (!trigger.value.conditionGroups) {
|
||||||
trigger.value.conditionGroup = {
|
trigger.value.conditionGroups = []
|
||||||
subGroups: []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
trigger.value.conditionGroups.push([])
|
||||||
}
|
}
|
||||||
|
|
||||||
// 事件处理
|
// 事件处理
|
||||||
|
|
@ -130,7 +96,7 @@ const handleConditionGroupValidate = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeConditionGroup = () => {
|
const removeConditionGroup = () => {
|
||||||
trigger.value.conditionGroup = undefined
|
trigger.value.conditionGroups = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateValidationResult = () => {
|
const updateValidationResult = () => {
|
||||||
|
|
@ -151,7 +117,7 @@ const updateValidationResult = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 主条件验证
|
// 主条件验证
|
||||||
if (!trigger.value.mainCondition) {
|
if (!trigger.value.value) {
|
||||||
isValid.value = false
|
isValid.value = false
|
||||||
validationMessage.value = '请配置主条件'
|
validationMessage.value = '请配置主条件'
|
||||||
emit('validate', { valid: false, message: validationMessage.value })
|
emit('validate', { valid: false, message: validationMessage.value })
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="p-16px">
|
<div class="p-16px">
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
<div
|
<div v-if="!subGroup || subGroup.length === 0" class="text-center py-24px">
|
||||||
v-if="!subGroup.conditions || subGroup.conditions.length === 0"
|
|
||||||
class="text-center py-24px"
|
|
||||||
>
|
|
||||||
<div class="flex flex-col items-center gap-12px">
|
<div class="flex flex-col items-center gap-12px">
|
||||||
<Icon icon="ep:plus" class="text-32px text-[var(--el-text-color-placeholder)]" />
|
<Icon icon="ep:plus" class="text-32px text-[var(--el-text-color-placeholder)]" />
|
||||||
<div class="text-[var(--el-text-color-secondary)]">
|
<div class="text-[var(--el-text-color-secondary)]">
|
||||||
|
|
@ -21,7 +18,7 @@
|
||||||
<!-- 条件列表 -->
|
<!-- 条件列表 -->
|
||||||
<div v-else class="space-y-16px">
|
<div v-else class="space-y-16px">
|
||||||
<div
|
<div
|
||||||
v-for="(condition, conditionIndex) in subGroup.conditions"
|
v-for="(condition, conditionIndex) in subGroup"
|
||||||
:key="`condition-${conditionIndex}`"
|
:key="`condition-${conditionIndex}`"
|
||||||
class="relative"
|
class="relative"
|
||||||
>
|
>
|
||||||
|
|
@ -47,7 +44,7 @@
|
||||||
size="small"
|
size="small"
|
||||||
text
|
text
|
||||||
@click="removeCondition(conditionIndex)"
|
@click="removeCondition(conditionIndex)"
|
||||||
v-if="subGroup.conditions!.length > 1"
|
v-if="subGroup!.length > 1"
|
||||||
class="hover:bg-red-50"
|
class="hover:bg-red-50"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:delete" />
|
<Icon icon="ep:delete" />
|
||||||
|
|
@ -67,11 +64,7 @@
|
||||||
|
|
||||||
<!-- 添加条件按钮 -->
|
<!-- 添加条件按钮 -->
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="subGroup && subGroup.length > 0 && subGroup.length < maxConditions"
|
||||||
subGroup.conditions &&
|
|
||||||
subGroup.conditions.length > 0 &&
|
|
||||||
subGroup.conditions.length < maxConditions
|
|
||||||
"
|
|
||||||
class="text-center py-16px"
|
class="text-center py-16px"
|
||||||
>
|
>
|
||||||
<el-button type="primary" plain @click="addCondition">
|
<el-button type="primary" plain @click="addCondition">
|
||||||
|
|
@ -90,22 +83,21 @@
|
||||||
import { useVModel } from '@vueuse/core'
|
import { useVModel } from '@vueuse/core'
|
||||||
import ConditionConfig from './ConditionConfig.vue'
|
import ConditionConfig from './ConditionConfig.vue'
|
||||||
import {
|
import {
|
||||||
ConditionFormData,
|
|
||||||
IotRuleSceneTriggerConditionTypeEnum,
|
IotRuleSceneTriggerConditionTypeEnum,
|
||||||
SubConditionGroupFormData
|
TriggerConditionFormData
|
||||||
} from '@/api/iot/rule/scene/scene.types'
|
} from '@/api/iot/rule/scene/scene.types'
|
||||||
|
|
||||||
/** 子条件组配置组件 */
|
/** 子条件组配置组件 */
|
||||||
defineOptions({ name: 'SubConditionGroupConfig' })
|
defineOptions({ name: 'SubConditionGroupConfig' })
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: SubConditionGroupFormData
|
modelValue: TriggerConditionFormData[]
|
||||||
triggerType: number
|
triggerType: number
|
||||||
maxConditions?: number
|
maxConditions?: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: SubConditionGroupFormData): void
|
(e: 'update:modelValue', value: TriggerConditionFormData[]): void
|
||||||
(e: 'validate', result: { valid: boolean; message: string }): void
|
(e: 'validate', result: { valid: boolean; message: string }): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
|
@ -119,15 +111,13 @@ const conditionValidations = ref<{ [key: number]: { valid: boolean; message: str
|
||||||
|
|
||||||
// 事件处理
|
// 事件处理
|
||||||
const addCondition = () => {
|
const addCondition = () => {
|
||||||
if (!subGroup.value.conditions) {
|
if (!subGroup.value) {
|
||||||
subGroup.value.conditions = []
|
subGroup.value = []
|
||||||
}
|
}
|
||||||
|
if (subGroup.value.length >= maxConditions.value) {
|
||||||
if (subGroup.value.conditions.length >= maxConditions.value) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const newCondition: TriggerConditionFormData = {
|
||||||
const newCondition: ConditionFormData = {
|
|
||||||
type: IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY, // 默认为设备属性
|
type: IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY, // 默认为设备属性
|
||||||
productId: undefined,
|
productId: undefined,
|
||||||
deviceId: undefined,
|
deviceId: undefined,
|
||||||
|
|
@ -135,13 +125,12 @@ const addCondition = () => {
|
||||||
operator: '=',
|
operator: '=',
|
||||||
param: ''
|
param: ''
|
||||||
}
|
}
|
||||||
|
subGroup.value.push(newCondition)
|
||||||
subGroup.value.conditions.push(newCondition)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeCondition = (index: number) => {
|
const removeCondition = (index: number) => {
|
||||||
if (subGroup.value.conditions) {
|
if (subGroup.value) {
|
||||||
subGroup.value.conditions.splice(index, 1)
|
subGroup.value.splice(index, 1)
|
||||||
delete conditionValidations.value[index]
|
delete conditionValidations.value[index]
|
||||||
|
|
||||||
// 重新索引验证结果
|
// 重新索引验证结果
|
||||||
|
|
@ -160,9 +149,9 @@ const removeCondition = (index: number) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateCondition = (index: number, condition: ConditionFormData) => {
|
const updateCondition = (index: number, condition: TriggerConditionFormData) => {
|
||||||
if (subGroup.value.conditions) {
|
if (subGroup.value) {
|
||||||
subGroup.value.conditions[index] = condition
|
subGroup.value[index] = condition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,7 +161,7 @@ const handleConditionValidate = (index: number, result: { valid: boolean; messag
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateValidationResult = () => {
|
const updateValidationResult = () => {
|
||||||
if (!subGroup.value.conditions || subGroup.value.conditions.length === 0) {
|
if (!subGroup.value || subGroup.value.length === 0) {
|
||||||
emit('validate', { valid: false, message: '子条件组至少需要一个条件' })
|
emit('validate', { valid: false, message: '子条件组至少需要一个条件' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +179,7 @@ const updateValidationResult = () => {
|
||||||
|
|
||||||
// 监听变化
|
// 监听变化
|
||||||
watch(
|
watch(
|
||||||
() => subGroup.value.conditions,
|
() => subGroup.value,
|
||||||
() => {
|
() => {
|
||||||
updateValidationResult()
|
updateValidationResult()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
<DeviceTriggerConfig
|
<DeviceTriggerConfig
|
||||||
v-if="isDeviceTrigger(triggerItem.type)"
|
v-if="isDeviceTrigger(triggerItem.type)"
|
||||||
:model-value="triggerItem"
|
:model-value="triggerItem"
|
||||||
|
:index="index"
|
||||||
@update:model-value="(value) => updateTriggerDeviceConfig(index, value)"
|
@update:model-value="(value) => updateTriggerDeviceConfig(index, value)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -111,13 +112,12 @@ import {
|
||||||
/** 触发器配置组件 */
|
/** 触发器配置组件 */
|
||||||
defineOptions({ name: 'TriggerSection' })
|
defineOptions({ name: 'TriggerSection' })
|
||||||
|
|
||||||
// Props 和 Emits 定义
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
triggers: TriggerFormData[]
|
triggers: TriggerFormData[]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
'update:triggers': [value: TriggerFormData[]]
|
(e: 'update:triggers', value: TriggerFormData[]): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const triggers = useVModel(props, 'triggers', emit)
|
const triggers = useVModel(props, 'triggers', emit)
|
||||||
|
|
@ -172,36 +172,15 @@ const updateTriggerCronConfig = (index: number, cronExpression?: string) => {
|
||||||
triggers.value[index].cronExpression = cronExpression
|
triggers.value[index].cronExpression = cronExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
const onTriggerTypeChange = (index: number, type: number) => {
|
const onTriggerTypeChange = (index: number, _: number) => {
|
||||||
const triggerItem = triggers.value[index]
|
const triggerItem = triggers.value[index]
|
||||||
|
triggerItem.productId = undefined
|
||||||
// 清理不相关的配置
|
triggerItem.deviceId = undefined
|
||||||
if (type === TriggerTypeEnum.TIMER) {
|
triggerItem.identifier = undefined
|
||||||
triggerItem.productId = undefined
|
triggerItem.operator = undefined
|
||||||
triggerItem.deviceId = undefined
|
triggerItem.value = undefined
|
||||||
triggerItem.identifier = undefined
|
triggerItem.cronExpression = undefined
|
||||||
triggerItem.operator = undefined
|
triggerItem.conditionGroups = []
|
||||||
triggerItem.value = undefined
|
|
||||||
triggerItem.mainCondition = undefined
|
|
||||||
triggerItem.conditionGroup = undefined
|
|
||||||
if (!triggerItem.cronExpression) {
|
|
||||||
triggerItem.cronExpression = '0 0 12 * * ?'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
triggerItem.cronExpression = undefined
|
|
||||||
if (type === TriggerTypeEnum.DEVICE_STATE_UPDATE) {
|
|
||||||
triggerItem.mainCondition = undefined
|
|
||||||
triggerItem.conditionGroup = undefined
|
|
||||||
} else {
|
|
||||||
// 设备属性、事件、服务触发需要条件配置
|
|
||||||
if (!triggerItem.mainCondition) {
|
|
||||||
triggerItem.mainCondition = undefined // 等待用户配置
|
|
||||||
}
|
|
||||||
if (!triggerItem.conditionGroup) {
|
|
||||||
triggerItem.conditionGroup = undefined // 可选的条件组
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化:确保至少有一个触发器
|
// 初始化:确保至少有一个触发器
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表单对话框 -->
|
<!-- 表单对话框 -->
|
||||||
<RuleSceneForm v-model="formVisible" :rule-scene="currentRule" @success="getList" />
|
<RuleSceneForm v-model="formVisible" @success="getList" />
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue