Browse Source

能管平台

bl_ai
selia-zx 2 weeks ago committed by 25604
parent
commit
6e277f9422
  1. 34
      src/router/index.js
  2. 170
      src/views/centerairC/aabRecord/index.vue
  3. 538
      src/views/comprehensiveEnergy/reportData/index.vue
  4. 1748
      src/views/newCenterairC/alarmManage/index.vue
  5. 1117
      src/views/newCenterairC/deviceManage/index.vue
  6. 943
      src/views/newCenterairC/energyManage/carbonEmissionsAnalysis/index.vue
  7. 2542
      src/views/newCenterairC/energyManage/energyConsumptionEfficiencyTrend/index.vue
  8. 887
      src/views/newCenterairC/energyManage/energyEfficiencyCalendarViz/index.vue
  9. 1041
      src/views/newCenterairC/energyManage/retrofitEffectivenessCompariso/index.vue
  10. 1280
      src/views/newCenterairC/home/index.vue
  11. 1210
      src/views/newCenterairC/reportManage/base/index.vue
  12. 1268
      src/views/newCenterairC/reportManage/machine/index.vue
  13. 531
      src/views/newCenterairC/sysMonitor/components/hostChart.vue
  14. 120
      src/views/newCenterairC/sysMonitor/components/lineChildren.vue
  15. 67
      src/views/newCenterairC/sysMonitor/components/lineSquare.vue
  16. 450
      src/views/newCenterairC/sysMonitor/components/loadData.vue
  17. 416
      src/views/newCenterairC/sysMonitor/components/performanceChart.vue
  18. 15
      src/views/newCenterairC/sysMonitor/components/titleImg.vue
  19. 2059
      src/views/newCenterairC/sysMonitor/hostDetails.vue
  20. 20
      src/views/newCenterairC/sysMonitor/index.vue
  21. 4668
      src/views/newCenterairC/sysMonitor/monitorCenter.vue
  22. 736
      src/views/newCenterairC/sysMonitor/performance.vue
  23. 1752
      src/views/newLifeWater/alarmManage/index.vue
  24. 1546
      src/views/newLifeWater/deviceManage/info/index.vue
  25. 2174
      src/views/newLifeWater/energyManage/energyConsumptionEfficiencyTrend/index.vue
  26. 1774
      src/views/newLifeWater/energyManage/energyWater/index.vue
  27. 1691
      src/views/newLifeWater/energyManage/retrofitEffectivenessCompariso/index.vue
  28. 1732
      src/views/newLifeWater/energyManage/warning/index.vue
  29. 1470
      src/views/newLifeWater/home/index.vue
  30. 1425
      src/views/newLifeWater/reportManage/base/index.vue
  31. 1748
      src/views/newLighting/alarmManage/index.vue
  32. 1378
      src/views/newLighting/deviceManage/info/index.vue
  33. 1201
      src/views/newLighting/deviceManage/strategy/index.vue
  34. 1854
      src/views/newLighting/energyManage/energyConsumptionEfficiencyTrend/index.vue
  35. 1738
      src/views/newLighting/energyManage/retrofitEffectivenessCompariso/index.vue
  36. 1515
      src/views/newLighting/energyManage/warning/index.vue
  37. 1317
      src/views/newLighting/home/index.vue
  38. 1210
      src/views/newLighting/reportManage/base/index.vue
  39. 765
      src/views/newSystem/systemDevice.vue
  40. 608
      src/views/newSystem/systemEnergy.vue
  41. 503
      src/views/newSystem/systemHome.vue

34
src/router/index.js

@ -68,7 +68,7 @@ export const constantRoutes = [
children: [ children: [
{ {
path: "index", path: "index",
component: () => import("@/views/index"), component: () => import("@/views/newSystem/systemHome"),
name: "Index", name: "Index",
meta: { title: "首页", icon: "dashboard", affix: true }, meta: { title: "首页", icon: "dashboard", affix: true },
}, },
@ -88,22 +88,22 @@ export const constantRoutes = [
}, },
], ],
}, },
// 综合大屏 // 综合大屏
{ {
path: "/Screen", path: "/Screen",
name:"Screen", name: "Screen",
hidden: true, hidden: true,
component: () => import("@/views/bigScreen/bigScreen"), component: () => import("@/views/bigScreen/bigScreen"),
meta: { title: "大屏总览", icon: "screen" }, meta: { title: "大屏总览", icon: "screen" },
}, },
// AI助手 // AI助手
{ {
path: "/ai", path: "/ai",
name: "AI", name: "AI",
hidden: true, hidden: true,
component: () => import("@/views/ai/index"), component: () => import("@/views/ai/index"),
meta: { title: "AI助手", icon: "robot" }, meta: { title: "AI助手", icon: "robot" },
}, },
]; ];
// 动态路由,基于用户权限动态去加载 // 动态路由,基于用户权限动态去加载

170
src/views/centerairC/aabRecord/index.vue

