驾驶舱

This commit is contained in:
1378012178@qq.com 2025-08-29 17:50:26 +08:00
parent f270321079
commit 2bef563b0a
17 changed files with 619 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 MiB

View File

@ -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,
];

View File

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB