|
|
@@ -0,0 +1,196 @@
|
|
|
+/**
|
|
|
+ * 积分历史列表页面
|
|
|
+ * @邠心vbe on 2024/05/07
|
|
|
+ */
|
|
|
+import React, { Component } from 'react';
|
|
|
+import { View, Text, RefreshControl, FlatList, StyleSheet } from 'react-native';
|
|
|
+import { MyRefreshProps } from '../../components/ThemesConfig';
|
|
|
+import TextView from '../../components/TextView';
|
|
|
+import Dialog from '../../components/Dialog';
|
|
|
+import apiVoucher from '../../api/apiVoucher';
|
|
|
+import app from '../../../app.json';
|
|
|
+
|
|
|
+export default class PointsHistory 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("[Points History]", "getNextPage");
|
|
|
+ const last = this.state.dataList[this.state.dataList.length-1]
|
|
|
+ this.getHistoryList(last.pointsHistoryId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ getHistoryList(lastPk="") {
|
|
|
+ apiVoucher.getPointsHistory(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
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.setState({
|
|
|
+ dataList: []
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ toastShort(err)
|
|
|
+ }).finally(() => {
|
|
|
+ this.setState({
|
|
|
+ refreshing: false
|
|
|
+ });
|
|
|
+ Dialog.dismissLoading();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ listItem = ({item, index, separators}) => {
|
|
|
+ return (
|
|
|
+ <View style={styles.itemView}>
|
|
|
+ <View style={styles.itemContent}>
|
|
|
+ <View style={ui.flex1}>
|
|
|
+ <TextView style={styles.issueName}>{item.remarks}</TextView>
|
|
|
+ <TextView style={styles.issueDesc}>{item.dateTime}</TextView>
|
|
|
+ <TextView style={styles.issueDesc}>{(item.siteName ?? item.voucherName) + (item.chargeBoxId ? ", " + item.chargeBoxId : "")}</TextView>
|
|
|
+ <TextView style={styles.issueDesc}>{"Transaction ID: " + item.refId}</TextView>
|
|
|
+ </View>
|
|
|
+ { item.action == "Increase"
|
|
|
+ ? <TextView style={styles.amountText}>+ {item.points}</TextView>
|
|
|
+ : <TextView style={styles.amountDuct}>- {item.points}</TextView>
|
|
|
+ }
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ 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.pointsHistoryId}
|
|
|
+ onEndReached={() => this.getNextPage()}
|
|
|
+ onEndReachedThreshold={0.3}
|
|
|
+ refreshControl={
|
|
|
+ <RefreshControl
|
|
|
+ {...MyRefreshProps()}
|
|
|
+ refreshing={this.state.refreshing}
|
|
|
+ onRefresh={() => this.onRefresh()}
|
|
|
+ />
|
|
|
+ }
|
|
|
+ ListEmptyComponent={<Text style={styles.noData}>{$t('points.noData')}</Text>}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const styles = StyleSheet.create({
|
|
|
+ listView: {
|
|
|
+ flex: 1
|
|
|
+ },
|
|
|
+ itemView: {
|
|
|
+ paddingLeft: 16,
|
|
|
+ paddingRight: 16,
|
|
|
+ alignItems: 'center',
|
|
|
+ flexDirection: 'row'
|
|
|
+ },
|
|
|
+ itemContent: {
|
|
|
+ flex: 1,
|
|
|
+ //marginLeft: 8,
|
|
|
+ ...$padding(16, 4),
|
|
|
+ alignItems: 'flex-start',
|
|
|
+ flexDirection: 'row'
|
|
|
+ },
|
|
|
+ divide: {
|
|
|
+ marginLeft: 16,
|
|
|
+ marginRight: 16,
|
|
|
+ borderTopWidth: 1,
|
|
|
+ borderTopColor: '#eee',
|
|
|
+ },
|
|
|
+ iconType: {
|
|
|
+ width: 28,
|
|
|
+ height: 28,
|
|
|
+ textAlign: 'center',
|
|
|
+ lineHeight: 27,
|
|
|
+ borderWidth: 1,
|
|
|
+ borderRadius: 30,
|
|
|
+ borderColor: textPrimary
|
|
|
+ },
|
|
|
+ issueName: {
|
|
|
+ color: textPrimary,
|
|
|
+ fontSize: 14,
|
|
|
+ paddingBottom: 2
|
|
|
+ },
|
|
|
+ issueDesc: {
|
|
|
+ color: textSecondary,
|
|
|
+ fontSize: 12
|
|
|
+ },
|
|
|
+ amountDuct: {
|
|
|
+ color: '#FF2E00',
|
|
|
+ fontSize: 14,
|
|
|
+ paddingLeft: 8
|
|
|
+ },
|
|
|
+ amountText: {
|
|
|
+ color: colorPrimary,
|
|
|
+ fontSize: 14,
|
|
|
+ paddingLeft: 8
|
|
|
+ },
|
|
|
+ noData: {
|
|
|
+ color: textPlacehoder,
|
|
|
+ fontSize: 12,
|
|
|
+ padding: 20,
|
|
|
+ textAlign: 'center'
|
|
|
+ },
|
|
|
+ noMore: {
|
|
|
+ color: textPlacehoder,
|
|
|
+ fontSize: 12,
|
|
|
+ padding: 16,
|
|
|
+ textAlign: 'center'
|
|
|
+ }
|
|
|
+})
|