index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <template>
  2. <view class="container fixed">
  3. <view class="toolbar" v-if="chargeInfo">
  4. <view class="tool-title">Charge</view>
  5. <view class="tool-desc" v-if="chargeInfo.chargeBoxId">{{chargeInfo.chargeBoxId + "-" + chargeInfo.connectorId}}</view>
  6. <view class="tool-desc" v-else>-</view>
  7. </view>
  8. <header-view
  9. title="Insert Charging Cable"
  10. :status="connectorInfo.status"
  11. :isLoading="isLoading"/>
  12. <info-view
  13. :info="connectorInfo"
  14. :isLoading="isLoading"/>
  15. <payment-view
  16. v-if="connectorInfo.status == 'Preparing'"
  17. :status="connectorInfo.paymentStatus"/>
  18. <divide size="36"/>
  19. <view class="bottom-button">
  20. <button
  21. v-if="connectorInfo.status == 'Initiating'"
  22. class="ui-button margin0"
  23. type="primary"
  24. @click="onStart"
  25. :disabled="!connectorInfo.shouldClickStart">START CHARGING</button>
  26. <button
  27. v-else-if="connectorInfo.status == 'Charging'"
  28. class="ui-button margin0"
  29. type="primary"
  30. @click="stopCharge">INPUT PIN TO STOP CHARGING</button>
  31. <button
  32. v-else-if="connectorInfo.status == 'Finishing'"
  33. class="ui-button margin0"
  34. type="primary"
  35. disabled>STOP CHARGING</button>
  36. <template v-else-if="connectorInfo.status == 'Preparing'">
  37. <button
  38. class="ui-button margin0"
  39. type="primary"
  40. @click="onStart"
  41. v-if="connectorInfo.paymentStatus == 'PAID'">START CHARGING</button>
  42. <button
  43. class="ui-button margin0"
  44. type="primary"
  45. @click="onPayment"
  46. v-else>
  47. <view class="flexcc">
  48. <text>MAKE PAYMENT</text>
  49. <view class="icon-key" v-if="password.length == 0">
  50. <i-icon name="key-fill" size="32rpx" color="#333"/>
  51. </view>
  52. </view>
  53. </button>
  54. </template>
  55. <button
  56. v-else-if="connectorInfo.status == 'Available' && isLoading"
  57. class="ui-button margin0"
  58. type="cancel"
  59. @click="cancelAuth">CANCEL</button>
  60. <button
  61. v-else
  62. class="ui-button margin0"
  63. type="primary"
  64. @click="onAuthentic"
  65. :disabled="connectorInfo.status != 'Available' || isLoading">
  66. <view class="flexcc">
  67. <text>AUTHENTICATE</text>
  68. <view class="icon-key" v-if="password.length == 0">
  69. <i-icon name="key-fill" size="32rpx" color="#333"/>
  70. </view>
  71. </view>
  72. </button>
  73. </view>
  74. <PasswordView
  75. :visible="showPin || stopPin"
  76. :verify="stopPin"
  77. @change="changePassword"/>
  78. </view>
  79. </template>
  80. <script>
  81. import HeaderView from './views/HeaderView.vue';
  82. import InfoView from './views/InfoView.vue';
  83. import PaymentView from './views/PaymentView.vue';
  84. import PasswordView from '@/components/PasswordView.vue';
  85. import apiCharge from '@/api/apiCharge';
  86. import {openUrl} from '@/utils/utils.js';
  87. import settings from '../../settings';
  88. import auth from '../../utils/auth';
  89. export default {
  90. data() {
  91. return {
  92. refreshId: 0,
  93. isLoading: false,
  94. waitPayment: false,
  95. isPaymentFailed: false,
  96. chargeInfo: {
  97. chargeBoxId: "",
  98. connectorId: ""
  99. },
  100. connectorInfo: {},
  101. stoped: false,
  102. creditHistoryPk: "",
  103. chargingPk: "",
  104. paymentId:"",
  105. showPin: false,
  106. stopPin: false,
  107. password: ""
  108. }
  109. },
  110. components: {
  111. HeaderView,
  112. InfoView,
  113. PaymentView,
  114. PasswordView
  115. },
  116. onLoad(query) {
  117. if (query.pk) {
  118. this.paymentId = query.pk;
  119. }
  120. if (query.info) {
  121. this.chargeInfo = JSON.parse(decodeURIComponent(query.info));
  122. } /*else {
  123. this.waitPayment = getApp().globalData.waitPayment;
  124. let id = auth.getPaymentId();
  125. if (id) {
  126. this.paymentId = id;
  127. }
  128. }*/
  129. if (!query.pk && !query.info) {
  130. uni.reLaunch({
  131. url: "/pages/index/index"
  132. });
  133. return;
  134. }
  135. this.refreshStatus(500);
  136. },
  137. methods: {
  138. refreshStatus(time=2000) {
  139. this.refreshId += 1;
  140. setTimeout(() => {
  141. if (this.stoped) {
  142. return;
  143. }
  144. if (this.paymentId) {
  145. this.getChargingStatus(this.refreshId);
  146. } else if (this.chargeInfo.connectorId) {
  147. this.getChargerInfo(this.refreshId)
  148. }
  149. }, time);
  150. },
  151. getChargerInfo(id) {
  152. if (id !== this.refreshId) {
  153. return;
  154. }
  155. apiCharge.getChargerDetails(this.chargeInfo).then(res => {
  156. if (res.data) {
  157. this.connectorInfo = res.data;
  158. this.showPageWithStatus()
  159. }
  160. }).catch(err => {
  161. uni.showModal({
  162. title: "Error",
  163. content: err,
  164. confirmText: "OK",
  165. showCancel: false,
  166. success: res => {
  167. if (res.confirm) {
  168. uni.navigateBack();
  169. }
  170. }
  171. })
  172. }).finally(() => {
  173. uni.stopPullDownRefresh();
  174. })
  175. },
  176. getChargingStatus(id) {
  177. if (id !== this.refreshId) {
  178. return;
  179. }
  180. apiCharge.getChargingDetails({
  181. creditHistoryPk: this.paymentId
  182. }).then(res => {
  183. if (res.data) {
  184. this.connectorInfo = res.data;
  185. if (res.data.creditHistoryPk) {
  186. this.createPayment(res.data.creditHistoryPk);
  187. }
  188. if (!this.chargeInfo.chargeBoxId && res.data.chargeBoxId) {
  189. this.chargeInfo.chargeBoxId = res.data.chargeBoxId;
  190. this.chargeInfo.connectorId = res.data.connectorId;
  191. }
  192. this.showPageWithStatus()
  193. }
  194. }).catch(err => {
  195. /*uni.showToast({
  196. icon: "none",
  197. title: err
  198. })*/
  199. uni.showModal({
  200. title: "Error",
  201. content: err,
  202. confirmText: "OK",
  203. showCancel: false,
  204. success: res => {
  205. if (res.confirm) {
  206. uni.navigateBack();
  207. }
  208. }
  209. })
  210. }).finally(() => {
  211. uni.stopPullDownRefresh();
  212. })
  213. },
  214. showPageWithStatus() {
  215. //this.connectorInfo.status = "Available"
  216. switch (this.connectorInfo.status) {
  217. case "Available":
  218. if (this.isLoading) {
  219. this.refreshStatus(3000);
  220. }
  221. break;
  222. case "Preparing":
  223. this.isLoading = false;
  224. if (this.connectorInfo.paymentStatus == "FAILED") {
  225. this.isPaymentFailed = true;
  226. }
  227. break;
  228. case "Initiating":
  229. if (this.isLoading || this.waitPayment) {
  230. this.refreshStatus(3000);
  231. } else {
  232. this.isLoading = true;
  233. this.refreshStatus(3000);
  234. }
  235. break;
  236. case "Charging":
  237. if (this.waitPayment) {
  238. this.isLoading = true;
  239. this.waitPayment = false;
  240. getApp().globalData.waitPayment = false;
  241. this.refreshStatus(3000);
  242. } else {
  243. this.isLoading = false;
  244. this.refreshStatus(10000);
  245. }
  246. break;
  247. case "Finishing":
  248. if (this.connectorInfo.chargingPk) {
  249. this.chargingPk = this.connectorInfo.chargingPk;
  250. this.toReceipt();
  251. } else {
  252. this.refreshStatus(5000);
  253. //uni.navigateBack();
  254. }
  255. break;
  256. default:
  257. this.refreshId = 0;
  258. this.isLoading = false;
  259. break;
  260. }
  261. uni.hideLoading();
  262. },
  263. changePassword(psd) {
  264. this.password = psd;
  265. if (this.stopPin) {
  266. this.stopPin = false;
  267. this.onStop();
  268. } else {
  269. this.showPin = false;
  270. this.onAuthentic();
  271. }
  272. },
  273. refreshPayment() {
  274. uni.showLoading({
  275. title: "Waiting..."
  276. });
  277. this.getChargingStatus();
  278. },
  279. onAuthentic() {
  280. if (this.password) {
  281. this.isLoading = true;
  282. this.refreshStatus();
  283. } else {
  284. this.showPin = true;
  285. }
  286. },
  287. cancelAuth() {
  288. this.isLoading = false;
  289. },
  290. onPayment() {
  291. if (!this.password) {
  292. this.showPin = true;
  293. return;
  294. }
  295. uni.showLoading({
  296. title: "Waiting..."
  297. })
  298. apiCharge.makePayment({
  299. ...this.chargeInfo,
  300. pin: this.password
  301. }).then(res => {
  302. if (res.data.creditHistoryPk) {
  303. this.createPayment(res.data.creditHistoryPk);
  304. }
  305. if (res.data.webPaymentUrl) {
  306. openUrl(res.data.webPaymentUrl);
  307. }
  308. }).catch(err => {
  309. uni.showModal({
  310. title: "Error",
  311. content: err,
  312. confirmText: "OK",
  313. showCancel: false,
  314. })
  315. /*uni.showToast({
  316. icon: "none",
  317. title: err
  318. })*/
  319. }).finally(() => {
  320. uni.hideLoading();
  321. });
  322. },
  323. onStart() {
  324. this.isLoading = true;
  325. uni.showLoading({
  326. title: "Loading..."
  327. })
  328. apiCharge.startCharge({
  329. //connectorPk: this.connectorPk,
  330. creditHistoryPk: this.paymentId
  331. }).then(res => {
  332. this.refreshStatus();
  333. if (res.msg) {
  334. uni.showToast({
  335. icon: "none",
  336. title: res.msg
  337. })
  338. } else {
  339. uni.hideLoading();
  340. }
  341. }).catch(err => {
  342. this.isLoading = false;
  343. //this.paymentId = "";
  344. //auth.setPaymentId("");
  345. this.connectorInfo.paymentStatus = "";
  346. uni.showToast({
  347. icon: "none",
  348. title: err
  349. })
  350. })
  351. },
  352. stopCharge() {
  353. uni.showModal({
  354. title: "Confirm Stop Charging?",
  355. content: "Your charging session will stop",
  356. confirmText: "CONFIRM",
  357. cancelText: "CANCEL",
  358. success: res => {
  359. if (res.confirm) {
  360. this.stopPin = true;
  361. }
  362. }
  363. })
  364. },
  365. onStop() {
  366. uni.showLoading({
  367. title: "Stopping..."
  368. })
  369. apiCharge.stopCharge({
  370. creditHistoryPk: this.paymentId,
  371. pin: this.password
  372. }).then(res => {
  373. this.stoped = true;
  374. this.paymentId = "";
  375. auth.setPaymentId("");
  376. if (res.data.chargingPk) {
  377. uni.hideLoading();
  378. this.chargingPk = res.data.chargingPk
  379. this.toReceipt();
  380. } else {
  381. uni.showToast({
  382. icon: "none",
  383. title: "Stop failed"
  384. });
  385. this.refreshStatus();
  386. }
  387. }).catch(err => {
  388. uni.showModal({
  389. title: "Error",
  390. content: err,
  391. confirmText: "OK",
  392. showCancel: false
  393. })
  394. uni.hideLoading();
  395. this.refreshStatus();
  396. })
  397. },
  398. confirmStop() {
  399. uni.showModal({
  400. title: "Confirm Stop Charging?",
  401. content: "Your charging session will stop",
  402. confirmText: "CONFIRM",
  403. cancelText: "BACK",
  404. //confirmColor: "var(--primary-color)",
  405. success: (res) => {
  406. if (res.confirm) {
  407. this.onStop();
  408. }
  409. }
  410. })
  411. },
  412. createPayment(id) {
  413. if (id) {
  414. this.paymentId = id;
  415. //auth.setPaymentId("" + id);
  416. }
  417. },
  418. resetPayment() {
  419. this.isLoading = false;
  420. this.waitPayment = false;
  421. this.isPaymentFailed = false;
  422. getApp().globalData.waitPayment = false;
  423. },
  424. toReceipt() {
  425. uni.navigateTo({
  426. url: "/pages/receipt/index?id=" + this.chargingPk
  427. })
  428. }
  429. },
  430. onPullDownRefresh() {
  431. this.refreshStatus(500);
  432. }
  433. }
  434. </script>
  435. <style scoped>
  436. .container {
  437. display: flex;
  438. flex-direction: column;
  439. }
  440. .toolbar {
  441. display: flex;
  442. padding: 16rpx;
  443. position: relative;
  444. align-items: center;
  445. flex-direction: column;
  446. justify-content: center;
  447. background-color: white;
  448. }
  449. .tool-title {
  450. color: #111;
  451. font-size: 32rpx;
  452. font-weight: bold;
  453. padding-bottom: 4rpx;
  454. }
  455. .tool-desc {
  456. color: #666;
  457. font-size: 24rpx;
  458. }
  459. .bottom-button {
  460. padding: 32rpx;
  461. background-color: white;
  462. box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
  463. }
  464. .icon-key {
  465. padding: 0 8rpx;
  466. transform: rotate(-90deg);
  467. }
  468. .ui-button[disabled] >>> .icon-key span {
  469. color: #888;
  470. }
  471. </style>