xiuos_IoT/xiuosiot-frontend/src/views/gateway/manage/index.vue

554 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-row
type="flex"
justify="space-between"
style="align-items: baseline; margin-bottom: 30px"
>
<div class="header">
<h1 class="title">网关</h1>
<span class="date">{{ date }}</span>
<span class="sum">{{ "共" + deviceSum + "个网关" }}</span>
</div>
</el-row>
<el-row>
<el-button
class="add_btn"
icon="el-icon-plus"
@click="visible = true"
>新增网关</el-button>
</el-row>
<div class="list_container">
<div class="title_box">
<p />
<p />
<p>最后连接时间</p>
<p>网关名称</p>
<p>网关ID</p>
<i />
</div>
<div
v-for="(item, index) in gatewayList"
:key="index"
class="item_box"
:class="
item.status === 1
? 'online'
: item.status === 2
? 'offline'
: 'never_seen'
"
>
<img :src="getStatusImg(item.status)">
<p>
{{
item.status === 1 ? "在线" : item.status === 2 ? "离线" : "从未连接"
}}
</p>
<p>{{ item.lastConnect ? item.lastConnect : "" }}</p>
<p>{{ item.name }}</p>
<p>
<a @click="showDataDialog(item.gatewayid)">{{ item.gatewayid }}</a>
</p>
<i
type="danger"
class="remove_icon el-icon-delete"
@click="remove(item.name, item.gatewayid)"
/>
</div>
</div>
<!-- 设备列表弹窗 -->
<div v-show="dataVisible" class="dialog_wrapper">
<div class="dialog-container">
<div class="dialog_header">
<p class="ip">包含设备列表</p>
<div class="remove_icon" @click="close">X</div>
</div>
<div class="dialog_content">
<div v-if="deviceList.length > 0" class="list_container">
<div class="title_box">
<p />
<p>状态</p>
<p>节点名称</p>
<p>终端ID</p>
</div>
<div class="content_box">
<div
v-for="(item, index) in deviceList"
:key="index"
class="item_box"
>
<img src="@/assets/images/geteway_device.png">
<p>
{{
item.status === 1 ? "在线" : item.status === 2 ? "离线" : "从未连接"
}}
</p>
<p>{{ item.name }}</p>
<p>{{ item.devEui }}</p>
</div>
</div>
</div>
<div v-else style="min-height:200px;text-align:center">
暂无数据
</div>
</div>
</div>
</div>
<!-- 设备新增弹窗 -->
<div v-show="visible" class="dialog_wrapper">
<div class="dialog-container">
<div class="dialog_header">
<p class="ip">网关新增</p>
<div class="remove_icon" @click="close">X</div>
</div>
<div class="dialog_content">
<div class="form">
<div class="form_content">
<div class="item_title">
<img src="@/assets/images/stock_status.png">名称
</div>
<div class="item_content">
<el-input v-model="form.name" />
</div>
</div>
<div class="line" />
<div class="form_content">
<div class="item_title">
<img src="@/assets/images/stock_no.png">网关<br>ID
</div>
<div class="item_content">
<el-input v-model="form.gatewayid" />
</div>
</div>
<div class="line" />
</div>
<div class="footer">
<el-button
size="medium"
class="cancel_btn"
@click="close"
>取消</el-button>
<el-button
size="medium"
class="save_btn"
style="border-radius: 4px"
type="primary"
@click="save"
>保存</el-button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import {
getGatewayList,
getDeviceList,
add,
updateGateway,
updateDevice,
remove
} from '@/api/gateway/manage'
export default {
data() {
return {
date: '',
deviceSum: 10,
// list: [
// {
// name: '11',
// gatewayid: '1234568932131331',
// lastConnect: '2023-10-11 12:00:00',
// status: 1,
// imgSrc: require('@/assets/images/gateway_online.png')
// },
// {
// name: '11',
// gatewayid: '1234568932131331',
// lastConnect: '2023-10-11 12:00:00',
// status: 2,
// imgSrc: require('@/assets/images/gateway_offline.png')
// },
// {
// name: '11',
// gatewayid: '1234568932131331',
// lastConnect: '2023-10-11 12:00:00',
// status: 0,
// imgSrc: require('@/assets/images/gateway_never_seen.png')
// }
// ],
deviceList: [],
visible: false,
dataVisible: false,
form: {
name: '',
gatewayid: ''
}
}
},
computed: {
...mapGetters(['gatewayList'])
},
mounted() {
this.date = new Date().toLocaleDateString()
this.getGatewayList()
},
methods: {
getGatewayList() {
getGatewayList().then((res) => {
this.$store.dispatch('app/setGatewayList', res.data)
this.deviceSum = this.gatewayList.length
})
},
getStatusImg(status) {
let imgSrc
switch (status) {
case 0:
imgSrc = require('@/assets/images/gateway_never_seen.png')
break
case 1:
imgSrc = require('@/assets/images/gateway_online.png')
break
case 2:
imgSrc = require('@/assets/images/gateway_offline.png')
break
}
return imgSrc
},
close() {
this.visible = false
this.dataVisible = false
},
remove(name, gatewayid) {
this.$confirm(`确认删除网关${name}`, '提示', { type: 'warning' })
.then(() => {
remove({ gatewayid }).then((res) => {
this.$message.success('删除成功')
this.getGatewayList()
})
})
.catch()
},
save() {
add({ ...this.form, status: 0 }).then((res) => {
this.$message.success('新增成功')
this.getGatewayList()
this.close()
})
},
showDataDialog(gatewayid) {
this.getDeviceList(gatewayid)
this.dataVisible = true
},
getDeviceList(gatewayid) {
getDeviceList({ gatewayid }).then((res) => {
if (res.data) {
this.deviceList = res.data
}
})
}
}
}
</script>
<style lang="scss" scoped>
.header {
font-family: Lato;
.title {
color: #174a84;
}
.date {
color: #a5c9ff;
}
.sum {
margin-left: 85px;
color: #a5c9ff;
}
}
.add_btn {
width: 100%;
color: #fff;
border: 2px solid transparent;
background: linear-gradient(#789af3, #789af3) padding-box,
repeating-linear-gradient(
45deg,
#789af3 0,
#789af3 12px,
#fff 12px,
#fff 24px
);
}
.list_container {
width: 100%;
margin-top: 30px;
.title_box {
width: 100%;
height: 40px;
margin: 10px auto;
display: inline-grid;
grid-template-columns: 100px 1fr minmax(260px, 2fr) 1fr 2fr 100px;
justify-items: center;
align-content: center;
align-items: center;
p {
line-height: 40px;
font-size: 26px;
font-family: Microsoft YaHei;
color: #2e4765;
}
}
.item_box {
border-radius: 10px;
width: 100%;
height: 100px;
margin: 5px auto;
display: inline-grid;
grid-template-columns: 100px 1fr minmax(260px, 2fr) 1fr 2fr 100px;
justify-items: center;
align-content: center;
align-items: center;
img {
width: 45px;
aspect-ratio: 1 / 1;
}
p {
line-height: 100px;
font-size: 26px;
font-family: Microsoft YaHei;
color: #2e4765;
a:hover {
text-decoration: underline;
}
}
.remove_icon {
font-size: 26px;
color: #f56c6c;
cursor: pointer;
}
}
.online {
background: linear-gradient(
90deg,
rgba(212, 252, 121, 0.2) 0%,
rgba(150, 230, 161, 0.2) 100%
);
}
.offline {
background: linear-gradient(
225deg,
rgba(254, 243, 229, 0.2) 0%,
rgba(254, 199, 168, 0.2) 0%,
rgba(254, 180, 141, 0.2) 38%,
rgba(255, 78, 0, 0.2) 100%
);
}
.never_seen {
background: linear-gradient(
90deg,
rgba(0, 204, 242, 0.2) 0%,
rgba(120, 154, 243, 0.2) 62%,
rgba(173, 223, 232, 0.2) 100%
);
}
}
.dialog_wrapper {
z-index: 2;
position: fixed;
left: 230px;
right: 0;
top: 0;
bottom: 0;
margin: 0;
&::before {
content: "";
position: absolute;
left: -230px;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 2;
}
.dialog-container {
z-index: 10;
width: 600px;
transform: none;
margin: 15vh auto;
position: relative;
border-radius: 8px;
border: 2px solid #20be0b;
font-family: Microsoft YaHei;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
.dialog_header {
background-color: #20be0b;
text-align: center;
color: #fff;
padding: 5px;
position: relative;
p {
font-size: 24px;
font-weight: bold;
margin: 5px auto;
}
.remove_icon {
position: absolute;
font-size: 18px;
right: 15px;
top: 10px;
cursor: pointer;
}
}
.dialog_content {
background-color: #fff;
border-radius: 0 0 8px 8px;
padding: 40px 10px 20px;
.form {
width: 80%;
margin: auto;
.form_content {
display: flex;
width: 100%;
div {
justify-content: center;
display: flex;
align-items: center;
img {
vertical-align: middle;
margin-right: 10px;
}
}
.item_title {
text-align: center;
background: #d5f3d1;
width: 110px;
min-height: 90px;
font-size: 20px;
color: #20be0b;
}
.item_content {
flex: 1;
word-break: break-all;
padding: 9px;
}
}
.line {
width: 100%;
height: 2px;
background-image: linear-gradient(
to right,
#20be0b 0%,
#20be0b 50%,
transparent 50%
);
background-size: 18px 100%;
background-repeat: repeat-x;
}
}
.list_container {
width: 100%;
margin-top: -20px;
.title_box {
width: 100%;
height: 40px;
margin: 10px auto;
display: inline-grid;
grid-template-columns: 80px 1fr 1fr 1fr;
justify-items: center;
align-content: center;
align-items: center;
p {
line-height: 40px;
font-size: 22px;
font-family: Microsoft YaHei;
color: #2e4765;
}
}
.content_box {
min-height: 200px;
.item_box {
border: 1px solid rgba(0, 204, 242, 0.2);
background: linear-gradient(
90deg,
rgba(0, 204, 242, 0.2) 0%,
rgba(150, 230, 161, 0.2) 100%
);
border-radius: 10px;
width: 100%;
height: 70px;
margin: 5px auto;
display: inline-grid;
grid-template-columns: 80px 1fr 1fr 1fr;
justify-items: center;
align-content: center;
align-items: center;
img {
width: 45px;
aspect-ratio: 1 / 1;
}
p {
line-height: 100px;
font-size: 22px;
font-family: Microsoft YaHei;
color: #2e4765;
a:hover {
text-decoration: underline;
}
}
.remove_icon {
font-size: 26px;
color: #f56c6c;
cursor: pointer;
}
}
}
}
}
// .radio {
// ::v-deep .el-radio-button__inner {
// color: #8f59eb;
// border-color: #8f59eb;
// }
// ::v-deep .el-radio-button__orig-radio:checked + .el-radio-button__inner {
// background-color: #8f59eb;
// color: #fff;
// }
// ::v-deep .el-radio-button:first-child .el-radio-button__inner {
// border-radius: 9px 0 0 9px;
// }
// ::v-deep .el-radio-button:last-child .el-radio-button__inner {
// border-radius: 0 9px 9px 0;
// }
// }
}
.footer {
text-align: center;
margin: 40px auto 20px;
.cancel_btn {
border-color: #20be0b;
color: #20be0b;
&:hover {
background-color: rgba(32, 190, 11, 0.1);
}
}
.save_btn {
border-color: #20be0b;
background-color: #20be0b;
border-radius: 2px;
&:hover {
background-color: #20be0b;
}
}
}
}
::v-deep .el-input > .el-input__inner {
border: none;
}
</style>