Przeglądaj źródła

完成场景定义的新增、删除、修改、及回显

yukai 2 lat temu
rodzic
commit
373a7ec590

+ 5 - 1
src/api/scene/index.ts

@@ -8,8 +8,12 @@ export default {
     del: (ids: number) => del('/scene/scene/delete', { ids }),
     status: (data: object) => post('/scene/scene/status', data),
     add: (data: any) => post('/scene/scene/add', data),
-    edit: (data: any) => post('/scene/scene/edit', data),
+    edit: (data: any) => put('/scene/scene/edit', data),
     getDetail: (data: any) => get('/scene/scene/get', data),
     getColumns: (data: any) => post('/scene/scene/parameter_columns', data),
+    addDetail: (data: any) => post('/scene/detail/add', data),
+    editDetail: (data: any) => put('/scene/detail/edit', data),
+    delDetail: (ids: number) => del('/scene/detail/delete', { ids }),
+    getOneDetail: (data: any) => get('/scene/detail/list', data),
   }
 }

+ 41 - 10
src/views/iot/scene/manage/component/condition.vue

@@ -24,7 +24,7 @@
                 style="background: #fff; color: #000;border: 1px solid #d9cde3;margin-left: 10px;margin-right: 10px;"
                 v-if="i > 0">并且</el-button>
 
-              <el-popover placement="bottom" trigger="click">
+              <el-popover placement="bottom" trigger="click"  ref="popoverRef" v-model:visible="isPopoverVisible">
                 <template #reference>
                   <el-button style="background: #9adbff4d; color: #00a4fe;border: 1px solid #00a4fe4d;">{{ vo.parameter_text ||
                     '请选择参数' }}</el-button>
@@ -38,14 +38,14 @@
                 </div>
               </el-popover>
 
-              <el-popover placement="bottom" trigger="click">
+              <el-popover placement="bottom" trigger="click" v-model:visible="isPopoverVisible1">
                 <template #reference>
                   <el-button style="background: #a3caff4d; color: #2f54eb;border: 1px solid #2f54eb4d;">{{ vo.operator_text ||
                     '操作符' }}</el-button>
                 </template>
                 <div class="popover-content">
                   <ul>
-                    <li v-for="option in operatorList" :key="option.Key" @click="vo.operator = option.Key;vo.operator_text = option.Name;">{{ option.Name
+                    <li v-for="option in vo.operatorList" :key="option.Key" @click="vo.operator = option.Key;vo.operator_text = option.Name;saveData();isPopoverVisible1=false;">{{ option.Name
                     }}</li>
                   </ul>
                 </div>
@@ -57,12 +57,12 @@
                     '参数值' }}</el-button>
                 </template>
                 <div class="popover-content">
-                   <el-input v-model="vo.value" placeholder="请输入参数值" />
+                   <el-input v-model="vo.value" placeholder="请输入参数值"  @input="saveData"  />
 
                 </div>
               </el-popover>
 
-              <el-icon size="16" v-if="i > 0" @click="DelSceneItem(index)" style="position: relative;top: -13px;">
+              <el-icon size="16" v-if="i > 0" @click="DelSceneItem(i, index)" style="position: relative;top: -13px;">
                 <CircleClose />
               </el-icon>
 
@@ -95,7 +95,9 @@
 <script lang="ts" setup>
 import { PropType, ref } from 'vue'
 import { CirclePlus, CircleClose, Right } from '@element-plus/icons-vue';
-
+const emit = defineEmits(['EditPen']);
+const isPopoverVisible = ref(false);
+const isPopoverVisible1 = ref(false);
 const operatorList=ref([{
   'Key':'',
   'Name':'',
@@ -131,20 +133,31 @@ const props = defineProps({
 const setParameter=(vo: IConditionItem,item:any)=>{
   vo.parameter_text = item.name;
   vo.parameter = item.column;
-  operatorList.value=item.termTypes
+  // operatorList.value=item.termTypes
+  vo.operatorList = item.termTypes; 
+  isPopoverVisible.value = false; // 关闭弹窗
+
+  saveData();
+}
 
+const saveData=()=>{
+  emit('EditPen', props.operate_index);
 }
 
-const addSceneItem = (index: any | number) => {
+const addSceneItem = (index:number) => {
   props.condition[index].push({
     'parameter': '',
     'operator': '',
     'value': ''
   })
+  saveData();
+
 }
 
-const DelSceneItem = (index: any | number) => {
-  props.condition[index].splice(index, 1);
+const DelSceneItem = (index: number, parentIndex: number) => {
+  props.condition[parentIndex].splice(index, 1);
+  saveData();
+
 }
 
 
@@ -158,6 +171,24 @@ const addScene = () => {
 const delScene = (index: number) => {
   props.condition.splice(index, 1);
 }
+const initItem = () => {
+  console.log(props.condition,'aaaaaa');
+  console.log(props.columnList,'bbbbbb');
+  props.condition.forEach((item) => {
+    item.forEach((vo) => {
+      const operator = vo.operator;
+      const matchedColumn = props.columnList.find((column) =>
+        column.termTypes.some((term) => term.Key === operator)
+      ); 
+      if (matchedColumn) {
+        vo.operatorList = matchedColumn.termTypes; 
+      } else {
+        vo.operatorList = []; // 如果没有匹配的列,设置为空数组
+      }
+    });
+  });
+};
+initItem();
 
 </script>
 <style scoped lang="scss">

+ 74 - 19
src/views/iot/scene/manage/component/sceneItem.vue

@@ -13,7 +13,8 @@
       <div class="product flex flex-warp">
 
         <el-form-item label="产品:" prop="productKey">
-          <el-select v-model="item.productKey" filterable placeholder="请选择产品" @change="seletChange(index,item.productKey!)">
+          <el-select v-model="item.productKey" filterable placeholder="请选择产品"
+            @change="seletChange(index, item.productKey!)">
             <el-option v-for="it in sourceData" :key="it.key" :label="it.name" :value="it.key">
               <span style="float: left">{{ it.name }}</span>
               <span style="float: right; font-size: 13px">{{ it.key }}</span>
@@ -21,7 +22,7 @@
           </el-select>
         </el-form-item>
         <el-form-item label="设备:" prop="deviceKey">
-          <el-select v-model="item.deviceKey" filterable placeholder="请选择设备">
+          <el-select v-model="item.deviceKey" filterable placeholder="请选择设备" @change="EditPen(index)">
             <el-option v-for="it in deviceListData" :key="it.key" :label="it.name" :value="it.key">
               <span style="float: left">{{ it.name }}</span>
               <span style="float: right; font-size: 13px">{{ it.key }}</span>
@@ -29,14 +30,16 @@
           </el-select>
         </el-form-item>
         <el-form-item label="触发类型:" prop="triggerType">
-          <el-select v-model="item.triggerType" filterable placeholder="请选择触发类型" @change="getcolumns(index,item.triggerType!)">
+          <el-select v-model="item.triggerType" filterable placeholder="请选择触发类型"
+            @change="getSelectcolumns(index, item.triggerType!)">
             <el-option v-for="it in sourceTypeData" :key="it.key" :label="it.name" :value="it.key">
               <span style="float: left">{{ it.name }}</span>
               <span style="float: right; font-size: 13px">{{ it.key }}</span>
             </el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="定时请求" v-if="item.triggerType && ['readAttribute', 'functionCall'].includes(item.triggerType)">
+        <el-form-item label="定时请求"
+          v-if="item.triggerType && ['readAttribute', 'functionCall'].includes(item.triggerType)">
           <div style="display:flex">
             <el-input v-model="item.timer" placeholder="请输入cron表达式" />
             <el-dialog v-model="dialogVisible" title="选择Cron规则" width="60%">
@@ -46,14 +49,13 @@
 
           </div>
         </el-form-item>
-
       </div>
 
       <div class="title flex">
-        <div class="icon"></div> 触发条件 <div class="ml10"> <el-switch v-model="item.triggerSwitch" />
+        <div class="icon"></div> 触发条件 <div class="ml10"> <el-switch v-model="item.triggerSwitch"   @change="EditPen(index)"/>
         </div>
       </div>
-      <Condition :condition="item.condition" :operate_index="index" :columnList="columnList" v-if="item.triggerSwitch">
+      <Condition :condition="item.condition" :operate_index="index" :columnList="columnList" v-if="item.triggerSwitch && columnList.length>0" @EditPen="EditPen">
       </Condition>
     </div>
     <div>
@@ -79,6 +81,8 @@ import Condition from './condition.vue';
 const { proxy } = getCurrentInstance() as any;
 const scene_type = proxy.useDict('scene_type');
 
+const emit = defineEmits(['addScenesDetail','delScenesDetail','editScenesDetail']);
+
 const dialogVisible = ref();
 const sourceData = ref<testIValueType[]>([]);
 
@@ -108,6 +112,8 @@ interface testIValueType {
 
 }
 
+
+
 const props = defineProps({
 
   sceneList: {
@@ -147,18 +153,23 @@ const props = defineProps({
     }]
   }
 })
+
+
+
+
 const getProductList = () => {
   product.product.getSubList().then((res: any) => {
     sourceData.value = res.product;
+    intScenel();
   });
 };
-getProductList();
-const seletChange = (index: number, val: string) => {
 
-  product_key = val;
 
+const seletChange = (index: number, val: string) => {
+  product_key = val;
   //根据产品key获取产品ID
   let info = unref(sourceData)?.find((pro: { key: any; }) => pro.key === val);
+
   if (info) {
     // 重置 deviceKey 的值
     props.sceneList[index].deviceKey = '';
@@ -170,14 +181,28 @@ const seletChange = (index: number, val: string) => {
     }]];
     getDeviceList(info.id)
   }
-
+  EditPen(index);
 }
 const getDeviceList = (_id: any) => {
   product.device.allList({ productId: _id }).then((res: any) => {
     deviceListData.value = res.device
   })
 }
-const getcolumns = (index: number, val: string)  => {
+
+const getSelectcolumns=(index: number, val: string) => {
+  EditPen(index);
+
+  getcolumns(index,val);
+
+    // 重置当前项的 condition 值
+    props.sceneList[index].condition = [[{
+    'parameter': '',
+    'operator': '',
+    'value': ''
+  }]];
+
+}
+const getcolumns = (index: number, val: string) => {
   let where = {
     "sceneType": props.sceneType, //场景类型
     "typeName": scene_type[props.sceneType],
@@ -190,16 +215,15 @@ const getcolumns = (index: number, val: string)  => {
     }
   }
   getcolumnsList(where);
- // 重置当前项的 condition 值
- props.sceneList[index].condition = [[{
-      'parameter': '',
-      'operator': '',
-      'value': ''
-    }]];
+  
+
+
 }
 const getcolumnsList = (where: any) => {
   api.manage.getColumns(where).then((res: any) => {
-    columnList.value = res;
+    if(res){
+      columnList.value = res;
+    }
   })
 }
 const addScene = () => {
@@ -216,8 +240,16 @@ const addScene = () => {
 
     }]]
   });
+  emit('addScenesDetail', 'definition');
 };
+
+const EditPen=(index: number)=>{
+  emit('editScenesDetail',index);
+
+}
 const delScene = (index: number) => {
+  emit('delScenesDetail', index);
+
   props.sceneList.splice(index, 1);
 }
 const setNull = (row: any, key: string, val: string) => {
@@ -225,6 +257,7 @@ const setNull = (row: any, key: string, val: string) => {
 }
 const handlelisten = (e: any) => {
   props.sceneList[e.type].timer = e.cron;
+  EditPen(e.type);
 
 };
 const showCron = () => {
@@ -234,6 +267,28 @@ const showCron = () => {
 const cronclose = () => {
   dialogVisible.value = false;
 }
+
+//初始化
+const intScenel=()=>{
+  let array_data=props.sceneList;
+  console.log(array_data);
+
+  array_data.map((val:any,index) => {
+      if(val.productKey){
+          product_key = val.productKey;
+          let info = unref(sourceData)?.find((pro: { key: any; }) => pro.key === val.productKey);
+
+          if (info) {
+            getDeviceList(info.id)
+          }
+      }
+      if(val.triggerType){
+        getcolumns(index,val.triggerType)
+      } 
+  });
+}
+getProductList(); 
+
 </script>
 <style scoped lang="scss">
 .type-item {

+ 63 - 5
src/views/iot/scene/manage/detail.vue

@@ -19,7 +19,7 @@
 	</el-card>
 	<el-card style="  margin-top: 15px;" >
 		<div class="font20">场景定义</div>
-		<SceneItem :sceneList="sceneList" :sceneType="detail.sceneType"></SceneItem>
+		<SceneItem v-if="showstatus" :sceneList="sceneList" :sceneType="detail.sceneType" @addScenesDetail="addScenesDetail" @delScenesDetail="delScenesDetail" @editScenesDetail="editScenesDetail"></SceneItem>
 	</el-card>
 	<el-card style="  margin-top: 15px;" >
 		<div class="font20">场景动作</div>
@@ -41,7 +41,8 @@ import api from '/@/api/scene';
 import product from '/@/api/device';
 
 const editFormRef = ref();
-const sceneList = [{
+//原始
+const sceneList = {
 	'productKey': '',
 				'deviceKey': '',
 				'triggerType': '',
@@ -54,7 +55,8 @@ const sceneList = [{
 						'value': ''
 
 				}]]
-}];
+};
+const originalSceneList=ref([{}]);
 
 
 export default defineComponent({
@@ -64,6 +66,7 @@ export default defineComponent({
 		const router = useRouter();
 		const state = reactive({
 			developer_status: 2,
+			showstatus : false,
 			detail: {},
 			sourceData:[],
 			actionList: [{
@@ -96,7 +99,59 @@ export default defineComponent({
 			api.manage.getDetail({ "id": id }).then((res: any) => {
 				state.detail = res
 			})
+			getOneDetail();
 		};
+
+		const getOneDetail = () => {
+			const id = route.params && route.params.id;
+			api.manage.getOneDetail({ "sceneId": id,'group':'definition' }).then((res: any) => {
+				if(!res){
+					addScenesDetail('definition');
+					getOneDetail();
+				}
+				originalSceneList.value=res;
+				const scenes = res.map((scene:any) => {
+					const parsedBodyJson = JSON.parse(scene.bodyjson);
+					return {
+						...parsedBodyJson
+					};
+				});
+
+				state.sceneList=scenes;
+				state.showstatus = true;
+
+			})
+		};
+
+		//新增一条场景定义
+		const addScenesDetail=(type:String)=>{
+			let data={
+				sceneId:route.params && route.params.id,
+				group:type,
+				bodyjson:sceneList,
+			}
+			api.manage.addDetail(data).then((res: any) => {
+				getOneDetail();
+			});
+		}
+
+		//删除一条场景
+		const delScenesDetail=(index)=>{
+			let ids=originalSceneList.value[index].id;
+			api.manage.delDetail(ids).then((res: any) => {
+				// getOneDetail();
+			});
+		}
+		
+		//修改一条场景
+		const editScenesDetail=(index:number)=>{
+			let saveData=state.sceneList[index];
+			let ids=originalSceneList.value[index].id;
+			api.manage.editDetail({id:ids,bodyjson:saveData}).then((res: any) => {
+				getOneDetail();
+			});
+			
+		}
 		const addOrEdit = async (row?: any) => {
 			editFormRef.value.open(row);
 		};
@@ -111,18 +166,21 @@ export default defineComponent({
 			router.push(`/iotmanager/network/server/edit/${route.params && route.params.id}`)
 		};
 		onMounted(() => {
-			getDetail();
+
 		});
 		const handleClick = (tab: TabsPaneContext, event: Event) => {
 			// console.log(tab, event)
 		}
 
+		getDetail();
 
 
 		return {
 			toEdit,
 			addOrEdit,
-
+			delScenesDetail,
+			addScenesDetail,
+			editScenesDetail,
 			editFormRef,
 			activeName,
 			freshData,