石广澎
2025-11-17 f28a4a64c825b02e32e79387e0a6763e934ce51d
pages/pay/wxpay.vue
New file
@@ -0,0 +1,292 @@
<template>
   <view>
      <view class="u-relative">
         <view class="u-p-30 u-flex">
            <image :src="info.logo_image||'/static/imgs/store-logo.png'" class="avg-img"></image>
            <view class="u-font-32 font-bold color-333 u-m-l-20">{{ info.shop_name }}</view>
         </view>
         <view class="pay-box bg-fff">
            <view class="u-font-24 color-666">金额</view>
            <view class="u-p-v-20 u-flex u-border-bottom-f5 u-relative">
               <view class="money-icon color-333">¥</view>
               <view class="u-flex-1 u-flex u-m-l-10" style="height: 80rpx;">
                  <view v-if="money" class="u-font-40">{{money}}</view>
                  <view v-if="!money&&bordShow" class="cursor"></view>
                  <view v-if="!money" class="u-font-32 color-999">请输入金额</view>
                  <view v-if="money&&bordShow" class="cursor"></view>
               </view>
               <!-- <u-input placeholder="请输入金额" v-model="money" border="none" disabled disabledColor="#FFFFFF"
                  placeholderStyle="color: #c0c4cc" fontSize="40rpx" color="#333"></u-input> -->
               <view class="mask" @click="showBord"></view>
            </view>
            <view class="u-font-24 color-666 u-p-v-20">选择支付方式</view>
            <view>
               <u-radio-group v-model="payType" placement="column">
                  <view v-if="platform == 0 || platform == 2"
                     class="u-border-bottom-f5 u-p-v-20 u-flex u-row-between">
                     <view class="flex-1 u-flex">
                        <image src="@/static/imgs/pay-wx.png" class="pay-icon"></image>
                        <view class="u-font-30 color-333 u-m-l-10">微信</view>
                     </view>
                     <u-radio :name="0" activeColor="#D41F28" :customStyle="{ marginLeft: '30rpx' }"></u-radio>
                  </view>
                  <view v-if="platform == 1 || platform == 2"
                     class="u-border-bottom-f5 u-p-v-20 u-flex u-row-between">
                     <view class="flex-1 u-flex">
                        <image src="@/static/imgs/pay-zfb.png" class="pay-icon"></image>
                        <view class="u-font-30 color-333 u-m-l-10">支付宝</view>
                     </view>
                     <u-radio :name="1" activeColor="#D41F28" :customStyle="{ marginLeft: '30rpx' }"></u-radio>
                  </view>
                  <view class="u-border-bottom-f5 u-p-v-20 u-flex u-row-between">
                     <view class="flex-1 u-flex">
                        <image src="@/static/imgs/pay-jyk.png" class="pay-icon"></image>
                        <view class="u-m-l-10 flex-1 u-flex u-row-between">
                           <view>
                              <view class="u-font-30 color-333">金燕卡(8646)</view>
                              <view class="u-font-24 color-999">
                                 可用
                                 <text class="color-red">15</text>
                                 积分
                                 <text class="color-red">满40-20</text>
                                 优惠券
                              </view>
                           </view>
                           <u-tag text="享8折优惠" type="error" plain size="mini"></u-tag>
                        </view>
                     </view>
                     <u-radio :name="2" activeColor="#D41F28" :customStyle="{ marginLeft: '30rpx' }"></u-radio>
                  </view>
               </u-radio-group>
            </view>
            <button class="pay-it" @click="pay">确定支付</button>
         </view>
      </view>
      <navigator class="reg-btn" :url="'/pages/pay/register?cid='+cid">
         <image src="/static/register-btn.png" mode=""></image>
      </navigator>
      <u-popup :show="bordShow" :overlay="false" @close="close" @open="open">
         <key-bord @changeMoney="changeMoney" :num.sync="money" @close="close" @pay="pay"></key-bord>
      </u-popup>
   </view>
