Bladeren bron

1. Add wallet V2

2. Prepare 2 in 1 QR as an option
https://dev.wormwood.com.sg/zentao/task-view-105.html
vbea 2 jaren geleden
bovenliggende
commit
6450cd3324

+ 3 - 0
Strides-APP/app/api/apiWallet.js

@@ -41,5 +41,8 @@ export default wallet = {
   },
   getTransactionList: (params) => {
     return get(prefix + 'getTransactionsHistory', params);
+  },
+  getTransactionListV2: (params) => {
+    return get(prefix + 'v2/trans-histories', params);
   }
 }

+ 4 - 1
Strides-APP/app/i18n/locales/en.js

@@ -55,6 +55,7 @@ export default {
     editVehicle: "Update Vehicle",
     feedback: "Feedback",
     forgotPassword: "Forgot Password",
+    history: "History",
     makePayment: "Make Payment",
     myVehicles: "My Vehicles",
     notifications: "Notifications",
@@ -386,7 +387,9 @@ export default {
     titleChoosePaymentType: "Choose Payment Method",
     titleLowCredits: "Low Credits",
     topUp: "Top Up",
-    viewHistory: "View History"
+    viewHistory: "View History",
+    viewMore: "View More",
+    noMore: "No More"
   },
   payment: {
     btnSave2gallery: "Save QR Code to Gallery",

+ 4 - 1
Strides-APP/app/i18n/locales/zh-TW.js

@@ -55,6 +55,7 @@ export default {
     editVehicle: "修改車輛訊息",
     feedback: "反饋",
     forgotPassword: "忘記密碼",
+    history: "曆史交易",
     makePayment: "收銀台",
     myVehicles: "我的車輛",
     notifications: "通知",
@@ -386,7 +387,9 @@ export default {
     titleChoosePaymentType: "選擇付款方式",
     titleLowCredits: "餘額過低",
     topUp: "充值",
-    viewHistory: "曆史記錄"
+    viewHistory: "曆史記錄",
+    viewMore: "查詢更多",
+    noMore: "已經到底了"
   },
   payment: {
     btnSave2gallery: "將二維碼儲存到相簿",

+ 4 - 1
Strides-APP/app/i18n/locales/zh.js

@@ -55,6 +55,7 @@ export default {
     editVehicle: "修改车辆信息",
     feedback: "反馈",
     forgotPassword: "忘记密码",
+    history: "历史交易",
     makePayment: "收银台",
     myVehicles: "我的车辆",
     notifications: "通知",
@@ -386,7 +387,9 @@ export default {
     titleChoosePaymentType: "选择支付方式",
     titleLowCredits: "余额过低",
     topUp: "充值",
-    viewHistory: "历史记录"
+    viewHistory: "历史记录",
+    viewMore: "查看更多",
+    noMore: "到底了"
   },
   payment: {
     btnSave2gallery: "将二维码保存到相册",

+ 6 - 0
Strides-APP/app/pages/Router.js

@@ -64,6 +64,7 @@ import ViewCampaign from './alert/ViewCampaign';
 import RefundPolicy from './payment/RefundPolicy';
 import ViewArticle from './alert/ViewArticle';
 import VehicleListV2 from './vehicles/VehicleListV2';
+import HistoryList from './wallet/HistoryList';
 
 export var PageList = {
   'splash': {
@@ -164,6 +165,11 @@ export var PageList = {
     titleScope: 'route.wallet',
     component: Wallet
   },
+  'history': {
+    title: 'History',
+    titleScope: 'route.history',
+    component: HistoryList
+  },
   'editProfile': {
     title: 'My Profile',
     titleScope: 'route.editProfile',

+ 1 - 0
Strides-APP/app/pages/alert/ListAlerts.js

@@ -187,6 +187,7 @@ export default class ListAlerts extends Component {
         ItemSeparatorComponent={this.divideView}
         keyExtractor={item => item.notificationId}
         onEndReached={() => this.getMessageListPage()}
+        onEndReachedThreshold={0.3}
         refreshControl={
           <RefreshControl
             {...MyRefreshProps()}

+ 1 - 0
Strides-APP/app/pages/alert/ListCampaign.js

@@ -101,6 +101,7 @@ export default class ListCampaign extends Component {
         ItemSeparatorComponent={this.divideView}
         keyExtractor={item => item.articleId}
         onEndReached={() => this.getMessageListPage()}
+        onEndReachedThreshold={0.3}
         refreshControl={
           <RefreshControl
             {...MyRefreshProps()}

+ 1 - 0
Strides-APP/app/pages/alert/ListNews.js

@@ -102,6 +102,7 @@ export default class ListNews extends Component {
         ItemSeparatorComponent={this.divideView}
         keyExtractor={item => item.articleId}
         onEndReached={() => this.getMessageListPage()}
+        onEndReachedThreshold={0.3}
         refreshControl={
           <RefreshControl
             {...MyRefreshProps()}

+ 12 - 0
Strides-APP/app/pages/charge/QRScan.js

@@ -128,6 +128,15 @@ export default class QRScan extends Component {
         this.getChargeDetail(qr);
         return;
       }
+    } else {
+      const qr = {
+        qrContent: msg.data
+      }
+      if (this.state.params.id) {
+        qr.sitePk = this.state.params.id
+      }
+      this.getChargeDetail(qr);
+      return;
     }
     Dialog.showDialog({
       title: 'Error',
@@ -141,6 +150,9 @@ export default class QRScan extends Component {
   }
 
   getChargeDetail(qr) {
+    console.log('===============SCAN QR===============');
+    console.log(qr);
+    console.log('===============SCAN QR===============');
     apiCharge.checkQRStatus(qr).then(res => {
       if (res.data && res.data.chargeBoxId) {
         QRResult.setResult(res.data);

+ 85 - 40
Strides-APP/app/pages/wallet/History.js

@@ -3,10 +3,11 @@
  * @邠心vbe on 2021/05/08
  */
 import React, { Component } from 'react';
-import { View, Text, StyleSheet, Image, Pressable } from 'react-native';
+import { View, Text, StyleSheet, Image, Pressable, TouchableOpacity } from 'react-native';
 import apiWallet from '../../api/apiWallet';
 import TextView from '../../components/TextView';
 import { PageList } from '../Router';
+import app from '../../../app.json';
 
 const IconCharge = require('../../images/wallet/ic-type-charge.png');
 const IconPayment = require('../../images/wallet/ic-type-payment.png');
@@ -21,13 +22,13 @@ export default class History extends Component {
   }
 
   componentDidMount() {
-    this.getHistory(true);
+    this.getHistory();
   }
 
   componentDidUpdate() {
     if (this.props.refresh && !this.refreshing && this.props.shown) {
       this.refreshing = true;
-      this.getHistory(true);
+      this.getHistory();
     }
   }
 
@@ -38,22 +39,42 @@ export default class History extends Component {
     return null;
   }
 
-  getHistory(refresh) {
-    apiWallet.getTransactionList({latestPk: refresh ? '' : this.getLastPk()}).then(res => {
+  getHistory() {
+    if (app.v3.overview) {
+      this.getHistoryV2();
+      return;
+    }
+    apiWallet.getTransactionList({latestPk: ''}).then(res => {
       this.stopRefresh();
       if (res.data) {
-        if (refresh) {
-          this.setState({
-            historyList: res.data
-          });
-        } else {
-          const list = this.state.historyList;
-          this.setState({
-            historyList: list.concat(res.data)
-          });
-        }
+        this.setState({
+          historyList: res.data
+        });
+      }
+    }).catch(err => {
+      this.setState({
+        historyList: []
+      });
+      this.stopRefresh();
+    });
+  }
+
+  getHistoryV2() {
+    apiWallet.getTransactionListV2({latestPk: ''}).then(res => {
+      this.stopRefresh();
+      if (res.data && res.data.length) {
+        this.setState({
+          historyList: res.data.slice(10)
+        });
+      } else {
+        this.setState({
+          historyList: []
+        });
       }
     }).catch(err => {
+      this.setState({
+        historyList: []
+      });
       this.stopRefresh();
     });
   }
@@ -84,6 +105,10 @@ export default class History extends Component {
     return title;
   }
 
+  toHistoryList() {
+    startPage(PageList.history);
+  }
+
   render() {
     return (
       <View style={this.props.shown ? ui.flex1 : styles.hide}>
@@ -96,35 +121,50 @@ export default class History extends Component {
         </View> */}
         <View style={styles.listView}>
         { this.state.historyList.length > 0
-          ? this.state.historyList.map((item, index) => {
-              return (
-                <Pressable
-                  key={index}
-                  android_ripple={ripple}
-                  style={styles.itemView}
-                  onPress={() => {
-                    this.toSummary(index)
-                  }}>
-                  <Image
-                    style={styles.iconType}
-                    resizeMode="contain"
-                    source={(item.amountSymbol == 'P' || item.remarks) ? IconPayment : IconCharge}/>
-                  <View style={[styles.itemContent, index > 0 && styles.divide]}>
-                    <View style={ui.flex1}>
-                      <TextView style={styles.issueName}>{this.getTransTitle(item)}</TextView>
-                      <TextView style={styles.issueDesc}>{$t('wallet.labelTransactionId') + item.creditRecordPk}</TextView>
+          ? <> 
+            {
+              this.state.historyList.map((item, index) => {
+                return (
+                  <Pressable
+                    key={index}
+                    android_ripple={ripple}
+                    style={styles.itemView}
+                    onPress={() => {
+                      this.toSummary(index)
+                    }}>
+                    <Image
+                      style={styles.iconType}
+                      resizeMode="contain"
+                      source={(item.amountSymbol == 'P' || item.remarks) ? IconPayment : IconCharge}/>
+                    <View style={[styles.itemContent, index > 0 && styles.divide]}>
+                      <View style={ui.flex1}>
+                        <TextView style={styles.issueName}>{this.getTransTitle(item)}</TextView>
+                        <TextView style={styles.issueDesc}>{$t('wallet.labelTransactionId') + item.creditRecordPk}</TextView>
+                      </View>
+                      { item.amountSymbol == 'M'
+                        ? <TextView style={styles.amountDuct}>- {item.amount}</TextView>
+                        : <TextView style={styles.amountText}>+ {item.amount}</TextView>
+                      }
                     </View>
-                    { item.amountSymbol == 'M'
-                      ? <TextView style={styles.amountDuct}>- {item.amount}</TextView>
-                      : <TextView style={styles.amountText}>+ {item.amount}</TextView>
-                    }
-                  </View>
-                </Pressable>
-              );
-            })
+                  </Pressable>
+                );
+              })
+            }
+            </>
           : <Text style={styles.noResult}>{$t('wallet.noHistoryData')}</Text>
         }
         </View>
+        { (app.v3.overview && this.state.historyList.length > 0) && 
+          <TouchableOpacity
+            style={styles.moreButton}
+            activeOpacity={0.4}
+            onPress={() => this.toHistoryList()}>
+            <Text
+              style={ui.link}>
+              {$t("wallet.viewMore")}
+            </Text>
+          </TouchableOpacity>
+        }
       </View>
     );
   }
@@ -187,5 +227,10 @@ const styles = StyleSheet.create({
   amountText: {
     color: textPrimary,
     fontSize: 14
+  },
+  moreButton: {
+    padding: 16,
+    alignItems: 'center',
+    marginBottom: 8
   }
 })

+ 215 - 0
Strides-APP/app/pages/wallet/HistoryList.js

@@ -0,0 +1,215 @@
+/**
+ * 交易历史页面
+ * @邠心vbe on 2024/03/29
+ */
+import React, { Component } from 'react';
+import { View, Text, RefreshControl, FlatList, StyleSheet, Pressable, Image, PixelRatio } from 'react-native';
+import { MyRefreshProps } from '../../components/ThemesConfig';
+import apiWallet from '../../api/apiWallet';
+import TextView from '../../components/TextView';
+import Dialog from '../../components/Dialog';
+import { PageList } from '../Router';
+
+const IconCharge = require('../../images/wallet/ic-type-charge.png');
+const IconPayment = require('../../images/wallet/ic-type-payment.png');
+
+export default class HistoryList extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      dataList: [],
+      hasMore: true,
+      refreshing: false
+    };
+  }
+
+  componentDidMount() {
+    Dialog.showProgressDialog();
+    this.getHistoryList();
+  }
+
+  onRefresh() {
+    this.setState({
+      refreshing: true
+    })
+    this.getHistoryList();
+  }
+
+  getNextPage() {
+    if (this.state.dataList.length > 0 && this.state.hasMore) {
+      console.log("[Wallet History]", "getNextPage");
+      const last = this.state.dataList[this.state.dataList.length-1]
+      this.getHistoryList(last.creditRecordPk);
+    }
+  }
+
+  getHistoryList(lastPk="") {
+    apiWallet.getTransactionListV2({latestPk: lastPk}).then(res => {
+      if (res.data) {
+        if (lastPk) {
+          if (res.data.length > 0) {
+            const list = this.state.dataList;
+            this.setState({
+              dataList: list.concat(res.data)
+            });
+          } else {
+            this.setState({
+              hasMore: false
+            })
+          }
+        } else {
+          this.setState({
+            dataList: res.data,
+            hasMore: true
+          });
+        }
+      }
+    }).catch(err => {
+      toastShort(err)
+    }).finally(() => {
+      this.setState({
+        refreshing: false
+      });
+      Dialog.dismissLoading();
+    });
+  }
+
+  toSummary(item) {
+    if (item.refPk) {
+      startPage(PageList.summary, { action: 'view', chargingPk: item.refPk });
+    }
+  }
+
+  getTransTitle(item) {
+    let title =  item.createTime;
+    if (item.remarks) {
+      title += ': ' + item.remarks;
+    } else if (item.amountSymbol == 'M') {
+      title += ': ' + (item.siteName || "Charging");
+    } else {
+      title += ': ' + $t('wallet.topUp');
+    }
+    return title;
+  }
+
+  listItem = ({item, index, separators}) => {
+    return (
+      <Pressable
+        android_ripple={ripple}
+        style={styles.itemView}
+        onPress={() => {
+          this.toSummary(item)
+        }}>
+        <Image
+          style={styles.iconType}
+          resizeMode="contain"
+          source={(item.amountSymbol == 'P' || item.remarks) ? IconPayment : IconCharge}/>
+        <View style={styles.itemContent}>
+          <View style={ui.flex1}>
+            <TextView style={styles.issueName}>{this.getTransTitle(item)}</TextView>
+            <TextView style={styles.issueDesc}>{$t('wallet.labelTransactionId') + item.creditRecordPk}</TextView>
+          </View>
+          { item.amountSymbol == 'M'
+            ? <TextView style={styles.amountDuct}>- {item.amount}</TextView>
+            : <TextView style={styles.amountText}>+ {item.amount}</TextView>
+          }
+        </View>
+      </Pressable>
+    )
+  }
+
+  divideView = (props) => {
+    return (<View style={styles.divide}></View>)
+  }
+
+  bottomView = () => {
+    if (!this.state.hasMore) {
+      return (<Text style={styles.noMore}>{$t('wallet.noMore')}</Text>)
+    } else {
+      return null
+    }
+  }
+
+  render() {
+    return (
+      <FlatList
+        style={styles.listView}
+        data={this.state.dataList}
+        renderItem={this.listItem}
+        ItemSeparatorComponent={this.divideView}
+        ListFooterComponent={this.bottomView}
+        keyExtractor={item => item.creditRecordPk}
+        onEndReached={() => this.getNextPage()}
+        onEndReachedThreshold={0.3}
+        refreshControl={
+          <RefreshControl
+            {...MyRefreshProps()}
+            refreshing={this.state.refreshing}
+            onRefresh={() => this.onRefresh()}
+          />
+        }
+        ListEmptyComponent={<Text style={styles.noData}>{$t('wallet.noHistoryData')}</Text>}
+      />
+    );
+  }
+}
+
+const styles = StyleSheet.create({
+  listView: {
+    flex: 1
+  },
+  itemView: {
+    paddingLeft: 16,
+    paddingRight: 16,
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  itemContent: {
+    flex: 1,
+    marginLeft: 16,
+    ...$padding(16, 4),
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  divide: {
+    marginLeft: 60,
+    marginRight: 16,
+    borderTopWidth: 1,
+    borderTopColor: '#eee',
+  },
+  iconType: {
+    width: 28,
+    height: 28
+  },
+  issueName: {
+    color: textPrimary,
+    fontSize: 12,
+    paddingBottom: 2
+  },
+  issueDesc: {
+    color: '#999',
+    fontSize: 11
+  },
+  amountDuct: {
+    color: '#FF2E00',
+    fontSize: 14,
+    paddingLeft: 8
+  },
+  amountText: {
+    color: textPrimary,
+    fontSize: 14,
+    paddingLeft: 8
+  },
+  noData: {
+    color: textPlacehoder,
+    fontSize: 14,
+    padding: 20,
+    textAlign: 'center'
+  },
+  noMore: {
+    color: textPlacehoder,
+    fontSize: 14,
+    padding: 16,
+    textAlign: 'center'
+  }
+})

+ 0 - 1
Strides-APP/app/pages/wallet/Wallet.js

@@ -176,7 +176,6 @@ export default class Wallet extends Component {
               refreshed={() => this.stopRefresh()}
               shown={this.state.tabIndex == 0}/>
           }
-          
           <History
             refresh={this.state.refreshing}
             refreshed={() => this.stopRefresh()}