ChargingPage.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /**
  2. * 新充电流程:充电主页
  3. * @邠心vbe on 2023/06/20
  4. */
  5. import React, { Component } from 'react';
  6. import { View } from 'react-native';
  7. import app from '../../../app.json';
  8. import apiCharge from '../../api/apiCharge';
  9. import apiWallet from '../../api/apiWallet';
  10. import Dialog from '../../components/Dialog';
  11. import { ErrorDialog } from '../chargeV2/InfoDialog';
  12. import { PaymentDefault, PAYTYPE } from '../payment/PaymentConfig';
  13. import { PageList } from '../Router';
  14. import StepAuth from './StepAuth';
  15. import StepCharging from './StepCharging';
  16. import StepStart from './StepStart';
  17. import StepStop from './StepStop';
  18. import PagerUtil from '../chargeV2/PagerUtil';
  19. import DialogPayPerUse from './DialogPayPerUse';
  20. import utils from '../../utils/utils';
  21. export default class ChargingPage extends Component {
  22. constructor(props) {
  23. super(props);
  24. this.state = {
  25. isStoping: false,
  26. isCharging: false,
  27. isAuthentic: false,
  28. stationInfo: {},
  29. connectorInfo: {},
  30. errorCode: 'A9',
  31. errorMessage: '',
  32. lastUpdated: '',
  33. showErrorDialog: false,
  34. showStationDialog: false,
  35. currentPerUse: "",
  36. currentPayment: PaymentDefault.DEFAULT.payType,
  37. currentPaytype: PaymentDefault.DEFAULT.payName,
  38. selectedVoucher: {},
  39. idleFeeConfig: "",
  40. showDialogPayPerUse: false
  41. };
  42. this.isPageShow = true;
  43. this.waitStartCharging = false;
  44. }
  45. componentDidMount() {
  46. this.init();
  47. this.isPageShow = true;
  48. //console.log("参数", this.props.route.params);
  49. if (this.props.route.params.connectorId && this.props.route.params.chargeBoxId) {
  50. this.setState({
  51. stationInfo: this.props.route.params
  52. }, () => {
  53. //测试进入
  54. //this.testInit();
  55. //正常进入
  56. this.getIdleFeeConfig();
  57. this.getConnectorInfo();
  58. })
  59. }
  60. this.props.navigation.addListener('focus', () => {
  61. //console.log("充电流程页面获取焦点" + this.isPageShow, this.state.currentPerUse);
  62. if (!this.isPageShow && this.state.currentPerUse == "Pending") {
  63. this.isPageShow = true;
  64. //console.log("继续充电流程");
  65. this.setState({
  66. currentPerUse: "Paid"
  67. })
  68. this.refreshChargeData();
  69. } else {
  70. this.isPageShow = true;
  71. //this.canShowLoginDialog();
  72. }
  73. if (PagerUtil.isSelectVoucher) {
  74. this.setState({
  75. selectedVoucher: PagerUtil.getSelectedVoucher()
  76. })
  77. }
  78. });
  79. this.props.navigation.addListener('blur', () => {
  80. this.isPageShow = false;
  81. //console.log("充电流程页面失去焦点");
  82. });
  83. }
  84. componentWillUnmount() {
  85. this.isPageShow = false;
  86. }
  87. testInit() {
  88. this.setState({
  89. isCharging: true,
  90. connectorInfo: {
  91. status: "Initiating"
  92. }
  93. }, () => {
  94. setTimeout(() => {
  95. this.getConnectorInfo();
  96. }, 2000);
  97. })
  98. }
  99. init() {
  100. this.setState({
  101. isStoping: false,
  102. isCharging: false,
  103. isAuthentic: false
  104. });
  105. this.waitAuthentic = false;
  106. this.waitStartCharging = false;
  107. }
  108. getConnectorInfo() {
  109. if (!this.isPageShow) return;
  110. //this.init();
  111. const params = {
  112. sitePk: this.state.stationInfo.id,
  113. chargeBoxId: this.state.stationInfo.chargeBoxId,
  114. connectorId: this.state.stationInfo.connectorId,
  115. paymentOption: this.state.currentPayment,
  116. }
  117. if (app.charge.paymentMethod && this.state.currentPayment?.code) {
  118. params.paymentMethod = this.state.currentPayment?.code
  119. }
  120. console.log("[ChargingPage]getConnectorInfo", params);
  121. apiCharge.getConnectorDetail(params).then(res => {
  122. if (res.data.status && !this.state.isStoping) {
  123. const state = {
  124. isStoping: false,
  125. isCharging: false,
  126. isAuthentic: false,
  127. connectorInfo: {}
  128. }
  129. state.connectorInfo = res.data;
  130. if (app.charge.paymentMethod && res.data.currentPaymentMethod) {
  131. //V3版获取当前支付方式
  132. state.currentPayment = {
  133. code: res.data.currentPaymentMethod
  134. }
  135. } else if (res.data.currentPaymentType && res.data.currentPaymentType == PAYTYPE.PAY_PER_USE) {
  136. //V2版获取当前支付方式
  137. state.currentPayment = PAYTYPE.PAY_PER_USE
  138. }
  139. if (res.data.vouchers && res.data.vouchers.length) {
  140. //获取已选择的优惠券
  141. state.selectedVoucher = res.data.vouchers[0];
  142. }
  143. console.log("状态", res.data.status);
  144. switch (res.data.status) {
  145. case 'Available': //可用的
  146. if (this.waitAuthentic) {
  147. state.isAuthentic = true;
  148. this.refreshChargeData(3000);
  149. } else {
  150. state.isAuthentic = false;
  151. }
  152. break;
  153. case 'Preparing': //已插入
  154. this.waitAuthentic = false;
  155. if (this.waitStartCharging) {
  156. state.isCharging = true;
  157. if (res.data.payPerUsePaymentStatus) {
  158. //等待PayPerUse支付-初始化充电
  159. if (res.data.payPerUsePaymentStatus == "PENDING" || res.data.payPerUsePaymentStatus == "PAID") {
  160. this.refreshChargeData(3000);
  161. } else {
  162. this.showErrorDialog('A4', $t('charging.errPayperusePayment') + res.data.payPerUsePaymentStatus);
  163. state.isCharging = false;
  164. state.isAuthentic = true;
  165. }
  166. } else {
  167. //普通充电-初始化充电
  168. this.refreshChargeData(3000);
  169. }
  170. } else {
  171. state.isAuthentic = true;
  172. //this.checkIsCharge();
  173. }
  174. break;
  175. case 'Charging': //正在充电
  176. state.isCharging = true;
  177. this.waitStartCharging = false;
  178. this.refreshChargeData(10000);
  179. break;
  180. case 'Initiating': //充电确认中
  181. state.isCharging = true;
  182. if (res.data.payPerUsePaymentStatus) {
  183. //等待PayPerUse支付-初始化充电
  184. if (res.data.payPerUsePaymentStatus == "PENDING" || res.data.payPerUsePaymentStatus == "PAID") {
  185. this.refreshChargeData();
  186. } else {
  187. this.showErrorDialog('A4', $t('charging.errPayperusePayment') + res.data.payPerUsePaymentStatus);
  188. state.isCharging = false;
  189. state.isAuthentic = false;
  190. }
  191. } else {
  192. //普通充电-初始化充电
  193. this.refreshChargeData();
  194. }
  195. break;
  196. case 'SuspendedEVSE':
  197. this.showErrorDialog('A5', $t('charging.errUnable2Charge'));
  198. break;
  199. case 'SuspendedEV': //已连接上但未充电
  200. state.isAuthentic = true;
  201. //this.refreshChargeData();
  202. break;
  203. case 'Reserved': //预定中
  204. this.showErrorDialog('A5', $t('charging.errUnable2Reserved'));
  205. break;
  206. case 'Finishing': //已完成
  207. if (res.data.chargingPk) {
  208. Dialog.showProgressDialog();
  209. setTimeout(() => {
  210. Dialog.dismissLoading();
  211. this.setState({
  212. isStart: false,
  213. isPending: false,
  214. isCharging: false
  215. });
  216. startPage(PageList.summary, {
  217. chargingPk: res.data.chargingPk,
  218. id: this.state.stationInfo.id,
  219. name: this.state.stationInfo.name,
  220. address: this.state.stationInfo.address
  221. });
  222. }, 2000);
  223. } else {
  224. goBack();
  225. }
  226. break;
  227. default:
  228. this.showErrorDialog('A4', $t('charging.errNotChargeE0'));
  229. break;
  230. }
  231. this.setState(state)
  232. }
  233. }).catch(err => {
  234. Dialog.showResultDialog("An error occurred:\n" + err, "Retry", () => {
  235. this.getConnectorInfo();
  236. })
  237. //toastShort(err)
  238. })
  239. }
  240. getIdleFeeConfig() {
  241. apiCharge.getIdleFeeConfig(this.state.stationInfo.chargeBoxId).then(res => {
  242. if (res.data && res.data.idleFee) {
  243. this.setState({
  244. idleFeeConfig: res.data
  245. })
  246. }
  247. }).catch(err => {
  248. this.setState({
  249. idleFeeConfig: ""
  250. })
  251. })
  252. }
  253. refreshChargeData(time=2000) {
  254. if (this.isPageShow) {
  255. //console.log("[刷新获取充电信息]", time);
  256. setTimeout(() => {
  257. this.getConnectorInfo();
  258. }, time);
  259. }
  260. }
  261. onPaymentMethodChanged(payment) {
  262. this.setState({
  263. currentPayment: payment
  264. })
  265. }
  266. onAuthenticate() {
  267. this.waitAuthentic = true;
  268. this.setState({
  269. isAuthentic: true
  270. }, () => {
  271. this.refreshChargeData()
  272. })
  273. }
  274. onStartCharge() {
  275. utils.logEventTracking("charging_start_click")
  276. if (app.charge.paymentMethod) { //V3版本开始充电
  277. if (utils.isNotEmpty(this.state.stationInfo.payPerUseAmount) && this.state.currentPayment?.code.indexOf(PAYTYPE.PAY_PER_USE_CONTAIN) >= 0) {
  278. this.setState({
  279. showDialogPayPerUse: true
  280. });
  281. } else {
  282. this.onStartChargeV3();
  283. }
  284. return;
  285. }
  286. if (this.state.currentPayment == PAYTYPE.PAY_PER_USE) { //V2版本PayPerUse
  287. if (utils.isNotEmpty(this.state.stationInfo.payPerUseAmount)) {
  288. this.setState({
  289. showDialogPayPerUse: true
  290. });
  291. } else {
  292. this.onStartChargePerUse();
  293. }
  294. return;
  295. }
  296. this.setState({
  297. isCharging: true
  298. });
  299. this.waitStartCharging = true;
  300. apiCharge.startCharge(this.state.stationInfo).then(res => {
  301. console.log("[开始充电-onStartCharge]", res);
  302. setTimeout(() => {
  303. this.canAutoRefresh = true;
  304. this.refreshChargeData(500);
  305. //Dialog.dismissLoading();
  306. if (res.msg) {
  307. //Dialog.showResultDialog(res.msg)
  308. toastShort(res.msg)
  309. }
  310. //this.autoCheckIsCharge();
  311. }, 3000);
  312. }).catch(({err, code, data}) => {
  313. //toastShort(err);
  314. console.log("[开始充电错误]", err, code);
  315. //Dialog.dismissLoading();
  316. if (code == 5200) {
  317. this.showErrorDialog('none', "(" + data.transactionPk + ') ' + err);
  318. } else {
  319. this.showErrorDialog('A4', err);
  320. }
  321. this.setState({
  322. isCharging: false
  323. });
  324. });
  325. }
  326. backDialogPayPerUse(confirm) {
  327. this.setState({
  328. showDialogPayPerUse: false
  329. });
  330. if (confirm) {
  331. if (app.charge.paymentMethod) { //V3版本开始充电
  332. this.onStartChargeV3();
  333. return;
  334. }
  335. if (this.state.currentPayment == PAYTYPE.PAY_PER_USE) { //V2版本PayPerUse
  336. this.onStartChargePerUse();
  337. return;
  338. }
  339. }
  340. }
  341. onStartChargePerUse() {
  342. this.setState({
  343. isCharging: true
  344. });
  345. this.waitStartCharging = true;
  346. const params = {
  347. paymentOption: this.state.currentPayment,
  348. ...this.state.stationInfo
  349. }
  350. apiWallet.doPaymentV2(params).then(res => {
  351. if (res.data.webPaymentUrl) {
  352. this.setState({
  353. currentPerUse: "Pending"
  354. })
  355. startPage(PageList.paymentWeb, { amount: params.payAmount, url: res.data.webPaymentUrl, type: 'PayPerUse' });
  356. } else {
  357. toastShort('Error 0')
  358. }
  359. }).catch(({err}) => {
  360. this.showErrorDialog('A9', err);
  361. this.setState({
  362. isCharging: false
  363. });
  364. });
  365. }
  366. onStartChargeV3() {
  367. this.setState({
  368. isCharging: true
  369. });
  370. this.waitStartCharging = true;
  371. const params = {
  372. sitePk: this.state.stationInfo.id,
  373. chargeBoxId: this.state.stationInfo.chargeBoxId,
  374. connectorId: this.state.stationInfo.connectorId
  375. }
  376. if (this.state.currentPayment?.code) {
  377. params.paymentMethod = this.state.currentPayment?.code
  378. }
  379. if (app.v3.vouchers && this.state.selectedVoucher?.userVoucherId) {
  380. params.userVoucherIds = [this.state.selectedVoucher.userVoucherId]
  381. }
  382. console.log("[开始充电V3-params]", params);
  383. apiCharge.startChargeV3(params).then(res => {
  384. console.log("[开始充电V3-response]", res);
  385. if (res.data.webPaymentUrl) {
  386. this.setState({
  387. currentPerUse: "Pending"
  388. })
  389. utils.logEventTracking("payment_initiate", res.data.webPaymentUrl)
  390. startPage(PageList.paymentWeb, { amount: params.sitePk, url: res.data.webPaymentUrl, type: 'PayPerUse' });
  391. } else {
  392. setTimeout(() => {
  393. this.canAutoRefresh = true;
  394. this.refreshChargeData(500);
  395. if (res.msg) {
  396. toastShort(res.msg)
  397. }
  398. }, 3000);
  399. }
  400. }).catch(({err, code, data}) => {
  401. //toastShort(err);
  402. console.log("[开始充电V3-错误]", err, code);
  403. //Dialog.dismissLoading();
  404. if (code == 5200) {
  405. this.showErrorDialog('none', "(" + data.transactionPk + ') ' + err);
  406. } else {
  407. this.showErrorDialog('A4', err);
  408. }
  409. this.setState({
  410. isCharging: false
  411. });
  412. });
  413. }
  414. onStopCharge() {
  415. Dialog.showDialog({
  416. title: $t('charging.titleStopCharging'),
  417. message: $t('charging.confirmStopCharging'),
  418. ok: $t('nav.confirm'),
  419. callback: ok => {
  420. if (ok == Dialog.BUTTON_OK) {
  421. this.stopCharge();
  422. }
  423. }
  424. });
  425. }
  426. stopCharge() {
  427. this.setState({
  428. isStoping: true
  429. })
  430. utils.logEventTracking("charging_stop_click")
  431. //Dialog.showProgressDialog();
  432. apiCharge.stopCharge().then(res => {
  433. if (res.data.chargingPk) {
  434. setTimeout(() => {
  435. //Dialog.dismissLoading();
  436. if (res.msg) {
  437. toastShort(res.msg)
  438. }
  439. this.setState({
  440. isCharging: false,
  441. isAuthentic: false,
  442. selectedVoucher: {}
  443. });
  444. PagerUtil.setSelectedVoucher({});
  445. //this.init();
  446. startPage(PageList.summary, {
  447. chargingPk: res.data.chargingPk,
  448. id: this.state.stationInfo.id,
  449. name: this.state.stationInfo.name,
  450. address: this.state.stationInfo.address
  451. });
  452. }, 3000);
  453. } else {
  454. if (res.msg) {
  455. toastShort(res.msg)
  456. } else {
  457. toastShort($t('charging.errDetected'));
  458. }
  459. this.refreshChargeData(500);
  460. }
  461. }).catch((err) => {
  462. //Dialog.dismissLoading();
  463. toastShort(err);
  464. this.setState({
  465. isStart: false,
  466. isPending: false,
  467. isCharging: false,
  468. isStoping: false
  469. });
  470. //模拟进入结算页
  471. /*startPage(PageList.summary, {
  472. chargingPk: 1,
  473. id: this.state.stationInfo.id,
  474. name: this.state.stationInfo.name,
  475. address: this.state.stationInfo.address
  476. });*/
  477. });
  478. }
  479. showErrorDialog(code, msg) {
  480. this.setState({
  481. errorCode: code,
  482. showErrorDialog: true,
  483. errorMessage: ''+msg
  484. });
  485. }
  486. closeError() {
  487. this.setState({
  488. showErrorDialog: false,
  489. showStationDialog: false
  490. });
  491. }
  492. render() {
  493. return (
  494. <View style={ui.flex1}>
  495. { this.state.isStoping
  496. ? <StepStop
  497. currentPayment={this.state.currentPayment}
  498. />
  499. : ( this.state.isCharging
  500. ? <StepCharging
  501. idleFeeConfig={this.state.idleFeeConfig}
  502. connectorInfo={this.state.connectorInfo}
  503. currentPayment={this.state.currentPayment}
  504. onStopCharge={() => this.onStopCharge()}
  505. selectedVoucher={this.state.selectedVoucher}
  506. />
  507. : ( this.state.isAuthentic
  508. ? <StepAuth
  509. status={this.state.connectorInfo?.status}
  510. connectorInfo={this.state.connectorInfo}
  511. currentPayment={this.state.currentPayment}
  512. onStartCharge={() => this.onStartCharge()}
  513. selectedVoucher={this.state.selectedVoucher}
  514. onPaymentMethodChanged={(type) => this.onPaymentMethodChanged(type)}
  515. />
  516. : <StepStart
  517. idleFeeConfig={this.state.idleFeeConfig}
  518. connectorInfo={this.state.connectorInfo}
  519. currentPayment={this.state.currentPayment}
  520. onAuthenticate={() => this.onAuthenticate()}
  521. selectedVoucher={this.state.selectedVoucher}
  522. onPaymentMethodChanged={(type) => this.onPaymentMethodChanged(type)}
  523. />
  524. )
  525. )
  526. }
  527. <ErrorDialog
  528. visible={this.state.showErrorDialog}
  529. code={this.state.errorCode}
  530. message={this.state.errorMessage}
  531. onClose={() => {
  532. this.closeError();
  533. }}/>
  534. <DialogPayPerUse
  535. visible={this.state.showDialogPayPerUse}
  536. amount={this.state.stationInfo.payPerUseAmount}
  537. onClose={confirm => this.backDialogPayPerUse(confirm)}/>
  538. </View>
  539. );
  540. }
  541. }