Эх сурвалжийг харах

Merge pull request #34 from tron/develop

合并微服务改造
Tron 2 жил өмнө
parent
commit
87770f92ea
35 өөрчлөгдсөн 932 нэмэгдсэн , 483 устгасан
  1. 1 0
      README.md
  2. 1 0
      package.json
  3. 11 11
      public/index.html
  4. 17 145
      src/App.vue
  5. 2 1
      src/api/mockData/checkout.qh5.response.json
  6. 232 0
      src/api/mockData/checkout.qh6.response.json
  7. 1 1
      src/api/parking/index.js
  8. 17 15
      src/api/request.js
  9. 1 0
      src/common/js/BaseDictionary.js
  10. 12 2
      src/components/plate-number/plateNumber.vue
  11. 10 0
      src/main.js
  12. 10 5
      src/pages/parkingFee/components/base/parkingFeeDetail.vue
  13. 8 6
      src/pages/parkingFee/components/base/parkingFeeDetailSuccess.vue
  14. 2 2
      src/pages/parkingFee/components/base/parkingFeeList.vue
  15. 8 4
      src/pages/parkingFee/components/base/parkingReceipt/parkingApplication.vue
  16. 46 44
      src/pages/parkingFee/components/base/parkingReceipt/parkingChooseHeader.vue
  17. 40 39
      src/pages/parkingFee/components/base/parkingReceipt/parkingHeaderDetail.vue
  18. 1 1
      src/pages/parkingFee/components/base/parkingReceipt/parkingInvoiceImage.vue
  19. 25 23
      src/pages/parkingFee/components/base/parkingReceipt/parkingOrderDetail.vue
  20. 1 1
      src/pages/parkingFee/components/base/parkingReceipt/parkingReceipt.vue
  21. 1 1
      src/pages/parkingFee/components/officeBlue/parkingFeeDetail.vue
  22. 1 1
      src/pages/parkingFee/components/officeBlue/parkingFeeDetailSuccess.vue
  23. 1 1
      src/pages/parkingFee/components/purple/parkingFee.vue
  24. 92 34
      src/pages/parkingFee/mixins/parkingFee.js
  25. 3 2
      src/pages/parkingFee/mixins/parkingFeeCoupon.js
  26. 71 27
      src/pages/parkingFee/mixins/parkingFeeDetail.js
  27. 6 14
      src/pages/parkingFee/mixins/parkingFeeList.js
  28. 5 15
      src/pages/parkingFee/mixins/parkingReceipt/parkingApplication.js
  29. 4 4
      src/pages/parkingFee/mixins/parkingReceipt/parkingReceipt.js
  30. 14 48
      src/pages/parkingFee/mixins/vehicleManagement.js
  31. 8 5
      src/store/index.js
  32. 100 22
      src/store/order.js
  33. 140 3
      src/utils/index.js
  34. 14 5
      vue.config.js
  35. 26 1
      yarn.lock

+ 1 - 0
README.md

@@ -106,3 +106,4 @@ font-size: 8px
 ```css
 font-size: 13px
 ```
+test

+ 1 - 0
package.json

@@ -20,6 +20,7 @@
     "sa-sdk-javascript": "^1.24.13",
     "uuid": "^9.0.0",
     "vant": "^2.12.50",
+    "vconsole": "^3.15.0",
     "vue": "^2.7.14",
     "vue-router": "^3.6.5",
     "vuex": "^3.6.2"

+ 11 - 11
public/index.html

@@ -33,17 +33,17 @@
   <script>
     // const debug = window.localStorage.getItem('H5_DEBUG');
     // 开发环境和qa环境 打开debug
