uniapp 微信小程序 支付

news/2024/10/6 8:22:01
<template>
  <view class="wrap">
    <view class="payComplete">
      <image class="img" src="@/static/image/index/6.png" />
      <text class="adress">支付完成后填写</text>
    </view>
    <view class="commodityWrap">
      <view class="title">
        <text class="border" />
        <text>商品信息</text>
      </view>
      <view class="min">
        <image v-if="productObj.picUrl" class="img" :src="productObj.picUrl" />
        <image v-else class="img" src="@/static/image/index/defaultImg.png" />
        <view class="right">
          <view class="name">
            <text class="secondaryContent">
              {{ productObj.productName }}
            </text>
            <text class="num"
              >¥ {{ productObj.price ? (Number(productObj.price) / 100).toFixed(2) : '0.00' }}</text
            >
          </view>
          <view class="name illustrate">
            <text class="secondaryContent">
              {{ productObj.productExt }}
            </text>
          </view>
        </view>
      </view>
      <view class="bottomNum">
        <view class="wraps">
          <text>选择数量</text>
          <up-number-box
            @change="valChange"
            v-model="chooseNumber"
            @blur="onNumberChange"
            :min="1"
            :max="999"
          />
        </view>
      </view>
    </view>
    <view class="commodityWrap payWay">
      <view class="title">
        <text class="border" />
        <text>支付方式</text>
      </view>
      <view class="payList">
        <view class="left">
          <image class="img" src="@/static/image/index/8.png" />
          <text class="adress">微信支付</text>
        </view>
        <image class="right" src="@/static/image/index/7.png" />
      </view>
    </view>
    <view class="goPay">
      <view class="wraps">
        <view class="left">
          <text class="name">应付:</text>
          <text class="name">¥ </text>
          <text class="name">{{ payNumberInteger }}</text>
          <text class="name">.{{ payNumberDecimal }}</text>
        </view>
        <view class="right" @tap="toPay"> 去支付 </view>
      </view>
    </view>
    <view class="bg" v-if="bgShow" />
    <view class="bgTwo" v-if="bgShowTwo" />
  </view>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onLoad, onShow, onUnload, onHide } from '@dcloudio/uni-app'
import { productInfoInfo, orderPaid, orderStatus } from '@/api/index'
const state = reactive({
  timeQuestions: null
})
const chooseNumber = ref(1)
const chooseNumberSure = ref(1)
const productId = ref('')
const productObj = ref({})
const bizOrderNo = ref('')
const userInfo = ref({})
const isstop = ref(false)
const isBack = ref(false)
// 整数部分
const payNumberInteger = ref('0')
// 小数部分
const payNumberDecimal = ref('00')
const bgShow = ref(false)
const bgShowTwo = ref(false)

