diff --git a/src/locales/en.ts b/src/locales/en.ts index 42a9b56f..17c11117 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -4724,6 +4724,9 @@ export default { } }, EnergyOverview: { + messages: { + singleDayOnly: 'The time range can only query data within a single day' + }, filters: { org: 'Region', orgPlaceholder: 'Please select region', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 36f12d80..5ca068dc 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -4935,6 +4935,9 @@ export default { } }, EnergyOverview: { + messages: { + singleDayOnly: '时间范围只能查询同一天的数据' + }, filters: { org: '所属区域', orgPlaceholder: '请选择所属区域', diff --git a/src/views/mes/energyOverview/index.vue b/src/views/mes/energyOverview/index.vue index e96bd42f..f525cba0 100644 --- a/src/views/mes/energyOverview/index.vue +++ b/src/views/mes/energyOverview/index.vue @@ -205,7 +205,34 @@ type DetailRow = EnergyOverviewDetailVO const { t } = useI18n() const message = useMessage() -const defaultTimeRange = ['2026-05-04 00:00:00', '2026-05-05 23:59:59'] +const getTodayTimeRange = () => { + 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') + 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) @@ -352,6 +379,47 @@ const metricThemeMap: Record = { range: { icon: 'ep:calendar', theme: 'orange' } } +const buildFallbackTrendXAxis = () => { + const timeRange = queryParams.timeRange?.length === 2 ? queryParams.timeRange : defaultTimeRange + const [startTime, endTime] = timeRange + const start = new Date(startTime.replace(/-/g, '/')) + const end = new Date(endTime.replace(/-/g, '/')) + if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || start > end) { + return [] + } + + const sameDay = + start.getFullYear() === end.getFullYear() && + start.getMonth() === end.getMonth() && + start.getDate() === end.getDate() + + const axis: string[] = [] + if (sameDay) { + const current = new Date(start) + current.setMinutes(0, 0, 0) + const limit = new Date(end) + limit.setMinutes(0, 0, 0) + while (current <= limit) { + axis.push(`${String(current.getHours()).padStart(2, '0')}:00`) + current.setHours(current.getHours() + 1) + } + return axis + } + + 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, @@ -368,8 +436,13 @@ const normalizeMetricCards = (metrics: EnergyOverviewMetricVO[]) => { } const updateCharts = (data: EnergyOverviewRespVO) => { - trendXAxis.value = data.trendChart?.xAxis || [] - trendSeries.value = (data.trendChart?.data || []).map((item) => Number(item) || 0) + 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, @@ -449,18 +522,31 @@ const getDefaultEnergyType = (list: EnergyTypeVO[]) => list[0] const getEnergyTypes = async () => { try { - const data = await EnergyTypeApi.getEnergyTypeList() + const data = await EnergyTypeApi.getEnergyTypeList({ orgId: queryParams.orgId }) energyTypeOptions.value = normalizeEnergyTypeList(data) } catch (error) { 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 queryParams.energyTypeId = defaultEnergyType?.id } const handleQuery = () => { + if (!isSingleDayRange(queryParams.timeRange)) { + message.warning(t('EnergyOverview.messages.singleDayOnly')) + return + } queryParams.pageNo = 1 getList() } @@ -469,11 +555,15 @@ const resetQuery = () => { queryFormRef.value?.resetFields() queryParams.orgId = undefined queryParams.energyTypeId = defaultEnergyTypeId.value - queryParams.timeRange = [...defaultTimeRange] + queryParams.timeRange = getTodayTimeRange() handleQuery() } const handleExport = async () => { + 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, @@ -499,6 +589,17 @@ onMounted(async () => { getList() } }) + +watch( + () => queryParams.orgId, + async () => { + await getEnergyTypes() + queryParams.pageNo = 1 + if (hasEnergyTypes.value) { + getList() + } + } +)