@ -0,0 +1,170 @@
<!-- ChillerLoadEvent.vue -->
<template>
<div class="app-container">
<el-card shadow="hover">
<div slot="header" class="clearfix">
<span>冷水机组加减载事件</span>
<el-button style="float:right;" size="mini" @click="clearList">清空</el-button>
</div>
<el-table
:data="list"
stripe
height="750"
:row-class-name="tableRowClassName"
@row-click="openDetail"
>
<el-table-column prop="time" label="时间" />
<el-table-column prop="chillerName" label="机组" />
<el-table-column prop="action" label="动作" >
<template slot-scope="{ row }">
<el-tag size="mini" :type="row.action === '加载' ? 'danger' : 'primary'">
{{ row.action }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="cause" label="触发原因" show-overflow-tooltip />
<el-table-column prop="targetLoad" label="目标负荷%" />
<el-table-column prop="actualLoad" label="实际负荷%" />
</el-table>
</el-card>
<!-- 详情抽屉 -->
<el-drawer title="原始数据" :visible.sync="drawer" direction="rtl" size="50%">
<div style="padding:0 20px;">
<json-viewer :value="currentRow.raw" :expand-depth="3" copyable boxed sort />
</div>
</el-drawer>
</div>
</template>
<script>
export default {
name: 'ChillerLoadEvent',
data() {
return {
list: [
{
time: '2026-03-03 08:10:01',
chillerName: 'CH-01',
action: '加载',
cause: '供水温度高于设定值 1.2 ℃',
targetLoad: 75,
actualLoad: 73,
raw: { supplyTemp: 8.2, setpoint: 7.0, deltaT: 1.2, compCurrent: 92.3, compFreq: 45.0 }
},
{
time: '2026-03-03 08:15:23',
chillerName: 'CH-02',
action: '减载',
cause: '供水温度低于设定值 0.9 ℃',
targetLoad: 60,
actualLoad: 62,
raw: { supplyTemp: 6.1, setpoint: 7.0, deltaT: 0.9, compCurrent: 68.5, compFreq: 38.2 }
},
{
time: '2026-03-03 08:22:45',
chillerName: 'CH-03',
action: '加载',
cause: '系统负荷增加 15%',
targetLoad: 80,
actualLoad: 78,
raw: { supplyTemp: 8.5, setpoint: 7.0, deltaT: 1.5, compCurrent: 95.1, compFreq: 48.6 }
},
{
time: '2026-03-03 08:28:12',
chillerName: 'CH-01',
action: '减载',
cause: '电动阀开度 < 25%',
targetLoad: 55,
actualLoad: 57,
raw: { supplyTemp: 6.3, setpoint: 7.0, deltaT: 0.7, compCurrent: 65.4, compFreq: 35.0 }
},
{
time: '2026-03-03 08:33:56',
chillerName: 'CH-02',
action: '加载',
cause: '回水温度超上限 0.8 ℃',
targetLoad: 78,
actualLoad: 76,
raw: { supplyTemp: 8.0, setpoint: 7.0, deltaT: 1.0, compCurrent: 90.0, compFreq: 46.2 }
},
{
time: '2026-03-03 08:39:30',
chillerName: 'CH-03',
action: '减载',
cause: '回水温度低于下限 1.1 ℃',
targetLoad: 50,
actualLoad: 52,
raw: { supplyTemp: 5.9, setpoint: 7.0, deltaT: 1.1, compCurrent: 60.0, compFreq: 32.5 }
},
{
time: '2026-03-03 08:45:11',
chillerName: 'CH-01',
action: '加载',
cause: '电动阀开度 > 95%',
targetLoad: 85,
actualLoad: 83,
raw: { supplyTemp: 8.7, setpoint: 7.0, deltaT: 1.7, compCurrent: 98.2, compFreq: 49.8 }
},
{
time: '2026-03-03 08:51:44',
chillerName: 'CH-02',
action: '减载',
cause: '系统负荷下降 12%',
targetLoad: 65,
actualLoad: 67,
raw: { supplyTemp: 6.5, setpoint: 7.0, deltaT: 0.5, compCurrent: 70.1, compFreq: 37.0 }
},
{
time: '2026-03-03 08:57:25',
chillerName: 'CH-03',
action: '加载',
cause: '供水温度高于设定值 1.0 ℃',
targetLoad: 72,
actualLoad: 70,
raw: { supplyTemp: 8.0, setpoint: 7.0, deltaT: 1.0, compCurrent: 88.5, compFreq: 44.3 }
},
{
time: '2026-03-03 09:03:05',
chillerName: 'CH-01',
action: '减载',
cause: '供水温度低于设定值 1.2 ℃',
targetLoad: 48,
actualLoad: 50,
raw: { supplyTemp: 5.8, setpoint: 7.0, deltaT: 1.2, compCurrent: 58.7, compFreq: 30.2 }
}
],
drawer: false,
currentRow: {}
}
},
methods: {
clearList() {
this.$confirm('确定清空所有记录?', '提示', { type: 'warning' }).then(() => {
this.list = []
})
},
tableRowClassName({ row }) {
return row.action === '加载' ? 'load-row' : 'unload-row'
},
openDetail(row) {
this.currentRow = row
this.drawer = true
}
}
}
</script>
<style scoped>
.app-container {
padding: 20px;
}
.load-row {
background-color: #fff5f5 !important;
}
.unload-row {
background-color: #f0f9ff !important;
}
</style>

538
src/views/comprehensiveEnergy/reportData/index.vue

@ -0,0 +1,538 @@
<template>
<div class="main-body">
<div class="irregular-border">
<div class="export main-content">
<div class="condition">
<div class="condition-left">
<div class="condition-btn">
<div
class="legend-li"
v-for="(item, index) in timeData"
:key="index"
@click="handleEnter(index)"
:class="{ timeStyle: timeIndex == index }"
>
{{ item.title }}
</div>
</div>
<div v-if="this.timeIndex == '0'">
<el-date-picker
v-model="dayData"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
></el-date-picker>
</div>
<div v-if="this.timeIndex == '1'">
<el-date-picker
v-model="monthData"
type="month"
value-format="yyyy-MM"
placeholder="选择月"
></el-date-picker>
</div>
<el-button
type="success"
style="margin-left: 0.24rem"
@click="findData"
>查询</el-button
>
</div>
<div class="condition-right">
<el-button type="warning" @click="exportData">导出</el-button>
<el-button type="primary" @click="leadingPrint">打印</el-button>
</div>
</div>
<div class="table-content">
<div class="table-title">{{ this.curDate }}{{ this.tableTitle }}</div>
<el-table
:data="tableData"
border
v-loading="listLoading"
:cell-style="cellStyle"
>
<el-table-column label="项目" prop="name"></el-table-column>
<el-table-column
:label="this.tableTitle === '日报表' ? '当日数据' : '当月数据'"
prop="value"
></el-table-column>
<el-table-column
:label="this.tableTitle === '日报表' ? '上日数据' : '上月数据'"
prop="lastValue"
></el-table-column>
<el-table-column label="同期数据" prop="yoyValue"></el-table-column>
<el-table-column label="环比" prop="mom"></el-table-column>
<el-table-column label="同比" prop="yoy"></el-table-column>
</el-table>
</div>
</div>
<el-dialog
:visible.sync="dialogPrintVisible"
title="打印预览"
width="900px"
>
<div id="report" ref="report" class="report">
<!-- <div class="print-title">铭汉云热水充值明细</div> -->
<table
border="1"
style="
table-layout: fixed;
width: 100%;
border: 1px solid #e2e6f0;
margin-bottom: 35px;
"
>
<thead>
<tr>
<th align="center">项目</th>
<th align="center" v-if="this.tableTitle == '日报表'">
当日数据
</th>
<th align="center" v-else>当月数据</th>
<th align="center" v-if="this.tableTitle == '日报表'">
上日数据
</th>
<th align="center" v-else>上月数据</th>
<th align="center">同期数据</th>
<th align="center">环比</th>
<th align="center">同比</th>
</tr>
</thead>
<tr v-for="(item, index) in tableData" :key="index">
<td style="word-break: break-word" align="center">
{{ item.name }}
</td>
<td align="center">{{ item.value }}</td>
<td align="center">{{ item.lastValue }}</td>
<td align="center">{{ item.yoyValue }}</td>
<td style="word-break: break-word" align="center">
{{ item.mom }}
</td>
<td style="word-break: break-word" align="center">
{{ item.yoy }}
</td>
</tr>
</table>
<div
class="detail"
style="
display: flex;
flex-direction: row;
font-size: 14px;
justify-content: space-between;
flex-wrap: nowrap;
width: 40%;
color: #ffffff;
"
>
<div>操作员: {{ this.userName }}</div>
<div class="print-date">日期 {{ this.operationDate }}</div>
</div>
</div>
<el-row type="flex" justify="end" style="margin-top: 0.2rem">
<el-col :span="2">
<el-button type="info" @click="dialogPrintVisible = false"
>取消</el-button
>
</el-col>
<el-col :span="2" style="margin-left: 60px">
<el-button type="success" @click="surePrint">确认</el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</div>
</template>
<script>
import { getDay, getMonth, getYear } from "@/utils/datetime";
export default {
data() {
return {
listLoading: false,
timeData: [{ title: "日报表" }, { title: "月报表" }, { title: "年报表" }],
timeIndex: 0, //
tableTitle: "日报表",
dayData: "",
monthData: "",
type: "", //
curDate: "", //
tableData: [],
dialogPrintVisible: false,
userName: "", //
operationDate: getDay(0), //
};
},
created() {
this.getInitializeDate(); //1
},
mounted() {
this.userName = sessionStorage.getItem("userName");
this.getTableData();
},
methods: {
cellStyle({ row, column, rowIndex, columnIndex }) {
if (
(parseFloat(row.mom) < 0 && columnIndex === 4) ||
(parseFloat(row.yoy) < 0 && columnIndex === 5)
) {
return { color: "#dc6565" };
} else if (
(parseFloat(row.mom) > 0 && columnIndex === 4) ||
(parseFloat(row.yoy) > 0 && columnIndex === 5)
) {
return { color: "#11dbb1" };
} else {
return "";
}
},
//
getInitializeDate() {
this.dayData = getDay(0);
this.monthData = getMonth(0);
},
handleEnter(index) {
this.timeIndex = index;
},
getTableData() {
if (this.timeIndex == "0") {
(this.type = "day"), (this.curDate = this.dayData);
} else {
(this.type = "month"), (this.curDate = this.monthData);
}
let data = {
type: this.type,
curDate: this.curDate,
};
this.listLoading = true;
console.log("用户管理-查询", data);
this.tableData = [
{
name: "气温(℃)",
value: "0.00~0.00",
lastValue: "0.00~0.00",
yoyValue: "0.00~0.00",
mom: "",
yoy: "",
},
{
name: "开机时间",
value: "2026-03-04 00:01:29",
lastValue: "2026-03-03 00:00:30",
yoyValue: "",
mom: "开机延迟0.98分钟",
yoy: "同期无数据",
},
{
name: "关机时间",
value: "2026-03-04 08:41:30",
lastValue: "2026-03-03 23:57:36",
yoyValue: "",
mom: "关机提前916.10分钟",
yoy: "同期无数据",
},
{
name: "运行时长",
value: "0天8小时40分",
lastValue: "0天23小时57分",
yoyValue: "",
mom: "运行减少917.08分钟",
yoy: "同期无数据",
},
{
name: "产冷量(kwr)",
value: "230",
lastValue: "505",
yoyValue: "",
mom: "-54.00%",
yoy: "同期无数据",
},
{
name: "耗电量(kwh)",
value: "498",
lastValue: "1096",
yoyValue: "332",
mom: "-55.00%",
yoy: "50.00%",
},
{
name: "主机耗电量(kwh)",
value: "170",
lastValue: "321",
yoyValue: "192",
mom: "-47.00%",
yoy: "-11.00%",
},
{
name: "主机COP",
value: "1.35",
lastValue: "1.57",
yoyValue: "0",
mom: "-14.00%",
yoy: "0%",
},
{
name: "主机耗电占比(%)",
value: "34.14",
lastValue: "29.29",
yoyValue: "0",
mom: "17.00%",
yoy: "0%",
},
{
name: "冷站EER",
value: "0.46",
lastValue: "0.46",
yoyValue: "0",
mom: "0%",
yoy: "0%",
},
];
// this.$api.dataReport.dataReport(data).then((res) => {
// console.log("", res);
// if (res.code == 200) {
// this.tableData = res.data.map(obj => {
// if (obj.name == 'startupTime') {
// obj.name = ''
// } else if (obj.name == 'shutdownTime') {
// obj.name = ''
// } else if (obj.name == 'runTime') {
// obj.name = ''
// } else if (obj.name == 'totalCoolCap') {
// obj.name = '(kwr)'
// } else if (obj.name == 'totalEleUsed') {
// obj.name = '(kwh)'
// } else if (obj.name == 'cop') {
// obj.name = 'EER'
// } else if (obj.name == 'temp') {
// obj.name = '()'
// } else if (obj.name == 'hostEleUsed') {
// obj.name = '(kwh)'
// } else if (obj.name == 'hostCop') {
// obj.name = 'COP'
// } else if (obj.name == 'hostEleLoad') {
// obj.name = '(%)'
// }
// return obj
// });
// }
// });
// Just to simulate the time of the request
setTimeout(() => {
this.listLoading = false;
}, 1.0 * 1000);
},
//
findData() {
console.log(
"this.curDate",
this.tableTitle,
this.curDate,
this.dayData,
this.monthData
);
if (this.timeIndex == 0) {
this.tableTitle = "日报表";
} else {
this.tableTitle = "月报表";
}
console.log("标题", this.tableTitle);
if (this.dayData === null || this.monthData === null) {
this.getInitializeDate();
this.getTableData();
} else {
this.getTableData();
}
},
//
exportData() {
import("@/assets/excel/Export2Excel").then((excel) => {
let outTitle = "";
let ourDate = "";
if (this.dayData === null || this.monthData === null) {
this.getInitializeDate();
}
if (this.timeIndex == "0") {
(this.type = "day"), (outTitle = "日报表");
ourDate = this.dayData;
} else {
(this.type = "month"), (outTitle = "月报表");
ourDate = this.monthData;
}
let data = {
type: this.type,
curDate: ourDate,
};
console.log("导出标题日期", outTitle, ourDate);
console.log("报表导出-导出", data);
this.$api.dataReport
.dataReport(data)
.then((res) => {
if (res.code == 200) {
const filterVal = [
"name",
"value",
"lastValue",
"yoyValue",
"mom",
"yoy",
]; // excel
let tHeader;
if (this.timeIndex == "0") {
tHeader = [
"项目",
"当日数据",
"上日数据",
"同期数据",
"环比",
"同比",
]; // excel
} else {
tHeader = [
"项目",
"当月数据",
"上月数据",
"同期数据",
"环比",
"同比",
]; // excel
}
const outTableData = res.data.map((obj) => {
if (obj.name == "startupTime") {
obj.name = "开机时间";
} else if (obj.name == "shutdownTime") {
obj.name = "关机时间";
} else if (obj.name == "runTime") {
obj.name = "运行时长";
} else if (obj.name == "totalCoolCap") {
obj.name = "产冷量(kwr)";
} else if (obj.name == "totalEleUsed") {
obj.name = "耗电量(kwh)";
} else if (obj.name == "cop") {
obj.name = "冷站EER";
} else if (obj.name == "temp") {
obj.name = "气温(℃)";
} else if (obj.name == "hostEleUsed") {
obj.name = "主机耗电量(kwh)";
} else if (obj.name == "hostCop") {
obj.name = "主机COP";
} else if (obj.name == "hostEleLoad") {
obj.name = "主机耗电占比(%)";
}
return obj;
});
const data = this.formatJson(filterVal, outTableData);
const autoWidth = true;
excel.export_json_to_excel({
header: tHeader, //
data, //
filename: `${outTitle + "_" + ourDate}`, //, //
autoWidth: true, //
});
} else {
this.$message.error("导出失败!");
}
})
.catch((err) => {
this.$message.error("导出失败!");
});
});
},
//,
formatJson(filterVal, jsonData) {
return jsonData.map((v) =>
filterVal.map((j) => {
if (j === "installDate") {
return format(v[j]);
} else {
return v[j];
}
})
);
},
//
leadingPrint() {
this.dialogPrintVisible = true;
},
//
surePrint() {
const printHTML = document.querySelector("#report").innerHTML;
//
window.document.body.innerHTML = printHTML;
window.print(); // window
window.location.reload(); //
},
},
};
</script>
<style lang="scss" scoped>
.export {
align-items: center;
min-height: 7.4rem;
.condition {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
.condition-left {
display: flex;
flex-direction: row;
align-items: center;
.condition-btn {
display: flex;
flex-direction: row;
overflow: hidden;
cursor: pointer;
border-radius: 4px;
margin-right: 0.24rem;
background-color: #1c285c;
.legend-li {
text-align: center;
padding: 10px 26px;
white-space: nowrap;
font-size: 16px;
color: #7394a8;
}
.timeStyle {
color: #ffffff !important;
background-color: #0c3ec7;
border: 1px solid #0c3ec7;
}
}
}
.condition-right {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
}
.table-content {
width: 100%;
margin-top: 20px;
padding: 0 0.2rem;
font-size: 0.22rem;
line-height: 0.13rem;
color: #ffffff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.table-title {
margin-bottom: 0.2rem;
}
}
}
</style>

1748
src/views/newCenterairC/alarmManage/index.vue

File diff suppressed because it is too large Load Diff

1117
src/views/newCenterairC/deviceManage/index.vue

File diff suppressed because it is too large Load Diff

943
src/views/newCenterairC/energyManage/carbonEmissionsAnalysis/index.vue

@ -0,0 +1,943 @@
<template>
<div class="carbon-emissions-analysis">
<!-- 时间选择器 -->
<div class="time-selector">
<div class="selector-label">时间维度</div>
<div class="time-periods">
<div
v-for="(period, index) in timePeriods"
:key="index"
:class="['period-item', { active: activePeriod === index }]"
@click="handlePeriodChange(index)"
>
{{ period }}
</div>
</div>
<div class="date-range" v-if="activePeriod === 3">
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="handleDateChange"
class="custom-picker"
/>
</div>
</div>
<!-- 碳排放核心指标 -->
<div class="carbon-indicators">
<div class="indicator-card primary">
<div class="card-header">
<div class="card-icon">
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/>
<path d="M464 336a48 48 0 1096 0 48 48 0 10-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z" fill="currentColor"/>
</svg>
</div>
<div class="card-title">累计碳排放</div>
</div>
<div class="card-value">{{ carbonIndicators.totalCarbon }} <span class="unit">tCO₂e</span></div>
<div class="card-trend" :class="carbonIndicators.carbonTrend >= 0 ? 'up' : 'down'">
<span v-if="carbonIndicators.carbonTrend >= 0"></span>
<span v-else></span>
{{ Math.abs(carbonIndicators.carbonTrend) }}%
</div>
</div>
<div class="indicator-card success">
<div class="card-header">
<div class="card-icon">
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/>
<path d="M672 464H352c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h320c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16z" fill="currentColor"/>
<path d="M512 592c-4.4 0-8 3.6-8 8v256c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V600c0-4.4-3.6-8-8-8h-48z" fill="currentColor"/>
</svg>
</div>
<div class="card-title">累计碳减排</div>
</div>
<div class="card-value">{{ carbonIndicators.totalReduction }} <span class="unit">tCO₂e</span></div>
<div class="card-trend" :class="carbonIndicators.reductionTrend >= 0 ? 'up' : 'down'">
<span v-if="carbonIndicators.reductionTrend >= 0"></span>
<span v-else></span>
{{ Math.abs(carbonIndicators.reductionTrend) }}%
</div>
</div>
<div class="indicator-card warning">
<div class="card-header">
<div class="card-icon">
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/>
<path d="M512 352c-8.8 0-16 7.2-16 16v224c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16h-48z" fill="currentColor"/>
<path d="M536 672h-72c-4.4 0-8 3.6-8 8v72c0 4.4 3.6 8 8 8h72c4.4 0 8-3.6 8-8v-72c0-4.4-3.6-8-8-8z" fill="currentColor"/>
</svg>
</div>
<div class="card-title">碳强度</div>
</div>
<div class="card-value">{{ carbonIndicators.carbonIntensity }} <span class="unit">kgCO₂/kWh</span></div>
<div class="card-trend" :class="carbonIndicators.intensityTrend >= 0 ? 'up' : 'down'">
<span v-if="carbonIndicators.intensityTrend >= 0"></span>
<span v-else></span>
{{ Math.abs(carbonIndicators.intensityTrend) }}%
</div>
</div>
<div class="indicator-card info">
<div class="card-header">
<div class="card-icon">
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/>
<path d="M688 464H336c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h352c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16z" fill="currentColor"/>
<path d="M688 592H336c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h352c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16z" fill="currentColor"/>
</svg>
</div>
<div class="card-title">节能率</div>
</div>
<div class="card-value">{{ carbonIndicators.energySavingRate }} <span class="unit">%</span></div>
<div class="card-trend" :class="carbonIndicators.savingTrend >= 0 ? 'up' : 'down'">
<span v-if="carbonIndicators.savingTrend >= 0"></span>
<span v-else></span>
{{ Math.abs(carbonIndicators.savingTrend) }}%
</div>
</div>
</div>
<!-- 碳排放趋势图 -->
<div class="chart-section">
<div class="chart-header">
<div class="chart-title">碳排放趋势</div>
<div class="chart-legend">
<div class="legend-item">
<span class="legend-dot" style="background: #EE6666;"></span>
<span>碳排放量</span>
</div>
<div class="legend-item">
<span class="legend-dot" style="background: #91CC75;"></span>
<span>碳减排量</span>
</div>
</div>
</div>
<div class="chart" ref="carbonTrendChartRef"></div>
</div>
<!-- 碳排放来源分布 -->
<div class="chart-section half-width">
<div class="chart-header">
<div class="chart-title">碳排放来源分布</div>
</div>
<div class="chart" ref="carbonSourceChartRef"></div>
</div>
<!-- 能耗与碳排放对比 -->
<div class="chart-section half-width">
<div class="chart-header">
<div class="chart-title">能耗与碳排放对比</div>
</div>
<div class="chart" ref="energyCarbonChartRef"></div>
</div>
<!-- 碳减排量详情表格 -->
<div class="table-section">
<div class="section-header">
<div class="section-title">碳减排量详情</div>
<el-button type="primary" size="small" @click="exportData">导出数据</el-button>
</div>
<div class="table-container">
<table class="data-table">
<thead>
<tr>
<th>日期</th>
<th>用电量(kWh)</th>
<th>碳排放量(tCO₂e)</th>
<th>基准碳排放(tCO₂e)</th>
<th>碳减排量(tCO₂e)</th>
<th>碳减排率(%)</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in carbonDetailList" :key="index">
<td>{{ item.date }}</td>
<td>{{ item.energy }}</td>
<td>{{ item.carbon }}</td>
<td>{{ item.baselineCarbon }}</td>
<td>{{ item.reduction }}</td>
<td>{{ item.reductionRate }}%</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 碳减排贡献分析 -->
<div class="contribution-section">
<div class="section-header">
<div class="section-title">碳减排贡献分析</div>
</div>
<div class="contribution-grid">
<div class="contribution-item" v-for="item in contributionList" :key="item.name">
<div class="contribution-icon" :style="{ background: item.bg }">
<span>{{ item.icon }}</span>
</div>
<div class="contribution-info">
<div class="contribution-name">{{ item.name }}</div>
<div class="contribution-value">{{ item.value }} <span class="unit">tCO₂e</span></div>
<div class="contribution-percent">{{ item.percent }}%</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "CarbonEmissionsAnalysis",
data() {
return {
//
timePeriods: ["近七日", "近一月", "近三月", "自定义"],
activePeriod: 0,
//
dateRange: [],
//
carbonIndicators: {
totalCarbon: 1256.8,
carbonTrend: -5.2,
totalReduction: 89.6,
reductionTrend: 12.5,
carbonIntensity: 0.52,
intensityTrend: -3.8,
energySavingRate: 28.5,
savingTrend: 2.3
},
//
carbonDetailList: [
{ date: "2024-03-01", energy: 178000, carbon: 92.56, baselineCarbon: 129.5, reduction: 36.94, reductionRate: 28.5 },
{ date: "2024-03-02", energy: 189000, carbon: 98.28, baselineCarbon: 137.5, reduction: 39.22, reductionRate: 28.5 },
{ date: "2024-03-03", energy: 197000, carbon: 102.44, baselineCarbon: 143.3, reduction: 40.86, reductionRate: 28.5 },
{ date: "2024-03-04", energy: 181000, carbon: 94.12, baselineCarbon: 131.6, reduction: 37.48, reductionRate: 28.5 },
{ date: "2024-03-05", energy: 204000, carbon: 106.08, baselineCarbon: 148.4, reduction: 42.32, reductionRate: 28.5 }
],
//
contributionList: [
{ name: "能效提升", icon: "EER", value: 45.6, percent: 50.9, bg: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)" },
{ name: "设备优化", icon: "设备", value: 25.8, percent: 28.8, bg: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)" },
{ name: "运行策略", icon: "策略", value: 12.3, percent: 13.7, bg: "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)" },
{ name: "其他措施", icon: "其他", value: 5.9, percent: 6.6, bg: "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)" }
],
//
carbonTrendChart: null,
carbonSourceChart: null,
energyCarbonChart: null
};
},
mounted() {
this.initCarbonTrendChart();
this.initCarbonSourceChart();
this.initEnergyCarbonChart();
window.addEventListener("resize", this.handleResize);
},
beforeDestroy() {
window.removeEventListener("resize", this.handleResize);
if (this.carbonTrendChart) this.carbonTrendChart.dispose();
if (this.carbonSourceChart) this.carbonSourceChart.dispose();
if (this.energyCarbonChart) this.energyCarbonChart.dispose();
},
watch: {
activePeriod() {
this.updateAllCharts();
}
},
methods: {
//
handlePeriodChange(index) {
this.activePeriod = index;
},
//
handleDateChange(value) {
console.log("自定义日期范围:", value);
this.updateAllCharts();
},
//
exportData() {
this.$message.success("数据导出成功");
},
//
initCarbonTrendChart() {
this.carbonTrendChart = echarts.init(this.$refs.carbonTrendChartRef);
this.updateCarbonTrendChart();
},
//
updateCarbonTrendChart() {
const dataMap = {
0: { //
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
carbon: [92.56, 98.28, 102.44, 94.12, 106.08, 112.56, 104.76],
reduction: [36.94, 39.22, 40.86, 37.48, 42.32, 44.96, 41.76]
},
1: { //
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"],
carbon: [856, 912, 888, 945, 1012, 956, 892],
reduction: [341.6, 364.8, 355.2, 378, 404.8, 382.4, 356.8]
},
2: { //
xData: ["1月", "2月", "3月"],
carbon: [24120, 27360, 25680],
reduction: [9648, 10944, 10272]
},
3: { //
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
carbon: [92.56, 98.28, 102.44, 94.12, 106.08, 112.56, 104.76],
reduction: [36.94, 39.22, 40.86, 37.48, 42.32, 44.96, 41.76]
}
};
const currentData = dataMap[this.activePeriod];
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross"
}
},
legend: {
data: ["碳排放量", "碳减排量"],
textStyle: {
color: "#ffffff"
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
data: currentData.xData,
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: {
type: "value",
name: "tCO₂e",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
series: [
{
name: "碳排放量",
type: "bar",
data: currentData.carbon,
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#EE6666"
},
{
offset: 1,
color: "#E53935"
}
]
}
}
},
{
name: "碳减排量",
type: "line",
smooth: true,
data: currentData.reduction,
itemStyle: {
color: "#91CC75"
},
lineStyle: {
color: "#91CC75",
width: 3
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(145, 204, 117, 0.5)"
},
{
offset: 1,
color: "rgba(145, 204, 117, 0)"
}
]
}
}
}
]
};
this.carbonTrendChart.setOption(option);
},
//
initCarbonSourceChart() {
this.carbonSourceChart = echarts.init(this.$refs.carbonSourceChartRef);
const option = {
tooltip: {
trigger: "item",
formatter: "{b}: {c}% ({d}%)"
},
legend: {
orient: "vertical",
left: "left",
textStyle: {
color: "#ffffff"
}
},
series: [
{
name: "碳排放来源",
type: "pie",
radius: ["30%", "70%"],
center: ["60%", "50%"],
data: [
{ value: 65, name: "主机", itemStyle: { color: "#5470C6" } },
{ value: 20, name: "冷冻泵", itemStyle: { color: "#91CC75" } },
{ value: 10, name: "冷却泵", itemStyle: { color: "#FAC858" } },
{ value: 3, name: "冷却塔风机", itemStyle: { color: "#EE6666" } },
{ value: 2, name: "其他", itemStyle: { color: "#73C0DE" } }
],
label: {
formatter: "{b}\n{d}%"
}
}
]
};
this.carbonSourceChart.setOption(option);
},
//
initEnergyCarbonChart() {
this.energyCarbonChart = echarts.init(this.$refs.energyCarbonChartRef);
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross"
}
},
legend: {
data: ["用电量", "碳排放量"],
textStyle: {
color: "#ffffff"
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: [
{
type: "value",
name: "kWh",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
{
type: "value",
name: "tCO₂e",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
show: false
}
}
],
series: [
{
name: "用电量",
type: "bar",
data: [178000, 189000, 197000, 181000, 204000, 215000, 200000],
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#15e1fd"
},
{
offset: 1,
color: "#208fff"
}
]
}
}
},
{
name: "碳排放量",
type: "line",
smooth: true,
yAxisIndex: 1,
data: [92.56, 98.28, 102.44, 94.12, 106.08, 112.56, 104.76],
itemStyle: {
color: "#EE6666"
},
lineStyle: {
color: "#EE6666",
width: 3
}
}
]
};
this.energyCarbonChart.setOption(option);
},
//
updateAllCharts() {
this.updateCarbonTrendChart();
},
//
handleResize() {
if (this.carbonTrendChart) this.carbonTrendChart.resize();
if (this.carbonSourceChart) this.carbonSourceChart.resize();
if (this.energyCarbonChart) this.energyCarbonChart.resize();
}
}
};
</script>
<style lang="scss" scoped>
.carbon-emissions-analysis {
padding: 0.16rem;
}
.time-selector {
display: flex;
align-items: center;
padding: 0.2rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
margin-bottom: 0.16rem;
flex-wrap: wrap;
gap: 0.15rem;
.selector-label {
font-size: 0.15rem;
color: #ffffff;
margin-right: 0.15rem;
}
.time-periods {
display: flex;
gap: 0.08rem;
.period-item {
padding: 0.06rem 0.2rem;
font-size: 0.13rem;
color: #ffffff;
opacity: 0.7;
cursor: pointer;
border-radius: 0.04rem;
transition: all 0.3s;
&:hover {
opacity: 1;
}
&.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
opacity: 1;
}
}
}
.date-range {
margin-left: 0.15rem;
::v-deep .custom-picker {
.el-input__wrapper {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
.el-input__inner {
color: #ffffff;
}
}
}
}
}
.carbon-indicators {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(2.5rem, 1fr));
gap: 0.15rem;
margin-bottom: 0.16rem;
.indicator-card {
padding: 0.25rem;
border-radius: 0.08rem;
&.primary {
background: linear-gradient(135deg, rgba(238, 102, 102, 0.2) 0%, rgba(229, 57, 53, 0.2) 100%);
border: 1px solid rgba(238, 102, 102, 0.3);
}
&.success {
background: linear-gradient(135deg, rgba(145, 204, 117, 0.2) 0%, rgba(102, 187, 106, 0.2) 100%);
border: 1px solid rgba(145, 204, 117, 0.3);
}
&.warning {
background: linear-gradient(135deg, rgba(250, 200, 88, 0.2) 0%, rgba(255, 179, 0, 0.2) 100%);
border: 1px solid rgba(250, 200, 88, 0.3);
}
&.info {
background: linear-gradient(135deg, rgba(84, 112, 198, 0.2) 0%, rgba(115, 192, 222, 0.2) 100%);
border: 1px solid rgba(84, 112, 198, 0.3);
}
.card-header {
display: flex;
align-items: center;
margin-bottom: 0.15rem;
.card-icon {
width: 0.4rem;
height: 0.4rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 0.12rem;
background: rgba(255, 255, 255, 0.1);
svg {
width: 0.2rem;
height: 0.2rem;
fill: #ffffff;
}
}
.card-title {
font-size: 0.14rem;
color: #ffffff;
opacity: 0.8;
}
}
.card-value {
font-size: 0.32rem;
color: #15e1fd;
font-weight: bold;
margin-bottom: 0.1rem;
.unit {
font-size: 0.16rem;
opacity: 0.8;
}
}
.card-trend {
font-size: 0.13rem;
&.up {
color: #EE6666;
}
&.down {
color: #91CC75;
}
}
}
}
.chart-section {
background: rgba(255, 255, 255, 0.03);
border-radius: 0.08rem;
padding: 0.2rem;
margin-bottom: 0.16rem;
&.half-width {
display: inline-block;
width: calc(50% - 0.08rem);
vertical-align: top;
&:nth-child(odd) {
margin-right: 0.16rem;
}
}
.chart-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.15rem;
.chart-title {
font-size: 0.16rem;
color: #ffffff;
font-weight: bold;
padding-left: 0.12rem;
border-left: 0.04rem solid #15e1fd;
}
.chart-legend {
display: flex;
gap: 0.2rem;
.legend-item {
display: flex;
align-items: center;
font-size: 0.13rem;
color: #ffffff;
.legend-dot {
width: 0.1rem;
height: 0.1rem;
border-radius: 50%;
margin-right: 0.06rem;
}
}
}
}
.chart {
width: 100%;
height: 3rem;
}
}
.table-section {
background: rgba(255, 255, 255, 0.03);
border-radius: 0.08rem;
padding: 0.2rem;
margin-bottom: 0.16rem;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.15rem;
.section-title {
font-size: 0.16rem;
color: #ffffff;
font-weight: bold;
padding-left: 0.12rem;
border-left: 0.04rem solid #15e1fd;
}
}
.table-container {
overflow-x: auto;
.data-table {
width: 100%;
border-collapse: collapse;
thead {
tr {
background: rgba(255, 255, 255, 0.05);
th {
padding: 0.12rem;
text-align: left;
font-size: 0.14rem;
color: #ffffff;
font-weight: bold;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
}
}
tbody {
tr {
&:hover {
background: rgba(255, 255, 255, 0.05);
}
td {
padding: 0.12rem;
font-size: 0.13rem;
color: #ffffff;
opacity: 0.8;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
}
}
}
}
}
.contribution-section {
background: rgba(255, 255, 255, 0.03);
border-radius: 0.08rem;
padding: 0.2rem;
.section-header {
margin-bottom: 0.15rem;
.section-title {
font-size: 0.16rem;
color: #ffffff;
font-weight: bold;
padding-left: 0.12rem;
border-left: 0.04rem solid #15e1fd;
}
}
.contribution-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(3rem, 1fr));
gap: 0.15rem;
.contribution-item {
display: flex;
align-items: center;
padding: 0.2rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.06rem;
.contribution-icon {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 0.15rem;
span {
font-size: 0.16rem;
color: #ffffff;
font-weight: bold;
}
}
.contribution-info {
flex: 1;
.contribution-name {
font-size: 0.14rem;
color: #ffffff;
opacity: 0.8;
margin-bottom: 0.05rem;
}
.contribution-value {
font-size: 0.2rem;
color: #15e1fd;
font-weight: bold;
margin-bottom: 0.03rem;
.unit {
font-size: 0.13rem;
opacity: 0.8;
}
}
.contribution-percent {
font-size: 0.12rem;
color: #91CC75;
}
}
}
}
}
@media (max-width: 1485px) {
.carbon-indicators {
grid-template-columns: repeat(2, 1fr);
}
.chart-section {
&.half-width {
width: 100%;
margin-right: 0;
}
}
.contribution-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>

2542
src/views/newCenterairC/energyManage/energyConsumptionEfficiencyTrend/index.vue

File diff suppressed because it is too large Load Diff

887
src/views/newCenterairC/energyManage/energyEfficiencyCalendarViz/index.vue

@ -0,0 +1,887 @@
<template>
<div class="energy-efficiency-calendar">
<!-- 顶部控制栏 -->
<div class="control-bar">
<div class="date-picker-group">
<el-date-picker
v-model="currentDate"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
@change="handleDateChange"
class="date-picker"
/>
<div class="view-toggle">
<div
v-for="(view, index) in viewTypes"
:key="index"
:class="['view-btn', { active: activeView === index }]"
@click="handleViewChange(index)"
>
{{ view }}
</div>
</div>
</div>
<div class="indicator-selector">
<el-select v-model="selectedIndicator" @change="handleIndicatorChange" class="custom-select">
<el-option
v-for="indicator in indicators"
:key="indicator.value"
:label="indicator.label"
:value="indicator.value"
>
<span class="option-dot" :style="{ background: indicator.color }"></span>
<span class="option-label">{{ indicator.label }}</span>
</el-option>
</el-select>
</div>
</div>
<!-- 月份导航 -->
<div class="month-navigation">
<el-button class="nav-btn" icon="el-icon-arrow-left" @click="prevMonth" size="small"></el-button>
<div class="current-month">{{ currentYear }}{{ currentMonth }}</div>
<el-button class="nav-btn" icon="el-icon-arrow-right" @click="nextMonth" size="small"></el-button>
</div>
<!-- 日历视图 -->
<div class="calendar-container">
<div class="calendar-header">
<div class="weekday" v-for="day in weekDays" :key="day">{{ day }}</div>
</div>
<div class="calendar-body">
<div
v-for="(day, index) in calendarDays"
:key="index"
:class="['calendar-day', { 'other-month': day.isOtherMonth, 'selected': isSelected(day), 'today': isToday(day) }]"
@click="handleDayClick(day)"
>
<div class="day-number">{{ day.day }}</div>
<div class="day-indicator" v-if="day.hasData">
<div class="indicator-value" :style="{ color: getIndicatorColor(day) }">
{{ getIndicatorValue(day) }}
</div>
<div class="indicator-unit">{{ getIndicatorUnit() }}</div>
</div>
</div>
</div>
</div>
<!-- 日期图例 -->
<div class="calendar-legend">
<div class="legend-item" v-for="item in legendItems" :key="item.label">
<span class="legend-color" :style="{ background: item.color }"></span>
<span class="legend-label">{{ item.label }}</span>
</div>
</div>
<!-- 日期详情面板 -->
<div class="detail-panel" v-if="selectedDateData">
<div class="detail-header">
<div class="detail-title">日期详情 - {{ selectedDateData.date }}</div>
<el-button class="close-btn" icon="el-icon-close" @click="closeDetail" size="small" circle></el-button>
</div>
<div class="detail-content">
<div class="detail-row" v-for="(item, index) in detailData" :key="index">
<div class="detail-label">
<span class="label-dot" :style="{ background: item.color }"></span>
{{ item.label }}
</div>
<div class="detail-value" :style="{ color: item.color }">
{{ selectedDateData[item.key] }} {{ item.unit }}
</div>
</div>
</div>
</div>
<!-- 月度汇总统计 -->
<div class="monthly-summary">
<div class="summary-header">
<div class="summary-title">月度汇总</div>
<div class="summary-period">{{ currentYear }}{{ currentMonth }}</div>
</div>
<div class="summary-cards">
<div class="summary-card">
<div class="summary-label">平均EER</div>
<div class="summary-value">{{ monthlySummary.avgEer }}</div>
</div>
<div class="summary-card">
<div class="summary-label">总用电量</div>
<div class="summary-value">{{ monthlySummary.totalEnergy }} <span class="unit">kWh</span></div>
</div>
<div class="summary-card">
<div class="summary-label">总供冷量</div>
<div class="summary-value">{{ monthlySummary.totalCooling }} <span class="unit">RT</span></div>
</div>
<div class="summary-card">
<div class="summary-label">平均单价</div>
<div class="summary-value">¥{{ monthlySummary.avgPrice }} <span class="unit">/kWh</span></div>
</div>
</div>
</div>
<!-- 趋势图 -->
<div class="trend-chart-section">
<div class="chart-header">
<div class="chart-title">{{ currentMonth }}月能效趋势</div>
</div>
<div class="chart" ref="trendChartRef"></div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "EnergyEfficiencyCalendarViz",
data() {
return {
//
viewTypes: ["日视图", "月视图"],
activeView: 1,
//
currentDate: new Date().toISOString().split('T')[0],
currentYear: new Date().getFullYear(),
currentMonth: new Date().getMonth() + 1,
selectedDay: null,
selectedDateData: null,
//
weekDays: ["日", "一", "二", "三", "四", "五", "六"],
//
indicators: [
{ label: "能效值(EER)", value: "eer", color: "#91CC75", unit: "" },
{ label: "用电量", value: "energy", color: "#5470C6", unit: "kWh" },
{ label: "供冷量", value: "cooling", color: "#15e1fd", unit: "RT" },
{ label: "供能单价", value: "price", color: "#FAC858", unit: "元/kWh" }
],
selectedIndicator: "eer",
//
calendarDays: [],
//
legendItems: [
{ label: "优秀(≥6.5)", color: "#91CC75" },
{ label: "良好(6.5-5.5)", color: "#4facfe" },
{ label: "一般(5.5-4.5)", color: "#FAC858" },
{ label: "急需改善(<4.5)", color: "#EE6666" }
],
//
detailData: [
{ label: "能效值(EER)", key: "eer", color: "#91CC75", unit: "" },
{ label: "用电量", key: "energy", color: "#5470C6", unit: "kWh" },
{ label: "供冷量", key: "cooling", color: "#15e1fd", unit: "RT" },
{ label: "供能单价", key: "price", color: "#FAC858", unit: "元/kWh" },
{ label: "节电量", key: "saving", color: "#EE6666", unit: "kWh" }
],
//
monthlySummary: {
avgEer: 6.5,
totalEnergy: 5620000,
totalCooling: 198500,
avgPrice: 1.18
},
//
dailyData: {},
//
trendChart: null
};
},
mounted() {
this.generateDailyData();
this.generateCalendar();
this.initTrendChart();
},
beforeDestroy() {
if (this.trendChart) this.trendChart.dispose();
},
methods: {
//
generateDailyData() {
const year = this.currentYear;
const month = this.currentMonth;
const daysInMonth = new Date(year, month, 0).getDate();
for (let day = 1; day <= daysInMonth; day++) {
const date = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
const eer = (4 + Math.random() * 4).toFixed(1);
const energy = Math.floor(150000 + Math.random() * 100000);
const cooling = Math.floor(energy / 25 + Math.random() * 10);
const price = (1.1 + Math.random() * 0.2).toFixed(2);
const saving = Math.floor(energy * 0.25 + Math.random() * 10000);
this.dailyData[date] = {
date,
eer: parseFloat(eer),
energy,
cooling,
price: parseFloat(price),
saving,
hasData: true
};
}
},
//
generateCalendar() {
const year = this.currentYear;
const month = this.currentMonth - 1;
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const prevMonthDays = new Date(year, month, 0).getDate();
const days = [];
//
for (let i = firstDay - 1; i >= 0; i--) {
days.push({
day: prevMonthDays - i,
isOtherMonth: true,
hasData: false
});
}
//
for (let i = 1; i <= daysInMonth; i++) {
const date = `${year}-${String(month + 1).padStart(2, '0')}-${String(i).padStart(2, '0')}`;
days.push({
day: i,
isOtherMonth: false,
...this.dailyData[date]
});
}
//
const remainingDays = 42 - days.length;
for (let i = 1; i <= remainingDays; i++) {
days.push({
day: i,
isOtherMonth: true,
hasData: false
});
}
this.calendarDays = days;
},
//
handleDateChange(value) {
if (value) {
const date = new Date(value);
this.currentYear = date.getFullYear();
this.currentMonth = date.getMonth() + 1;
this.selectedDay = date.getDate();
this.generateCalendar();
}
},
//
handleViewChange(index) {
this.activeView = index;
},
//
handleIndicatorChange(value) {
this.selectedIndicator = value;
},
//
prevMonth() {
if (this.currentMonth === 1) {
this.currentYear--;
this.currentMonth = 12;
} else {
this.currentMonth--;
}
this.generateCalendar();
this.updateTrendChart();
},
//
nextMonth() {
if (this.currentMonth === 12) {
this.currentYear++;
this.currentMonth = 1;
} else {
this.currentMonth++;
}
this.generateCalendar();
this.updateTrendChart();
},
//
handleDayClick(day) {
if (day.isOtherMonth || !day.hasData) return;
this.selectedDay = day.day;
this.selectedDateData = day;
},
//
isSelected(day) {
return !day.isOtherMonth && day.day === this.selectedDay;
},
//
isToday(day) {
if (day.isOtherMonth) return false;
const today = new Date();
return day.day === today.getDate() &&
this.currentMonth === today.getMonth() + 1 &&
this.currentYear === today.getFullYear();
},
//
getIndicatorColor(day) {
if (this.selectedIndicator !== 'eer') {
const indicator = this.indicators.find(i => i.value === this.selectedIndicator);
return indicator ? indicator.color : '#ffffff';
}
const eer = day.eer;
if (eer >= 6.5) return '#91CC75';
if (eer >= 5.5) return '#4facfe';
if (eer >= 4.5) return '#FAC858';
return '#EE6666';
},
//
getIndicatorValue(day) {
const key = this.selectedIndicator;
return day[key] !== undefined ? day[key] : '-';
},
//
getIndicatorUnit() {
const indicator = this.indicators.find(i => i.value === this.selectedIndicator);
return indicator ? indicator.unit : '';
},
//
closeDetail() {
this.selectedDateData = null;
this.selectedDay = null;
},
//
initTrendChart() {
this.trendChart = echarts.init(this.$refs.trendChartRef);
this.updateTrendChart();
},
//
updateTrendChart() {
const daysInMonth = new Date(this.currentYear, this.currentMonth, 0).getDate();
const xData = [];
const eerData = [];
const energyData = [];
for (let day = 1; day <= daysInMonth; day++) {
const date = `${this.currentYear}-${String(this.currentMonth).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
const data = this.dailyData[date];
xData.push(`${day}`);
eerData.push(data ? data.eer : null);
energyData.push(data ? data.energy : null);
}
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross"
}
},
legend: {
data: ["能效值(EER)", "用电量"],
textStyle: {
color: "#ffffff"
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
data: xData,
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: [
{
type: "value",
name: "EER",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
{
type: "value",
name: "kWh",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
show: false
}
}
],
series: [
{
name: "能效值(EER)",
type: "line",
smooth: true,
data: eerData,
itemStyle: {
color: "#91CC75"
},
lineStyle: {
color: "#91CC75",
width: 2
}
},
{
name: "用电量",
type: "bar",
yAxisIndex: 1,
data: energyData,
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#5470C6"
},
{
offset: 1,
color: "#73C0DE"
}
]
}
}
}
]
};
this.trendChart.setOption(option);
}
}
};
</script>
<style lang="scss" scoped>
.energy-efficiency-calendar {
padding: 0.16rem;
}
.control-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.2rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
margin-bottom: 0.16rem;
flex-wrap: wrap;
gap: 0.15rem;
.date-picker-group {
display: flex;
align-items: center;
gap: 0.15rem;
::v-deep .date-picker {
.el-input__wrapper {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
.el-input__inner {
color: #ffffff;
}
}
}
.view-toggle {
display: flex;
gap: 0.08rem;
.view-btn {
padding: 0.06rem 0.2rem;
font-size: 0.13rem;
color: #ffffff;
opacity: 0.7;
cursor: pointer;
border-radius: 0.04rem;
transition: all 0.3s;
&:hover {
opacity: 1;
}
&.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
opacity: 1;
}
}
}
}
.indicator-selector {
::v-deep .custom-select {
.el-input__wrapper {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
.el-input__inner {
color: #ffffff;
}
}
}
}
::v-deep .option-dot {
display: inline-block;
width: 0.1rem;
height: 0.1rem;
border-radius: 50%;
margin-right: 0.08rem;
}
}
.month-navigation {
display: flex;
justify-content: center;
align-items: center;
gap: 0.3rem;
padding: 0.15rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
margin-bottom: 0.16rem;
.current-month {
font-size: 0.18rem;
color: #ffffff;
font-weight: bold;
}
.nav-btn {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #ffffff;
&:hover {
background: rgba(255, 255, 255, 0.2);
}
}
}
.calendar-container {
background: rgba(255, 255, 255, 0.03);
border-radius: 0.08rem;
padding: 0.2rem;
margin-bottom: 0.16rem;
.calendar-header {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 0.1rem;
margin-bottom: 0.15rem;
.weekday {
text-align: center;
font-size: 0.15rem;
color: #ffffff;
font-weight: bold;
padding: 0.1rem 0;
}
}
.calendar-body {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 0.1rem;
.calendar-day {
aspect-ratio: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0.1rem;
border-radius: 0.06rem;
cursor: pointer;
transition: all 0.3s;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
&:hover {
background: rgba(255, 255, 255, 0.08);
}
&.other-month {
opacity: 0.3;
cursor: default;
&:hover {
background: rgba(255, 255, 255, 0.03);
}
}
&.selected {
background: rgba(21, 225, 253, 0.2);
border: 2px solid #15e1fd;
}
&.today {
background: rgba(145, 204, 117, 0.2);
border: 1px solid #91CC75;
}
.day-number {
font-size: 0.16rem;
color: #ffffff;
margin-bottom: 0.05rem;
}
.day-indicator {
text-align: center;
.indicator-value {
font-size: 0.14rem;
font-weight: bold;
}
.indicator-unit {
font-size: 0.1rem;
opacity: 0.7;
}
}
}
}
}
.calendar-legend {
display: flex;
justify-content: center;
gap: 0.3rem;
padding: 0.2rem;
background: rgba(255, 255, 255, 0.03);
border-radius: 0.08rem;
margin-bottom: 0.16rem;
flex-wrap: wrap;
.legend-item {
display: flex;
align-items: center;
font-size: 0.13rem;
color: #ffffff;
.legend-color {
width: 0.12rem;
height: 0.12rem;
border-radius: 50%;
margin-right: 0.08rem;
}
.legend-label {
opacity: 0.8;
}
}
}
.detail-panel {
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
padding: 0.2rem;
margin-bottom: 0.16rem;
.detail-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.15rem;
.detail-title {
font-size: 0.16rem;
color: #ffffff;
font-weight: bold;
padding-left: 0.12rem;
border-left: 0.04rem solid #15e1fd;
}
.close-btn {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #ffffff;
&:hover {
background: rgba(255, 255, 255, 0.2);
}
}
}
.detail-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(2rem, 1fr));
gap: 0.15rem;
.detail-row {
padding: 0.15rem;
background: rgba(255, 255, 255, 0.03);
border-radius: 0.06rem;
.detail-label {
font-size: 0.13rem;
color: #ffffff;
opacity: 0.7;
margin-bottom: 0.08rem;
display: flex;
align-items: center;
.label-dot {
width: 0.08rem;
height: 0.08rem;
border-radius: 50%;
margin-right: 0.08rem;
}
}
.detail-value {
font-size: 0.18rem;
font-weight: bold;
}
}
}
}
.monthly-summary {
background: rgba(255, 255, 255, 0.03);
border-radius: 0.08rem;
padding: 0.2rem;
margin-bottom: 0.16rem;
.summary-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.15rem;
.summary-title {
font-size: 0.16rem;
color: #ffffff;
font-weight: bold;
padding-left: 0.12rem;
border-left: 0.04rem solid #15e1fd;
}
.summary-period {
font-size: 0.14rem;
color: #ffffff;
opacity: 0.7;
}
}
.summary-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(2rem, 1fr));
gap: 0.15rem;
.summary-card {
padding: 0.2rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.06rem;
text-align: center;
.summary-label {
font-size: 0.13rem;
color: #ffffff;
opacity: 0.7;
margin-bottom: 0.1rem;
}
.summary-value {
font-size: 0.22rem;
color: #15e1fd;
font-weight: bold;
.unit {
font-size: 0.13rem;
opacity: 0.8;
}
}
}
}
}
.trend-chart-section {
background: rgba(255, 255, 255, 0.03);
border-radius: 0.08rem;
padding: 0.2rem;
.chart-header {
margin-bottom: 0.15rem;
.chart-title {
font-size: 0.16rem;
color: #ffffff;
font-weight: bold;
padding-left: 0.12rem;
border-left: 0.04rem solid #15e1fd;
}
}
.chart {
width: 100%;
height: 3rem;
}
}
@media (max-width: 1485px) {
.calendar-body {
.calendar-day {
.day-number {
font-size: 0.14rem;
}
.day-indicator {
.indicator-value {
font-size: 0.12rem;
}
.indicator-unit {
font-size: 0.09rem;
}
}
}
}
.detail-content {
grid-template-columns: repeat(2, 1fr);
}
.summary-cards {
grid-template-columns: repeat(2, 1fr);
}
}
</style>

1041
src/views/newCenterairC/energyManage/retrofitEffectivenessCompariso/index.vue

File diff suppressed because it is too large Load Diff

1280
src/views/newCenterairC/home/index.vue

File diff suppressed because it is too large Load Diff

1210
src/views/newCenterairC/reportManage/base/index.vue

File diff suppressed because it is too large Load Diff

1268
src/views/newCenterairC/reportManage/machine/index.vue

File diff suppressed because it is too large Load Diff

531
src/views/newCenterairC/sysMonitor/components/hostChart.vue

@ -0,0 +1,531 @@
<template>
<div>
<div class="historyCharts" ref="chart_ref"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: {
temArray: {
type: Array,
default: () => [],
},
},
data() {
return {
chartInstance: null,
option: {},
chartData1: [],
chartData2: [],
chartData3: [],
chartData4: [],
chartData5: [],
bottomData: [],
};
},
watch: {
temArray: {
immediate: true, //
handler(newVal, oldVal) {
if (newVal) {
this.chartData1 = []; // chartData1
this.chartData2 = []; // chartData2
this.bottomData = []; // bottomData
console.log("charts传值", newVal);
let data = newVal;
if (data.length > 0) {
// title titleStr
const title = data[0].title;
const titleStr = data[1].titleStr;
// dataList
const dataList = data[3].dataList;
// dataList
dataList.forEach((item) => {
// name title
const index = title.indexOf(item.name);
if (index !== -1) {
// name titleStr
item.name = titleStr[index];
}
});
console.log("处理后的data", data);
let name1 = "";
let name2 = "";
let name3 = "";
let name4 = "";
let name5 = "";
data.forEach((item) => {
if (item.timeStr) {
this.bottomData = item.timeStr;
}
if (item.dataList) {
// name
const names = [];
// chartData
const chartData = [];
//
let loadDataIndex = -1;
for (let i = 0; i < item.dataList.length; i++) {
if (
item.dataList[i].name &&
item.dataList[i].name.includes("负载")
) {
loadDataIndex = i;
this.chartData5 = item.dataList[i].value;
name5 = item.dataList[i].name;
break;
}
}
//
if (loadDataIndex !== -1) {
item.dataList.splice(loadDataIndex, 1);
}
//
item.dataList.slice(0, 4).forEach((val, index) => {
if (val.name) {
chartData[index] = val.value;
names[index] = val.name;
}
});
// chartData this.chartDataX
this.chartData1 = chartData[0] || "";
this.chartData2 = chartData[1] || "";
this.chartData3 = chartData[2] || "";
this.chartData4 = chartData[3] || "";
// names
name1 = names[0] || "";
name2 = names[1] || "";
name3 = names[2] || "";
name4 = names[3] || "";
}
});
// console.log("this.chartData1", this.chartData1);
// console.log("this.chartData2", this.chartData2);
// console.log("this.chartData3", this.chartData3);
// console.log("this.chartData4", this.chartData4);
// console.log("this.chartData5", this.chartData5);
this.$nextTick(() => {
// y
var Min1 = 0,
Min2 = 0,
Max1 = Math.ceil(
Math.max(
...this.chartData1,
...this.chartData2,
...this.chartData3,
...this.chartData4
)
),
Max2 = Math.ceil(Math.max(...this.chartData5));
console.log("Min1", Min1);
console.log("Min2", Min2);
console.log("Max1", Max1);
console.log("Max2", Max2);
const adapterOption = {
xAxis: {
data: this.bottomData,
},
yAxis: [
//y
{
min: Min1,
max: Max1,
splitNumber: 10,
interval: (Max1 - Min1) / 10,
},
{
min: Min2,
max: Max2,
splitNumber: 10,
interval: (Max2 - Min2) / 10,
},
],
series: [
{
yAxisIndex: 0,
name: name1,
data: this.chartData1,
},
{
yAxisIndex: 0,
name: name2,
data: this.chartData2,
},
{
yAxisIndex: 0,
name: name3,
data: this.chartData3,
},
{
yAxisIndex: 0,
name: name4,
data: this.chartData4,
},
{
yAxisIndex: 1,
name: name5,
data: this.chartData5,
},
],
};
this.chartInstance.setOption(adapterOption);
// resize
this.chartInstance.resize();
});
} else {
this.$nextTick(() => {
const adapterOption = {
xAxis: {
data: [],
},
yAxis: [
//y
{
min: 0,
max: 0,
splitNumber: 10,
interval: 0,
},
{
min: 0,
max: 0,
splitNumber: 10,
interval: 0,
},
],
series: [
{
yAxisIndex: 0,
data: [],
},
{
yAxisIndex: 0,
data: [],
},
{
yAxisIndex: 0,
data: [],
},
{
yAxisIndex: 0,
data: [],
},
{
yAxisIndex: 0,
data: [],
},
],
};
this.chartInstance.setOption(adapterOption);
//resize
this.chartInstance.resize();
this.screenAdapter();
});
}
}
},
},
},
mounted() {
this.initChart();
this.screenAdapter();
},
destroyed() {
//
window.removeEventListener("resize", this.screenAdapter);
},
methods: {
// 线+ + 线
screenAdapter() {
//,2.6 mes_ref
const titleFontSize = this.$refs.chart_ref.offsetWidth / 130;
//optionoption
const adapterOption = {};
//.chartInstanceoptiondataoption
this.chartInstance.setOption(adapterOption);
//resize
this.chartInstance.resize();
},
//chartInstance
initChart() {
var Min1 = 0,
Min2 = 0,
Max1 = Math.ceil(
Math.max(
...this.chartData1,
...this.chartData2,
...this.chartData3,
...this.chartData4
) + 4
),
Max2 = Math.ceil(Math.max(...this.chartData5) + 4);
const chartRef = this.$refs.chart_ref;
if (chartRef) {
//
this.chartInstance = echarts.init(this.$refs.chart_ref);
const titleFontSize = this.$refs.chart_ref.offsetWidth / 130;
this.option = {
tooltip: {
trigger: "axis",
// tooltip
formatter: function (params) {
var res = params[0].name + "<br/>";
for (var i = 0, l = params.length; i < l; i++) {
var seriesName = params[i].seriesName;
var value = params[i].value;
// console.log("", params[i].color)
var marker =
'<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' +
params[i].color +
'"></span>';
// seriesName
if (seriesName.includes("负载")) {
res +=
marker +
seriesName +
":" +
'<span style="color: #000000; font-weight: bold;margin-left:5px">' +
value +
" " +
"%" +
"</span><br>";
} else {
res +=
marker +
seriesName +
":" +
'<span style="color: #000000; font-weight: bold;margin-left:5px">' +
value +
" " +
"℃" +
"</span><br>";
}
}
return res;
},
textStyle: {
fontSize: titleFontSize * 1.5,
},
},
legend: {
show: true,
top: 0,
textStyle: {
color: "white",
fontSize: titleFontSize * 1.5,
},
},
grid: {
top: "10%",
left: "4%",
right: "6%",
bottom: "3%",
containLabel: true,
},
xAxis: {
type: "category",
//true
boundaryGap: true,
// x
axisLabel: {
// interval: 0, //x
// rotate: 30, //x30
color: "rgba(255, 255, 255, 1)",
textStyle: {
fontSize: titleFontSize * 1.5,
},
},
axisTick: {
show: false, // 线
},
// x
axisLine: {
show: true,
lineStyle: {
color: "#365576",
},
},
splitLine: {
lineStyle: {
color: "#e2e6f0",
},
}, //x线
data: this.bottomData,
},
yAxis: [
{
min: Min1,
max: Max1,
splitNumber: 10,
interval: (Max1 - Min1) / 10,
// name
nameTextStyle: {
color: "rgba(255, 255, 255, 1)",
fontSize: titleFontSize * 2,
},
miniInterval: 5,
type: "value",
// y
axisLabel: {
color: "rgba(255, 255, 255, 1)",
textStyle: {
fontSize: titleFontSize * 1.5,
},
},
// y
axisLine: {
show: true,
lineStyle: {
color: "#365576", // y 线
},
},
//y线
// splitNumber: 10,
// y线
splitLine: {
lineStyle: {
color: "#1a3d62", // 线
type: "dashed", // 线线
},
},
},
{
min: Min2,
max: Max2,
splitNumber: 10,
interval: (Max2 - Min2) / 10,
// name
nameTextStyle: {
color: "rgba(255, 255, 255, 1)",
fontSize: titleFontSize * 1.5,
},
miniInterval: 5,
type: "value",
name: "负载", // y
// y
axisLabel: {
color: "rgba(255, 255, 255, 1)",
textStyle: {
fontSize: titleFontSize * 1.5,
},
},
// y
axisLine: {
show: true,
lineStyle: {
color: "#365576", // y 线
},
},
//y线
// splitNumber: 10,
// y线
splitLine: {
lineStyle: {
color: "#1a3d62", // 线
type: "dashed", // 线线
},
},
},
],
series: [
{
type: "line",
//
symbolSize: 8,
data: this.chartData1,
yAxisIndex: 0,
//线
itemStyle: {
color: "#00CED1", //线
},
lineStyle: {
color: "#00CED1", //线
},
smooth: false,
// 线
showSymbol: false,
},
{
type: "line",
//
symbolSize: 8,
data: this.chartData2,
yAxisIndex: 0,
//线
itemStyle: {
color: "#3ba272", //线
},
smooth: false,
// 线
showSymbol: false,
},
{
type: "line",
//
symbolSize: 8,
data: this.chartData3,
yAxisIndex: 0,
//线
itemStyle: {
color: "#1a69f1", //线
},
smooth: false,
// 线
showSymbol: false,
},
{
type: "line",
//
symbolSize: 8,
data: this.chartData4,
yAxisIndex: 0,
//线
itemStyle: {
color: "#ee6666", //线
},
smooth: false,
// 线
showSymbol: false,
},
{
type: "line",
//
symbolSize: 8,
data: this.chartData5,
yAxisIndex: 1,
//线
itemStyle: {
color: "#fac858", //线
},
smooth: false,
// 线
showSymbol: false,
},
],
};
//
this.chartInstance.setOption(this.option, true);
} else {
console.error("未找到有效的 DOM 元素");
}
},
},
};
</script>
<style lang="scss" scoped>
.historyCharts {
width: 100%;
height: 4.4rem;
}
</style>

120
src/views/newCenterairC/sysMonitor/components/lineChildren.vue

@ -0,0 +1,120 @@
<template>
<div class="line-container">
<!-- 第一个圆点 -->
<div class="dot dot-start"></div>
<!-- 第一条直线 -->
<div
class="line line1"
:style="{
transform: `rotate(${angle1}deg)`,
width: lineWidth1Rem + 'rem'
}"
></div>
<!-- 中间圆点 -->
<div
class="dot dot-mid"
:style="{
top: (1 + Math.sin((angle1 * Math.PI) / 180) * lineWidth1Rem - 0.025) + 'rem',
left: (1 + Math.cos((angle1 * Math.PI) / 180) * lineWidth1Rem - 0.025) + 'rem'
}"
></div>
<!-- 第二条直线 -->
<div
class="line line2"
:style="{
top: (1 + Math.sin((angle1 * Math.PI) / 180) * lineWidth1Rem) + 'rem',
left: (1 + Math.cos((angle1 * Math.PI) / 180) * lineWidth1Rem) + 'rem',
transform: `rotate(${angle2}deg)`,
width: lineWidth2Rem + 'rem'
}"
></div>
<!-- 最后一个圆点 -->
<div
class="dot dot-end"
:style="{
top: endDotTop + 'rem',
left: endDotLeft + 'rem'
}"
></div>
</div>
</template>
<script>
export default {
props: {
// 线
angle1: {
type: Number,
default: 0
},
// 线
angle2: {
type: Number,
default: 0
},
// 线px
lineWidth1: {
type: Number,
default: 100
},
// 线px
lineWidth2: {
type: Number,
default: 100
}
},
computed: {
lineWidth1Rem() {
return this.lineWidth1 / 100;
},
lineWidth2Rem() {
return this.lineWidth2 / 100;
},
endDotTop() {
// 线 y
const firstLineEndY = 1 + Math.sin((this.angle1 * Math.PI) / 180) * this.lineWidth1Rem;
// 线线 y
const secondLineYOffset = Math.sin((this.angle2 * Math.PI) / 180) * this.lineWidth2Rem;
return firstLineEndY + secondLineYOffset - 0.025;
},
endDotLeft() {
// 线 x
const firstLineEndX = 1 + Math.cos((this.angle1 * Math.PI) / 180) * this.lineWidth1Rem;
// 线线 x
const secondLineXOffset = Math.cos((this.angle2 * Math.PI) / 180) * this.lineWidth2Rem;
return firstLineEndX + secondLineXOffset - 0.025;
}
}
};
</script>
<style scoped>
.line-container {
position: relative;
}
.line {
position: absolute;
height: 1px;
background-color: rgba(0, 255, 255, 0.5);
transform-origin: left center;
}
.line1 {
top: 1rem;
left: 1rem;
}
.dot {
position: absolute;
width: 0.05rem;
height: 0.05rem;
background-color: aqua;
border-radius: 50%;
}
.dot-start {
top: 0.97rem;
left: 0.97rem;
}
</style>

67
src/views/newCenterairC/sysMonitor/components/lineSquare.vue

@ -0,0 +1,67 @@
<template>
<div class="crossed-lines-container">
<!-- 上边线 -->
<div
class="line horizontal-line"
:style="{ width: (horizontalLength / 100) + 'rem', left: `calc(50% - ${horizontalLength / 200}rem)`, top: `calc(50% - ${(verticalLength / 200) - (overlap / 100)}rem)` }"
></div>
<!-- 右边线 -->
<div
class="line vertical-line"
:style="{ height: (verticalLength / 100) + 'rem', top: `calc(50% - ${verticalLength / 200}rem)`, left: `calc(50% + ${(horizontalLength / 200) - (overlap / 100)}rem)` }"
></div>
<!-- 下边线 -->
<div
class="line horizontal-line"
:style="{ width: (horizontalLength / 100) + 'rem', left: `calc(50% - ${horizontalLength / 200}rem)`, top: `calc(50% + ${(verticalLength / 200) - (overlap / 100)}rem)` }"
></div>
<!-- 左边线 -->
<div
class="line vertical-line"
:style="{ height: (verticalLength / 100) + 'rem', top: `calc(50% - ${verticalLength / 200}rem)`, left: `calc(50% - ${(horizontalLength / 200) - (overlap / 100)}rem)` }"
></div>
</div>
</template>
<script>
export default {
props: {
// 线
horizontalLength: {
type: Number,
default: 100
},
// 线
verticalLength: {
type: Number,
default: 100
},
// 线
overlap: {
type: Number,
default: 10
}
}
};
</script>
<style scoped>
.crossed-lines-container {
position: relative;
width: 100%;
height: 100%;
}
.line {
position: absolute;
background-color: rgb(45, 121, 236,0.7);
}
.horizontal-line {
height: 0.01rem;
}
.vertical-line {
width: 0.01rem;
}
</style>

450
src/views/newCenterairC/sysMonitor/components/loadData.vue

@ -0,0 +1,450 @@
<template>
<div>
<div class="sys_charts" ref="sys_charts"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: {
hostData: {
type: Array,
default: () => [],
},
},
data() {
return {
chartInstance: null,
option: {},
loadPercent: "",
};
},
watch: {
hostData: {
immediate: true, //
handler(newVal, oldVal) {
if (newVal) {
console.log("charts传值", newVal);
let data = newVal;
if (data.length > 0) {
data.forEach((item) => {
if (item.otherName === "负载") {
this.loadPercent = item.curValue;
}
});
this.$nextTick(() => {
// ECharts
if (this.chartInstance) {
this.chartInstance.dispose();
}
//
this.initChart();
});
} else {
}
}
},
},
},
mounted() {
this.initChart();
this.screenAdapter();
window.addEventListener("resize", this.screenAdapter);
},
destroyed() {
//mounted
window.removeEventListener("resize", this.screenAdapter);
},
methods: {
//
getAxisLineColor(useData, maxData) {
//
// 0.75使
const threshold = maxData * 0.75;
//
if (useData > threshold) {
return [
[
useData / maxData,
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(0,127,208,1)" },
{ offset: 0.6, color: "rgba(0,127,208,1)" },
{ offset: 1, color: "rgba(69, 235, 167,0.5)" },
]),
],
[1, "rgba(28,128,245,.0)"],
];
} else {
return [
[
useData / maxData,
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(0,127,208,1)" },
{ offset: 0.5, color: "rgba(0,127,208,1)" },
{ offset: 1, color: "rgba(0,127,208,1)" },
]),
],
[1, "rgba(28,128,245,.0)"],
];
}
},
//chartInstance2 线
initChart() {
var value = 80;
//
const dataArr = this.loadPercent; //
const dataX = 100;
const titleFontSize = this.$refs.sys_charts.offsetWidth / 20;
this.chartInstance = echarts.init(this.$refs.sys_charts);
this.option = {
backgroundStyle: {
borderWidth: 1,
color: "transparent",
},
title: [
{
text: `${dataArr} %`,
bottom: titleFontSize,
left: "center",
textStyle: {
fontSize: titleFontSize * 1.5, //
color: "#ffff",
fontWeight: 800,
},
triggerEvent: true,
},
],
legend: {
show: false,
},
series: [
{
name: "最外部进度条",
type: "gauge",
radius: "99%",
splitNumber: 10,
axisLine: {
lineStyle: {
color: [
[
dataArr / dataX,
{
type: "linear",
x: 0,
y: 1,
x2: 0.5,
y2: 0.5,
colorStops: [
{
offset: 0,
color: "rgba(0,0,0,0)", // 0%
},
{
offset: 0.8,
color: "#195b9d", // 100%
},
{
offset: 1,
color: "#0a2256", // 100%
},
],
global: false, // false
},
],
[1, "#083158"],
],
width: 5, //
},
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
itemStyle: {
show: false,
},
detail: {
show: false,
},
title: {
//
show: false,
},
data: [
{
name: "title",
value: dataArr,
},
],
pointer: {
show: false,
},
animationDuration: 4000,
},
{
name: "刻度尺",
type: "gauge",
radius: "88%",
splitNumber: 10, //
min: 0, //
max: dataX, //
// 线
splitLine: {
show: true,
length: 12,
lineStyle: {
width: 3,
color: "#12E5FE",
},
},
// 线
axisTick: {
show: true,
splitNumber: 10,
length: 5,
lineStyle: {
color: "#12E5FE",
width: 2,
},
},
//
axisLabel: {
distance: -8, //线
color: "#CEF3FE",
fontSize: "6",
fontWeight: 600,
},
detail: {
show: false,
},
axisLine: {
lineStyle: {
width: -10, //线
color: [
[
1,
{
type: "radial",
x: 0.5,
y: 0.6,
r: 0.6,
colorStops: [
{
offset: 0.85,
color: "#031F46", // 0%
},
{
offset: 0.93,
color: "#060d25", // 100%
},
{
offset: 1,
color: "#12D7EF", // 100%
},
],
},
],
],
},
},
},
{
name: "外部指针",
type: "gauge",
radius: "90%",
axisLine: {
lineStyle: {
color: [
[dataArr / dataX - 0.001, "rgba(0,0,0,0)"],
[dataArr / dataX + 0.003, "#e43c59"],
[1, "rgba(0,0,0,0)"],
],
width: 33,
},
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
itemStyle: {
show: false,
},
detail: {
show: false,
},
title: {
//
show: false,
},
data: [
{
name: "title",
value: dataArr,
},
],
pointer: {
show: false,
},
},
{
name: "内层带指针",
type: "gauge",
radius: "60%",
splitNumber: 10, //
min: 0, //
max: dataX, //
// 线
axisLine: {
lineStyle: {
color: [
[
1,
{
type: "radial",
x: 0.5,
y: 0.59,
r: 0.6,
colorStops: [
{
offset: 0.72,
color: "#032046",
},
{
offset: 0.94,
color: "#086989",
},
{
offset: 0.98,
color: "#0FAFCB",
},
{
offset: 1,
color: "#0EA4C1",
},
],
},
],
],
width: 1000,
},
},
// 线
splitLine: {
show: false,
},
// 线
axisTick: {
show: false,
},
//
axisLabel: {
show: false,
},
//
pointer: {
show: true,
length: "95%",
width: 5, //
},
//
itemStyle: {
color: "#01eaf8",
},
data: [
{
value: dataArr,
},
],
detail: {
show: false,
},
},
//
{
type: "gauge",
radius: "110%", //
center: ["50%", "127%"],
axisLine: {
show: true,
lineStyle: {
// 线
width: 4, //
color: [
[
1,
{
type: "radial",
x: 0.5,
y: 0,
r: 0.6,
colorStops: [
{
offset: 0,
color: "#00f3f9", // 0%
},
{
offset: 1,
color: "#000", // 100%
},
],
},
],
],
},
},
axisTick: {
//
show: false,
},
splitLine: {
// 线
show: false,
},
axisLabel: {
//
show: false,
},
pointer: {
//
show: false,
},
detail: {
//
show: false,
},
},
],
};
//
this.chartInstance.setOption(this.option, true);
},
screenAdapter() {
const titleFontSize = this.$refs.sys_charts.offsetWidth / 18;
const adapterOption = {};
this.chartInstance.setOption(adapterOption);
this.chartInstance.resize();
},
},
};
</script>
<style lang="scss" scoped>
.sys_charts {
width: 2rem;
height: 2rem;
}
</style>

416
src/views/newCenterairC/sysMonitor/components/performanceChart.vue

@ -0,0 +1,416 @@
<template>
<div>
<div class="historyCharts" ref="chart_ref"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: {
temArray: {
type: Array,
default: () => [],
},
},
data() {
return {
chartInstance: null,
option: {},
chartData1: [],
chartData2: [],
chartData3: [],
chartData4: [],
bottomData: [],
};
},
watch: {
temArray: {
immediate: true, //
handler(newVal, oldVal) {
if (newVal) {
this.chartData1 = []; // chartData1
this.chartData2 = []; // chartData2
this.bottomData = []; // bottomData
console.log("charts传值", newVal);
let data = newVal;
if (data.length > 0) {
// title titleStr
const title = data.data[0].title;
const titleStr = data.data[1].titleStr;
// dataList
const dataList = data.data[3].dataList;
// dataList
dataList.forEach((item) => {
// name title
const index = title.indexOf(item.name);
if (index !== -1) {
// name titleStr
item.name = titleStr[index];
}
});
console.log("处理后的data", data);
data.forEach((item) => {
if (item.timeStr) {
this.bottomData = item.timeStr;
}
if (item.dataList) {
let name1 = "";
let name2 = "";
let name3 = "";
let name4 = "";
item.dataList.forEach((val, index) => {
if (val.name) {
switch (index) {
case 0:
this.chartData1 = val.value;
name1 = val.name;
break;
case 1:
this.chartData2 = val.value;
name2 = val.name;
break;
case 2:
this.chartData3 = val.value;
name3 = val.name;
break;
case 3:
this.chartData4 = val.value;
name4 = val.name;
break;
default:
break;
}
}
});
}
});
this.$nextTick(() => {
const adapterOption = {
xAxis: {
data: this.bottomData,
},
series: [
{
yAxisIndex: 0,
name:name1,
data: this.chartData1,
},
{
yAxisIndex: 0,
name:name2,
data: this.chartData2,
},
{
yAxisIndex: 0,
name:name3,
data: this.chartData3,
},
{
yAxisIndex: 0,
name:name4,
data: this.chartData4,
},
],
};
this.chartInstance.setOption(adapterOption);
//resize
this.chartInstance.resize();
});
} else {
this.$nextTick(() => {
const adapterOption = {
xAxis: {
data: [],
},
series: [
{
yAxisIndex: 0,
data: [],
},
{
yAxisIndex: 0,
data: [],
},
{
yAxisIndex: 0,
data: [],
},
{
yAxisIndex: 0,
data: [],
},
],
};
this.chartInstance.setOption(adapterOption);
//resize
this.chartInstance.resize();
this.screenAdapter();
});
}
}
},
},
},
mounted() {
this.initChart();
this.screenAdapter();
},
destroyed() {
//
window.removeEventListener("resize", this.screenAdapter);
},
methods: {
// 线+ + 线
screenAdapter() {
//,2.6 mes_ref
const titleFontSize = this.$refs.chart_ref.offsetWidth / 130;
//optionoption
const adapterOption = {};
//.chartInstanceoptiondataoption
this.chartInstance.setOption(adapterOption);
//resize
this.chartInstance.resize();
},
//chartInstance
initChart() {
const chartRef = this.$refs.chart_ref;
if (chartRef) {
//
this.chartInstance = echarts.init(this.$refs.chart_ref);
this.option = {
tooltip: {
trigger: "axis",
},
legend: {
show: true,
top: 0,
textStyle: {
color: "white",
},
},
grid: {
top: "10%",
left: "4%",
right: "6%",
bottom: "3%",
containLabel: true,
},
xAxis: {
type: "category",
//true
boundaryGap: true,
// x
axisLabel: {
// interval: 0, //x
// rotate: 30, //x30
color: "rgba(255, 255, 255, 1)",
},
axisTick: {
show: false, // 线
},
// x
axisLine: {
show: true,
lineStyle: {
color: "#365576",
},
},
splitLine: {
lineStyle: {
color: "#e2e6f0",
},
}, //x线
data: this.bottomData,
},
yAxis: {
min: 0,
// max:20,
// // // min:'dataMin',
// // // max:'dataMax',
// name: "kwh", // y
// name
nameTextStyle: {
color: "rgba(255, 255, 255, 1)",
fontSize: 12,
},
miniInterval: 5,
type: "value",
// y
axisLabel: {
color: "rgba(255, 255, 255, 1)",
},
// y
axisLine: {
show: true,
lineStyle: {
color: "#365576", // y 线
},
},
//y线
// splitNumber: 10,
// y线
splitLine: {
lineStyle: {
color: "#1a3d62", // 线
type: "dashed", // 线线
},
},
},
series: [
{
type: "line",
//
symbolSize: 8,
data: this.chartData1,
//线
itemStyle: {
color: "#1a69f1", //线
},
lineStyle: {
color: "#1a69f1", //线
},
smooth: false,
// 线
showSymbol: false,
//
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(26, 105, 241, 0.5)", //
},
{
offset: 1,
color: "rgba(26, 105, 241, 0)", //
},
],
global: false, // false
},
},
},
{
type: "line",
//
symbolSize: 8,
data: this.chartData2,
//线
itemStyle: {
color: "#00CED1", //线
},
smooth: false,
// 线
showSymbol: false,
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(0, 206, 209, 0.5)", //
},
{
offset: 1,
color: "rgba(0, 206, 209, 0)", //
},
],
global: false, // false
},
},
},
{
type: "line",
//
symbolSize: 8,
data: this.chartData3,
//线
itemStyle: {
color: "#00CED1", //线
},
smooth: false,
// 线
showSymbol: false,
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(0, 206, 209, 0.5)", //
},
{
offset: 1,
color: "rgba(0, 206, 209, 0)", //
},
],
global: false, // false
},
},
},
{
type: "line",
//
symbolSize: 8,
data: this.chartData4,
//线
itemStyle: {
color: "#00CED1", //线
},
smooth: false,
// 线
showSymbol: false,
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(0, 206, 209, 0.5)", //
},
{
offset: 1,
color: "rgba(0, 206, 209, 0)", //
},
],
global: false, // false
},
},
},
],
};
//
this.chartInstance.setOption(this.option, true);
} else {
console.error("未找到有效的 DOM 元素");
}
},
},
};
</script>
<style lang="scss" scoped>
.historyCharts {
width: 100%;
height:3rem;
}
</style>

15
src/views/newCenterairC/sysMonitor/components/titleImg.vue

@ -0,0 +1,15 @@
<template>
<div class="title-img">
<img src="../../../../assets/images/big.png" class="img1" alt="" />
</div>
</template>
<style lang="scss" scoped>
.title-img {
position: relative;
}
.img1 {
width: 0.8rem;
height: 0.5rem;
z-index: 10;
}
</style>

2059
src/views/newCenterairC/sysMonitor/hostDetails.vue

File diff suppressed because it is too large Load Diff

20
src/views/newCenterairC/sysMonitor/index.vue

@ -0,0 +1,20 @@
<template>
<div></div>
</template>
<script>
export default {
created() {
this.toPage();
},
methods: {
toPage() {
console.log("需要跳转的")
//
this.$router.push("/monitorCenter")
},
},
};
</script>
<style></style>

4668
src/views/newCenterairC/sysMonitor/monitorCenter.vue

File diff suppressed because it is too large Load Diff

736
src/views/newCenterairC/sysMonitor/performance.vue

@ -0,0 +1,736 @@
<template>
<div class="monitor" v-loading="loading">
<div class="monitor-top">
<img
class="title-left"
src="../../../assets/images/title-left.png"
alt=""
/>
<img
class="title-center"
src="../../../assets/images/title-center.png"
@click="goSys"
alt=""
/>
<img
class="title-right"
src="../../../assets/images/title-right.png"
alt=""
/>
<div class="sys-title" @click="goSys">铭汉高效冷源站管理系统</div>
<!-- logo -->
<img src="../../../assets/images/logo-3.png" class="sys-logo" alt="" />
<div class="nowTime">{{ formattedDate }}</div>
<div class="monitor-time">已监测时长:{{ dayData }}</div>
<img
class="icon_warning"
src="../../../assets/images/warning.png"
title="报警记录"
@click="goWarning"
v-if="isShowWarning"
alt=""
/>
<img
class="icon_home"
src="../../../assets/images/icon_home.png"
title="首页"
@click="goSys"
alt=""
/>
<img
class="back-icon"
src="../../../assets/images/back-icon.png"
title="返回"
@click="goBack"
alt=""
/>
</div>
<div class="host-detail">
<div class="detail-top">
<div class="detail-top-left">
<div class="host-li">
<img
class="host-img"
src="../../../assets/images/host-img4.png"
alt=""
/>
<div class="host-name">1号螺旋机</div>
<div class="detail-data hostparams">
<div class="detail-data-top">
<title-img></title-img>
<div class="details-title">冷机性能</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时EER:</span>
<span class="dotData">10.365</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时功率:</span>
<span class="dotData">126</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时冷量:</span>
<span class="dotData">1306</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li year-data">
<div class="rightDot">
<div class="leftDot">
<span>全年EER:</span>
<span class="dotData">0.000</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>全年用电:</span>
<span class="dotData">64098</span>
<span class="dotUnit">kw/H</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>全年供电:</span>
<span class="dotData">101365</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="host-li">
<img
class="host-img"
src="../../../assets/images/host-img4.png"
alt=""
/>
<div class="host-name">2号螺旋机</div>
<div class="detail-data hostparams">
<div class="detail-data-top">
<title-img></title-img>
<div class="details-title">冷机性能</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时EER:</span>
<span class="dotData">10.365</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时功率:</span>
<span class="dotData">126</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时冷量:</span>
<span class="dotData">1306</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li year-data">
<div class="rightDot">
<div class="leftDot">
<span>全年EER:</span>
<span class="dotData">0.000</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>全年用电:</span>
<span class="dotData">64098</span>
<span class="dotUnit">kw/H</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>全年供电:</span>
<span class="dotData">101365</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="host-li">
<img
class="host-img"
src="../../../assets/images/host-img3.png"
alt=""
/>
<div class="host-name">3号磁悬浮机</div>
<div class="detail-data hostparams">
<div class="detail-data-top">
<title-img></title-img>
<div class="details-title">冷机性能</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时EER:</span>
<span class="dotData">10.365</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时功率:</span>
<span class="dotData">126</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>实时冷量:</span>
<span class="dotData">1306</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li year-data">
<div class="rightDot">
<div class="leftDot">
<span>全年EER:</span>
<span class="dotData">0.000</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>全年用电:</span>
<span class="dotData">64098</span>
<span class="dotUnit">kw/H</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>全年供电:</span>
<span class="dotData">101365</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="detail-top-right">
<div class="detail-data hostparams">
<div class="detail-data-top">
<title-img></title-img>
<div class="details-title">系统性能</div>
<title-img></title-img>
</div>
<div class="detail-data-bottom">
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>今日EER:</span>
<span class="dotData">6.531</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>今日用电:</span>
<span class="dotData">367</span>
<span class="dotUnit">kw/H</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>今日供冷:</span>
<span class="dotData">2397</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li year-data">
<div class="rightDot">
<div class="leftDot">
<span>当月EER:</span>
<span class="dotData">6.131</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>今月用电:</span>
<span class="dotData">27840</span>
<span class="dotUnit">kw/H</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>当月供冷:</span>
<span class="dotData">172069</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li year-data">
<div class="rightDot">
<div class="leftDot">
<span>当年EER:</span>
<span class="dotData">6.531</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>当年用电:</span>
<span class="dotData">105771</span>
<span class="dotUnit">kw/H</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span>当年供冷:</span>
<span class="dotData">744519</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
<div class="detail-data-li year-data">
<div class="rightDot">
<div class="leftDot">
<span class="dotTitle">累计EER:</span>
<span class="dotData">5.531</span>
<span class="dotUnit">kw/kw</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span class="dotTitle">累计用电:</span>
<span class="dotData">1096628</span>
<span class="dotUnit">kw/H</span>
</div>
</div>
</div>
<div class="detail-data-li">
<div class="rightDot">
<div class="leftDot">
<span class="dotTitle">累计供冷:</span>
<span class="dotData">6107983</span>
<span class="dotUnit">kw</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="detail-bottom">
<performance-chart :temArray="temArray"></performance-chart>
</div>
</div>
</div>
</template>
<script>
import {
hostDetailsData,
hostTemData,
runTime,
} from "@/api/centerairC/sysMonitor";
import { alarmRecordList } from "@/api/alarm/alarmRecord";
import titleImg from "./components/titleImg.vue";
import { format } from "@/utils/datetime";
import PerformanceChart from "./components/performanceChart.vue";
export default {
name: "sysControl",
components: { titleImg, PerformanceChart },
data() {
return {
loading: false,
currentDate: new Date(),
nowTimer: null,
deviceName: "", //
hostData: [], //
rightHostData: [], //
automaticObj: {}, //
localObj: {}, //
badObj: {}, //
timeObj: {}, //
compressorData: [], //
temArray: [], //
isMagnetic: false,
isShowWarning: false, //
dayData: "", //
};
},
computed: {
formattedDate() {
const year = this.currentDate.getFullYear();
const month = String(this.currentDate.getMonth() + 1).padStart(2, "0");
const day = String(this.currentDate.getDate()).padStart(2, "0");
const hours = String(this.currentDate.getHours()).padStart(2, "0");
const minutes = String(this.currentDate.getMinutes()).padStart(2, "0");
const seconds = String(this.currentDate.getSeconds()).padStart(2, "0");
const weekDays = [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
];
const weekDay = weekDays[this.currentDate.getDay()];
return `${year}${month}${day}${hours}:${minutes}:${seconds} ${weekDay}`;
},
},
created() {},
mounted() {
this.getHostDetailsData();
this.getDayData();
//
setTimeout(() => {
this.requestFullscreen();
}, 100); // 100
},
beforeDestroy() {
//
if (this.nowTimer) {
clearInterval(this.nowTimer);
}
},
methods: {
//
requestFullscreen() {
const element = document.documentElement;
console.log("全屏了吗");
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
// Firefox
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
// Chrome, Safari and Opera
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
// IE/Edge
element.msRequestFullscreen();
}
},
// 退
exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
// Firefox
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
// Chrome, Safari and Opera
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
// IE/Edge
document.msExitFullscreen();
}
},
//
goSys() {
// this.exitFullscreen();
this.$router.push("/");
},
//
goBack() {
this.$router.back();
},
getHostDetailsData() {
//
// this.getHostParams(deviceLedgerId);
},
//
getDayData() {
runTime().then((res) => {
if (res.code == 200) {
this.dayData = res.data.runTime;
}
});
},
//
getAlarnStatus() {
let data = {
pageNum: 1,
pageSize: 10,
status: "0",
};
let timeArr = [getDay(0), getDay(0)];
alarmRecordList(this.addDateRange(data, timeArr)).then((res) => {
if (res.code == 200 && res.rows.length > 0) {
this.isShowWarning = true;
} else {
this.isShowWarning = false;
}
});
},
goWarning() {
// this.exitFullscreen();
this.$router.push("/alarm/alarmRecord");
},
},
};
</script>
<style lang="scss" scoped>
.monitor {
width: 100%;
min-height: 100vh;
height: auto;
background-color: black;
color: #fff;
.monitor-top {
width: 100%;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
flex-wrap: nowrap;
padding: 0.1rem 0.2rem;
position: relative;
.title-left {
width: 3.41rem;
height: 0.8rem;
}
.title-center {
width: 9.46rem;
height: 0.8rem;
}
.title-right {
width: 5.04rem;
height: 0.78rem;
}
.sys-title {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 0.28rem;
color: #ffffff;
font-weight: bold;
z-index: 100;
cursor: pointer;
}
.nowTime {
position: absolute;
top: 0.37rem;
right: 0.6rem;
font-size: 0.18rem;
color: #ffffff;
font-weight: bold;
z-index: 100;
}
.sys-logo {
width: 1.8rem;
height: 0.5rem;
position: absolute;
top: 0.26rem;
left: 0.8rem;
z-index: 10;
}
.monitor-time {
position: absolute;
top: 0.44rem;
left: 4.2rem;
z-index: 10;
font-size: 0.18rem;
color: #ffffff;
font-weight: bold;
}
.icon_warning {
position: absolute;
top: 0.39rem;
right: 4.4rem;
z-index: 10;
width: 0.35rem;
height: 0.32rem;
margin: 0 0.25rem 0 0.27rem;
cursor: pointer;
/* 添加闪烁动画 */
animation: blink 1s infinite;
}
@keyframes blink {
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
.icon_home {
position: absolute;
top: 0.39rem;
right: 4rem;
z-index: 10;
width: 0.35rem;
height: 0.32rem;
margin: 0 0.2rem 0 0.27rem;
cursor: pointer;
}
.back-icon {
position: absolute;
top: 0.39rem;
right: 3.7rem;
z-index: 10;
width: 0.35rem;
height: 0.32rem;
cursor: pointer;
}
}
.host-detail {
padding: 0.2rem;
width: 100%;
display: flex;
flex-direction: column;
.detail-top {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.detail-top-left {
width: 14rem;
// background-color: aquamarine;
position: relative;
display: flex;
flex-direction: row;
align-items: flex-start;
.host-li {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: 0.3rem;
position: relative;
.host-img {
width: 3.5rem;
height: 2.6rem;
margin-bottom: 0.1rem;
}
.host-name {
position: absolute;
top: 0.8rem;
left: 1.6rem;
color: #3520f8;
font-size: 0.18rem;
font-weight: bold;
}
}
}
.detail-top-right {
width: calc(100% - 14rem);
display: flex;
flex-direction: column;
align-items: center;
}
.detail-data {
display: flex;
flex-direction: column;
width: 4.5rem;
position: relative;
.detail-data-top {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
color: #c0dffc;
font-weight: bold;
font-size: 0.18rem;
width: 100%;
text-align: center;
z-index: 10;
.details-title {
margin: 0 0.15rem;
}
}
.detail-data-bottom {
width: 100%;
padding: 0rem 0.3rem;
z-index: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
justify-content: center;
}
.line1 {
position: absolute;
top: 0.53rem;
}
}
}
.detail-bottom {
// margin: 0.3rem 0.5rem 0 0.5rem;
display: flex;
flex-direction: row;
justify-content: space-between;
height: 3rem;
// background-color: #217df5;
}
}
}
</style>

1752
src/views/newLifeWater/alarmManage/index.vue

File diff suppressed because it is too large Load Diff

1546
src/views/newLifeWater/deviceManage/info/index.vue

File diff suppressed because it is too large Load Diff

2174
src/views/newLifeWater/energyManage/energyConsumptionEfficiencyTrend/index.vue

File diff suppressed because it is too large Load Diff

1774
src/views/newLifeWater/energyManage/energyWater/index.vue

File diff suppressed because it is too large Load Diff

1691
src/views/newLifeWater/energyManage/retrofitEffectivenessCompariso/index.vue

File diff suppressed because it is too large Load Diff

1732
src/views/newLifeWater/energyManage/warning/index.vue

File diff suppressed because it is too large Load Diff

1470
src/views/newLifeWater/home/index.vue

File diff suppressed because it is too large Load Diff

1425
src/views/newLifeWater/reportManage/base/index.vue

File diff suppressed because it is too large Load Diff

1748
src/views/newLighting/alarmManage/index.vue

File diff suppressed because it is too large Load Diff

1378
src/views/newLighting/deviceManage/info/index.vue

File diff suppressed because it is too large Load Diff

1201
src/views/newLighting/deviceManage/strategy/index.vue

File diff suppressed because it is too large Load Diff

1854
src/views/newLighting/energyManage/energyConsumptionEfficiencyTrend/index.vue

File diff suppressed because it is too large Load Diff

1738
src/views/newLighting/energyManage/retrofitEffectivenessCompariso/index.vue

File diff suppressed because it is too large Load Diff

1515
src/views/newLighting/energyManage/warning/index.vue

File diff suppressed because it is too large Load Diff

1317
src/views/newLighting/home/index.vue

File diff suppressed because it is too large Load Diff

1210
src/views/newLighting/reportManage/base/index.vue

File diff suppressed because it is too large Load Diff

765
src/views/newSystem/systemDevice.vue

@ -0,0 +1,765 @@
<template>
<div class="app-container">
<!-- 关键指标统计 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">关键指标统计</div>
<div class="time-tabs">
<div
v-for="(tab, index) in deviceTimeTabs"
:key="index"
:class="['time-tab', { active: activeDeviceTab === index }]"
@click="handleDeviceTabChange(index)"
>
{{ tab }}
</div>
</div>
</div>
<div class="device-indicators">
<div class="indicator-card" v-for="device in deviceIndicators" :key="device.name">
<div class="indicator-header" :style="{ background: device.bg }">
<div class="indicator-icon">
<img :src="device.icon" :alt="device.name" />
</div>
<div class="indicator-name">{{ device.name }}</div>
</div>
<div class="indicator-content">
<div class="indicator-value">{{ device.total }}</div>
<div class="indicator-label">总设备数</div>
</div>
<div class="indicator-footer">
<div class="footer-item">
<span class="footer-label">在线:</span>
<span class="footer-value online">{{ device.online }}</span>
</div>
<div class="footer-item">
<span class="footer-label">离线:</span>
<span class="footer-value offline">{{ device.offline }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 设备在线数量趋势 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">全系统设备在线数量趋势</div>
<div class="time-tabs">
<div
v-for="(tab, index) in trendTimeTabs"
:key="index"
:class="['time-tab', { active: activeTrendTab === index }]"
@click="handleTrendTabChange(index)"
>
{{ tab }}
</div>
</div>
</div>
<div class="trend-chart" ref="deviceTrendChartRef"></div>
</div>
<!-- 网关在线数量趋势 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">网关在线数量趋势</div>
<div class="time-tabs">
<div
v-for="(tab, index) in gatewayTimeTabs"
:key="index"
:class="['time-tab', { active: activeGatewayTab === index }]"
@click="handleGatewayTabChange(index)"
>
{{ tab }}
</div>
</div>
</div>
<div class="trend-chart" ref="gatewayTrendChartRef"></div>
</div>
<!-- 设备状态概览 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">设备状态概览</div>
</div>
<div class="status-overview">
<div class="status-card">
<div class="status-icon online"></div>
<div class="status-info">
<div class="status-value">{{ overview.online }}</div>
<div class="status-label">在线设备</div>
</div>
</div>
<div class="status-card">
<div class="status-icon offline"></div>
<div class="status-info">
<div class="status-value">{{ overview.offline }}</div>
<div class="status-label">离线设备</div>
</div>
</div>
<div class="status-card">
<div class="status-icon warning"></div>
<div class="status-info">
<div class="status-value">{{ overview.warning }}</div>
<div class="status-label">告警设备</div>
</div>
</div>
<div class="status-card">
<div class="status-icon fault"></div>
<div class="status-info">
<div class="status-value">{{ overview.fault }}</div>
<div class="status-label">故障设备</div>
</div>
</div>
</div>
<div class="status-pie-chart" ref="statusPieRef"></div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "SystemDevice",
data() {
return {
//
deviceTimeTabs: ["近七日", "当月", "当年"],
activeDeviceTab: 0,
//
trendTimeTabs: ["近七日", "当月", "当年"],
activeTrendTab: 0,
gatewayTimeTabs: ["近七日", "当月", "当年"],
activeGatewayTab: 0,
//
deviceIndicators: [
{
name: "照明系统",
total: 1250,
online: 1180,
offline: 70,
icon: "",
bg: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
},
{
name: "空调系统",
total: 86,
online: 78,
offline: 8,
icon: "",
bg: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)"
},
{
name: "水泵系统",
total: 156,
online: 148,
offline: 8,
icon: "",
bg: "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)"
},
{
name: "电梯系统",
total: 24,
online: 22,
offline: 2,
icon: "",
bg: "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)"
},
{
name: "风机系统",
total: 328,
online: 305,
offline: 23,
icon: "",
bg: "linear-gradient(135deg, #fa709a 0%, #fee140 100%)"
},
{
name: "监控系统",
total: 189,
online: 175,
offline: 14,
icon: "",
bg: "linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)"
}
],
//
overview: {
online: 2008,
offline: 125,
warning: 32,
fault: 15
},
//
deviceTrendChart: null,
gatewayTrendChart: null,
statusPieChart: null
};
},
mounted() {
this.initDeviceTrendChart();
this.initGatewayTrendChart();
this.initStatusPieChart();
window.addEventListener("resize", this.handleResize);
},
beforeDestroy() {
window.removeEventListener("resize", this.handleResize);
if (this.deviceTrendChart) this.deviceTrendChart.dispose();
if (this.gatewayTrendChart) this.gatewayTrendChart.dispose();
if (this.statusPieChart) this.statusPieChart.dispose();
},
methods: {
//
handleDeviceTabChange(index) {
this.activeDeviceTab = index;
//
},
//
handleTrendTabChange(index) {
this.activeTrendTab = index;
this.updateDeviceTrendChart();
},
//
handleGatewayTabChange(index) {
this.activeGatewayTab = index;
this.updateGatewayTrendChart();
},
// 线
initDeviceTrendChart() {
this.deviceTrendChart = echarts.init(this.$refs.deviceTrendChartRef);
this.updateDeviceTrendChart();
},
// 线
updateDeviceTrendChart() {
const dataMap = {
0: { //
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
onlineData: [1985, 1990, 1988, 1995, 2000, 1992, 2008],
offlineData: [148, 143, 145, 138, 133, 141, 125]
},
1: { //
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"],
onlineData: [1950, 1965, 1980, 1975, 1990, 1998, 2008],
offlineData: [183, 168, 153, 158, 143, 135, 125]
},
2: { //
xData: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
onlineData: [1800, 1820, 1850, 1880, 1920, 1950, 1980, 1990, 2000, 2005, 2008, 2010],
offlineData: [333, 313, 283, 253, 213, 183, 153, 143, 133, 128, 125, 123]
}
};
const currentData = dataMap[this.activeTrendTab];
const option = {
tooltip: {
trigger: "axis"
},
legend: {
data: ["在线", "离线"],
textStyle: {
color: "#ffffff"
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
data: currentData.xData,
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: {
type: "value",
name: "台",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
series: [
{
name: "在线",
type: "line",
smooth: true,
data: currentData.onlineData,
itemStyle: {
color: "#91CC75"
},
lineStyle: {
color: "#91CC75"
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(145, 204, 117, 0.5)"
},
{
offset: 1,
color: "rgba(145, 204, 117, 0)"
}
]
}
}
},
{
name: "离线",
type: "line",
smooth: true,
data: currentData.offlineData,
itemStyle: {
color: "#EE6666"
},
lineStyle: {
color: "#EE6666"
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(238, 102, 102, 0.5)"
},
{
offset: 1,
color: "rgba(238, 102, 102, 0)"
}
]
}
}
}
]
};
this.deviceTrendChart.setOption(option);
},
// 线
initGatewayTrendChart() {
this.gatewayTrendChart = echarts.init(this.$refs.gatewayTrendChartRef);
this.updateGatewayTrendChart();
},
// 线
updateGatewayTrendChart() {
const dataMap = {
0: { //
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
onlineData: [45, 46, 45, 47, 48, 47, 48],
offlineData: [3, 2, 3, 1, 0, 1, 0]
},
1: { //
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"],
onlineData: [42, 44, 45, 46, 46, 47, 48],
offlineData: [6, 4, 3, 2, 2, 1, 0]
},
2: { //
xData: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
onlineData: [40, 41, 42, 43, 44, 45, 46, 47, 47, 48, 48, 48],
offlineData: [8, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0]
}
};
const currentData = dataMap[this.activeGatewayTab];
const option = {
tooltip: {
trigger: "axis"
},
legend: {
data: ["在线", "离线"],
textStyle: {
color: "#ffffff"
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
data: currentData.xData,
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: {
type: "value",
name: "台",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
series: [
{
name: "在线",
type: "line",
smooth: true,
data: currentData.onlineData,
itemStyle: {
color: "#5470C6"
},
lineStyle: {
color: "#5470C6"
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(84, 112, 198, 0.5)"
},
{
offset: 1,
color: "rgba(84, 112, 198, 0)"
}
]
}
}
},
{
name: "离线",
type: "line",
smooth: true,
data: currentData.offlineData,
itemStyle: {
color: "#FAC858"
},
lineStyle: {
color: "#FAC858"
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(250, 200, 88, 0.5)"
},
{
offset: 1,
color: "rgba(250, 200, 88, 0)"
}
]
}
}
}
]
};
this.gatewayTrendChart.setOption(option);
},
//
initStatusPieChart() {
this.statusPieChart = echarts.init(this.$refs.statusPieRef);
const option = {
tooltip: {
trigger: "item"
},
legend: {
orient: "vertical",
left: "left",
textStyle: {
color: "#ffffff"
}
},
series: [
{
name: "设备状态",
type: "pie",
radius: "60%",
center: ["60%", "50%"],
data: [
{ value: 2008, name: "在线", itemStyle: { color: "#91CC75" } },
{ value: 125, name: "离线", itemStyle: { color: "#EE6666" } },
{ value: 32, name: "告警", itemStyle: { color: "#FAC858" } },
{ value: 15, name: "故障", itemStyle: { color: "#5470C6" } }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)"
}
},
label: {
formatter: "{b}\n{d}%"
}
}
]
};
this.statusPieChart.setOption(option);
},
//
handleResize() {
if (this.deviceTrendChart) this.deviceTrendChart.resize();
if (this.gatewayTrendChart) this.gatewayTrendChart.resize();
if (this.statusPieChart) this.statusPieChart.resize();
}
}
};
</script>
<style lang="scss" scoped>
.time-tabs {
display: flex;
gap: 0.1rem;
.time-tab {
padding: 0.06rem 0.2rem;
font-size: 0.14rem;
color: #ffffff;
opacity: 0.7;
cursor: pointer;
border-radius: 0.04rem;
transition: all 0.3s;
&:hover {
opacity: 1;
}
&.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
opacity: 1;
}
}
}
.device-indicators {
display: flex;
flex-wrap: wrap;
padding: 0.3rem 0.2rem;
gap: 0.2rem;
.indicator-card {
flex: 1;
min-width: 2.5rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
overflow: hidden;
.indicator-header {
display: flex;
align-items: center;
padding: 0.15rem;
color: #ffffff;
.indicator-icon {
width: 0.4rem;
height: 0.4rem;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
margin-right: 0.1rem;
img {
width: 0.24rem;
height: 0.24rem;
}
}
.indicator-name {
font-size: 0.16rem;
font-weight: bold;
}
}
.indicator-content {
padding: 0.2rem;
text-align: center;
.indicator-value {
font-size: 0.36rem;
color: #15e1fd;
font-weight: bold;
margin-bottom: 0.05rem;
}
.indicator-label {
font-size: 0.14rem;
color: #ffffff;
opacity: 0.6;
}
}
.indicator-footer {
display: flex;
justify-content: space-around;
padding: 0.15rem 0.2rem;
background: rgba(0, 0, 0, 0.1);
.footer-item {
font-size: 0.14rem;
color: #ffffff;
.footer-label {
opacity: 0.7;
}
.footer-value {
font-weight: bold;
&.online {
color: #91CC75;
}
&.offline {
color: #EE6666;
}
}
}
}
}
}
.trend-chart {
width: 100%;
height: 3rem;
padding: 0.2rem;
}
.status-overview {
display: flex;
justify-content: space-around;
padding: 0.3rem 0.2rem;
gap: 0.2rem;
.status-card {
flex: 1;
display: flex;
align-items: center;
padding: 0.2rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
.status-icon {
width: 0.08rem;
height: 0.4rem;
border-radius: 0.04rem;
margin-right: 0.15rem;
&.online {
background: #91CC75;
}
&.offline {
background: #EE6666;
}
&.warning {
background: #FAC858;
}
&.fault {
background: #5470C6;
}
}
.status-info {
flex: 1;
.status-value {
font-size: 0.28rem;
color: #15e1fd;
font-weight: bold;
margin-bottom: 0.05rem;
}
.status-label {
font-size: 0.14rem;
color: #ffffff;
opacity: 0.7;
}
}
}
}
.status-pie-chart {
width: 100%;
height: 3rem;
padding: 0.2rem;
}
@media (max-width: 1485px) {
.device-indicators {
.indicator-card {
min-width: 2rem;
}
}
.status-overview {
flex-direction: column;
}
}
</style>

608
src/views/newSystem/systemEnergy.vue

@ -0,0 +1,608 @@
<template>
<div class="app-container">
<!-- 项目整体用能/碳排放趋势 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">项目整体趋势</div>
<div class="time-tabs">
<div
v-for="(tab, index) in trendTimeTabs"
:key="index"
:class="['time-tab', { active: activeTrendTab === index }]"
@click="handleTrendTabChange(index)"
>
{{ tab }}
</div>
</div>
</div>
<div class="trend-charts">
<div class="chart-container">
<div class="chart-title">全系统用电量趋势</div>
<div class="chart" ref="electricTrendChartRef"></div>
</div>
<div class="chart-container">
<div class="chart-title">碳排放指标趋势</div>
<div class="chart" ref="carbonTrendChartRef"></div>
</div>
</div>
</div>
<!-- 分系统用电分布 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">分系统用电分布</div>
</div>
<div class="bar-chart" ref="barChartRef"></div>
</div>
<!-- 周期用量统计 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">近七日用量统计</div>
</div>
<div class="period-stats">
<div class="stat-card">
<div class="stat-label">近七日用电量</div>
<div class="stat-value">{{ periodData.electricity }} <span class="unit">万kWh</span></div>
<div class="stat-change" :class="{ positive: periodData.electricityChange >= 0 }">
<span v-if="periodData.electricityChange >= 0"></span>
<span v-else></span>
环比 {{ Math.abs(periodData.electricityChange) }}%
<span class="compare-label">| 同比 {{ Math.abs(periodData.electricityYoy) }}%</span>
</div>
</div>
<div class="stat-card">
<div class="stat-label">近七日用水量</div>
<div class="stat-value">{{ periodData.water }} <span class="unit">t</span></div>
<div class="stat-change" :class="{ positive: periodData.waterChange >= 0 }">
<span v-if="periodData.waterChange >= 0"></span>
<span v-else></span>
环比 {{ Math.abs(periodData.waterChange) }}%
<span class="compare-label">| 同比 {{ Math.abs(periodData.waterYoy) }}%</span>
</div>
</div>
</div>
</div>
<!-- 周期水电用量可视化 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">周期水电用量分布</div>
</div>
<div class="ring-charts">
<div class="ring-chart-container">
<div class="ring-chart-title">用电量分布</div>
<div class="ring-chart" ref="electricRingRef"></div>
</div>
<div class="ring-chart-container">
<div class="ring-chart-title">用水量分布</div>
<div class="ring-chart" ref="waterRingRef"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "SystemEnergy",
data() {
return {
//
trendTimeTabs: ["近七日", "当月", "当年", "自定义"],
activeTrendTab: 0,
//
periodData: {
electricity: 12.58,
electricityChange: 3.2,
electricityYoy: -1.5,
water: 456.8,
waterChange: -2.1,
waterYoy: 5.3
},
//
electricTrendChart: null,
carbonTrendChart: null,
barChart: null,
electricRingChart: null,
waterRingChart: null
};
},
mounted() {
this.initElectricTrendChart();
this.initCarbonTrendChart();
this.initBarChart();
this.initElectricRingChart();
this.initWaterRingChart();
window.addEventListener("resize", this.handleResize);
},
beforeDestroy() {
window.removeEventListener("resize", this.handleResize);
if (this.electricTrendChart) this.electricTrendChart.dispose();
if (this.carbonTrendChart) this.carbonTrendChart.dispose();
if (this.barChart) this.barChart.dispose();
if (this.electricRingChart) this.electricRingChart.dispose();
if (this.waterRingChart) this.waterRingChart.dispose();
},
methods: {
//
handleTrendTabChange(index) {
this.activeTrendTab = index;
//
},
//
initElectricTrendChart() {
this.electricTrendChart = echarts.init(this.$refs.electricTrendChartRef);
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "line"
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: {
type: "value",
name: "万kWh",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
series: [
{
name: "用电量",
type: "line",
smooth: true,
data: [1.8, 2.1, 1.9, 2.3, 2.5, 1.5, 1.4],
itemStyle: {
color: "#15e1fd"
},
lineStyle: {
color: "#15e1fd"
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(21, 225, 253, 0.5)"
},
{
offset: 1,
color: "rgba(21, 225, 253, 0)"
}
]
}
}
}
]
};
this.electricTrendChart.setOption(option);
},
//
initCarbonTrendChart() {
this.carbonTrendChart = echarts.init(this.$refs.carbonTrendChartRef);
const option = {
tooltip: {
trigger: "axis"
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: {
type: "value",
name: "tCO₂e",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
series: [
{
name: "碳排放",
type: "line",
smooth: true,
data: [0.9, 1.1, 0.95, 1.15, 1.25, 0.75, 0.7],
itemStyle: {
color: "#91CC75"
},
lineStyle: {
color: "#91CC75"
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(145, 204, 117, 0.5)"
},
{
offset: 1,
color: "rgba(145, 204, 117, 0)"
}
]
}
}
}
]
};
this.carbonTrendChart.setOption(option);
},
//
initBarChart() {
this.barChart = echarts.init(this.$refs.barChartRef);
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
data: ["照明系统", "空调系统", "水泵系统", "电梯系统", "风机系统", "监控系统"],
axisLabel: {
color: "rgba(255, 255, 255, 0.8)",
interval: 0,
rotate: 20
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
axisTick: {
show: false
}
},
yAxis: {
type: "value",
name: "kWh",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLabel: {
color: "rgba(255, 255, 255, 0.8)"
},
axisLine: {
lineStyle: {
color: "#365576"
}
},
splitLine: {
lineStyle: {
color: "#1a3d62",
type: "dashed"
}
}
},
series: [
{
name: "用电量",
type: "bar",
barWidth: "40%",
data: [12500, 8900, 5600, 2300, 4200, 1800],
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#15e1fd"
},
{
offset: 1,
color: "#208fff"
}
]
}
}
}
]
};
this.barChart.setOption(option);
},
//
initElectricRingChart() {
this.electricRingChart = echarts.init(this.$refs.electricRingRef);
const option = {
tooltip: {
trigger: "item"
},
legend: {
orient: "vertical",
left: "left",
textStyle: {
color: "#ffffff"
}
},
series: [
{
name: "用电量分布",
type: "pie",
radius: ["30%", "60%"],
center: ["60%", "50%"],
data: [
{ value: 35, name: "照明系统" },
{ value: 25, name: "空调系统" },
{ value: 18, name: "水泵系统" },
{ value: 12, name: "电梯系统" },
{ value: 10, name: "其他系统" }
],
label: {
formatter: "{b}\n{d}%"
}
}
]
};
this.electricRingChart.setOption(option);
},
//
initWaterRingChart() {
this.waterRingChart = echarts.init(this.$refs.waterRingRef);
const option = {
tooltip: {
trigger: "item"
},
legend: {
orient: "vertical",
left: "left",
textStyle: {
color: "#ffffff"
}
},
series: [
{
name: "用水量分布",
type: "pie",
radius: ["30%", "60%"],
center: ["60%", "50%"],
data: [
{ value: 40, name: "生活用水" },
{ value: 25, name: "冷却补水" },
{ value: 20, name: "绿化用水" },
{ value: 15, name: "其他用水" }
],
label: {
formatter: "{b}\n{d}%"
}
}
]
};
this.waterRingChart.setOption(option);
},
//
handleResize() {
if (this.electricTrendChart) this.electricTrendChart.resize();
if (this.carbonTrendChart) this.carbonTrendChart.resize();
if (this.barChart) this.barChart.resize();
if (this.electricRingChart) this.electricRingChart.resize();
if (this.waterRingChart) this.waterRingChart.resize();
}
}
};
</script>
<style lang="scss" scoped>
.time-tabs {
display: flex;
gap: 0.1rem;
.time-tab {
padding: 0.06rem 0.2rem;
font-size: 0.14rem;
color: #ffffff;
opacity: 0.7;
cursor: pointer;
border-radius: 0.04rem;
transition: all 0.3s;
&:hover {
opacity: 1;
}
&.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
opacity: 1;
}
}
}
.trend-charts {
display: flex;
gap: 0.16rem;
padding: 0.2rem;
.chart-container {
flex: 1;
.chart-title {
font-size: 0.16rem;
color: #ffffff;
text-align: center;
margin-bottom: 0.15rem;
}
.chart {
width: 100%;
height: 2.5rem;
}
}
}
.bar-chart {
width: 100%;
height: 3rem;
padding: 0.2rem;
}
.period-stats {
display: flex;
justify-content: space-around;
padding: 0.3rem 0.2rem;
gap: 0.2rem;
.stat-card {
flex: 1;
padding: 0.25rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
text-align: center;
.stat-label {
font-size: 0.16rem;
color: #ffffff;
opacity: 0.8;
margin-bottom: 0.15rem;
}
.stat-value {
font-size: 0.28rem;
color: #15e1fd;
font-weight: bold;
margin-bottom: 0.1rem;
.unit {
font-size: 0.16rem;
opacity: 0.8;
}
}
.stat-change {
font-size: 0.14rem;
color: #91CC75;
&.positive {
color: #ee5e5e;
}
.compare-label {
margin-left: 0.15rem;
opacity: 0.8;
}
}
}
}
.ring-charts {
display: flex;
gap: 0.2rem;
padding: 0.2rem;
.ring-chart-container {
flex: 1;
text-align: center;
.ring-chart-title {
font-size: 0.16rem;
color: #ffffff;
margin-bottom: 0.15rem;
}
.ring-chart {
width: 100%;
height: 2.5rem;
}
}
}
@media (max-width: 1485px) {
.trend-charts,
.ring-charts {
flex-direction: column;
}
.period-stats {
flex-direction: column;
}
}
</style>

503
src/views/newSystem/systemHome.vue

@ -0,0 +1,503 @@
<template>
<div class="app-container">
<!-- 综合类指标 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">综合指标</div>
</div>
<div class="comprehensive-indicators">
<div class="indicator-item">
<div class="indicator-label">综合节能率</div>
<div class="indicator-value">{{ comprehensiveData.energySavingRate }}%</div>
</div>
<div class="indicator-item">
<div class="indicator-label">节电金额</div>
<div class="indicator-value">¥{{ comprehensiveData.electricSavingAmount }}</div>
</div>
<div class="indicator-item">
<div class="indicator-label">减碳量</div>
<div class="indicator-value">{{ comprehensiveData.carbonReduction }}t</div>
</div>
<div class="indicator-item">
<div class="indicator-label">累计用电</div>
<div class="indicator-value">{{ comprehensiveData.totalElectricity }}kWh</div>
</div>
<div class="indicator-item">
<div class="indicator-label">节电量</div>
<div class="indicator-value">{{ comprehensiveData.electricSaving }}kWh</div>
</div>
</div>
</div>
<!-- 设备规模指标 -->
<div class="special-div">
<div class="special-top">
<div class="special-title">设备规模</div>
<div class="time-tabs">
<div
v-for="(tab, index) in timeTabs"
:key="index"
:class="['time-tab', { active: activeTab === index }]"
@click="handleTabChange(index)"
>
{{ tab }}
</div>
</div>
</div>
<div class="device-scale">
<div class="device-item" v-for="device in deviceList" :key="device.name">
<div class="device-icon" :style="{ background: device.bg }">
<img :src="device.icon" :alt="device.name" />
</div>
<div class="device-info">
<div class="device-name">{{ device.name }}</div>
<div class="device-count">{{ device.count }}</div>
</div>
</div>
</div>
</div>
<!-- 项目节能统计和用能类型 -->
<div class="energy-stats-row">
<!-- 项目节能统计 -->
<div class="special-div energy-stats">
<div class="special-top">
<div class="special-title">项目节能统计</div>
</div>
<div class="energy-data">
<div class="energy-item">
<div class="energy-label">日节电量</div>
<div class="energy-value">{{ energySaving.daySaving }}kWh</div>
</div>
<div class="energy-item">
<div class="energy-label">累计节电量</div>
<div class="energy-value">{{ energySaving.totalSaving }}kWh</div>
</div>
</div>
<div class="ring-chart" ref="ringChartRef"></div>
<div class="chart-legend">
<div
class="legend-item"
v-for="(item, index) in energyLegend"
:key="index"
>
<span
class="legend-color"
:style="{ background: item.color }"
></span>
<span class="legend-text">{{ item.name }}</span>
</div>
</div>
<div class="compare-tabs">
<div
:class="['compare-tab', { active: compareType === 'yoy' }]"
@click="compareType = 'yoy'"
>
同比
</div>
<div
:class="['compare-tab', { active: compareType === 'mom' }]"
@click="compareType = 'mom'"
>
环比
</div>
</div>
</div>
<!-- 项目用能类型 -->
<div class="special-div energy-type">
<div class="special-top">
<div class="special-title">项目用能类型</div>
</div>
<div class="pie-chart" ref="pieChartRef"></div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "SystemHome",
data() {
return {
//
comprehensiveData: {
energySavingRate: 15.8,
electricSavingAmount: 125.6,
carbonReduction: 89.3,
totalElectricity: 45680,
electricSaving: 7890
},
//
timeTabs: ["近七日", "当月", "当年", "自定义"],
activeTab: 0,
//
deviceList: [
{ name: "照明系统", count: 1250, icon: "", bg: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)" },
{ name: "空调系统", count: 86, icon: "", bg: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)" },
{ name: "水泵系统", count: 156, icon: "", bg: "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)" },
{ name: "电梯系统", count: 24, icon: "", bg: "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)" },
{ name: "风机系统", count: 328, icon: "", bg: "linear-gradient(135deg, #fa709a 0%, #fee140 100%)" },
{ name: "监控系统", count: 189, icon: "", bg: "linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)" }
],
//
energySaving: {
daySaving: 328,
totalSaving: 7890
},
//
energyLegend: [
{ name: "照明系统", color: "#5470C6" },
{ name: "空调系统", color: "#91CC75" },
{ name: "水泵系统", color: "#FAC858" },
{ name: "其他系统", color: "#EE6666" }
],
//
compareType: "yoy",
//
ringChart: null,
pieChart: null
};
},
mounted() {
this.initRingChart();
this.initPieChart();
window.addEventListener("resize", this.handleResize);
},
beforeDestroy() {
window.removeEventListener("resize", this.handleResize);
if (this.ringChart) this.ringChart.dispose();
if (this.pieChart) this.pieChart.dispose();
},
watch: {
compareType() {
this.updateRingChart();
}
},
methods: {
//
handleTabChange(index) {
this.activeTab = index;
//
},
//
initRingChart() {
this.ringChart = echarts.init(this.$refs.ringChartRef);
this.updateRingChart();
},
//
updateRingChart() {
const data = this.compareType === "yoy"
? [
{ value: 35, name: "照明系统" },
{ value: 28, name: "空调系统" },
{ value: 22, name: "水泵系统" },
{ value: 15, name: "其他系统" }
]
: [
{ value: 32, name: "照明系统" },
{ value: 30, name: "空调系统" },
{ value: 25, name: "水泵系统" },
{ value: 13, name: "其他系统" }
];
const option = {
tooltip: {
trigger: "item",
formatter: "{b}: {c}% ({d}%)"
},
legend: {
show: false
},
series: [
{
name: "节能占比",
type: "pie",
radius: ["40%", "70%"],
center: ["50%", "45%"],
avoidLabelOverlap: false,
label: {
show: true,
formatter: "{b}\n{d}%"
},
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: "bold"
}
},
data: data
}
]
};
this.ringChart.setOption(option);
},
//
initPieChart() {
this.pieChart = echarts.init(this.$refs.pieChartRef);
const option = {
tooltip: {
trigger: "item",
formatter: "{b}: {c}% ({d}%)"
},
legend: {
orient: "vertical",
left: "left",
textStyle: {
color: "#ffffff"
}
},
series: [
{
name: "用能类型",
type: "pie",
radius: "60%",
center: ["60%", "50%"],
data: [
{ value: 28, name: "生活用水" },
{ value: 35, name: "空调用电" },
{ value: 18, name: "照明用电" },
{ value: 12, name: "动力用电" },
{ value: 7, name: "其他" }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)"
}
},
label: {
formatter: "{b}\n{d}%"
}
}
]
};
this.pieChart.setOption(option);
},
//
handleResize() {
if (this.ringChart) this.ringChart.resize();
if (this.pieChart) this.pieChart.resize();
}
}
};
</script>
<style lang="scss" scoped>
.comprehensive-indicators {
display: flex;
justify-content: space-around;
padding: 0.3rem 0.2rem;
flex-wrap: wrap;
gap: 0.2rem;
.indicator-item {
text-align: center;
flex: 1;
min-width: 1.8rem;
.indicator-label {
font-size: 0.16rem;
color: #ffffff;
opacity: 0.8;
margin-bottom: 0.1rem;
}
.indicator-value {
font-size: 0.24rem;
color: #15e1fd;
font-weight: bold;
}
}
}
.time-tabs {
display: flex;
gap: 0.1rem;
.time-tab {
padding: 0.06rem 0.2rem;
font-size: 0.14rem;
color: #ffffff;
opacity: 0.7;
cursor: pointer;
border-radius: 0.04rem;
transition: all 0.3s;
&:hover {
opacity: 1;
}
&.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
opacity: 1;
}
}
}
.device-scale {
display: flex;
flex-wrap: wrap;
padding: 0.3rem 0.2rem;
gap: 0.2rem;
.device-item {
display: flex;
align-items: center;
padding: 0.15rem 0.25rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.08rem;
flex: 1;
min-width: 2rem;
.device-icon {
width: 0.5rem;
height: 0.5rem;
border-radius: 0.08rem;
display: flex;
align-items: center;
justify-content: center;
margin-right: 0.15rem;
img {
width: 0.3rem;
height: 0.3rem;
}
}
.device-info {
flex: 1;
.device-name {
font-size: 0.14rem;
color: #ffffff;
opacity: 0.8;
margin-bottom: 0.05rem;
}
.device-count {
font-size: 0.2rem;
color: #15e1fd;
font-weight: bold;
}
}
}
}
.energy-stats-row {
display: flex;
gap: 0.16rem;
margin-top: 0.16rem;
.special-div {
flex: 1;
}
}
.energy-stats {
.energy-data {
display: flex;
justify-content: space-around;
padding: 0.2rem;
.energy-item {
text-align: center;
.energy-label {
font-size: 0.14rem;
color: #ffffff;
opacity: 0.7;
margin-bottom: 0.08rem;
}
.energy-value {
font-size: 0.22rem;
color: #15e1fd;
font-weight: bold;
}
}
}
.ring-chart {
width: 100%;
height: 2.5rem;
}
.chart-legend {
display: flex;
justify-content: center;
gap: 0.3rem;
padding: 0.1rem 0;
.legend-item {
display: flex;
align-items: center;
font-size: 0.14rem;
color: #ffffff;
.legend-color {
width: 0.12rem;
height: 0.12rem;
border-radius: 50%;
margin-right: 0.08rem;
}
}
}
.compare-tabs {
display: flex;
justify-content: center;
gap: 0.2rem;
margin-top: 0.1rem;
.compare-tab {
padding: 0.05rem 0.2rem;
font-size: 0.14rem;
color: #ffffff;
opacity: 0.7;
cursor: pointer;
border-radius: 0.04rem;
transition: all 0.3s;
&:hover {
opacity: 1;
}
&.active {
background: linear-gradient(135deg, #5470C6 0%, #91CC75 100%);
opacity: 1;
}
}
}
}
.energy-type {
.pie-chart {
width: 100%;
height: 3.2rem;
}
}
@media (max-width: 1485px) {
.comprehensive-indicators {
.indicator-item {
min-width: 1.5rem;
flex: none;
}
}
.device-scale {
.device-item {
min-width: 1.8rem;
}
}
.energy-stats-row {
flex-direction: column;
}
}
</style>
Loading…
Cancel
Save