Explorar o código

add app/pages/wallet/OverviewV2.js

wudebin hai 5 meses
pai
achega
be7b473021
Modificáronse 1 ficheiros con 390 adicións e 0 borrados
  1. 390 0
      Strides-SPAPP/app/pages/wallet/OverviewV2.js

+ 390 - 0
Strides-SPAPP/app/pages/wallet/OverviewV2.js

@@ -0,0 +1,390 @@
+/**
+ * 钱包概述页面优化版
+ * @邠心vbe on 2024/03/27
+ */
+import React, { Component } from 'react';
+import { View, StyleSheet, Text, Pressable } from 'react-native';
+import { ElevationObject } from '../../components/Button';
+import apiWallet from '../../api/apiWallet';
+import utils from '../../utils/utils';
+import TextView from '../../components/TextView';
+import Dialog from '../../components/Dialog';
+
+const chartThemes = "#A6EB7C"; //配置柱状图颜色
+
+export default class OverviewV2 extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      skeleton: true,
+      glanceData: {},
+      monthData: [],
+      weekdayData: [],
+      weekIndex: 0,
+      monthIndex: 0,
+      maxWeek: 0,
+      maxMonth: 0
+    };
+    this.nowDataString = new Date().toDateString()
+    this.refreshing = false;
+  }
+
+  componentDidMount() {
+    console.log("概述", this.props);
+    if (!this.props.skeleton) {
+      this.refreshing = true;
+      //Dialog.showProgressDialog();
+      this.getOverview();
+    }
+  }
+
+  componentDidUpdate() {
+    if (this.props.shown && !this.props.skeleton) {
+      if (this.props.refresh && !this.refreshing) {
+        this.refreshing = true;
+        this.getOverview();
+      } else if (this.state.skeleton && !this.refreshing) {
+        this.refreshing = true;
+        this.getOverview();
+      }
+    }
+  }
+
+  getOverview() {
+    apiWallet.getOverviewData().then(res => {
+      var glanceData = {}
+      var weekdayData = []
+      var monthData = []
+      var weekIndex = 0
+      var monthIndex = 0
+      let maxWeek = 0;
+      let maxMonth = 0;
+      if (res.data) {
+        if (res.data.atAGlance) {
+          glanceData = res.data.atAGlance
+        }
+        if (res.data.statisticsForThisWeek) {
+          res.data.statisticsForThisWeek.forEach((item, index) => {
+            if (this.nowDataString.indexOf(item.x) >= 0) {
+              weekIndex = index;
+            }
+            if (item.y > maxWeek) {
+              maxWeek = item.y;
+            }
+            //item.y += index + 2;
+            item.label = currency + item.y;
+            item.title = item.dateTimeStr + ' | ' + item.label + ' | ' + item.power + 'kW';
+            weekdayData.push(item);
+          });
+        }
+        if (res.data.pastSixMonths) {
+          res.data.pastSixMonths.forEach((item, index) => {
+            if (this.nowDataString.indexOf(item.x) >= 0) {
+              monthIndex = index;
+            }
+            //item.y += index + 3;
+            if (item.y > maxMonth) {
+              maxMonth = item.y;
+            }
+            item.label = currency + item.y;
+            item.title = item.x + ' | ' + item.label + ' | ' + item.power + 'kW';
+            monthData.push(item);
+          });
+        }
+      }
+      this.setState({
+        glanceData: glanceData,
+        weekIndex: weekIndex,
+        monthIndex: monthIndex,
+        weekdayData: weekdayData,
+        monthData: monthData,
+        maxWeek: maxWeek,
+        maxMonth: maxMonth
+      }, () => {
+        this.setState({
+          skeleton: false
+        }, () => {
+          this.stopRefresh();
+        })
+      });
+      
+    }).catch(err => {
+      toastShort(err);
+      this.stopRefresh();
+    });
+  }
+
+  stopRefresh() {
+    if (this.props.refreshed) {
+      this.props.refreshed();
+    }
+    this.refreshing = false;
+    Dialog.dismissLoading();
+  }
+
+  changeWeek(index) {
+    this.setState({
+      weekIndex: index
+    });
+  }
+
+  changeMonth(index) {
+    this.setState({
+      monthIndex: index
+    });
+  }
+
+  getWeekHeight(y) {
+    if (y) {
+      let r = y / this.state.maxWeek * 100;
+      return Math.ceil(r);
+    } else {
+      return 1;
+    }
+  }
+  
+  getMonthHeight(y) {
+    if (y) {
+      let r = y / this.state.maxMonth * 100;
+      return Math.ceil(r);
+    } else {
+      return 1;
+    }
+  }
+
+  render() {
+    return (
+      <View style={this.props.shown ? ui.flex1 : styles.hide}>
+        { this.props.atAglance &&
+          <View style={styles.glanceView}>
+            <TextView style={styles.glanceTitle}>{$t('wallet.atAglance')}</TextView>
+            <View style={styles.overviewRow}>
+              <View style={ui.flex1}>
+                <TextView style={styles.valueText}>{this.state.glanceData.averageCharge ?? 0}</TextView>
+                <TextView style={styles.titleText}>kWh/{$t('wallet.perWeek')}</TextView>
+                <TextView style={styles.subTitleText}>{$t('wallet.averageCharge')}</TextView>
+              </View>
+              <View style={ui.flex1}>
+                <TextView style={styles.valueText}>{this.state.glanceData.averageSpend ?? 0}</TextView>
+                <TextView style={styles.titleText}>{currency}/{$t('wallet.perWeek')}</TextView>
+                <TextView style={styles.subTitleText}>{$t('wallet.averageSpend')}</TextView>
+              </View>
+              <View style={ui.flex1}>
+                <TextView style={styles.valueText}>{utils.hour2HHmm(this.state.glanceData.averageTime)}</TextView>
+                <TextView style={styles.titleText}>{$t('wallet.perHrWeek')}</TextView>
+                <TextView style={styles.subTitleText}>{$t('wallet.averageTime')}</TextView>
+              </View>
+            </View>
+          </View>
+        }
+        <View style={styles.statisticView}>
+          <View style={ui.flexcw}>
+            <TextView style={this.props.isTabPage ? styles.sectionTitleV2 : styles.sectionTitle}>{$t('wallet.forWeekOf')}</TextView>
+            {/* <Text style={styles.linkText}>1st Jan to 8th Jan </Text> */}
+          </View>
+          <View style={styles.overviewRow}>
+            <View style={ui.flex1}>
+              {/* <Text style={styles.valueText}>{this.state.glanceData.averageCharge ?? 0}</Text> */}
+              <TextView style={styles.titleText}>{this.state.glanceData.averageCharge ?? 0} kWh{/*$t('wallet.perWeek')*/}</TextView>
+              <TextView style={styles.subTitleText}>{$t('wallet.averageCharge')}</TextView>
+            </View>
+            <View style={styles.overviewDivide}></View>
+            <View style={ui.flex1}>
+              {/* <Text style={styles.valueText}>{this.state.glanceData.averageSpend ?? 0}</Text> */}
+              <TextView style={styles.titleText}>{this.state.glanceData.currencySymbol} {this.state.glanceData.averageSpend ?? 0}{/*$t('wallet.perWeek')*/}</TextView>
+              <TextView style={styles.subTitleText}>{$t('wallet.averageSpend')}</TextView>
+            </View>
+            <View style={styles.overviewDivide}></View>
+            <View style={ui.flex1}>
+              {/* <Text style={styles.valueText}>{utils.hour2HHmm(this.state.glanceData.averageTime)}</Text> */}
+              <TextView style={styles.titleText}>{utils.hour2HHmm(this.state.glanceData.averageTime)}{/*$t('wallet.perWeek')*/}</TextView>
+              <TextView style={styles.subTitleText}>{$t('wallet.averageTime')}</TextView>
+            </View>
+          </View>
+        </View>
+        <View style={ui.flex1}>
+          <View style={styles.statisticView}>
+            <TextView style={this.props.isTabPage ? styles.sectionTitleV2 : styles.sectionTitle}>{$t('wallet.statistics4week')}</TextView>
+            <TextView style={styles.statisticTitle}>{this.state.weekdayData[this.state.weekIndex]?.title}</TextView>
+            <View style={styles.barChartView}>
+              { this.state.weekdayData.map((item, index) => (
+                <View
+                  style={styles.barChartItem}
+                  key={index}>
+                  <Text
+                    style={styles.barLabelText}
+                    onPress={() => this.changeWeek(index)}>
+                    {item.label}
+                  </Text>
+                  <Pressable
+                    style={[
+                      styles.barChartValue,
+                      {
+                        height: this.getWeekHeight(item.y),
+                        opacity: index == this.state.weekIndex ? 1 : 0.6
+                      }
+                    ]}
+                    onPress={() => this.changeWeek(index)}
+                  />
+                  <Text style={styles.barLabelText}>{item.x}</Text>
+                </View>
+              ))}
+            </View>
+          </View>
+          <View style={styles.statisticView}>
+            <TextView style={this.props.isTabPage ? styles.sectionTitleV2 : styles.sectionTitle}>{$t('wallet.statistics4HalfYear')}</TextView>
+            <TextView style={styles.statisticTitle}>{this.state.monthData[this.state.monthIndex]?.title}</TextView>
+            <View style={styles.barChartView}>
+              { this.state.monthData.map((item, index) => (
+                <View
+                  style={styles.barChartItem}
+                  key={index}>
+                  <Text
+                    style={styles.barLabelText}
+                    onPress={() => this.changeMonth(index)}>
+                    {item.label}
+                  </Text>
+                  <Pressable
+                    style={[
+                      styles.barChartValue,
+                      {
+                        height: this.getMonthHeight(item.y),
+                        opacity: index == this.state.monthIndex ? 1 : 0.6
+                      }
+                    ]}
+                    onPress={() => this.changeMonth(index)}
+                  />
+                  <Text style={styles.barLabelText}>{item.x}</Text>
+                </View>
+              ))}
+            </View>
+          </View>
+        </View>
+      </View>
+    );
+  }
+}
+
+const animate = {
+  duration: 500,
+  onLoad: {
+    duration: 200
+  }
+}
+
+const axisTheme = {
+  axis: {stroke: "#fff"},
+  grid: {strokeWidth: 0},
+  ticks: {size: 0},
+  tickLabels: {color: '#666', fontSize: 12, padding: 8},
+}
+
+const styles = StyleSheet.create({
+  hide: {
+    display: 'none'
+  },
+  glanceView: {
+    marginTop: 16,
+    marginLeft: 16,
+    marginRight: 16,
+    marginBottom: 4,
+    ...ElevationObject(2),
+    overflow: 'hidden',
+    borderTopLeftRadius: 6,
+    borderTopRightRadius: 6,  
+    backgroundColor: colorLight
+  },
+  glanceTitle: {
+    color: textPrimary,
+    fontSize: 16,
+    paddingTop: 4,
+    paddingLeft: 16,
+    paddingBottom: 4,
+    backgroundColor: '#C4C8DF'
+  },
+  overviewRow: {
+    paddingTop: 16,
+    paddingBottom: 10,
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  overviewDivide: {
+    width: 1,
+    height: 12,
+    backgroundColor: '#D9D9D9'
+  },
+  valueText: {
+    color: '#000',
+    fontSize: 22,
+    paddingBottom: 8,
+    textAlign: 'center'
+  },
+  titleText: {
+    color: textPrimary,
+    fontSize: 14,
+    textAlign: 'center'
+  },
+  subTitleText: {
+    color: textCancel,
+    fontSize: 12,
+    textAlign: 'center'
+  },
+  statisticView: {
+    marginTop: 0,
+    paddingBottom: 16,
+    backgroundColor: colorLight
+  },
+  sectionTitle: {
+    color: textPrimary,
+    fontSize: 14,
+    paddingLeft: 16,
+    fontWeight: 'bold'
+  },
+  sectionTitleV2: {
+    flex: 1,
+    color: textPrimary,
+    fontSize: 14,
+    marginLeft: 16,
+    marginRight: 16,
+    paddingBottom: 4,
+    fontWeight: 'bold',
+    textTransform: 'uppercase',
+    borderBottomWidth: 1,
+    borderBottomColor: colorPrimary
+  },
+  statisticTitle: {
+    color: textPrimary,
+    fontSize: 14,
+    paddingTop: 24,
+    paddingBottom: 8,
+    textAlign: 'center'
+  },
+  statisticChart: {
+    height: 120
+  },
+  linkText: {
+    ...ui.link,
+    fontSize: 14,
+    paddingRight: 16
+  },
+  barChartView: {
+    height: 200,
+    padding: 16,
+    alignItems: 'flex-end',
+    flexDirection: 'row',
+    justifyContent: 'space-between'
+  },
+  barChartItem: {
+    alignItems: 'center'
+  },
+  barLabelText: {
+    padding: 4,
+    fontSize: 12,
+    textAlign: 'center'
+  },
+  barChartValue: {
+    width: 24,
+    minHeight: 1,
+    backgroundColor: colorAccent
+  }
+})