293 lines
8.0 KiB
Vue
293 lines
8.0 KiB
Vue
<template>
|
||
<div>
|
||
<span class="close-btn2" @click="closeModal"><span style="color: white;">×</span></span>
|
||
</div>
|
||
<div class="wrap">
|
||
<!-- 页面顶部中间显示 公司/锅炉房/换热站 -->
|
||
<div class="title">{{ headerText }}</div>
|
||
|
||
<!-- Tabs -->
|
||
<a-tabs v-model:activeKey="activeTab" centered @change="onTabChange">
|
||
<a-tab-pane key="temp" tab="温度指标">
|
||
<div ref="tempChartRef" class="chart-box"></div>
|
||
</a-tab-pane>
|
||
<a-tab-pane key="press" tab="压力指标">
|
||
<div ref="pressChartRef" class="chart-box"></div>
|
||
</a-tab-pane>
|
||
</a-tabs>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ref, nextTick, defineProps, onUnmounted } from 'vue';
|
||
import * as echarts from 'echarts';
|
||
import { useMessage } from '/@/hooks/web/useMessage';
|
||
import { list } from '/@/views/heating/history/HeatanalysisHistory.api';
|
||
|
||
const emit = defineEmits(['close']);
|
||
|
||
const props = defineProps({});
|
||
const { createMessage } = useMessage();
|
||
|
||
const activeTab = ref('temp'); // 默认进入温度指标 tab
|
||
|
||
// 日期:近7天(含今天)
|
||
const end = new Date();
|
||
end.setHours(23, 59, 59, 999);
|
||
const start = new Date(end);
|
||
start.setDate(end.getDate() - 6);
|
||
start.setHours(0, 0, 0, 0);
|
||
|
||
const pad = (n: number) => String(n).padStart(2, '0');
|
||
function formatDateTime(d: Date) {
|
||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||
}
|
||
|
||
const tempChartRef = ref<HTMLElement | null>(null);
|
||
const pressChartRef = ref<HTMLElement | null>(null);
|
||
let tempChart: echarts.ECharts | null = null;
|
||
let pressChart: echarts.ECharts | null = null;
|
||
let tempOption: any = null;
|
||
let pressOption: any = null;
|
||
const headerText = ref(''); // 页面顶部显示文本
|
||
|
||
function safeNum(v: any) {
|
||
if (v === null || v === undefined || v === '') return null;
|
||
const n = Number(v);
|
||
return Number.isNaN(n) ? null : n;
|
||
}
|
||
|
||
function buildHeader(records: any[], record_: any) {
|
||
const r = (records && records.length > 0) ? records[0] : record_;
|
||
|
||
// 取出名称
|
||
const names = [r.view001Name, r.view002Name, r.view004Name].filter(v => v && v !== '');
|
||
|
||
// 用箭头连接
|
||
return names.join(' → ');
|
||
}
|
||
|
||
|
||
function initChartsOptions(records: any[]) {
|
||
records.sort((a: any, b: any) => new Date(a.datatime).getTime() - new Date(b.datatime).getTime());
|
||
const xAxis = records.map((r: any) => r.datatime);
|
||
|
||
const tempSeries = [
|
||
{ name: '一次供水温度', key: 'view005', color: '#00c6ff' }, // 直接使用颜色而不是渐变
|
||
{ name: '一次回水温度', key: 'view006', color: '#ff6a00' },
|
||
{ name: '二次供水温度', key: 'view009', color: '#ff007f' },
|
||
{ name: '二次回水温度', key: 'view010', color: '#6a5acd' },
|
||
].map(s => ({
|
||
name: s.name,
|
||
type: 'line',
|
||
showSymbol: false,
|
||
connectNulls: false,
|
||
lineStyle: { width: 2 }, // 设置线条的宽度
|
||
itemStyle: {
|
||
color: s.color, // 设置折线的颜色
|
||
},
|
||
data: records.map((r: any) => safeNum(r[s.key])),
|
||
}));
|
||
|
||
const pressSeries = [
|
||
{ name: '一次供水压力', key: 'view007', color: '#00c6ff' },
|
||
{ name: '一次回水压力', key: 'view008', color: '#ff6a00' },
|
||
{ name: '二次供水压力', key: 'view011', color: '#ff007f' },
|
||
{ name: '二次回水压力', key: 'view012', color: '#6a5acd' },
|
||
].map(s => ({
|
||
name: s.name,
|
||
type: 'line',
|
||
showSymbol: false,
|
||
connectNulls: false,
|
||
lineStyle: { width: 2 }, // 设置线条的宽度
|
||
itemStyle: {
|
||
color: s.color, // 设置折线的颜色
|
||
},
|
||
data: records.map((r: any) => safeNum(r[s.key])),
|
||
}));
|
||
|
||
const baseOption = {
|
||
tooltip: { trigger: 'axis', axisPointer: { type: 'cross' } },
|
||
legend: { top: 36, left: 'center', textStyle: { color: '#ffffff' } }, // 设置折线图legend文字为白色
|
||
grid: { left: '5%', right: '5%', bottom: 70, top: 70, containLabel: true },
|
||
xAxis: {
|
||
type: 'category',
|
||
data: xAxis,
|
||
boundaryGap: false,
|
||
axisLabel: {
|
||
interval: 0,
|
||
formatter: (val: string) => val.replace(' ', '\n'),
|
||
color: '#ffffff' // 设置x轴文字颜色为白色
|
||
},
|
||
},
|
||
yAxis: { type: 'value', scale: true, axisLabel: { color: '#ffffff' } }, // 设置y轴文字颜色为白色
|
||
};
|
||
|
||
tempOption = { ...baseOption, title: { text: '温度指标', left: 'center', top: 8, textStyle: { color: '#ffffff' } }, series: tempSeries };
|
||
pressOption = { ...baseOption, title: { text: '压力指标', left: 'center', top: 8, textStyle: { color: '#ffffff' } }, series: pressSeries };
|
||
}
|
||
|
||
|
||
|
||
let resizeAdded = false;
|
||
function ensureResizeListener() {
|
||
if (resizeAdded) return;
|
||
const onResize = () => {
|
||
tempChart?.resize();
|
||
pressChart?.resize();
|
||
};
|
||
window.addEventListener('resize', onResize);
|
||
onUnmounted(() => {
|
||
window.removeEventListener('resize', onResize);
|
||
});
|
||
resizeAdded = true;
|
||
}
|
||
|
||
function init(record_: any) {
|
||
const params = {
|
||
pageNo: 1,
|
||
pageSize: -1,
|
||
regionType: '城区',
|
||
view001: record_.view001,
|
||
view002: record_.view002,
|
||
view004: record_.view004 || -1,
|
||
SDateStr: formatDateTime(start),
|
||
EDateStr: formatDateTime(end),
|
||
};
|
||
|
||
list(params).then((res: any) => {
|
||
const records = (res && res.records) ? res.records : [];
|
||
headerText.value = buildHeader(records, record_);
|
||
initChartsOptions(records);
|
||
nextTick(() => {
|
||
// 初始化温度图表(默认tab)
|
||
if (tempChartRef.value) {
|
||
tempChart = echarts.init(tempChartRef.value);
|
||
tempChart.setOption(tempOption);
|
||
}
|
||
ensureResizeListener();
|
||
});
|
||
}).catch(err => {
|
||
console.error(err);
|
||
createMessage.error('获取数据失败');
|
||
});
|
||
}
|
||
|
||
// tab切换时,第一次进来才 init
|
||
function onTabChange(key: string) {
|
||
nextTick(() => {
|
||
if (key === 'temp') {
|
||
if (!tempChart && tempChartRef.value) {
|
||
tempChart = echarts.init(tempChartRef.value);
|
||
tempChart.setOption(tempOption);
|
||
}
|
||
tempChart?.resize();
|
||
} else if (key === 'press') {
|
||
if (!pressChart && pressChartRef.value) {
|
||
pressChart = echarts.init(pressChartRef.value);
|
||
pressChart.setOption(pressOption);
|
||
}
|
||
pressChart?.resize();
|
||
}
|
||
});
|
||
}
|
||
|
||
function closeModal() {
|
||
emit('close')
|
||
}
|
||
|
||
defineExpose({ init });
|
||
|
||
onUnmounted(() => {
|
||
if (tempChart) { tempChart.dispose(); tempChart = null; }
|
||
if (pressChart) { pressChart.dispose(); pressChart = null; }
|
||
});
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.close-btn2 {
|
||
position: absolute;
|
||
top: 10px;
|
||
right: 10px;
|
||
float: right;
|
||
color: white;
|
||
cursor: pointer;
|
||
z-index: 299;
|
||
}
|
||
|
||
.wrap {
|
||
width: 100%;
|
||
margin: 0 auto;
|
||
background: linear-gradient(135deg, rgba(20, 35, 55, 0.85), rgba(0, 20, 40, 0.7));
|
||
/* 渐变背景色 */
|
||
padding: 20px;
|
||
border-radius: 15px;
|
||
/* 增加圆角 */
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||
/* 添加阴影 */
|
||
backdrop-filter: blur(10px);
|
||
/* 背景模糊效果 */
|
||
}
|
||
|
||
.title {
|
||
text-align: center;
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
margin: 20px 0;
|
||
color: #ffffff;
|
||
background: linear-gradient(135deg, #66d9ff, #ff8c00);
|
||
/* 渐变文字 */
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.5);
|
||
/* 增加文字的荧光效果 */
|
||
}
|
||
|
||
.chart-box {
|
||
width: 100%;
|
||
height: 60vh;
|
||
background-color: rgba(0, 0, 0, 0.3);
|
||
/* 深色背景让图表突出 */
|
||
border-radius: 12px;
|
||
/* 圆角效果 */
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||
/* 给图表增加阴影 */
|
||
overflow: hidden;
|
||
}
|
||
|
||
a-tabs {
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
/* Tab 背景色 */
|
||
border-radius: 8px;
|
||
}
|
||
|
||
a-tab-pane {
|
||
background-color: rgba(255, 255, 255, 0.836);
|
||
/* Tab 选项卡背景 */
|
||
border-radius: 8px;
|
||
}
|
||
|
||
a-tab-pane .ant-tabs-tab {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #ffffff;
|
||
/* 确保未选中的 Tab 文字为白色 */
|
||
padding: 10px 20px;
|
||
}
|
||
|
||
a-tab-pane .ant-tabs-tab-active {
|
||
background-color: #ff8c00;
|
||
/* 激活的Tab颜色 */
|
||
color: #ffffff;
|
||
}
|
||
|
||
a-tab-pane .ant-tabs-tab:hover {
|
||
color: #ffffff;
|
||
/* hover时也为白色 */
|
||
}
|
||
|
||
:deep .ant-tabs-tab-btn {
|
||
color: white;
|
||
}
|
||
</style>
|