2025-05-20 13:25:47 +08:00
|
|
|
<script setup>
|
|
|
|
import { ref, reactive, onMounted, watch } from 'vue';
|
|
|
|
import { isEmpty, getAssetsFile } from '@/utils';
|
|
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
const route = useRoute();
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
devices: {
|
|
|
|
type: Array,
|
|
|
|
required: true,
|
|
|
|
default: () => [],
|
|
|
|
validator: (items) => {
|
|
|
|
return items.every((item) => {
|
|
|
|
return (
|
|
|
|
typeof item === 'object' &&
|
|
|
|
item !== null &&
|
|
|
|
typeof item.id === 'number' &&
|
|
|
|
typeof item.isOpen === 'number' &&
|
|
|
|
typeof item.isOperation === 'number' &&
|
|
|
|
typeof item.name === 'string' &&
|
|
|
|
typeof item.serial === 'string' &&
|
|
|
|
typeof item.icon === 'string' &&
|
|
|
|
(!item.status || typeof item.status === 'number')
|
|
|
|
);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
title: {
|
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
default: () => '',
|
|
|
|
validator: (items) => {
|
|
|
|
return items;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<div>
|
|
|
|
<el-card style="border-radius: 16px">
|
|
|
|
<div class="device-list-title" style="">{{ title }}</div>
|
|
|
|
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap; gap: 16px">
|
|
|
|
<div v-for="(item, index) in devices" :key="index" class="device">
|
|
|
|
<div v-if="item.status == 1" class="status" style="background-color: #25bf82">正常</div>
|
|
|
|
<div v-else-if="item.status == 0" class="status" style="background-color: #999999">离线</div>
|
|
|
|
<div v-else-if="item.status == -1" class="status" style="background-color: #fe4066">故障</div>
|
|
|
|
<div style="display: flex; flex-direction: column; justify-content: space-between; height: 100%">
|
|
|
|
<div style="display: flex; justify-content: flex-start">
|
|
|
|
<img v-if="item.icon === 'plant'" :src="getAssetsFile('images/smartFarm/育苗.png')" alt="" />
|
|
|
|
<img v-else-if="item.icon === 'gogga'" :src="getAssetsFile('images/smartFarm/病虫害.png')" alt="" />
|
|
|
|
<img v-else-if="item.icon === 'water'" :src="getAssetsFile('images/smartFarm/灌溉控制.png')" alt="" />
|
|
|
|
<div style="margin-left: 10px">
|
2025-05-20 17:49:10 +08:00
|
|
|
<div style="font-size: 16px; text-align: left; color: #000000">{{ item.name }}</div>
|
2025-05-20 13:25:47 +08:00
|
|
|
<div style="font-size: 12px; text-align: left">{{ item.serial }}</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div style="text-align: left; font-size: 16px; display: flex; justify-content: space-between; padding-left: 6px">
|
|
|
|
<div style="width: 128px; height: 30px; border-radius: 15px; background-color: #ffffff">
|
|
|
|
<div v-if="item.status == '0'" :class="{ 'swich-box2': true, 'swich-box-close': item.isOpen == 0 }">
|
|
|
|
<span class="swich-btn" :style="{ color: item.isOpen == 0 ? '#999999' : '#ffffff' }">开启</span>
|
|
|
|
<span class="swich-btn" :style="{ color: item.isOpen == 1 ? '#999999' : '#ffffff' }">关闭</span>
|
|
|
|
</div>
|
|
|
|
<div v-else :class="{ 'swich-box': true, 'swich-box-close': item.isOpen == 0 }">
|
|
|
|
<span class="swich-btn" :style="{ color: item.isOpen == 0 ? '#25bf82' : '#ffffff' }" @click="item.isOpen = 1">开启</span>
|
|
|
|
<span class="swich-btn" :style="{ color: item.isOpen == 1 ? '#999999' : '#ffffff' }" @click="item.isOpen = 0">关闭</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span v-if="item.isOperation == 0" style="color: #999999">待机中...</span>
|
|
|
|
<span v-else-if="item.isOperation == 1" style="color: #25bf82">运作中...</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.device-list-title {
|
|
|
|
font-size: 16px;
|
|
|
|
font-weight: bold;
|
|
|
|
text-align: left;
|
|
|
|
color: #000;
|
|
|
|
margin-bottom: 20px;
|
|
|
|
}
|
|
|
|
.device {
|
|
|
|
height: 150px;
|
|
|
|
flex: 0 0 calc(33.33% - 11px);
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
border-radius: 16px;
|
|
|
|
position: relative;
|
|
|
|
cursor: pointer;
|
|
|
|
padding: 16px 16px 16px 10px;
|
|
|
|
img {
|
|
|
|
height: 64px;
|
|
|
|
width: 64px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.status {
|
|
|
|
border-radius: 0 16px 0 16px;
|
|
|
|
height: 32px;
|
|
|
|
line-height: 26px;
|
|
|
|
width: 40px;
|
|
|
|
position: absolute;
|
|
|
|
right: 0;
|
|
|
|
top: 0;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
color: #ffffff;
|
|
|
|
font-size: 12px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.swich-box,
|
|
|
|
.swich-box2 {
|
|
|
|
width: 128px;
|
|
|
|
height: 30px;
|
|
|
|
border-radius: 15px;
|
|
|
|
z-index: 0;
|
|
|
|
position: relative;
|
|
|
|
&::before {
|
|
|
|
display: inline-block;
|
|
|
|
position: absolute;
|
|
|
|
content: '';
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
z-index: -1;
|
|
|
|
width: 64px;
|
|
|
|
height: 30px;
|
|
|
|
background-color: #25bf82;
|
|
|
|
border-radius: 15px;
|
|
|
|
transition: all 0.3s ease-in-out;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.swich-box-close::before {
|
|
|
|
left: 64px;
|
|
|
|
background-color: #999999;
|
|
|
|
}
|
|
|
|
|
|
|
|
::v-deep .swich-btn {
|
|
|
|
display: inline-block;
|
|
|
|
font-size: 16px;
|
|
|
|
width: 64px;
|
|
|
|
height: 30px;
|
|
|
|
line-height: 30px;
|
|
|
|
border-radius: 15px;
|
|
|
|
text-align: center;
|
|
|
|
transition: all 0.3s ease-in-out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.swich-box2 {
|
|
|
|
&::before {
|
|
|
|
background-color: #999999;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|