onLoad((options) => {
  productId.value = options.productId
})
onUnload(() => {
  const isScan = uni.getStorageSync('wxScans')
  clearInterval(state.timeQuestions)
  state.timeQuestions = null
  if (isScan && isScan == 'true' && !isBack.value) {
    uni.switchTab({
      url: '/pages/load/index'
    })
    // uni.switchTab({
    //   url: '/pages/index/index'
    // })
  }
})
onHide(() => {
  uni.removeStorageSync('isBack')
  uni.removeStorageSync('isChoose')
})
onShow(() => {
  bgShow.value = false
  bgShowTwo.value = false
  userInfo.value = uni.getStorageSync('userInfo') ? JSON.parse(uni.getStorageSync('userInfo')) : {}
  productObj.value = {}
  chooseNumber.value = 1
  chooseNumberSure.value = 1
  payNumberInteger.value = '0'
  payNumberDecimal.value = '00'
  init()
})
const init = () => {
  if (uni.getStorageSync('paySuccess') == 'true') {
    uni.showLoading({
      title: '支付中...'
    })
    bgShowTwo.value = true
  } else {
    uni.showLoading({
      title: '加载中'
    })
  }
  const param = '?productId=' + productId.value
  productInfoInfo(param).then((res: any) => {
    if (isstop.value == false) {
      uni.hideLoading()
    }
    if (res.code == 0) {
      if (res.data) {
        if (res.data.productStatus == 'off') {
          uni.removeStorageSync('isBack')
          uni.removeStorageSync('isChoose')
          bgShowTwo.value = true
          uni.showToast({
            title: '该商品已下架',
            icon: 'none',
            duration: 2000
          })
          setTimeout(() => {
            bgShowTwo.value = false
            uni.switchTab({
              url: '/pages/index/index'
            })
          }, 2000)
        } else {
          if (res.data && res.data.productName) {
            productObj.value = res.data
            const price =
              res.data && res.data.price ? (Number(res.data.price) / 100).toFixed(2) : '0.00'
            payNumberInteger.value = price.split('.')[0]
            payNumberDecimal.value = price.split('.')[1]
          }
        }
      }
    }
  })
}
const valChange = (e) => {
  chooseNumberSure.value = e.value
  const price = (
    (productObj.value && productObj.value.price ? Number(productObj.value.price) / 100 : 0) *
    e.value
  ).toFixed(2)
  payNumberInteger.value = price.split('.')[0]
  payNumberDecimal.value = price.split('.')[1]
}
const onNumberChange = (event) => {
  if (!event.value) {
    chooseNumber.value = 1000
    chooseNumberSure.value = 1000
    setTimeout(() => {
      chooseNumber.value = 1
      chooseNumberSure.value = 1
    }, 20)

    const price =
      productObj.value && productObj.value.price
        ? (Number(productObj.value.price) / 100).toFixed(2)
        : '0.00'
    payNumberInteger.value = price.split('.')[0]
    payNumberDecimal.value = price.split('.')[1]
  }
}
//支付
const toPay = () => {
  uni.showLoading({
    title: '加载中'
  })

  const param = {
    patientId: userInfo.value.patientId,
    openid: userInfo.value.openId,
    productId: productId.value,
    doctorId: userInfo.value.bindDoctorId ? userInfo.value.bindDoctorId : null,
    num: chooseNumberSure.value
  }
  orderPaid(param).then((res: any) => {
    uni.hideLoading()
    if (res.code == 0) {
      const payParam = JSON.parse(res.data.payBody)
      bizOrderNo.value = res.data.bizOrderNo
      uni.requestPayment({
        provider: 'wxpay',
        timeStamp: payParam.timeStamp,
        nonceStr: payParam.nonceStr,
        package: payParam.package,
        signType: payParam.signType,
        paySign: payParam.paySign,
        success: function (res) {
          isstop.value = true
          bgShow.value = true
          uni.setStorageSync('paySuccess', 'true')
          loopTime()
          console.log('success:' + JSON.stringify(res))
        },
        fail: function (err) {
          isstop.value = false
          isBack.value = true
          bgShow.value = false
          bgShowTwo.value = false
          //   console.log('支付失败')
          uni.removeStorageSync('isBack')
          uni.removeStorageSync('isChoose')
          uni.redirectTo({
            url:
              '/packA/pages/pay/nopayIndex?productId=' +
              productId.value +
              '&chooseNumberSure=' +
              chooseNumberSure.value +
              '&bizOrderNo=' +
              bizOrderNo.value
          })
          console.log('fail:' + JSON.stringify(err))
        }
      })
    }
  })
}
const loopTime = () => {
  let s = 0
  state.timeQuestions = setInterval(() => {
    s++
后端说 orderStatusFun这个方法的接口 两秒内肯定会更新支付状态  所以两秒后调用这个方法
    if (s >= 2) {
      s = 0
      orderStatusFun()
    }
  }, 1000)
}
const orderStatusFun = () => {
  const param = bizOrderNo.value
  orderStatus(param).then((res) => {
    isstop.value = true
    if (res.data.payState == 'PROGRESS') {
      console.log('PROGRESS')
    } else if (res.data.payState == 'SUCCESS') {
      bgShow.value = false
      uni.removeStorageSync('paySuccess')
      clearInterval(state.timeQuestions)
      state.timeQuestions = null
      uni.showToast({
        title: '支付成功',
        icon: 'none',
        duration: 2000
      })
      setTimeout(() => {
        isstop.value = false
        bgShowTwo.value = false
        isBack.value = true
        uni.removeStorageSync('isBack')
        uni.removeStorageSync('isChoose')
        uni.hideLoading()
        uni.redirectTo({ url: '/packA/pages/address/index?bizOrderNo=' + bizOrderNo.value })
      }, 2000)
    } else {
      clearInterval(state.timeQuestions)
      state.timeQuestions = null
    }
  })
}
</script>