-    const debug = /dev-|qa-/.test(window?.injectConfig?.api) || window.location.href.indexOf(8080) > -1;
-    if (debug) {
-      const script = document.createElement('script');
-      script.src = 'https://unpkg.com/vconsole@latest/dist/vconsole.min.js';
-      document.head.appendChild(script);
-      script.addEventListener('load', () => {
-        setTimeout(() => {
-          window.vConsole = new window.VConsole();
-        }, 200);
-      });
-    }
+    // const debug = /dev-|qa-/.test(window?.injectConfig?.api) || window.location.href.indexOf(8080) > -1;
+    // if (debug) {
+    //   const script = document.createElement('script');
+    //   script.src = 'https://unpkg.com/vconsole@latest/dist/vconsole.min.js';
+    //   document.head.appendChild(script);
+    //   script.addEventListener('load', () => {
+    //     setTimeout(() => {
+    //       window.vConsole = new window.VConsole();
+    //     }, 200);
+    //   });
+    // }
     if ( /(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent) ) {
       // https://developers.weixin.qq.com/community/develop/doc/000ae2cb950808f90d8bc415551800
       window.H5_LAUNCH_URL = location.href;

+ 17 - 145
src/App.vue

@@ -23,20 +23,17 @@
   </div>
 </template>
 <script>
-import { createAxiosByinterceptors } from '@/api/request';
-import Stomp from '@/lib/stompjs';
 import loginMinix from '@/mixins/login';
-import { Decrypt, Encrypt } from '@/utils/crypto';
-import { getIsMin, getIsWxh5, getUrlParams } from '@/utils/index.js';
-import SockJS from '@/utils/sockjs';
+import { getIsMin,getIsWxh5,getUrlParams,initEnv,requestInit,wssInit } from '@/utils/index.js';
 import uni from '@/utils/uniHooks';
 import { getAppIdByGroupIdAndMallId } from '@/utils/index.js';
-import sensorsFn from '@/plugins/sensors'
+import sensorsFn from '@/plugins/sensors';
+
 export default {
   mixins: [loginMinix],
   async created() {
-    await this.initEnv();
-    await this.requestInit();
+    await initEnv();
+    await requestInit();
     await this.init();
     // await sensorsFn(); // 埋点初始化
     // 初始化环境变量
@@ -77,6 +74,9 @@ export default {
       uni.setStorageSync('env', window.env);
       // 如果是微信小程序。初始化wss
       if (getIsMin()) {
+        if (window.location.href.indexOf('cryptojs') > -1) {
+          return
+        }
         // 保留 carList
         const carList = uni.getStorageSync('carList');
         // 每次进入页面清空 缓存数据
@@ -84,17 +84,16 @@ export default {
         if (carList) {
           uni.setStorageSync('carList', JSON.parse(carList));
         }
-
         this.$store.commit('SET_IS_INIT', false);
         window.token = `${window.location.href}`.replace(/.*wx\/(.*)\/.*/g, '$1');
         try {
-          const options = await this.wss();
+          const options = await wssInit();
           this.$store.dispatch('baseInit', {
             options,
             callback: () => {
               this.$store.commit('SET_IS_INIT', true);
               // 无感积分逻辑
-              this.wxEasyPointsCommitStatusInit();
+              // this.wxEasyPointsCommitStatusInit();
             },
           });
         } catch (err) {
@@ -107,136 +106,10 @@ export default {
         this.micromessengerInit();
       }
     },
-    wss() {
-      return new Promise((resolve, reject) => {
-        try {
-          const socket = new SockJS(`${this.getUrl()}/hafengWebsocket?token=${window.token}`);
-          window.stompClient = Stomp.over(socket);
-          window.stompClient.debug = null;
-          this.windowSendInit();
-          window.stompClient.connect({}, (frame) => {
-            // 请求 projectId
-            window.toWXSendMsg({
-              type: 'getProjectId',
-              options: {},
-            });
-            window.subscribe('projectId', (options) => {
-              resolve(options);
-            });
-          });
-        } catch (err) {
-          // console.log(err);
-          reject(err);
-          // callback && callback();
-        }
-      });
-    },
-    windowSendInit() {
-      const token = window.token;
-      // console.log(118, token);
-      window.toWXSendMsg = function ({ type = '', funcName = '', options = {} }) {
-        /**
-         * 向小程序端发送消息
-         */
-        if (!type) return;
-        // console.log(259, '微信支付的options', options);
-        window.stompClient.send(
-          '/sendToWechat',
-          {},
-          JSON.stringify({
-            token,
-            data: Encrypt(
-              JSON.stringify({
-                type: type,
-                funcName,
-                options,
-              })
-            ),
-          })
-        );
-      };
-
-      // 主动订阅事件回调
-      window.subscribe = function (type, callback) {
-        const subscribeId = window.stompClient.subscribe('/user/' + token + '/toH5', function (response) {
-          try {
-            let res = {
-              token: '', // 微信小程序端 页面的传递过来的token
-              data: '', // 微信小程序端 页面的传递过来的信息(已加密)
-            };
-            if (response.body) {
-              res = JSON.parse(response.body);
-            }
-            // 检查 微信小程序端 发送过来的信息和token是否与当前页面的 token一致。并且 res.data 携带信息,在解密之后是 json 格式
-            if (res.token && res.token === token && res.data) {
-              const msgJson = JSON.parse(Decrypt(res.data));
-              const reg = new RegExp(type);
-              // 获取 projectId
-              if (reg.test(msgJson.type)) {
-                callback(msgJson.options, subscribeId);
-                subscribeId.unsubscribe();
-                return;
-              }
-            }
-          } catch (err) {
-            console.log('stomp error', err);
-          }
-        });
-      };
-    },
-    initEnv() {
-      const href = window.location.href;
-      console.log('当前页面的url地址  ', href);
-      if (/dev-|8080/.test(href)) {
-        // window.env = 'qa';
-        // window.profileApi = 'https://qa-apim.kerryplus.com/c/api';
-        // window.api = 'qaApi';
-        window.env = 'dev';
-        window.profileApi = 'https://dev-gateway-kip.kerryonvip.com/api';
-        window.api = 'devApi';
-        return;
-      }
-      if (/qa-/.test(href)) {
-        window.env = 'qa';
-        window.api = 'qaApi';
-        window.profileApi = 'https://qa-apim.kerryplus.com/c/api';
-        return;
-      }
-      window.env = 'prod';
-      window.profileApi = 'https://apim.kerryplus.com/c/api';
-      window.api = 'api';
-    },
-    requestInit() {
-      let baseURL = window.profileApi + '/temporary-parking/v1';
-      if (window.location.href.indexOf('tparking.') < 0 ) {
-        baseURL = '/msApi'
-      }
-      window.requestms = createAxiosByinterceptors({
-        // baseURL: `https://dev-kip-service-internal.kerryonvip.com/`,
-        // baseURL: `http://tp.hht.test/`,
-        // baseURL: window.profileApi, // TODO: 微服务发布到DEV环境之后取消注释
-        baseURL
-        // baseURL: `/msApi`,
-      });
-    },
-    // websocket 链接
-    getUrl() {
-      // 如果 kerry+ 这边的访问环境是 sl 或者 lt,需要把 wss 指向 qa 环境。
-      const href = `${window.location.href}`;
-      if (/dev-|8080/.test(href)) {
-        return 'https://qa-crm-kpl.kerryprops.com.cn/xcrm-api';
-      }
-      if (/qa-/.test(href)) {
-        return 'https://qa-crm-kpl.kerryprops.com.cn/xcrm-api';
-      }
-      // return 'https://qa-crm-kpl.kerryprops.com.cn/xcrm-api';
-      return `https://crm.kerryplus.com/xcrm-api`;
-    },
     micromessengerInit() {
       this.$store.commit('SET_IS_INIT', false);
       let path = '';
       let [groupId, mallId] = window.location.pathname.split('/').filter((elm) => elm);
-      console.log(265, groupId, mallId);
       // return;
       // 如果groupId 是 tparking
       if (groupId === 'tparking') {
@@ -260,7 +133,6 @@ export default {
       const openid = uni.getStorageSync('openid');
 
       const query = getUrlParams();
-      console.log(284, query, groupId, mallId);
       // return;
       // 设置openid
       this.$nextTick(() => {
@@ -301,16 +173,16 @@ export default {
     },
     // 无感积分相关
     async wxEasyPointsCommitStatusInit() {
-      return
+      return;
       this.$refs.wxPointsCommit.open();
       // 判断用户是否登陆
       if (uni.getStorageSync('openid') && uni.getStorageSync('member') && uni.getStorageSync('member') !== {}) {
-				const easyPointsCommitStatus = await getWxEasyPointsCommitStatus()
-				if (easyPointsCommitStatus) {
-					this.$refs.wxPointsCommit.open();
-				}
-			}
-    }
+        const easyPointsCommitStatus = await getWxEasyPointsCommitStatus();
+        if (easyPointsCommitStatus) {
+          this.$refs.wxPointsCommit.open();
+        }
+      }
+    },
   },
 };
 </script>

+ 2 - 1
src/api/mockData/checkout.qh5.response.json

@@ -4,11 +4,12 @@
     "enterTime": "2023-01-06 19:24:50", 
     "serviceMin": 84, 
     "totalFee": 1, 
+    "thirdPartyId": "B1vrk1fRLoLuNEnKaUVrN", 
     "totalFeeInYuan": 0.01
   }, 
   "parkInfo": {
     "parkName": "VLhpfQGTMDYpsBZxvfBoeygjb", 
-    "description": "深圳停车费用说明", 
+    "description": "计费基础规则:15分钟内免费,首小时15元,其后每小时5元,全天封顶60元。\n嘉湾汇会员停车礼遇:\n银卡:每月可免费领取2张首2小时停车券\n金卡:每月可免费领取5张首2小时停车券\n铂金卡:每月可免费领取10张首2小时停车券\n*数量有限,领完即止\n仅限开具一个月内的停车费电子发票 ", 
     "parkMallCode": 5, 
     "buildingId": "QHKC-P1"
   }

+ 232 - 0
src/api/mockData/checkout.qh6.response.json

@@ -0,0 +1,232 @@
+{
+  "parkingRecord": {
+    "vehicleNo": "粤BDF1412", 
+    "enterTime": "2023-01-06 19:24:50", 
+    "serviceMin": 84, 
+    "totalFee": 1, 
+    "actualPayFee": 0, 
+    "thirdPartyId": "B1vrk1fRLoLuNEnKaUVrN", 
+    "totalFeeInYuan": 0.01
+  }, 
+  "discountInfo": {
+    "usingTotalDiscount": 5, 
+    "memberLevelDiscount": false, 
+    "points": [
+      {
+        "available": 5450, 
+        "maxDiscountFee": 20, 
+        "pointsPerUnit": 1500, 
+        "unitAmount": 5, 
+        "newMember": false, 
+        "label": "5450积分可减免"
+      }
+    ], 
+    "coupons": [
+      {
+        "code": "0uwn32xo2of_t", 
+        "name": "积分商城兑换券", 
+        "expirationDate": "2023-03-31 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "1", 
+        "limitCountPerOrder": 0
+      }, 
+      {
+        "code": "hbnptz3kau5_t", 
+        "name": "积分商城兑换券", 
+        "expirationDate": "2023-03-31 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "1", 
+        "limitCountPerOrder": 0
+      }, 
+      {
+        "code": "vic3iqevsxg_t", 
+        "name": "积分商城兑换券", 
+        "expirationDate": "2023-03-31 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "1", 
+        "limitCountPerOrder": 0
+      }, 
+      {
+        "code": "e7magsgvvmp_t", 
+        "name": "积分商城兑换券", 
+        "expirationDate": "2023-03-31 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "1", 
+        "limitCountPerOrder": 0
+      }, 
+      {
+        "code": "xtifg1r1q2t_t", 
+        "name": "积分商城兑换券", 
+        "expirationDate": "2023-03-31 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "1", 
+        "limitCountPerOrder": 0
+      }, 
+      {
+        "code": "gwpohn04hxs_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "defaultSelected": true, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "2ryj2z6xyb7_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "dv97sa11phj_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "rxoyldb7k40_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "dcjja5kg6u1_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "u0ybm5n8txq_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "qk4wvrk9s04_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "gf4cwhgkq8n_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "5utf424l8f3_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "06yq5t60xaa_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "hplv3n26pck_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "1q938eflsbc_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "pspiwou65fl_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "3htmstjwway_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "ote7fpbvl9z_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "mpjtd2bj4y7_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "n09uhdzgu1z_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }, 
+      {
+        "code": "wzjfo0idpvo_t", 
+        "name": "可叠加电子券2(上限3)", 
+        "expirationDate": "2023-03-10 23:59:59", 
+        "discountFee": 5, 
+        "superposition": "2", 
+        "limitCountPerOrder": 3
+      }
+    ]
+  }, 
+  "parkingRule": {
+    "maxOneDayDiscountFee": 60, 
+    "enableNewMemberPoints": false, 
+    "enablePoints": true, 
+    "enableCoupon": true, 
+    "maxOneDayCoupons": 5, 
+    "remainCoupons": 5, 
+    "enablePaperCoupons": false, 
+    "maxPointsTime": 3, 
+    "enableConsume": false, 
+    "enableConsumeSplit": false, 
+    "availableDiscountFee": 50, 
+    "hourPrice": 5
+  }, 
+  "parkInfo": {
+    "parkName": "VLhpfQGTMDYpsBZxvfBoeygjb", 
+    "description": "计费基础规则:15分钟内免费,首小时15元,其后每小时5元,全天封顶60元。\n嘉湾汇会员停车礼遇:\n银卡:每月可免费领取2张首2小时停车券\n金卡:每月可免费领取5张首2小时停车券\n铂金卡:每月可免费领取10张首2小时停车券\n*数量有限,领完即止\n仅限开具一个月内的停车费电子发票 ", 
+    "parkMallCode": 5, 
+    "buildingId": "QHKC-P1"
+  }
+}

+ 1 - 1
src/api/parking/index.js

@@ -20,7 +20,7 @@ export function parkingLots(lbsId) {
 // 1.6 查询车辆是否在场及停车费用: https://kerryprops.atlassian.net/wiki/spaces/TAIC/pages/94076936/1.6
 // 新接口路径:https://{kip-service-host}/c/api/temporary-parking-service/parking/check-out?vehicleNo={{vehicleNo}}
 export function checkOut(vehicleNo, unlicensed) {
-  console.log(212121, vehicleNo);
+  // console.log(212121, vehicleNo);
   // 'https://dev-kip-service-internal.kerryonvip.com/temporary-parking-service/parking/check-out?vehicleNo=浙
   return window.requestms.get(`/parking/check-out?vehicleNo=${vehicleNo}&unlicensed=${unlicensed}`, {
     loading: true,

+ 17 - 15
src/api/request.js

@@ -21,13 +21,12 @@ const CONTENT_TYPE_ARRAY = {
 };
 
 function getHeaders(config = {}) {
-  console.log(24, '接口返送出去的config', config);
   const { contentType = 'json' } = config;
   const ct = CONTENT_TYPE_ARRAY[contentType];
   let header = {
     // appId: uni.getStorageSync('appid'),
-    appId: 'wx92c3e55fbef6b2af',
-    'Content-Type': ct,
+    // appId: 'wx92c3e55fbef6b2af',
+    // 'Content-Type': ct,
   };
   const token = getToken();
   if (token) {
@@ -36,12 +35,12 @@ function getHeaders(config = {}) {
 
   const groupId = uni.getStorageSync('groupId');
   const mallId = uni.getStorageSync('mallid');
-  if (groupId) {
-    header['brandId'] = groupId;
-  }
-  if (mallId) {
-    header['lbsId'] = mallId;
-  }
+  // if (groupId) {
+  //   header['brandId'] = groupId;
+  // }
+  // if (mallId) {
+  //   header['lbsId'] = mallId;
+  // }
   const sourceObj = getUTMSource();
   return Object.assign(header, sourceObj);
 }
@@ -52,7 +51,6 @@ function handleConfig(config = {}) {
   if (noToken) {
     delete header.Authorization;
   }
-  console.log(525252, header);
   return { header, ...config };
 }
 
@@ -101,7 +99,7 @@ function XUser(config) {
     lbsId: store.state?.lbsId || '',
   };
   // params = {"userId":"8aaa809d835ba76d018377d482ac0004","sourceType":"WECHAT","phoneNumber":"15090631337","projectId":"","brandId":"8aaa81947c6e1ca0017c73c13cc30006","cid":"oudWQ5ccsJLSlUGt0s_RQysoHqgg","vipCode":"KERRY100213432","lbsId":"8aaa82ea804d07cd0180516ff03b0008"}
-  if (/orders-and-prepay|calculate-discount|unlicensed-car-check-in/.test(config.url)) {
+  if (/orders-and-prepay|calculate-discount|unlicensed-car-check-in|unlicensed-car-checkout/g.test(config.url)) {
     params.buildingId = window.localStorage.getItem('buildingId');
   }
   return JSON.stringify(params);
@@ -122,7 +120,10 @@ export const createAxiosByinterceptors = (config) => {
     timeout: 100000, //超时配置
     baseURL: `${window.profileApi}/temporary-parking-service`,
     // baseURL: `https://dev-kip-service-internal.kerryonvip.com/temporary-parking-service`,
-    withCredentials: true, //跨域携带cookie
+    withCredentials: false, //跨域携带cookie
+    xhrFields: {
+      withCredentials: false // 允许跨域携带cookie信息
+    },
     ...config, // 自定义配置覆盖基本配置
   });
   // 添加请求拦截器
@@ -135,9 +136,10 @@ export const createAxiosByinterceptors = (config) => {
       config.headers = {
         ...config.headers,
         ...handleConfig().header,
-        ...getSign(config),
-        'XConversationId': uuidv4(),
+        // ...getSign(config),
+        'x-conversation-id': uuidv4(),
         'X-User': XUser(config),
+        'withCredentials': 'false'
       };
       return config;
     },
@@ -175,7 +177,7 @@ export const createAxiosByinterceptors = (config) => {
       }
       // 错误信息提示
       const { code, langMessage, message } = error.response.data;
-      const codeList = ['INTERNAL_SERVER_ERROR', 'VALIDATION_FAILED', 'CAR_NOT_FOUND', 'CAR_HAS_PLATE', "NOT_FOUND"]; // 默认处理的错误code
+      const codeList = ['INTERNAL_SERVER_ERROR', 'VALIDATION_FAILED', 'CAR_NOT_FOUND', 'CAR_HAS_PLATE', "NOT_FOUND", "LOCAL_PARK_ERROR", "LOCK_OCCUPIED", "REMOTE_CALL_FAIL", 'PLEASE_SCAN_QRCODE']; // 默认处理的错误code
       if (codeList.indexOf(code) > -1) {
         uni.showToast({ title: langMessage || message, duration: 3000, icon: 'fail' });
       }

+ 1 - 0
src/common/js/BaseDictionary.js

@@ -92,6 +92,7 @@ export const ORDER_STATUS = {
   PAID: '已支付',
   REFUND: '已退款',
   TIME_OUT: '已超时',
+  FAILED: '支付失败'
 }
 
 // 不同环境的基础数据

+ 12 - 2
src/components/plate-number/plateNumber.vue

@@ -5,7 +5,7 @@
       <div class="plate_number_wrap">
         <!-- 提示区域 -->
         <div class="event-box">
-          <div class="close" @click.stop="close_keyboard"></div>
+          <div class="close" @click.stop="close_keyboard">取消</div>
           <div>车牌键盘</div>
           <div class="sure" @click.stop="close_keyboard">确认</div>
         </div>
@@ -70,6 +70,12 @@ export default {
       default() {
         return [];
       },
+    },
+    noDisBtn:{
+      type: Array,
+      default() {
+        return [];
+      },
     }
   },
   data() {
@@ -360,7 +366,7 @@ export default {
           id: 56,
         },
         {
-          name: '返回',
+          name: '地区',
           id: 66,
         },
         {
@@ -431,6 +437,10 @@ export default {
       if(this?.disBtn?.length && this.disBtn.indexOf(index) > -1) {
         dis = true;
       }
+      // 
+      if(this?.noDisBtn?.length && this.noDisBtn.indexOf(index) > -1) {
+        dis = false;
+      }
       return dis;
     },
     // 选择车牌号前面的汉字

+ 10 - 0
src/main.js

@@ -1,6 +1,16 @@
 import Vue from 'vue';
 import VueRouter from 'vue-router';
+import VConsole from 'vconsole';
 
+
+// 或者使用配置参数来初始化,详情见文档
+// 开发环境和qa环境 打开debug
+const debug = /dev-|qa-/.test(window?.injectConfig?.api) || window.location.href.indexOf(8080) > -1;
+if (debug) {
+  window.vConsole = new VConsole(
+    // { theme: 'dark' }
+  );
+}
 import './plugins/install';
 import App from './App.vue';
 import store from './store/index.js';

+ 10 - 5
src/pages/parkingFee/components/base/parkingFeeDetail.vue

@@ -51,7 +51,9 @@
             <img style="width: 26px; height: 26px" :src="`${require('../../static/images/arrows.png')}`" />
           </div>
         </div>
-        <div class="warp_index warp_index_da" v-if="enablePoints">
+        <!-- v-if="enablePoints" -->
+        <!-- 用户登录时展示 -->
+        <div class="warp_index warp_index_da" v-if="orderDetail && orderDetail.discountInfo">
           <div>积分减免</div>
           <div class="warp_index_color" @click="showPointsMathPopup('bottom')">
             <div style="margin-right: 10px" :class="integralDesc === '今日已达上限' ? 'text-disable' : 'text-red'">
@@ -60,10 +62,13 @@
             <img style="width: 26px; height: 26px" :src="`${require('../../static/images/arrows.png')}`" />
           </div>
         </div>
-        <div class="warp_index warp_index_da" v-if="enableCoupon">
+        <!-- v-if="enableCoupon" -->
+        <!-- 用户登录时展示 -->
+        <div class="warp_index warp_index_da" v-if="orderDetail && orderDetail.discountInfo">
           <div>优惠劵</div>
           <div class="warp_index_color" @click="coupon">
-            <div style="margin-right: 10px" :class="maxOneDayCoupons > 0 ? 'text-red' : 'text-disable'">
+            <!-- maxOneDayCoupons > 0 && -->
+            <div style="margin-right: 10px" :class="coupons.length > 0 ? 'text-red' : 'text-disable'">
               {{ couponDesc }}
             </div>
             <img style="width: 26px; height: 26px" :src="`${require('../../static/images/arrows.png')}`" />
@@ -143,9 +148,9 @@
           <div>抵扣{{ orderDetail.parkInfo.parkMallCode === 5 ? '金额' : '时长' }}</div>
           <div class="popue_box_index" style="width: 325px">
             <div class="popue_box_index4_xs">
-              <div class="popue_box_index4_xs_index1" @click="$store.dispatch('order/pointsMath',{type: 'minus'})">-</div>
+              <div class="popue_box_index4_xs_index1" @click="$store.dispatch('order/pointsMath',{type: 'minus', callback: pointsMathCallback})">-</div>
               <div class="popue_box_index4_xs_index2">{{ pointsTime }}</div>
-              <div class="popue_box_index4_xs_index3" @click="$store.dispatch('order/pointsMath',{type: 'add'})">+</div>
+              <div class="popue_box_index4_xs_index3" @click="$store.dispatch('order/pointsMath',{type: 'add', callback: pointsMathCallback})">+</div>
             </div>
             <div style="color: #808080">
               {{ orderDetail.parkInfo.parkMallCode === 5 ? '元' : '小时' }}

+ 8 - 6
src/pages/parkingFee/components/base/parkingFeeDetailSuccess.vue

@@ -8,7 +8,9 @@
           <div class="price">{{ detail.actualPayFee | currency }}</div>
           <div class="price-text">
             <!-- {{ ['支付成功', '支付失败', '已退款'][detail.payStatus] }} -->
-            {{ detail.orderStatus | orderStatus }}
+            <!-- {{ detail.refundStatus === '1' ? '已退款' : detail.paymentStatus }} -->
+            <!-- {{ detail.refundStatus !== 'NO_REFUND' ? '已退款' : detail.payStatus }} -->
+            {{ detail.refundStatus !== 'NO_REFUND' ? '已退款' : {'PAID': '支付成功', 'FAILED': '支付失败'}[detail.payStatus || 'FAIED'] }}
           </div>
         </div>
         <div class="parking-part parking-detail">
@@ -19,7 +21,7 @@
 
           <div class="parking-info-item">
             <span class="info-key">支付时间</span>
-            <span class="info-value">{{ detail.createTime | momentFormat }}</span>
+            <span class="info-value">{{ detail.paymentTime }}</span>
           </div>
           <div class="parking-info-item">
             <span class="info-key">车牌号</span>
@@ -37,7 +39,7 @@
           </div>
           <div class="parking-info-item">
             <span class="info-key">入场时间</span>
-            <span class="info-value">{{ detail.enterTime | momentFormat }}</span>
+            <span class="info-value">{{ detail.enterTime }}</span>
           </div>
           <!-- <div class="parking-info-item">
             <span class="info-key">离场时间</span>
@@ -53,7 +55,7 @@
           </div>
         </div>
       </div>
-      <div class="parking-info mgb-40 mb-save">
+      <div class="parking-info mgb-40 mb-save" v-if="detail.discountInfo">
         <div class="parking-part">
           <div class="parking-info-item" v-if="false">
             <!--todo: 杭州首停不显示暂时根据groupId写死-->
@@ -63,7 +65,7 @@
           <div class="parking-info-item">
             <span class="info-key">会员等级减免</span>
             <!-- // (detail.discountInfo.memberLevelDiscount / 100) | currency -->
-            <span class="info-value">{{ detail.discountInfo && detail.discountInfo.memberLevelDiscount }}</span>
+            <span class="info-value">{{ detail.discountInfo && detail.discountInfo.memberLevelDiscount | currency }}</span>
           </div>
           <div class="parking-info-item">
             <span class="info-key">消费减免</span>
@@ -97,7 +99,7 @@
         <div class="parking-part parking-detail">
           <div class="parking-info-item">
             <span class="info-key">应缴</span>
-            <span class="info-value">{{ (detail.totalFee / 100) | currency }}</span>
+            <span class="info-value">{{ (detail.totalFee ) | currency }}</span>
           </div>
           <div class="parking-info-item">
             <span class="info-key">实缴</span>

+ 2 - 2
src/pages/parkingFee/components/base/parkingFeeList.vue

@@ -28,7 +28,7 @@
             {{ item.orderNo + '-' + item.vehicleNo }}
           </div>
           <div style="color: red; margin-right: 6px">
-            {{ (item.totalPaidAmount ) | currency }}
+            {{ item.actualPayFee | currency }}
           </div>
         </div>
 
@@ -47,7 +47,7 @@
         >
           <div>停车时长 : {{ item.serviceMin | parkingTime }}</div>
           <div style="margin-right: 20px">
-            {{ item.orderStatus | orderStatus  }}
+              {{ item.refundStatus !== 'NO_REFUND' ? '已退款' : {'PAID': '支付成功', 'FAILED': '支付失败'}[item.paymentStatus || 'FAIED'] }}
             <!-- {{ ['支付成功', '支付失败', '已退款'][] item.refundStatus | orderStatus }} -->
           </div>
         </div>

+ 8 - 4
src/pages/parkingFee/components/base/parkingReceipt/parkingApplication.vue

@@ -3,7 +3,9 @@
     <!--    <wx-points-commit ref='wxPointsCommit'></wx-points-commit>-->
 
     <scroll-view class="push-box">
-      <div class="choose-invoice-header lines" @click="changeHeader">
+      <div>
+        <div style="height: 20px"></div>
+        <div class="choose-invoice-header lines" @click="changeHeader">
         <div class="invoice-header-info" v-if="headerInfo.titleName">
           <div
             class="invoice-header-name"
@@ -41,9 +43,9 @@
       <div class="part" v-if="headerInfo.titleName">
         <div class="invoice-header">
           <!-- <div class="part-item">
-          			<span class="part-item-key">开票订单号</span>
-          			<span class="part-item-value">{{ orderInfo.orderNo }}</span>
-          		</div> -->
+                <span class="part-item-key">开票订单号</span>
+                <span class="part-item-value">{{ orderInfo.orderNo }}</span>
+              </div> -->
           <div class="part-item">
             <span class="part-item-key">发票类型</span>
             <span class="part-item-value">增值税普通发票</span>
@@ -152,6 +154,8 @@
           v-model="condition.remark"
         ></textarea>
       </div>
+      <div style="height:160px"></div>
+      </div>
     </scroll-view>
     <div class="push-btn">
       <div

+ 46 - 44
src/pages/parkingFee/components/base/parkingReceipt/parkingChooseHeader.vue

@@ -2,58 +2,60 @@
   <scroll-view class="scroll-Y" scroll-y>
 <!--    <wx-points-commit ref='wxPointsCommit'></wx-points-commit>-->
 
-    <div class="choose-invoice-header" v-if="list.length">
-      <van-radio-group class="radios">
-        <div
-          class="uni-list-cell uni-list-cell-pd radio-label lines"
-          v-for="(item, index) in list"
-          :key="index"
-        >
+    <div>
+      <div class="choose-invoice-header" v-if="list.length">
+        <van-radio-group class="radios">
           <div
-            class="invoice-header-info"
-            @click="chooseHeader(item, index)"
+            class="uni-list-cell uni-list-cell-pd radio-label lines"
+            v-for="(item, index) in list"
+            :key="index"
           >
-            <!-- <div><radio :value="item.id" :checked="index === current" /></div> -->
-            <div class="invoice-header-text">
-              <div class="invoice-header-name">
-                <div class="invoice-header-name-text">
-                  {{ item.titleName
-                  }}<span class="isDefault" v-if="item.defaultOrNot"
-                >默认</span
-                >
-                </div>
-                <div class="invoice-header-name-icon">
-                  <div
-                    class="edit-header"
-                    @click.stop="changeHeader('edit', item.id, item)"
+            <div
+              class="invoice-header-info"
+              @click="chooseHeader(item, index)"
+            >
+              <!-- <div><radio :value="item.id" :checked="index === current" /></div> -->
+              <div class="invoice-header-text">
+                <div class="invoice-header-name">
+                  <div class="invoice-header-name-text">
+                    {{ item.titleName
+                    }}<span class="isDefault" v-if="item.defaultOrNot"
+                  >默认</span
                   >
-                    <img
-                      class="invoice-header-arrow"
-                      :src="editwIcon"
-                      mode="widthFix"
-                    />
                   </div>
-                  <div class="edit-header" @click.stop="delHeader(item.id)">
-                    <img
-                      class="invoice-header-arrow"
-                      :src="delwIcon"
-                      mode="widthFix"
-                    />
+                  <div class="invoice-header-name-icon">
+                    <div
+                      class="edit-header"
+                      @click.stop="changeHeader('edit', item.id, item)"
+                    >
+                      <img
+                        class="invoice-header-arrow"
+                        :src="editwIcon"
+                        mode="widthFix"
+                      />
+                    </div>
+                    <div class="edit-header" @click.stop="delHeader(item.id)">
+                      <img
+                        class="invoice-header-arrow"
+                        :src="delwIcon"
+                        mode="widthFix"
+                      />
+                    </div>
                   </div>
                 </div>
-              </div>
-              <div class="duty-paragraph">
-                税号 {{ item.taxNo }}
+                <div class="duty-paragraph">
+                  税号 {{ item.taxNo }}
+                </div>
               </div>
             </div>
           </div>
-        </div>
-      </van-radio-group>
-    </div>
-
-    <div class="choose-invoice-header noData" v-else>
-      <img class="noDataImg" :src="noDataIcon" mode="widthFix" />
-      <div class="">您还没添加发票抬头</div>
+        </van-radio-group>
+      </div>
+      <div class="choose-invoice-header noData" v-else>
+        <div style="height: 30px"></div>
+        <img class="noDataImg" :src="noDataIcon" mode="widthFix" />
+        <div class="">您还没添加发票抬头</div>
+      </div>
     </div>
     <div class="footer">
       <div
@@ -148,7 +150,7 @@ export default {
   }
   .noData {
     position: relative;
-    top: 20%;
+    top: 80%;
     transform: translateY(-50%);
     color: #cccccc;
     text-align: center;

+ 40 - 39
src/pages/parkingFee/components/base/parkingReceipt/parkingHeaderDetail.vue

@@ -1,45 +1,46 @@
 <template>
   <scroll-view class="scroll-Y" scroll-y >
-<!--    <wx-points-commit ref='wxPointsCommit'></wx-points-commit>-->
-
-    <div class="part" v-if="header.invoiceTitleType === 0">
-      <div class="part-item">
-        <span class="part-item-key">抬头类型</span>
-        <div class="part-item-value">单位</div>
-      </div>
-      <div class="part-item">
-        <span class="part-item-key">抬头名称</span>
-        <span class="part-item-value">{{ header.invoiceTitleName }}</span>
-      </div>
-      <div class="part-item">
-        <span class="part-item-key">公司税号</span>
-        <span class="part-item-value">{{ header.corporationTax }}</span>
-      </div>
-      <div class="part-item">
-        <span class="part-item-key">公司地址</span>
-        <span class="part-item-value">{{ header.companyAddress }}</span>
-      </div>
-      <div class="part-item">
-        <span class="part-item-key">公司电话</span>
-        <span class="part-item-value">{{ header.companyTel }}</span>
-      </div>
-      <div class="part-item">
-        <span class="part-item-key">开户银行</span>
-        <span class="part-item-value">{{ header.depositBank }}</span>
-      </div>
-      <div class="part-item">
-        <span class="part-item-key">开户账户</span>
-        <span class="part-item-value">{{ header.accountNumber }}</span>
-      </div>
-    </div>
-    <div class="part" v-else>
-      <div class="part-item">
-        <span class="part-item-key">抬头类型</span>
-        <div class="part-item-value">个人/非企业单位</div>
+    <!-- <wx-points-commit ref='wxPointsCommit'></wx-points-commit> -->
+    <div>
+      <div class="part" v-if="header.invoiceTitleType === 0">
+        <div class="part-item">
+          <span class="part-item-key">抬头类型</span>
+          <div class="part-item-value">单位</div>
+        </div>
+        <div class="part-item">
+          <span class="part-item-key">抬头名称</span>
+          <span class="part-item-value">{{ header.invoiceTitleName }}</span>
+        </div>
+        <div class="part-item">
+          <span class="part-item-key">公司税号</span>
+          <span class="part-item-value">{{ header.corporationTax }}</span>
+        </div>
+        <div class="part-item">
+          <span class="part-item-key">公司地址</span>
+          <span class="part-item-value">{{ header.companyAddress }}</span>
+        </div>
+        <div class="part-item">
+          <span class="part-item-key">公司电话</span>
+          <span class="part-item-value">{{ header.companyTel }}</span>
+        </div>
+        <div class="part-item">
+          <span class="part-item-key">开户银行</span>
+          <span class="part-item-value">{{ header.depositBank }}</span>
+        </div>
+        <div class="part-item">
+          <span class="part-item-key">开户账户</span>
+          <span class="part-item-value">{{ header.accountNumber }}</span>
+        </div>
       </div>
-      <div class="part-item">
-        <span class="part-item-key">抬头名称</span>
-        <span class="part-item-value">{{ header.invoiceTitleName }}</span>
+      <div class="part" v-else>
+        <div class="part-item">
+          <span class="part-item-key">抬头类型</span>
+          <div class="part-item-value">个人/非企业单位</div>
+        </div>
+        <div class="part-item">
+          <span class="part-item-key">抬头名称</span>
+          <span class="part-item-value">{{ header.invoiceTitleName }}</span>
+        </div>
       </div>
     </div>
   </scroll-view>

+ 1 - 1
src/pages/parkingFee/components/base/parkingReceipt/parkingInvoiceImage.vue

@@ -1,6 +1,6 @@
 <template>
   <scroll-view class="scroll-Y" scroll-y>
-    <wx-points-commit ref='wxPointsCommit'></wx-points-commit>
+    <!-- <wx-points-commit ref='wxPointsCommit'></wx-points-commit> -->
 
     <div class="part">
       <div class="part-item lines">

+ 25 - 23
src/pages/parkingFee/components/base/parkingReceipt/parkingOrderDetail.vue

@@ -1,28 +1,30 @@
 <template>
   <scroll-view class="scroll-Y" scroll-y >
-<!--    <wx-points-commit ref='wxPointsCommit'></wx-points-commit>-->
-
-    <div class="order-price">
-      <div class="text">开票金额</div>
-      <div class="price">¥{{ parFee }}元</div>
-    </div>
-    <div class="tab-header">缴费订单总数 <sapn class="red">{{orderList.length}}单</sapn></div>
-    <div class="order-list">
-      <div class="order-item" v-for="(item, index) in orderList" :key="index" @click="gotoDetail(item)">
-        <!-- 0:停车缴费  1:活动报名 2:积分兑换 -->
-        <template>
-          <div class="item-header">
-            <div>{{ item.orderNo }}-{{ item.vehicleNo }}</div>
-            <div class="red">¥{{ item.totalPaidAmount }}</div>
-          </div>
-          <div class="item-bottom">
-            <div>{{ item.parkName }}</div>
-            <div>入场时间: {{ item.enterTime }}</div>
-            <div>停车时长: 停车时长: {{ item.serviceMin | parkingTime }}</div>
-          </div>
-        </template>
-        <!-- <template v-else-if="item.invoiceCategory === 1"></template>
-        <template v-else-if="item.invoiceCategory === 2"></template> -->
+    <div>
+      <div style="height:20px"></div>
+      <!-- <wx-points-commit ref='wxPointsCommit'></wx-points-commit> -->
+      <div class="order-price">
+        <div class="text">开票金额</div>
+        <div class="price">¥{{ parFee }}元</div>
+      </div>
+      <div class="tab-header">缴费订单总数 <sapn class="red">{{orderList.length}}单</sapn></div>
+      <div class="order-list">
+        <div class="order-item" v-for="(item, index) in orderList" :key="index" @click="gotoDetail(item)">
+          <!-- 0:停车缴费  1:活动报名 2:积分兑换 -->
+          <template>
+            <div class="item-header">
+              <div>{{ item.orderNo }}-{{ item.vehicleNo }}</div>
+              <div class="red">¥{{ item.totalPaidAmount }}</div>
+            </div>
+            <div class="item-bottom">
+              <div>{{ item.parkName }}</div>
+              <div>入场时间: {{ item.enterTime }}</div>
+              <div>停车时长: 停车时长: {{ item.serviceMin | parkingTime }}</div>
+            </div>
+          </template>
+          <!-- <template v-else-if="item.invoiceCategory === 1"></template>
+          <template v-else-if="item.invoiceCategory === 2"></template> -->
+        </div>
       </div>
     </div>
   </scroll-view>

+ 1 - 1
src/pages/parkingFee/components/base/parkingReceipt/parkingReceipt.vue

@@ -265,7 +265,7 @@
                 class="choice_card_index choice_card_index3"
                 v-if="tabIndex == 2 && item.status === 'FAILED'"
                 style="padding-bottom: 20px;justify-content: flex-end;font-size: 20px;"
-                @click.stop="showFailureReason(item)"
+                @click.stop="showFailureReason(item.errorMessage)"
               >
               <van-icon name="info"  size="12" color="#d7d7d7" style="margin-right: 10px;"/>
                 <!-- <van-icon name="info-o" > -->

+ 1 - 1
src/pages/parkingFee/components/officeBlue/parkingFeeDetail.vue

@@ -28,7 +28,7 @@
           <div class="warp_index">
             <div>应缴</div>
             <div class="warp_index_color">
-              {{ (orderDetail.parkingRecord.totalFee / 100) | currency }}
+              {{ (orderDetail.parkingRecord.totalFeeInYuan) | currency }}
             </div>
           </div>
         </div>

+ 1 - 1
src/pages/parkingFee/components/officeBlue/parkingFeeDetailSuccess.vue

@@ -112,7 +112,7 @@
           <div class="parking-info-item">
             <span class="info-key">应缴</span>
             <span class="info-value fw">{{
-              (detail.totalFee / 100) | currency
+              (detail.totalFee ) | currency
             }}</span>
           </div>
           <div class="parking-info-item">

+ 1 - 1
src/pages/parkingFee/components/purple/parkingFee.vue

@@ -135,7 +135,7 @@
           <div class="top_down" @click="top_display" v-else><van-icon name="arrow-up" /></div>
         </div>
       </div>
-      <plate-number ref="plateKeyboard" :carType="carType" :active="active" :ind="ind" :numArr="numArr" @carnoArr="updateCarno"></plate-number>
+      <plate-number ref="plateKeyboard" :noDisBtn="[36, 37]" :carType="carType" :active="active" :ind="ind" :numArr="numArr" @carnoArr="updateCarno"></plate-number>
     </div>
   </scroll-view>
 </template>

+ 92 - 34
src/pages/parkingFee/mixins/parkingFee.js

@@ -3,8 +3,8 @@ import { REG_SOURCE } from '@/constants';
 import LoginDom from '@/components/Login/Login.vue';
 import { mapState } from 'vuex';
 import { initWxJsSdkConfig } from '@/utils/login';
-import { getPlatform } from '@/utils/index';
-import { wxToLoginCallback } from '@/utils';
+import { getPlatform,requestInit } from '@/utils/index';
+import { wxToLoginCallback, getUrlParams } from '@/utils';
 
 const app = {
   globalData: {
@@ -95,7 +95,8 @@ export default {
     },
     unlicensedInfo:{
       handler(){
-        console.log('用户是扫码进来的97', this.unlicensedInfo);
+        const member = uni.getStorageSync('member');
+        if(!member) return // 如果用户走未登录流程的话
         // 不论是否出入场,都使用此函数获取 gateId(闸口机器的ID)
         if (this.unlicensedInfo?.type && /unlicensedOut|unlicensedIn/.test(this.unlicensedInfo.type) && this.endlessLoop.length === 0) {
           // 此处记录扫码流程执行次数。如果超过一次则不再执行
@@ -119,19 +120,41 @@ export default {
       await initWxJsSdkConfig(['checkJsApi', 'scanQRCode']);
     }
     const member = uni.getStorageSync('member');
-    console.log(4141, member);
-    if (!member && !uni.getStorageSync('isLogin') && window?.toWXSendMsg) {
+    // 如果用户未登录的话,返回之后,重新获取数据用户的基础数据
+    if (!member && window?.toWXSendMsg) {
       wxToLoginCallback('parkingFee', (options) => {
-        uni.setStorageSync('isLogin', 'isLogin');
-        // console.log(126, options);
-        // if (options?.noLoginParkingFeeWebView === 'fail') {
-        //   this.loadData();
-        // } else {
-        //   this.$router.back(-1);
-        // }
+        console.log('用户是扫码进来的125', this.unlicensedInfo);
+        console.log('用户是扫码进来的126', options);
+        this.$store.commit('SET_IS_INIT', false);
+        // 请求 projectId
+        window.toWXSendMsg({
+          type: 'getProjectId',
+          options: {},
+        });
+        window.subscribe('projectId', (newOptions) => {
+          console.log('用户是扫码进来的134', newOptions);
+          this.$store.dispatch('baseInit', {
+            options: newOptions,
+            callback: () => {
+              this.$nextTick(( ) => {
+                requestInit();
+                this.getParkInfo();
+                this.$store.commit('SET_IS_INIT', true);
+                this.$nextTick(() => {
+                  // 如果是无牌车的扫码出入场
+                  if(options?.options?.type && /unlicensedIn|unlicensedOut/.test(options.options.type)) {
+                    this.$store.commit('SET_UNLICENSED_INFO', options.options);
+                    this.qrCodesRule(options.options.code);
+                  }  
+                })
+              })
+            },
+          });
+        });
       });
+      // return
     }
-
+    console.log(136, this.openid);
     if (this.openid) {
       this.getParkInfo();
       this.showSq = false;
@@ -181,7 +204,10 @@ export default {
         title: '加载中',
       });
       try {
-        const res = await parkingLots('8aaa82ea804d07cd0180516ff03b0008'); // TODO: 临时写死
+        console.log('加载车场信息', this.$store.state.lbsId);
+        // const res = await parkingLots('8aaa82ea804d07cd0180516ff03b0008'); // TODO: 临时写死
+        const res = await parkingLots(this.$store.state.lbsId); // TODO: 临时写死
+        console.log(res);
         let reg = /[;;]/g;
         this.description = res.description.replace(reg, '\r\n').replace(/\r\n/g, '<br/>');
         const carList = uni.getStorageSync('carList');
@@ -258,6 +284,7 @@ export default {
       this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
         name: 'parkingFeeDetail',
       });
+
       this.$nextTick(() => {
         this.$router.push({
           path: 'parkingFeeDetail',
@@ -391,6 +418,7 @@ export default {
     },
     // 缴费记录
     doRouter: function () {
+      this.$store.dispatch('clearUnlicensed');
       window?.toWXSendMsg({
         type: 'uni_func',
         funcName: 'setStorageSync',
@@ -408,6 +436,7 @@ export default {
     },
     // 车牌管理
     doRouter2: function () {
+      this.$store.dispatch('clearUnlicensed');
       window?.toWXSendMsg({
         type: 'uni_func',
         funcName: 'setStorageSync',
@@ -426,6 +455,7 @@ export default {
     },
     //停车发票
     doRouter1: function () {
+      this.$store.dispatch('clearUnlicensed');
       window?.toWXSendMsg({
         type: 'uni_func',
         funcName: 'setStorageSync',
@@ -454,6 +484,7 @@ export default {
     },
     //停车券兑换
     doRouter3: function () {
+      this.$store.dispatch('clearUnlicensed');
       window?.toWXSendMsg({
         type: 'uni_func',
         funcName: 'setStorageSync',
@@ -478,6 +509,7 @@ export default {
       this.tabbarActive = name
       if (name === '无牌缴费') {
         this.$store.dispatch('order/unlicensedRule', (code) => {
+
           // CAR_NOT_FOUND 车场扫描道闸入口,发现无车
           if (code === 'CAR_NOT_FOUND') {
 
@@ -495,25 +527,27 @@ export default {
         // this.qrCodesRule('e41d4d9dd5534f4aa3de88326a2e6f85')
         // return
         const runScanFn = (res) => {
-          if (res.scanType == 'QR_CODE' && res.scanType) {
+          console.log(513, res);
+          if (res.scanType && res.scanType == 'QR_CODE') {
             console.log(res.result);
             // 获取二维码参数之后,模拟提取参数
             const url = res.result;
-            if (url.indexOf('auth/') === -1) { // 单纯的code
-              console.log('提取到的参数', res.result);
-              this.qrCodesRule(res.result)
-              // this.getPaperCouponInfo(res.result);
-            } else { // 从url中提取参数
-              const start = url.indexOf('auth/');
-              const end = url.indexOf('?');
-              const params = url.slice(start, end).split('/');
-              if (params && params.length) {
-                const couponCode = params[1];
-                console.log('提取到的参数', couponCode);
-                this.qrCodesRule(couponCode)
-                // this.getPaperCouponInfo(couponCode);
-              }
+            const {path} = getUrlParams(res.result)
+            let params = null
+            if(path) {
+              params = getUrlParams(decodeURIComponent(path))
             }
+            /*
+            微信扫码之后,处理过的参数 {"code": "e41d4d9dd5534f4aa3de88326a2e6f85", "type": "unlicensedIn#wechat-redirect"}
+            */
+            if (params?.type.indexOf('wechat-redirect') > -1) {
+              params.type = params.type.replace('#wechat-redirect', '');
+            }
+            console.log('微信扫码之后,处理过的参数', params);
+            this.$store.commit('SET_UNLICENSED_INFO', params);
+            this.$nextTick(() => {
+              this.qrCodesRule(params.code);
+            })
           }
         };
         // 微信小程序
@@ -555,20 +589,42 @@ export default {
         window.localStorage.setItem('buildingId', qrCodesres.buildingId);
         // 如果是无牌车扫码:出场
         console.log('模拟出场', this.unlicensedInfo.type);
+        this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
+          name: 'parkingFeeDetail',
+        });
         // return
         if (this.unlicensedInfo?.type === 'unlicensedOut') {
-          // 查询用户是否存在车牌
-          this.$store.dispatch('order/unlicensedRule', (vehicleNo) => {
+          this.$router.push({
+            path: 'parkingFeeDetail',
+            query: {
+              type: 'success',
+              gateId: qrCodesres.gateId,
+              vehicleNo: '',
+              type: this.unlicensedInfo.type
+            } 
+          })
+          // const res = await unlicensedCarCheckout({
+          //   gateId: qrCodesres.gateId
+          // });
+          // console.log(595, res);
+          // return
+          // 查询用户是否存在车牌(出场扫码不查询车牌,直接前往支付页面)
+          /*this.$store.dispatch('order/unlicensedRule', (vehicleNo) => {
+            if(vehicleNo === 'error') {
+
+              return
+            }
             // 出场前,扫码缴费
             this.$router.push({
               path: 'parkingFeeDetail',
               query: {
                 type: 'success',
                 gateId: qrCodesres.gateId,
-                vehicleNo: vehicleNo
+                vehicleNo: vehicleNo,
+                type: this.unlicensedInfo.type
               }
             })
-          });
+          });*/
           return
         }
         // 如果是无牌车扫码:入场
@@ -601,7 +657,9 @@ export default {
     },
     // 前往支付
     unlicensedToPay() {
-      this.toHandleSearch(this.unlicensedCar)
+      // 无牌车这边去支付的时候,属于场内缴费,需要调用场内缴费的接口 /parking/check-out
+      this.$store.commit('SET_ENDLESS_LOOP', '');
+      this.toHandleSearch(this.unlicensedCar);
     }
   },
 };

+ 3 - 2
src/pages/parkingFee/mixins/parkingFeeCoupon.js

@@ -28,6 +28,7 @@ export default {
       coupons: (state) => state.order.coupons,
       maxOneDayDiscountFee: (state) => state.order.maxOneDayDiscountFee, // 深圳单日单次使用上限
       usingTotalDiscount: (state) => state.order.usingTotalDiscount, // 当前已使用优惠
+      availableDiscountFee: (state) => state.order.availableDiscountFee, // 当前已使用优惠
     }),
   },
 
@@ -53,7 +54,7 @@ export default {
        * 2、superposition  叠加使用规则 (1不可叠加,2仅同类型可叠加,3可叠加);
        * */
       this.couponList = [...this.coupons];
-      this.remainPrice = this.usingTotalDiscount * 1;
+      this.remainPrice = this.availableDiscountFee * 1;
       if (this.couponList.length) {
         this.couponList = this.couponList.map((elm, index) => {
           elm.disabled = true;
@@ -313,7 +314,7 @@ export default {
        // });
        }*/
       // 深圳超限处理
-      if (parkMallCode === 5 && this.remainPrice  > actualPayFee) {
+      if (parkMallCode === 5 && this.remainPrice  <= actualPayFee) {
         return Toast({
           message: `每日最高可抵扣${this.remainPrice}元`,
           icon: 'none',

+ 71 - 27
src/pages/parkingFee/mixins/parkingFeeDetail.js

@@ -37,6 +37,7 @@ export default {
         title: '停车支付',
       });
     }, 300);
+    this.pageInit();
   },
   computed: {
     ...mapState({
@@ -63,6 +64,7 @@ export default {
       enableConsume: (state) => state.order.enableConsume,
       unitAmount: (state) => state.order.unitAmount,
       unlicensedInfo: state => state.unlicensedInfo,
+      endlessLoop: (state) => state.endlessLoop,
       appId: state => state.appId,
     }),
     // 支付按钮状态
@@ -70,22 +72,22 @@ export default {
       // 当存在待支付金额 或者 用户登陆
       return !this.orderDetail?.parkingRecord?.totalFeeInYuan || (JSON.stringify(this.member) !== '{}' && !this.orderDetail.parkInfo);
     },
-    integralDesc() {
-      if (this.pointsTime > 0) {
-        // 深圳特殊处理(单位:金额)
-        if (this.orderDetail.parkInfo.parkMallCode === 5 || this.orderDetail.parkInfo.parkMallCode === 999) {
-          return `已选择兑换${this.pointsTime}元`;
-        }
-        return `已选择兑换${this.pointsTime}小时`;
-      }
-      if (this.bonusCopy < this.integral) {
-        return `${this.integral}积分可停车1小时`;
-      }
-      if (this.orderDetail.parkInfo.parkMallCode === 3 && app.globalData.member?.currnentintegral >= this.integral && !this.bonus) {
-        return `今日已达上限`;
-      }
-      return `${this.available}积分可减免`;
-    },
+    // integralDesc() {
+    //   if (this.pointsTime > 0) {
+    //     // 深圳特殊处理(单位:金额)
+    //     if (this.orderDetail.parkInfo.parkMallCode === 5 || this.orderDetail.parkInfo.parkMallCode === 999) {
+    //       return `已选择兑换${this.pointsTime}元`;
+    //     }
+    //     return `已选择兑换${this.pointsTime}小时`;
+    //   }
+    //   if (this.bonusCopy < this.integral) {
+    //     return `${this.integral}积分可停车1小时`;
+    //   }
+    //   if (this.orderDetail.parkInfo.parkMallCode === 3 && app.globalData.member?.currnentintegral >= this.integral && !this.bonus) {
+    //     return `今日已达上限`;
+    //   }
+    //   return `${this.available}积分可减免`;
+    // },
   },
   filters: {
     parkingTime(val) {
@@ -101,23 +103,22 @@ export default {
       return `${minutes}分钟`
     },
   },
-  created() {
-    this.pageInit();
-  },
   methods: {
     // 前往支付
     async toPay() {
-      const { parkingRecord, discountInfo = {} } = this.orderDetail;
+      const { parkingRecord, discountInfo = {}, parkingRule = {}} = this.orderDetail;
       const { coupons, points } = discountInfo
+      const { hourPrice } = parkingRule
       try {
         const params = {
           // vehicleNo: '', // 车牌号
           // points
           parkingRecord: {
+            ...parkingRecord,
             vehicleNo: parkingRecord.vehicleNo,
             enterTime: parkingRecord.enterTime,
             serviceMin: parkingRecord.serviceMin,
-            totalFee: parkingRecord.totalFee, //应缴
+            totalFee: parkingRecord.totalFeeInYuan, //应缴
             actualPayFee: this.actualPayFee, //应付金额
           },
           discountInfo: {
@@ -130,9 +131,9 @@ export default {
           // 15 兑换 5元
           const { pointsPerUnit, unitAmount, discountFee, available } = points[0]
           params.discountInfo.points = {
-            "discountTime": discountFee / pointsPerUnit,
+            "discountTime": discountFee / hourPrice * 60,
             "discountFee": discountFee,
-            "discountPoints": discountFee * (unitAmount / pointsPerUnit)
+            "discountPoints": discountFee / hourPrice * pointsPerUnit
           }
         }
         // 优惠券
@@ -140,6 +141,9 @@ export default {
           const selectedCoupons = coupons.filter(elm => {
             const selected = elm.hasOwnProperty('selected') ? elm.selected : elm.defaultSelected;
             return selected
+          }).map(elm => {
+            elm.discountTime = elm.discountFee / hourPrice * 60
+            return elm
           })
           if (selectedCoupons.length) {
             params.discountInfo.coupons = selectedCoupons
@@ -241,12 +245,12 @@ export default {
               });
             }
           } else {
-            // this.reCreateParkOrder();
+            this.reCreateParkOrder();
           }
         })
         .catch((err) => {
           console.log(1854, err);
-          // this.reCreateParkOrder();
+          this.reCreateParkOrder();
         });
     },
     // 支付失败后返还优惠券
@@ -278,6 +282,7 @@ export default {
         message: '支付失败',
         confirmButtonColor: '#333',
       }).then(() => {
+        this.$refs.countDown.reset(); // 停车场重置费用倒计时3分钟
         this.$store.dispatch('order/orderInit', {
           gateId: this.$route.query?.gateId,
           vehicleNo: this.$route.query?.vehicleNo,
@@ -315,7 +320,29 @@ export default {
           gateId: this.$route.query?.gateId,
           endlessLoop: this.endlessLoop,
           callback: (res) => {
-            console.log(303, res);
+            setTimeout(() => {
+              this.$store.dispatch('clearUnlicensed');
+            }, 700);
+            // 如果 无牌车扫码出场扫码 无需缴费,直接展示无需缴费页面
+            if(/unlicensedOut/.test(res.code) && res?.unlicensed) {
+              this.$router.replace({
+                path: 'parkingFeeMsg?type=pay',
+              });
+              return
+            }
+            // 如果是无需缴费的话,提示用户无需缴费
+            if (res?.orderDetail?.parkingRecord?.totalFee <= 0) {
+              this.$store.dispatch('order/orderInitRule', res.orderDetail);
+                setTimeout(() => {
+                  Dialog.alert({
+                    message: '当前无需缴费',
+                    confirmButtonColor: '#333',
+                  }).then(() => {
+                    this.$router.back()
+                  });
+                }, 1000)
+              return
+            }
             if (/NOT_FOUND|PARKING_RECORD_NOT_FOUND/.test(res.code)) {
               // 当前车辆没有查到账单
               this.$router.replace({
@@ -327,13 +354,16 @@ export default {
               });
               return
             }
-            if (res.code === "INTERNAL_SERVER_ERROR") {
+            if (/LOCAL_PARK_ERROR|INTERNAL_SERVER_ERROR|VALIDATION_FAILED|PLEASE_SCAN_QRCODE/g.test(res.code)) {
               setTimeout(() => {
                 this.$router.back()
               }, 1000)
             }
           }
         });
+        setTimeout(() => {
+          this.$store.dispatch('clearUnlicensed');
+        }, 1200);
       } catch (err) {
         console.log('查询车辆是否在场的报错信息?', err, err.code === "INTERNAL_SERVER_ERROR");
         // 如果网络异常(这里是因为订单页面存在空白场景,才需要单独处理报错交互)
@@ -381,6 +411,13 @@ export default {
       return 1;
     },
     coupon() {
+      // 如果没有电子券的话,提示用户
+      if (this.coupons.length === 0) {
+      uni.showToast({
+        title: '暂无可使用的优惠券,请前往积分商城兑换优惠券'
+      })
+        return
+      }
       this.$router.push({
         path: 'parkingFeeCoupon',
       });
@@ -425,6 +462,13 @@ export default {
         pagePath = 'parkingFeeMsg?type=pay'
       }
       return pagePath
+    },
+    pointsMathCallback({type, message}) {
+      // console.log(465, type);
+      Toast({
+        message: message,
+        icon: 'none',
+      });
     }
   },
 };

+ 6 - 14
src/pages/parkingFee/mixins/parkingFeeList.js

@@ -36,27 +36,19 @@ export default {
       uni.setNavigationBarTitle({
         title: '缴费记录',
       });
-    }, 300);
+    }, 301);
+    this.$store.dispatch('clearUnlicensed');
     this.list = [];
     // 重新获取数据
     canloading = true;
     pageNum = 0;
     const member = uni.getStorageSync('member');
-    // console.log('用户不走未登录', !uni.getStorageSync('loadData'));
-    if (member) {
-      this.loadData();
-    } else if(!uni.getStorageSync('loadData')){
+    this.loadData();
+    if(!uni.getStorageSync('loadData') && !member){
+      uni.setStorageSync('loadData', 'loadData')
       wxToLoginCallback('parkingFeeList', (options) => {
-        // console.log(229, options);
-        uni.setStorageSync('loadData', 'loadData')
-        if (options?.noLoginParkingFeeWebView === 'fail') {
-          this.loadData();
-        } else {
-          this.$router.back(-1);
-        }
+        this.loadData();
       });
-    } else {
-      this.loadData();
     }
   },
   filters: {

+ 5 - 15
src/pages/parkingFee/mixins/parkingReceipt/parkingApplication.js

@@ -216,14 +216,11 @@ export default {
           });
           const headerInfo = list[currentIndex] || {};
           self.headerInfo = headerInfo;
-        } else {
-          Toast({
-            message: '服务器开小差了呢,请您稍后再试',
-          });
         }
-      } catch {
+      } catch(err) {
+        console.log(111, err)
         uni.showToast({
-          title: '服务器开小差了呢,请您稍后再试',
+          title: err.langMessage,
           icon: 'none',
         });
       }
@@ -427,16 +424,9 @@ export default {
       this.$router.replace({
         path: 'parkingReceipt',
       });
-    } else {
-      Toast({
-        message: '服务器开小差了呢,请您稍后再试',
-      });
     }
-  } catch {
-    uni.showToast({
-      title: '服务器开小差了呢,请您稍后再试',
-      icon: 'none',
-    });
+  } catch (err) {
+    console.log(111, err);
   }
 //   uni.request({
 //   // url: self.$baseURL + 'api/1.0/invoice/addMyInvoiceInfo',

+ 4 - 4
src/pages/parkingFee/mixins/parkingReceipt/parkingReceipt.js

@@ -85,6 +85,7 @@ export default {
         title: '停车发票',
       });
     }, 300);
+    this.$store.dispatch('clearUnlicensed');
     if (JSON.stringify(this.member) !== '{}') {
       this.invoice(1);
     } else {
@@ -409,13 +410,12 @@ export default {
        this.totalNum = totalNum;
        } */
     },
-    showFailureReason(item) {
-      console.log(458, item);
+    showFailureReason(reson) {
       this.$dialog({
         title: '开票失败原因',
-        message: '',
+        message: reson,
         confirmButtonText: '关闭',
-        confirmButtonColor: '#064c8a',
+        confirmButtonColor: '#644A79',
       }).then(() => {
         // on confirm
         console.log('confirm');

+ 14 - 48
src/pages/parkingFee/mixins/vehicleManagement.js

@@ -49,30 +49,7 @@ export default {
   },
 
   async created() {
-    const option = this.$route.query;
-    this.options = option;
-    await this.$onLaunched;
-    this.localimgPic = this.$staticPicUrl + '/wxminilocalimg/parkingFee/';
-    // #ifdef H5
-    app.globalData.member = JSON.parse(uni.getStorageSync('member'));
-    // #endif
-    // 场景二维码记录(是否扫码进入)
-    app.globalData.paramsScene = {};
-    this.$saveSceneQrcodeDetail(
-      'page',
-      'vehicleManagement',
-      '车牌管理',
-      '',
-      '',
-      '',
-      ''
-    );
-    // 埋点本地化
-    this.preUrl = uni.getStorageSync('previousUrl');
-    uni.setStorageSync(
-      'previousUrl',
-      '/pages/parkingFee/vehicleManagement.vue'
-    );
+    this.options = this.$route.query;
   },
   async mounted() {
     setTimeout(() => {
@@ -80,39 +57,28 @@ export default {
         title: '车辆管理',
       });
     }, 300);
-    // await this.$onLaunched
-    this.isBeijing = isCruMarketByKey('北京');
+    this.$store.dispatch('clearUnlicensed');
     const member = uni.getStorageSync('member');
-    if (JSON.stringify(this.member) !== '{}') {
+    if (member && JSON.stringify(this.member) !== '{}') {
       this.getKipMemberVehicles();
     } else {
       wxToLoginCallback('vehicleManagement', (options) => {
-        // console.log(229, options);
         if (options?.noLoginParkingFeeWebView === 'fail') {
           // 如果是用户明确拒绝登录,执行这段逻辑
-          Toast({
-            message: '您还未登录,请登录',
-            icon: 'none',
-            onClose: () => {
-              this.$router.back();
-            },
-          });
+          setTimeout(() => {
+            Toast({
+              message: '您还未登录,请登录',
+              icon: 'none',
+              onClose: () => {
+                this.$router.back();
+                return
+              },
+            });
+          }, 300)
         } else {
           this.$router.back();
         }
       });
-      // const regSource = REG_SOURCE.PARKING;
-      // app.globalData.regSource = regSource;
-      // if (this.options?.regSource) {
-      //   app.globalData.regSource = REG_SOURCE[this.options?.regSource];
-      // }
-      // if (this.options?.tpName) {
-      //   app.globalData.tpName = this.options?.tpName;
-      // }
-      // // this.$refs.authorize.login('/pages/parkingFee/parkingFee', () => {
-      // //   this.getKipMemberVehicles()
-      // // })
-      // this.getKipMemberVehicles();
     }
   },
   onUnload() {
@@ -144,7 +110,7 @@ export default {
       this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
         name: 'parkingFeeDetail',
       });
-      uni.setStorageSync('carList', [...new Set([carno, ...JSON.parse(uni.getStorageSync('carList'))])].slice(0, 6));
+      uni.setStorageSync('carList', [...new Set([carno, ...JSON.parse(uni.getStorageSync('carList') || '[]')])].slice(0, 6));
       this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
         name: 'parkingFeeDetail',
       });

+ 8 - 5
src/store/index.js

@@ -51,7 +51,7 @@ const store = new Vuex.Store({
     source: '', // 访问方:微信小程序:(CRM|KIP)
     brandInfo: {},
     curMarket: {},
-    isInit: true, // 当内嵌在小程序中的H5页面,没有接收到小程序数据时,默认显示骨架屏幕
+    isInit: false, // 当内嵌在小程序中的H5页面,没有接收到小程序数据时,默认显示骨架屏幕
     // 无牌车
     unlicensedInfo: '',
     // 防止用户在无牌车流程中卡死
@@ -159,7 +159,6 @@ const store = new Vuex.Store({
     },
     // 无牌车
     SET_UNLICENSED_INFO(state, payload) {
-      console.log('用户扫码进入的', payload);
       state.unlicensedInfo = payload;
     },
     SET_ENDLESS_LOOP(state, payload) {
@@ -233,10 +232,10 @@ const store = new Vuex.Store({
         commit('SET_GROUP_ID', groupId);
         commit('SET_MALL_ID', mallId);
         commit('SET_BRAND_ID', brandId);
-        console.log('用户扫码进入的', unlicensedInfo, unlicensedInfo?.type);
+        // console.log('用户扫码进入的', unlicensedInfo, unlicensedInfo?.type);
         // 如果是无牌车
         if (unlicensedInfo?.type) {
-          console.log('用户扫码进入的', unlicensedInfo);
+          // console.log('用户扫码进入的', unlicensedInfo);
           commit('SET_UNLICENSED_INFO', unlicensedInfo)
           // commit('SET_ENDLESS_LOOP', true)
         }
@@ -250,7 +249,7 @@ const store = new Vuex.Store({
          commit('SET_MALL_ID', '8a888aed7d0295e5017d029ff1f40000');
          }*/
         commit('SET_LBS_ID', lbsId);
-        commit('SET_OPENID', openid);
+        commit('SET_OPENID', openid || uni.getStorageSync('openid'));
         if (isLogin) {
           commit('SET_ACCESS_TOKEN', accessToken);
           commit('SET_KIP_USER_ID', kipUserId);
@@ -284,6 +283,10 @@ const store = new Vuex.Store({
       commit('SET_USER_INFO', res.data);
       // console.log('user_info', res);
     },
+    clearUnlicensed({state, commit}) {
+      commit('SET_UNLICENSED_INFO', '');
+      commit('SET_ENDLESS_LOOP', '');
+    }
   },
   modules: {
     cachedViews,

+ 100 - 22
src/store/order.js

@@ -2,9 +2,13 @@ import { checkOut, calculateDiscount, ordersAndPrepay, currentUnlicensedPlate, u
 
 // import checkOutQHResponse from '@/api/mockData/checkout.qh3.response.json'
 // import checkOutQHResponse from '@/api/mockData/checkout.hz.response.json';
-// import checkOutQHResponse from '@/api/mockData/checkout.qh5  .response.json'
+// import checkOutQHResponse from '@/api/mockData/checkout.qh6.response.json'
 // import unlicensedCarCheckInResponse from '@/api/mockData/unlicensedCarCheckIn.qh.response.json';
 
+/* 
+([a-z]*):(.*),
+state.$1 =$2;
+ */
 // 大于等于停车费
 // 微服务接口字段
 const state = {
@@ -130,6 +134,40 @@ const mutations = {
   setUnlicensedCar(state, payload) {
     state.unlicensedCar = payload;
   },
+  // 订单初始化
+  clearOrderInfo(state) {
+    state.orderDetail = {}; // 订单原始数据
+    state.isShowDiscounts = false; // 是否展示会员登记优惠
+    state.discountDesc = ''; // 停车优惠(首停、会员减免、消费减免)
+    state.checkedTotal = 0; // 选中count数
+    state.enableNewMemberPoints = false; // 是否开启新会员积分
+    state.enablePoints = false; // 是否开启积分减免
+    state.usePoints = 0; // 用户已选择的积分
+    state.isFirst = 0; // 判断用户是否首次进入
+    state.integralDesc = ''; // 积分减免说明文案
+    state.pointsPerHour = 0; // 每小时兑换积分
+    state.enableCoupon = false; // 电子优惠券是否启用
+    state.maxOneDayCoupons = 0; // 单日可选优惠券上限
+    state.coupons = []; // 可选优惠券数量
+    state.couponCount = 0; // 已选择优惠券
+    state.couponDesc = ''; // 优惠券说明文案
+    state.enablePaperCoupons = false; // 启动纸质优惠券
+    state.usingTotalDiscount = 0; // 优惠金额
+    state.actualPayFee = 0; // 应付金额
+    state.availableDiscountFee = 0; // 当日剩余可使用优惠金额
+    // 积分相关
+    state.available = 0; // 用户可用积分
+    state.maxPointsTime = ''; // 积分最大兑换时长
+    state.pointsTime = ''; // 已兑换的积分时间
+    state.unitAmount = 0;
+    // 停车优惠:会员等级和消费减免
+    state.memberLevelDiscount = false; // 是否开启会员等级
+    state.enableConsume = false; // 是否开启消费减免
+    state.pointsPerUnit = 0; //
+    // unlicensed: false // true: 临时车牌;false:普通车牌
+    // 无牌车逻辑
+    state.unlicensedCar = '';
+  }
 };
 
 const actions = {
@@ -141,24 +179,34 @@ const actions = {
    * @param {*} param1.callback  回调函数,用于接口报错时,展示对应的信息
    * @param {*} param1.endlessLoop 用于判断当前用户是否扫码进入 
    */
-  async orderInit({ commit, dispatch, state }, { gateId='124p3LK1', vehicleNo = '浙A616A1', callback, endlessLoop }) {
+  async orderInit({ commit, dispatch, state }, { gateId = '124p3LK1', vehicleNo = '浙A616A1', callback, endlessLoop }) {
     try {
-      const unlicensed = vehicleNo.indexOf('临') > -1; // true: 临时车牌;false:普通车牌
+      commit('clearOrderInfo');
+      const unlicensed = vehicleNo.indexOf('临') > -1 || !vehicleNo; // true: 临时车牌;false:普通车牌
       // const res = await checkOut('浙A616A1');
       // const res = await checkOut('闽AAQ5519', unlicensed);
       // const res = await checkOut('粤A51113');
       // const res = await checkOut('沪DCJ986');
       // console.log('无牌车扫码出场', endlessLoop);
       // 场内缴费,调 check-out 接口,
-      const method = unlicensed && endlessLoop ? unlicensedCarCheckout : checkOut
+      const method = unlicensed && endlessLoop || !vehicleNo ? unlicensedCarCheckout : checkOut
       const res = await method(vehicleNo, false, gateId);
+      if (res?.parkingRecord?.totalFee <= 0) {
+        callback && callback({
+          unlicensed,
+          endlessLoop,
+          code: endlessLoop,
+          orderDetail: res,
+        }); // 统一处理错误原因
+        return
+      }
       // console.log(vehicleNo, res);
       // 所有的优惠时间长转为金额
-      // console.log(112, '所有的优惠时间长转为金额');
+      console.log(112, '所有的优惠时间长转为金额');
       // dispatch('orderInitRule', checkOutQHResponse);
       dispatch('orderInitRule', res);
     } catch (error) {
-      // console.log('151151151151151', error);
+      console.log('151151151151151', error);
       /* if (/NOT_FOUND|PARKING_RECORD_NOT_FOUND/.test(error.code)) {
         callback && callback(error)
       } */
@@ -168,12 +216,14 @@ const actions = {
   orderInitRule({ commit, dispatch, state }, checkOutResponse) {
     console.log(119, checkOutResponse);
     // 记录buildingId
-    window.localStorage.setItem('buildingId', checkOutResponse.parkInfo.buildingId);
+    if (checkOutResponse?.parkInfo?.buildingId) {
+      window.localStorage.setItem('buildingId', checkOutResponse.parkInfo.buildingId);
+    }
     commit('setOrderDetail', checkOutResponse);
     const isShowDiscounts = checkOutResponse?.parkingRule?.enableCoupon || false;
     // 是否展示优惠
     commit('setIsShowDiscounts', isShowDiscounts);
-    if(isShowDiscounts) {
+    if (checkOutResponse.parkingRule) {
       // 会员等级减免
       // 停车优惠(首停、会员减免、消费减免)
       dispatch('getCheckedTotal', checkOutResponse);
@@ -186,12 +236,16 @@ const actions = {
       // 处理电子优惠券相关逻辑
       dispatch('couponRule', checkOutResponse);
       // 纸质优惠券(hold)
-      commit('setEnablePaperCoupons', checkOutResponse?.parkingRule?.enablePaperCoupons || []);
+      commit('setEnablePaperCoupons', checkOutResponse?.parkingRule?.enablePaperCoupons || false);
       // 其他数据收集
       commit('setUsingTotalDiscount', checkOutResponse?.discountInfo?.usingTotalDiscount || 0);
+      // console.log(191, checkOutResponse?.parkingRecord.hasOwnProperty(actualPayFee));
+    }
+    if (checkOutResponse?.parkingRecord?.hasOwnProperty('actualPayFee')) {
+      commit('setActualPayFee', checkOutResponse.parkingRecord?.actualPayFee);
+    } else {
+      commit('setActualPayFee', checkOutResponse.parkingRecord?.totalFeeInYuan);
     }
-    console.log('190190190190', checkOutResponse);
-    commit('setActualPayFee', checkOutResponse.parkingRecord?.actualPayFee || checkOutResponse.parkingRecord?.totalFeeInYuan || 0.00);
   },
   // 停车优惠(首停、会员减免、消费减免)
   getCheckedTotal({ commit, dispatch }, orderDetail) {
@@ -265,7 +319,7 @@ const actions = {
     commit('setMaxOneDayDiscountFee', maxOneDayDiscountFee);
     commit('setPointsPerHour', pointsPerUnit);
     commit('setUnitAmount', unitAmount);
-    commit('setIntegralDesc', label);
+    commit('setIntegralDesc', discountFee ? `已选择兑换${discountFee}元` : available > pointsPerUnit ? `${available}积分可减免` : `${pointsPerUnit}积分可停车1小时`); // 积分优惠处的描述
   },
   // 当前最大可选优惠时间
   /*
@@ -307,29 +361,47 @@ const actions = {
   },
 
   // 积分减免
-  pointsMath({ commit, dispatch, state }, { type }) {
+  pointsMath({ commit, dispatch, state }, { type, callback }) {
     /**
      * maxDiscountFee 单次最大可使用金额 
      * availableDiscountFee 当日剩余可使用优惠金额
      * available 当前用户的剩余积分,也可以说是可以抵扣的积分,如果有积分抵扣自动勾选,那么这个值=这个值-已勾选积分
      */
-
-    // console.log('289289289289289289289289', state.available / (state.pointsPerUnit / state.unitAmount) + state.pointsTime);
     // 计算用户当前的最大可使用积分的总数(单位:元)
     let maxPointsTime = state.available / (state.pointsPerUnit / state.unitAmount) + state.pointsTime;
     if (maxPointsTime > state.maxDiscountFee) {
       maxPointsTime = state.maxDiscountFee
     }
+    let msg = ''
     // 验证最大积分的总数(单位:元)
     if (maxPointsTime > state.availableDiscountFee) {
       maxPointsTime = state.availableDiscountFee
     }
-    console.log(303, maxPointsTime);
+    if (type === 'add' && state.pointsTime >= maxPointsTime) {
+      // 以下是深圳积分上限规则
+      // 超出抵扣上限,每日最高可抵扣${this.parkFee.parkInfoEntity.maxOneDayHour}元 '优惠金额' >= '每日最高可抵扣'
+      if (state.usingTotalDiscount >= state.maxOneDayDiscountFee) {
+        msg = `超出抵扣上限,每日最高可抵扣${state.maxDiscountFee}元`
+      }
+      // 超出抵扣上限,每次最高可抵扣${this.integralMaxMoney}元 '积分兑换时长' >= '深圳前海停车积分上限'
+      if (state.pointsTime >= state.maxPointsTime) {
+        msg = `超出抵扣上限,每次最高可抵扣${state.maxDiscountFee}元`
+      }
+      callback({
+        message: msg
+      });
+      return
+    }
     if (type === 'add' && state.pointsTime < maxPointsTime) {
       const pointsTime = state.pointsTime + state.unitAmount;
-      // 如果是深圳车场
-      commit('setAvailable', state.available - state.pointsPerUnit);
-      commit('setPointsTime', pointsTime);
+      const available = state.available - state.pointsPerUnit;
+      const usingTotalDiscount = state.usingTotalDiscount + state.unitAmount; // 重新计算已经使用的优惠逻辑
+      if (available > -1) {
+        // 如果是深圳车场
+        commit('setAvailable', available);
+        commit('setPointsTime', pointsTime);
+        commit('setUsingTotalDiscount', usingTotalDiscount);
+      }
     }
     if (type === 'minus' && state.pointsTime > 0) {
       const pointsTime = state.pointsTime - state.unitAmount;
@@ -470,6 +542,7 @@ const actions = {
         }
       });
       commit('setCouponCount', couponCount);
+      console.log(479, couponCount);
       if (couponCount > 0) {
         return commit('setCouponDesc', `已选择${couponCount}张优惠劵`);
       } else {
@@ -478,6 +551,8 @@ const actions = {
         }
         return commit('setCouponDesc', `暂无可用优惠券`);
       }
+    } else {
+      commit('setCouponDesc', `暂无可用优惠券`);
     }
   },
 
@@ -495,13 +570,15 @@ const actions = {
       console.log('无牌车的查询记录', res);
       commit('setUnlicensedCar', res.vehicleNo);
       // 如果是扫码进入的用户,在出场时需要重新扫码,这时会在此处传入的一个回调函数,在获取到临牌时,返回给 qrCodesRule 函数
-      if(res.vehicleNo && callback) {
+      if (res.vehicleNo && callback) {
         callback(res.vehicleNo);
+      } else {
+        callback('error');
       }
     } catch (err) {
       console.log(err);
     }
-  }
+  },
 
   // 是否展示优惠
   // getIsShowDiscounts({commit, dispatch}, orderDetail) {
@@ -512,12 +589,13 @@ const actions = {
   /*
    如果积分发生变化
    */
+
 };
 
 export default {
   //开启命名模块
   namespaced: true,
-  state,
+  state: state,
   mutations,
   actions,
 };

+ 140 - 3
src/utils/index.js

@@ -1,5 +1,10 @@
+import { createAxiosByinterceptors } from '@/api/request';
+import Stomp from "@/lib/stompjs";
+import { Decrypt,Encrypt } from "@/utils/crypto";
+import SockJS from "@/utils/sockjs";
 import qs from 'qs';
 import { lbsDictionary } from '@/common/js/BaseDictionary';
+import uni from './uniHooks';
 
 export function getMobileOperatingSystem() {
   // #ifdef H5
@@ -132,8 +137,10 @@ export function getGroupIdAndMallIdByLsbId(lbsId) {
 
 // 微信小程序端登录之后的回调
 export function wxToLoginCallback(path, callback) {
+  const oldPath = uni.getStorageSync('oldPath');
   // 如果是在微信小程序内部运行的话
-  if (getIsMin()) {
+  if (getIsMin() && oldPath !== path) {
+    uni.setStorageSync('oldPath', path);
     // 前往登录
     window.toWXSendMsg({
       type: 'toLogin',
@@ -144,8 +151,10 @@ export function wxToLoginCallback(path, callback) {
     window.subscribe('callback', (options) => {
       console.log('登录页面的回调', JSON.stringify(options));
       if (options.isReload) {
+        console.log('刷新页面');
         window.location.reload();
       } else {
+        console.log('刷新页面:callback');
         callback && callback(options);
       }
     });
@@ -153,6 +162,134 @@ export function wxToLoginCallback(path, callback) {
   }
   // 如果是在微信公众号环境运行的话
   /*if ( getIsWxh5() ) {
-    return
-  }*/
+   return
+   }*/
+}
+
+export function initEnv() {
+  const href = window.location.href;
+  console.log('当前页面的url地址  ', href);
+  if (/dev-|8080/.test(href)) {
+    // window.env = 'qa';
+    // window.profileApi = 'https://qa-apim.kerryplus.com/c/api';
+    // window.api = 'qaApi';
+    window.env = 'dev';
+    window.profileApi = 'https://dev-gateway-kip.kerryonvip.com/api';
+    window.api = 'devApi';
+    return;
+  }
+  if (/qa-/.test(href)) {
+    window.env = 'qa';
+    window.api = 'qaApi';
+    window.profileApi = 'https://qa-apim.kerryplus.com/c/api';
+    return;
+  }
+  window.env = 'prod';
+  window.profileApi = 'https://apim.kerryplus.com/c/api';
+  window.api = 'api';
+}
+
+export function requestInit() {
+  let baseURL = window.profileApi + '/temporary-parking/v1';
+  if (window.location.href.indexOf('parking.') < 0) {
+    baseURL = '/msApi';
+  }
+  window.requestms = createAxiosByinterceptors({
+    // baseURL: `https://dev-kip-service-internal.kerryonvip.com/`,
+    // baseURL: `http://tp.hht.test/`,
+    // baseURL: window.profileApi, // TODO: 微服务发布到DEV环境之后取消注释
+    baseURL,
+    // baseURL: `/msApi`,
+  });
+}
+
+// websocket 链接
+export function getUrl() {
+  return `https://crm.kerryplus.com/xcrm-api`; // TODO: 临时更改websocket域名为prod
+  // 如果 kerry+ 这边的访问环境是 sl 或者 lt,需要把 wss 指向 qa 环境。
+  const href = `${window.location.href}`;
+  if (/dev-|8080/.test(href)) {
+    return 'https://qa-crm-kpl.kerryprops.com.cn/xcrm-api';
+  }
+  if (/qa-/.test(href)) {
+    return 'https://qa-crm-kpl.kerryprops.com.cn/xcrm-api';
+  }
+  // return 'https://qa-crm-kpl.kerryprops.com.cn/xcrm-api';
+  return `https://crm.kerryplus.com/xcrm-api`;
+}
+
+export function windowSendInit() {
+  const token = window.token;
+  window.toWXSendMsg = function ({ type = '', funcName = '', options = {} }) {
+    /**
+     * 向小程序端发送消息
+     */
+    if (!type) return;
+    window.stompClient.send(
+      '/sendToWechat',
+      {},
+      JSON.stringify({
+        token,
+        data: Encrypt(
+          JSON.stringify({
+            type: type,
+            funcName,
+            options,
+          })
+        ),
+      })
+    );
+  };
+
+  // 主动订阅事件回调
+  window.subscribe = function (type, callback) {
+    const subscribeId = window.stompClient.subscribe('/user/' + token + '/toH5', function (response) {
+      try {
+        let res = {
+          token: '', // 微信小程序端 页面的传递过来的token
+          data: '', // 微信小程序端 页面的传递过来的信息(已加密)
+        };
+        if (response.body) {
+          res = JSON.parse(response.body);
+        }
+        // 检查 微信小程序端 发送过来的信息和token是否与当前页面的 token一致。并且 res.data 携带信息,在解密之后是 json 格式
+        if (res.token && res.token === token && res.data) {
+          const msgJson = JSON.parse(Decrypt(res.data));
+          const reg = new RegExp(type);
+          // 获取 projectId
+          if (reg.test(msgJson.type)) {
+            callback(msgJson.options, subscribeId);
+            subscribeId.unsubscribe();
+            return;
+          }
+        }
+      } catch (err) {
+        console.log('stomp error', err);
+      }
+    });
+  };
+}
+
+
+export function wssInit() {
+  return new Promise((resolve, reject) => {
+    try {
+      const socket = new SockJS(`${getUrl()}/hafengWebsocket?token=${window.token}`);
+      window.stompClient = Stomp.over(socket);
+      window.stompClient.debug = null;
+      windowSendInit();
+      window.stompClient.connect({}, (frame) => {
+        // 请求 projectId
+        window.toWXSendMsg({
+          type: 'getProjectId',
+          options: {},
+        });
+        window.subscribe('projectId', (options) => {
+          resolve(options);
+        });
+      });
+    } catch (err) {
+      reject(err);
+    }
+  });
 }

+ 14 - 5
vue.config.js

@@ -78,8 +78,11 @@ module.exports = {
         return newArgs;
       })
       .end();
-      // 编译之后清理console.log
-      config.optimization.minimizer('vue').use(TerserPlugin, [{ terserOptions: { compress: { drop_console: true } } }])
+      if ( process.env.NODE_ENV === 'production' ) {
+        // 编译之后清理console.log
+        // config.optimization.minimizer('vue').use(TerserPlugin, [{ terserOptions: { compress: { drop_console: true } } }])  // TODO: 临时注释
+      }
+      
   },
   configureWebpack: {
     devtool: process.env.NODE_ENV === 'dev' ? 'source-map' : undefined,
@@ -89,6 +92,11 @@ module.exports = {
       },
     },
   },
+ transpileDependencies: [
+    // can be string or regex
+    '@stomp/stompjs',
+    // /other-dep/
+  ],
   devServer: {
     proxy: {
       '/profileApi': {
@@ -114,12 +122,13 @@ module.exports = {
         },
       },
       '/msApi': {
-        // target: 'http://172.20.50.208:8080',
-        // target: 'https://dev-kip-service-internal.kerryonvip.com/temporary-parking-service', //代理地址,这里设置的地址会代替axios中设置的baseURL
+        // target: 'http://172.20.248.37:8080',
+        // target: 'http://172.21.202.133:8080',
+        target: 'https://dev-kip-service-internal.kerryonvip.com/temporary-parking-service', //代理地址,这里设置的地址会代替axios中设置的baseURL
         // target: 'http://172.21.203.140:8080', //代理地址,这里设置的地址会代替axios中设置的baseURL   2023-2-9
         // target: 'http://172.21.203.20:8080', //代理地址,这里设置的地址会代替axios中设置的baseURL
         // target: 'http://172.21.200.89:8080', //代理地址,这里设置的地址会代替axios中设置的baseURL
-        target: 'http://172.21.201.227:8080', // 代理地址,这里设置的地址会代替axios中设置的baseURL
+        // target: 'http://172.21.201.227:8080', // 代理地址,这里设置的地址会代替axios中设置的baseURL
         changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
         //ws: true, // proxy websockets
         //pathRewrite方法重写url

+ 26 - 1
yarn.lock

@@ -922,7 +922,7 @@
     "@babel/types" "^7.4.4"
     esutils "^2.0.2"
 
-"@babel/runtime@7.x", "@babel/runtime@^7.11.0", "@babel/runtime@^7.8.4", "@babel/runtime@~7.17.9":
+"@babel/runtime@7.x", "@babel/runtime@^7.11.0", "@babel/runtime@^7.17.2", "@babel/runtime@^7.8.4", "@babel/runtime@~7.17.9":
   version "7.17.9"
   resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
   integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
@@ -3285,6 +3285,11 @@ copy-descriptor@^0.1.0:
   resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
   integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==
 
+copy-text-to-clipboard@^3.0.1:
+  version "3.1.0"
+  resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/copy-text-to-clipboard/-/copy-text-to-clipboard-3.1.0.tgz#6bf40deef0a51ac6858efb0d76ded2c6d6a15059"
+  integrity sha512-PFM6BnjLnOON/lB3ta/Jg7Ywsv+l9kQGD4TWDCSlRBGmqnnTM5MrDkhAFgw+8HZt0wW6Q2BBE4cmy9sq+s9Qng==
+
 copy-webpack-plugin@^5.1.1:
   version "5.1.2"
   resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz#8a889e1dcafa6c91c6cd4be1ad158f1d3823bae2"
@@ -3310,6 +3315,11 @@ core-js-compat@^3.25.1, core-js-compat@^3.6.5:
   dependencies:
     browserslist "^4.21.4"
 
+core-js@^3.11.0:
+  version "3.29.0"
+  resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/core-js/-/core-js-3.29.0.tgz#0273e142b67761058bcde5615c503c7406b572d6"
+  integrity sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==
+
 core-js@^3.6.5:
   version "3.25.5"
   resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/core-js/-/core-js-3.25.5.tgz#e86f651a2ca8a0237a5f064c2fe56cef89646e27"
@@ -6750,6 +6760,11 @@ multicast-dns@^6.0.1:
     dns-packet "^1.3.1"
     thunky "^1.0.2"
 
+mutation-observer@^1.0.3:
+  version "1.0.3"
+  resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/mutation-observer/-/mutation-observer-1.0.3.tgz#42e9222b101bca82e5ba9d5a7acf4a14c0f263d0"
+  integrity sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA==
+
 mz@^2.4.0:
   version "2.7.0"
   resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
@@ -9696,6 +9711,16 @@ vary@~1.1.2:
   resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
   integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
 
+vconsole@^3.15.0:
+  version "3.15.0"
+  resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/vconsole/-/vconsole-3.15.0.tgz#2383482b0a4106204090046ec128071284e04a90"
+  integrity sha512-8hq7wabPcRucSWQyN7/1tthMawP9JPvM95zgtMHpPknMMMCKj+abpoK7P7oKK4B0qw58C24Mdvo9+raUdpHyVQ==
+  dependencies:
+    "@babel/runtime" "^7.17.2"
+    copy-text-to-clipboard "^3.0.1"
+    core-js "^3.11.0"
+    mutation-observer "^1.0.3"
+
 vendors@^1.0.0:
   version "1.0.4"
   resolved "https://nexus-internal.kerryonvip.com/repository/kerry-npm-group/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e"