Explorar el Código

初始同步项目代码

zaijin hace 2 años
commit
481547434e
Se han modificado 100 ficheros con 18844 adiciones y 0 borrados
  1. 3 0
      .eslintignore
  2. 19 0
      .gitignore
  3. 114 0
      App.vue
  4. 21 0
      LICENSE
  5. 18 0
      README.md
  6. 154 0
      common/apiurl.js
  7. 33 0
      common/config.js
  8. 205 0
      common/http.api.js
  9. 68 0
      common/http.interceptor.js
  10. 228 0
      components/coupon-swiper-list-item/coupon-swiper-list-item.vue
  11. 43 0
      main.js
  12. 113 0
      manifest.json
  13. 101 0
      package.json
  14. 342 0
      pages.json
  15. 68 0
      pages/OnsitePayment/OnsitePayment.scss
  16. 193 0
      pages/OnsitePayment/OnsitePayment.vue
  17. 30 0
      pages/VehicleInquiry/VehicleInquiry.scss
  18. 221 0
      pages/VehicleInquiry/VehicleInquiry.vue
  19. 77 0
      pages/applyRefund/applyRefund.scss
  20. 161 0
      pages/applyRefund/applyRefund.vue
  21. 69 0
      pages/applyRefundDetails/applyRefundAchieveDetails.vue
  22. 84 0
      pages/applyRefundDetails/applyRefundDetails.scss
  23. 105 0
      pages/applyRefundDetails/applyRefundDetails.vue
  24. 56 0
      pages/bannerDetails/bannerDetails.vue
  25. 35 0
      pages/center/coupon/couponRules/couponRules.vue
  26. 68 0
      pages/center/coupon/myCoupon/myCoupon.scss
  27. 337 0
      pages/center/coupon/myCoupon/myCoupon.vue
  28. 258 0
      pages/center/index.vue
  29. 68 0
      pages/center/invoice/invoice.scss
  30. 173 0
      pages/center/invoice/invoice.vue
  31. 0 0
      pages/center/invoice/invoiceDetails/invoiceDetails.scss
  32. 25 0
      pages/center/invoice/invoiceDetails/invoiceDetails.vue
  33. 15 0
      pages/center/invoice/makeinvoice/makeinvoice.scss
  34. 72 0
      pages/center/invoice/makeinvoice/makeinvoice.vue
  35. 103 0
      pages/center/monthly/monthly.scss
  36. 217 0
      pages/center/monthly/monthly.vue
  37. 196 0
      pages/center/monthly/monthly1.vue
  38. 90 0
      pages/center/order/order.scss
  39. 420 0
      pages/center/order/order.vue
  40. 41 0
      pages/center/order/orderDetails/orderDetails.scss
  41. 376 0
      pages/center/order/orderDetails/orderDetails.vue
  42. 298 0
      pages/center/phoneLogin/phoneLogin - 副本.vue
  43. 258 0
      pages/center/phoneLogin/phoneLogin.vue
  44. 122 0
      pages/chargeStandard/chargeStandard.scss
  45. 244 0
      pages/chargeStandard/chargeStandard.vue
  46. 118 0
      pages/choosePayment/choosePayment.scss
  47. 769 0
      pages/choosePayment/choosePayment.vue
  48. 21 0
      pages/common/paymentSuccess/paymentSuccess.scss
  49. 38 0
      pages/common/paymentSuccess/paymentSuccess.vue
  50. 115 0
      pages/favourableActivity/favourableActivity.scss
  51. 67 0
      pages/favourableActivity/favourableActivity.vue
  52. 309 0
      pages/geomagnetismLock/geomagnetismLock.scss
  53. 283 0
      pages/geomagnetismLock/geomagnetismLock.vue
  54. 283 0
      pages/geomagnetismLock/geomagnetismLock20230222.vue
  55. 101 0
      pages/goldPlan/goldPlan.vue
  56. 180 0
      pages/handleMonthly/handleMonthly.scss
  57. 414 0
      pages/handleMonthly/handleMonthly.vue
  58. 522 0
      pages/handleMonthly/handleMonthly20230220.vue
  59. 604 0
      pages/handleMonthly/handleMonthly20230314.vue
  60. 29 0
      pages/handleMonthly/monthPay.vue
  61. 367 0
      pages/index/index.scss
  62. 777 0
      pages/index/index.vue
  63. 65 0
      pages/message/message.scss
  64. 159 0
      pages/message/message.vue
  65. 74 0
      pages/message/messageInfo.vue
  66. 132 0
      pages/myCars/myCars.scss
  67. 273 0
      pages/myCars/myCars.vue
  68. 81 0
      pages/noninductivePay/addVehicle.vue
  69. 8 0
      pages/noninductivePay/noninductivePay.vue
  70. 309 0
      pages/parkadvance/parkadvance.scss
  71. 90 0
      pages/parkadvance/parkadvance.vue
  72. 309 0
      pages/parkentrace/parkentrace.scss
  73. 110 0
      pages/parkentrace/parkentrace.vue
  74. 309 0
      pages/parkexport/parkexport.scss
  75. 224 0
      pages/parkexport/parkexport.vue
  76. 222 0
      pages/parkexport/parkexport20230220.vue
  77. 130 0
      pages/parkingInformation/parkingInformation.scss
  78. 146 0
      pages/parkingInformation/parkingInformation.vue
  79. 414 0
      pages/parkingLists/copy/parkingLists - 副本.vue
  80. 441 0
      pages/parkingLists/copy/parkingLists20221110.scss
  81. 420 0
      pages/parkingLists/copy/parkingLists20221110.vue
  82. 19 0
      pages/parkingLists/map_web_view/map_web_view.vue
  83. 441 0
      pages/parkingLists/parkingLists.scss
  84. 564 0
      pages/parkingLists/parkingLists.vue
  85. 306 0
      pages/parkingLock/parkingLock.scss
  86. 352 0
      pages/parkingLock/parkingLock.vue
  87. 567 0
      pages/parkingLock/parkingLock20230222.vue
  88. 30 0
      pages/parkroadgate/parkroadgate.scss
  89. 33 0
      pages/parkroadgate/parkroadgate.vue
  90. 26 0
      pages/payLists/pay.vue
  91. 131 0
      pages/payLists/payLists.scss
  92. 366 0
      pages/payLists/payLists.vue
  93. 103 0
      pages/payPage/payPage.scss
  94. 157 0
      pages/payPage/payPage.vue
  95. 58 0
      pages/paymentMethod/jumpMiddle.vue
  96. 81 0
      pages/paymentMethod/paymentMethod.scss
  97. 392 0
      pages/paymentMethod/paymentMethod.vue
  98. 62 0
      pages/privacyPolicy/privacyPolicy.vue
  99. 301 0
      pages/roadGateSystem/roadGateSystem.scss
  100. 0 0
      pages/roadGateSystem/roadGateSystem.vue

+ 3 - 0
.eslintignore

@@ -0,0 +1,3 @@
+unpackage
+node_modules
+uview-ui

+ 19 - 0
.gitignore

@@ -0,0 +1,19 @@
+.DS_Store
+
+unpackage/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.hbuilderx
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+package-lock.json
+/unpackage/
+/node_modules/
+/.history/

+ 114 - 0
App.vue

@@ -0,0 +1,114 @@
+<script>
+export default {
+  onLaunch: function () {
+    this.handleUrl(location.href);
+    //判断客户端类别
+    if (/MicroMessenger/.test(window.navigator.userAgent)) {
+      uni.setStorage({
+        key: 'userAgent',
+        data: 'wxAgent'
+      });
+      console.log('微信客户端');
+    } else if (/AlipayClient/.test(window.navigator.userAgent)) {
+      uni.setStorage({
+        key: 'userAgent',
+        data: 'aliAgent'
+      });
+      console.log('支付宝客户端');
+    } else {
+      uni.setStorage({
+        key: 'userAgent',
+        data: 'otherAgent'
+      });
+      console.log('其他浏览器');
+    }
+    // 判断从什么入口进入 车位锁等页面无需调用
+    const backUrl = location.href,
+      openidPage = this.config.onlyWxLogin, // 只需要穿openid的页面集合
+      needValidPage = openidPage.filter((item) => backUrl.indexOf(item) > -1); // 是否为需要验证的页面集合
+    const { openId } = this.vuex_wxinfo;
+    console.log('openId', openId);
+    console.log('needValidPage', needValidPage);
+    if (openId && needValidPage.length === 0) {
+      this.getUserInfo(openId);
+    }
+    // 获取参数
+    const paramsValidPage = openidPage.filter((item) => backUrl.indexOf(item) > -1);
+    if (paramsValidPage.length === 0) {
+      this.getFreeTime();
+    }
+  },
+  onShow: function () {
+    console.log('App Show');
+  },
+  onHide: function () {
+    // console.log('App Hide')
+  },
+  methods: {
+    /**
+     * @description:
+     * @param {*} openId
+     * @return {*}
+     */
+    async getUserInfo(openId) {
+      try {
+        const queryParams = {
+          loginType: 1,
+          openid: openId,
+          nickName: this?.vuex_wxinfo?.nickname,
+          avatar: this?.vuex_wxinfo?.headImgUrl
+        };
+        const userInfo = await this.$u.api.userLoginApi.openidLoginApi({ ...queryParams });
+        const { accessToken, needVerify } = userInfo.data;
+        this.$u.vuex('vuex_token', accessToken);
+        this.$u.vuex('vuex_hasLogin', true);
+        if (needVerify) {
+          localStorage.setItem('backUrl', this.backUrl);
+          this.$u.route({
+            url: 'pages/center/phoneLogin/phoneLogin',
+            type: 'reLaunch'
+          });
+        }
+      } catch (error) {
+        this.$refs.uToast.show({
+          title: '获取用户信息失败!',
+          type: 'error'
+        });
+      }
+    },
+    /**
+     * @description: 获取参数免费时长
+     * @return {*}
+     */
+    async getFreeTime() {
+      try {
+        const { msg } = await this.$u.api.getParamsApi({ key: 'park.lock.freetime' });
+        this.$u.vuex('free_time', msg);
+      } catch (error) {
+        console.log(error);
+      }
+    },
+    /**
+     * @description: 首次加载url加入时间戳,防止页面未进行刷新
+     * @param {*} url
+     * @return {*}
+     */
+    handleUrl(url) {
+      // 判断时间戳是否存在
+      if (url.indexOf('_t') < 0) {
+        // 判断?是否存在  存在直接拼接后面   不存在需要拼接?
+        location.href = url.indexOf('?') > -1 ? `${url}&_t=${Date.now()}` : `${url}?_t=${Date.now()}`;
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '/static/quill/quill.bubble.scss';
+@import '/static/quill/quill.snow.scss';
+@import '/static/quill/quill.core.scss';
+@import './static/css/iconfont.css';
+@import 'uview-ui/index.scss';
+/*每个页面公共css */
+</style>

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 www.uviewui.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 18 - 0
README.md

@@ -0,0 +1,18 @@
+
+## 城市智慧停车(二期)
+
+### 修改访问地址
+- 如果api地址有变动 修改package.json 中的环境变量配置
+- common/config.js 本地运行地址修改
+- 项目中的点金计划页面修改static/html/wxPayCallback.html中(jumpOutUrl)修改为需要跳转的页面
+
+### 打包
+- 打包测试环境: 发行 => 自定义发行 => build:test
+- 打包正式环境: 发行 => 自定义发行 => build:pro
+### 执行 `npm install`
+
+#### 安装vue-jsonp 获取地址数据跨域处理
+`npm install vue-jsonp --save`
+
+#### 安装weixin-js-sdk 微信支付
+`npm install weixin-js-sdk --save`

+ 154 - 0
common/apiurl.js

@@ -0,0 +1,154 @@
+export const apiurl = {
+  //反馈
+  feedbackAddUrl: '/client/articleFeedback/add',
+  // 获取微信用户信息
+  getuseinfourl: '/client/wechat/h5/user',
+  // 公众号支付
+  payurl: '/client/app/pay',
+  // 创建订单
+  createOrderurl: '/client/order/createOrder',
+  // 退款
+  refundurl: '/client/app/order/refund',
+  // 绑定手机号
+  bindphoneurl: '/client/app/order/refund2',
+  // 手机登录验证码
+  phoneLoginCodeUrl: '/client/auth/sendSmsCode',
+  // 手机登录验证码验证
+  phoneLoginAuthUrl: '/client/auth/verifyCode',
+  // code换取微信信息
+  getWXInfoUrl: '/client/wechat/h5/code/',
+  // 微信支付 在pay.js中使用
+  wxPayUrl: '/client/wechat/pay',
+  // 客户端首页
+  getIndexDataUrl: '/client/index',
+  //获取路段信息
+  roadInfoById: '/client/roadinfo/selectById/',
+
+  // 用户车辆
+  mycarsUrl: '/client/membervehicle',
+  // 设置为默认车辆
+  setDefaultCarUrl: '/client/membervehicle/modifyDefault/',
+  //室内停车订单列表
+  getRoomparkingList: '/client/parking-orderinfo/pageList',
+  // 获取订单列表
+  getOrderListUrl: '/client/orderinfo',
+  // 获取支付订单详情
+  getOrderinfoUrl: '/client/orderinfo/paydetail/',
+  // 获取订单详情
+  getOrderDetailUrl: '/client/orderinfo/detail/',
+  getRoomOrderDetailUrl: '/client/parking-orderinfo/detail/',
+  //获取信息列表
+  getMessageListUrl: '/client/membernews',
+  //消息已读接口
+  messageReadUrl: '/client/membernews/read/',
+  // 获取附近的路段
+  nearRoadslUrl: '/client/roadinfo/nearRoads',
+  // 获取路段收费规则
+  roadsChargeRuleUrl: '/client/roadinfo/feeRule/',
+  // 获取附近的停车场
+  nearParkingLotUrl: '/client/parkingInfo/pageList',
+  // 获取停车场收费规则
+  parkingLotChargeRuleUrl: '/client/parkingInfo/feeRule/',
+  //包月信息
+  monthInfoUrl: '/client/memberinfo/monthInfo',
+  //创建包月
+  createMonthUrl: '/client/memberinfo/createMonth',
+  //包月支付
+  monthPayUrl: '/client/monthpay/gzbank/quick',
+  //包月支付查询
+  getMonthPayUrl: '/client/monthpay/query/',
+  //包月列表
+  getMonthListUrl: '/client/memberinfo/monthList',
+  // 停车场包月列表
+  getParkMonthListUrl: '/client/memberinfo/monthList',
+  //取消包月订单
+  cancelMonthUrl: '/client/memberinfo/cancelMonth/',
+
+  //启动无感支付
+  feePayUrl: '/client/membervehicle/enable/feepay/',
+  //贵州银行快捷支付
+  payGzbankUrl: '/client/pay/gzbank/quick',
+
+  // 贵州银行支付
+  gzbankurl: '/client/gzbank/paygate',
+  // 订单查询
+  getOrderInfoApi: '/client/pay/query/',
+  // 查询设备状态
+  getEqupmentStatusApi: '/client/hardware/deviceInfo/',
+  // 订单退款
+  updateOrderRefundApi: '/client/orderinfo/refundApply',
+  // 获取退款详情
+  getOrderRefundDetailsApi: '/client/orderinfo/refund/detail/',
+  // 普通微信支付
+  ordinaryWxPayApi: '/client/pay/gzbank/poly',
+  // 包月微信支付
+  monthlyWxPayApi: '/client/monthpay/gzbank/poly',
+  // 获取条款须知
+  getSystermsApi: '/client/systerms/getByType/',
+  //车位锁新增车牌信息
+  bindVehicleNoApi: '/client/orderinfo/bindVehicleNo',
+  // 第二版本验证码
+  codeV2Url: {
+    // 发送验证码V2
+    sendSmsCodeV2Url: '/client/auth/sendSmsCodeV2',
+    // 验证短信验证码V2
+    verifyCodeV2Url: '/client/auth/verifyCodeV2',
+    // 登出
+    logoutUrl: '/client/auth/loginout'
+  },
+  // 用户登录区分手机号和微信openid登录
+  userLoginUrl: {
+    // openid登录
+    openidLoginUrl: '/client/auth/loginToWxOpenId',
+    // 发送验证码
+    sendSmsCodeUrl: '/client/auth/sendSmsCodeV3',
+    // 手机号登录
+    mobileLoginUrl: '/client/auth/loginToMobile'
+  },
+  // 地磁获取小票详情
+  geomaLockDetailsUrl: '/client/orderinfo/detailByQrcode',
+  //入场扫码信息
+  getDetailEntrance: '/client/parking-orderinfo/detail/entrance',
+  //场内码扫码信息
+  getDetailAdvance: '/client/parking-orderinfo/detail/advance',
+  //出场码扫码信息
+  getDetailExport: '/client/parking-orderinfo/detail/export',
+  //无牌入场
+  entranceByNoVehicle: '/client/parking-orderinfo/entrance/noVehicleNo',
+  //场内车牌查询订单信息
+  getAdvanceInfo: '/client/parking-orderinfo/advance/info-by-vehicle',
+  //出场页面信息
+  getExportInfo: '/client/parking-orderinfo/export/info',
+  // 出场支付状态查询
+  getOrderStateExportUrl: '/client/payment/parking/query',
+  // 出场快捷支付
+  quickPayExportUrl: '/client/payment/parking/gzbank/quick',
+  // 出场聚合支付
+  polyPayExportUrl: '/client/payment/parking/gzbank/poly',
+  // 获取数据字典接口
+  getDictUrl: '/admin/dict/data/type/',
+  // 微信支付
+  wechatPayUrl: '/client/pay/wechat',
+  // 停车场微信支付
+  parkingWechatPayUrl: '/client/payment/parking/wechat',
+  // 获取参数
+  getParamsUrl: '/admin/config/configKey/',
+  // 微信包月支付
+  wechatMonthlyPayUrl: '/client/monthpay/wechat',
+  // 包月规则详情
+  monthlyRuleDetailsUrl: '/admin/feemonthrule',
+  // 查询优惠券列表
+  couponListUrl: '/client/couponInfo/couponList',
+  // 兑换优惠券
+  exchangeCouponUrl: '/client/couponInfo/couponExchange',
+  // 根据订单号刷新优惠券状态(用于取消支付情况)
+  updateCouponStatusUrl: '/client/couponInfo/backCoupon',
+  // 根据订单id获取符合要求的优惠券
+  getCouponByOrderIdUrl: '/client/couponInfo/memberCoupon',
+  // 根据室内停车场二维码查询车辆列表信息
+  getVehicleInquiryListUrl: '/client/parking-orderinfo/detail/advance',
+  // 根据停车场编号和车牌查询订单
+  getOrderInfoByParknoUrl: '/client/parking-orderinfo/advance/getOrderInfo',
+  // 停车场支付
+  indoorPaymentUrl: '/client/payment/parking/gotoPay'
+};

+ 33 - 0
common/config.js

@@ -0,0 +1,33 @@
+/**
+ * 在package.json中定义的H_NODE_ENV
+ * 在本地运行该环境为未定义,设置初始baseUrl
+ * 只有在打包环境下才会有H_NODE_ENV
+ */
+const node_dev = process.env.H_NODE_ENV;
+let baseUrl = 'https://wx.hw.hongweisoft.com/parking', // 默认为普定测试环境
+  wxAppid = 'wx6e9cdf7a0ee8a51b', // 默认为达泽公众号appid
+  projectFlag = 'puding';
+
+if (node_dev) {
+  (baseUrl = process.env.H_BASE_URL), (wxAppid = process.env.H_WXAPPID), (projectFlag = process.env.H_PROJECT);
+}
+export const config = {
+  wxAppid,
+  baseUrl,
+  projectFlag,
+  onlyWxLogin: [
+    'pages/parkingLock/parkingLock',
+    'pages/wechatLogin/wechatLogin',
+    'pages/VehicleInquiry/VehicleInquiry',
+    'pages/OnsitePayment/OnsitePayment',
+    'pages/parkadvance/parkadvance',
+    'pages/parkexport/parkexport',
+    'pages/parkroadgate/parkroadgate',
+    'pages/roadGateSystem/roadGateSystem',
+    'pages/parkentrace/parkentrace',
+    'pages/geomagnetismLock/geomagnetismLock',
+    'pages/wechatLogin/wechatLogin',
+    'pages/goldPlan/goldPlan',
+		'pages/center/phoneLogin/phoneLogin'
+  ] // 只需要微信登录的页面路径
+};

+ 205 - 0
common/http.api.js

@@ -0,0 +1,205 @@
+import { apiurl } from './apiurl.js';
+
+// 此处第二个参数vm,就是我们在页面使用的this,你可以通过vm获取vuex等操作,更多内容详见uView对拦截器的介绍部分:
+const install = (Vue, vm) => {
+  // 反馈提交
+  let feedbackAdd = (params = {}) => vm.$u.post(apiurl.feedbackAddUrl, params);
+
+  let getuseinfo = (params = {}) => vm.$u.get(apiurl.getuseinfourl + '/' + params);
+
+  let createOrder = (params = {}) => vm.$u.post(apiurl.createOrderurl, params);
+
+  let bindphone = (params = {}) => vm.$u.post(apiurl.bindphoneurl, params);
+
+  let getPhoneLoginCode = (params = {}) => vm.$u.post(apiurl.phoneLoginCodeUrl, params);
+
+  let phoneLoginAuth = (params = {}) =>
+    vm.$u.post(
+      apiurl.phoneLoginAuthUrl,
+      {
+        code: params.code
+      },
+      {
+        Authorization: `Bearer ${params.accessToken}`,
+        user_id: params.userId
+      }
+    );
+
+  let getWXInfo = (params = {}) => vm.$u.get(apiurl.getWXInfoUrl + params);
+
+  let wxPay = (params = {}) => vm.$u.post(apiurl.wxPayUrl, params);
+
+  let getIndexData = (params = {}) => vm.$u.post(apiurl.getIndexDataUrl, params);
+
+  let roadInfoById = (params = {}) => vm.$u.get(apiurl.roadInfoById + params.id);
+
+  let getMycars = (params = {}) => vm.$u.get(apiurl.mycarsUrl, params);
+  let addCar = (params = {}) => vm.$u.post(apiurl.mycarsUrl, params);
+  let delCar = (params = {}) => vm.$u.delete(apiurl.mycarsUrl + '/' + params);
+  let setDefaultCar = (params = {}) => vm.$u.put(apiurl.setDefaultCarUrl + params.id);
+
+  let getOrderList = (params = {}) => vm.$u.get(apiurl.getOrderListUrl, params);
+  //室内停车订单列表api
+  let getRoomParkingApi = (params = {}) => vm.$u.get(apiurl.getRoomparkingList, params);
+  let getOrderinfo = (params = {}) => vm.$u.get(apiurl.getOrderinfoUrl + params.id);
+  let getRoomOrderDetail = (params = {}) =>
+    vm.$u.get(apiurl.getRoomOrderDetailUrl + params.id, {
+      showLoading: false
+    });
+  let getOrderDetail = (params = {}) =>
+    vm.$u.get(apiurl.getOrderDetailUrl + params.id, {
+      showLoading: false
+    });
+
+  let getMessageList = (params = {}) => vm.$u.get(apiurl.getMessageListUrl, params);
+  let messageRead = (params = {}) => vm.$u.put(apiurl.messageReadUrl + params.newId);
+
+  let nearRoadsl = (params = {}) => vm.$u.post(apiurl.nearRoadslUrl, params);
+  let roadChargeRule = (params = {}) => vm.$u.get(apiurl.roadsChargeRuleUrl + params.roadNo);
+
+  let nearParkingLot = (params = {}) => vm.$u.get(apiurl.nearParkingLotUrl, params);
+  let parkingLotChargeRule = (params = {}) => vm.$u.get(apiurl.parkingLotChargeRuleUrl + params.parkNo, params);
+
+  let monthInfo = (params = {}) => vm.$u.get(apiurl.monthInfoUrl, params);
+  let createMonth = (params = {}) => vm.$u.post(apiurl.createMonthUrl, params);
+  let monthPay = (params = {}) => vm.$u.post(apiurl.monthPayUrl, params);
+  let getMonthPay = (params = {}) => vm.$u.get(apiurl.getMonthPayUrl + params.id);
+  let getMonthList = (params = {}) => vm.$u.get(apiurl.getMonthListUrl, params);
+  // 停车场包月列表
+  let getParkMonthList = (params = {}) => vm.$u.get(apiurl.getParkMonthListUrl, params);
+  let cancelMonth = (params = {}) => vm.$u.put(apiurl.cancelMonthUrl + params.monthId);
+
+  let feePay = (params = {}) => vm.$u.put(apiurl.feePayUrl + params.vehicleId);
+  let payGzbank = (params = {}) => vm.$u.post(apiurl.payGzbankUrl, params);
+
+  let bindVehicleNo = (params = {}) => vm.$u.post(apiurl.bindVehicleNoApi, params);
+
+  //贵州银行支付
+  let gzbank = (params = {}) => vm.$u.post(apiurl.gzbankurl, params);
+  // 订单查询
+  let getOrderInfo = (params = {}) => vm.$u.get(apiurl.getOrderInfoApi + params.orderId);
+  // 设备状态查询
+  let getEquomentInfo = (params = {}) => vm.$u.get(apiurl.getEqupmentStatusApi + params.orderNo);
+  // 订单退款操作
+  let updateOrderRefund = (params = {}) => vm.$u.post(apiurl.updateOrderRefundApi, params);
+  // 获取订单退款详情
+  let getOrderRefundDetails = (params = {}) => vm.$u.get(apiurl.getOrderRefundDetailsApi + params.orderId);
+  // 普通微信支付
+  let ordinaryWxPay = (params = {}) => vm.$u.post(apiurl.ordinaryWxPayApi, params);
+  // 包月微信支付
+  let monthlyWxPay = (params = {}) => vm.$u.post(apiurl.monthlyWxPayApi, params);
+  // 获取自定义富文本内容: 0-包月须知 1-用户服务条款 2-隐私权政策信息 3-收费标准 4-退款温馨提示
+  let getSysterms = (params = {}) => vm.$u.get(apiurl.getSystermsApi + params.termsType);
+  // 通过微信登录获取openid
+  let codeV2Api = {
+    // 发送验证码V2
+    sendSmsCodeV2api: (params = {}) => vm.$u.post(apiurl.codeV2Url.sendSmsCodeV2Url, params),
+    // 验证短信验证码V2
+    verifyCodeV2Api: (params = {}) => vm.$u.post(apiurl.codeV2Url.verifyCodeV2Url, params),
+    // 登出
+    logoutApi: (params = {}) => vm.$u.post(apiurl.codeV2Url.logoutUrl, params)
+  };
+  let userLoginApi = {
+    openidLoginApi: (params = {}) => vm.$u.post(apiurl.userLoginUrl.openidLoginUrl, params),
+    sendSmsCodeApi: (params = {}) => vm.$u.post(apiurl.userLoginUrl.sendSmsCodeUrl, params),
+    mobileLoginApi: (params = {}) => vm.$u.post(apiurl.userLoginUrl.mobileLoginUrl, params)
+  };
+  let geomaLockDetailsApi = (params = {}) => vm.$u.post(apiurl.geomaLockDetailsUrl, params);
+  let getDetailEntranceApi = (params = {}) => vm.$u.post(apiurl.getDetailEntrance, params);
+  let getDetailAdvanceApi = (params = {}) => vm.$u.post(apiurl.getDetailAdvance, params);
+  let getDetailExportApi = (params = {}) => vm.$u.post(apiurl.getDetailExport, params);
+  let entranceByNoVehicleApi = (params = {}) => vm.$u.post(apiurl.entranceByNoVehicle, params);
+  let getAdvanceInfoApi = (params = {}) => vm.$u.post(apiurl.getAdvanceInfo, params);
+  let getExportInfoApi = (params = {}) => vm.$u.post(apiurl.getExportInfo, params);
+  let getOrderStateExportApi = (params = {}) => vm.$u.post(apiurl.getOrderStateExportUrl, params);
+  let quickPayExportApi = (params = {}) => vm.$u.post(apiurl.quickPayExportUrl, params);
+  let polyPayExportApi = (params = {}) => vm.$u.post(apiurl.polyPayExportUrl, params);
+  let getDictApi = (params = {}) => vm.$u.get(apiurl.getDictUrl + params.type);
+  let wechatPayApi = (params = {}) => vm.$u.post(apiurl.wechatPayUrl, params);
+  let parkingWechatPayApi = (params = {}) => vm.$u.post(apiurl.parkingWechatPayUrl, params);
+  let getParamsApi = (params = {}) => vm.$u.get(apiurl.getParamsUrl + params.key);
+  let wechatMonthlyPayapi = (params = {}) => vm.$u.post(apiurl.wechatMonthlyPayUrl, params);
+  let monthlyRuleDetailsApi = (params = {}) => vm.$u.get(apiurl.monthlyRuleDetailsUrl, params);
+  let couponListApi = (params = {}) => vm.$u.get(apiurl.couponListUrl, params);
+  let exchangeCouponApi = (params = {}) => vm.$u.put(apiurl.exchangeCouponUrl, params);
+  let updateCouponStatusApi = (params = {}) => vm.$u.post(apiurl.updateCouponStatusUrl, params);
+  let getCouponByOrderIdApi = (params = {}) => vm.$u.get(apiurl.getCouponByOrderIdUrl, params);
+  let getVehicleInquiryListApi = (params = {}) => vm.$u.post(apiurl.getVehicleInquiryListUrl, params);
+  let getOrderInfoByParknoApi = (params = {}) => vm.$u.post(apiurl.getOrderInfoByParknoUrl, params);
+  let indoorPaymentApi = (params = {}) => vm.$u.post(apiurl.indoorPaymentUrl, params);
+  // 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
+  vm.$u.api = {
+    feedbackAdd,
+    getuseinfo,
+    createOrder,
+    bindphone,
+    getPhoneLoginCode,
+    phoneLoginAuth,
+    getWXInfo,
+    wxPay,
+    getIndexData,
+    getMycars,
+    addCar,
+    delCar,
+    setDefaultCar,
+    roadInfoById,
+    getOrderinfo,
+    getOrderList,
+    getOrderDetail,
+    gzbank,
+    nearRoadsl,
+    roadChargeRule,
+    nearParkingLot,
+    parkingLotChargeRule,
+    getMessageList,
+    payGzbank,
+    monthInfo,
+    createMonth,
+    monthPay,
+    getMonthPay,
+    getMonthList,
+    getParkMonthList,
+    cancelMonth,
+    messageRead,
+    feePay,
+    getOrderInfo,
+    getEquomentInfo,
+    updateOrderRefund,
+    getOrderRefundDetails,
+    ordinaryWxPay,
+    monthlyWxPay,
+    getSysterms,
+    bindVehicleNo,
+    codeV2Api,
+    userLoginApi,
+    geomaLockDetailsApi,
+    getDetailEntranceApi,
+    getDetailAdvanceApi,
+    getDetailExportApi,
+    entranceByNoVehicleApi,
+    getAdvanceInfoApi,
+    getExportInfoApi,
+    getOrderStateExportApi,
+    quickPayExportApi,
+    polyPayExportApi,
+    getRoomParkingApi,
+    getRoomOrderDetail,
+    getDictApi,
+    wechatPayApi,
+    parkingWechatPayApi,
+    getParamsApi,
+    wechatMonthlyPayapi,
+    monthlyRuleDetailsApi,
+    couponListApi,
+    exchangeCouponApi,
+    updateCouponStatusApi,
+    getCouponByOrderIdApi,
+    getVehicleInquiryListApi,
+    getOrderInfoByParknoApi,
+    indoorPaymentApi
+  };
+};
+
+export default {
+  install
+};

+ 68 - 0
common/http.interceptor.js

@@ -0,0 +1,68 @@
+// vm,就是我们在vue文件里面的this,所以我们能在这里获取vuex的变量,比如存放在里面的token
+const install = (Vue, vm) => {
+  Vue.prototype.$u.http.setConfig({
+    baseUrl: vm.config.baseUrl,
+		loadingText: '努力加载中~',
+		loadingTime: 800
+  });
+  // 请求拦截,配置Token等参数
+  Vue.prototype.$u.http.interceptor.request = (config) => {
+    if (vm.vuex_token) {
+      config.header.Authorization = `Bearer ${vm.vuex_token}`;
+    }
+    // 请求地址加时间戳
+    config.url = config.url + '?t=' + Date.now();
+    let noTokenList = ['/client/wechat/h5/code/', '/client/auth/sendSmsCodeV2', '/client/auth/verifyCodeV2', '/client/auth/loginToWxOpenId', '/client/auth/sendSmsCodeV3', '/client/auth/loginToMobile'];
+    if (noTokenList.includes(config.url)) config.header.noToken = true;
+    return config;
+  };
+  // 响应拦截,判断状态码是否通过
+  Vue.prototype.$u.http.interceptor.response = (res) => {
+    if (res.code == 200) {
+      return res;
+    } else if (res.code == 401 || res.code == 400) {
+      const backUrl = location.href,
+        openidPage = vm.config.onlyWxLogin, // 只需要传openid的页面集合
+        needValidPage = openidPage.filter((item) => backUrl.indexOf(item) > -1); // 是否为需要验证的页面集合
+      // 判断浏览器
+      const ua = window.navigator.userAgent.toLowerCase();
+      // 微信中打开
+      if (ua.match(/MicroMessenger/i) == 'micromessenger') {
+        // 防止重复跳转
+        if (backUrl.indexOf('backUrl') === -1) {
+          vm.$u.route('pages/wechatLogin/wechatLogin', { backUrl: encodeURIComponent(backUrl), loginType: needValidPage.length ? 2 : 1 });
+        }
+      } else {
+        // 普通浏览器中打开
+        if (backUrl.indexOf('backUrl') === -1) {
+          localStorage.setItem('backUrl', encodeURIComponent(backUrl));
+        }
+        uni.showModal({
+          title: '提示',
+          content: '未查询到登录信息或信息已失效, 请重新登录',
+          showCancel: false,
+          success: function (res) {
+            if (res.confirm) {
+              localStorage.removeItem('lifeData');
+              uni.redirectTo({
+                url: '/pages/center/phoneLogin/phoneLogin'
+              });
+            }
+          }
+        });
+      }
+      return false;
+    } else {
+      uni.showToast({
+        title: res.msg || '程序错误!',
+        duration: 2000,
+        icon: 'none'
+      });
+      return false;
+    }
+  };
+};
+
+export default {
+  install
+};

+ 228 - 0
components/coupon-swiper-list-item/coupon-swiper-list-item.vue

@@ -0,0 +1,228 @@
+<!-- 在这个文件对每个tab对应的列表进行渲染 -->
+<template>
+  <view class="content">
+    <z-paging ref="paging" v-model="dataList" @query="queryList" :fixed="false" :auto="false">
+      <view class="coupon-list-item" v-for="(item, index) in dataList" :key="index">
+        <view class="coupon-list-item-top">
+          <view class="clit-left">
+            <view class="clit-left-top"
+              >¥<text>{{ item.couponContent }}</text></view
+            >
+            <view class="clit-left-bottom">{{ Number(item.threshold) > 0 ? `停车时长满${item.threshold}分钟` : '无门槛' }}</view>
+          </view>
+          <view class="clit-center">
+            <view>{{ item.couponName }}</view>
+            <view>{{ item.vehicleNo }}</view>
+          </view>
+          <template v-if="Number(item.status) === 0">
+            <view class="clit-right">
+              <!-- <u-button class="clit-right-btn" type="primary" size="default" @click="goToUse(item)">立即使用</u-button> -->
+              <u-button class="clit-right-btn" disabled type="primary" size="default">未使用</u-button>
+            </view>
+          </template>
+          <template v-else-if="Number(item.status) === 1">
+            <view class="clit-right">
+              <u-image width="128rpx" height="128rpx" src="/static/img/have-used-icon.svg"/>
+            </view>
+          </template>
+          <template v-else-if="Number(item.status) === 2">
+            <view class="clit-right">
+              <u-image width="128rpx" height="128rpx" src="/static/img/have-overdued-icon.svg"/>
+            </view>
+          </template>
+        </view>
+        <view class="coupon-list-item-bottom">
+          <view class="coupon-list-item-bottom-left">
+            适用停车点:
+            <template v-if="item.parkList.length > 1"> 适用多个停车点 </template>
+            <template v-else> 仅限{{ item.parkList.map((item) => item.parkName).join('、') }} </template>
+          </view>
+          <template v-if="Number(item.status) === 0">
+            <view class="coupon-list-item-bottom-right">有效期:{{ calcValidity(item.startTime, item.endTime) }} </view>
+          </template>
+          <template v-else>
+            <view class="coupon-list-item-bottom-right">已失效</view>
+          </template>
+        </view>
+        <template v-if="item.parkList.length > 1">
+          <view class="clibl-point">
+            <u-read-more
+              text-indent="0"
+              show-height="0"
+              :toggle="true"
+              :shadow-style="{ backgroundImage: 'none' }"
+              fontSize="20rpx"
+              close-text="展开所有停车点"
+            >
+              <view class="clibl-point-content">{{ item.parkList.map((item) => item.parkName).join('、') }}</view>
+            </u-read-more>
+          </view>
+        </template>
+      </view>
+    </z-paging>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      dataList: [],
+      firstLoaded: false
+    };
+  },
+  props: {
+    tabIndex: {
+      type: Number,
+      default: function () {
+        return 0;
+      }
+    },
+    currentIndex: {
+      type: Number,
+      default: function () {
+        return 0;
+      }
+    }
+  },
+  watch: {
+    currentIndex: {
+      handler(newVal) {
+        if (newVal === this.tabIndex) {
+          //懒加载,当滑动到当前的item时,才去加载
+          if (!this.firstLoaded) {
+            setTimeout(() => {
+              this.$refs.paging.reload();
+            }, 100);
+          }
+        }
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    queryList(pageNo, pageSize) {
+      const params = {
+        pageNum: pageNo,
+        pageSize: pageSize,
+        status: this.currentIndex
+      };
+      this.$u.api
+        .couponListApi(params)
+        .then((res) => {
+          this.$refs.paging.complete(res.data.rows);
+          this.firstLoaded = true;
+        })
+        .catch((res) => {
+          this.$refs.paging.complete(false);
+        });
+    },
+    /**
+     * 重载数据
+     * @date 2022-12-23
+     * @returns {any}
+     */
+    reloadData() {
+      this.$refs.paging.reload();
+    },
+    goToUse(item) {
+      this.$u.route({
+        url: 'pages/payLists/payLists'
+      });
+    },
+    /**
+     * 计算剩余时间
+     * @date 2022-12-23
+     * @param {any} datetime
+     * @returns {any}
+     */
+    calcValidity(startTime, endTime) {
+      let endTimeStr = new Date(endTime).valueOf(),
+        nowTimeStr = new Date(startTime).valueOf() < Date.now() ? Date.now() : new Date(startTime).valueOf(),
+        remainTimeStr = endTimeStr - nowTimeStr,
+        day = Math.floor(remainTimeStr / (1000 * 3600 * 24)),
+        dayOver = remainTimeStr % (1000 * 3600 * 24),
+        hours = Math.floor(dayOver / (3600 * 1000)),
+        hourOver = dayOver % (3600 * 1000),
+        minutes = Math.floor(hourOver / (60 * 1000));
+      return `${day}天${hours}小时${minutes}分`;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+/* 注意:父节点需要固定高度,z-paging的height:100%才会生效 */
+.content {
+  height: 100%;
+	padding-top: 30rpx;
+}
+.coupon-list-item {
+  background-color: #fff;
+  border-radius: 17rpx;
+  box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.08);
+  padding: 20rpx 0;
+  margin-bottom: 30rpx;
+  &-top {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 26rpx 30rpx 37rpx;
+    border-bottom: 1px solid #eeeeee;
+    .clit-left {
+      color: #ff6d6d;
+      font-size: 24rpx;
+      width: 30%;
+      &-top {
+        margin-bottom: 10rpx;
+        text {
+          font-size: 60rpx;
+        }
+      }
+      &-bottom {
+        width: 100%;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
+    }
+    .clit-center {
+      font-size: 20rpx;
+      color: #333;
+      width: 40%;
+      margin-left: 2%;
+      view:first-child {
+        width: 100%;
+        font-size: 32rpx;
+        color: #666;
+        font-weight: 500;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        margin-bottom: 16rpx;
+      }
+    }
+    .clit-right {
+      margin-left: 2%;
+      &-btn {
+        background-color: #ff6d6d;
+      }
+    }
+  }
+  &-bottom {
+    font-size: 20rpx;
+    color: #999999;
+    display: flex;
+    justify-content: space-between;
+    padding: 10rpx 30rpx 0;
+  }
+  .clibl-point {
+    margin-top: 20rpx;
+    font-size: 22rpx;
+    &-content {
+      font-size: 22rpx;
+      padding: 0 30rpx;
+    }
+  }
+}
+</style>

+ 43 - 0
main.js

@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import App from './App';
+
+Vue.config.productionTip = false;
+import { config } from './common/config';
+Vue.prototype.config = config;
+// 项目标识
+Vue.prototype.projectFlag = config.projectFlag;
+
+if (process.env.H_NODE_ENV !== 'production') {
+	const vconsole = require('vconsole')
+	Vue.prototype.$vconsole = new vconsole()
+}
+
+import './utils/filter';
+
+App.mpType = 'app';
+
+// 引入全局uView
+import uView from 'uview-ui';
+Vue.use(uView);
+
+// 此处为演示vuex使用,非uView的功能部分
+import store from '@/store';
+
+// 引入uView提供的对vuex的简写法文件
+let vuexStore = require('@/store/$u.mixin.js');
+Vue.mixin(vuexStore);
+
+const app = new Vue({
+  store,
+  ...App
+});
+
+// http拦截器,将此部分放在new Vue()和app.$mount()之间,才能App.vue中正常使用
+import httpInterceptor from '@/common/http.interceptor.js';
+Vue.use(httpInterceptor, app);
+
+// http接口API抽离,免于写url或者一些固定的参数
+import httpApi from '@/common/http.api.js';
+Vue.use(httpApi, app);
+
+app.$mount();

+ 113 - 0
manifest.json

@@ -0,0 +1,113 @@
+{
+    "name" : "智慧停车",
+    "appid" : "__UNI__BF6D66C",
+    "description" : "普定停车二期",
+    "versionName" : "1.5.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "safearea" : {
+            "bottom" : {
+                "offset" : "none"
+            }
+        },
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {},
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    /* 百度地图 */
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\" />",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />",
+                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\" />",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\" />",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+                    /* 高德地图 */
+                    "<uses-permission android:name=\"android.permission.INTERNET\" />",
+                    "<uses-permission android:name=\"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\" />",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH\" />",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\" />"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {},
+            /* SDK配置 */
+            "sdkConfigs" : {
+                "maps" : {
+                    "amap" : {
+                        "appkey_ios" : "",
+                        "appkey_android" : ""
+                    }
+                },
+                "geolocation" : {},
+                "push" : {},
+                "ad" : {}
+            },
+            "splashscreen" : {
+                "androidStyle" : "common"
+            }
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "wxc256e348c4032ebd",
+        "setting" : {
+            "urlCheck" : false
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "h5" : {
+        "template" : "template.h5.html",
+        "router" : {
+            "mode" : "hash",
+            "base" : "./"
+        },
+        "sdkConfigs" : {
+            "maps" : {
+                "qqmap" : {
+                    "key" : "BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL"
+                }
+            }
+        },
+        "devServer" : {
+            "https" : false
+        }
+    }
+}

+ 101 - 0
package.json

@@ -0,0 +1,101 @@
+{
+	"uni-app": {
+		"scripts": {
+			"dev:pudingtest": {
+				"title": "dev:pudingtest",
+				"env": {
+					"UNI_PLATFORM": "h5",
+					"H_NODE_ENV": "development",
+					"H_BASE_URL": "https://wx.hw.hongweisoft.com/parking",
+					"H_WXAPPID": "wx6e9cdf7a0ee8a51b",
+					"DESCRIBE": "普定测试环境",
+					"H_PROJECT": "puding",
+					"H_PROJECT_NAME": "普定",
+					"H_PROJECT_URL": "https://parkingh5.hw.hongweisoft.com/#/?type=jumpurl"
+				}
+			},
+			"build:pudingtest": {
+				"title": "build:pudingtest",
+				"env": {
+					"UNI_PLATFORM": "h5",
+					"H_NODE_ENV": "development",
+					"H_BASE_URL": "https://wx.hw.hongweisoft.com/parking",
+					"H_WXAPPID": "wx6e9cdf7a0ee8a51b",
+					"DESCRIBE": "普定测试环境",
+					"H_PROJECT": "puding",
+					"H_PROJECT_NAME": "普定",
+					"H_PROJECT_URL": "https://parkingh5.hw.hongweisoft.com/#/?type=jumpurl"
+				}
+			},
+			"build:pudingpro": {
+				"title": "build:pudingpro",
+				"env": {
+					"UNI_PLATFORM": "h5",
+					"H_NODE_ENV": "production",
+					"H_BASE_URL": "https://parking.pdzhtc.com",
+					"H_WXAPPID": "wx45c3cf2b632f5fd5",
+					"DESCRIBE": "普定正式环境",
+					"H_PROJECT_NAME": "普定",
+					"H_PROJECT_URL": "https://h5.pdzhtc.com/#/?type=jumpurl"
+				}
+			},
+			"dev:zhenningtest": {
+				"title": "dev:zhenningtest",
+				"env": {
+					"UNI_PLATFORM": "h5",
+					"H_NODE_ENV": "development",
+					"H_BASE_URL": "https://wx.hw.hongweisoft.com/parkingzn",
+					"H_WXAPPID": "wx2968efc3cf10ec7a",
+					"DESCRIBE": "镇宁测试环境",
+					"H_PROJECT": "zhenning",
+					"H_PROJECT_NAME": "镇宁",
+					"H_PROJECT_URL": "https://parkingznh5.hw.hongweisoft.com/#/?type=jumpurl"
+				}
+			},
+			"build:zhenningtest": {
+				"title": "build:zhenningtest",
+				"env": {
+					"UNI_PLATFORM": "h5",
+					"H_NODE_ENV": "development",
+					"H_BASE_URL": "https://wx.hw.hongweisoft.com/parkingzn",
+					"H_WXAPPID": "wx2968efc3cf10ec7a",
+					"DESCRIBE": "镇宁测试环境",
+					"H_PROJECT": "zhenning",
+					"H_PROJECT_NAME": "镇宁",
+					"H_PROJECT_URL": "https://parkingznh5.hw.hongweisoft.com/#/?type=jumpurl"
+				}
+			},
+			"build:zhenningpro": {
+				"title": "build:zhenningpro",
+				"env": {
+					"UNI_PLATFORM": "h5",
+					"H_NODE_ENV": "production",
+					"H_BASE_URL": "https://parking.znzhtc.com",
+					"H_WXAPPID": "wx2968efc3cf10ec7a",
+					"DESCRIBE": "镇宁正式环境",
+					"H_PROJECT": "zhenning",
+					"H_PROJECT_NAME": "镇宁",
+					"H_PROJECT_URL": "https://h5.znzhtc.com/#/?type=jumpurl"
+				}
+			},
+			"build:wudangpro": {
+				"title": "build:wudangpro",
+				"env": {
+					"UNI_PLATFORM": "h5",
+					"H_NODE_ENV": "production",
+					"H_BASE_URL": "https://parking.qfzhtc.com",
+					"H_WXAPPID": "wxea865618d910b155",
+					"DESCRIBE": "乌当正式环境",
+					"H_PROJECT": "wudang",
+					"H_PROJECT_NAME": "wudang",
+					"H_PROJECT_URL": "https://h5.wud.qfzhtc.com/#/?type=jumpurl"
+				}
+			}
+		}
+	},
+	"dependencies": {
+		"vconsole": "^3.15.0",
+		"vue-jsonp": "^2.0.0",
+		"weixin-js-sdk": "^1.6.0"
+	}
+}

+ 342 - 0
pages.json

@@ -0,0 +1,342 @@
+{
+  "easycom": {
+    "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
+  },
+  "pages": [
+    {
+      "path": "pages/index/index",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "城市智慧停车"
+      }
+    },
+    {
+      "path": "pages/center/index",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTextStyle": "white",
+        "navigationBarTitleText": "城市智慧停车"
+      }
+    },
+    {
+      "path": "pages/center/phoneLogin/phoneLogin",
+      "style": {
+        "navigationBarTitleText": "手机号登录",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/center/order/order",
+      "style": {
+        "navigationBarTitleText": "停车记录",
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/center/order/orderDetails/orderDetails",
+      "style": {
+        "navigationBarTitleText": "订单详情"
+      }
+    },
+    {
+      "path": "pages/parkingLists/parkingLists",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "停车点"
+      }
+    },
+    {
+      "path": "pages/myCars/myCars",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "我的车辆",
+        "enablePullDownRefresh": true
+      }
+    },
+    {
+      "path": "pages/message/message",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "消息中心"
+      }
+    },
+    {
+      "path": "pages/message/messageInfo",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "消息中心"
+      }
+    },
+    {
+      "path": "pages/payLists/payLists",
+      "style": {
+        "navigationBarTitleText": "停车缴费",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/parkingInformation/parkingInformation",
+      "style": {
+        "navigationBarTitleText": "停车场信息",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black"
+      }
+    },
+    {
+      "path": "pages/chargeStandard/chargeStandard",
+      "style": {
+        "navigationBarTitleText": "收费标准",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/handleMonthly/handleMonthly",
+      "style": {
+        "navigationBarTitleText": "办理包月",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/center/monthly/monthly",
+      "style": {
+        "navigationBarTitleText": "我的包月",
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/handleMonthly/monthPay",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "包月支付"
+      }
+    },
+    {
+      "path": "pages/searchparking/searchparking",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "停车查询"
+      }
+    },
+    {
+      "path": "pages/favourableActivity/favourableActivity",
+      "style": {
+        "navigationBarTitleText": "一分钱停车",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/parkingLock/parkingLock",
+      "style": {
+        "navigationBarTitleText": "车位锁",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/parkingLists/map_web_view/map_web_view",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "导航",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/bannerDetails/bannerDetails",
+      "style": {
+        "navigationBarTitleText": "详情页",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/applyRefund/applyRefund",
+      "style": {
+        "navigationBarTitleText": "申请退款",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/applyRefundDetails/applyRefundDetails",
+      "style": {
+        "navigationBarTitleText": "申请退款",
+        "navigationStyle": "custom",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/applyRefundDetails/applyRefundAchieveDetails",
+      "style": {
+        "navigationBarTitleText": "订单详情"
+      }
+    },
+    {
+      "path": "pages/privacyPolicy/privacyPolicy",
+      "style": {
+        "navigationBarTitleText": "隐私政策",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/wechatLogin/wechatLogin",
+      "style": {
+        "navigationBarTitleText": "微信登录",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/geomagnetismLock/geomagnetismLock",
+      "style": {
+        "navigationBarTitleText": "地磁",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/parkentrace/parkentrace",
+      "style": {
+        "navigationBarTitleText": "入口扫码",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/parkadvance/parkadvance",
+      "style": {
+        "navigationBarTitleText": "场内扫码",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/parkexport/parkexport",
+      "style": {
+        "navigationBarTitleText": "出口扫码",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/parkroadgate/parkroadgate",
+      "style": {
+        "navigationBarTitleText": "道闸",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/roadGateSystem/roadGateSystem",
+      "style": {
+        "navigationBarTitleText": "道闸系统",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/center/coupon/myCoupon/myCoupon",
+      "style": {
+        "navigationBarTitleText": "我的优惠券",
+        "enablePullDownRefresh": false,
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/center/coupon/couponRules/couponRules",
+      "style": {
+        "navigationBarTitleText": "优惠券说明",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/VehicleInquiry/VehicleInquiry",
+      "style": {
+        "navigationBarTitleText": "车费查询",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/OnsitePayment/OnsitePayment",
+      "style": {
+        "navigationBarTitleText": "停车场",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/common/paymentSuccess/paymentSuccess",
+      "style": {
+        "navigationBarTitleText": "支付成功",
+        "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#008CFF",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/goldPlan/goldPlan",
+      "style": {
+        "navigationBarTitleText": "点金计划",
+        "enablePullDownRefresh": false,
+        "navigationStyle": "custom"
+      }
+    }
+  ],
+  "globalStyle": {
+    "navigationBarTextStyle": "black",
+    "navigationBarTitleText": "普定智慧停车",
+    "navigationBarBackgroundColor": "#F8F8F8",
+    "backgroundColor": "#F8F8F8",
+    "backgroundColorTop": "#FFFFFF"
+  },
+  "tabBar": {
+    "color": "#909399",
+    "selectedColor": "#303133",
+    "borderStyle": "black",
+    "backgroundColor": "#ffffff",
+    "list": [
+      {
+        "pagePath": "pages/index/index",
+        "iconPath": "static/index.png",
+        "selectedIconPath": "static/index-selected.png",
+        "text": "首页"
+      },
+      {
+        "pagePath": "pages/parkingLists/parkingLists",
+        "iconPath": "static/car_h.png",
+        "selectedIconPath": "static/car.png",
+        "text": "找车位"
+      },
+      {
+        "pagePath": "pages/center/index",
+        "iconPath": "static/center.png",
+        "selectedIconPath": "static/center-selected.png",
+        "text": "我"
+      }
+    ]
+  }
+}

+ 68 - 0
pages/OnsitePayment/OnsitePayment.scss

@@ -0,0 +1,68 @@
+.parking-lock {
+  min-height: calc(100vh - 88rpx);
+  background-color: #f6f6ff;
+  &-box {
+    padding: 40rpx 0 0;
+  }
+  &-title {
+    font-size: 46rpx;
+    color: #292929;
+    text-align: center;
+    padding-top: 31rpx;
+    line-height: 65rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+  }
+  &-tips {
+    width: calc(100% - 72rpx);
+    font-size: 30rpx;
+    color: #777777;
+    text-align: center;
+    margin: 10rpx auto;
+    line-height: 47rpx;
+  }
+  &-info {
+    width: calc(100% - 72rpx);
+    margin: 31rpx auto 54rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    padding: 39rpx 41rpx;
+    &-item {
+      display: flex;
+      margin-bottom: 16rpx;
+      view {
+        font-size: 28rpx;
+        &:first-child {
+          width: 30%;
+          color: #2a2a2a;
+        }
+        &:last-child {
+          color: #6e6e6e;
+        }
+      }
+      .really-money {
+        color: #fa7319 !important;
+      }
+    }
+  }
+  &-pay-btn {
+    width: calc(100% - 72rpx);
+    margin: 0 auto;
+    button {
+      width: 100%;
+      height: 100rpx;
+      line-height: 100rpx;
+      background-color: #008cff;
+      border: none;
+      color: #fff;
+      box-shadow: 0px 7px 13px 0px rgba(16, 153, 250, 0.31);
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+  }
+  &-pay-attention {
+    width: calc(100% - 100rpx);
+    margin: 50rpx auto;
+    color: #777777;
+  }
+}

+ 193 - 0
pages/OnsitePayment/OnsitePayment.vue

@@ -0,0 +1,193 @@
+<!-- 场内支付---停车场 -->
+<template>
+  <view class="parking-lock">
+    <view class="parking-lock-box">
+      <view class="parking-lock-pay">
+        <view class="parking-lock-title">支付停车费</view>
+        <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view>
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item" v-for="(item, index) in fieldList" :key="index">
+            <view>{{ item.label }}</view>
+            <view :class="item.money ? 'really-money' : ''">{{ orderInfo[item.key] }}</view>
+          </view>
+        </view>
+        <view class="parking-lock-pay-btn">
+          <button type="default" @click="payMoney" :disabled="!orderInfo.id">立即支付</button>
+        </view>
+        <view class="parking-lock-pay-attention">
+          <text>温馨提示:支付完成请尽快离场,超过免费时长将会重新计费</text>
+        </view>
+      </view>
+      <!-- 支付方式 -->
+      <ChoosePayment ref="choosePayment" :curOrderList="orderList" :jumpUrl="jumpUrl" :isIndoor="true" />
+    </view>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import ChoosePayment from '@/pages/choosePayment/choosePayment.vue';
+export default {
+  components: {
+    ChoosePayment
+  },
+  data() {
+    return {
+      // 支付订单编号
+      orderList: [],
+      // 订单信息
+      orderInfo: {},
+      // 回调地址
+      jumpUrl: '',
+      // 显示的字段集合
+      fieldList: [
+        { key: 'vehicleNo', label: '车牌号' },
+        { key: 'parkingName', label: '停车场名称' },
+        { key: 'entranceName', label: '入场车道' },
+        { key: 'inTime', label: '入场时间' },
+        { key: 'freeDuration', label: '免费时长' },
+        { key: 'calcDuration', label: '计费时长' },
+        { key: 'duration', label: '累计停车时长' },
+        { key: 'payAmount', label: '应缴金额', money: true },
+        { key: 'id', label: '订单编号' }
+      ],
+      paramsObj: {
+        vehicleNo: '',
+        parkNo: ''
+      },
+      timer: null,
+      polyOrderId: undefined, // 预支付订单id
+      isBack: 0,
+      needPay: ''
+    };
+  },
+  onLoad(options) {
+    console.log('options', options);
+    const { vehicleNo, parkNo, isBack, polyOrderId, needPay } = options;
+    if (vehicleNo && parkNo) {
+      this.paramsObj.vehicleNo = vehicleNo;
+      this.paramsObj.parkNo = parkNo;
+      this.isBack = isBack ?? 0;
+      this.polyOrderId = polyOrderId;
+      this.needPay = needPay;
+      console.log('isBack', Number(this.isBack) !== 1);
+      if (needPay && needPay === 'not') {
+        this.$u.route({
+          url: '/pages/center/order/order',
+          type: 'redirectTo'
+        });
+      } else if (Number(this.isBack) !== 1) {
+        this.getOrderDetails(vehicleNo, parkNo);
+      }
+      this.jumpUrl = `${location.origin}/#/pages/OnsitePayment/OnsitePayment?vehicleNo=${vehicleNo}&parkNo=${parkNo}&isBack=1`;
+    } else {
+      uni.showModal({
+        title: '提示',
+        content: '参数丢失, 返回首页',
+        showCancel: false,
+        success: function (res) {
+          if (res.confirm) {
+            uni.switchTab({
+              url: '/pages/index/index'
+            });
+          }
+        }
+      });
+    }
+  },
+  onShow() {
+    const { isBack, polyOrderId, needPay } = this;
+    if (Number(isBack) === 1 && polyOrderId && needPay !== 'not') {
+      uni.showLoading({
+        title: '支付查询中...',
+        mask: true
+      });
+      this.timer = setInterval(() => {
+        this.handlePayStatus(this.polyOrderId);
+      }, 2000);
+    }
+  },
+  methods: {
+    /**
+     * 立即支付
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    payMoney() {
+      this.$nextTick(() => {
+        this.$refs['choosePayment'].openPopup({ ...this.orderInfo }, 'single', 'parking');
+      });
+    },
+    /**
+     * 根据订单id查询订单信息
+     * @date 2023-02-22
+     * @param {any} vehicleNo
+     * @param {any} parkNo
+     * @returns {any}
+     */
+    async getOrderDetails(vehicleNo, parkNo) {
+      try {
+        const { code, data } = await this.$u.api.getOrderInfoByParknoApi({ vehicleNo, parkNo });
+        if (code === 200) {
+          const { id } = data;
+          this.orderList = [id];
+          this.orderInfo = data;
+          if (Number(data?.payStatus) === 1) {
+            this.$refs.uToast.show({
+              title: '该订单已支付完成!',
+              type: 'success',
+              url: '/pages/common/paymentSuccess/paymentSuccess',
+              callback: () => {
+                // this.loading = false;
+              }
+            });
+          }
+        }
+      } catch (error) {
+        this.showToast(error?.msg, 'error');
+      }
+    },
+    /**
+     * 反复查询支付状态
+     * @param { String } orderId
+     */
+    async handlePayStatus(orderId) {
+      try {
+        const { code, data } = await this.$u.api.getOrderInfo({ orderId });
+        if (code === 200) {
+          if (data?.payStatus === 1 || data?.payStatus === 3) {
+            clearInterval(this.timer);
+            this.$refs.uToast.show({
+              title: '该订单已支付成功!',
+              type: 'success',
+              url: '/pages/common/paymentSuccess/paymentSuccess',
+              callback: () => {
+                uni.hideLoading();
+              }
+            });
+          }
+        }
+      } catch (error) {
+        clearInterval(this.timer);
+        uni.hideLoading();
+      }
+    },
+    /**
+     * @description: 显示提示信息
+     * @param {*} title
+     * @param {*} type
+     * @return {*}
+     */
+    showToast(title = '操作失败', type = 'error') {
+      this.$refs.uToast.show({
+        title,
+        type
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './OnsitePayment.scss';
+</style>

+ 30 - 0
pages/VehicleInquiry/VehicleInquiry.scss

@@ -0,0 +1,30 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: calc(100vh - 44px);
+  &-title {
+    text-align: center;
+    font-size: 30rpx;
+    color: #888;
+    margin-bottom: 40rpx;
+  }
+  &-select {
+    width: 620rpx;
+    text-align: center;
+    color: #777777;
+    padding: 20rpx 0x;
+    &-empty {
+      text-align: center;
+      font-size: 26rpx;
+    }
+    &-scroll {
+      height: 600rpx;
+    }
+  }
+  &-btn {
+    width: 680rpx;
+    margin-top: 40rpx;
+  }
+}

+ 221 - 0
pages/VehicleInquiry/VehicleInquiry.vue

@@ -0,0 +1,221 @@
+<!-- 车辆查询 -->
+<template>
+  <view class="container">
+    <view class="container-title">
+      <text>输入车牌,查询车费</text>
+    </view>
+    <!-- 车牌输入 -->
+    <view class="container-input" @click="vehicleNoInputClick">
+      <u-message-input :maxlength="8" width="60" font-size="40" :disabled-keyboard="true" v-model="form.vehicleNo" />
+    </view>
+    <!-- 车辆下拉 -->
+    <view class="container-select">
+      <u-collapse ref="refValue" :head-style="{ fontSize: '28rpx' }">
+        <u-collapse-item title="点击选择车牌" align="center">
+          <scroll-view class="container-select-scroll" scroll-y="true">
+            <u-cell-group v-if="vehicleList.length">
+              <u-cell-item :title="item.value" v-for="(item, index) in vehicleList" :key="index" :arrow="false">
+                <u-radio-group v-model="form.vehicleNo" @change="radioGroupChange">
+                  <u-radio :name="item.value" :key="index" />
+                </u-radio-group>
+              </u-cell-item>
+            </u-cell-group>
+            <template v-else>
+              <view class="container-select-empty">暂无绑定车牌</view>
+            </template>
+          </scroll-view>
+        </u-collapse-item>
+      </u-collapse>
+    </view>
+    <view class="container-btn">
+      <u-button type="primary" :loading="loading" :disabled="!form.vehicleNo" @click="submitVehicleInquiry">确定</u-button>
+    </view>
+    <!-- 选择颜色 -->
+    <u-action-sheet :list="bindVehiclePop.colorList" @click="confirmColor" v-model="bindVehiclePop.colorShow" />
+    <!-- 车牌号键盘 -->
+    <u-keyboard ref="uKeyboard" mode="car" @change="keyboardChange" @confirm="keyboardConfirm" @backspace="backspace" v-model="keyboardshow" />
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      form: {
+        vehicleNo: '',
+        parkNo: ''
+      },
+      vehicleList: [],
+      keyboardshow: false,
+      loading: false,
+      showChangeVehicleNo: false,
+      bindVehiclePop: {
+        colorShow: false,
+        colorList: [
+          {
+            text: '蓝色',
+            colorCode: 0
+          },
+          {
+            text: '黄色',
+            colorCode: 1
+          },
+          {
+            text: '黑色',
+            colorCode: 2
+          },
+          {
+            text: '白色',
+            colorCode: 3
+          },
+          {
+            text: '绿色',
+            colorCode: 4
+          },
+          {
+            text: '其他',
+            colorCode: 99
+          }
+        ]
+      },
+      parkNo: null,
+      parkInfo: {}
+    };
+  },
+  onLoad(options) {
+    const { parkNo } = options;
+    if (parkNo) {
+      this.form.parkNo = parkNo;
+      this.getVehicleInquiryList(parkNo);
+    } else {
+      uni.showModal({
+        title: '提示',
+        content: '参数丢失, 返回首页',
+        showCancel: false,
+        success: function (res) {
+          if (res.confirm) {
+            uni.switchTab({
+              url: '/pages/index/index'
+            });
+          }
+        }
+      });
+    }
+  },
+  methods: {
+    /**
+     * @description: 车牌输入框点击
+     * @return {*}
+     */
+    vehicleNoInputClick() {
+      this.keyboardshow = true;
+      this.form.vehicleNo = '';
+    },
+    /**
+     * @description: 单击车牌
+     * @param {*} e
+     * @return {*}
+     */
+    radioGroupChange(e) {
+      this.form.vehicleNo = e;
+    },
+    /**
+     * @description: 颜色下拉确认
+     * @return {*}
+     */
+    confirmColor() {
+      this.bindVehiclePop.colorShow = false;
+    },
+    /**
+     * @description: 车牌键盘输入变化
+     * @param {*} val
+     * @return {*}
+     */
+    keyboardChange(val) {
+      // 将每次按键的值拼接到value变量中,注意+=写法
+      this.form.vehicleNo += val;
+    },
+    /**
+     * @description: 键盘输入完成确认时
+     * @return {*}
+     */
+    keyboardConfirm() {
+      this.bindVehiclePop.colorShow = true;
+    },
+    /**
+     * @description: 退格键被点击
+     * @return {*}
+     */
+    backspace() {
+      // 删除value的最后一个字符
+      if (this.form.vehicleNo.length) this.form.vehicleNo = this.form.vehicleNo.substr(0, this.form.vehicleNo.length - 1);
+    },
+    /**
+     * @description: 获取当前用户车辆
+     * @return {*}
+     */
+    async getVehicleInquiryList(parkNo) {
+      try {
+        const { data, code } = await this.$u.api.getVehicleInquiryListApi({ parkNo });
+        if (code === 200) {
+          this.parkInfo = data;
+          this.vehicleList = data.vehicleList.map((item) => {
+            return { label: item, value: item };
+          });
+          await this.$nextTick();
+          this.$refs.refValue.init();
+        }
+      } catch (error) {}
+    },
+    /**
+     * @description: 确认车费查询
+     * @return {*}
+     */
+    async submitVehicleInquiry() {
+      const { vehicleNo } = this.form;
+      if (this.$u.test.carNo(vehicleNo)) {
+        this.loading = true;
+        try {
+          const { code } = await this.$u.api.getOrderInfoByParknoApi({ ...this.form });
+          if (code === 200) {
+            this.$refs.uToast.show({
+              title: '查询成功!',
+              type: 'success',
+              url: '/pages/OnsitePayment/OnsitePayment',
+              params: {
+                ...this.form
+              },
+              callback: () => {
+                this.loading = false;
+              }
+            });
+          }
+        } catch (error) {
+          this.loading = false;
+          // this.showToast(error?.msg, 'error');
+        }
+      } else {
+        this.loading = false;
+        this.showToast('请输入有效的车牌号!', 'error');
+      }
+    },
+    /**
+     * @description: 提示
+     * @param {*} title
+     * @param {*} type
+     * @return {*}
+     */
+    showToast(title = '操作失败!', type = 'error') {
+      this.$refs.uToast.show({
+        title,
+        type
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './VehicleInquiry.scss';
+</style>

+ 77 - 0
pages/applyRefund/applyRefund.scss

@@ -0,0 +1,77 @@
+.apply-refund {
+  background-color: #f6f6ff;
+  min-height: calc(100vh - 44px);
+  .apply-refund-form {
+    background-color: #fff;
+    font-size: 28rpx;
+    .apply-refund-form-item {
+      display: flex;
+      flex-wrap: wrap;
+      line-height: 100rpx;
+      padding: 0 34rpx;
+      border-bottom: solid 2px #f5f5f5;
+      .apply-refund-form-label {
+        width: 150rpx;
+      }
+      .apply-refund-form-content {
+        color: #787878;
+        background-color: #fff;
+        .money {
+          color: #fa6400;
+        }
+        textarea {
+          width: 100%;
+          background-color: #f5f5f5;
+          font-size: 26rpx;
+          &:after {
+            content: attr(data-maxnum);
+            position: absolute;
+            right: 10px;
+            bottom: 3px;
+            font-size: 12px;
+          }
+        }
+      }
+      .full-width {
+        width: 100%;
+        background-color: #f5f5f5;
+        padding: 30rpx;
+        margin-bottom: 30rpx;
+        border-radius: 5px;
+        /deep/ .u-add-wrap {
+          border: 1px dashed #606266;
+        }
+      }
+    }
+  }
+  .apply-refund-form-submit {
+    padding: 0 34rpx;
+    margin: 50rpx 0;
+  }
+  .refund-tips {
+    padding: 34rpx;
+    background-color: #fff;
+  }
+  .pop-warp {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: 100%;
+    .pop-warp-icon {
+      width: 100rpx;
+      height: 100rpx;
+      line-height: 120rpx;
+      margin: 0 auto;
+      border-radius: 50%;
+      background-color: $u-type-primary;
+      text-align: center;
+    }
+    .pop-warp-tips {
+      color: $u-type-primary;
+      width: 260rpx;
+      text-align: center;
+      margin-top: 30rpx;
+    }
+  }
+}

+ 161 - 0
pages/applyRefund/applyRefund.vue

@@ -0,0 +1,161 @@
+<template>
+  <view class="apply-refund">
+    <view class="apply-refund-form">
+      <view class="apply-refund-form-item">
+        <view class="apply-refund-form-label"> 退款金额: </view>
+        <view class="apply-refund-form-content">
+          <text class="money">{{ Number(refundForm.refundAmount).toFixed(2) }}</text
+          >元
+        </view>
+      </view>
+      <view class="apply-refund-form-item">
+        <view class="apply-refund-form-label"> 退款原因: </view>
+        <view class="apply-refund-form-content full-width">
+          <textarea
+            v-model="refundForm.refundReason"
+            maxlength="200"
+            placeholder="请填写申请退款原因"
+            :data-maxnum="refundForm.refundReason.length + '/200'"
+          />
+          <u-upload
+            :header="{
+              Authorization: 'Bearer ' + vuex_token
+            }"
+            max-count="3"
+            ref="uUpload"
+            :action="action"
+          ></u-upload>
+        </view>
+      </view>
+    </view>
+    <view class="apply-refund-form-submit">
+      <u-button type="primary" @click="submit">提交</u-button>
+    </view>
+    <view class="refund-tips" v-if="refundTipsContent">
+      <u-parse :html="refundTipsContent"></u-parse>
+    </view>
+    <u-mask :show="successPop" :zoom="true" :custom-style="{ background: 'rgba(255, 255, 255, 0.8)' }">
+      <view class="pop-warp">
+        <view class="pop-warp-icon">
+          <u-icon name="checkbox-mark" color="#fff" size="50"></u-icon>
+        </view>
+        <view class="pop-warp-tips">
+          <text>提交成功!预计3-7个工作日内处理</text>
+        </view>
+      </view>
+    </u-mask>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import { mapState, mapMutations } from 'vuex';
+import { config } from '@/common/config.js';
+export default {
+  data() {
+    return {
+      refundForm: {
+        orderId: '',
+        refundAmount: '',
+        refundReason: '',
+        images: []
+      },
+      action: config.baseUrl + '/file/tencent/upload',
+      successPop: false,
+      // 退款温馨提示
+      refundTipsContent: ''
+    };
+  },
+  computed: {
+    ...mapState(['vuex_token'])
+  },
+  onLoad(page) {
+    this.refundForm.orderId = page.orderId;
+    this.refundForm.refundAmount = Number(page.payAmount);
+    this.getSysterms(4);
+  },
+  methods: {
+    submit() {
+      let files = [];
+      // 是否有未完成上传的图片标识
+      let isHas = false;
+      this.$refs.uUpload.lists.forEach((item) => {
+        if (item.progress === 100 && item.response) {
+          const url = item?.response?.data?.url;
+          if (url) {
+            files.push(url);
+          }
+        } else {
+          isHas = true;
+        }
+      });
+      this.refundForm.images = files;
+      if (this.refundForm.refundReason && !isHas) {
+        this.$u.api
+          .updateOrderRefund(this.refundForm)
+          .then((res) => {
+            this.successPop = true;
+            if (res.code === 200) {
+              setTimeout(() => {
+                this.$u.route('pages/applyRefundDetails/applyRefundDetails', {
+                  orderId: this.refundForm.orderId
+                });
+              }, 2000);
+            } else {
+              this.successPop = false;
+              this.$refs.uToast.show({
+                title: res.msg,
+                type: 'error'
+              });
+            }
+          })
+          .catch((err) => {
+            this.$refs.uToast.show({
+              title: '操作失败!',
+              type: 'error'
+            });
+          });
+      } else if (this.refundForm.refundReason == '') {
+        this.$refs.uToast.show({
+          title: '请填写申请退款原因',
+          type: 'warning'
+        });
+      } else if (isHas) {
+        this.$refs.uToast.show({
+          title: '还有图片未完成上传,请稍等!',
+          type: 'warning'
+        });
+      }
+    },
+    /**
+     * 获取收费标准
+     * */
+    getSysterms(termsType) {
+      this.$u.api
+        .getSysterms({
+          termsType: Number(termsType)
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.refundTipsContent = res.data?.content;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '系统错误!',
+            type: 'error'
+          });
+        });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './applyRefund.scss';
+</style>

+ 69 - 0
pages/applyRefundDetails/applyRefundAchieveDetails.vue

@@ -0,0 +1,69 @@
+<template>
+  <!-- 订单详情  状态支付退款成功 -->
+  <view class="order-details">
+    <view class="order-details-content">
+      <view class="order-details-content-header">
+        <image src="../../static/img/refund-success.png"></image>
+        <view>+{{ details.refundAmount }}</view>
+      </view>
+      <view class="order-details-content-item">
+        <view>当前状态</view>
+        <view>已全额退款</view>
+      </view>
+      <view class="order-details-content-item">
+        <view>退款时间</view>
+        <view>{{ details.auditTime }}</view>
+      </view>
+      <view class="order-details-content-item">
+        <view>退款方式</view>
+        <view>退回原支付账户</view>
+      </view>
+      <view class="order-details-content-item">
+        <view>退款单号</view>
+        <view>{{ details.refundNo }}</view>
+      </view>
+    </view>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      details: {}
+    };
+  },
+  onLoad(page) {
+    this.getOrderRefundDetails(page.orderId);
+  },
+  methods: {
+    getOrderRefundDetails(orderId) {
+      this.$u.api
+        .getOrderRefundDetails({
+          orderId: orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.details = res.data;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '操作失败',
+            type: 'error'
+          });
+        });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './applyRefundDetails.scss';
+</style>

+ 84 - 0
pages/applyRefundDetails/applyRefundDetails.scss

@@ -0,0 +1,84 @@
+.refund-details {
+  background-color: #f5f5f5;
+  padding-bottom: 100rpx;
+  min-height: calc(100vh - 44px);
+  .refund-details-list {
+    background-color: #fff;
+    padding: 30rpx 0;
+    .refund-details-list-item {
+      display: flex;
+      padding: 0 17px;
+      line-height: 70rpx;
+      .rdli-label {
+        width: 150rpx;
+        text-align: right;
+      }
+      .rdli-content {
+        width: calc(100% - 150rpx);
+      }
+      .rdli-font {
+        color: #fa6400;
+      }
+      .image {
+        width: 100%;
+        margin-top: 20rpx;
+        image {
+          width: 100%;
+        }
+      }
+    }
+  }
+  .apply-button {
+    padding: 0 50rpx;
+    margin-top: 50rpx;
+  }
+  .refund-details-status {
+    background-color: #fff;
+    padding: 0 17px;
+    margin-top: 50rpx;
+    .refund-details-status-item {
+      display: flex;
+      line-height: 70rpx;
+      view {
+        &:first-child {
+          width: 150rpx;
+          text-align: right;
+        }
+        &:last-child {
+          width: calc(100% - 150rpx);
+        }
+      }
+    }
+  }
+}
+/* 订单详情  状态支付退款成功 */
+.order-details {
+  padding: 0 20px;
+  .order-details-content {
+    .order-details-content-header {
+      text-align: center;
+      margin-top: 54rpx;
+      font-size: 50rpx;
+      font-weight: 600;
+      image {
+        width: 90rpx;
+        height: 90rpx;
+      }
+    }
+    .order-details-content-item {
+      display: flex;
+      line-height: 70rpx;
+      view {
+        &:first-child {
+          width: 150rpx;
+          color: #2a2a2a;
+        }
+        &:last-child {
+          width: calc(100% - 150rpx);
+          text-align: right;
+          color: #6e6e6e;
+        }
+      }
+    }
+  }
+}

+ 105 - 0
pages/applyRefundDetails/applyRefundDetails.vue

@@ -0,0 +1,105 @@
+<template>
+  <view class="refund-details">
+    <u-navbar
+      v-if="details.refundStatus === 0"
+      :is-back="false"
+      back-text=""
+      title="申请退款"
+      :background="{ backgroundColor: '#008CFF' }"
+      title-color="#fff"
+      back-icon-color="#fff"
+    ></u-navbar>
+    <u-navbar v-else back-text="" title="申请退款" :background="{ backgroundColor: '#008CFF' }" title-color="#fff" back-icon-color="#fff"></u-navbar>
+    <view class="refund-details-list">
+      <view class="refund-details-list-item">
+        <view class="rdli-label">申请时间:</view>
+        <view class="rdli-content">{{ details.applyTime }}</view>
+      </view>
+      <view class="refund-details-list-item">
+        <view class="rdli-label">消费金额:</view>
+        <view class="rdli-content"
+          ><text class="rdli-font">{{ details.refundAmount }}</text
+          >元</view
+        >
+      </view>
+      <view class="refund-details-list-item">
+        <view class="rdli-label">退款原因:</view>
+        <view class="rdli-content">{{ details.refundReason }}</view>
+      </view>
+      <view class="refund-details-list-item" v-if="details.images && details.images.length > 0">
+        <view class="rdli-label">图片:</view>
+        <view class="rdli-content">
+          <u-lazy-load class="image" v-for="(item, index) in details.images" :key="index" :image="item" img-mode="aspectFill"></u-lazy-load>
+        </view>
+      </view>
+    </view>
+    <view class="apply-button" v-if="details.refundStatus === 0">
+      <u-button type="primary" disabled>申请中</u-button>
+    </view>
+    <view class="apply-button" v-if="details.refundStatus === 0">
+      <u-button type="primary" @click="jumpPage('pages/center/order/order')">返回列表页</u-button>
+    </view>
+    <view class="refund-details-status" v-if="details.refundStatus === 2">
+      <view class="refund-details-status-item">
+        <view>处理时间:</view>
+        <view>{{ details.auditTime }}</view>
+      </view>
+      <view class="refund-details-status-item">
+        <view>处理结果:</view>
+        <view v-if="details.refundStatus === 1">已通过</view>
+        <view v-if="details.refundStatus === 2">已驳回</view>
+      </view>
+      <view class="refund-details-status-item">
+        <view>备注:</view>
+        <view>{{ details.refuseReason }}</view>
+      </view>
+    </view>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      details: {}
+    };
+  },
+  onLoad(page) {
+    this.getOrderRefundDetails(page.orderId);
+  },
+  methods: {
+    getOrderRefundDetails(orderId) {
+      this.$u.api
+        .getOrderRefundDetails({
+          orderId: orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.details = res.data;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '操作失败',
+            type: 'error'
+          });
+        });
+    },
+    jumpPage(url) {
+      this.$u.route({
+        url
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './applyRefundDetails.scss';
+</style>

+ 56 - 0
pages/bannerDetails/bannerDetails.vue

@@ -0,0 +1,56 @@
+<template>
+  <!-- 轮播详情 -->
+  <view>
+    <u-parse :html="dom"></u-parse>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      dom: ''
+    };
+  },
+  onLoad(page) {
+    if (page.id) {
+      this.getDetails(page.id);
+    }
+  },
+  methods: {
+    // 获取详情
+    getDetails(id) {
+      this.$u.api
+        .getIndexData()
+        .then((res) => {
+          if (res.code === 200) {
+            const list = res.data?.advs;
+            list.forEach((item) => {
+              if (item.id == id) {
+                this.dom = item.content;
+              }
+            });
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '操作失败!',
+            type: 'error'
+          });
+        });
+    }
+  }
+};
+</script>
+
+<style>
+page {
+  padding: 24rpx;
+}
+</style>

+ 35 - 0
pages/center/coupon/couponRules/couponRules.vue

@@ -0,0 +1,35 @@
+<template>
+  <view class="content ql-editor">
+		<u-parse :html="details.content"></u-parse>
+	</view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+			details: {}
+		};
+  },
+  onLoad(options) {
+    this.getExplain();
+  },
+  methods: {
+    getExplain() {
+      this.$u.api
+        .getSysterms({
+          termsType: 5
+        })
+        .then((res) => {
+					this.details = res.data
+        });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.content {
+	padding: 30rpx;
+}
+</style>

+ 68 - 0
pages/center/coupon/myCoupon/myCoupon.scss

@@ -0,0 +1,68 @@
+page {
+	height: 100%;
+}
+.navbar-font {
+  color: #fff;
+  padding-right: 20rpx;
+}
+.swiper {
+  height: 100%;
+  padding: 0 30rpx;
+  background-color: #f9f9f9;
+}
+.content {
+	height: calc(100% - 74px);
+}
+.search-part {
+  display: flex;
+  padding: 30rpx 0 0;
+  margin-bottom: 30rpx;
+  &-input {
+    background-color: #fff;
+    border-radius: 32rpx;
+    padding-left: 30rpx !important;
+    margin-right: 30rpx;
+  }
+  &-btn {
+    background-color: #ff6d6d;
+  }
+}
+.popup-vehicleNo {
+  padding: 30rpx 0;
+}
+.popup-vehicleNo-title {
+  font-size: 40rpx;
+  text-align: center;
+  padding-top: 20rpx;
+}
+.popup-vehicleNo-center {
+  width: 90%;
+  height: 2rpx;
+  border-top: solid rgb(146, 146, 146) 2rpx;
+  margin: 30rpx auto 20rpx;
+}
+.popup-vehicleNo-content {
+  width: 100%;
+  margin: 0 auto;
+}
+.popup-vehicleNo-select {
+  text-align: center;
+  color: #777777;
+  padding: 20rpx 40rpx;
+  &-empty {
+    text-align: center;
+    font-size: 26rpx;
+  }
+  &-scroll {
+    height: 600rpx;
+  }
+}
+.vehicleNo-btn {
+  display: flex;
+  margin: 40rpx 0;
+}
+.parking-lock-pay-attention {
+  margin: 50rpx;
+  line-height: 48rpx;
+  color: #777777;
+}

+ 337 - 0
pages/center/coupon/myCoupon/myCoupon.vue

@@ -0,0 +1,337 @@
+<template>
+  <view class="content">
+    <z-paging-swiper>
+      <u-navbar
+        slot="top"
+        title-color="#fff"
+        :custom-back="customBack"
+        :border-bottom="false"
+        back-icon-color="#CCE8FF"
+        :background="{ background: '#008CFF' }"
+        title="我的优惠券"
+      >
+        <view class="navbar-font" slot="right" @click="jumpPage('/pages/center/coupon/couponRules/couponRules')"> 规则 </view>
+      </u-navbar>
+      <z-tabs ref="tabs" slot="top" :list="tabList" :current="current" barWidth="90rpx" @change="tabsChange"> </z-tabs>
+      <swiper class="swiper" :current="current" @transition="swiperTransition" @animationfinish="swiperAnimationfinish">
+        <swiper-item class="swiper-item" v-for="(item, index) in tabList" :key="index">
+          <!-- <view class="search-part" v-if="current === 0">
+            <u-input class="search-part-input" v-model="form.exchangeCode" placeholder="请输入兑换码" />
+            <u-button class="search-part-btn" type="primary" shape="circle" size="medium" @click.stop="handleExchange">兑换</u-button>
+          </view> -->
+          <coupon-swiper-list-item :tabIndex="index" :currentIndex="current" ref="swiperListItem" />
+        </swiper-item>
+      </swiper>
+      <!-- 绑定车牌 -->
+      <u-popup v-model="bindVehiclePop.showChangeVehicleNo" :mask-close-able="false" mode="center" border-radius="20" width="700rpx">
+        <view class="popup-vehicleNo">
+          <view class="popup-vehicleNo-title">绑定车牌</view>
+          <view class="popup-vehicleNo-center"></view>
+          <view class="popup-vehicleNo-content">
+            <view class="new-plate-number">
+              <view class="message-input-wrap" @click="messageInputClick">
+                <u-message-input :maxlength="8" width="60" font-size="40" :disabled-keyboard="true" v-model="form.vehicleNo" />
+              </view>
+            </view>
+          </view>
+          <view class="popup-vehicleNo-select">
+            <u-collapse ref="refValue" :head-style="{ fontSize: '28rpx' }">
+              <u-collapse-item title="点击选择车牌" align="center">
+                <scroll-view class="popup-vehicleNo-select-scroll" scroll-y="true">
+                  <u-cell-group v-if="bindVehiclePop.vehicleList.length">
+                    <u-cell-item :title="item.value" v-for="(item, index) in bindVehiclePop.vehicleList" :key="index" :arrow="false">
+                      <u-radio-group v-model="form.vehicleNo" @change="radioGroupChange">
+                        <u-radio :name="item.value" :key="index"></u-radio>
+                      </u-radio-group>
+                    </u-cell-item>
+                  </u-cell-group>
+                  <template v-else>
+                    <view class="popup-vehicleNo-select-empty">暂无绑定车牌</view>
+                  </template>
+                </scroll-view>
+              </u-collapse-item>
+            </u-collapse>
+          </view>
+          <view class="vehicleNo-btn">
+            <u-button type="primary" :disabled="!form.vehicleNo" :loading="bindVehiclePop.loading" @click="handleBindVehicle">确认</u-button>
+            <u-button type="primary" plain @click="cencelBindVehicle">取消</u-button>
+          </view>
+        </view>
+      </u-popup>
+      <!-- 选择颜色 -->
+      <u-action-sheet :list="bindVehiclePop.colorList" @click="confirmColor" v-model="bindVehiclePop.colorShow" />
+      <!-- 车牌号键盘 -->
+      <u-keyboard
+        ref="uKeyboard"
+        mode="car"
+        @change="keyboardChange"
+        @confirm="keyboardConfirm"
+        @backspace="backspace"
+        v-model="bindVehiclePop.keyboardshow"
+      />
+    </z-paging-swiper>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      tabList: [
+        {
+          name: '未使用',
+          value: 0,
+          list: []
+        },
+        {
+          name: '已使用',
+          value: 1,
+          list: []
+        },
+        {
+          name: '已失效',
+          value: 2,
+          list: []
+        }
+      ],
+      current: 0,
+      form: {
+        exchangeCode: '',
+        source: 1,
+        vehicleNo: '',
+        merchantCode: '',
+        qrcodeNo: '',
+        couponId: ''
+      },
+      // 绑定车牌
+      bindVehiclePop: {
+        show: false,
+        vehicleList: [],
+        showChangeVehicleNo: false,
+        colorShow: false,
+        loading: false,
+        colorList: [
+          {
+            text: '蓝色',
+            colorCode: 0
+          },
+          {
+            text: '黄色',
+            colorCode: 1
+          },
+          {
+            text: '黑色',
+            colorCode: 2
+          },
+          {
+            text: '白色',
+            colorCode: 3
+          },
+          {
+            text: '绿色',
+            colorCode: 4
+          },
+          {
+            text: '其他',
+            colorCode: 99
+          }
+        ],
+        keyboardshow: false
+      }
+    };
+  },
+  onLoad(options) {
+    const { merchantCode, qrcodeNo, couponId } = options;
+    if (merchantCode && qrcodeNo && couponId) {
+      this.form.merchantCode = merchantCode;
+      this.form.couponId = couponId;
+      this.form.qrcodeNo = qrcodeNo;
+      this.bindVehiclePop.showChangeVehicleNo = true;
+      this.getCarsList();
+    }
+  },
+  methods: {
+    // tabs通知swiper切换
+    tabsChange(index) {
+      this.current = index;
+    },
+    // swiper滑动中
+    swiperTransition(e) {
+      this.$refs.tabs.setDx(e.detail.dx);
+    },
+    //swiper滑动结束
+    swiperAnimationfinish(e) {
+      this.current = e.detail.current;
+      this.$refs.tabs.unlockDx();
+    },
+    /**
+     * 兑换
+     * @date 2022-12-23
+     * @returns {any}
+     */
+    handleExchange() {
+      if (this.form.exchangeCode) {
+        this.bindVehiclePop.showChangeVehicleNo = true;
+        this.getCarsList();
+      } else {
+        this.$refs.uToast.show({
+          title: '请输入兑换码',
+          type: 'warning'
+        });
+      }
+    },
+    /**
+     * @description: 获取我的车辆列表
+     * @return {*}
+     */
+    async getCarsList() {
+      const { data } = await this.$u.api.getMycars({ pageNum: 1, pageSize: 100 });
+      const vehicleList = [];
+      data.rows.forEach((item) => {
+        const { vehicleNo } = item;
+        vehicleList.push({ label: vehicleNo, value: vehicleNo });
+      });
+      this.bindVehiclePop.vehicleList = vehicleList;
+      await this.$nextTick();
+      this.$refs.refValue.init();
+    },
+    /**
+     * 兑换优惠券
+     * @date 2022-12-23
+     * @returns {any}
+     */
+    async exchangeCoupon() {
+      const { vehicleNo } = this.form;
+      if (this.$u.test.carNo(vehicleNo)) {
+        try {
+          this.bindVehiclePop.loading = true;
+          const { code } = await this.$u.api.exchangeCouponApi({ ...this.form });
+          if (code === 200) {
+            this.$refs.uToast.show({
+              title: '兑换成功!',
+              type: 'success'
+            });
+            this.$refs['swiperListItem'][this.current].reloadData();
+            setTimeout(() => {
+              location.href = location.origin + location.pathname;
+            }, 500);
+          }
+          this.bindVehiclePop.loading = false;
+        } catch (error) {
+          this.bindVehiclePop.loading = false;
+        }
+      } else {
+        this.$refs.uToast.show({
+          title: '请输入有效的车牌号!',
+          type: 'error'
+        });
+      }
+    },
+    /**
+     * 点击输入框弹出车牌键盘
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    messageInputClick() {
+      this.bindVehiclePop.keyboardshow = true;
+      this.form.vehicleNo = '';
+    },
+    /**
+     * 颜色下拉确认
+     * @date 2023-02-22
+     * @param {any} e
+     * @returns {any}
+     */
+    confirmColor(e) {
+      this.bindVehiclePop.colorShow = false;
+    },
+    /**
+     * 按键被点击(点击退格键不会触发此事件)
+     * @date 2023-02-22
+     * @param {any} val
+     * @returns {any}
+     */
+    keyboardChange(val) {
+      // 将每次按键的值拼接到value变量中,注意+=写法
+      this.form.vehicleNo += val;
+    },
+    /**
+     * 退格键被点击
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    backspace() {
+      // 删除value的最后一个字符
+      if (this.form.vehicleNo.length) this.form.vehicleNo = this.form.vehicleNo.substr(0, this.form.vehicleNo.length - 1);
+    },
+    /**
+     * 键盘输入完成后确认
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    keyboardConfirm() {
+      this.bindVehiclePop.colorShow = true;
+    },
+    /**
+     * 单选点击
+     * @date 2023-02-22
+     * @param {any} e
+     * @returns {any}
+     */
+    radioGroupChange(e) {
+      this.form.vehicleNo = e;
+    },
+    /**
+     * 关闭绑定弹框
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    cencelBindVehicle() {
+      this.form.vehicleNo = '';
+      this.bindVehiclePop.showChangeVehicleNo = false;
+    },
+    /**
+     * 提交绑定
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    handleBindVehicle() {
+      if (this.form.vehicleNo) {
+        this.exchangeCoupon();
+      } else {
+        this.$refs.uToast.show({
+          title: '请输入或选择车牌号!',
+          type: 'warning'
+        });
+      }
+    },
+    /**
+     * 调整页面
+     * @date 2023-02-22
+     * @param {any} url
+     * @returns {any}
+     */
+    jumpPage(url) {
+      this.$u.route({
+        url
+      });
+    },
+    /**
+     * tabbar 返回
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    customBack() {
+      this.$u.route({
+        type: 'switchTab',
+        url: 'pages/center/index'
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './myCoupon.scss';
+</style>

+ 258 - 0
pages/center/index.vue

@@ -0,0 +1,258 @@
+<template>
+  <view>
+    <!-- ===================================== tabbar ===================================== -->
+    <u-navbar
+      title-color="#fff"
+      :custom-back="customBack"
+      :border-bottom="false"
+      back-icon-color="#CCE8FF"
+      :background="{ background: '#008CFF' }"
+      title="我的"
+    />
+
+    <!-- ===================================== 头像 ===================================== -->
+    <view class="u-flex user-box u-p-l-30 u-p-r-20 u-p-b-30 u-p-t-30">
+      <view class="u-m-r-24" @click="clickHead">
+        <u-avatar :src="userInfo.headImgUrl || userInfo.avatar || pic" size="140"></u-avatar>
+      </view>
+      <view class="u-flex-1">
+        <view class="u-font-18 u-p-b-20">{{ userInfo.nickname || userInfo.mobile }}</view>
+        <view class="u-font-14">手机号:{{ userInfo.mobile || '暂无' }}</view>
+      </view>
+    </view>
+
+    <view class="u-m-t-20">
+      <u-cell-group>
+        <u-cell-item title="我的车辆" @click="openPage('pages/myCars/myCars', true)">
+          <u-icon slot="icon" custom-prefix="custom-icon" size="35" name="wodecheliang"></u-icon>
+        </u-cell-item>
+        <u-cell-item title="停车记录" @click="openPage('pages/center/order/order')">
+          <u-icon slot="icon" custom-prefix="custom-icon" size="35" name="tingchejilu"></u-icon>
+        </u-cell-item>
+      </u-cell-group>
+    </view>
+
+    <view class="u-m-t-20">
+      <u-cell-group>
+        <u-cell-item title="包月" @click="openPage('pages/center/monthly/monthly')">
+          <u-icon slot="icon" custom-prefix="custom-icon" size="35" name="baoyue"></u-icon>
+        </u-cell-item>
+      </u-cell-group>
+    </view>
+    <view class="u-m-t-20">
+      <u-cell-group>
+        <u-cell-item title="消息中心" @click="openPage('pages/message/message', true)">
+          <u-icon slot="icon" custom-prefix="custom-icon" size="35" name="xiaoxi"></u-icon>
+          <u-badge type="success" :count="messageNum" :offset="[38, 80]"></u-badge>
+        </u-cell-item>
+      </u-cell-group>
+    </view>
+    <view class="u-m-t-20 u-m-b-40">
+      <u-cell-group>
+        <u-cell-item title="拨打客服电话" @click="callPhoneShow = true">
+          <u-icon slot="icon" custom-prefix="custom-icon" size="35" name="dianhua"></u-icon>
+        </u-cell-item>
+      </u-cell-group>
+    </view>
+    <u-select v-model="callPhoneShow" :list="callPhoneList" @confirm="phoneCall"></u-select>
+    <template v-if="projectFlag !== 'zhenning'">
+      <view class="u-m-t-20">
+        <u-cell-group>
+          <u-cell-item icon="coupon" title="我的优惠券" @click="openPage('/pages/center/coupon/myCoupon/myCoupon')"></u-cell-item>
+        </u-cell-group>
+      </view>
+    </template>
+    <!-- ===================================== 登出提示 ===================================== -->
+    <u-modal
+      v-model="logoutPop"
+      :title-style="{ color: '#404040' }"
+      title="登出提示"
+      :show-confirm-button="true"
+      confirm-text="确认"
+      :confirm-style="{ backgroundColor: '#3397FA', color: '#fff' }"
+      :show-cancel-button="true"
+      cancel-text="取消"
+      @cancel="logoutPop = false"
+      :cancel-style="{ backgroundColor: '#EBF1FF', color: '#3397FA' }"
+      @confirm="loginOut"
+    >
+      <view class="slot-content">
+        <view class="pay-tips">你确认退出登录吗?</view>
+      </view>
+    </u-modal>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      // 默认头像
+      pic: '/static/img/default-avatar.png',
+      // 用户信息
+      userInfo: {},
+      logoutPop: false,
+      messageNum: 0,
+      callPhoneShow: false,
+      callPhoneList: []
+    };
+  },
+  onLoad() {},
+  onShow() {
+    this.getMsgNum();
+    this.getDict();
+    if (this.vuex_hasLogin) {
+      this.userInfo = this.vuex_user;
+      if (this.vuex_wxinfo) {
+        this.userInfo = Object.assign(this.userInfo, this.vuex_wxinfo);
+      }
+    } else {
+      this.userInfo = {};
+    }
+  },
+  methods: {
+    /**
+     * 获取客服电话字典
+     */
+    getDict() {
+      this.$u.api
+        .getDictApi({
+          type: 'customer_service_phone'
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.callPhoneList = res.data.map((item) => {
+              return {
+                value: item.dictValue,
+                label: item.dictLabel
+              };
+            });
+          }
+        });
+    },
+    /**
+     * 打开新页面
+     * @param {String} path 跳转路径
+     * @param {flag} flag 返回存储标识
+     * */
+    openPage(path, flag) {
+      this.$u.route({
+        url: path
+      });
+      if (flag) {
+        uni.setStorage({
+          key: 'messageBack',
+          data: 'pages/center/index'
+        });
+      }
+    },
+    // 获取消息未读条数
+    getMsgNum() {
+      this.$u.api.getIndexData().then((res) => {
+        if (res.code === 200) {
+          let num = 0;
+          if (res.data.news) {
+            res.data.news.forEach((item) => {
+              if (item.readFlag == 0) {
+                num += 1;
+              }
+            });
+          }
+          this.messageNum = num;
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg,
+            type: 'error'
+          });
+        }
+      });
+    },
+    // tabbar 返回
+    customBack() {
+      this.$u.route({
+        type: 'switchTab',
+        url: 'pages/index/index'
+      });
+    },
+    // 拨打电话
+    phoneCall(phone) {
+      uni.makePhoneCall({
+        phoneNumber: phone[0].value || '0851-38222696'
+      });
+    },
+    // 登出
+    loginOut() {
+      this.$u.api.codeV2Api.logoutApi().then((res) => {
+        if (res.code === 200) {
+          this.$u.vuex('vuex_hasLogin', false);
+          this.$u.vuex('vuex_token', '');
+          this.$u.vuex('vuex_user', null);
+          uni.removeStorage({
+            key: 'jumpUrl'
+          });
+          uni.removeStorage({
+            key: 'backUrl'
+          });
+          setTimeout(() => {
+            this.logoutPop = false;
+            uni.navigateTo({
+              url: '/pages/center/phoneLogin/phoneLogin'
+            });
+          }, 500);
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg || '登出失败',
+            type: 'error'
+          });
+        }
+      });
+    },
+    // 点击头像
+    clickHead() {
+      if (this.$store.state.vuex_hasLogin) {
+        this.logoutPop = true;
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+page {
+  background-color: $my-page-bg-color;
+}
+
+.user-box {
+  position: relative;
+  background-color: $my-main-color;
+  color: #fff;
+
+  &:after {
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    content: '';
+    background: url('/static/img/center-top-bg.png') no-repeat;
+    background-position: -90rpx 0;
+    width: 305rpx;
+    height: 145rpx;
+    z-index: 999;
+  }
+}
+
+.u-avatar {
+  border: 10rpx solid #4caeff;
+}
+
+.u-cell-box /deep/ .u-cell__left-icon-wrap,
+.u-cell-box /deep/ .custom-icon {
+  color: $my-main-color;
+  margin-right: 10rpx;
+}
+
+.pay-tips {
+  text-align: center;
+  margin: 30rpx 0;
+}
+</style>

+ 68 - 0
pages/center/invoice/invoice.scss

@@ -0,0 +1,68 @@
+.swiper-wrap{
+	display: flex;
+	flex-direction: column;
+	height: calc(100vh - var(--window-top));
+	width: 100%;
+	.swiper-box {
+		flex: 1;
+	}
+}
+.page-box{
+	margin: 25rpx 40rpx;
+	.order{
+		overflow: hidden;
+		margin-bottom: 20rpx;
+		background-color: #fff;
+		border-radius: 15rpx;
+		.order-top{
+			margin-bottom: 31rpx;
+			padding: 25rpx 40rpx;
+			border-bottom: 1px solid #DFDFDF;
+			.car{
+				font-size: 32rpx;
+				font-weight: 600;
+				color: #3A3A3A;
+				line-height: 45rpx;
+				letter-spacing: 1px;
+				.invoice-type{
+					margin-left: 20rpx;
+					padding: 0 8rpx;
+					font-size: 18rpx;
+					font-weight: 400;
+					color: #787878;
+					line-height: 25rpx;
+					border: 1px solid #979797;
+					border-radius: 4px;
+				}
+			}
+			.addr{
+				color: #858585;
+				font-size: 26rpx;
+				line-height: 37rpx;
+			}
+			.order-top-right{
+				padding: 0 15rpx;
+				height: 50rpx;
+				line-height: 48rpx;
+				border-radius: 5rpx;
+				border: 1px solid #FA6400;
+				color: #FA6400;
+			}
+		}
+		.order-center{
+			padding: 0 40rpx 25rpx;
+			border-bottom: 1px solid #DFDFDF;
+			.order-center-item{
+				margin-bottom: 9rpx;
+				font-size: 26rpx;
+				font-weight: 400;
+				color: #595959;
+				line-height: 37rpx;
+				letter-spacing: 1px;
+				.pay-amount{
+					color: #FA6400;
+				}
+			}
+		}
+	}
+}

+ 173 - 0
pages/center/invoice/invoice.vue

@@ -0,0 +1,173 @@
+<template>
+	<view>
+		<view class="swiper-wrap">
+			<view class="u-tabs-box">
+				<u-tabs-swiper activeColor="#008CFF" ref="tabs" :list="list" :current="current" @change="change" :is-scroll="false" swiperWidth="100%"></u-tabs-swiper>
+			</view>
+			<swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
+				<swiper-item class="swiper-item" v-for="(item, index) in list" :key="index">
+					<scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom">
+						<view class="page-box">
+							<view class="order" @click="goDetails(orderItem.id)" v-for="(orderItem, index) in  orderList[index]" :key="orderItem.id">
+								<view class="order-top u-flex">
+									<view class="order-top-left u-flex-1">
+										<view class="car">{{orderItem.vehicleNo}}<span class="invoice-type">电子发票</span></view>
+										<view class="addr">{{orderItem.roadName}}</view>
+									</view>
+									<view class="order-top-right">{{orderItem.orderStatus | verifyStatusFilter}}</view>
+								</view>
+								<view class="order-center">
+									<view class="order-center-item">订单编号:{{orderItem.orderId}}</view>
+									<view class="order-center-item">入场时间:{{orderItem.inTime}}</view>
+									<view class="order-center-item">出场时间:{{orderItem.outTime}}</view>
+									<view class="order-center-item">停留时间:{{orderItem.duration}}</view>
+									<view class="order-center-item">应付金额:<span class="pay-amount">{{orderItem.payAmount}}</span></view>
+								</view>
+								<view class="order-bottom">
+									<u-cell-item v-if="orderItem.payStatus==1" value="我要开票" :value-style="{textAlign: 'center',fontSize: '30rpx',color: '#008CFF'}" :arrow="false"></u-cell-item>
+									<u-cell-item v-if="orderItem.payStatus==3" value="重发发票" :value-style="{textAlign: 'center',fontSize: '30rpx',color: '#949494'}" :arrow="false"></u-cell-item>
+								</view>
+							</view>
+							<u-loadmore :status="loadStatus[index]" bgColor="#F6F6FF"></u-loadmore>
+						</view>
+					</scroll-view>
+				</swiper-item>
+			</swiper>
+		</view>
+		
+		<u-toast ref="uToast" />
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			orderList: [[], [], [], []],
+			list: [
+				{index:0,name: '全部',orderStatu:null,pageNum:1,total:null},
+				{index:1,name: '已开票',orderStatu:1,pageNum:1,total:null},
+				{index:2,name: '未开票',orderStatu:2,pageNum:1,total:null},
+			],
+			current: 0,
+			swiperCurrent: 0,
+			tabsHeight: 0,
+			dx: 0,
+			loadStatus: ['loadmore','loadmore','loadmore','loadmore'],
+		};
+	},
+	onLoad() {
+		this.getOrderList(this.list[0]);
+		// this.getOrderList(this.list[1]);
+		// this.getOrderList(this.list[2]);
+		// this.getOrderList(this.list[3]);
+	},
+	computed: {
+		// 价格小数
+		priceDecimal() {
+			return val => {
+				if (val !== parseInt(val)) return val.slice(-2);
+				else return '00';
+			};
+		},
+		// 价格整数
+		priceInt() {
+			return val => {
+				if (val !== parseInt(val)) return val.split('.')[0];
+				else return val;
+			};
+		}
+	},
+	methods: {
+		reachBottom() {
+			// console.log('this.list[this.current]',this.list[this.current]);
+			if(this.orderList[this.current].length>=this.list[this.current].total){
+				this.loadStatus.splice(this.list[this.current].index,1,"nomore");
+				return;
+			};
+			this.loadStatus.splice(this.list[this.current].index,1,"loading");
+			this.getOrderList(this.list[this.current]);
+		},
+		// 页面数据
+		
+		getOrderList(orderType) {			
+			let param = {
+				pageNum:orderType.pageNum,
+				orderStatus:orderType.orderStatu,
+			};
+			// 未出场: orderStatu = 1-停放中
+			// 缴费中: orderStatu = 2-出场中  && payStatus = 2-支付中 
+			// 完成:   orderStatu = 4-完成
+			this.$u.api.getOrderList(param)
+			.then(res=>{
+				for(let item of res.data.pageInfo.rows){
+					this.orderList[orderType.index].push(item);
+				}
+				console.log('this.list[orderType.index]',this.list[orderType.index]);
+				this.list[this.current].total = res.data.pageInfo.total;
+				this.list[orderType.index].pageNum++;
+				if(this.orderList[this.current].length>=this.list[this.current].total){
+					this.loadStatus.splice(this.list[orderType.index].index,1,"nomore");
+				};
+				console.log(JSON.parse(JSON.stringify(this.orderList[this.swiperCurrent])));
+				console.log('this.list[this.current]',this.list[this.current]);
+			}).catch(err=>{
+				this.$refs.uToast.show({
+					title: err.msg,
+					type: 'error',
+				});
+				console.log('getOrderList ',err)
+			});
+			
+			this.loadStatus.splice(this.current,1,"loadmore")
+		},
+		// tab栏切换
+		change(index) {
+			// this.swiperCurrent = this.list[index].orderStatu;
+			this.swiperCurrent = index;
+			this.getOrderList(this.list[index]);
+		},
+		transition({ detail: { dx } }) {
+			this.$refs.tabs.setDx(dx);
+		},
+		animationfinish({ detail: { current } }) {
+			this.$refs.tabs.setFinishCurrent(current);
+			this.swiperCurrent = current;
+			this.current = current;
+		},
+		goDetails(id){
+			this.$u.route({
+				url: 'pages/center/invoice/makeinvoice/makeinvoice',
+				params: {
+					invoice: id
+				}
+			});
+		}
+	},
+	filters:{
+		verifyStatusFilter(value) {
+			if (value === 0) {
+			  return '';
+			} else if(value === 1){
+				return '已开票';				
+			} else if(value === 2){
+				return '未开票';				
+			} else {
+			  return '';
+			}
+		},
+	}
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+	height: 100%;
+	background-color: #F6F6FF;
+}
+/* #endif */
+</style>
+<style lang="scss" scoped>
+	@import "./invoice.scss";
+</style>

+ 0 - 0
pages/center/invoice/invoiceDetails/invoiceDetails.scss


+ 25 - 0
pages/center/invoice/invoiceDetails/invoiceDetails.vue

@@ -0,0 +1,25 @@
+<template>
+	<view>
+		
+	</view>
+</template>
+
+<script>
+	export default{
+		data(){
+			return{
+				
+			}
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "./invoiceDetails.scss";
+</style>

+ 15 - 0
pages/center/invoice/makeinvoice/makeinvoice.scss

@@ -0,0 +1,15 @@
+page{
+	background-color: #F6F6FF;
+}
+.title{
+	padding: 25rpx 40rpx 18rpx;
+	font-size: 28rpx;
+	font-weight: 400;
+	color: #999999;
+	line-height: 40rpx;
+	letter-spacing: 1px;
+}
+.form{
+	padding: 28rpx 40rpx 50rpx;
+	background-color: #fff;
+}

+ 72 - 0
pages/center/invoice/makeinvoice/makeinvoice.vue

@@ -0,0 +1,72 @@
+<template>
+	<view>
+		<view class="title">发票详情</view>		
+		<u-form class="form" :model="form" ref="uForm">
+			<u-form-item label="公司名称" label-width="160rpx" prop="name">
+				<u-radio-group v-model="radio" @change="radioGroupChange" :width="radioCheckWidth" :wrap="radioCheckWrap">
+					<u-radio shape="circle" v-for="(item, index) in radioList" :key="index" :name="item.name">{{ item.name }}</u-radio>
+				</u-radio-group>
+			</u-form-item>
+			<u-form-item label="公司名称" label-width="160rpx" prop="name">
+				<u-input v-model="form.name" placeholder="请输入公司名称" />
+			</u-form-item>
+			<u-form-item label="公司税号" label-width="160rpx">
+				<u-input v-model="form.name" placeholder="选填" />
+			</u-form-item>
+			<u-form-item label="注册地址" label-width="160rpx">
+				<u-input v-model="form.name" placeholder="选填" />
+			</u-form-item>
+			<u-form-item label="注册电话" label-width="160rpx">
+				<u-input v-model="form.name" placeholder="选填" />
+			</u-form-item>
+			<u-form-item label="开户银行" label-width="160rpx">
+				<u-input v-model="form.name" placeholder="选填" />
+			</u-form-item>
+			<u-form-item label="银行账号" label-width="160rpx">
+				<u-input v-model="form.name" placeholder="选填" />
+			</u-form-item>
+		</u-form>
+		<u-button @click="submit">提交</u-button>
+	</view>
+</template>
+
+<script>
+	export default{
+		data(){
+			return{
+				form:{
+					name:'',
+					invoiceType:'',
+					payType:null,
+				},
+				radioList: [
+					{
+						name: '支付宝',
+						checked: true,
+						disabled: false
+					},
+					{
+						name: '微信',
+						checked: false,
+						disabled: false
+					}
+				],
+				
+			}
+		},
+		onLoad(page){
+			console.log('page',page)
+		},
+		methods:{
+			// radio选择发生变化
+			radioGroupChange(e) {
+				this.form.payType = e;
+			},
+			
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "./makeinvoice.scss";
+</style>

+ 103 - 0
pages/center/monthly/monthly.scss

@@ -0,0 +1,103 @@
+page {
+	background-color: #F6F6FF
+}
+.monthly {
+	height: calc(100vh - 88rpx);
+	overflow-y: scroll;
+	&-tab {
+		width: 100%;
+		background-color: #fff;
+	}
+	.monthly-list {
+		padding: 37rpx 40rpx;
+		.monthly-list-item {
+			overflow: hidden;
+			width: 100%;
+			background-color: #fff;
+			border-radius: 15rpx;
+			margin-bottom: 20rpx;
+			.monthly-list-item-top {
+				display: flex;
+				justify-content: space-between;
+				padding: 26rpx 39rpx;
+				border-bottom: solid 1px #DFDFDF;
+				.mlit-left {
+					view {
+						&:first-child {
+							font-size: 32rpx;
+							color: #3A3A3A;
+							font-family: PingFangSC-Semibold, PingFang SC;
+							font-weight: 600;
+							line-height: 45rpx;
+						}
+						&:last-child {
+							color: #787878;
+							font-size: 26rpx;
+							font-family: PingFangSC-Regular, PingFang SC;
+							font-weight: 400;
+							line-height: 37rpx;
+						}
+					}
+				}
+				.mlit-right {
+					line-height: 50rpx;
+					text-align: center;
+					border-radius: 5rpx;
+					color: #858585;
+					font-size: 24rpx;
+					.mlit-right-item{
+						padding: 0 15rpx;
+						border: solid 1px #BDBDBD;
+					}
+					.mlit-right-item.fee-status{color: #FA6400;border-color: #FA6400;}
+					.mlit-right-item + .mlit-right-item{margin-left: 10rpx;}
+				}
+			}
+			.monthly-list-item-bottom {
+				padding: 31rpx 39rpx;
+				.mlib-item {
+					display: flex;
+					flex-direction: row;
+					color: #595959;
+					font-family: PingFangSC-Regular, PingFang SC;
+					font-size: 26rpx;
+					line-height: 40rpx;
+					view {
+						&:first-child {
+							width: 20%;
+							text-align: justify;
+							text-align-last: justify;
+							margin-right: 5rpx;
+						}
+						&:last-child {
+							margin-left: 10rpx;
+						}
+					}
+					&:last-child {
+						view {
+							&:last-child {
+								color: #FA6400;
+							}
+						}
+					}
+				}
+			}
+			.button-wrap{
+				border-top: 1px solid #DFDFDF;
+				// padding: 26rpx 39rpx;
+				.tool-btn{
+					padding: 26rpx 39rpx;
+					flex: 1;
+					text-align: center;
+					&-cancel{
+						// background-color: red;
+					}
+				}
+				.pay-btn {
+					background-color: #2b85e4;
+					color: #fff;
+				}
+			}
+		}
+	}
+}

+ 217 - 0
pages/center/monthly/monthly.vue

@@ -0,0 +1,217 @@
+<template>
+  <!-- 包月 -->
+  <view class="monthly">
+    <z-paging class="paging" ref="paging" v-model="dataList" @query="queryList">
+      <!-- 选项卡 -->
+      <template v-if="projectFlag !== 'zhenning'">
+        <view class="monthly-tab" slot="top">
+          <u-tabs
+            :list="tabList"
+            :is-scroll="false"
+            :current="current"
+            @change="tabChange"
+            bg-color="#fff"
+            inactive-color="#000000"
+            active-color="#008CFF"
+            :bold="false"
+            :active-item-style="{ color: '#008CFF' }"
+          />
+        </view>
+      </template>
+      <view class="monthly-list">
+        <view class="monthly-list-item" v-for="(monthlyItem, index) in dataList" :key="index">
+          <view class="monthly-list-item-top">
+            <view class="mlit-left">
+              <view>{{ monthlyItem.vehicleNo }}</view>
+              <view>{{ monthlyItem.roadName || monthlyItem.parkName }}</view>
+            </view>
+            <view class="mlit-right u-flex">
+              <view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 0">未缴费</view>
+              <view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 1">已缴费</view>
+              <view class="mlit-right-item" v-if="monthlyItem.energyType === 1">汽油车</view>
+              <view class="mlit-right-item" v-if="monthlyItem.energyType === 2">新能源</view>
+            </view>
+          </view>
+          <view class="monthly-list-item-bottom">
+            <view class="mlib-item">
+              <view>有效期限</view>:
+              <view> {{ monthlyItem.beginTime.split('-').join('.') }}-{{ monthlyItem.endTime.split('-').join('.') }} </view>
+            </view>
+            <view class="mlib-item">
+              <view>剩余天数</view>:
+              <view>{{ monthlyItem.surplusDays }}天</view>
+            </view>
+          </view>
+          <view v-if="monthlyItem.feeStatus == '0'" class="button-wrap u-flex u-row-right">
+            <view
+              class="tool-btn"
+              :class="{ 'tool-btn-cancel': monthlyItem.feeStatus == '0' }"
+              v-if="monthlyItem.feeStatus == '0'"
+              @click="cancelMonth(monthlyItem.monthId)"
+              >取消订单</view
+            >
+            <view class="tool-btn pay-btn" v-if="monthlyItem.feeStatus == '0'" @click="goMonthPay(monthlyItem)">重新支付</view>
+          </view>
+          <view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays > 2" class="button-wrap u-flex u-row-right">
+            <view class="tool-btn">已缴费</view>
+          </view>
+          <view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays < 3" class="button-wrap u-flex u-row-right">
+            <view class="tool-btn" @click="goRenewal(monthlyItem)">去续费</view>
+          </view>
+        </view>
+      </view>
+    </z-paging>
+    <u-modal ref="uModal" v-model="cancelShow" content="确认取消该订单?" :async-close="true" @confirm="confirm" :show-cancel-button="true"></u-modal>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      tabList: [
+        {
+          name: '路段',
+          value: 'road'
+        },
+        {
+          name: '停车场',
+          value: 'park'
+        }
+      ],
+      current: 0,
+      currentValue: 'road',
+      id: '', // 当前选中的条目id
+      cancelShow: false,
+      dataList: [],
+      pageSize: 10,
+      pageNo: 1
+    };
+  },
+  onLoad(page) {
+    const obj = {
+      road: 0,
+      park: 1
+    };
+    if (page.type) {
+      this.current = obj[page.type];
+    }
+  },
+  onShow() {
+    this.$nextTick(() => {
+      this.$refs.paging.reload();
+    });
+  },
+  onBackPress(options) {
+    this.$u.route({
+      type: 'switchTab',
+      url: 'pages/center/index'
+    });
+    return true;
+  },
+  methods: {
+    //tabs通知swiper切换
+    tabChange(index) {
+      this.current = index;
+      this.currentValue = this.tabList[index].value;
+      this.$refs.paging.reload();
+    },
+    // 下拉刷新操作
+    queryList(pageNo, pageSize) {
+      const tabObj = {
+        road: 'getMonthList',
+        park: 'getParkMonthList'
+      };
+      this.$u.api[tabObj[this.currentValue]]({
+        pageSize: pageSize,
+        pageNum: pageNo,
+        ifPark: this.current
+      }).then((res) => {
+        if (res.code === 200) {
+          this.pageNo = pageNo;
+          this.pageSize = pageSize;
+          this.$refs.paging.complete(res.data.rows);
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg,
+            type: 'error'
+          });
+        }
+      });
+    },
+    // 取消订单
+    cancelMonth(monthId) {
+      this.id = monthId;
+      this.cancelShow = true;
+    },
+    // 重新支付
+    goMonthPay(item) {
+      const params = {
+        vehicleNo: item.vehicleNo,
+        monthId: item.monthId
+      };
+      if (this.current === 0) {
+        params.roadNo = item.roadNo;
+      } else {
+        params.parkNo = item.parkNo;
+      }
+      this.$u.route({
+        url: 'pages/handleMonthly/handleMonthly',
+        params
+      });
+    },
+    // 确认取消订单
+    confirm() {
+      this.$u.api
+        .cancelMonth({
+          monthId: this.id
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'success'
+            });
+            this.queryList(this.pageNo, this.pageSize);
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+          this.$refs['uModal'].clearLoading();
+          this.cancelShow = false;
+        })
+        .catch((err) => {
+          this.$refs['uModal'].clearLoading();
+          this.$refs.uToast.show({
+            title: '操作失败',
+            type: 'error'
+          });
+        });
+    },
+    /**
+     * 去续费
+     * */
+    goRenewal(item) {
+      const params = {
+        vehicleNo: item.vehicleNo
+      };
+      if (this.current === 0) {
+        params.roadNo = item.roadNo;
+      } else {
+        params.parkNo = item.parkNo;
+      }
+      this.$u.route({
+        url: 'pages/handleMonthly/handleMonthly',
+        params
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './monthly.scss';
+</style>

+ 196 - 0
pages/center/monthly/monthly1.vue

@@ -0,0 +1,196 @@
+<template>
+	<!-- 包月 -->
+	<view class="monthly">
+		<!-- <u-navbar
+		 title-color="#fff" 
+		 :custom-back="customBack" 
+		 :border-bottom="false" 
+		 back-icon-color="#CCE8FF" 
+		 :background="{background: '#008CFF' }" title="我的包月"></u-navbar> -->
+		<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
+			<view class="monthly-list">
+				<view class="monthly-list-item" :index="index" v-for="(monthlyItem, index) in  monthlyList" :key="index">
+					<view class="monthly-list-item-top">
+						<view class="mlit-left">
+							<view>{{monthlyItem.vehicleNo}}</view>
+							<view>{{monthlyItem.roadName}}</view>
+						</view>
+						<view class="mlit-right u-flex">
+						<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 0">未缴费</view>
+						<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 1">已缴费</view>
+						<view class="mlit-right-item" v-if="monthlyItem.energyType === 1">汽油车</view>
+						<view class="mlit-right-item" v-if="monthlyItem.energyType === 2">新能源</view>
+						</view>
+					</view>
+					<view class="monthly-list-item-bottom" >
+						<view class="mlib-item">
+							<view>有效期限</view>:
+							<view>{{(monthlyItem.beginTime.split('-')).join('.')}}-{{(monthlyItem.endTime.split('-')).join('.')}}</view>
+						</view>
+						<view class="mlib-item">
+							<view>剩余天数</view>:
+							<view>{{monthlyItem.surplusDays}}天</view>
+						</view>
+					</view>
+					<view v-if="monthlyItem.feeStatus=='0'" class="button-wrap u-flex u-row-right">
+						<view class="tool-btn" 
+						:class="{'tool-btn-cancel':monthlyItem.feeStatus=='0'}" 
+						v-if="monthlyItem.feeStatus=='0'" 
+						@click="cancelMonth(monthlyItem.monthId)">取消订单</view>
+					</view>
+					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays > 2" class="button-wrap u-flex u-row-right">
+						<view class="tool-btn">已缴费</view>
+					</view>
+					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays < 3" class="button-wrap u-flex u-row-right">
+						<view class="tool-btn" @click="goRenewal(monthlyItem)">去续费</view>
+					</view>
+				</view>
+			</view>
+		</mescroll-body>
+		<u-modal v-model="canclShow" content="确认取消该订单?" @confirm="confirm" :show-cancel-button="true"></u-modal>
+		<u-toast ref="uToast" />
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 使用mixin
+		data() {
+			return {
+				id:'',
+				canclShow: false,
+				monthlyList: [],
+				monthList:'',
+				beginTime:'',
+				endTime:'',
+				time:[],
+			}
+		},
+		onShow() {
+			// onShow 刷新数据
+			if(this.mescroll){
+				this.mescroll.triggerDownScroll();
+			}
+		},
+		methods: {
+			customBack(){
+				this.$u.route({
+					type:'switchTab',
+					url: 'pages/center/index'
+				});
+			},
+			/*下拉刷新的回调*/
+			downCallback(){
+				// 第2种: 下拉刷新和上拉加载调同样的接口, 则不用第1种, 直接mescroll.resetUpScroll()即可
+				this.mescroll.resetUpScroll(); // 重置列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
+			},
+			/*上拉加载的回调*/
+			upCallback(page) {
+				let pageNum = page.num; // 页码, 默认从1开始
+				let pageSize = page.size; // 页长, 默认每页10条
+				// this.getMessageList()
+				this.$u.api.getMonthList({pageSize:pageSize ,pageNum: pageNum})
+				.then(res=>{
+					if(res.code == 200){
+					console.log('res',res)
+					// 接口返回的当前页数据列表 (数组)
+					let curPageData = res.data.rows;
+					// 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
+					let curPageLen = curPageData.length; 
+					// 接口返回的总页数 (如列表有26个数据,每页10条,共3页; 则totalPage=3)
+					let totalPage = res.data.pages; 
+					// 接口返回的总数据量(如列表有26个数据,每页10条,共3页; 则totalSize=26)
+					let totalSize = res.data.total; 
+					// 接口返回的是否有下一页 (true/false)
+					// let hasNext = Number(res.data.page) < Number(res.data.pages); 
+					
+					//设置列表数据
+					if(page.num == 1) this.monthlyList = []; //如果是第一页需手动置空列表
+					this.monthlyList = this.monthlyList.concat(curPageData); //追加新数据
+					
+					// 请求成功,隐藏加载状态
+					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
+					this.mescroll.endByPage(curPageLen, totalPage); 
+					setTimeout(()=>{
+						this.mescroll.endSuccess(curPageLen)
+					},20)
+					this.monthList=[],
+					res.data.rows.forEach(item => {
+						const obj = {
+							beginTime: item.beginTime,
+							endTime: item.endTime,
+						}
+						this.monthList.push(obj)
+						// console.log(obj)
+					});
+					this.time = this.monthList[0]
+					let Date1 = this.time.beginTime;
+					let Date2 = this.time.endTime;
+					// Date1 = Date1.valueOf() + 24 * 60 * 60 * 1000
+					Date1 = new Date(Date1)
+					const year = Date1.getFullYear()
+					const month = Date1.getMonth()+1
+					const day = Date1.getDate()
+					Date2 = new Date(Date2)
+					const year2 = Date2.getFullYear()
+					const month2 = Date2.getMonth()+1
+					const day2 = Date2.getDate()
+					this.beginTime = year + '.' + month + '.' + day
+					console.log(this.beginTime)
+					this.endTime = year2 + '.' + month2 + '.' + day2
+					}else{
+						this.mescroll.endErr()
+					}
+				}).catch(err=>{
+					// console.log('err',err);
+					// this.$refs.uToast.show({
+					// 	title: err.msg,
+					// 	type: 'error',
+					// });
+				});
+				
+			},
+			cancelMonth(monthId){
+				this.id=monthId;
+				this.canclShow = true;
+				console.log('monthId',monthId)
+			},
+			confirm(){
+				this.$u.api.cancelMonth({monthId: this.id})
+				.then(res=>{
+					if(res.code === 200){
+					this.$refs.uToast.show({ 
+						title: res.msg,
+						type: 'success',
+					});
+					this.downCallback()
+					}else{
+						
+					}
+				}).catch(err=>{
+					this.$refs.uToast.show({
+						title: err.msg,
+						type: 'error',
+					});
+				})
+			},
+			/**
+			 * 去续费
+			 * */
+			goRenewal(item) {
+				this.$u.route({
+					url: 'pages/handleMonthly/handleMonthly',
+					params: {
+						roadNo: item.roadNo,
+						vehicleNo: item.vehicleNo
+					}
+				})
+			 }
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+@import './monthly.scss';
+</style>

+ 90 - 0
pages/center/order/order.scss

@@ -0,0 +1,90 @@
+.swiper-wrap{
+	display: flex;
+	flex-direction: column;
+	height: calc(100vh - var(--window-top));
+	width: 100%;
+	.swiper-box {
+		flex: 1;
+	}
+}
+.page-box{
+	margin: 25rpx 40rpx;
+	.order{
+		overflow: hidden;
+		margin-bottom: 20rpx;
+		background-color: #fff;
+		border-radius: 15rpx;
+		.order-top{
+			margin-bottom: 31rpx;
+			padding: 25rpx 40rpx;
+			border-bottom: 1px solid #DFDFDF;
+			.car{
+				font-size: 32rpx;
+				font-weight: 600;
+				color: #3A3A3A;
+				line-height: 45rpx;
+				letter-spacing: 1px
+			}
+			.addr{
+				color: #858585;
+				font-size: 26rpx;
+				line-height: 37rpx;
+			}
+			.order-top-right{
+				padding: 0 15rpx;
+				height: 50rpx;
+				line-height: 48rpx;
+				border-radius: 5rpx;
+				border: 1px solid #FA6400;
+				color: #FA6400;
+				&-finished{
+					border-color: #BDBDBD;
+					color: #858585;
+				}
+			}
+			.apply-refund {
+				border-color: #BDBDBD;
+				color: #858585;
+				margin-right: 5rpx;
+			}
+		}
+		.order-center{
+			padding: 0 40rpx 25rpx;
+			border-bottom: 1px solid #DFDFDF;
+			.order-center-item{
+				margin-bottom: 9rpx;
+				font-size: 26rpx;
+				font-weight: 400;
+				color: #595959;
+				line-height: 37rpx;
+				letter-spacing: 1px;
+				.pay-amount{
+					color: #FA6400;
+				}
+			}
+		}
+	}
+}
+
+.type-list {
+	height: 236rpx;
+	width: 116rpx;
+	position: fixed;
+	right: 53rpx;
+	bottom: 93rpx;
+	z-index: 100;
+	&-item {
+		width: 116rpx;
+		height: 116rpx;
+		line-height: 116rpx;
+		text-align: center;
+		background: url('../../../static/img/type-not-current.svg') no-repeat center center;
+		background-size: 100% 100%;
+		color: #008cff;
+	}
+	&-item-current {
+		background: url('../../../static/img/type-current.svg') no-repeat center center;
+		background-size: 100% 100%;
+		color: #fff;
+	}
+}

+ 420 - 0
pages/center/order/order.vue

@@ -0,0 +1,420 @@
+<template>
+  <view>
+    <view class="swiper-wrap">
+      <view class="u-tabs-box">
+        <u-tabs-swiper activeColor="#008CFF" ref="tabs" :list="list" :current="current" @change="change" :is-scroll="false" swiperWidth="100%" />
+      </view>
+      <swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
+        <swiper-item class="swiper-item" v-for="(item, index) in list" :key="index">
+          <scroll-view scroll-y style="height: 100%; width: 100%" @scrolltolower="reachBottom">
+            <view class="page-box">
+              <view class="order" @click="goDetails(orderItem)" v-for="(orderItem, index) in orderList[current]" :key="'o-' + index">
+                <view class="order-top u-flex">
+                  <view class="order-top-left u-flex-1">
+                    <view class="car">{{ orderItem.vehicleNo }}</view>
+                    <view class="addr">{{ orderItem.roadName }}</view>
+                  </view>
+                  <!--
+                    显示申请退款按钮满足一下条件:
+                    1.允许退款allowRefund等于1 并且
+                    2.退款状态auditStatus等于2 已驳回 或者
+                    3.退款状态auditStatus不能为空 并且不能等于0
+                  -->
+                  <view
+                    class="order-top-right apply-refund"
+                    v-show="orderItem.allowRefund == 1 && (orderItem.auditStatus == 2 || (!orderItem.auditStatus && orderItem.auditStatus != 0))"
+                    @click.stop="applyRefund(orderItem)"
+                    >申请退款</view
+                  >
+                  <!--
+                    显示申请状态满足以下条件
+                    申请状态存在或者审核状态存在(由于0比较特殊,所以单独拉出来判断)
+                  -->
+                  <view
+                    class="order-top-right apply-refund"
+                    @click.stop="applyRefundDetails(orderItem)"
+                    v-if="orderItem.refundStatus || orderItem.refundStatus == 0 || orderItem.auditStatus || orderItem.auditStatus == 0"
+                    >{{ orderItem | verifyRefundStatus }}</view
+                  >
+                  <view class="order-top-right" v-else :class="{ 'order-top-right-finished': orderItem.orderStatus == '4' }">
+                    {{ orderItem.orderStatus | verifyStatusFilter }}
+                  </view>
+                </view>
+                <!-- 路段显示字段 -->
+                <view class="order-center" v-if="typeCurrent.value === 'road'">
+                  <view class="order-center-item">订单编号:{{ orderItem.orderId }}</view>
+                  <!-- <view class="order-center-item">入场时间:{{ orderItem.inTime }}</view> -->
+                  <view class="order-center-item" v-if="orderItem.deviceType == 1"> 入场时间:{{ orderItem.inTime }}</view>
+                  <view class="order-center-item" v-else>开始计费:{{ orderItem.inTime }}</view>
+                  <template v-if="orderItem.deviceType == 1">
+                    <view class="order-center-item" v-if="orderItem.orderStatus == 1 && orderItem.outTime"> 出场时间:{{ `未出场` }}</view>
+                    <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 出场时间:{{ orderItem.outTime }}</view>
+                  </template>
+                  <template v-else>
+                    <view class="order-center-item" v-if="orderItem.orderStatus == 1 && orderItem.outTime"> 结束计费:{{ `未出场` }}</view>
+                    <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 结束计费:{{ orderItem.outTime }}</view>
+                  </template>
+                  <!-- <view class="order-center-item">
+										停车时长:{{ orderItem.duration || 0 }}</view> -->
+                  <!-- <view class="order-center-item" v-if="orderItem.orderStatus !== 1">
+										免费时长:{{ orderItem.freeDuration || 0 }}</view> -->
+                  <view class="order-center-item" v-if="orderItem.deviceType == 1">
+                    免费时长:{{ orderItem.freeDuration || `0天0时${free_time}分0秒` }}</view
+                  >
+                  <!-- <view class="order-center-item" v-if="orderItem.deviceType == 2">
+										免费时长:0天0时15分0秒</view> -->
+                  <view class="order-center-item" v-if="orderItem.deviceType == 2">
+                    免费时长:{{ orderItem.freeDuration || `0天0时${free_time}分0秒` }}</view
+                  >
+                  <!-- <view class="order-center-item" v-if="orderItem.orderStatus !== 1">
+										计费时长:{{ orderItem.calcDuration || 0 }}</view> -->
+                  <view class="order-center-item"> 计费时长:{{ orderItem.calcDuration || 0 }}</view>
+                  <view class="order-center-item"> 累计停车时长:{{ orderItem.duration || 0 }}</view>
+                  <view class="order-center-item" v-if="orderItem.orderStatus == 1">
+                    预计金额:
+                    <span class="pay-amount">{{ orderItem.payAmount || 0 }}</span>
+                  </view>
+                  <view class="order-center-item" v-else>
+                    应付金额:
+                    <span class="pay-amount">{{ orderItem.payAmount || 0 }}</span>
+                  </view>
+                  <view
+                    class="order-center-item"
+                    v-if="(orderItem.actualAmount || orderItem.actualAmount === 0) && orderItem.orderStatus !== 2 && orderItem.orderStatus !== 1"
+                  >
+                    实缴金额:
+                    <span class="pay-amount">{{ orderItem.actualAmount || 0 }}</span>
+                  </view>
+                  <view class="order-center-item">泊位号:{{ orderItem.spaceName }}</view>
+                  <view class="order-center-item" v-if="Number(orderItem.deviceType) !== 1"> 车位锁设备号:{{ orderItem.deviceNo }}</view>
+                </view>
+                <!-- 停车场显示字段 -->
+                <view class="order-center" v-if="typeCurrent.value === 'park'">
+                  <view class="order-center-item">订单编号:{{ orderItem.orderId }}</view>
+                  <view class="order-center-item"> 入场通道:{{ orderItem.roadwayName }}</view>
+                  <view class="order-center-item"> 入场时间:{{ orderItem.inTime }}</view>
+                  <view class="order-center-item" v-if="orderItem.orderStatus == 1 && orderItem.outTime"> 出场通道:{{ `未出场` }}</view>
+                  <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 出场通道:{{ orderItem.outParkingName }}</view>
+                  <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 出场时间:{{ orderItem.inTime }}</view>
+                  <view class="order-center-item"> 免费时长:{{ orderItem.freeDuration || `0天0时${free_time}分0秒` }}</view>
+                  <view class="order-center-item"> 计费时长:{{ orderItem.calcDuration || 0 }}</view>
+                  <view class="order-center-item"> 累计停车时长:{{ orderItem.duration || 0 }}</view>
+                  <view class="order-center-item">
+                    应缴金额:
+                    <span class="pay-amount">{{ orderItem.payAmount || 0 }}</span>
+                  </view>
+                  <view
+                    class="order-center-item"
+                    v-if="(orderItem.actualAmount || orderItem.actualAmount === 0) && orderItem.orderStatus !== 2 && orderItem.orderStatus !== 1"
+                  >
+                    实缴金额:
+                    <span class="pay-amount">{{ orderItem.actualAmount || 0 }}</span>
+                  </view>
+                </view>
+                <view class="order-bottom">
+                  <u-cell-item title="收费标准" @click.native.stop="jumpChargeStandard(orderItem)"> </u-cell-item>
+                </view>
+              </view>
+              <u-loadmore :status="loadStatus[index]" bg-color="#F6F6FF"></u-loadmore>
+            </view>
+          </scroll-view>
+        </swiper-item>
+      </swiper>
+    </view>
+
+    <!-- 停车场和路段切换 -->
+    <template v-if="projectFlag !== 'zhenning'">
+      <view class="type-list">
+        <view
+          class="type-list-item"
+          v-for="(item, index) in typeList"
+          :key="index"
+          :class="{ 'type-list-item-current': typeCurrent.value === item.value }"
+          @click="typeTabClick(item)"
+        >
+          {{ item.label }}
+        </view>
+      </view>
+    </template>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+// 订单状态orderStatus: 1-停放中 2-出场中 3-欠费 4-完成
+export default {
+  data() {
+    return {
+      orderList: [[], [], [], []],
+      list: [
+        {
+          index: 0,
+          name: '全部',
+          orderStatus: null,
+          pageNum: 1,
+          total: null
+        },
+        {
+          index: 1,
+          name: '停放中',
+          orderStatus: 1,
+          pageNum: 1,
+          total: null
+        },
+        {
+          index: 2,
+          name: '欠费未缴',
+          orderStatus: 2,
+          pageNum: 1,
+          total: null
+        },
+        {
+          index: 3,
+          name: '已完成',
+          orderStatus: 4,
+          pageNum: 1,
+          total: null
+        }
+      ],
+      current: 0,
+      swiperCurrent: 0,
+      tabsHeight: 0,
+      dx: 0,
+      loadStatus: ['loadmore', 'loadmore', 'loadmore', 'loadmore'],
+      // 停车类型
+      typeList: [
+        {
+          label: '路段',
+          value: 'road'
+        },
+        {
+          label: '停车场',
+          value: 'park'
+        }
+      ],
+      typeCurrent: {
+        //设置停车类型默认值
+        label: '路段',
+        value: 'road'
+      }
+    };
+  },
+  onShow() {},
+  onLoad(options) {
+    let questCurrent = options.orderStatus;
+    if (questCurrent) {
+      this.current = questCurrent;
+      this.change(questCurrent);
+    } else {
+      this.list[this.current].pageNum = 1;
+      this.orderList = [[], [], [], []];
+      this.getOrderList(this.list[this.current], this.typeCurrent);
+    }
+  },
+  computed: {
+    // 价格小数
+    priceDecimal() {
+      return (val) => {
+        if (val !== parseInt(val)) return val.slice(-2);
+        else return '00';
+      };
+    },
+    // 价格整数
+    priceInt() {
+      return (val) => {
+        if (val !== parseInt(val)) return val.split('.')[0];
+        else return val;
+      };
+    }
+  },
+  onBackPress(e) {
+    // 返回主页面tabBar
+    uni.switchTab({
+      url: '../../center/index'
+    });
+    // 此处一定要return为true,否则页面不会返回到指定路径
+    return true;
+  },
+  methods: {
+    reachBottom() {
+      if (this.orderList[this.current].length >= this.list[this.current].total) {
+        this.loadStatus.splice(this.list[this.current].index, 1, 'nomore');
+        return;
+      }
+      this.loadStatus.splice(this.list[this.current].index, 1, 'loading');
+      this.getOrderList(this.list[this.current], this.typeCurrent);
+    },
+    // 页面数据
+
+    getOrderList(orderType, typeCurrent) {
+      //初始化订单列表
+      const param = {
+        pageNum: orderType.pageNum,
+        orderStatus: orderType.orderStatus
+      };
+
+      // 未出场: orderStatus	 = 1-停放中
+      // 缴费中: orderStatus	 = 2-出场中  && payStatus = 2-支付中
+      // 完成:   orderStatus	 = 4-完成
+      if (typeCurrent.value == 'road') {
+        this.$u.api
+          .getOrderList(param)
+          .then((res) => {
+            for (const item of res.data.pageInfo.rows) {
+              this.orderList[orderType.index].push(item);
+            }
+            this.list[this.current].total = res.data.pageInfo.total;
+            this.list[orderType.index].pageNum++;
+            if (this.orderList[this.current].length >= this.list[this.current].total) {
+              this.loadStatus.splice(this.list[orderType.index].index, 1, 'nomore');
+            }
+          })
+          .catch((err) => {
+            this.$refs.uToast.show({
+              title: err.msg,
+              type: 'error'
+            });
+          });
+      } else {
+        this.$u.api
+          .getRoomParkingApi(param)
+          .then((res) => {
+            for (const item of res.data.pageInfo.rows) {
+              this.orderList[orderType.index].push(item);
+            }
+            this.list[this.current].total = res.data.pageInfo.total;
+            this.list[orderType.index].pageNum++;
+            if (this.orderList[this.current].length >= this.list[this.current].total) {
+              this.loadStatus.splice(this.list[orderType.index].index, 1, 'nomore');
+            }
+          })
+          .catch((err) => {
+            this.$refs.uToast.show({
+              title: err.msg,
+              type: 'error'
+            });
+          });
+      }
+
+      this.loadStatus.splice(this.current, 1, 'loadmore');
+    },
+    // tab栏切换
+    change(index) {
+      this.swiperCurrent = index;
+      //重新初始化
+      this.orderList = [[], [], [], []];
+      this.list[index].pageNum = 1;
+      this.getOrderList(this.list[index], this.typeCurrent);
+    },
+    transition({ detail: { dx } }) {
+      this.$refs.tabs.setDx(dx);
+    },
+    animationfinish({ detail: { current } }) {
+      this.$refs.tabs.setFinishCurrent(current);
+      this.swiperCurrent = current;
+      this.current = current;
+    },
+    /**
+     * 跳转详情
+     * 未发起退款或者未退款成功的
+     * */
+    goDetails(item) {
+      this.$u.route({
+        url: 'pages/center/order/orderDetails/orderDetails',
+        params: {
+          orderId: item.id,
+          orderType: this.typeCurrent.value
+        }
+      });
+    },
+    jumpChargeStandard(item) {
+      let roadNo = item?.roadNo;
+      if (this.typeCurrent.value === 'park') {
+        roadNo = item?.parkingNo;
+      }
+      this.$u.route({
+        url: 'pages/chargeStandard/chargeStandard',
+        params: {
+          roadNo
+        }
+      });
+    },
+    // 申请退款
+    applyRefund(item) {
+      this.$u.route('pages/applyRefund/applyRefund', {
+        orderId: item.orderId,
+        payAmount: item.actualAmount
+      });
+    },
+    /**
+     * 申请退款详情
+     * 只要申请退款状态等于1并且审批状态等于1跳转到退款完成详情页
+     *  否则跳转到退款过程页
+     * */
+    applyRefundDetails(item) {
+      if (item.refundStatus === 1 && item.auditStatus === 1) {
+        this.$u.route('pages/applyRefundDetails/applyRefundAchieveDetails', {
+          orderId: item.orderId
+        });
+      } else {
+        this.$u.route('pages/applyRefundDetails/applyRefundDetails', {
+          orderId: item.orderId
+        });
+      }
+    },
+    /**
+     * 类型切换
+     * @param {Object} item
+     */
+    typeTabClick(item) {
+      this.typeCurrent = item;
+      //重新初始化
+      this.orderList = [[], [], [], []];
+      this.list[this.current].pageNum = 1;
+      this.getOrderList(this.list[this.current], this.typeCurrent);
+    }
+  },
+  filters: {
+    verifyStatusFilter(value) {
+      if (value === 0) {
+        return '';
+      } else if (value === 1) {
+        return '停放中';
+      } else if (value === 2) {
+        return '欠费未缴';
+      } else if (value === 4) {
+        return '已完成';
+      } else {
+        return '';
+      }
+    },
+    verifyRefundStatus(item) {
+      if (item.auditStatus === 0) {
+        return '申请退款中';
+      } else if (item.auditStatus === 1) {
+        if (item.refundStatus === 0) {
+          return '退款失败';
+        } else if (item.refundStatus === 1) {
+          return '退款成功';
+        }
+      } else if (item.auditStatus === 2) {
+        return '已驳回';
+      }
+    }
+  }
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+  height: 100%;
+  background-color: #f6f6ff;
+}
+
+/* #endif */
+</style>
+
+<style lang="scss" scoped>
+@import './order.scss';
+</style>

+ 41 - 0
pages/center/order/orderDetails/orderDetails.scss

@@ -0,0 +1,41 @@
+.order-info {
+  .u-cell {
+    padding: 17rpx 0;
+  }
+  /deep/ .u-cell_title {
+    font-weight: 600;
+  }
+}
+.order-info-img {
+  margin: 54rpx auto 10rpx;
+}
+.addr {
+  text-align: center;
+  margin-bottom: 10rpx;
+  font-size: 26rpx;
+  font-weight: 400;
+  color: #737373;
+  line-height: 37rpx;
+  letter-spacing: 1px;
+}
+.pay-amount {
+  text-align: center;
+  font-size: 60rpx;
+  font-weight: 500;
+  color: #010101;
+  line-height: 84rpx;
+  letter-spacing: 2px;
+  margin-bottom: 18rpx;
+}
+.loading-warp {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+}
+.loading-text {
+  margin-top: 20rpx;
+  color: #fff;
+  font-size: 20rpx;
+}

+ 376 - 0
pages/center/order/orderDetails/orderDetails.vue

@@ -0,0 +1,376 @@
+<template>
+  <view class="wrap">
+    <view class="order-info">
+      <u-image class="order-info-img" width="90rpx" height="90rpx" src="/static/img/position.png" />
+      <view class="addr">{{ orderInfo.roadName }}</view>
+      <view class="pay-amount" v-if="orderInfo.payAmount">-{{ orderInfo.payAmount }}</view>
+      <view class="pay-amount" v-else>{{ orderInfo.payAmount }}</view>
+      <u-cell-group :border="false">
+        <u-cell-item title="车牌号" :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.vehicleNo" />
+        <u-cell-item
+          title="优惠总金额"
+          :arrow="false"
+          :border-bottom="false"
+          :border-top="false"
+          :value="(orderInfo.preferentialAmount ? orderInfo.preferentialAmount.toFixed(2) : 0) + ' 元'"
+        />
+      </u-cell-group>
+      <!-- 路段显示 -->
+      <u-cell-group v-if="orderType == 'road'">
+        <u-cell-item title="订单编号 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.orderId" />
+        <template v-if="orderInfo.deviceType == 1">
+          <u-cell-item title="入场时间 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.inTime" />
+          <u-cell-item title="出场时间 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.outTime" />
+        </template>
+        <template v-else>
+          <u-cell-item title="开始计费 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.inTime" />
+          <u-cell-item title="结束计费 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.outTime" />
+        </template>
+        <template v-if="orderInfo.deviceType !== 2">
+          <u-cell-item
+            title="免费时长 "
+            :arrow="false"
+            :border-bottom="false"
+            :border-top="false"
+            :value="orderInfo.freeDuration || `0天0时${free_time}分0秒`"
+          />
+        </template>
+        <template v-else>
+          <u-cell-item
+            title="免费时长 "
+            :arrow="false"
+            :border-bottom="false"
+            :border-top="false"
+            :value="orderInfo.freeDuration || `0天0时${free_time}分0秒`"
+          />
+        </template>
+        <u-cell-item title="计费时长 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.calcDuration" />
+        <u-cell-item title="累计停车时长 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.duration" />
+        <u-cell-item
+          v-if="orderInfo.createTime"
+          title="订单创建时间 "
+          :arrow="false"
+          :border-bottom="false"
+          :border-top="false"
+          :value="orderInfo.createTime"
+        />
+        <u-cell-item
+          v-if="orderInfo.payTime"
+          title="支付时间 "
+          :arrow="false"
+          :border-bottom="false"
+          :border-top="false"
+          :value="orderInfo.payTime"
+        />
+        <u-cell-item
+          v-if="orderInfo.payStatus == 1"
+          title="缴费方式 "
+          :arrow="false"
+          :border-bottom="false"
+          :border-top="false"
+          :value="orderInfo.paySource | verifyPaySource"
+        />
+      </u-cell-group>
+      <!-- 停车场时长 -->
+      <u-cell-group v-if="orderType == 'park'">
+        <u-cell-item title="订单编号 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.orderId" />
+        <template v-if="orderInfo.deviceType == 1">
+          <u-cell-item title="入场通道 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.roadwayName" />
+          <u-cell-item title="入场时间 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.inTime" />
+          <u-cell-item title="出场通道 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.outRoadwayName" />
+          <u-cell-item title="出场时间 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.outTime" />
+        </template>
+        <template v-else>
+          <u-cell-item title="开始计费 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.inTime" />
+          <u-cell-item title="结束计费 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.outTime" />
+        </template>
+        <template v-if="orderInfo.deviceType == 1">
+          <u-cell-item
+            title="免费时长 "
+            :arrow="false"
+            :border-bottom="false"
+            :border-top="false"
+            :value="orderInfo.freeDuration || `0天0时${free_time}分0秒`"
+          />
+        </template>
+        <template v-else>
+          <u-cell-item
+            title="免费时长 "
+            :arrow="false"
+            :border-bottom="false"
+            :border-top="false"
+            :value="orderInfo.freeDuration || `0天0时${free_time}分0秒`"
+          />
+        </template>
+        <u-cell-item title="计费时长 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.calcDuration" />
+        <u-cell-item title="累计停车时长 " :arrow="false" :border-bottom="false" :border-top="false" :value="orderInfo.duration" />
+        <u-cell-item
+          v-if="orderInfo.createTime"
+          title="订单创建时间 "
+          :arrow="false"
+          :border-bottom="false"
+          :border-top="false"
+          :value="orderInfo.createTime"
+        />
+        <u-cell-item
+          v-if="orderInfo.payTime"
+          title="支付时间 "
+          :arrow="false"
+          :border-bottom="false"
+          :border-top="false"
+          :value="orderInfo.payTime"
+        />
+        <u-cell-item
+          v-if="orderInfo.payStatus == 1"
+          title="缴费方式 "
+          :arrow="false"
+          :border-bottom="false"
+          :border-top="false"
+          :value="orderInfo.paySource | verifyPaySource"
+        />
+      </u-cell-group>
+      <!-- 地磁订单金额为0并且未支付 -->
+      <view class v-if="orderInfo.deviceType == 1 && orderInfo.payAmount == 0 && orderInfo.payStatus !== 1"
+        >提示:可寻找附近的收费员打印小票并扫码出场</view
+      >
+    </view>
+    <!-- 地磁显示支付按钮条件  支付状态(0-未支付,2-支付中,3-支付失败)并且订单金额不能为0 -->
+    <template v-if="orderInfo.deviceType === 1 && orderInfo.payStatus !== 1 && openFlag !== 'open'">
+      <view class="bottom-btn-wrap" v-if="Number(orderInfo.payAmount) !== 0">
+        <view class="bottom-btn" @click="goPay(orderId)">去支付</view>
+      </view>
+      <view class="bottom-btn-wrap" v-else-if="Number(orderInfo.payAmount) === 0">
+        <view class="tips">提示:可寻找附近的收费员打印小票并扫码出场</view>
+      </view>
+    </template>
+    <!-- 其他显示支付按钮条件  支付状态(0-未支付,2-支付中,3-支付失败) 订单类型非停车场 -->
+    <template v-else-if="orderInfo.deviceType !== 1 && orderInfo.payStatus !== 1 && openFlag !== 'open' && orderType !== 'park'">
+      <view class="bottom-btn-wrap">
+        <view class="bottom-btn" @click="goPay(orderId)">去支付</view>
+      </view>
+    </template>
+    <!-- 订单类型停车场 订单状态欠费未缴 orderStatus为2  -->
+    <template v-else-if="orderInfo.deviceType !== 1 && orderType === 'park' && Number(orderInfo.orderStatus) === 2">
+      <view class="bottom-btn-wrap">
+        <view class="bottom-btn" @click="goPay(orderId)">去支付</view>
+      </view>
+    </template>
+    <view class="bottom-btn-wrap" v-if="openFlag === 'open' && orderInfo.payStatus == 1">
+      <view class="bottom-btn" @click="jumpOrderList()">返回订单页</view>
+    </view>
+
+    <!-- 支付方式 -->
+    <!-- <PaymentMethod
+      :payWayPop="payWayPop"
+      :exportFlag="exportFlag"
+      :curOrderList="orderList"
+      :jumpUrl="jumpUrl"
+      @closePaymentMethod="closePaymentMethod"
+    /> -->
+
+    <!-- 加载中遮罩 -->
+    <u-mask :show="loadingMask">
+      <view class="loading-warp">
+        <view class="loading-icon">
+          <u-loading mode="flower" size="50"></u-loading>
+        </view>
+        <view class="loading-text">
+          <text>订单支付状态查询中...</text>
+        </view>
+      </view>
+    </u-mask>
+    <ChoosePayment
+      ref="choosePayment"
+      :exportFlag="exportFlag"
+      :curOrderList="orderList"
+      :jumpUrl="jumpUrl"
+      @closePaymentMethod="closePaymentMethod"
+    />
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+// import PaymentMethod from '@/pages/paymentMethod/paymentMethod.vue';
+import ChoosePayment from '@/pages/choosePayment/choosePayment.vue';
+export default {
+  components: {
+    // PaymentMethod,
+    ChoosePayment
+  },
+  data() {
+    return {
+      orderId: null,
+      // 用来区分是支付完成返回的标识
+      openFlag: null,
+      polyOrderId: null,
+      // 订单信息
+      orderInfo: {},
+      // 立即支付弹框
+      payWayPop: false,
+      // 订单列表,一般长度为1的数组
+      orderList: [],
+      // 重定向页面
+      jumpUrl: location.href + '&type=open',
+      loadingMask: false,
+      exportFlag: false,
+      // 订单类型  road 路段  park  停车场
+      orderType: 'road'
+    };
+  },
+  onLoad(page) {
+    this.orderId = page?.orderId;
+    // 该标识判断是否是从支付完成页面回调回来
+    this.openFlag = page?.type;
+    this.orderType = page?.orderType;
+    this.polyOrderId = page?.polyOrderId;
+    if (this.orderId) {
+      // 如果type标识和支付订单id同时存在,证明需要执行轮询判断支付状态,否则直接查询
+      if (this.openFlag && this.polyOrderId) {
+        this.loadingMask = true;
+        this.handlePayStatus(this.polyOrderId);
+        let time = 0;
+        this.timer = setInterval(() => {
+          time++;
+          this.handlePayStatus(this.polyOrderId);
+          // 超过60s直接清除轮询
+          if (time === 60) {
+            clearInterval(this.timer);
+          }
+        }, 1000);
+      } else {
+        this.handleGetOrderinfo(this.orderId, this.orderType);
+      }
+    }
+  },
+  methods: {
+    jumpOrderList() {
+      this.$u.route({
+        url: 'pages/center/order/order'
+      });
+    },
+    /**
+     * 通过订单id去获取订单信息
+     * */
+    handleGetOrderinfo(orderId, orderType) {
+      if (orderType == 'road') {
+        this.$u.api
+          .getOrderDetail({
+            id: orderId
+          })
+          .then((res) => {
+            if (res.code === 200) {
+              this.orderInfo = res.data;
+            } else {
+              this.$refs.uToast.show({
+                title: res.msg,
+                type: 'error'
+              });
+            }
+          });
+      } else {
+        this.$u.api
+          .getRoomOrderDetail({
+            id: orderId
+          })
+          .then((res) => {
+            if (res.code === 200) {
+              this.orderInfo = res.data;
+            } else {
+              this.$refs.uToast.show({
+                title: res.msg,
+                type: 'error'
+              });
+            }
+          });
+      }
+    },
+    /**
+     * 查询支付状态
+     * @param { String } orderId
+     */
+    handlePayStatus(orderId) {
+      this.$u.api
+        .getOrderInfo({
+          orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.payStatus === 1 || res.data.payStatus === 3) {
+              this.loadingMask = false;
+              clearInterval(this.timer);
+              this.handleGetOrderinfo(this.orderId, this.orderType);
+            }
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+            this.loadingMask = false;
+            clearInterval(this.timer);
+          }
+        })
+        .catch(() => {
+          this.loadingMask = false;
+          clearInterval(this.timer);
+        });
+    },
+    goPay(orderId) {
+      this.orderList = [];
+      this.orderList.push(orderId);
+      if (this.orderType == 'park') {
+        this.exportFlag = true;
+      } else {
+        this.exportFlag = false;
+      }
+      if (this.orderList.length > 0) {
+        // this.payWayPop = true;
+        this.$nextTick(() => {
+          this.$refs['choosePayment'].openPopup({ ...this.orderInfo }, 'single', this.orderType === 'road' ? 'road' : 'parking');
+        });
+      } else {
+        this.$refs.uToast.show({
+          title: '当前订单编号不存在,请重新进入当前页面!',
+          type: 'warning'
+        });
+      }
+    },
+    /**
+     * 关闭支付方式弹框
+     * */
+    closePaymentMethod() {
+      this.payWayPop = false;
+    }
+  },
+  filters: {
+    verifyPaySource(value) {
+      if (value === 0) {
+        return '现金支付';
+      } else if (value === 1) {
+        return '微信支付';
+      } else if (value === 2) {
+        return '支付宝支付';
+      } else if (value === 3) {
+        return '贵州银行快捷支付';
+      } else if (value === 4) {
+        return '贵州银行扫码支付';
+      } else if (value === 5) {
+        return '贵州银行被扫支付';
+      } else if (value === 6) {
+        return '贵州银行无感支付';
+      } else {
+        return '其他';
+      }
+    }
+  },
+  destroyed() {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './orderDetails.scss';
+</style>

+ 298 - 0
pages/center/phoneLogin/phoneLogin - 副本.vue

@@ -0,0 +1,298 @@
+<template>
+	<view class="wrap">
+		<view class="content">
+			<view class="title">手机号登录</view>
+			<input class="u-border-bottom" type="number" maxlength="11" v-model="tel" placeholder="请输入手机号" />
+			<view class="u-text-center u-type-error u-m-t-20" v-if="telError">手机号输入错误</view>
+			<button @tap="submit" :style="[inputStyle]" class="getCaptcha">获取短信验证码</button>
+			<u-message-input v-if="show" :focus="true" :value="messageCode" @change="change" @finish="finish"
+				mode="bottomLine" :maxlength="codelength"></u-message-input>
+		</view>
+		<!-- <view class="u-text-center u-type-error" v-if="phoneError">手机号输入错误</view> -->
+		<view class="captcha">
+			<!-- <text v-if="show&&this.messageDisable==false" @tap="noCaptcha">收不到验证码点这里</text> -->
+			<text v-if="messageShow">{{ second }}秒后可重新获取验证码</text>
+		</view>
+		<view class="buttom">
+			<view class="hint u-text-center">
+				登录代表同意
+				<text class="link" @tap="jumpToPage(1)">《用户服务条款》</text>和
+				<text class="link" @tap="jumpToPage(2)">《隐私政策》</text>
+				并授权使用您的账号信息(如昵称、头像、收货地址)以便您统一管理
+			</view>
+		</view>
+		<u-toast ref="uToast" />
+	</view>
+</template>
+
+<script>
+	import getUrlParams from "./../../../utils/getUrlParams.js";
+	export default {
+		data() {
+			return {
+				tel: '',
+				messageCode: '',
+				messageShow: false,
+				messageDisable: false,
+				codelength: 4,
+				show: false,
+				second: 60,
+				toastMsg: '',
+				toastUrl: '',
+				toastType: '',
+				accessToken: '',
+				userId: '',
+				telError: false,
+				// messageError:false
+			}
+		},
+		onLoad(page) {
+			//  如果存在code 则认为是微信登录完成后跳转过来的,直接获取信息跳转首页或者指定页面
+			let locationLocaturl = window.location.search;
+			this.code = getUrlParams(locationLocaturl, "code"); // 截取code
+			if (this.code) {
+				this.handleGetWXInfo(this.code) //把code传给后台获取用户信息
+			}
+		},
+		computed: {
+			inputStyle() {
+				let style = {};
+				if (this.tel.length == 11 && this.messageDisable == false && this.$u.test.mobile(this.tel)) {
+					style.color = "#fff";
+					style.backgroundColor = '#5295F5';
+					this.telError = false;
+					// style.backgroundColor = this.$u.color['warning'];
+				} else if (this.tel.length == 11 && !this.$u.test.mobile(this.tel)) {
+					this.telError = true;
+				}
+				return style;
+			}
+		},
+		methods: {
+			showToast() {
+				this.$refs.uToast.show({
+					title: this.toastMsg,
+					type: this.toastType,
+					url: this.toastUrl
+				})
+			},
+			submit() {
+				if (this.$u.test.mobile(this.tel) && this.messageDisable == false) {
+					let that = this;
+					this.$u.api.getPhoneLoginCode({
+							mobile: this.tel
+						})
+						.then(res => {
+							this.messageDisable = true;
+							this.messageShow = true;
+							this.show = true;
+							let interval = setInterval(() => {
+								that.second--;
+								if (that.second <= 0) {
+									that.messageDisable = false
+									that.messageShow = false;
+									if (that.messageCode.lenth != 4) {
+										// this.messageError = true;
+									}
+									clearInterval(interval);
+									that.second = 60;
+								}
+							}, 1000);
+							this.accessToken = res.data.accessToken;
+							this.userId = res.data.userId;
+						}).catch(err => {
+							this.toastMsg = err.code + ":" + err.msg;
+							this.showToast();
+						});
+				}
+			},
+			// 收不到验证码选择时的选择
+			// noCaptcha() {
+			// 	uni.showActionSheet({
+			// 		itemList: ['重新获取验证码', '接听语音验证码'],
+			// 		success: function(res) {
+
+			// 		},
+			// 		fail: function(res) {
+
+			// 		}
+			// 	});
+			// },
+			// change事件侦听
+			change(value) {
+				// console.log('change', value);
+			},
+			// 输入完验证码最后一位执行
+			finish(value) {
+				let params = {
+					accessToken: this.accessToken,
+					userId: this.userId,
+					code: value
+				};
+				this.$u.api.phoneLoginAuth(params)
+					.then(res => {
+						if (res.code == '200') {
+							this.$u.vuex('vuex_token', this.accessToken);
+							this.$u.vuex('vuex_user', res.data);
+							this.$u.vuex('vuex_hasLogin', true);
+							this.wechatLogin()
+
+						} else {
+							this.toastMsg = res.msg;
+							this.showToast();
+						}
+					}).catch(err => {
+						this.toastMsg = err.msg;
+						this.showToast();
+					});
+			},
+			// 微信登录
+			wechatLogin() {
+				this.jumpIndex()
+				// const openId = this.$store.state.vuex_wxinfo?.openId
+				// if (openId) {
+				// 	this.jumpIndex()
+				// } else {
+				// 	this.getCode()
+				// }
+			},
+			// 微信已登录则跳转到首页
+			jumpIndex() {
+				let ret = localStorage.getItem('backUrl')
+				if (ret && ret.indexOf('phoneLogin') < 0) {
+					// 截取url
+					const pagesIndex = ret.indexOf('pages')
+					if (pagesIndex > (-1)) {
+						const pageUrl = ret.slice(pagesIndex)
+						const tabbarUrl = ['pages/center/index', 'pages/parkingLists/parkingLists']
+						if (tabbarUrl.indexOf(pageUrl) > (-1)) {
+							setTimeout(() => {
+								uni.switchTab({
+									url: '../../index/index'
+								})
+							}, 100)
+						} else {
+							setTimeout(() => {
+								uni.navigateTo({
+									url: '/' + pageUrl
+								})
+							}, 100)
+						}
+					} else {
+						uni.switchTab({
+							url: '../../index/index'
+						})
+					}
+				} else {
+					uni.switchTab({
+						url: '../../index/index'
+					})
+				}
+			},
+			// 获取code
+			getCode() {
+				const local = window.location.href // 获取页面url
+				let locationLocaturl = window.location.search;
+				this.code = getUrlParams(locationLocaturl, "code"); // 截取code
+				if (this.code) { // 如果没有code,则去请求
+					this.handleGetWXInfo(this.code) //把code传给后台获取用户信息
+				} else {
+					window.location.href =
+						`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.config.wxAppid}&redirect_uri=${encodeURIComponent(local)}&response_type=code&scope=snsapi_userinfo&#wechat_redirect`
+				}
+			},
+			// 通过code获取 openId等用户信息,/api/user/wechat/login 为后台接口
+			handleGetWXInfo(code) {
+				uni.showLoading({
+			  title: '加载中'
+				})
+				this.$u.api.getWXInfo(code).then((res) => {
+					if (res.code === 200) {
+						this.$u.vuex('vuex_wxinfo', res.data);
+						this.jumpIndex()
+					} else {
+						this.$refs.uToast.show({
+							title: '获取用户信息失败!',
+							type: 'error',
+						});
+					}
+					uni.hideLoading()
+				}).catch((err) => {
+					this.$refs.uToast.show({
+						title: '获取用户信息失败!',
+						type: 'error',
+					});
+				})
+			},
+			/**
+			 * 跳转页面
+			 * */
+			jumpToPage(flag) {
+				uni.navigateTo({
+					url: "/pages/privacyPolicy/privacyPolicy?termsType=" + flag,
+				})
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.hide {
+		display: none !important;
+	}
+
+	.wrap {
+		font-size: 28rpx;
+
+		.content {
+			width: 600rpx;
+			margin: 80rpx auto 0;
+
+			.title {
+				text-align: left;
+				font-size: 60rpx;
+				font-weight: 500;
+				margin-bottom: 100rpx;
+			}
+
+			input {
+				text-align: left;
+				margin-bottom: 10rpx;
+				padding-bottom: 20rpx;
+				border-bottom: 1px solid #ddd;
+			}
+
+			.getCaptcha {
+				margin: 45rpx auto 130rpx;
+				background-color: #a8c6f1;
+				color: $u-tips-color;
+				border: none;
+				font-size: 30rpx;
+				padding: 12rpx 0;
+
+				&::after {
+					border: none;
+				}
+			}
+		}
+
+		.buttom {
+			.hint {
+				padding: 20rpx 40rpx;
+				font-size: 20rpx;
+				color: $u-tips-color;
+
+				.link {
+					color: $u-type-warning;
+				}
+			}
+		}
+
+		.captcha {
+			color: $u-type-warning;
+			font-size: 30rpx;
+			margin-top: 40rpx;
+			text-align: center;
+		}
+	}
+</style>

+ 258 - 0
pages/center/phoneLogin/phoneLogin.vue

@@ -0,0 +1,258 @@
+<template>
+  <view class="wrap">
+    <view class="content">
+      <view class="title">手机号登录</view>
+      <input class="u-border-bottom" type="number" maxlength="11" v-model="tel" placeholder="请输入手机号" />
+      <view class="u-text-center u-type-error u-m-t-20" v-if="telError">手机号输入错误</view>
+      <button @tap="submit" :style="[inputStyle]" class="getCaptcha">获取短信验证码</button>
+      <u-message-input
+        v-if="show"
+        :focus="true"
+        :value="messageCode"
+        @change="change"
+        @finish="finish"
+        mode="bottomLine"
+        :maxlength="codelength"
+      ></u-message-input>
+    </view>
+    <view class="captcha">
+      <text v-if="messageShow">{{ second }}秒后可重新获取验证码</text>
+    </view>
+    <view class="buttom">
+      <view class="hint u-text-center">
+        登录代表同意
+        <text class="link" @tap="jumpToPage(1)">《用户服务条款》</text>和
+        <text class="link" @tap="jumpToPage(2)">《隐私政策》</text>
+        并授权使用您的账号信息(如昵称、头像、收货地址)以便您统一管理
+      </view>
+    </view>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import getUrlParams from './../../../utils/getUrlParams.js';
+export default {
+  data() {
+    return {
+      tel: '',
+      messageCode: '',
+      messageShow: false,
+      messageDisable: false,
+      codelength: 4,
+      show: false,
+      second: 60,
+      toastMsg: '',
+      toastUrl: '',
+      toastType: '',
+      accessToken: '',
+      userId: '',
+      telError: false,
+      openId: ''
+    };
+  },
+  onLoad(page) {
+    this.openId = this.vuex_wxinfo?.openId;
+    const backUrl = location.href;
+    if (!this.openId) {
+      // 判断浏览器
+      const ua = window.navigator.userAgent.toLowerCase();
+      if (ua.match(/MicroMessenger/i) == 'micromessenger') {
+        // 微信中打开
+        this.$u.route('pages/wechatLogin/wechatLogin', {
+          backUrl
+        });
+      }
+    }
+    const pages = getCurrentPages();
+    if (pages.length >= 2) {
+      uni.setStorageSync('last_page', pages[pages.length - 2].route);
+      if (pages[pages.length - 2].options) {
+        uni.setStorageSync('last_page_options', pages[pages.length - 2].options);
+      }
+    }
+  },
+  computed: {
+    inputStyle() {
+      let style = {};
+      if (this.tel.length == 11 && this.messageDisable == false && this.$u.test.mobile(this.tel)) {
+        style.color = '#fff';
+        style.backgroundColor = '#5295F5';
+        this.telError = false;
+      } else if (this.tel.length == 11 && !this.$u.test.mobile(this.tel)) {
+        this.telError = true;
+      }
+      return style;
+    }
+  },
+  methods: {
+    showToast() {
+      this.$refs.uToast.show({
+        title: this.toastMsg,
+        type: this.toastType,
+        url: this.toastUrl
+      });
+    },
+    submit() {
+      if (this.$u.test.mobile(this.tel) && this.messageDisable == false) {
+        let that = this;
+        this.$u.api.userLoginApi.sendSmsCodeApi({ mobile: this.tel }).then((res) => {
+          this.messageDisable = true;
+          this.messageShow = true;
+          this.show = true;
+          let interval = setInterval(() => {
+            that.second--;
+            if (that.second <= 0) {
+              that.messageDisable = false;
+              that.messageShow = false;
+              clearInterval(interval);
+              that.second = 60;
+            }
+          }, 1000);
+          this.accessToken = res?.data?.accessToken;
+          this.userId = res?.data?.userId;
+        });
+      }
+    },
+    // change事件侦听
+    change(value) {
+      // console.log('change', value);
+    },
+    // 输入完验证码最后一位执行
+    finish(value) {
+      let params = {
+        loginType: 1,
+        nickName: this.vuex_wxinfo?.nickname,
+        code: value,
+        openid: this.vuex_wxinfo?.openId,
+        mobile: this.tel,
+        avatar: this.vuex_wxinfo?.headImgUrl
+      };
+      this.$u.api.userLoginApi
+        .mobileLoginApi(params)
+        .then((res) => {
+          if (res.code == '200') {
+            this.$u.vuex('vuex_token', res.data.accessToken);
+            this.$u.vuex('vuex_user', res.data);
+            this.$u.vuex('vuex_hasLogin', true);
+            setTimeout(() => {
+              this.jumpIndex();
+            }, 500);
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.toastMsg = err.msg;
+          this.showToast();
+        });
+    },
+    // 微信已登录则跳转到首页
+    jumpIndex() {
+      let ret = localStorage.getItem('backUrl');
+      ret = decodeURIComponent(ret);
+      if ((ret && ret.indexOf('wechatLogin') > -1) || (ret && ret.indexOf('phoneLogin') < 0)) {
+        // 截取url
+        const pagesIndex = ret.indexOf('pages');
+        if (pagesIndex > -1) {
+          const pageUrl = ret.slice(pagesIndex);
+          const tabbarUrl = ['pages/center/index', 'pages/parkingLists/parkingLists', 'page/index/index'];
+          if (tabbarUrl.indexOf(pageUrl) > -1) {
+            setTimeout(() => {
+              uni.switchTab({
+                url: '../../index/index'
+              });
+            }, 100);
+          } else {
+            setTimeout(() => {
+              uni.redirectTo({
+                url: '/' + pageUrl
+              });
+            }, 100);
+          }
+        } else {
+          uni.switchTab({
+            url: '../../index/index'
+          });
+        }
+      } else {
+        uni.switchTab({
+          url: '/pages/index/index'
+        });
+      }
+    },
+    /**
+     * 跳转页面
+     * */
+    jumpToPage(flag) {
+      uni.navigateTo({
+        url: '/pages/privacyPolicy/privacyPolicy?termsType=' + flag
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.hide {
+  display: none !important;
+}
+
+.wrap {
+  font-size: 28rpx;
+
+  .content {
+    width: 600rpx;
+    margin: 80rpx auto 0;
+
+    .title {
+      text-align: left;
+      font-size: 60rpx;
+      font-weight: 500;
+      margin-bottom: 100rpx;
+    }
+
+    input {
+      text-align: left;
+      margin-bottom: 10rpx;
+      padding-bottom: 20rpx;
+      border-bottom: 1px solid #ddd;
+    }
+
+    .getCaptcha {
+      margin: 45rpx auto 130rpx;
+      background-color: #a8c6f1;
+      color: $u-tips-color;
+      border: none;
+      font-size: 30rpx;
+      padding: 12rpx 0;
+
+      &::after {
+        border: none;
+      }
+    }
+  }
+
+  .buttom {
+    .hint {
+      padding: 20rpx 40rpx;
+      font-size: 20rpx;
+      color: $u-tips-color;
+
+      .link {
+        color: $u-type-warning;
+      }
+    }
+  }
+
+  .captcha {
+    color: $u-type-warning;
+    font-size: 30rpx;
+    margin-top: 40rpx;
+    text-align: center;
+  }
+}
+</style>

+ 122 - 0
pages/chargeStandard/chargeStandard.scss

@@ -0,0 +1,122 @@
+.charge {
+  background-color: #f6f6ff;
+  padding-bottom: 20rpx;
+  .charge-rules-container {
+    margin-bottom: 20rpx;
+    .charge-list {
+      width: 100%;
+      margin: 0 auto;
+      padding: 33rpx 38rpx;
+      display: flex;
+      justify-content: space-between;
+      background-color: #f6f6ff;
+      .charge-list-item {
+        width: 32%;
+        margin-right: 2%;
+        background-color: #fff;
+        border-radius: 10rpx;
+        padding: 29rpx;
+        text-align: center;
+        &:last-child {
+          margin-right: 0;
+        }
+        view {
+          &:first-child {
+            color: #008cff;
+            font-size: 30rpx;
+            font-weight: 500;
+            line-height: 42rpx;
+          }
+          &:last-child {
+            color: #999999;
+            font-size: 24rpx;
+            font-weight: 400;
+            margin-top: 7rpx;
+            line-height: 33rpx;
+          }
+        }
+      }
+    }
+  }
+  .charge-rules-list {
+    padding: 32rpx 40rpx;
+    border-radius: 25rpx;
+    background-color: #fff;
+  }
+  .charge-type {
+    text {
+      font-size: 32rpx;
+      font-weight: 400;
+      color: #2e2e2e;
+      line-height: 40rpx;
+      font-family: PingFangSC-Regular, PingFang SC;
+    }
+  }
+  .charge-rule-list-header {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    .charge-time {
+      display: flex;
+      flex-direction: row;
+      font-size: 24rpx;
+      line-height: 40rpx;
+      color: #999999;
+      // view:first-child {
+      // 	margin-right: 40rpx;
+      // }
+      text {
+        color: #008cff;
+        margin-left: 10rpx;
+      }
+    }
+  }
+  .charge-rules-box {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    padding: 25rpx 0;
+    border-bottom: solid 2rpx #eaeaea;
+    view:first-child {
+      color: #2a2a2a;
+      font-weight: 400;
+    }
+    view.charge-rules-right {
+      width: 70%;
+      view {
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        font-size: 24rpx;
+        font-weight: 400;
+        color: #6e6e6e;
+        line-height: 40rpx;
+      }
+    }
+  }
+  .charge-instructions {
+    background-color: #fff;
+    border-radius: 25rpx;
+    padding: 40rpx;
+    .charge-instructions-title {
+      line-height: 40rpx;
+      font-size: 32rpx;
+      color: #2e2e2e;
+      margin-bottom: 30rpx;
+    }
+    .charge-instructions-item {
+      text-indent: -1.5em;
+      margin-left: 1.5em;
+      line-height: 40rpx;
+      font-size: 24rpx;
+      color: #757575;
+    }
+  }
+  .charge-telphone {
+    margin-top: 30rpx;
+    font-size: 24rpx;
+    font-weight: 400;
+    color: #757575;
+    line-height: 40rpx;
+  }
+}

+ 244 - 0
pages/chargeStandard/chargeStandard.vue

@@ -0,0 +1,244 @@
+<template>
+  <!-- 收费标准 -->
+  <view class="charge">
+    <view class="charge-rules-container" v-for="(item, index) in chargeRulesInfo" :key="index">
+      <view class="charge-rules-list">
+        <view class="charge-rule-list-header">
+          <view class="charge-type">
+            <text v-if="item.feePeriod == 1">节假日规则</text>
+            <text v-else>非节假日规则</text>
+          </view>
+          <view class="charge-time">
+            <view
+              >免费时长<text>{{ item.freeTime || 0 }}分钟内</text></view
+            >
+            <view v-if="item.topAmt"
+              >封顶金额<text>{{ item.topAmt || 0 }}元</text></view
+            >
+            <view v-else>无封顶金额</view>
+          </view>
+        </view>
+        <view class="charge-rules" v-for="(type, tIndex) in item.list" :key="tIndex">
+          <view v-if="type.list[0].amt || type.list[1].amt" class="charge-rules-box">
+            <view v-if="type.vehicleType == 0">小车</view>
+            <view v-if="type.vehicleType == 1">大车</view>
+            <view v-if="type.vehicleType == 2">超大型车</view>
+            <view v-if="type.vehicleType == 3">摩托车</view>
+            <view v-if="type.vehicleType == 4">非机动车</view>
+            <view v-if="type.vehicleType == 5">其他</view>
+            <view class="charge-rules-right">
+              <view v-for="(time, tIndex) in type.list" :key="tIndex">
+                <text>{{ time.beginTime.substring(0, 5) }}-{{ time.beginTime > time.endTime ? '次日' : '' }}{{ time.endTime.substring(0, 5) }}</text>
+                <text>{{ time.amt }}元/小时</text>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view class="charge-instructions">
+      <u-parse :html="chargeContent"></u-parse>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      roadNo: '',
+			parkNo: '',
+      info: {
+        freeTime: '',
+        topAmt: ''
+      },
+      chargeRulesInfo: [],
+      // 收费标准说明
+      chargeContent: ''
+    };
+  },
+  onLoad(page) {
+    const { roadNo, parkNo } = page;
+    if (roadNo) {
+      this.roadNo = roadNo;
+      this.getSysterms(3);
+      this.getChargeRulesInfo(roadNo);
+    } else if (parkNo) {
+			this.parkNo = parkNo;
+			this.getSysterms(3);
+			this.getParkingChargeRulesInfo(parkNo);
+		} else {
+      uni.showToast({
+        title: '参数丢失,返回上一个页面',
+        duration: 2000,
+        icon: 'none',
+        mask: true
+      });
+    }
+  },
+  onShow() {},
+  methods: {
+    /**
+     * 获取收费标准
+     * {roadNo} 路段
+     * */
+    getChargeRulesInfo(roadNo) {
+      this.$u.api.roadChargeRule({ roadNo }).then((res) => {
+        if (res.code === 200) {
+          // 数据整合后
+          let chargeRulesArr = [];
+          for (let i = 0; i < res.data.length; i++) {
+            let item = res.data[i];
+            this.info.freeTime = res.data[0].freeTime;
+            this.info.topAmt = res.data[0].topAmt;
+            const obj = {
+              feeName: item.feeName,
+              feeNo: item.feeNo,
+              feePeriod: item.feePeriod,
+              feeStep: item.feeStep,
+              feeType: item.feeType,
+              freeTime: item.freeTime,
+              topAmt: item.topAmt,
+              id: item.id,
+              list: [],
+              repeatList: [] // 用来检验已存在
+            };
+            for (let j = 0; j < item.vehicleRules.length; j++) {
+              let jItem = item.vehicleRules[j];
+              const obj1 = {
+                amt: jItem.amt,
+                beginTime: jItem.beginTime,
+                endTime: jItem.endTime,
+                vehicleFeeNo: jItem.vehicleFeeNo,
+                vehicleType: jItem.vehicleType,
+                list: []
+              };
+              if (obj.repeatList.indexOf(jItem.vehicleType) === -1) {
+                obj.repeatList.push(jItem.vehicleType);
+                obj1.list.push(jItem);
+              } else {
+                for (let k = 0; k < item.vehicleRules.length; k++) {
+                  if (obj1.vehicleType === item.vehicleRules[k].vehicleType) {
+                    obj1.list.push(item.vehicleRules[k]);
+                    obj.list.push(obj1);
+                  }
+                }
+              }
+            }
+            // 存在重复,去除重复操作
+            let obj2 = {};
+            obj.list = obj.list.reduce((cur, next) => {
+              obj[next.vehicleType] ? '' : (obj[next.vehicleType] = true && cur.push(next));
+              return cur;
+            }, []);
+            chargeRulesArr.push(obj);
+          }
+          this.chargeRulesInfo = chargeRulesArr;
+        } else {
+          uni.showToast({
+            title: `${res.msg}`,
+            duration: 3000,
+            icon: 'none',
+            mask: true
+          });
+        }
+      });
+    },
+		/**
+		 * 获取收费标准
+		 * {roadNo} 路段
+		 * */
+		getParkingChargeRulesInfo(parkNo) {
+		  this.$u.api.parkingLotChargeRule({ parkNo }).then((res) => {
+		    if (res.code === 200) {
+		      // 数据整合后
+		      let chargeRulesArr = [];
+		      for (let i = 0; i < res.data.length; i++) {
+		        let item = res.data[i];
+		        this.info.freeTime = res.data[0].freeTime;
+		        this.info.topAmt = res.data[0].topAmt;
+		        const obj = {
+		          feeName: item.feeName,
+		          feeNo: item.feeNo,
+		          feePeriod: item.feePeriod,
+		          feeStep: item.feeStep,
+		          feeType: item.feeType,
+		          freeTime: item.freeTime,
+		          topAmt: item.topAmt,
+		          id: item.id,
+		          list: [],
+		          repeatList: [] // 用来检验已存在
+		        };
+		        for (let j = 0; j < item.vehicleRules.length; j++) {
+		          let jItem = item.vehicleRules[j];
+		          const obj1 = {
+		            amt: jItem.amt,
+		            beginTime: jItem.beginTime,
+		            endTime: jItem.endTime,
+		            vehicleFeeNo: jItem.vehicleFeeNo,
+		            vehicleType: jItem.vehicleType,
+		            list: []
+		          };
+		          if (obj.repeatList.indexOf(jItem.vehicleType) === -1) {
+		            obj.repeatList.push(jItem.vehicleType);
+		            obj1.list.push(jItem);
+		          } else {
+		            for (let k = 0; k < item.vehicleRules.length; k++) {
+		              if (obj1.vehicleType === item.vehicleRules[k].vehicleType) {
+		                obj1.list.push(item.vehicleRules[k]);
+		                obj.list.push(obj1);
+		              }
+		            }
+		          }
+		        }
+		        // 存在重复,去除重复操作
+		        let obj2 = {};
+		        obj.list = obj.list.reduce((cur, next) => {
+		          obj[next.vehicleType] ? '' : (obj[next.vehicleType] = true && cur.push(next));
+		          return cur;
+		        }, []);
+		        chargeRulesArr.push(obj);
+		      }
+		      this.chargeRulesInfo = chargeRulesArr;
+		    } else {
+		      uni.showToast({
+		        title: `${res.msg}`,
+		        duration: 3000,
+		        icon: 'none',
+		        mask: true
+		      });
+		    }
+		  });
+		},
+    /**
+     * 获取收费标准
+     * */
+    getSysterms(termsType) {
+      this.$u.api
+        .getSysterms({
+          termsType: Number(termsType)
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.chargeContent = res.data?.content;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '系统错误!',
+            type: 'error'
+          });
+        });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './chargeStandard.scss';
+</style>

+ 118 - 0
pages/choosePayment/choosePayment.scss

@@ -0,0 +1,118 @@
+.pay-content {
+  padding: 40rpx;
+  .pay-list {
+    &-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      height: 104rpx;
+      border-top: solid 1px #eeeeee;
+      &-image {
+        display: flex;
+        font-size: 30rpx;
+        color: #1E1E1E;
+        .image {
+          width: 54rpx;
+          height: 45rpx;
+          margin-right: 20rpx;
+        }
+				text {
+					font-size: 20rpx;
+          color: #FA6400;
+          margin-left: 10rpx;
+				}
+      }
+      &:last-child {
+        border-bottom: solid 1px #eeeeee;
+      }
+    }
+  }
+  .pay-money {
+    text-align: center;
+    font-size: 38rpx;
+    color: #008CFF;
+    margin-top: 20rpx;
+    font-weight: bold;
+    .original-discount-money {
+      text-decoration: line-through;
+      color: #333;
+      font-size: 24rpx;
+      margin-left: 20rpx;
+    }
+  }
+  .pay-btn {
+    margin-top: 34rpx;
+  }
+}
+.coupon-popup {
+  position: relative;
+  min-height: 100vh;
+  overflow-y: auto;
+  background-color: #F9F9F9;
+  &-list {
+    padding: 30rpx;
+    &-item {
+      background-color: #fff;
+      border-radius: 17rpx;
+      margin-bottom: 20rpx;
+      &-top {
+        padding: 30rpx;
+        display: flex;
+        justify-content: space-between;
+        align-items: baseline;
+        border-bottom: 1px solid #EEEEEE;
+        &-left {
+          display: flex;
+          align-items: baseline;
+          .cplitl-left {
+            color: #FF6D6D;
+            font-size: 20rpx;
+            margin-right: 34rpx;
+            text:last-child {
+              font-size: 60rpx;
+              font-weight: bold;
+            }
+            &-bottom {
+              color: #333333;
+              font-size: 24rpx;
+            }
+          }
+          .cplitl-right {
+            view {
+              &:first-child {
+                font-size: 32rpx;
+                color: #333333;
+                font-weight: 700;
+                margin-bottom: 8rpx;
+              }
+              &:last-child {
+                font-size: 20rpx;
+                color: #666;
+              }
+            }
+          }
+        }
+      }
+      &-bottom {
+        color: #999999;
+        padding: 10rpx 30rpx;
+        font-size: 20rpx;
+        .cplib-point {
+          margin-top: 10rpx;
+          &-content {
+            padding-top: 10rpx;
+            font-size: 24rpx;
+            color: #999999;
+          }
+        }
+      }
+    }
+  }
+  &-btn {
+    width: 100%;
+    padding: 80rpx 30rpx;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+  }
+}

+ 769 - 0
pages/choosePayment/choosePayment.vue

@@ -0,0 +1,769 @@
+<template>
+  <view>
+    <u-modal
+      v-model="payWayPop"
+      :title-style="{ color: '#1E1E1E', fontSize: '34rpx' }"
+      title="选择支付方式"
+      width="600rpx"
+      :show-confirm-button="false"
+      :show-cancel-button="false"
+      :mask-close-able="true"
+      @input="modalClose"
+    >
+      <view class="pay-content">
+        <view class="pay-list">
+          <radio-group @change="payRadioChange">
+            <template v-if="projectFlag !== 'zhenning' && projectFlag !== 'wudang'">
+              <!-- #ifdef H5 || MP-WEIXIN -->
+              <view class="pay-list-item" v-if="wxEnv">
+                <view class="pay-list-item-image">
+                  <image class="image" src="/static/img/wechat-icon-new.png" mode="aspectFit" />
+                  <view>微信支付</view>
+                </view>
+                <view class="radioBox">
+                  <radio color="#2DCF8C" value="weixin" :checked="'weixin' === radioCurrent" />
+                </view>
+              </view>
+              <!-- #endif -->
+            </template>
+            <template v-if="alipayEnv && projectFlag === 'puding'">
+              <view class="pay-list-item">
+                <view class="pay-list-item-image">
+                  <image class="image" src="/static/img/alipay-icon-new.png" mode="aspectFit" />
+                  <view>支付宝支付<text>随机立减最高10元</text></view>
+                </view>
+                <view class="radioBox">
+                  <radio color="#2DCF8C" value="juhe" :checked="'juhe' === radioCurrent" />
+                </view>
+              </view>
+            </template>
+            <view class="pay-list-item">
+              <view class="pay-list-item-image">
+                <image class="image" src="/static/img/gy-icon-new.png" mode="aspectFit" />
+                <view>贵州银行</view>
+              </view>
+              <view class="radioBox">
+                <radio color="#2DCF8C" value="gzyh" :checked="'gzyh' === radioCurrent" />
+              </view>
+            </view>
+            <template v-if="projectFlag === 'zhenning'">
+              <view class="pay-list-item">
+                <view class="pay-list-item-image">
+                  <image class="image" src="/static/img/wechat-icon-new.png" mode="aspectFit" />
+                  <view>微信/支付宝</view>
+                </view>
+                <view class="radioBox">
+                  <radio color="#2DCF8C" value="weixinzn" :checked="'weixinzn' === radioCurrent" />
+                </view>
+              </view>
+            </template>
+            <template v-if="projectFlag !== 'zhenning'">
+              <view class="pay-list-item">
+                <view class="pay-list-item-image">
+                  <image class="image" src="/static/img/juhe-icon-new.png" mode="aspectFit" />
+                  <view>聚合支付</view>
+                </view>
+                <view class="radioBox">
+                  <radio color="#2DCF8C" value="juhe" :checked="'juhe' === radioCurrent" />
+                </view>
+              </view>
+            </template>
+          </radio-group>
+        </view>
+        <view class="pay-coupon" v-if="radioCurrent === 'weixin' && isShowCoupon">
+          <u-cell-group :border="false">
+            <u-cell-item
+              icon=""
+              title="优惠券"
+              :value="couponPopup.currentCoupon.couponName || (couponPopup.couponList.length ? '暂未选择优惠券' : '无可用优惠券')"
+              :border-bottom="false"
+              @click="chooseCoupon"
+            ></u-cell-item>
+          </u-cell-group>
+        </view>
+        <view class="pay-money">
+          <text class="discount-money" v-if="couponPopup.currentCoupon.couponContent && radioCurrent === 'weixin'"
+            >¥ {{ getDifference(orderMoney, couponPopup.currentCoupon.couponContent).toFixed(2) }}</text
+          >
+          <text class="original-money" :class="couponPopup.currentCoupon.couponContent && radioCurrent === 'weixin' && 'original-discount-money'"
+            >¥ {{ orderMoney }}</text
+          >
+        </view>
+        <view class="pay-btn">
+          <u-button type="primary" shape="circle" :disabled="!radioCurrent" @tap="$u.debounce(immediatePayment, 1500, true)">立即支付</u-button>
+        </view>
+      </view>
+    </u-modal>
+    <!-- 选择优惠券弹框 -->
+    <u-popup v-model="couponPopup.show" mode="top" length="100%">
+      <view class="coupon-popup">
+        <u-navbar
+          back-text=""
+          title="我的优惠券"
+          :background="couponPopup.background"
+          title-color="#fff"
+          back-icon-color="#fff"
+          :custom-back="customBack"
+        />
+        <view class="coupon-popup-list">
+          <template v-if="couponPopup.couponList.length">
+            <radio-group @change="couponRadioChange">
+              <view class="coupon-popup-list-item" v-for="(item, index) in couponPopup.couponList" :key="index">
+                <view class="coupon-popup-list-item-top">
+                  <view class="coupon-popup-list-item-top-left">
+                    <view class="cplitl-left">
+                      <view>
+                        <text>¥</text>
+                        <text>{{ item.couponContent }}</text>
+                      </view>
+                      <view class="cplitl-left-bottom">{{ Number(item.threshold) > 0 ? `停车时长满${item.threshold}分钟` : '无门槛' }}</view>
+                    </view>
+                    <view class="cplitl-right">
+                      <view>{{ item.couponName }}</view>
+                      <view>有限期:剩余{{ calcValidity(item.startTime, item.endTime) }}</view>
+                    </view>
+                  </view>
+                  <view class="coupon-popup-list-item-top-right">
+                    <radio color="#FF6D6D" :value="item.id" :checked="item.id === couponPopup.radioCurrent" @click="couponItemClick(item)" />
+                  </view>
+                </view>
+                <view class="coupon-popup-list-item-bottom">
+                  适用停车点:
+                  <template v-if="item.parkList">
+                    <template v-if="item.parkList.length > 1"> 适用多个停车点 </template>
+                    <template v-else> 仅限{{ item.parkList.map((item) => item.parkName).join('、') }} </template>
+                    <template v-if="item.parkList && item.parkList.length > 1">
+                      <view class="cplib-point">
+                        <u-read-more
+                          text-indent="0"
+                          show-height="0"
+                          :toggle="true"
+                          :shadow-style="{ backgroundImage: 'none' }"
+                          fontSize="20rpx"
+                          close-text="展开所有停车点"
+                        >
+                          <view class="cplib-point-content">{{ item.parkList.map((item) => item.parkName).join('、') }}</view>
+                        </u-read-more>
+                      </view>
+                    </template>
+                  </template>
+                </view>
+              </view>
+            </radio-group>
+          </template>
+          <template v-else>
+            <u-empty text="没有适合的优惠券" mode="coupon" margin-top="300"></u-empty>
+          </template>
+        </view>
+        <view class="coupon-popup-btn">
+          <u-button type="primary" shape="circle" @click="confimCoupon">确 定</u-button>
+        </view>
+      </view>
+    </u-popup>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import { getEnvIsWx, getEnvIsAlipay } from '@/utils/judgEnvironment.js';
+import $wxPay from '@/utils/wxPay.js';
+export default {
+  props: {
+    // 订单数组
+    curOrderList: {
+      type: Array,
+      default: null
+    },
+    // 设备编号
+    deviceNo: {
+      type: String,
+      default: null
+    },
+    // 地磁支付需要字段
+    payeeId: {
+      type: String,
+      default: undefined
+    },
+    // 地磁支付需要字段
+    payeeName: {
+      type: String,
+      default: undefined
+    },
+    // 扫码支付需要字段
+    sanPay: {
+      type: Boolean,
+      default: false
+    },
+    // 追缴类型
+    pursueType: {
+      type: String,
+      default: undefined
+    },
+    // 车牌号
+    vehicleNo: {
+      type: String,
+      default: undefined
+    },
+    // 跳转页面
+    jumpUrl: {
+      type: String,
+      default: null
+    },
+    // 出口扫码   接口不一样
+    exportFlag: {
+      type: Boolean,
+      default: false
+    },
+    // 区分包月支付
+    isMonthPay: {
+      type: Boolean,
+      default: false
+    },
+    // 包月id
+    monthId: {
+      type: String,
+      default: null
+    },
+    // 室内扫码
+    isIndoor: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      // 支付弹框显示
+      payWayPop: false,
+      // 是否微信环境
+      wxEnv: true,
+      // 支付宝环境
+      alipayEnv: true,
+      // 支付方式选择
+      radioCurrent: '',
+      // 订单金额
+      orderMoney: '',
+      // 显示优惠券选项
+      isShowCoupon: false,
+      // 是否取消优惠券标识
+      isCancelCoupon: false,
+      // 选择优惠券弹框
+      couponPopup: {
+        // 弹框标识
+        show: false,
+        // 优惠券列表
+        couponList: [],
+        // 优惠券选中项value
+        radioCurrent: '',
+        // navbar背景
+        background: {
+          backgroundColor: '#008CFF'
+        },
+        // 优惠券选中项
+        currentCoupon: {}
+      }
+    };
+  },
+  methods: {
+    /**
+     * 打开弹框触发
+     * @date 2023-02-17
+     * @param {any} details
+     * @param {any} numType   single 单笔订单  multiple 多比订单  用于区分多笔订单不能使用优惠券
+     * @param {any} orderType   road 路段订单  parking 停车场订单  用于区分路段订单不使用优惠券
+     * @returns {any}
+     */
+    openPopup(details, numType = 'single', orderType = 'road') {
+      // 获取环境信息
+      this.wxEnv = getEnvIsWx();
+      // 判断支付宝环境
+      this.alipayEnv = getEnvIsAlipay();
+      if (this.projectFlag === 'zhenning') {
+        this.radioCurrent = 'weixinzn';
+      } else if (this.wxEnv) {
+        this.radioCurrent = 'weixin';
+      } else {
+        this.radioCurrent = 'juhe';
+      }
+      // 打开弹出层
+      this.payWayPop = true;
+      // 计算订单金额
+      this.orderMoney = details.payAmount.toFixed(2);
+      // 如果是单个停车订单,且是路边停车,且不是月卡支付,则显示优惠券
+      if (numType === 'single' && orderType === 'parking' && !this.isMonthPay && this.wxEnv) {
+        this.isShowCoupon = true;
+        this.isCancelCoupon = true;
+        this.getCouponList(details.id);
+      }
+    },
+    /**
+     * 获取优惠券列表
+     * @date 2023-02-17
+     * @param {any} orderId
+     * @returns {any}
+     */
+    getCouponList(orderId) {
+      this.$u.api.getCouponByOrderIdApi({ orderId }).then((res) => {
+        this.couponPopup.couponList = res?.data ?? [];
+      });
+    },
+    /**
+     * 选中支付类型
+     * @date 2023-02-17
+     * @param {any} {detail}
+     * @returns {any}
+     */
+    payRadioChange({ detail }) {
+      this.radioCurrent = detail.value;
+    },
+    /**
+     * 选中优惠券
+     * @date 2023-02-17
+     * @returns {any}
+     */
+    chooseCoupon() {
+      this.couponPopup.show = true;
+    },
+    /**
+     * 贵阳银行支付
+     * @param {Array} orderList 需要支付的订单号组成的数组
+     * @param {String} deviceNo 设备编号(只有车位锁部分有)
+     * */
+    async gyBankPay() {
+      const params = {
+        orderList: this.curOrderList,
+        deviceNo: this.deviceNo,
+        jumpUrl: this.jumpUrl,
+        payeeId: this.payeeId,
+        payeeName: this.payeeName,
+        pursueType: this.pursueType,
+        vehicleNo: this.vehicleNo,
+        sanPay: this.sanPay
+      };
+      const apiCall = this.exportFlag ? this.$u.api.quickPayExportApi : this.$u.api.payGzbank;
+      try {
+        const res = await apiCall({ ...params });
+        if (res.data.needPay) {
+          location.href = res.data.url;
+        } else {
+          this.showToast('无需支付', 'info');
+          setTimeout(() => {
+            location.reload();
+          }, 1000);
+        }
+      } catch (err) {
+        // this.showToast(err.msg, 'error');
+      }
+    },
+    /**
+     * @description: 贵阳银行包月支付
+     * @return {*}
+     */
+    async gyBankMonthPay() {
+      try {
+        const res = await this.$u.api.monthPay({ monthId: this.monthId, jumpUrl: this.jumpUrl });
+        if (res.code === 200) {
+          location.href = res?.data?.url;
+        }
+      } catch (err) {
+        this.showToast('无法调起支付', 'error');
+      }
+    },
+    /**
+     * @description: 显示报错信息
+     * @param {*} title
+     * @param {*} type
+     * @return {*}
+     */
+    showToast(title, type = 'error') {
+      this.$refs.uToast.show({ title, type });
+    },
+    /**
+     * 聚合支付
+     * */
+    juhePay() {
+      this.getWXPayByJava(this.curOrderList, this.deviceNo);
+    },
+    /**
+     * @description: 聚合包月支付
+     * @return {*}
+     */
+    async juheMonthPay() {
+      const params = { monthId: this.monthId, jumpUrl: this.jumpUrl };
+      try {
+        const res = await this.$u.api.monthlyWxPay({ ...params });
+        if (res.code === 200) {
+          ocalStorage.setItem('jumpUrl', this.jumpUrl);
+          location.href = res.data.qrCodeUrl;
+        }
+      } catch (err) {
+        // this.showToast(`无法调起${this.alipayEnv ? '支付宝' : this.wxEnv ? '微信' : '聚合'}支付!`, type: 'error');
+      }
+    },
+    /**
+     * 微信支付处理参数
+     */
+    wechatPay() {
+      const params = {
+        orderList: this.curOrderList,
+        openid: this.vuex_wxinfo.openId,
+        deviceNo: this.deviceNo || undefined,
+        payeeId: this.payeeId || undefined,
+        payeeName: this.payeeName || undefined,
+        vehicleNo: this.vehicleNo,
+        sanPay: this.sanPay
+      };
+      if (this.couponPopup.radioCurrent) {
+        params.couponMemberId = this.couponPopup.radioCurrent;
+      }
+      this.handleWxPay.call(this, params);
+    },
+    /**
+     * @description: 微信支付
+     * @param {*} params
+     * @return {*}
+     */
+    handleWxPay(params) {
+      const api = this.exportFlag ? this.$u.api.parkingWechatPayApi : this.$u.api.wechatPayApi;
+      api(params).then((res) => {
+        if (res.code !== 200) {
+          return;
+        }
+        if (!res.data.needPay) {
+          this.showToast('无需支付', 'info');
+          setTimeout(() => {
+            uni.hideLoading();
+            location.reload();
+          }, 1000);
+          return;
+        }
+        $wxPay.weixinPay(res.data.wx).then((r) => {
+          const messageMap = {
+            0: '成功',
+            1: '已取消支付',
+            2: '支付失败,请检查!'
+          };
+          switch (Number(r.code)) {
+            case 0: // 成功
+              //#ifdef H5
+              location.reload();
+              //#endif
+              break;
+            case 1: // 取消
+              if (this.isCancelCoupon) {
+                this.cancelCoupon(messageMap[r.code]);
+              } else {
+                this.showToast(messageMap[r.code], 'info');
+              }
+              break;
+            case 2: // 支付失败
+              this.showToast(messageMap[r.code], 'error');
+              break;
+          }
+        });
+      });
+    },
+    /**
+     * @description: 取消优惠券
+     * @param {*} msg
+     * @return {*}
+     */
+    async cancelCoupon(msg) {
+      try {
+        const { code } = await this.$u.api.updateCouponStatusApi({ orderList: this.curOrderList });
+        if (code === 200) {
+          this.showToast(msg, 'info');
+          location.reload();
+        }
+      } catch (error) {}
+    },
+    /**
+     * @description: 微信包月支付
+     * @return {*}
+     */
+    wechatMonthPay() {
+      this.$u.api.wechatMonthlyPayapi({ monthId: this.monthId, openid: this.vuex_wxinfo.openId }).then((response) => {
+        if (response.code === 200) {
+          $wxPay.weixinPay(response.data.wx).then((res) => {
+            this.handleMonthlyPay.call(this, res);
+          });
+        }
+      });
+    },
+    /**
+     * @description: 微信包月支付响应处理
+     * @param {*} response
+     * @return {*}
+     */
+    handleMonthlyPay(response) {
+      const messageMap = {
+        0: { title: '成功', jumpUrl: this.jumpUrl },
+        1: { title: '已取消支付' },
+        2: { title: '支付失败,请检查!', type: 'error' }
+      };
+      const message = messageMap[Number(response.code)];
+      this.showToast(message.title, message.type || 'info');
+      if (message.jumpUrl) {
+        location.href = message.jumpUrl;
+      }
+    },
+    /**
+     * 直接通过后台获取贵阳银行微信支付地址
+     * @param {Array} list 需要支付的订单组合数组
+     * @param {Number} deviceNo 设备编号(在停车锁部分需要)
+     * */
+    async getWXPayByJava(orderList, deviceNo) {
+      try {
+        let params = {
+          orderList,
+          openid: this.vuex_wxinfo.openId,
+          jumpUrl: this.jumpUrl,
+          deviceNo: deviceNo ? deviceNo : null,
+          payeeId: this.payeeId,
+          payeeName: this.payeeName,
+          pursueType: this.pursueType,
+          vehicleNo: this.vehicleNo,
+          sanPay: this.sanPay
+        };
+        const api = this.exportFlag ? 'polyPayExportApi' : 'ordinaryWxPay'; // 优化代码
+        const res = await this.$u.api[api](params);
+        if (res.code === 200) {
+          if (res.data.needPay) {
+            localStorage.setItem('jumpUrl', this.jumpUrl);
+            location.href = res.data.qrCodeUrl;
+          } else {
+            this.showToast('无需支付', 'info');
+            setTimeout(() => {
+              location.href = this.jumpUrl;
+            }, 1000);
+          }
+        } else {
+          uni.hideLoading();
+        }
+      } catch (err) {
+        // this.showToast(`无法调起${this.alipayEnv ? '支付宝' : this.wxEnv ? '微信' : '聚合'}支付!`, 'error');
+      }
+    },
+    /**
+     * @description: 镇宁微信支付
+     * @param {*} orderList
+     * @param {*} deviceNo
+     * @return {*}
+     */
+    async znWechatPay() {
+      try {
+        const params = {
+          orderList: this.curOrderList,
+          openid: '',
+          jumpUrl: this.jumpUrl,
+          deviceNo: this.deviceNo ? this.deviceNo : null,
+          payeeId: this.payeeId,
+          payeeName: this.payeeName,
+          pursueType: this.pursueType
+        };
+        const res = await this.$u.api.ordinaryWxPay(params);
+        if (res.code === 200) {
+          const { needPay, qrCodeUrl } = res.data;
+          if (needPay) {
+            localStorage.setItem('jumpUrl', this.jumpUrl);
+            location.href = qrCodeUrl;
+          } else {
+            this.showToast('无需支付', 'info');
+            setTimeout(() => {
+              location.href = this.jumpUrl;
+            }, 1000);
+          }
+        } else {
+          uni.hideLoading();
+        }
+      } catch (err) {
+        this.showToast('无法调起微信支付!', 'error');
+      }
+    },
+    /**
+     * @description: 镇宁聚合
+     * @return {*}
+     */
+    async getWXMonthPayByJava() {
+      const { monthId, jumpUrl } = this;
+      try {
+        const res = await this.$u.api.monthlyWxPay({ monthId, jumpUrl });
+        if (res.code === 200) {
+          localStorage.setItem('jumpUrl', jumpUrl);
+          location.href = res.data.qrCodeUrl;
+        }
+      } catch (err) {
+        // this.showToast('无法调起支付!', 'error');
+      }
+    },
+    /**
+     * 支付弹框关闭触发
+     * @date 2023-02-17
+     * @returns {any}
+     */
+    modalClose() {
+      Object.assign(this, {
+        payWayPop: false,
+        wxEnv: true,
+        alipayEnv: true,
+        radioCurrent: '',
+        orderMoney: '',
+        isShowCoupon: false,
+        isCancelCoupon: false,
+        couponPopup: {
+          show: false,
+          couponList: [],
+          radioCurrent: '',
+          background: {
+            backgroundColor: '#008CFF'
+          },
+          currentCoupon: {}
+        }
+      });
+      this.$emit('closePaymentMethod');
+    },
+    /**
+     * 关闭优惠券弹框
+     * @date 2023-02-17
+     * @returns {any}
+     */
+    customBack() {
+      this.couponPopup.show = false;
+    },
+    /**
+     * 优惠券单选触发
+     * @date 2023-02-17
+     * @param {any} val
+     * @returns {any}
+     */
+    couponRadioChange(val) {
+      // this.couponPopup.radioCurrent = val.detail.value;
+      // this.couponPopup.currentCoupon = this.couponPopup.couponList.find((item) => item.id === this.couponPopup.radioCurrent);
+    },
+    couponItemClick(item) {
+      this.couponPopup.radioCurrent = item.id === this.couponPopup.radioCurrent ? '' : item.id;
+    },
+    /**
+     * 优惠券确认
+     * @date 2023-02-17
+     * @returns {any}
+     */
+    confimCoupon() {
+      this.couponPopup.currentCoupon = this.couponPopup.radioCurrent
+        ? this.couponPopup.couponList.find((item) => item.id === this.couponPopup.radioCurrent)
+        : {};
+      this.couponPopup.show = false;
+    },
+    /**
+     * 立即支付
+     * @date 2023-02-17
+     * @returns {any}
+     */
+    async immediatePayment() {
+      if (this.isIndoor) {
+        const relationObj = {
+          weixin: 'wechat',
+          gzyh: 'quick',
+          juhe: 'poly'
+        };
+        this.indoorPayment(relationObj[this.radioCurrent]);
+      } else {
+        const paymentMethods = {
+          weixin: this.isMonthPay ? this.wechatMonthPay : this.wechatPay,
+          gzyh: this.isMonthPay ? this.gyBankMonthPay : this.gyBankPay,
+          juhe: this.isMonthPay ? this.juheMonthPay : this.juhePay,
+          weixinzn: this.isMonthPay ? this.getWXMonthPayByJava : this.znWechatPay
+        };
+        const paymentMethod = paymentMethods[this.radioCurrent];
+        if (paymentMethod) {
+          await paymentMethod.call(this);
+        }
+      }
+    },
+    /**
+     * @description: 室内支付
+     * @param {*} payMode
+     * @return {*}
+     */
+    async indoorPayment(payMode) {
+      const { curOrderList, couponPopup, vuex_wxinfo, jumpUrl } = this;
+      const params = {
+        orderList: curOrderList,
+        payMode,
+        couponMemberId: couponPopup?.radioCurrent,
+        openid: vuex_wxinfo?.openId,
+        sanPay: true,
+        jumpUrl
+      };
+      const { code, data } = await this.$u.api.indoorPaymentApi({ ...params });
+      if (code === 200) {
+        if (data?.needPay) {
+          switch (payMode) {
+            case 'wechat': // 微信支付
+              $wxPay.weixinPay(data?.wechat?.wx).then((r) => {
+                const messageMap = {
+                  0: '成功',
+                  1: '已取消支付',
+                  2: '支付失败,请检查!'
+                };
+                switch (Number(r.code)) {
+                  case 0: // 成功
+                    //#ifdef H5
+                    this.jumpUrl ? (location.href = `${this.jumpUrl}&polyOrderId=${data.polyOrderId}`) : location.reload();
+                    //#endif
+                    break;
+                  case 1: // 取消
+                    if (this.isCancelCoupon) {
+                      this.cancelCoupon(messageMap[r.code]);
+                    } else {
+                      this.showToast(messageMap[r.code], 'info');
+                    }
+                    break;
+                  case 2: // 支付失败
+                    this.showToast(messageMap[r.code], 'error');
+                    break;
+                }
+              });
+              break;
+            case 'quick': // 快捷支付
+              location.href = data?.quick?.url;
+              break;
+            case 'poly':
+              localStorage.setItem('jumpUrl', this.jumpUrl);
+              location.href = data?.poly?.qrCodeUrl;
+              break;
+          }
+        } else {
+          this.showToast('无需支付', 'info');
+          setTimeout(() => {
+            this.jumpUrl ? (location.href = `${this.jumpUrl}&polyOrderId=${data.polyOrderId}`) : location.reload();
+          }, 1000);
+        }
+      }
+    },
+    /**
+     * 计算剩余时间
+     * @date 2022-02-17
+     * @param {any} datetime
+     * @returns {any}
+     */
+    calcValidity(startTime, endTime) {
+      let endTimeStr = new Date(endTime).valueOf(),
+        nowTimeStr = new Date(startTime).valueOf() < Date.now() ? Date.now() : new Date(startTime).valueOf(),
+        remainTimeStr = endTimeStr - nowTimeStr,
+        day = Math.floor(remainTimeStr / (1000 * 3600 * 24)),
+        dayOver = remainTimeStr % (1000 * 3600 * 24),
+        hours = Math.floor(dayOver / (3600 * 1000)),
+        hourOver = dayOver % (3600 * 1000),
+        minutes = Math.floor(hourOver / (60 * 1000));
+      return `${day}天${hours}小时${minutes}分`;
+    },
+    getDifference(a, b) {
+      return a > b ? a - b : 0;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './choosePayment.scss';
+</style>

+ 21 - 0
pages/common/paymentSuccess/paymentSuccess.scss

@@ -0,0 +1,21 @@
+.payment-success {
+  width: calc(100% - 60rpx);
+  margin: 0 auto;
+
+  &-icon {
+    width: 441rpx;
+    height: 100%;
+    margin: 0 auto;
+    padding: 133rpx 0 55rpx 0;
+  }
+
+  &-content {
+    color: #4ccd8a;
+    font-size: 50rpx;
+    text-align: center;
+  }
+
+  &-cancel {
+    margin-top: 202rpx;
+  }
+}

+ 38 - 0
pages/common/paymentSuccess/paymentSuccess.vue

@@ -0,0 +1,38 @@
+<!-- 支付成功 -->
+<template>
+  <view class="payment-success">
+    <view class="payment-success-icon">
+      <u-image width="441rpx" height="441rpx" src="/static/img/payment-success-icon.svg" />
+    </view>
+    <view class="payment-success-content">
+      <text>支付成功!</text>
+    </view>
+    <view class="payment-success-cancel">
+      <u-button type="primary" @click="cancelClick">返回</u-button>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    /**
+     * @description: 返回操作
+     * @return {*}
+     */
+    cancelClick() {
+      this.$u.route({
+        url: '/pages/center/order/order',
+        type: 'redirectTo'
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './paymentSuccess.scss';
+</style>

+ 115 - 0
pages/favourableActivity/favourableActivity.scss

@@ -0,0 +1,115 @@
+.container {
+  height: calc(100vh - 88rpx);
+  .penny-parking {
+    height: 100%;
+    background-color: #b3ddff;
+    padding-top: 39rpx;
+    .penny-parking-icon {
+      width: calc(100% - 56rpx);
+      height: 141rpx;
+      margin: 0 auto;
+      background-image: url('/static/img/penny-parking-icon.png');
+      background-position: center center;
+      background-size: 100% 100%;
+    }
+    .penny-parking-content {
+      width: 100%;
+      background-image: url('/static/img/penny-parking-bg.png');
+      background-position: center 40px;
+      background-repeat: no-repeat;
+      view {
+        &:nth-child(1) {
+          color: #4e4e4e;
+          font-size: 28rpx;
+          font-weight: 300;
+          text-align: center;
+        }
+        &:nth-child(2) {
+          margin-top: 400rpx;
+          color: #1a517e;
+          font-weight: 400;
+          font-size: 26rpx;
+          line-height: 52rpx;
+          padding: 0 39rpx;
+        }
+        &:nth-child(3) {
+          margin-top: 60rpx;
+          color: #1a517e;
+          font-weight: 400;
+          font-size: 26rpx;
+          line-height: 52rpx;
+          padding: 0 39rpx;
+        }
+        button {
+          width: calc(100% - 56rpx);
+          height: 96rpx;
+          line-height: 96rpx;
+          background-color: #008cff;
+          color: #fff;
+          margin-top: 80rpx;
+          border-radius: 10rpx;
+          font-size: 28rpx;
+          font-weight: 500;
+          border: none;
+        }
+      }
+    }
+  }
+  .eighty-percent-of-parking {
+    height: 100%;
+    background-color: #ffecec;
+    padding-top: 39rpx;
+    .penny-parking-icon {
+      width: calc(100% - 84rpx);
+      height: 141rpx;
+      margin: 0 auto;
+      background-image: url('/static/img/eighty-percent-parking-icon.png');
+      background-position: center center;
+      background-size: 100% 100%;
+    }
+    .penny-parking-content {
+      width: 100%;
+      background-image: url('/static/img/eighty-percent-parking-bg.png');
+      background-size: 554rpx 551rpx;
+      background-position: top;
+      background-repeat: no-repeat;
+      view {
+        &:nth-child(1) {
+          color: #4f4f4f;
+          font-size: 30rpx;
+          font-weight: 300;
+          text-align: center;
+        }
+        &:nth-child(2) {
+          margin-top: 500rpx;
+          color: #946969;
+          font-weight: 400;
+          font-size: 26rpx;
+          line-height: 52rpx;
+          padding: 0 39rpx;
+        }
+        &:nth-child(3) {
+          margin-top: 60rpx;
+          color: #946969;
+          font-weight: 400;
+          font-size: 26rpx;
+          line-height: 52rpx;
+          padding: 0 39rpx;
+        }
+        button {
+          width: calc(100% - 56rpx);
+          height: 96rpx;
+          line-height: 96rpx;
+          background-color: #ffbaba;
+          background: linear-gradient(#ffa9a9, #ff8c8c);
+          color: #fff;
+          margin-top: 60rpx;
+          border-radius: 10rpx;
+          font-size: 28rpx;
+          font-weight: 500;
+          border: none;
+        }
+      }
+    }
+  }
+}

+ 67 - 0
pages/favourableActivity/favourableActivity.vue

@@ -0,0 +1,67 @@
+<template>
+  <!-- 优惠活动 -->
+  <view class="container">
+    <view class="penny-parking" v-if="id == 1">
+      <view class="penny-parking-icon"></view>
+      <view class="penny-parking-content">
+        <view>使用贵州银行支付可一分钱停车</view>
+        <view
+          >从客户启用贵州银行行卡支付的第四个月开始,使用我行卡支付永久享受八折优惠(单日不限次数)。时间计算同上。三个月最后一天,假如车主跨天的话,拆分账单计算:三个月内一分钱或八折,三个月外时段八折。
+        </view>
+        <view>如果停车场、路边停车位有{{ free_time }}分钟内等免费政策的,我行客户自然享受后再按“一分钱停车”、“八折停车”执行。</view>
+        <view>
+          <button type="default" class="btn1" @click="openAcount">银行卡开户</button>
+        </view>
+      </view>
+    </view>
+    <view class="eighty-percent-of-parking" v-if="id == 2">
+      <view class="penny-parking-icon"></view>
+      <view class="penny-parking-content">
+        <view>使用贵州银行支付可享永久八折优惠</view>
+        <view
+          >从客户启用贵州银行行卡支付的第四个月开始,使用我行卡支付永久享受八折优惠(单日不限次数)。时间计算同上。三个月最后一天,假如车主跨天的话,拆分账单计算:三个月内一分钱或八折,三个月外时段八折。
+        </view>
+        <view>如果停车场、路边停车位有{{ free_time }}分钟内等免费政策的,我行客户自然享受后再按“一分钱停车”、“八折停车”执行。</view>
+        <view>
+          <button type="default" class="btn2" @click="openAcount">银行卡开户</button>
+        </view>
+      </view>
+    </view>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      id: ''
+    };
+  },
+  onLoad(page) {
+    if (page.title) {
+      uni.setNavigationBarTitle({
+        title: page.title
+      });
+      this.id = page.id;
+    } else {
+      uni.setNavigationBarTitle({
+        title: '一分钱停车'
+      });
+      this.id = 1;
+    }
+  },
+  onShow() {},
+  methods: {
+    openAcount() {
+      this.$refs.uToast.show({
+        title: '该功能尚未开发',
+        type: 'warning'
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+@import './favourableActivity.scss';
+</style>

+ 309 - 0
pages/geomagnetismLock/geomagnetismLock.scss

@@ -0,0 +1,309 @@
+.parking-lock {
+  height: calc(100vh - 88rpx);
+  background-color: #f6f6ff;
+  padding-top: 133rpx;
+  .parking-lock-title {
+    font-size: 46rpx;
+    color: #292929;
+    text-align: center;
+    padding-top: 31rpx;
+    line-height: 65rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+  }
+  .parking-lock-tips {
+    width: calc(100% - 72rpx);
+    font-size: 30rpx;
+    color: #777777;
+    text-align: center;
+    margin: 10rpx auto;
+    line-height: 47rpx;
+  }
+  .parking-lock-info {
+    width: calc(100% - 72rpx);
+    margin: 31rpx auto 54rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    padding: 39rpx 41rpx;
+    .parking-lock-info-item {
+      display: flex;
+      margin-bottom: 16rpx;
+      view {
+        font-size: 28rpx;
+        &:first-child {
+          width: 30%;
+          color: #2a2a2a;
+          font-weight: 500;
+        }
+        &:last-child {
+          color: #6e6e6e;
+        }
+      }
+      .weight {
+        color: #2a2a2a !important;
+        font-weight: 500;
+      }
+      .really-money {
+        color: #fa7319 !important;
+      }
+    }
+  }
+  .parking-lock-pay-btn {
+    width: calc(100% - 72rpx);
+    margin: 0 auto;
+    button {
+      width: 100%;
+      height: 100rpx;
+      line-height: 100rpx;
+      background-color: #008cff;
+      border: none;
+      color: #fff;
+      box-shadow: 0px 7px 13px 0px rgba(16, 153, 250, 0.31);
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+  }
+  .parking-lock-begin-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(270deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    // animation: spin 3s linear infinite;
+    .parking-lock-begin-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-begin-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-loading-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(0deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    animation: spin 3s linear infinite;
+    .parking-lock-loading-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-loading-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-success {
+    .parking-lock-success-box {
+      width: 441rpx;
+      height: 441rpx;
+      margin: 0 auto;
+      image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .parking-lock-success-info {
+      color: #4ccd8a;
+      font-size: 50rpx;
+      text-align: center;
+      margin: 56rpx 0 202rpx;
+    }
+    .parking-lock-success-button {
+      width: calc(100% - 80rpx);
+      margin: 0 auto;
+      button {
+        width: 100%;
+        height: 100rpx;
+        line-height: 100rpx;
+        background-color: #008cff;
+        font-size: 28rpx;
+        color: #fff;
+      }
+    }
+  }
+}
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 34rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}
+@keyframes rotate {
+  0% {
+    transform: rotate(0);
+  }
+  50% {
+    transform: rotate(200deg);
+  }
+  100% {
+    transform: rotate(0);
+  }
+}
+@keyframes spin {
+  from {
+    transform: rotate(0);
+  }
+  to {
+    transform: rotate(359deg);
+  }
+}
+.loadingSelect {
+  text-align: center;
+  margin-top: 20rpx;
+}
+.spinner {
+  margin: auto;
+  width: 50px;
+  height: 60px;
+  text-align: center;
+  font-size: 10px;
+}
+
+.spinner > view {
+  background-color: #6495ed;
+  height: 100%;
+  width: 10rpx;
+  margin-right: 2rpx;
+  display: inline-block;
+
+  -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
+  animation: stretchdelay 1.2s infinite ease-in-out;
+}
+
+.spinner .rect2 {
+  -webkit-animation-delay: -1.1s;
+  animation-delay: -1.1s;
+}
+
+.spinner .rect3 {
+  -webkit-animation-delay: -1s;
+  animation-delay: -1s;
+}
+
+.spinner .rect4 {
+  -webkit-animation-delay: -0.9s;
+  animation-delay: -0.9s;
+}
+
+.spinner .rect5 {
+  -webkit-animation-delay: -0.8s;
+  animation-delay: -0.8s;
+}
+
+@-webkit-keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    -webkit-transform: scaleY(1);
+  }
+}
+
+@keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    transform: scaleY(0.4);
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    transform: scaleY(1);
+    -webkit-transform: scaleY(1);
+  }
+}
+.new-plate-number {
+  margin-bottom: 70rpx;
+}
+.message-input-wrap {
+  margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item {
+  background-color: #e8ffe8;
+}
+.really-license-txt {
+  color: #008cff;
+}
+.really-license-txt1 {
+  color: #008cff;
+  margin: 20rpx;
+}
+.popup-vehicleNo-title {
+  font-size: 48rpx;
+  text-align: center;
+  padding-top: 20rpx;
+}
+.popup-vehicleNo-center {
+  width: 95%;
+  height: 2rpx;
+  border-top: solid rgb(146, 146, 146) 2rpx;
+  margin: 30rpx 20rpx 50rpx 20rpx;
+}
+.popup-vehicleNo-select {
+  text-align: center;
+  color: #777777;
+}
+.vehicleNo-btn {
+  display: flex;
+  margin: 40rpx 0;
+}
+.parking-lock-pay-attention {
+  margin: 50rpx;
+  line-height: 48rpx;
+  color: #777777;
+}

+ 283 - 0
pages/geomagnetismLock/geomagnetismLock.vue

@@ -0,0 +1,283 @@
+<template>
+  <!-- 地磁 -->
+  <view class="parking-lock">
+    <view class="Jump">
+      <view class="Jump-btn" @click="jumpArrears"> 欠费补缴 </view>
+    </view>
+    <!-- 地磁支付 -->
+    <template v-if="parkingLockStatus === 1">
+      <view class="parking-lock-pay">
+        <view class="parking-lock-title">支付停车费</view>
+        <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view>
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>车牌号</view>
+            <view class="weight">{{ orderInfo.vehicleNo }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>停车场名称</view>
+            <view>{{ orderInfo.roadName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>停车泊位</view>
+            <view>{{ orderInfo.spaceName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入场时间</view>
+            <view>{{ orderInfo.inTime }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>出场时间</view>
+            <view>{{ orderInfo.outTime }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>免费时长</view>
+            <view>{{ orderInfo.freeDuration || `0天0时${free_time}分0秒` }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>计费时长</view>
+            <view>{{ orderInfo.calcDuration || 0 }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>累计停车时长</view>
+            <view>{{ orderInfo.duration || 0 }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>应缴金额</view>
+            <view class="really-money">{{ orderInfo.payAmount || 0 }} 元</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>订单编号</view>
+            <view>{{ orderInfo.orderId }}</view>
+          </view>
+        </view>
+        <view class="parking-lock-pay-btn" v-if="is_pay">
+          <button type="default" @click="payMoney">立即支付</button>
+        </view>
+      </view>
+    </template>
+    <template v-else-if="parkingLockStatus === 2">
+      <view class="parking-lock-pay">
+        <view class="parking-lock-tips">{{ tipsMsg }}</view>
+      </view>
+    </template>
+    <!-- 支付方式 -->
+    <ChoosePayment
+      ref="choosePayment"
+      :curOrderList="[orderId]"
+      :jumpUrl="jumpUrl"
+      :payeeId="payeeId"
+      :payeeName="payeeName"
+      :pursueType="pursueType"
+      :vehicleNo="orderInfo.vehicleNo"
+    />
+    <u-popup v-model="show" mode="center" border-radius="14" width="200rpx" height="200rpx">
+      <view class="loadingSelect">订单查询中...</view>
+      <view class="spinner">
+        <view class="rect1"></view>
+        <view class="rect2"></view>
+        <view class="rect3"></view>
+        <view class="rect4"></view>
+        <view class="rect5"></view>
+      </view>
+    </u-popup>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import ChoosePayment from '@/pages/choosePayment/choosePayment.vue';
+export default {
+  components: {
+    ChoosePayment
+  },
+  data() {
+    return {
+      // 车位锁状态 1:需支付 2:查询失败返回提醒
+      parkingLockStatus: 0,
+      // 支付方式选择弹框
+      payWayPop: false,
+      // 订单编号
+      orderList: [],
+      // 提示信息
+      tipsMsg: null,
+      // 轮询
+      timer: null,
+      // 订单信息
+      orderInfo: {},
+      // 订单id
+      orderId: null,
+      // 重定向地址
+      jumpUrl: location.href + '&isBack=1',
+      show: false,
+      isBack: '',
+      polyOrderId: '',
+      // 地磁
+      spaceId: '',
+      payeeId: '',
+      payeeName: '',
+      pursueType: '',
+      is_pay: false
+    };
+  },
+  onLoad(page) {
+    if (page.orderId) {
+      this.orderId = page?.orderId;
+      this.spaceId = page?.spaceId;
+      this.payeeId = page?.payeeId;
+      this.polyOrderId = page?.polyOrderId;
+      this.pursueType = page?.pursueType;
+      this.isBack = page?.isBack;
+    } else {
+      this.tipsMsg = page.msg || '参数丢失!';
+      this.parkingLockStatus = 2;
+    }
+  },
+  onShow() {
+    if (this.orderId) {
+      this.getOrderDetails(this.spaceId, this.orderId, this.payeeId);
+      if (this.polyOrderId && this.isBack == 1) {
+        this.timer = setInterval(() => {
+          this.show = true;
+          this.handlePayStatus(this.polyOrderId);
+        }, 1000);
+      }
+    } else {
+      this.show = false;
+    }
+  },
+  onUnload() {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+  },
+  methods: {
+    jumpArrears() {
+      uni.navigateTo({
+        url: '../center/order/order?orderStatus=2'
+      });
+    },
+    /**
+     * 反复查询支付状态
+     * @param { String } orderId
+     */
+    handlePayStatus(orderId) {
+      this.$u.api
+        .getOrderInfo({
+          orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.payStatus === 1 || res.data.payStatus === 3) {
+              this.show = false;
+              clearInterval(this.timer);
+              this.is_pay = false;
+              uni.showModal({
+                title: '提示',
+                content: '支付成功,返回首页',
+                showCancel: false,
+                success: (res) => {
+                  if (res.confirm) {
+                    uni.switchTab({
+                      url: '/pages/index/index'
+                    });
+                  }
+                }
+              });
+            } else if (res.data.payStatus === 2) {
+              this.is_pay = true;
+            }
+          } else {
+            this.show = false;
+            clearInterval(this.timer);
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch(() => {
+          this.show = false;
+          clearInterval(this.timer);
+        });
+    },
+    /**
+     * 立即支付
+     */
+    payMoney() {
+      this.$nextTick(() => {
+        this.$refs['choosePayment'].openPopup({ ...this.orderInfo }, 'single', 'road');
+      });
+    },
+    /**
+     * 查询订单信息
+     * @param { String } spaceId 车位ID
+     * @param { String } orderId 订单id
+     * @param { String } payeeId 收费员ID
+     */
+    getOrderDetails(spaceId, orderId, payeeId) {
+      this.$u.api
+        .geomaLockDetailsApi({
+          spaceId,
+          orderId,
+          payeeId
+        })
+        .then((res) => {
+          if (res.code === 200 && res.data.id) {
+            this.payeeName = res.data.payeeName;
+            this.parkingLockStatus = 1;
+            this.orderInfo = res.data;
+            this.show = false;
+            if (res.data.payStatus == 0 || res.data.payStatus == 2 || res.data.payStatus == 3) {
+              this.is_pay = true;
+            } else if (res.data.payStatus == 1) {
+              this.is_pay = false;
+              uni.showModal({
+                title: '提示',
+                content: '订单已支付,返回首页',
+                showCancel: false,
+                success: function (res) {
+                  if (res.confirm) {
+                    uni.switchTab({
+                      url: '/pages/index/index'
+                    });
+                  }
+                }
+              });
+            }
+            if (res.data.payAmount == 0) {
+              this.is_pay = false;
+            }
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg || '订单无数据',
+              type: 'error'
+            });
+          }
+        });
+    },
+    /**
+     * 关闭支付弹框
+     */
+    closePaymentMethod() {
+      this.payWayPop = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './geomagnetismLock.scss';
+
+.Jump {
+  position: fixed;
+  top: 50px;
+  right: 0;
+  background-color: #f6f6ff;
+
+  &-btn {
+    color: rgb(0, 140, 255);
+    padding: 20rpx 30rpx;
+  }
+}
+</style>

+ 283 - 0
pages/geomagnetismLock/geomagnetismLock20230222.vue

@@ -0,0 +1,283 @@
+<template>
+  <!-- 地磁 -->
+  <view class="parking-lock">
+    <view class="Jump">
+      <view class="Jump-btn" @click="jumpArrears"> 欠费补缴 </view>
+    </view>
+    <!-- 地磁支付 -->
+    <template v-if="parkingLockStatus === 1">
+      <view class="parking-lock-pay">
+        <view class="parking-lock-title">支付停车费</view>
+        <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view>
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>车牌号</view>
+            <view class="weight">{{ orderInfo.vehicleNo }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>停车场名称</view>
+            <view>{{ orderInfo.roadName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>停车泊位</view>
+            <view>{{ orderInfo.spaceName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入场时间</view>
+            <view>{{ orderInfo.inTime }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>出场时间</view>
+            <view>{{ orderInfo.outTime }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>免费时长</view>
+            <view>{{ orderInfo.freeDuration || `0天0时${free_time}分0秒` }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>计费时长</view>
+            <view>{{ orderInfo.calcDuration || 0 }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>累计停车时长</view>
+            <view>{{ orderInfo.duration || 0 }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>应缴金额</view>
+            <view class="really-money">{{ orderInfo.payAmount || 0 }} 元</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>订单编号</view>
+            <view>{{ orderInfo.orderId }}</view>
+          </view>
+        </view>
+        <view class="parking-lock-pay-btn" v-if="is_pay">
+          <button type="default" @click="payMoney">立即支付</button>
+        </view>
+      </view>
+    </template>
+    <template v-else-if="parkingLockStatus === 2">
+      <view class="parking-lock-pay">
+        <view class="parking-lock-tips">{{ tipsMsg }}</view>
+      </view>
+    </template>
+    <!-- 支付方式 -->
+    <PaymentMethod
+      :payWayPop="payWayPop"
+      :curOrderList="[orderId]"
+      :jumpUrl="jumpUrl"
+      :payeeId="payeeId"
+      :payeeName="payeeName"
+      :pursueType="pursueType"
+      :vehicleNo="orderInfo.vehicleNo"
+      @closePaymentMethod="closePaymentMethod"
+    ></PaymentMethod>
+    <u-popup v-model="show" mode="center" border-radius="14" width="200rpx" height="200rpx">
+      <view class="loadingSelect">订单查询中...</view>
+      <view class="spinner">
+        <view class="rect1"></view>
+        <view class="rect2"></view>
+        <view class="rect3"></view>
+        <view class="rect4"></view>
+        <view class="rect5"></view>
+      </view>
+    </u-popup>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import getUrlParams from '../../utils/getUrlParams.js';
+import PaymentMethod from '@/pages/paymentMethod/paymentMethod.vue';
+export default {
+  components: {
+    PaymentMethod
+  },
+  data() {
+    return {
+      // 车位锁状态 1:需支付 2:查询失败返回提醒
+      parkingLockStatus: 0,
+      // 支付方式选择弹框
+      payWayPop: false,
+      // 订单编号
+      orderList: [],
+      // 提示信息
+      tipsMsg: null,
+      // 轮询
+      timer: null,
+      // 订单信息
+      orderInfo: {},
+      // 订单id
+      orderId: null,
+      // 重定向地址
+      jumpUrl: location.href + '&isBack=1',
+      show: true,
+      isBack: '',
+      polyOrderId: '',
+      // 地磁
+      spaceId: '',
+      payeeId: '',
+      payeeName: '',
+      pursueType: '',
+      is_pay: false
+    };
+  },
+  onLoad(page) {
+    if (page.orderId) {
+      this.orderId = page?.orderId;
+      this.spaceId = page?.spaceId;
+      this.payeeId = page?.payeeId;
+      this.polyOrderId = page?.polyOrderId;
+      this.pursueType = page?.pursueType;
+      this.isBack = page?.isBack;
+    } else {
+      this.tipsMsg = page.msg || '参数丢失!';
+      this.parkingLockStatus = 2;
+    }
+  },
+  onShow() {
+    if (this.orderId) {
+      this.getOrderDetails(this.spaceId, this.orderId, this.payeeId);
+      if (this.polyOrderId && this.isBack == 1) {
+        this.timer = setInterval(() => {
+          this.show = true;
+          this.handlePayStatus(this.polyOrderId);
+        }, 1000);
+      }
+    } else {
+      this.show = false;
+    }
+  },
+  onUnload() {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+  },
+  methods: {
+    jumpArrears() {
+      uni.navigateTo({
+        url: '../center/order/order?orderStatus=2'
+      });
+    },
+    /**
+     * 反复查询支付状态
+     * @param { String } orderId
+     */
+    handlePayStatus(orderId) {
+      this.$u.api
+        .getOrderInfo({
+          orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.payStatus === 1 || res.data.payStatus === 3) {
+              this.show = false;
+              clearInterval(this.timer);
+              this.is_pay = false;
+              uni.showModal({
+                title: '提示',
+                content: '支付成功,返回首页',
+                showCancel: false,
+                success: (res) => {
+                  if (res.confirm) {
+                    uni.switchTab({
+                      url: '/pages/index/index'
+                    });
+                  }
+                }
+              });
+            } else if (res.data.payStatus === 2) {
+              this.is_pay = true;
+            }
+          } else {
+            this.show = false;
+            clearInterval(this.timer);
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch(() => {
+          this.show = false;
+          clearInterval(this.timer);
+        });
+    },
+    /**
+     * 立即支付
+     */
+    payMoney() {
+      this.payWayPop = true;
+    },
+    /**
+     * 查询订单信息
+     * @param { String } spaceId 车位ID
+     * @param { String } orderId 订单id
+     * @param { String } payeeId 收费员ID
+     */
+    getOrderDetails(spaceId, orderId, payeeId) {
+      this.$u.api
+        .geomaLockDetailsApi({
+          spaceId,
+          orderId,
+          payeeId
+        })
+        .then((res) => {
+          if (res.code === 200 && res.data.id) {
+            this.payeeName = res.data.payeeName;
+            this.parkingLockStatus = 1;
+            this.orderInfo = res.data;
+            this.show = false;
+            if (res.data.payStatus == 0 || res.data.payStatus == 2 || res.data.payStatus == 3) {
+              this.is_pay = true;
+            } else if (res.data.payStatus == 1) {
+              this.is_pay = false;
+              uni.showModal({
+                title: '提示',
+                content: '订单已支付,返回首页',
+                showCancel: false,
+                success: function (res) {
+                  if (res.confirm) {
+                    uni.switchTab({
+                      url: '/pages/index/index'
+                    });
+                  }
+                }
+              });
+            }
+            if (res.data.payAmount == 0) {
+              this.is_pay = false;
+            }
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg || '订单无数据',
+              type: 'error'
+            });
+          }
+        });
+    },
+    /**
+     * 关闭支付弹框
+     */
+    closePaymentMethod() {
+      this.payWayPop = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './geomagnetismLock.scss';
+
+.Jump {
+  position: fixed;
+  top: 50px;
+  right: 0;
+  background-color: #f6f6ff;
+
+  &-btn {
+    color: rgb(0, 140, 255);
+    padding: 20rpx 30rpx;
+  }
+}
+</style>

+ 101 - 0
pages/goldPlan/goldPlan.vue

@@ -0,0 +1,101 @@
+<template>
+  <view class="container">
+    <view class="text-img">
+      <image src="../../static/img/text-html-bg.png" mode="aspectFit" />
+    </view>
+    <view class="car-img">
+      <image src="../../static/img/car-html-bg.png" mode="aspectFit" />
+    </view>
+    <view @click="goToBgzchina()" class="button">回到{{ project_name }}智慧停车</view>
+  </view>
+</template>
+
+<script>
+const goldPlan = require('../../static/js/jgoldplan-1.0.0.js');
+export default {
+  data() {
+    return {
+      sub_mch_id: '',
+      out_trade_no: '',
+      project_name: process.env.H_PROJECT_NAME
+    };
+  },
+  onLoad(option) {
+    this.sub_mch_id = option.sub_mch_id; //特约商户号
+    this.out_trade_no = option.out_trade_no; //商户订单号
+  },
+  onReady() {
+    let mchData = {
+      action: 'onIframeReady',
+      displayStyle: 'SHOW_CUSTOM_PAGE',
+      height: 960
+    };
+    let postData = JSON.stringify(mchData);
+    parent.postMessage(postData, 'https://payapp.weixin.qq.com');
+  },
+  methods: {
+    /**
+     * @description: 返回停车页面
+     * @return {*}
+     */
+    goToBgzchina() {
+      const mchData = {
+        action: 'jumpOut',
+        jumpOutUrl: process.env.H_PROJECT_URL //跳转的页面
+      };
+      const pData = JSON.stringify(mchData);
+      parent.postMessage(pData, 'https://payapp.weixin.qq.com');
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.container {
+  height: 100vh;
+  width: 100%;
+  padding: 50px 0;
+  text-align: center;
+  background: linear-gradient(138deg, #7ebab8 0%, #48999a 100%);
+  box-shadow: 0px 2px 4px 0px #0b7c7d;
+}
+
+.text-img {
+  margin: 0 auto;
+  width: 80%;
+  height: 20%;
+  image {
+    width: 100%;
+    height: 100%;
+  }
+}
+
+.car-img {
+  margin: 39px auto 0;
+  width: 65%;
+  height: 25%;
+  image {
+    width: 100%;
+    height: 100%;
+  }
+}
+
+.button {
+  display: inline-block;
+  width: calc(100% - 84px);
+  height: 6vh;
+  line-height: 6vh;
+  text-decoration: none;
+  margin-top: 4vh;
+  outline: none;
+  border: none;
+  background: #ffffff;
+  box-shadow: 0px 7px 13px 0px rgba(0, 105, 106, 0.26);
+  border-radius: 10px;
+  font-size: 1.1em;
+  font-weight: 500;
+  color: #1d8587;
+  font-family: 'PingFangSC-Medium, PingFang SC';
+  cursor: pointer;
+}
+</style>

+ 180 - 0
pages/handleMonthly/handleMonthly.scss

@@ -0,0 +1,180 @@
+.handle-monthly {
+  padding: 40rpx;
+  .handle-monthly-item {
+    display: flex;
+    flex-direction: row;
+		align-items: center;
+    border-bottom: solid 1rpx #cecece;
+    // height: 96rpx;
+    line-height: 96rpx;
+		position: relative;
+    > view {
+      &:first-child {
+        width: 22%;
+        color: #757575;
+        font-size: 32rpx;
+        font-weight: 400;
+        text-align: justify;
+        text-align-last: justify;
+        margin-right: 8%;
+      }
+      &:last-child {
+        width: 70%;
+        color: #404040;
+        font-size: 36rpx;
+        font-weight: 400;
+      }
+    }
+    .choose-license {
+      display: flex;
+      justify-content: space-between;
+    }
+    .handle-monthly-money {
+      color: #f97219 !important;
+    }
+    .handle-monthly-time-long {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      button {
+        margin: 0;
+        padding: 0;
+        width: 46rpx;
+        height: 46rpx;
+        line-height: 40rpx;
+        border: solid 1px #008cff;
+        color: #008cff;
+        text-align: center;
+      }
+      view {
+        padding: 0 61rpx;
+      }
+    }
+		.handle-monthly-time-tips {
+			width: 100%!important;
+			position: absolute;
+			bottom: -24rpx;
+			font-size: 24rpx!important;
+			color: #2979ff!important;
+		}
+  }
+  .handle-monthly-explain {
+    font-size: 24rpx;
+    line-height: 40rpx;
+    color: #3a3a3a;
+    font-weight: 400;
+  }
+  .handle-monthly-confirm-button {
+    width: calc(100% - 60rpx);
+    margin: 52rpx auto;
+  }
+}
+.pb20 {
+	padding-bottom: 30rpx;
+}
+.pay-content {
+  padding: 40rpx;
+  .pay-list {
+    &-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      height: 104rpx;
+      border-top: solid 1px #eeeeee;
+      &-image {
+        display: flex;
+        font-size: 30rpx;
+        color: #1E1E1E;
+        .image {
+          width: 54rpx;
+          height: 45rpx;
+          margin-right: 20rpx;
+        }
+      }
+      &:last-child {
+        border-bottom: solid 1px #eeeeee;
+      }
+    }
+  }
+  .pay-money {
+    text-align: center;
+    font-size: 34rpx;
+    color: #008CFF;
+    margin-top: 20rpx;
+  }
+  .pay-btn {
+    margin-top: 34rpx;
+  }
+}
+.coupon-popup {
+  position: relative;
+  min-height: 100vh;
+  overflow-y: auto;
+  background-color: #F9F9F9;
+  &-list {
+    padding: 30rpx;
+    &-item {
+      background-color: #fff;
+      border-radius: 17rpx;
+      margin-bottom: 20rpx;
+      &-top {
+        padding: 30rpx;
+        display: flex;
+        justify-content: space-between;
+        align-items: baseline;
+        border-bottom: 1px solid #EEEEEE;
+        &-left {
+          display: flex;
+          align-items: baseline;
+          .cplitl-left {
+            color: #FF6D6D;
+            font-size: 20rpx;
+            margin-right: 34rpx;
+            text:last-child {
+              font-size: 60rpx;
+              font-weight: bold;
+            }
+            &-bottom {
+              color: #333333;
+              font-size: 24rpx;
+            }
+          }
+          .cplitl-right {
+            view {
+              &:first-child {
+                font-size: 32rpx;
+                color: #333333;
+                font-weight: 700;
+                margin-bottom: 8rpx;
+              }
+              &:last-child {
+                font-size: 20rpx;
+                color: #666;
+              }
+            }
+          }
+        }
+      }
+      &-bottom {
+        color: #999999;
+        padding: 10rpx 30rpx;
+        font-size: 20rpx;
+        .cplib-point {
+          margin-top: 10rpx;
+          &-content {
+            padding-top: 10rpx;
+            font-size: 24rpx;
+            color: #999999;
+          }
+        }
+      }
+    }
+  }
+  &-btn {
+    width: 100%;
+    padding: 80rpx 30rpx;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+  }
+}

+ 414 - 0
pages/handleMonthly/handleMonthly.vue

@@ -0,0 +1,414 @@
+<template>
+  <view class="handle-monthly">
+    <view class="handle-monthly-item">
+      <view>车牌选择</view>
+      <view class="choose-license" @click="isShowCarLicense = true">
+        <view>{{ form.carLicense.label || '未选车牌' }}</view>
+        <u-icon name="arrow-down" color="#7B7B7B" size="30"></u-icon>
+      </view>
+    </view>
+    <u-select v-model="isShowCarLicense" :list="carLicenseList" :default-value="carLicenseDefaultValue" @confirm="carLicenseListConfirm"></u-select>
+    <view class="handle-monthly-item">
+      <view>车辆信息</view>
+      <view>{{ form.carLicense.value | verifyStatusFilter }}</view>
+    </view>
+    <view class="handle-monthly-item">
+      <view>包月金额</view>
+      <view class="handle-monthly-money">{{ form.monthAmount || 0 }}元</view>
+    </view>
+    <view
+      class="handle-monthly-item"
+      v-if="monthlyRuleObj.giveFlag && Number(monthlyRuleObj.giveFlag) === 1"
+      :class="{ pb20: monthlyRuleObj.minMonth && form.month >= monthlyRuleObj.minMonth && Number(monthlyRuleObj.giveFlag) === 1 }"
+    >
+      <view>包月时长</view>
+      <view class="handle-monthly-time-long">
+        <button @click="reduceMonthNum()">-</button>
+        <view>{{ form.month || 0 }}个月</view>
+        <button @click="addMonthNum()">+</button>
+      </view>
+      <view
+        class="handle-monthly-time-tips"
+        v-if="monthlyRuleObj.minMonth && form.month >= monthlyRuleObj.minMonth && Number(monthlyRuleObj.giveFlag) === 1"
+      >
+        赠送提示:可获得{{ freeMonthNum || 0 }}个月的免费停车时长
+      </view>
+    </view>
+    <view class="handle-monthly-item" v-else>
+      <view>包月时长</view>
+      <view class="handle-monthly-time-long">
+        <button @click="reduceMonthNum()">-</button>
+        <view>{{ form.month || 0 }}个月</view>
+        <button @click="addMonthNum()">+</button>
+      </view>
+    </view>
+    <view class="handle-monthly-item">
+      <view>有效期限</view>
+      <view>{{ dateRange || '-' }}</view>
+    </view>
+    <view class="handle-monthly-explain">
+      <u-parse :html="monthlyContent"></u-parse>
+    </view>
+    <view class="handle-monthly-confirm-button">
+      <template v-if="carLicenseList.length && form.carLicense && form.carLicense.label">
+        <u-button type="primary" :loading="loading" @click="submit()">确认包月</u-button>
+      </template>
+      <template v-else>
+        <u-button>未选车牌</u-button>
+      </template>
+    </view>
+    <!-- 选择支付 -->
+    <choose-payment ref="choosePayment" :monthId="monthId" :jumpUrl="jumpUrl" :isMonthPay="true" @closePaymentMethod="closePaymentMethod" />
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import ChoosePayment from '../choosePayment/choosePayment.vue';
+export default {
+  components: {
+    ChoosePayment
+  },
+  data() {
+    return {
+      startTime: '',
+      endTime: '',
+      payUrl: '',
+      monthId: '',
+      vehicleNo: '',
+      monthEndTime: '',
+      monthStartTime: '',
+      lastActiveDate: null,
+      roadNo: null,
+      parkNo: null,
+      carLicenseList: [],
+      isShowCarLicense: false,
+      form: {
+        energyType: [],
+        monthAmount: 0,
+        carLicense: {},
+        month: 1,
+        dateRange: ''
+      },
+      payWayPop: false,
+      jumpUrl: undefined,
+      monthlyContent: '',
+      carLicenseDefaultValue: [0],
+      wxEnv: false,
+      loading: false,
+      type: 'road',
+      monthlyRuleObj: {},
+      freeMonthNum: 0,
+      radioCurrent: '',
+      orderMoney: ''
+    };
+  },
+  watch: {
+    'form.month': {
+      handler(val) {
+        this.calcFreeMonthNum(val);
+      },
+      deep: true,
+      immediate: false
+    }
+  },
+  onLoad(page) {
+    this.getSysterms(0);
+    if (page.vehicleNo && page.roadNo) {
+      this.roadNo = page.roadNo;
+      this.vehicleNo = page.vehicleNo;
+      this.type = 'road';
+      this.getMonthInfo();
+    } else if (page.roadNo) {
+      this.roadNo = page.roadNo;
+      this.type = 'road';
+      this.getMonthInfo();
+    } else if (page.vehicleNo && page.parkNo) {
+      this.parkNo = page.parkNo;
+      this.vehicleNo = page.vehicleNo;
+      this.type = 'park';
+      this.getMonthInfo();
+    } else if (page.parkNo) {
+      this.parkNo = page.parkNo;
+      this.type = 'park';
+      this.getMonthInfo();
+    }
+    if (page.monthId) {
+      this.monthId = page.monthId;
+      // this.payWayPop = true;
+    }
+    if (page.roadNo) {
+      this.monthlyRuleDetails();
+    }
+    this.jumpUrl = location.origin + '/#/pages/center/monthly/monthly?type=' + this.type;
+  },
+  methods: {
+    /**
+     * 获取几个月的日期范围
+     * {date} Date 起始日期,往后推一天
+     * {monthNum} Number  往后月数
+     * */
+    getMonthRange(date, monthNum) {
+      let Date1 = this.lastActiveDate;
+      Date1 = new Date(date || Date1);
+      const year = Date1.getFullYear();
+      const month = Date1.getMonth() + 1;
+      const day = Date1.getDate();
+      const hours = Date1.getHours();
+      const minutes = Date1.getMinutes();
+      const seconds = Date1.getSeconds();
+      let days = new Date(year, month, 0);
+      days = days.getDate(); //获取当前日期中的月的天数
+      let year2 = year;
+      let month2 = parseInt(month) + parseInt(monthNum);
+      if (month2 > 12) {
+        year2 = parseInt(year2) + parseInt(parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12);
+        month2 = parseInt(month2) % 12;
+      }
+      let day2 = day;
+      let days2 = new Date(year2, month2, 0);
+      days2 = days2.getDate();
+      if (day2 > days2) {
+        day2 = days2;
+      }
+      if (month2 < 10) {
+        month2 = '0' + month2;
+      }
+      const t1 = year + '.' + (month > 9 ? month : '0' + month) + '.' + (day > 9 ? day : '0' + day);
+      const t2 = year2 + '.' + month2 + '.' + (day2 > 9 ? day2 : '0' + day2);
+      this.startTime = t1;
+      this.endTime = t2;
+      this.monthStartTime =
+        year + '-' + (month > 9 ? month : '0' + month) + '-' + (day > 9 ? day : '0' + day) + ' ' + hours + ':' + minutes + ':' + seconds;
+      this.monthEndTime = year2 + '-' + month2 + '-' + day2 + ' ' + hours + ':' + minutes + ':' + seconds;
+      return t1 + '-' + t2;
+    },
+    /**
+     * 月操作 减1
+     * */
+    reduceMonthNum() {
+      if (this.form.month > 1) {
+        this.form.month -= 1;
+        this.form.dateRange = this.getMonthRange(new Date(), this.form.month + this.freeMonthNum);
+      }
+    },
+    /**
+     * 月操作 加1
+     * */
+    addMonthNum() {
+      if (this.form.month >= 24) {
+        this.$refs.uToast.show({
+          title: '最多24月',
+          type: 'warning'
+        });
+        return;
+      }
+      this.form.month += 1;
+      this.form.dateRange = this.getMonthRange(new Date(), this.form.month + this.freeMonthNum);
+    },
+    carLicenseListConfirm(item) {
+      this.form.carLicense = item[0];
+      this.vehicleNo = item[0].label;
+      this.getMonthInfo();
+    },
+    /**
+     * 获取包月信息
+     * @date 2022-10-09
+     * @returns {any}
+     */
+    getMonthInfo() {
+      let paramsObj = {
+          park: 'parkNo',
+          road: 'roadNo'
+        },
+        params = {
+          vehicleNo: this.vehicleNo
+        };
+      params[paramsObj[this.type]] = this[paramsObj[this.type]];
+      this.$u.api
+        .monthInfo(params)
+        .then((res) => {
+          if (res.code === 200 && res.data.vehicleList && res.data.vehicleList.length) {
+            this.lastActiveDate = res.data.lastActiveDate;
+            this.form.monthAmount = res.data.monthAmount;
+            this.orderMoney = (Number(this.form.monthAmount) * Number(this.form.month)).toFixed(2);
+            this.carLicenseList = [];
+            let vehicleNoItem = null;
+            res.data.vehicleList.forEach((item, index) => {
+              const obj = {
+                value: item.energyType,
+                label: item.vehicleNo,
+                energyType: item.energyType
+              };
+              if (this.vehicleNo == item.vehicleNo) {
+                vehicleNoItem = obj;
+                this.carLicenseDefaultValue = [index];
+              }
+              this.carLicenseList.push(obj);
+            });
+            // 判断是否url存在车牌号,存在则选中项默认选中
+            if (vehicleNoItem) {
+              this.form.carLicense = vehicleNoItem;
+            } else {
+              this.form.carLicense = this.carLicenseList[0];
+            }
+            if (this.monthId) {
+              this.$nextTick(() => {
+                this.$refs['choosePayment'].openPopup({ payAmount: Number(this.orderMoney) }, 'single', this.type);
+              });
+            }
+          }
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    },
+    /**
+     * 获取包月规则详情
+     * @date 2022-12-20
+     * @returns {any}
+     */
+    monthlyRuleDetails() {
+      let paramsObj = {
+          park: 'parkNo',
+          road: 'roadNo'
+        },
+        params = {};
+      params[paramsObj[this.type]] = this[paramsObj[this.type]];
+      this.$u.api.monthlyRuleDetailsApi(params).then((res) => {
+        if (res.code === 200) {
+          this.monthlyRuleObj = res?.rows[0] ?? {};
+          this.calcFreeMonthNum(this.form.month);
+        }
+      });
+    },
+    /**
+     * @description: 计算免费的包月数量
+     * @param {*} val
+     * @return {*}
+     */
+    calcFreeMonthNum(val) {
+      if (this.monthlyRuleObj.giveFlag && Number(this.monthlyRuleObj.giveFlag) === 1) {
+        let timesNum = parseInt(Number(val) / Number(this.monthlyRuleObj.minMonth));
+        if (timesNum > 0) {
+          this.freeMonthNum = Number(timesNum) * Number(this.monthlyRuleObj.giveMonth);
+        } else {
+          this.freeMonthNum = 0;
+        }
+      }
+    },
+    /**
+     * 提交包月信息
+     * @date 2022-10-09
+     * @returns {any}
+     */
+    submit() {
+      this.loading = true;
+      let paramsObj = {
+          park: 'parkNo',
+          road: 'roadNo'
+        },
+        params = {
+          vehicleNo: this.form.carLicense.label,
+          energyType: this.form.carLicense.energyType,
+          monthStartTime: this.monthStartTime,
+          monthEndTime: this.monthEndTime,
+          monthCount: this.form.month
+        };
+      params[paramsObj[this.type]] = this[paramsObj[this.type]];
+      this.$u.api
+        .createMonth(params)
+        .then((res) => {
+          if (res.code === 200) {
+            this.monthId = res.data.monthId;
+            this.orderMoney = (Number(this.form.monthAmount) * Number(this.form.month)).toFixed(2);
+            // this.payWayPop = true;
+            this.$nextTick(() => {
+              this.$refs['choosePayment'].openPopup({ payAmount: Number(this.orderMoney) }, 'single', this.type);
+            });
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+          this.loading = false;
+        })
+        .catch((err) => {
+          this.loading = false;
+        });
+    },
+    /**
+     * 获取包月说明
+     * @date 2022-10-09
+     * @param {any} termsType
+     * @returns {any}
+     */
+    getSysterms(termsType) {
+      this.$u.api
+        .getSysterms({
+          termsType: termsType
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.monthlyContent = res.data?.content;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '系统错误!',
+            type: 'error'
+          });
+        });
+    },
+    /**
+     * @description: 调整到包月列表页面
+     * @return {*}
+     */
+    jumpMonthList() {
+      this.$u.route({
+        url: '/pages/center/monthly/monthly',
+        type: 'redirect',
+        params: {
+          type: this.type
+        }
+      });
+    },
+    /** 
+     * @description: 关闭支付弹框
+     * @return {*}
+     */
+    closePaymentMethod() {
+      if (this.monthId) this.jumpMonthList();
+    }
+  },
+  computed: {
+    dateRange: function () {
+      return this.getMonthRange(this.lastActiveDate, this.form.month + this.freeMonthNum);
+    }
+  },
+  filters: {
+    verifyStatusFilter(value) {
+      if (value === 0) {
+        return '-';
+      } else if (value === 1) {
+        return '汽油车';
+      } else if (value === 2) {
+        return '新能源';
+      } else {
+        return '-';
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './handleMonthly.scss';
+@import '../paymentMethod/paymentMethod.scss';
+</style>

+ 522 - 0
pages/handleMonthly/handleMonthly20230220.vue

@@ -0,0 +1,522 @@
+<template>
+	<view class="handle-monthly">
+		<view class="handle-monthly-item">
+			<view>车牌选择</view>
+			<view class="choose-license" @click="isShowCarLicense = true">
+				<view>{{ form.carLicense.label || '未选车牌' }}</view>
+				<u-icon name="arrow-down" color="#7B7B7B" size="30"></u-icon>
+			</view>
+		</view>
+		<u-select v-model="isShowCarLicense" :list="carLicenseList" :default-value="carLicenseDefaultValue"
+			@confirm="carLicenseListConfirm"></u-select>
+		<view class="handle-monthly-item">
+			<view>车辆信息</view>
+			<view>{{ form.carLicense.value | verifyStatusFilter }}</view>
+		</view>
+		<view class="handle-monthly-item">
+			<view>包月金额</view>
+			<view class="handle-monthly-money">{{ form.monthAmount || 0 }}元</view>
+		</view>
+		<view class="handle-monthly-item"
+			v-if="monthlyRuleObj.giveFlag && Number(monthlyRuleObj.giveFlag) === 1"
+			:class="{ 'pb20': monthlyRuleObj.minMonth && form.month >= monthlyRuleObj.minMonth && Number(monthlyRuleObj.giveFlag) === 1 }">
+			<view>包月时长</view>
+			<view class="handle-monthly-time-long">
+				<button @click="reduceMonthNum()">-</button>
+				<view>{{ form.month || 0 }}个月</view>
+				<button @click="addMonthNum()">+</button>
+			</view>
+			<view class="handle-monthly-time-tips"
+				v-if="monthlyRuleObj.minMonth && form.month >= monthlyRuleObj.minMonth && Number(monthlyRuleObj.giveFlag) === 1">
+				赠送提示:可获得{{ freeMonthNum }}个月的免费停车时长
+			</view>
+		</view>
+		<view class="handle-monthly-item" v-else>
+			<view>包月时长</view>
+			<view class="handle-monthly-time-long">
+				<button @click="reduceMonthNum()">-</button>
+				<view>{{ form.month || 0 }}个月</view>
+				<button @click="addMonthNum()">+</button>
+			</view>
+		</view>
+		<view class="handle-monthly-item">
+			<view>有效期限</view>
+			<view>{{ dateRange || '-' }}</view>
+		</view>
+		<view class="handle-monthly-explain">
+			<u-parse :html="monthlyContent"></u-parse>
+		</view>
+		<view class="handle-monthly-confirm-button">
+			<template v-if="carLicenseList.length && form.carLicense && form.carLicense.label">
+				<u-button type="primary" :loading="loading" @click="submit(roadNo)">确认包月</u-button>
+			</template>
+			<template v-else>
+				<u-button>未选车牌</u-button>
+			</template>
+		</view>
+		<u-modal v-model="payWayPop" :title-style="{ color: '#404040' }" title="缴费方式" :show-confirm-button="false"
+			:show-cancel-button="false">
+			<view class="slot-content">
+				<view class="pay-way-new">
+					<view class="pay-way-item pay-way-item-hy"
+						@click="$u.debounce(gyBankPay, 1000, (immediate = true))">
+						<image src="/static/img/gyyh-icon.svg" mode=""></image>
+						<view class="title">贵州银行</view>
+					</view>
+					<!-- #ifdef H5 || MP-WEIXIN -->
+					<view class="pay-way-item pay-way-item-wx" @click="$u.debounce(wechatPay, 1000, (immediate = true))"
+						v-if="wxEnv">
+						<image src="/static/img/weixin-icon.svg" mode=""></image>
+						<view class="title">微信支付</view>
+					</view>
+					<!-- #endif -->
+					<view class="pay-way-item pay-way-item-jh" @click="$u.debounce(juhePay, 1000, (immediate = true))">
+						<image src="/static/img/juhe-icon.svg" mode=""></image>
+						<view class="title">聚合支付</view>
+					</view>
+				</view>
+				<view class="pay-way-subtitle">
+					<view class="pay-way-subtitle-item">前三个月每天首次一分钱,长期八折优惠</view>
+					<!-- #ifdef H5 || MP-WEIXIN -->
+					<!-- <view class="pay-way-subtitle-item" v-if="wxEnv">&nbsp;</view> -->
+					<!-- #endif -->
+					<view class="pay-way-subtitle-item">&nbsp;</view>
+				</view>
+				<button class="pay-way-close-btn" @click="cancel">关闭</button>
+			</view>
+		</u-modal>
+		<u-toast ref="uToast" />
+	</view>
+</template>
+
+<script>
+	import {
+		getEnvIsWx
+	} from '@/utils/judgEnvironment.js';
+	import $wxPay from '@/utils/wxPay.js';
+	export default {
+		data() {
+			return {
+				startTime: '',
+				endTime: '',
+				payUrl: '',
+				monthId: '',
+				vehicleNo: '',
+				monthEndTime: '',
+				monthStartTime: '',
+				lastActiveDate: null,
+				roadNo: null,
+				parkNo: null,
+				carLicenseList: [],
+				isShowCarLicense: false,
+				form: {
+					energyType: [],
+					monthAmount: 0,
+					carLicense: {},
+					month: 1,
+					dateRange: ''
+				},
+				label: '',
+				payWayPop: false,
+				jumpUrl: undefined,
+				monthlyContent: '',
+				carLicenseDefaultValue: [0],
+				wxEnv: false,
+				loading: false,
+				type: 'road',
+				monthlyRuleObj: {},
+				freeMonthNum: 0
+			};
+		},
+		watch: {
+			'form.month':{
+					handler(val){
+						this.calcFreeMonthNum(val)
+					},
+					deep:true,
+					immediate:false
+			}
+		},
+		onLoad(page) {
+			this.wxEnv = getEnvIsWx();
+			this.getSysterms(0);
+			if (page.vehicleNo && page.roadNo) {
+				this.roadNo = page.roadNo;
+				this.vehicleNo = page.vehicleNo;
+				this.type = 'road'
+				this.getMonthInfo(this.roadNo, this.vehicleNo);
+			} else if (page.roadNo) {
+				this.roadNo = page.roadNo;
+				this.type = 'road'
+				this.getMonthInfo(this.roadNo);
+			} else if (page.vehicleNo && page.parkNo) {
+				this.parkNo = page.parkNo;
+				this.vehicleNo = page.vehicleNo;
+				this.type = 'park'
+				this.getMonthInfo(this.parkNo, this.vehicleNo);
+			} else if (page.parkNo) {
+				this.parkNo = page.parkNo;
+				this.type = 'park'
+				this.getMonthInfo(this.parkNo);
+			}
+			if (page.monthId) {
+				this.monthId = page.monthId
+				this.payWayPop = true
+			}
+			if (page.roadNo) {
+				this.monthlyRuleDetails(page.roadNo);
+			}
+			const baseUrl = window.location.href.split('#')[0];
+			let jumpUrl = baseUrl + '#/pages/center/monthly/monthly?type=' + this.type;
+			this.jumpUrl = jumpUrl;
+		},
+		methods: {
+			/**
+			 * 获取几个月的日期范围
+			 * {date} Date 起始日期,往后推一天
+			 * {monthNum} Number  往后月数
+			 * */
+			getMonthRange(date, monthNum) {
+				let Date1 = this.lastActiveDate;
+				Date1 = new Date(Date1);
+				const year = Date1.getFullYear();
+				const month = Date1.getMonth() + 1;
+				const day = Date1.getDate();
+				const hours = Date1.getHours();
+				const minutes = Date1.getMinutes();
+				const seconds = Date1.getSeconds();
+				let days = new Date(year, month, 0);
+				days = days.getDate(); //获取当前日期中的月的天数
+				let year2 = year;
+				let month2 = parseInt(month) + parseInt(monthNum);
+				if (month2 > 12) {
+					year2 = parseInt(year2) + parseInt(parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12);
+					month2 = parseInt(month2) % 12;
+				}
+				let day2 = day;
+				let days2 = new Date(year2, month2, 0);
+				days2 = days2.getDate();
+				if (day2 > days2) {
+					day2 = days2;
+				}
+				if (month2 < 10) {
+					month2 = '0' + month2;
+				}
+				const t1 = year + '.' + (month > 9 ? month : '0' + month) + '.' + (day > 9 ? day : '0' + day);
+				const t2 = year2 + '.' + month2 + '.' + (day2 > 9 ? day2 : '0' + day2);
+				this.startTime = t1;
+				this.endTime = t2;
+				this.monthStartTime =
+					year + '-' + (month > 9 ? month : '0' + month) + '-' + (day > 9 ? day : '0' + day) + ' ' + hours +
+					':' + minutes + ':' + seconds;
+				this.monthEndTime = year2 + '-' + month2 + '-' + day2 + ' ' + hours + ':' + minutes + ':' + seconds;
+				return t1 + '-' + t2;
+			},
+			/**
+			 * 月操作 减1
+			 * */
+			reduceMonthNum() {
+				if (this.form.month > 1) {
+					this.form.month -= 1;
+					this.form.dateRange = this.getMonthRange(new Date(), this.form.month + this.freeMonthNum);
+				}
+			},
+			/**
+			 * 月操作 加1
+			 * */
+			addMonthNum() {
+				if (this.form.month >= 24) {
+					this.$refs.uToast.show({
+						title: '最多24月',
+						type: 'warning'
+					});
+					return;
+				}
+				this.form.month += 1;
+				this.form.dateRange = this.getMonthRange(new Date(), (this.form.month + this.freeMonthNum));
+			},
+			carLicenseListConfirm(item) {
+				this.form.carLicense = item[0];
+				this.vehicleNo = item[0].label;
+				this.getMonthInfo(this.roadNo, this.vehicleNo);
+			},
+			/**
+			 * 获取包月信息
+			 * @date 2022-10-09
+			 * @param {any} roadNo
+			 * @param {any} vehicleNo
+			 * @returns {any}
+			 */
+			getMonthInfo(roadNo, vehicleNo) {
+				const params = {
+					vehicleNo
+				}
+				if (this.type === 'park') {
+					params.parkNo = roadNo
+				} else {
+					params.roadNo = roadNo
+				}
+				this.$u.api
+					.monthInfo(params)
+					.then((res) => {
+						if (res.code === 200 && res.data.vehicleList && res.data.vehicleList.length) {
+							this.lastActiveDate = res.data.lastActiveDate;
+							this.form.monthAmount = res.data.monthAmount;
+							this.carLicenseList = [];
+							let vehicleNoItem = null;
+							res.data.vehicleList.forEach((item, index) => {
+								const obj = {
+									value: item.energyType,
+									label: item.vehicleNo,
+									energyType: item.energyType
+								};
+								if (this.vehicleNo == item.vehicleNo) {
+									vehicleNoItem = obj;
+									this.carLicenseDefaultValue = [index];
+								}
+								this.carLicenseList.push(obj);
+							});
+							// 判断是否url存在车牌号,存在则选中项默认选中
+							if (vehicleNoItem) {
+								this.form.carLicense = vehicleNoItem;
+							} else {
+								this.form.carLicense = this.carLicenseList[0];
+							}
+						}
+					}).catch((err) => {
+						console.log(err);
+					})
+			},
+			/**
+			 * 获取包月规则详情
+			 * @date 2022-12-20
+			 * @param {any} roadNo
+			 * @returns {any}
+			 */
+			monthlyRuleDetails(roadNo) {
+				this.$u.api.monthlyRuleDetailsApi({
+					roadNo
+				}).then(res => {
+					if (res.code === 200) {
+						this.monthlyRuleObj = res?.rows[0] ?? {}
+						this.calcFreeMonthNum(this.form.month)
+					}
+				})
+			},
+			calcFreeMonthNum(val){
+				let freeNum = 0;
+				if (this.monthlyRuleObj.giveFlag && Number(this.monthlyRuleObj.giveFlag) === 1) {
+					// let remainNum = Number(val) % Number(this.monthlyRuleObj.minMonth)
+					let	timesNum = parseInt(Number(val) / Number(this.monthlyRuleObj.minMonth));
+					if (timesNum > 0) {
+						this.freeMonthNum = Number(timesNum) * Number(this.monthlyRuleObj.giveMonth);
+					} else {
+						this.freeMonthNum = 0
+					}
+				}
+			},
+			/**
+			 * 提交包月信息
+			 * @date 2022-10-09
+			 * @param {any} roadNo
+			 * @returns {any}
+			 */
+			submit(roadNo) {
+				this.loading = true;
+				const params = {
+					vehicleNo: this.form.carLicense.label,
+					energyType: this.form.carLicense.energyType,
+					monthStartTime: this.monthStartTime,
+					monthEndTime: this.monthEndTime,
+					monthCount: this.form.month
+				}
+				if (this.type === 'park') {
+					params.parkNo = this.parkNo
+				} else {
+					params.roadNo = this.roadNo
+				}
+				this.$u.api
+					.createMonth(params)
+					.then((res) => {
+						if (res.code === 200) {
+							this.monthId = res.data.monthId;
+							this.payWayPop = true;
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error'
+							});
+						}
+						this.loading = false;
+					})
+					.catch((err) => {
+						this.$refs.uToast.show({
+							title: '程序错误!',
+							type: 'error'
+						});
+						this.loading = false;
+					});
+			},
+			/**
+			 * 贵州银行包月支付
+			 * @date 2022-10-09
+			 * @returns {any}
+			 */
+			gyBankPay() {
+				this.$u.api
+					.monthPay({
+						monthId: this.monthId,
+						jumpUrl: this.jumpUrl
+					})
+					.then((res) => {
+						if (res.code === 200) {
+							window.location.href = res.data.url;
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error'
+							});
+							this.jumpMonthList()
+						}
+					});
+			},
+			/**
+			 * 聚合支付直接通过后台获取贵阳银行微信支付地址
+			 * @date 2022-10-09
+			 * @returns {any}
+			 */
+			juhePay() {
+				// 支付成功跳转到包月页面
+				let params = {
+					monthId: this.monthId,
+					openid: '',
+					jumpUrl: this.jumpUrl
+				};
+				this.$u.api
+					.monthlyWxPay(params)
+					.then((res) => {
+						if (res.code === 200) {
+							localStorage.setItem('jumpUrl', this.jumpUrl);
+							location.href = res.data.qrCodeUrl;
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error'
+							});
+							this.jumpMonthList()
+						}
+					})
+					.catch((err) => {
+						this.$refs.uToast.show({
+							title: '无法调起微信支付!',
+							type: 'error'
+						});
+					});
+			},
+			/**
+			 * 微信支付
+			 * @date 2022-10-09
+			 * @returns {any}
+			 */
+			wechatPay() {
+				this.$u.api
+					.wechatMonthlyPayapi({
+						monthId: this.monthId,
+						openid: this.vuex_wxinfo.openId
+					})
+					.then((r) => {
+						if (r.code === 200) {
+							$wxPay.weixinPay(r.data.wx).then((res) => {
+								switch (Number(res.code)) {
+									case 0: // 成功
+										//#ifdef H5
+										// this.jumpMonthList()
+										location.href = this.jumpUrl
+										//#endif
+										break;
+									case 1: // 取消
+										this.$refs.uToast.show({
+											title: '已取消支付',
+											type: 'info'
+										});
+										this.jumpMonthList()
+										break;
+									case 2: // 支付失败
+										this.$refs.uToast.show({
+											title: '支付失败,请检查!',
+											type: 'error'
+										});
+										this.jumpMonthList()
+										break;
+								}
+							});
+						}
+					});
+			},
+			/**
+			 * 获取包月说明
+			 * @date 2022-10-09
+			 * @param {any} termsType
+			 * @returns {any}
+			 */
+			getSysterms(termsType) {
+				this.$u.api
+					.getSysterms({
+						termsType: termsType
+					})
+					.then((res) => {
+						if (res.code === 200) {
+							this.monthlyContent = res.data?.content;
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error'
+							});
+						}
+					})
+					.catch((err) => {
+						this.$refs.uToast.show({
+							title: '系统错误!',
+							type: 'error'
+						});
+					});
+			},
+			cancel() {
+				this.payWayPop = false
+				this.jumpMonthList()
+			},
+			jumpMonthList() {
+				this.$u.route({
+					url: '/pages/center/monthly/monthly',
+					type: 'redirect',
+					params: {
+						type: this.type
+					}
+				})
+			}
+		},
+		computed: {
+			dateRange: function() {
+				return this.getMonthRange(this.lastActiveDate, this.form.month + this.freeMonthNum);
+			}
+		},
+		filters: {
+			verifyStatusFilter(value) {
+				if (value === 0) {
+					return '-';
+				} else if (value === 1) {
+					return '汽油车';
+				} else if (value === 2) {
+					return '新能源';
+				} else {
+					return '-';
+				}
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	@import './handleMonthly.scss';
+	@import '../paymentMethod/paymentMethod.scss';
+</style>

+ 604 - 0
pages/handleMonthly/handleMonthly20230314.vue

@@ -0,0 +1,604 @@
+<template>
+  <view class="handle-monthly">
+    <view class="handle-monthly-item">
+      <view>车牌选择</view>
+      <view class="choose-license" @click="isShowCarLicense = true">
+        <view>{{ form.carLicense.label || '未选车牌' }}</view>
+        <u-icon name="arrow-down" color="#7B7B7B" size="30"></u-icon>
+      </view>
+    </view>
+    <u-select v-model="isShowCarLicense" :list="carLicenseList" :default-value="carLicenseDefaultValue" @confirm="carLicenseListConfirm"></u-select>
+    <view class="handle-monthly-item">
+      <view>车辆信息</view>
+      <view>{{ form.carLicense.value | verifyStatusFilter }}</view>
+    </view>
+    <view class="handle-monthly-item">
+      <view>包月金额</view>
+      <view class="handle-monthly-money">{{ form.monthAmount || 0 }}元</view>
+    </view>
+    <view
+      class="handle-monthly-item"
+      v-if="monthlyRuleObj.giveFlag && Number(monthlyRuleObj.giveFlag) === 1"
+      :class="{ pb20: monthlyRuleObj.minMonth && form.month >= monthlyRuleObj.minMonth && Number(monthlyRuleObj.giveFlag) === 1 }"
+    >
+      <view>包月时长</view>
+      <view class="handle-monthly-time-long">
+        <button @click="reduceMonthNum()">-</button>
+        <view>{{ form.month || 0 }}个月</view>
+        <button @click="addMonthNum()">+</button>
+      </view>
+      <view
+        class="handle-monthly-time-tips"
+        v-if="monthlyRuleObj.minMonth && form.month >= monthlyRuleObj.minMonth && Number(monthlyRuleObj.giveFlag) === 1"
+      >
+        赠送提示:可获得{{ freeMonthNum }}个月的免费停车时长
+      </view>
+    </view>
+    <view class="handle-monthly-item" v-else>
+      <view>包月时长</view>
+      <view class="handle-monthly-time-long">
+        <button @click="reduceMonthNum()">-</button>
+        <view>{{ form.month || 0 }}个月</view>
+        <button @click="addMonthNum()">+</button>
+      </view>
+    </view>
+    <view class="handle-monthly-item">
+      <view>有效期限</view>
+      <view>{{ dateRange || '-' }}</view>
+    </view>
+    <view class="handle-monthly-explain">
+      <u-parse :html="monthlyContent"></u-parse>
+    </view>
+    <view class="handle-monthly-confirm-button">
+      <template v-if="carLicenseList.length && form.carLicense && form.carLicense.label">
+        <u-button type="primary" :loading="loading" @click="submit(roadNo)">确认包月</u-button>
+      </template>
+      <template v-else>
+        <u-button>未选车牌</u-button>
+      </template>
+    </view>
+    <u-modal
+      ref="uModal"
+      v-model="payWayPop"
+      :title-style="{ color: '#1E1E1E', fontSize: '34rpx' }"
+      title="选择支付方式"
+      width="550rpx"
+      :show-cancel-button="true"
+      :mask-close-able="false"
+      confirm-text="立即支付"
+      confirm-color="#fff"
+      :confirm-style="{ backgroundColor: '#008CFF' }"
+      :async-close="true"
+      @confirm="immediatePayment"
+      @cancel="cancel"
+    >
+      <view class="pay-content">
+        <view class="pay-list">
+          <radio-group @change="payRadioChange">
+            <template v-if="projectFlag !== 'zhenning' && projectFlag !== 'wudang'">
+              <!-- #ifdef H5 || MP-WEIXIN -->
+              <view class="pay-list-item" v-if="wxEnv">
+                <view class="pay-list-item-image">
+                  <image class="image" src="/static/img/wechat-icon-new.png" mode="aspectFit" />
+                  <view>微信支付</view>
+                </view>
+                <view class="radioBox">
+                  <radio color="#2DCF8C" value="weixin" :checked="'weixin' === radioCurrent" />
+                </view>
+              </view>
+              <!-- #endif -->
+            </template>
+            <view class="pay-list-item">
+              <view class="pay-list-item-image">
+                <image class="image" src="/static/img/gy-icon-new.png" mode="aspectFit" />
+                <view>贵州银行</view>
+              </view>
+              <view class="radioBox">
+                <radio color="#2DCF8C" value="gzyh" :checked="'gzyh' === radioCurrent" />
+              </view>
+            </view>
+            <template v-if="projectFlag === 'zhenning'">
+              <view class="pay-list-item">
+                <view class="pay-list-item-image">
+                  <image class="image" src="/static/img/wechat-icon-new.png" mode="aspectFit" />
+                  <view>微信/支付宝</view>
+                </view>
+                <view class="radioBox">
+                  <radio color="#2DCF8C" value="weixinzn" :checked="'weixinzn' === radioCurrent" />
+                </view>
+              </view>
+            </template>
+            <template v-if="projectFlag !== 'zhenning'">
+              <view class="pay-list-item">
+                <view class="pay-list-item-image">
+                  <image class="image" src="/static/img/juhe-icon-new.png" mode="aspectFit" />
+                  <view>聚合支付</view>
+                </view>
+                <view class="radioBox">
+                  <radio color="#2DCF8C" value="juhe" :checked="'juhe' === radioCurrent" />
+                </view>
+              </view>
+            </template>
+          </radio-group>
+        </view>
+        <view class="pay-money"> 金额:¥{{ orderMoney }} </view>
+      </view>
+    </u-modal>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import { getEnvIsWx } from '@/utils/judgEnvironment.js';
+import $wxPay from '@/utils/wxPay.js';
+export default {
+  data() {
+    return {
+      startTime: '',
+      endTime: '',
+      payUrl: '',
+      monthId: '',
+      vehicleNo: '',
+      monthEndTime: '',
+      monthStartTime: '',
+      lastActiveDate: null,
+      roadNo: null,
+      parkNo: null,
+      carLicenseList: [],
+      isShowCarLicense: false,
+      form: {
+        energyType: [],
+        monthAmount: 0,
+        carLicense: {},
+        month: 1,
+        dateRange: ''
+      },
+      label: '',
+      payWayPop: false,
+      jumpUrl: undefined,
+      monthlyContent: '',
+      carLicenseDefaultValue: [0],
+      wxEnv: false,
+      loading: false,
+      type: 'road',
+      monthlyRuleObj: {},
+      freeMonthNum: 0,
+      radioCurrent: '',
+      orderMoney: ''
+    };
+  },
+  watch: {
+    'form.month': {
+      handler(val) {
+        this.calcFreeMonthNum(val);
+      },
+      deep: true,
+      immediate: false
+    }
+  },
+  onLoad(page) {
+    this.wxEnv = getEnvIsWx();
+    this.getSysterms(0);
+    if (page.vehicleNo && page.roadNo) {
+      this.roadNo = page.roadNo;
+      this.vehicleNo = page.vehicleNo;
+      this.type = 'road';
+      this.getMonthInfo(this.roadNo, this.vehicleNo);
+    } else if (page.roadNo) {
+      this.roadNo = page.roadNo;
+      this.type = 'road';
+      this.getMonthInfo(this.roadNo);
+    } else if (page.vehicleNo && page.parkNo) {
+      this.parkNo = page.parkNo;
+      this.vehicleNo = page.vehicleNo;
+      this.type = 'park';
+      this.getMonthInfo(this.parkNo, this.vehicleNo);
+    } else if (page.parkNo) {
+      this.parkNo = page.parkNo;
+      this.type = 'park';
+      this.getMonthInfo(this.parkNo);
+    }
+    if (page.monthId) {
+      this.monthId = page.monthId;
+      this.payWayPop = true;
+    }
+    if (page.roadNo) {
+      this.monthlyRuleDetails(page.roadNo);
+    }
+    const baseUrl = location.origin;
+    let jumpUrl = baseUrl + '/pages/center/monthly/monthly?type=' + this.type;
+    this.jumpUrl = jumpUrl;
+  },
+  methods: {
+    /**
+     * 获取几个月的日期范围
+     * {date} Date 起始日期,往后推一天
+     * {monthNum} Number  往后月数
+     * */
+    getMonthRange(date, monthNum) {
+      let Date1 = this.lastActiveDate;
+      Date1 = new Date(Date1);
+      const year = Date1.getFullYear();
+      const month = Date1.getMonth() + 1;
+      const day = Date1.getDate();
+      const hours = Date1.getHours();
+      const minutes = Date1.getMinutes();
+      const seconds = Date1.getSeconds();
+      let days = new Date(year, month, 0);
+      days = days.getDate(); //获取当前日期中的月的天数
+      let year2 = year;
+      let month2 = parseInt(month) + parseInt(monthNum);
+      if (month2 > 12) {
+        year2 = parseInt(year2) + parseInt(parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12);
+        month2 = parseInt(month2) % 12;
+      }
+      let day2 = day;
+      let days2 = new Date(year2, month2, 0);
+      days2 = days2.getDate();
+      if (day2 > days2) {
+        day2 = days2;
+      }
+      if (month2 < 10) {
+        month2 = '0' + month2;
+      }
+      const t1 = year + '.' + (month > 9 ? month : '0' + month) + '.' + (day > 9 ? day : '0' + day);
+      const t2 = year2 + '.' + month2 + '.' + (day2 > 9 ? day2 : '0' + day2);
+      this.startTime = t1;
+      this.endTime = t2;
+      this.monthStartTime =
+        year + '-' + (month > 9 ? month : '0' + month) + '-' + (day > 9 ? day : '0' + day) + ' ' + hours + ':' + minutes + ':' + seconds;
+      this.monthEndTime = year2 + '-' + month2 + '-' + day2 + ' ' + hours + ':' + minutes + ':' + seconds;
+      return t1 + '-' + t2;
+    },
+    /**
+     * 月操作 减1
+     * */
+    reduceMonthNum() {
+      if (this.form.month > 1) {
+        this.form.month -= 1;
+        this.form.dateRange = this.getMonthRange(new Date(), this.form.month + this.freeMonthNum);
+      }
+    },
+    /**
+     * 月操作 加1
+     * */
+    addMonthNum() {
+      if (this.form.month >= 24) {
+        this.$refs.uToast.show({
+          title: '最多24月',
+          type: 'warning'
+        });
+        return;
+      }
+      this.form.month += 1;
+      this.form.dateRange = this.getMonthRange(new Date(), this.form.month + this.freeMonthNum);
+    },
+    carLicenseListConfirm(item) {
+      this.form.carLicense = item[0];
+      this.vehicleNo = item[0].label;
+      this.getMonthInfo(this.roadNo, this.vehicleNo);
+    },
+    /**
+     * 获取包月信息
+     * @date 2022-10-09
+     * @param {any} roadNo
+     * @param {any} vehicleNo
+     * @returns {any}
+     */
+    getMonthInfo(roadNo, vehicleNo) {
+      const params = {
+        vehicleNo
+      };
+      if (this.type === 'park') {
+        params.parkNo = roadNo;
+      } else {
+        params.roadNo = roadNo;
+      }
+      this.$u.api
+        .monthInfo(params)
+        .then((res) => {
+          if (res.code === 200 && res.data.vehicleList && res.data.vehicleList.length) {
+            this.lastActiveDate = res.data.lastActiveDate;
+            this.form.monthAmount = res.data.monthAmount;
+            this.orderMoney = (Number(this.form.monthAmount) * Number(this.form.month)).toFixed(2);
+            this.carLicenseList = [];
+            let vehicleNoItem = null;
+            res.data.vehicleList.forEach((item, index) => {
+              const obj = {
+                value: item.energyType,
+                label: item.vehicleNo,
+                energyType: item.energyType
+              };
+              if (this.vehicleNo == item.vehicleNo) {
+                vehicleNoItem = obj;
+                this.carLicenseDefaultValue = [index];
+              }
+              this.carLicenseList.push(obj);
+            });
+            // 判断是否url存在车牌号,存在则选中项默认选中
+            if (vehicleNoItem) {
+              this.form.carLicense = vehicleNoItem;
+            } else {
+              this.form.carLicense = this.carLicenseList[0];
+            }
+          }
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    },
+    /**
+     * 获取包月规则详情
+     * @date 2022-12-20
+     * @param {any} roadNo
+     * @returns {any}
+     */
+    monthlyRuleDetails(roadNo) {
+      this.$u.api
+        .monthlyRuleDetailsApi({
+          roadNo
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.monthlyRuleObj = res?.rows[0] ?? {};
+            this.calcFreeMonthNum(this.form.month);
+          }
+        });
+    },
+    calcFreeMonthNum(val) {
+      let freeNum = 0;
+      if (this.monthlyRuleObj.giveFlag && Number(this.monthlyRuleObj.giveFlag) === 1) {
+        // let remainNum = Number(val) % Number(this.monthlyRuleObj.minMonth)
+        let timesNum = parseInt(Number(val) / Number(this.monthlyRuleObj.minMonth));
+        if (timesNum > 0) {
+          this.freeMonthNum = Number(timesNum) * Number(this.monthlyRuleObj.giveMonth);
+        } else {
+          this.freeMonthNum = 0;
+        }
+      }
+    },
+    /**
+     * 提交包月信息
+     * @date 2022-10-09
+     * @param {any} roadNo
+     * @returns {any}
+     */
+    submit(roadNo) {
+      this.loading = true;
+      const params = {
+        vehicleNo: this.form.carLicense.label,
+        energyType: this.form.carLicense.energyType,
+        monthStartTime: this.monthStartTime,
+        monthEndTime: this.monthEndTime,
+        monthCount: this.form.month
+      };
+      if (this.type === 'park') {
+        params.parkNo = this.parkNo;
+      } else {
+        params.roadNo = this.roadNo;
+      }
+      this.$u.api
+        .createMonth(params)
+        .then((res) => {
+          if (res.code === 200) {
+            this.monthId = res.data.monthId;
+            this.orderMoney = (Number(this.form.monthAmount) * Number(this.form.month)).toFixed(2);
+            this.payWayPop = true;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+          this.loading = false;
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '程序错误!',
+            type: 'error'
+          });
+          this.loading = false;
+        });
+    },
+    /**
+     * 贵州银行包月支付
+     * @date 2022-10-09
+     * @returns {any}
+     */
+    gyBankPay() {
+      this.$u.api
+        .monthPay({
+          monthId: this.monthId,
+          jumpUrl: this.jumpUrl
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            window.location.href = res.data.url;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+            this.jumpMonthList();
+          }
+        });
+    },
+    /**
+     * 聚合支付直接通过后台获取贵阳银行微信支付地址
+     * @date 2022-10-09
+     * @returns {any}
+     */
+    juhePay() {
+      // 支付成功跳转到包月页面
+      let params = {
+        monthId: this.monthId,
+        openid: '',
+        jumpUrl: this.jumpUrl
+      };
+      this.$u.api
+        .monthlyWxPay(params)
+        .then((res) => {
+          if (res.code === 200) {
+            localStorage.setItem('jumpUrl', this.jumpUrl);
+            location.href = res.data.qrCodeUrl;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+            this.jumpMonthList();
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '无法调起微信支付!',
+            type: 'error'
+          });
+        });
+    },
+    /**
+     * 微信支付
+     * @date 2022-10-09
+     * @returns {any}
+     */
+    wechatPay() {
+      this.$u.api
+        .wechatMonthlyPayapi({
+          monthId: this.monthId,
+          openid: this.vuex_wxinfo.openId
+        })
+        .then((r) => {
+          if (r.code === 200) {
+            $wxPay.weixinPay(r.data.wx).then((res) => {
+              switch (Number(res.code)) {
+                case 0: // 成功
+                  //#ifdef H5
+                  location.href = this.jumpUrl;
+                  //#endif
+                  break;
+                case 1: // 取消
+                  this.$refs.uToast.show({
+                    title: '已取消支付',
+                    type: 'info'
+                  });
+                  this.jumpMonthList();
+                  break;
+                case 2: // 支付失败
+                  this.$refs.uToast.show({
+                    title: '支付失败,请检查!',
+                    type: 'error'
+                  });
+                  this.jumpMonthList();
+                  break;
+              }
+            });
+          }
+        });
+    },
+    /**
+     * 获取包月说明
+     * @date 2022-10-09
+     * @param {any} termsType
+     * @returns {any}
+     */
+    getSysterms(termsType) {
+      this.$u.api
+        .getSysterms({
+          termsType: termsType
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.monthlyContent = res.data?.content;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '系统错误!',
+            type: 'error'
+          });
+        });
+    },
+    cancel() {
+      this.radioCurrent = '';
+      this.orderMoney = '';
+      this.payWayPop = false;
+      this.jumpMonthList();
+    },
+    jumpMonthList() {
+      this.$u.route({
+        url: '/pages/center/monthly/monthly',
+        type: 'redirect',
+        params: {
+          type: this.type
+        }
+      });
+    },
+    /**
+     * 选中支付类型
+     * @date 2023-02-17
+     * @param {any} {detail}
+     * @returns {any}
+     */
+    payRadioChange({ detail }) {
+      this.radioCurrent = detail.value;
+    },
+    /**
+     * 立即支付
+     * @date 2023-02-17
+     * @returns {any}
+     */
+    immediatePayment() {
+      if (this.radioCurrent) {
+        switch (this.radioCurrent) {
+          case 'weixin': // 微信支付
+            this.wechatPay();
+            break;
+          case 'gzyh':
+            this.gyBankPay();
+            break;
+          case 'juhe':
+            this.juhePay();
+            break;
+          case 'weixinzn':
+            this.juhePay();
+            break;
+        }
+      } else {
+        this.$refs.uToast.show({
+          title: '请选择支付方式!',
+          type: 'warning'
+        });
+      }
+      this.$refs['uModal'].clearLoading();
+    }
+  },
+  computed: {
+    dateRange: function () {
+      return this.getMonthRange(this.lastActiveDate, this.form.month + this.freeMonthNum);
+    }
+  },
+  filters: {
+    verifyStatusFilter(value) {
+      if (value === 0) {
+        return '-';
+      } else if (value === 1) {
+        return '汽油车';
+      } else if (value === 2) {
+        return '新能源';
+      } else {
+        return '-';
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './handleMonthly.scss';
+@import '../paymentMethod/paymentMethod.scss';
+</style>

+ 29 - 0
pages/handleMonthly/monthPay.vue

@@ -0,0 +1,29 @@
+<template>
+	<view>
+		<a ref="payUrlRef" :href="PayUrl"></a>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				PayUrl: "",
+			};
+		},
+		onLoad(page) {
+			// console.log('page',page);
+			// console.log('page1',this.$u.queryParams(page).slice(0));
+			//15是因为传了‘currentPayUrl’,不要更改参数名
+			this.PayUrl = this.$u.queryParams(page).slice(8);
+		},
+		mounted() {
+			// console.log('this.PayUrl',this.PayUrl);
+			// console.log('this.$refs.payUrlRef',this.$refs.payUrlRef);
+			this.$refs.payUrlRef.click();
+		}
+	}
+</script>
+
+<style>
+</style>

+ 367 - 0
pages/index/index.scss

@@ -0,0 +1,367 @@
+page {
+  background-color: $my-page-bg-color;
+}
+
+.header-bar {
+  background-color: $my-main-color;
+  height: 106rpx;
+  display: flex;
+  padding: 0 40rpx;
+  .city {
+    display: flex;
+    margin-right: 23rpx;
+    color: #fff;
+    align-items: center;
+    .city-name {
+      margin-right: 8rpx;
+    }
+  }
+  .scan {
+    margin-left: 23rpx;
+  }
+}
+.content-nav {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  .content-nav-item {
+    .content-nav-item-icon-wrap {
+      width: 95rpx;
+      height: 95rpx;
+      margin: 0 auto 13rpx;
+      // border-radius: 30rpx;
+      // background: linear-gradient(163deg, #FFCC60 0%, #FF9221 100%);
+    }
+    .content-nav-item-icon-text {
+      font-size: 28rpx;
+      font-weight: 500;
+      color: #5a5a5a;
+      line-height: 1;
+    }
+  }
+  .content-nav-item + .content-nav-item {
+    // margin-left: 74rpx;
+  }
+}
+.pending-order-head {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  color: $my-main-color;
+  .pending-order-head-left {
+    font-size: 30rpx;
+    b {
+      font-weight: 500;
+      font-size: 50rpx;
+      margin-right: 5rpx;
+    }
+  }
+  .pending-order-head-right {
+    font-size: 22rpx;
+    font-weight: 500;
+  }
+}
+.pending-order-body {
+  .pending-order-body-nav {
+    display: flex;
+    border-radius: 32px;
+    border: 1px solid $my-main-color;
+    margin-bottom: 36rpx;
+    .nav-item {
+      flex: 1;
+      height: 62rpx;
+      line-height: 62rpx;
+      font-size: 24rpx;
+      text-align: center;
+      &.active {
+        background: $my-main-color;
+        color: #fff;
+        border-radius: 32rpx;
+      }
+    }
+  }
+  .pending-order-body-wrap {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    .pending-order-body-left-label {
+      font-size: 22rpx;
+      font-weight: 500;
+      color: #787878;
+      display: inline-block;
+      width: 160rpx;
+      text-align: right;
+    }
+    .pending-order-body-right-label {
+      color: #008cff;
+      margin-left: 20rpx;
+    }
+    .pending-order-body-center-label {
+      color: #008cff;
+    }
+    .nosign {
+      width: 100%;
+      line-height: 56rpx;
+      .nosign1 {
+        font-size: 40rpx;
+        color: #ff6d6d;
+        text-align: center;
+      }
+      .nosign2 {
+        color: #a6a6a6;
+        text-align: center;
+      }
+    }
+    .sign {
+      width: 100%;
+      line-height: 56rpx;
+      .sign1 {
+        font-size: 40rpx;
+        color: #52bd4e;
+        text-align: center;
+      }
+      .sign2 {
+        color: #a6a6a6;
+        text-align: center;
+      }
+    }
+  }
+  .pending-order-body-left {
+    .car-number {
+      margin-bottom: 20rpx;
+      font-size: 30rpx;
+      font-weight: 600;
+      color: #3a3a3a;
+      line-height: 42rpx;
+      letter-spacing: 1px;
+    }
+    .item-cell {
+      margin-bottom: 5rpx;
+      font-size: 26rpx;
+    }
+    .cost {
+      .number {
+        font-size: 26rpx;
+        line-height: 50rpx;
+        color: $my-main-color;
+      }
+    }
+  }
+  .pending-order-body-right {
+    text-align: left;
+    font-size: 24rpx;
+    .order {
+      margin-bottom: 28rpx;
+      font-weight: 400;
+      color: #9a9a9a;
+    }
+  }
+  .go-pay-wrap {
+    margin-top: 50rpx;
+    width: 100%;
+    text-align: center;
+    .go-pay {
+      display: inline-block;
+      padding: 12rpx 39rpx 11rpx;
+      background: linear-gradient(90deg, #ff2727 0%, #ff9a13 100%, #ff0f0f 100%);
+      color: #fff;
+      border-radius: 10rpx;
+      cursor: pointer;
+    }
+    .go-pay1 {
+      display: inline-block;
+      padding: 12rpx 39rpx 11rpx;
+      background: linear-gradient(90deg, #d3d3d3 0%, #f5f5f5 100%, #dcdcdc 100%);
+      color: #fff;
+      border-radius: 10rpx;
+      cursor: pointer;
+    }
+  }
+}
+
+.popup-order-details {
+  color: #545454;
+  &-til {
+    padding: 61rpx 40rpx 16rpx;
+    font-size: 36rpx;
+    color: #008cff;
+    line-height: 50rpx;
+    text-align: center;
+  }
+  &-con {
+    margin-bottom: 40rpx;
+  }
+  &-footer {
+    border-top: 1px solid #cecece;
+    padding: 28rpx 0 26rpx;
+    font-size: 45rpx;
+    line-height: 63rpx;
+    text-align: center;
+    color: #008cff;
+  }
+  dl {
+    margin: 20rpx 38rpx;
+    display: flex;
+    font-size: 30rpx;
+    dt {
+      width: 150rpx;
+      color: #a3a3a3;
+      text-align: right;
+    }
+    dd {
+      flex: 1;
+    }
+  }
+}
+
+.promotion {
+  margin: 20rpx 40rpx 40rpx;
+  background-color: #ffffff;
+  border-radius: 15rpx;
+  &-header {
+    padding: 26rpx 40rpx 12rpx;
+    border-bottom: 1px solid #dfdfdf;
+    margin-bottom: 26rpx;
+    .promotion-header-til {
+      font-size: 30rpx;
+      color: #383838;
+      line-height: 42rpx;
+    }
+    .promotion-header-con {
+      font-size: 22rpx;
+      color: #787878;
+      line-height: 30rpx;
+    }
+  }
+  &-body {
+    padding: 0 40rpx 24rpx;
+    .promotion-body-til {
+      font-size: 26rpx;
+      color: #676767;
+      line-height: 37rpx;
+      margin-bottom: 15rpx;
+    }
+    .promotion-body-con {
+      font-size: 20rpx;
+      color: #a5a5a5;
+      line-height: 34rpx;
+    }
+  }
+}
+.notice-bar-wrap {
+  margin: 20rpx 40rpx;
+  background-color: #fff;
+  padding: 32rpx 0 25rpx 30rpx;
+  border-radius: 15rpx;
+  overflow: hidden;
+}
+/* 优惠活动 */
+.promotion-box {
+  padding: 10px 20px;
+  .promotion-title {
+    text {
+      color: #3a3a3a;
+      font-size: 36rpx;
+      font-family: PingFangSC-Regular, PingFang SC;
+    }
+  }
+  .promotion-banner {
+    margin-top: 20rpx;
+    /deep/ .u-indicator-item-round {
+      background-color: #aad8ff;
+    }
+    /deep/ .u-indicator-item-round-active {
+      background-color: #ffffff;
+      // width: 20rpx;
+    }
+  }
+}
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 34rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}
+.empty-data-box {
+  background-color: #fff;
+  height: 462rpx;
+  width: calc(100% - 80rpx);
+  margin: 0 auto;
+  border-radius: 16rpx;
+  margin-top: 20rpx;
+}
+
+.myorders-item {
+  position: relative;
+  margin-bottom: 8rpx;
+  padding-left: 30rpx;
+  &::before {
+    content: '';
+    width: 9rpx;
+    height: 9rpx;
+    border-radius: 50%;
+    background-color: #626262;
+    position: absolute;
+    left: 0;
+    top: 17rpx;
+  }
+}
+.new-plate-number {
+  margin-bottom: 70rpx;
+}
+.message-input-wrap {
+  margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item {
+  background-color: #e8ffe8;
+}
+.really-license-txt {
+  color: #008cff;
+}
+.really-license-txt1 {
+  color: #008cff;
+  margin: 20rpx;
+}
+.popup-vehicleNo-title {
+  font-size: 48rpx;
+  text-align: center;
+  padding-top: 20rpx;
+}
+.popup-vehicleNo-center {
+  width: 95%;
+  height: 2rpx;
+  border-top: solid rgb(146, 146, 146) 2rpx;
+  margin: 30rpx 20rpx 50rpx 20rpx;
+}
+.popup-vehicleNo-select {
+  text-align: center;
+  color: #777777;
+}
+.vehicleNo-btn {
+  display: flex;
+  margin: 40rpx 0;
+}
+.parking-lock-pay-attention {
+  margin: 50rpx;
+  line-height: 48rpx;
+  color: #777777;
+}

+ 777 - 0
pages/index/index.vue

@@ -0,0 +1,777 @@
+<template>
+  <view>
+    <!-- ===================================== 搜索栏 ===================================== -->
+    <view class="header-bar">
+      <view class="city" @click="handleCitySelect">
+        <view class="city-name">{{ city }}</view>
+        <u-icon name="arrow-down" color="#fff" size="32"></u-icon>
+      </view>
+      <u-search placeholder="搜索停车点" :show-action="false" @search="handleSearch" v-model="keyword"></u-search>
+      <!-- <u-icon class="scan" name="scan" color="#fff" size="48" @click="$refs.uToast.show({title: '建设中'})"></u-icon> -->
+    </view>
+
+    <!-- ===================================== 轮播图 ===================================== -->
+    <u-swiper :list="bannerList" border-radius="0" mode="none" @click="swiperClick"></u-swiper>
+
+    <!-- ===================================== 城市选择器 ===================================== -->
+    <u-city-select v-model="cityOpen" @city-change="cityChange" :areaCode="['52', '5201']"></u-city-select>
+
+    <!-- ===================================== 滚动信息栏 ===================================== -->
+    <view class="notice-bar-wrap u-flex" v-if="noticeList.length >= 1" @click="openPage('pages/message/message', true)">
+      <u-icon custom-prefix="custom-icon" size="50" name="xiaoxi" color="#008CFF"></u-icon>
+      <u-notice-bar
+        class="u-flex-1"
+        mode="vertical"
+        :autoplay="true"
+        :list="noticeList"
+        :volume-icon="false"
+        bg-color="#fff"
+        color="#727272"
+        :more-icon="true"
+      ></u-notice-bar>
+    </view>
+
+    <!-- ===================================== 宫格菜单 ===================================== -->
+    <u-card :show-head="false" :show-foot="false" border-radius="16" margin="20rpx 40rpx" padding="30">
+      <view class="content-nav" slot="body">
+        <view class="content-nav-item" v-for="(grid, index) in gridList" :key="'g-' + index" @click="openPage(grid.url, true)">
+          <view class="content-nav-item-icon-wrap">
+            <u-image :src="grid.imageUrl" :width="grid.width || '95rpx'" :height="grid.height || '95rpx'" :mode="grid.mode || 'heightFix'"></u-image>
+          </view>
+          <view class="content-nav-item-icon-text">{{ grid.title }}</view>
+        </view>
+      </view>
+    </u-card>
+
+    <u-card :show-head="false" :show-foot="false" border-radius="16" margin="20rpx 40rpx" padding="30">
+      <view slot="body" class="myorders">
+        <view class="myorders-item"
+          >当前已缴费<text style="color: #008cff">{{ totalCount || '0' }}</text
+          >笔,合计<text style="color: #008cff">{{ totalActualAmount || '0' }}</text
+          >元</view
+        >
+        <view class="myorders-item"
+          >当前欠费<text style="color: #ff482b">{{ totalPayCount || '0' }}</text
+          >笔,合计<text style="color: #ff482b">{{ totalPayAmount || '0' }}</text
+          >元</view
+        >
+      </view>
+    </u-card>
+    <!-- ===================================== 无停车信息 ===================================== -->
+    <view class="empty-data-box" v-if="!orderList || orderList.length < 1">
+      <u-empty text="暂无停车信息" mode="list"></u-empty>
+    </view>
+
+    <!-- ===================================== 停车列表 ===================================== -->
+    <view v-for="item in orderList" :key="item.id">
+      <u-card :show-foot="false" border-radius="16" margin="20rpx 40rpx" padding="30">
+        <view class="pending-order-head" slot="head">
+          <view class="pending-order-head-left">
+            <b>P</b>
+            {{ item.roadName }}
+          </view>
+          <view class="pending-order-head-right" @click="onRoadInfo(item)">
+            <u-icon class="arrow-down" name="arrow-down" size="32" color="#aaa"></u-icon>
+          </view>
+        </view>
+        <view class="pending-order-body" slot="body">
+          <view class="pending-order-body-nav">
+            <view class="nav-item nav-manual" @click="orderNavclick()" :class="{ active: orderNav == 0 }"> 手动缴费</view>
+            <view class="nav-item nav-auto" @click="orderNavclick()" :class="{ active: orderNav == 1 }">无感支付 </view>
+          </view>
+          <view class="pending-order-body-wrap" v-show="orderNav == 0">
+            <view class="pending-order-body-left">
+              <view class="car-number">{{ item.vehicleNo }}</view>
+              <view class="item-cell">
+                <span class="pending-order-body-left-label">入场时间:</span>
+                <span>{{ item.inTime }}</span>
+              </view>
+              <view class="item-cell">
+                <span class="pending-order-body-left-label">出场时间:</span>
+                <span>{{ item.outTime || '未出场' }}</span>
+              </view>
+              <view class="item-cell">
+                <span class="pending-order-body-left-label">预计金额:</span>
+                <span>{{ item.payAmount || 0 }}</span>
+              </view>
+              <view class="item-cell" v-if="item.vehicleNo == ''">
+                <span class="pending-order-body-left-label">车牌信息:</span>
+                <span class="pending-order-body-center-label" @click="addvehicleNo(item.orderId)">添加车牌</span>
+              </view>
+              <view class="item-cell" v-else>
+                <span class="pending-order-body-left-label">车牌信息:</span>
+                <span>{{ item.vehicleNo }}</span>
+                <!-- <span class="pending-order-body-right-label" @click="changevehicleNo(item.orderId)">更换</span> -->
+              </view>
+              <!-- <view class="item-cell">
+                <span class="pending-order-body-left-label">出场时间:</span>
+                <span>{{item.outTime||'停放中'}}</span>
+              </view>
+              <view class="item-cell">
+                <span class="pending-order-body-left-label">停留时间:</span>
+                <span>{{item.duration||'停放中'}}</span>
+              </view>
+              <view class="item-cell cost">
+                <span class="pending-order-body-left-label">停车费用:</span>
+                <span>
+                  <span class="number" v-if="item.payAmount">¥{{item.payAmount}}</span>
+                  <span class="number" v-else>停放中</span>
+                </span>
+              </view>-->
+            </view>
+            <view class="pending-order-body-right">
+              <view class="order">停车泊位:{{ item.spaceName }}</view>
+            </view>
+            <view class="go-pay-wrap" v-if="Number(item.deviceType) !== 2">
+              <view class="go-pay" @click="goPay(item)" v-if="item.payAmount != 0">出场缴费</view>
+              <view class="go-pay1" v-else>出场缴费</view>
+            </view>
+          </view>
+          <view class="pending-order-body-wrap" v-show="orderNav == 1">
+            <view v-if="contractStatus == 0" class="nosign">
+              <view class="nosign1">您的车牌未签约贵州银行无感支付</view>
+              <view class="nosign2">请下载贵州银行手机银行app进行签约</view>
+            </view>
+            <view v-if="contractStatus == 1" class="sign">
+              <view class="sign1">您已签约贵州银行无感支付</view>
+              <view class="sign2">停车出场时将默认使用无感支付进行支付</view>
+            </view>
+          </view>
+        </view>
+      </u-card>
+    </view>
+
+    <!-- ===================================== 优惠活动 ===================================== -->
+    <view class="promotion-box">
+      <view class="promotion-title">
+        <text>优惠活动</text>
+      </view>
+      <view class="promotion-banner">
+        <u-swiper :list="promotionBannerList" @click="promotionBannerClick" height="221"></u-swiper>
+      </view>
+    </view>
+
+    <!-- ===================================== 绑定车牌号弹框 ===================================== -->
+    <u-modal
+      v-model="bindCarShow"
+      title="绑定车牌号"
+      :show-cancel-button="true"
+      confirm-text="去绑定"
+      content="首次使用请先绑定您的车牌"
+      @confirm="$u.route({ url: 'pages/myCars/myCars' })"
+    ></u-modal>
+
+    <!-- ===================================== 停车场信息弹框 ===================================== -->
+    <u-popup class="popup-order-details" v-model="showOrderDetails" mode="center" width="90%" border-radius="20">
+      <view class="popup-order-details-til">停车场信息</view>
+      <view class="popup-order-details-con">
+        <dl>
+          <dt>路段名称:</dt>
+          <dd>{{ popupOrderDetails.roadName }}</dd>
+        </dl>
+        <dl>
+          <dt>路段编码:</dt>
+          <dd>{{ popupOrderDetails.roadNo }}</dd>
+        </dl>
+        <dl>
+          <dt>联系人:</dt>
+          <dd>{{ popupOrderDetails.manager }}</dd>
+        </dl>
+        <dl>
+          <dt>联系电话:</dt>
+          <dd @click="phoneCall(popupOrderDetails.telephone)">{{ popupOrderDetails.telephone }}</dd>
+        </dl>
+      </view>
+      <view class="popup-order-details-footer" @click="closeOrderDetails">知道了</view>
+    </u-popup>
+
+    <!-- ===================================== 支付方式弹框 ===================================== -->
+    <!-- <PaymentMethod :payWayPop="payWayPop" :curOrderList="curOrderList" :jumpUrl="jumpUrl" @closePaymentMethod="closePaymentMethod"></PaymentMethod> -->
+
+    <!-- ===================================== 0元提示弹出层 ===================================== -->
+    <u-modal v-model="jumpMsgModal" :content="jumpMsgContent" :show-title="false" :show-confirm-button="false" />
+    <u-toast ref="uToast" />
+
+    <!-- ===================================== 添加车牌弹出层 ===================================== -->
+    <u-popup class="popup-vehicleNo" v-model="ShowaddvehicleNo" mode="center" border-radius="20" width="710rpx" height="auto">
+      <view class="popup-vehicleNo-title">添加车牌</view>
+      <view class="popup-vehicleNo-center"></view>
+      <view class="popup-vehicleNo-content">
+        <view class="new-plate-number">
+          <view class="message-input-wrap" @click="messageInputClick">
+            <u-message-input :maxlength="8" width="70" font-size="50" :disabled-keyboard="true" v-model="newPlateNumber"></u-message-input>
+          </view>
+        </view>
+      </view>
+      <view class="popup-vehicleNo-select">暂无绑定车牌</view>
+      <view class="vehicleNo-btn">
+        <u-button type="primary" @click="handleAddCar">确认</u-button>
+        <u-button type="primary" plain @click="ShowaddvehicleNo = false">取消</u-button>
+      </view>
+    </u-popup>
+
+    <u-action-sheet :list="colorList" @click="confirmColor" v-model="colorShow"></u-action-sheet>
+    <u-keyboard
+      ref="uKeyboard"
+      mode="car"
+      @change="keyboardChange"
+      @confirm="keyboardConfirm"
+      @backspace="backspace"
+      v-model="keyboardshow"
+    ></u-keyboard>
+
+    <!-- ===================================== 更换车牌弹出层 ===================================== -->
+    <u-popup class="popup-vehicleNo" v-model="ShowchangevehicleNo" mode="center" border-radius="20" width="710rpx" height="auto">
+      <view class="popup-vehicleNo-title">更换车牌</view>
+      <view class="popup-vehicleNo-center"></view>
+      <view class="popup-vehicleNo-content">
+        <view class="new-plate-number">
+          <view class="message-input-wrap" @click="messageInputClick">
+            <u-message-input :maxlength="8" width="70" font-size="50" :disabled-keyboard="true" v-model="newPlateNumber"></u-message-input>
+          </view>
+        </view>
+      </view>
+      <view class="popup-vehicleNo-select">
+        <u-collapse ref="refValue">
+          <u-collapse-item title="点击选择车牌" align="center">
+            <u-cell-group>
+              <u-cell-item :title="item.vehicleNo" v-for="(item, index) in groupList" :key="index" :arrow="false">
+                <u-radio-group v-model="selectvalue" @change="radioGroupChange">
+                  <u-radio :name="item.vehicleNo" :key="index"></u-radio>
+                </u-radio-group>
+              </u-cell-item>
+            </u-cell-group>
+          </u-collapse-item>
+        </u-collapse>
+      </view>
+      <view class="vehicleNo-btn">
+        <u-button type="primary" @click="handleAddCar">确认</u-button>
+        <u-button type="primary" plain @click="ShowchangevehicleNo = false">取消</u-button>
+      </view>
+    </u-popup>
+    <!-- 选择支付 -->
+    <ChoosePayment ref="choosePayment" :curOrderList="curOrderList" :jumpUrl="jumpUrl" @closePaymentMethod="closePaymentMethod" />
+  </view>
+</template>
+
+<script>
+import getUrlParams from '../../utils/getUrlParams.js';
+// import PaymentMethod from '@/pages/paymentMethod/paymentMethod.vue';
+import ChoosePayment from '@/pages/choosePayment/choosePayment.vue';
+import { jsonp } from 'vue-jsonp';
+export default {
+  components: {
+    // PaymentMethod,
+    ChoosePayment
+  },
+  data() {
+    return {
+      orderid: '',
+      selectvalue: null,
+      groupList: [],
+      radiogroupList: [],
+      keyboardshow: false,
+      colorShow: false,
+      colorList: [
+        { text: '蓝色', colorCode: 0 },
+        { text: '黄色', colorCode: 1 },
+        { text: '黑色', colorCode: 2 },
+        { text: '白色', colorCode: 3 },
+        { text: '绿色', colorCode: 4 },
+        { text: '其他', colorCode: 99 }
+      ],
+      vehicleColor: 0,
+      newPlateNumber: '',
+      //更换车牌弹窗
+      ShowchangevehicleNo: false,
+      //添加车牌弹窗
+      ShowaddvehicleNo: false,
+      // 城市选择框
+      cityOpen: false,
+      // 选中城市
+      city: '贵州省',
+      // 搜索框值
+      keyword: '',
+      // 轮播图
+      bannerList: [
+        {
+          image: require('@/static/img/index-banner01.png')
+        }
+      ],
+      // 订单列表
+      orderList: [],
+      // 微信code
+      code: null,
+      // 手动,无感
+      orderNav: '',
+      // 绑定车询问弹窗
+      bindCarShow: false,
+      // 是否线上订单细节
+      showOrderDetails: false,
+      // 订单详情
+      popupOrderDetails: [],
+      // 消息列表
+      noticeList: [],
+      // 优惠活动广告图
+      promotionBannerList: [
+        {
+          id: 1,
+          image: '/static/img/promotion-banner-1.png',
+          title: '1分钱停车'
+        },
+        {
+          id: 2,
+          image: '/static/img/promotion-banner-2.png',
+          title: '八折停车'
+        }
+      ],
+      // 签约状态
+      contractStatus: '',
+      vehicleId: '',
+      recordList: [],
+      // 支付方式弹框
+      payWayPop: false,
+      // 订单号
+      curOrderList: [],
+      // 当前位置经纬度
+      latLongItude: {},
+      // 跳转地址
+      jumpUrl: '',
+      // 宫格菜单列表
+      gridList: [
+        {
+          url: 'pages/payLists/payLists',
+          imageUrl: '../../static/img/index-content-nav-01.png',
+          title: '停车缴费'
+        },
+        {
+          url: 'pages/favourableActivity/favourableActivity',
+          imageUrl: '../../static/img/index-content-nav-02.png',
+          title: '优惠活动'
+        },
+        {
+          url: 'pages/myCars/myCars',
+          imageUrl: '../../static/img/index-content-nav-03.png',
+          title: '车辆管理'
+        },
+        {
+          url: 'pages/searchparking/searchparking',
+          imageUrl: '../../static/img/index-content-nav-04.png',
+          title: '我的停车'
+        }
+      ],
+      totalActualAmount: '', //缴费总额
+      totalPayAmount: '', //应支付总额
+      totalCount: '', //缴费总笔数
+      totalPayCount: '', //应支付总笔数
+      // 0元提示框
+      jumpMsgModal: false,
+      // 0元提示内容
+      jumpMsgContent: ''
+    };
+  },
+  onLoad(page) {
+    // 获取参数免费时长
+    this.$u.api
+      .getParamsApi({
+        key: 'park.lock.freetime'
+      })
+      .then((res) => {
+        if (res.code === 200) {
+          this.$u.vuex('free_time', res.msg);
+        }
+      });
+    const locationLocaturl = window.location.href;
+    // 微信聚合支付完成跳转过来重定向到详情页
+    const type = getUrlParams(locationLocaturl, 'type');
+    if (type && type === 'jumpurl') {
+      const jumpurl = localStorage.getItem('jumpUrl');
+      if (jumpurl) {
+        uni.showLoading({
+          title: '正在跳转中...'
+        });
+        setTimeout(() => {
+          uni.hideLoading();
+          location.href = jumpurl;
+        }, 0);
+      }
+    }
+    // 0元支付情况添加一个加载层
+    const jumpMsg = getUrlParams(locationLocaturl, 'jumpMsg');
+    if (jumpMsg) {
+      this.jumpMsgModal = true;
+      this.jumpMsgContent = jumpMsg;
+      setTimeout(() => {
+        this.jumpMsgModal = false;
+      }, 3000);
+    }
+    this.getLocation();
+  },
+  onShow() {
+    this.handleGetIndexData();
+    const locationLocaturl = window.location.search;
+    this.code = getUrlParams(locationLocaturl, 'code');
+    if (this.code && !this.$store.state.vuex_wxinfo.openId) {
+      this.handleGetWXInfo(this.code);
+    }
+  },
+  methods: {
+    radioGroupChange(e) {
+      this.newPlateNumber = e;
+    },
+    // 获取车辆列表
+    handlegetMycars() {
+      let that = this;
+      this.$u.api.getMycars().then((res) => {
+        if (res.code === 200) {
+          this.groupList = res.data.rows;
+          this.radiogroupList = res.data.rows;
+          this.$nextTick(() => {
+            // dom元素更新后执行,因此这里能正确打印更改之后的值
+            console.log(that.$refs.refValue.init()); // 改变了的值
+          });
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg,
+            type: 'error'
+          });
+        }
+      });
+    },
+    //更换车牌信息
+    changevehicleNo(id) {
+      this.orderid = id;
+      this.ShowchangevehicleNo = true;
+      this.handlegetMycars();
+    },
+    // 添加车辆
+    handleAddCar() {
+      if (!this.$u.test.carNo(this.newPlateNumber)) {
+        this.$refs.uToast.show({
+          title: '请正确填写车牌号',
+          type: 'error'
+        });
+        return;
+      }
+      let param = {
+        orderId: this.orderid,
+        vehicleNo: this.newPlateNumber,
+        vehicleColor: this.vehicleColor
+      };
+      let that = this;
+      this.$u.api.bindVehicleNo(param).then((res) => {
+        if (res.code === 200) {
+          this.$refs.uToast.show({
+            title: res.msg,
+            type: 'success'
+          });
+          that.handleGetIndexData();
+          that.ShowchangevehicleNo = false;
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg,
+            type: 'error'
+          });
+        }
+      });
+    },
+    //新增车牌
+    addvehicleNo() {
+      this.ShowaddvehicleNo = true;
+    },
+
+    // 点击输入框
+    messageInputClick() {
+      this.keyboardshow = true;
+    },
+    // 按键被点击(点击退格键不会触发此事件)
+    keyboardChange(val) {
+      // 将每次按键的值拼接到value变量中,注意+=写法
+      this.newPlateNumber += val;
+    },
+    // 退格键被点击
+    backspace() {
+      // 删除value的最后一个字符
+      if (this.newPlateNumber.length) this.newPlateNumber = this.newPlateNumber.substr(0, this.newPlateNumber.length - 1);
+    },
+    // 键盘输入完成后确认
+    keyboardConfirm() {
+      this.colorShow = true;
+    },
+    // 确认颜色
+    confirmColor(e) {
+      this.vehicleColor = this.colorList[e].colorCode;
+    },
+    //添加车牌
+    addvehicleNo(id) {
+      this.orderid = id;
+      this.ShowaddvehicleNo = true;
+    },
+    // 定位
+    getLocation() {
+      const that = this;
+      if (navigator.geolocation) {
+        // 判断是否有这个对象
+        navigator.geolocation.getCurrentPosition(
+          function (pos) {
+            that.latLongItude = {
+              latitude: pos.coords.latitude,
+              longitude: pos.coords.longitude
+            };
+            that.latitude = pos.coords.latitude;
+            that.longitude = pos.coords.longitude;
+            that.getCityNameByLonLat(that.latLongItude);
+          },
+          function (err) {
+            // 错误处理
+            // switch (err.code) {
+            //   case 1:
+            //     alert('位置服务被拒绝。');
+            //     break;
+            //   case 2:
+            //     alert('暂时获取不到位置信息。');
+            //     break;
+            //   case 3:
+            //     alert('获取信息超时。');
+            //     break;
+            //   default:
+            //     alert('未知错误。');
+            //     break;
+            // }
+            uni.getLocation({
+              type: 'gcj02',
+              success: function (res) {
+                that.latLongItude = {
+                  latitude: res.latitude,
+                  longitude: res.longitude
+                };
+                that.latitude = res.latitude;
+                that.longitude = res.longitude;
+                that.getCityNameByLonLat(that.latLongItude);
+              }
+            });
+          }
+        );
+      } else {
+        alert('当前系统不支持GPS API');
+      }
+    },
+    // 通过经纬度获取地区详细信息
+    getCityNameByLonLat({ longitude, latitude } = {}) {
+      const that = this;
+      uni.showLoading({
+        title: '加载中',
+        mask: true
+      });
+      const str = `output=jsonp&key=BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL&location=${latitude},${longitude}`;
+      jsonp('https://apis.map.qq.com/ws/geocoder/v1/?' + str, {}).then((res) => {
+        uni.hideLoading();
+        if (res.status == 0) {
+          if (res.result.ad_info) {
+            that.city = res.result.ad_info.district;
+          }
+        }
+      });
+    },
+    // 轮播图点击
+    swiperClick(item) {
+      this.$u.route({
+        url: 'pages/bannerDetails/bannerDetails',
+        params: {
+          id: this.bannerList[item].id
+        }
+      });
+    },
+    // 切换无感和手动
+    orderNavclick() {
+      uni.showLoading({
+        title: '加载中'
+      });
+      console.log('this.recordList[1]', this.recordList[1]);
+      console.log('orderNav', this.orderNav);
+      if (!this.recordList[1]) {
+        uni.hideLoading();
+        return;
+      }
+      this.$u.api
+        .feePay({
+          vehicleId: this.recordList[1]
+        })
+        .then((res) => {
+          console.log('res', res);
+          if (res?.code == 200) {
+            this.handleGetIndexData();
+          } else {
+            // this.$refs.uToast.show({
+            //   title: res?.msg,
+            //   type: 'error'
+            // })
+          }
+          uni.hideLoading();
+        })
+        .catch((err) => {
+          console.log('orderNavclick err', err);
+        });
+    },
+    /**
+     * 跳转页面
+     * path 跳转路径
+     * flag 是否存储
+     * */
+    openPage(path, flag) {
+      this.$u.route({
+        url: path
+      });
+      if (flag) {
+        uni.setStorage({
+          key: 'messageBack',
+          data: 'pages/index/index'
+        });
+      }
+    },
+    // 搜索
+    handleSearch() {
+      uni.reLaunch({
+        url: `/pages/parkingLists/parkingLists?keyword=${this.keyword}`
+      });
+    },
+    // 城市选择
+    handleCitySelect() {
+      this.cityOpen = true;
+    },
+    // 城市选择下拉变化
+    cityChange(e) {
+      if (e.area) {
+        this.city = e.area.label;
+      } else if (e.city) {
+        this.city = e.city.label;
+      } else {
+        this.city = e.province.label;
+      }
+    },
+    // 获取首页数据
+    handleGetIndexData() {
+      this.$u.api.getIndexData().then((res) => {
+        if (res.code === 200) {
+          // 轮播
+          const bannerList = [];
+          const banner = res.data?.advs;
+          banner.forEach((item) => {
+            const obj = {
+              image: item.bannerUrl,
+              id: item.id,
+              name: item.name,
+              content: item.content
+            };
+            bannerList.push(obj);
+          });
+          if (bannerList.length > 0) {
+            this.bannerList = bannerList;
+          }
+          // 是否有绑定车牌: 没有则通过弹框去绑定
+          const vehicleList = res.data?.vehicleList ?? [];
+          if (vehicleList.length === 0) {
+            this.bindCarShow = true;
+          }
+          // 无感和手动
+          const enableFeepay = [];
+          const orderList = res.data?.orderList ?? [];
+          orderList.forEach((item) => {
+            if (item.enableFeepay) {
+              enableFeepay.push(item.enableFeepay);
+            } else {
+              enableFeepay.push(0);
+            }
+            enableFeepay.push(item.vehicleId);
+            if (item.contractStatus) {
+              enableFeepay.push(item.contractStatus);
+            } else {
+              enableFeepay.push(0);
+            }
+          });
+          this.totalActualAmount = res.data?.payedInfo?.totalActualAmount;
+          this.totalCount = res.data?.payedInfo?.totalCount;
+          this.totalPayAmount = res.data?.payingInfo?.totalPayAmount;
+          this.totalPayCount = res.data?.payingInfo?.totalCount;
+          this.recordList = enableFeepay;
+          this.orderNav = enableFeepay[0];
+          this.contractStatus = enableFeepay[2];
+          this.orderList = res.data.orderList;
+          // 消息提示
+          const newsList = [];
+          const news = res.data?.news ?? [];
+          news.forEach((item) => {
+            newsList.push(item.content);
+          });
+          this.noticeList = newsList;
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg,
+            type: 'error'
+          });
+        }
+      });
+    },
+    // 去支付,选择支付方式
+    goPay(item) {
+      const href = location.origin;
+      this.jumpUrl = href + '/pages/center/order/orderDetails/orderDetails?orderId=' + item.id + '&type=open';
+      // this.payWayPop = true;
+      this.curOrderList = [];
+      this.curOrderList.push(item.id);
+      this.$refs['choosePayment'].openPopup({ ...item }, 'single', 'road');
+    },
+    // 获取路段详情
+    onRoadInfo(item) {
+      this.$u.api
+        .roadInfoById({
+          id: item.roadId
+        })
+        .then((res) => {
+          this.popupOrderDetails = res.data;
+          this.showOrderDetails = true;
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '系统异常',
+            type: 'error'
+          });
+        });
+    },
+    // 关闭路段详情弹框
+    closeOrderDetails() {
+      this.showOrderDetails = false;
+    },
+    // 打电话
+    phoneCall(phone) {
+      uni.makePhoneCall({
+        phoneNumber: phone
+      });
+    },
+    /**
+     * 点击优惠活动的广告图
+     * */
+    promotionBannerClick(cur) {
+      this.promotionBannerList.forEach((item, index) => {
+        if (cur === index) {
+          this.$u.route({
+            url: 'pages/favourableActivity/favourableActivity',
+            params: {
+              title: item.title,
+              id: item.id
+            }
+          });
+        }
+      });
+    },
+    // 关闭支付弹框
+    closePaymentMethod() {
+      this.payWayPop = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './index.scss';
+</style>

+ 65 - 0
pages/message/message.scss

@@ -0,0 +1,65 @@
+.swiper-wrap {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - var(--window-top));
+  width: 100%;
+  .swiper-box {
+    flex: 1;
+  }
+}
+.page-box {
+  margin: 25rpx 40rpx;
+  .message {
+    overflow: hidden;
+    margin-bottom: 20rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    .message-top {
+      margin-bottom: 20rpx;
+      padding: 25rpx 40rpx;
+      .car {
+        font-size: 32rpx;
+        font-weight: 600;
+        color: #3a3a3a;
+        line-height: 45rpx;
+        letter-spacing: 1px;
+      }
+      .addr {
+        color: #858585;
+        font-size: 26rpx;
+        line-height: 37rpx;
+      }
+      .message-top-right {
+        padding: 0 15rpx;
+        height: 50rpx;
+        line-height: 48rpx;
+        border-radius: 5rpx;
+        position: relative;
+      }
+    }
+    .message-center {
+      padding: 0 40rpx 25rpx;
+      border-bottom: 1px solid #dfdfdf;
+      .message-center-item {
+        margin-bottom: 9rpx;
+        font-size: 26rpx;
+        font-weight: 400;
+        color: #595959;
+        line-height: 37rpx;
+        letter-spacing: 1px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        display: -webkit-box;
+        -webkit-line-clamp: 2;
+        -webkit-box-orient: vertical;
+      }
+    }
+    .u-cell_title {
+      color: '#008CFF';
+    }
+  }
+}
+.time {
+  margin-left: 115px;
+  margin-top: 10px;
+}

+ 159 - 0
pages/message/message.vue

@@ -0,0 +1,159 @@
+<template>
+  <view>
+    <u-navbar
+      title-color="#fff"
+      :custom-back="customBack"
+      :border-bottom="false"
+      back-icon-color="#CCE8FF"
+      :background="{ background: '#008CFF' }"
+      title="消息中心"
+    />
+    <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
+      <scroll-view scroll-y style="height: 100%; width: 100%" v-for="(messageItem, index) in messageList" :key="messageItem.id">
+        <view class="time">{{ messageItem.createTime }}</view>
+        <view class="page-box">
+          <view class="message" @click="goDetails(messageItem)">
+            <view class="message-top u-flex">
+              <view class="message-top-left u-flex-1">
+                <view class="car">{{ messageItem.title }}</view>
+              </view>
+              <view class="message-top-right u-flex-2">
+                <u-badge :is-dot="true" type="error" v-if="messageItem.readFlag == '0'"></u-badge>
+              </view>
+            </view>
+            <view class="message-center">
+              <view class="message-center-item">{{ messageItem.content }}</view>
+            </view>
+            <view class="message-bottom">
+              <u-cell-item title="查看详情" style="color: #008cff"></u-cell-item>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+    </mescroll-body>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
+export default {
+  mixins: [MescrollMixin], // 使用mixin
+  data() {
+    return {
+      messageList: []
+    };
+  },
+  methods: {
+    // 返回上一页
+    customBack() {
+      uni.getStorage({
+        key: 'messageBack',
+        success: (res) => {
+          this.$u.route({
+            type: 'switchTab',
+            url: res.data
+          });
+        }
+      });
+    },
+    /*下拉刷新的回调*/
+    downCallback() {
+      // 第2种: 下拉刷新和上拉加载调同样的接口, 则不用第1种, 直接mescroll.resetUpScroll()即可
+      this.mescroll.resetUpScroll(); // 重置列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
+    },
+    /*上拉加载的回调*/
+    upCallback(page) {
+      let pageNum = page.num; // 页码, 默认从1开始
+      let pageSize = page.size; // 页长, 默认每页10条
+      this.$u.api
+        .getMessageList({
+          pageSize: pageSize,
+          pageNum: pageNum
+        })
+        .then((res) => {
+          if (res.code == 200) {
+            // 接口返回的当前页数据列表 (数组)
+            let curPageData = res.data?.rows ?? [];
+            // 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
+            let curPageLen = curPageData.length;
+            // 接口返回的总页数 (如列表有26个数据,每页10条,共3页; 则totalPage=3)
+            let totalPage = res.data.pages;
+            // 接口返回的总数据量(如列表有26个数据,每页10条,共3页; 则totalSize=26)
+            let totalSize = res.data.total;
+            // 接口返回的是否有下一页 (true/false)
+            let hasNext = res.data.page < res.data.pages;
+
+            //设置列表数据
+            if (page.num == 1) this.messageList = []; // 如果是第一页需手动置空列表
+            this.messageList = this.messageList.concat(curPageData); // 追加新数据
+            // 后台接口有返回列表的总页数 totalPage
+            this.mescroll.endByPage(curPageLen, totalPage);
+            setTimeout(() => {
+              this.mescroll.endSuccess(curPageLen);
+            }, 20);
+          } else {
+            this.mescroll.endErr();
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+        });
+    },
+    // 跳转消息详情
+    goDetails(item) {
+      if (Number(item.readFlag) === 0) {
+        this.$u.api
+          .messageRead({
+            newId: item.id
+          })
+          .then((res) => {
+            if (res.code == 200) {
+              this.$u.route({
+                url: 'pages/message/messageInfo',
+                params: {
+                  details: JSON.stringify(item)
+                }
+              });
+            } else {
+              this.$refs.uToast.show({
+                title: res.msg,
+                type: 'error'
+              });
+            }
+          })
+          .catch((err) => {
+            this.$refs.uToast.show({
+              title: '操作失败',
+              type: 'error'
+            });
+          });
+      } else {
+        this.$u.route({
+          url: 'pages/message/messageInfo',
+          params: {
+            details: JSON.stringify(item)
+          }
+        });
+      }
+    }
+  }
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+  height: 100%;
+  background-color: #f6f6ff;
+}
+
+/* #endif */
+</style>
+
+<style lang="scss" scoped>
+@import './message.scss';
+</style>

+ 74 - 0
pages/message/messageInfo.vue

@@ -0,0 +1,74 @@
+<template>
+  <view class="info">
+    <u-navbar
+      title-color="#fff"
+      :custom-back="customBack"
+      :border-bottom="false"
+      back-icon-color="#CCE8FF"
+      :background="{ background: '#008CFF' }"
+      title="消息详情"
+    ></u-navbar>
+    <view class="time">{{ details.createTime }}</view>
+    <view class="box">
+      <view class="title">{{ details.title }}</view>
+      <view class="content">{{ details.content }}</view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      details: {}
+    };
+  },
+  onLoad(page) {
+    const details = JSON.parse(page.details);
+    if (details) {
+      this.details = details;
+    }
+  },
+  methods: {
+    customBack() {
+      this.$u.route({
+        url: 'pages/message/message'
+      });
+    }
+  }
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+  height: 100%;
+  background-color: #f6f6ff;
+}
+
+/* #endif */
+</style>
+
+<style lang="scss" scoped>
+.info {
+  padding: 40rpx 40rpx;
+}
+
+.box {
+  margin-top: 20rpx;
+  background-color: white;
+  border-radius: 15rpx;
+
+  .title {
+    padding-top: 20rpx;
+    text-align: center;
+    font-size: 40rpx;
+  }
+}
+
+.content {
+  text-indent: 2em;
+  padding: 20rpx 40rpx;
+  line-height: 44rpx;
+}
+</style>

+ 132 - 0
pages/myCars/myCars.scss

@@ -0,0 +1,132 @@
+.header {
+  height: 296rpx;
+  overflow: hidden;
+  background: url(../../static/img/myCars-header-bg.png) no-repeat;
+  background-size: contain;
+  color: $my-main-color;
+}
+.header .header-title {
+  margin-top: 80rpx;
+  color: #fff;
+  font-size: 50rpx;
+  text-align: center;
+}
+
+.statistics {
+  margin: -78rpx 0 59rpx;
+  background-color: #fff;
+  box-shadow: 0px 6rpx 10px 0px rgba(0, 0, 0, 0.06);
+  border-radius: 15rpx;
+  height: 182rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #323232;
+}
+.statistics-title {
+  font-size: 60rpx;
+  letter-spacing: 2rpx;
+}
+.statistics-center {
+  width: 4rpx;
+  height: 106rpx;
+  margin: 0 103rpx;
+  box-shadow: 0px 6rpx 10rpx 0rx rgba(0, 0, 0, 0.06);
+  opacity: 0.5;
+  border: 1px solid #979797;
+}
+.statistics-number-wrap {
+  font-size: 28rpx;
+}
+.statistics-number-wrap .number {
+  margin-right: 4rpx;
+  font-size: 72rpx;
+}
+.add-car-btn {
+  height: 100rpx;
+  line-height: 100rpx;
+  background: #008cff;
+  color: #fff;
+  font-size: 28rpx;
+  text-align: center;
+  box-shadow: 0px 7rpx 13rpx 0px rgba(16, 153, 250, 0.31);
+  border-radius: 10rpx;
+  margin-bottom: 50rpx;
+}
+.new-plate-number {
+  margin-bottom: 70rpx;
+}
+.message-input-wrap {
+  margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item {
+  background-color: #e8ffe8;
+}
+.mycars {
+  padding-bottom: 30rpx;
+}
+.mycars-item {
+  display: flex;
+  align-items: center;
+  height: 111rpx;
+  border-bottom: 1px solid #eaeaea;
+}
+.mycars-item:nth-last-child(2) {
+  margin-bottom: 30rpx;
+}
+.mycars-item-name {
+  // margin-right: 43rpx;
+  width: 258rpx;
+  font-size: 36rpx;
+  color: #4b4b4b;
+}
+.mycars-item-type {
+  font-size: 26rpx;
+  color: #959595;
+}
+.mycars-item-sign {
+  line-height: 40rpx;
+  text-align: center;
+  border-radius: 5rpx;
+  color: #fff;
+  font-size: 22rpx;
+  padding: 0 15rpx;
+  border: solid 1px #ff6d6d;
+  background-color: #ff6d6d;
+  margin-left: 40rpx;
+}
+.mycars-item-sign1 {
+  line-height: 40rpx;
+  text-align: center;
+  border-radius: 5rpx;
+  color: #fff;
+  font-size: 22rpx;
+  padding: 0 15rpx;
+  border: solid 1px #d8d8d8;
+  background-color: #d8d8d8;
+  margin-left: 40rpx;
+}
+.mycars-item-tool {
+  flex: 1;
+  font-size: 22rpx;
+  color: #c9c9c9;
+  text-align: right;
+}
+.mycars-item-tool .default {
+  display: inline-block;
+  box-sizing: border-box;
+  // width: 75rpx;
+  height: 38rpx;
+  line-height: 34rpx;
+  border-radius: 5rpx;
+  border: 1px solid #e3e3e3;
+  text-align: center;
+  margin-right: 17rpx;
+  font-size: 18rpx;
+  color: #cdcdcd;
+}
+.mycars-item-tool .default.isDefault {
+  background-color: #ffeee3;
+  border-color: #ffeee3;
+  color: #fa6400;
+}

+ 273 - 0
pages/myCars/myCars.vue

@@ -0,0 +1,273 @@
+<template>
+  <view>
+    <u-navbar
+      title-color="#fff"
+      :custom-back="customBack"
+      :border-bottom="false"
+      back-icon-color="#CCE8FF"
+      :background="{ background: '#008CFF' }"
+      title="车辆管理"
+    ></u-navbar>
+    <view class="header">
+      <view class="header-title">我的车辆</view>
+    </view>
+    <view class="wrap">
+      <view class="statistics">
+        <view class="statistics-title">车辆</view>
+        <view class="statistics-center"></view>
+        <view class="statistics-number-wrap"
+          ><span class="number">{{ mycarsTotal }}</span
+          >辆</view
+        >
+      </view>
+      <view class="new-plate-number">
+        <view class="message-input-wrap" @click="messageInputClick">
+          <u-message-input :maxlength="8" width="70" font-size="50" :disabled-keyboard="true" v-model="newPlateNumber"></u-message-input>
+        </view>
+        <u-keyboard
+          ref="uKeyboard"
+          mode="car"
+          @change="keyboardChange"
+          @confirm="keyboardConfirm"
+          @backspace="backspace"
+          v-model="keyboardshow"
+        ></u-keyboard>
+      </view>
+      <view class="add-car-btn" @click="handleAddCar">添加车辆</view>
+      <view class="mycars">
+        <template v-if="mycars.length">
+          <view class="mycars-item" v-for="(item, index) in mycars" :key="index">
+            <view class="mycars-item-name">{{ item.vehicleNo }}</view>
+            <view class="mycars-item-type">{{ item.energyTpye | energyTpye }}</view>
+            <view class="mycars-item-sign" v-if="item.contractStatus == 1">已签约</view>
+            <view class="mycars-item-sign1" v-if="item.contractStatus == 0">未签约</view>
+            <view class="mycars-item-tool">
+              <span class="default" v-if="item.isDefault == 1" :class="{ isDefault: item.isDefault == 1 }" @click="handlesetDefault(item.id)"
+                >默认</span
+              >
+              <span class="default" v-else @click="handlesetDefault(item.id)">设为默认</span>
+              <span @click="handleDelCar(item.id, item.vehicleNo)">删除</span>
+            </view>
+          </view>
+          <u-loadmore :status="status" />
+        </template>
+        <template v-else>
+          <u-empty text="无车辆数据" mode="list"></u-empty>
+        </template>
+      </view>
+    </view>
+
+    <u-toast ref="uToast" />
+    <u-modal v-model="delCarshow" :show-cancel-button="true" @confirm="confirmDelCar" :content="delCarContent"></u-modal>
+    <u-action-sheet :list="colorList" @click="confirmColor" v-model="colorShow"></u-action-sheet>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      keyboardshow: false,
+      delCarshow: false,
+      delCarId: null,
+      delCarContent: '',
+      newPlateNumber: '',
+      vehicleColor: 0,
+      mycars: [],
+      status: 'loadmore',
+      page: {
+        num: 1,
+        size: 10,
+        total: 0
+      },
+      mycarsTotal: 0,
+      colorShow: false,
+      colorList: [
+        { text: '蓝色', colorCode: 0 },
+        { text: '黄色', colorCode: 1 },
+        { text: '黑色', colorCode: 2 },
+        { text: '白色', colorCode: 3 },
+        { text: '绿色', colorCode: 4 },
+        { text: '其他', colorCode: 99 }
+      ]
+    };
+  },
+  onLoad() {
+    this.mycars = [];
+    this.handlegetMycars();
+  },
+  onPullDownRefresh() {
+    Object.assign(this, {
+      keyboardshow: false,
+      delCarshow: false,
+      delCarId: null,
+      delCarContent: '',
+      newPlateNumber: '',
+      vehicleColor: 0,
+      mycars: [],
+      status: 'loadmore',
+      page: {
+        num: 1,
+        size: 10,
+        total: 0
+      },
+      mycarsTotal: 0,
+      colorShow: false,
+      colorList: [
+        { text: '蓝色', colorCode: 0 },
+        { text: '黄色', colorCode: 1 },
+        { text: '黑色', colorCode: 2 },
+        { text: '白色', colorCode: 3 },
+        { text: '绿色', colorCode: 4 },
+        { text: '其他', colorCode: 99 }
+      ]
+    });
+    setTimeout(() => {
+      this.handlegetMycars();
+      uni.stopPullDownRefresh(); //停止刷新
+    }, 1000);
+  },
+  onReachBottom() {
+    if (this.page.num >= this.page.total) return;
+    this.status = 'loading';
+    this.page.num = ++this.page.num;
+    setTimeout(() => {
+      this.handlegetMycars();
+    }, 1500);
+  },
+  methods: {
+    customBack() {
+      uni.getStorage({
+        key: 'messageBack',
+        success: (res) => {
+          this.$u.route({
+            type: 'switchTab',
+            url: res.data
+          });
+        },
+        fail: () => {
+          this.$u.route({
+            type: 'switchTab',
+            url: 'pages/index/index'
+          });
+        }
+      });
+    },
+    // 获取车辆列表
+    handlegetMycars() {
+      const { num, size } = this.page;
+      this.$u.api.getMycars({ pageNum: num, pageSize: size }).then((res) => {
+        if (res.code === 200) {
+          this.mycars = this.mycars.concat(res?.data?.rows ?? []);
+          this.page.total = Number(res?.data?.pages ?? 0);
+          this.mycarsTotal = Number(res?.data?.total ?? 0);
+          if (this.page.num >= this.page.total) this.status = 'nomore';
+          else this.status = 'loading';
+        }
+      });
+    },
+    // 添加车辆
+    async handleAddCar() {
+      const { newPlateNumber, vehicleColor } = this;
+      if (!this.$u.test.carNo(newPlateNumber)) {
+        this.showToast('请正确填写车牌号', 'warning');
+        return;
+      }
+      try {
+        const { code, msg } = await this.$u.api.addCar({ vehicleNo: newPlateNumber, vehicleColor });
+        if (code === 200) {
+          this.showToast(msg, 'success');
+          Object.assign(this.page, {
+            num: 1,
+            size: 10,
+            total: 0
+          });
+          this.mycars = [];
+          this.newPlateNumber = '';
+          this.vehicleColor = '';
+          this.handlegetMycars();
+        }
+      } catch (error) {
+        this.showToast('操作失败!', 'error');
+      }
+    },
+    // 删除车辆
+    handleDelCar(id, content) {
+      this.delCarContent = `是否删除${content}`;
+      this.delCarId = id;
+      this.delCarshow = true;
+    },
+    // 确认删除
+    async confirmDelCar() {
+      try {
+        const { code, msg } = await this.$u.api.delCar(this.delCarId);
+        if (code === 200) {
+          this.showToast(msg, 'success');
+          Object.assign(this.page, {
+            num: 1,
+            size: 10,
+            total: 0
+          });
+          this.mycars = [];
+          this.handlegetMycars();
+        }
+      } catch (error) {
+        this.showToast('操作失败!', 'error');
+      }
+    },
+    // 点击输入框
+    messageInputClick() {
+      this.keyboardshow = true;
+    },
+    // 按键被点击(点击退格键不会触发此事件)
+    keyboardChange(val) {
+      // 将每次按键的值拼接到value变量中,注意+=写法
+      this.newPlateNumber += val;
+    },
+    // 退格键被点击
+    backspace() {
+      // 删除value的最后一个字符
+      if (this.newPlateNumber.length) this.newPlateNumber = this.newPlateNumber.substr(0, this.newPlateNumber.length - 1);
+    },
+    // 键盘输入完成后确认
+    keyboardConfirm() {
+      this.colorShow = true;
+    },
+    // 确认颜色
+    confirmColor(e) {
+      this.vehicleColor = this.colorList[e].colorCode;
+    },
+    // 设置默认车辆操作
+    async handlesetDefault(id) {
+      try {
+        const { code, msg } = await this.$u.api.setDefaultCar({ id });
+        if (code === 200) {
+          this.showToast(msg, 'success');
+          Object.assign(this.page, {
+            num: 1,
+            size: 10,
+            total: 0
+          });
+          this.mycars = [];
+          this.handlegetMycars();
+        }
+      } catch (error) {
+        this.showToast('操作失败!', 'error');
+      }
+    },
+    /**
+     * @description: 显示提示
+     * @param {*} title
+     * @param {*} type
+     * @return {*}
+     */
+    showToast(title = '操作失败', type = 'info') {
+      this.$refs.uToast.show({ title, type });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import url('./myCars.scss');
+</style>

+ 81 - 0
pages/noninductivePay/addVehicle.vue

@@ -0,0 +1,81 @@
+<template>
+  <view>
+    <u-navbar
+      title-color="#fff"
+      :custom-back="customBack"
+      :border-bottom="false"
+      back-icon-color="#CCE8FF"
+      :background="{ background: '#008CFF' }"
+      title="新增免密支付车牌"
+    ></u-navbar>
+    <view class="new-plate-number">
+      <view class="message-input-wrap" @click="messageInputClick">
+        <u-message-input :maxlength="8" width="70" font-size="50" :disabled-keyboard="true" v-model="newPlateNumber"></u-message-input>
+      </view>
+      <u-keyboard
+        ref="uKeyboard"
+        mode="car"
+        @change="keyboardChange"
+        @confirm="keyboardConfirm"
+        @backspace="backspace"
+        v-model="keyboardshow"
+      ></u-keyboard>
+    </view>
+
+    <u-toast ref="uToast" />
+    <u-modal v-model="delCarshow" :show-cancel-button="true" @confirm="confirmDelCar" :content="delCarContent"></u-modal>
+    <u-action-sheet :list="colorList" @click="confirmColor" v-model="colorShow"></u-action-sheet>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      keyboardshow: false,
+      delCarshow: false,
+      colorShow: false,
+      delCarContent: '',
+      colorList: [
+        { text: '蓝色', colorCode: 0 },
+        { text: '黄色', colorCode: 1 },
+        { text: '黑色', colorCode: 2 },
+        { text: '白色', colorCode: 3 },
+        { text: '绿色', colorCode: 4 },
+        { text: '其他', colorCode: 99 }
+      ]
+    };
+  },
+  methods: {
+    customBack() {
+      this.$u.route({
+        type: 'switchTab',
+        url: 'pages/index/index'
+      });
+    },
+    messageInputClick() {
+      this.keyboardshow = true;
+    },
+    // 按键被点击(点击退格键不会触发此事件)
+    keyboardChange(val) {
+      // 将每次按键的值拼接到value变量中,注意+=写法
+      this.newPlateNumber += val;
+      console.log(this.newPlateNumber);
+    },
+    // 退格键被点击
+    backspace() {
+      // 删除value的最后一个字符
+      if (this.newPlateNumber.length) this.newPlateNumber = this.newPlateNumber.substr(0, this.newPlateNumber.length - 1);
+      console.log(this.newPlateNumber);
+    },
+    keyboardConfirm() {
+      this.colorShow = true;
+    },
+    confirmColor(e) {
+      this.vehicleColor = this.colorList[e].colorCode;
+    }
+  }
+};
+</script>
+
+<style></style>

+ 8 - 0
pages/noninductivePay/noninductivePay.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 309 - 0
pages/parkadvance/parkadvance.scss

@@ -0,0 +1,309 @@
+.parking-lock {
+  height: calc(100vh - 88rpx);
+  background-color: #f6f6ff;
+  padding-top: 133rpx;
+  .parking-lock-title {
+    font-size: 46rpx;
+    color: #292929;
+    text-align: center;
+    padding-top: 31rpx;
+    line-height: 65rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+  }
+  .parking-lock-tips {
+    width: calc(100% - 72rpx);
+    font-size: 30rpx;
+    color: #777777;
+    text-align: center;
+    margin: 10rpx auto;
+    line-height: 47rpx;
+  }
+  .parking-lock-info {
+    width: calc(100% - 72rpx);
+    margin: 31rpx auto 54rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    padding: 39rpx 41rpx;
+    .parking-lock-info-item {
+      display: flex;
+      margin-bottom: 16rpx;
+      view {
+        font-size: 28rpx;
+        &:first-child {
+          width: 30%;
+          color: #2a2a2a;
+          font-weight: 500;
+        }
+        &:last-child {
+          color: #6e6e6e;
+        }
+      }
+      .weight {
+        color: #2a2a2a !important;
+        font-weight: 500;
+      }
+      .really-money {
+        color: #fa7319 !important;
+      }
+    }
+  }
+  .parking-lock-pay-btn {
+    width: calc(100% - 72rpx);
+    margin: 0 auto;
+    button {
+      width: 100%;
+      height: 100rpx;
+      line-height: 100rpx;
+      background-color: #008cff;
+      border: none;
+      color: #fff;
+      box-shadow: 0px 7px 13px 0px rgba(16, 153, 250, 0.31);
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+  }
+  .parking-lock-begin-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(270deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    // animation: spin 3s linear infinite;
+    .parking-lock-begin-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-begin-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-loading-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(0deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    animation: spin 3s linear infinite;
+    .parking-lock-loading-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-loading-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-success {
+    .parking-lock-success-box {
+      width: 441rpx;
+      height: 441rpx;
+      margin: 0 auto;
+      image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .parking-lock-success-info {
+      color: #4ccd8a;
+      font-size: 50rpx;
+      text-align: center;
+      margin: 56rpx 0 202rpx;
+    }
+    .parking-lock-success-button {
+      width: calc(100% - 80rpx);
+      margin: 0 auto;
+      button {
+        width: 100%;
+        height: 100rpx;
+        line-height: 100rpx;
+        background-color: #008cff;
+        font-size: 28rpx;
+        color: #fff;
+      }
+    }
+  }
+}
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 34rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}
+@keyframes rotate {
+  0% {
+    transform: rotate(0);
+  }
+  50% {
+    transform: rotate(200deg);
+  }
+  100% {
+    transform: rotate(0);
+  }
+}
+@keyframes spin {
+  from {
+    transform: rotate(0);
+  }
+  to {
+    transform: rotate(359deg);
+  }
+}
+.loadingSelect {
+  text-align: center;
+  margin-top: 20rpx;
+}
+.spinner {
+  margin: auto;
+  width: 50px;
+  height: 60px;
+  text-align: center;
+  font-size: 10px;
+}
+
+.spinner > view {
+  background-color: #6495ed;
+  height: 100%;
+  width: 10rpx;
+  margin-right: 2rpx;
+  display: inline-block;
+
+  -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
+  animation: stretchdelay 1.2s infinite ease-in-out;
+}
+
+.spinner .rect2 {
+  -webkit-animation-delay: -1.1s;
+  animation-delay: -1.1s;
+}
+
+.spinner .rect3 {
+  -webkit-animation-delay: -1s;
+  animation-delay: -1s;
+}
+
+.spinner .rect4 {
+  -webkit-animation-delay: -0.9s;
+  animation-delay: -0.9s;
+}
+
+.spinner .rect5 {
+  -webkit-animation-delay: -0.8s;
+  animation-delay: -0.8s;
+}
+
+@-webkit-keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    -webkit-transform: scaleY(1);
+  }
+}
+
+@keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    transform: scaleY(0.4);
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    transform: scaleY(1);
+    -webkit-transform: scaleY(1);
+  }
+}
+.new-plate-number {
+  margin-bottom: 70rpx;
+}
+.message-input-wrap {
+  margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item {
+  background-color: #e8ffe8;
+}
+.really-license-txt {
+  color: #008cff;
+}
+.really-license-txt1 {
+  color: #008cff;
+  margin: 20rpx;
+}
+.popup-vehicleNo-title {
+  font-size: 48rpx;
+  text-align: center;
+  padding-top: 20rpx;
+}
+.popup-vehicleNo-center {
+  width: 95%;
+  height: 2rpx;
+  border-top: solid rgb(146, 146, 146) 2rpx;
+  margin: 30rpx 20rpx 50rpx 20rpx;
+}
+.popup-vehicleNo-select {
+  text-align: center;
+  color: #777777;
+}
+.vehicleNo-btn {
+  display: flex;
+  margin: 40rpx 0;
+}
+.parking-lock-pay-attention {
+  margin: 50rpx;
+  line-height: 48rpx;
+  color: #777777;
+}

+ 90 - 0
pages/parkadvance/parkadvance.vue

@@ -0,0 +1,90 @@
+<template>
+  <!-- 地磁 -->
+  <view class="parking-lock">
+    <!-- 地磁支付 -->
+    <template>
+      <view class="parking-lock-pay" v-if="infoData">
+        <!-- <view class="parking-lock-title">支付停车费</view> -->
+        <!-- <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view> -->
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>停车场</view>
+            <view class="weight">{{ infoData.parkName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <input type="text" placeholder="请输入车牌" v-model="formInfo.vehicleNo" />
+          </view>
+        </view>
+        <view class="parking-lock-pay-btn">
+          <button type="default" @click="onSearchClick">查询</button>
+        </view>
+      </view>
+      <view v-else>
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>入口无车辆</view>
+          </view>
+        </view>
+      </view>
+    </template>
+  </view>
+</template>
+
+<script>
+export default {
+  components: {},
+  data() {
+    return {
+      intoInfo: {
+        parkNo: ''
+      },
+      formInfo: {
+        vehicleNo: ''
+      },
+      infoData: undefined
+    };
+  },
+  onLoad(page) {
+    this.intoInfo.parkNo = page?.parkNo;
+  },
+  onShow() {
+    this.getOrderDetails(this.intoInfo.parkNo);
+  },
+  onUnload() {},
+  methods: {
+    onSearchClick() {
+      let askParams = {
+        parkNo: this.intoInfo.parkNo,
+        vehicleNo: this.formInfo.vehicleNo
+      };
+      this.$u.api.getAdvanceInfoApi(askParams).then((res) => {
+        if (res.code === 200) {
+        } else {
+        }
+      });
+    },
+    /**
+     * 查询订单信息
+     * @param { String } tqgThree 车位ID
+     * @param { String } orderId 订单id
+     * @param { String } payeeId 收费员ID
+     */
+    getOrderDetails(parkNo) {
+      this.$u.api.getDetailAdvanceApi({ parkNo }).then((res) => {
+        if (res.code === 200) {
+          this.infoData = res.data;
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg || '订单无数据',
+            type: 'error'
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkadvance.scss';
+</style>

+ 309 - 0
pages/parkentrace/parkentrace.scss

@@ -0,0 +1,309 @@
+.parking-lock {
+  height: calc(100vh - 88rpx);
+  background-color: #f6f6ff;
+  padding-top: 133rpx;
+  .parking-lock-title {
+    font-size: 46rpx;
+    color: #292929;
+    text-align: center;
+    padding-top: 31rpx;
+    line-height: 65rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+  }
+  .parking-lock-tips {
+    width: calc(100% - 72rpx);
+    font-size: 30rpx;
+    color: #777777;
+    text-align: center;
+    margin: 10rpx auto;
+    line-height: 47rpx;
+  }
+  .parking-lock-info {
+    width: calc(100% - 72rpx);
+    margin: 31rpx auto 54rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    padding: 39rpx 41rpx;
+    .parking-lock-info-item {
+      display: flex;
+      margin-bottom: 16rpx;
+      view {
+        font-size: 28rpx;
+        &:first-child {
+          width: 30%;
+          color: #2a2a2a;
+          font-weight: 500;
+        }
+        &:last-child {
+          color: #6e6e6e;
+        }
+      }
+      .weight {
+        color: #2a2a2a !important;
+        font-weight: 500;
+      }
+      .really-money {
+        color: #fa7319 !important;
+      }
+    }
+  }
+  .parking-lock-pay-btn {
+    width: calc(100% - 72rpx);
+    margin: 0 auto;
+    button {
+      width: 100%;
+      height: 100rpx;
+      line-height: 100rpx;
+      background-color: #008cff;
+      border: none;
+      color: #fff;
+      box-shadow: 0px 7px 13px 0px rgba(16, 153, 250, 0.31);
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+  }
+  .parking-lock-begin-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(270deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    // animation: spin 3s linear infinite;
+    .parking-lock-begin-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-begin-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-loading-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(0deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    animation: spin 3s linear infinite;
+    .parking-lock-loading-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-loading-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-success {
+    .parking-lock-success-box {
+      width: 441rpx;
+      height: 441rpx;
+      margin: 0 auto;
+      image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .parking-lock-success-info {
+      color: #4ccd8a;
+      font-size: 50rpx;
+      text-align: center;
+      margin: 56rpx 0 202rpx;
+    }
+    .parking-lock-success-button {
+      width: calc(100% - 80rpx);
+      margin: 0 auto;
+      button {
+        width: 100%;
+        height: 100rpx;
+        line-height: 100rpx;
+        background-color: #008cff;
+        font-size: 28rpx;
+        color: #fff;
+      }
+    }
+  }
+}
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 34rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}
+@keyframes rotate {
+  0% {
+    transform: rotate(0);
+  }
+  50% {
+    transform: rotate(200deg);
+  }
+  100% {
+    transform: rotate(0);
+  }
+}
+@keyframes spin {
+  from {
+    transform: rotate(0);
+  }
+  to {
+    transform: rotate(359deg);
+  }
+}
+.loadingSelect {
+  text-align: center;
+  margin-top: 20rpx;
+}
+.spinner {
+  margin: auto;
+  width: 50px;
+  height: 60px;
+  text-align: center;
+  font-size: 10px;
+}
+
+.spinner > view {
+  background-color: #6495ed;
+  height: 100%;
+  width: 10rpx;
+  margin-right: 2rpx;
+  display: inline-block;
+
+  -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
+  animation: stretchdelay 1.2s infinite ease-in-out;
+}
+
+.spinner .rect2 {
+  -webkit-animation-delay: -1.1s;
+  animation-delay: -1.1s;
+}
+
+.spinner .rect3 {
+  -webkit-animation-delay: -1s;
+  animation-delay: -1s;
+}
+
+.spinner .rect4 {
+  -webkit-animation-delay: -0.9s;
+  animation-delay: -0.9s;
+}
+
+.spinner .rect5 {
+  -webkit-animation-delay: -0.8s;
+  animation-delay: -0.8s;
+}
+
+@-webkit-keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    -webkit-transform: scaleY(1);
+  }
+}
+
+@keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    transform: scaleY(0.4);
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    transform: scaleY(1);
+    -webkit-transform: scaleY(1);
+  }
+}
+.new-plate-number {
+  margin-bottom: 70rpx;
+}
+.message-input-wrap {
+  margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item {
+  background-color: #e8ffe8;
+}
+.really-license-txt {
+  color: #008cff;
+}
+.really-license-txt1 {
+  color: #008cff;
+  margin: 20rpx;
+}
+.popup-vehicleNo-title {
+  font-size: 48rpx;
+  text-align: center;
+  padding-top: 20rpx;
+}
+.popup-vehicleNo-center {
+  width: 95%;
+  height: 2rpx;
+  border-top: solid rgb(146, 146, 146) 2rpx;
+  margin: 30rpx 20rpx 50rpx 20rpx;
+}
+.popup-vehicleNo-select {
+  text-align: center;
+  color: #777777;
+}
+.vehicleNo-btn {
+  display: flex;
+  margin: 40rpx 0;
+}
+.parking-lock-pay-attention {
+  margin: 50rpx;
+  line-height: 48rpx;
+  color: #777777;
+}

+ 110 - 0
pages/parkentrace/parkentrace.vue

@@ -0,0 +1,110 @@
+<template>
+  <!-- 地磁 -->
+  <view class="parking-lock">
+    <!-- 地磁支付 -->
+    <template>
+      <view class="parking-lock-pay" v-if="infoData">
+        <!-- <view class="parking-lock-title">支付停车费</view> -->
+        <!-- <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view> -->
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>停车场</view>
+            <view class="weight">{{ infoData.parkingName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入口名称</view>
+            <view>{{ infoData.entranceName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>通道名称</view>
+            <view>{{ infoData.roadwayName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入场时间</view>
+            <view>{{ infoData.inTime }}</view>
+          </view>
+        </view>
+        <view class="parking-lock-pay-btn">
+          <button type="default" @click="onEntraceClick">立即入场</button>
+        </view>
+      </view>
+      <view v-else>
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>入口无车辆</view>
+          </view>
+        </view>
+      </view>
+    </template>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  components: {},
+  data() {
+    return {
+      intoInfo: {
+        parkNo: '',
+        roadwayNo: ''
+      },
+      infoData: undefined
+    };
+  },
+  onLoad(page) {
+    this.intoInfo.parkNo = page?.parkNo;
+    this.intoInfo.roadwayNo = page?.roadwayNo;
+  },
+  onShow() {
+    this.getOrderDetails(this.intoInfo.parkNo, this.intoInfo.roadwayNo);
+  },
+  onUnload() {},
+  methods: {
+    onEntraceClick() {
+      let askParams = {
+        orderId: this.infoData.id
+      };
+
+      this.$u.api.entranceByNoVehicleApi(askParams).then((res) => {
+        if (res.code === 200) {
+          this.$refs.uToast.show({
+            title: res.msg || '入场成功',
+            type: 'success'
+          });
+          uni.reLaunch({
+            url: '/pages/parkroadgate/parkroadgate'
+          });
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg || '入场失败',
+            type: 'error'
+          });
+        }
+      });
+    },
+    /**
+     * 查询订单信息
+     * @param { String } tqgThree 车位ID
+     * @param { String } orderId 订单id
+     * @param { String } payeeId 收费员ID
+     */
+    getOrderDetails(parkNo, roadwayNo) {
+      this.$u.api.getDetailEntranceApi({ parkNo, roadwayNo }).then((res) => {
+        if (res.code === 200) {
+          this.infoData = res.data;
+        } else {
+          this.$refs.uToast.show({
+            title: res.msg || '订单无数据',
+            type: 'error'
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkentrace.scss';
+</style>

+ 309 - 0
pages/parkexport/parkexport.scss

@@ -0,0 +1,309 @@
+.parking-lock {
+  height: calc(100vh - 88rpx);
+  background-color: #f6f6ff;
+  padding-top: 133rpx;
+  .parking-lock-title {
+    font-size: 46rpx;
+    color: #292929;
+    text-align: center;
+    padding-top: 31rpx;
+    line-height: 65rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+  }
+  .parking-lock-tips {
+    width: calc(100% - 72rpx);
+    font-size: 30rpx;
+    color: #777777;
+    text-align: center;
+    margin: 10rpx auto;
+    line-height: 47rpx;
+  }
+  .parking-lock-info {
+    width: calc(100% - 72rpx);
+    margin: 31rpx auto 54rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    padding: 39rpx 41rpx;
+    .parking-lock-info-item {
+      display: flex;
+      margin-bottom: 16rpx;
+      view {
+        font-size: 28rpx;
+        &:first-child {
+          width: 30%;
+          color: #2a2a2a;
+          font-weight: 500;
+        }
+        &:last-child {
+          color: #6e6e6e;
+        }
+      }
+      .weight {
+        color: #2a2a2a !important;
+        font-weight: 500;
+      }
+      .really-money {
+        color: #fa7319 !important;
+      }
+    }
+  }
+  .parking-lock-pay-btn {
+    width: calc(100% - 72rpx);
+    margin: 0 auto;
+    button {
+      width: 100%;
+      height: 100rpx;
+      line-height: 100rpx;
+      background-color: #008cff;
+      border: none;
+      color: #fff;
+      box-shadow: 0px 7px 13px 0px rgba(16, 153, 250, 0.31);
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+  }
+  .parking-lock-begin-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(270deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    // animation: spin 3s linear infinite;
+    .parking-lock-begin-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-begin-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-loading-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(0deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    animation: spin 3s linear infinite;
+    .parking-lock-loading-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-loading-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-success {
+    .parking-lock-success-box {
+      width: 441rpx;
+      height: 441rpx;
+      margin: 0 auto;
+      image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .parking-lock-success-info {
+      color: #4ccd8a;
+      font-size: 50rpx;
+      text-align: center;
+      margin: 56rpx 0 202rpx;
+    }
+    .parking-lock-success-button {
+      width: calc(100% - 80rpx);
+      margin: 0 auto;
+      button {
+        width: 100%;
+        height: 100rpx;
+        line-height: 100rpx;
+        background-color: #008cff;
+        font-size: 28rpx;
+        color: #fff;
+      }
+    }
+  }
+}
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 34rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}
+@keyframes rotate {
+  0% {
+    transform: rotate(0);
+  }
+  50% {
+    transform: rotate(200deg);
+  }
+  100% {
+    transform: rotate(0);
+  }
+}
+@keyframes spin {
+  from {
+    transform: rotate(0);
+  }
+  to {
+    transform: rotate(359deg);
+  }
+}
+.loadingSelect {
+  text-align: center;
+  margin-top: 20rpx;
+}
+.spinner {
+  margin: auto;
+  width: 50px;
+  height: 60px;
+  text-align: center;
+  font-size: 10px;
+}
+
+.spinner > view {
+  background-color: #6495ed;
+  height: 100%;
+  width: 10rpx;
+  margin-right: 2rpx;
+  display: inline-block;
+
+  -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
+  animation: stretchdelay 1.2s infinite ease-in-out;
+}
+
+.spinner .rect2 {
+  -webkit-animation-delay: -1.1s;
+  animation-delay: -1.1s;
+}
+
+.spinner .rect3 {
+  -webkit-animation-delay: -1s;
+  animation-delay: -1s;
+}
+
+.spinner .rect4 {
+  -webkit-animation-delay: -0.9s;
+  animation-delay: -0.9s;
+}
+
+.spinner .rect5 {
+  -webkit-animation-delay: -0.8s;
+  animation-delay: -0.8s;
+}
+
+@-webkit-keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    -webkit-transform: scaleY(1);
+  }
+}
+
+@keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    transform: scaleY(0.4);
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    transform: scaleY(1);
+    -webkit-transform: scaleY(1);
+  }
+}
+.new-plate-number {
+  margin-bottom: 70rpx;
+}
+.message-input-wrap {
+  margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item {
+  background-color: #e8ffe8;
+}
+.really-license-txt {
+  color: #008cff;
+}
+.really-license-txt1 {
+  color: #008cff;
+  margin: 20rpx;
+}
+.popup-vehicleNo-title {
+  font-size: 48rpx;
+  text-align: center;
+  padding-top: 20rpx;
+}
+.popup-vehicleNo-center {
+  width: 95%;
+  height: 2rpx;
+  border-top: solid rgb(146, 146, 146) 2rpx;
+  margin: 30rpx 20rpx 50rpx 20rpx;
+}
+.popup-vehicleNo-select {
+  text-align: center;
+  color: #777777;
+}
+.vehicleNo-btn {
+  display: flex;
+  margin: 40rpx 0;
+}
+.parking-lock-pay-attention {
+  margin: 50rpx;
+  line-height: 48rpx;
+  color: #777777;
+}

+ 224 - 0
pages/parkexport/parkexport.vue

@@ -0,0 +1,224 @@
+<template>
+  <!-- 地磁 -->
+  <view class="parking-lock">
+    <!-- 地磁支付 -->
+    <template v-if="infoData">
+      <view class="parking-lock-pay">
+        <view class="parking-lock-title">支付停车费</view>
+        <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view>
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>车牌号</view>
+            <view class="weight">{{ infoData.vehicleNo }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>停车场名称</view>
+            <view class="weight">{{ infoData.parkingName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入场车道</view>
+            <view class="weight">{{ infoData.entranceName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入场时间</view>
+            <view class="weight">{{ infoData.inTime }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>出场车道</view>
+            <view class="weight">{{ infoData.outEntranceName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>出场时间</view>
+            <view class="weight">{{ infoData.outTime }}</view>
+          </view>
+          <!-- <view class="parking-lock-info-item">
+						<view>通道名称</view>
+						<view class="weight">{{infoData.roadwayName}}</view>
+					</view> -->
+          <view class="parking-lock-info-item">
+            <view>免费时长</view>
+            <view class="weight">{{ infoData.freeDuration || `0天0时${free_time}分0秒` }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view class="weight">计费时长</view>
+            <view class="weight">{{ infoData.calcDuration }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>累计停车时长</view>
+            <view class="weight">{{ infoData.duration }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>应收金额</view>
+            <view class="weight">{{ infoData.totalAmount }}元</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>订单编号</view>
+            <view class="weight">{{ infoData.id }}</view>
+          </view>
+        </view>
+        <view class="parking-lock-pay-btn">
+          <button type="default" v-if="isPay" @click="onEntraceClick">支付出场</button>
+          <button type="default" v-else @click="jumpHome('/pages/index/index')">支付成功,返回首页</button>
+        </view>
+      </view>
+    </template>
+    <template v-else>
+      <view class="parking-lock-info">
+        <view class="parking-lock-info-item">
+          <view>出口无车辆</view>
+        </view>
+      </view>
+    </template>
+    <!-- 支付方式 -->
+    <ChoosePayment
+      ref="choosePayment"
+      :payWayPop="payWayPop"
+      :curOrderList="orderList"
+      :jumpUrl="jumpUrl"
+      :exportFlag="true"
+      :sanPay="saopay"
+      :otherParams="{ parkType: 'export' }"
+      @closePaymentMethod="closePaymentMethod"
+    />
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import ChoosePayment from '@/pages/choosePayment/choosePayment.vue';
+export default {
+  components: {
+    ChoosePayment
+  },
+  data() {
+    return {
+      intoInfo: {
+        parkNo: '',
+        roadwayNo: '',
+        polyOrderId: '',
+        isBack: 0
+      },
+      saopay: true,
+      payWayPop: false, // 支付弹框
+      infoData: undefined, // 订单信息
+      orderList: [], // 支付订单列表
+      jumpUrl: location.href + '&isBack=1', // 回调地址
+      timer: null, // 轮询
+      isPay: false // 支付按钮显示
+    };
+  },
+  onLoad(page) {
+    this.intoInfo.parkNo = page?.parkNo;
+    this.intoInfo.roadwayNo = page?.roadwayNo;
+    this.intoInfo.polyOrderId = page?.polyOrderId;
+    this.intoInfo.isBack = page?.isBack;
+  },
+  onShow() {
+    this.getOrderDetails(this.intoInfo.parkNo, this.intoInfo.roadwayNo);
+    if (this.intoInfo.polyOrderId && this.intoInfo.isBack == 1) {
+      uni.showLoading({
+        title: '订单状态查询中...'
+      });
+      this.timer = setInterval(() => {
+        this.handlePayStatus(this.intoInfo.polyOrderId);
+      }, 1000);
+    }
+  },
+  onUnload() {
+    clearInterval(this.timer);
+  },
+  methods: {
+    /**
+     * 立即支付
+     */
+    onEntraceClick() {
+      this.$nextTick(() => {
+        this.$refs['choosePayment'].openPopup({ ...this.infoData }, 'single', 'parking');
+      });
+    },
+    /**
+     * 反复查询支付状态
+     * @param { String } orderId
+     */
+    handlePayStatus(orderId) {
+      this.$u.api
+        .getOrderStateExportApi({
+          orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.payStatus === 1 || res.data.payStatus === 3) {
+              clearInterval(this.timer);
+              uni.hideLoading();
+              this.getOrderDetails(this.intoInfo.parkNo, this.intoInfo.roadwayNo);
+            } else if (res.data.payStatus === 2) {
+              this.isPay = true;
+              uni.hideLoading();
+            }
+          } else {
+            clearInterval(this.timer);
+            uni.hideLoading();
+            this.$refs.uToast.show({
+              title: res.msg || '支付失败!',
+              type: 'error'
+            });
+          }
+        })
+        .catch(() => {
+          uni.hideLoading();
+          clearInterval(this.timer);
+        });
+    },
+    /**
+     * 查询订单信息
+     * @param { String } parkNo 停车场编号
+     * @param { String } roadwayNo 出口编号
+     */
+    getOrderDetails(parkNo, roadwayNo) {
+      uni.showLoading({
+        title: '订单查询中...'
+      });
+      this.$u.api
+        .getDetailExportApi({
+          parkNo,
+          roadwayNo
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.infoData = res.data;
+            this.orderList = [res.data.id];
+            if (res.data.orderStatus == 2 || res.data.orderStatus == 3) {
+              this.isPay = true;
+            } else {
+              this.isPay = false;
+            }
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg || '订单无数据',
+              type: 'error'
+            });
+          }
+          uni.hideLoading();
+        })
+        .catch((err) => {
+          uni.hideLoading();
+        });
+    },
+    /**
+     * 关闭支付弹框
+     */
+    closePaymentMethod() {
+      this.payWayPop = false;
+    },
+    jumpHome(url) {
+      uni.switchTab({
+        url: url
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkexport.scss';
+</style>

+ 222 - 0
pages/parkexport/parkexport20230220.vue

@@ -0,0 +1,222 @@
+
+<template>
+  <!-- 地磁 -->
+  <view class="parking-lock">
+    <!-- 地磁支付 -->
+    <template v-if="infoData">
+      <view class="parking-lock-pay">
+        <view class="parking-lock-title">支付停车费</view>
+        <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view>
+        <view class="parking-lock-info">
+          <view class="parking-lock-info-item">
+            <view>车牌号</view>
+            <view class="weight">{{ infoData.vehicleNo }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>停车场名称</view>
+            <view class="weight">{{ infoData.parkingName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入场车道</view>
+            <view class="weight">{{ infoData.entranceName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>入场时间</view>
+            <view class="weight">{{ infoData.inTime }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>出场车道</view>
+            <view class="weight">{{ infoData.outEntranceName }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>出场时间</view>
+            <view class="weight">{{ infoData.outTime }}</view>
+          </view>
+          <!-- <view class="parking-lock-info-item">
+						<view>通道名称</view>
+						<view class="weight">{{infoData.roadwayName}}</view>
+					</view> -->
+          <view class="parking-lock-info-item">
+            <view>免费时长</view>
+            <view class="weight">{{ infoData.freeDuration || `0天0时${free_time}分0秒` }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view class="weight">计费时长</view>
+            <view class="weight">{{ infoData.calcDuration }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>累计停车时长</view>
+            <view class="weight">{{ infoData.duration }}</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>应收金额</view>
+            <view class="weight">{{ infoData.totalAmount }}元</view>
+          </view>
+          <view class="parking-lock-info-item">
+            <view>订单编号</view>
+            <view class="weight">{{ infoData.id }}</view>
+          </view>
+        </view>
+        <view class="parking-lock-pay-btn">
+          <button type="default" v-if="isPay" @click="onEntraceClick">支付出场</button>
+          <button type="default" v-else @click="jumpHome('/pages/index/index')">支付成功,返回首页</button>
+        </view>
+      </view>
+    </template>
+    <template v-else>
+      <view class="parking-lock-info">
+        <view class="parking-lock-info-item">
+          <view>出口无车辆</view>
+        </view>
+      </view>
+    </template>
+    <!-- 支付方式 -->
+    <PaymentMethod
+      :payWayPop="payWayPop"
+      :curOrderList="orderList"
+      :jumpUrl="jumpUrl"
+      :exportFlag="true"
+      :sanPay="saopay"
+			:otherParams="{ parkType: 'export' }"
+      @closePaymentMethod="closePaymentMethod"
+    ></PaymentMethod>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import PaymentMethod from '@/pages/paymentMethod/paymentMethod.vue';
+export default {
+  components: {
+    PaymentMethod,
+  },
+  data() {
+    return {
+      intoInfo: {
+        parkNo: '',
+        roadwayNo: '',
+        polyOrderId: '',
+        isBack: 0
+      },
+      saopay: true,
+      payWayPop: false, // 支付弹框
+      infoData: undefined, // 订单信息
+      orderList: [], // 支付订单列表
+      jumpUrl: location.href + '&isBack=1', // 回调地址
+      timer: null, // 轮询
+      isPay: false // 支付按钮显示
+    };
+  },
+  onLoad(page) {
+    this.intoInfo.parkNo = page?.parkNo;
+    this.intoInfo.roadwayNo = page?.roadwayNo;
+    this.intoInfo.polyOrderId = page?.polyOrderId;
+    this.intoInfo.isBack = page?.isBack;
+  },
+  onShow() {
+    this.getOrderDetails(this.intoInfo.parkNo, this.intoInfo.roadwayNo);
+    if (this.intoInfo.polyOrderId && this.intoInfo.isBack == 1) {
+      uni.showLoading({
+        title: '订单状态查询中...'
+      });
+      this.timer = setInterval(() => {
+        this.handlePayStatus(this.intoInfo.polyOrderId);
+      }, 1000);
+    }
+  },
+  onUnload() {
+    clearInterval(this.timer);
+  },
+  methods: {
+    /**
+     * 立即支付
+     */
+    onEntraceClick() {
+      this.payWayPop = true;
+    },
+    /**
+     * 反复查询支付状态
+     * @param { String } orderId
+     */
+    handlePayStatus(orderId) {
+      this.$u.api
+        .getOrderStateExportApi({
+          orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.payStatus === 1 || res.data.payStatus === 3) {
+              clearInterval(this.timer);
+              uni.hideLoading();
+              this.getOrderDetails(this.intoInfo.parkNo, this.intoInfo.roadwayNo);
+            } else if (res.data.payStatus === 2) {
+              this.isPay = true;
+              uni.hideLoading();
+            }
+          } else {
+            clearInterval(this.timer);
+            uni.hideLoading();
+            this.$refs.uToast.show({
+              title: res.msg || '支付失败!',
+              type: 'error'
+            });
+          }
+        })
+        .catch(() => {
+          uni.hideLoading();
+          clearInterval(this.timer);
+        });
+    },
+    /**
+     * 查询订单信息
+     * @param { String } parkNo 停车场编号
+     * @param { String } roadwayNo 出口编号
+     */
+    getOrderDetails(parkNo, roadwayNo) {
+      uni.showLoading({
+        title: '订单查询中...'
+      });
+      this.$u.api
+        .getDetailExportApi({
+          parkNo,
+          roadwayNo
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.infoData = res.data;
+            this.orderList = [res.data.id];
+            if (res.data.orderStatus == 2 || res.data.orderStatus == 3) {
+              this.isPay = true;
+            } else {
+              this.isPay = false;
+            }
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg || '订单无数据',
+              type: 'error'
+            });
+          }
+          uni.hideLoading();
+        })
+        .catch((err) => {
+          uni.hideLoading();
+        });
+    },
+    /**
+     * 关闭支付弹框
+     */
+    closePaymentMethod() {
+      this.payWayPop = false;
+    },
+    jumpHome(url) {
+      uni.switchTab({
+        url: url
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkexport.scss';
+</style>

+ 130 - 0
pages/parkingInformation/parkingInformation.scss

@@ -0,0 +1,130 @@
+.parking-information {
+  background-color: #fff;
+  width: 100%;
+  .parking-information-slider {
+    image {
+      width: 100%;
+      height: 410rpx;
+    }
+  }
+  .parking-information-content {
+    padding: 35rpx 40rpx;
+    .parking-information-content-title {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      border-bottom: solid 1px #979797;
+      padding-bottom: 25rpx;
+      .pict-left {
+        .title {
+          font-size: 32rpx;
+          color: #484848;
+          font-weight: 600;
+          text {
+            font-size: 24rpx;
+            color: #aaaaaa;
+            margin-left: 19rpx;
+          }
+        }
+        .subtitle {
+          font-size: 24rpx;
+          color: #969696;
+          font-weight: 400;
+          line-height: 33rpx;
+          margin-top: 10rpx;
+        }
+        .tags {
+          display: flex;
+          word-wrap: break-word;
+          margin-top: 10rpx;
+          .tag {
+            padding: 3rpx 18rpx;
+            border: solid 2rpx #fa6400;
+            border-radius: 4px;
+            color: #fa6400;
+            margin-right: 10rpx;
+            font-size: 18rpx;
+          }
+        }
+      }
+      .pict-right {
+        text-align: center;
+        font-size: 18rpx;
+        color: #3a3a3a;
+        font-weight: 400;
+        image {
+          width: 44rpx;
+          height: 44rpx;
+        }
+      }
+    }
+    .parking-information-content-subtitle {
+      font-size: 24rpx;
+      color: #3a3a3a;
+      margin: 13rpx 0;
+    }
+    .parking-information-content-time {
+      color: #555555;
+      font-size: 24rpx;
+      margin-bottom: 73rpx;
+      margin-top: 23rpx;
+      display: flex;
+      flex-direction: row;
+      view {
+        width: 50%;
+      }
+    }
+    .parking-information-content-cars {
+      display: flex;
+      justify-content: space-between;
+      .picc-tag {
+        width: 48%;
+        background-color: #f6f6ff;
+        border-radius: 15rpx;
+        height: 139rpx;
+        align-items: center;
+        text-align: center;
+        view {
+          line-height: 50rpx;
+          &:first-child {
+            color: #1997ff;
+            font-size: 56rpx;
+            padding-top: 28rpx;
+          }
+          &:last-child {
+            color: #838383;
+            font-size: 24rpx;
+          }
+        }
+      }
+    }
+    .parking-information-content-price {
+      text-align: center;
+      margin: 37rpx 0 81rpx 0;
+      font-size: 24rpx;
+      color: #a4a4a4;
+      font-weight: 400;
+      text {
+        margin-right: 33rpx;
+      }
+    }
+    .parking-information-content-button {
+      background-color: #008cff;
+      color: #fff;
+      height: 100rpx;
+    }
+    .parking-information-content-rule {
+      padding: 33rpx 0 37rpx 0;
+      font-size: 24rpx;
+      color: #3a3a3a;
+      line-height: 40rpx;
+      border-bottom: solid 2rpx #dddddd;
+    }
+    .parking-information-content-telphone {
+      padding: 23rpx 0 33rpx 0;
+      font-size: 24rpx;
+      color: #3a3a3a;
+      line-height: 45rpx;
+    }
+  }
+}

+ 146 - 0
pages/parkingInformation/parkingInformation.vue

@@ -0,0 +1,146 @@
+<template>
+  <view class="parking-information">
+    <view class="parking-information-slider">
+      <image src="../../static/img/parking-info-bg.png" mode=""></image>
+    </view>
+    <view class="parking-information-content">
+      <view class="parking-information-content-title">
+        <view class="pict-left">
+          <view class="title">{{ roadInfo.areaName }}</view>
+          <view class="subtitle">{{ roadInfo.roadName }}</view>
+        </view>
+        <view class="pict-right" @click="navigation(roadInfo.latitude, roadInfo.longitude, roadInfo.areaName)">
+          <image src="../../static/img/distance-icon.png" mode=""></image>
+          <view class="m">{{ roadInfo.distance | kmUnit }}</view>
+        </view>
+      </view>
+      <view class="parking-information-content-time">
+        <view
+          >服务时间:<text>{{ roadInfo.workBeginTime }}-{{ roadInfo.workEndTime }}</text></view
+        >
+        <view
+          >包月费用:<text>{{ roadInfo.monthAmount }}</text
+          >元</view
+        >
+      </view>
+      <view class="parking-information-content-cars">
+        <view class="picc-tag">
+          <view>{{ roadInfo.spaceTotal }}</view>
+          <view>共有车位</view>
+        </view>
+        <view class="picc-tag">
+          <view>{{ roadInfo.spaceIdle }}</view>
+          <view>空闲车位</view>
+        </view>
+      </view>
+      <view class="parking-information-content-price" @click="lookParkingRule(roadInfo)">
+        <text>点击查看停车规则</text>
+        <u-icon name="arrow-right"></u-icon>
+      </view>
+      <u-button class="parking-information-content-button" @click="createMonth(roadInfo)">办理包月</u-button>
+    </view>
+    <u-select v-model="mapSelect" :list="mapSelectList" @confirm="mapSelectConfirm"></u-select>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      roadInfo: [],
+      latitude: '',
+      longitude: '',
+      mapSelect: false,
+      mapSelectList: [
+        {
+          value: '1',
+          label: '腾讯地图'
+        },
+        {
+          value: '2',
+          label: '百度地图'
+        },
+        {
+          value: '3',
+          label: '高德地图'
+        }
+      ],
+      // 选中位置经纬度
+      currentPositionHover: {}
+    };
+  },
+  onLoad(page) {
+    this.roadInfo = JSON.parse(page.roadInfo);
+    const { latitude, longitude, roadInfo } = page;
+    this.latitude = latitude;
+    this.longitude = longitude;
+    this.roadInfo = JSON.parse(roadInfo);
+    console.log('this.roadInfo', this.roadInfo);
+  },
+  methods: {
+    /**
+     * 跳转停车标准页面
+     * {roadNo} 路段编码
+     * */
+    lookParkingRule(item) {
+      this.$u.route({
+        url: 'pages/chargeStandard/chargeStandard',
+        params: {
+          roadNo: item.roadNo
+        }
+      });
+    },
+    createMonth(item) {
+      this.$u.route({
+        url: 'pages/handleMonthly/handleMonthly',
+        params: {
+          roadNo: item.roadNo
+        }
+      });
+    },
+    /**
+     * 导航
+     * */
+    navigation(latitude, longitude, areaName) {
+      this.currentPositionHover = {
+        latitude,
+        longitude,
+        areaName
+      };
+      this.mapSelect = true;
+    },
+    // 多地图选择
+    mapSelectConfirm(item) {
+      const name = item[0].label;
+      switch (name) {
+        case '腾讯地图':
+          // uni.navigateTo({
+          //   url:
+          //     '/pages/parkingLists/map_web_view/map_web_view?url=https://3gimg.qq.com/lightmap/v1/marker/?marker=coord:' +
+          //     this.currentPositionHover.latitude +
+          //     ',' +
+          //     this.currentPositionHover.longitude +
+          //     '&referer=myApp&key=BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL'
+          // });
+          location.href = `https://apis.map.qq.com/uri/v1/routeplan?type=drive&from=我的位置&fromcoord=${this.latitude},${this.longitude}&to=${this.currentPositionHover.areaName}&tocoord=${this.currentPositionHover.latitude},${this.currentPositionHover.longitude}&policy=1&referer=BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL`;
+          break;
+        case '百度地图':
+          location.href = `http://api.map.baidu.com/marker?location=
+			${this.currentPositionHover.latitude},${this.currentPositionHover.longitude}&title=目的地&content=${this.currentPositionHover.areaName}
+			&output=html&src=webapp.baidu.openAPIdemo`;
+          break;
+        case '高德地图':
+          console.log(this.longitude);
+          // const gdurl = `https://uri.amap.com/navigation?from=${this.currentPosition.longitude},${this.currentPosition.latitude},起点&to=${this.currentPositionHover.longitude},${this.currentPositionHover.latitude},终点&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0`;
+          // window.location.href = gdurl;
+          location.href = `https://uri.amap.com/navigation?from=${this.longitude},${this.latitude},我的位置&to=${this.currentPositionHover.longitude},${this.currentPositionHover.latitude},${this.currentPositionHover.areaName}&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0`;
+          break;
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkingInformation';
+</style>

+ 414 - 0
pages/parkingLists/copy/parkingLists - 副本.vue

@@ -0,0 +1,414 @@
+<template>
+  <view class="parking">
+    <view class="loading" v-show="loading"><u-loadmore status="loading" icon-type="flower" :load-text="{ loading: '正在定位中...' }" /></view>
+    <view class="parking-header">
+      <u-search placeholder="搜索停车场" v-model="searchContent" :show-action="false" @change="searchInputChange"></u-search>
+      <u-icon
+        v-if="!searchContent && isShowSearchParking == false"
+        class="icon"
+        name="list"
+        size="44"
+        color="#ffffff"
+        placeholder-color="#B5B5B5"
+        search-icon-color="#B3B3B3"
+        @click="listIconClick"
+      ></u-icon>
+      <u-icon
+        v-if="searchContent || isShowSearchParking == true"
+        class="icon"
+        name="close"
+        size="36"
+        color="#ffffff"
+        placeholder-color="#B5B5B5"
+        search-icon-color="#B3B3B3"
+        @click="clearSearchInput"
+      ></u-icon>
+    </view>
+    <view class="parking-map">
+      <map
+        id="pagemap"
+        style="width: 100%; height: calc(100vh - 240rpx)"
+        :show-location="true"
+        :latitude="latitude"
+        :longitude="longitude"
+        @markertap="markertap"
+        :enable-traffic="true"
+        :enable-zoom="true"
+        :scale="scale"
+        :markers="covers"
+      ></map>
+    </view>
+    <view class="parking-current-address" v-if="nearParkingFlag">
+      <swiper
+        class="swiper"
+        :current="swiperCurrent"
+        :indicator-dots="false"
+        :vertical="true"
+        :autoplay="false"
+        previous-margin="30rpx"
+        next-margin="30rpx"
+        @change="swiperChange"
+      >
+        <swiper-item v-for="(item, index) in nearParkingList" :key="index + 'n'">
+          <view class="swiper-item">
+            <view @click="clickSearchParking(item)">{{ item.roadName }}</view>
+            <view>{{ item.areaName }}</view>
+            <view class="swiper-item-font">
+              <view>
+                <text>空闲车位</text>
+                <text class="yellow-font">{{ item.spaceIdle }}</text>
+              </view>
+              <view v-if="item.monthAmount">
+                <text>包月费用</text>
+                <text class="yellow-font">{{ item.monthAmount }}元</text>
+              </view>
+              <view>
+                <text>距离</text>
+                <text>{{ item.distance | kmUnit }}</text>
+              </view>
+            </view>
+            <view class="swiper-item-button">
+              <button type="default" @click="navigation(item.latitude, item.longitude)">导航</button>
+              <button type="default" :disabled="!item.monthAmount" :class="{ disabled: !item.monthAmount }" @click="createMonth(item)">
+                办理包月
+              </button>
+            </view>
+            <view @click="lookParkingRule(item)">
+              <text>点击查看停车规则</text>
+              <u-icon name="arrow-right"></u-icon>
+            </view>
+          </view>
+        </swiper-item>
+      </swiper>
+    </view>
+    <view class="parking-address-list" v-if="isShowSearchParking">
+      <view class="parking-address-list-item" v-for="(item, index) in searchParkingList" :key="index + 's'" @click="clickSearchParking(item)">
+        <view class="pali-left">
+          <view>{{ item.roadName }}</view>
+          <view>{{ item.areaName }}</view>
+        </view>
+        <view class="pali-right">
+          <image src="../../static/img/distance-icon.png" mode="" @click.stop="navigation(item.latitude, item.longitude)"></image>
+          <view>路线</view>
+        </view>
+      </view>
+    </view>
+    <u-select v-model="mapSelect" :list="mapSelectList" @confirm="mapSelectConfirm"></u-select>
+    <map id="map" hidden="true"></map>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import { qqMapTransBMap } from '../../utils/mapTrans.js';
+export default {
+  data() {
+    return {
+      searchContent: '',
+      page_map: '',
+      loading: false,
+      latitude: 26.64969,
+      longitude: 106.636453,
+      scale: 16,
+      currentPosition: {
+        latitude: 26.64969,
+        longitude: 106.636453
+      },
+      covers: [],
+      // 附近列表是否显示
+      nearParkingFlag: false,
+      // 轮播选中
+      swiperCurrent: 0,
+      // 附近停车列表
+      nearParkingList: [],
+      // 是否显示停车场列表
+      isShowSearchParking: false,
+      // 搜索停车场列表
+      searchParkingList: [],
+      // 显示单个停车场数据
+      isShowParkingDetail: false,
+      // 单个停车场数据
+      parkingDetailData: {},
+      mapSelect: false,
+      mapSelectList: [
+        {
+          value: '1',
+          label: '腾讯地图'
+        },
+        // {
+        //  value: '2',
+        //  label: '百度地图'
+        // },
+        {
+          value: '3',
+          label: '高德地图'
+        }
+      ],
+      // 选中位置经纬度
+      currentPositionHover: {}
+    };
+  },
+  onLoad(page) {
+    this.getLocation();
+    if (page.keyword) {
+      this.searchContent = page.keyword;
+      this.searchInputChange(page.keyword);
+    }
+  },
+  methods: {
+    /**
+     * 查询输入框发生变化
+     * @date 2021-08-10
+     * @param {String} value
+     */
+    searchInputChange(value) {
+      // 为空时关闭搜索列表
+      if (value === '') {
+        this.isShowSearchParking = false;
+      }
+      this.isShowParkingDetail = false;
+      this.getNearRoadsl();
+    },
+    /**
+     * 获取定位
+     * @date 2021-08-10
+     * @returns {any}
+     */
+    getLocation() {
+      const that = this;
+      console.log('请求定位');
+			that.getNearRoadsl();
+      // that.loading = true;
+      if (navigator.geolocation) {
+        // 判断是否有这个对象
+        navigator.geolocation.getCurrentPosition(function (pos) {
+          console.log('经度:' + pos.coords.longitude + '纬度:' + pos.coords.latitude);
+          that.latitude = pos.coords.latitude;
+          that.longitude = pos.coords.longitude;
+          that.currentPosition.latitude = pos.coords.latitude;
+          that.currentPosition.longitude = pos.coords.longitude;
+          that.loading = false;
+          that.getNearRoadsl();
+        });
+      } else {
+        this.$refs.uToast.show({
+          title: '当前系统不支持GPS API',
+          type: 'error'
+        });
+      }
+    },
+    /**
+     * 导航
+     * @date 2021-08-10
+     * @param {Number} latitude
+     * @param {Number} longitude
+     * @returns {any}
+     */
+    navigation(latitude, longitude) {
+      this.currentPositionHover = {
+        latitude: latitude,
+        longitude: longitude
+      };
+      this.mapSelect = true;
+    },
+    // 多地图选择
+    mapSelectConfirm(item) {
+      const name = item[0].label;
+      switch (name) {
+        case '腾讯地图':
+          uni.navigateTo({
+            url:
+              '/pages/parkingLists/map_web_view/map_web_view?url=https://3gimg.qq.com/lightmap/v1/marker/?marker=coord:' +
+              this.currentPositionHover.latitude +
+              ',' +
+              this.currentPositionHover.longitude +
+              '&referer=myApp&key=BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL'
+          });
+          break;
+        case '百度地图':
+          const bdOriginPoint = qqMapTransBMap(this.currentPosition.longitude, this.currentPosition.latitude); // 起点坐标
+          const bdCurrPoint = qqMapTransBMap(this.currentPositionHover.longitude, this.currentPositionHover.latitude); // 终点坐标
+          const baiduMap = 'https://map.baidu.com/mobile/webapp/index/index/foo=bar/vt=map';
+          const bdurl = `https://api.map.baidu.com/direction?origin=latlng:${bdOriginPoint.lat},${bdOriginPoint.lng}|name:起点&destination=latlng:${bdCurrPoint.lat},${bdCurrPoint.lng}|name:终点&mode=driving&output=html&src=webapp.baidu.openAPIdemo`;
+          console.log('百度地图theurl', bdurl);
+          window.location.href = baiduMap;
+          break;
+        case '高德地图':
+          const gdurl = `https://uri.amap.com/navigation?from=${this.currentPosition.longitude},${this.currentPosition.latitude},起点&to=${this.currentPositionHover.longitude},${this.currentPositionHover.latitude},终点&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0`;
+          console.log('高德地图theurl', gdurl);
+          window.location.href = gdurl;
+          // window.open(url, "_blank", "scrollbars=yes,resizable=1,modal=false,alwaysRaised=yes");
+          // uni.navigateTo({
+          //   url: `/pages/parkingLists/map_web_view/map_web_view?url=${encodeURIComponent(`//uri.amap.com/navigation?from=${this.currentPosition.longitude},${this.currentPosition.latitude},起点&to=${this.currentPositionHover.longitude},${this.currentPositionHover.latitude},终点&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0`)}`
+          // })
+          break;
+      }
+    },
+    /**
+     * 清空搜索框内容
+     * @date 2021-08-10
+     * @returns {any}
+     */
+    clearSearchInput() {
+      this.searchContent = '';
+      this.isShowSearchParking = false;
+      this.getNearRoadsl();
+    },
+    /**
+     * 默认首个点放大 如果有传入经纬度则对应的点放大
+     * @date 2021-08-10
+     * @param {Number} lon
+     * @param {Number} lat
+     * @returns {any}
+     */
+    getNearRoadsl(lon, lat) {
+      this.$u.api
+        .nearRoadsl({
+          latitude: this.currentPosition.latitude,
+          longitude: this.currentPosition.longitude,
+          roadName: this.searchContent
+        })
+        .then((res) => {
+          const nearParkingList = []; // 附近停车场列表
+          this.covers = [];
+          res.data.forEach((item, index, arr) => {
+            if (item.latitude && item.longitude) {
+              nearParkingList.push(item);
+              const marker = {
+                latitude: item.latitude,
+                longitude: item.longitude,
+                id: String(index),
+                iconPath: require('./../../static/img/parking-icon.png'),
+                width: 20,
+                height: 25
+              };
+              // 选中经纬度图标变大
+              if (lon && lat) {
+                if (lon === item.longitude && lat === item.latitude) {
+                  marker.width = 40;
+                  marker.height = 50;
+                }
+              } else {
+                if (this.covers.length > 0) {
+                  this.covers[0].width = 40;
+                  this.covers[0].height = 50;
+                }
+              }
+              this.covers.push(marker);
+            }
+          });
+          this.nearParkingList = nearParkingList;
+          if (nearParkingList.length > 0) {
+            this.latitude = nearParkingList[0]?.latitude || this.currentPosition.latitude;
+            this.longitude = nearParkingList[0]?.longitude || this.currentPosition.longitude;
+          } else {
+            this.$refs.uToast.show({
+              title: '没有相关停车场信息',
+              type: 'warning'
+            });
+          }
+          this.nearParkingFlag = true;
+          if (this.searchContent) {
+            this.searchParkingList = nearParkingList;
+            this.isShowSearchParking = true;
+            this.nearParkingFlag = false;
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+        });
+    },
+    /**
+     * 点击地图上的标记点触发
+     **/
+    markertap(e) {
+      let lon, lat;
+      this.covers.forEach((item, index) => {
+        if (e.detail.markerId === item.id) {
+          lon = item.longitude;
+          lat = item.latitude;
+          this.swiperCurrent = index;
+        }
+      });
+      this.getNearRoadsl(lon, lat);
+    },
+    /**
+     * 地址发生变化
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    swiperChange(item) {
+      const map = uni.createMapContext('pagemap');
+      map.moveToLocation({
+        longitude: this.nearParkingList[item.detail.current].longitude,
+        latitude: this.nearParkingList[item.detail.current].latitude
+      });
+      this.getNearRoadsl(this.nearParkingList[item.detail.current].longitude, this.nearParkingList[item.detail.current].latitude);
+    },
+    /**
+     * 点击单个停车场看详情
+     * @date 2021-08-10
+     * @param {Object} item 为选中项参数
+     * @returns {any}
+     */
+    clickSearchParking(item) {
+      if (item.monthAmount) {
+        this.$u.route({
+          url: 'pages/parkingInformation/parkingInformation',
+          params: {
+            roadInfo: JSON.stringify(item)
+          }
+        });
+      }
+    },
+    /**
+     * 跳转停车标准页面
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    lookParkingRule(item) {
+      this.$u.route({
+        url: 'pages/chargeStandard/chargeStandard',
+        params: {
+          roadNo: item.roadNo
+        }
+      });
+    },
+    /**
+     * 搜索右侧按钮点击
+     **/
+    listIconClick() {
+      this.isShowSearchParking = true;
+      this.nearParkingFlag = false;
+      this.searchParkingList = this.nearParkingList;
+    },
+    /**
+     * 跳转包月
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    createMonth(item) {
+      this.$u.route({
+        url: 'pages/handleMonthly/handleMonthly',
+        params: {
+          roadNo: item.roadNo
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.wrap {
+  margin-top: 20vh;
+}
+
+@import url('./parkingLists.scss');
+</style>

+ 441 - 0
pages/parkingLists/copy/parkingLists20221110.scss

@@ -0,0 +1,441 @@
+.parking {
+  background-color: #008cff;
+  position: relative;
+}
+.parking-header {
+  padding: 36rpx 40rpx;
+  display: flex;
+  justify-content: space-between;
+}
+.parking-header .icon {
+  margin-left: 42rpx;
+}
+.parking-details {
+  position: absolute;
+  width: calc(100% - 60rpx);
+  margin: 0 auto;
+  bottom: 68rpx;
+  z-index: 1000;
+  left: 30rpx;
+  background-color: #fff;
+  border-radius: 26.5rpx;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+.parking-details-header {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 40rpx;
+}
+.parking-details-left-address {
+  font-size: 28rpx;
+  font-weight: 700;
+}
+.parking-details-left-number {
+  display: flex;
+  flex-direction: row;
+  color: rgba(47, 47, 47, 0.5);
+  justify-content: space-between;
+  margin-top: 10rpx;
+}
+.parking-details-left-number text {
+  font-size: 40rpx;
+  color: rgba(0, 140, 255, 1);
+}
+.parking-details-button {
+  background-color: #008cff;
+  height: 103rpx;
+  line-height: 103rpx;
+  border-bottom-left-radius: 26.5rpx;
+  border-bottom-right-radius: 26.5rpx;
+  text-align: center;
+  color: #fff;
+  font-size: 28rpx;
+  font-family: PingFangSC-Medium;
+}
+.parking-details-right-time,
+.parking-details-right-distance {
+  height: 44rpx;
+  line-height: 44rpx;
+  color: #008cff;
+  display: flex;
+  flex-direction: row;
+  margin-bottom: 20rpx;
+  margin-top: 30rpx;
+}
+.parking-details-right-time image,
+.parking-details-right-distance image {
+  width: 44rpx;
+  height: 44rpx;
+  margin-right: 10rpx;
+}
+.parking-details-right-time text,
+.parking-details-right-distance text {
+  display: block;
+  font-weight: 500;
+}
+.parking-current-address {
+  position: absolute;
+  bottom: 80rpx;
+  z-index: 1000;
+  width: 100%;
+  height: 345rpx;
+}
+.parking-current-address .swiper {
+  height: 430rpx;
+}
+.parking-current-address .swiper-item {
+  background-color: #fff;
+  transform: scaleY(0.9);
+  margin: 0 10rpx;
+  border-radius: 25rpx;
+  padding: 30rpx;
+}
+.parking-current-address .swiper-item > view:first-child {
+  font-size: 32rpx;
+  color: #484848;
+  line-height: 50rpx;
+}
+.parking-current-address .swiper-item > view:nth-child(2) {
+  font-size: 24rpx;
+  color: #969696;
+  line-height: 50rpx;
+}
+.parking-current-address .swiper-item > view:nth-child(3) {
+  display: flex;
+  flex-direction: row;
+  background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#f4f7ff)); /*谷歌*/
+  background: linear-gradient(to right, #fff 0%, #f4f7ff 50%, #fff 100%);
+  justify-content: space-around;
+  height: 71rpx;
+  line-height: 71rpx;
+  border-radius: 20rpx;
+  margin-top: 20rpx;
+  margin-bottom: 20rpx;
+}
+.parking-current-address .swiper-item > view:nth-child(4) {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+}
+.parking-current-address .swiper-item > view:nth-child(5) {
+  text-align: center;
+  margin-top: 30rpx;
+  color: #a4a4a4;
+  font-size: 24rpx;
+}
+.parking-address-list {
+  position: absolute;
+  z-index: 99;
+  width: 100%;
+  padding: 32rpx 28rpx;
+  bottom: 0;
+  max-height: 65vh;
+  overflow-y: scroll;
+  // background-image: linear-gradient(top, rgba(246, 245, 255, 0) 0%, rgba(246, 245, 255, 1) 100%);
+  background-image: url('./../../static/img/parking-search-list-bg.png');
+  background-size: 100% 100%;
+}
+.parking-address-list-item {
+  background-color: #fff;
+  border-radius: 25rpx;
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 26rpx;
+  margin-top: 20rpx;
+}
+.pali-left {
+  width: 74%;
+}
+.pali-left view:first-child {
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #484848;
+}
+.pali-left view:last-child {
+  font-size: 24rpx;
+  font-weight: 400;
+  color: #969696;
+  margin-top: 10rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.pali-right image {
+  width: 58rpx;
+  height: 58rpx;
+}
+.pali-right view {
+  color: #969696;
+  font-size: 20rpx;
+}
+.yellow-font {
+  color: #fa6400;
+  margin-left: 10rpx;
+}
+.swiper-item-font {
+  color: #6d6d6d;
+  font-size: 28rpx;
+}
+.swiper-item-button button {
+  width: 48%;
+  height: 70rpx;
+  line-height: 70rpx;
+  font-size: 30rpx;
+}
+.swiper-item-button button:first-child {
+  border: solid 1px #008cff;
+  color: #008cff;
+  margin-right: 4%;
+}
+.swiper-item-button button:last-child {
+  background-color: #008cff;
+  color: #fff;
+}
+.swiper-item-button .disabled {
+  background-color: #d2d2d2 !important;
+}
+.loading {
+  width: 100%;
+  height: calc(100vh - 100rpx);
+  line-height: calc(100vh - 100rpx);
+  position: absolute;
+  z-index: 99999;
+  text-align: center;
+  background-color: rgba(0, 0, 0, 0.1);
+}
+.parking-address-details {
+  position: absolute;
+  bottom: 50rpx;
+  z-index: 1000000;
+  background: transparent;
+  width: 100%;
+}
+.parking-address-details-title {
+  width: calc(100% - 30rpx);
+  margin: 0 auto;
+  background: url(../../static/img/parking-info-bg.png) center center;
+  background-size: 100% 100%;
+}
+.padt-header {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 25rpx;
+}
+.padt-header > view > view:nth-child(1) {
+  color: #484848;
+  font-size: 32rpx;
+}
+.padt-header > view.padt-header-title > view:nth-child(2) {
+  color: #969696;
+  font-size: 24rpx;
+  margin-top: 16rpx;
+}
+.padt-header-icon {
+  text-align: center;
+}
+.padt-header-icon view {
+  font-size: 18rpx;
+  color: #3a3a3a;
+}
+.padt-header image {
+  width: 45rpx;
+  height: 45rpx;
+}
+.padt-timeline {
+  padding-left: 25rpx;
+  padding-bottom: 25rpx;
+  font-size: 25rpx;
+  color: #727275;
+}
+.padt-timeline text {
+  color: #fa6b0b;
+  margin-left: 5rpx;
+  font-size: 29rpx;
+}
+.parking-address-details-numer {
+  background-color: #fff;
+  border-radius: 25rpx;
+  width: calc(100% - 30rpx);
+  margin: 10rpx auto 0;
+  padding: 35rpx 25rpx;
+  display: flex;
+  flex-direction: row;
+}
+.parking-address-details-numer > view {
+  width: 48%;
+  height: 110rpx;
+  padding: 15rpx;
+  text-align: center;
+  background: linear-gradient(359deg, #ffffff 0%, #f6f6ff 100%);
+  border-radius: 15px;
+}
+.parking-address-details-numer > view > view:first-child {
+  color: #008cff;
+  font-size: 56rpx;
+  font-weight: 400;
+}
+.parking-address-details-numer > view > view:last-child {
+  color: #838383;
+  font-size: 24rpx;
+  font-weight: 400;
+}
+.parking-address-details-numer > view:last-child {
+  margin-left: 4%;
+}
+.parking-address-details-price {
+  background-color: #fff;
+  border-radius: 25rpx;
+  width: calc(100% - 30rpx);
+  margin: 10rpx auto 0;
+}
+.parking-address-details-price > view:first-child {
+  font-size: 24rpx;
+  color: #787878;
+  font-weight: 400;
+  text-align: center;
+  padding-top: 24rpx;
+}
+.parking-address-details-price > view > text:first-child {
+  font-size: 66rpx;
+  color: #008cff;
+}
+.parking-address-details-price > view:last-child {
+  width: 100%;
+  height: 81rpx;
+  line-height: 81rpx;
+  background: linear-gradient(180deg, #efefff 0%, #ffffff 100%);
+  border-bottom-left-radius: 25rpx;
+  border-bottom-right-radius: 25rpx;
+  text-align: center;
+  margin-top: 36rpx;
+}
+.parking-address-details-button {
+  width: calc(100% - 80rpx);
+  height: 96rpx;
+  line-height: 96rpx;
+  margin: 103rpx auto 57rpx;
+  background-color: #008cff;
+  border-radius: 10rpx;
+  text-align: center;
+  font-size: 28rpx;
+  color: #fff;
+}
+.address-box {
+  width: calc(100% - 60rpx);
+	height: 70vh;
+  padding: 15rpx 0;
+  position: absolute;
+  left: 30rpx;
+  bottom: 0;
+  z-index: 1000;
+  background-color: #f9f9f9;
+	transition: height .5s linear;
+  &-down-icon {
+    width: 32rpx;
+    height: 28rpx;
+    margin: 0 auto;
+    background: url('./../../static/img/down-icon.svg') no-repeat center center;
+    background-size: 100% 100%;
+		transform: rotate(0deg);
+		transition: transform 0.5s linear;
+  }
+  .up-icon {
+    transform: rotate(180deg);
+  }
+  &-scroll {
+    overflow: hidden;
+  }
+  &-list {
+    padding: 12rpx 30rpx;
+    &-item {
+      padding: 30rpx 40rpx;
+      background-color: #fff;
+      box-shadow: 0px 0px 10rpx 0px rgba(0, 0, 0, 0.08);
+      border-radius: 16rpx;
+      margin-bottom: 20rpx;
+      .abli-header {
+        padding-bottom: 26rpx;
+        margin-bottom: 26rpx;
+        border-bottom: dashed 1px #e1e5eb;
+        &-title {
+          font-size: 30rpx;
+          font-weight: 500;
+          color: #333333;
+          margin-bottom: 16rpx;
+        }
+        &-subtitle {
+          font-size: 26rpx;
+          color: #999;
+          margin-bottom: 26rpx;
+          margin-left: 30rpx;
+        }
+        &-surplus {
+          display: flex;
+          justify-content: space-between;
+          &-left {
+            font-size: 26rpx;
+            color: #999999;
+            text {
+              font-size: 30rpx;
+              color: #ff6d6d;
+              margin-left: 10rpx;
+            }
+          }
+          &-right {
+            padding: 6rpx 17rpx;
+            background-color: #008cff;
+            border-radius: 4rpx;
+            color: #fff;
+            font-size: 24rpx;
+          }
+          .disabled {
+            background-color: #cccccc;
+          }
+        }
+      }
+      .abli-bottom {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        &-left {
+          display: flex;
+          align-items: center;
+          &-navigation {
+            color: #008cff;
+            font-size: 26rpx;
+            border-right: solid 1px #cccccc;
+            padding-right: 20rpx;
+            &::before {
+              content: '';
+              display: inline-block;
+              width: 40rpx;
+              height: 31rpx;
+              background: url('./../../static/img/navigation-icon.svg') no-repeat center center;
+              background-size: 100% 100%;
+              margin-right: 10rpx;
+              vertical-align: middle;
+            }
+          }
+          &-distance {
+            padding-left: 20rpx;
+            color: #666666;
+            font-size: 26rpx;
+          }
+        }
+        &-right {
+          color: #999999;
+          font-size: 22rpx;
+        }
+      }
+    }
+  }
+}
+.address-down {
+	height: 60vh;
+}
+.address-up {
+	height: 20vh;
+}

+ 420 - 0
pages/parkingLists/copy/parkingLists20221110.vue

@@ -0,0 +1,420 @@
+<template>
+  <view class="parking">
+    <view class="loading" v-show="loading">
+      <u-loadmore status="loading" icon-type="flower" :load-text="{ loading: '正在定位中...' }" />
+    </view>
+    <view class="parking-header">
+      <u-search placeholder="搜索停车点" v-model="searchContent" :show-action="false" @change="searchInputChange"> </u-search>
+      <u-icon
+        v-if="!searchContent && isShowSearchParking == false"
+        class="icon"
+        name="list"
+        size="44"
+        color="#ffffff"
+        placeholder-color="#B5B5B5"
+        search-icon-color="#B3B3B3"
+        @click="listIconClick"
+      >
+      </u-icon>
+      <u-icon
+        v-if="searchContent || isShowSearchParking == true"
+        class="icon"
+        name="close"
+        size="36"
+        color="#ffffff"
+        placeholder-color="#B5B5B5"
+        search-icon-color="#B3B3B3"
+        @click="clearSearchInput"
+      >
+      </u-icon>
+    </view>
+    <view class="parking-map">
+      <map
+        id="pagemap"
+        style="width: 100%; height: calc(100vh - 240rpx)"
+        :show-location="true"
+        :latitude="latitude"
+        :longitude="longitude"
+        @markertap="markertap"
+        :enable-traffic="true"
+        :enable-zoom="true"
+        :scale="scale"
+        :markers="covers"
+      ></map>
+    </view>
+    <view class="address-box" :class="nearParkingObj.type == 'down' ? 'address-down' : 'address-up'" v-if="nearParkingFlag">
+      <view class="address-box-down-icon" :class="{ 'up-icon': nearParkingObj.type === 'up' }" @click="pullDown"> </view>
+      <scroll-view scroll-y class="address-box-scroll" :style="{ height: `calc(${nearParkingObj.height} - 76rpx)` }">
+        <view class="address-box-list">
+          <view class="address-box-list-item" v-for="(item, index) in nearParkingList" :key="index" @click="positionAddress(item)">
+            <view class="abli-header">
+              <view class="abli-header-title"
+                >{{ item.roadName }} <text class="abli-header-subtitle">{{ item.areaName }}</text></view
+              >
+              <!-- <view class="abli-header-subtitle">{{ item.areaName }}</view> -->
+              <view class="abli-header-surplus">
+                <view class="abli-header-surplus-left"
+                  >余位<text>{{ item.spaceIdle }}</text></view
+                >
+                <view class="abli-header-surplus-right" :class="{ disabled: !item.monthAmount }" @click.stop="createMonth(item)">办理包月</view>
+              </view>
+            </view>
+            <view class="abli-bottom">
+              <view class="abli-bottom-left">
+                <view class="abli-bottom-left-navigation" @click.stop="navigation(item.latitude, item.longitude, item.areaName)">导航</view>
+                <view class="abli-bottom-left-distance">{{ item.distance | kmUnit }}</view>
+              </view>
+              <view class="abli-bottom-right" @click.stop="lookParkingRule(item)">收费规则</view>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+    <view class="parking-address-list" v-if="isShowSearchParking">
+      <view class="parking-address-list-item" v-for="(item, index) in searchParkingList" :key="index + 's'" @click="clickSearchParking(item)">
+        <view class="pali-left">
+          <view>{{ item.roadName }}</view>
+          <view>{{ item.areaName }}</view>
+        </view>
+        <view class="pali-right">
+          <image src="../../static/img/distance-icon.png" mode="" @click.stop="navigation(item.latitude, item.longitude, item.areaName)"></image>
+          <view>路线</view>
+        </view>
+      </view>
+    </view>
+    <u-select v-model="mapSelect" :list="mapSelectList" @confirm="mapSelectConfirm"></u-select>
+    <map id="map" hidden="true"></map>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import { qqMapTransBMap } from '@/utils/mapTrans.js';
+export default {
+  data() {
+    return {
+      searchContent: '',
+      page_map: '',
+      loading: false,
+      latitude: 26.64969,
+      longitude: 106.636453,
+      scale: 16,
+      currentPosition: {
+        latitude: 26.64969,
+        longitude: 106.636453
+      },
+      covers: [],
+      // 附近列表是否显示
+      nearParkingFlag: false,
+      // 轮播选中
+      swiperCurrent: 0,
+      // 附近停车列表
+      nearParkingList: [],
+      // 是否显示停车场列表
+      isShowSearchParking: false,
+      // 搜索停车场列表
+      searchParkingList: [],
+      // 显示单个停车场数据
+      isShowParkingDetail: false,
+      // 单个停车场数据
+      parkingDetailData: {},
+      mapSelect: false,
+      mapSelectList: [
+        {
+          value: '1',
+          label: '腾讯地图'
+        },
+        {
+          value: '2',
+          label: '百度地图'
+        },
+        {
+          value: '3',
+          label: '高德地图'
+        }
+      ],
+      // 选中位置经纬度
+      currentPositionHover: {},
+      nearParkingObj: {
+        height: '60vh',
+        type: 'down'
+      }
+    };
+  },
+  onLoad(page) {
+    this.getLocation();
+    if (page.keyword) {
+      this.searchContent = page.keyword;
+      this.searchInputChange(page.keyword);
+    }
+  },
+  methods: {
+    /**
+     * 查询输入框发生变化
+     * @date 2021-08-10
+     * @param {String} value
+     */
+    searchInputChange(value) {
+      // 为空时关闭搜索列表
+      if (value === '') {
+        this.isShowSearchParking = false;
+      }
+      this.isShowParkingDetail = false;
+      this.getNearRoadsl();
+    },
+    /**
+     * 获取定位
+     * @date 2021-08-10
+     * @returns {any}
+     */
+    getLocation() {
+      const that = this;
+      console.log('请求定位');
+      // that.getNearRoadsl();
+      that.loading = true;
+      if (navigator.geolocation) {
+        // 判断是否有这个对象
+        navigator.geolocation.getCurrentPosition(function (pos) {
+          console.log('经度:' + pos.coords.longitude + '纬度:' + pos.coords.latitude);
+          that.latitude = pos.coords.latitude;
+          that.longitude = pos.coords.longitude;
+          that.currentPosition.latitude = pos.coords.latitude;
+          that.currentPosition.longitude = pos.coords.longitude;
+          that.loading = false;
+          that.getNearRoadsl();
+        });
+      } else {
+        this.$refs.uToast.show({
+          title: '当前系统不支持GPS API',
+          type: 'error'
+        });
+      }
+    },
+    /**
+     * 导航
+     * @date 2021-08-10
+     * @param {Number} latitude
+     * @param {Number} longitude
+     * @returns {any}
+     */
+    navigation(latitude, longitude, areaName) {
+      this.currentPositionHover = {
+        latitude,
+        longitude,
+        areaName
+      };
+      this.mapSelect = true;
+    },
+    // 多地图选择
+    mapSelectConfirm(item) {
+      const name = item[0].label;
+      switch (name) {
+        case '腾讯地图':
+          location.href = `https://apis.map.qq.com/uri/v1/routeplan?type=drive&from=我的位置&fromcoord=${this.currentPosition.latitude},${this.currentPosition.longitude}&to=${this.currentPositionHover.areaName}&tocoord=${this.currentPositionHover.latitude},${this.currentPositionHover.longitude}&policy=1&referer=BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL`;
+          break;
+        case '百度地图':
+          const lnglatObj = qqMapTransBMap(this.currentPositionHover.longitude, this.currentPositionHover.latitude);
+          location.href = `http://api.map.baidu.com/marker?location=
+			${lnglatObj.lat},${lnglatObj.lng}&title=目的地&content=${this.currentPositionHover.areaName}
+			&output=html&src=webapp.baidu.openAPIdemo`;
+          break;
+        case '高德地图':
+          location.href = `https://uri.amap.com/navigation?from=${this.currentPosition.longitude},${this.currentPosition.latitude},我的位置&to=${this.currentPositionHover.longitude},${this.currentPositionHover.latitude},${this.currentPositionHover.areaName}&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0`;
+          break;
+      }
+    },
+    /**
+     * 清空搜索框内容
+     * @date 2021-08-10
+     * @returns {any}
+     */
+    clearSearchInput() {
+      this.searchContent = '';
+      this.isShowSearchParking = false;
+      this.getNearRoadsl();
+    },
+    /**
+     * 默认首个点放大 如果有传入经纬度则对应的点放大
+     * @date 2021-08-10
+     * @param {Number} lon
+     * @param {Number} lat
+     * @returns {any}
+     */
+    getNearRoadsl(lon, lat) {
+      this.$u.api
+        .nearRoadsl({
+          latitude: this.currentPosition.latitude,
+          longitude: this.currentPosition.longitude,
+          roadName: this.searchContent
+        })
+        .then((res) => {
+          const nearParkingList = []; // 附近停车场列表
+          this.covers = [];
+          res.data.forEach((item, index, arr) => {
+            if (item.latitude && item.longitude) {
+              nearParkingList.push(item);
+              const marker = {
+                latitude: item.latitude,
+                longitude: item.longitude,
+                id: String(index),
+                iconPath: require('./../../static/img/parking-icon.png'),
+                width: 20,
+                height: 25
+              };
+              // 选中经纬度图标变大
+              if (lon && lat) {
+                if (lon === item.longitude && lat === item.latitude) {
+                  marker.width = 40;
+                  marker.height = 50;
+                }
+              } else {
+                if (this.covers.length > 0) {
+                  this.covers[0].width = 40;
+                  this.covers[0].height = 50;
+                }
+              }
+              this.covers.push(marker);
+            }
+          });
+          this.nearParkingList = nearParkingList;
+          if (nearParkingList.length > 0) {
+            this.latitude = nearParkingList[0]?.latitude || this.currentPosition.latitude;
+            this.longitude = nearParkingList[0]?.longitude || this.currentPosition.longitude;
+          } else {
+            this.$refs.uToast.show({
+              title: '没有相关停车场信息',
+              type: 'warning'
+            });
+          }
+          this.nearParkingFlag = true;
+          if (this.searchContent) {
+            this.searchParkingList = nearParkingList;
+            this.isShowSearchParking = true;
+            this.nearParkingFlag = false;
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+        });
+    },
+    /**
+     * 点击地图上的标记点触发
+     **/
+    markertap(e) {
+      let lon, lat;
+      this.covers.forEach((item, index) => {
+        if (e.detail.markerId === item.id) {
+          lon = item.longitude;
+          lat = item.latitude;
+          this.swiperCurrent = index;
+        }
+      });
+      this.getNearRoadsl(lon, lat);
+    },
+    /**
+     * 地址发生变化
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    swiperChange(item) {
+      const map = uni.createMapContext('pagemap');
+      map.moveToLocation({
+        longitude: this.nearParkingList[item.detail.current].longitude,
+        latitude: this.nearParkingList[item.detail.current].latitude
+      });
+      this.getNearRoadsl(this.nearParkingList[item.detail.current].longitude, this.nearParkingList[item.detail.current].latitude);
+    },
+    /**
+     * 点击单个地址
+     * @date 2022-08-31
+     * @param {any} item
+     * @returns {any}
+     */
+    positionAddress(item) {
+      const map = uni.createMapContext('pagemap');
+      map.moveToLocation({
+        longitude: item.longitude,
+        latitude: item.latitude
+      });
+      this.getNearRoadsl(item.longitude, item.latitude);
+    },
+    /**
+     * 点击单个停车场看详情
+     * @date 2021-08-10
+     * @param {Object} item 为选中项参数
+     * @returns {any}
+     */
+    clickSearchParking(item) {
+      if (item.monthAmount) {
+        this.$u.route({
+          url: 'pages/parkingInformation/parkingInformation',
+          params: {
+            roadInfo: JSON.stringify(item),
+            longitude: this.currentPosition.longitude,
+            latitude: this.currentPosition.latitude
+          }
+        });
+      }
+    },
+    /**
+     * 跳转停车标准页面
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    lookParkingRule(item) {
+      this.$u.route({
+        url: 'pages/chargeStandard/chargeStandard',
+        params: {
+          roadNo: item.roadNo
+        }
+      });
+    },
+    /**
+     * 搜索右侧按钮点击
+     **/
+    listIconClick() {
+      this.isShowSearchParking = true;
+      this.nearParkingFlag = false;
+      this.searchParkingList = this.nearParkingList;
+    },
+    /**
+     * 跳转包月
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    createMonth(item) {
+      if (item.monthAmount) {
+        this.$u.route({
+          url: 'pages/handleMonthly/handleMonthly',
+          params: {
+            roadNo: item.roadNo
+          }
+        });
+      }
+    },
+    pullDown() {
+      if (this.nearParkingObj.height === '20vh') {
+        this.nearParkingObj.height = '60vh';
+        this.nearParkingObj.type = 'down';
+      } else {
+        this.nearParkingObj.height = '20vh';
+        this.nearParkingObj.type = 'up';
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.wrap {
+  margin-top: 20vh;
+}
+
+@import './parkingLists.scss';
+</style>

+ 19 - 0
pages/parkingLists/map_web_view/map_web_view.vue

@@ -0,0 +1,19 @@
+<template>
+  <!-- webview用来装地图容器 -->
+  <web-view :src="url"></web-view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      url: ''
+    };
+  },
+  onLoad(e) {
+    this.url = e.url;
+  }
+};
+</script>
+
+<style></style>

+ 441 - 0
pages/parkingLists/parkingLists.scss

@@ -0,0 +1,441 @@
+.parking {
+  background-color: #008cff;
+  position: relative;
+}
+.parking-header {
+  padding: 36rpx 40rpx;
+  display: flex;
+  justify-content: space-between;
+}
+.parking-header .icon {
+  margin-left: 42rpx;
+}
+.parking-details {
+  position: absolute;
+  width: calc(100% - 60rpx);
+  margin: 0 auto;
+  bottom: 68rpx;
+  z-index: 1000;
+  left: 30rpx;
+  background-color: #fff;
+  border-radius: 26.5rpx;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+.parking-details-header {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 40rpx;
+}
+.parking-details-left-address {
+  font-size: 28rpx;
+  font-weight: 700;
+}
+.parking-details-left-number {
+  display: flex;
+  flex-direction: row;
+  color: rgba(47, 47, 47, 0.5);
+  justify-content: space-between;
+  margin-top: 10rpx;
+}
+.parking-details-left-number text {
+  font-size: 40rpx;
+  color: rgba(0, 140, 255, 1);
+}
+.parking-details-button {
+  background-color: #008cff;
+  height: 103rpx;
+  line-height: 103rpx;
+  border-bottom-left-radius: 26.5rpx;
+  border-bottom-right-radius: 26.5rpx;
+  text-align: center;
+  color: #fff;
+  font-size: 28rpx;
+  font-family: PingFangSC-Medium;
+}
+.parking-details-right-time,
+.parking-details-right-distance {
+  height: 44rpx;
+  line-height: 44rpx;
+  color: #008cff;
+  display: flex;
+  flex-direction: row;
+  margin-bottom: 20rpx;
+  margin-top: 30rpx;
+}
+.parking-details-right-time image,
+.parking-details-right-distance image {
+  width: 44rpx;
+  height: 44rpx;
+  margin-right: 10rpx;
+}
+.parking-details-right-time text,
+.parking-details-right-distance text {
+  display: block;
+  font-weight: 500;
+}
+.parking-current-address {
+  position: absolute;
+  bottom: 80rpx;
+  z-index: 1000;
+  width: 100%;
+  height: 345rpx;
+}
+.parking-current-address .swiper {
+  height: 430rpx;
+}
+.parking-current-address .swiper-item {
+  background-color: #fff;
+  transform: scaleY(0.9);
+  margin: 0 10rpx;
+  border-radius: 25rpx;
+  padding: 30rpx;
+}
+.parking-current-address .swiper-item > view:first-child {
+  font-size: 32rpx;
+  color: #484848;
+  line-height: 50rpx;
+}
+.parking-current-address .swiper-item > view:nth-child(2) {
+  font-size: 24rpx;
+  color: #969696;
+  line-height: 50rpx;
+}
+.parking-current-address .swiper-item > view:nth-child(3) {
+  display: flex;
+  flex-direction: row;
+  background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#f4f7ff)); /*谷歌*/
+  background: linear-gradient(to right, #fff 0%, #f4f7ff 50%, #fff 100%);
+  justify-content: space-around;
+  height: 71rpx;
+  line-height: 71rpx;
+  border-radius: 20rpx;
+  margin-top: 20rpx;
+  margin-bottom: 20rpx;
+}
+.parking-current-address .swiper-item > view:nth-child(4) {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+}
+.parking-current-address .swiper-item > view:nth-child(5) {
+  text-align: center;
+  margin-top: 30rpx;
+  color: #a4a4a4;
+  font-size: 24rpx;
+}
+.parking-address-list {
+  position: absolute;
+  z-index: 99;
+  width: 100%;
+  padding: 32rpx 28rpx;
+  bottom: 0;
+  max-height: 65vh;
+  overflow-y: scroll;
+  // background-image: linear-gradient(top, rgba(246, 245, 255, 0) 0%, rgba(246, 245, 255, 1) 100%);
+  background-image: url('./../../static/img/parking-search-list-bg.png');
+  background-size: 100% 100%;
+}
+.parking-address-list-item {
+  background-color: #fff;
+  border-radius: 25rpx;
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 26rpx;
+  margin-top: 20rpx;
+}
+.pali-left {
+  width: 74%;
+}
+.pali-left view:first-child {
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #484848;
+}
+.pali-left view:last-child {
+  font-size: 24rpx;
+  font-weight: 400;
+  color: #969696;
+  margin-top: 10rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.pali-right image {
+  width: 58rpx;
+  height: 58rpx;
+}
+.pali-right view {
+  color: #969696;
+  font-size: 20rpx;
+}
+.yellow-font {
+  color: #fa6400;
+  margin-left: 10rpx;
+}
+.swiper-item-font {
+  color: #6d6d6d;
+  font-size: 28rpx;
+}
+.swiper-item-button button {
+  width: 48%;
+  height: 70rpx;
+  line-height: 70rpx;
+  font-size: 30rpx;
+}
+.swiper-item-button button:first-child {
+  border: solid 1px #008cff;
+  color: #008cff;
+  margin-right: 4%;
+}
+.swiper-item-button button:last-child {
+  background-color: #008cff;
+  color: #fff;
+}
+.swiper-item-button .disabled {
+  background-color: #d2d2d2 !important;
+}
+.loading {
+  width: 100%;
+  height: calc(100vh - 100rpx);
+  line-height: calc(100vh - 100rpx);
+  position: absolute;
+  z-index: 99999;
+  text-align: center;
+  background-color: rgba(0, 0, 0, 0.1);
+}
+.parking-address-details {
+  position: absolute;
+  bottom: 50rpx;
+  z-index: 1000000;
+  background: transparent;
+  width: 100%;
+}
+.parking-address-details-title {
+  width: calc(100% - 30rpx);
+  margin: 0 auto;
+  background: url(../../static/img/parking-info-bg.png) center center;
+  background-size: 100% 100%;
+}
+.padt-header {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 25rpx;
+}
+.padt-header > view > view:nth-child(1) {
+  color: #484848;
+  font-size: 32rpx;
+}
+.padt-header > view.padt-header-title > view:nth-child(2) {
+  color: #969696;
+  font-size: 24rpx;
+  margin-top: 16rpx;
+}
+.padt-header-icon {
+  text-align: center;
+}
+.padt-header-icon view {
+  font-size: 18rpx;
+  color: #3a3a3a;
+}
+.padt-header image {
+  width: 45rpx;
+  height: 45rpx;
+}
+.padt-timeline {
+  padding-left: 25rpx;
+  padding-bottom: 25rpx;
+  font-size: 25rpx;
+  color: #727275;
+}
+.padt-timeline text {
+  color: #fa6b0b;
+  margin-left: 5rpx;
+  font-size: 29rpx;
+}
+.parking-address-details-numer {
+  background-color: #fff;
+  border-radius: 25rpx;
+  width: calc(100% - 30rpx);
+  margin: 10rpx auto 0;
+  padding: 35rpx 25rpx;
+  display: flex;
+  flex-direction: row;
+}
+.parking-address-details-numer > view {
+  width: 48%;
+  height: 110rpx;
+  padding: 15rpx;
+  text-align: center;
+  background: linear-gradient(359deg, #ffffff 0%, #f6f6ff 100%);
+  border-radius: 15px;
+}
+.parking-address-details-numer > view > view:first-child {
+  color: #008cff;
+  font-size: 56rpx;
+  font-weight: 400;
+}
+.parking-address-details-numer > view > view:last-child {
+  color: #838383;
+  font-size: 24rpx;
+  font-weight: 400;
+}
+.parking-address-details-numer > view:last-child {
+  margin-left: 4%;
+}
+.parking-address-details-price {
+  background-color: #fff;
+  border-radius: 25rpx;
+  width: calc(100% - 30rpx);
+  margin: 10rpx auto 0;
+}
+.parking-address-details-price > view:first-child {
+  font-size: 24rpx;
+  color: #787878;
+  font-weight: 400;
+  text-align: center;
+  padding-top: 24rpx;
+}
+.parking-address-details-price > view > text:first-child {
+  font-size: 66rpx;
+  color: #008cff;
+}
+.parking-address-details-price > view:last-child {
+  width: 100%;
+  height: 81rpx;
+  line-height: 81rpx;
+  background: linear-gradient(180deg, #efefff 0%, #ffffff 100%);
+  border-bottom-left-radius: 25rpx;
+  border-bottom-right-radius: 25rpx;
+  text-align: center;
+  margin-top: 36rpx;
+}
+.parking-address-details-button {
+  width: calc(100% - 80rpx);
+  height: 96rpx;
+  line-height: 96rpx;
+  margin: 103rpx auto 57rpx;
+  background-color: #008cff;
+  border-radius: 10rpx;
+  text-align: center;
+  font-size: 28rpx;
+  color: #fff;
+}
+.address-box {
+  width: calc(100% - 60rpx);
+	height: 70vh;
+  padding: 15rpx 0;
+  position: absolute;
+  left: 30rpx;
+  bottom: 0;
+  z-index: 1000;
+  background-color: #f9f9f9;
+	transition: height .5s linear;
+  &-down-icon {
+    width: 32rpx;
+    height: 28rpx;
+    margin: 0 auto;
+    background: url('./../../static/img/down-icon.svg') no-repeat center center;
+    background-size: 100% 100%;
+		transform: rotate(0deg);
+		transition: transform 0.5s linear;
+  }
+  .up-icon {
+    transform: rotate(180deg);
+  }
+  &-scroll {
+    overflow: hidden;
+  }
+  &-list {
+    padding: 12rpx 30rpx;
+    &-item {
+      padding: 30rpx 40rpx;
+      background-color: #fff;
+      box-shadow: 0px 0px 10rpx 0px rgba(0, 0, 0, 0.08);
+      border-radius: 16rpx;
+      margin-bottom: 20rpx;
+      .abli-header {
+        padding-bottom: 26rpx;
+        margin-bottom: 26rpx;
+        border-bottom: dashed 1px #e1e5eb;
+        &-title {
+          font-size: 30rpx;
+          font-weight: 500;
+          color: #333333;
+          margin-bottom: 16rpx;
+        }
+        &-subtitle {
+          font-size: 26rpx;
+          color: #999;
+          margin-bottom: 26rpx;
+          margin-left: 30rpx;
+        }
+        &-surplus {
+          display: flex;
+          justify-content: space-between;
+          &-left {
+            font-size: 26rpx;
+            color: #999999;
+            text {
+              font-size: 30rpx;
+              color: #ff6d6d;
+              margin-left: 10rpx;
+            }
+          }
+          &-right {
+            padding: 6rpx 17rpx;
+            background-color: #008cff;
+            border-radius: 4rpx;
+            color: #fff;
+            font-size: 24rpx;
+          }
+          .disabled {
+            background-color: #cccccc;
+          }
+        }
+      }
+      .abli-bottom {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        &-left {
+          display: flex;
+          align-items: center;
+          &-navigation {
+            color: #008cff;
+            font-size: 26rpx;
+            border-right: solid 1px #cccccc;
+            padding-right: 20rpx;
+            &::before {
+              content: '';
+              display: inline-block;
+              width: 40rpx;
+              height: 31rpx;
+              background: url('./../../static/img/navigation-icon.svg') no-repeat center center;
+              background-size: 100% 100%;
+              margin-right: 10rpx;
+              vertical-align: middle;
+            }
+          }
+          &-distance {
+            padding-left: 20rpx;
+            color: #666666;
+            font-size: 26rpx;
+          }
+        }
+        &-right {
+          color: #999999;
+          font-size: 22rpx;
+        }
+      }
+    }
+  }
+}
+.address-down {
+	height: 60vh;
+}
+.address-up {
+	height: 20vh;
+}

+ 564 - 0
pages/parkingLists/parkingLists.vue

@@ -0,0 +1,564 @@
+<template>
+  <view class="parking">
+    <view class="loading" v-show="loading">
+      <u-loadmore status="loading" icon-type="flower" :load-text="{ loading: '正在定位中...' }" />
+    </view>
+    <view class="parking-header">
+      <u-search placeholder="搜索停车点" v-model="searchContent" :show-action="false" @change="searchInputChange"> </u-search>
+      <u-icon
+        v-if="!searchContent && isShowSearchParking == false"
+        class="icon"
+        name="list"
+        size="44"
+        color="#ffffff"
+        placeholder-color="#B5B5B5"
+        search-icon-color="#B3B3B3"
+        @click="listIconClick"
+      />
+      <u-icon
+        v-if="searchContent || isShowSearchParking == true"
+        class="icon"
+        name="close"
+        size="36"
+        color="#ffffff"
+        placeholder-color="#B5B5B5"
+        search-icon-color="#B3B3B3"
+        @click="clearSearchInput"
+      />
+    </view>
+    <view class="parking-map">
+      <map
+        id="pagemap"
+        style="width: 100%; height: calc(100vh - 240rpx)"
+        :show-location="true"
+        :latitude="latitude"
+        :longitude="longitude"
+        @markertap="markertap"
+        :enable-traffic="true"
+        :enable-zoom="true"
+        :scale="scale"
+        :markers="covers"
+      />
+    </view>
+    <view class="address-box" :class="nearParkingObj.type == 'down' ? 'address-down' : 'address-up'" v-if="nearParkingFlag">
+      <view class="address-box-down-icon" :class="{ 'up-icon': nearParkingObj.type === 'up' }" @click="pullDown"> </view>
+      <!-- tab -->
+      <template v-if="projectFlag !== 'zhenning'">
+        <u-tabs :list="tabObj.tabList" :is-scroll="false" :current="tabObj.current" bg-color="transparent" @change="tabChange" />
+      </template>
+      <scroll-view scroll-y class="address-box-scroll" :style="{ height: `calc(${nearParkingObj.height} - 164rpx)` }">
+        <view class="address-box-list" v-if="nearParkingList.length > 0">
+          <view class="address-box-list-item" v-for="(item, index) in nearParkingList" :key="index" @click="positionAddress(item)">
+            <view class="abli-header">
+              <view class="abli-header-title"
+                >{{ item.roadName || item.parkName }} <text class="abli-header-subtitle">{{ item.areaName }}</text></view
+              >
+              <view class="abli-header-surplus">
+                <view class="abli-header-surplus-left">
+                  余位<text>{{ item.spaceIdle || item.surplusPlace }}</text></view
+                >
+                <template v-if="tabObj.current === 1">
+                  <view class="abli-header-surplus-right" @click.stop="createMonth(item)">办理包月</view>
+                </template>
+                <template v-else-if="item.monthAmount">
+                  <view class="abli-header-surplus-right" @click.stop="createMonth(item)">办理包月</view>
+                </template>
+                <template v-else>
+                  <view class="abli-header-surplus-right" :class="{ disabled: !item.monthAmount }"> 办理包月</view>
+                </template>
+              </view>
+            </view>
+            <view class="abli-bottom">
+              <view class="abli-bottom-left">
+                <view class="abli-bottom-left-navigation" @click.stop="navigation(item.latitude, item.longitude, item.areaName)">导航</view>
+                <view class="abli-bottom-left-distance">{{ item.distance | kmUnit }}</view>
+              </view>
+              <view class="abli-bottom-right" @click.stop="lookParkingRule(item)">收费规则</view>
+            </view>
+          </view>
+        </view>
+        <view class="address-box-list" v-else>
+          <u-empty text="暂无数据" mode="list"></u-empty>
+        </view>
+      </scroll-view>
+    </view>
+    <view class="parking-address-list" v-if="isShowSearchParking">
+      <view class="parking-address-list-item" v-for="(item, index) in searchParkingList" :key="index + 's'" @click="clickSearchParking(item)">
+        <view class="pali-left">
+          <view>{{ item.roadName || item.parkName }}</view>
+          <view>{{ item.areaName }}</view>
+        </view>
+        <view class="pali-right">
+          <image src="../../static/img/distance-icon.png" mode="" @click.stop="navigation(item.latitude, item.longitude, item.areaName)"></image>
+          <view>路线</view>
+        </view>
+      </view>
+    </view>
+    <u-select v-model="mapSelect" :list="mapSelectList" @confirm="mapSelectConfirm" />
+    <map id="map" hidden="true" />
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import { qqMapTransBMap } from '@/utils/mapTrans.js';
+export default {
+  data() {
+    return {
+      tabObj: {
+        current: 0,
+        tabList: [
+          {
+            name: '路段'
+          },
+          {
+            name: '停车场'
+          }
+        ]
+      },
+      searchContent: '',
+      page_map: '',
+      loading: false,
+      latitude: 26.64969,
+      longitude: 106.636453,
+      scale: 16,
+      currentPosition: {
+        latitude: 26.64969,
+        longitude: 106.636453
+      },
+      covers: [],
+      // 附近列表是否显示
+      nearParkingFlag: false,
+      // 轮播选中
+      swiperCurrent: 0,
+      // 附近停车列表
+      nearParkingList: [],
+      // 是否显示停车场列表
+      isShowSearchParking: false,
+      // 搜索停车场列表
+      searchParkingList: [],
+      // 显示单个停车场数据
+      isShowParkingDetail: false,
+      // 单个停车场数据
+      parkingDetailData: {},
+      mapSelect: false,
+      mapSelectList: [
+        {
+          value: '1',
+          label: '腾讯地图'
+        },
+        {
+          value: '2',
+          label: '百度地图'
+        },
+        {
+          value: '3',
+          label: '高德地图'
+        }
+      ],
+      // 选中位置经纬度
+      currentPositionHover: {},
+      nearParkingObj: {
+        height: '60vh',
+        type: 'down'
+      }
+    };
+  },
+  onLoad(page) {
+    this.getLocation();
+    if (page.keyword) {
+      this.searchContent = page.keyword;
+      this.searchInputChange(page.keyword);
+    }
+  },
+  methods: {
+    /**
+     * 查询输入框发生变化
+     * @date 2021-08-10
+     * @param {String} value
+     */
+    searchInputChange(value) {
+      // 为空时关闭搜索列表
+      if (value === '') {
+        this.isShowSearchParking = false;
+      }
+      this.isShowParkingDetail = false;
+      const obj = {
+        0: 'getNearRoadsl',
+        1: 'getParkingLotList'
+      };
+      this[obj[this.tabObj.current]]();
+    },
+    /**
+     * 获取定位
+     * @date 2021-08-10
+     * @returns {any}
+     */
+    getLocation() {
+      const that = this;
+      console.log('请求定位');
+      that.loading = true;
+      if (navigator.geolocation) {
+        // 判断是否有这个对象
+        navigator.geolocation.getCurrentPosition(
+          function (pos) {
+            console.log('浏览器获取位置成功:', JSON.stringify(pos));
+            console.log('经度:' + pos.coords.longitude + '纬度:' + pos.coords.latitude);
+            that.latitude = pos.coords.latitude;
+            that.longitude = pos.coords.longitude;
+            that.currentPosition.latitude = pos.coords.latitude;
+            that.currentPosition.longitude = pos.coords.longitude;
+            that.loading = false;
+            const obj = {
+              0: 'getNearRoadsl',
+              1: 'getParkingLotList'
+            };
+            that[obj[that.tabObj.current]]();
+          },
+          function (err) {
+            console.log('浏览器获取位置失败:', JSON.stringify(err));
+            uni.getLocation({
+              type: 'gcj02',
+              success: function (res) {
+                console.log('当前位置的经度:' + res.longitude);
+                console.log('当前位置的纬度:' + res.latitude);
+                that.currentPosition.latitude = res.latitude;
+                that.currentPosition.longitude = res.longitude;
+                that.loading = false;
+                const obj = {
+                  0: 'getNearRoadsl',
+                  1: 'getParkingLotList'
+                };
+                that[obj[that.tabObj.current]]();
+              }
+            });
+          }
+        );
+      } else {
+        this.$refs.uToast.show({
+          title: '当前系统不支持GPS API',
+          type: 'error'
+        });
+      }
+    },
+    /**
+     * 导航
+     * @date 2021-08-10
+     * @param {Number} latitude
+     * @param {Number} longitude
+     * @returns {any}
+     */
+    navigation(latitude, longitude, areaName) {
+      this.currentPositionHover = {
+        latitude,
+        longitude,
+        areaName
+      };
+      this.mapSelect = true;
+    },
+    // 多地图选择
+    mapSelectConfirm(item) {
+      const name = item[0].label;
+      switch (name) {
+        case '腾讯地图':
+          location.href = `https://apis.map.qq.com/uri/v1/routeplan?type=drive&from=我的位置&fromcoord=${this.currentPosition.latitude},${
+            this.currentPosition.longitude
+          }&to=${this.currentPositionHover.areaName || item.parkName}&tocoord=${this.currentPositionHover.latitude},${
+            this.currentPositionHover.longitude
+          }&policy=1&referer=BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL`;
+          break;
+        case '百度地图':
+          const lnglatObj = qqMapTransBMap(this.currentPositionHover.longitude, this.currentPositionHover.latitude);
+          location.href = `http://api.map.baidu.com/marker?location=
+			${lnglatObj.lat},${lnglatObj.lng}&title=目的地&content=${this.currentPositionHover.areaName || item.parkName}
+			&output=html&src=webapp.baidu.openAPIdemo`;
+          break;
+        case '高德地图':
+          location.href = `https://uri.amap.com/navigation?from=${this.currentPosition.longitude},${this.currentPosition.latitude},我的位置&to=${
+            this.currentPositionHover.longitude
+          },${this.currentPositionHover.latitude},${
+            this.currentPositionHover.areaName || item.parkName
+          }&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0`;
+          break;
+      }
+    },
+    /**
+     * 清空搜索框内容
+     * @date 2021-08-10
+     * @returns {any}
+     */
+    clearSearchInput() {
+      this.searchContent = '';
+      this.isShowSearchParking = false;
+      const obj = {
+        0: 'getNearRoadsl',
+        1: 'getParkingLotList'
+      };
+      this[obj[this.tabObj.current]]();
+    },
+    /**
+     * 默认首个点放大 如果有传入经纬度则对应的点放大
+     * @date 2021-08-10
+     * @param {Number} lon
+     * @param {Number} lat
+     * @returns {any}
+     */
+    getNearRoadsl(lon, lat) {
+      this.$u.api
+        .nearRoadsl({
+          latitude: this.currentPosition.latitude,
+          longitude: this.currentPosition.longitude,
+          roadName: this.searchContent
+        })
+        .then((res) => {
+          const nearParkingList = []; // 附近停车场列表
+          this.covers = [];
+          res.data.forEach((item, index, arr) => {
+            if (item.latitude && item.longitude) {
+              nearParkingList.push(item);
+              const marker = {
+                latitude: item.latitude,
+                longitude: item.longitude,
+                id: String(index),
+                iconPath: require('./../../static/img/parking-icon.png'),
+                width: 20,
+                height: 25
+              };
+              // 选中经纬度图标变大
+              if (lon && lat) {
+                if (lon === item.longitude && lat === item.latitude) {
+                  marker.width = 40;
+                  marker.height = 50;
+                }
+              } else {
+                if (this.covers.length > 0) {
+                  this.covers[0].width = 40;
+                  this.covers[0].height = 50;
+                }
+              }
+              this.covers.push(marker);
+            }
+          });
+          this.nearParkingList = nearParkingList;
+          if (nearParkingList.length > 0) {
+            this.latitude = nearParkingList[0]?.latitude || this.currentPosition.latitude;
+            this.longitude = nearParkingList[0]?.longitude || this.currentPosition.longitude;
+          }
+          this.nearParkingFlag = true;
+          if (this.searchContent) {
+            this.searchParkingList = nearParkingList;
+            this.isShowSearchParking = true;
+            this.nearParkingFlag = false;
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+        });
+    },
+    getParkingLotList(lon, lat) {
+      this.$u.api
+        .nearParkingLot({
+          status: 1,
+          latitude: this.currentPosition.latitude,
+          longitude: this.currentPosition.longitude,
+          parkName: this.searchContent
+        })
+        .then((res) => {
+          const nearParkingList = []; // 附近停车场列表
+          this.covers = [];
+          res?.data?.rows.forEach((item, index, arr) => {
+            if (item.latitude && item.longitude) {
+              nearParkingList.push(item);
+              const marker = {
+                latitude: item.latitude,
+                longitude: item.longitude,
+                id: String(index),
+                iconPath: require('./../../static/img/parking-icon.png'),
+                width: 20,
+                height: 25
+              };
+              // 选中经纬度图标变大
+              if (lon && lat) {
+                if (lon === item.longitude && lat === item.latitude) {
+                  marker.width = 40;
+                  marker.height = 50;
+                }
+              } else {
+                if (this.covers.length > 0) {
+                  this.covers[0].width = 40;
+                  this.covers[0].height = 50;
+                }
+              }
+              this.covers.push(marker);
+            }
+          });
+          this.nearParkingList = nearParkingList;
+          if (nearParkingList.length > 0) {
+            this.latitude = nearParkingList[0]?.latitude || this.currentPosition.latitude;
+            this.longitude = nearParkingList[0]?.longitude || this.currentPosition.longitude;
+          }
+          this.nearParkingFlag = true;
+          if (this.searchContent) {
+            this.searchParkingList = nearParkingList;
+            this.isShowSearchParking = true;
+            this.nearParkingFlag = false;
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+        });
+    },
+    /**
+     * 点击地图上的标记点触发
+     **/
+    markertap(e) {
+      let lon, lat;
+      this.covers.forEach((item, index) => {
+        if (e.detail.markerId === item.id) {
+          lon = item.longitude;
+          lat = item.latitude;
+          this.swiperCurrent = index;
+        }
+      });
+      const obj = {
+        0: 'getNearRoadsl',
+        1: 'getParkingLotList'
+      };
+      this[obj[this.tabObj.current]](lon, lat);
+    },
+    /**
+     * 地址发生变化
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    swiperChange(item) {
+      const map = uni.createMapContext('pagemap');
+      map.moveToLocation({
+        longitude: this.nearParkingList[item.detail.current].longitude,
+        latitude: this.nearParkingList[item.detail.current].latitude
+      });
+      const obj = {
+        0: 'getNearRoadsl',
+        1: 'getParkingLotList'
+      };
+      this[obj[this.tabObj.current]](this.nearParkingList[item.detail.current].longitude, this.nearParkingList[item.detail.current].latitude);
+    },
+    /**
+     * 点击单个地址
+     * @date 2022-08-31
+     * @param {any} item
+     * @returns {any}
+     */
+    positionAddress(item) {
+      const map = uni.createMapContext('pagemap');
+      map.moveToLocation({
+        longitude: item.longitude,
+        latitude: item.latitude
+      });
+      const obj = {
+        0: 'getNearRoadsl',
+        1: 'getParkingLotList'
+      };
+      this[obj[this.tabObj.current]](item.longitude, item.latitude);
+    },
+    /**
+     * 点击单个停车场看详情
+     * @date 2021-08-10
+     * @param {Object} item 为选中项参数
+     * @returns {any}
+     */
+    clickSearchParking(item) {
+      if (item.monthAmount) {
+        this.$u.route({
+          url: 'pages/parkingInformation/parkingInformation',
+          params: {
+            roadInfo: JSON.stringify(item),
+            longitude: this.currentPosition.longitude,
+            latitude: this.currentPosition.latitude
+          }
+        });
+      }
+    },
+    /**
+     * 跳转停车标准页面
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    lookParkingRule(item) {
+      const obj = {
+        0: 'roadNo',
+        1: 'parkNo'
+      };
+      const params = {};
+      params[obj[this.tabObj.current]] = item[obj[this.tabObj.current]];
+      this.$u.route({
+        url: 'pages/chargeStandard/chargeStandard',
+        params
+      });
+    },
+    /**
+     * 搜索右侧按钮点击
+     **/
+    listIconClick() {
+      this.isShowSearchParking = true;
+      this.nearParkingFlag = false;
+      this.searchParkingList = this.nearParkingList;
+    },
+    /**
+     * 跳转包月
+     * @date 2021-08-10
+     * @param {Object} item
+     * @returns {any}
+     */
+    createMonth(item) {
+      const obj = {
+        0: 'roadNo',
+        1: 'parkNo'
+      };
+      const params = {};
+      params[obj[this.tabObj.current]] = item[obj[this.tabObj.current]];
+      this.$u.route({
+        url: 'pages/handleMonthly/handleMonthly',
+        params
+      });
+    },
+    pullDown() {
+      if (this.nearParkingObj.height === '20vh') {
+        this.nearParkingObj.height = '60vh';
+        this.nearParkingObj.type = 'down';
+      } else {
+        this.nearParkingObj.height = '20vh';
+        this.nearParkingObj.type = 'up';
+      }
+    },
+    /**
+     * tab切换触发
+     * @param {Object} val
+     */
+    tabChange(val) {
+      this.tabObj.current = val;
+      const obj = {
+        0: 'getNearRoadsl',
+        1: 'getParkingLotList'
+      };
+      this[obj[val]]();
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.wrap {
+  margin-top: 20vh;
+}
+
+@import './parkingLists.scss';
+</style>

+ 306 - 0
pages/parkingLock/parkingLock.scss

@@ -0,0 +1,306 @@
+.parking-lock {
+  min-height: calc(100vh - 88rpx);
+  background-color: #f6f6ff;
+  &-box {
+    padding: 40rpx 0 0;
+  }
+  .parking-lock-title {
+    font-size: 46rpx;
+    color: #292929;
+    text-align: center;
+    padding-top: 31rpx;
+    line-height: 65rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+  }
+  .parking-lock-tips {
+    width: calc(100% - 72rpx);
+    font-size: 30rpx;
+    color: #777777;
+    text-align: center;
+    margin: 10rpx auto;
+    line-height: 47rpx;
+  }
+  .parking-lock-info {
+    width: calc(100% - 72rpx);
+    margin: 31rpx auto 54rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    padding: 39rpx 41rpx;
+    .parking-lock-info-item {
+      display: flex;
+      margin-bottom: 16rpx;
+      view {
+        font-size: 28rpx;
+        &:first-child {
+          width: 30%;
+          color: #2a2a2a;
+        }
+        &:last-child {
+          color: #6e6e6e;
+        }
+      }
+      .really-money {
+        color: #fa7319 !important;
+      }
+    }
+  }
+  .parking-lock-pay-btn {
+    width: calc(100% - 72rpx);
+    margin: 0 auto;
+    button {
+      width: 100%;
+      height: 100rpx;
+      line-height: 100rpx;
+      background-color: #008cff;
+      border: none;
+      color: #fff;
+      box-shadow: 0px 7px 13px 0px rgba(16, 153, 250, 0.31);
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+  }
+  .parking-lock-begin-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(270deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    // animation: spin 3s linear infinite;
+    .parking-lock-begin-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-begin-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-loading-box {
+    width: 441rpx;
+    height: 441rpx;
+    line-height: 441rpx;
+    background: #31a2ff;
+    background: linear-gradient(0deg, rgba(49, 162, 255, 0.1) 20%, rgba(49, 162, 255, 1) 100%);
+    border-radius: 50%;
+    text-align: center;
+    margin: 0 auto;
+    animation: spin 3s linear infinite;
+    .parking-lock-loading-bg {
+      display: inline-block;
+      width: 420rpx;
+      height: 420rpx;
+      line-height: 420rpx;
+      vertical-align: middle;
+      border: solid 12rpx #fff;
+      background: linear-gradient(346deg, #008cff 0%, #95cfff 100%);
+      border-radius: 50%;
+      image {
+        width: 194rpx;
+        height: 239rpx;
+        vertical-align: middle;
+      }
+    }
+  }
+  .parking-lock-loading-info {
+    text-align: center;
+    font-size: 50rpx;
+    color: #008cff;
+    margin-top: 57rpx;
+  }
+  .parking-lock-success {
+    .parking-lock-success-box {
+      width: 441rpx;
+      height: 441rpx;
+      margin: 0 auto;
+      image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .parking-lock-success-info {
+      color: #4ccd8a;
+      font-size: 50rpx;
+      text-align: center;
+      margin: 56rpx 0 202rpx;
+    }
+    .parking-lock-success-button {
+      width: calc(100% - 80rpx);
+      margin: 0 auto;
+      button {
+        width: 100%;
+        height: 100rpx;
+        line-height: 100rpx;
+        background-color: #008cff;
+        font-size: 28rpx;
+        color: #fff;
+      }
+    }
+  }
+}
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 34rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}
+@keyframes rotate {
+  0% {
+    transform: rotate(0);
+  }
+  50% {
+    transform: rotate(200deg);
+  }
+  100% {
+    transform: rotate(0);
+  }
+}
+@keyframes spin {
+  from {
+    transform: rotate(0);
+  }
+  to {
+    transform: rotate(359deg);
+  }
+}
+.loadingSelect {
+  text-align: center;
+  margin-top: 20rpx;
+}
+.spinner {
+  margin: auto;
+  width: 50px;
+  height: 60px;
+  text-align: center;
+  font-size: 10px;
+}
+
+.spinner > view {
+  background-color: #6495ed;
+  height: 100%;
+  width: 10rpx;
+  margin-right: 2rpx;
+  display: inline-block;
+
+  -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
+  animation: stretchdelay 1.2s infinite ease-in-out;
+}
+
+.spinner .rect2 {
+  -webkit-animation-delay: -1.1s;
+  animation-delay: -1.1s;
+}
+
+.spinner .rect3 {
+  -webkit-animation-delay: -1s;
+  animation-delay: -1s;
+}
+
+.spinner .rect4 {
+  -webkit-animation-delay: -0.9s;
+  animation-delay: -0.9s;
+}
+
+.spinner .rect5 {
+  -webkit-animation-delay: -0.8s;
+  animation-delay: -0.8s;
+}
+
+@-webkit-keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    -webkit-transform: scaleY(1);
+  }
+}
+
+@keyframes stretchdelay {
+  0%,
+  40%,
+  100% {
+    transform: scaleY(0.4);
+    -webkit-transform: scaleY(0.4);
+  }
+  20% {
+    transform: scaleY(1);
+    -webkit-transform: scaleY(1);
+  }
+}
+.new-plate-number {
+  margin-bottom: 70rpx;
+}
+.message-input-wrap {
+  margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item {
+  background-color: #e8ffe8;
+}
+.really-license-txt {
+  color: #008cff;
+}
+.really-license-txt1 {
+  color: #008cff;
+  margin: 20rpx;
+}
+.popup-vehicleNo-title {
+  font-size: 48rpx;
+  text-align: center;
+  padding-top: 20rpx;
+}
+.popup-vehicleNo-center {
+  width: 95%;
+  height: 2rpx;
+  border-top: solid rgb(146, 146, 146) 2rpx;
+  margin: 30rpx 20rpx 50rpx 20rpx;
+}
+.popup-vehicleNo-select {
+  text-align: center;
+  color: #777777;
+}
+.vehicleNo-btn {
+  display: flex;
+  margin: 40rpx 0;
+}
+.parking-lock-pay-attention {
+  margin: 50rpx;
+  line-height: 48rpx;
+  color: #777777;
+}

+ 352 - 0
pages/parkingLock/parkingLock.vue

@@ -0,0 +1,352 @@
+<template>
+  <view class="parking-lock">
+    <view class="Jump">
+      <view class="Jump-btn" @click="jumpArrears"> 欠费补缴 </view>
+    </view>
+    <!-- 车位锁 -->
+    <view class="parking-lock-box">
+      <!-- 车位锁支付 -->
+      <template v-if="parkingLockStatus === 1">
+        <view class="parking-lock-pay">
+          <view class="parking-lock-title">支付停车费</view>
+          <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view>
+          <view class="parking-lock-info">
+            <view class="parking-lock-info-item">
+              <view>停车场名称</view>
+              <view>{{ orderInfo.roadName }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>停车泊位</view>
+              <view>{{ orderInfo.spaceName }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>开始计费</view>
+              <view>{{ orderInfo.inTime }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>结束计费</view>
+              <view>{{ orderInfo.outTime }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>免费时长</view>
+              <view>{{ orderInfo.freeDuration || `0天0时${free_time}分0秒` }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>计费时长</view>
+              <view>{{ orderInfo.calcDuration || 0 }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>累计停车时长</view>
+              <view>{{ orderInfo.duration || 0 }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>应缴金额</view>
+              <view class="really-money">{{ orderInfo.payAmount || 0 }} 元</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>订单编号</view>
+              <view>{{ orderInfo.orderId }}</view>
+            </view>
+          </view>
+          <view class="parking-lock-pay-btn">
+            <button type="default" @click="payMoney">立即支付</button>
+          </view>
+          <view class="parking-lock-pay-attention">
+            <text>
+              温馨提示:车辆计费前您有{{ orderInfo.freeDurationNum / 60 }}分钟免费停车时长,{{
+                orderInfo.freeDurationNum / 60
+              }}分钟过后则升板锁车开始计费。
+            </text>
+          </view>
+        </view>
+      </template>
+      <!-- 车位锁开始状态 -->
+      <template v-else-if="parkingLockStatus === 2">
+        <view class="parking-lock-begin">
+          <view class="parking-lock-begin-box">
+            <view class="parking-lock-begin-bg">
+              <image src="../../static/img/parking-lock-bg.png" mode=""></image>
+            </view>
+          </view>
+          <view class="parking-lock-begin-info">车位锁正在动作,还未到位</view>
+        </view>
+      </template>
+      <!-- 车位锁正在状态 -->
+      <template v-else-if="parkingLockStatus === 3">
+        <view class="parking-lock-loading">
+          <view class="parking-lock-loading-box">
+            <view class="parking-lock-loading-bg">
+              <image src="../../static/img/parking-lock-bg.png" mode=""></image>
+            </view>
+          </view>
+          <view class="parking-lock-loading-info">开锁中,请等待!</view>
+        </view>
+      </template>
+      <!-- 开锁完成 -->
+      <template v-else-if="parkingLockStatus === 4">
+        <view class="parking-lock-success">
+          <view class="parking-lock-success-box">
+            <image src="../../static/img/parking-lock-achieve.png" mode=""></image>
+          </view>
+          <view class="parking-lock-success-info">开锁已完成</view>
+          <view class="parking-lock-success-button">
+            <button @click="cancel">返回</button>
+          </view>
+        </view>
+      </template>
+      <template v-else-if="parkingLockStatus === 5">
+        <view class="parking-lock-pay">
+          <view class="parking-lock-tips">{{ tipsMsg }}</view>
+        </view>
+      </template>
+      <!-- 支付方式 -->
+      <ChoosePayment ref="choosePayment" :curOrderList="orderList" :deviceNo="deviceNo" :jumpUrl="jumpUrl" />
+      <!-- 订单查询加载弹框 -->
+      <u-popup v-model="show" mode="center" border-radius="14" width="200rpx" height="200rpx">
+        <view class="loadingSelect">订单查询中...</view>
+        <view class="spinner">
+          <view class="rect1"></view>
+          <view class="rect2"></view>
+          <view class="rect3"></view>
+          <view class="rect4"></view>
+          <view class="rect5"></view>
+        </view>
+      </u-popup>
+    </view>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import getUrlParams from '@/utils/getUrlParams.js';
+import ChoosePayment from '@/pages/choosePayment/choosePayment.vue';
+export default {
+  components: {
+    ChoosePayment
+  },
+  data() {
+    return {
+      // 车位锁状态 1:支付 2:开始开锁 3:开锁中 4:开锁完成
+      parkingLockStatus: 0,
+      // 支付方式选择弹框
+      payWayPop: false,
+      // 订单编号
+      orderList: [],
+      // 提示信息
+      tipsMsg: null,
+      // 设备编号
+      deviceNo: null,
+      // 设备状态轮询
+      timer: null,
+      // 订单状态查询轮询
+      timer1: null,
+      // 订单信息
+      orderInfo: {},
+      // 订单id
+      orderId: null,
+      // 重定向地址
+      jumpUrl: location.href + '&isBack=1',
+      // 订单查询中弹框显示
+      show: false,
+      // 是否为返回标识
+      isBack: '',
+      // 预支付订单
+      polyOrderId: ''
+    };
+  },
+  onLoad(page) {
+    if (page.orderId) {
+      this.getOrderDetails(page.orderId);
+      this.orderList = [];
+      this.orderId = page.orderId;
+      this.orderList.push(page.orderId);
+      this.deviceNo = page.deviceNo;
+      this.isBack = page?.isBack;
+      this.polyOrderId = page?.polyOrderId;
+    } else {
+      uni.showModal({
+        title: '提示',
+        content: '参数丢失, 返回首页',
+        showCancel: false,
+        success: function (res) {
+          if (res.confirm) {
+            uni.switchTab({
+              url: '/pages/index/index'
+            });
+          }
+        }
+      });
+      this.parkingLockStatus = 5;
+    }
+  },
+  onShow() {
+    if (this.orderId) {
+      if (this.polyOrderId && this.isBack == 1) {
+        this.timer1 = setInterval(() => {
+          this.show = true;
+          this.handlePayStatus(this.polyOrderId);
+        }, 2000);
+      }
+    } else {
+      this.show = false;
+    }
+  },
+  onUnload() {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+    if (this.timer1) {
+      clearInterval(this.timer1);
+    }
+  },
+  methods: {
+    /**
+     * 跳转欠费页面
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    jumpArrears() {
+      uni.navigateTo({
+        url: '../center/order/order?orderStatus=2'
+      });
+    },
+    /**
+     * 反复查询支付状态
+     * @param { String } orderId
+     */
+    handlePayStatus(orderId) {
+      this.$u.api
+        .getOrderInfo({
+          orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.payStatus === 1 || res.data.payStatus === 3) {
+              this.show = false;
+              clearInterval(this.timer1);
+              this.getOrderDetails(this.orderId);
+            }
+          } else {
+            this.show = false;
+            clearInterval(this.timer1);
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch(() => {
+          this.show = false;
+          clearInterval(this.timer1);
+        });
+    },
+    /**
+     * 立即支付
+     * @date 2023-02-22
+     * @returns {any}
+     */
+    payMoney() {
+      this.$nextTick(() => {
+        this.$refs['choosePayment'].openPopup({ ...this.orderInfo }, 'single', 'road');
+      });
+    },
+    /**
+     * 根据订单id查询订单信息
+     * @date 2023-02-22
+     * @param {any} id
+     * @returns {any}
+     */
+    getOrderDetails(id) {
+      this.$u.api
+        .getOrderDetail({
+          id
+        })
+        .then((res) => {
+          if (res.code === 200 && res.data.id) {
+            this.parkingLockStatus = 1;
+            // 获取页面完整url
+            const local = window.location.href;
+            // 获取url后面的参数
+            const locationLocaturl = window.location.search;
+            // 截取url中的isBack
+            let isBack = getUrlParams(local, 'isBack');
+            // 如果没有isBack,则去请求
+            if (!isBack) {
+              // uni.hideLoading();
+              clearInterval(this.timer1);
+            }
+            this.orderInfo = res.data;
+            if (res.data.payStatus === 1) {
+              clearInterval(this.timer1);
+              this.checkEqupment();
+            }
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg || '订单无数据',
+              type: 'error'
+            });
+            if (this.timer1) {
+              clearInterval(this.timer1);
+            }
+          }
+        })
+        .catch(() => {
+          if (this.timer1) {
+            clearInterval(this.timer1);
+          }
+        });
+    },
+    // 检测设备
+    checkEqupment() {
+      this.timer = setInterval(() => {
+        this.getEqumentStatus(this.deviceNo);
+      }, 1000);
+    },
+    // 查询设备状态
+    getEqumentStatus(orderNo) {
+      this.$u.api
+        .getEquomentInfo({
+          orderNo
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.deviceStatus == 0) {
+              this.parkingLockStatus = 4;
+              clearInterval(this.timer);
+            } else if (res.data.deviceStatus == 1 || res.data.deviceStatus == 5) {
+              this.parkingLockStatus = 2;
+            } else if (res.data.deviceStatus == 6) {
+              this.parkingLockStatus = 3;
+            }
+          } else {
+            clearInterval(this.timer);
+          }
+        })
+        .catch(() => {
+          clearInterval(this.timer);
+        });
+    },
+    // 返回首页
+    cancel() {
+      uni.switchTab({
+        url: '/pages/index/index'
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkingLock.scss';
+
+.Jump {
+  display: flex;
+  justify-content: flex-end;
+  background-color: #f6f6ff;
+
+  &-btn {
+    color: rgb(0, 140, 255);
+    padding: 20rpx 30rpx;
+  }
+}
+</style>

+ 567 - 0
pages/parkingLock/parkingLock20230222.vue

@@ -0,0 +1,567 @@
+<template>
+  <view class="parking-lock">
+    <view class="Jump">
+      <view class="Jump-btn" @click="jumpArrears"> 欠费补缴 </view>
+    </view>
+    <!-- 车位锁 -->
+    <view class="parking-lock-box">
+      <!-- 车位锁支付 -->
+      <template v-if="parkingLockStatus === 1">
+        <view class="parking-lock-pay">
+          <view class="parking-lock-title">支付停车费</view>
+          <view class="parking-lock-tips">请您确认停车费用,确认后请支付费用,结束停车。谢谢您的使用!</view>
+          <view class="parking-lock-info">
+            <view class="parking-lock-info-item">
+              <view>停车场名称</view>
+              <view>{{ orderInfo.roadName }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>停车泊位</view>
+              <view>{{ orderInfo.spaceName }}</view>
+            </view>
+            <!-- <view class="parking-lock-info-item">
+							<view>入场时间</view>
+							<view>{{orderInfo.inTime}}</view>
+						</view>
+						<view class="parking-lock-info-item">
+							<view>出场时间</view>
+							<view>{{orderInfo.outTime}}</view>
+						</view>
+						<view class="parking-lock-info-item">
+							<view>停车时长</view>
+							<view>{{ orderInfo.duration || 0}}</view>
+						</view>
+						<view class="parking-lock-info-item">
+							<view>免费时长</view>
+							<view>{{ orderInfo.freeDuration || 0 }}</view>
+						</view> -->
+            <view class="parking-lock-info-item">
+              <view>开始计费</view>
+              <view>{{ orderInfo.inTime }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>结束计费</view>
+              <view>{{ orderInfo.outTime }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>免费时长</view>
+              <view>{{ orderInfo.freeDuration || `0天0时${free_time}分0秒` }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>计费时长</view>
+              <view>{{ orderInfo.calcDuration || 0 }}</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>累计停车时长</view>
+              <view>{{ orderInfo.duration || 0 }}</view>
+            </view>
+            <!-- <view class="parking-lock-info-item">
+							<view>合计金额</view>
+							<view>{{orderInfo.totalAmount}} 元</view>
+						</view>
+						<view class="parking-lock-info-item">
+							<view>优惠金额</view>
+							<view>{{orderInfo.preferentialAmount}} 元</view>
+						</view> -->
+            <view class="parking-lock-info-item">
+              <view>应缴金额</view>
+              <view class="really-money">{{ orderInfo.payAmount || 0 }} 元</view>
+            </view>
+            <view class="parking-lock-info-item">
+              <view>订单编号</view>
+              <view>{{ orderInfo.orderId }}</view>
+            </view>
+            <!-- <view class="parking-lock-info-item" v-if="orderInfo.vehicleNo">
+							<view>车牌信息</view>
+							<view class="really-license">{{ orderInfo.vehicleNo }}</view>
+						</view> -->
+            <!-- <view class="parking-lock-info-item" v-if="orderInfo.vehicleNo==''">
+							<view>车牌信息</view>
+							<view class="really-license"><text class="really-license-txt" @click="addvehicleNo">添加车牌</text>
+							</view>
+						</view>
+						<view class="parking-lock-info-item" v-else>
+							<view>车牌信息</view>
+							<view class="really-license">{{orderInfo.vehicleNo}} <text @click="changevehicleNo"
+									class="really-license-txt1">更换</text></view>
+						</view> -->
+          </view>
+          <view class="parking-lock-pay-btn">
+            <button type="default" @click="payMoney">立即支付</button>
+          </view>
+          <!-- <view class="parking-lock-pay-attention">
+						<text>
+							温馨提示:车牌信息可填可不填,如果您已通过本机号码办理了特定车或包月车业务,则需要输入车牌号,否则将按照常规收费标准进行收费。
+						</text>
+					</view> -->
+          <view class="parking-lock-pay-attention">
+            <text>
+              温馨提示:车辆计费前您有{{ orderInfo.freeDurationNum / 60 }}分钟免费停车时长,{{
+                orderInfo.freeDurationNum / 60
+              }}分钟过后则升板锁车开始计费。
+            </text>
+          </view>
+        </view>
+      </template>
+      <!-- 车位锁开始状态 -->
+      <template v-else-if="parkingLockStatus === 2">
+        <view class="parking-lock-begin">
+          <view class="parking-lock-begin-box">
+            <view class="parking-lock-begin-bg">
+              <image src="../../static/img/parking-lock-bg.png" mode=""></image>
+            </view>
+          </view>
+          <view class="parking-lock-begin-info">车位锁正在动作,还未到位</view>
+        </view>
+      </template>
+      <!-- 车位锁正在状态 -->
+      <template v-else-if="parkingLockStatus === 3">
+        <view class="parking-lock-loading">
+          <view class="parking-lock-loading-box">
+            <view class="parking-lock-loading-bg">
+              <image src="../../static/img/parking-lock-bg.png" mode=""></image>
+            </view>
+          </view>
+          <view class="parking-lock-loading-info">开锁中,请等待!</view>
+        </view>
+      </template>
+      <!-- 开锁完成 -->
+      <template v-else-if="parkingLockStatus === 4">
+        <view class="parking-lock-success">
+          <view class="parking-lock-success-box">
+            <image src="../../static/img/parking-lock-achieve.png" mode=""></image>
+          </view>
+          <view class="parking-lock-success-info">开锁已完成</view>
+          <view class="parking-lock-success-button">
+            <button @click="cancel">返回</button>
+          </view>
+        </view>
+      </template>
+      <template v-else-if="parkingLockStatus === 5">
+        <view class="parking-lock-pay">
+          <view class="parking-lock-tips">{{ tipsMsg }}</view>
+        </view>
+      </template>
+      <!-- 支付方式 -->
+      <PaymentMethod
+        :payWayPop="payWayPop"
+        :curOrderList="orderList"
+        :deviceNo="deviceNo"
+        :jumpUrl="jumpUrl"
+        @closePaymentMethod="closePaymentMethod"
+      ></PaymentMethod>
+      <u-toast ref="uToast" />
+      <u-popup v-model="show" mode="center" border-radius="14" width="200rpx" height="200rpx">
+        <view class="loadingSelect">订单查询中...</view>
+        <view class="spinner">
+          <view class="rect1"></view>
+          <view class="rect2"></view>
+          <view class="rect3"></view>
+          <view class="rect4"></view>
+          <view class="rect5"></view>
+        </view>
+      </u-popup>
+      <u-popup class="popup-vehicleNo" v-model="ShowaddvehicleNo" mode="center" border-radius="20" width="710rpx" height="auto">
+        <view class="popup-vehicleNo-title">添加车牌</view>
+        <view class="popup-vehicleNo-center"></view>
+        <view class="popup-vehicleNo-content">
+          <view class="new-plate-number">
+            <view class="message-input-wrap" @click="messageInputClick">
+              <u-message-input :maxlength="8" width="70" font-size="50" :disabled-keyboard="true" v-model="newPlateNumber"></u-message-input>
+            </view>
+          </view>
+        </view>
+        <view class="popup-vehicleNo-select">暂无绑定车牌</view>
+        <view class="vehicleNo-btn">
+          <u-button type="primary" @click="handleAddCar">确认</u-button>
+          <u-button type="primary" plain @click="ShowaddvehicleNo = false">取消</u-button>
+        </view>
+      </u-popup>
+
+      <u-popup class="popup-vehicleNo" v-model="ShowchangevehicleNo" mode="center" border-radius="20" width="710rpx" height="auto">
+        <view class="popup-vehicleNo-title">更换车牌</view>
+        <view class="popup-vehicleNo-center"></view>
+        <view class="popup-vehicleNo-content">
+          <view class="new-plate-number">
+            <view class="message-input-wrap" @click="messageInputClick">
+              <u-message-input :maxlength="8" width="70" font-size="50" :disabled-keyboard="true" v-model="newPlateNumber"></u-message-input>
+            </view>
+          </view>
+        </view>
+        <view class="popup-vehicleNo-select">
+          <u-collapse ref="refValue">
+            <u-collapse-item title="点击选择车牌" align="center">
+              <u-cell-group>
+                <u-cell-item :title="item.vehicleNo" v-for="(item, index) in groupList" :key="index" :arrow="false">
+                  <u-radio-group v-model="selectvalue" @change="radioGroupChange">
+                    <u-radio :name="item.vehicleNo" :key="index"></u-radio>
+                  </u-radio-group>
+                </u-cell-item>
+              </u-cell-group>
+            </u-collapse-item>
+          </u-collapse>
+        </view>
+        <view class="vehicleNo-btn">
+          <u-button type="primary" @click="handleAddCar">确认</u-button>
+          <u-button type="primary" plain @click="ShowchangevehicleNo = false">取消</u-button>
+        </view>
+      </u-popup>
+      <u-action-sheet :list="colorList" @click="confirmColor" v-model="colorShow"></u-action-sheet>
+      <u-keyboard
+        ref="uKeyboard"
+        mode="car"
+        @change="keyboardChange"
+        @confirm="keyboardConfirm"
+        @backspace="backspace"
+        v-model="keyboardshow"
+      ></u-keyboard>
+    </view>
+  </view>
+</template>
+
+<script>
+import getUrlParams from '../../utils/getUrlParams.js';
+import PaymentMethod from '@/pages/paymentMethod/paymentMethod.vue';
+export default {
+  components: {
+    PaymentMethod
+  },
+  data() {
+    return {
+      selectvalue: null,
+      groupList: [],
+      radiogroupList: [],
+      keyboardshow: false,
+      colorShow: false,
+      colorList: [
+        {
+          text: '蓝色',
+          colorCode: 0
+        },
+        {
+          text: '黄色',
+          colorCode: 1
+        },
+        {
+          text: '黑色',
+          colorCode: 2
+        },
+        {
+          text: '白色',
+          colorCode: 3
+        },
+        {
+          text: '绿色',
+          colorCode: 4
+        },
+        {
+          text: '其他',
+          colorCode: 99
+        }
+      ],
+      vehicleColor: 0,
+      newPlateNumber: '',
+      //更换车牌弹窗
+      ShowchangevehicleNo: false,
+      //添加车牌弹窗
+      ShowaddvehicleNo: false,
+      // 车位锁状态 1:支付 2:开始开锁 3:开锁中 4:开锁完成
+      parkingLockStatus: 0,
+      // 支付方式选择弹框
+      payWayPop: false,
+      // 订单编号
+      orderList: [],
+      // 提示信息
+      tipsMsg: null,
+      // 设备编号
+      deviceNo: null,
+      // 轮询
+      timer: null,
+      timer1: null,
+      // 订单信息
+      orderInfo: {},
+      // 订单id
+      orderId: null,
+      // 重定向地址
+      jumpUrl: location.href + '&isBack=1',
+      show: true,
+      isBack: '',
+      polyOrderId: ''
+    };
+  },
+  onLoad(page) {
+    if (page.orderId) {
+      this.getOrderDetails(page.orderId);
+      this.orderList = [];
+      this.orderId = page.orderId;
+      this.orderList.push(page.orderId);
+      this.deviceNo = page.deviceNo;
+      this.isBack = page?.isBack;
+      this.polyOrderId = page?.polyOrderId;
+    } else {
+      this.tipsMsg = page.msg || '参数丢失!';
+      this.parkingLockStatus = 5;
+    }
+  },
+  onShow() {
+    if (this.orderId) {
+      if (this.polyOrderId && this.isBack == 1) {
+        this.timer1 = setInterval(() => {
+          this.show = true;
+          this.handlePayStatus(this.polyOrderId);
+        }, 2000);
+      }
+    } else {
+      this.show = false;
+    }
+  },
+  onUnload() {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+    if (this.timer1) {
+      clearInterval(this.timer1);
+    }
+  },
+  methods: {
+    jumpArrears() {
+      uni.navigateTo({
+        url: '../center/order/order?orderStatus=2'
+      });
+    },
+    radioGroupChange(e) {
+      this.newPlateNumber = e;
+    },
+    // 获取车辆列表
+    handlegetMycars() {
+      let that = this;
+      this.$u.api
+        .getMycars()
+        .then((res) => {
+          if (res.code === 200) {
+            this.groupList = res.data.rows;
+            this.radiogroupList = res.data.rows;
+            this.$nextTick(() => {
+              // dom元素更新后执行,因此这里能正确打印更改之后的值
+              console.log(that.$refs.refValue.init()); // 改变了的值
+            });
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '操作失败!',
+            type: 'error'
+          });
+        });
+    },
+    //更换车牌信息
+    changevehicleNo() {
+      this.ShowchangevehicleNo = true;
+      this.handlegetMycars();
+    },
+    // 添加车辆
+    handleAddCar() {
+      if (!this.$u.test.carNo(this.newPlateNumber)) {
+        this.$refs.uToast.show({
+          title: '请正确填写车牌号',
+          type: 'error'
+        });
+        return;
+      }
+      let param = {
+        orderId: this.orderId,
+        vehicleNo: this.newPlateNumber,
+        vehicleColor: this.vehicleColor
+      };
+      let that = this;
+      this.$u.api
+        .bindVehicleNo(param)
+        .then((res) => {
+          if (res.code === 200) {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'success'
+            });
+            that.getOrderDetails(that.orderId);
+            that.ShowchangevehicleNo = false;
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: '操作失败!',
+            type: 'error'
+          });
+        });
+    },
+    //新增车牌
+    addvehicleNo() {
+      this.ShowaddvehicleNo = true;
+    },
+
+    // 点击输入框
+    messageInputClick() {
+      this.keyboardshow = true;
+    },
+    // 按键被点击(点击退格键不会触发此事件)
+    keyboardChange(val) {
+      // 将每次按键的值拼接到value变量中,注意+=写法
+      this.newPlateNumber += val;
+    },
+    // 退格键被点击
+    backspace() {
+      // 删除value的最后一个字符
+      if (this.newPlateNumber.length) this.newPlateNumber = this.newPlateNumber.substr(0, this.newPlateNumber.length - 1);
+    },
+    // 键盘输入完成后确认
+    keyboardConfirm() {
+      this.colorShow = true;
+    },
+    // 确认颜色
+    confirmColor(e) {
+      this.vehicleColor = this.colorList[e].colorCode;
+    },
+    /**
+     * 反复查询支付状态
+     * @param { String } orderId
+     */
+    handlePayStatus(orderId) {
+      this.$u.api
+        .getOrderInfo({
+          orderId
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.payStatus === 1 || res.data.payStatus === 3) {
+              this.show = false;
+              clearInterval(this.timer1);
+              this.getOrderDetails(this.orderId);
+            }
+          } else {
+            this.show = false;
+            clearInterval(this.timer1);
+            this.$refs.uToast.show({
+              title: res.msg,
+              type: 'error'
+            });
+          }
+        })
+        .catch(() => {
+          this.show = false;
+          clearInterval(this.timer1);
+        });
+    },
+    payMoney() {
+      this.payWayPop = true;
+    },
+    // 查询订单信息
+    getOrderDetails(id) {
+      this.$u.api
+        .getOrderDetail({
+          id
+        })
+        .then((res) => {
+          if (res.code === 200 && res.data.id) {
+            this.parkingLockStatus = 1;
+            // 获取页面完整url
+            const local = window.location.href;
+            // 获取url后面的参数
+            const locationLocaturl = window.location.search;
+            // 截取url中的isBack
+            let isBack = getUrlParams(local, 'isBack');
+            // 如果没有isBack,则去请求
+            if (!isBack) {
+              // uni.hideLoading();
+              this.show = false;
+              clearInterval(this.timer1);
+            }
+            this.orderInfo = res.data;
+            if (res.data.payStatus === 1) {
+              this.show = false;
+              clearInterval(this.timer1);
+              this.checkEqupment();
+            }
+          } else {
+            this.$refs.uToast.show({
+              title: res.msg || '订单无数据',
+              type: 'error'
+            });
+            this.show = false;
+            if (this.timer1) {
+              clearInterval(this.timer1);
+            }
+          }
+        })
+        .catch(() => {
+          this.show = false;
+          if (this.timer1) {
+            clearInterval(this.timer1);
+          }
+        });
+    },
+    // 检测设备
+    checkEqupment() {
+      this.timer = setInterval(() => {
+        this.getEqumentStatus(this.deviceNo);
+      }, 1000);
+    },
+    // 查询设备状态
+    getEqumentStatus(orderNo) {
+      this.$u.api
+        .getEquomentInfo({
+          orderNo
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            if (res.data.deviceStatus == 0) {
+              this.parkingLockStatus = 4;
+              clearInterval(this.timer);
+            } else if (res.data.deviceStatus == 1 || res.data.deviceStatus == 5) {
+              this.parkingLockStatus = 2;
+            } else if (res.data.deviceStatus == 6) {
+              this.parkingLockStatus = 3;
+            }
+          } else {
+            clearInterval(this.timer);
+          }
+        })
+        .catch(() => {
+          clearInterval(this.timer);
+        });
+    },
+    // 返回首页
+    cancel() {
+      uni.switchTab({
+        url: '/pages/index/index'
+      });
+    },
+    closePaymentMethod() {
+      this.payWayPop = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkingLock.scss';
+
+.Jump {
+  display: flex;
+  justify-content: flex-end;
+  background-color: #f6f6ff;
+
+  &-btn {
+    color: rgb(0, 140, 255);
+    padding: 20rpx 30rpx;
+  }
+}
+</style>

+ 30 - 0
pages/parkroadgate/parkroadgate.scss

@@ -0,0 +1,30 @@
+	.parking-lock-success {
+		padding-top: 80rpx;
+		.parking-lock-success-box {
+			width: 441rpx;
+			height: 441rpx;
+			margin: 0 auto;
+			image {
+				width: 100%;
+				height: 100%;
+			}
+		}
+		.parking-lock-success-info {
+			color: #4CCD8A;
+			font-size: 50rpx;
+			text-align: center;
+			margin: 56rpx 0 202rpx;
+		}
+		.parking-lock-success-button {
+			width: calc(100% - 80rpx);
+			margin: 0 auto;
+			button {
+				width: 100%;
+				height: 100rpx;
+				line-height: 100rpx;
+				background-color: #008CFF;
+				font-size: 28rpx;
+				color: #fff;
+			}
+		}
+	}

+ 33 - 0
pages/parkroadgate/parkroadgate.vue

@@ -0,0 +1,33 @@
+<template>
+  <!-- 道闸 -->
+  <view class="parking-roadgate">
+    <view class="parking-lock-success">
+      <view class="parking-lock-success-box">
+        <image src="../../static/img/parking-lock-achieve.png" mode=""></image>
+      </view>
+      <view class="parking-lock-success-info">已开闸,请入场</view>
+      <view class="parking-lock-success-button">
+        <button @click="cancel">返回</button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    cancel() {
+      uni.reLaunch({
+        url: '/pages/index/index'
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './parkroadgate';
+</style>

+ 26 - 0
pages/payLists/pay.vue

@@ -0,0 +1,26 @@
+<template>
+	<view>
+		<!-- <web-view :src="PayUrl"></web-view> -->
+		<a ref="payUrlRef" :href="PayUrl"></a>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				PayUrl: "",
+			};
+		},
+		onLoad(page) {
+			//15是因为传了‘currentPayUrl’,不要更改参数名
+			this.PayUrl = this.$u.queryParams(page).slice(15);
+		},
+		mounted() {
+			this.$refs.payUrlRef.click();
+		}
+	}
+</script>
+
+<style>
+</style>

+ 131 - 0
pages/payLists/payLists.scss

@@ -0,0 +1,131 @@
+page {
+  padding-bottom: 240rpx;
+}
+.swiper-wrap {
+  display: flex;
+  flex-direction: column;
+  height: calc(82vh - var(--window-top));
+  width: 100%;
+  .swiper-box {
+    flex: 1;
+  }
+  /deep/ .uni-swiper-slides {
+    bottom: 20rpx;
+  }
+}
+.page-box {
+  margin: 25rpx 40rpx;
+  .pay {
+    overflow: hidden;
+    margin-bottom: 20rpx;
+    background-color: #fff;
+    border-radius: 15rpx;
+    .pay-top {
+      margin-bottom: 20rpx;
+      padding: 25rpx 40rpx;
+      border-bottom: 1px solid #dfdfdf;
+      .car {
+        font-size: 32rpx;
+        font-weight: 600;
+        color: #3a3a3a;
+        line-height: 45rpx;
+        letter-spacing: 1px;
+      }
+      .addr {
+        color: #858585;
+        font-size: 26rpx;
+        line-height: 37rpx;
+      }
+      .pay-top-right {
+        padding: 0 15rpx;
+        height: 50rpx;
+        line-height: 48rpx;
+        border-radius: 5rpx;
+        border: 1px solid #fa6400;
+        color: #fa6400;
+      }
+    }
+    .pay-center {
+      padding: 0 40rpx 25rpx;
+      border-bottom: 1px solid #dfdfdf;
+      .pay-center-item {
+        margin-bottom: 9rpx;
+        font-size: 26rpx;
+        font-weight: 400;
+        color: #595959;
+        line-height: 37rpx;
+        letter-spacing: 1px;
+      }
+    }
+    .u-cell_title {
+      color: '#008CFF';
+    }
+  }
+}
+.bottom {
+  background-color: #ffffff;
+  height: 240rpx;
+  width: 100%;
+  position: fixed;
+  z-index: 1000;
+  bottom: 0;
+}
+.bottom-total {
+  font-size: 32rpx;
+  border-radius: 6rpx;
+  width: 710rpx;
+  text-align: center;
+  padding-top: 16rpx;
+  background-color: #e4f3ff;
+  height: 72rpx;
+  margin: 40rpx 20rpx;
+  .total {
+    color: #3397fa;
+  }
+}
+.button-wrap {
+  height: 120rpx;
+  .button {
+    position: fixed;
+    left: 20rpx;
+    bottom: 10rpx;
+    right: 20rpx;
+    z-index: 999;
+  }
+}
+.pay-tips {
+  width: calc(100% - 34rpx);
+  margin: 23rpx auto;
+  border-top: solid 1px #979797;
+  padding: 38rpx 0;
+  color: #5f5f5f;
+  text {
+    color: #3397fa;
+    padding: 0 10rpx;
+  }
+}
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 34rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}

+ 366 - 0
pages/payLists/payLists.vue

@@ -0,0 +1,366 @@
+<template>
+  <view>
+    <view class="swiper-wrap">
+      <template v-if="projectFlag !== 'zhenning'">
+        <view class="u-tabs-box">
+          <u-tabs-swiper activeColor="#008CFF" ref="tabs" :list="list" :current="current" @change="change" :is-scroll="false" swiperWidth="100%" />
+        </view>
+      </template>
+      <swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish" disable-touch>
+        <swiper-item class="swiper-item" v-for="(item, index) in list" :key="index">
+          <scroll-view scroll-y style="height: 100%; width: 100%" @scrolltolower="reachBottom">
+            <view class="page-box">
+              <view class="pay" v-for="(payItem, index) in payList[index]" :key="index">
+                <view v-if="item.index == 0">
+                  <view class="pay-top u-flex">
+                    <view class="pay-top-left u-flex-1">
+                      <view class="car">{{ payItem.vehicleNo }}</view>
+                      <view class="addr">{{ payItem.roadName }}</view>
+                    </view>
+                    <view class="pay-top-right">{{ payItem.orderStatus | filterOrderStatus }} </view>
+                  </view>
+                  <view class="pay-center">
+                    <view class="pay-center-item">订单编号:{{ payItem.orderId }}</view>
+                    <view class="pay-center-item" v-if="payItem.deviceType == 1">入场时间:{{ payItem.inTime || '' }} </view>
+                    <view class="pay-center-item" v-else>开始计费:{{ payItem.inTime || '' }}</view>
+                    <template v-if="payItem.deviceType == 1">
+                      <view class="pay-center-item" v-if="payItem.orderStatus == 1 && payItem.outTime"> 出场时间:{{ `未出场` }}</view>
+                      <view class="pay-center-item" v-if="payItem.orderStatus !== 1"> 出场时间:{{ payItem.outTime || 0 }}</view>
+                    </template>
+                    <template v-else>
+                      <view class="pay-center-item" v-if="payItem.orderStatus == 1 && payItem.outTime"> 结束计费:{{ `未出场` }}</view>
+                      <view class="pay-center-item" v-if="payItem.orderStatus !== 1"> 结束计费:{{ payItem.outTime || 0 }}</view>
+                    </template>
+                    <view class="pay-center-item" v-if="payItem.orderStatus !== 1">
+                      免费时长:{{ payItem.freeDuration || `0天0时${free_time}分0秒` }}
+                    </view>
+                    <!-- 计费时长=停车时长-免费时长 -->
+                    <view class="pay-center-item" v-if="payItem.orderStatus !== 1"> 计费时长:{{ payItem.calcDuration || 0 }} </view>
+                    <view class="pay-center-item" v-if="payItem.orderStatus !== 1"> 累计停车时长:{{ payItem.duration || 0 }} </view>
+                    <view class="pay-center-item" v-if="payItem.orderStatus == 1"
+                      >预计金额:<span class="pay-amount">{{ payItem.payAmount || 0 }}</span>
+                    </view>
+                    <view class="pay-center-item" v-else
+                      >应付金额:<span class="pay-amount">{{ payItem.payAmount || 0 }}</span>
+                    </view>
+                    <view
+                      class="pay-center-item"
+                      v-if="(payItem.actualAmount || payItem.actualAmount === 0) && payItem.orderStatus !== 2 && payItem.orderStatus !== 1"
+                    >
+                      实缴金额:<span class="pay-amount">{{ payItem.actualAmount || 0 }}</span>
+                    </view>
+                    <view class="pay-center-item">泊位号:{{ payItem.spaceName }}</view>
+                    <view class="pay-center-item" v-if="payItem.deviceType && payItem.deviceType != 1"> 车位锁设备号:{{ payItem.deviceNo }} </view>
+                  </view>
+                  <view class="pay-bottom">
+                    <u-cell-item title="去支付" @click="choosePayWay(payItem.orderId, payItem)" style="color: #008cff"> </u-cell-item>
+                  </view>
+                </view>
+                <view v-if="item.index == 1">
+                  <view class="pay-top u-flex">
+                    <view class="pay-top-left u-flex-1">
+                      <view class="car">{{ payItem.vehicleNo }}</view>
+                      <view class="addr">{{ payItem.parkingName }}</view>
+                    </view>
+                    <view class="pay-top-right">{{ payItem.orderStatus | filterOrderStatus }} </view>
+                  </view>
+                  <view class="pay-center">
+                    <view class="pay-center-item">订单编号:{{ payItem.orderId }}</view>
+                    <view class="pay-center-item">入场通道:{{ payItem.entranceName }}</view>
+                    <view class="pay-center-item">入场时间:{{ payItem.inTime || 0 }}</view>
+                    <view class="pay-center-item">出场通道:{{ payItem.outEntranceName }}</view>
+                    <view class="pay-center-item" v-if="payItem.orderStatus !== 1"> 出场时间:{{ payItem.outTime || 0 }} </view>
+                    <view class="pay-center-item" v-if="payItem.orderStatus !== 1">
+                      免费时长:{{ payItem.freeDuration || `0天0时${free_time}分0秒` }}
+                    </view>
+                    <!-- 计费时长=停车时长-免费时长 -->
+                    <view class="pay-center-item" v-if="payItem.orderStatus !== 1"> 计费时长:{{ payItem.calcDuration || 0 }} </view>
+                    <view class="pay-center-item" v-if="payItem.orderStatus !== 1"> 累计停车时长:{{ payItem.duration || 0 }} </view>
+                    <view class="pay-center-item"
+                      >应付金额:<span class="pay-amount">{{ payItem.payAmount || 0 }}</span>
+                    </view>
+                    <view class="pay-center-item" v-if="payItem.deviceType && payItem.deviceType != 1"> 车位锁设备号:{{ payItem.deviceNo }} </view>
+                  </view>
+                  <view class="pay-bottom">
+                    <u-cell-item title="去支付" @click="choosePayWay(payItem.orderId, payItem)" style="color: #008cff"> </u-cell-item>
+                  </view>
+                </view>
+              </view>
+              <u-loadmore :status="loadStatus[index]" bg-color="#F6F6FF"></u-loadmore>
+            </view>
+          </scroll-view>
+        </swiper-item>
+      </swiper>
+    </view>
+
+    <view class="bottom">
+      <view class="bottom-total">
+        累计欠费<span class="total">{{ totalCount || 0 }}</span
+        >笔,合计<span class="total">{{ totalPayAmount || 0 }}</span
+        >元
+      </view>
+      <view class="button-wrap" v-if="payList.length && payList.length >= 1">
+        <button class="button" type="primary" :disabled="!totalPayAmount" @click="confirmPrice()">全部缴费</button>
+      </view>
+    </view>
+
+    <!-- 缴费提示-->
+    <u-modal
+      v-model="payTipsPop"
+      :title-style="{ color: '#404040' }"
+      title="缴费提示"
+      :show-confirm-button="true"
+      confirm-text="立即缴费"
+      :confirm-style="{ backgroundColor: '#3397FA', color: '#fff' }"
+      :show-cancel-button="true"
+      cancel-text="取消"
+      :cancel-style="{ backgroundColor: '#EBF1FF', color: '#3397FA' }"
+      @confirm="payTipsPopConfirm"
+    >
+      <view class="slot-content">
+        <view class="pay-tips">
+          <text>{{ totalCount || 0 }}</text
+          >场停车欠费,共 <text>{{ totalPayAmount || 0 }}</text
+          >元
+        </view>
+      </view>
+    </u-modal>
+    <!-- 支付方式 -->
+    <ChoosePayment
+      ref="choosePayment"
+      :exportFlag="exportFlag"
+      :curOrderList="payOrderIdList"
+      :jumpUrl="jumpUrl"
+      @closePaymentMethod="closePaymentMethod"
+    />
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+// import PaymentMethod from '@/pages/paymentMethod/paymentMethod.vue';
+import ChoosePayment from '@/pages/choosePayment/choosePayment.vue';
+export default {
+  components: {
+    // PaymentMethod,
+    ChoosePayment
+  },
+  data() {
+    return {
+      totalPayAmount: '',
+      totalCount: '',
+      currentPayUrl: '',
+      payList: [[], []],
+      list: [
+        {
+          index: 0,
+          name: '路段',
+          orderStatus: null,
+          pageNum: 1,
+          total: null
+        },
+        {
+          index: 1,
+          name: '停车场',
+          orderStatus: 1,
+          pageNum: 1,
+          total: null
+        }
+      ],
+      current: 0,
+      swiperCurrent: 0,
+      dx: 0,
+      loadStatus: ['loadmore', 'loadmore', 'loadmore', 'loadmore'],
+      isLoadMore: false, //是否加载中
+      orderList: [],
+      exportFlag: false,
+      PayUrl: '',
+      payTipsPop: false,
+      payWayPop: false,
+      // 用来筛选已经加入列表中的id集合
+      haveIncludesIdList: [],
+      // 订单支付id集合
+      payOrderIdList: [],
+      // 所有订单列表(不分页)
+      allOrderList: [],
+      code: null,
+      jumpUrl: ''
+    };
+  },
+  computed: {
+    // 价格小数
+    priceDecimal() {
+      return (val) => {
+        if (val !== parseInt(val)) return val.slice(-2);
+        else return '00';
+      };
+    },
+    // 价格整数
+    priceInt() {
+      return (val) => {
+        if (val !== parseInt(val)) return val.split('.')[0];
+        else return val;
+      };
+    }
+  },
+  onLoad() {
+    const href = location.href.split('#');
+    this.jumpUrl = href[0] + '#/pages/center/order/order?';
+  },
+  onShow() {
+    this.list[this.current].pageNum = 1;
+    this.payList = [[], []];
+    this.orderListArr(this.list[this.current], this.swiperCurrent);
+    // this.getAllOrderList(this.swiperCurrent);
+  },
+  methods: {
+    reachBottom() {
+      if (this.payList[this.current].length >= this.list[this.current].total) {
+        this.loadStatus.splice(this.list[this.current].index, 1, 'nomore');
+        return;
+      }
+      this.loadStatus.splice(this.list[this.current].index, 1, 'loading');
+      this.orderListArr(this.list[this.current], this.swiperCurrent);
+    },
+    // tab栏切换
+    change(index) {
+      this.swiperCurrent = index;
+      this.current = index;
+      //重新初始化
+      this.haveIncludesIdList = [];
+      this.payOrderIdList = [];
+      this.payList = [[], []];
+      this.list[index].pageNum = 1;
+      if (index == 1) {
+        this.exportFlag = true;
+      } else {
+        this.exportFlag = false;
+      }
+      this.orderListArr(this.list[index], index);
+      // this.getAllOrderList(index);
+    },
+    transition({ detail: { dx } }) {
+      this.$refs.tabs.setDx(dx);
+    },
+    animationfinish({ detail: { current } }) {
+      this.$refs.tabs.setFinishCurrent(current);
+      this.swiperCurrent = current;
+      this.current = current;
+    },
+    customBack() {
+      this.$u.route({
+        type: 'switchTab',
+        url: 'pages/index/index'
+      });
+    },
+    /**
+     * @description: 获取所有订单用于全部缴费
+     * @param {*} index
+     * @return {*}
+     */
+    getAllOrderList(index) {
+      const apiName = index === 0 ? 'getOrderList' : 'getRoomParkingApi';
+      this.$u.api[apiName]({
+        pageSize: 1000,
+        pageNum: 1,
+        paying: true
+      }).then((res) => {
+        if (res.code === 200) {
+          this.allOrderList = res?.data?.pageInfo?.rows ?? [];
+        }
+      });
+    },
+    /**
+     * @description: 分页订单列表
+     * @param {*} orderType
+     * @param {*} index
+     * @return {*}
+     */
+    orderListArr(orderType, index) {
+      const apiName = index === 0 ? 'getOrderList' : 'getRoomParkingApi';
+      let pageNum = orderType.pageNum; // 页码, 默认从1开始
+      this.$u.api[apiName]({
+        pageSize: 10000,
+        pageNum,
+        paying: true
+      })
+        .then((res) => {
+          // 判断重复
+          let newListFlag = true;
+          this.allOrderList = res?.data?.pageInfo?.rows ?? [];
+          for (const item of res.data.pageInfo.rows) {
+            if (this.haveIncludesIdList.includes(item.orderId)) {
+              newListFlag = false;
+            } else {
+              this.payList[orderType.index].push(item);
+            }
+          }
+          if (newListFlag) {
+            this.list[this.current].total = res.data.pageInfo.total;
+            this.list[orderType.index].pageNum++;
+            if (this.payList[this.current].length >= this.list[this.current].total) {
+              this.loadStatus.splice(this.list[orderType.index].index, 1, 'nomore');
+            }
+            this.totalCount = res.data.costInfo.totalCount;
+            this.totalPayAmount = res.data.costInfo.totalPayAmount;
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+        });
+    },
+    // 去支付,选择支付方式
+    choosePayWay(orderId, item) {
+      this.payOrderIdList = [];
+      this.payOrderIdList.push(orderId);
+      this.$nextTick(() => {
+        this.$refs['choosePayment'].openPopup(item, 'single', this.current === 0 ? 'road' : 'parking');
+      });
+    },
+    // 全部缴费确认
+    confirmPrice() {
+      let payOrderIdList = [];
+      this.allOrderList.forEach((item) => {
+        if (item.orderStatus !== 4 && item.payStatus !== 1) {
+          payOrderIdList.push(item.orderId);
+        }
+      });
+      this.payOrderIdList = payOrderIdList;
+      if (this.totalCount !== 0 && this.totalPayAmount !== 0) {
+        this.payTipsPop = true;
+      } else {
+        this.$refs.uToast.show({
+          title: '没有需要支付的订单',
+          type: 'warning'
+        });
+      }
+    },
+    // 缴费提示弹框确认
+    payTipsPopConfirm() {
+      this.$nextTick(() => {
+        this.$refs['choosePayment'].openPopup({ payAmount: Number(this.totalPayAmount) }, 'multiple', this.current === 0 ? 'road' : 'parking');
+      });
+    },
+    closePaymentMethod() {
+      this.payWayPop = false;
+    }
+  }
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+  height: 100%;
+  background-color: #f6f6ff;
+}
+
+/* #endif */
+</style>
+
+<style lang="scss" scoped>
+@import './payLists.scss';
+</style>

+ 103 - 0
pages/payPage/payPage.scss

@@ -0,0 +1,103 @@
+.order-info {
+  margin-top: 50rpx;
+  margin-bottom: 75rpx;
+  .order-info-top {
+    position: relative;
+    border-top-left-radius: 20rpx;
+    border-top-right-radius: 20rpx;
+    color: #fff;
+    padding: 35rpx 40rpx;
+    background: linear-gradient(135deg, #00bfff 0%, #008dff 100%);
+    .addr {
+      margin-bottom: 16rpx;
+      .addr-text {
+        margin-left: 17rpx;
+        font-size: 24rpx;
+        font-weight: 400;
+      }
+    }
+    .car {
+      .car-no {
+        font-size: 40rpx;
+        font-weight: 500;
+        color: #ffffff;
+        letter-spacing: 1px;
+        line-height: 56rpx;
+        margin-right: 13rpx;
+      }
+      .car-type {
+        font-size: 24rpx;
+      }
+    }
+    .time {
+      font-size: 22rpx;
+      font-weight: 400;
+      color: #cdecff;
+      line-height: 30rpx;
+      margin-bottom: 3rpx;
+    }
+    .duration {
+      margin-top: 17rpx;
+      font-size: 30rpx;
+      font-weight: 400;
+      color: #ffffff;
+      line-height: 42rpx;
+      letter-spacing: 1px;
+    }
+    .total-amount {
+      position: absolute;
+      right: 40rpx;
+      bottom: 25rpx;
+      font-size: 60rpx;
+      font-weight: 500;
+      color: #ffffff;
+      letter-spacing: 2rpx;
+    }
+  }
+  .order-info-bottom {
+    padding-top: 44rpx;
+    padding-bottom: 56rpx;
+    background: #ffffff;
+    border-bottom-left-radius: 20rpx;
+    border-bottom-right-radius: 20rpx;
+    box-shadow: 0px 6rpx 14rpx 0px rgba(200, 200, 200, 0.5);
+    .u-cell {
+      padding-left: 40rpx;
+      padding-right: 40rpx;
+    }
+    /deep/ .u-iconfont {
+      color: #d8d8d8;
+    }
+    .pay-amount {
+      border-top: 1px solid #cacaca;
+      padding-top: 33rpx;
+      padding: 33rpx 40rpx 9rpx;
+      color: #ff751d;
+      .title {
+        font-size: 30rpx;
+        font-weight: 600;
+        color: #ff751d;
+        line-height: 42rpx;
+        letter-spacing: 1px;
+      }
+      .amount {
+        font-size: 36rpx;
+        font-weight: 600;
+        color: #ff8233;
+        line-height: 33rpx;
+        letter-spacing: 1px;
+        .rmb {
+          font-size: 24rpx;
+          margin-right: 5rpx;
+        }
+      }
+    }
+    .tip {
+      font-size: 22rpx;
+      font-weight: 400;
+      color: #999999;
+      line-height: 30rpx;
+      padding: 0 40rpx;
+    }
+  }
+}

+ 157 - 0
pages/payPage/payPage.vue

@@ -0,0 +1,157 @@
+<template>
+  <view class="wrap">
+    <view class="order-info">
+      <view class="order-info-top">
+        <view class="addr u-flex">
+          <u-icon name="map-fill" color="#fff" size="28"></u-icon>
+          <view class="addr-text">{{ orderInfo.roadName }}</view>
+        </view>
+        <view class="car u-flex">
+          <view class="car-no">{{ orderInfo.vehicleNo }}</view>
+          <view class="car-type">临时车</view>
+        </view>
+        <view class="time in-time">进场时间:{{ orderInfo.inTime }}</view>
+        <view class="time out-time">进场时间:{{ orderInfo.outTime }}</view>
+        <view class="duration">已停放 {{ orderInfo.duration }}</view>
+        <view class="total-amount">¥{{ orderInfo.totalAmount }}</view>
+      </view>
+      <view class="order-info-bottom">
+        <u-cell-item
+          center
+          :border-bottom="false"
+          :value="orderInfo.preferentialAmount"
+          :title-style="{ color: '#8A8A8A' }"
+          :icon-style="{ color: '#D8D8D8' }"
+          title="已优惠"
+        ></u-cell-item>
+        <view class="pay-amount u-flex u-row-between">
+          <view class="title">应付金额</view>
+          <view class="amount"><span class="rmb">¥</span>{{ orderInfo.payAmount }}</view>
+        </view>
+        <view class="tip">停车费不超过30元,可先离场后在付费</view>
+      </view>
+    </view>
+    <view class="bottom-btn static" @click="handlewxpay">去支付</view>
+
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+import getUrlParams from '@/utils/getUrlParams.js';
+export default {
+  data() {
+    return {
+      orderId: null,
+      orderInfo: []
+    };
+  },
+  onLoad() {
+    let locationLocaturl = window.location.hash;
+    this.orderId = getUrlParams(locationLocaturl, 'orderId'); // 截取orderId
+    console.log('this.orderId', this.orderId);
+    this.handleGetOrderinfo(this.orderId);
+  },
+  methods: {
+    handleGetOrderinfo(orderId) {
+      this.$u.api
+        .getOrderinfo({ id: orderId })
+        .then((res) => {
+          // this.$refs.uToast.show({
+          // 	title: res.msg,
+          // 	type: 'success',
+          // });
+          this.orderInfo = res.data;
+          console.log('handleGetOrderinfo', JSON.parse(JSON.stringify(res)));
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+          console.log('handleGetOrderinfo ', err);
+        });
+    },
+    getCode() {
+      var local = window.location.href; // 获取页面url
+      let locationLocaturl = window.location.search;
+      this.code = getUrlParams(locationLocaturl, 'code'); // 截取code
+      if (this.code == null || this.code === '') {
+        // 如果没有code,则去请求
+        window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.config.wxAppid}&redirect_uri=${encodeURIComponent(
+          local
+        )}&response_type=code&scope=snsapi_userinfo&#wechat_redirect`;
+      } else {
+        this.handleGetWXInfo(this.code); //把code传给后台获取用户信息
+      }
+    },
+    handleGetWXInfo(code) {
+      // 通过code获取 openId等用户信息,/api/user/wechat/login 为后台接口
+      let _this = this;
+      this.$u.api
+        .getWXInfo(code)
+        .then((res) => {
+          if (res.code === 200) {
+            this.$u.vuex('vuex_wxinfo', res.data);
+            // 继续支付
+          }
+        })
+        .catch((err) => {
+          this.$refs.uToast.show({
+            title: err.msg,
+            type: 'error'
+          });
+        });
+    },
+    handlewxpay() {
+      if (!this.$store.state.vuex_wxinfo.openId) {
+        // 如果微信openId,则需用code去后台获取
+        this.$refs.uToast.show({
+          title: '请登录后重试!',
+          type: 'info'
+          // url: '/pages/user/index'
+        });
+        this.getCode();
+      } else {
+        // 别的业务逻辑
+        this.getWXPay();
+      }
+    },
+    async getWXPay(id) {
+      let params = {
+        orderId: this.orderId,
+        openid: this.$store.state.vuex_wxinfo.openId,
+        tradeType: 'test'
+      };
+      await this.$wxApi.config();
+      this.$pay.wxPay(params).then((res) => {
+        console.log('wxPay', res.code);
+        if (res.code == 0) {
+          // 成功
+          this.$u.route({
+            url: 'pages/index/index'
+            // params: {
+            // 	keyword: this.keyword
+            // }
+          });
+        } else if (res.code == 1) {
+          // 取消
+          // uni.redirectTo({
+          // 	url: '/pages/userCenter/myOrder/myOrder'
+          // })
+        } else if (res.code == 2) {
+          this.$refs.uToast.show({
+            title: '支付失败,请检查!',
+            type: 'error'
+            // url: '/pages/user/index'
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './payPage.scss';
+</style>

+ 58 - 0
pages/paymentMethod/jumpMiddle.vue

@@ -0,0 +1,58 @@
+<template>
+  <view>
+    <a ref="payUrlRef" :href="jumpUrl"></a>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      jumpUrl: ''
+    };
+  },
+  onload() {
+    let url = localStorage.getItem('jumpUrl');
+    // let url = this.cookie.get("jumpUrl");
+    if (url) {
+      this.jumpUrl = url;
+    } else {
+      this.jumpUrl = 'https://h5.pdzhtc.com';
+    }
+    this.getOrderId();
+  },
+  mounted() {
+    this.$refs.payUrlRef.click();
+  },
+  methods: {
+    getOrderId(id) {
+      const localToken = JSON.parse(localStorage.getItem('lifeData') ?? '{}');
+      const token = localToken?.data?.vuex_token;
+      $.ajax({
+        //请求方式
+        type: 'get',
+        //请求地址
+        url: baseUrl + '/client/orderinfo/orderListByPoly/' + id,
+        // token
+        beforeSend: function (request) {
+          request.setRequestHeader('Authorization', 'Bearer ' + token);
+        },
+        //请求成功
+        success: function (result) {
+          if (result.code === 200) {
+            this.jumpUrl = result?.data?.jumpUrl ?? 'https://h5.pdzhtc.com';
+          } else {
+            alert(result.msg);
+          }
+        },
+        //请求失败,包含具体的错误信息
+        error: function (e) {
+          alert('程序错误!');
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style></style>

+ 81 - 0
pages/paymentMethod/paymentMethod.scss

@@ -0,0 +1,81 @@
+.pay-way {
+  display: flex;
+  justify-content: space-between;
+  width: calc(100% - 34rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto;
+  padding: 38rpx 86rpx;
+  .pay-way-item {
+    text-align: center;
+    font-size: 30rpx;
+    color: #5f5f5f;
+    image {
+      width: 143rpx;
+      height: 143rpx;
+    }
+  }
+}
+.pay-way-new {
+  display: flex;
+  justify-content: space-around;
+  width: calc(100% - 60rpx);
+  border-top: solid 1px #979797;
+  margin: 23rpx auto 0;
+  padding: 36rpx 0 10rpx;
+  .pay-way-item {
+    width: calc(33% - 9rpx);
+    border-radius: 20rpx;
+    text-align: center;
+    padding: 30rpx 0;
+    image {
+      width: 110rpx;
+      height: 110rpx;
+    }
+    .title {
+      font-size: 28rpx;
+      font-weight: 400;
+      font-family: 'PingFangSC-Regular, PingFang SC';
+      color: #fff;
+      margin: 10rpx 0;
+    }
+    .subtitle {
+      font-size: 14rpx;
+      font-weight: 400;
+      font-family: 'PingFangSC-Regular, PingFang SC';
+      color: #fff;
+      opacity: 0.73;
+    }
+  }
+  .pay-way-item-hy {
+    background: linear-gradient(153deg, #fa9460 0%, #ff5065 100%);
+  }
+  .pay-way-item-wx {
+    background: linear-gradient(155deg, #5ee3a6 0%, #3eb9c8 100%);
+  }
+  .pay-way-item-jh {
+    background: linear-gradient(155deg, #5aa6ff 0%, #c782ff 100%);
+  }
+}
+.pay-way-subtitle {
+  display: flex;
+  justify-content: space-around;
+  width: calc(100% - 60rpx);
+  margin: 0 auto 60rpx;
+  &-item {
+    width: calc(33% - 9rpx);
+    border-radius: 20rpx;
+    text-align: center;
+    font-size: 20rpx;
+    font-weight: 400;
+    font-family: 'PingFangSC-Regular, PingFang SC';
+    opacity: 0.73;
+  }
+}
+.pay-way-close-btn {
+  width: calc(100% - 80rpx);
+  margin: 0 auto 68rpx;
+  border: none;
+  background-color: #3397fa;
+  color: #fff;
+  border-radius: 10rpx;
+}

+ 392 - 0
pages/paymentMethod/paymentMethod.vue

@@ -0,0 +1,392 @@
+<!--
+ * @Description: 支付方式选择  微信or快捷支付or聚合支付
+ * @Author: 空白格
+ * @Date: 2022-08-01 11:45:20
+ * @LastEditors: 空白格
+ * @LastEditTime: 2023-01-03 10:21:16
+ * @FilePath: \parking_h5\pages\choosePayment\choosePayment.vue
+ * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved. 
+-->
+
+<template>
+	<view>
+		<u-modal v-model="payWayPop" :title-style="{ color: '#404040' }" title="缴费方式" width="660rpx"
+			:show-confirm-button="false" :show-cancel-button="false">
+			<view class="slot-content">
+				<view class="pay-way-new">
+					<!-- <view class="pay-way-item pay-way-item-hy" @click="gyBankPay">
+						<image src="../../static/img/guiyang-bank-icon.png" mode=""></image>
+						<view class="title">贵州银行</view>
+						<view class="subtitle">前三个月每天首次一分钱<br/>长期八折优惠</view>
+					</view>
+					<view class="pay-way-item pay-way-item-jh" @click="wechatPay">
+						<image src="../../static/img/juhe-icon.png" mode=""></image>
+						<view class="title">微信/支付宝</view>
+					</view> -->
+					<view class="pay-way-item pay-way-item-hy"
+						@click="$u.debounce(gyBankPay, 1000, (immediate = true))">
+						<image src="/static/img/gyyh-icon.svg" mode=""></image>
+						<view class="title">贵州银行</view>
+					</view>
+					<!-- #ifdef H5 || MP-WEIXIN -->
+					<view class="pay-way-item pay-way-item-wx" @click="$u.debounce(wechatPay, 1000, (immediate = true))"
+						v-if="wxEnv">
+						<image src="/static/img/weixin-icon.svg" mode=""></image>
+						<view class="title">微信支付</view>
+					</view>
+					<!-- #endif -->
+					<view class="pay-way-item pay-way-item-jh" @click="$u.debounce(juhePay, 1000, (immediate = true))">
+						<image src="/static/img/juhe-icon.svg" mode=""></image>
+						<view class="title">聚合支付</view>
+					</view>
+				</view>
+				<view class="pay-way-subtitle">
+					<view class="pay-way-subtitle-item">前三个月每天首次一分钱,长期八折优惠</view>
+					<!-- #ifdef H5 || MP-WEIXIN -->
+					<view class="pay-way-subtitle-item" v-if="wxEnv">&nbsp;</view>
+					<!-- #endif -->
+					<view class="pay-way-subtitle-item">&nbsp;</view>
+				</view>
+				<button class="pay-way-close-btn" @click="closePaymentMethod">关闭</button>
+			</view>
+		</u-modal>
+		<u-toast ref="uToast" />
+	</view>
+</template>
+
+<script>
+	import {
+		getEnvIsWx
+	} from '@/utils/judgEnvironment.js';
+	import $wxPay from '@/utils/wxPay.js';
+	export default {
+		props: {
+			// 弹框显示
+			payWayPop: {
+				type: Boolean,
+				default: false
+			},
+			// 订单数组
+			curOrderList: {
+				type: Array,
+				default: null
+			},
+			// 设备编号
+			deviceNo: {
+				type: String,
+				default: null
+			},
+			// 地磁支付需要字段
+			payeeId: {
+				type: String,
+				default: undefined
+			},
+			// 地磁支付需要字段
+			payeeName: {
+				type: String,
+				default: undefined
+			},
+			// 扫码支付需要字段
+			sanPay: {
+				type: Boolean,
+				default: false
+			},
+			// 追缴类型
+			pursueType: {
+				type: String,
+				default: undefined
+			},
+			// 车牌号
+			vehicleNo: {
+				type: String,
+				default: undefined
+			},
+			// 跳转页面
+			jumpUrl: {
+				type: String,
+				default: null
+			},
+			// 出口扫码   接口不一样
+			exportFlag: {
+				type: Boolean,
+				default: false
+			},
+			// 其他参数
+			otherParams: {
+				type: Object,
+				default: () => {}
+			}
+		},
+		data() {
+			return {
+				wxEnv: true
+			};
+		},
+		created() {
+			this.wxEnv = getEnvIsWx();
+		},
+		methods: {
+			/**
+			 * 贵阳银行支付
+			 * @param {Array} orderList 需要支付的订单号组成的数组
+			 * @param {String} deviceNo 设备编号(只有车位锁部分有)
+			 * */
+			gyBankPay() {
+				const params = {
+					orderList: this.curOrderList,
+					deviceNo: this.deviceNo,
+					jumpUrl: this.jumpUrl,
+					payeeId: this.payeeId,
+					payeeName: this.payeeName,
+					pursueType: this.pursueType,
+					vehicleNo: this.vehicleNo,
+					sanPay: this.sanPay
+				};
+				if (this.exportFlag == true) {
+					this.$u.api
+						.quickPayExportApi(params)
+						.then((res) => {
+							if (res.data.needPay) {
+								let payUrl = res.data.url;
+								location.href = payUrl;
+							} else {
+								this.$refs.uToast.show({
+									title: '无需支付',
+									type: 'info'
+								});
+								setTimeout(() => {
+									uni.hideLoading();
+									location.reload();
+								}, 1000);
+							}
+						})
+						.catch((err) => {
+							this.$refs.uToast.show({
+								title: err.msg,
+								type: 'error'
+							});
+						});
+				} else {
+					this.$u.api
+						.payGzbank(params)
+						.then((res) => {
+							if (res.data.needPay) {
+								let payUrl = res.data.url;
+								location.href = payUrl;
+							} else {
+								this.$refs.uToast.show({
+									title: '无需支付',
+									type: 'info'
+								});
+								setTimeout(() => {
+									uni.hideLoading();
+									location.reload();
+								}, 1000);
+							}
+						})
+						.catch((err) => {
+							this.$refs.uToast.show({
+								title: err.msg,
+								type: 'error'
+							});
+						});
+				}
+			},
+			/**
+			 * 聚合支付
+			 * */
+			juhePay() {
+				this.getWXPayByJava(this.curOrderList, this.deviceNo);
+			},
+			/**
+			 * 微信支付
+			 */
+			wechatPay() {
+				const params = {
+					orderList: this.curOrderList,
+					openid: this.vuex_wxinfo.openId,
+					deviceNo: this.deviceNo || undefined,
+					payeeId: this.payeeId || undefined,
+					payeeName: this.payeeName || undefined,
+					vehicleNo: this.vehicleNo,
+					sanPay: this.sanPay,
+					...this.otherParams
+				};
+				if (this.exportFlag) {
+					this.$u.api.parkingWechatPayApi(params).then((res) => {
+						if (res.code === 200) {
+							if (res.data.needPay) {
+								$wxPay.weixinPay(res.data.wx).then((r) => {
+									switch (Number(r.code)) {
+										case 0: // 成功
+											//#ifdef H5
+											window.location.reload();
+											//#endif
+											break;
+										case 1: // 取消
+											this.$u.api.updateCouponStatusApi({
+												orderList: this.curOrderList
+											}).then(res => {
+												if (res.code === 200) {
+													this.$refs.uToast.show({
+														title: '已取消支付',
+														type: 'info'
+													});
+													window.location.reload();
+												}
+											})
+											break;
+										case 2: // 支付失败
+											this.$refs.uToast.show({
+												title: '支付失败,请检查!',
+												type: 'error'
+											});
+											break;
+									}
+								});
+							} else {
+								this.$refs.uToast.show({
+									title: '无需支付',
+									type: 'info'
+								});
+								setTimeout(() => {
+									uni.hideLoading();
+									location.reload();
+								}, 1000);
+							}
+						}
+					});
+				} else {
+					this.$u.api.wechatPayApi(params).then((res) => {
+						if (res.code === 200) {
+							if (res.data.needPay) {
+								$wxPay.weixinPay(res.data.wx).then((r) => {
+									switch (Number(r.code)) {
+										case 0: // 成功
+											//#ifdef H5
+											window.location.reload();
+											//#endif
+											break;
+										case 1: // 取消
+											this.$u.api.updateCouponStatusApi({
+												orderList: this.curOrderList
+											}).then(res => {
+												if (res.code === 200) {
+													this.$refs.uToast.show({
+														title: '已取消支付',
+														type: 'info'
+													});
+													window.location.reload();
+												}
+											})
+											break;
+										case 2: // 支付失败
+											this.$refs.uToast.show({
+												title: '支付失败,请检查!',
+												type: 'error'
+											});
+											break;
+									}
+								});
+							} else {
+								this.$refs.uToast.show({
+									title: '无需支付',
+									type: 'info'
+								});
+								setTimeout(() => {
+									uni.hideLoading();
+									location.reload();
+								}, 1000);
+							}
+						}
+					});
+				}
+			},
+			/**
+			 * 直接通过后台获取贵阳银行微信支付地址
+			 * @param {Array} list 需要支付的订单组合数组
+			 * @param {Number} deviceNo 设备编号(在停车锁部分需要)
+			 * */
+			getWXPayByJava(orderList, deviceNo) {
+				let params = {
+					orderList: orderList,
+					openid: this.vuex_wxinfo.openId,
+					jumpUrl: this.jumpUrl,
+					deviceNo: deviceNo ? deviceNo : null,
+					payeeId: this.payeeId,
+					payeeName: this.payeeName,
+					pursueType: this.pursueType,
+					vehicleNo: this.vehicleNo,
+					sanPay: this.sanPay
+				};
+				if (this.exportFlag) {
+					this.$u.api
+						.polyPayExportApi(params)
+						.then((res) => {
+							if (res.code === 200) {
+								if (res.data.needPay) {
+									localStorage.setItem('jumpUrl', this.jumpUrl);
+									location.href = res.data.qrCodeUrl;
+								} else {
+									this.$refs.uToast.show({
+										title: '无需支付',
+										type: 'info'
+									});
+									setTimeout(() => {
+										uni.hideLoading();
+										location.href = this.jumpUrl;
+									}, 1000);
+								}
+							} else {
+								uni.hideLoading();
+							}
+						})
+						.catch((err) => {
+							this.$refs.uToast.show({
+								title: '无法调起微信支付!',
+								type: 'error'
+							});
+						});
+				} else {
+					this.$u.api
+						.ordinaryWxPay(params)
+						.then((res) => {
+							if (res.code === 200) {
+								if (res.data.needPay) {
+									localStorage.setItem('jumpUrl', this.jumpUrl);
+									location.href = res.data.qrCodeUrl;
+								} else {
+									this.$refs.uToast.show({
+										title: '无需支付',
+										type: 'info'
+									});
+									setTimeout(() => {
+										uni.hideLoading();
+										location.href = this.jumpUrl;
+									}, 1000);
+								}
+							} else {
+								uni.hideLoading();
+							}
+						})
+						.catch((err) => {
+							this.$refs.uToast.show({
+								title: '无法调起微信支付!',
+								type: 'error'
+							});
+						});
+				}
+			},
+			/**
+			 * 关闭弹框
+			 * */
+			closePaymentMethod() {
+				this.$emit('closePaymentMethod');
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	@import './paymentMethod.scss';
+</style>

+ 62 - 0
pages/privacyPolicy/privacyPolicy.vue

@@ -0,0 +1,62 @@
+<!-- ============================= 隐私政策/用户服务条款 ============================= -->
+<template>
+  <view class="u-content">
+    <u-parse :html="content"></u-parse>
+    <u-toast ref="uToast" />
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      content: ''
+    };
+  },
+  onLoad(query) {
+    const termsType = query?.termsType;
+    if (termsType) {
+      const termsTypeObj = {
+        1: '用户服务条款',
+        2: '隐私政策'
+      };
+      uni.setNavigationBarTitle({
+        title: termsTypeObj[Number(termsType)]
+      });
+      this.getSysterms(Number(termsType));
+    }
+  },
+  methods: {
+    /**
+     * @description: 获取系统参数
+     * @param {*} termsType
+     * @return {*}
+     */
+    async getSysterms(termsType) {
+      try {
+        const { code, data } = await this.$u.api.getSysterms({ termsType });
+        if (code === 200) {
+          this.content = data?.content;
+        }
+      } catch (error) {
+        this.showToast('系统错误!', 'error');
+      }
+    },
+    /**
+     * @description: 显示提示
+     * @param {*} title
+     * @param {*} type
+     * @return {*}
+     */
+    showToast(title = '操作失败', type = 'info') {
+      this.$refs.uToast.show({ title, type });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.u-content {
+  padding: 20rpx;
+}
+</style>

+ 301 - 0
pages/roadGateSystem/roadGateSystem.scss

@@ -0,0 +1,301 @@
+
+.parking-lock {
+	height: calc(100vh - 88rpx);
+	background-color: #F6F6FF;
+	padding-top: 133rpx;
+	.parking-lock-title {
+		font-size: 46rpx;
+		color: #292929;
+		text-align: center;
+		padding-top: 31rpx;
+		line-height: 65rpx;
+		font-family: PingFangSC-Regular, PingFang SC;
+		font-weight: 400;
+	}
+	.parking-lock-tips {
+		width: calc(100% - 72rpx);
+		font-size: 30rpx;
+		color: #777777;
+		text-align: center;
+		margin: 10rpx auto;
+		line-height: 47rpx;
+	}
+	.parking-lock-info {
+		width: calc(100% - 72rpx);
+		margin: 31rpx auto 54rpx;
+		background-color: #fff;
+		border-radius: 15rpx;
+		padding: 39rpx 41rpx;
+		.parking-lock-info-item {
+			display: flex;
+			margin-bottom: 16rpx;
+			view {
+				font-size: 28rpx;
+				&:first-child {
+					width: 30%;
+					color: #2A2A2A;
+					font-weight: 500;
+				}
+				&:last-child {
+					color: #6E6E6E;
+				}
+			}
+			.weight {
+				color: #2A2A2A!important;
+				font-weight: 500;
+			}
+			.really-money {
+				color: #FA7319!important;
+			}
+		}
+	}
+	.parking-lock-pay-btn {
+		width: calc(100% - 72rpx);
+		margin: 0 auto;
+		button {
+			width: 100%;
+			height: 100rpx;
+			line-height: 100rpx;
+			background-color: #008CFF;
+			border: none;
+			color: #fff;
+			box-shadow: 0px 7px 13px 0px rgba(16, 153, 250, 0.31);
+			font-size: 28rpx;
+			font-weight: 500;
+		}
+	}
+	.parking-lock-begin-box {
+		width: 441rpx;
+		height: 441rpx;
+		line-height: 441rpx;
+		background: #31A2FF;
+		background: linear-gradient(270deg, rgba(49,162,255,0.1) 20%, rgba(49,162,255,1) 100%);
+		border-radius: 50%;
+		text-align: center;
+		margin: 0 auto;
+		// animation: spin 3s linear infinite;
+		.parking-lock-begin-bg {
+			display: inline-block;
+			width: 420rpx;
+			height: 420rpx;
+			line-height: 420rpx;
+			vertical-align: middle;
+			border: solid 12rpx #fff;
+			background: linear-gradient(346deg, #008CFF 0%, #95CFFF 100%);
+			border-radius: 50%;
+			image {
+				width: 194rpx;
+				height: 239rpx;
+				vertical-align: middle;
+			}
+		}
+	}
+	.parking-lock-begin-info {
+		text-align: center;
+		font-size: 50rpx;
+		color: #008CFF;
+		margin-top: 57rpx;
+	}
+	.parking-lock-loading-box {
+		width: 441rpx;
+		height: 441rpx;
+		line-height: 441rpx;
+		background: #31A2FF;
+		background: linear-gradient(0deg, rgba(49,162,255,0.1) 20%, rgba(49,162,255,1) 100%);
+		border-radius: 50%;
+		text-align: center;
+		margin: 0 auto;
+		animation: spin 3s linear infinite;
+		.parking-lock-loading-bg {
+			display: inline-block;
+			width: 420rpx;
+			height: 420rpx;
+			line-height: 420rpx;
+			vertical-align: middle;
+			border: solid 12rpx #fff;
+			background: linear-gradient(346deg, #008CFF 0%, #95CFFF 100%);
+			border-radius: 50%;
+			image {
+				width: 194rpx;
+				height: 239rpx;
+				vertical-align: middle;
+			}
+		}
+	}
+	.parking-lock-loading-info {
+		text-align: center;
+		font-size: 50rpx;
+		color: #008CFF;
+		margin-top: 57rpx;
+	}
+	.parking-lock-success {
+		.parking-lock-success-box {
+			width: 441rpx;
+			height: 441rpx;
+			margin: 0 auto;
+			image {
+				width: 100%;
+				height: 100%;
+			}
+		}
+		.parking-lock-success-info {
+			color: #4CCD8A;
+			font-size: 50rpx;
+			text-align: center;
+			margin: 56rpx 0 202rpx;
+		}
+		.parking-lock-success-button {
+			width: calc(100% - 80rpx);
+			margin: 0 auto;
+			button {
+				width: 100%;
+				height: 100rpx;
+				line-height: 100rpx;
+				background-color: #008CFF;
+				font-size: 28rpx;
+				color: #fff;
+			}
+		}
+	}
+}
+.pay-way {
+	display: flex;
+	justify-content: space-between;
+	width: calc(100% - 34rpx);
+	border-top: solid 1px #979797;
+	margin: 23rpx auto;
+	padding: 38rpx 86rpx;
+	.pay-way-item {
+		text-align: center;
+		font-size: 30rpx;
+		color: #5F5F5F;
+		image {
+			width: 143rpx;
+			height: 143rpx;
+		}
+	}
+}
+.pay-way-close-btn {
+	width: calc(100% - 34rpx);
+	margin: 0 auto 68rpx;
+	border: none;
+	background-color: #3397FA;
+	color: #fff;
+	border-radius: 10rpx;
+}
+@keyframes rotate {
+    0%{
+        transform: rotate(0);
+    }
+    50% {
+    	transform:rotate(200deg);
+    }
+    100% {
+        transform: rotate(0);
+	}
+}
+@keyframes spin {
+  from {
+    transform: rotate(0);
+  }
+  to{
+    transform: rotate(359deg);
+  }
+}
+.loadingSelect{
+	    text-align: center;
+	    margin-top: 20rpx;
+}
+.spinner {
+  margin: auto;
+  width: 50px;
+  height: 60px;
+  text-align: center;
+  font-size: 10px;
+}
+ 
+.spinner > view {
+  background-color: #6495ED;
+  height: 100%;
+  width: 10rpx;
+  margin-right: 2rpx;
+  display: inline-block;
+   
+  -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
+  animation: stretchdelay 1.2s infinite ease-in-out;
+}
+ 
+.spinner .rect2 {
+  -webkit-animation-delay: -1.1s;
+  animation-delay: -1.1s;
+}
+ 
+.spinner .rect3 {
+  -webkit-animation-delay: -1.0s;
+  animation-delay: -1.0s;
+}
+ 
+.spinner .rect4 {
+  -webkit-animation-delay: -0.9s;
+  animation-delay: -0.9s;
+}
+ 
+.spinner .rect5 {
+  -webkit-animation-delay: -0.8s;
+  animation-delay: -0.8s;
+}
+ 
+@-webkit-keyframes stretchdelay {
+  0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 
+  20% { -webkit-transform: scaleY(1.0) }
+}
+ 
+@keyframes stretchdelay {
+  0%, 40%, 100% {
+    transform: scaleY(0.4);
+    -webkit-transform: scaleY(0.4);
+  }  20% {
+    transform: scaleY(1.0);
+    -webkit-transform: scaleY(1.0);
+  }
+}
+.new-plate-number{	
+	margin-bottom: 70rpx;
+}
+.message-input-wrap{
+	margin: 0 -40rpx;
+}
+.message-input-wrap /deep/ .u-input ~ uni-view:last-of-type .u-char-item{
+	background-color: #E8FFE8;
+}
+.really-license-txt{
+	color: #008CFF;
+}
+.really-license-txt1{
+	color: #008CFF;
+	margin: 20rpx;
+}
+.popup-vehicleNo-title{
+	font-size: 48rpx;
+	text-align: center;
+	padding-top: 20rpx;
+}
+.popup-vehicleNo-center{
+	width: 95%;
+	height: 2rpx;
+	border-top: solid rgb(146, 146, 146) 2rpx;
+	margin: 30rpx 20rpx 50rpx 20rpx;
+}
+.popup-vehicleNo-select{
+	text-align: center;
+	color: #777777;
+}
+.vehicleNo-btn{
+	display: flex;
+	margin: 40rpx 0;
+}
+.parking-lock-pay-attention{
+	margin: 50rpx;
+	line-height: 48rpx;
+	color: #777777;
+}

+ 0 - 0
pages/roadGateSystem/roadGateSystem.vue


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio