|
|
@@ -0,0 +1,289 @@
|
|
|
+<template>
|
|
|
+ <view class="code-container">
|
|
|
+ <view class="title center">{{isPayment? "向商家付款":"扫一扫,向我付款"}}</view>
|
|
|
+ <view class="main-content">
|
|
|
+ <view v-if="isPayment">
|
|
|
+ <!-- 占位 -->
|
|
|
+ <view style="height: 50rpx;"></view>
|
|
|
+ <!-- 条形码 -->
|
|
|
+ <view class="bar-code center">
|
|
|
+ <tki-barcode ref="barcode" :val="content" onval=true :opations="barOption" />
|
|
|
+ </view>
|
|
|
+ <!-- 付款码 -->
|
|
|
+ <view class="qr-code center">
|
|
|
+ <tki-qrcode cid="2" ref="qrcode" :val="content" size="300" :onval="true" :loadMake="true"
|
|
|
+ :usingComponents="true" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 收款码 -->
|
|
|
+ <view v-else class="charge-code center">
|
|
|
+ <tki-qrcode cid="1" ref="qrcode-charge" :val="id" :icon="avatar" size="440" :onval="true"
|
|
|
+ :loadMake="true" :usingComponents="true" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="footer center">
|
|
|
+ <text class="text-xl text-bold">{{nickName}}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import tkiQrcode from "tki-qrcode"
|
|
|
+ import tkiBarcode from "@/components/tki-barcode/tki-barcode.vue"
|
|
|
+ import totp from "@/utils/totp.js"
|
|
|
+ export default {
|
|
|
+ components: {
|
|
|
+ tkiBarcode,
|
|
|
+ tkiQrcode
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ content() {
|
|
|
+ let transformStr = this.id
|
|
|
+ return transformStr + this.secret
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ id: '',
|
|
|
+ avatar: "",
|
|
|
+ nickName:'',
|
|
|
+ secret: '000000',
|
|
|
+ isPayment: true,
|
|
|
+ timer: '',
|
|
|
+ timerBillRecords:null,
|
|
|
+ barOption: {
|
|
|
+ width: 3,
|
|
|
+ height: 130,
|
|
|
+ displayValue: false
|
|
|
+ },
|
|
|
+
|
|
|
+ //webSocket
|
|
|
+ connected: false,
|
|
|
+ connecting: false,
|
|
|
+ socketTask: false,
|
|
|
+ msg: false,
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async onLoad(options) {
|
|
|
+ let res = await this.$api.loginUser.detail({
|
|
|
+ id: this.vuex_userId
|
|
|
+ })
|
|
|
+ this.nickName=res.data.nickName
|
|
|
+ // this.avatar =(await this.initAvatat(res.data.avatar)).tempFilePath;
|
|
|
+ //清除缓存
|
|
|
+ await this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
|
|
|
+ //连接websocket
|
|
|
+ this.connect()
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ //获取用户ID
|
|
|
+ this.id = this.vuex_userId
|
|
|
+ //生成动态密码
|
|
|
+ this.refreshCode();
|
|
|
+ },
|
|
|
+ onUnload() {
|
|
|
+ uni.hideLoading()
|
|
|
+ if (this.socketTask && this.socketTask.close) {
|
|
|
+ this.socketTask.close()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ clearInterval(this.timer);
|
|
|
+ clearInterval(this.timerBillRecords);
|
|
|
+ uni.hideLoading()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ refreshCode() {
|
|
|
+ this.timer = setInterval(() => {
|
|
|
+ this.secret = totp.getSecret(this.id);
|
|
|
+ }, 1000)
|
|
|
+ },
|
|
|
+ async initAvatat(url) {
|
|
|
+ return new Promise((reslove, reject) => {
|
|
|
+ uni.downloadFile({
|
|
|
+ url,
|
|
|
+ success: (res) => {
|
|
|
+ reslove(res);
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ reject(err)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ async queryBillRecords(){
|
|
|
+ let resp=await this.$api.loginUser.getBillrecordFromRedis({userId:this.vuex_userId})
|
|
|
+ if (this.$isEmpty(resp.data)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (resp.data.realPayAmount>0) {
|
|
|
+ //清除轮询
|
|
|
+ clearInterval(this.timerBillRecords)
|
|
|
+ //关闭通讯
|
|
|
+ this.close()
|
|
|
+ //去支付
|
|
|
+ let params={
|
|
|
+ orderType:this.$global.orderType.USER_PAY,
|
|
|
+ orderId:resp.data.id,
|
|
|
+ payStatus:this.$global.payStatus.IS_WAIT
|
|
|
+ }
|
|
|
+ let res=await this.$api.pay.payOrder(params)
|
|
|
+ if (!this.$isEmpty(res.data.prePayTn)) {
|
|
|
+ let prePayTn= JSON.parse(res.data.prePayTn)
|
|
|
+ this.$mpi.requestPayment(prePayTn).then(()=>{
|
|
|
+ //通知商户端付款成功
|
|
|
+ this.sendInfo(resp.data)
|
|
|
+ this.$dialog.showModal('支付成功',false).then(()=>{
|
|
|
+ this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
|
|
|
+ uni.navigateBack({
|
|
|
+ delta:1
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }).catch(err=>{
|
|
|
+ this.$dialog.showModal('支付失败',false).then(()=>{
|
|
|
+ this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
|
|
|
+ uni.navigateBack({
|
|
|
+ delta:1
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$dialog.showModal('支付失败',false).then(()=>{
|
|
|
+ this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
|
|
|
+ uni.navigateBack({
|
|
|
+ delta:1
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ connect() {
|
|
|
+ if (this.connected || this.connecting) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ this.connecting = true
|
|
|
+ this.socketTask = uni.connectSocket({
|
|
|
+ url: this.$global.WebSocketUrl+this.vuex_userId,
|
|
|
+ // #ifdef MP
|
|
|
+ header: {
|
|
|
+ 'content-type': 'application/json'
|
|
|
+ },
|
|
|
+ // #endif
|
|
|
+ // #ifdef MP-WEIXIN
|
|
|
+ method: 'GET',
|
|
|
+ // #endif
|
|
|
+ success(res) {
|
|
|
+ console.log(res);
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log(err);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.socketTask.onOpen((res) => {
|
|
|
+ this.connecting = false
|
|
|
+ this.connected = true
|
|
|
+ console.log('onOpen', res);
|
|
|
+ //连接成功,清除轮询
|
|
|
+ clearInterval(this.timerBillRecords)
|
|
|
+ })
|
|
|
+ this.socketTask.onError((err) => {
|
|
|
+ this.connecting = false
|
|
|
+ this.connected = false
|
|
|
+ //连接失败就轮询查询订单
|
|
|
+ this.timerBillRecords = setInterval(this.queryBillRecords,5000);
|
|
|
+ })
|
|
|
+ this.socketTask.onMessage((res) => {
|
|
|
+ this.msg= JSON.parse(res.data)
|
|
|
+ if (this.msg.content==this.$global.socketMessage.payForPaymentCode) {
|
|
|
+ this.queryBillRecords()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.socketTask.onClose((res) => {
|
|
|
+ this.connected = false
|
|
|
+ this.socketTask = false
|
|
|
+ this.msg = false
|
|
|
+ console.log('onClose', res)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ send(data) {
|
|
|
+ this.socketTask.send({
|
|
|
+ data: JSON.stringify(data),
|
|
|
+ success(res) {
|
|
|
+ console.log(res);
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log(err);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ close() {
|
|
|
+ if (this.socketTask && this.socketTask.close) {
|
|
|
+ this.socketTask.close()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ sendInfo(data){
|
|
|
+ let msg={
|
|
|
+ sid:data.shopId,
|
|
|
+ content:"账户到账"+data.payAmount,
|
|
|
+ }
|
|
|
+ this.$api.webSocket.sendInfo(msg)
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+ page {
|
|
|
+ background-color: #18b566;
|
|
|
+ }
|
|
|
+</style>
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .code-container {
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ min-height: 800rpx;
|
|
|
+ margin: 60rpx 20rpx;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ border-radius: 25rpx 25rpx 0 0;
|
|
|
+ height: 100rpx;
|
|
|
+ width: 100%;
|
|
|
+ font-size: 35rpx;
|
|
|
+ color: #18b566;
|
|
|
+ background-color: #F7F7F7;
|
|
|
+ font-weight: 600;
|
|
|
+ letter-spacing: 3rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer {
|
|
|
+ width: 90%;
|
|
|
+ height: 160rpx;
|
|
|
+ margin-left: 5%;
|
|
|
+ border-top: 1rpx dashed #dddddd;
|
|
|
+ }
|
|
|
+
|
|
|
+ .main-content {
|
|
|
+ width: 100%;
|
|
|
+ height: 600rpx;
|
|
|
+ scroll-margin-top: 600rpx;
|
|
|
+
|
|
|
+ // overflow: hidden;
|
|
|
+ .bar-code {
|
|
|
+ margin-left: 5%;
|
|
|
+ width: 90%;
|
|
|
+ height: 150rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .qr-code {
|
|
|
+ width: 100%;
|
|
|
+ height: 450rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .charge-code {
|
|
|
+ width: 100%;
|
|
|
+ height: 600rpx;
|
|
|
+ transition: transform 1s ease-in-out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|