驾驶舱
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 55 MiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 53 MiB |
|
|
@ -97,6 +97,18 @@ export const tempRoute: AppRouteRecordRaw = {
|
|||
},
|
||||
};
|
||||
|
||||
// 驾驶舱
|
||||
export const newDashboardRoute: AppRouteRecordRaw = {
|
||||
path: '/screen/dashboard',
|
||||
name: 'dashboardIndex',
|
||||
//新版后台登录,如果想要使用旧版登录放开即可
|
||||
// component: () => import('/@/views/sys/login/Login.vue'),
|
||||
component: () => import('/@/views/screen/Dashboard.vue'),
|
||||
meta: {
|
||||
title: t('routes.basic.login'),
|
||||
},
|
||||
};
|
||||
|
||||
// Basic routing without permission
|
||||
export const basicRoutes = [
|
||||
LoginRoute,
|
||||
|
|
@ -109,4 +121,5 @@ export const basicRoutes = [
|
|||
newHomeRoute,
|
||||
newScreenRoute,
|
||||
tempRoute,
|
||||
newDashboardRoute,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,606 @@
|
|||
<template>
|
||||
<div class="dashboard">
|
||||
<!-- 顶部 -->
|
||||
<div class="top">
|
||||
<div class="title">磐石市供热信息化平台</div>
|
||||
<div class="time">{{ currentTime }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 下半部分 -->
|
||||
<div class="bottom">
|
||||
<!-- 左侧 -->
|
||||
<div class="left">
|
||||
<!-- 模板(只展示被改动的 area-3 部分,其他不变) -->
|
||||
<div class="area1 areabg area-3">
|
||||
<div class="area-header">
|
||||
<div class="header-left">
|
||||
<img src="./dashboard/dp_icon4.png" alt="icon" />
|
||||
<span class="header-left-text">城区供水温度【实时】</span>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div style="background: linear-gradient(90deg, #ffce53, #6eecff);"></div>
|
||||
<div>供水</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="area-body">
|
||||
<div id="main" style="width: 100%; height: 100%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="area2 areabg area-4">
|
||||
<div class="area-header">
|
||||
<div class="header-left">
|
||||
<img src="./dashboard/dp_icon4.png" alt="icon" />
|
||||
<span class="header-left-text">城区回水温度【实时】</span>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div style="background: linear-gradient(90deg, #fff, #5BB7F7);"></div>
|
||||
<div>回水</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" area-body">
|
||||
</div>
|
||||
</div>
|
||||
<div class="area3 areabg area-9">列表</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧 -->
|
||||
<div class="right">
|
||||
<div class="area area-5">
|
||||
<div class="left-img">
|
||||
<img src="./dashboard/dp_icon1.png" />
|
||||
</div>
|
||||
<div class="right-text">
|
||||
<div class="top-text-1">{{ cqglfsl }}</div>
|
||||
<div class="bottom-text-1">城区锅炉房总数</div>
|
||||
</div>
|
||||
<div class="left-img">
|
||||
<img src="./dashboard/dp_21.png" />
|
||||
</div>
|
||||
<div class="right-text">
|
||||
<div class="top-text-2">{{ cqhrzsl }}</div>
|
||||
<div class="bottom-text-2">城区换热站总数</div>
|
||||
</div>
|
||||
<div class="left-img">
|
||||
<img src="./dashboard/dp_icon3.png" />
|
||||
</div>
|
||||
<div class="right-text">
|
||||
<div class="top-text-3">{{ jxglfsl }}</div>
|
||||
<div class="bottom-text-3">郊县总数</div>
|
||||
</div>
|
||||
<div class="left-img">
|
||||
<img src="./dashboard/dp_icon1.png" />
|
||||
</div>
|
||||
<div class="right-text">
|
||||
<div class="top-text-4">{{ jxsl }}</div>
|
||||
<div class="bottom-text-4">郊县锅炉房总数</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="middle">
|
||||
<div class="area areabg area-6">
|
||||
<div class="area-header">
|
||||
<div class="header-left">
|
||||
<img src="./dashboard/dp_icon4.png" alt="icon" />
|
||||
<span class="header-left-text">郊县瞬时热量【实时】</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" area-body">
|
||||
</div>
|
||||
</div>
|
||||
<div class="area areabg area-7">
|
||||
<div class="area-header">
|
||||
<div class="header-left">
|
||||
<img src="./dashboard/dp_icon4.png" alt="icon" />
|
||||
<span class="header-left-text">郊县瞬时流量【实时】</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" area-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="area areabg area-8">
|
||||
<div class="area-header">
|
||||
<div class="header-left">
|
||||
<img src="./dashboard/dp_icon4.png" alt="icon" />
|
||||
<span class="header-left-text">郊县供回水温度【实时】</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" area-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, nextTick,onBeforeUnmount } from 'vue';
|
||||
import { slcx, cqglfgswd } from '/@/api/dashboard/api';
|
||||
import * as echarts from 'echarts';
|
||||
import aImg from './dashboard/c.png';
|
||||
|
||||
let myChart: echarts.ECharts | null = null;
|
||||
|
||||
const currentTime = ref(new Date().toLocaleString());
|
||||
|
||||
let dataTimer: number | null = null;
|
||||
let timer: number;
|
||||
const cqglfsl = ref(0)
|
||||
const cqhrzsl = ref(0)
|
||||
const jxglfsl = ref(0)
|
||||
const jxsl = ref(0)
|
||||
async function loadData() {
|
||||
try {
|
||||
const s = await slcx();
|
||||
cqglfsl.value = s.cqglfsl || 0
|
||||
cqhrzsl.value = s.cqhrzsl || 0
|
||||
jxglfsl.value = s.jxglfsl || 0
|
||||
jxsl.value = s.jxsl || 0
|
||||
console.log("🌊 ~ loadData ~ s:", s)
|
||||
const r = await cqglfgswd();
|
||||
console.log("🌊 ~ loadData ~ r:", r)
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
currentTime.value = new Date().toLocaleString();
|
||||
}, 1000);
|
||||
|
||||
window.addEventListener('resize', adjustHeight);
|
||||
nextTick(adjustHeight);
|
||||
|
||||
loadData();
|
||||
dataTimer = window.setInterval(() => {
|
||||
loadData();
|
||||
}, 5 * 60 * 1000);
|
||||
|
||||
|
||||
const chartDom = document.getElementById("main") as HTMLElement;
|
||||
myChart = echarts.init(chartDom);
|
||||
|
||||
const option: echarts.EChartsOption = {
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: [
|
||||
"恒大锅炉房", "恒大锅炉房", "恒大锅炉房", "恒大锅炉房", "恒大锅炉房",
|
||||
"恒大锅炉房", "恒大锅炉房", "恒大锅炉房", "恒大锅炉房", "恒大锅炉房",
|
||||
"恒大锅炉房", "恒大锅炉房", "恒大锅炉房", "恒大锅炉房", "恒大锅炉房",
|
||||
"恒大锅炉房", "恒大锅炉房", "恒大锅炉房"
|
||||
],
|
||||
axisLabel: {
|
||||
rotate: 35,
|
||||
interval: 0
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: "value"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "bar",
|
||||
barWidth:'15px',
|
||||
data: [120,200,150,80,70,110,120,200,150,80,70,110,120,200,150,80,70,110],
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: "linear",
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: "#e8a929" },
|
||||
{ offset: 1, color: "#27a3d5" }
|
||||
]
|
||||
},
|
||||
opacity: 0.8
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "pictorialBar",
|
||||
symbol: `image://${aImg}`,
|
||||
symbolSize: [15, 15],
|
||||
symbolOffset: [0, -10],
|
||||
symbolPosition: "end",
|
||||
data: [120,200,150,80,70,110,120,200,150,80,70,110,120,200,150,80,70,110],
|
||||
z: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
|
||||
// 响应式自适应
|
||||
window.addEventListener("resize", resizeChart);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
window.removeEventListener('resize', adjustHeight);
|
||||
|
||||
if (dataTimer) {
|
||||
clearInterval(dataTimer);
|
||||
dataTimer = null;
|
||||
}
|
||||
});
|
||||
function resizeChart() {
|
||||
if (myChart) {
|
||||
myChart.resize();
|
||||
}
|
||||
}
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("resize", resizeChart);
|
||||
if (myChart) {
|
||||
myChart.dispose();
|
||||
myChart = null;
|
||||
}
|
||||
});
|
||||
|
||||
// 调整左下 a9 和右下 a8 高度一致
|
||||
function adjustHeight() {
|
||||
const a8 = document.querySelector('.area-8') as HTMLElement;
|
||||
const a9 = document.querySelector('.area-9') as HTMLElement;
|
||||
if (a8 && a9) {
|
||||
const maxH = Math.max(a8.offsetHeight, a9.offsetHeight);
|
||||
a8.style.height = maxH + 'px';
|
||||
a9.style.height = maxH + 'px';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.dashboard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
background: url("./dashboard/bg.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
/* 顶部 */
|
||||
.top {
|
||||
position: relative;
|
||||
height: 65px;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* title 居中 */
|
||||
background: url("./dashboard/top.png") no-repeat;
|
||||
background-size: 80% auto;
|
||||
/* 宽放大到150%,高自适应 */
|
||||
background-position: center top;
|
||||
}
|
||||
|
||||
.top .title {
|
||||
text-align: center;
|
||||
font-size: 35px;
|
||||
font-weight: bold;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
font-family: '经典雅黑', 'Microsoft YaHei', sans-serif;
|
||||
|
||||
/* 渐变文字 */
|
||||
background: linear-gradient(to bottom, #a9e5ff, #55cdff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
|
||||
/* 荧光效果 */
|
||||
text-shadow: 0 0 6px rgba(85, 205, 255, 0.3),
|
||||
0 0 12px rgba(85, 205, 255, 0.3);
|
||||
}
|
||||
|
||||
|
||||
.top .time {
|
||||
position: absolute;
|
||||
/* 脱离文档流,固定在右上角 */
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #cbf8ff;
|
||||
padding: 0 8px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* 下半部分 */
|
||||
.bottom {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
/* 左侧 */
|
||||
.left {
|
||||
flex: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.left .area {
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.area1 {
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex: 4;
|
||||
}
|
||||
.area2 {
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex: 3;
|
||||
}
|
||||
.area3 {
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex: 3;
|
||||
}
|
||||
/* 右侧 */
|
||||
.right {
|
||||
flex: 12;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
/* ========== 替换开始:area-5 与子元素布局 ========== */
|
||||
.area-5 {
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* 垂直居中 */
|
||||
/* 关键:控制四组之间的水平间距,想更宽改这个值 */
|
||||
padding: 8px 16px;
|
||||
/* 内边距,避免元素贴边 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 左侧图片块:固定宽度,保证各列宽度一致 */
|
||||
.left-img {
|
||||
flex: 0 0 80px;
|
||||
/* 固定 60px 宽度(可调整) */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 图片填充父容器宽度 */
|
||||
.left-img img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.right-text {
|
||||
flex: 1 1 120px;
|
||||
/* 可伸缩但有最小基准宽度 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 0;
|
||||
/* 垂直紧贴(数字与说明贴在一起) */
|
||||
margin-left: 0;
|
||||
/* 移除之前的负 margin,避免重叠 */
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 数字行:紧凑显示 */
|
||||
.top-text-1,
|
||||
.top-text-2,
|
||||
.top-text-3,
|
||||
.top-text-4 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
font-size: 32px;
|
||||
/* 你可以按需微调数字大小 */
|
||||
font-weight: bold;
|
||||
transform: scaleY(0.85);
|
||||
}
|
||||
|
||||
/* 说明行 */
|
||||
.bottom-text-1,
|
||||
.bottom-text-2,
|
||||
.bottom-text-3,
|
||||
.bottom-text-4 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.top-text-1 {
|
||||
color: #01A096;
|
||||
}
|
||||
|
||||
.top-text-2 {
|
||||
color: #E5B55B;
|
||||
}
|
||||
|
||||
.top-text-3 {
|
||||
color: #479FFE;
|
||||
}
|
||||
|
||||
.top-text-4 {
|
||||
color: #00A094;
|
||||
}
|
||||
|
||||
.bottom-text-1 {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
font-weight: bold;
|
||||
background: linear-gradient(to right, #67E4D4, #ffffff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.bottom-text-2 {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
font-weight: bold;
|
||||
background: linear-gradient(to right, #FAEEC4, #ffffff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.bottom-text-3 {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
font-weight: bold;
|
||||
background: linear-gradient(to right, #8eb9ff, #ffffff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.bottom-text-4 {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
font-weight: bold;
|
||||
background: linear-gradient(to right, #67E4D4, #ffffff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.middle {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
/* 中排填充剩余高度 */
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.area-6,
|
||||
.area-7 {
|
||||
flex: 1;
|
||||
/* 各占一半宽度 */
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.area-8 {
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.areabg {
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
-webkit-backdrop-filter: blur(6px);
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
/* 样式:把这些放到你现有 <style> 末尾或覆盖对应类 */
|
||||
.area-3,
|
||||
.area-4,
|
||||
.area-6,
|
||||
.area-7,
|
||||
.area-8 {
|
||||
/* 使 area-3 垂直布局:头部固定 50px,下面主体撑满 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* header 独占一行,高度 50px,左右对齐 */
|
||||
.area-header {
|
||||
height: 30px;
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 0 12px;
|
||||
box-sizing: border-box;
|
||||
/* 可选分隔线,透明度低 */
|
||||
// border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* header 左侧:图片 + 文本 */
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 小图标尺寸 */
|
||||
.header-left img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 左侧文字样式(按需改色)*/
|
||||
.header-left-text {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
color: #6AD3FF;
|
||||
/* 若在浅背景上看不清,可改为深色 */
|
||||
}
|
||||
|
||||
/* 右侧文字样式 */
|
||||
.header-right {
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
/* 两个项之间间距,可调 */
|
||||
color: #6AD3FF;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 第一个子元素:圆角、左右渐变、居中 */
|
||||
.header-right>div:first-child {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 25px;
|
||||
/* 最小宽度,根据需要调整 */
|
||||
height: 6px;
|
||||
/* 固定高度,和 border-radius 搭配好看 */
|
||||
padding: 0 8px;
|
||||
/* 横向内间距,可调 */
|
||||
border-radius: 10px;
|
||||
/* 从左到右渐变 */
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 第二个子元素样式(可选) */
|
||||
.header-right>div:last-child {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
/* 根据背景调色 */
|
||||
}
|
||||
|
||||
/* area 的主体内容(header 下方占剩余空间) */
|
||||
.area-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
padding-top: 8px;
|
||||
box-sizing: border-box;
|
||||
/* 如果你之前对 .left .area 有 align/justify: center,这里保证主体仍居中 */
|
||||
}
|
||||
#main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 966 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 36 KiB |