|
|
<template> <div class="borads-index"> <screen-adapter class="adapter"> <div class="boards-container"> <div class="center" title="使用鼠标左键、滚轮实现拖拽、放大缩小。"></div> <div class="top"> <div class="title" @click="reset" title="点击此标题将鸟瞰图恢复成初始状态。">{{ $store.state.user.tenantName || '平台看板' }}</div> <div class="time" v-if="timeCount && timeCount.ts > 0"> <div class="time-left"> {{ $m(timeCount.ts).format('HH:mm:ss') }} </div> <div class="time-right"> <div>{{ $date.getDay(timeCount.ts) }}</div> <div> {{ $m(timeCount.ts).format('YYYY/MM/DD') }} </div> </div> </div> </div> <div class="pop"> <pop v-for="(item, index) in pop" :key="index" :item="item" :index="index"></pop> </div> <div class="left"> <block v-for="(item, index) in left" :key="index" :item="item" :data-form="dataForm" @change-code="dataForm.code = $event"> <component :is="item.comp" :key="index" :item="item" :option="item.option" tip-loop></component> </block> </div> <div class="right"> <block v-for="(item, index) in right" :key="index" :item="item" :data-form="dataForm" @change-code="dataForm.code = $event"> <component :is="item.comp" :key="index" :item="item" :option="item.option" tip-loop></component> </block> </div> <!--<div class="bottom"> <block size-type="2" :item="bottom"> <component :is="bottom.comp" :item="bottom" :option="bottom.option" tip-loop></component> </block> </div>--> </div> <tooltip :data="toolTipData" /> </screen-adapter> </div></template>
<script lang="ts">import { defineComponent, reactive, toRefs, onMounted, nextTick, watch, onBeforeUnmount } from 'vue';import ScreenAdapter from '@/components/screen-adapter.vue';import Block from './comp/block.vue';import Bar from './comp/bar.vue';import Pop from './comp/pop.vue';import timeCountHooks from '@/hooks/time-count';import { useFetch } from '@/hooks/fetch';import utilService from '@/service/utilService';import Chart from '@/components/chart.vue';import { costStatistic, elecPayload, monthEnergyUsageTrend, usageRanking, energyUsageDistribution } from './common/model';import { IObject } from '@/types/interface';import moment from 'moment';import toolHooks from '@/hooks/tool';import { init, setPointerLineStatusAll } from './common/style';import Tooltip from './comp/tooltip.vue';import switchScreenHooks from '@/hooks/switch-screen';export default defineComponent({ components: { ScreenAdapter, Tooltip, Block, Chart,
Bar, Pop, }, setup() { const { timeCount } = timeCountHooks(); const { generateSvg2Dom } = toolHooks();
const state = reactive({ opt: { scale: 0.8 }, dragStretch: null, toolTipData: {}, timer: null, dataForm: { code: '电', codeMap: { 电: 'kWh', 水: 't', 蒸汽: 't', 压缩空气: 'Nm³' }, }, timeCount, pop: [ { key: 'yearCarbon', icon: '', label: '年碳排放量', value: '--', unit: 'tCO₂', toFixed: 2, }, { key: 'monthConsumptionValue', icon: '', label: '月综合能耗', value: '--', unit: 'tce', }, { key: 'yearConsumptionValue', icon: '', label: '年综合能耗', value: '--', unit: 'tce', }, ], left: [ { comp: 'bar', title: '月用能统计', data: [ { key: 'electricDayValue', icon: 'elec', label: '电用量', value: '', unit: 'kWh', }, { key: 'waterDayValue', icon: 'water', label: '水用量', value: '', unit: 't', }, { key: 'steamDayValue', icon: 'steam', label: '蒸汽用量', value: '', unit: 't', }, { key: 'airDayValue', icon: 'air', label: '压缩空气用量', value: '', unit: 'Nm³', }, { key: 'gasValue', icon: 'gas', label: '天然气用量', value: '', unit: 'Nm³', }, ], }, { title: '年用能统计', comp: 'bar', data: [ { key: 'electricDayValue', icon: 'elec', label: '电用量', value: '', unit: 'kWh', }, { key: 'waterDayValue', icon: 'water', label: '水用量', value: '', unit: 't', }, { key: 'steamDayValue', icon: 'steam', label: '蒸汽用量', value: '', unit: 't', }, { key: 'airDayValue', icon: 'air', label: '压缩空气用量', value: '', unit: 'Nm³', }, { key: 'gasValue', icon: 'gas', label: '天然气用量', value: '', unit: 'Nm³', }, ], }, { comp: 'chart', title: '当日电力负荷', option: elecPayload(), unit: 'kWh', }, ], right: [ { comp: 'chart', title: '能耗统计(月)', option: costStatistic(), unit: '', }, { comp: 'chart', title: '用能排行(月)', option: usageRanking(), unit: 'kWh', select: true, }, { title: '当月用能趋势', comp: 'chart', option: monthEnergyUsageTrend(), unit: 'kWh', select: true, }, ], bottom: { comp: 'chart', title: '24小时用能分布情况', option: energyUsageDistribution(), }, }) as IObject;
const changeType = (type: string) => { const c = state.dataForm.code; const u = state.dataForm.codeMap[c]; state.left[2].unit = u; state.right[1].unit = u;
//当月用能趋势
useFetch('/board/monthEnergy/analyse', { data: { month: moment().format('YYYY-MM'), type, }, cb: (res: any) => { if (utilService.isValidObject(res) && utilService.isValidArray(res.currentMonthData)) { const d = res.currentMonthData; const c = state.dataForm.code; const u = state.dataForm.codeMap[c]; state.right[2].option = monthEnergyUsageTrend(d, u); } }, });
//用能排行(月)
useFetch('/board/monthEnergy/ranking', { data: { day: moment().format('YYYY-MM'), type, }, cb: (res: any) => { if (utilService.isValidArray(res)) { const c = state.dataForm.code; const u = state.dataForm.codeMap[c]; state.right[1].option = usageRanking(res, u); } }, }); };
const fn = () => { //三个小气泡
useFetch('/board/carbonAndConsumption', { cb: (res: any) => { if (utilService.isValidObject(res)) { for (const item of state.pop) { item.value = res[item.key] ? (item.toFixed ? utilService.number2Fixed(res[item.key]) : res[item.key]) : '--'; } } }, }); //月用能统计
useFetch('/board/eachEnergy', { cb: (res: any) => { if (utilService.isValidObject(res)) { for (const item of state.left[0].data) { item.value = res[item.key] ?? '--'; } } }, }); //年用能统计
useFetch('/board/eachEnergyYear', { cb: (res: any) => { if (utilService.isValidObject(res)) { for (const item of state.left[1].data) { item.value = res[item.key] ?? '--'; } } }, });
//能耗费用统计
useFetch('/board/energyCost', { data: { day: moment().format('YYYY-MM-DD'), }, cb: (res: any) => { if (utilService.isValidArray(res)) { state.right[0].option = costStatistic(res); } }, });
//当日电力负荷
useFetch('/board/qcDayLoad/analyse', { data: { day: moment().format('YYYY-MM-DD'), }, cb: (res: any) => { if (utilService.isValidObject(res) && utilService.isValidArray(res.currentMonthData)) { const d = res.currentMonthData; state.left[2].option = elecPayload(d); } }, }); };
//24小时用能分布情况
// useFetch('/board/dayEnergy/trend', {
// data: {
// //day: '2025-04-01',
// day: moment().subtract(1, 'days').format('YYYY-MM-DD'),
// },
// cb: (res: any) => {
// if (utilService.isValidObject(res)) {
// state.bottom.option = energyUsageDistribution(res);
// }
// },
// });
changeType(state.dataForm.code); fn();
const reset = () => { setPointerLineStatusAll('none');
state.dragStretch.reset(); };
const methods = { changeType, reset };
watch( () => state.dataForm.code, (newCode: string) => { changeType(newCode); }, );
const getSvg = () => { const target = document.querySelector('.boards-container .center') as HTMLElement; generateSvg2Dom('/cdn/normal_bg.svg', target, () => { target.style.transform = 'scale(0.7)';
nextTick(() => { init(state, target); // document.getElementById("layer-d-animate").innerHTML = '<animate href="#path23264" attributeName="stroke-dashoffset" dur="15s" to="0" fill="freeze"></animate><animate href="#path23264-3" attributeName="stroke-dashoffset" dur="15s" to="0" fill="freeze"></animate>';
}); }); };
onMounted(() => { getSvg(); state.timer = setInterval(() => { changeType(state.dataForm.code); fn(); }, 1 * 60 * 1000); });
onBeforeUnmount(() => { clearInterval(state.timer); state.timer = null; });
return { ...toRefs(state), ...methods, ...switchScreenHooks({ screen: '1' }) }; },});</script><!-- <style lang="scss">.rr-view-ctx-card { height: 100%;
.el-card__body { position: relative; height: 100%; }}</style> -->
<style lang="less" scoped>.borads-index { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; background: #000b31;
.adapter { .boards-container { position: relative; height: 100%; display: flex; flex-direction: column;
> .top { position: relative; z-index: 2; height: 88px;
> .title { position: absolute; left: 0; top: 0; width: 100%; height: 100%; color: #e2edff; letter-spacing: 6px; background: url('@/assets/images/njhl/title.png') no-repeat center; background-size: 100% 100%; text-align: center; font-weight: bold; font-size: 40px; cursor: pointer; }
> .time { position: absolute; left: 0; top: 3px; display: flex; align-items: center;
> .time-left { position: relative; font-size: 32px; margin: 0 60px; background: linear-gradient(to top, #fff 30%, #3e576f 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-family: 'Alibaba PuHuiTi Heavy'; //阿里巴巴 普惠体
&:after { position: absolute; content: ''; background: #3e576f; right: -30px; top: 50%; width: 1px; height: 40px; transform: translate(-50%, -50%); } }
> .time-right { color: rgba(#fff, 0.7); } } }
> .center { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; cursor: move; //background: url("@/assets/images/njhl/bg.png");
//transform: translate(-50%, -50%);
/* 初始阴影设置(透明) */ &::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: inherit; //opacity: 0;
//transition: opacity 0.4s;
box-shadow: inset 0 0 80px 30px #000b31; }
&:hover::before { // opacity: 1;
} }
.icon { opacity: 0.4; position: absolute; top: 8px; right: 120px; z-index: 999; ::v-deep svg { transition: all 80ms; // opacity: 0.8;
//&:hover {
// width: 35px !important;
// height: 35px !important;
// opacity: 1;
//}
} }
.pop { position: absolute; display: flex; align-items: center; justify-content: space-between; height: 86px; left: 50%; top: 88px; transform: translate(-50%);
> * { margin: 0 40px; background: rgba(#000b31, 0.7); } }
.left, .right { position: absolute; top: 88px; height: calc(100% - 108px); display: flex; flex-direction: column; justify-content: space-between; background: rgba(#000b31, 0.7); z-index: 2; }
.bottom { > * { background-color: rgba(#000b31, 0.7) !important; } } .left { //left: 0;
left: 16px; }
.right { //right: 0;
right: 16px; }
.bottom { position: absolute; bottom: 20px; width: 100%; height: 318px; left: 0; > * { margin: 0 auto; } } } }}</style>
|