|
|
|
@ -8,29 +8,35 @@
|
|
|
|
:inline="true"
|
|
|
|
:inline="true"
|
|
|
|
label-width="auto"
|
|
|
|
label-width="auto"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<el-form-item label="所属区域" prop="orgId">
|
|
|
|
<el-form-item :label="t('EnergyOverview.filters.org')" prop="orgId">
|
|
|
|
<el-select v-model="queryParams.orgId" clearable filterable placeholder="请选择所属区域" class="!w-220px">
|
|
|
|
<el-select
|
|
|
|
|
|
|
|
v-model="queryParams.orgId"
|
|
|
|
|
|
|
|
clearable
|
|
|
|
|
|
|
|
filterable
|
|
|
|
|
|
|
|
:placeholder="t('EnergyOverview.filters.orgPlaceholder')"
|
|
|
|
|
|
|
|
class="!w-220px"
|
|
|
|
|
|
|
|
>
|
|
|
|
<el-option v-for="item in orgOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
<el-option v-for="item in orgOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="能源类型" prop="energyTypeId">
|
|
|
|
<el-form-item :label="t('EnergyOverview.filters.energyType')" prop="energyTypeId">
|
|
|
|
<el-select
|
|
|
|
<el-select
|
|
|
|
v-model="queryParams.energyTypeId"
|
|
|
|
v-model="queryParams.energyTypeId"
|
|
|
|
:disabled="!hasEnergyTypes"
|
|
|
|
:disabled="!hasEnergyTypes"
|
|
|
|
placeholder="请选择能源类型"
|
|
|
|
:placeholder="t('EnergyOverview.filters.energyTypePlaceholder')"
|
|
|
|
class="!w-220px"
|
|
|
|
class="!w-220px"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<el-option v-for="item in energyTypeOptions" :key="item.id" :label="item.name" :value="item.id" />
|
|
|
|
<el-option v-for="item in energyTypeOptions" :key="item.id" :label="item.name" :value="item.id" />
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="时间范围" prop="timeRange">
|
|
|
|
<el-form-item :label="t('EnergyOverview.filters.timeRange')" prop="timeRange">
|
|
|
|
<el-date-picker
|
|
|
|
<el-date-picker
|
|
|
|
v-model="queryParams.timeRange"
|
|
|
|
v-model="queryParams.timeRange"
|
|
|
|
type="datetimerange"
|
|
|
|
type="datetimerange"
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
start-placeholder="开始时间"
|
|
|
|
:start-placeholder="t('common.startTimeText')"
|
|
|
|
end-placeholder="结束时间"
|
|
|
|
:end-placeholder="t('common.endTimeText')"
|
|
|
|
range-separator="~"
|
|
|
|
range-separator="~"
|
|
|
|
:default-time="[new Date('2000-01-01 00:00:00'), new Date('2000-01-01 23:59:59')]"
|
|
|
|
:default-time="[new Date('2000-01-01 00:00:00'), new Date('2000-01-01 23:59:59')]"
|
|
|
|
class="!w-420px"
|
|
|
|
class="!w-420px"
|
|
|
|
@ -39,15 +45,15 @@
|
|
|
|
<el-form-item>
|
|
|
|
<el-form-item>
|
|
|
|
<el-button type="primary" @click="handleQuery">
|
|
|
|
<el-button type="primary" @click="handleQuery">
|
|
|
|
<Icon icon="ep:search" class="mr-5px" />
|
|
|
|
<Icon icon="ep:search" class="mr-5px" />
|
|
|
|
查询
|
|
|
|
{{ t('common.query') }}
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
<el-button @click="resetQuery">
|
|
|
|
<el-button @click="resetQuery">
|
|
|
|
<Icon icon="ep:refresh" class="mr-5px" />
|
|
|
|
<Icon icon="ep:refresh" class="mr-5px" />
|
|
|
|
重置
|
|
|
|
{{ t('common.reset') }}
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
<el-button type="success" plain @click="handleExport">
|
|
|
|
<el-button type="success" plain @click="handleExport">
|
|
|
|
<Icon icon="ep:download" class="mr-5px" />
|
|
|
|
<Icon icon="ep:download" class="mr-5px" />
|
|
|
|
导出
|
|
|
|
{{ t('action.export') }}
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
@ -63,7 +69,7 @@
|
|
|
|
<div class="metric-label">{{ item.label }}</div>
|
|
|
|
<div class="metric-label">{{ item.label }}</div>
|
|
|
|
<div class="metric-value">
|
|
|
|
<div class="metric-value">
|
|
|
|
{{ item.value }}
|
|
|
|
{{ item.value }}
|
|
|
|
<span class="metric-unit">{{ item.unit }}</span>
|
|
|
|
<span v-if="item.unit" class="metric-unit">{{ item.unit }}</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="metric-sub">
|
|
|
|
<div class="metric-sub">
|
|
|
|
<span>{{ item.subLabel }}</span>
|
|
|
|
<span>{{ item.subLabel }}</span>
|
|
|
|
@ -82,17 +88,9 @@
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-title">
|
|
|
|
<div class="panel-title">
|
|
|
|
能源用量趋势
|
|
|
|
{{ t('EnergyOverview.panels.trend') }}
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="panel-actions">
|
|
|
|
|
|
|
|
<el-button text type="primary">
|
|
|
|
|
|
|
|
<Icon icon="ep:trend-charts" />
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
<el-button text type="primary">
|
|
|
|
|
|
|
|
<Icon icon="ep:download" />
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<Echart :height="300" :options="trendChartOptions" />
|
|
|
|
<Echart :height="300" :options="trendChartOptions" />
|
|
|
|
</ContentWrap>
|
|
|
|
</ContentWrap>
|
|
|
|
@ -101,17 +99,9 @@
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-title">
|
|
|
|
<div class="panel-title">
|
|
|
|
区域能耗占比
|
|
|
|
{{ t('EnergyOverview.panels.region') }}
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="panel-actions">
|
|
|
|
|
|
|
|
<el-button text type="primary">
|
|
|
|
|
|
|
|
<Icon icon="ep:pie-chart" />
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
<el-button text type="primary">
|
|
|
|
|
|
|
|
<Icon icon="ep:download" />
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<Echart :height="300" :options="regionPieOptions" />
|
|
|
|
<Echart :height="300" :options="regionPieOptions" />
|
|
|
|
</ContentWrap>
|
|
|
|
</ContentWrap>
|
|
|
|
@ -123,19 +113,24 @@
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-title">
|
|
|
|
<div class="panel-title">
|
|
|
|
能耗排行 TOP5
|
|
|
|
{{ t('EnergyOverview.panels.top5') }}
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<el-table :data="rankList" :stripe="true" :show-overflow-tooltip="true">
|
|
|
|
<el-table :data="rankList" :stripe="true" :show-overflow-tooltip="true">
|
|
|
|
<el-table-column label="排名" align="center" width="70">
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.rank')" align="center" width="70">
|
|
|
|
<template #default="scope">
|
|
|
|
<template #default="scope">
|
|
|
|
<span class="rank-index" :class="`rank-${scope.$index + 1}`">{{ scope.$index + 1 }}</span>
|
|
|
|
<span class="rank-index" :class="`rank-${scope.$index + 1}`">{{ scope.$index + 1 }}</span>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
</el-table-column>
|
|
|
|
<el-table-column label="名称" prop="name" min-width="150" />
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.name')" prop="name" min-width="150" />
|
|
|
|
<el-table-column label="所属区域" prop="region" width="110" />
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.region')" prop="region" width="110" />
|
|
|
|
<el-table-column :label="`用量 (${selectedEnergyUnit})`" prop="value" align="right" width="120" />
|
|
|
|
<el-table-column
|
|
|
|
|
|
|
|
:label="`${t('EnergyOverview.table.usage')} (${selectedEnergyUnit})`"
|
|
|
|
|
|
|
|
prop="value"
|
|
|
|
|
|
|
|
align="right"
|
|
|
|
|
|
|
|
width="120"
|
|
|
|
|
|
|
|
/>
|
|
|
|
</el-table>
|
|
|
|
</el-table>
|
|
|
|
</ContentWrap>
|
|
|
|
</ContentWrap>
|
|
|
|
</el-col>
|
|
|
|
</el-col>
|
|
|
|
@ -143,17 +138,22 @@
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<ContentWrap class="overview-panel">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-header">
|
|
|
|
<div class="panel-title">
|
|
|
|
<div class="panel-title">
|
|
|
|
能源明细表
|
|
|
|
{{ t('EnergyOverview.panels.detail') }}
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
<Icon icon="ep:info-filled" class="panel-info" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<el-table v-loading="loading" :data="pageDetailList" :stripe="true" :show-overflow-tooltip="true">
|
|
|
|
<el-table v-loading="loading" :data="pageDetailList" :stripe="true" :show-overflow-tooltip="true">
|
|
|
|
<el-table-column label="表名称" prop="name" min-width="170" />
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.meterName')" prop="name" min-width="170" />
|
|
|
|
<el-table-column label="能源类型" prop="energyType" align="center" width="100" />
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.energyType')" prop="energyType" align="center" width="100" />
|
|
|
|
<el-table-column label="所属区域" prop="region" align="center" width="120" />
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.region')" prop="region" align="center" width="120" />
|
|
|
|
<el-table-column :label="`能源用量 (${selectedEnergyUnit})`" prop="value" align="right" width="150" />
|
|
|
|
<el-table-column
|
|
|
|
<el-table-column label="开始时间" prop="startTime" align="center" width="180" />
|
|
|
|
:label="`${t('EnergyOverview.table.energyUsage')} (${selectedEnergyUnit})`"
|
|
|
|
<el-table-column label="结束时间" prop="endTime" align="center" width="180" />
|
|
|
|
prop="value"
|
|
|
|
|
|
|
|
align="right"
|
|
|
|
|
|
|
|
width="150"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.startTime')" prop="startTime" align="center" width="180" />
|
|
|
|
|
|
|
|
<el-table-column :label="t('EnergyOverview.table.endTime')" prop="endTime" align="center" width="180" />
|
|
|
|
</el-table>
|
|
|
|
</el-table>
|
|
|
|
<Pagination
|
|
|
|
<Pagination
|
|
|
|
:total="total"
|
|
|
|
:total="total"
|
|
|
|
@ -167,7 +167,7 @@
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<ContentWrap v-else class="empty-panel">
|
|
|
|
<ContentWrap v-else class="empty-panel">
|
|
|
|
<el-empty description="请先配置能源类型" :image-size="120" />
|
|
|
|
<el-empty :description="t('EnergyOverview.empty')" :image-size="120" />
|
|
|
|
</ContentWrap>
|
|
|
|
</ContentWrap>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
@ -176,6 +176,14 @@
|
|
|
|
import { EChartsOption } from 'echarts'
|
|
|
|
import { EChartsOption } from 'echarts'
|
|
|
|
import { Echart } from '@/components/Echart'
|
|
|
|
import { Echart } from '@/components/Echart'
|
|
|
|
import { EnergyTypeApi, EnergyTypeVO } from '@/api/mes/energytype'
|
|
|
|
import { EnergyTypeApi, EnergyTypeVO } from '@/api/mes/energytype'
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
EnergyDeviceApi,
|
|
|
|
|
|
|
|
EnergyOverviewDetailVO,
|
|
|
|
|
|
|
|
EnergyOverviewMetricVO,
|
|
|
|
|
|
|
|
EnergyOverviewRankVO,
|
|
|
|
|
|
|
|
EnergyOverviewRespVO
|
|
|
|
|
|
|
|
} from '@/api/mes/energydevice'
|
|
|
|
|
|
|
|
import { OrganizationApi, OrganizationVO } from '@/api/mes/organization'
|
|
|
|
|
|
|
|
|
|
|
|
defineOptions({ name: 'EnergyOverview' })
|
|
|
|
defineOptions({ name: 'EnergyOverview' })
|
|
|
|
|
|
|
|
|
|
|
|
@ -192,24 +200,40 @@ interface MetricCard {
|
|
|
|
subValue?: string
|
|
|
|
subValue?: string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface DetailRow {
|
|
|
|
type DetailRow = EnergyOverviewDetailVO
|
|
|
|
id: number
|
|
|
|
|
|
|
|
name: string
|
|
|
|
|
|
|
|
energyType: string
|
|
|
|
|
|
|
|
region: string
|
|
|
|
|
|
|
|
value: string
|
|
|
|
|
|
|
|
startTime: string
|
|
|
|
|
|
|
|
endTime: string
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { t } = useI18n()
|
|
|
|
const message = useMessage()
|
|
|
|
const message = useMessage()
|
|
|
|
|
|
|
|
|
|
|
|
const defaultTimeRange = ['2026-05-04 00:00:00', '2026-05-05 23:59:59']
|
|
|
|
const getTodayTimeRange = () => {
|
|
|
|
const orgOptions = [
|
|
|
|
const now = new Date()
|
|
|
|
{ label: '成型系统', value: 1 },
|
|
|
|
const year = now.getFullYear()
|
|
|
|
{ label: '蛋托线01', value: 2 },
|
|
|
|
const month = String(now.getMonth() + 1).padStart(2, '0')
|
|
|
|
{ label: '烘干系统', value: 3 }
|
|
|
|
const day = String(now.getDate()).padStart(2, '0')
|
|
|
|
]
|
|
|
|
const date = `${year}-${month}-${day}`
|
|
|
|
|
|
|
|
return [`${date} 00:00:00`, `${date} 23:59:59`]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const parseRangeTime = (value?: string) => {
|
|
|
|
|
|
|
|
if (!value) return undefined
|
|
|
|
|
|
|
|
const date = new Date(value.replace(/-/g, '/'))
|
|
|
|
|
|
|
|
return Number.isNaN(date.getTime()) ? undefined : date
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isSingleDayRange = (timeRange?: string[]) => {
|
|
|
|
|
|
|
|
if (!timeRange || timeRange.length !== 2) return false
|
|
|
|
|
|
|
|
const start = parseRangeTime(timeRange[0])
|
|
|
|
|
|
|
|
const end = parseRangeTime(timeRange[1])
|
|
|
|
|
|
|
|
if (!start || !end) return false
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
start.getFullYear() === end.getFullYear() &&
|
|
|
|
|
|
|
|
start.getMonth() === end.getMonth() &&
|
|
|
|
|
|
|
|
start.getDate() === end.getDate()
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const defaultTimeRange = getTodayTimeRange()
|
|
|
|
|
|
|
|
const orgOptions = ref<{ label: string; value: string | number; raw?: OrganizationVO }[]>([])
|
|
|
|
|
|
|
|
|
|
|
|
const loading = ref(false)
|
|
|
|
const loading = ref(false)
|
|
|
|
const queryFormRef = ref()
|
|
|
|
const queryFormRef = ref()
|
|
|
|
@ -224,55 +248,19 @@ const queryParams = reactive({
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const metricCards = ref<MetricCard[]>([])
|
|
|
|
const metricCards = ref<MetricCard[]>([])
|
|
|
|
const rankList = ref([
|
|
|
|
const rankList = ref<EnergyOverviewRankVO[]>([])
|
|
|
|
{ name: '蛋托成型柜用电量', region: '成型系统', value: '2,139.09' },
|
|
|
|
|
|
|
|
{ name: '蛋托线真空柜用电量', region: '蛋托线01', value: '0' },
|
|
|
|
|
|
|
|
{ name: '蛋托干燥柜用电量', region: '烘干系统', value: '0' },
|
|
|
|
|
|
|
|
{ name: '蛋托线其它用电量', region: '蛋托线01', value: '0' },
|
|
|
|
|
|
|
|
{ name: '烘干系统其它用电量', region: '烘干系统', value: '0' }
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
const detailList = ref<DetailRow[]>([])
|
|
|
|
|
|
|
|
const pageDetailList = ref<DetailRow[]>([])
|
|
|
|
const pageDetailList = ref<DetailRow[]>([])
|
|
|
|
const total = ref(0)
|
|
|
|
const total = ref(0)
|
|
|
|
const hasEnergyTypes = computed(() => energyTypeOptions.value.length > 0)
|
|
|
|
const hasEnergyTypes = computed(() => energyTypeOptions.value.length > 0)
|
|
|
|
const selectedEnergyType = computed(() =>
|
|
|
|
const selectedEnergyType = computed(() =>
|
|
|
|
energyTypeOptions.value.find((item) => item.id === queryParams.energyTypeId)
|
|
|
|
energyTypeOptions.value.find((item) => item.id === queryParams.energyTypeId)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
const selectedEnergyName = computed(() => selectedEnergyType.value?.name || '电')
|
|
|
|
|
|
|
|
const selectedEnergyUnit = computed(() => selectedEnergyType.value?.unit || 'kWh')
|
|
|
|
const selectedEnergyUnit = computed(() => selectedEnergyType.value?.unit || 'kWh')
|
|
|
|
const selectedUnitConsumptionUnit = computed(() => `${selectedEnergyUnit.value}/件`)
|
|
|
|
|
|
|
|
|
|
|
|
const trendXAxis = ref<string[]>([])
|
|
|
|
const hours = [
|
|
|
|
const trendSeries = ref<number[]>([])
|
|
|
|
'00:00',
|
|
|
|
const regionItems = ref<{ name: string; value: number; percent: string }[]>([])
|
|
|
|
'01:00',
|
|
|
|
const regionTotal = ref('0')
|
|
|
|
'02:00',
|
|
|
|
|
|
|
|
'03:00',
|
|
|
|
|
|
|
|
'04:00',
|
|
|
|
|
|
|
|
'05:00',
|
|
|
|
|
|
|
|
'06:00',
|
|
|
|
|
|
|
|
'07:00',
|
|
|
|
|
|
|
|
'08:00',
|
|
|
|
|
|
|
|
'09:00',
|
|
|
|
|
|
|
|
'10:00',
|
|
|
|
|
|
|
|
'11:00',
|
|
|
|
|
|
|
|
'12:00',
|
|
|
|
|
|
|
|
'13:00',
|
|
|
|
|
|
|
|
'14:00',
|
|
|
|
|
|
|
|
'15:00',
|
|
|
|
|
|
|
|
'16:00',
|
|
|
|
|
|
|
|
'17:00',
|
|
|
|
|
|
|
|
'18:00',
|
|
|
|
|
|
|
|
'19:00',
|
|
|
|
|
|
|
|
'20:00',
|
|
|
|
|
|
|
|
'21:00',
|
|
|
|
|
|
|
|
'22:00'
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
const trendData = [90, 80, 72, 75, 74, 85, 105, 116, 120, 112, 123, 127, 122, 146, 156.8, 147, 116, 94, 88, 102, 103, 116, 106]
|
|
|
|
|
|
|
|
const regionData = [
|
|
|
|
|
|
|
|
{ name: '成型系统', value: 2139.09 },
|
|
|
|
|
|
|
|
{ name: '蛋托线01', value: 0 },
|
|
|
|
|
|
|
|
{ name: '烘干系统', value: 0 }
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const trendChartOptions = reactive<EChartsOption>({
|
|
|
|
const trendChartOptions = reactive<EChartsOption>({
|
|
|
|
color: ['#2f7df6'],
|
|
|
|
color: ['#2f7df6'],
|
|
|
|
@ -280,12 +268,12 @@ const trendChartOptions = reactive<EChartsOption>({
|
|
|
|
trigger: 'axis',
|
|
|
|
trigger: 'axis',
|
|
|
|
formatter: (params: any) => {
|
|
|
|
formatter: (params: any) => {
|
|
|
|
const item = params?.[0]
|
|
|
|
const item = params?.[0]
|
|
|
|
return `${item.axisValue}<br />用电量:${item.data} kWh`
|
|
|
|
return `${item?.axisValue || ''}<br />${t('EnergyOverview.chart.usage')}:${item?.data || 0} ${selectedEnergyUnit.value}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
legend: {
|
|
|
|
legend: {
|
|
|
|
top: 4,
|
|
|
|
top: 4,
|
|
|
|
data: ['用电量 (kWh)']
|
|
|
|
data: [t('EnergyOverview.chart.usage')]
|
|
|
|
},
|
|
|
|
},
|
|
|
|
grid: {
|
|
|
|
grid: {
|
|
|
|
left: 24,
|
|
|
|
left: 24,
|
|
|
|
@ -297,25 +285,23 @@ const trendChartOptions = reactive<EChartsOption>({
|
|
|
|
xAxis: {
|
|
|
|
xAxis: {
|
|
|
|
type: 'category',
|
|
|
|
type: 'category',
|
|
|
|
boundaryGap: false,
|
|
|
|
boundaryGap: false,
|
|
|
|
name: '时间(小时)',
|
|
|
|
name: t('EnergyOverview.chart.time'),
|
|
|
|
nameLocation: 'middle',
|
|
|
|
nameLocation: 'middle',
|
|
|
|
nameGap: 28,
|
|
|
|
nameGap: 28,
|
|
|
|
data: hours,
|
|
|
|
data: trendXAxis.value,
|
|
|
|
axisLine: { lineStyle: { color: '#dcdfe6' } },
|
|
|
|
axisLine: { lineStyle: { color: '#dcdfe6' } },
|
|
|
|
axisLabel: { color: '#606266' }
|
|
|
|
axisLabel: { color: '#606266' }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
yAxis: {
|
|
|
|
yAxis: {
|
|
|
|
type: 'value',
|
|
|
|
type: 'value',
|
|
|
|
name: 'kWh',
|
|
|
|
name: selectedEnergyUnit.value,
|
|
|
|
min: 0,
|
|
|
|
min: 0,
|
|
|
|
max: 180,
|
|
|
|
|
|
|
|
interval: 30,
|
|
|
|
|
|
|
|
axisLabel: { color: '#606266' },
|
|
|
|
axisLabel: { color: '#606266' },
|
|
|
|
splitLine: { lineStyle: { color: '#e8edf5' } }
|
|
|
|
splitLine: { lineStyle: { color: '#e8edf5' } }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
name: '用电量 (kWh)',
|
|
|
|
name: t('EnergyOverview.chart.usage'),
|
|
|
|
type: 'line',
|
|
|
|
type: 'line',
|
|
|
|
smooth: true,
|
|
|
|
smooth: true,
|
|
|
|
symbol: 'circle',
|
|
|
|
symbol: 'circle',
|
|
|
|
@ -334,21 +320,16 @@ const trendChartOptions = reactive<EChartsOption>({
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
data: trendData,
|
|
|
|
data: trendSeries.value
|
|
|
|
markPoint: {
|
|
|
|
|
|
|
|
symbolSize: 48,
|
|
|
|
|
|
|
|
label: { color: '#2f7df6', formatter: '{c}' },
|
|
|
|
|
|
|
|
data: [{ type: 'max', name: '峰值' }]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}) as EChartsOption
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const regionPieOptions = reactive<EChartsOption>({
|
|
|
|
const regionPieOptions = reactive<EChartsOption>({
|
|
|
|
color: ['#2f7df6', '#52c41a', '#faad14'],
|
|
|
|
color: ['#2f7df6', '#52c41a', '#faad14', '#13c2c2', '#fa8c16'],
|
|
|
|
tooltip: {
|
|
|
|
tooltip: {
|
|
|
|
trigger: 'item',
|
|
|
|
trigger: 'item',
|
|
|
|
formatter: '{b}<br />{c} kWh ({d}%)'
|
|
|
|
formatter: `{b}<br />{c} ${selectedEnergyUnit.value} ({d}%)`
|
|
|
|
},
|
|
|
|
},
|
|
|
|
legend: {
|
|
|
|
legend: {
|
|
|
|
orient: 'vertical',
|
|
|
|
orient: 'vertical',
|
|
|
|
@ -357,15 +338,15 @@ const regionPieOptions = reactive<EChartsOption>({
|
|
|
|
itemWidth: 12,
|
|
|
|
itemWidth: 12,
|
|
|
|
itemHeight: 12,
|
|
|
|
itemHeight: 12,
|
|
|
|
formatter: (name: string) => {
|
|
|
|
formatter: (name: string) => {
|
|
|
|
const item = regionData.find((row) => row.name === name)
|
|
|
|
const item = regionItems.value.find((row) => row.name === name)
|
|
|
|
const value = item?.value ?? 0
|
|
|
|
const value = item?.value ?? 0
|
|
|
|
const percent = value > 0 ? '100.00' : '0.00'
|
|
|
|
const percent = item?.percent ?? '0.00'
|
|
|
|
return `${name} ${value.toLocaleString()} kWh (${percent}%)`
|
|
|
|
return `${name} ${value.toLocaleString()} ${selectedEnergyUnit.value} (${percent}%)`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
name: '区域能耗',
|
|
|
|
name: t('EnergyOverview.chart.regionEnergy'),
|
|
|
|
type: 'pie',
|
|
|
|
type: 'pie',
|
|
|
|
radius: ['58%', '76%'],
|
|
|
|
radius: ['58%', '76%'],
|
|
|
|
center: ['34%', '50%'],
|
|
|
|
center: ['34%', '50%'],
|
|
|
|
@ -373,7 +354,7 @@ const regionPieOptions = reactive<EChartsOption>({
|
|
|
|
label: {
|
|
|
|
label: {
|
|
|
|
show: true,
|
|
|
|
show: true,
|
|
|
|
position: 'center',
|
|
|
|
position: 'center',
|
|
|
|
formatter: '总用电量\n{total|2,139.09 kWh}',
|
|
|
|
formatter: `${t('EnergyOverview.chart.totalUsage')}\n{total|${regionTotal.value} ${selectedEnergyUnit.value}}`,
|
|
|
|
color: '#303133',
|
|
|
|
color: '#303133',
|
|
|
|
rich: {
|
|
|
|
rich: {
|
|
|
|
total: {
|
|
|
|
total: {
|
|
|
|
@ -385,116 +366,145 @@ const regionPieOptions = reactive<EChartsOption>({
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
labelLine: { show: false },
|
|
|
|
labelLine: { show: false },
|
|
|
|
data: regionData
|
|
|
|
data: regionItems.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}) as EChartsOption
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const buildMetrics = () => {
|
|
|
|
const metricThemeMap: Record<string, { icon: string; theme: string }> = {
|
|
|
|
metricCards.value = [
|
|
|
|
total: { icon: 'ep:lightning', theme: 'blue' },
|
|
|
|
{
|
|
|
|
deviceCount: { icon: 'ep:cpu', theme: 'green' },
|
|
|
|
key: 'total',
|
|
|
|
topDevice: { icon: 'ep:histogram', theme: 'purple' },
|
|
|
|
label: '总用电量',
|
|
|
|
topRegion: { icon: 'ep:pie-chart', theme: 'cyan' },
|
|
|
|
value: '2,139.09',
|
|
|
|
range: { icon: 'ep:calendar', theme: 'orange' }
|
|
|
|
unit: selectedEnergyUnit.value,
|
|
|
|
|
|
|
|
icon: 'ep:lightning',
|
|
|
|
|
|
|
|
theme: 'blue',
|
|
|
|
|
|
|
|
subLabel: '较昨日',
|
|
|
|
|
|
|
|
change: '12.53%'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
key: 'today',
|
|
|
|
|
|
|
|
label: '今日用电量',
|
|
|
|
|
|
|
|
value: '860.32',
|
|
|
|
|
|
|
|
unit: selectedEnergyUnit.value,
|
|
|
|
|
|
|
|
icon: 'ep:calendar',
|
|
|
|
|
|
|
|
theme: 'green',
|
|
|
|
|
|
|
|
subLabel: '较昨日',
|
|
|
|
|
|
|
|
change: '12.15%'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
key: 'peak',
|
|
|
|
|
|
|
|
label: '峰值用电',
|
|
|
|
|
|
|
|
value: '156.8',
|
|
|
|
|
|
|
|
unit: selectedEnergyUnit.value,
|
|
|
|
|
|
|
|
icon: 'ep:histogram',
|
|
|
|
|
|
|
|
theme: 'purple',
|
|
|
|
|
|
|
|
subLabel: '时间:',
|
|
|
|
|
|
|
|
subValue: '2026-05-04 14:00 ~ 15:00'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
key: 'unit',
|
|
|
|
|
|
|
|
label: '单位产量能耗',
|
|
|
|
|
|
|
|
value: '0.38',
|
|
|
|
|
|
|
|
unit: selectedUnitConsumptionUnit.value,
|
|
|
|
|
|
|
|
icon: 'ep:orange',
|
|
|
|
|
|
|
|
theme: 'orange',
|
|
|
|
|
|
|
|
subLabel: '较昨日',
|
|
|
|
|
|
|
|
change: '5.21%',
|
|
|
|
|
|
|
|
down: true
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
key: 'region',
|
|
|
|
|
|
|
|
label: '最大耗能区域',
|
|
|
|
|
|
|
|
value: '成型系统',
|
|
|
|
|
|
|
|
unit: '',
|
|
|
|
|
|
|
|
icon: 'ep:pie-chart',
|
|
|
|
|
|
|
|
theme: 'cyan',
|
|
|
|
|
|
|
|
subLabel: '占比:',
|
|
|
|
|
|
|
|
subValue: '100.00%'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const buildDetails = () => {
|
|
|
|
const buildFallbackTrendXAxis = () => {
|
|
|
|
const timeRange = queryParams.timeRange?.length === 2 ? queryParams.timeRange : defaultTimeRange
|
|
|
|
const timeRange = queryParams.timeRange?.length === 2 ? queryParams.timeRange : defaultTimeRange
|
|
|
|
detailList.value = [
|
|
|
|
const [startTime, endTime] = timeRange
|
|
|
|
{
|
|
|
|
const start = new Date(startTime.replace(/-/g, '/'))
|
|
|
|
id: 1,
|
|
|
|
const end = new Date(endTime.replace(/-/g, '/'))
|
|
|
|
name: '蛋托线真空柜用电量',
|
|
|
|
if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || start > end) {
|
|
|
|
energyType: selectedEnergyName.value,
|
|
|
|
return []
|
|
|
|
region: '蛋托线01',
|
|
|
|
}
|
|
|
|
value: '0',
|
|
|
|
|
|
|
|
startTime: timeRange[0],
|
|
|
|
const sameDay =
|
|
|
|
endTime: timeRange[1]
|
|
|
|
start.getFullYear() === end.getFullYear() &&
|
|
|
|
},
|
|
|
|
start.getMonth() === end.getMonth() &&
|
|
|
|
{
|
|
|
|
start.getDate() === end.getDate()
|
|
|
|
id: 2,
|
|
|
|
|
|
|
|
name: '蛋托成型柜用电量',
|
|
|
|
const axis: string[] = []
|
|
|
|
energyType: selectedEnergyName.value,
|
|
|
|
if (sameDay) {
|
|
|
|
region: '成型系统',
|
|
|
|
const current = new Date(start)
|
|
|
|
value: '2,139.09',
|
|
|
|
current.setMinutes(0, 0, 0)
|
|
|
|
startTime: timeRange[0],
|
|
|
|
const limit = new Date(end)
|
|
|
|
endTime: timeRange[1]
|
|
|
|
limit.setMinutes(0, 0, 0)
|
|
|
|
},
|
|
|
|
while (current <= limit) {
|
|
|
|
{
|
|
|
|
axis.push(`${String(current.getHours()).padStart(2, '0')}:00`)
|
|
|
|
id: 3,
|
|
|
|
current.setHours(current.getHours() + 1)
|
|
|
|
name: '蛋托干燥柜用电量',
|
|
|
|
|
|
|
|
energyType: selectedEnergyName.value,
|
|
|
|
|
|
|
|
region: '烘干系统',
|
|
|
|
|
|
|
|
value: '0',
|
|
|
|
|
|
|
|
startTime: timeRange[0],
|
|
|
|
|
|
|
|
endTime: timeRange[1]
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
return axis
|
|
|
|
total.value = detailList.value.length
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const current = new Date(start)
|
|
|
|
|
|
|
|
current.setHours(0, 0, 0, 0)
|
|
|
|
|
|
|
|
const limit = new Date(end)
|
|
|
|
|
|
|
|
limit.setHours(0, 0, 0, 0)
|
|
|
|
|
|
|
|
while (current <= limit) {
|
|
|
|
|
|
|
|
const year = current.getFullYear()
|
|
|
|
|
|
|
|
const month = String(current.getMonth() + 1).padStart(2, '0')
|
|
|
|
|
|
|
|
const day = String(current.getDate()).padStart(2, '0')
|
|
|
|
|
|
|
|
axis.push(`${year}-${month}-${day}`)
|
|
|
|
|
|
|
|
current.setDate(current.getDate() + 1)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return axis
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeMetricCards = (metrics: EnergyOverviewMetricVO[]) => {
|
|
|
|
|
|
|
|
metricCards.value = metrics.map((item) => ({
|
|
|
|
|
|
|
|
key: item.key,
|
|
|
|
|
|
|
|
label: item.label,
|
|
|
|
|
|
|
|
value: item.value,
|
|
|
|
|
|
|
|
unit: item.unit || '',
|
|
|
|
|
|
|
|
icon: metricThemeMap[item.key]?.icon || 'ep:data-line',
|
|
|
|
|
|
|
|
theme: metricThemeMap[item.key]?.theme || 'blue',
|
|
|
|
|
|
|
|
subLabel: item.subLabel || '',
|
|
|
|
|
|
|
|
subValue: item.subValue || '',
|
|
|
|
|
|
|
|
change: item.change,
|
|
|
|
|
|
|
|
down: item.down
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const updateCharts = (data: EnergyOverviewRespVO) => {
|
|
|
|
|
|
|
|
const fallbackXAxis = buildFallbackTrendXAxis()
|
|
|
|
|
|
|
|
trendXAxis.value = data.trendChart?.xAxis?.length ? data.trendChart.xAxis : fallbackXAxis
|
|
|
|
|
|
|
|
const responseSeries = (data.trendChart?.data || []).map((item) => Number(item) || 0)
|
|
|
|
|
|
|
|
trendSeries.value =
|
|
|
|
|
|
|
|
responseSeries.length > 0
|
|
|
|
|
|
|
|
? responseSeries
|
|
|
|
|
|
|
|
: new Array(trendXAxis.value.length).fill(0)
|
|
|
|
|
|
|
|
regionItems.value = (data.regionChart?.items || []).map((item) => ({
|
|
|
|
|
|
|
|
name: item.name,
|
|
|
|
|
|
|
|
value: Number(item.value) || 0,
|
|
|
|
|
|
|
|
percent: item.percent
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
regionTotal.value = data.regionChart?.totalValue || '0'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trendChartOptions.xAxis = {
|
|
|
|
|
|
|
|
...(trendChartOptions.xAxis as any),
|
|
|
|
|
|
|
|
data: trendXAxis.value,
|
|
|
|
|
|
|
|
name: t('EnergyOverview.chart.time')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
trendChartOptions.yAxis = {
|
|
|
|
|
|
|
|
...(trendChartOptions.yAxis as any),
|
|
|
|
|
|
|
|
name: selectedEnergyUnit.value
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(trendChartOptions.legend?.data)) {
|
|
|
|
|
|
|
|
trendChartOptions.legend.data = [t('EnergyOverview.chart.usage')]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(trendChartOptions.series) && trendChartOptions.series[0]) {
|
|
|
|
|
|
|
|
;(trendChartOptions.series[0] as any).name = t('EnergyOverview.chart.usage')
|
|
|
|
|
|
|
|
;(trendChartOptions.series[0] as any).data = trendSeries.value
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(regionPieOptions.series) && regionPieOptions.series[0]) {
|
|
|
|
|
|
|
|
;(regionPieOptions.series[0] as any).name = t('EnergyOverview.chart.regionEnergy')
|
|
|
|
|
|
|
|
;(regionPieOptions.series[0] as any).data = regionItems.value
|
|
|
|
|
|
|
|
;(regionPieOptions.series[0] as any).label = {
|
|
|
|
|
|
|
|
...(regionPieOptions.series[0] as any).label,
|
|
|
|
|
|
|
|
formatter: `${t('EnergyOverview.chart.totalUsage')}\n{total|${regionTotal.value} ${selectedEnergyUnit.value}}`
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const getList = () => {
|
|
|
|
const getList = async () => {
|
|
|
|
if (!hasEnergyTypes.value) {
|
|
|
|
if (!hasEnergyTypes.value) {
|
|
|
|
metricCards.value = []
|
|
|
|
metricCards.value = []
|
|
|
|
detailList.value = []
|
|
|
|
rankList.value = []
|
|
|
|
pageDetailList.value = []
|
|
|
|
pageDetailList.value = []
|
|
|
|
total.value = 0
|
|
|
|
total.value = 0
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
loading.value = true
|
|
|
|
loading.value = true
|
|
|
|
buildMetrics()
|
|
|
|
try {
|
|
|
|
buildDetails()
|
|
|
|
const timeRange = queryParams.timeRange?.length === 2 ? queryParams.timeRange : defaultTimeRange
|
|
|
|
const start = (queryParams.pageNo - 1) * queryParams.pageSize
|
|
|
|
const res = await EnergyDeviceApi.queryOverviewData({
|
|
|
|
pageDetailList.value = detailList.value.slice(start, start + queryParams.pageSize)
|
|
|
|
orgId: queryParams.orgId,
|
|
|
|
loading.value = false
|
|
|
|
energyTypeId: queryParams.energyTypeId,
|
|
|
|
|
|
|
|
startTime: timeRange[0],
|
|
|
|
|
|
|
|
endTime: timeRange[1],
|
|
|
|
|
|
|
|
pageNo: queryParams.pageNo,
|
|
|
|
|
|
|
|
pageSize: queryParams.pageSize
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
const data = ((res as any)?.data || res) as EnergyOverviewRespVO
|
|
|
|
|
|
|
|
normalizeMetricCards(data.metrics || [])
|
|
|
|
|
|
|
|
rankList.value = data.rankList || []
|
|
|
|
|
|
|
|
pageDetailList.value = data.detailList || []
|
|
|
|
|
|
|
|
total.value = data.total || 0
|
|
|
|
|
|
|
|
updateCharts(data)
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeEnergyTypeList = (data: unknown): EnergyTypeVO[] => {
|
|
|
|
const normalizeEnergyTypeList = (data: unknown): EnergyTypeVO[] => {
|
|
|
|
@ -508,31 +518,33 @@ const normalizeEnergyTypeList = (data: unknown): EnergyTypeVO[] => {
|
|
|
|
return []
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const getDefaultEnergyType = (list: EnergyTypeVO[]) => {
|
|
|
|
const getDefaultEnergyType = (list: EnergyTypeVO[]) => list[0]
|
|
|
|
return (
|
|
|
|
|
|
|
|
list.find((item) => item.name === '电') ||
|
|
|
|
|
|
|
|
list.find((item) => item.name === '水') ||
|
|
|
|
|
|
|
|
list.find((item) => item.name === '气') ||
|
|
|
|
|
|
|
|
list[0]
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getEnergyTypes = async () => {
|
|
|
|
const getEnergyTypes = async () => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const data = await EnergyTypeApi.getEnergyTypeList()
|
|
|
|
const data = await EnergyTypeApi.getEnergyTypeList({ orgId: queryParams.orgId })
|
|
|
|
energyTypeOptions.value = normalizeEnergyTypeList(data)
|
|
|
|
energyTypeOptions.value = normalizeEnergyTypeList(data)
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
energyTypeOptions.value = []
|
|
|
|
energyTypeOptions.value = []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const defaultEnergyType = getDefaultEnergyType(energyTypeOptions.value)
|
|
|
|
let defaultEnergyType = getDefaultEnergyType(energyTypeOptions.value)
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const deviceRes = await EnergyDeviceApi.getList({ orgId: queryParams.orgId })
|
|
|
|
|
|
|
|
const devices = ((deviceRes as any)?.data || deviceRes || []) as Array<{ deviceTypeId?: number }>
|
|
|
|
|
|
|
|
const deviceTypeIds = new Set(devices.map((item) => item.deviceTypeId).filter(Boolean))
|
|
|
|
|
|
|
|
defaultEnergyType =
|
|
|
|
|
|
|
|
energyTypeOptions.value.find((item) => deviceTypeIds.has(item.id)) || defaultEnergyType
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
// ignore and use the first energy type
|
|
|
|
|
|
|
|
}
|
|
|
|
defaultEnergyTypeId.value = defaultEnergyType?.id
|
|
|
|
defaultEnergyTypeId.value = defaultEnergyType?.id
|
|
|
|
queryParams.energyTypeId = defaultEnergyType?.id
|
|
|
|
queryParams.energyTypeId = defaultEnergyType?.id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleQuery = () => {
|
|
|
|
const handleQuery = () => {
|
|
|
|
if (!hasEnergyTypes.value) {
|
|
|
|
if (!isSingleDayRange(queryParams.timeRange)) {
|
|
|
|
getList()
|
|
|
|
message.warning(t('EnergyOverview.messages.singleDayOnly'))
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
@ -543,20 +555,51 @@ const resetQuery = () => {
|
|
|
|
queryFormRef.value?.resetFields()
|
|
|
|
queryFormRef.value?.resetFields()
|
|
|
|
queryParams.orgId = undefined
|
|
|
|
queryParams.orgId = undefined
|
|
|
|
queryParams.energyTypeId = defaultEnergyTypeId.value
|
|
|
|
queryParams.energyTypeId = defaultEnergyTypeId.value
|
|
|
|
queryParams.timeRange = [...defaultTimeRange]
|
|
|
|
queryParams.timeRange = getTodayTimeRange()
|
|
|
|
handleQuery()
|
|
|
|
handleQuery()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleExport = () => {
|
|
|
|
const handleExport = async () => {
|
|
|
|
message.info('示例页暂未接入导出接口')
|
|
|
|
if (!isSingleDayRange(queryParams.timeRange)) {
|
|
|
|
|
|
|
|
message.warning(t('EnergyOverview.messages.singleDayOnly'))
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const timeRange = queryParams.timeRange?.length === 2 ? queryParams.timeRange : defaultTimeRange
|
|
|
|
|
|
|
|
await EnergyDeviceApi.exportQueryDataRecords({
|
|
|
|
|
|
|
|
orgId: queryParams.orgId,
|
|
|
|
|
|
|
|
startTime: timeRange[0],
|
|
|
|
|
|
|
|
endTime: timeRange[1]
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
message.success(t('EnergyOverview.exportSuccess'))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const loadOrgOptions = async () => {
|
|
|
|
|
|
|
|
if (orgOptions.value.length) return
|
|
|
|
|
|
|
|
const data: any = await OrganizationApi.getOrganizationList({})
|
|
|
|
|
|
|
|
const rows = (Array.isArray(data) ? data : data?.list ?? data?.data ?? []) as OrganizationVO[]
|
|
|
|
|
|
|
|
orgOptions.value = rows
|
|
|
|
|
|
|
|
.filter((r) => r?.id !== undefined && r?.name)
|
|
|
|
|
|
|
|
.map((r) => ({ label: r.name, value: r.id, raw: r }))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
|
|
await loadOrgOptions()
|
|
|
|
await getEnergyTypes()
|
|
|
|
await getEnergyTypes()
|
|
|
|
if (hasEnergyTypes.value) {
|
|
|
|
if (hasEnergyTypes.value) {
|
|
|
|
getList()
|
|
|
|
getList()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
|
|
() => queryParams.orgId,
|
|
|
|
|
|
|
|
async () => {
|
|
|
|
|
|
|
|
await getEnergyTypes()
|
|
|
|
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
|
|
|
|
if (hasEnergyTypes.value) {
|
|
|
|
|
|
|
|
getList()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
)
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
<style scoped lang="scss">
|
|
|
|
@ -705,19 +748,6 @@ onMounted(async () => {
|
|
|
|
color: var(--el-color-primary-light-3);
|
|
|
|
color: var(--el-color-primary-light-3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.panel-actions {
|
|
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.el-button {
|
|
|
|
|
|
|
|
width: 30px;
|
|
|
|
|
|
|
|
height: 30px;
|
|
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
|
|
border: 1px solid var(--el-border-color-light);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.rank-index {
|
|
|
|
.rank-index {
|
|
|
|
display: inline-flex;
|
|
|
|
display: inline-flex;
|
|
|
|
width: 22px;
|
|
|
|
width: 22px;
|
|
|
|
|