| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- /**
- * 新版充电预定页面
- * @邠心vbe on 2023/02/06
- */
- import React, { Component } from 'react'
- import { Image, RefreshControl, ScrollView, StyleSheet, Text, View } from 'react-native'
- import Button from '../../components/Button';
- import { ChargeStyle, EnterStationDialog, TypeImage } from './Charging';
- import apiCharge from '../../api/apiCharge';
- import Dialog from '../../components/Dialog';
- import { PageList } from '../Router';
- import { CancelReserveDialog } from './InfoDialog';
- import PagerUtil from './PagerUtil';
- import BadgeSelectItem from '../../components/BadgeSelectItem';
- import TextView from '../../components/TextView';
- import { MyRefreshProps } from '../../components/ThemesConfig';
- import QRResult from '../charge/QRResult';
- import { PagerList } from './ChargeAdapter';
- export default class TabReserve extends Component {
- constructor(props) {
- super(props);
- this.state = {
- total: 0,
- leftId: 0,
- refreshing: false,
- checkIndex: -1,
- available: false,
- showReserve: false,
- stationInfo: {},
- checkConnector: {},
- userReserve: {},
- timeLeft: '',
- showCancelDialog: false,
- showStationDialog: false
- };
- }
- componentDidMount() {
- PagerUtil.addOnRefresh(this);
- this.onRefresh();
- }
- onRefresh() {
- console.log("Reserve刷新", this.props.route.name);
- this.setState({
- refreshing: false,
- stationInfo: PagerUtil.getStationInfo()
- }, () => this.init());
- }
- onPullRefresh() {
- this.setState({
- refreshing: true
- })
- PagerUtil.setBackRefreshing();
- }
- init() {
- this.stopCountdown(true);
- if (this.state.stationInfo.rateList && this.state.stationInfo.rateList.length > 0) {
- for (var i = 0; i < this.state.stationInfo.rateList.length; i++) {
- const item = this.state.stationInfo.rateList[i]
- if (item.available) {
- this.setState({
- checkIndex: i,
- checkConnector: item,
- })
- break;
- }
- }
- this.setState({
- total: this.state.stationInfo.rateList.length,
- showReserve: this.state.stationInfo.enableReservation ? true : false
- })
- this.getReserve();
- //this.refreshAvailable();
- } else {
- this.setState({
- showReserve: false
- })
- }
- }
- //刷新可用充电接口
- refreshAvailable() {
- const info = this.state.stationInfo
- const all = info?.allConnector;
- /*if (info.siteType == 'Private') {
- this.setState({
- isPrivate: true
- })
- }*/
- if (all) {
- this.setState({
- available: !all.available > 0
- });
- }
- }
- checkChange(index) {
- if (this.state.checkIndex !== index) {
- this.setState({
- checkIndex: index,
- checkConnector: this.state.stationInfo.rateList[index],
- })
- }
- }
- getAvailable(type) {
- let count = type;
- if (typeof type === 'string') {
- count = type == "AC" ? this.state.stationInfo.acConnector : this.state.stationInfo.dcConnector;
- }
- if (count) {
- return count.available + '/' + count.all;
- } else {
- return '0/0';
- }
- }
- getReserve() {
- apiCharge.getUserReserve(this.state.stationInfo.id).then(res => {
- if (res.data.reservePk && res.data.reserveEndTimeTimestamp > 0) {
- this.setState({
- userReserve: res.data
- }, () => this.startCountdown());
- } else {
- this.stopCountdown();
- }
- }).catch((err) => {
- this.stopCountdown();
- });
- }
- onReserve() {
- if (this.state.checkConnector?.chargeTypePk) {
- Dialog.showProgressDialog();
- apiCharge.reserveCharge({
- sitePk: this.state.stationInfo.id,
- chargeTypePk: this.state.checkConnector.chargeTypePk
- }).then(res => {
- Dialog.dismissLoading();
- toastShort($t('charging.reservedSuccess'));
- PagerUtil.setBackRefreshing();
- this.getReserve();
- }).catch((err) => {
- Dialog.dismissLoading();
- toastShort(err)
- });
- } else {
- toastShort($t('charging.plsSelectConnnector'))
- }
- }
- onCancel() {
- if (this.state.userReserve.reservePk) {
- Dialog.showProgressDialog();
- apiCharge.cancelReserve(this.state.userReserve.reservePk).then(res => {
- Dialog.dismissLoading();
- PagerUtil.setBackRefreshing();
- toastShort($t('common.cancelSuccess'));
- this.getReserve();
- }).catch((err) => {
- Dialog.dismissLoading();
- toastShort(err)
- });
- }
- }
- cancelReserve() {
- // this.setState({
- // showCancelDialog: true
- // });
- Dialog.showDialog({
- title: $t('charging.cancelReservation'),
- message: $t('charging.confirmCancelReservation'),
- ok: $t('nav.yes'),
- cancel: $t('nav.no'),
- callback: (btn => {
- if (btn == "ok") {
- this.onCancel();
- }
- })
- })
- }
- startCountdown() {
- if (this.state.userReserve.reserveEndTimeTimestamp > 0) {
- if (!QRResult.haveResult()) {
- PagerUtil.onReserve(this.props);
- }
- const leftId = this.state.leftId;
- this.countdown(leftId);
- } else {
- this.stopCountdown(false, true);
- }
- }
- countdown(leftId) {
- if (leftId != this.state.leftId) {
- console.log(leftId, this.state.leftId);
- return;
- }
- const now = new Date().getTime();
- let left = this.state.userReserve.reserveEndTimeTimestamp - now;
- let s = 0, m = 0, h = 0;
- if (left > 1000) {
- s = left / 1000;
- if (s > 60) {
- m = s / 60;
- s = s % 60;
- if (m > 60) {
- h = m / 60;
- m = m % 60;
- }
- }
- } else {
- this.stopCountdown(false, true)
- }
- this.setState({
- timeLeft: this.formatNumber(h) + ' : ' + this.formatNumber(m) + ' : ' + this.formatNumber(s)
- });
- setTimeout(() => {
- this.countdown(leftId);
- }, 1000);
- }
- formatNumber(ins) {
- const num = parseInt(ins)
- if (num > 0) {
- if (num < 10) {
- return '0' + num;
- } else {
- return num;
- }
- } else {
- return '00';
- }
- }
- stopCountdown(just, refresh) {
- if (just) {
- this.setState({
- leftId: this.state.leftId + 1
- });
- } else {
- this.setState({
- leftId: this.state.leftId + 1,
- userReserve: {}
- });
- }
- if (refresh) {
- PagerUtil.setBackRefreshing();
- }
- }
- enterStatioinId() {
- PagerUtil.onEnterStation(this.props);
- setTimeout(() => {
- PagerUtil.setRefreshing(PagerList.tabCharge)
- }, 300);
- }
- render() {
- return (
- <ScrollView
- style={ui.flex1}
- keyboardShouldPersistTaps={isIOS ? 'never' : 'handled'}
- contentContainerStyle={$padding(0, 16)}
- refreshControl={
- <RefreshControl
- {...MyRefreshProps()}
- refreshing={this.state.refreshing}
- onRefresh={() => this.onPullRefresh()}
- />
- }>
- { this.state.showReserve
- ? (
- this.state.userReserve.reservePk
- ? this.countdownView()
- : this.reserveView()
- )
- : <View style={[{height: $vh(50)}, ui.flexvc]}>
- <TextView style={{color: textPrimary, fontSize: 14}}>{$t('charging.unallowReservation')}</TextView>
- </View>
- }
- <CancelReserveDialog
- visible={this.state.showCancelDialog}
- onClose={confirm => {
- this.setState({
- showCancelDialog: false
- });
- if (confirm) {
- this.onCancel();
- }
- }}/>
- <EnterStationDialog
- visible={this.state.showStationDialog}
- stationId={this.state.stationInfo.id}
- onConfirm={() => this.enterStatioinId()}
- onClose={() => {
- this.setState({
- showStationDialog: false
- });
- }}
- />
- </ScrollView>
- );
- }
- //预定页面
- reserveView() {
- return (
- <>
- <View style={{minHeight: $vht(75)}}>
- <TextView style={styles.title}>{$t('charging.chooseConnector')}</TextView>
- { this.state.total > 0
- ? this.state.stationInfo.rateList.map((item, index) => {
- const _type = item.type?.indexOf('AC') >= 0 ? 'AC' : 'DC';
- return (
- <BadgeSelectItem
- key={index}
- style={ChargeStyle.stationInfoView}
- onPress={() => {
- if (item.available) {
- this.checkChange(index)
- }
- }
- }
- checked={index == this.state.checkIndex}>
- {/* <SelectableIcon selected={index == this.state.checkIndex}>
-
- </SelectableIcon> */}
- <Image
- style={ChargeStyle.infoIcon}
- source={_type == "AC" ? TypeImage.AC : TypeImage.DC}/>
- <View style={ChargeStyle.infoGroup}>
- <TextView style={ChargeStyle.infoText}>{item.type}</TextView>
- <TextView style={ChargeStyle.infoTitle}>{$t('charging.labelType')}</TextView>
- </View>
- <View style={ChargeStyle.infoGroup}>
- <TextView style={ChargeStyle.infoText}>{item.power}</TextView>
- <TextView style={ChargeStyle.infoTitle}>{$t('charging.labelPower')}</TextView>
- </View>
- <View style={ChargeStyle.infoGroup}>
- <TextView style={ChargeStyle.infoText}>{this.getAvailable(_type)}</TextView>
- <TextView style={ChargeStyle.infoTitle}>{$t('charging.labelAvailableTotal')}</TextView>
- </View>
- <View style={ChargeStyle.infoGroup}>
- { item?.connectorCount?.available > 0
- ? <TextView style={[ChargeStyle.infoStatus, ChargeStyle.statusAvailable]}>{$t('charging.statusAvailable')}</TextView>
- : <TextView style={[ChargeStyle.infoStatus, ChargeStyle.statusUnavailable]}>{$t('charging.statusUnavailable')}</TextView>
- }
- <TextView style={ChargeStyle.infoTitle}>{$t('charging.labelStatus')}</TextView>
- </View>
- {/* index == this.state.checkIndex
- ? <Text style={[ChargeStyle.infoStatus, ChargeStyle.statusSelected]}>Selected</Text>
- : (item.available
- ? <TextView style={[ChargeStyle.infoStatus, ChargeStyle.statusAvailable]}>Available</TextView>
- : <TextView style={[ChargeStyle.infoStatus, ChargeStyle.statusUnavailable]}>Unavailable</TextView>
- )
- */}
- </BadgeSelectItem>
- )
- }) : null
- }
- { this.state.checkConnector.available
- ? <>
- <TextView style={styles.title}>{$t('charging.chooseRate')}</TextView>
- <BadgeSelectItem
- style={ChargeStyle.stationInfoView}
- checked={true}>
- <Image
- style={ChargeStyle.infoIcon}
- source={require('../../images/charge/ic-type-rate.png')}/>
- <TextView style={ChargeStyle.rateText}>{$t('charging.labelRate')}</TextView>
- <TextView style={[ChargeStyle.ratePrice]}>{this.state.checkConnector.rates}</TextView>
- <Text></Text>
- {/* <Text style={[ChargeStyle.infoStatus, ChargeStyle.statusSelected]}>Selected</Text> */}
- </BadgeSelectItem>
- </>
- : <View style={{height: 60}}></View>
- }
- {/* <Text style={styles.title}>Choose Payment Method</Text>
- <Payment refreshId={this.state.refreshId}/> */}
- </View>
- <Button
- style={styles.buttonView}
- elevation={1.5}
- text={$t('charging.btnReserve')}
- disabled={this.state.available}
- onClick={() => this.onReserve()}
- />
- </>
- )
- }
- //倒计时页面
- countdownView() {
- let info = this.state.userReserve.siteRate
- return (
- <>
- <View style={{minHeight: $vht(80)}}>
- <TextView style={styles.title}>Your Selection</TextView>
- { info &&
- <View>
- <BadgeSelectItem
- style={ChargeStyle.stationInfoView}
- checked={true}>
- <Image
- style={ChargeStyle.infoIcon}
- source={info.type?.indexOf('AC') >= 0 ? TypeImage.AC : TypeImage.DC}/>
- <View style={ChargeStyle.infoGroup}>
- <TextView style={ChargeStyle.infoText}>{info.type}</TextView>
- <TextView style={ChargeStyle.infoTitle}>{$t('charging.labelType')}</TextView>
- </View>
- <View style={ChargeStyle.infoGroup}>
- <TextView style={ChargeStyle.infoText}>{info.power}</TextView>
- <TextView style={ChargeStyle.infoTitle}>{$t('charging.labelPower')}</TextView>
- </View>
- <View style={ChargeStyle.infoGroup}>
- <TextView style={ChargeStyle.infoBoldNumber}>{this.getAvailable(info.connectorCount)}</TextView>
- <TextView style={ChargeStyle.infoTitle}>{$t('charging.labelAvailableTotal')}</TextView>
- </View>
- <Text></Text>
- {/* <SelectableIcon selected={true}/> */}
- </BadgeSelectItem>
- <BadgeSelectItem
- checked={true}
- style={ChargeStyle.stationInfoView}>
- <Image
- style={ChargeStyle.infoIcon}
- source={require('../../images/charge/ic-type-rate.png')}/>
- <TextView style={ChargeStyle.rateText}>{$t('charging.labelRate')}</TextView>
- <TextView style={[ChargeStyle.ratePrice]}>{info.rates}</TextView>
- <Text></Text>
- {/* <SelectableIcon selected={true}/> */}
- </BadgeSelectItem>
- </View>
- }
- <TextView style={styles.timeleftText}>{$t('charging.reserveTimeLeft')}</TextView>
- <View style={styles.timeleftView}>
- <TextView style={styles.timeleft}>{this.state.timeLeft}</TextView>
- </View>
- <View style={styles.cancelView}>
- <Button
- text={$t('charging.btnCancelReservation')}
- textColor={textButton}
- style={styles.cancelButton}
- viewStyle={styles.cancelButtonView}
- onClick={() => this.cancelReserve()}
- />
- </View>
- {/* <Text style={styles.title}>Choose Payment Method</Text>
- <Payment refreshId={this.state.refreshId}/> */}
- </View>
- <View style={styles.buttonGroup}>
- <Button
- style={styles.buttonLeft}
- text={$t('charging.scanQR')}
- disabled={this.state.available}
- onClick={() => {
- PagerUtil.onInnerScanQR();
- startPage(PageList.scanqr, {actionDetail: false, id: this.state.stationInfo.id});
- }}/>
- <Button
- style={styles.buttonRight}
- text={$t('charging.enterStationId')}
- disabled={this.state.available}
- onClick={() => {
- this.setState({
- showStationDialog: true
- });
- //startPage(PageList.summary)
- }
- }/>
- </View>
- </>
- )
- }
- }
- const styles = StyleSheet.create({
- title: {
- color: '#000',
- fontSize: 15,
- fontWeight: 'bold',
- paddingTop: 16,
- paddingBottom: 16
- },
- listView: {
- padding: 8,
- borderRadius: 8,
- backgroundColor: '#F5F5F5'
- },
- buttonView: {
- marginTop: 32,
- marginBottom: 16
- },
- timeleftText: {
- color: '#000',
- fontSize: 16,
- fontWeight: 'bold',
- paddingTop: 16,
- paddingBottom: 8,
- textAlign: 'center'
- },
- timeleftView: {
- alignItems: 'center',
- justifyContent: 'center',
- marginBottom: 16
- },
- timeleft: {
- color: '#FF2E00',
- fontSize: 18,
- fontWeight: 'bold'
- },
- cancelView: {
- paddingTop: 8,
- paddingBottom: 8
- },
- cancelButton: {
- borderRadius: 10,
- backgroundColor: '#ED4A4A'
- },
- cancelButtonView: {
- flex: 1,
- height: 48,
- paddingLeft: 16,
- paddingRight: 16,
- alignItems: 'center',
- flexDirection: 'row'
- },
- buttonGroup: {
- marginTop: 16,
- marginBottom: 24,
- alignItems: 'center',
- flexDirection: 'row'
- },
- buttonLeft: {
- flex: 1,
- elevation: 1.5,
- },
- buttonRight: {
- flex: 1,
- marginLeft: 16,
- elevation: 1.5
- },
- })
|