ChargingPage.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  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. if (app.charge.paymentMethod) { //V3版本开始充电
  276. if (utils.isNotEmpty(this.state.stationInfo.payPerUseAmount) && this.state.currentPayment?.code.indexOf(PAYTYPE.PAY_PER_USE_CONTAIN) >= 0) {
  277. this.setState({
  278. showDialogPayPerUse: true
  279. });
  280. } else {
  281. this.onStartChargeV3();
  282. }
  283. return;
  284. }
  285. if (this.state.currentPayment == PAYTYPE.PAY_PER_USE) { //V2版本PayPerUse
  286. if (utils.isNotEmpty(this.state.stationInfo.payPerUseAmount)) {
  287. this.setState({
  288. showDialogPayPerUse: true
  289. });
  290. } else {
  291. this.onStartChargePerUse();
  292. }
  293. return;
  294. }
  295. this.setState({
  296. isCharging: true
  297. });
  298. this.waitStartCharging = true;
  299. apiCharge.startCharge(this.state.stationInfo).then(res => {
  300. console.log("[开始充电-onStartCharge]", res);
  301. setTimeout(() => {
  302. this.canAutoRefresh = true;
  303. this.refreshChargeData(500);
  304. //Dialog.dismissLoading();
  305. if (res.msg) {
  306. //Dialog.showResultDialog(res.msg)
  307. toastShort(res.msg)
  308. }
  309. //this.autoCheckIsCharge();
  310. }, 3000);
  311. }).catch(({err, code, data}) => {
  312. //toastShort(err);
  313. console.log("[开始充电错误]", err, code);
  314. //Dialog.dismissLoading();
  315. if (code == 5200) {
  316. this.showErrorDialog('none', "(" + data.transactionPk + ') ' + err);
  317. } else {
  318. this.showErrorDialog('A4', err);
  319. }
  320. this.setState({
  321. isCharging: false
  322. });
  323. });
  324. }
  325. backDialogPayPerUse(confirm) {
  326. this.setState({
  327. showDialogPayPerUse: false
  328. });
  329. if (confirm) {
  330. if (app.charge.paymentMethod) { //V3版本开始充电
  331. this.onStartChargeV3();
  332. return;
  333. }
  334. if (this.state.currentPayment == PAYTYPE.PAY_PER_USE) { //V2版本PayPerUse
  335. this.onStartChargePerUse();
  336. return;
  337. }
  338. }
  339. }
  340. onStartChargePerUse() {
  341. this.setState({
  342. isCharging: true
  343. });
  344. this.waitStartCharging = true;
  345. const params = {
  346. paymentOption: this.state.currentPayment,
  347. ...this.state.stationInfo
  348. }
  349. apiWallet.doPaymentV2(params).then(res => {
  350. if (res.data.webPaymentUrl) {
  351. this.setState({
  352. currentPerUse: "Pending"
  353. })
  354. startPage(PageList.paymentWeb, { amount: params.payAmount, url: res.data.webPaymentUrl, type: 'PayPerUse' });
  355. } else {
  356. toastShort('Error 0')
  357. }
  358. }).catch(({err}) => {
  359. this.showErrorDialog('A9', err);
  360. this.setState({
  361. isCharging: false
  362. });
  363. });
  364. }
  365. onStartChargeV3() {
  366. this.setState({
  367. isCharging: true
  368. });
  369. this.waitStartCharging = true;
  370. const params = {
  371. sitePk: this.state.stationInfo.id,
  372. chargeBoxId: this.state.stationInfo.chargeBoxId,
  373. connectorId: this.state.stationInfo.connectorId
  374. }
  375. if (this.state.currentPayment?.code) {
  376. params.paymentMethod = this.state.currentPayment?.code
  377. }
  378. if (app.v3.vouchers && this.state.selectedVoucher?.userVoucherId) {
  379. params.userVoucherIds = [this.state.selectedVoucher.userVoucherId]
  380. }
  381. console.log("[开始充电V3-params]", params);
  382. apiCharge.startChargeV3(params).then(res => {
  383. console.log("[开始充电V3-response]", res);
  384. if (res.data.webPaymentUrl) {
  385. this.setState({
  386. currentPerUse: "Pending"
  387. })
  388. startPage(PageList.paymentWeb, { amount: params.sitePk, url: res.data.webPaymentUrl, type: 'PayPerUse' });
  389. } else {
  390. setTimeout(() => {
  391. this.canAutoRefresh = true;
  392. this.refreshChargeData(500);
  393. if (res.msg) {
  394. toastShort(res.msg)
  395. }
  396. }, 3000);
  397. }
  398. }).catch(({err, code, data}) => {
  399. //toastShort(err);
  400. console.log("[开始充电V3-错误]", err, code);
  401. //Dialog.dismissLoading();
  402. if (code == 5200) {
  403. this.showErrorDialog('none', "(" + data.transactionPk + ') ' + err);
  404. } else {
  405. this.showErrorDialog('A4', err);
  406. }
  407. this.setState({
  408. isCharging: false
  409. });
  410. });
  411. }
  412. onStopCharge() {
  413. Dialog.showDialog({
  414. title: $t('charging.titleStopCharging'),
  415. message: $t('charging.confirmStopCharging'),
  416. ok: $t('nav.confirm'),
  417. callback: ok => {
  418. if (ok == Dialog.BUTTON_OK) {
  419. this.stopCharge();
  420. }
  421. }
  422. });
  423. }
  424. stopCharge() {
  425. this.setState({
  426. isStoping: true
  427. })
  428. //Dialog.showProgressDialog();
  429. apiCharge.stopCharge().then(res => {
  430. if (res.data.chargingPk) {
  431. setTimeout(() => {
  432. //Dialog.dismissLoading();
  433. if (res.msg) {
  434. toastShort(res.msg)
  435. }
  436. this.setState({
  437. isCharging: false,
  438. isAuthentic: false,
  439. selectedVoucher: {}
  440. });
  441. PagerUtil.setSelectedVoucher({});
  442. //this.init();
  443. startPage(PageList.summary, {
  444. chargingPk: res.data.chargingPk,
  445. id: this.state.stationInfo.id,
  446. name: this.state.stationInfo.name,
  447. address: this.state.stationInfo.address
  448. });
  449. }, 3000);
  450. } else {
  451. if (res.msg) {
  452. toastShort(res.msg)
  453. } else {
  454. toastShort($t('charging.errDetected'));
  455. }
  456. this.refreshChargeData(500);
  457. }
  458. }).catch((err) => {
  459. //Dialog.dismissLoading();
  460. toastShort(err);
  461. this.setState({
  462. isStart: false,
  463. isPending: false,
  464. isCharging: false,
  465. isStoping: false
  466. });
  467. //模拟进入结算页
  468. /*startPage(PageList.summary, {
  469. chargingPk: 1,
  470. id: this.state.stationInfo.id,
  471. name: this.state.stationInfo.name,
  472. address: this.state.stationInfo.address
  473. });*/
  474. });
  475. }
  476. showErrorDialog(code, msg) {
  477. this.setState({
  478. errorCode: code,
  479. showErrorDialog: true,
  480. errorMessage: ''+msg
  481. });
  482. }
  483. closeError() {
  484. this.setState({
  485. showErrorDialog: false,
  486. showStationDialog: false
  487. });
  488. }
  489. render() {
  490. return (
  491. <View style={ui.flex1}>
  492. { this.state.isStoping
  493. ? <StepStop
  494. currentPayment={this.state.currentPayment}
  495. />
  496. : ( this.state.isCharging
  497. ? <StepCharging
  498. idleFeeConfig={this.state.idleFeeConfig}
  499. connectorInfo={this.state.connectorInfo}
  500. currentPayment={this.state.currentPayment}
  501. onStopCharge={() => this.onStopCharge()}
  502. selectedVoucher={this.state.selectedVoucher}
  503. />
  504. : ( this.state.isAuthentic
  505. ? <StepAuth
  506. status={this.state.connectorInfo?.status}
  507. connectorInfo={this.state.connectorInfo}
  508. currentPayment={this.state.currentPayment}
  509. onStartCharge={() => this.onStartCharge()}
  510. selectedVoucher={this.state.selectedVoucher}
  511. onPaymentMethodChanged={(type) => this.onPaymentMethodChanged(type)}
  512. />
  513. : <StepStart
  514. idleFeeConfig={this.state.idleFeeConfig}
  515. connectorInfo={this.state.connectorInfo}
  516. currentPayment={this.state.currentPayment}
  517. onAuthenticate={() => this.onAuthenticate()}
  518. selectedVoucher={this.state.selectedVoucher}
  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. <DialogPayPerUse
  532. visible={this.state.showDialogPayPerUse}
  533. amount={this.state.stationInfo.payPerUseAmount}
  534. onClose={confirm => this.backDialogPayPerUse(confirm)}/>
  535. </View>
  536. );
  537. }
  538. }