TabCharge.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /**
  2. * 新版充电页面
  3. * @邠心vbe on 2023/02/06
  4. */
  5. import React, { Component } from 'react';
  6. import { StyleSheet, ScrollView, RefreshControl } from 'react-native';
  7. import apiCharge from '../../api/apiCharge';
  8. import Dialog from '../../components/Dialog';
  9. import { PageList } from '../Router';
  10. import { EnterStationDialog } from './Charging';
  11. import { QRResult } from '../charge/QRScan';
  12. import { ErrorDialog } from './InfoDialog';
  13. import PagerUtil from './PagerUtil';
  14. import StepStartView from '../charging/StepStartView';
  15. import StepChargeView from '../charging/StepChargeView';
  16. import utils from '../../utils/utils';
  17. import app from '../../../app.json';
  18. import { PaymentDefault } from '../payment/PaymentConfig';
  19. import { MyRefreshProps } from '../../components/ThemesConfig';
  20. export default class TabCharge extends Component {
  21. constructor(props) {
  22. super(props);
  23. this.state = {
  24. available: false,
  25. isPrivate: false,
  26. refreshing: false,
  27. isStart: false,
  28. isPending: false,
  29. isCharging: false,
  30. isAuthentic: false,
  31. selectRate: '',
  32. connectorInfo: {},
  33. stationInfo: {},
  34. lastUpdated: '',
  35. errorCode: 'A9',
  36. errorMessage: '',
  37. showErrorDialog: false,
  38. showStationDialog: false,
  39. currentPerUser: undefined,
  40. canIntoCharging: false,
  41. //currentPayment: PAYTYPE.CREDIT_WALLET,
  42. //currentPaytype: "Credit Wallet",
  43. currentPayment: PaymentDefault.DEFAULT.payType,
  44. currentPaytype: PaymentDefault.DEFAULT.payName,
  45. selectedVoucher: {}
  46. };
  47. this.changeMethod = false;
  48. this.canAutoRefresh = false;
  49. this.inputStationId = '';
  50. this.autoIntoCharging = true;
  51. this.intoChargingStatus = ["Preparing", "Charging", "Initiating", "SuspendedEVSE", "SuspendedEV"]
  52. }
  53. componentDidMount() {
  54. this.canAutoRefresh = true;
  55. PagerUtil.addOnRefresh(this);
  56. //this.onRefresh();
  57. }
  58. onRefresh() {
  59. console.log("Charge刷新", this.props.route.name);
  60. const info = PagerUtil.getStationInfo();
  61. this.setState({
  62. refreshing: false,
  63. stationInfo: info
  64. }, () => {
  65. this.init();
  66. console.log("站点信息", this.state.stationInfo);
  67. //this.checkIsCharge();
  68. });
  69. }
  70. onPullRefresh() {
  71. this.setState({
  72. refreshing: true
  73. })
  74. PagerUtil.setBackRefreshing();
  75. }
  76. init() {
  77. console.log("Charge刷新", "init");
  78. if (PagerUtil.isSelectVoucher) {
  79. this.setState({
  80. selectedVoucher: PagerUtil.getSelectedVoucher()
  81. })
  82. }
  83. this.onMethodChanged();
  84. this.refreshAvailable();
  85. if (QRResult.haveResult()) {
  86. console.log("Charge刷新", "haveResult");
  87. const info = QRResult.getResult()
  88. console.log('QRResult', info);
  89. if (PagerUtil.ENABLE_NEW_UI) {
  90. //新充电流程
  91. this.setState({
  92. connectorInfo: info
  93. }, () => {
  94. this.checkChargeStatus(true);
  95. })
  96. } else {
  97. this.setState({
  98. isAuthentic: true,
  99. connectorInfo: info
  100. //soc: info.chargeType == 'AC' ? 0 : 'In Charging'
  101. }, () => {
  102. PagerUtil.onCharge(this.props);
  103. this.checkChargeStatus(true);
  104. });
  105. }
  106. //QRResult.clearResult();
  107. } else if (this.state.isStart) {
  108. console.log("Charge刷新", "isStart");
  109. this.checkIsCharge();
  110. } else {
  111. console.log("Charge刷新", "noStart");
  112. this.getConnectorInfo();
  113. //this.checkChargeStatus();
  114. }
  115. }
  116. componentWillUnmount() {
  117. this.canAutoRefresh = false;
  118. }
  119. //刷新可用充电接口
  120. refreshAvailable() {
  121. const info = this.state.stationInfo
  122. const all = info?.allConnector;
  123. if (info.siteType == 'Private') {
  124. this.setState({
  125. isPrivate: true
  126. })
  127. }
  128. if (all) {
  129. this.setState({
  130. available: !all.available > 0
  131. });
  132. }
  133. }
  134. /**
  135. * 激活自动进入新充电页面的开关
  136. */
  137. activeNewUIPage() {
  138. this.autoIntoCharging = true;
  139. }
  140. toChargingPage() {
  141. this.autoIntoCharging = false;
  142. utils.toChargingPage({
  143. id: this.state.stationInfo.id,
  144. name: this.state.stationInfo.name,
  145. address: this.state.stationInfo.address,
  146. chargeBoxId: this.state.connectorInfo.chargeBoxId,
  147. connectorId: this.state.connectorInfo.connectorId
  148. });
  149. }
  150. enterStatioinId() {
  151. if (QRResult.haveResult()) {
  152. if (PagerUtil.ENABLE_NEW_UI) {
  153. this.onRefresh();
  154. } else {
  155. const info = QRResult.getResult()
  156. console.log('EnterResult', info);
  157. this.setState({
  158. isAuthentic: true,
  159. connectorInfo: info
  160. //soc: info.chargeType == 'AC' ? 0 : 'In Charging'
  161. });
  162. this.checkChargeStatus();
  163. }
  164. }
  165. }
  166. onPaymentMethodChanged(payment) {
  167. this.setState({
  168. currentPayment: payment
  169. })
  170. }
  171. onMethodChange() {
  172. this.changeMethod = true;
  173. startPage(PageList.paymentMethod, {info: this.state.connectorInfo, type: this.state.currentPayment});
  174. }
  175. onMethodChanged() {
  176. if (this.changeMethod) {
  177. this.changeMethod = false;
  178. if (global.paymentOption?.title) {
  179. this.setState({
  180. //currentPerUser: global.paymentOption.amount,
  181. currentPayment: global.paymentOption.value,
  182. currentPaytype: global.paymentOption.title
  183. }, () => {
  184. global.paymentOption= {}
  185. })
  186. }
  187. }
  188. }
  189. //打开输入弹窗
  190. onEnterStation() {
  191. this.setState({
  192. showStationDialog: true
  193. })
  194. }
  195. //自动刷新
  196. autoCheckIsCharge() {
  197. if (this.canAutoRefresh) {
  198. this.checkIsCharge();
  199. }
  200. }
  201. //自动刷新状态
  202. autoCheckChargeStatus() {
  203. setTimeout(() => {
  204. if (this.canAutoRefresh) {
  205. this.checkChargeStatus();
  206. }
  207. }, 10000);
  208. }
  209. //扫码后获取连接器数据
  210. getConnectorInfo() {
  211. console.log("[TabCharge] getConnectorInfo", this.state.stationInfo.id);
  212. apiCharge.checkIsCharging({sitePk: this.state.stationInfo.id}).then(res => {
  213. this.setState({
  214. connectorInfo: res.data
  215. }, () => {
  216. this.checkChargeStatus();
  217. });
  218. }).catch((err) => {
  219. });
  220. }
  221. //获取充电进度数据(百分比)
  222. checkIsCharge(showError) {
  223. const params = {
  224. sitePk: this.state.stationInfo.id
  225. }
  226. apiCharge.checkIsCharging(params).then(res => {
  227. this.setState({
  228. isStart: true,
  229. isCharging: true,
  230. isAuthentic: true,
  231. connectorInfo: res.data,
  232. lastUpdated: utils.getNowHHmm()
  233. });
  234. if (this.canAutoRefresh) {
  235. setTimeout(() => {
  236. this.autoCheckIsCharge();
  237. }, 30000);
  238. }
  239. PagerUtil.onCharge(this.props);
  240. }).catch(({err, code}) => {
  241. //TODO 模拟测试
  242. //TODO 模拟测试-End
  243. this.setState({
  244. isStart: false,
  245. isCharging: false
  246. });
  247. setTimeout(() => {
  248. this.autoCheckIsCharge();
  249. this.canAutoRefresh = false;
  250. }, 30000);
  251. if (showError) {
  252. this.setState({
  253. errorCode: 'A4',
  254. showErrorDialog: true,
  255. errorMessage: 'Your vehicle doesn’t seem to be charging. Please check your vehicle.'
  256. });
  257. }
  258. });
  259. }
  260. //获取充电进度数据-end
  261. //获取充电桩对应接口的状态
  262. checkChargeStatus(haveResult=false) {
  263. //TODO 模拟测试
  264. /*this.setState({
  265. isStart: true,
  266. isCharging: true,
  267. isAuthentic: true
  268. });
  269. return;*/
  270. //TODO 模拟测试-End
  271. const params = {
  272. connectorId: this.state.connectorInfo.connectorId,
  273. chargeBoxId: this.state.connectorInfo.chargeBoxId,
  274. }
  275. if (!PagerUtil.ENABLE_NEW_UI) {
  276. if (!params.chargeBoxId || !params.connectorId) {
  277. this.checkIsCharge();
  278. return;
  279. }
  280. }
  281. apiCharge.getCurrentStatus(params).then(res => {
  282. if (res.data.status) {
  283. if (PagerUtil.ENABLE_NEW_UI && (this.intoChargingStatus.indexOf(res.data.status) >= 0 || haveResult)) {
  284. //进入新流程
  285. this.setState({
  286. canIntoCharging: true
  287. }, () => {
  288. if (this.autoIntoCharging) {
  289. this.toChargingPage();
  290. } else {
  291. PagerUtil.onCharge(this.props);
  292. }
  293. })
  294. } else {
  295. if (haveResult) {
  296. PagerUtil.onCharge(this.props);
  297. }
  298. switch (res.data.status) {
  299. case 'Available': //可用的
  300. this.state.connectorInfo.isCheckThrough = false;
  301. this.setState({
  302. isStart: false,
  303. isPending: false,
  304. isCharging: false,
  305. connectorInfo: this.state.connectorInfo
  306. });
  307. break;
  308. case 'Preparing': //已插入
  309. this.state.connectorInfo.isCheckThrough = true;
  310. this.setState({
  311. isStart: false,
  312. isPending: false,
  313. isCharging: false,
  314. available: true,
  315. connectorInfo: this.state.connectorInfo
  316. });
  317. //this.checkIsCharge();
  318. break;
  319. case 'Charging': //正在充电
  320. this.canAutoRefresh = true;
  321. this.state.connectorInfo.isCheckThrough = true;
  322. this.setState({
  323. isPending: false,
  324. connectorInfo: this.state.connectorInfo
  325. });
  326. this.checkIsCharge();
  327. break;
  328. case 'Initiating': //充电确认中
  329. this.canAutoRefresh = true;
  330. this.state.connectorInfo.isCheckThrough = true;
  331. this.setState({
  332. isStart: true,
  333. isPending: true,
  334. isCharging: true,
  335. isAuthentic: true,
  336. connectorInfo: this.state.connectorInfo
  337. });
  338. this.autoCheckChargeStatus();
  339. break;
  340. case 'SuspendedEVSE':
  341. this.setState({
  342. errorCode: 'A5',
  343. showErrorDialog: true,
  344. errorMessage: $t('charging.errUnable2Charge')
  345. });
  346. break;
  347. case 'SuspendedEV': //已连接上但未充电
  348. this.checkIsCharge(true);
  349. break;
  350. case 'Reserved': //预定中
  351. this.setState({
  352. errorCode: 'A5',
  353. showErrorDialog: true,
  354. errorMessage: $t('charging.errUnable2Reserved')
  355. });
  356. break;
  357. case 'Finishing': //已完成
  358. if (res.data.chargingPk) {
  359. Dialog.showProgressDialog();
  360. setTimeout(() => {
  361. Dialog.dismissLoading();
  362. this.setState({
  363. isStart: false,
  364. isPending: false,
  365. isCharging: false
  366. });
  367. startPage(PageList.summary, {
  368. chargingPk: res.data.chargingPk,
  369. id: this.state.stationInfo.id,
  370. name: this.state.stationInfo.name,
  371. address: this.state.stationInfo.address
  372. });
  373. }, 2000);
  374. } else {
  375. this.setState({
  376. isStart: true,
  377. isPending: false,
  378. isCharging: false
  379. });
  380. }
  381. break;
  382. default:
  383. this.setState({
  384. isStart: false,
  385. isPending: false,
  386. isCharging: false
  387. });
  388. this.setState({
  389. errorCode: 'A4',
  390. showErrorDialog: true,
  391. errorMessage: $t('charging.errNotChargeE0')
  392. });
  393. break;
  394. }
  395. }
  396. } else {
  397. this.setState({
  398. errorCode: 'A4',
  399. showErrorDialog: true,
  400. errorMessage: $t('charging.errNotChargeE0')
  401. });
  402. }
  403. }).catch((err) => {
  404. toastShort(err)
  405. this.setState({
  406. errorCode: 'A9',
  407. showErrorDialog: true,
  408. errorMessage: $t('charging.errAuthenticationError')
  409. });
  410. })
  411. }
  412. //获取充电桩对应接口的状态-end
  413. //开始充电-start
  414. startCharge() {
  415. if (this.state.connectorInfo.isCheckThrough) {
  416. Dialog.showProgressDialog();
  417. const params = {
  418. sitePk: this.state.stationInfo.id,
  419. chargeBoxId: this.state.connectorInfo.chargeBoxId,
  420. connectorId: this.state.connectorInfo.connectorId
  421. }
  422. if (app.charge.paymentMethod) { //V3版本开始充电
  423. this.onStartChargeV3(params);
  424. return;
  425. }
  426. apiCharge.startCharge(params).then(res => {
  427. console.log("开始充电返回", res);
  428. setTimeout(() => {
  429. this.setState({
  430. isStart: true,
  431. isPending: true,
  432. isCharging: true
  433. });
  434. this.canAutoRefresh = true;
  435. this.autoCheckChargeStatus();
  436. Dialog.dismissLoading();
  437. if (res.msg) {
  438. Dialog.showResultDialog(res.msg)
  439. }
  440. //this.autoCheckIsCharge();
  441. }, 3000);
  442. }).catch(({err, code, data}) => {
  443. //toastShort(err);
  444. console.log("开始充电错误", err, code);
  445. Dialog.dismissLoading();
  446. if (code == 5200) {
  447. this.setState({
  448. errorCode: 'none',
  449. showErrorDialog: true,
  450. errorMessage: "(" + data.transactionPk + ') ' + err
  451. });
  452. } else {
  453. this.setState({
  454. errorCode: 'A4',
  455. showErrorDialog: true,
  456. errorMessage: ''+err
  457. });
  458. }
  459. });
  460. } else {
  461. this.setState({
  462. errorCode: 'A1',
  463. showErrorDialog: true,
  464. errorMessage: $t('charging.errNotConnected')
  465. });
  466. }
  467. }
  468. onStartChargeV3(params) {
  469. if (this.state.currentPayment?.code) {
  470. params.paymentMethod = this.state.currentPayment?.code
  471. }
  472. if (app.v3.vouchers && this.state.selectedVoucher?.userVoucherId) {
  473. params.userVoucherIds = [this.state.selectedVoucher.userVoucherId]
  474. }
  475. console.log("[开始充电V3-params]", params);
  476. apiCharge.startChargeV3(params).then(res => {
  477. console.log("[开始充电V3-response]", res);
  478. if (res.data.webPaymentUrl) {
  479. this.setState({
  480. currentPerUse: "Pending"
  481. })
  482. startPage(PageList.paymentWeb, { amount: params.sitePk, url: res.data.webPaymentUrl, type: 'PayPerUse' });
  483. } else {
  484. setTimeout(() => {
  485. this.setState({
  486. isStart: true,
  487. isPending: true,
  488. isCharging: true
  489. });
  490. this.canAutoRefresh = true;
  491. this.autoCheckChargeStatus();
  492. Dialog.dismissLoading();
  493. if (res.msg) {
  494. Dialog.showResultDialog(res.msg)
  495. }
  496. //this.autoCheckIsCharge();
  497. }, 3000);
  498. }
  499. }).catch(({err, code, data}) => {
  500. //toastShort(err);
  501. console.log("[开始充电V3-错误]", err, code);
  502. Dialog.dismissLoading();
  503. if (code == 5200) {
  504. this.setState({
  505. errorCode: 'none',
  506. showErrorDialog: true,
  507. errorMessage: "(" + data.transactionPk + ') ' + err
  508. });
  509. } else {
  510. this.setState({
  511. errorCode: 'A4',
  512. showErrorDialog: true,
  513. errorMessage: ''+err
  514. });
  515. }
  516. });
  517. }
  518. //开始充电-end
  519. //停止充电-start
  520. onStopCharge() {
  521. if (this.state.isCharging) {
  522. Dialog.showDialog({
  523. title: $t('charging.titleStopCharging'),
  524. message: $t('charging.confirmStopCharging'),
  525. callback: ok => {
  526. if (ok == Dialog.BUTTON_OK) {
  527. this.stopCharge();
  528. }
  529. }
  530. });
  531. } else {
  532. this.stopCharge();
  533. }
  534. }
  535. stopCharge() {
  536. this.canAutoRefresh = false;
  537. Dialog.showProgressDialog();
  538. apiCharge.stopCharge().then(res => {
  539. if (res.msg) {
  540. toastShort(res.msg)
  541. }
  542. if (res.data.chargingPk) {
  543. setTimeout(() => {
  544. Dialog.dismissLoading();
  545. this.setState({
  546. isStart: false,
  547. isPending: false,
  548. isCharging: false,
  549. selectedVoucher: {}
  550. });
  551. PagerUtil.setSelectedVoucher({});
  552. startPage(PageList.summary, {
  553. chargingPk: res.data.chargingPk,
  554. id: this.state.stationInfo.id,
  555. name: this.state.stationInfo.name,
  556. address: this.state.stationInfo.address
  557. });
  558. }, 3000);
  559. } else {
  560. Dialog.dismissLoading();
  561. toastShort($t('charging.errDetected'));
  562. }
  563. }).catch((err) => {
  564. Dialog.dismissLoading();
  565. toastShort(err);
  566. this.setState({
  567. isStart: false,
  568. isPending: false,
  569. isCharging: false
  570. });
  571. //模拟进入结算页
  572. /*startPage(PageList.summary, {
  573. chargingPk: 1,
  574. id: this.state.stationInfo.id,
  575. name: this.state.stationInfo.name,
  576. address: this.state.stationInfo.address
  577. });*/
  578. });
  579. }
  580. //停止充电-end
  581. closeError() {
  582. this.setState({
  583. showErrorDialog: false,
  584. showStationDialog: false
  585. });
  586. }
  587. render() {
  588. return (
  589. <ScrollView
  590. style={styles.container}
  591. keyboardShouldPersistTaps={isIOS ? 'never' : 'handled'}
  592. contentContainerStyle={$padding(0, 16)}
  593. refreshControl={
  594. <RefreshControl
  595. {...MyRefreshProps()}
  596. refreshing={this.state.refreshing}
  597. onRefresh={() => this.onPullRefresh()}
  598. />
  599. }>
  600. { this.state.isAuthentic //是否扫码认证
  601. ? <StepChargeView
  602. isStart={this.state.isStart} //是否开始充电
  603. isPending={this.state.isPending}
  604. isCharging={this.state.isCharging}
  605. lastUpdated={this.state.lastUpdated}
  606. connectorInfo={this.state.connectorInfo}
  607. currentPayment={this.state.currentPayment}
  608. selectedVoucher={this.state.selectedVoucher}
  609. onStartCharge={() => this.startCharge()}
  610. onStopCharge={() => this.onStopCharge()}
  611. onPaymentMethodChanged={(type) => this.onPaymentMethodChanged(type)}/>
  612. : <StepStartView
  613. isPrivate={this.state.isPrivate}
  614. canIntoCharging={this.state.canIntoCharging}
  615. stationInfo={this.state.stationInfo}
  616. onEnterStation={() => this.onEnterStation()}
  617. onIntoCharging={() => this.toChargingPage()}
  618. />
  619. }
  620. <ErrorDialog
  621. visible={this.state.showErrorDialog}
  622. code={this.state.errorCode}
  623. message={this.state.errorMessage}
  624. onClose={() => {
  625. this.closeError();
  626. }}
  627. />
  628. <EnterStationDialog
  629. visible={this.state.showStationDialog}
  630. stationId={this.state.stationInfo.id}
  631. onConfirm={() => this.enterStatioinId()}
  632. onClose={() => this.closeError()}
  633. />
  634. </ScrollView>
  635. );
  636. }
  637. }
  638. const styles = StyleSheet.create({
  639. container: {
  640. flex: 1
  641. },
  642. title: {
  643. color: '#000',
  644. fontSize: 14,
  645. fontWeight: 'bold',
  646. paddingTop: 16,
  647. paddingBottom: 16
  648. }
  649. })