@ledvance/group-ui-biz-bundle 1.0.140 → 1.0.141

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "@ledvance/group-ui-biz-bundle",
5
5
  "pid": [],
6
6
  "uiid": "",
7
- "version": "1.0.140",
7
+ "version": "1.0.141",
8
8
  "scripts": {},
9
9
  "dependencies": {
10
10
  "@ledvance/base": "^1.x",
@@ -12,8 +12,8 @@ import { OverviewItem } from "./EnergyConsumptionPage";
12
12
  import dayjs from "dayjs";
13
13
  import { isNumber } from "lodash";
14
14
  import { EnergyData, UnitList } from "./component/EnergyModal";
15
- import I18n from "@ledvance/base/src/i18n";
16
15
  import {NativeApi} from "@ledvance/base/src/api/native";
16
+ import {xLog, retryWithBackoff} from "@ledvance/base/src/utils"
17
17
 
18
18
  interface LightConfig {
19
19
  energyConsumption?: EnergyData
@@ -50,17 +50,18 @@ export async function getElectricity(devIdGroup: string[], addEleDpCode: string,
50
50
  return res
51
51
  }
52
52
 
53
- let dpResultByMonthCache: DpResultByMonthResData[] | undefined
53
+ let dpResultByMonthCache: {key: DpResultByMonthResData[]} = {}
54
54
  const getDpResultByYear = async (devIdGroup: string[], addEleDpCode: string, dateStr: string): Promise<OverviewItem[]> => {
55
55
  const year = dateStr;
56
- let successGroup = dpResultByMonthCache;
56
+ const key = devIdGroup.join()
57
+ let successGroup = dpResultByMonthCache[key];
57
58
  if (!successGroup) {
58
59
  const promiseGroup = devIdGroup.map(devId =>
59
60
  getDpResultByMonth(devId, addEleDpCode, 'sum').catch(error => ({ error }))
60
61
  );
61
62
  // @ts-ignore
62
- dpResultByMonthCache = (await Promise.all(promiseGroup)).filter(v => !v.error);
63
- successGroup = dpResultByMonthCache
63
+ dpResultByMonthCache[key] = (await Promise.all(promiseGroup)).filter(v => !v.error);
64
+ successGroup = dpResultByMonthCache[key]
64
65
  }
65
66
  if (!successGroup) {
66
67
  return []
@@ -134,11 +135,12 @@ const getDpResultByYearMonth = async (deviceIdGroup: string[], addEleDpCode: str
134
135
 
135
136
 
136
137
  const getDpResultByDate = async (deviceIdGroup: string[], addEleDpCode: string, date: string): Promise<OverviewItem[]> => {
137
- if (overDays(date, 7)) {
138
- console.log("getDpResultByDate overDays true")
138
+ const newDate = date.replaceAll('/', '')
139
+ if (overDays(newDate, 7)) {
140
+ xLog("getDpResultByDate overDays true")
139
141
  return []
140
142
  }
141
- const promiseGroup = deviceIdGroup.map(devId => getDpResultByHour(devId, addEleDpCode, date, 'sum').catch(error => ({ error })))
143
+ const promiseGroup = deviceIdGroup.map(devId => getDpResultByHour(devId, addEleDpCode, newDate, 'sum').catch(error => ({ error })))
142
144
  const res = await Promise.all(promiseGroup);
143
145
  // @ts-ignore
144
146
  const successGroup: DpResultByDataWithSpecifiedResData[] = res.filter(v => !v.error);
@@ -174,8 +176,7 @@ const getDpResultByDate = async (deviceIdGroup: string[], addEleDpCode: string,
174
176
  return list
175
177
  }
176
178
 
177
- export const exportEnergyCsv = (values: any[][], unit: string) => {
178
- const headers = [I18n.getLang('date'), `${I18n.getLang('consumption_data_annual_bar_chart_system_back_text')} (kWh)`, `Price(${unit})`]
179
+ export const exportEnergyCsv = (headers: string[], values: any[][]) => {
179
180
  const functionName = 'EnergyConsumption'
180
181
  exportCsvFile(headers, values, functionName)
181
182
  }
@@ -195,12 +196,37 @@ export interface EnergyGeneration {
195
196
  history: EnergyHistory[]
196
197
  }
197
198
 
199
+ async function getJsonWithError(devId: string, key: string) {
200
+ const res = await NativeApi.getJson(devId, key)
201
+ if (!res.success) {
202
+ xLog(`getJsonWithError ${devId} ${key} failed`, res)
203
+ throw new Error(`API失败: ${res.msg || '未知错误'}`, { cause: res })
204
+ }
205
+ return res
206
+ }
207
+
198
208
  export async function getEnergyGenerationValue(devId: string): Promise<EnergyGeneration | undefined> {
199
- const res = await NativeApi.getJson(devId, EnergyGenerationId)
200
- if (res.success && res.data) {
201
- return JSON.parse(res.data)
202
- } else {
203
- console.log('getEnergyGenerationValue failed', res)
209
+ try {
210
+ const res = await retryWithBackoff(
211
+ () => getJsonWithError(devId, EnergyGenerationId),
212
+ {
213
+ // 自定义判断哪些错误需要重试
214
+ shouldRetry: (error) => {
215
+ // 网络错误、超时错误或服务器错误(5xx)通常需要重试
216
+ const isNetworkError = !error.cause?.success && error.cause?.msg === 'connection closed'
217
+
218
+ return isNetworkError;
219
+ }
220
+ }
221
+ )
222
+ if (res.success && res.data) {
223
+ return JSON.parse(res.data)
224
+ } else {
225
+ return undefined
226
+ }
227
+ } catch (error) {
228
+ xLog('getEnergyGenerationValue error', error.cause)
204
229
  return undefined
205
230
  }
231
+
206
232
  }
@@ -174,7 +174,7 @@ const EnergyConsumptionCard = (props: EnergyConsumptionProp) => {
174
174
  consumedEnergyItemUnit: {
175
175
  color: props.theme?.global.secondFontColor,
176
176
  fontSize: cx(14),
177
- fontFamily: 'helvetica_neue_lt_std_roman',
177
+ // fontFamily: 'helvetica_neue_lt_std_roman',
178
178
  textAlign: 'center'
179
179
  },
180
180
  subContent: {
@@ -188,13 +188,13 @@ const EnergyConsumptionCard = (props: EnergyConsumptionProp) => {
188
188
  color: props.theme?.global.secondBrand,
189
189
  },
190
190
  titleText: {
191
- fontFamily: 'helvetica_neue_lt_std_roman',
191
+ // fontFamily: 'helvetica_neue_lt_std_roman',
192
192
  fontSize: cx(14),
193
193
  color: props.theme?.global.secondFontColor,
194
194
  textAlign: 'center',
195
195
  },
196
196
  unitText: {
197
- fontFamily: 'helvetica_neue_lt_std_roman',
197
+ // fontFamily: 'helvetica_neue_lt_std_roman',
198
198
  fontSize: cx(14),
199
199
  color: props.theme?.global.secondFontColor,
200
200
  },
@@ -1,13 +1,19 @@
1
1
  import I18n from '@ledvance/base/src/i18n'
2
2
  import React, { useCallback } from 'react'
3
- import { View } from 'react-native'
3
+ import { Image, TouchableOpacity, View } from 'react-native'
4
4
  import { DateType } from '../co2Data'
5
5
  import DateSelectedItem from '../component/DateSelectedItem'
6
6
  import DateTypeItem from '../component/DateTypeItem'
7
+ import DateSwitch from '../component/DateSwitch'
7
8
  import NewBarChart from '../component/NewBarChart'
8
9
  import { EmptyDataView } from './EmptyDataView'
10
+ import { exportEnergyCsv } from '../EnergyConsumptionActions'
11
+ import { Utils } from 'tuya-panel-kit'
12
+ import res from '@ledvance/base/src/res'
9
13
 
10
- export const ChartSection = ({ state, actions, params, styles, theme, chartHeight }) => {
14
+ const { convertX: cx } = Utils.RatioUtils
15
+
16
+ export const ChartSection = ({ isLandscape, state, actions, params, styles, theme, chartHeight }) => {
11
17
  const getEmptyDataTip = useCallback(() => {
12
18
  if (state.over365Days && state.dateType !== DateType.Day) {
13
19
  return I18n.getLang('energyconsumption_Daylimit')
@@ -18,10 +24,97 @@ export const ChartSection = ({ state, actions, params, styles, theme, chartHeigh
18
24
  return I18n.getLang('energyconsumption_emptydata')
19
25
  }, [state.dateType, state.over365Days, state.over7Days])
20
26
 
21
- const isDataEmpty = state.chartData.length <= 0
27
+ const handleExportCsv = useCallback(() => {
28
+ const displayMode = state.displayMode || 'consumption'
29
+ const consumedData = state.consumptionChartData;
30
+ const generatedData = state.generationChartData;
31
+ const price = params.price;
32
+ const unit = params.unit;
33
+ const consumedName = I18n.getLang('chart_legend_consumption');
34
+ const generatedName = I18n.getLang('chart_legend_generation');
35
+ // 1. 创建CSV头部 (与之前相同)
36
+ const header = [I18n.getLang('date')];
37
+ if (displayMode === 'consumption' || displayMode === 'both') {
38
+ header.push(`${consumedName} (kWh)`, `${consumedName} (${unit})`);
39
+ }
40
+ if (displayMode === 'generation' || displayMode === 'both') {
41
+ header.push(`${generatedName} (kWh)`, `${generatedName} (${unit})`);
42
+ }
43
+ const rows = [];
44
+ let i = 0; // 指向 consumedData 的指针
45
+ let j = 0; // 指向 generatedData 的指针
46
+ // 2. 双指针合并算法
47
+ while (i < consumedData.length || j < generatedData.length) {
48
+ const consumedItem = consumedData[i];
49
+ const generatedItem = generatedData[j];
50
+ const consumedKey = consumedItem?.headlineText;
51
+ const generatedKey = generatedItem?.headlineText;
52
+ let rowData = [];
53
+ let dateKey = '';
54
+ if (consumedKey === generatedKey) {
55
+ dateKey = consumedItem.key;
56
+ const consumedValue = Number(consumedItem.value);
57
+ const generatedValue = Number(generatedItem.value);
58
+ if (displayMode === 'consumption' || displayMode === 'both') {
59
+ rowData.push(consumedValue.toFixed(2), (consumedValue * price).toFixed(2));
60
+ }
61
+ if (displayMode === 'generation' || displayMode === 'both') {
62
+ rowData.push(generatedValue.toFixed(2), (generatedValue * price).toFixed(2));
63
+ }
64
+ i++;
65
+ j++;
66
+ } else if (consumedKey > generatedKey || !generatedKey) {
67
+ dateKey = consumedItem.key;
68
+ const consumedValue = Number(consumedItem.value);
69
+ if (displayMode === 'consumption' || displayMode === 'both') {
70
+ rowData.push(consumedValue.toFixed(2), (consumedValue * price).toFixed(2));
71
+ }
72
+ if (displayMode === 'generation' || displayMode === 'both') {
73
+ // 在 'generation' 或 'both' 模式下,为缺失的产生数据补0
74
+ rowData.push('0.00', '0.00');
75
+ }
76
+ i++;
77
+ } else {
78
+ dateKey = generatedItem.key;
79
+ const generatedValue = Number(generatedItem.value);
80
+ if (displayMode === 'consumption' || displayMode === 'both') {
81
+ // 在 'consumption' 或 'both' 模式下,为缺失的消耗数据补0
82
+ rowData.push('0.00', '0.00');
83
+ }
84
+ if (displayMode === 'generation' || displayMode === 'both') {
85
+ rowData.push(generatedValue.toFixed(2), (generatedValue * price).toFixed(2));
86
+ }
87
+ j++;
88
+ }
89
+
90
+ // 将日期和处理好的数据行组合起来
91
+ rows.push([dateKey, ...rowData]);
92
+ }
93
+
94
+ exportEnergyCsv(header, rows);
95
+ }, [state.displayMode, state.consumptionChartData, state.generationChartData, params.price, params.unit])
96
+
97
+ const isDataEmpty = state.consumptionChartData.length <= 0 && state.generationChartData.length <= 0
22
98
 
23
99
  return (
24
100
  <>
101
+ {!isLandscape && (
102
+ <View style={styles.dateSwitchContainer}>
103
+ <DateSwitch
104
+ style={{ flex: 1 }}
105
+ date={state.date}
106
+ dateType={state.dateType}
107
+ headlineText={state.headlineText}
108
+ onDateChange={actions.setDate}
109
+ />
110
+ <TouchableOpacity style={{ width: cx(30) }} onPress={handleExportCsv}>
111
+ <Image
112
+ style={styles.downloadIcon}
113
+ source={{ uri: !isDataEmpty ? res.download_icon : undefined }}
114
+ />
115
+ </TouchableOpacity>
116
+ </View>
117
+ )}
25
118
  <View style={styles.dateControlsContainer}>
26
119
  <DateTypeItem
27
120
  style={styles.dateTypeItem}
@@ -43,6 +136,9 @@ export const ChartSection = ({ state, actions, params, styles, theme, chartHeigh
43
136
  <NewBarChart
44
137
  height={chartHeight}
45
138
  data={state.chartData}
139
+ displayMode={state.displayMode}
140
+ consumedData={state.consumptionChartData}
141
+ generatedData={state.generationChartData}
46
142
  price={state.price}
47
143
  unit={params.unit}
48
144
  />
@@ -1,21 +1,13 @@
1
1
  import Page from '@ledvance/base/src/components/Page'
2
2
  import res from '@ledvance/base/src/res'
3
- import React, { useCallback } from 'react'
4
- import { Image, ScrollView, TouchableOpacity, View } from 'react-native'
3
+ import React from 'react'
4
+ import { ScrollView, } from 'react-native'
5
5
  import { Utils } from 'tuya-panel-kit'
6
- import DateSwitch from '../component/DateSwitch'
7
- import { exportEnergyCsv } from '../EnergyConsumptionActions'
8
6
  import { ChartSection } from './ChartSection'
9
7
 
10
8
  const { convertX: cx } = Utils.RatioUtils
11
9
 
12
10
  export const PortraitView = ({ state, actions, params, styles, theme }) => {
13
-
14
- const handleExportCsv = useCallback(() => {
15
- const values = state.chartData.map(item => [item.key, item.value, (Number(params.price) * Number(item.value)).toFixed(2)])
16
- exportEnergyCsv(values, params.unit)
17
- }, [state.chartData, params.price, params.unit])
18
-
19
11
  return (
20
12
  <Page
21
13
  backText={params.backTitle}
@@ -25,26 +17,10 @@ export const PortraitView = ({ state, actions, params, styles, theme }) => {
25
17
  rightButtonIcon={state.isSupportLandscape ? res.screen_full : undefined}
26
18
  rightButtonStyle={styles.fullScreenIcon}
27
19
  rightButtonIconClick={actions.toggleLandscape}
28
- headlineContent={
29
- <View style={styles.headlineContainer}>
30
- <DateSwitch
31
- style={styles.dateSwitch}
32
- date={state.date}
33
- dateType={state.dateType}
34
- headlineText={state.headlineText}
35
- onDateChange={actions.setDate}
36
- />
37
- <TouchableOpacity style={styles.downloadButton} onPress={handleExportCsv}>
38
- <Image
39
- style={styles.downloadIcon}
40
- source={{ uri: !(state.chartData.length <= 0) ? res.download_icon : undefined }}
41
- />
42
- </TouchableOpacity>
43
- </View>
44
- }
45
20
  >
46
21
  <ScrollView nestedScrollEnabled={true} style={styles.scrollViewContent}>
47
22
  <ChartSection
23
+ isLandscape={false}
48
24
  state={state}
49
25
  actions={actions}
50
26
  params={params}
@@ -9,6 +9,11 @@ export const getStyles = (theme: ThemeType | undefined) => StyleSheet.create({
9
9
  scrollViewContent: {
10
10
  marginHorizontal: cx(24),
11
11
  },
12
+ dateSwitchContainer: {
13
+ width: '100%',
14
+ flexDirection: 'row',
15
+ marginVertical: cx(15),
16
+ },
12
17
  dateControlsContainer: {
13
18
  flexDirection: 'row',
14
19
  },
@@ -1,15 +1,17 @@
1
1
  import { OrientationService } from '@ledvance/base/src/api/OrientationService'
2
- import { overDays } from '@ledvance/base/src/utils'
2
+ import { overDays, xLog } from '@ledvance/base/src/utils'
3
3
  import { loopsText, monthFormat } from '@ledvance/base/src/utils/common'
4
4
  import { useReactive, useUpdateEffect } from 'ahooks'
5
5
  import dayjs from 'dayjs'
6
- import { useCallback } from 'react'
6
+ import { useCallback, useEffect } from 'react'
7
7
  import { DateType } from '../co2Data'
8
8
  import { getElectricity } from '../EnergyConsumptionActions'
9
9
  import { EnergyConsumptionChartProps } from '../EnergyConsumptionChart'
10
10
 
11
+ export type EnergyDisplayMode = 'consumption' | 'generation' | 'both';
12
+
11
13
  export const useEnergyData = (params: EnergyConsumptionChartProps) => {
12
- const { addEleDpCode, price, date, over365Days, over7Days, chartData, deviceIdGroup } = params
14
+ const { addEleDpCode, price, unit, date, over365Days, over7Days, chartData, deviceIdGroup, consumptionDeviceIds, generationDeviceIds } = params
13
15
 
14
16
  const getDateType = useCallback((d: string) => {
15
17
  const datejs = dayjs(d)
@@ -30,7 +32,11 @@ export const useEnergyData = (params: EnergyConsumptionChartProps) => {
30
32
  date: date,
31
33
  headlineText: initialDateType === DateType.Year ? date : params.headlineText,
32
34
  chartData: chartData.filter((item) => initialDateType !== DateType.Year || item.headlineText.startsWith(date)),
35
+ displayMode: params.displayMode || 'consumption',
36
+ consumptionChartData: [],
37
+ generationChartData: [],
33
38
  price: isNaN(Number(price)) ? 0 : Number(price),
39
+ unit: unit,
34
40
  over365Days: over365Days,
35
41
  over7Days: over7Days,
36
42
  })
@@ -53,16 +59,17 @@ export const useEnergyData = (params: EnergyConsumptionChartProps) => {
53
59
  }
54
60
  }, [state.dateType])
55
61
 
56
- useUpdateEffect(() => {
62
+ useEffect(() => {
57
63
  state.loading = true
58
- getElectricity(deviceIdGroup, addEleDpCode, state.date, state.dateType)
59
- .then((res) => {
60
- state.chartData = res
61
- state.loading = false
62
- })
63
- .catch(() => {
64
- state.loading = false
65
- })
64
+ const consumptionData = getElectricity(consumptionDeviceIds, addEleDpCode, state.date, state.dateType)
65
+ const generationData = getElectricity(generationDeviceIds, addEleDpCode, state.date, state.dateType)
66
+ Promise.all([consumptionData, generationData]).then(([consumptionRes, generationRes]) => {
67
+ state.consumptionChartData = consumptionRes
68
+ state.generationChartData = generationRes
69
+ state.loading = false
70
+ }).catch(() => {
71
+ state.loading = false
72
+ })
66
73
  }, [state.date])
67
74
 
68
75
  useUpdateEffect(() => {
@@ -96,6 +103,9 @@ export const useEnergyData = (params: EnergyConsumptionChartProps) => {
96
103
  setDateType: useCallback((type: DateType) => {
97
104
  state.dateType = type
98
105
  }, []),
106
+ setDisplayMode: useCallback((mode: EnergyDisplayMode) => {
107
+ state.displayMode = mode
108
+ }, []),
99
109
  toggleLandscape: useCallback(() => {
100
110
  if (!state.isSupportLandscape) return
101
111
  const newIsLandscape = !state.isLandscape
@@ -106,6 +116,10 @@ export const useEnergyData = (params: EnergyConsumptionChartProps) => {
106
116
  OrientationService.lockToPortrait()
107
117
  }
108
118
  }, []),
119
+ setPriceAndUnit: useCallback((newPrice: string, newUnit: string) => {
120
+ state.price = isNaN(Number(newPrice)) ? 0 : Number(newPrice)
121
+ state.unit = newUnit
122
+ }, []),
109
123
  }
110
124
 
111
125
  return { state, actions }
@@ -1,4 +1,5 @@
1
1
  import { OverviewItem } from './EnergyConsumptionPage'
2
+ import { EnergyDisplayMode } from './EnergyConsumptionChart/useEnergyData'
2
3
 
3
4
  export interface EnergyConsumptionChartProps {
4
5
  addEleDpCode: string
@@ -8,6 +9,9 @@ export interface EnergyConsumptionChartProps {
8
9
  over365Days?: boolean
9
10
  over7Days?: boolean,
10
11
  deviceIdGroup: string[];
12
+ displayMode?: EnergyDisplayMode;
13
+ consumptionDeviceIds: string[];
14
+ generationDeviceIds: string[];
11
15
  price: string,
12
16
  unit: string,
13
17
  date: string,
@@ -22,7 +22,7 @@ import EnergyPopup, { EnergyData } from "./component/EnergyModal";
22
22
  import { carbonDioxideEmission, countryAndRegion } from "./co2Data";
23
23
  import ThemeType from '@ledvance/base/src/config/themeType'
24
24
  import { exportEnergyCsv } from "./EnergyConsumptionActions";
25
-
25
+ import { EnergyDisplayMode } from './EnergyConsumptionChart/useEnergyData'
26
26
  const { convertX: cx } = Utils.RatioUtils
27
27
  const { withTheme } = Utils.ThemeUtils
28
28
 
@@ -33,6 +33,9 @@ export interface EnergyConsumptionDetailProps {
33
33
  price: string
34
34
  unit: string
35
35
  deviceIdGroup: string[];
36
+ displayMode?: EnergyDisplayMode;
37
+ consumptionDeviceIds: string[];
38
+ generationDeviceIds: string[];
36
39
  isSolarMode: boolean
37
40
  updateEnergyData: (data: EnergyData) => {}
38
41
  }
@@ -171,7 +174,7 @@ const EnergyConsumptionDetail = (props: { theme?: ThemeType }) => {
171
174
  },
172
175
  consumptionNum: {
173
176
  color: props.theme?.global.secondBrand,
174
- fontFamily: 'helvetica_neue_lt_std_bd',
177
+ // fontFamily: 'helvetica_neue_lt_std_bd',
175
178
  },
176
179
  subContent: {
177
180
  flex: 1,
@@ -184,7 +187,7 @@ const EnergyConsumptionDetail = (props: { theme?: ThemeType }) => {
184
187
  color: props.theme?.global.secondBrand,
185
188
  },
186
189
  titleText: {
187
- fontFamily: 'helvetica_neue_lt_std_roman',
190
+ // fontFamily: 'helvetica_neue_lt_std_roman',
188
191
  fontSize: cx(14),
189
192
  color: props.theme?.global.secondFontColor,
190
193
  textAlign: 'center',
@@ -218,8 +221,9 @@ const EnergyConsumptionDetail = (props: { theme?: ThemeType }) => {
218
221
  headlineText={params.curMonth.key}
219
222
  headlineIcon={state.overviewList.length ? res.download_icon : undefined}
220
223
  onHeadlineIconClick={() => {
224
+ const headers = [I18n.getLang('date'), `${I18n.getLang('consumption_data_annual_bar_chart_system_back_text')} (kWh)`, `Price(${params.unit})`]
221
225
  const values = state.overviewList.map(item => [item.key, item.value, (Number(params.price) * Number(item.value)).toFixed(2)])
222
- exportEnergyCsv(values, params.unit)
226
+ exportEnergyCsv(headers, values)
223
227
  }}
224
228
  showGreenery={false}
225
229
  greeneryIcon={res.energy_consumption_greenery}
@@ -241,34 +245,34 @@ const EnergyConsumptionDetail = (props: { theme?: ThemeType }) => {
241
245
  <Spacer />
242
246
  {/* CO2 */}
243
247
  {params.isSolarMode && <>
244
- <View style={{ flexDirection: 'row', alignItems: 'center' }}>
245
- <View style={styles.priceBg}>
246
- <Image
247
- source={{ uri: res.energy_consumption_cash}}
248
- resizeMode="contain"
249
- style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
250
- />
248
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
249
+ <View style={styles.priceBg}>
250
+ <Image
251
+ source={{ uri: res.energy_consumption_cash}}
252
+ resizeMode="contain"
253
+ style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
254
+ />
255
+ </View>
256
+ <View style={styles.priceNum}>
257
+ <View style={{ flexDirection: 'row' }}>
258
+ <Text style={{ color: props.theme?.global.secondFontColor, marginRight: cx(5) }}>{I18n.getLang('consumption_data_field3_co2_topic_text')}</Text>
259
+ <TouchableOpacity
260
+ onPress={() => {
261
+ state.showPopup = true
262
+ state.popupType = 'co2'
263
+ }}
264
+ >
265
+ <Image
266
+ source={{ uri: res.co2_icon}}
267
+ resizeMode="contain"
268
+ style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
269
+ />
270
+ </TouchableOpacity>
271
+ </View>
272
+ <Text style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}>{`${state.co2Saved} kg`}</Text>
273
+ </View>
251
274
  </View>
252
- <View style={styles.priceNum}>
253
- <View style={{ flexDirection: 'row' }}>
254
- <Text style={{ color: props.theme?.global.secondFontColor, marginRight: cx(5) }}>{I18n.getLang('consumption_data_field3_co2_topic_text')}</Text>
255
- <TouchableOpacity
256
- onPress={() => {
257
- state.showPopup = true
258
- state.popupType = 'co2'
259
- }}
260
- >
261
- <Image
262
- source={{ uri: res.co2_icon}}
263
- resizeMode="contain"
264
- style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
265
- />
266
- </TouchableOpacity>
267
- </View>
268
- <Text style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}>{`${state.co2Saved} kg`}</Text>
269
- </View>
270
- </View>
271
- <Spacer height={cx(10)} />
275
+ <Spacer height={cx(10)} />
272
276
  </>}
273
277
  {/* money */}
274
278
  <View style={{ flexDirection: 'row', alignItems: 'center' }}>
@@ -311,6 +315,9 @@ const EnergyConsumptionDetail = (props: { theme?: ThemeType }) => {
311
315
  addEleDpCode: params.addEleDpCode,
312
316
  date: params.curMonth.headlineText,
313
317
  deviceIdGroup: params.deviceIdGroup,
318
+ displayMode: params.displayMode,
319
+ consumptionDeviceIds: params.consumptionDeviceIds,
320
+ generationDeviceIds: params.generationDeviceIds,
314
321
  } as EnergyConsumptionChartProps)
315
322
  }}
316
323
  overviewItemClick={async (item) => {
@@ -327,6 +334,9 @@ const EnergyConsumptionDetail = (props: { theme?: ThemeType }) => {
327
334
  unit: state.unit,
328
335
  date: item.headlineText,
329
336
  deviceIdGroup: params.deviceIdGroup,
337
+ displayMode: params.displayMode,
338
+ consumptionDeviceIds: params.consumptionDeviceIds,
339
+ generationDeviceIds: params.generationDeviceIds,
330
340
  } as EnergyConsumptionChartProps)
331
341
  }}
332
342
  overViewList={state.overviewList}