<style lang="scss" scoped>
.wrap {
  min-height: 100vh;

  .payComplete {
    display: inline-block;
    width: calc(100% - 64rpx);
    margin: 32rpx 32rpx 24rpx;
    padding: 24rpx 32rpx;
    border-radius: 16rpx;
    background: #fff;
    color: #222;
    font-size: 32rpx;
    font-weight: 700;

    .img {
      display: inline-block;
      width: 32rpx;
      height: 32rpx;
      margin-right: 16rpx;
      vertical-align: middle;
    }

    .adress {
      display: inline-block;
      vertical-align: middle;
    }
  }

  .commodityWrap {
    margin: 0 32rpx;
    overflow: hidden;
    border-radius: 16rpx;
    background: #fff;

    .title {
      position: relative;
      padding: 24rpx 32rpx;
      color: #222;
      font-size: 32rpx;
      font-weight: 700;

      .border {
        position: absolute;
        top: 50%;
        left: 0;
        width: 8rpx;
        height: 32rpx;
        transform: translateY(-50%);
        background: #316ffe;
      }
    }

    .min {
      padding: 0 32rpx;

      .img {
        display: inline-block;
        width: 136rpx;
        height: 136rpx;
        border-radius: 12rpx;
        vertical-align: top;
      }

      .right {
        display: inline-block;
        width: calc(100% - 160rpx);
        margin-left: 24rpx;
        vertical-align: top;

        .name {
          position: relative;
          width: 100%;
          color: #222;
          font-size: 28rpx;
          font-weight: 700;

          .secondaryContent {
            display: -webkit-box;
            width: calc(100% - 140rpx);
            height: 73rpx;
            overflow: hidden;
            text-overflow: ellipsis;
            -webkit-box-orient: vertical;
            -webkit-line-clamp: 2; /* 定义文本的行数 */
          }

          .num {
            position: absolute;
            top: 0;
            right: 0;
            width: 140rpx;
            color: #ff503d;
            text-align: right;
            white-space: nowrap;
          }

          &.illustrate {
            margin-top: 24rpx;
            color: #999;
            font-size: 24rpx;
            font-weight: 400;

            .secondaryContent {
              width: 100%;
              height: auto;
              -webkit-line-clamp: 1;
            }
          }
        }
      }
    }

    ::v-deep .bottomNum {
      padding: 24rpx 32rpx;
      color: #222;
      font-size: 30rpx;

      .wraps {
        position: relative;
        height: 56rpx;
        line-height: 56rpx;

        .u-number-box {
          position: absolute;
          top: 50%;
          right: 0rpx;
          transform: translateY(-50%);
          border: 1rpx solid #e5e6eb;
          border-radius: 4rpx;

          .u-number-box__minus,
          .u-number-box__input,
          .u-number-box__plus {
            height: 56rpx !important;
            background-color: #fff !important;
          }

          .u-number-box__input {
            width: 80rpx !important;
            margin: 0 !important;
            border-right: 1rpx solid #e5e6eb;
          }

          .u-number-box__minus {
            border-right: 1rpx solid #e5e6eb;

            &.u-number-box__minus--disabled {
              .u-icon__icon {
                color: #cfcfcf !important;
              }
            }
          }

          .u-number-box__plus {
            &.u-number-box__minus--disabled {
              .u-icon__icon {
                color: #cfcfcf !important;
              }
            }
          }
        }
      }
    }

    &.payWay {
      margin-top: 24rpx;
      padding-bottom: 24rpx;

      .payList {
        position: relative;
        margin: 0 32rpx;
        padding: 8rpx 0 32rpx;
        border-bottom: 1rpx solid #e5e6eb;

        .left {
          .img {
            display: inline-block;
            width: 32rpx;
            height: 32rpx;
            vertical-align: middle;
          }

          .adress {
            display: inline-block;
            margin-left: 16rpx;
            color: #222;
            font-size: 32rpx;
            font-weight: 700;
            vertical-align: middle;
          }
        }

        .right {
          display: block;
          position: absolute;
          top: calc(50% - 12rpx);
          right: 0;
          width: 32rpx;
          height: 32rpx;
          transform: translateY(-50%);
        }
      }
    }
  }

  .goPay {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
    background: #fff;

    .wraps {
      position: relative;
      padding: 32rpx 40rpx;

      .left {
        color: #222;
        font-size: 28rpx;
        font-weight: 700;

        .name {
          &:nth-child(2),
          &:nth-child(4) {
            color: #ff503d;
            font-size: 24rpx;
          }

          &:nth-child(3) {
            color: #ff503d;
            font-size: 56rpx;
          }
        }
      }

      .right {
        position: absolute;
        top: 50%;
        right: 32rpx;
        padding: 22rpx 64rpx;
        transform: translateY(-50%);
        border-radius: 44rpx;
        background: #ff503d;
        color: #fff;
        font-size: 32rpx;
      }
    }
  }

  .bg {
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgb(0 0 0 / 50%);
  }

  .bgTwo {
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgb(0 0 0 / 0.1%);
  }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/54670.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

元气日语 Genki-1 第 7 课 家庭照片

家族の写真 课文 I ゆい: これはソラさんの家族の写真ですか。 ソラ: ええ。 ゆい: ソラさんはどれですか。 ソラ: これです。高校の時はめがねをかけていました。 ゆい: かわいいですね。 ソラ: これは父です。ニューヨークの会社で働いています。 ゆい: 背が高…

【Mysql】mysql count主键字段很慢超时 执行计划Select tables optimized away ,最终调整buffer pool问题解决

背景:mysql表 主键字段 count,速度很慢,耗时将近30s从执行计划可以看出:explain SELECT COUNT(rule_id) AS dataCount FROM `sku_safe_stock_rule`; 原理分析:Select tables optimized awaySELECT操作已经优化到不能再优化了 (MySQL根本没有遍历表或索引就返回数据了)由此…

Oracle 19c OCP 082认证考试题库(第6题)- 2024年修正版

【优技教育】Oracle 19c OCP 082题库(第6题)- 2024年修正版 考试科目:1Z0-082 考试题量:90 通过分数:60% 考试时间:150min 本文为(CUUG 原创)整理并解析,转发请注明出处,禁止抄袭及未经注明出处的转载。 原文地址:http://www.cuug.com/index.php?s=/home/article/detai…

08年买的电脑!一样玩《黑神话:悟空》!(影视级画质)

中国PC游戏界迎来了一场“大地震”!备受瞩目的国产3A级游戏《黑神话:悟空》正式全球发售。这款由游戏科学公司开发的动作角色扮演游戏,在研发阶段就吸引了无数目光。根据游戏平台Steam的数据显示,《黑神话:悟空》不仅在中国区,而且在全球范围内都持续占据热销榜首。游戏中…

[MYSQL] MYSQL 优化总结

0 查询变量参数查询某个参数时 select @@…1 数据插入与导入普通插入:采用批量插入(一次插入的数据不建议超过1000条) 手动提交事务 主键顺序插入大批量插入: ​> + 如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令插…

AI加持的开发平台,如何满足您的独一无二?

在数字化浪潮席卷全球的今天,软件开发平台在企业发展中的地位正变得愈发重要。作为技术创新的基石,开发平台已逐渐成为当今时代信息技术进步的中坚力量,更是推动企业技术升级、业务发展的关键所在。 而今,随着人工智能技术的飞速发展,开发平台也再次迎来新的变革。AI的加持…

VulNyx - Mail 靶机

扫描靶机 发现22 和 80端口 访问80端口 发现id=1 和2 时都会有回显dirsearch -u http://http://192.168.200.39访问这个1 和 2的路径 发现竟然和上面那个id=1和id=2的内容相同 这里就可以判断是个include漏洞了用php_filter_chain_generator-main构造伪协议链 执行rce执行反弹…

电科邮件系统短信轰炸

短信轰炸 在该页面下,只有对于学号与验证码的检测实现对于密码的找回,我的想法是对于学号的构造实现短信轰炸。因为学校中的学号构成有规律,所以可以构造不同的学号 ![](C:\Users\21094\Pictures\Screenshots\屏幕截图 2024-08-28 155947.png) 点击下一步后,可以看到该学号…