ChargingPage.js 17 KB

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