浏览代码

feat: 微服务接入改造30%(创建订单页面:优惠券选择逻辑优化)

John-Hong 2 年之前
父节点
当前提交
526107e8f2

+ 38 - 0
src/api/mockData/checkout.qh4.response.json

@@ -0,0 +1,38 @@
+{
+  "parkingRecord": { "vehicleNo": "粤A51113", "enterTime": "2023-02-03 08:00:00", "serviceMin": 18975, "totalFee": 129300, "actualPayFee": 592.0, "buildingId": "QHKC-P1", "totalFeeInYuan": 1293.0 },
+  "discountInfo": {
+    "usingTotalDiscount": 701,
+    "memberLevelDiscount": false,
+    "points": [{ "available": 10, "maxDiscountFee": 999999999, "pointsPerUnit": 15, "unitAmount": 1, "newMember": false, "label": "已选择兑换666元", "discountFee": 666 }],
+    "coupons": [
+      { "code": "57q5hahlprd_t", "name": "可叠加电子券2(上限3)", "limitCountPerOrder": 3, "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "defaultSelected": true, "superposition": "2" },
+      { "code": "sztsq81fumq_t", "name": "可叠加电子券2(上限3)", "limitCountPerOrder": 3, "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "defaultSelected": true, "superposition": "2" },
+      { "code": "dj700g1e1mh_t", "name": "可叠加电子券2(上限3)", "limitCountPerOrder": 3, "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "defaultSelected": true, "superposition": "2" },
+      { "code": "hejm57s01sf_t", "name": "可叠加电子券2(上限3)", "limitCountPerOrder": 3, "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "defaultSelected": true, "superposition": "2" },
+      { "code": "jmcn5djj9bk_t", "name": "可叠加电子券1(上限2)", "limitCountPerOrder": 2, "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "defaultSelected": true, "superposition": "2" },
+      { "code": "zosjoe59tcd_t", "name": "可叠加电子券1(上限2)", "limitCountPerOrder": 2, "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "defaultSelected": true, "superposition": "2" },
+      { "code": "tt8rsdeo8ia_t", "name": "可叠加电子券1(上限2)", "limitCountPerOrder": 2, "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "defaultSelected": true, "superposition": "2" },
+      { "code": "ctdhlegs287_t", "name": "不可叠加停车券", "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "superposition": "1" },
+      { "code": "ydgk07bvb88_t", "name": "不可叠加停车券", "expirationDate": "2023-02-28 23:59:59", "discountFee": 5, "superposition": "1" }
+    ]
+  },
+  "parkingRule": {
+    "maxOneDayDiscountFee": 60,
+    "enableNewMemberPoints": false,
+    "enablePoints": true,
+    "enableCoupon": true,
+    "maxOneDayCoupons": 5,
+    "remainCoupons": 5,
+    "enablePaperCoupons": false,
+    "maxPointsTime": 666,
+    "enableConsume": false,
+    "enableConsumeSplit": false,
+    "availableDiscountFee": 60,
+    "hourPrice": 5
+  },
+  "parkInfo": {
+    "parkName": "深圳嘉湾汇停车场",
+    "description": "计费基础规则:15分钟内免费,首小时15元,其后每小时5元,全天封顶60元。\r\n嘉湾汇会员停车礼遇:\r\n银卡:每月可免费领取2张首2小时停车券\r\n金卡:每月可免费领取5张首2小时停车券\r\n铂金卡:每月可免费领取10张首2小时停车券\r\n*数量有限,领完即止\r\n仅限开具一个月内的停车费电子发票 ",
+    "parkMallCode": 5
+  }
+}

+ 7 - 4
src/api/request.js

@@ -23,7 +23,8 @@ function getHeaders(config = {}) {
   const { contentType = 'json' } = config;
   const ct = CONTENT_TYPE_ARRAY[contentType];
   let header = {
-    appId: uni.getStorageSync('appid'),
+    // appId: uni.getStorageSync('appid'),
+    appId: 'wx92c3e55fbef6b2af',
     'Content-Type': ct,
   };
   const token = getToken();
@@ -101,7 +102,8 @@ function XUser(config) {
   // console.log('101101101101',  store.state.member);
   const params = {
     // userId: '8aaa828583bbbc030183cf34b536000a',
-    userId: store.state.kipUserId, // K+用户ID
+    // userId: store.state.kipUserId, // K+用户ID
+    userId: '2c9d85868652dee50186532bdbbb0001', // K+用户ID
     sourceType: 'WECHAT',
     // phoneNumber: '18521563898',
     phoneNumber: store.state.mobile, // 终端用户ID, 微信端传openId, 支付宝小程序传阿里userId, APP传KIP的userId
@@ -115,8 +117,9 @@ function XUser(config) {
     // cid: '8aaa809d835ba76d018378bc57180006',
     cId: store.state.openid, // 终端用户ID, 微信端传openId, 支付宝小程序传阿里userId, APP传KIP的userId
     // vipCode: 'KERRY100213505',
-    vipCode: store.state.member.vipcode, // 终端用户ID, 微信端传openId, 支付宝小程序传阿里userId, APP传KIP的userId
-    // vipCode: 'KERRY100213853', // 终端用户ID, 微信端传openId, 支付宝小程序传阿里userId, APP传KIP的userId
+    // vipCode: store.state.member.vipcode, // 终端用户ID, 微信端传openId, 支付宝小程序传阿里userId, APP传KIP的userId
+    vipCode: 'KERRY100213853', // 终端用户ID, 微信端传openId, 支付宝小程序传阿里userId, APP传KIP的userId
+    // vipCode: 'KERRY100213851', // 终端用户ID, 微信端传openId, 支付宝小程序传阿里userId, APP传KIP的userId
     lbsId: '8aaa82ea804d07cd0180516ff03b0008',
     // lbsId: store.state.lbsId,
   };

+ 90 - 16
src/components/plate-number/plateNumber.vue

@@ -9,18 +9,23 @@
       :maskClick="false"
     >
       <div class="plate_number_wrap">
-        <div class="close-box">
-          <div @click.stop="close_keyboard">关闭</div>
+        <!-- 提示区域 -->
+        <div class="event-box">
+          <div class="close" @click.stop="close_keyboard">取消</div>
+          <div>车牌键盘</div>
+          <div class="sure" @click.stop="close_keyboard">确认</div>
         </div>
         <div class="plate_chinese_box">
           <button
             size="small"
+            :class="[item.id === 99 && 'del']"
             v-for="(item, index) in ChineseList"
             :key="item.id"
             :disabled="disabledKeyboard(index)"
             @click="checkChinese(index)"
           >
-            {{ item.name }}
+            <span v-if="item.id !== 99">{{ item.name }}</span>
+            <img v-else :src="require(`../../static/images/close.png`)" alt="">
           </button>
         </div>
       </div>
@@ -34,17 +39,24 @@
       :close-on-click-overlay="false"
     >
       <div class="allBoard_wrap">
+        <!-- 提示区域 -->
+        <div class="event-box">
+          <div class="close" @click.stop="close_keyboard">取消</div>
+          <div>全拼键盘</div>
+          <div class="sure" @click.stop="close_keyboard">确认</div>
+        </div>
         <div class="close-box">
-          <div @click.stop="close_keyboard">关闭</div>
           <div class="plate_number_box">
             <button
               size="small"
               v-for="(item, index) in English_Number"
               :key="item.id"
+              :class="[item.id === 99 && 'del', item.id === 66 && 'mini']"
               :disabled="item.id === 45 || item.id === 46 ? true : false"
               @click="checkEnglish_num(index)"
             >
-              {{ item.name }}
+              <span v-if="item.id !== 99">{{ item.name }}</span>
+              <img v-else :src="require(`../../static/images/back.png`)" alt="">
             </button>
           </div>
         </div>
@@ -205,10 +217,10 @@ export default {
           name: '宁',
           id: 30,
         },
-        {
+        /* {
           name: 'ABC',
           id: 66,
-        },
+        }, */
         {
           name: '新',
           id: 31,
@@ -237,6 +249,14 @@ export default {
           name: '澳',
           id: 37,
         },
+        {
+          name: '台',
+          id: 38,
+        },
+        {
+          name: '临',
+          id: 39,
+        },
         {
           name: '←',
           id: 99,
@@ -537,8 +557,29 @@ export default {
 .class-van-button-small {
   min-width: 0;
   border-radius: 10px;
-  margin: 10px 3px;
-  box-shadow: 10px 10px 10px #aaa;
+  margin: 6px 3px;
+  box-shadow: 0px 2px 0px #9DA0A3;
+}
+.event-box {
+  display: flex;
+  justify-content: space-around;
+  background: #FFFFFF;
+  & > * {
+    flex: 1;
+    text-align: center;
+    padding: 26px 0;
+    color: #333;
+    font-size: 34px;
+  }
+  .close {
+    text-align: left;
+    padding-left: 44px;
+
+  }
+  .sure {
+    text-align: right;
+    padding-right: 44px;
+  }
 }
 .plate_number {
   width: 100%;
@@ -570,15 +611,34 @@ export default {
       display: flex;
       flex-wrap: wrap;
       justify-content: center;
+      background-color: #D1D5DB;
+      box-sizing: border-box;
+      padding-top: 18px;
+      padding-bottom: 24px;
 
       button {
         width: 9%;
-        height: 2.5rem;
-        line-height: 2.5rem;
+        height: 85px;
+        line-height: 85px;
         text-align: center;
         padding: 0;
-        font-size: 28px;
+        color: #000;
+        font-weight: 400;
+        font-size: 38px;
+        margin: 6px;
+        background: #FFFFFF;
         .class-van-button-small;
+        
+        &.del{
+          background-color: #ADB3BC;
+          img {
+            width: 43px;
+            height: 30px;
+          }
+        }
+      }
+      button[disabled="disabled"] {
+        color: #9DA0A3;
       }
     }
   }
@@ -599,12 +659,12 @@ export default {
   }
 
   .close-box {
-    padding-top: 22px;
+    padding-top: 18px;
     box-sizing: border-box;
     font-size: 24px;
-    color: #3e67ff;
     text-align: right;
-    margin-right: 1.25rem;
+    background: #D1D5DB;
+    padding-bottom: 24px;
   }
 
   .plate_number_box {
@@ -619,8 +679,22 @@ export default {
       line-height: 2.5rem;
       text-align: center;
       padding: 0;
-      font-size: 28px;
+      font-size: 38px;
+      background: #FFFFFF;
       .class-van-button-small;
+
+      &.del{
+        img {
+          width: 33px;
+          height: 22px;
+        }
+      }
+      &.mini{
+        font-size: 28px;
+      }
+    }
+    button[disabled="disabled"] {
+      color: #9DA0A3;
     }
   }
 }

+ 1 - 2
src/pages/parkingFee/components/base/parkingFeeDetail.vue

@@ -2,7 +2,6 @@
   <scroll-view class="scroll-Y" v-if="orderDetail && orderDetail.parkingRecord && orderDetail.parkingRecord.vehicleNo">
     <div>
       <!--    <wx-points-commit ref="wxPointsCommit"></wx-points-commit>-->
-
       <div class="warp">
         <div
           :class="{
@@ -113,7 +112,7 @@
         <span style="color: #8d8d8d; padding-left: 30px; font-size: 28px">已优惠{{ usingTotalDiscount | currency }}元</span>
         <div class="count-down-box">
-          <van-count-down v-if="orderDetail.parkingRecord.vehicleNo" format="mm:ss" :time="refreshTime * 1000" @finish="resetCountDown()" />
+          <van-count-down v-if="orderDetail.parkingRecord.vehicleNo" format="mm:ss" ref="countDown" :time="refreshTime * 1000" @finish="resetCountDown()" />
           <span class="desc">后同步最新费用</span>
         </div>
       </div>

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

@@ -44,11 +44,11 @@
           </div> -->
           <div class="parking-info-item">
             <span class="info-key">停车时长</span>
-            <span class="info-value">{{ detail.parkDuration }}</span>
+            <span class="info-value">{{ detail.serviceMin }}</span>
           </div>
           <div class="parking-info-item">
             <span class="info-key">开票状态</span>
-            <span class="info-value">{{ isInvoiceName }}</span>
+            <span class="info-value">{{ detail.invoiceStatusText }}</span>
           </div>
         </div>
       </div>

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

@@ -195,7 +195,7 @@ export default {
 };
 </script>
 
-<style lang="less">
+<style lang="less" scoped>
 page {
   background-color: #f4f7ff;
 }

+ 144 - 261
src/pages/parkingFee/components/purple/parkingFee.vue

@@ -1,12 +1,7 @@
 <template>
-  <scroll-view :class="{ 'scroll-Y': true, 'color-scroll-Y': custTypeId !== 0 }">
-    <!--    <wx-points-commit ref='wxPointsCommit'></wx-points-commit>-->
-    <!--    <authorize ref="authorize"></authorize>-->
-    <!--    <my-protocol-modal ref="szProtocolModal" title="会员协议政策更新提示"></my-protocol-modal>-->
+  <scroll-view class="scroll-Y color-scroll-Y">
     <div class="wrap">
       <div class="parkingFee">
-        <!--        <div>{{ `url(${picUrl}${blueHeadBg});` }}:{{ typeof custTypeId }}:{{ custTypeId }}</div>-->
-        <!--        <img :src="`${picUrl}${blueHeadBg}`" alt="">-->
         <!-- 菜单 -->
         <div
           :class="{
@@ -73,10 +68,10 @@
                 <div class="li" @click="clickShowKeyboard(5)" :class="[active === 5 ? 'active' : '']">
                   {{ numArr[5] }}
                 </div>
-                <div class="li" @click="clickShowKeyboard(6)" :class="[active === 6 ? 'active' : '']">
+                <div :class="['li', carType !== 1 && 'dashed', active === 6 ? 'active' : '']" @click="clickShowKeyboard(6)">
                   {{ numArr[6] }}
                 </div>
-                <div class="li" @click="clickShowKeyboard(7)" :class="[active === 7 ? 'active' : '']" v-if="carType == 1">
+                <div class="li dashed" @click="clickShowKeyboard(7)" :class="[active === 7 ? 'active' : '']" v-if="carType == 1">
                   <span v-if="numArr[7]">{{ numArr[7] }}</span>
                 </div>
               </div>
@@ -96,36 +91,45 @@
           </div>
 
           <!-- 无牌缴费 -->
-          <div class="unlicensed-box">无牌车</div>
+          <div class="unlicensed-box" v-else>
+            <!-- 无牌车 -->
+            
+            <div class="no-car-unlicensed-box">
+              <img :src="`${require(`../../static/images/unlicensed-1.png`)}`" />
+              <div class="no-car-unlicensed-info">未查询到无牌车信息</div>
+              <div class="search-btn">
+                <!-- <van-icon name="scan" />扫描进场二维码领取无牌车号牌 -->
+                <img class="unlicensed-scan" :src="`${require(`../../static/images/unlicensed-scan.png`)}`" />扫描进场二维码领取无牌车号牌
+              </div>
+            </div>
+            <!-- 有无牌车 -->
+            <div class="in-car" v-if="false">
+              <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="tips">车辆类型:无牌车辆</div>
+                </div>
+              </div>
+              <div class="search-btn">
+                去支付
+              </div>
+            </div>
+          </div>
         </div>
-        <div
-          class="parkingFee-top"
-          :style="{
-            color: '#999',
-            background: `url(${require('../../static/images/parking-bgi.png')})`,
-            a: 'url()',
-            backgroundAttachment: 'fixed',
-          }"
-        >
-          <div
-            :class="{
-              top_content: true,
-              blue_top_content: custTypeId === 1,
-              green_top_content: custTypeId === 2,
-            }"
-            :style="{
-              'background-image': custTypeId === 1 ? `url(${picUrl}${blueHeadBg})` : '',
-            }"
-          >
+        <div class="parkingFee-top">
+          <div class="top_content">
             <div class="title_box">
               <span class="btn">缴费说明</span>
             </div>
             <div class="info" :class="!init_ch ? 'info_show' : ''">
-              <span>{{ description }}</span>
+              <!-- <p></p> -->
+              <!-- <p>{{ description }}</p> -->
+              <p v-html="description"></p>
             </div>
           </div>
-          <div class="top_down" @click="top_display" v-if="!init_ch && description && description.length > 60"></div>
-          <div class="top_down" @click="top_display" v-else></div>
+          <div class="top_down" @click="top_display" v-if="!init_ch && description && description.length > 60"><van-icon name="arrow-down" /></div>
+          <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>
@@ -143,16 +147,14 @@ export default {
 </script>
 
 <style lang="less" scoped>
-//@import '../../styles/mixins.less';
 .scroll-Y {
   width: 100%;
-  // display: flex;
-  // flex-direction: column;
   height: 100vh;
 }
 
 .color-scroll-Y {
   background: #f5f7fe;
+  // background: red;
 }
 
 .wrap {
@@ -165,23 +167,12 @@ export default {
     flex-direction: column;
 
     .top_menu {
-      //margin-top: 10px;
       background: #fff;
-      //padding-top: 50px;
       box-sizing: border-box;
       display: flex;
       justify-content: space-between;
-      //border-radius: 15px;
-      // position: absolute;
-      // left: 50%;
-      //box-shadow: 0 0 5px #666;
-      // transform: translateX(-50%);
-      //top: 160px;
-      //width: 700px;
-      //margin-left: 25px;
       padding-top: 34px;
       margin-bottom: 20px;
-      //height: 250px;
       padding-bottom: 30px;
 
       .menu_item {
@@ -241,8 +232,6 @@ export default {
         display: flex;
         flex-direction: column;
         background: #fff;
-        //border-radius: 15px;
-        //padding: 26px 25px 20px;
         box-sizing: border-box;
 
         .search_tip {
@@ -302,23 +291,21 @@ export default {
 
           .li {
             width: 100%;
-            border: 1px solid #D9DBE0;
+            border: 1px solid #d9dbe0;
             box-sizing: border-box;
             height: 90px;
             display: flex;
             align-items: center;
             justify-content: center;
             color: #333333;
-            background-color: #f4f7ff;
+            background-color: #F4F7FF;
             border-radius: 4px;
             font-size: 40px;
             margin: 0 3px;
-
-            &:nth-child(9) {
+            &.dashed {
               background-color: #fafbff;
               border-style: dashed;
             }
-
             &.active {
               border-color: #3e67ff;
             }
@@ -355,10 +342,12 @@ export default {
         }
       }
 
+      /* 历史车牌 */
       .vehicleMgt-list {
         display: flex;
         flex-direction: column;
-        margin-bottom: 35px;
+        // margin-bottom: 34px;
+        padding-bottom: 34px;
         //margin-top: 20px;
         //padding-top: 20px;
         background-color: #ffffff;
@@ -372,8 +361,11 @@ export default {
           //margin-left: 4%;
           // padding-left: 30px;
           //padding-top: 30px;
+          height: 40px;
+          line-height: 40px;
           box-sizing: border-box;
-          border-top: 1px solid #f2f2f2;
+          margin-bottom: 24px;
+          // border-top: 1px solid #f2f2f2;
           font-size: 30px;
 
           .vehicleMgt-title-img {
@@ -384,7 +376,7 @@ export default {
 
         .vehicleMgt-content {
           width: 94%;
-          margin-left: 3%;
+          margin-left: 29px;
           display: flex;
           flex-wrap: wrap;
           // justify-content: space-around;
@@ -393,81 +385,121 @@ export default {
           .item {
             width: 30%;
             height: 60px;
-            margin-top: 30px;
-            margin-left: 16px;
+            // margin-top: 30px;
+            // margin-left: 16px;
+            margin-right: 15px;
+            margin-bottom: 16px;
             text-align: center;
             box-sizing: border-box;
-            border: 2px solid #dcdcdc;
+            border: 1px solid #d9dbe0;
+            background-color: #f4f7ff;
             line-height: 60px;
             font-size: 26px;
-            border-radius: 10px;
-            color: #a5a5a5;
+            border-radius: 30px;
+            color: #666666;
           }
 
           .vehicleMgt-content_cls {
             color: #703a98;
             border: 2px solid #703a98;
           }
-
-          // .item::after {
-          // 	content: '';
-          // 	display: block;
-          // 	height: 1px;
-          // 	width: 92%;
-          // 	position: absolute;
-          // 	background-color: #F2F2F2;
-          // 	bottom: 0px;
-          // 	left: 4%;
-          // }
-          // .item:last-child::after {
-          // 	display: none;
-          // }
         }
       }
-
-      .search-list {
-        display: flex;
-        flex-direction: column;
-        background: #fff;
-        padding: 0 30px;
+    }
+    /* 无牌车UI */
+    .unlicensed-box {
+      background-color: #fff;
+      
+      .no-car-unlicensed-box {
+        
         box-sizing: border-box;
-        margin-top: 20px;
-        border-radius: 15px;
-        width: 100%;
+        img{
+          width: 391px;
+          display: block;
+          margin: 0 auto;
+        }
+        .no-car-unlicensed-info {
+          color: #919BAA;
+          font-size: 36px;
+          line-height: 36px;
+          text-align: center;
+          margin-bottom: 60px;
+        }
+        .search-btn {
+          font-size: 34px;
+          height: 90px;
+          color: #FFFFFF;
+          line-height: 90px;
+          background: #644A79;
+          text-align: center;
+          margin: 0 30px;
+          border-radius: 45px;
+          margin-bottom: 58px;
+          .unlicensed-scan {
+            display: inline-block;
+            width: 60px;
+            height: 60px;
+            position: relative;
+            top: 17px;
+            margin-right: 15px;
+          }
+        }
+    
+      }
 
-        .list_item {
-          padding: 38px 0;
-          box-sizing: border-box;
+      .in-car {
+        box-sizing: border-box;
+        .car-number-box {
+          padding-top: 53px;
+          padding-left: 18px;
+          padding-bottom: 34px;
+          background: #FBFCFF;
+          border: 1px solid #D9DBE0;
+          border-radius: 4px;
+          margin: 0 24px;
           display: flex;
-          align-items: center;
-          justify-content: space-between;
-          border-bottom: 1px solid #f2f2f2;
-
-          span {
-            font-size: 28px;
+          margin-bottom: 40px;
+          img{
+            width: 288px;
           }
-
-          button {
-            height: 60px;
-            line-height: 60px;
-            margin: 0;
+          .car-number {
+            .number{
+              font-size: 50px;
+              line-height: 56px;
+              font-weight: 600;
+              color: #333333;
+              margin-bottom: 23px;
+            } 
+            .tips{
+              color: #999999;
+            }
           }
+          
+        }
+        .search-btn {
+          background: #644A79;
+          border-radius: 45px;
+          color: #FFFFFF;
+          line-height: 90px;
+          height: 90px;
+          font-size: 36px;
+          text-align: center;
+          margin: 0 30px 40px;
         }
       }
     }
-
+    
+    /* 缴费说明 */
     .parkingFee-top {
       display: flex;
       flex-direction: column;
       background-size: 100% 30%;
-      // height: 350px;
-      // margin-bottom: 25px;
+      padding-left: 27px;
+      padding-right: 27px;
+      background-color: #ffffff;
 
       .top_content {
-        padding: 25px 35px;
         box-sizing: border-box;
-        display: flex;
-        flex-direction: column;
 
         span {
           font-size: 24px;
@@ -482,21 +514,23 @@ export default {
           margin-bottom: 20px;
 
           .btn {
-            padding: 0px 14px;
             box-sizing: border-box;
             border-radius: 20px;
             font-size: 30px;
-            color: #000;
-            text-align: center;
+            color: #333;
+            text-align: left;
           }
         }
 
         .info {
-          padding-left: 18px;
+          padding-left: 2px;
           font-size: 27px;
           width: 95%;
           color: #666;
           line-height: 45px;
+          p{
+            margin: 0;
+          }
         }
 
         .info_show {
@@ -509,72 +543,12 @@ export default {
         }
       }
 
-      .blue_top_content {
-        .color_top_content('blue');
-        background-position: 0 0;
-        background-size: 100% 100%;
-        background-repeat: no-repeat;
-      }
-
-      .green_top_content {
-        .color_top_content('green');
-      }
-
-      .color_top_content(@value) {
-        @color: 'color-@{value}';
-        background-color: @@color;
-        span {
-          color: @color-white;
-        }
-        .title_box {
-          .btn {
-            color: @color-gold;
-          }
-        }
-        .info {
-          font-size: 24px;
-        }
-      }
-
       .top_down {
         width: 100%;
         text-align: center;
-        color: #b0a9a9;
-      }
-    }
-
-    .blue_top_menu {
-      .color_top_menu('blue');
-      background: @color-pink;
-    }
-
-    .green_top_menu {
-      .color_top_menu('green');
-      background: @color-light-green;
-    }
-
-    .color_top_menu(@value) {
-      @color: 'color-@{value}';
-      margin-top: 0;
-      margin-left: 0;
-      padding-top: 0;
-      width: 100%;
-      height: 211px;
-      color: @@color;
-      border-radius: 0;
-      align-items: center;
-      .menu_item {
-        width: 25%;
-
-        image {
-          width: 83px;
-          height: 83px;
-        }
-
-        span {
-          font-size: 24px;
-          margin-top: 20px;
-        }
+        color: #999999;
+        margin-top: 30px;
+        margin-bottom: 32px;
       }
     }
   }
@@ -618,12 +592,6 @@ export default {
   }
 }
 
-.class-van-button-small {
-  min-width: 0;
-  border-radius: 10px;
-  margin: 10px 3px;
-  box-shadow: 10px 10px 10px #aaa;
-}
 
 .class-plate-box {
   width: 100%;
@@ -632,91 +600,6 @@ export default {
   position: relative;
 }
 
-.plate_number {
-  width: 100%;
-  display: flex;
-  flex-direction: column;
-
-  .plate_number_wrap {
-    width: 100%;
-    display: flex;
-    flex-direction: column;
-    background: #eaf1f9;
-    padding: 0 0 10px;
-    box-sizing: border-box;
-
-    .close-box {
-      width: 100%;
-      font-size: 24px;
-      color: #3e67ff;
-      text-align: right;
-      margin-right: 1.25rem;
-
-      div {
-        padding: 10px;
-      }
-    }
-
-    .plate_chinese_box {
-      width: 100%;
-      display: flex;
-      flex-wrap: wrap;
-      justify-content: center;
-
-      button {
-        width: 9%;
-        height: 2.5rem;
-        line-height: 2.5rem;
-        text-align: center;
-        padding: 0;
-        font-size: 28px;
-        .class-van-button-small;
-      }
-    }
-  }
-}
-
-.allBoard {
-  width: 100%;
-  display: flex;
-  flex-direction: column;
-
-  .allBoard_wrap {
-    width: 100%;
-    display: flex;
-    flex-direction: column;
-    background: #eaf1f9;
-    padding: 0 0 10px;
-    box-sizing: border-box;
-  }
-
-  .close-box {
-    padding-top: 22px;
-    box-sizing: border-box;
-    font-size: 24px;
-    color: #3e67ff;
-    text-align: right;
-    margin-right: 1.25rem;
-  }
-
-  .plate_number_box {
-    width: 100%;
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: center;
-
-    button {
-      width: 9%;
-      height: 2.5rem;
-      line-height: 2.5rem;
-      text-align: center;
-      padding: 0;
-      font-size: 28px;
-      .class-van-button-small;
-    }
-  }
-}
-
 .delBtn {
   color: #fff;
   height: 38px;

+ 10 - 8
src/pages/parkingFee/mixins/parkingFee.js

@@ -56,7 +56,7 @@ export default {
   },
   computed: {
     disabledBtn() {
-      return this.numArr.findIndex((val) => !val) !== -1;
+      return this.numArr.filter((val) => !val).length > 0;
     },
     ...mapState({
       groupId: (state) => state.groupId,
@@ -221,8 +221,8 @@ export default {
       try {
         console.log(222222);
         // const res = await parkingLots('8aaa83397bf7310e017bf7c8fb740009');
-        const res = await parkingLots('8aaa87bc7ce98224017ce995fd8a0002');
-        console.log('223,2323', res);
+        // const res = await parkingLots('8aaa87bc7ce98224017ce995fd8a0002');
+        const res = await parkingLots('8aaa82ea804d07cd0180516ff03b0008'); // TODO: 临时写死
         /*const data = {
          parkName: '杭州停车场',
          parkCode: 'hz01',
@@ -232,7 +232,9 @@ export default {
          };*/
         // let reg = /[;;]/g;
         // this.parkInfoEntity.description = data.description.replace(reg, '\r\n');
-        this.description = res.description;
+        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');
@@ -310,12 +312,11 @@ export default {
     },
     // 接收子组件数据
     updateCarno(val) {
-      this.numArr = val.numArr;
+      this.numArr = [...val.numArr];
       this.vehicleNumber = this.numArr.join('');
       this.active = val.active;
       this.ind = val.ind;
     },
-
     // 节流函数
     throttle(fc, waitTime = 500, imme = true) {
       if (imme) {
@@ -339,9 +340,10 @@ export default {
 
     // 校验车牌号
     preHandleSearch() {
+      if ( this.disabledBtn ) return
       uni.setStorageSync('carList', [
         ...new Set([this.vehicleNumber, ...this.carList]),
-      ]);
+      ].slice(0, 6));
       this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
         name: 'parkingFeeDetail',
       });
@@ -356,7 +358,7 @@ export default {
     toHandleSearch(carno) {
       // uni.getStorageSync('carList');
 
-      uni.setStorageSync('carList', [...new Set([carno, ...this.carList])]);
+      uni.setStorageSync('carList', [...new Set([carno, ...this.carList])].slice(0, 6));
 
       this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
         name: 'parkingFeeDetail',

+ 64 - 52
src/pages/parkingFee/mixins/parkingFeeCoupon.js

@@ -5,10 +5,10 @@ import { Toast } from 'vant';
 import { getPlatform, getAppIdByGroupIdAndMallId, isInWeixinH5 } from '@/utils';
 import { initWxJsSdkConfig } from '@/utils/login';
 import { compare } from '@/utils/location.js';
+import { isArray } from 'lodash';
 // import { v4 as uuidv4 } from 'uuid';
 
 export default {
-  created() {},
   data() {
     return {
       checkedCouponList: [],
@@ -149,24 +149,79 @@ export default {
       return Number.parseInt(i.replace(/coupon/g, ''));
     },
     checkboxItemChange(name, index) {
-      console.log(7676, name);
       // 取消勾选时
       if (this.checkedCouponList.indexOf(name) > -1) {
-        this.couponList = this.couponList.map((elm, index) => {
-          elm.disabled = false;
-          return elm;
-        });
         this.checkedCouponList = this.checkedCouponList.filter((i) => i !== name);
+        setTimeout(() => {
+          // console.log(158, this.checkedCouponList);
+          this.groupedCouponData();
+        }, 100)
         return;
       }
       // 如果有选中项
       const item = this.couponList[index];
       if (!item.disabled) {
         this.checkedCouponList.push(`coupon${index}`);
-        // 根据电子券规则判断是否可选
-        this.isDisabledByRule(item);
+        setTimeout(() => {
+          // 根据电子券规则判断是否可选
+          this.isDisabledByRule(item, index);
+        }, 100)
       }
     },
+    // 对不同类型的优惠券进行汇总统计
+    groupedCouponData() {
+      const groupedData = {}; // 所有的电子券按照批次分组;
+      let couponList = [...this.couponList]; // 获取目前用户的电子券
+      couponList.forEach((elm, index) => {
+        // 初始化数据
+        const elmName = `coupon${index}`;
+        const newElm = { ...elm };
+        if (!groupedData[elm.name] || !groupedData[elm.name].hasOwnProperty('noSelectedList')) {
+          groupedData[newElm.name] = {
+            noSelectedList: [], // 未选择的
+            selectedList: [], // 已选择的
+          }
+        }
+        newElm.index = index; // 记录每张电子券的顺序
+        // 所有的电子券按照 已选择 和 未选择的分组,存储到同批次下
+        if (this.checkedCouponList.indexOf(elmName) > -1) {
+          newElm.selected = true;
+          groupedData[newElm.name]['selectedList'].push(newElm)
+        } else {
+          newElm.selected = false;
+          groupedData[newElm.name]['noSelectedList'].push(newElm)
+        }
+      })
+      // 对分好组的优惠券进行不同规则处理
+      Object.keys(groupedData).forEach(key => {
+        const { selectedList, noSelectedList } = groupedData[key]; //
+        const { superposition, limitCountPerOrder = 0 } = [...selectedList, ...noSelectedList][0]; // 获取当前批次兑换的类型和可选上限
+        switch (superposition) {
+          case '1':
+            couponList = couponList.map(elm => {
+              if (elm.superposition === '1') {
+                elm.disabled = this.checkedCouponList.length > 0;
+              }
+              return elm
+            })
+            break
+          case '2':
+            noSelectedList.forEach(elm => {
+              const _elm = { ...couponList[elm.index] };
+              couponList = couponList.map((item, index) => {
+                if (index === elm.index && limitCountPerOrder > 0) {
+                  elm.disabled = selectedList.length >= limitCountPerOrder;
+                  _elm.disabled = selectedList.length >= limitCountPerOrder;
+                  return _elm
+                }
+                return item
+              })
+            })
+            break
+        }
+      })
+      this.couponList = [...couponList];
+    },
     // 根据电子券规则判断是否可选
     isDisabledByRule(item) {
       const { parkMallCode } = this.orderDetail.parkInfo;
@@ -207,50 +262,7 @@ export default {
       }
 
       // 选中状态赋值
-      this.couponList = this.couponList.map((e, i) => {
-        if (this.checkedCouponList.findIndex((c) => c === `coupon${i}`) !== -1) {
-          e.checked = true;
-        } else {
-          e.checked = false;
-        }
-        // superposition  叠加使用规则 (1不可叠加,2仅同类型可叠加,3可叠加)
-        if (item.superposition === '1') {
-          if (e.code !== item.code) {
-            e.disabled = true;
-          }
-        } else if (item.superposition === '2') {
-          if (e.superposition === '2') {
-            // 统计当前(同类型&同可叠加次数)
-            let count = 0;
-            this.checkedCouponList.forEach((i) => {
-              const index = this.item2Number(i);
-              if (this.couponList[index].code === item.code) {
-                count++;
-              }
-            });
-            console.log(item.code + '合计:' + count);
-            if (item.code === e.code) {
-              // 超限判断
-              if (item.limitUseNum !== 0 && count + 1 > item.limitUseNum) {
-                if (e.checked === false) {
-                  e.disabled = true;
-                }
-              } else {
-                e.disabled = false;
-              }
-            } else {
-              e.disabled = false;
-            }
-          } else {
-            // 异类
-            e.disabled = true;
-          }
-        } else {
-          // 类型3可叠加
-          e.disabled = false;
-        }
-        return e;
-      });
+      this.groupedCouponData();
     },
     // 是否选中
     isCheck(val) {

+ 166 - 7
src/pages/parkingFee/mixins/parkingFeeDetail.js

@@ -116,8 +116,8 @@ export default {
             actualPayFee: parkingRecord.actualPayFee, //应付金额
           },
           discountInfo: {
-            usingTotalDiscount: discountInfo.usingTotalDiscount, //优惠金额"
-            actualUsedDiscount: discountInfo.usingTotalDiscount, //实际优惠金额
+            usingTotalDiscount: discountInfo?.usingTotalDiscount || 0, //优惠金额"
+            actualUsedDiscount: discountInfo?.usingTotalDiscount || 0, //实际优惠金额
             // points: {
             //   discountTime: 60,
             //   // 如果是深圳的话,是金额,还得计算出对应的积分
@@ -131,10 +131,169 @@ export default {
         };
         const res = await ordersAndPrepay(params);
         console.log('orderDetail', res);
+
+        this.kerryPayment(res.sessionId)
       } catch (err) {
         console.log(err);
       }
     },
+    kerryPayment(session = '011cad54-735f-4e92-8f1b-f22bdfe073cd', payParams) {
+      const platform = getPlatform();
+      let appId = uni.getStorageSync('appid');
+      let openId = uni.getStorageSync('openid') || this.openid;
+      if (platform === 'miniprogram') {
+        appId = 'wx92c3e55fbef6b2af';
+      }
+      const params = {
+        region: 'cn',
+        payChannel: 'OFFICIAL_ACCOUNT',
+        // payChannel: 'MOBILE_WEB',
+        payOption: 'WECHATPAY',
+        appId: appId,
+        // openId: 'oudWQ5SCDElfn-IQH6eBR5JesOz4', // 下的appid: wxd830fe4d1e04988e
+        openId,
+      };
+      // console.log(1854, params);
+      this.$md(params);
+      // let path = `/profileApi/payment/v1/services/session/${session}/transactions`;
+      let path = `${window.profileApi}/payment/v1/services/session/${session}/transactions`;
+      this.$request({
+        url: path,
+        data: params,
+        method: 'POST',
+        header: JSON.parse(uni.getStorageSync('handleUser')),
+      })
+        .then(async (res) => {
+          // this.Toastloading.clear();
+          // console.log(1795, res);
+          if (res.data?.code == '000000') {
+            const prepayJson = res.data.data.params;
+            const platform = getPlatform();
+            // TODO: h5环境判断
+            if (platform === 'micromessenger') {
+              const weixinH5PayRes = await this.weixinH5Pay(prepayJson);
+              // 微信支付完成,判断结果
+              console.log(1784, weixinH5PayRes);
+              //  errMsg: 'requestPayment:ok'
+              if (weixinH5PayRes?.errMsg === 'requestPayment:ok') {
+                this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
+                  name: 'parkingFeeDetail'
+                });
+                this.$router.replace({
+                  path: 'parkingFeeSuccess?carno=' + this.parkInfo.carno,
+                });
+              } else {
+                this.reCreateParkOrder();
+              }
+            } else {
+              window.toWXSendMsg({
+                type: 'openWxPay',
+                options: {
+                  provider: 'wxpay',
+                  timeStamp: prepayJson.timeStamp,
+                  nonceStr: prepayJson.nonceStr,
+                  package: prepayJson.package,
+                  signType: prepayJson.signType,
+                  paySign: prepayJson.paySign,
+                },
+              });
+              window.subscribe('wxPayOver', (options) => {
+                // this.Toastloading.clear();
+                // console.log('微信支付结束之后的返回参数', options);
+                // T-ODO: 在 qa 新发版前,只提示支付成功的信息(已处理成功信息)
+                if (options?.wxPayOver === 'fail') {
+                  console.log('支付失败');
+                  this.reCreateParkOrder();
+                } else {
+                  this.btnLoading = false;
+                  this.$router.replace({
+                    path: 'parkingFeeSuccess?carno=' + this.parkInfo.carno,
+                  });
+                }
+              });
+            }
+            return;
+            // 微信支付接口
+            // uni.requestPayment({
+            //   provider: 'wxpay',
+            //   timeStamp: prepayJson.timeStamp,
+            //   nonceStr: prepayJson.nonceStr,
+            //   package: prepayJson.package,
+            //   signType: prepayJson.signType,
+            //   paySign: prepayJson.paySign,
+            //   success: () => {
+            //     uni.showModal({
+            //       showCancel: false,
+            //       title: '提示',
+            //       content: '支付成功',
+            //       complete: () => {
+            //         this.sensorsClick('$ClickParkingPay', {
+            //           car_no: payParams.carno,
+            //           pay_fee: payParams.payfee,
+            //           total_fee: payParams.totalfee,
+            //           redirect_path: 'pages/parkingFee/parkingFeeSuccess',
+            //         });
+            //         this.$router.replace({
+            //           path: './parkingFeeSuccess?carno=' + this.parkInfo.carno,
+            //         });
+            //       },
+            //     });
+            //   },
+            //   fail: () => {
+            //     this.reCreateParkOrder();
+            //   },
+            // });
+          } else {
+            // this.reCreateParkOrder();
+          }
+        })
+        .catch((err) => {
+          console.log(1854, err);
+          // this.reCreateParkOrder();
+        });
+    },
+    // 支付失败后返还优惠券
+    failedParkOrder() {
+      // this.Toastloading.clear();
+      const param = {
+        orderno: this.parkInfo.orderno,
+      };
+      this.$md(param);
+      uni
+        .request({
+          url: this.$baseURL + 'api/1.0/park/failedParkOrder',
+          data: param,
+          method: 'POST',
+          header: JSON.parse(uni.getStorageSync('handleUser')),
+        })
+        .then((res) => {
+          this.reCreateParkOrder();
+        })
+        .catch((err) => {
+          this.reCreateParkOrder();
+        });
+    },
+    // 支付失败弹框 重新创建订单
+    reCreateParkOrder() {
+      // console.log('支付失败弹框 重新创建订单');
+      Dialog.alert({
+        title: '提示',
+        message: '支付失败',
+        confirmButtonColor: '#333',
+      }).then(() => {
+        this.$store.dispatch('order/orderInit', '粤A51113')
+        this.btnLoading = false;
+        // this.createParkOrder();
+      });
+      // uni.showModal({
+      //   showCancel: false,
+      //   title: '提示',
+      //   content: '支付失败',
+      //   complete: (r) => {
+      //     this.createParkOrder();
+      //   },
+      // });
+    },
     // 初始化
     async pageInit() {
       // console.log(247, checkOutResponse);
@@ -186,13 +345,13 @@ export default {
         path: 'parkingFeeCoupon',
       });
     },
-    paperCoupon() {},
-    duration() {},
-    couponCount() {},
+    paperCoupon() { },
+    duration() { },
+    couponCount() { },
     // 重置倒计时
     resetCountDown() {
-      this.refreshTime = 180;
-      this.$store.dispatch('order/orderInit', '000')
+      this.$refs.countDown.reset();
+      // this.$store.dispatch('order/orderInit', '000')
       // 重新创建订单
       // this.createParkOrder();
     },

+ 3 - 0
src/pages/parkingFee/parkingFee.vue

@@ -14,5 +14,8 @@ export default {
     baseParkingFeeCom,
     purpleCom,
   },
+  mounted() {
+    this.componentName = 'purpleCom';
+  }
 };
 </script>

二进制
src/pages/parkingFee/static/images/unlicensed-0.png


二进制
src/pages/parkingFee/static/images/unlicensed-1.png


二进制
src/pages/parkingFee/static/images/unlicensed-scan.png


二进制
src/static/images/back.png


二进制
src/static/images/close.png


+ 5 - 0
src/store/index.js

@@ -146,6 +146,9 @@ const store = new Vuex.Store({
     SET_LBS_ID(state, payload) {
       state.lbsId = payload;
     },
+    SET_BRAND_ID(state, payload) {
+      state.brandId = payload;
+    },
   },
   actions: {
     async baseInit({ commit, dispatch }, { options, callback }) {
@@ -164,6 +167,7 @@ const store = new Vuex.Store({
           mallId = '',
           kipUserId = '',
           custTypeId = '',
+          brandId = '',
 
           openid = '',
           mobile = '',
@@ -209,6 +213,7 @@ const store = new Vuex.Store({
         const href = window.location.href;
         commit('SET_GROUP_ID', groupId);
         commit('SET_MALL_ID', mallId);
+        commit('SET_BRAND_ID', brandId);
         /*if (/dev-|8080|qa-/.test(href)) {
          commit('SET_GROUP_ID', groupId);
          commit('SET_MALL_ID', mallId);

+ 60 - 18
src/store/order.js

@@ -2,6 +2,7 @@ import { checkOut, calculateDiscount, ordersAndPrepay } from '@/api/parking';
 
 // import checkOutQHResponse from '@/api/mockData/checkout.qh3.response.json'
 // import checkOutQHResponse from '@/api/mockData/checkout.hz.response.json';
+import checkOutQHResponse from '@/api/mockData/checkout.qh4.response.json'
 
 // 微服务接口字段
 const state = {
@@ -24,6 +25,7 @@ const state = {
   enablePaperCoupons: false, // 启动纸质优惠券
   usingTotalDiscount: 0, // 优惠金额
   actualPayFee: 0, // 应付金额
+  availableDiscountFee: 0, // 当日剩余可使用优惠金额
   // 积分相关
   available: 0, // 用户可用积分
   maxPointsTime: '', // 积分最大兑换时长
@@ -87,6 +89,9 @@ const mutations = {
   setActualPayFee(state, payload) {
     state.actualPayFee = payload;
   },
+  setAvailableDiscountFee(state, payload) {
+    state.availableDiscountFee = payload;
+  },
   setPointsPerHour(state, payload) {
     state.pointsPerHour = payload;
   },
@@ -130,13 +135,13 @@ const actions = {
       // }
       // const res = await checkOut('浙A616A1');
       // const res = await checkOut('闽AAQ5519');
-      const res = await checkOut('闽AAQ5518');
+      const res = await checkOut('粤A51113');
       // const res = await checkOut('沪DCJ986');
       // console.log('浙A616A1', res);
       // 所有的优惠时间长转为金额
       // console.log(112, '所有的优惠时间长转为金额');
       // dispatch('orderInitRule', checkOutQHResponse);
-      dispatch('orderInitRule', res);
+      dispatch('orderInitRule', checkOutQHResponse);
     } catch (error) {
       console.log(error);
     }
@@ -211,6 +216,7 @@ const actions = {
     const {
       maxPointsTime = 0, // 最大积分
       enablePoints,
+      availableDiscountFee,
       maxOneDayDiscountFee, // 每日最大优惠金额(深圳车场)
       remainConsumeTime, // 当前订单剩余可使用的优惠
     } = parkingRule;
@@ -225,6 +231,7 @@ const actions = {
         label,
       },
     ] = points;
+    commit('setAvailableDiscountFee', availableDiscountFee);
     dispatch('maxPointsTimeMath', checkOutResponse) // 剩余积分可兑换上限
     commit('setEnablePoints', enablePoints);
     commit('setAvailable', available);
@@ -243,19 +250,27 @@ const actions = {
    * 1、不能超过积分上限
    * 2、
    * */
-  maxPointsTimeMath({ commit, dispatch, state }, checkOutResponse){
+  maxPointsTimeMath({ commit, dispatch, state }, checkOutResponse) {
     const { discountInfo, parkingRule, parkInfo } = checkOutResponse
-    const {points:[{
+    const { points: [{
       available, // 用户可用的积分(当前车辆在) available是用户选择抵扣N小时后剩余的可用积分
       unitAmount, // 兑换值(元)
       pointsPerUnit = 0, // 500 积分对应的价值
       discountFee,
       maxDiscountFee,
-    }]} = discountInfo
+    }] } = discountInfo
     // 总积分
     const max = available / pointsPerUnit * unitAmount;
     const timeNum = maxDiscountFee / unitAmount;
     console.log(';999988888;', timeNum);
+
+    /**
+     * maxDiscountFee 单次最大可使用金额 
+     * availableDiscountFee 当日剩余可使用优惠金额
+     * available 当前用户的剩余积分,也可以说是可以抵扣的积分,如果有积分抵扣自动勾选,那么这个值=这个值-已勾选积分
+     *
+     */
+
     // if ( !state.maxPointsTime ) {
     //   commit('setMaxPointsTime', discountFee || max)
     // }
@@ -270,19 +285,31 @@ const actions = {
 
   // 积分减免
   pointsMath({ commit, dispatch, state }, { type }) {
+    /**
+     * 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) {
+    if (maxPointsTime > state.maxDiscountFee) {
       maxPointsTime = state.maxDiscountFee
     }
+    // 验证最大积分的总数(单位:元)
+    if (maxPointsTime > state.availableDiscountFee) {
+      maxPointsTime = state.availableDiscountFee
+    }
+    console.log(303, maxPointsTime);
     if (type === 'add' && state.pointsTime < maxPointsTime) {
-      const pointsTime = state.pointsTime + 1;
+      const pointsTime = state.pointsTime + state.unitAmount;
       // 如果是深圳车场
       commit('setAvailable', state.available - state.pointsPerUnit / state.unitAmount);
       commit('setPointsTime', pointsTime);
     }
     if (type === 'minus' && state.pointsTime > 0) {
-      const pointsTime = state.pointsTime - 1;
+      const pointsTime = state.pointsTime - state.unitAmount;
       // 如果是深圳车场
       commit('setAvailable', state.available + state.pointsPerUnit / state.unitAmount);
       commit('setPointsTime', pointsTime);
@@ -293,25 +320,38 @@ const actions = {
       discountInfo: { points },
       parkingRule,
     } = state.orderDetail;
-    const [{ pointsPerHour, available }] = points;
+    const [{ pointsPerHour, available, discountFee }] = points;
     const { maxPointsTime, enablePoints } = parkingRule;
     commit('setAvailable', available);
-    commit('setPointsTime', maxPointsTime);
+    commit('setPointsTime', discountFee || 0);
     callback && callback();
   },
   async savePointsMath({ commit, dispatch, state }, callback) {
-    const orderDetail = { ...state.orderDetail };
-    // 计算积分修改之后的金额,返回给后端
-    // orderDetail.discountInfo.points[0].discountFee = state.pointsTime * orderDetail.discountInfo.points[0].unitAmount;
-    orderDetail.discountInfo.points[0].discountFee = state.pointsTime;
-    orderDetail.discountInfo.points[0].available = state.available;
-    orderDetail.discountInfo.points[0].selected = true;
     try {
+      const orderDetail = { ...state.orderDetail };
+      // 如果是重复提交,则不做重新计算
+      if (orderDetail.discountInfo.points[0].available === state.available) {
+        callback && callback();
+        return
+      }
+      // 计算积分修改之后的金额,返回给后端
+      // orderDetail.discountInfo.points[0].discountFee = state.pointsTime * orderDetail.discountInfo.points[0].unitAmount;
+      orderDetail.discountInfo.points[0].discountFee = state.pointsTime;
+      orderDetail.discountInfo.points[0].available = state.available;
+      orderDetail.discountInfo.points[0].selected = true;
+      /* 其他优惠统计 */
+      // 优惠券: 如果没有添加 selected 字段,则增加 selected; 默认取 defaultSelected;
+      if (orderDetail?.discountInfo?.hasOwnProperty('coupons') && !orderDetail?.discountInfo?.coupons[0]?.hasOwnProperty('selected')) {
+        orderDetail.discountInfo.coupons = orderDetail.discountInfo.coupons.map(elm => {
+          elm.selected = elm.defaultSelected || false;
+          return elm;
+        })
+      }
       const res = await calculateDiscount({
         ...orderDetail,
       });
       console.log('积分修改失败', { res });
-      dispatch('orderInitRule', res);
+      dispatch('orderInitRule', checkOutQHResponse);
       callback && callback();
     } catch (err) {
       console.log('积分修改失败!', err);
@@ -322,7 +362,9 @@ const actions = {
   async saveCouponMath({ commit, dispatch, state }, { couponList, callback }) {
     const orderDetail = { ...state.orderDetail };
     orderDetail.discountInfo.coupons = couponList;
-    orderDetail.discountInfo.points[0].selected = false;
+    if (orderDetail?.discountInfo?.points[0]?.discountFee) {
+      orderDetail.discountInfo.points[0].selected = true;
+    }
     try {
       const res = await calculateDiscount({
         ...orderDetail,