fix: 大屏自适应

This commit is contained in:
fyy
2025-09-15 11:13:58 +08:00
parent 5f927bf330
commit e752c0a254

View File

@@ -22,12 +22,12 @@
<div class="header"> <div class="header">
<div class="header-item"> <div class="header-item">
<span class="header-label">今年用电量</span> <span class="header-label">今年用电量</span>
<span class="header-value orange">{{powerYear}}</span> <span class="header-value orange">{{ powerYear }}</span>
<span class="header-unit">KW·h</span> <span class="header-unit">KW·h</span>
</div> </div>
<div class="header-item"> <div class="header-item">
<span class="header-label">本月用电总量</span> <span class="header-label">本月用电总量</span>
<span class="header-value green">{{powerMonth}}</span> <span class="header-value green">{{ powerMonth }}</span>
<span class="header-unit">KW·h</span> <span class="header-unit">KW·h</span>
</div> </div>
<div class="header-item"> <div class="header-item">
@@ -42,7 +42,7 @@
</div> </div>
<div class="header-item"> <div class="header-item">
<span class="header-label">设备总数</span> <span class="header-label">设备总数</span>
<span class="header-value green">{{total}}</span> <span class="header-value green">{{ total }}</span>
<span class="header-unit"></span> <span class="header-unit"></span>
</div> </div>
</div> </div>
@@ -53,7 +53,7 @@
<div <div
ref="barChart" ref="barChart"
class="bar-chart" class="bar-chart"
style="width: 100%; height:242px;" style="width: 100%; height: 15.12rem"
@click="goWorkOrder" @click="goWorkOrder"
></div> ></div>
</div> </div>
@@ -71,54 +71,44 @@
</div> </div>
</div> </div>
<div class="content-center-second"> <div class="content-center-second">
<div style="position: relative;left: 2%;padding-top: 10%"> <div style="position: relative; left: 2%; padding-top: 10%">
<div class="offline">离线</div> <div class="offline">离线</div>
<div class="online">在线</div> <div class="online">在线</div>
</div> </div>
<div> <div>
<EchartsUI <EchartsUI ref="water" height="100%" width="8.875rem" />
ref="water"
height="100%"
width="150px"
/>
</div> </div>
<div> <div>
<EchartsUI <EchartsUI ref="electricity" height="100%" width="8.875rem" />
ref="electricity"
height="100%"
width="150px"
/>
</div> </div>
<div> <div>
<EchartsUI <EchartsUI ref="accessControl" height="100%" width="8.875rem" />
ref="accessControl"
height="100%"
width="150px"
/>
</div> </div>
<div> <div>
<EchartsUI <EchartsUI ref="camera" height="100%" width="8.875rem" />
ref="camera"
height="100%"
width="150px"
/>
</div> </div>
</div> </div>
</div> </div>
<div class="content-right"> <div class="content-right">
<div class="first"> <div class="first">
<div class="mt-8" style="position: relative"> <div class="mt-8" style="position: relative">
<div <div class="flex items-center justify-between p-5">
class="flex items-center justify-between p-5"
>
<Radio.Group v-model:value="timeUnit" size="small"> <Radio.Group v-model:value="timeUnit" size="small">
<Radio.Button value="1" style="background-color: transparent;color: #fff">电量</Radio.Button> <Radio.Button
value="1"
style="background-color: transparent; color: #fff"
>电量</Radio.Button
>
</Radio.Group> </Radio.Group>
<DatePicker <DatePicker
v-model:value="selectedDate" v-model:value="selectedDate"
picker="month" picker="month"
placeholder="请选择月份" placeholder="请选择月份"
style="width: 130px;height: 25px;background-color: transparent;" style="
width: 8.125rem;
height: 1.56rem;
background-color: transparent;
"
@change="handleDateChange" @change="handleDateChange"
class="white-text-datepicker" class="white-text-datepicker"
/> />
@@ -135,20 +125,24 @@
</div> </div>
<div class="second" @click="goWarningProcessing"> <div class="second" @click="goWarningProcessing">
<div class="second-box"> <div class="second-box">
<div class="box-content" v-for="(item,index) in warning" :key="index"> <div
class="box-content"
v-for="(item, index) in warning"
:key="index"
>
<div class="box-content-label">{{ item.typeName }}</div> <div class="box-content-label">{{ item.typeName }}</div>
<div class="box-content-num">{{item.total}}</div> <div class="box-content-num">{{ item.total }}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="third" @click="goReservationRecords"> <div class="third" @click="goReservationRecords">
<div class="third-item"> <div class="third-item">
<div class="third-title">会议室总数</div> <div class="third-title">会议室总数</div>
<div class="third-num">{{todayMeetCount?.meetCount}}</div> <div class="third-num">{{ todayMeetCount?.meetCount }}</div>
</div> </div>
<div class="third-item"> <div class="third-item">
<div class="third-title">当日预约会议室总数</div> <div class="third-title">当日预约会议室总数</div>
<div class="third-num">{{todayMeetCount?.timeQuantity}}</div> <div class="third-num">{{ todayMeetCount?.timeQuantity }}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -158,14 +152,23 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {getStatistics,getworkOrder,getTodayMeetCount,getHydropower,getAccessControl,getCamera,queryTwentyfourRunningDatasByPlNos,getVisitorCount} from '#/api/analytics'; import {
getStatistics,
getworkOrder,
getTodayMeetCount,
getHydropower,
getAccessControl,
getCamera,
queryTwentyfourRunningDatasByPlNos,
getVisitorCount,
} from '#/api/analytics';
import AnalyticsTrends from './analytics-trends.vue'; import AnalyticsTrends from './analytics-trends.vue';
import { computed } from 'vue'; import { computed } from 'vue';
import { Radio } from 'ant-design-vue'; import { Radio } from 'ant-design-vue';
import {EchartsUI, useEcharts} from "@vben/plugins/echarts"; import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
//预警类型 //预警类型
const warning = ref([]) const warning = ref([]);
async function getWarning() { async function getWarning() {
warning.value = await getStatistics(); warning.value = await getStatistics();
} }
@@ -198,11 +201,11 @@ const water = ref();
const waterTotal = ref(); const waterTotal = ref();
const { renderEcharts: renderWater } = useEcharts(water); const { renderEcharts: renderWater } = useEcharts(water);
async function fetchWater() { async function fetchWater() {
const data = await getHydropower() const data = await getHydropower();
waterTotal.value = data.water.off + data.water.on; waterTotal.value = data.water.off + data.water.on;
const waterData = [ const waterData = [
{ name: '离线', value: data.water.off }, { name: '离线', value: data.water.off },
{ name: '在线', value: data.water.on } { name: '在线', value: data.water.on },
]; ];
renderWater({ renderWater({
title: { title: {
@@ -213,10 +216,10 @@ async function fetchWater() {
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontSize: 16, fontSize: 16,
} },
}, },
tooltip: { tooltip: {
trigger: 'item' trigger: 'item',
}, },
series: [ series: [
{ {
@@ -226,7 +229,7 @@ async function fetchWater() {
itemStyle: { itemStyle: {
borderRadius: 5, borderRadius: 5,
borderColor: '#fff', borderColor: '#fff',
borderWidth: 1 borderWidth: 1,
}, },
label: { label: {
show: true, show: true,
@@ -234,32 +237,32 @@ async function fetchWater() {
formatter: `${waterTotal.value}`, formatter: `${waterTotal.value}`,
fontSize: 14, fontSize: 14,
color: '#fff', color: '#fff',
fontWeight: 'bold' fontWeight: 'bold',
}, },
emphasis: { emphasis: {
label: { label: {
show: true, show: true,
fontSize: 14, fontSize: 14,
} },
}, },
labelLine: { labelLine: {
show: false show: false,
}, },
data:waterData data: waterData,
} },
] ],
}) });
} }
// 电 // 电
const electricity = ref(); const electricity = ref();
const electricityTotal = ref(); const electricityTotal = ref();
const { renderEcharts: renderElectricity } = useEcharts(electricity); const { renderEcharts: renderElectricity } = useEcharts(electricity);
async function fetchElectricity() { async function fetchElectricity() {
const data = await getHydropower() const data = await getHydropower();
electricityTotal.value = data.power.off + data.power.on; electricityTotal.value = data.power.off + data.power.on;
const electricityData = [ const electricityData = [
{ name: '离线', value: data.power.off }, { name: '离线', value: data.power.off },
{ name: '在线', value: data.power.on } { name: '在线', value: data.power.on },
]; ];
renderElectricity({ renderElectricity({
title: { title: {
@@ -270,10 +273,10 @@ async function fetchElectricity() {
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontSize: 16, fontSize: 16,
} },
}, },
tooltip: { tooltip: {
trigger: 'item' trigger: 'item',
}, },
series: [ series: [
{ {
@@ -283,7 +286,7 @@ async function fetchElectricity() {
itemStyle: { itemStyle: {
borderRadius: 5, borderRadius: 5,
borderColor: '#fff', borderColor: '#fff',
borderWidth: 1 borderWidth: 1,
}, },
label: { label: {
show: true, show: true,
@@ -291,32 +294,32 @@ async function fetchElectricity() {
formatter: `${electricityTotal.value}`, formatter: `${electricityTotal.value}`,
fontSize: 14, fontSize: 14,
color: '#fff', color: '#fff',
fontWeight: 'bold' fontWeight: 'bold',
}, },
emphasis: { emphasis: {
label: { label: {
show: true, show: true,
fontSize: 14, fontSize: 14,
} },
}, },
labelLine: { labelLine: {
show: false show: false,
}, },
data:electricityData data: electricityData,
} },
] ],
}) });
} }
// 门禁 // 门禁
const accessControl = ref(); const accessControl = ref();
const accessControlTotal = ref(); const accessControlTotal = ref();
const { renderEcharts: renderAccessControl } = useEcharts(accessControl); const { renderEcharts: renderAccessControl } = useEcharts(accessControl);
async function fetchAccessControl() { async function fetchAccessControl() {
const data = await getAccessControl() const data = await getAccessControl();
accessControlTotal.value = data.off + data.on; accessControlTotal.value = data.off + data.on;
const accessControlData = [ const accessControlData = [
{ name: '离线', value: data.off }, { name: '离线', value: data.off },
{ name: '在线', value: data.on } { name: '在线', value: data.on },
]; ];
renderAccessControl({ renderAccessControl({
title: { title: {
@@ -327,10 +330,10 @@ async function fetchAccessControl() {
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontSize: 16, fontSize: 16,
} },
}, },
tooltip: { tooltip: {
trigger: 'item' trigger: 'item',
}, },
series: [ series: [
{ {
@@ -340,7 +343,7 @@ async function fetchAccessControl() {
itemStyle: { itemStyle: {
borderRadius: 5, borderRadius: 5,
borderColor: '#fff', borderColor: '#fff',
borderWidth: 1 borderWidth: 1,
}, },
label: { label: {
show: true, show: true,
@@ -348,32 +351,32 @@ async function fetchAccessControl() {
formatter: `${accessControlTotal.value}`, formatter: `${accessControlTotal.value}`,
fontSize: 14, fontSize: 14,
color: '#fff', color: '#fff',
fontWeight: 'bold' fontWeight: 'bold',
}, },
emphasis: { emphasis: {
label: { label: {
show: true, show: true,
fontSize: 14, fontSize: 14,
} },
}, },
labelLine: { labelLine: {
show: false show: false,
}, },
data:accessControlData data: accessControlData,
} },
] ],
}) });
} }
// 摄像头 // 摄像头
const camera = ref(); const camera = ref();
const cameraTotal = ref(); const cameraTotal = ref();
const { renderEcharts: renderCamera } = useEcharts(camera); const { renderEcharts: renderCamera } = useEcharts(camera);
async function fetchCamera() { async function fetchCamera() {
const data = await getCamera() const data = await getCamera();
cameraTotal.value = data.off + data.on; cameraTotal.value = data.off + data.on;
const cameraData = [ const cameraData = [
{ name: '离线', value: data.off }, { name: '离线', value: data.off },
{ name: '在线', value: data.on } { name: '在线', value: data.on },
]; ];
renderCamera({ renderCamera({
title: { title: {
@@ -384,10 +387,10 @@ async function fetchCamera() {
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontSize: 16, fontSize: 16,
} },
}, },
tooltip: { tooltip: {
trigger: 'item' trigger: 'item',
}, },
series: [ series: [
{ {
@@ -397,7 +400,7 @@ async function fetchCamera() {
itemStyle: { itemStyle: {
borderRadius: 5, borderRadius: 5,
borderColor: '#fff', borderColor: '#fff',
borderWidth: 1 borderWidth: 1,
}, },
label: { label: {
show: true, show: true,
@@ -405,24 +408,29 @@ async function fetchCamera() {
formatter: `${cameraTotal.value}`, formatter: `${cameraTotal.value}`,
fontSize: 14, fontSize: 14,
color: '#fff', color: '#fff',
fontWeight: 'bold' fontWeight: 'bold',
}, },
emphasis: { emphasis: {
label: { label: {
show: true, show: true,
fontSize: 14, fontSize: 14,
} },
}, },
labelLine: { labelLine: {
show: false show: false,
}, },
data:cameraData data: cameraData,
} },
] ],
}) });
} }
const total = computed(() => { const total = computed(() => {
return Number(waterTotal.value) + Number(electricityTotal.value) + Number(cameraTotal.value) + Number(accessControlTotal.value); return (
Number(waterTotal.value) +
Number(electricityTotal.value) +
Number(cameraTotal.value) +
Number(accessControlTotal.value)
);
}); });
//顶部 电 //顶部 电
const powerMonth = ref(); const powerMonth = ref();
@@ -432,7 +440,6 @@ function fetchPowerDate(data) {
powerYear.value = data.month.nowYear.total; powerYear.value = data.month.nowYear.total;
} }
import { ref, onMounted, onBeforeUnmount } from 'vue'; import { ref, onMounted, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
@@ -442,7 +449,7 @@ import {
removeChartFromResizeManager, removeChartFromResizeManager,
} from '#/utils/echartsResize'; } from '#/utils/echartsResize';
import { useFlexibleRem } from '#/utils/useFlexibleRem'; import { useFlexibleRem } from '#/utils/useFlexibleRem';
import {DatePicker} from "ant-design-vue"; import { DatePicker } from 'ant-design-vue';
useFlexibleRem(); useFlexibleRem();
// 路由 // 路由
const router = useRouter(); const router = useRouter();
@@ -508,14 +515,16 @@ const initBarChart = async () => {
if (!barChart.value) return; if (!barChart.value) return;
const myChart = echarts.init(barChart.value); const myChart = echarts.init(barChart.value);
const workOrder = await getworkOrder(); const workOrder = await getworkOrder();
const title = workOrder.map((item) => {return item.type}) const title = workOrder.map((item) => {
return item.type;
});
const statuses = ['已派单', '处理中', '已完成', '创建工单']; const statuses = ['已派单', '处理中', '已完成', '创建工单'];
const seriesData = statuses.map(status => { const seriesData = statuses.map((status) => {
return { return {
name: status, name: status,
type: 'bar', type: 'bar',
emphasis: { focus: 'series' }, emphasis: { focus: 'series' },
data: workOrder.map(item => item.statusCounts[status]) data: workOrder.map((item) => item.statusCounts[status]),
}; };
}); });
myChart.setOption({ myChart.setOption({
@@ -524,13 +533,13 @@ const initBarChart = async () => {
data: statuses, data: statuses,
top: 10, top: 10,
textStyle: { textStyle: {
color: '#fff' color: '#fff',
} },
}, },
grid: { left: 40, right: 20, top: 50, bottom: 25 }, grid: { left: 40, right: 20, top: 50, bottom: 25 },
xAxis: { data: title ,axisLabel: { color: '#fff' },}, xAxis: { data: title, axisLabel: { color: '#fff' } },
yAxis: {axisLabel: { color: '#fff' },}, yAxis: { axisLabel: { color: '#fff' } },
series:seriesData, series: seriesData,
}); });
}; };
@@ -538,24 +547,24 @@ const initBarChart = async () => {
const initPowerChart = async () => { const initPowerChart = async () => {
if (!powerChart.value) return; if (!powerChart.value) return;
const chart = echarts.init(powerChart.value); const chart = echarts.init(powerChart.value);
const res = await getVisitorCount() const res = await getVisitorCount();
const visitorData = []; const visitorData = [];
const invitationData = []; const invitationData = [];
res.forEach(item => { res.forEach((item) => {
const { type, todayCounts } = item; const { type, todayCounts } = item;
Object.entries(todayCounts).forEach(([date, count]) => { Object.entries(todayCounts).forEach(([date, count]) => {
const dataItem = { date, value: count }; const dataItem = { date, value: count };
if (type === "访客") { if (type === '访客') {
visitorData.push(dataItem); visitorData.push(dataItem);
} else if (type === "邀约") { } else if (type === '邀约') {
invitationData.push(dataItem); invitationData.push(dataItem);
} }
}); });
}); });
const dates = visitorData.map(item => item.date); const dates = visitorData.map((item) => item.date);
const visitor = visitorData.map(item => item.value); const visitor = visitorData.map((item) => item.value);
const invitation = invitationData.map(item => item.value); const invitation = invitationData.map((item) => item.value);
console.log(dates,1,visitor,2,invitation) console.log(dates, 1, visitor, 2, invitation);
const option = { const option = {
tooltip: { trigger: 'axis' }, tooltip: { trigger: 'axis' },
grid: { left: 40, right: 20, top: 50, bottom: 20 }, grid: { left: 40, right: 20, top: 50, bottom: 20 },
@@ -604,9 +613,9 @@ const initPowerChart = async () => {
// 人流车流 // 人流车流
const initEnvChart = async () => { const initEnvChart = async () => {
if (!envChart.value) return; if (!envChart.value) return;
const data = await queryTwentyfourRunningDatasByPlNos() const data = await queryTwentyfourRunningDatasByPlNos();
const inCounts = data.data.inCounts const inCounts = data.data.inCounts;
const staticTimeStrs = data.data.staticTimeStrs const staticTimeStrs = data.data.staticTimeStrs;
const chart = echarts.init(envChart.value); const chart = echarts.init(envChart.value);
const option = { const option = {
tooltip: { trigger: 'axis' }, tooltip: { trigger: 'axis' },
@@ -655,12 +664,12 @@ const initEnvChart = async () => {
// 组件挂载时初始化 // 组件挂载时初始化
onMounted(() => { onMounted(() => {
getWarning() getWarning();
handleTodayMeetCount() handleTodayMeetCount();
fetchWater() fetchWater();
fetchElectricity() fetchElectricity();
fetchAccessControl() fetchAccessControl();
fetchCamera() fetchCamera();
updateTime(); updateTime();
timer = setInterval(updateTime, 1000); timer = setInterval(updateTime, 1000);
@@ -758,7 +767,7 @@ onBeforeUnmount(() => {
} }
} }
.header { .header {
margin-top: 2.125rem; margin-top: 1.125rem;
margin-left: 4.625rem; margin-left: 4.625rem;
margin-right: 4.25rem; margin-right: 4.25rem;
height: 6rem; height: 6rem;
@@ -822,7 +831,7 @@ onBeforeUnmount(() => {
.first { .first {
height: 16.81rem; height: 16.81rem;
.bar-chart { .bar-chart {
margin-top: 35px; margin-top: 2.187rem;
} }
} }
.second { .second {
@@ -858,25 +867,27 @@ onBeforeUnmount(() => {
height: 12.5rem; height: 12.5rem;
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
.offline,.online { .offline,
.online {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 0.5rem;
color: #fff; color: #fff;
font-size: 14px; font-size: 0.875rem;
} }
.offline::before,.online::before { .offline::before,
content: ""; .online::before {
width: 30px; content: '';
height: 15px; width: 1.875rem;
border-radius: 3px; height: 0.94rem;
border: 1.5px solid #fff; border-radius: 0.18rem;
border: 0.1rem solid #fff;
} }
.offline::before{ .offline::before {
background-color: #5470C6; background-color: #5470c6;
} }
.online::before { .online::before {
background-color: #9CDB7D; background-color: #9cdb7d;
} }
} }
} }
@@ -934,19 +945,19 @@ onBeforeUnmount(() => {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
.third-item{ .third-item {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
.third-title{ .third-title {
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-weight: 400; font-weight: 400;
font-size: 0.8rem; font-size: 0.8rem;
color: #c4d6ff; color: #c4d6ff;
line-height: 2rem; line-height: 2rem;
} }
.third-num{ .third-num {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;