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.
 
 
 
 

256 lines
6.1 KiB

<template>
<div class="company-shore-power">
<div class="left" style="width: 1000px;">
<!-- 码头信息卡片 -->
<div class="card digital-twin-card--deep-blue">
<div class="card-title" style="display: flex; align-items: center; justify-content: space-between;">
<div class="card-title">
<div class="vertical-line"></div>
<img src="@/assets/svgs/data.svg" class="title-icon" />
<span class="title-text">码头与泊位信息</span>
</div>
<!-- <div>
<el-date-picker type="daterange" range-separator="" start-placeholder="开始日期" end-placeholder="结束日期"
format="YYYY-MM-DD" value-format="YYYY-MM-DD" class="date-range-picker" />
</div> -->
</div>
<div class="card-content">
<div v-for="company in companyComparisonData" :key="company.name" class="company-section">
<div class="company-header">
<div class="company-name">{{ company.name }}</div>
<div class="company-total">总量: {{ calculateTotal(company.children).toFixed(2) }}</div>
</div>
<div class="overview-grid">
<div v-for="(berth, index) in (company.children || [])" :key="index" class="overview-item"
@click="showShorePowerHistory(berth)">
<div class="overview-value">{{ berth.measureValue?.toFixed(2)
|| 0 }}</div>
<div class="overview-label">{{ berth.name }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<ship-history-dialog v-model="historyVisible.visible" :ship-param="historyVisible.searchParams"
:realtime-device-data="realtimeDeviceData" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { MapApi } from "@/api/shorepower/map";
import ShipHistoryDialog from './ShipHistoryDialog.vue';
import { RealtimeDeviceData } from '@/types/shorepower';
// 定义组件属性
interface ChartDataItem {
name: string;
value?: number;
measureValue?: number;
children?: ChartDataItem[];
}
const historyVisible = ref({
visible: false,
searchParams: {
shipId: 0 as number | null,
ids: [] as number[] | null,
type: 1 as number
}
})
// 计算总量的函数
const calculateTotal = (children?: ChartDataItem[]) => {
if (!children || children.length === 0) return 0;
return children.reduce((total, item) => {
return total + (item.measureValue || 0);
}, 0);
};
// 显示岸电箱历史记录
const showShorePowerHistory = (berth: ChartDataItem) => {
console.log(berth)
// console.log('shorepower', shorepower)
// currentShorePower.value = shorepower
/* shorePowerHistoryVisible.value = {
visible: true,
shorePowerId: shorepower.id || 0
} */
historyVisible.value = {
visible: true,
searchParams: {
shipId: null,
ids: [berth.id],
type: 4,
}
}
}
interface Props {
companyComparisonData?: ChartDataItem[];
realtimeDeviceData: RealtimeDeviceData[];
}
const props = defineProps<Props>()
const companyComparisonData = ref<ChartDataItem[]>([])
const handleGetBuildData = async () => {
const dockList = await MapApi.getDockIdAndNameList()
const berthList = await MapApi.getBerthIdAndNameList()
const buildData = dockList.map(dock => ({
...dock,
children: berthList.filter(berth => berth.dockId === dock.id).map(berth => ({
...berth,
...props.realtimeDeviceData.find(item => (item.id === berth.id) && (item.deviceCode.includes('Kwh')))
}))
}))
console.log('buildData', buildData)
console.log('props.realtimeDeviceData', props.realtimeDeviceData)
companyComparisonData.value = buildData
/* MapApi.getBerthIdAndNameList().then(res => {
console.log(res)
const buildData = res.map(item => ({
...item,
children: props.realtimeDeviceData.filter(item => item.id === item.id)
}))
}) */
}
watch(() => props.realtimeDeviceData, (newVal) => {
handleGetBuildData()
})
onMounted(() => {
// console.log(props.realtimeDeviceData)
handleGetBuildData()
})
</script>
<style scoped>
.company-shore-power {
display: flex;
height: 100%;
gap: 10px;
}
.left {
/* display: flex;
flex-direction: column;
height: 100%;
gap: 10px; */
}
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card-content {
flex: 1;
height: 100%;
min-height: 0;
padding-bottom: 50px;
overflow-y: auto;
}
/* 总览网格样式 */
.overview-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 8px;
padding: 4px;
height: 100%;
}
.overview-item {
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 4px;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 6px;
}
.overview-label {
text-align: center;
font-size: 24px;
color: #ccc;
margin-bottom: 2px;
}
.overview-value {
font-size: 36px;
font-weight: bold;
color: #1296db;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
margin-bottom: 2px;
}
.overview-text {
font-size: 10px;
color: #999;
text-align: center;
}
/* 企业区块样式 */
.company-section {
margin-bottom: 16px;
padding-bottom: 16px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.company-section:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
/* 企业头部样式 */
.company-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
padding: 0 4px;
}
.company-name {
font-size: 24px;
font-weight: bold;
color: #fff;
}
.company-total {
font-size: 24px;
font-weight: bold;
color: #1296db;
background-color: rgba(18, 150, 219, 0.1);
padding: 2px 8px;
border-radius: 4px;
}
/* 自定义滚动条样式 */
.card-content::-webkit-scrollbar {
width: 6px;
}
.card-content::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
}
.card-content::-webkit-scrollbar-thumb {
background: rgba(17, 138, 237, 0.7);
border-radius: 3px;
}
.card-content::-webkit-scrollbar-thumb:hover {
background: rgba(17, 138, 237, 1);
}
</style>