浏览代码

Merge branch 'Microservices' into lock/Microservices/inovice

lock.qiu@kerryprops.com 2 年之前
父节点
当前提交
4ad268d9a2

+ 2 - 1
package.json

@@ -49,7 +49,8 @@
     "sass": "^1.56.2",
     "sass-loader": "^10.4.1",
     "vue-template-compiler": "^2.7.14",
-    "webpack": "^4.36.0"
+    "webpack": "^4.36.0",
+    "terser-webpack-plugin": "^4"
   },
   "browserslist": [
     "Android >= 4.4",

+ 19 - 1
src/App.vue

@@ -19,6 +19,7 @@
       <br />
       <br />
     </div>
+    <wx-points-commit ref="wxPointsCommit"></wx-points-commit>
   </div>
 </template>
 <script>
@@ -91,6 +92,8 @@ export default {
             options,
             callback: () => {
               this.$store.commit('SET_IS_INIT', true);
+              // 无感积分逻辑
+              this.wxEasyPointsCommitStatusInit();
             },
           });
         } catch (err) {
@@ -206,6 +209,7 @@ export default {
       window.requestms = createAxiosByinterceptors({
         // baseURL: `https://dev-kip-service-internal.kerryonvip.com/`,
         // baseURL: `http://tp.hht.test/`,
+        // baseURL: window.profileApi, // TODO: 微服务发布到DEV环境之后取消注释
         baseURL: `/msApi`,
       });
     },
@@ -269,7 +273,9 @@ export default {
               // window.location.reload();
               this.$store.dispatch('getUserDetail');
               this.$store.commit('SET_MEMBER', uni.getStorageSync('member'));
-              uni.getStorageSync();
+              // 无感积分逻辑
+              this.wxEasyPointsCommitStatusInit();
+              // uni.getStorageSync();
             });
           }
         } else {
@@ -287,6 +293,18 @@ export default {
         }
       });
     },
+    // 无感积分相关
+    async wxEasyPointsCommitStatusInit() {
+      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();
+				}
+			}
+    }
   },
 };
 </script>

+ 22 - 0
src/api/parking/index.js