</template>
<script>
   import {
      config
   } from '@/common/config.js';
   import {
      queryShop,
      getWechatInfo,
      getWechatConfigInfo,
      saveWxOrder
   } from '@/common/api/index'
   import wx from 'weixin-js-sdk'; // 使用js-sdk
   export default {
      data() {
         return {
        platform: this.$utils.getPlat(),
            cid: '',
            info: {
               shop_name: '',
               scan_flag: '',
               use_score_flag: '',
               user_coupon_flag: ''
            },
            hasNum: false, // 是否输入金额
            money: '', // 金额
            transStyles: {
               position: 'fixed',
               bottom: 0,
               left: 0,
               width: '100%',
               backgroundColor: '#FFFFFF',
               zIndex: 1001
            },
            payType: this.$utils.getPlat(), // 支付方式
            bordShow: false // 显示键盘
         };
      },
      onLoad(opt) {
         this.cid = opt.cid
         uni.showLoading()
         queryShop({
            params: opt
         }).then(res => {
            if (res.logo_image) {
               try {
                  let arr = JSON.parse(res.logo_image)
                  res.logo_image = config.sftpURL + arr[0].path
               } catch (e) {
                  //TODO handle the exception
                  res.logo_image = ''
               }
            }
            this.info = res
            this.registerSDK()
         }).catch(() => {
            uni.hideLoading()
         })
      },
      methods: {
         registerSDK() {
            const uri = encodeURIComponent(window.location)
            getWechatConfigInfo({
               url: uri
            }).then(res => {
               uni.hideLoading()
               wx.config({
                  debug: false, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。
                  appId: res.appId, // 必填,公众号的唯一标识
                  timestamp: res.timestamp, // 必填,生成签名的时间戳
                  nonceStr: res.nonceStr, // 必填,生成签名的随机串
                  signature: res.signature, // 必填,签名
                  jsApiList: ['chooseWXPay'] // 必填,需要使用的 JS 接口列表
               });
            }).catch(() => {
               uni.hideLoading()
            })
         },
         // 更新金额
         changeMoney(str) {
            this.money = str;
         },
         // 展示键盘
         showBord() {
            this.bordShow = true;
         },
         // 关闭键盘
         close() {
            this.bordShow = false;
         },
         pay() {
            if (!this.money) {
               uni.showToast({
                  icon: 'none',
                  title: '请输入金额'
               });
               return;
            }
            uni.showLoading()
            saveWxOrder({
               cusid: this.info.cusid,
               c: this.info.c,
               money: parseInt(this.money * 100)
            }).then(res => {
               uni.hideLoading()
               setTimeout(() => {
                  wx.chooseWXPay({
                     timestamp: res.timeStamp, // 支付签名时间戳
                     nonceStr: res.nonceStr, // 支付签名随机串,不长于 32 位
                     package: res.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
                     signType: res.signType, // 微信支付V3的传入 RSA ,微信支付V2的传入格式与V2统一下单的签名格式保持一致
                     paySign: res.paySign, // 支付签名
                     success: function(ret) {
                        // 支付成功后的回调函数
                        uni.navigateTo({
                           url: '/pages/pay/paySuccess?youHuiInfo=' + JSON
                              .stringify(res.youHuiInfo)
                        })
                     }
                  });
               }, 200)
            }).catch(() => {
               uni.hideLoading()
            })
         }
      }
   };
</script>
<style scoped lang="scss">
   .avg-img {
      width: 80rpx;
      height: 80rpx;
   }
   .reg-btn {
      display: block;
      margin: 80rpx auto 0;
      width: 686rpx;
      height: 198rpx;
      image {
         width: 100%;
         height: 100%;
      }
   }
   .pay-box {
      padding: 40rpx 20rpx;
      border-radius: 10rpx;
      margin: 0 30rpx;
   }
   .money-icon {
      font-size: 50rpx;
      font-weight: bold;
      margin-right: 20rpx;
   }
   .money-num {
      font-size: 50rpx;
      font-weight: bold;
   }
   .pay-icon {
      width: 48rpx;
      height: 48rpx;
   }
   .mask {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      bottom: 0;
      z-index: 101;
      background-color: rgba(0, 0, 0, 0);
   }
   .pay-it {
      border-radius: 50rpx;
      font-size: 34rpx;
      color: #ffffff;
      background-color: #de2d35;
      width: 90%;
      margin-top: 20rpx;
   }
   @keyframes cursor-blinks {
      0% {
         opacity: 1;
         display: block;
      }
      50% {
         opacity: 0;
         display: none;
      }
      100% {
         opacity: 1;
         display: block;
      }
   }
   .cursor {
      border-left: 1px solid #333;
      margin-left: 2px;
      height: 40rpx;
      animation: cursor-blinks 1s infinite steps(1, start)
   }
   .cursor-act {
      border-left-color: transparent;
      animation: cursor-blinks 1s infinite steps(1, start);
   }
</style>