Merge remote-tracking branch 'origin/master'
@ -1,25 +0,0 @@
|
||||
package com.hw.mqtt.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author WenJY
|
||||
* @date 2023年03月14日 13:46
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ServerNode {
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* ip:port
|
||||
*/
|
||||
private String peerHost;
|
||||
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hw.mqtt.service;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* mqtt broker 服务
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public interface IMqttBrokerService {
|
||||
|
||||
/**
|
||||
* 获取在线客户端数量
|
||||
* @author WenJY
|
||||
* @date 2023-03-14 13:51
|
||||
* @return long
|
||||
*/
|
||||
long getOnlineClientSize();
|
||||
|
||||
/**
|
||||
* 获取所有在线的客户端
|
||||
* @author WenJY
|
||||
* @date 2023-03-14 13:51
|
||||
* @return java.util.List<java.lang.String>
|
||||
*/
|
||||
List<String> getOnlineClients();
|
||||
|
||||
/**
|
||||
* 向指定主题发送消息
|
||||
* @author WenJY
|
||||
* @date 2023-03-14 13:50
|
||||
* @param topic
|
||||
* @param payload
|
||||
* @return boolean
|
||||
*/
|
||||
boolean publish(String topic,String payload);
|
||||
|
||||
/**
|
||||
* 主动关闭指定客户端连接
|
||||
* @author WenJY
|
||||
* @date 2023-03-18 9:23
|
||||
* @param clientId
|
||||
*/
|
||||
boolean closeClientById(String clientId);
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hw.mqtt.service.impl;
|
||||
|
||||
import com.hw.mqtt.enums.RedisKeys;
|
||||
import com.hw.mqtt.service.IMqttBrokerService;
|
||||
import net.dreamlu.iot.mqtt.spring.server.MqttServerTemplate;
|
||||
import net.dreamlu.mica.core.utils.StringPool;
|
||||
import net.dreamlu.mica.redis.cache.MicaRedisCache;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* mqtt broker 服务
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Service
|
||||
public class MqttBrokerServiceImpl implements IMqttBrokerService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(MqttBrokerServiceImpl.class);
|
||||
@Autowired private MicaRedisCache redisCache;
|
||||
@Autowired private MqttServerTemplate server;
|
||||
|
||||
@Override
|
||||
public long getOnlineClientSize() {
|
||||
Set<String> keySet = redisCache.scan(RedisKeys.CONNECT_STATUS.getKey(StringPool.STAR));
|
||||
if (keySet.isEmpty()) {
|
||||
return 0L;
|
||||
}
|
||||
long result = 0;
|
||||
for (String redisKey : keySet) {
|
||||
Long count = redisCache.getSetOps().size(redisKey);
|
||||
if (count != null) {
|
||||
result += count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getOnlineClients() {
|
||||
Set<String> keySet = redisCache.scan(RedisKeys.CONNECT_STATUS.getKey(StringPool.STAR));
|
||||
if (keySet.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> clientList = new ArrayList<>();
|
||||
for (String redisKey : keySet) {
|
||||
Set<String> members = redisCache.sMembers(redisKey);
|
||||
if (members != null && !members.isEmpty()) {
|
||||
clientList.addAll(members);
|
||||
}
|
||||
}
|
||||
return clientList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean publish(String topic, String payload) {
|
||||
boolean result = server.publishAll(topic, payload.getBytes(StandardCharsets.UTF_8));
|
||||
logger.info("Mqtt publishAll result:{};topic:{};payload:{}", result, topic, payload);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closeClientById(String clientId) {
|
||||
try{
|
||||
server.close(clientId);
|
||||
}catch (Exception ex){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hw.mqtt.util;
|
||||
|
||||
import net.dreamlu.mica.core.utils.CharPool;
|
||||
|
||||
/**
|
||||
* redis 工具
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public class RedisUtil {
|
||||
|
||||
/**
|
||||
* 转换成 redis 的 pattern 规则
|
||||
*
|
||||
* @return pattern
|
||||
*/
|
||||
public static String getTopicPattern(String topicFilter) {
|
||||
// mqtt 分享主题 $share/{ShareName}/{filter}
|
||||
return topicFilter
|
||||
.replace(CharPool.PLUS, CharPool.STAR)
|
||||
.replace(CharPool.HASH, CharPool.STAR);
|
||||
}
|
||||
|
||||
}
|
After Width: | Height: | Size: 611 B |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 993 B |
After Width: | Height: | Size: 262 KiB |
After Width: | Height: | Size: 490 KiB |
After Width: | Height: | Size: 121 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 611 B |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 305 KiB |
After Width: | Height: | Size: 490 KiB |
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
export default {
|
||||
expose: ['setData'],
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
setData(option) {
|
||||
this.initChart(option)
|
||||
},
|
||||
initChart(option) {
|
||||
this.chart = echarts.init(this.$el, 'macarons')
|
||||
|
||||
this.chart.setOption(option)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -0,0 +1,537 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div>
|
||||
<div class="menu " style="left: 2%">
|
||||
<span>
|
||||
监控主页
|
||||
</span>
|
||||
</div>
|
||||
<div class="menu menuClick" style="left: 9%">
|
||||
<el-dropdown trigger="click">
|
||||
<span class="el-dropdown-link">
|
||||
智慧场景 <i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>黄金糕</el-dropdown-item>
|
||||
<el-dropdown-item>狮子头</el-dropdown-item>
|
||||
<el-dropdown-item>螺蛳粉</el-dropdown-item>
|
||||
<el-dropdown-item>双皮奶</el-dropdown-item>
|
||||
<el-dropdown-item>蚵仔煎</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<div class="menu" style="left: 16%">
|
||||
<span>
|
||||
设备监测
|
||||
</span>
|
||||
</div>
|
||||
<div class="menu" style="left: 23%">
|
||||
<span>
|
||||
传感器汇总
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="num1">30</div>
|
||||
<div class="num2">216</div>
|
||||
<div class="num3">0</div>
|
||||
<div class="num4">0</div>
|
||||
<div class="num5">0</div>
|
||||
<div class="num6">0</div>
|
||||
<div class="num7">0</div>
|
||||
<div class="num8">0</div>
|
||||
<div class="title1">监控单元</div>
|
||||
<div class="title2">传感器</div>
|
||||
<div class="title3">设备高温</div>
|
||||
<div class="title4">设备振动</div>
|
||||
<div class="title5">烟雾火情</div>
|
||||
<div class="title6">环境大风</div>
|
||||
<div class="title7">柜内温度</div>
|
||||
<div class="title8">柜内冰浸</div>
|
||||
<div class="title9">告警信息</div>
|
||||
<div class="title10">监控单元</div>
|
||||
|
||||
<div class="table1">
|
||||
<div style="background-color: #094170">
|
||||
<div class="scrollTable" style="font-weight: bold;width: 8%">
|
||||
告警编号
|
||||
</div>
|
||||
<div class="scrollTable" style="font-weight: bold;width: 8%">
|
||||
告警类型
|
||||
</div>
|
||||
<div class="scrollTable" style="font-weight: bold;width: 15%">
|
||||
告警单元
|
||||
</div>
|
||||
<div class="scrollTable" style="font-weight: bold;width: 30%">
|
||||
告警信息
|
||||
</div>
|
||||
<div class="scrollTable" style="font-weight: bold;width: 11%">
|
||||
告警位置
|
||||
</div>
|
||||
<div class="scrollTable" style="font-weight: bold;width: 20%">
|
||||
告警时间
|
||||
</div>
|
||||
<div class="scrollTable" style="font-weight: bold;width: 8%">
|
||||
处理情况
|
||||
</div>
|
||||
</div>
|
||||
<vue-seamless-scroll :class-option="chart1TableOption" :data="table1Data" class="case-item"
|
||||
style="height: calc(100% - 33px);overflow: hidden;">
|
||||
<div v-for="(item, index) in table1Data" :key="index">
|
||||
<div :style='"background-color:" + ((index % 2 === 0) ? "#053460" : "#032d57")'>
|
||||
<div class="scrollTable" style="width: 8%">
|
||||
{{ item.data1 }}
|
||||
</div>
|
||||
<div class="scrollTable" style="width: 8%">
|
||||
{{ item.data2 }}
|
||||
</div>
|
||||
<div class="scrollTable" style="width: 15%">
|
||||
{{ item.data3 }}
|
||||
</div>
|
||||
<div class="scrollTable" style="width: 30%">
|
||||
{{ item.data4 }}
|
||||
</div>
|
||||
<div class="scrollTable" style="width: 11%">
|
||||
{{ item.data5 }}
|
||||
</div>
|
||||
<div class="scrollTable" style="width: 20%">
|
||||
{{ item.data6 }}
|
||||
</div>
|
||||
<div class="scrollTable" style="width: 8%">
|
||||
<span style="color: #67C23A;">已处理</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vue-seamless-scroll>
|
||||
</div>
|
||||
<div class="right">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="item">
|
||||
<div class="titleBg"></div>
|
||||
<div class="title">
|
||||
<span style="margin-right: 28px;"> 变压器 </span>
|
||||
<el-tag type="success">正常</el-tag>
|
||||
</div>
|
||||
<div class="img"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="item">
|
||||
<div class="titleBg"></div>
|
||||
<div class="title">
|
||||
<span style="margin-right: 28px;"> 变压器 </span>
|
||||
<el-tag type="success">正常</el-tag>
|
||||
</div>
|
||||
<div class="img"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="item">
|
||||
<div class="titleBg"></div>
|
||||
<div class="title">
|
||||
<span style="margin-right: 28px;"> 变压器 </span>
|
||||
<el-tag type="success">正常</el-tag>
|
||||
</div>
|
||||
<div class="img"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="item">
|
||||
<div class="titleBg"></div>
|
||||
<div class="title">
|
||||
<span style="margin-right: 28px;"> 变压器 </span>
|
||||
<el-tag type="success">正常</el-tag>
|
||||
</div>
|
||||
<div class="img"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="pagination">
|
||||
<el-pagination :page-size="20" :pager-count="11" layout="prev, pager, next" :total="1000">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import vueSeamlessScroll from "vue-seamless-scroll";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
vueSeamlessScroll,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
table1Data: [
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
{
|
||||
data1: '001',
|
||||
data2: '越限',
|
||||
data3: '123123',
|
||||
data4: '无线检测 检测值为 21° - 25°',
|
||||
data5: '设备11233',
|
||||
data6: '2021.01.01 00:00:00',
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
background-image: url("~@/assets/board/standard/bg.jpg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
height: calc(100vh);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.menu {
|
||||
background-image: url("~@/assets/board/common/subheadClick1.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: absolute;
|
||||
width: 8vw;
|
||||
height: 1.66vw;
|
||||
top: 3.8%;
|
||||
line-height: 1.66vw;
|
||||
font-size: 0.8vw;
|
||||
color: #d4d4d4;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.menu .el-dropdown {
|
||||
font-size: 0.8vw;
|
||||
color: #d4d4d4;
|
||||
}
|
||||
|
||||
.menuClick {
|
||||
background-image: url("~@/assets/board/common/subheadClick.png");
|
||||
color: #f3f3f3;
|
||||
}
|
||||
|
||||
.num1 {
|
||||
position: absolute;
|
||||
top: 21%;
|
||||
left: 18%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 3vw;
|
||||
color: #15d654;
|
||||
}
|
||||
|
||||
.num2 {
|
||||
position: absolute;
|
||||
top: 21%;
|
||||
left: 33%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 3vw;
|
||||
color: #00fff0;
|
||||
}
|
||||
|
||||
.num3 {
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
left: 7.5%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #d73827;
|
||||
}
|
||||
|
||||
.num4 {
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
left: 15%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #1ef16d;
|
||||
}
|
||||
|
||||
.num5 {
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
left: 22.5%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #f2711f;
|
||||
}
|
||||
|
||||
.num6 {
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
left: 30%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #2a46f9;
|
||||
}
|
||||
|
||||
.num7 {
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
left: 37.5%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #00a3fd;
|
||||
}
|
||||
|
||||
.num8 {
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
left: 45%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #eff721;
|
||||
}
|
||||
|
||||
.title1 {
|
||||
position: absolute;
|
||||
top: 28%;
|
||||
left: 18%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #62bff2;
|
||||
}
|
||||
|
||||
.title2 {
|
||||
position: absolute;
|
||||
top: 28%;
|
||||
left: 33%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 2vw;
|
||||
color: #62bff2;
|
||||
}
|
||||
|
||||
.title3 {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 7.5%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title4 {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 15%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title5 {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 22.5%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title6 {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 30%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title7 {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 37.5%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title8 {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 45%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title9 {
|
||||
position: absolute;
|
||||
top: 61%;
|
||||
left: 26.1%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title10 {
|
||||
position: absolute;
|
||||
top: 13%;
|
||||
left: 74.3%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.table1 {
|
||||
position: absolute;
|
||||
top: 63%;
|
||||
left: 3.5%;
|
||||
width: 45.4%;
|
||||
height: 32%;
|
||||
}
|
||||
|
||||
.scrollTable {
|
||||
color: rgb(185, 186, 192);
|
||||
margin: auto 0px;
|
||||
padding: 4px 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: absolute;
|
||||
top: 16%;
|
||||
left: 52%;
|
||||
width: 44.8%;
|
||||
height: 80%;
|
||||
|
||||
.item {
|
||||
width: 22vw;
|
||||
height: 37vh;
|
||||
position: relative;
|
||||
border: 1px solid #1ea6ec;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.titleBg {
|
||||
position: absolute;
|
||||
top: 0%;
|
||||
left: 0%;
|
||||
width: 100%;
|
||||
height: 10%;
|
||||
background-color: #063b5a;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
top: 5%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #fff9f6;
|
||||
font-size: 0.9vw;
|
||||
|
||||
.el-tag.el-tag--success {
|
||||
vertical-align: top !important;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
background-image: url("~@/assets/board/standard/device.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 90%;
|
||||
top: 10%;
|
||||
}
|
||||
|
||||
}
|
||||
.pagination{
|
||||
position: relative;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: inline-block;
|
||||
.el-pagination{
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|