调整设备运行总览

main
liutao 19 hours ago
parent b2ae6a27b0
commit 4af7c8199b

@ -31,9 +31,17 @@
<div class="timeline-table__device">{{ t('DataCollection.RunOverview.tableDeviceNameColumn') }}</div>
<div class="timeline-table__rate">{{ t('DataCollection.RunOverview.tableUtilizationRateColumn') }}</div>
</div>
<div class="timeline-scale">
<div v-for="hour in hourTicks" :key="hour" class="timeline-scale__tick">
{{ hour }}
<div class="timeline-chart" :style="timelineChartStyle">
<div class="timeline-scale">
<div
v-for="tick in hourTicks"
:key="tick.key"
class="timeline-scale__tick"
:class="`is-${tick.align}`"
:style="{ left: `${tick.position}%` }"
>
{{ tick.label }} :00
</div>
</div>
</div>
</div>
@ -43,18 +51,25 @@
<div class="timeline-table__device">{{ row.name }}</div>
<div class="timeline-table__rate">{{ row.utilizationRate.toFixed(2) }}%</div>
</div>
<div class="timeline-track">
<div v-for="hour in 24" :key="hour" class="timeline-track__hour"></div>
<div
v-for="(segment, index) in row.segments"
:key="`${row.id}-${index}`"
class="timeline-segment"
:style="{
left: `${(segment.startHour / 24) * 100}%`,
width: `${((segment.endHour - segment.startHour) / 24) * 100}%`,
background: statusColors[segment.status]
}"
></div>
<div class="timeline-chart" :style="timelineChartStyle">
<div class="timeline-track">
<div
v-for="tick in hourTicks"
:key="tick.key"
class="timeline-track__hour"
:style="{ left: `${tick.position}%` }"
></div>
<div
v-for="(segment, index) in row.segments"
:key="`${row.id}-${index}`"
class="timeline-segment"
:style="{
left: `${(segment.startHour / 24) * 100}%`,
width: `${((segment.endHour - segment.startHour) / 24) * 100}%`,
background: statusColors[segment.status]
}"
></div>
</div>
</div>
</div>
</div>
@ -84,6 +99,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import dayjs from 'dayjs'
import type { DeviceTimelineRow, RunStatus } from './types'
const props = defineProps<{
@ -116,7 +132,40 @@ const legendItems = computed(() => [
{ status: 'offline' as const, color: statusColors.offline, label: t('DataCollection.RunOverview.legend.offline') }
])
const hourTicks = Array.from({ length: 24 }, (_, index) => `${String(index).padStart(2, '0')}:00`)
const timelineRange = computed(() => {
const start = dayjs(props.statisticsStart)
const end = dayjs(props.statisticsEnd)
if (start.isValid() && end.isValid() && end.isAfter(start)) return { start, end }
const fallbackStart = dayjs().startOf('day')
return { start: fallbackStart, end: fallbackStart.add(1, 'day') }
})
const rangeHours = computed(() => Math.max(timelineRange.value.end.diff(timelineRange.value.start, 'hour', true), 1))
const hourTicks = computed(() => {
const { start, end } = timelineRange.value
const ticks: Array<{ key: string; label: string; position: number; align: 'start' | 'center' | 'end' }> = []
const totalSeconds = end.diff(start, 'second', true)
let current = start.startOf('hour')
if (current.isBefore(start)) current = current.add(1, 'hour')
while (!current.isAfter(end)) {
const position = (current.diff(start, 'second', true) / totalSeconds) * 100
ticks.push({
key: current.valueOf().toString(),
label: current.format('HH'),
position,
align: position === 0 ? 'start' : position === 100 ? 'end' : 'center'
})
current = current.add(1, 'hour')
}
return ticks
})
const timelineChartStyle = computed(() => ({
minWidth: `${Math.max(720, Math.ceil(rangeHours.value) * 64)}px`
}))
const timelineRows = computed(() =>
props.rows.map((row) => ({
@ -219,30 +268,34 @@ const timelineRows = computed(() =>
font-weight: 600;
}
.timeline-chart {
min-width: 720px;
}
.timeline-scale,
.timeline-track {
position: relative;
display: grid;
grid-template-columns: repeat(24, 1fr);
}
.timeline-scale {
height: 30px;
color: #667085;
font-size: 12px;
}
.timeline-scale__tick {
position: relative;
position: absolute;
top: 0;
white-space: nowrap;
transform: translateX(-50%);
}
.timeline-scale__tick::after {
position: absolute;
top: 18px;
right: 0;
width: 1px;
height: 12px;
background: #e4e7ec;
content: '';
.timeline-scale__tick.is-start {
transform: none;
}
.timeline-scale__tick.is-end {
transform: translateX(-100%);
}
.timeline-track {
@ -252,7 +305,11 @@ const timelineRows = computed(() =>
}
.timeline-track__hour {
border-right: 1px solid #edf1f7;
position: absolute;
top: 0;
bottom: 0;
width: 1px;
background: #edf1f7;
}
.timeline-segment {

@ -28,7 +28,7 @@ v-model="queryParams.timeRange" type="datetimerange" value-format="YYYY-MM-DD HH
format="YYYY-MM-DD HH:mm:ss"
:start-placeholder="t('EnergyManagement.EnergyDeviceCheck.searchTimeRangeStartPlaceholder')"
:end-placeholder="t('EnergyManagement.EnergyDeviceCheck.searchTimeRangeEndPlaceholder')"
:default-time="[new Date('2000-01-01 00:00:00'), new Date('2000-01-01 23:00:00')]"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
:shortcuts="timeRangeShortcuts"
:disabled-time="getDisabledTime" class="!w-360px " popper-class="energydevicecheckPicker" />
</el-form-item>
@ -103,6 +103,7 @@ v-if="getPointDetailsRows(scope.row).length" :data="getPointDetailsRows(scope.ro
import download from '@/utils/download'
import { EnergyDeviceApi, EnergyDeviceDataRecordVO } from '@/api/mes/energydevice'
import { OrganizationApi } from '@/api/mes/organization'
import dayjs from "dayjs";
defineOptions({ name: 'EnergyDeviceCheckRecord' })
@ -244,7 +245,11 @@ const queryParams = reactive({
pageSize: 10,
name: undefined as string | undefined,
orgId: undefined as string | number | undefined,
timeRange: buildDefaultTimeRange(),
//timeRange: buildDefaultTimeRange(),
timeRange: [
dayjs().subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
dayjs().subtract(1, 'day').endOf('day').format('YYYY-MM-DD HH:mm:ss')
] as string[],
startTime: undefined as string | undefined,
endTime: undefined as string | undefined
})

Loading…
Cancel
Save