@@ -130,5 +130,27 @@ export function invoicesAgainSandEmail(invoiceId) {
 
 export function submitInvoice(params) {
   return window.requestms.post(`/invoices`,params, { loading: true });
+
+}
+// 1.19 无牌车出场
+/**
+ * 
+ * @param params.gateId string 车厂出口道闸编号
+ * @param params.vehicleNo string 临牌
+ * @returns {*}
+ */
+export function unlicensedCarCheckout(vehicleNo, unlicensed, gateId) {
+  return window.requestms.post(`/parking/unlicensed-car-checkout`, { vehicleNo, gateId }, { loading: true });
 }
+// 1.25 车场二维码信息查询(通过CodeID)
+/**
+ * 
+ * @param params.gateId string 车厂入口道闸编号
+ * @param params.vehicleNo string 临牌
+ * @returns {*}
+ */
+export function qrCodes(codeId) {
+  return window.requestms.get(`qr-codes/code-ids/${codeId}`, { loading: true });
+}
+
 

+ 3 - 2
src/api/request.js

@@ -134,7 +134,7 @@ function XUser(config) {
    vipCode: 'KERRY100213853',
    lbsId: '8aaa82ea804d07cd0180516ff03b0008',
    };*/
-  if (/orders-and-prepay|calculate-discount/.test(config.url)) {
+  if (/orders-and-prepay|calculate-discount|unlicensed-car-check-in/.test(config.url)) {
     params.buildingId = window.localStorage.getItem('buildingId');
   }
   console.log(140140140140, params);
@@ -217,7 +217,8 @@ export const createAxiosByinterceptors = (config) => {
       }
       // 错误信息提示
       const { code, langMessage } = error.response.data;
-      if (code === 'INTERNAL_SERVER_ERROR') {
+      const codeList = ['INTERNAL_SERVER_ERROR', 'VALIDATION_FAILED', 'CAR_NOT_FOUND', 'CAR_HAS_PLATE']; // 默认处理的错误code
+      if (codeList.indexOf(code) > -1) {
         uni.showToast({ title: langMessage, duration: 3000, icon: 'fail' });
       }
       // Message.error(error?.response?.data?.message || '服务端异常');

+ 194 - 311
src/components/wx-points-commit/wx-points-commit.vue

@@ -1,365 +1,248 @@
 <template>
-  <div class="authorize-hz" v-if="show">
-    <div class="mid">
-      <div class="authorize-box">
-        <div class="bold">{{ title }}</div>
-        <div class="other">
-          感谢您{{ lbsName }}的信任!请您仔细阅读并充分理解我们最新更新的
-          <sapn
-            v-if="!privacyReminder"
-            style="color: #627ecf"
-            @click="gotoProtocol('privacyPolicy')"
-            >《{{ brandInfo.privacyPolicyName }}》</sapn
-          >&nbsp;
-          <sapn
-            v-if="!protocolReminder"
-            style="color: #627ecf"
-            @click="gotoProtocol('protocol')"
-            >《{{ brandInfo.protocolName }}》</sapn
-          >。
-          新的协议政策将不影响您现有的会员权益,您点击“同意”按钮后,将视为同意本次协议更新。
-        </div>
-      </div>
-      <div class="authorize-footer">
-        <uni-button class="disagree_btn" @click="handleDisagree"
-          >不同意</uni-button
-        >
-        <uni-button class="agree_btn" @click="handleConfirm">同意</uni-button>
-      </div>
-    </div>
-  </div>
+  <view class="box" v-if="show" @touchmove.stop.prevent>
+    <view class="boxIn">
+      <view class="content">
+        <image class="commit-star" src="https://cnsh-kerry-crm-prod.oss-cn-shanghai.aliyuncs.com/images/wx-points/points-commit.png"> </image>
+        <image v-if="custTypeId === 0" class="commit-logo-default" src="https://cnsh-kerry-crm-prod.oss-cn-shanghai.aliyuncs.com/images/wx-points/kerry.png"> </image>
+        <image v-else class="commit-logo-ko" src="https://cnsh-kerry-crm-prod.oss-cn-shanghai.aliyuncs.com/images/wx-points/ko.png"> </image>
+        <view class="logo"> </view>
+        <view class="title"> 您有消费积分未领取 </view>
+        <view class="text"> 如您的微信支付积分未到账,请于消费当日申请领取 </view>
+        <view @click="toWxPointsAuth" class="commit-btn" :class="{ 'commit-btn--blue': custTypeId === 1, 'commit-btn--green': custTypeId === 2 }"> 去领取 </view>
+        <image @click="close" class="commit-cancel" src="https://cnsh-kerry-crm-prod.oss-cn-shanghai.aliyuncs.com/images/wx-points/close.svg"> </image>
+      </view>
+    </view>
+  </view>
 </template>
 
 <script>
+import { mapState } from 'vuex';
+import { kipGetPointsConfig } from '@/utils/api-kip.js';
 // const app = getApp();
-import {
-  kipGetBrandInfo,
-  kipLogout,
-  kipAgreementCheck,
-  kipAgreementSave,
-} from '@/utils/api-kip.js';
-
-import CacheTool from '@/utils/cache-tool.js';
-import { isKOMiniApp } from '@/utils/utils.js';
-import uni from '@/utils/uniHooks'
-import { mapState } from "vuex";
-const YES = '1';
-const NO = '0';
+const app = {};
 export default {
-  name: 'my-protocol-modal',
-  props: {
-    title: {
-      type: String,
-      default: '亲爱的会员',
-    },
+  props: {},
+  created() {
+    // this.handleGetPointsConfig()
   },
+  watch: {},
   data() {
     return {
+      pointsConfig: null,
       show: false,
-      // curMarket: null,
-      // brandInfo: null,
-      cacheKey: '',
-      privacyReminder: true,
-      protocolReminder: true,
+      clickToWxPointsAuth: false,
     };
   },
-  mounted() {},
   computed: {
-    lbsName() {
-      if (!this.curMarket) {
-        return '';
-      }
-      const lbsName = this.curMarket?.name || '';
-      return lbsName ? `对${lbsName}` : '';
-    },
+    // custTypeId: 0 默认版本,1 上海静安 2 上海浦东
     ...mapState({
-      curMarket: (state) => state.curMarket,
-      brandInfo: (state) => state.brandInfo,
-      groupId: (state) => state.groupId,
-      mallid: (state) => state.mallId,
+      // custTypeId: 0
+      custTypeId: (state) => state.custTypeId,
     }),
   },
   methods: {
-    gotoProtocol(type) {
-      const brandId = this.groupId || uni.getStorageSync('groupId');
-      const lbsId = this.mallid || uni.getStorageSync('mallid');
-      // uni.navigateTo({
-      //   url: `/pages/protocol/protocol?type=${type}&brandId=${brandId}&lbsId=${lbsId}&noBtn=1`,
-      // });
-      window.toWXSendMsg({
-        type: 'toPage',
-        options: {
-          fnName: 'navigateTo',
-          url: `/pages/protocol/protocol?type=${type}&brandId=${brandId}&lbsId=${lbsId}&noBtn=1`
-        },
+    checkoutLogin() {
+      const pages = getCurrentPages();
+      let url = '/' + pages[pages.length - 1].route;
+      pages[pages.length - 1].$vm.$refs.child.login(url, () => {
+        this.toWxPointsAuth();
       });
     },
-    handleConfirm() {
-      this.saveAgreementAction(YES);
-    },
-    handleDisagree() {
-      this.saveAgreementAction(NO);
-    },
-    open() {
-      // 获取当前商场
-      const { brandInfo, curMarket } = this;
-      const mallid = this.mallid || uni.getStorageSync('mallid');
-      const groupId = this.groupId || uni.getStorageSync('groupId');
-      if (!groupId || !mallid) {
-        console.warn('===>groupId活mallid不存在');
-        this.show = false;
-        return;
-      }
-      // 判断是否已登录
-      const member = uni.getStorageSync('member');
-      if (!member) {
-        console.warn('===>没有登录');
-        this.show = false;
-        return;
-      }
-      // 找到商场信息
-      if (curMarket) {
-        this.curMarket = curMarket;
-      }
-      // 找到品牌信息
-      if (brandInfo && brandInfo.id === groupId) {
-        this.brandInfo = brandInfo;
-        this.checkVersion();
-      } else {
-        // 根据brandId和lbsId请求
-        const params = {
-          id: groupId,
-          lbsId: mallid,
-        };
-        kipGetBrandInfo(params)
-          .then((resp) => {
-            const result = resp.data;
-            if (result && result.code === '000000') {
-              const brandArray = result.data;
-              if (brandArray && brandArray.length > 0 && brandArray[0]) {
-                const brandInfo = brandArray[0].brand;
-                // 拿到商场信息,版本号
-                this.brandInfo = brandInfo;
-                // 请求接口判断是否需要弹出
-                this.checkVersion();
-                // this.show = true;
+    handleGetPointsConfig() {
+      kipGetPointsConfig()
+        .then((resp) => {
+          const result = resp.data;
+          // codes,wxAuth,aliAuth
+          this.pointsConfig = result;
+          if (result) {
+            if (result && result.codes) {
+              // codes,wxAuth,aliAuth
+              this.pointsConfig = result;
+              this.checkoutLogin();
+            } else {
+              if (result.code && result.code === '300000') {
+                this.checkoutLogin();
+              } else {
+                uni.showToast({
+                  icon: 'none',
+                  mask: true,
+                  duration: 2000,
+                  title: result.errorMessage || result.message || '出错了,请稍后再试',
+                });
               }
+            }
+          } else {
+            if (resp.code && resp.code === '300000') {
+              this.checkoutLogin();
             } else {
               uni.showToast({
-                title: result.message,
-                duration: 2000,
                 icon: 'none',
+                mask: true,
+                duration: 2000,
+                title: resp.message,
               });
             }
-          })
-          .catch((err) => {
-            this.show = false;
-            console.error(err);
-            uni.showToast({
-              title: '请求错误',
-              duration: 2000,
-              icon: 'none',
-            });
-          });
-      }
-    },
-    logout() {
-      const member = uni.getStorageSync('member');
-      const openid = member ? member.openid : '';
-      kipLogout()
-        .then((resp) => {
-          uni.hideLoading();
-          const result = resp.data;
-          if (result && (result.code == '000000' || result.code == '300000')) {
-            // 用户不同意协议直接静默退出
-            // 清除所有缓存,跳转到首页
-            // MemberCacheTool.cleanMemberCache(app);
-            // KipCacheTool.cleanKipCache();
-            // uni.redirectTo({
-            //   url: '/pages/automatic/automaticIndex',
-            // });
-            window.toWXSendMsg({
-              type: 'logout',
-              options: {},
-            });
-
-          } else {
-            uni.showToast({
-              title: result.message,
-              duration: 2000,
-              icon: 'none',
-            });
           }
         })
-        .catch((err) => {
-          uni.hideLoading();
-          console.error(err);
+        .catch((e) => {
           uni.showToast({
-            title: '请求错误',
-            duration: 2000,
             icon: 'none',
-          });
-        });
-    },
-    getKeyByMallid(mallid) {
-      if (CacheTool.isShenZhenMallid(mallid)) {
-        return 'agreeProtocolSZ';
-      } else if (CacheTool.isShenYangMallid(mallid)) {
-        return 'agreeProtocolSY';
-      }
-      return '';
-    },
-    checkVersion() {
-      kipAgreementCheck()
-        .then((resp) => {
-          const result = resp.data;
-          if (result && result.code === '000000') {
-            const { agreementStatus, privacyReminder, protocolReminder } =
-              result.data || {};
-            this.privacyReminder = privacyReminder;
-            this.protocolReminder = protocolReminder;
-            if (privacyReminder && protocolReminder) {
-              this.show = false;
-            } else {
-              this.show = true;
-            }
-          } else {
-            uni.showToast({
-              title: result.message,
-              duration: 2000,
-              icon: 'none',
-            });
-          }
-        })
-        .catch((err) => {
-          console.error(err);
-          uni.showToast({
+            mask: true,
             title: '请求错误',
-            duration: 2000,
-            icon: 'none',
           });
         });
     },
-    saveAgreementAction(status) {
-      const params = {};
-      if (!this.protocolReminder) {
-        params.protocolStatus = status;
-      }
-      if (!this.privacyReminder) {
-        params.privacyStatus = status;
+    async toWxPointsAuth() {
+      console.log('授权微信无感积分');
+      if (this.clickToWxPointsAuth) {
+        console.log('授权微信无感积分重复点击');
+        return;
       }
-      kipAgreementSave(params)
-        .then((resp) => {
-          const result = resp.data;
-          if (!result || result.code !== '000000') {
-            uni.showToast({
-              title: result.message,
-              duration: 2000,
-              icon: 'none',
-            });
-          } else {
-            // 如果不同意协议则调用退出接口
-            this.show = false;
-            if (NO === status) {
-              this.logout();
-            }
-          }
-        })
-        .catch((err) => {
-          console.error(err);
-          uni.showToast({
-            title: '请求错误',
-            duration: 2000,
-            icon: 'none',
+      await this.handleGetPointsConfig();
+      this.clickToWxPointsAuth = true;
+      var myPluginInterface = requirePlugin('myPlugin');
+      uni.showLoading();
+      const _this = this;
+      await myPluginInterface.getLocation(app.globalData.openId).then((res) => {
+        const that = _this;
+        if (res.return_code === 0) {
+          uni.navigateTo({
+            url: `plugin://myPlugin/index?openid=${app.globalData.openId}&mch_id=${that.pointsConfig.mchId}&member_status=${that.pointsConfig.wxAuth ? 1 : 0}`,
+            success: function () {
+              that.close();
+              uni.hideLoading();
+              that.clickToWxPointsAuth = false;
+            },
           });
-        });
+        } else if (res.return_code === '102') {
+          uni.showModal({
+            title: '提示',
+            content: '请您在”定位服务“中允许”微信”使用位置信息, 并允许该小程序使用定位功能',
+            showCancel: false,
+            confirmText: '确认',
+            success: function (res) {
+              that.close();
+              that.clickToWxPointsAuth = false;
+            },
+          });
+          uni.hideLoading();
+        } else {
+          that.clickToWxPointsAuth = false;
+        }
+      });
+    },
+    open() {
+      this.show = true;
+    },
+    close() {
+      this.show = false;
     },
   },
 };
 </script>
-
-<style lang="less">
-// new
-.authorize-hz {
-  background: rgba(0, 0, 0, 0.6);
+<style scoped lang="less">
+.box {
   position: fixed;
-  z-index: 998;
+  z-index: 10000;
+  width: 100vw;
+  height: 100vh;
+  background: rgba(0, 0, 0, 0.7);
+}
+
+.boxIn {
+  position: relative;
   width: 100%;
   height: 100%;
-  left: 0;
-  top: 0;
+}
 
-  .mid {
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    transform: translateX(-50%) translateY(-50%);
-    width: 588px;
-    background: #fff;
-    border-radius: 17px;
-    padding: 56px 44px;
+.content {
+  position: relative;
+  width: calc(100% - 110px);
+  height: 232px;
+  background: #ffffff;
+  border-radius: 8px;
+  margin: 0 auto;
+  margin-top: 280px;
+}
 
-    .authorize-box {
-      width: 100%;
+.commit-star {
+  position: absolute;
+  width: calc(100vw - 40px);
+  height: calc(48.1vw - 23.6px);
+  top: calc(11.8px - 24.05vw);
+  left: -33px;
+}
 
-      .bold {
-        text-align: center;
-        color: #333333;
-        padding-bottom: 44px;
-      }
+.commit-logo-default {
+  width: 84px;
+  height: 20px;
+  position: relative;
+  display: block;
+  top: 15px;
+  left: 30px;
+}
 
-      .other {
-        color: #666666;
-        line-height: 48px;
-        font-size: 28px;
-        color: #666666;
-        opacity: 1;
-      }
+.commit-logo-ko {
+  width: 80px;
+  height: 20px;
+  position: relative;
+  display: block;
+  top: 15px;
+  left: 35px;
+}
 
-      .checkBox {
-        display: flex;
-        justify-content: flex-start;
-        align-items: flex-start;
-        margin-top: 40px;
+.logo {
+  height: 35px;
+  border-bottom: 1rpx solid rgba(151, 151, 151, 0.1);
+}
 
-        .popup-a {
-          color: #4e99ff;
-          text-decoration: underline;
-        }
-      }
-    }
+.title {
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
+  text-align: center;
+  margin-top: 22px;
+}
 
-    .authorize-footer {
-      display: flex;
-      justify-content: space-between;
-      color: #ffffff;
-      margin-top: 56px;
+.text {
+  width: 180px;
+  margin: 0 auto;
+  margin-top: 8px;
+  color: #999;
+  font-size: 12px;
+  text-align: center;
+}
 
-      .disagree_btn {
-        width: 176px;
-        height: 68px;
-        line-height: 68px;
-        border: 2px solid #b3b3b3;
-        border-radius: 34px;
-        color: #999999;
-        font-size: 30px;
-      }
+.commit-btn {
+  width: calc(100vw - 180px);
+  height: 40px;
+  margin: 0 auto;
+  margin-top: 17px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 15px;
+  color: #fff;
+  background: #644a79;
+  border-radius: 25px;
+  box-shadow: 3px 3px 12px 0px #644a79;
+}
 
-      .agree_btn {
-        width: 286px;
-        height: 68px;
-        line-height: 68px;
-        background: linear-gradient(90deg, #662d91 0%, #1b1464 100%);
-        opacity: 0.83;
-        border-radius: 34px;
-        color: #ffffff;
-        font-size: 30px;
-      }
+.commit-btn--blue {
+  box-shadow: 3px 3px 12px 0px #13358e;
+  background: #13358e;
+}
 
-      .disabled {
-        background: #999999;
-      }
-    }
-  }
+.commit-btn--green {
+  box-shadow: 3px 3px 12px 0px #25673c;
+  background: #25673c;
+}
+
+.commit-cancel {
+  position: relative;
+  display: block;
+  margin: 0 auto;
+  margin-top: 56px;
+  width: 32px;
+  height: 32px;
 }
 </style>

+ 1 - 0
src/kui/components/k-button/k-button.vue

@@ -57,6 +57,7 @@
     @getuserinfo="onGetuserinfo"
     @getphonenumber="onGetphonenumber"
   >
+    <slot name="left"/>
     <k-icon
       v-if="type == 'icon'"
       :name="icon"

+ 4 - 4
src/pages/parkingFee/components/base/parkingFeeDetailSuccess.vue

@@ -19,7 +19,7 @@
 
           <div class="parking-info-item">
             <span class="info-key">支付时间</span>
-            <span class="info-value">{{ detail.createTime || '' }}</span>
+            <span class="info-value">{{ detail.createTime | momentFormat }}</span>
           </div>
           <div class="parking-info-item">
             <span class="info-key">车牌号</span>
@@ -37,7 +37,7 @@
           </div>
           <div class="parking-info-item">
             <span class="info-key">入场时间</span>
-            <span class="info-value">{{ detail.enterTime }}</span>
+            <span class="info-value">{{ detail.enterTime | momentFormat }}</span>
           </div>
           <!-- <div class="parking-info-item">
             <span class="info-key">离场时间</span>
@@ -45,7 +45,7 @@
           </div> -->
           <div class="parking-info-item">
             <span class="info-key">停车时长</span>
-            <span class="info-value">{{ detail.serviceMin }}</span>
+            <span class="info-value">{{ detail.serviceMin | parkingTime }}</span>
           </div>
           <div class="parking-info-item">
             <span class="info-key">开票状态</span>
@@ -101,7 +101,7 @@
           </div>
           <div class="parking-info-item">
             <span class="info-key">实缴</span>
-            <span class="info-value red">{{ (detail.actualPayFee / 100) | currency }}</span>
+            <span class="info-value red">{{ detail.actualPayFee | currency }}</span>
           </div>
         </div>
       </div>

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

@@ -28,7 +28,7 @@
             {{ item.id + '-' + item.vehicleNo }}
           </div>
           <div style="color: red; margin-right: 6px">
-            {{ (item.actualPayFee / 100) | currency }}
+            {{ (item.totalPaidAmount ) | currency }}
           </div>
         </div>
 

+ 6 - 7
src/pages/parkingFee/components/purple/parkingFee.vue

@@ -1,5 +1,5 @@
 <template>
-  <scroll-view class="theme-mall scroll-Y color-scroll-Y">
+  <scroll-view :class="['scroll-Y' ,'color-scroll-Y', theme]">
     <div class="wrap">
       <div class="parkingFee">
         <!-- 菜单 -->
@@ -99,7 +99,7 @@
           <div class="unlicensed-box" v-else>
             <!-- 无牌车 -->
             <!-- <k-illustration name="no-parking-fee" description="未查询到无牌车信息" /> -->
-            <div class="no-car-unlicensed-box">
+            <div class="no-car-unlicensed-box" v-if="!unlicensedCar">
               <img :src="`${require(`../../static/images/unlicensed-1.png`)}`" />
               <div class="no-car-unlicensed-info">未查询到无牌车信息</div>
               <div class="search-btn" @click="scanCarCode">
@@ -108,15 +108,15 @@
               </div>
             </div>
             <!-- 有无牌车 -->
-            <div class="in-car" v-if="false">
+            <div class="in-car" v-else>
               <div class="car-number-box">
                 <img :src="`${require(`../../static/images/unlicensed-0.png`)}`" />
                 <div class="car-number">
-                  <div class="number">临K 9Q289H</div>
+                  <div class="number">{{ unlicensedCar }}</div>
                   <div class="tips">车辆类型:无牌车辆</div>
                 </div>
               </div>
-              <div class="search-btn">去支付</div>
+              <div class="search-btn" @click="unlicensedToPay">去支付</div>
             </div>
           </div>
         </div>
@@ -331,8 +331,7 @@ export default {
             align-items: center;
             font-size: 120px;
             height: 70px;
-            //line-height: 20px;
-            color: #644a79;
+            color: var(--k-color-primary);
           }
         }
 

+ 3 - 0
src/pages/parkingFee/mixins/base.js

@@ -4,6 +4,7 @@ export default {
   data() {
     return {
       componentName: '',
+      theme: 'theme-mall',
     };
   },
   computed: {
@@ -15,8 +16,10 @@ export default {
     const com = ['purpleCom', 'blueCom', 'greenCom', 'officeBlueCom', 'purpleCom'];
     if ( this.custTypeId < 3 || ! this.custTypeId) {
       this.componentName = 'baseParkingFeeCom';
+      this.theme = 'theme-mall'
     } else {
       this.componentName = com[this.custTypeId];
+      this.theme = 'theme-office'
     }
   },
 }

+ 145 - 219
src/pages/parkingFee/mixins/parkingFee.js

@@ -15,9 +15,15 @@ import uni from '@/utils/uniHooks';
 // import greenCom from '../components/green/home.vue';
 // import officeBlueCom from '../components/officeBlue/home.vue';
 // import purpleCom from '../components/purple/home.vue';
-import { parkingLots } from '@/api/parking';
+import { parkingLots, qrCodes, unlicensedCarCheckIn } from '@/api/parking';
 
 export default {
+  props:{
+    theme:{
+      type: String,
+      default: ''
+    }
+  },
   components: {
     plateNumber,
     LoginDom,
@@ -69,6 +75,10 @@ export default {
       member: (state) => state.member,
       mobile: (state) => state.mobile,
       custTypeId: (state) => state.custTypeId,
+      unlicensedCar: (state) => state.order.unlicensedCar,
+      // 如果是扫码进入的无牌车
+      unlicensedInfo: (state) => state.unlicensedInfo,
+      endlessLoop: (state) => state.endlessLoop,
     }),
   },
   beforeRouteLeave(to, from, next) {
@@ -76,17 +86,13 @@ export default {
     next();
   },
   watch: {
-    userInfo() {
-      this.initPage();
-    },
     openid() {
       if (this.openid) {
         this.getParkInfo();
         this.showSq = false;
       }
-    },
+    }
   },
-  async created(params) { },
   async mounted() {
     setTimeout(() => {
       uni.setNavigationBarTitle({
@@ -97,7 +103,13 @@ export default {
     if (platform === 'micromessenger') {
       await initWxJsSdkConfig(['checkJsApi', 'scanQRCode']);
     }
-
+    // 不论是否出入场,都使用此函数获取 gateId(闸口机器的ID)
+    if (this.unlicensedInfo?.type && /unlicensedOut|unlicensedIn/.test(this.unlicensedInfo.type) && this.endlessLoop.length === 0) {
+      console.log('用户是扫码进来的97', this.unlicensedInfo);
+      // 此处记录扫码流程执行次数。如果超过一次则不再执行
+      this.$store.commit('SET_ENDLESS_LOOP', this.unlicensedInfo.type);
+      this.qrCodesRule(this.unlicensedInfo.code)
+    }
     if (this.openid) {
       this.getParkInfo();
       this.showSq = false;
@@ -114,39 +126,6 @@ export default {
     }
   },
   methods: {
-    async initPage() {
-      // ws()
-      console.time('time');
-      const name = {
-        a: 'label',
-        c: 'label',
-      };
-      // const nameD = Encrypt(JSON.stringify(name))
-      // this.options = params;
-      // await this.$onLaunched;
-      this.localimgPic = this.$staticPicUrl + '/wxminilocalimg/parkingFee/';
-      // app.globalData.pullVipcode = params.pullVipcode || '';
-      // app.globalData.mallid = params.mallid || app.globalData.mallid
-      if (this.userInfo) {
-        // this.getParkInfo();
-        return;
-        // app.globalData.isNewMember = '';
-        // 场景二维码记录(是否扫码进入)
-        // app.globalData.paramsScene = {};
-        // this.$saveSceneQrcodeDetail(
-        //   'page',
-        //   'parkingFee',
-        //   '停车缴费',
-        //   '',
-        //   '',
-        //   '',
-        //   ''
-        // );
-      }
-      // 埋点本地化
-      this.preUrl = uni.getStorageSync('previousUrl');
-      uni.setStorageSync('previousUrl', '/pages/parkingFee/home.vue');
-    },
     toggleType(carType) {
       this.ind = 0;
       this.active = 0;
@@ -179,102 +158,17 @@ export default {
       uni.showLoading({
         title: '加载中',
       });
-      /*const openid = uni.getStorageSync('openid') || this.openId;
-       let params = {
-       // mallid: '8a84853b7c91ac5b017c961a9b2a030d',
-       // groupId: '8a84853b7c91ac5b017c962dab55030e',
-       mallid: this.mallId,
-       groupId: this.groupId,
-       openid: openid,
-       vipcode: this.member?.vipcode,
-       };
-       console.log(342, params);
-       this.$md(params);
-       this.$request({
-       url: this.$baseURL + 'api/1.0/park/parkInfo',
-       data: params,
-       method: 'POST',
-       header: JSON.parse(uni.getStorageSync('handleUser')),
-       })
-       .then((res) => {
-       if (res.data.code === 0) {
-       const data = res.data.data || {};
-       this.carList = data.carList;
-       this.parkInfoEntity = data.parkInfoEntity;
-       this.hourMoney =
-       parseFloat(this.parkInfoEntity.needmoney) /
-       parseFloat(this.parkInfoEntity.tohours);
-       let reg = /[;;]/g;
-       this.parkInfoEntity.payinstruction =
-       this.parkInfoEntity.payinstruction.replace(reg, '\r\n');
-       this.parkInfoEntity.hourMoney = this.hourMoney;
-       uni.setStorageSync('parkinfo', JSON.stringify(this.parkInfoEntity));
-       } else {
-       uni.showToast({
-       title: res.data.msg,
-       duration: 2000,
-       icon: 'none',
-       });
-       }
-       })
-       .catch((err) => {
-       uni.showToast({
-       title: '网络超时请稍后再试',
-       duration: 2000,
-       icon: 'none',
-       });
-       console.log(err);
-       });*/
       try {
-        console.log(222222);
-        // const res = await parkingLots('8aaa83397bf7310e017bf7c8fb740009');
-        // const res = await parkingLots('8aaa87bc7ce98224017ce995fd8a0002');
         const res = await parkingLots('8aaa82ea804d07cd0180516ff03b0008'); // TODO: 临时写死
-        /*const data = {
-         parkName: '杭州停车场',
-         parkCode: 'hz01',
-         carList: [],
-         description:
-         '计费基础规则:10元每小时,上不封顶 ;\n线上缴费渠道:CRM小程序 (分会员通道及非会员通道);1\n会员等级减免:铂金卡当日可免费停车4小时,金卡当时可免费停车2小时,银卡无减免 (当日仅限使用1次,可与其它减免共享);\n积分抵扣:1000积分抵扣10元(手动输入抵扣积分);\n消费减免:消费200元可减免2小时,消费400元可减免4小时,消费800元可减免6小时 。仅限会员,当日有效,当日可多次享受该减免,当日最多可享受消费减免6小时。;\n        消费减免举例:;\n        (1) 某顾客第一次进场,消费230元  离场时可看到减免2小时的选项,默认为选中;\n        (2) 如果顾客未使用减免,顾客第二次进场,消费+270  离场时可看到减免金额提高到4小时;\n         如果顾客使用减免:顾客第二次进场,消费+270  离场时可看到还是只能减免2小时;\n        (3) CRM小程序缴费页面停留时长1分钟,1分钟后自动刷新获取最新缴费金额;\n纸质优惠券核销: 顾客在CRM小程序手动扫码获取优惠券金额;\n会员活动及积分兑换优惠 :通过CRM系统获取(详细情况由CRM另行描述)!',
-         };*/
-        // let reg = /[;;]/g;
-        // this.parkInfoEntity.description = data.description.replace(reg, '\r\n');
         let reg = /[;;]/g;
         this.description = res.description.replace(reg, '\r\n').replace(/\r\n/g, '<br/>');
-        // console.log(238238238238238238238, this.description);
-        // const data = res.data.data || {};
-        // console.log(236, uni.getStorageSync('carList'));
         const carList = uni.getStorageSync('carList');
         if (carList) {
           this.carList = JSON.parse(carList);
         }
-        console.log(238, this.carList);
-        // this.parkInfoEntity = data.parkInfoEntity;
-        // this.hourMoney =
-        //   parseFloat(this.parkInfoEntity.needmoney) /
-        //   parseFloat(this.parkInfoEntity.tohours);
-        // let reg = /[;;]/g;
-        // this.parkInfoEntity.payinstruction =
-        //   this.parkInfoEntity.payinstruction.replace(reg, '\r\n');
-        // this.parkInfoEntity.hourMoney = this.hourMoney;
-        // uni.setStorageSync('parkinfo', JSON.stringify(this.parkInfoEntity));
-
-        // console.log(233, res);
       } catch (e) {
         console.log(225225, e);
       }
-      // return;
-      // const data = res.data || {};
-      // this.carList = data.carList;
-      // this.parkInfoEntity = data.parkInfoEntity;
-      // this.hourMoney =
-      //   parseFloat(this.parkInfoEntity.needmoney) /
-      //   parseFloat(this.parkInfoEntity.tohours);
-      // let reg = /[;;]/g;
-      // this.parkInfoEntity.payinstruction =
-      //   this.parkInfoEntity.payinstruction.replace(reg, '\r\n');
-      // this.parkInfoEntity.hourMoney = this.hourMoney;
-      // uni.setStorageSync('parkinfo', JSON.stringify(this.parkInfoEntity));
     },
     //缴费说明隐藏显示
     top_display() {
@@ -497,20 +391,16 @@ export default {
         return;
       }
       // uni.removeStorageSync('passLogin');
-      // 北京停车场开票
-      // if (this.parkInfoEntity.parkMallCode === 3) {
-      //   uni.navigateToMiniProgram({
-      //     appId: this.$etcpAppId,
-      //     path: this.$etcpAppInvoicePath,
-      //     envVersion: 'release',
-      //   })
-      //   return
-      // }
-      // this.$router.push({
-      //   path: './parkingReceipt/parkingReceipt',
-      // })
-      if (this.$store.state.passLogin) {
+      // TODO: 北京停车场开票
+      /* if (this.parkInfoEntity.parkMallCode === 3) {
+        uni.navigateToMiniProgram({
+          appId: this.$etcpAppId,
+          path: this.$etcpAppInvoicePath,
+          envVersion: 'release',
+        })
+        return
       }
+      */
       this.$router.push({ path: 'parkingReceipt' });
     },
     //停车券兑换
@@ -528,96 +418,132 @@ export default {
     },
     tabbarActiveEvent(name) {
       this.tabbarActive = name
-      this.$store.dispatch('order/unlicensedRule', (code) => {
-        // CAR_NOT_FOUND 车场扫描道闸入口,发现无车
-        if (code === 'CAR_NOT_FOUND') {
+      if (name === '无牌缴费') {
+        this.$store.dispatch('order/unlicensedRule', (code) => {
+          // CAR_NOT_FOUND 车场扫描道闸入口,发现无车
+          if (code === 'CAR_NOT_FOUND') {
 
-        }
-        // CAR_HAS_PLATE 车场扫描道闸入口,发现有牌车
-        if (code === 'CAR_HAS_PLATE') {
+          }
+          // CAR_HAS_PLATE 车场扫描道闸入口,发现有牌车
+          if (code === 'CAR_HAS_PLATE') {
 
-        }
-      })
+          }
+        })
+      }
     },
     // 无牌车闸机扫码
-    scanCarCode() {
-      // 模拟失败
-      this.$router.push({
-        path: 'parkingFeeMsg',
-        query:{
-          type: 'success'
-        }
-      })
-      return
-      const runScanFn = (res) => {
-        if (res.scanType == 'QR_CODE' && res.scanType) {
-          console.log(res.result);
-         // 获取二维码参数之后,模拟提取参数
-          const url = res.result;
-          if (url.indexOf('auth/') === -1) { // 单纯的code
-            console.log('提取到的参数', 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.getPaperCouponInfo(couponCode);
+    async scanCarCode() {
+      try {
+        this.qrCodesRule('e41d4d9dd5534f4aa3de88326a2e6f85')
+        return
+        const runScanFn = (res) => {
+          if (res.scanType == 'QR_CODE' && res.scanType) {
+            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 platform = getPlatform();
+        if (platform === 'miniprogram') {
+          window.toWXSendMsg({
+            type: 'scanQRCode',
+          });
+          window.subscribe('scanQRCodeOver', (options) => {
+            console.log('微信扫码结束之后的返回参数', options);
+            runScanFn(options);
+          });
+        } else {
+          this.$wx.scanQRCode({
+            desc: 'scanQRCode desc',
+            needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
+            // scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
+            success: (res) => {
+              console.log('H5页面扫码获取到的参数——成功', res);
+              runScanFn(res);
+              // this.formMsg.deviceCode = res.resultStr;
+            },
+            error: (res) => {
+              console.log('H5页面扫码获取到的参数——失败', res);
+              // console.log(242, res);
+            },
+          });
         }
-      };
-      // 微信小程序
-      const platform = getPlatform();
-      if (platform === 'miniprogram') {
-        window.toWXSendMsg({
-          type: 'scanQRCode',
-        });
-        window.subscribe('scanQRCodeOver', (options) => {
-          console.log('微信扫码结束之后的返回参数', options);
-          runScanFn(options);
-        });
-      } else {
-        this.$wx.scanQRCode({
-          desc: 'scanQRCode desc',
-          needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
-          // scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
-          success: (res) => {
-            console.log('H5页面扫码获取到的参数——成功', res);
-            runScanFn(res);
-            // this.formMsg.deviceCode = res.resultStr;
-          },
-          error: (res) => {
-            console.log('H5页面扫码获取到的参数——失败', res);
-            // console.log(242, res);
-          },
-        });
+      } catch (err) {
+        console.log(624, err);
       }
 
-      /* uni.scanCode({
-       onlyFromCamera: false,
-       scanType: ['qrCode'],
-       success: (res) => {
-       console.log('扫码', res);
-       if (res.scanType == 'QR_CODE' && res.scanType) {
-       console.log(res.result);
-       const url = res.result;
-       if (url.indexOf('auth/') === -1) {
-       this.getPaperCouponInfo(res.result);
-       } else {
-       const start = url.indexOf('auth/');
-       const end = url.indexOf('?');
-       const params = url.slice(start, end).split('/');
-       if (params && params.length) {
-       const couponCode = params[1];
-       this.getPaperCouponInfo(couponCode);
-       }
-       }
-       }
-       },
-       }); */
     },
+    // 处理扫码结果: 组装参数,剩余流程,在 缴费支付页面 实现
+    async qrCodesRule(code) {
+      try {
+        const qrCodesres = await qrCodes(code); // 无牌车扫码
+        // 记录buildingId,确保 buildingId 是最新的数据
+        window.localStorage.setItem('buildingId', qrCodesres.buildingId);
+        // 如果是无牌车扫码:出场
+        console.log('模拟出场', this.unlicensedInfo.type);
+        // return
+        if (this.unlicensedInfo?.type === 'unlicensedOut') {
+          // 查询用户是否存在车牌
+          this.$store.dispatch('order/unlicensedRule', (vehicleNo) => {
+            // 出场前,扫码缴费
+            this.$router.push({
+              path: 'parkingFeeDetail',
+              query: {
+                type: 'success',
+                gateId: qrCodesres.gateId,
+                vehicleNo: vehicleNo
+              }
+            })
+          });
+          return
+        }
+        // 如果是无牌车扫码:入场
+        const unlicensedCarCheckInres = await unlicensedCarCheckIn({ // 获取无牌车牌
+          gateId: qrCodesres.gateId
+        });
+        // 前往 缴费支付页面
+        this.$router.push({
+          path: 'parkingFeeMsg',
+          query: {
+            type: 'success',
+            vehicleNo: unlicensedCarCheckInres.vehicleNo
+          }
+        })
+      } catch (err) {
+        // 车场扫描道闸入口,发现无车/车场扫描道闸入口,发现有牌车 >>> 停止往下执行,默认提示报错信息
+        if (/CAR_NOT_FOUND|CAR_HAS_PLATE/.test(err.code)) {
+          return
+        }
+        console.log('模拟出场的报错', err);
+        return
+        // 如果是其他错误的话,则继续往下执行
+        this.$router.push({
+          path: 'parkingFeeMsg',
+          query: {
+            type: 'fail'
+          }
+        })
+      }
+    },
+    // 前往支付
+    unlicensedToPay() {
+      this.toHandleSearch(this.unlicensedCar)
+    }
   },
 };

+ 32 - 17
src/pages/parkingFee/mixins/parkingFeeDetail.js

@@ -62,16 +62,13 @@ export default {
       usePointsTime: (state) => state.order.usePointsTime,
       enableConsume: (state) => state.order.enableConsume,
       unitAmount: (state) => state.order.unitAmount,
+      unlicensedInfo: state => state.unlicensedInfo
       // checkedTotal: state => state.order.checkedTotal,
     }),
     // 支付按钮状态
     payBtnDisabled() {
-      console.log('62626262626', this.member, this.orderDetail, !this.orderDetail.parkInfo);
-      return false
-      /* return (
-        !this.actualPayFee ||
-        (JSON.stringify(this.member) !== '{}' && !this.orderDetail.parkInfo)
-      ); */
+      // 当存在待支付金额 或者 用户登陆
+      return !this.orderDetail?.parkingRecord?.totalFeeInYuan || (JSON.stringify(this.member) !== '{}' && !this.orderDetail.parkInfo);
     },
     integralDesc() {
       if (this.pointsTime > 0) {
@@ -149,11 +146,11 @@ export default {
           }
         }
         const res = await ordersAndPrepay(params);
-        console.log('orderDetail', res);
+        // console.log('orderDetail', res);
         if (res?.paymentType === 'NO_FEE_PAY') {
           this.btnLoading = false;
           this.$router.replace({
-            path: 'parkingFeeSuccess?vehicleNo=' + this.$route.query.vehicleNo,
+            path: this.getPagePath(),
           });
           // 支付成功
           return
@@ -207,7 +204,8 @@ export default {
                   name: 'parkingFeeDetail'
                 });
                 this.$router.replace({
-                  path: 'parkingFeeSuccess?carno=' + this.parkInfo.carno,
+                  // path: 'parkingFeeSuccess?carno=' + this.parkInfo.carno,
+                  path: this.getPagePath(),
                 });
               } else {
                 this.reCreateParkOrder();
@@ -234,7 +232,8 @@ export default {
                 } else {
                   this.btnLoading = false;
                   this.$router.replace({
-                    path: 'parkingFeeSuccess?vehicleNo=' + this.$route.query.vehicleNo,
+                    // path: 'parkingFeeSuccess?vehicleNo=' + this.$route.query.vehicleNo,
+                    path: this.getPagePath(),
                   });
                 }
               });
@@ -277,7 +276,11 @@ export default {
         message: '支付失败',
         confirmButtonColor: '#333',
       }).then(() => {
-        this.$store.dispatch('order/orderInit', '粤A51113')
+        this.$store.dispatch('order/orderInit', {
+          gateId: this.$route.query?.gateId,
+          vehicleNo: this.$route.query?.vehicleNo,
+          endlessLoop: this.endlessLoop
+        })
         this.btnLoading = false;
         // this.createParkOrder();
       });
@@ -301,12 +304,12 @@ export default {
       // 纸质优惠券
       // 优惠金额
       // 应付金额
-      console.log(83838383);
-
       // this.$store.commit('order/SET_ORDER_DETAIL', checkOutResponse);
       try {
         this.$store.dispatch('order/orderInit', {
           vehicleNo: this.$route.query.vehicleNo,
+          gateId: this.$route.query?.gateId,
+          endlessLoop: this.endlessLoop,
           callback: (res) => {
             console.log(303, res);
             if (/NOT_FOUND|PARKING_RECORD_NOT_FOUND/.test(res.code)) {
@@ -368,9 +371,9 @@ export default {
     //
     // 计算优惠信息
     discountssss(params) {
-      console.log(275, params);
-      console.log(275, params.discountInfo);
-      console.log(275, params.discountInfo.consume);
+      // console.log(275, params);
+      // console.log(275, params.discountInfo);
+      // console.log(275, params.discountInfo.consume);
       return 1;
     },
     coupon() {
@@ -384,7 +387,11 @@ export default {
     // 重置倒计时
     resetCountDown() {
       this.$refs.countDown.reset();
-      // this.$store.dispatch('order/orderInit', '000')
+      this.$store.dispatch('order/orderInit', {
+        gateId: this.$route.query?.gateId,
+        vehicleNo: this.$route.query?.vehicleNo,
+        endlessLoop: this.endlessLoop
+      })
       // 重新创建订单
       // this.createParkOrder();
     },
@@ -405,6 +412,14 @@ export default {
       this.$store.dispatch('order/savePointsMath', () => {
         this.popup = false;
       });
+    },
+    // 获取成功缴费之后前往的页面
+    getPagePath() {
+      let pagePath = 'parkingFeeSuccess?vehicleNo=' + this.$route.query.vehicleNo
+      if (this.$route.query.vehicleNo.indexOf('临') > -1) {
+        pagePath = 'parkingFeeMsg?type=pay'
+      }
+      return pagePath
     }
   },
 };

+ 22 - 16
src/pages/parkingFee/mixins/parkingFeeDetailSuccess.js

@@ -2,7 +2,8 @@ import { mapState } from 'vuex';
 import uni from '@/utils/uniHooks';
 import { orderInfo } from '@/api/parking';
 import ordersInfoMockData from '@/api/mockData/ordersInfo.json';
-import {ORDER_STATUS} from '@/common/js/BaseDictionary'
+import { ORDER_STATUS } from '@/common/js/BaseDictionary'
+import moment from 'moment'
 export default {
   data() {
     return {
@@ -22,19 +23,7 @@ export default {
     this.getData();
   },
   computed: {
-    parkingTime() {
-      const time = this.detail.serviceMin;
-      const days = parseInt(time / 60 / 24);
-      const hours = parseInt((time / 60) % 24);
-      const minutes = parseInt(time % 60);
-      if (days > 0) {
-        return `${days}天 ${hours}小时 ${minutes}分钟`;
-      }
-      if (hours > 0) {
-        return `${hours}小时 ${minutes}分钟`;
-      }
-      return `${minutes}分钟`;
-    },
+
     ...mapState({
       // custTypeId: (state) => state.custTypeId,
       // paramsScene: (state) => state.paramsScene,
@@ -117,9 +106,26 @@ export default {
       });
     },
   },
-  filters:{
+  filters: {
     orderStatus(val) {
       return ORDER_STATUS[val]
-    } 
+    },
+    parkingTime(val) {
+      const time = val;
+      const days = parseInt(time / 60 / 24);
+      const hours = parseInt((time / 60) % 24);
+      const minutes = parseInt(time % 60);
+      if (days > 0) {
+        return `${days}天 ${hours}小时 ${minutes}分钟`;
+      }
+      if (hours > 0) {
+        return `${hours}小时 ${minutes}分钟`;
+      }
+      return `${minutes}分钟`;
+    },
+    momentFormat(val) {
+      if(!val)return val
+      return moment(val).format('YYYY-MM-DD hh:mm:ss')
+    }
   }
 };

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

@@ -1,5 +1,5 @@
 <template>
-  <component :is="componentName"></component>
+  <component :is="componentName" :theme="theme"></component>
 </template>
 
 <script>

+ 153 - 9
src/pages/parkingFee/parkingFeeMsg.vue

@@ -1,15 +1,39 @@
 <template>
-  <div :class="[theme]">
+  <div :class="[theme, 'bg']">
     <!-- 领取临牌:成功 -->
     <div class="success-box" v-if="type === 'success'">
-      <img class="success-icon" :src="require(`./static/images/unlicensed/success.png`)" />
+      <img class="icon" :src="require(`./static/images/unlicensed/success.png`)" />
       <div class="status-title">临牌领取成功</div>
-      <div class="status-info">若未正常抬杠,请关闭当前页面重新扫码 或联系车场管理人员处理</div>
-      <k-button title="进入首页" disabledColor="#D1D2D9" />
+      <div class="status-info">若未正常抬杠,请关闭当前页面重新扫码</div>
+      <div class="status-info">或联系车场管理人员处理</div>
+      <div class="card-box">
+        <img :src="`${require(`./static/images/unlicensed-0.png`)}`" />
+        <div class="car-number">
+          <div class="number">{{ vehicleNo | formatCarno}}</div>
+          <div class="tips">车辆类型:无牌车辆</div>
+        </div>
+      </div>
+      <k-button title="进入首页" disabledColor="#D1D2D9" @click="goHome" />
     </div>
     <!-- 领取临牌:失败 -->
-    <div class="fill-box" v-if="type === 'fill'">
-      <img class="fill" :src="require(`./static/images/unlicensed/fill.png`)" />
+    <div class="fail-box" v-if="type === 'fail'">
+      <img class="icon" :src="require(`./static/images/unlicensed/fail.png`)" />
+      <div class="status-title">临牌领取失败</div>
+      <div class="status-info">请关闭当前页面重新扫码</div>
+      <div class="status-info">或联系车场管理人员处理</div>
+      <div class="card-box">
+        <img :src="`${require(`./static/images/unlicensed-0.png`)}`" />
+        <div class="car-number">
+          <div class="number">临K ???</div>
+          <div class="tips">车辆类型:无牌车辆</div>
+        </div>
+      </div>
+      <k-button disabledColor="#D1D2D9" @click="scanCarCode">
+        <template v-slot:left>
+          <img class="unlicensed-scan" :src="`${require(`./static/images/unlicensed-scan.png`)}`" />
+        </template>
+        重新扫码
+      </k-button>
     </div>
     <!-- 支付成功 -->
     <div class="pay-box" v-if="type === 'pay'">
@@ -20,32 +44,102 @@
 </template>
 
 <script>
+import uni from '@/utils/uniHooks';
+import { initWxJsSdkConfig } from '@/utils/login';
+import { getPlatform } from '@/utils/index';
 export default {
   name: 'parkingFeeMsg',
   data() {
     return {
       theme: 'theme-mall',
       type: '',
+      vehicleNo: '',
     };
   },
-  created() {
+  async created() {
     setTimeout(() => {
       uni.setNavigationBarTitle({
         title: '停车缴费提示',
       });
     }, 300);
+    const platform = getPlatform();
+    if (platform === 'micromessenger') {
+      await initWxJsSdkConfig(['checkJsApi', 'scanQRCode']);
+    }
     console.log(this.$route.query);
     if (this.$route.query?.type) {
       this.type = this.$route.query?.type;
     }
     if (this.type === 'success') {
+      this.vehicleNo = this.$route.query?.vehicleNo;
     }
   },
   mounted() {},
+  methods: {
+    // 无牌车闸机扫码
+    scanCarCode() {
+      const runScanFn = (res) => {
+        if (res.scanType == 'QR_CODE' && res.scanType) {
+          console.log(res.result);
+          // 获取二维码参数之后,模拟提取参数
+          const url = res.result;
+          if (url.indexOf('auth/') === -1) {
+            // 单纯的code
+            console.log('提取到的参数', 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.getPaperCouponInfo(couponCode);
+            }
+          }
+        }
+      };
+      // 微信小程序
+      const platform = getPlatform();
+      if (platform === 'miniprogram') {
+        window.toWXSendMsg({
+          type: 'scanQRCode',
+        });
+        window.subscribe('scanQRCodeOver', (options) => {
+          console.log('微信扫码结束之后的返回参数', options);
+          runScanFn(options);
+        });
+      } else {
+        this.$wx.scanQRCode({
+          desc: 'scanQRCode desc',
+          needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
+          // scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
+          success: (res) => {
+            console.log('H5页面扫码获取到的参数——成功', res);
+            runScanFn(res);
+            // this.formMsg.deviceCode = res.resultStr;
+          },
+          error: (res) => {
+            console.log('H5页面扫码获取到的参数——失败', res);
+            // console.log(242, res);
+          },
+        });
+      }
+    },
+    goHome() {
+      this.$router.replace({
+        path: 'home',
+      });
+    },
+  },
 };
 </script>
 
 <style lang="less" scoped>
+.bg {
+  background-color: #fbfcff;
+}
 .pay-box {
   text-align: center;
   margin-top: 84px;
@@ -65,10 +159,12 @@ export default {
   }
 }
 
-.success-box {
+.success-box,
+.fail-box {
   margin-top: 123px;
   text-align: center;
-  .success-icon {
+  padding: 0 24px;
+  .icon {
     width: 80px;
     height: 80px;
     display: block;
@@ -82,5 +178,53 @@ export default {
     line-height: 50px;
     color: #333333;
   }
+  .status-info {
+    font-family: 'PingFang SC';
+    font-style: normal;
+    font-weight: 400;
+    font-size: 26px;
+    line-height: 40px;
+    text-align: center;
+    color: #999999;
+  }
+  .card-box {
+    height: 230px;
+    margin-top: 39px;
+    margin-bottom: 52px;
+    background: #fbfcff;
+    border: 1px solid #d9dbe0;
+    border-radius: 4px;
+    display: flex;
+    // align-items: center;
+    // padding-top: 53px;
+    // padding-left: 18px;
+    // padding-bottom: 34px;
+
+    img {
+      width: 288px;
+      height: 142px;
+      margin-top: 62px;
+      display: block;
+    }
+    .car-number {
+      margin-top: 68px;
+      .number {
+        font-size: 50px;
+        line-height: 56px;
+        font-weight: 600;
+        color: #333333;
+        margin-bottom: 23px;
+        letter-spacing: 6.5px;
+      }
+      .tips {
+        color: #999999;
+      }
+    }
+  }
+  .unlicensed-scan {
+    width: 60px;
+    height: 60px;
+    margin-right: 16px;
+  }
 }
 </style>

+ 0 - 0
src/pages/parkingFee/static/images/unlicensed/fill.png → src/pages/parkingFee/static/images/unlicensed/fail.png


+ 17 - 1
src/store/index.js

@@ -52,6 +52,10 @@ const store = new Vuex.Store({
     brandInfo: {},
     curMarket: {},
     isInit: true, // 当内嵌在小程序中的H5页面,没有接收到小程序数据时,默认显示骨架屏幕
+    // 无牌车
+    unlicensedInfo: {},
+    // 防止用户在无牌车流程中卡死
+    endlessLoop: ''
   },
   mutations: {
     SET_GROUP_ID(state, payload) {
@@ -153,6 +157,13 @@ const store = new Vuex.Store({
     SET_BRAND_ID(state, payload) {
       state.brandId = payload;
     },
+    // 无牌车
+    SET_UNLICENSED_INFO(state, payload) {
+      state.unlicensedInfo = payload;
+    },
+    SET_ENDLESS_LOOP(state, payload) {
+      state.endlessLoop = payload;
+    },
   },
   actions: {
     async baseInit({ commit, dispatch }, { options, callback }) {
@@ -181,7 +192,8 @@ const store = new Vuex.Store({
           accessToken = '',
           source = '',
           appId = '',
-
+          // 无牌车逻辑
+          unlicensedInfo,
           // CRM
           // brandInfo = {},
           // curMarket = {}
@@ -218,6 +230,10 @@ const store = new Vuex.Store({
         commit('SET_GROUP_ID', groupId);
         commit('SET_MALL_ID', mallId);
         commit('SET_BRAND_ID', brandId);
+        // 如果是无牌车
+        // console.log('218218218218', unlicensedInfo);
+        console.log('用户扫码进入的', unlicensedInfo);
+        commit('SET_UNLICENSED_INFO', unlicensedInfo)
         /*if (/dev-|8080|qa-/.test(href)) {
          commit('SET_GROUP_ID', groupId);
          commit('SET_MALL_ID', mallId);

+ 23 - 7
src/store/order.js

@@ -1,4 +1,4 @@
-import { checkOut, calculateDiscount, ordersAndPrepay, currentUnlicensedPlate, unlicensedCarCheckIn } from '@/api/parking';
+import { checkOut, calculateDiscount, ordersAndPrepay, currentUnlicensedPlate, unlicensedCarCheckIn, unlicensedCarCheckout } from '@/api/parking';
 
 // import checkOutQHResponse from '@/api/mockData/checkout.qh3.response.json'
 // import checkOutQHResponse from '@/api/mockData/checkout.hz.response.json';
@@ -133,21 +133,31 @@ const mutations = {
 };
 
 const actions = {
-  async orderInit({ commit, dispatch, state }, { vehicleNo = '浙A616A1', callback }) {
+  /**
+   * 车辆订单的缴费信息初始化
+   * @param {*} param0
+   * @param {*} param1.gateId  车场闸机口ID
+   * @param {*} param1.vehicleNo  车牌号(包含临牌)
+   * @param {*} param1.callback  回调函数,用于接口报错时,展示对应的信息
+   * @param {*} param1.endlessLoop 用于判断当前用户是否扫码进入 
+   */
+  async orderInit({ commit, dispatch, state }, { gateId='124p3LK1', vehicleNo = '浙A616A1', callback, endlessLoop }) {
     try {
       const unlicensed = vehicleNo.indexOf('临') > -1; // true: 临时车牌;false:普通车牌
       // const res = await checkOut('浙A616A1');
       // const res = await checkOut('闽AAQ5519', unlicensed);
       // const res = await checkOut('粤A51113');
       // const res = await checkOut('沪DCJ986');
-      const res = await checkOut(vehicleNo, unlicensed);
-      console.log(vehicleNo, res);
+      // 场内缴费,调 check-out 接口,
+      const method = unlicensed && endlessLoop ? unlicensedCarCheckout : checkOut
+      const res = await method(vehicleNo, unlicensed, gateId);
+      // console.log(vehicleNo, res);
       // 所有的优惠时间长转为金额
       // console.log(112, '所有的优惠时间长转为金额');
       // dispatch('orderInitRule', checkOutQHResponse);
       dispatch('orderInitRule', res);
     } catch (error) {
-      console.log('143143143143143', error);
+      // console.log('151151151151151', error);
       /* if (/NOT_FOUND|PARKING_RECORD_NOT_FOUND/.test(error.code)) {
         callback && callback(error)
       } */
@@ -467,7 +477,7 @@ const actions = {
   },
 
   // 无牌车逻辑
-  async unlicensedRule({ commit, dispatch, state }) {
+  async unlicensedRule({ commit, dispatch, state }, callback) {
     try {
       // const res = await currentUnlicensedPlate(); // 无牌车查询
       // const res = await unlicensedCarCheckIn({gateId: 1}); // 无牌车入场
@@ -475,8 +485,14 @@ const actions = {
        * CAR_NOT_FOUND 车场扫描道闸入口,发现无车
        * CAR_HAS_PLATE 车场扫描道闸入口,发现有牌车
        */
-      const res = unlicensedCarCheckInResponse;
+      // const res = unlicensedCarCheckInResponse;
+      const res = await currentUnlicensedPlate();
       console.log('无牌车的查询记录', res);
+      commit('setUnlicensedCar', res.vehicleNo);
+      // 如果是扫码进入的用户,在出场时需要重新扫码,这时会在此处传入的一个回调函数,在获取到临牌时,返回给 qrCodesRule 函数
+      if(res.vehicleNo && callback) {
+        callback(res.vehicleNo);
+      }
     } catch (err) {
       console.log(err);
     }

+ 9 - 0
src/utils/api-kip.js

@@ -208,3 +208,12 @@ export function kipAgreementCheck (params) {
   const url = `/profile/v1/customer/agreemen/checkUserAgreementVersion`;
   return request.post(url, params, {...DEFAULT_CONFIG});
 }
+
+/**
+ * 补录无感积分
+ * 商圈会员待积分状态: PENDING: 需要弹窗提示补录, FINISHED: 不需要提示补录
+ */
+export function wxEasyPointsCommitStatus(params) {
+	const url = `/points/v1/auto/points/commit-status`;
+	return request.get(url, params);
+}

+ 1 - 1
src/utils/index.js

@@ -61,7 +61,7 @@ export function getPlatform() {
   if (/micromessenger/g.test(userAgent)) {
     return 'micromessenger';
   }
-  return 'miniprogram';
+  return 'miniprogram'; // TODO: 上线前改为其他
 }
 
 // 是否在微信小程序中运行

+ 21 - 0
src/utils/wx-points-commit-status.js

@@ -0,0 +1,21 @@
+import { wxEasyPointsCommitStatus } from '@/utils/api-kip.js'
+
+export async function  getWxEasyPointsCommitStatus() {
+    try {
+        const res = await wxEasyPointsCommitStatus()
+        console.log('无感积分补录信息', res)
+        if (res.data.pointsCommitStatus === 'FINISHED') {
+            return false
+        }
+        if (res.data.pointsCommitStatus === 'PENDING') {
+            return true
+        }
+
+    } catch (err) {
+        uni.showToast({
+            title: err.message,
+            duration: 2000,
+            icon: 'none'
+        })
+    }
+}

+ 7 - 0
vue.config.js

@@ -2,6 +2,7 @@ const path = require('path');
 const postcssPxToViewport = require('./postcss.config');
 const vueSrc = 'src';
 const CDN_URL = process.env.CDN_URL || '';
+const TerserPlugin = require('terser-webpack-plugin')
 
 module.exports = {
   publicPath:
@@ -11,6 +12,8 @@ module.exports = {
         : '/tparking/'
       : '/tparking/',
   assetsDir: 'static',
+  // productionSourceMap: true,
+  productionSourceMap: process.env.NODE_ENV === 'dev',
   css: {
     loaderOptions: {
       // 给 less-loader 传递 Less.js 相关选项
@@ -30,6 +33,7 @@ module.exports = {
       //   additionalData: `@import "~@/uni.scss";`,
       // },
     },
+    sourceMap: true
   },
   // pluginOptions: {
   //   'style-resources-loader': {
@@ -74,8 +78,11 @@ module.exports = {
         return newArgs;
       })
       .end();
+      // 编译之后清理console.log
+      config.optimization.minimizer('vue').use(TerserPlugin, [{ terserOptions: { compress: { drop_console: true } } }])
   },
   configureWebpack: {
+    devtool: process.env.NODE_ENV === 'dev' ? 'source-map' : undefined,
     resolve: {
       alias: {
         '@': path.join(__dirname, vueSrc),