You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

648 lines
16 KiB

<template>
<div class="show-data">
<div class="right" style="width: 800px">
<div class="card digital-twin-card--deep-blue">
<div class="card-title">
<div class="vertical-line"></div>
<img src="@/assets/svgs/data.svg" class="title-icon" />
<!-- <span class="title-text">岸电管理大屏系统</span> -->
<span class="title-date">{{ currentDate }}</span>
<span class="update-time">更新时间: {{ realtimeDeviceDataTime }}</span>
</div>
<div class="card-content">
<!-- 港口岸电使用情况 -->
<div class="module-section">
<div class="module-header">
<h3 class="module-title" @click="handleGoToModule(1)">港口岸电使用情况</h3>
<div class="period-filter">
<div v-for="period in periodOptions" :key="period"
:class="['period-option', { active: activePeriod === period }]" @click="switchPeriod(period)">
{{ period }}
</div>
</div>
</div>
<div class="port-overview">
<div class="first-row">
<div class="benefit-card">
<div class="benefit-value">835380.87</div>
<div class="benefit-unit">累计用电 (千瓦时)</div>
</div>
<div class="benefit-card">
<div class="benefit-value">559705.19</div>
<div class="benefit-unit">减少二氧化碳排放 (千克)</div>
</div>
</div>
<div class="second-row">
<div class="benefit-card">
<div class="benefit-value">105.25</div>
<div class="benefit-unit">减少燃油 (吨)</div>
</div>
<div class="benefit-card">
<div class="benefit-value">1219.66</div>
<div class="benefit-unit">减少PM2.5排放 (千克)</div>
</div>
<div class="benefit-card">
<div class="benefit-value">15120.39</div>
<div class="benefit-unit">减少氮氧化物 (千克)</div>
</div>
<div class="benefit-card">
<div class="benefit-value">8771.51</div>
<div class="benefit-unit">减少二氧化硫 (千克)</div>
</div>
</div>
</div>
</div>
<!-- 港口企业岸电使用 -->
<div class="module-section">
<div class="module-header">
<h3 class="module-title" @click="handleGoToModule(2)">港口企业岸电使用</h3>
<div class="period-filter">
<div v-for="period in periodOptions" :key="period"
:class="['period-option', { active: activePeriod === period }]" @click="switchPeriod(period)">
{{ period }}
</div>
</div>
</div>
<div class="enterprise-usage">
<div class="usage-bars">
<div class="bar-item">
<div class="bar-header">
<span class="bar-name">华能码头</span>
<span class="bar-value">232235.88 kWH</span>
</div>
<el-progress :percentage="65" :show-text="false" />
</div>
<div class="bar-item">
<div class="bar-header">
<span class="bar-name">国投码头</span>
<span class="bar-value">413513.53 kWH</span>
</div>
<el-progress :percentage="95" :show-text="false" />
</div>
<div class="bar-item">
<div class="bar-header">
<span class="bar-name">华电码头 (储运)</span>
<span class="bar-value">189631.46 kWH</span>
</div>
<el-progress :percentage="55" :show-text="false" />
</div>
</div>
<!-- <div class="current-usage">
<div class="usage-detail">
<span>华能码头</span>
<span>3泊位</span>
<span>华元503</span>
<span>正在用电</span>
<span>2192kWH</span>
</div>
</div> -->
</div>
</div>
<!-- 船舶岸电使用情况 -->
<div class="module-section">
<div class="module-header">
<h3 class="module-title" @click="handleGoToModule(3)">船舶岸电使用情况</h3>
<div class="period-filter">
<div v-for="period in periodOptions" :key="period"
:class="['period-option', { active: activePeriod === period }]" @click="switchPeriod(period)">
{{ period }}
</div>
</div>
</div>
<div class="ship-status">
<div class="usage-rate">
<div class="rate-value">23.08%</div>
<div class="rate-label">岸电使用率</div>
</div>
<div class="status-grid">
<div class="status-card">
<div class="status-value">13</div>
<div class="status-label">在港船舶数量</div>
</div>
<div class="status-card">
<div class="status-value">3</div>
<div class="status-label">使用岸电船舶数量</div>
</div>
<div class="status-card">
<div class="status-value">10</div>
<div class="status-label">未使用岸电船舶数量</div>
</div>
</div>
<!-- <div class="ship-list">
<div class="ship-item">
<span class="ship-name">华元503</span>
<span class="ship-dock">华能码头</span>
<span class="ship-berth">3泊位</span>
<span class="ship-status-text">使用岸电21小时45分钟, 2479kWH</span>
</div>
<div class="ship-item">
<span class="ship-name">信洋新征程</span>
<span class="ship-dock">国投码头</span>
<span class="ship-berth">202#泊位</span>
<span class="ship-status-text">无受电设备</span>
</div>
<div class="ship-item">
<span class="ship-name">华海航2</span>
<span class="ship-dock">华电码头 (储运)</span>
<span class="ship-berth">806泊位</span>
<span class="ship-status-text">船电设施损坏, 预计2025-11-30恢复</span>
</div>
<div class="ship-item">
<span class="ship-name">东亿603</span>
<span class="ship-dock">国投码头</span>
<span class="ship-berth">205#泊位</span>
<span class="ship-status-text">电缆长度不匹配</span>
</div>
<div class="ship-item">
<span class="ship-name">东成山</span>
<span class="ship-dock">华能码头</span>
<span class="ship-berth">2泊位</span>
<span class="ship-status-text">岸电用电接口不匹配</span>
</div>
<div class="ship-item">
<span class="ship-name">中茂98</span>
<span class="ship-dock">华电码头 (储运)</span>
<span class="ship-berth">807泊位</span>
<span class="ship-status-text">岸电设施维护中</span>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
interface Props {
handleGoToModule: (moduleType: number) => void
realtimeDeviceDataTime: string
}
defineProps<Props>()
// 获取当前日期
const currentDate = computed(() => {
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
})
// 获取更新时间(模拟数据更新时间)
const updateTime = computed(() => {
const now = new Date()
const hours = String(now.getHours()).padStart(2, '0')
const minutes = String(now.getMinutes()).padStart(2, '0')
const seconds = String(now.getSeconds()).padStart(2, '0')
return `${hours}:${minutes}:${seconds}`
})
// 时间段筛选相关
const activePeriod = ref('今日')
const periodOptions = ['今日', '本月', '本年', '全部']
// 模拟不同时间段的数据
const rankingData = {
今日: [
{ rank: 1, name: '华能曹妃甸港口有限公司', value: '350,000', change: '+15%', isUp: true },
{ rank: 2, name: '河北华电曹妃甸储运有限公司', value: '280,000', change: '+8%', isUp: true },
{ rank: 3, name: '国投曹妃甸港口有限公司', value: '220,000', change: '-3%', isUp: false }
],
本月: [
{ rank: 1, name: '华能曹妃甸港口有限公司', value: '8,350,000', change: '+12%', isUp: true },
{ rank: 2, name: '国投曹妃甸港口有限公司', value: '7,280,000', change: '+5%', isUp: true },
{ rank: 3, name: '河北华电曹妃甸储运有限公司', value: '6,220,000', change: '-2%', isUp: false }
],
本年: [
{ rank: 1, name: '华能曹妃甸港口有限公司', value: '120,350,000', change: '+18%', isUp: true },
{ rank: 2, name: '国投曹妃甸港口有限公司', value: '95,280,000', change: '+9%', isUp: true },
{ rank: 3, name: '河北华电曹妃甸储运有限公司', value: '82,220,000', change: '+3%', isUp: true }
],
全部: [
{ rank: 1, name: '华能曹妃甸港口有限公司', value: '2,120,350,000', change: '+15%', isUp: true },
{ rank: 2, name: '国投曹妃甸港口有限公司', value: '1,095,280,000', change: '+11%', isUp: true },
{ rank: 3, name: '河北华电曹妃甸储运有限公司', value: '882,220,000', change: '+7%', isUp: true }
]
}
// 获取当前选中时间段的数据
const currentRankingData = computed(() => {
return rankingData[activePeriod.value as keyof typeof rankingData] || []
})
// 切换时间段
const switchPeriod = (period: string) => {
activePeriod.value = period
}
</script>
<style scoped>
.show-data {
display: flex;
gap: 10px;
height: 100%;
}
.card {
padding-right: 0px;
padding-left: 12px;
}
.card-content {
display: flex;
flex-direction: column;
gap: 12px;
padding: 12px;
}
.card-title {
display: flex;
align-items: center;
}
.title-text {
font-size: 28px;
font-weight: bold;
}
.title-date {
font-size: 16px;
color: #a0cfff;
margin-left: auto;
padding-right: 20px;
}
.update-time {
font-size: 14px;
color: #67c23a;
margin-left: 10px;
padding-right: 20px;
}
.section-title {
font-size: 24px;
font-weight: bold;
color: #409eff;
margin: 0;
padding-bottom: 6px;
border-bottom: 1px solid rgba(64, 158, 255, 0.3);
}
.module-section {
margin-bottom: 0px;
}
.module-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 8px;
/* border-bottom: 2px solid rgba(64, 158, 255, 0.3); */
}
.module-title {
font-size: 24px;
font-weight: bold;
color: #409eff;
text-decoration: underline;
margin: 0;
cursor: pointer;
transition: all 0.3s ease;
user-select: none;
}
.module-title:hover {
transform: translateY(-2px);
color: #66b1ff;
}
.module-title:active {
transform: translateY(-4px);
color: #337ecc;
text-decoration: none;
}
/* 港口岸电使用情况 */
.port-overview {
margin-bottom: 6px;
}
.first-row {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
margin-bottom: 8px;
}
.second-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 8px;
}
.total-electricity {
text-align: center;
margin-bottom: 20px;
padding: 20px;
background: rgba(30, 120, 255, 0.1);
border-radius: 10px;
}
.total-value {
font-size: 48px;
font-weight: bold;
color: #FFF;
margin-bottom: 5px;
}
.total-unit {
font-size: 16px;
color: #a0cfff;
}
.benefits-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15px;
}
.benefit-card {
background: rgba(30, 120, 255, 0.1);
border: 1px solid rgba(64, 158, 255, 0.3);
border-radius: 8px;
padding: 15px;
text-align: center;
}
.benefit-value {
font-size: 28px;
font-weight: bold;
color: #FFF;
margin-bottom: 5px;
}
.benefit-unit {
font-size: 14px;
color: #a0cfff;
}
/* 港口企业岸电使用 */
.enterprise-usage {
margin-bottom: 20px;
}
.usage-bars {
margin-bottom: 15px;
}
.bar-item {
margin-bottom: 15px;
}
.bar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
}
.bar-name {
font-size: 16px;
color: #a0cfff;
}
.bar-value {
font-size: 14px;
color: #FFF;
font-weight: bold;
}
:deep(.el-progress-bar__outer) {
background: rgba(30, 120, 255, 0.2);
border-radius: 10px;
overflow: hidden;
}
:deep(.el-progress-bar__inner) {
background: linear-gradient(90deg, #67c23a, #409eff);
border-radius: 10px;
}
.current-usage {
background: rgba(30, 120, 255, 0.1);
border: 1px solid rgba(64, 158, 255, 0.3);
border-radius: 8px;
padding: 15px;
}
.usage-detail {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 16px;
color: #a0cfff;
}
/* 船舶岸电使用情况 */
.ship-status {
margin-bottom: 8px;
}
.usage-rate {
text-align: center;
padding: 20px;
background: rgba(30, 120, 255, 0.1);
border-radius: 10px;
margin-bottom: 8px;
}
.rate-value {
font-size: 48px;
font-weight: bold;
color: #FFF;
margin-bottom: 5px;
}
.rate-label {
font-size: 16px;
color: #a0cfff;
}
.status-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
margin-bottom: 8px;
}
.status-card {
background: rgba(30, 120, 255, 0.1);
border: 1px solid rgba(64, 158, 255, 0.3);
border-radius: 8px;
padding: 20px;
text-align: center;
}
.status-value {
font-size: 36px;
font-weight: bold;
color: #FFF;
margin-bottom: 5px;
}
.status-label {
font-size: 16px;
color: #a0cfff;
}
.ship-list {
background: rgba(30, 120, 255, 0.1);
border: 1px solid rgba(64, 158, 255, 0.3);
border-radius: 8px;
padding: 15px;
}
.ship-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid rgba(64, 158, 255, 0.2);
}
.ship-item:last-child {
border-bottom: none;
}
.ship-name {
font-size: 16px;
color: #67c23a;
font-weight: bold;
width: 120px;
}
.ship-dock {
font-size: 16px;
color: #a0cfff;
width: 120px;
}
.ship-berth {
font-size: 16px;
color: #a0cfff;
width: 100px;
}
.ship-status-text {
font-size: 14px;
color: #a0cfff;
text-align: right;
flex: 1;
}
/* 分公司排名样式 */
.period-filter {
display: flex;
gap: 10px;
margin-bottom: 0;
}
.period-option {
padding: 4px 8px;
background: rgba(30, 120, 255, 0.1);
border: 1px solid rgba(64, 158, 255, 0.3);
border-radius: 8px;
color: #a0cfff;
cursor: pointer;
transition: all 0.3s ease;
}
.period-option:hover {
background: rgba(30, 120, 255, 0.2);
}
.period-option.active {
background: #409eff;
color: white;
border-color: #409eff;
}
.ranking-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.ranking-item {
display: flex;
align-items: center;
padding: 10px 12px;
background: rgba(30, 120, 255, 0.05);
border-radius: 8px;
border: 1px solid rgba(30, 120, 255, 0.1);
}
.change {
font-size: 16px;
font-weight: bold;
}
.up {
color: #67c23a;
}
.down {
color: #f56c6c;
}
.rank-number {
width: 24px;
height: 24px;
border-radius: 50%;
background: #409eff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
margin-right: 12px;
}
.first .rank-number {
background: #ffd700;
color: #333;
}
.second .rank-number {
background: #c0c0c0;
color: #333;
}
.third .rank-number {
background: #cd7f32;
color: #333;
}
.branch-name {
flex: 1;
font-size: 20px;
color: #e6f2ff;
}
.branch-value {
font-size: 26px;
font-weight: bold;
color: #409eff;
min-width: 140px;
text-align: right;
margin-right: 12px;
}
</style>