2548 lines
90 KiB
Vue
2548 lines
90 KiB
Vue
|
|
<template>
|
|||
|
|
<div style="padding: 10px; background-color: #f8f8f8">
|
|||
|
|
<!-- 天气以及设备统计信息 -->
|
|||
|
|
<el-row :gutter="20" style="margin: 10px 0px 20px 0px">
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
|
|||
|
|
<!-- 天气 -->
|
|||
|
|
<el-card
|
|||
|
|
class="weather-card"
|
|||
|
|
shadow="hover"
|
|||
|
|
:style="{
|
|||
|
|
'--background-start': getBackgroundColor(weatherData.data.type).start,
|
|||
|
|
'--background-end': getBackgroundColor(weatherData.data.type).end,
|
|||
|
|
}"
|
|||
|
|
>
|
|||
|
|
<!-- 头部:城市名称、日期与星期 -->
|
|||
|
|
<div class="weather-header">
|
|||
|
|
<h2>{{ weatherData.city }}</h2>
|
|||
|
|
<div class="date-week">
|
|||
|
|
<span>{{ weatherData.data.date }}</span>
|
|||
|
|
<span>{{ weatherData.data.week }}</span>
|
|||
|
|
</div>
|
|||
|
|
<p class="weather-description">{{ weatherData.data.type }}</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 主体:天气图标与温度 -->
|
|||
|
|
<div class="weather-main">
|
|||
|
|
<img :src="weatherData.data.typeIcon" alt="天气图标" class="weather-icon" />
|
|||
|
|
<div class="temperature">{{ weatherData.data.low }} - {{ weatherData.data.high }}</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 详情信息:风向、风力 -->
|
|||
|
|
<div class="weather-details">
|
|||
|
|
<div class="detail-item">
|
|||
|
|
<i class="el-icon-cloudy-and-sunny"></i>
|
|||
|
|
<span class="detail-text">{{ weatherData.data.fengxiang }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="detail-item">
|
|||
|
|
<i class="el-icon-s-operation"></i>
|
|||
|
|
<span class="detail-text">{{ weatherData.data.fengli }}</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 空气质量信息 -->
|
|||
|
|
<div class="air-quality">
|
|||
|
|
<div class="aqi-info">
|
|||
|
|
<span class="aqi-value" :class="aqiClass">空气质量</span>
|
|||
|
|
<span class="aqi-level" :class="aqiClass">{{ weatherData.air.aqi }}</span>
|
|||
|
|
<span class="aqi-level">{{ weatherData.air.aqi_name }}</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 天气提示 -->
|
|||
|
|
<div class="weather-tip">
|
|||
|
|
<i class="el-icon-info"></i>
|
|||
|
|
<span>{{ weatherData.tip }}</span>
|
|||
|
|
</div>
|
|||
|
|
</el-card>
|
|||
|
|
</el-col>
|
|||
|
|
<!-- 设备统计 -->
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="10">
|
|||
|
|
<el-row :gutter="20" style="height: 420px">
|
|||
|
|
<el-col :span="8" style="margin-bottom: 20px">
|
|||
|
|
<!-- 设备数量 -->
|
|||
|
|
<div class="card-panel" style="background: linear-gradient(135deg, #f0fff0 0%, #f5fffa 100%)">
|
|||
|
|
<div class="card-content device">
|
|||
|
|
<div class="card-icon">
|
|||
|
|
<svg-icon icon-class="device" class-name="card-panel-icon" />
|
|||
|
|
</div>
|
|||
|
|
<div class="card-data">
|
|||
|
|
<div class="card-title">{{ $t('home.number') }}</div>
|
|||
|
|
<count-to :start-val="0" :end-val="deviceStatistic.deviceCount" :duration="3000" class="card-panel-num" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
<el-col :span="8" style="margin-bottom: 20px">
|
|||
|
|
<!-- 产品数量 -->
|
|||
|
|
|
|||
|
|
<div class="card-panel" style="background: linear-gradient(135deg, #fffaf0 0%, #fff0f5 100%)">
|
|||
|
|
<div class="card-content product">
|
|||
|
|
<div class="card-icon">
|
|||
|
|
<svg-icon icon-class="model" class-name="card-panel-icon" />
|
|||
|
|
</div>
|
|||
|
|
<div class="card-data">
|
|||
|
|
<div class="card-title">{{ $t('home.product') }}</div>
|
|||
|
|
<count-to :start-val="0" :end-val="deviceStatistic.productCount" :duration="3000" class="card-panel-num" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
<el-col :span="8" style="margin-bottom: 20px">
|
|||
|
|
<!-- 操作记录 -->
|
|||
|
|
<div class="card-panel" style="background: linear-gradient(135deg, #fffef3 0%, #fffdf0 100%)">
|
|||
|
|
<div class="card-content function">
|
|||
|
|
<div class="card-icon">
|
|||
|
|
<svg-icon icon-class="log-a" class-name="card-panel-icon" />
|
|||
|
|
</div>
|
|||
|
|
<div class="card-data">
|
|||
|
|
<div class="card-title">{{ $t('home.records') }}</div>
|
|||
|
|
|
|||
|
|
<count-to :start-val="0" :end-val="deviceStatistic.functionCount" :duration="3000" class="card-panel-num" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
<el-col :span="8">
|
|||
|
|
<!-- 监测数据 -->
|
|||
|
|
<div class="card-panel" style="background: linear-gradient(135deg, #e3f2fd 0%, #e1f5fe 100%)">
|
|||
|
|
<div class="card-content monitor">
|
|||
|
|
<div class="card-icon">
|
|||
|
|
<svg-icon icon-class="monitor-a" class-name="card-panel-icon" />
|
|||
|
|
</div>
|
|||
|
|
<div class="card-data">
|
|||
|
|
<div class="card-title">{{ $t('home.monitoring') }}</div>
|
|||
|
|
|
|||
|
|
<count-to :start-val="0" :end-val="deviceStatistic.monitorCount" :duration="3000" class="card-panel-num" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
<el-col :span="8">
|
|||
|
|
<!-- 告警数量 -->
|
|||
|
|
<div class="card-panel" style="background: linear-gradient(135deg, #f0e7ff 0%, #f6f0ff 100%)">
|
|||
|
|
<div class="card-content alert">
|
|||
|
|
<div class="card-icon">
|
|||
|
|
<svg-icon icon-class="alert" class-name="card-panel-icon" />
|
|||
|
|
</div>
|
|||
|
|
<div class="card-data">
|
|||
|
|
<div class="card-title">{{ $t('home.alarm') }}</div>
|
|||
|
|
|
|||
|
|
<count-to :start-val="0" :end-val="deviceStatistic.alertCount" :duration="3000" class="card-panel-num" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
<el-col :span="8">
|
|||
|
|
<!-- 上报事件 -->
|
|||
|
|
<div class="card-panel" style="background: linear-gradient(135deg, #f3f9ec 0%, #edfaea 100%)">
|
|||
|
|
<div class="card-content reports">
|
|||
|
|
<div class="card-icon">
|
|||
|
|
<svg-icon icon-class="event-a" class-name="card-panel-icon" />
|
|||
|
|
</div>
|
|||
|
|
<div class="card-data">
|
|||
|
|
<div class="card-title">{{ $t('home.reports') }}</div>
|
|||
|
|
<count-to :start-val="0" :end-val="deviceStatistic.eventCount" :duration="3000" class="card-panel-num" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
</el-row>
|
|||
|
|
|
|||
|
|
<!-- 统计信息 -->
|
|||
|
|
<!-- <el-card shadow="none" style="height: 220px; background-color: #ccc; margin-bottom: 10px"></el-card>
|
|||
|
|
<el-card shadow="none" style="height: 220px; background-color: #ccc"></el-card> -->
|
|||
|
|
</el-col>
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
|
|||
|
|
<!-- 一个折线图 -->
|
|||
|
|
|
|||
|
|
<el-card class="line-card" shadow="hover">
|
|||
|
|
<div ref="line" style="height: 400px; width: 100%"></div>
|
|||
|
|
</el-card>
|
|||
|
|
</el-col>
|
|||
|
|
</el-row>
|
|||
|
|
|
|||
|
|
<el-row :gutter="20" style="margin: 10px 0px 20px 0px">
|
|||
|
|
<!-- 地图部分 -->
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16">
|
|||
|
|
<div class="map-card" shadow="hover">
|
|||
|
|
<div class="map-container">
|
|||
|
|
<div ref="map" class="map"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
|
|||
|
|
<!-- mqtt状态数据 -->
|
|||
|
|
<div class="card-container">
|
|||
|
|
<div ref="statsChart" style="height: 240px; width: 100%"></div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
</el-row>
|
|||
|
|
|
|||
|
|
<el-card class="rate" shadow="hover" style="margin: 10px 10px 20px 10px">
|
|||
|
|
<el-row :gutter="80" v-if="isAdmin">
|
|||
|
|
<!-- cpu使用率 -->
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="12">
|
|||
|
|
<div style="">
|
|||
|
|
<div ref="pieCpu" class="pieCpu"></div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
<!-- 内存使用率 -->
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="5" :xl="6">
|
|||
|
|
<div style="">
|
|||
|
|
<div ref="pieMemery" style="height: 161px"></div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
<!-- 系统盘使用率 -->
|
|||
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="5" :xl="6">
|
|||
|
|
<div style="">
|
|||
|
|
<div ref="pieDisk" style="height: 161px"></div>
|
|||
|
|
</div>
|
|||
|
|
</el-col>
|
|||
|
|
</el-row>
|
|||
|
|
</el-card>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import axios from 'axios';
|
|||
|
|
import { getDeviceStatistic } from '@/api/iot/device';
|
|||
|
|
import { listNotice, getNotice } from '@/api/system/notice';
|
|||
|
|
import CountTo from 'vue-count-to';
|
|||
|
|
import { loadBMap } from '@/utils/map.js';
|
|||
|
|
//安装的是echarts完整包,里面包含百度地图扩展,路径为 echarts/extension/bmap/bmap.js,将其引入
|
|||
|
|
//ECharts的百度地图扩展,可以在百度地图上展现点图,线图,热力图等可视化
|
|||
|
|
require('echarts/extension/bmap/bmap');
|
|||
|
|
import { getServer } from '@/api/monitor/server';
|
|||
|
|
import { listAllDeviceShort } from '@/api/iot/device';
|
|||
|
|
import 'echarts-liquidfill';
|
|||
|
|
import { color, time } from 'echarts';
|
|||
|
|
import { searchUserCount } from '@/api/monitor/jobLog';
|
|||
|
|
import { getNettyMqttStats, statisticNettyMqtt } from '@/api/iot/netty';
|
|||
|
|
// import { count } from 'echarts/types/src/component/dataZoom/history.js';
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
name: 'Index',
|
|||
|
|
components: {
|
|||
|
|
CountTo,
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
//天气信息
|
|||
|
|
weatherData: {
|
|||
|
|
success: true,
|
|||
|
|
city: '北京市',
|
|||
|
|
data: {
|
|||
|
|
date: '2024-03-14',
|
|||
|
|
week: '星期四',
|
|||
|
|
type: '晴',
|
|||
|
|
typeIcon: require('../../src/assets/icons/qing.png'), // 确保路径正确
|
|||
|
|
low: '5°C',
|
|||
|
|
high: '21°C',
|
|||
|
|
fengxiang: '西南风',
|
|||
|
|
fengli: '3-4级',
|
|||
|
|
},
|
|||
|
|
air: {
|
|||
|
|
aqi: 85,
|
|||
|
|
aqi_level: 2,
|
|||
|
|
aqi_name: '良',
|
|||
|
|
},
|
|||
|
|
tip: '天有点冷,注意保暖~',
|
|||
|
|
},
|
|||
|
|
// mqtt状态数据
|
|||
|
|
stats: {},
|
|||
|
|
// mqtt统计信息
|
|||
|
|
static: {},
|
|||
|
|
// 折线图信息
|
|||
|
|
linechart: {
|
|||
|
|
date: [],
|
|||
|
|
counts: [],
|
|||
|
|
},
|
|||
|
|
// 遮罩层
|
|||
|
|
loading: true,
|
|||
|
|
// 是否显示弹出层
|
|||
|
|
open: false,
|
|||
|
|
// 信息列表
|
|||
|
|
noticeList: [],
|
|||
|
|
// 信息详情
|
|||
|
|
notice: {},
|
|||
|
|
// 是否为管理员
|
|||
|
|
isAdmin: false,
|
|||
|
|
// 设备列表
|
|||
|
|
deviceList: [],
|
|||
|
|
// 设备统计信息
|
|||
|
|
deviceStatistic: {},
|
|||
|
|
// 设备总数
|
|||
|
|
deviceCount: 0,
|
|||
|
|
// 版本号
|
|||
|
|
version: '3.8.0',
|
|||
|
|
animate: true,
|
|||
|
|
duration: 10, // 公告滚动一次的时长(单位:秒)
|
|||
|
|
interval: 2000, // 公告间隔时间(单位:毫秒)
|
|||
|
|
// 服务器信息
|
|||
|
|
server: {
|
|||
|
|
jvm: {
|
|||
|
|
name: '',
|
|||
|
|
version: '',
|
|||
|
|
startTime: '',
|
|||
|
|
runTime: '',
|
|||
|
|
used: '',
|
|||
|
|
total: 100,
|
|||
|
|
},
|
|||
|
|
sys: {
|
|||
|
|
computerName: '',
|
|||
|
|
osName: '',
|
|||
|
|
computerIp: '',
|
|||
|
|
osArch: '',
|
|||
|
|
},
|
|||
|
|
cpu: {
|
|||
|
|
cpuNum: 1,
|
|||
|
|
},
|
|||
|
|
mem: {
|
|||
|
|
total: 2,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
tableData: [],
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
computed: {
|
|||
|
|
aqiClass() {
|
|||
|
|
switch (this.weatherData.air.aqi_level) {
|
|||
|
|
case 1:
|
|||
|
|
return 'aqi-good';
|
|||
|
|
case 2:
|
|||
|
|
return 'aqi-moderate';
|
|||
|
|
case 3:
|
|||
|
|
return 'aqi-unhealthy';
|
|||
|
|
default:
|
|||
|
|
return '';
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
mounted() {
|
|||
|
|
this.startScroll();
|
|||
|
|
},
|
|||
|
|
beforeDestroy() {
|
|||
|
|
this.stopScroll();
|
|||
|
|
},
|
|||
|
|
created() {
|
|||
|
|
this.init();
|
|||
|
|
this.getAllDevice();
|
|||
|
|
this.getNoticeList();
|
|||
|
|
this.getDeviceStatistic();
|
|||
|
|
this.fetchWeather();
|
|||
|
|
|
|||
|
|
this.getMqttStats();
|
|||
|
|
this.statisticMqtt();
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
// 公告栏滚动
|
|||
|
|
startScroll() {
|
|||
|
|
this.intervalId = setInterval(() => {
|
|||
|
|
const firstNotice = this.noticeList.shift();
|
|||
|
|
this.noticeList.push(firstNotice);
|
|||
|
|
}, this.interval);
|
|||
|
|
},
|
|||
|
|
stopScroll() {
|
|||
|
|
if (this.intervalId) {
|
|||
|
|
clearInterval(this.intervalId);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
// 折线图
|
|||
|
|
getChartData() {
|
|||
|
|
searchUserCount().then((response) => {
|
|||
|
|
console.log('折线图信息', response);
|
|||
|
|
response.data.reverse().forEach((item) => {
|
|||
|
|
this.linechart.date.push(item.datetime);
|
|||
|
|
this.linechart.counts.push(item.user_count);
|
|||
|
|
});
|
|||
|
|
console.log('折线图数据', this.linechart);
|
|||
|
|
this.drawLine();
|
|||
|
|
|
|||
|
|
// this.responseData.data.forEach(item => {
|
|||
|
|
// this.chartData.xAxisData.push(item.datetime);
|
|||
|
|
// this.chartData.yAxisData.push(item.user_count);
|
|||
|
|
//});
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
// mqtt统计数据
|
|||
|
|
statisticMqtt() {
|
|||
|
|
statisticNettyMqtt().then((response) => {
|
|||
|
|
this.static = response.data;
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
/** 查询mqtt状态数据*/
|
|||
|
|
getMqttStats() {
|
|||
|
|
getNettyMqttStats().then((response) => {
|
|||
|
|
this.stats = response.data;
|
|||
|
|
this.drawStats();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
// 绘制柱状图
|
|||
|
|
drawStats() {
|
|||
|
|
// 基于准备好的dom,初始化echarts实例
|
|||
|
|
let myChart = this.$echarts.init(this.$refs.statsChart);
|
|||
|
|
var option;
|
|||
|
|
|
|||
|
|
option = {
|
|||
|
|
title: {
|
|||
|
|
text: this.$t('netty.mqtt.564432-12'),
|
|||
|
|
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 19,
|
|||
|
|
color: '#4A4A4A',
|
|||
|
|
fontWeight: 'bold',
|
|||
|
|
fontFamily: 'Arial, sans-serif', // 现代字体
|
|||
|
|
},
|
|||
|
|
left: 'left',
|
|||
|
|
top: '5%',
|
|||
|
|
},
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: 'item',
|
|||
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)', // 更加柔和的背景
|
|||
|
|
borderColor: '#FF6F61', // 边框颜色
|
|||
|
|
borderWidth: 1,
|
|||
|
|
textStyle: {
|
|||
|
|
color: '#333', // 文字颜色
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
legend: {
|
|||
|
|
textStyle: {
|
|||
|
|
color: '#4A4A4A',
|
|||
|
|
fontFamily: 'Arial, sans-serif',
|
|||
|
|
},
|
|||
|
|
orient: 'vertical',
|
|||
|
|
right: '10%',
|
|||
|
|
top: '15%',
|
|||
|
|
itemGap: 10, // 图例之间的间距
|
|||
|
|
},
|
|||
|
|
grid: {
|
|||
|
|
left: '10%',
|
|||
|
|
right: '10%',
|
|||
|
|
bottom: '10%',
|
|||
|
|
containLabel: true,
|
|||
|
|
},
|
|||
|
|
xAxis: {
|
|||
|
|
type: 'value',
|
|||
|
|
axisLine: {
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#B0BEC5', // 和谐的轴线颜色
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
splitNumber: 3,
|
|||
|
|
splitLine: {
|
|||
|
|
lineStyle: {
|
|||
|
|
type: 'dashed',
|
|||
|
|
color: '#E0E0E0',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
yAxis: {
|
|||
|
|
type: 'category',
|
|||
|
|
axisLabel: {
|
|||
|
|
fontSize: 14,
|
|||
|
|
color: '#455A64', // 标签颜色
|
|||
|
|
fontFamily: 'Arial, sans-serif', // 现代字体
|
|||
|
|
},
|
|||
|
|
splitNumber: 3,
|
|||
|
|
axisLine: {
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#B0BEC5',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
data: [this.$t('netty.mqtt.564432-13'), this.$t('netty.mqtt.564432-14'), this.$t('netty.mqtt.564432-15'), this.$t('netty.mqtt.564432-16'), this.$t('netty.mqtt.564432-17')],
|
|||
|
|
},
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
name: this.$t('netty.mqtt.564432-18'),
|
|||
|
|
type: 'bar',
|
|||
|
|
data: [this.stats['connection_count'], this.stats['session_count'], this.stats['subscription_count'], this.stats['retain_count'], this.stats['retain_count']],
|
|||
|
|
itemStyle: {
|
|||
|
|
color: new this.$echarts.graphic.LinearGradient(
|
|||
|
|
0,
|
|||
|
|
0,
|
|||
|
|
1,
|
|||
|
|
0, // 横向渐变
|
|||
|
|
[
|
|||
|
|
{ offset: 0, color: '#FFE3E3' }, // 更加浅的粉色
|
|||
|
|
{ offset: 1, color: '#FFD1D1' }, // 更加柔和的粉色
|
|||
|
|
]
|
|||
|
|
),
|
|||
|
|
borderRadius: [20, 20, 20, 20], // 圆角柱子
|
|||
|
|
shadowColor: 'rgba(255, 105, 180, 0.5)', // 柔和的阴影
|
|||
|
|
shadowBlur: 10, // 阴影模糊度
|
|||
|
|
shadowOffsetX: 5, // 阴影偏移
|
|||
|
|
shadowOffsetY: 5, // 阴影偏移
|
|||
|
|
},
|
|||
|
|
globalCoord: false, // 缺省为 false
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: this.$t('netty.mqtt.564432-19'),
|
|||
|
|
type: 'bar',
|
|||
|
|
data: [this.stats['connection_total'], this.stats['session_total'], this.stats['subscription_total'], this.stats['retain_total'], this.stats['retain_total']],
|
|||
|
|
itemStyle: {
|
|||
|
|
color: new this.$echarts.graphic.LinearGradient(
|
|||
|
|
0,
|
|||
|
|
0,
|
|||
|
|
1,
|
|||
|
|
0, // 横向渐变
|
|||
|
|
[
|
|||
|
|
{ offset: 0, color: '#85E3FF' }, // 清新的蓝色
|
|||
|
|
{ offset: 1, color: '#B9FBC0' }, // 更加柔和的绿色
|
|||
|
|
]
|
|||
|
|
),
|
|||
|
|
borderRadius: [20, 20, 20, 20], // 圆角柱子
|
|||
|
|
shadowColor: 'rgba(0, 191, 255, 0.5)', // 柔和的阴影
|
|||
|
|
shadowBlur: 10, // 阴影模糊度
|
|||
|
|
shadowOffsetX: 5, // 阴影偏移
|
|||
|
|
shadowOffsetY: 5, // 阴影偏移
|
|||
|
|
},
|
|||
|
|
globalCoord: false, // 缺省为 false
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
option && myChart.setOption(option);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 天气
|
|||
|
|
async fetchWeather() {
|
|||
|
|
this.isLoading = true;
|
|||
|
|
this.error = null;
|
|||
|
|
try {
|
|||
|
|
const response = await axios.get('https://api.vvhan.com/api/weather');
|
|||
|
|
if (response.data && response.data.success) {
|
|||
|
|
console.log(response.data);
|
|||
|
|
this.weatherData = {
|
|||
|
|
success: true,
|
|||
|
|
city: response.data.city,
|
|||
|
|
data: {
|
|||
|
|
date: response.data.data.date,
|
|||
|
|
week: response.data.data.week,
|
|||
|
|
type: response.data.data.type,
|
|||
|
|
typeIcon: this.getTypeIcon(response.data.data.type),
|
|||
|
|
low: response.data.data.low,
|
|||
|
|
high: response.data.data.high,
|
|||
|
|
fengxiang: response.data.data.fengxiang,
|
|||
|
|
fengli: response.data.data.fengli,
|
|||
|
|
night: {
|
|||
|
|
type: response.data.data.night.type,
|
|||
|
|
fengxiang: response.data.data.night.fengxiang,
|
|||
|
|
fengli: response.data.data.night.fengli,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
air: {
|
|||
|
|
aqi: response.data.air.aqi,
|
|||
|
|
aqi_level: response.data.air.aqi_level,
|
|||
|
|
aqi_name: response.data.air.aqi_name,
|
|||
|
|
co: response.data.air.co,
|
|||
|
|
no2: response.data.air.no2,
|
|||
|
|
o3: response.data.air.o3,
|
|||
|
|
pm10: response.data.air.pm10,
|
|||
|
|
pm2_5: response.data.air.pm2_5,
|
|||
|
|
so2: response.data.air.so2,
|
|||
|
|
},
|
|||
|
|
tip: response.data.tip,
|
|||
|
|
};
|
|||
|
|
// 动态设置背景颜色
|
|||
|
|
const background = this.getBackgroundColor(response.data.data.type);
|
|||
|
|
document.documentElement.style.setProperty('--background-start', background.start);
|
|||
|
|
document.documentElement.style.setProperty('--background-end', background.end);
|
|||
|
|
} else {
|
|||
|
|
this.error = '获取天气数据失败,请稍后重试。';
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
console.error(err);
|
|||
|
|
this.error = '无法连接到天气服务,请检查网络或稍后再试。';
|
|||
|
|
} finally {
|
|||
|
|
this.isLoading = false;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
getBackgroundColor(type) {
|
|||
|
|
const backgrounds = {
|
|||
|
|
晴: {
|
|||
|
|
start: '#FFF0C1', // 浅黄色(柔和的阳光色)
|
|||
|
|
end: '#FFD1D1', // 柔和的粉色(温暖可爱)
|
|||
|
|
},
|
|||
|
|
多云: {
|
|||
|
|
start: '#F3F6FF', // 极浅的柔和蓝色
|
|||
|
|
end: '#DCE6FA', // 柔和的蓝灰色(轻盈的云朵感)
|
|||
|
|
},
|
|||
|
|
阴: {
|
|||
|
|
start: '#F5F5F5', // 近乎白色的浅灰色
|
|||
|
|
end: '#D3D3D3', // 柔和的浅灰色(朦胧感)
|
|||
|
|
},
|
|||
|
|
小雨: {
|
|||
|
|
start: '#D8F0FF', // 非常柔和的浅蓝色(水滴感)
|
|||
|
|
end: '#BCE0FF', // 更加可爱的浅蓝色
|
|||
|
|
},
|
|||
|
|
中雨: {
|
|||
|
|
start: '#C4DFFF', // 轻柔的灰蓝色
|
|||
|
|
end: '#A1C4F8', // 带点温柔感的蓝色
|
|||
|
|
},
|
|||
|
|
大雨: {
|
|||
|
|
start: '#A8E3FF', // 清新的浅蓝色
|
|||
|
|
end: '#8CCFFF', // 柔和的蓝色渐变
|
|||
|
|
},
|
|||
|
|
雷阵雨: {
|
|||
|
|
start: '#F2E7FF', // 柔和的浅紫色(雷电的闪烁感)
|
|||
|
|
end: '#C2C2C2', // 柔和的灰色(符合雷阵雨的阴沉感)
|
|||
|
|
},
|
|||
|
|
暴雨: {
|
|||
|
|
start: '#D8F0FF', // 非常柔和的浅蓝色(水滴感)
|
|||
|
|
end: '#C2C2C2', // 柔和的灰色
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
return backgrounds[type] || { start: '#F5F9FF', end: '#FBFBFD' }; // 默认柔和的蓝白色背景
|
|||
|
|
},
|
|||
|
|
getTypeIcon(type) {
|
|||
|
|
console.log(type);
|
|||
|
|
// 根据天气类型返回对应的图标路径
|
|||
|
|
const icons = {
|
|||
|
|
晴: require('../../src/assets/icons/qing.png'),
|
|||
|
|
多云: require('../../src/assets/icons/duoyun.png'),
|
|||
|
|
阴: require('../../src/assets/icons/yin.png'),
|
|||
|
|
小雨: require('../../src/assets/icons/xiaoyu.png'),
|
|||
|
|
中雨: require('../../src/assets/icons/zhongyu.png'),
|
|||
|
|
大雨: require('../../src/assets/icons/dayu.png'),
|
|||
|
|
雷阵雨: require('../../src/assets/icons/leizhenyu.png'),
|
|||
|
|
暴雨: require('../../src/assets/icons/dayu.png'),
|
|||
|
|
// 添加更多天气类型和对应图标
|
|||
|
|
};
|
|||
|
|
return icons[type] || require('../../src/assets/icons/qing.png');
|
|||
|
|
},
|
|||
|
|
init() {
|
|||
|
|
if (this.$store.state.user.roles.indexOf('tenant') === -1 && this.$store.state.user.roles.indexOf('general') === -1) {
|
|||
|
|
this.isAdmin = true;
|
|||
|
|
this.getServer();
|
|||
|
|
this.getChartData();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
//刷新iframe
|
|||
|
|
flushIframe() {
|
|||
|
|
var iframe = window.parent.document.getElementById('iframe');
|
|||
|
|
iframe.contentWindow.location.reload(true);
|
|||
|
|
},
|
|||
|
|
/** 查询设备统计信息 */
|
|||
|
|
getDeviceStatistic() {
|
|||
|
|
getDeviceStatistic().then((response) => {
|
|||
|
|
this.deviceStatistic = response.data;
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
/** 查询公告列表 */
|
|||
|
|
getNoticeList() {
|
|||
|
|
let queryParams = {
|
|||
|
|
pageNum: 1,
|
|||
|
|
pageSize: 6,
|
|||
|
|
};
|
|||
|
|
listNotice(queryParams).then((response) => {
|
|||
|
|
this.noticeList = response.rows.splice(0, 6);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
// 打开信息详情
|
|||
|
|
openDetail(id) {
|
|||
|
|
this.open = true;
|
|||
|
|
this.loading = true;
|
|||
|
|
getNotice(id).then((response) => {
|
|||
|
|
this.notice = response.data;
|
|||
|
|
this.open = true;
|
|||
|
|
this.loading = false;
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
// 取消按钮
|
|||
|
|
closeDetail() {
|
|||
|
|
this.title = '';
|
|||
|
|
this.open = false;
|
|||
|
|
},
|
|||
|
|
/**查询所有设备 */
|
|||
|
|
getAllDevice() {
|
|||
|
|
listAllDeviceShort(this.queryParams).then((response) => {
|
|||
|
|
this.deviceList = response.rows;
|
|||
|
|
this.deviceCount = response.total;
|
|||
|
|
this.loadMap();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
/**加载地图*/
|
|||
|
|
loadMap() {
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
loadBMap().then(() => {
|
|||
|
|
this.getmap();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
/** 查询服务器信息 */
|
|||
|
|
getServer() {
|
|||
|
|
getServer().then((response) => {
|
|||
|
|
this.server = response.data;
|
|||
|
|
console.log(response.data);
|
|||
|
|
this.tableData = [
|
|||
|
|
{
|
|||
|
|
server: this.$t('home.serverName'),
|
|||
|
|
serverContent: this.server.sys.computerName,
|
|||
|
|
java: this.$t('home.javaName'),
|
|||
|
|
javaContent: this.server.jvm.name,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
server: this.$t('home.serverIp'),
|
|||
|
|
serverContent: this.server.sys.computerIp,
|
|||
|
|
java: this.$t('home.startTime'),
|
|||
|
|
javaContent: this.server.jvm.startTime,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
server: this.$t('home.system'),
|
|||
|
|
serverContent: this.server.sys.osName,
|
|||
|
|
java: this.$t('home.javaVer'),
|
|||
|
|
javaContent: this.server.jvm.version,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
server: this.$t('home.architecture'),
|
|||
|
|
serverContent: this.server.sys.osArch,
|
|||
|
|
java: this.$t('home.runtime'),
|
|||
|
|
javaContent: this.server.jvm.runTime,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
server: this.$t('home.core'),
|
|||
|
|
serverContent: this.server.cpu.cpuNum,
|
|||
|
|
java: this.$t('home.memory'),
|
|||
|
|
javaContent: this.server.jvm.used,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
server: this.$t('home.size'),
|
|||
|
|
serverContent: this.server.mem.total,
|
|||
|
|
java: this.$t('home.JVM'),
|
|||
|
|
javaContent: this.server.jvm.total,
|
|||
|
|
},
|
|||
|
|
];
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
this.drawPieCpu();
|
|||
|
|
this.drawPieMemery();
|
|||
|
|
this.drawPieDisk();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/** 地图 */
|
|||
|
|
getmap() {
|
|||
|
|
var myChart = this.$echarts.init(this.$refs.map);
|
|||
|
|
var option;
|
|||
|
|
|
|||
|
|
// 单击事件
|
|||
|
|
myChart.on('click', (params) => {
|
|||
|
|
if (params.data.deviceId) {
|
|||
|
|
this.$router.push({
|
|||
|
|
path: '/iot/device-edit',
|
|||
|
|
query: {
|
|||
|
|
t: Date.now(),
|
|||
|
|
deviceId: params.data.deviceId,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 格式化数据
|
|||
|
|
let convertData = function (data, status) {
|
|||
|
|
var res = [];
|
|||
|
|
for (var i = 0; i < data.length; i++) {
|
|||
|
|
var geoCoord = [data[i].longitude, data[i].latitude];
|
|||
|
|
if (geoCoord && data[i].status == status) {
|
|||
|
|
res.push({
|
|||
|
|
name: data[i].deviceName,
|
|||
|
|
value: geoCoord,
|
|||
|
|
status: data[i].status,
|
|||
|
|
isShadow: data[i].isShadow,
|
|||
|
|
firmwareVersion: data[i].firmwareVersion,
|
|||
|
|
networkAddress: data[i].networkAddress,
|
|||
|
|
productName: data[i].productName,
|
|||
|
|
activeTime: data[i].activeTime == null ? '' : data[i].activeTime,
|
|||
|
|
deviceId: data[i].deviceId,
|
|||
|
|
serialNumber: data[i].serialNumber,
|
|||
|
|
locationWay: data[i].locationWay,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return res;
|
|||
|
|
};
|
|||
|
|
option = {
|
|||
|
|
title: {
|
|||
|
|
text: this.$t('home.onlineDevice') + this.deviceList.filter((x) => x.status == 3).length + ')',
|
|||
|
|
subtext: 'Lidee open source iot platform',
|
|||
|
|
sublink: 'https://iot.lidee.cn',
|
|||
|
|
target: '_blank',
|
|||
|
|
textStyle: {
|
|||
|
|
color: '#333',
|
|||
|
|
textBorderColor: '#fff',
|
|||
|
|
textBorderWidth: 10,
|
|||
|
|
},
|
|||
|
|
top: 10,
|
|||
|
|
left: 'center',
|
|||
|
|
},
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: 'item',
|
|||
|
|
formatter: function (params) {
|
|||
|
|
var htmlStr = '<div style="padding:5px;line-height:28px;">';
|
|||
|
|
htmlStr += "设备名称: <span style='color:#409EFF'>" + params.data.name + '</span><br />';
|
|||
|
|
htmlStr += '设备编号: ' + params.data.serialNumber + '<br />';
|
|||
|
|
htmlStr += '设备状态: ';
|
|||
|
|
if (params.data.status == 1) {
|
|||
|
|
htmlStr += "<span style='color:#E6A23C'>未激活</span>" + '<br />';
|
|||
|
|
} else if (params.data.status == 2) {
|
|||
|
|
htmlStr += "<span style='color:#F56C6C'>禁用</span>" + '<br />';
|
|||
|
|
} else if (params.data.status == 3) {
|
|||
|
|
htmlStr += "<span style='color:#67C23A'>在线</span>" + '<br />';
|
|||
|
|
} else if (params.data.status == 4) {
|
|||
|
|
htmlStr += "<span style='color:#909399'>离线</span>" + '<br />';
|
|||
|
|
}
|
|||
|
|
if (params.data.isShadow == 1) {
|
|||
|
|
htmlStr += '设备影子: ' + "<span style='color:#67C23A'>启用</span>" + '<br />';
|
|||
|
|
} else {
|
|||
|
|
htmlStr += '设备影子: ' + "<span style='color:#909399'>未启用</span>" + '<br />';
|
|||
|
|
}
|
|||
|
|
htmlStr += '产品名称: ' + params.data.productName + '<br />';
|
|||
|
|
htmlStr += '固件版本: Version ' + params.data.firmwareVersion + '<br />';
|
|||
|
|
htmlStr += '激活时间: ' + params.data.activeTime + '<br />';
|
|||
|
|
htmlStr += '定位方式: ';
|
|||
|
|
if (params.data.locationWay == 1) {
|
|||
|
|
htmlStr += '自动定位' + '<br />';
|
|||
|
|
} else if (params.data.locationWay == 2) {
|
|||
|
|
htmlStr += '设备定位' + '<br />';
|
|||
|
|
} else if (params.data.locationWay == 3) {
|
|||
|
|
htmlStr += '自定义位置' + '<br />';
|
|||
|
|
} else {
|
|||
|
|
htmlStr += '未知' + '<br />';
|
|||
|
|
}
|
|||
|
|
htmlStr += '所在地址: ' + params.data.networkAddress + '<br />';
|
|||
|
|
htmlStr += '</div>';
|
|||
|
|
return htmlStr;
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
bmap: {
|
|||
|
|
center: [133, 38],
|
|||
|
|
zoom: 5,
|
|||
|
|
roam: true,
|
|||
|
|
mapStyle: {
|
|||
|
|
styleJson: [
|
|||
|
|
{
|
|||
|
|
featureType: 'water',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#a0cfff',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'land',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#fafafa', // #fffff8 淡黄色
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'railway',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
visibility: 'off',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'highway',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#fdfdfd',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'highway',
|
|||
|
|
elementType: 'labels',
|
|||
|
|
stylers: {
|
|||
|
|
visibility: 'off',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'arterial',
|
|||
|
|
elementType: 'geometry',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#fefefe',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'arterial',
|
|||
|
|
elementType: 'geometry.fill',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#fefefe',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'poi',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
visibility: 'off',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'green',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
visibility: 'off',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'subway',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
visibility: 'off',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'manmade',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#d1d1d1',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'local',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#d1d1d1',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'arterial',
|
|||
|
|
elementType: 'labels',
|
|||
|
|
stylers: {
|
|||
|
|
visibility: 'off',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'boundary',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#999999',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'building',
|
|||
|
|
elementType: 'all',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#d1d1d1',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
featureType: 'label',
|
|||
|
|
elementType: 'labels.text.fill',
|
|||
|
|
stylers: {
|
|||
|
|
color: '#999999',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
type: 'scatter',
|
|||
|
|
coordinateSystem: 'bmap',
|
|||
|
|
data: convertData(this.deviceList, 1),
|
|||
|
|
symbolSize: 15,
|
|||
|
|
itemStyle: {
|
|||
|
|
color: '#E6A23C',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'scatter',
|
|||
|
|
coordinateSystem: 'bmap',
|
|||
|
|
data: convertData(this.deviceList, 2),
|
|||
|
|
symbolSize: 15,
|
|||
|
|
itemStyle: {
|
|||
|
|
color: '#F56C6C',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'scatter',
|
|||
|
|
coordinateSystem: 'bmap',
|
|||
|
|
data: convertData(this.deviceList, 4),
|
|||
|
|
symbolSize: 15,
|
|||
|
|
itemStyle: {
|
|||
|
|
color: '#909399',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'effectScatter',
|
|||
|
|
coordinateSystem: 'bmap',
|
|||
|
|
data: convertData(this.deviceList, 3),
|
|||
|
|
symbolSize: 15,
|
|||
|
|
showEffectOn: 'render',
|
|||
|
|
rippleEffect: {
|
|||
|
|
brushType: 'stroke',
|
|||
|
|
scale: 5,
|
|||
|
|
},
|
|||
|
|
label: {
|
|||
|
|
formatter: '{b}',
|
|||
|
|
position: 'right',
|
|||
|
|
show: false,
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
color: '#67C23A',
|
|||
|
|
shadowBlur: 100,
|
|||
|
|
shadowColor: '#333',
|
|||
|
|
},
|
|||
|
|
zlevel: 1,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
option && myChart.setOption(option);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
drawPieCpu() {
|
|||
|
|
// 基于准备好的dom,初始化echarts实例
|
|||
|
|
let myChart = this.$echarts.init(this.$refs.pieCpu);
|
|||
|
|
var option;
|
|||
|
|
|
|||
|
|
// 水球图
|
|||
|
|
option = {
|
|||
|
|
backgroundColor: '#fff',
|
|||
|
|
|
|||
|
|
title: {
|
|||
|
|
text: this.$t('home.usage'),
|
|||
|
|
left: 'left',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 16,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: 'item',
|
|||
|
|
formatter: '{b}: {c}',
|
|||
|
|
},
|
|||
|
|
grid: {
|
|||
|
|
left: '10%',
|
|||
|
|
right: '10%',
|
|||
|
|
top: '10%',
|
|||
|
|
bottom: '10%',
|
|||
|
|
},
|
|||
|
|
series: [
|
|||
|
|
// CPU 用户
|
|||
|
|
{
|
|||
|
|
type: 'liquidFill',
|
|||
|
|
name: this.$t('home.user'),
|
|||
|
|
radius: '85%',
|
|||
|
|
center: ['25%', '55%'],
|
|||
|
|
amplitude: 10,
|
|||
|
|
backgroundStyle: {
|
|||
|
|
borderWidth: 1,
|
|||
|
|
color: 'rgba(246, 65, 108,0.1)',
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
shadowColor: 'rgba(0, 0, 0, 0)',
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
color: [
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{ offset: 1, color: '#FFF6B7' },
|
|||
|
|
{ offset: 0, color: '#fa9eb3' },
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#FFD3A5',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#FFD3A5',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#feada6',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#f5efef',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.used / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.user'),
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.used / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.user'),
|
|||
|
|
direction: 'left',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.used / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.user'),
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
label: {
|
|||
|
|
normal: {
|
|||
|
|
formatter: (value) => {
|
|||
|
|
return (value.value * 100).toFixed(0) + '%';
|
|||
|
|
},
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 20,
|
|||
|
|
color: '#333',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
outline: {
|
|||
|
|
show: true,
|
|||
|
|
itemStyle: {
|
|||
|
|
borderWidth: 0,
|
|||
|
|
},
|
|||
|
|
borderDistance: 0,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
// CPU 系统
|
|||
|
|
{
|
|||
|
|
type: 'liquidFill',
|
|||
|
|
name: this.$t('home.system'),
|
|||
|
|
radius: '85%',
|
|||
|
|
center: ['50%', '55%'],
|
|||
|
|
amplitude: 10,
|
|||
|
|
backgroundStyle: {
|
|||
|
|
borderWidth: 1,
|
|||
|
|
color: 'rgba(201,219,252, 0.5)',
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
shadowColor: 'rgba(0, 0, 0, 0)',
|
|||
|
|
},
|
|||
|
|
color: [
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{ offset: 1, color: '#3C8CE7' },
|
|||
|
|
{ offset: 0, color: '#00EAFF' },
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#e0c3fc',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#8ec5fc',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#accbee',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#e7f0fd',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.sys / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.system'),
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.sys / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.system'),
|
|||
|
|
direction: 'left',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.sys / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.system'),
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
label: {
|
|||
|
|
normal: {
|
|||
|
|
formatter: (value) => {
|
|||
|
|
return (value.value * 100).toFixed(0) + '%';
|
|||
|
|
},
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 20,
|
|||
|
|
color: '#333',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
outline: {
|
|||
|
|
show: true,
|
|||
|
|
itemStyle: {
|
|||
|
|
borderWidth: 0,
|
|||
|
|
},
|
|||
|
|
borderDistance: 0,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
// CPU 空闲
|
|||
|
|
{
|
|||
|
|
type: 'liquidFill',
|
|||
|
|
name: this.$t('home.free'),
|
|||
|
|
radius: '85%',
|
|||
|
|
center: ['75%', '55%'],
|
|||
|
|
amplitude: 10,
|
|||
|
|
backgroundStyle: {
|
|||
|
|
borderWidth: 1,
|
|||
|
|
color: 'rgba(216, 218, 62, 0.1)',
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
shadowColor: 'rgba(0, 0, 0, 0)',
|
|||
|
|
},
|
|||
|
|
color: [
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#c4f4fe',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#fdefbe',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#FFFEFF',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#D7FFFE',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#abecd6',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#fbed96',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.free / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.free'),
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.free / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.free'),
|
|||
|
|
direction: 'left',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: (this.server.cpu.free / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free)).toFixed(2),
|
|||
|
|
name: this.$t('home.free'),
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
label: {
|
|||
|
|
normal: {
|
|||
|
|
formatter: (value) => {
|
|||
|
|
return (value.value * 100).toFixed(0) + '%';
|
|||
|
|
},
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 20,
|
|||
|
|
color: '#333',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
outline: {
|
|||
|
|
show: true,
|
|||
|
|
itemStyle: {
|
|||
|
|
borderWidth: 0,
|
|||
|
|
},
|
|||
|
|
borderDistance: 0,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
legend: {
|
|||
|
|
orient: 'vertical',
|
|||
|
|
right: 20,
|
|||
|
|
data: [this.$t('home.user'), this.$t('home.system'), this.$t('home.free')],
|
|||
|
|
textStyle: {
|
|||
|
|
color: '#333',
|
|||
|
|
fontSize: 14,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
option && myChart.setOption(option);
|
|||
|
|
},
|
|||
|
|
drawPieMemery() {
|
|||
|
|
// 基于准备好的dom,初始化echarts实例
|
|||
|
|
let myChart = this.$echarts.init(this.$refs.pieMemery);
|
|||
|
|
var option;
|
|||
|
|
|
|||
|
|
// 水球图
|
|||
|
|
var value = this.server.mem.used / 10;
|
|||
|
|
|
|||
|
|
option = {
|
|||
|
|
backgroundColor: '#fff',
|
|||
|
|
title: [
|
|||
|
|
{
|
|||
|
|
text: this.$t('home.memory'),
|
|||
|
|
left: 'left',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 16,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
text: '剩余:' + this.server.mem.free + 'G',
|
|||
|
|
left: '50%',
|
|||
|
|
top: '55%',
|
|||
|
|
textAlign: 'center',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: '13',
|
|||
|
|
fontWeight: '400',
|
|||
|
|
color: '#fff',
|
|||
|
|
|
|||
|
|
textAlign: 'center',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
text: '已用:' + this.server.mem.used + 'G',
|
|||
|
|
left: '50%',
|
|||
|
|
top: '67%',
|
|||
|
|
textAlign: 'center',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: '13',
|
|||
|
|
fontWeight: '400',
|
|||
|
|
color: '#fff',
|
|||
|
|
|
|||
|
|
textAlign: 'center',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: 'item',
|
|||
|
|
formatter: (value) => {
|
|||
|
|
return '已使用:' + value.value.toFixed(2);
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
legend: {
|
|||
|
|
orient: 'vertical',
|
|||
|
|
left: 'right',
|
|||
|
|
},
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
type: 'liquidFill',
|
|||
|
|
radius: '85%',
|
|||
|
|
z: 6,
|
|||
|
|
center: ['50%', '55%'],
|
|||
|
|
amplitude: 10,
|
|||
|
|
backgroundStyle: {
|
|||
|
|
borderWidth: 1,
|
|||
|
|
color: 'rgba(201,219,252, 0.5)', // 球体
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
shadowColor: 'rgba(0, 0, 0, 0)',
|
|||
|
|
},
|
|||
|
|
color: [
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#fff1eb',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#ace0f9',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#3C8CE7',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#00EAFF',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#e0c3fc',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#8ec5fc',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
value: value,
|
|||
|
|
name: '已使用',
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
value: value,
|
|||
|
|
direction: 'left',
|
|||
|
|
name: '已使用',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: value,
|
|||
|
|
name: '已使用',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
label: {
|
|||
|
|
normal: {
|
|||
|
|
formatter: (value) => {
|
|||
|
|
return (value.value * 100).toFixed(0) + '%';
|
|||
|
|
},
|
|||
|
|
position: ['53.3%', '40%'],
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 21,
|
|||
|
|
color: '#233d7d',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
outline: {
|
|||
|
|
show: true,
|
|||
|
|
itemStyle: {
|
|||
|
|
borderWidth: 0,
|
|||
|
|
},
|
|||
|
|
borderDistance: 0,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
};
|
|||
|
|
option && myChart.setOption(option);
|
|||
|
|
},
|
|||
|
|
drawPieDisk() {
|
|||
|
|
// 基于准备好的dom,初始化echarts实例
|
|||
|
|
let myChart = this.$echarts.init(this.$refs.pieDisk);
|
|||
|
|
var option;
|
|||
|
|
let one = this.server.sysFiles[0].used.replace('GB', '');
|
|||
|
|
let two = this.server.sysFiles[0].free.replace('GB', '');
|
|||
|
|
let values = parseFloat(one) / (parseFloat(one) + parseFloat(two));
|
|||
|
|
// option = {
|
|||
|
|
// title: {
|
|||
|
|
// text: this.$t('home.disk'),
|
|||
|
|
// left: 'left',
|
|||
|
|
// textStyle: {
|
|||
|
|
// fontSize: 16,
|
|||
|
|
// },
|
|||
|
|
// },
|
|||
|
|
// tooltip: {
|
|||
|
|
// trigger: 'item',
|
|||
|
|
// },
|
|||
|
|
// legend: {
|
|||
|
|
// orient: 'vertical',
|
|||
|
|
// left: 'right',
|
|||
|
|
// },
|
|||
|
|
// color: ['#F56C6C', '#DDD'],
|
|||
|
|
// series: [
|
|||
|
|
// {
|
|||
|
|
// name: this.$t('home.diskStatus'),
|
|||
|
|
// type: 'pie',
|
|||
|
|
// radius: '55%',
|
|||
|
|
// label: {
|
|||
|
|
// show: false,
|
|||
|
|
// },
|
|||
|
|
// labelLine: {
|
|||
|
|
// normal: {
|
|||
|
|
// position: 'inner',
|
|||
|
|
// show: false,
|
|||
|
|
// },
|
|||
|
|
// },
|
|||
|
|
// data: [
|
|||
|
|
// {
|
|||
|
|
// value: one,
|
|||
|
|
// name: this.$t('home.used'),
|
|||
|
|
// },
|
|||
|
|
// {
|
|||
|
|
// value: two,
|
|||
|
|
// name: this.$t('home.available'),
|
|||
|
|
// },
|
|||
|
|
// ],
|
|||
|
|
// },
|
|||
|
|
// ],
|
|||
|
|
// };
|
|||
|
|
// 水球图
|
|||
|
|
var value = values;
|
|||
|
|
|
|||
|
|
option = {
|
|||
|
|
backgroundColor: '#fff',
|
|||
|
|
title: [
|
|||
|
|
{
|
|||
|
|
text: this.$t('home.disk'),
|
|||
|
|
left: 'left',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 16,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
text: '剩余:' + two + 'G',
|
|||
|
|
left: '50%',
|
|||
|
|
top: '55%',
|
|||
|
|
textAlign: 'center',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: '13',
|
|||
|
|
fontWeight: '400',
|
|||
|
|
color: '#fff',
|
|||
|
|
|
|||
|
|
textAlign: 'center',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
text: '已用:' + one + 'G',
|
|||
|
|
left: '50%',
|
|||
|
|
top: '67%',
|
|||
|
|
textAlign: 'center',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: '13',
|
|||
|
|
fontWeight: '400',
|
|||
|
|
color: '#fff',
|
|||
|
|
|
|||
|
|
textAlign: 'center',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: 'item',
|
|||
|
|
formatter: (value) => {
|
|||
|
|
return '已使用:' + value.value.toFixed(2);
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
legend: {
|
|||
|
|
orient: 'vertical',
|
|||
|
|
left: 'right',
|
|||
|
|
},
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
type: 'liquidFill',
|
|||
|
|
radius: '85%',
|
|||
|
|
z: 6,
|
|||
|
|
center: ['50%', '55%'],
|
|||
|
|
amplitude: 10,
|
|||
|
|
backgroundStyle: {
|
|||
|
|
borderWidth: 1,
|
|||
|
|
color: 'rgba(245, 239, 239,0.5)', // 球体
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
shadowColor: 'rgba(0, 0, 0, 0)',
|
|||
|
|
},
|
|||
|
|
color: [
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#feada6',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#feada6',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#FFF6B7',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#FFF6B7',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'linear',
|
|||
|
|
x: 0,
|
|||
|
|
y: 0,
|
|||
|
|
x2: 0,
|
|||
|
|
y2: 1,
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#ff9a9e',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#fecfef',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
value: value,
|
|||
|
|
name: '已使用',
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
value: value,
|
|||
|
|
direction: 'left',
|
|||
|
|
name: '已使用',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
value: value,
|
|||
|
|
name: '已使用',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
label: {
|
|||
|
|
normal: {
|
|||
|
|
formatter: (value) => {
|
|||
|
|
return (value.value * 100).toFixed(0) + '%';
|
|||
|
|
},
|
|||
|
|
position: ['53.3%', '40%'],
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 21,
|
|||
|
|
color: '#73545c',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
outline: {
|
|||
|
|
show: true,
|
|||
|
|
itemStyle: {
|
|||
|
|
borderWidth: 0,
|
|||
|
|
borderColor: '#ff9a9e',
|
|||
|
|
},
|
|||
|
|
borderDistance: 0,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
option && myChart.setOption(option);
|
|||
|
|
},
|
|||
|
|
// 折线图的初始化
|
|||
|
|
drawLine() {
|
|||
|
|
let myChart = this.$echarts.init(this.$refs.line);
|
|||
|
|
var option;
|
|||
|
|
option = {
|
|||
|
|
title: {
|
|||
|
|
text: this.$t('views.index.394840-16'),
|
|||
|
|
left: 'left',
|
|||
|
|
textStyle: {
|
|||
|
|
fontSize: 19,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: 'axis',
|
|||
|
|
},
|
|||
|
|
legend: {
|
|||
|
|
orient: 'vertical',
|
|||
|
|
left: 'right',
|
|||
|
|
},
|
|||
|
|
xAxis: [
|
|||
|
|
{
|
|||
|
|
type: 'category',
|
|||
|
|
data: this.linechart.date,
|
|||
|
|
axisLine: {
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#999',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
yAxis: [
|
|||
|
|
{
|
|||
|
|
type: 'value',
|
|||
|
|
splitNumber: 4,
|
|||
|
|
splitLine: {
|
|||
|
|
lineStyle: {
|
|||
|
|
type: 'dashed',
|
|||
|
|
color: '#DDD',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
axisLine: {
|
|||
|
|
show: false,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#333',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
nameTextStyle: {
|
|||
|
|
color: '#999',
|
|||
|
|
},
|
|||
|
|
splitArea: {
|
|||
|
|
show: false,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
name: this.$t('views.index.394840-16'),
|
|||
|
|
type: 'line',
|
|||
|
|
data: this.linechart.counts,
|
|||
|
|
radius: '55%',
|
|||
|
|
|
|||
|
|
lineStyle: {
|
|||
|
|
normal: {
|
|||
|
|
width: 8,
|
|||
|
|
color: {
|
|||
|
|
type: 'linear',
|
|||
|
|
colorStops: [
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: '#A9F387', // 0% 处的颜色
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: '#48D8BF', // 100% 处的颜色
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
globalCoord: false, // 缺省为 false
|
|||
|
|
},
|
|||
|
|
shadowColor: 'rgba(72,216,191, 0.3)',
|
|||
|
|
shadowBlur: 10,
|
|||
|
|
shadowOffsetY: 20,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
normal: {
|
|||
|
|
color: 'rgba(72,216,191, 0.3)',
|
|||
|
|
borderWidth: 10,
|
|||
|
|
/*shadowColor: 'rgba(72,216,191, 0.3)',
|
|||
|
|
shadowBlur: 100,*/
|
|||
|
|
borderColor: '#A9F387',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
smooth: true,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
};
|
|||
|
|
option && myChart.setOption(option);
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
// 天气
|
|||
|
|
$primary-gradient-start: #a1c4fd;
|
|||
|
|
$primary-gradient-end: #c2e9fb;
|
|||
|
|
$secondary-color: #ffffff;
|
|||
|
|
$icon-color: #ffffff;
|
|||
|
|
$shadow-color: rgba(0, 0, 0, 0.1);
|
|||
|
|
$hover-shadow-color: rgba(0, 0, 0, 0.2);
|
|||
|
|
$aqi-good-color: #4caf50;
|
|||
|
|
$aqi-moderate-color: #ffeb3b;
|
|||
|
|
$aqi-unhealthy-color: #f44336;
|
|||
|
|
|
|||
|
|
.weather-card {
|
|||
|
|
height: 420px;
|
|||
|
|
background: linear-gradient(135deg, var(--background-start) 0%, var(--background-end) 100%);
|
|||
|
|
border-radius: 15px;
|
|||
|
|
padding: 16px;
|
|||
|
|
color: $secondary-color;
|
|||
|
|
box-shadow: 0 4px 20px $shadow-color;
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s,
|
|||
|
|
box-shadow 0.3s;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 8px 30px $hover-shadow-color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-header {
|
|||
|
|
text-align: center;
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
|
|||
|
|
h2 {
|
|||
|
|
margin: 0;
|
|||
|
|
font-size: 26px;
|
|||
|
|
font-weight: bold;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
color: $secondary-color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.date-week {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
font-size: 14px;
|
|||
|
|
color: rgba($secondary-color, 0.8);
|
|||
|
|
margin-top: 5px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-description {
|
|||
|
|
margin-top: 5px;
|
|||
|
|
font-size: 16px;
|
|||
|
|
color: rgba($secondary-color, 0.9);
|
|||
|
|
white-space: nowrap;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-main {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
|
|||
|
|
.weather-icon {
|
|||
|
|
width: 100px; // 增大图标尺寸
|
|||
|
|
height: 100px;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.temperature {
|
|||
|
|
font-size: 23px; // 增大温度字体
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: $secondary-color;
|
|||
|
|
margin-left: 20px;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-details {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-around;
|
|||
|
|
margin-top: 10px;
|
|||
|
|
|
|||
|
|
.detail-item {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
font-size: 14px;
|
|||
|
|
color: $secondary-color;
|
|||
|
|
|
|||
|
|
i {
|
|||
|
|
font-size: 18px;
|
|||
|
|
margin-right: 5px;
|
|||
|
|
color: $icon-color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-text {
|
|||
|
|
white-space: nowrap;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.air-quality {
|
|||
|
|
margin-top: 15px;
|
|||
|
|
padding: 10px 15px;
|
|||
|
|
background-color: rgba($secondary-color, 0.15);
|
|||
|
|
border-radius: 8px;
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
|
|||
|
|
.aqi-info {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
|
|||
|
|
.aqi-value {
|
|||
|
|
font-size: 18px;
|
|||
|
|
font-weight: bold;
|
|||
|
|
padding: 5px 10px;
|
|||
|
|
border-radius: 5px;
|
|||
|
|
color: #fff;
|
|||
|
|
background-color: inherit; // 继承父元素的背景色
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
&.aqi-good {
|
|||
|
|
background-color: $aqi-good-color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
&.aqi-moderate {
|
|||
|
|
background-color: $aqi-moderate-color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
&.aqi-unhealthy {
|
|||
|
|
background-color: $aqi-unhealthy-color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.aqi-level {
|
|||
|
|
font-size: 14px;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: rgba($secondary-color, 0.9);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 天气提示 */
|
|||
|
|
.weather-tip {
|
|||
|
|
margin-top: 15px;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
font-size: 14px;
|
|||
|
|
background-color: rgba($secondary-color, 0.2);
|
|||
|
|
padding: 10px 15px;
|
|||
|
|
border-radius: 10px;
|
|||
|
|
color: $secondary-color;
|
|||
|
|
|
|||
|
|
i {
|
|||
|
|
font-size: 18px;
|
|||
|
|
margin-right: 10px;
|
|||
|
|
color: $icon-color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
span {
|
|||
|
|
white-space: nowrap;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 响应式设计 */
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.weather-card {
|
|||
|
|
padding: 15px;
|
|||
|
|
|
|||
|
|
.weather-header {
|
|||
|
|
h2 {
|
|||
|
|
font-size: 22px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.date-week {
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-description {
|
|||
|
|
font-size: 14px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-main {
|
|||
|
|
flex-direction: column;
|
|||
|
|
|
|||
|
|
.temperature {
|
|||
|
|
margin-left: 0;
|
|||
|
|
margin-top: 10px;
|
|||
|
|
font-size: 22px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-icon {
|
|||
|
|
width: 80px;
|
|||
|
|
height: 80px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-details {
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.air-quality {
|
|||
|
|
padding: 8px 12px;
|
|||
|
|
|
|||
|
|
.aqi-info {
|
|||
|
|
flex-direction: row;
|
|||
|
|
gap: 8px;
|
|||
|
|
|
|||
|
|
.aqi-value {
|
|||
|
|
font-size: 16px;
|
|||
|
|
padding: 4px 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.aqi-level {
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.weather-tip {
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//天气完
|
|||
|
|
// 设备数据统计显示
|
|||
|
|
.card-panel {
|
|||
|
|
height: 200px;
|
|||
|
|
border-radius: 35px;
|
|||
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|||
|
|
padding: 20px;
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s ease,
|
|||
|
|
box-shadow 0.3s ease;
|
|||
|
|
|
|||
|
|
/* 悬停效果,增加交互性 */
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
|
|||
|
|
}
|
|||
|
|
.device {
|
|||
|
|
.card-panel-icon {
|
|||
|
|
fill: #a7de87;
|
|||
|
|
}
|
|||
|
|
.card-icon {
|
|||
|
|
&:hover .card-panel-icon {
|
|||
|
|
fill: #007aff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.card-data {
|
|||
|
|
.card-panel-num {
|
|||
|
|
color: #a7de87;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.product {
|
|||
|
|
.card-panel-icon {
|
|||
|
|
fill: #f3728c;
|
|||
|
|
}
|
|||
|
|
.card-icon {
|
|||
|
|
&:hover .card-panel-icon {
|
|||
|
|
fill: #007aff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.card-data {
|
|||
|
|
.card-panel-num {
|
|||
|
|
color: #f3728c;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.function {
|
|||
|
|
.card-panel-icon {
|
|||
|
|
fill: #ffc766;
|
|||
|
|
}
|
|||
|
|
.card-icon {
|
|||
|
|
&:hover .card-panel-icon {
|
|||
|
|
fill: #007aff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.card-data {
|
|||
|
|
.card-panel-num {
|
|||
|
|
color: #ffc766;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.monitor {
|
|||
|
|
.card-panel-icon {
|
|||
|
|
fill: #66c9ff;
|
|||
|
|
}
|
|||
|
|
.card-icon {
|
|||
|
|
&:hover .card-panel-icon {
|
|||
|
|
fill: #007aff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.card-data {
|
|||
|
|
.card-panel-num {
|
|||
|
|
color: #66c9ff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.alert {
|
|||
|
|
.card-panel-icon {
|
|||
|
|
fill: #a076ef;
|
|||
|
|
}
|
|||
|
|
.card-icon {
|
|||
|
|
&:hover .card-panel-icon {
|
|||
|
|
fill: #007aff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.card-data {
|
|||
|
|
.card-panel-num {
|
|||
|
|
color: #a076ef;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.reports {
|
|||
|
|
.card-panel-icon {
|
|||
|
|
fill: #5dd5d1;
|
|||
|
|
}
|
|||
|
|
.card-icon {
|
|||
|
|
&:hover .card-panel-icon {
|
|||
|
|
fill: #007aff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.card-data {
|
|||
|
|
.card-panel-num {
|
|||
|
|
color: #5dd5d1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-content {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 100%;
|
|||
|
|
|
|||
|
|
.card-icon {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
width: 55px;
|
|||
|
|
height: 55px;
|
|||
|
|
margin-bottom: 15px;
|
|||
|
|
background-color: rgba(#ffffff, 0.65);
|
|||
|
|
padding: 10px;
|
|||
|
|
border-radius: 10px;
|
|||
|
|
|
|||
|
|
/* 图标样式 */
|
|||
|
|
.card-panel-icon {
|
|||
|
|
width: 80%;
|
|||
|
|
height: 80%;
|
|||
|
|
transition: fill 0.3s ease;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 悬停时图标颜色变化 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 数据区域 */
|
|||
|
|
.card-data {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
|
|||
|
|
/* 标题样式 */
|
|||
|
|
.card-title {
|
|||
|
|
font-size: 1.05rem;
|
|||
|
|
color: #4d4d4d;
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
text-transform: uppercase;
|
|||
|
|
letter-spacing: 1px;
|
|||
|
|
font-weight: 600;
|
|||
|
|
white-space: nowrap; /* 防止文本换行 */
|
|||
|
|
overflow: hidden; /* 超出部分隐藏 */
|
|||
|
|
text-overflow: ellipsis; /* 使用省略号表示超出部分 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 数字样式 */
|
|||
|
|
.card-panel-num {
|
|||
|
|
font-size: 1.5rem;
|
|||
|
|
|
|||
|
|
font-weight: bold;
|
|||
|
|
position: relative;
|
|||
|
|
animation: countAnimation 3s ease-out forwards;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 响应式设计,当屏幕宽度小于768px时 */
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
height: 150px; /* 减小卡片高度 */
|
|||
|
|
padding: 15px; /* 减小内边距 */
|
|||
|
|
|
|||
|
|
.card-content {
|
|||
|
|
.card-icon {
|
|||
|
|
width: 40px;
|
|||
|
|
height: 40px;
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
|
|||
|
|
.card-panel-icon {
|
|||
|
|
width: 80%;
|
|||
|
|
height: 80%;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-data {
|
|||
|
|
.card-title {
|
|||
|
|
font-size: 1rem;
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-panel-num {
|
|||
|
|
font-size: 1.5rem;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 数字递增动画关键帧 */
|
|||
|
|
@keyframes countAnimation {
|
|||
|
|
0% {
|
|||
|
|
opacity: 0;
|
|||
|
|
transform: translateY(-10px);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
opacity: 1;
|
|||
|
|
transform: translateY(5px);
|
|||
|
|
}
|
|||
|
|
100% {
|
|||
|
|
opacity: 1;
|
|||
|
|
transform: translateY(0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//数据完
|
|||
|
|
// 折线图卡片
|
|||
|
|
.line-card {
|
|||
|
|
height: 420px;
|
|||
|
|
border-radius: 15px;
|
|||
|
|
padding: 16px;
|
|||
|
|
color: $secondary-color;
|
|||
|
|
box-shadow: 0 4px 20px $shadow-color;
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s,
|
|||
|
|
box-shadow 0.3s;
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 8px 30px $hover-shadow-color;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 折线图完
|
|||
|
|
// 地图
|
|||
|
|
.map-card {
|
|||
|
|
background: #ffffff; /* 使用纯色背景,增加清新感 */
|
|||
|
|
border-radius: 15px; /* 略微减小圆角 */
|
|||
|
|
overflow: hidden;
|
|||
|
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); /* 更柔和的阴影 */
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s ease,
|
|||
|
|
box-shadow 0.3s ease;
|
|||
|
|
height: 500px;
|
|||
|
|
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-header {
|
|||
|
|
height: 30px;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
border-bottom: 1px dashed #e0e0e0;
|
|||
|
|
|
|||
|
|
.card-title {
|
|||
|
|
margin: 0;
|
|||
|
|
color: #333333;
|
|||
|
|
font-size: 18px;
|
|||
|
|
font-weight: 600;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
|
|||
|
|
i {
|
|||
|
|
margin-right: 8px;
|
|||
|
|
color: #409eff; /* 主题色图标 */
|
|||
|
|
font-size: 20px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.map-container {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 500px; /* 减少高度 */
|
|||
|
|
position: relative;
|
|||
|
|
border-radius: 15px;
|
|||
|
|
overflow: hidden;
|
|||
|
|
|
|||
|
|
.map {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
/* 可根据需要添加地图相关样式 */
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 响应式设计 */
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.map-card {
|
|||
|
|
padding: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-header {
|
|||
|
|
padding: 18px 12px;
|
|||
|
|
|
|||
|
|
.card-title {
|
|||
|
|
font-size: 16px;
|
|||
|
|
|
|||
|
|
i {
|
|||
|
|
font-size: 18px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.map-container {
|
|||
|
|
height: 250px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 480px) {
|
|||
|
|
.map-card {
|
|||
|
|
padding: 10px;
|
|||
|
|
border-radius: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-header {
|
|||
|
|
padding: 15px 10px;
|
|||
|
|
|
|||
|
|
.card-title {
|
|||
|
|
font-size: 14px;
|
|||
|
|
|
|||
|
|
i {
|
|||
|
|
font-size: 16px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.map-container {
|
|||
|
|
height: 200px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 地图完
|
|||
|
|
// 信息栏
|
|||
|
|
.message-card {
|
|||
|
|
height: 240px;
|
|||
|
|
margin-bottom: 20px;
|
|||
|
|
border-radius: 15px;
|
|||
|
|
box-shadow: 0 4px 20px $shadow-color;
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s,
|
|||
|
|
box-shadow 0.3s;
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 8px 30px $hover-shadow-color;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 柱状图
|
|||
|
|
.card-container {
|
|||
|
|
height: 240px;
|
|||
|
|
width: 100%;
|
|||
|
|
padding: 16px;
|
|||
|
|
background: #ffffff;
|
|||
|
|
border-radius: 15px;
|
|||
|
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
|||
|
|
overflow: hidden;
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s ease,
|
|||
|
|
box-shadow 0.3s ease;
|
|||
|
|
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 响应式设计 */
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.card-container {
|
|||
|
|
.card {
|
|||
|
|
flex-direction: column;
|
|||
|
|
height: auto;
|
|||
|
|
|
|||
|
|
.card-image {
|
|||
|
|
width: 100%;
|
|||
|
|
|
|||
|
|
height: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-content {
|
|||
|
|
width: 100%;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 480px) {
|
|||
|
|
.card-container {
|
|||
|
|
.card {
|
|||
|
|
.card-content {
|
|||
|
|
padding: 10px;
|
|||
|
|
|
|||
|
|
.author {
|
|||
|
|
font-size: 1em;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.content {
|
|||
|
|
font-size: 0.9em;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.footer {
|
|||
|
|
font-size: 0.8em;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-image {
|
|||
|
|
.overlay .thumb {
|
|||
|
|
width: 40px;
|
|||
|
|
height: 40px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 书摘完
|
|||
|
|
// 使用率
|
|||
|
|
.rate {
|
|||
|
|
border-radius: 15px;
|
|||
|
|
padding: 16px;
|
|||
|
|
color: $secondary-color;
|
|||
|
|
box-shadow: 0 4px 20px $shadow-color;
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s,
|
|||
|
|
box-shadow 0.3s;
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 8px 30px $hover-shadow-color;
|
|||
|
|
}
|
|||
|
|
.pieCpu {
|
|||
|
|
height: 161px;
|
|||
|
|
}
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
height: 100%;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 使用率完
|
|||
|
|
.phone-card {
|
|||
|
|
border-radius: 15px;
|
|||
|
|
box-shadow: 0 4px 20px $shadow-color;
|
|||
|
|
transition:
|
|||
|
|
transform 0.3s,
|
|||
|
|
box-shadow 0.3s;
|
|||
|
|
&:hover {
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
box-shadow: 0 8px 30px $hover-shadow-color;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.phone {
|
|||
|
|
height: 729px;
|
|||
|
|
width: 370px;
|
|||
|
|
background-image: url('../assets/images/phone.png');
|
|||
|
|
background-size: cover;
|
|||
|
|
margin: 0 auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.phone-container {
|
|||
|
|
height: 618px;
|
|||
|
|
width: 343px;
|
|||
|
|
position: relative;
|
|||
|
|
top: 46px;
|
|||
|
|
left: 12px;
|
|||
|
|
background-color: #fff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.content {
|
|||
|
|
line-height: 24px;
|
|||
|
|
padding: 10px;
|
|||
|
|
border: 1px solid #eee;
|
|||
|
|
border-radius: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.description {
|
|||
|
|
font-size: 12px;
|
|||
|
|
|
|||
|
|
tr {
|
|||
|
|
line-height: 20px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.notice-bar {
|
|||
|
|
overflow: hidden;
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
.animating {
|
|||
|
|
animation: scroll 10s linear infinite;
|
|||
|
|
}
|
|||
|
|
</style>
|