Bladeren bron

【功能完善】IoT: 规则场景监听器相关组件

puhui999 1 jaar geleden
bovenliggende
commit
9389cf8863

+ 6 - 6
src/api/iot/rule/scene/index.ts

@@ -2,12 +2,12 @@ import request from '@/config/axios'
 
 // IoT 规则场景(场景联动) VO
 export interface RuleSceneVO {
-  id: number // 场景编号
-  name: string // 场景名称
-  description: string // 场景描述
-  status: number // 场景状态
-  triggers: string // 触发器数组
-  actions: string // 执行器数组
+  id?: number // 场景编号
+  name?: string // 场景名称
+  description?: string // 场景描述
+  status?: number // 场景状态
+  triggers?: any[] // 触发器数组
+  actions?: any[] // 执行器数组
 }
 
 // IoT 规则场景(场景联动) API

+ 20 - 18
src/views/iot/rule/scene/IoTRuleSceneForm.vue

@@ -1,5 +1,5 @@
 <template>
-  <Dialog :title="dialogTitle" v-model="dialogVisible" width="70%">
+  <Dialog :title="dialogTitle" v-model="dialogVisible" width="1080px">
     <el-form
       ref="formRef"
       :model="formData"
@@ -33,12 +33,18 @@
         </el-col>
         <el-col :span="24">
           <el-divider content-position="left">触发器配置</el-divider>
-          <device-listener v-model="formData.triggers" />
+          <device-listener
+            v-for="(trigger, index) in formData.triggers"
+            :model-value="trigger"
+            :key="index"
+            class="mb-10px"
+          />
+          <el-text class="ml-10px!" type="primary" @click="addTrigger">添加触发器</el-text>
         </el-col>
         <el-col :span="24">
           <el-divider content-position="left">执行动作配置</el-divider>
           <el-form-item label="执行器数组" prop="actionConfigs">
-            <el-input v-model="formData.actions" placeholder="请输入执行器数组" />
+            <!--            <el-input v-model="formData.actions" placeholder="请输入执行器数组" />-->
           </el-form-item>
         </el-col>
       </el-row>
@@ -64,14 +70,10 @@ const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
-const formData = ref({
-  id: undefined,
-  name: undefined,
-  description: undefined,
-  status: undefined,
-  triggers: undefined,
-  actions: undefined
-})
+const formData = ref<RuleSceneVO>({
+  status: 0,
+  triggers: []
+} as RuleSceneVO)
 const formRules = reactive({
   name: [{ required: true, message: '场景名称不能为空', trigger: 'blur' }],
   status: [{ required: true, message: '场景状态不能为空', trigger: 'blur' }],
@@ -80,6 +82,10 @@ const formRules = reactive({
 })
 const formRef = ref() // 表单 Ref
 
+const addTrigger = () => {
+  formData.value.triggers?.push({})
+}
+
 /** 打开弹窗 */
 const open = async (type: string, id?: number) => {
   dialogVisible.value = true
@@ -125,13 +131,9 @@ const submitForm = async () => {
 /** 重置表单 */
 const resetForm = () => {
   formData.value = {
-    id: undefined,
-    name: undefined,
-    description: undefined,
-    status: undefined,
-    triggers: undefined,
-    actions: undefined
-  }
+    status: 0,
+    triggers: []
+  } as RuleSceneVO
   formRef.value?.resetFields()
 }
 </script>

+ 27 - 14
src/views/iot/rule/scene/components/DeviceListener.vue

@@ -20,6 +20,8 @@
         <span class="mr-10px">设备</span>
         <el-button type="primary">选择设备</el-button>
       </div>
+      <!-- 添加规则 -->
+      <el-button class="device-listener-delete" type="danger" circle :icon="Delete" size="small" />
     </div>
     <div class="device-listener-condition flex p-10px">
       <div class="flex flex-col items-center justify-center mr-10px h-a">
@@ -32,38 +34,35 @@
           />
         </el-select>
       </div>
-      <div class="flex items-center flex-wrap">
+      <div class="">
         <DeviceListenerCondition
-          v-for="i in 2"
-          :key="i"
-          v-model="conditionParameter"
+          v-for="(conditionParameter, index) in conditionParameters"
+          :key="index"
+          :model-value="conditionParameter"
+          @update:model-value="(val) => (conditionParameters[index] = val)"
           class="mb-10px last:mb-0"
         />
       </div>
-      <div class="flex flex-col items-center justify-center mr-10px h-a">
+      <div class="flex flex-1 flex-col items-center justify-center mr-10px h-a">
         <!-- 添加规则 -->
-        <el-button type="primary" circle :icon="Plus" size="small" />
+        <el-button type="primary" circle :icon="Plus" size="small" @click="addConditionParameter" />
       </div>
     </div>
-
-    <!-- 新增条件按钮 -->
-    <div class="mt-4">
-      <el-button type="primary"> 新增监听器 </el-button>
-    </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { Plus } from '@element-plus/icons-vue'
+import { Delete, Plus } from '@element-plus/icons-vue'
 import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
 import { ref } from 'vue'
 import DeviceListenerCondition from './DeviceListenerCondition.vue'
+import { IotRuleSceneTriggerConditionParameter } from '@/api/iot/rule/scene/scene.types'
 
 /** 场景联动之监听器组件 */
 defineOptions({ name: 'DeviceListener' })
 
 defineProps<{
-  modelValue: any[]
+  modelValue: any
 }>()
 
 const emit = defineEmits(['update:modelValue'])
@@ -71,13 +70,27 @@ const emit = defineEmits(['update:modelValue'])
 // 添加响应式变量
 const triggerType = ref()
 const messageType = ref('property')
-const conditionParameter = ref({})
+const conditionParameters = ref<IotRuleSceneTriggerConditionParameter[]>([])
+const addConditionParameter = () => {
+  conditionParameters.value?.push({} as IotRuleSceneTriggerConditionParameter)
+}
+onMounted(() => {
+  addConditionParameter()
+})
 </script>
 
 <style lang="scss" scoped>
 .device-listener {
   .device-listener-header {
+    position: relative;
     background-color: #eff3f7;
+
+    .device-listener-delete {
+      position: absolute;
+      top: auto;
+      right: 33px;
+      bottom: auto;
+    }
   }
 
   .device-listener-condition {