parkingFeeDetail.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. import moment from 'moment';
  2. import { mapState } from 'vuex';
  3. import log from '@/utils/log.js';
  4. import { compare } from '@/utils/location.js';
  5. import uni from '@/utils/uniHooks';
  6. import { initWxJsSdkConfig } from '@/utils/login';
  7. import { getAppIdByGroupIdAndMallId, getIsWxh5, getPlatform } from '@/utils';
  8. import { Dialog, Toast } from 'vant';
  9. import { ordersAndPrepay } from '@/api/parking';
  10. // import checkOutResponse from '@/api/mockData/checkout.hz.response'
  11. export default {
  12. name: 'parkingFeeDetail',
  13. data() {
  14. return {
  15. hasDiscount: false,
  16. parkFee: {},
  17. refreshTime: 180, // 停车场重置费用倒计时3分钟
  18. // 微服务接口字段
  19. isShowDescription: true, // 缴费说明true:显示全部 false:显示部分
  20. btnLoading: false,
  21. popup: false,
  22. msData: {},
  23. };
  24. },
  25. beforeRouteLeave(to, from, next) {
  26. // 设置下一个路由的 meta
  27. if (/index|home/.test(to.name)) {
  28. // 不在缓存列表中,从cachedViews缓存列表中移除
  29. this.$store.commit('cachedViews/DEL_CACHED_VIEW', from);
  30. }
  31. next();
  32. },
  33. created() {
  34. setTimeout(() => {
  35. uni.setNavigationBarTitle({
  36. title: '停车支付',
  37. });
  38. }, 300);
  39. },
  40. computed: {
  41. ...mapState({
  42. orderDetail: (state) => state.order.orderDetail,
  43. discountDesc: (state) => state.order.discountDesc,
  44. enableNewMemberPoints: (state) => state.order.enableNewMemberPoints,
  45. enablePoints: (state) => state.order.enablePoints,
  46. integralDesc: (state) => state.order.integralDesc,
  47. enableCoupon: (state) => state.order.enableCoupon,
  48. maxOneDayCoupons: (state) => state.order.maxOneDayCoupons,
  49. coupons: (state) => state.order.coupons,
  50. couponDesc: (state) => state.order.couponDesc,
  51. enablePaperCoupons: (state) => state.order.enablePaperCoupons,
  52. custTypeId: (state) => state.custTypeId,
  53. usingTotalDiscount: (state) => state.order.usingTotalDiscount,
  54. actualPayFee: (state) => state.order.actualPayFee,
  55. available: (state) => state.order.available,
  56. member: (state) => state.member,
  57. maxPointsTime: (state) => state.order.maxPointsTime,
  58. pointsTime: (state) => state.order.pointsTime,
  59. pointsPerHour: (state) => state.order.pointsPerHour,
  60. usePoints: (state) => state.order.usePoints,
  61. usePointsTime: (state) => state.order.usePointsTime,
  62. enableConsume: (state) => state.order.enableConsume,
  63. unitAmount: (state) => state.order.unitAmount,
  64. unlicensedInfo: state => state.unlicensedInfo
  65. // checkedTotal: state => state.order.checkedTotal,
  66. }),
  67. // 支付按钮状态
  68. payBtnDisabled() {
  69. // 当存在待支付金额 或者 用户登陆
  70. return !this.orderDetail?.parkingRecord?.totalFeeInYuan || (JSON.stringify(this.member) !== '{}' && !this.orderDetail.parkInfo);
  71. },
  72. integralDesc() {
  73. if (this.pointsTime > 0) {
  74. // 深圳特殊处理(单位:金额)
  75. if (this.orderDetail.parkInfo.parkMallCode === 5 || this.orderDetail.parkInfo.parkMallCode === 999) {
  76. return `已选择兑换${this.pointsTime}元`;
  77. }
  78. return `已选择兑换${this.pointsTime}小时`;
  79. }
  80. if (this.bonusCopy < this.integral) {
  81. return `${this.integral}积分可停车1小时`;
  82. }
  83. if (this.orderDetail.parkInfo.parkMallCode === 3 && app.globalData.member?.currnentintegral >= this.integral && !this.bonus) {
  84. return `今日已达上限`;
  85. }
  86. return `${this.available}积分可减免`;
  87. },
  88. },
  89. filters: {
  90. parkingTime(val) {
  91. const days = parseInt(val / 60 / 24)
  92. const hours = parseInt((val / 60) % 24)
  93. const minutes = parseInt(val % 60)
  94. if (days > 0) {
  95. return `${days}天 ${hours}小时 ${minutes}分钟`
  96. }
  97. if (hours > 0) {
  98. return `${hours}小时 ${minutes}分钟`
  99. }
  100. return `${minutes}分钟`
  101. },
  102. },
  103. created() {
  104. this.pageInit();
  105. },
  106. methods: {
  107. // 前往支付
  108. async toPay() {
  109. const { parkingRecord, discountInfo } = this.orderDetail;
  110. const { coupons, points } = discountInfo
  111. try {
  112. const params = {
  113. // vehicleNo: '', // 车牌号
  114. // points
  115. parkingRecord: {
  116. vehicleNo: parkingRecord.vehicleNo,
  117. enterTime: parkingRecord.enterTime,
  118. serviceMin: parkingRecord.serviceMin,
  119. totalFee: parkingRecord.totalFee, //应缴
  120. actualPayFee: parkingRecord.actualPayFee, //应付金额
  121. },
  122. discountInfo: {
  123. usingTotalDiscount: discountInfo?.usingTotalDiscount || 0, //优惠金额"
  124. actualUsedDiscount: discountInfo?.usingTotalDiscount || 0, //实际优惠金额
  125. },
  126. };
  127. // 积分
  128. if (points?.length && points[0].discountFee > 0) {
  129. // 15 兑换 5元
  130. const { pointsPerUnit, unitAmount, discountFee, available } = points[0]
  131. params.discountInfo.points = {
  132. "discountTime": discountFee / pointsPerUnit,
  133. "discountFee": discountFee,
  134. "discountPoints": discountFee * (unitAmount / pointsPerUnit)
  135. }
  136. }
  137. // 优惠券
  138. if (coupons?.length) {
  139. const selectedCoupons = coupons.filter(elm => {
  140. const selected = elm.hasOwnProperty('selected') ? elm.selected : elm.defaultSelected;
  141. return selected
  142. })
  143. if (selectedCoupons.length) {
  144. params.discountInfo.coupons = selectedCoupons
  145. }
  146. }
  147. const res = await ordersAndPrepay(params);
  148. // console.log('orderDetail', res);
  149. if (res?.paymentType === 'NO_FEE_PAY') {
  150. this.btnLoading = false;
  151. this.$router.replace({
  152. path: this.getPagePath(),
  153. });
  154. // 支付成功
  155. return
  156. }
  157. this.kerryPayment(res.sessionId);
  158. } catch (err) {
  159. console.log(err);
  160. }
  161. },
  162. kerryPayment(session = '011cad54-735f-4e92-8f1b-f22bdfe073cd', payParams) {
  163. const platform = getPlatform();
  164. let appId = uni.getStorageSync('appid');
  165. let openId = uni.getStorageSync('openid') || this.openid;
  166. if (platform === 'miniprogram') {
  167. appId = 'wx92c3e55fbef6b2af';
  168. // appId = 'wxd830fe4d1e04988e';
  169. }
  170. const params = {
  171. region: 'cn',
  172. payChannel: 'OFFICIAL_ACCOUNT',
  173. // payChannel: 'MOBILE_WEB',
  174. payOption: 'WECHATPAY',
  175. appId: appId,
  176. // openId: 'oudWQ5SCDElfn-IQH6eBR5JesOz4', // 下的appid: wxd830fe4d1e04988e
  177. openId,
  178. };
  179. // console.log(1854, params);
  180. this.$md(params);
  181. // let path = `/profileApi/payment/v1/services/session/${session}/transactions`;
  182. let path = `${window.profileApi}/payment/v1/services/session/${session}/transactions`;
  183. this.$request({
  184. url: path,
  185. data: params,
  186. method: 'POST',
  187. header: JSON.parse(uni.getStorageSync('handleUser')),
  188. })
  189. .then(async (res) => {
  190. // this.Toastloading.clear();
  191. // console.log(1795, res);
  192. if (res.data?.code == '000000') {
  193. const prepayJson = res.data.data.params;
  194. const platform = getPlatform();
  195. // TODO: h5环境判断
  196. if (platform === 'micromessenger') {
  197. const weixinH5PayRes = await this.weixinH5Pay(prepayJson);
  198. // 微信支付完成,判断结果
  199. console.log(1784, weixinH5PayRes);
  200. // errMsg: 'requestPayment:ok'
  201. if (weixinH5PayRes?.errMsg === 'requestPayment:ok') {
  202. this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
  203. name: 'parkingFeeDetail'
  204. });
  205. this.$router.replace({
  206. // path: 'parkingFeeSuccess?carno=' + this.parkInfo.carno,
  207. path: this.getPagePath(),
  208. });
  209. } else {
  210. this.reCreateParkOrder();
  211. }
  212. } else {
  213. window.toWXSendMsg({
  214. type: 'openWxPay',
  215. options: {
  216. provider: 'wxpay',
  217. timeStamp: prepayJson.timeStamp,
  218. nonceStr: prepayJson.nonceStr,
  219. package: prepayJson.package,
  220. signType: prepayJson.signType,
  221. paySign: prepayJson.paySign,
  222. },
  223. });
  224. window.subscribe('wxPayOver', (options) => {
  225. // this.Toastloading.clear();
  226. // console.log('微信支付结束之后的返回参数', options);
  227. // T-ODO: 在 qa 新发版前,只提示支付成功的信息(已处理成功信息)
  228. if (options?.wxPayOver === 'fail') {
  229. console.log('支付失败');
  230. this.reCreateParkOrder();
  231. } else {
  232. this.btnLoading = false;
  233. this.$router.replace({
  234. // path: 'parkingFeeSuccess?vehicleNo=' + this.$route.query.vehicleNo,
  235. path: this.getPagePath(),
  236. });
  237. }
  238. });
  239. }
  240. } else {
  241. // this.reCreateParkOrder();
  242. }
  243. })
  244. .catch((err) => {
  245. console.log(1854, err);
  246. // this.reCreateParkOrder();
  247. });
  248. },
  249. // 支付失败后返还优惠券
  250. failedParkOrder() {
  251. // this.Toastloading.clear();
  252. const param = {
  253. orderno: this.parkInfo.orderno,
  254. };
  255. this.$md(param);
  256. uni
  257. .request({
  258. url: this.$baseURL + 'api/1.0/park/failedParkOrder',
  259. data: param,
  260. method: 'POST',
  261. header: JSON.parse(uni.getStorageSync('handleUser')),
  262. })
  263. .then((res) => {
  264. this.reCreateParkOrder();
  265. })
  266. .catch((err) => {
  267. this.reCreateParkOrder();
  268. });
  269. },
  270. // 支付失败弹框 重新创建订单
  271. reCreateParkOrder() {
  272. // console.log('支付失败弹框 重新创建订单');
  273. Dialog.alert({
  274. title: '提示',
  275. message: '支付失败',
  276. confirmButtonColor: '#333',
  277. }).then(() => {
  278. this.$store.dispatch('order/orderInit', {
  279. gateId: this.$route.query?.gateId,
  280. vehicleNo: this.$route.query?.vehicleNo,
  281. endlessLoop: this.endlessLoop
  282. })
  283. this.btnLoading = false;
  284. // this.createParkOrder();
  285. });
  286. // uni.showModal({
  287. // showCancel: false,
  288. // title: '提示',
  289. // content: '支付失败',
  290. // complete: (r) => {
  291. // this.createParkOrder();
  292. // },
  293. // });
  294. },
  295. // 初始化
  296. async pageInit() {
  297. // console.log(247, checkOutResponse);
  298. // this.msData.detail = checkOutResponse
  299. // 停车优惠
  300. // this.discounts(this.msData.detail)
  301. // 积分减免
  302. // 优惠券
  303. // 纸质优惠券
  304. // 优惠金额
  305. // 应付金额
  306. // this.$store.commit('order/SET_ORDER_DETAIL', checkOutResponse);
  307. try {
  308. this.$store.dispatch('order/orderInit', {
  309. vehicleNo: this.$route.query.vehicleNo,
  310. gateId: this.$route.query?.gateId,
  311. endlessLoop: this.endlessLoop,
  312. callback: (res) => {
  313. console.log(303, res);
  314. if (/NOT_FOUND|PARKING_RECORD_NOT_FOUND/.test(res.code)) {
  315. // 当前车辆没有查到账单
  316. this.$router.replace({
  317. path: 'parkingFeePayment',
  318. query: {
  319. msg: res.message,
  320. vehicleNo: this.$route.query.vehicleNo,
  321. },
  322. });
  323. return
  324. }
  325. if (res.code === "INTERNAL_SERVER_ERROR") {
  326. setTimeout(() => {
  327. this.$router.back()
  328. }, 1000)
  329. }
  330. }
  331. });
  332. } catch (err) {
  333. console.log('查询车辆是否在场的报错信息?', err, err.code === "INTERNAL_SERVER_ERROR");
  334. // 如果网络异常(这里是因为订单页面存在空白场景,才需要单独处理报错交互)
  335. if (err.code === "INTERNAL_SERVER_ERROR") {
  336. this.$router.back()
  337. }
  338. }
  339. },
  340. // 停车优惠
  341. discounts() {
  342. if (!this.enableConsume && orderDetail.parkInfo.parkMallCode !== 2) {
  343. return Toast({
  344. message: '暂无可用优惠',
  345. });
  346. }
  347. this.$router.push({
  348. path: 'parkingFeeDiscounts',
  349. });
  350. },
  351. setColor() {
  352. window?.toWXSendMsg({
  353. type: 'uni_func',
  354. funcName: 'setNavigationBarColor',
  355. options: {
  356. frontColor: '#000000',
  357. backgroundColor: '#2151C5',
  358. },
  359. });
  360. // uni.setNavigationBarColor({
  361. // frontColor: '#000000',
  362. // backgroundColor: '#FAFBFF',
  363. // });
  364. },
  365. // 是否展示优惠信息
  366. // isShowDiscounts(params) {
  367. // console.log(277, params?.parkingRule?.enableCoupon);
  368. // return params?.parkingRule?.enableCoupon
  369. // },
  370. //
  371. // 计算优惠信息
  372. discountssss(params) {
  373. // console.log(275, params);
  374. // console.log(275, params.discountInfo);
  375. // console.log(275, params.discountInfo.consume);
  376. return 1;
  377. },
  378. coupon() {
  379. this.$router.push({
  380. path: 'parkingFeeCoupon',
  381. });
  382. },
  383. paperCoupon() { },
  384. duration() { },
  385. couponCount() { },
  386. // 重置倒计时
  387. resetCountDown() {
  388. this.$refs.countDown.reset();
  389. this.$store.dispatch('order/orderInit', {
  390. gateId: this.$route.query?.gateId,
  391. vehicleNo: this.$route.query?.vehicleNo,
  392. endlessLoop: this.endlessLoop
  393. })
  394. // 重新创建订单
  395. // this.createParkOrder();
  396. },
  397. //缴费说明隐藏显示
  398. togglePayinstruction() {
  399. this.isShowDescription = !this.isShowDescription;
  400. },
  401. // 积分修改框
  402. showPointsMathPopup() {
  403. this.popup = true;
  404. },
  405. cancelPointsMathPopup() {
  406. this.$store.dispatch('order/cancelPointsMath', () => {
  407. this.popup = false;
  408. });
  409. },
  410. savePointsMathPopup() {
  411. this.$store.dispatch('order/savePointsMath', () => {
  412. this.popup = false;
  413. });
  414. },
  415. // 获取成功缴费之后前往的页面
  416. getPagePath() {
  417. let pagePath = 'parkingFeeSuccess?vehicleNo=' + this.$route.query.vehicleNo
  418. if (this.$route.query.vehicleNo.indexOf('临') > -1 && this.endlessLoop) {
  419. pagePath = 'parkingFeeMsg?type=pay'
  420. }
  421. return pagePath
  422. }
  423. },
  424. };