全网最详细实现微信小程序支付功能【前端部分】

功能描述:

用户点击立即购买后进入确认订单页面,在此页面可选择商品数量,是否使用优惠券,以及一些简单的个人信息填写,点击支付输入密码则支付成功,如果点击支付后没有付款关闭了页面会跳转到待支付页面并开始倒计时(待支付页面显示该商品适用的店铺信息及个人信息订单信息等),倒计时结束后未支付则订单失效如需购买需要重新下单

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

准备工作

申请微信支付接口权限

微信小程序管理后台 -> 微信支付->接入微信支付 及关联(设置)商户信息

在这里插入图片描述
如果是第一次接入, 直接申请接入,然后选择弹出窗口的"我还没有商户号"选项接入即可

微信支付api需要的参数说明

在这里插入图片描述

示例代码
wx.requestPayment({
  timeStamp: '',
  nonceStr: '',
  package: '',
  signType: 'MD5',
  paySign: '',
  success (res) { },
  fail (res) { }
})

需要传入后端接口的参数说明:

在这里插入图片描述

接口返回的参数说明:

在这里插入图片描述

支付逻辑代码(只包含支付功能)

goPay () {
//在控制台输出'goPay'
console.log('goPay');

//检查使用人姓名是否填写,如果未填写则弹出提示并返回false
if(!this.reserved_name){ uni.showToast({title:"使用人姓名未填写",icon:"none"}); return false;}

//检查使用人手机号是否填写,如果未填写则弹出提示并返回false
if(!this.reserved_phone){ uni.showToast({title:"使用人手机号未填写",icon:"none"}); return false;}

//定义一个正则表达式,用于验证手机号格式
const reg = /^1[3|4|5|7|8|6|9][0-9]d{8}$/;

//检查手机号格式是否正确,如果不正确则弹出提示并返回false
if(!reg.test(this.reserved_phone)){ uni.showToast({title:"手机格式错误",icon:"none"}); return false;}

//检查是否同意协议,如果未同意则弹出提示并返回false
if(!this.isChecked){ uni.showToast({title:"请同意协议后购买",icon:"none"}); return false;}

//向服务器发送下单请求
uni.request({
	url: app.globalData.URL + "localLive/createStoreGoodsOrder",
	method: 'POST',
	data: {
		version:'251',
		client:'wxmp',
		count: this.spnumber,
		reserved_name: this.reserved_name,
		reserved_phone: this.reserved_phone,
		reserved_remark: this.reserved_remark,
		spec_id: this.specId,
		store_discount_code: this.store_discount_code,
		store_goods_id: this.goodsId,
		token:this.token.token, 
		//openid:''
	},
	success(res) {
		//如果下单失败,则弹出提示并返回false
		if(res.data.status=='no'){
			uni.showToast({title:res.data.msg,icon:"none"});
			return false;
		}
		
		//如果不需要支付,则跳转到订单详情页面并返回false
		if(res.data.data.is_need_pay==0){
			uni.redirectTo({
				url:'./localLifeOrderDetail?store_order_id='+res.data.data.goods_order_id
			})
			return false ;
		}else{
			//如果需要支付,则调用微信支付接口
			uni.requestPayment({
			    provider: 'wxpay',
			    timeStamp: res.data.data.pay_data.timeStamp,
			    nonceStr:  res.data.data.pay_data.nonceStr,
			    package:  res.data.data.pay_data.package,
			    signType: 'MD5',
			    paySign:  res.data.data.pay_data.paySign,
				appId:app.globalData.appid,
			    success: function (ress) {
					//支付成功后弹出提示,并在2秒后跳转到订单详情页面
					uni.showToast({
					    title: '支付成功',
					    duration: 2000
					});	
					setTimeout(function() {
						uni.redirectTo({
							url:'./localLifeOrderDetail?store_order_id='+res.data.data.store_order_id
						}) 
					}, 2000)
			    },
			    fail: function (err) {
					//支付失败后直接跳转到订单详情页面
			      uni.redirectTo({
			      	url:'./localLifeOrderDetail?store_order_id='+res.data.data.store_order_id
			      }) 
			    }
			});
		}
		
		//在控制台输出服务器返回的数据和请求的接口名称
		console.log(res.data,'createStoreGoodsOrder');	
	}
})

/* uni.navigateTo({
	url:'./localLifeOrderDetail?store_order_id='+
}) */
},

以下是功能完整代码

确认订单页面

结构部分
<template>
	<view class="container">
		<view class="spContainer">
			<view class="spInfo">
				<view class="spDetail">
					<view class="spImg" :style="{ backgroundImage: `url(${spImg})` }">
					</view>
					<view class="spCon">
						<view class="spName">{{GoodsInfo.specification_name}}</view>
						<view class="spIntro" v-if="goods.goods_desc!=null">{{goods.goods_desc}}</view>
					</view>
				</view>
				<view class="buyNum clearfix">
					<view class="titname fl">购买数量</view>
					<view class="spbuyNum fr">
						<text class="jian" @click="btnReduce">-</text>
						<text class="spnumber">{{spnumber}}</text>
						<text class="jia" @click="btnAdd">+</text>
					</view>
				</view>
				<view class="buyNum coupon clearfix">
					<view class="titname fl">优 惠 券</view>
					<view class="titleInfo fr" v-if="discouponNum > 0" @click="useCouponList">
						<view v-if="coupon_id" class="amountprice">-{{amount/100}}</view>
						<view class="isCanuse" v-else>{{discouponNum}}张可用</view>
						<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/common/arr1.png" mode=""></image>
					</view>
					<view class="titleInfo fr" v-else  @click="useCouponList">
						<view class="nocoupon">暂无优惠券可用</view>
						<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/common/arr1.png" mode=""></image>
					</view>
				</view>
				<view class="allPrice clearfix">
					<view class="titname fl">总  价</view>
					<view class="price fr">¥ <text>{{(price-(amount))/100}}</text></view>
				</view>
			</view>
			<view class="userInfo">
				<view class="title">使用人信息</view>
				<view class="list">
					<view class="listCon">
						<view class="titleName">姓名</view>
						<view class="titleInput">
							<input type="text" v-model="reserved_name"  placeholder="请输入姓名">
						</view>
					</view>
					<view class="listCon">
						<view class="titleName">手机号码</view>
						<view class="titleInput">
							<input type="text" v-model="reserved_phone"   placeholder="请输入手机号码">
						</view>
					</view>
					<view class="listCon">
						<view class="titleName">备注</view>
						<view class="titleInput">
							<input type="text" v-model="reserved_remark"  placeholder="请输入备注(非必填)">
						</view>
					</view>
				</view>
			</view>
			<view class="submitTips">
				<!-- <view :class="['ischecked', isChecked? 'active': '']" @click="isChecked =!isChecked"></view>
				<view class="tips">提交订单则表示您同意<navigator url="/pages/localLife/localLifeIsagress" class="link">《平台用户服务协议》</navigator>
				</view> -->
			</view>
			<view class="mealTips" style="margin-top: 20rpx;">此套餐为限时限量购买产品,为了避免资源浪费,请您在有效期内及时使用,逾期自动作废。</view>
		</view>

		<view class="bottom oncePay">
			<view class="content">
				<view class="finallyPrice">实付金额:<text>¥{{(price-(amount))/100}}</text></view>
				<view class="goPay" @click="goPay">去支付</view>
			</view>
		</view>
	</view>
</template>
逻辑部分(内涵详细注释)
<script>
//引入全局变量app
let app = getApp()

//导出一个默认的对象
export default {
	
	//定义data属性
	data() {
		return {
			spImg: '', //商品图片
			discouponNum: 0, //可用优惠券数量
			isChecked: true, //是否同意协议
			goodsId:0, //商品ID
			specId:0, //规格ID
			GoodsInfo:[], //商品信息
			goods:[], //商品列表
			spnumber:1, //购买数量
			price:0, //价格
			vip_price:0, //会员价
			token:{}, //用户token
			reserved_name:null, //预定人姓名
			reserved_phone:null, //预定人手机号
			store_discount_code:null, //商家折扣码
			coupon_id:0, //优惠券ID
			code:'', //优惠券码
			amount:0, //优惠金额
			not_length:'' //未使用优惠券数量
			
			//userInfo:{}
		}
	},
	
	//页面加载时执行的函数
	onLoad(e) {
		this.goodsId=e.goodsId //获取商品ID
		this.specId = e.specId; //获取规格ID
		this.token=	uni.getStorageSync('token'); //获取用户token
		this.reserved_phone=uni.getStorageSync('userInfo').mobile; //获取用户手机号
		this.reserved_name=uni.getStorageSync('userInfo').nickname; //获取用户昵称
		this.getspDetail(); //获取商品详情
		this.getUsableStoreDiscountList(); //获取可用优惠券列表
	},
	
	//页面显示时执行的函数
	onShow() {
		let that = this;
		
		//监听up_coupon事件,获取优惠券信息
		uni.$on('up_coupon',function(data){ 
			console.log(data.amount);
			   
			that.coupon_id=data.coupon_id;
			that.store_discount_code=data.code;			
			that.amount=data.amount;
			
			console.log('监听到事件来自 up_coupon ,携带参数 msg 为:' + data);
		})
	},
	
	//页面挂载时执行的函数
	mounted() {},
	
	//定义方法
	methods: {
		
		//支付函数
		goPay () {
			console.log('goPay');
			
			//检查预定人姓名是否填写,如果未填写则弹出提示并返回false
			if(!this.reserved_name){ uni.showToast({title:"使用人姓名未填写",icon:"none"}); return false;}
			
			//检查预定人手机号是否填写,如果未填写则弹出提示并返回false
			if(!this.reserved_phone){ uni.showToast({title:"使用人手机号未填写",icon:"none"}); return false;}
			
			//定义一个正则表达式,用于验证手机号格式
			const reg = /^1[3|4|5|7|8|6|9][0-9]d{8}$/;
			
			//检查手机号格式是否正确,如果不正确则弹出提示并返回false
			if(!reg.test(this.reserved_phone)){ uni.showToast({title:"手机格式错误",icon:"none"}); return false;} 
			
			//检查是否同意协议,如果未同意则弹出提示并返回false
			if(!this.isChecked){ uni.showToast({title:"请同意后购买",icon:"none"}); return false;}
			
			//向服务器发送下单请求
			uni.request({
				url: app.globalData.URL + "localLive/createStoreGoodsOrder",
					method: 'POST',
					data: {
						version:'251',
						client:'wxmp',
						count: this.spnumber,
						reserved_name: this.reserved_name,
						reserved_phone: this.reserved_phone,
						reserved_remark: this.reserved_remark,
						spec_id: this.specId,
						store_discount_code: this.store_discount_code,
						store_goods_id: this.goodsId,
						token:this.token.token, 
						
						//openid:''
					},
					success(res) {
						//如果下单失败,则弹出提示并返回false
						if(res.data.status=='no'){
						//弹出下单失败的提示
							uni.showToast({title:res.data.msg,icon:"none"});
							return false;
							}

						//如果不需要支付,则跳转到订单详情页并返回false
						if(res.data.data.is_need_pay==0){
							uni.redirectTo({
								url:'./localLifeOrderDetail?store_order_id='+res.data.data.goods_order_id
							})
							return false ;
						}else{
							
							//否则,调用微信支付接口进行支付
							uni.requestPayment({
							    provider: 'wxpay',
							    timeStamp: res.data.data.pay_data.timeStamp,
							    nonceStr:  res.data.data.pay_data.nonceStr,
							    package:  res.data.data.pay_data.package,
							    signType: 'MD5',
							    paySign:  res.data.data.pay_data.paySign,
								appId:app.globalData.appid,
							    success: function (ress) {
								//支付成功后,弹出提示并在2秒后跳转到订单详情页
								uni.showToast({
								    title: '成功',
								    duration: 2000
								});	
								setTimeout(function() {
								uni.redirectTo({
									url:'./localLifeOrderDetail?store_order_id='+res.data.data.store_order_id
								}) 
								}, 2000)
							    },
							    fail: function (err) {
							      //支付失败后,直接跳转到订单详情页
							      uni.redirectTo({
							      	url:'./localLifeOrderDetail?store_order_id='+res.data.data.store_order_id
							      }) 
							    }
							});
						}					
						
						console.log(res.data,'createStoreGoodsOrder');	
					}
			})
		},
		
		//获取商品详情函数
		async getspDetail () {
			let that = this;
			
			//向服务器发送获取商品详情的请求
			uni.request({
				url: app.globalData.URL + "localLive/getStoreGoodsInfo",
				method: 'POST',
				data: {
					version:'251',
					client:'wxmp',
					store_goods_id:this.goodsId
				},
				success(res) {
					
					//将商品信息保存到goods属性中
					that.goods=res.data.data;
					
					//将商品图片保存到spImg属性中
					var spimgList = that.goods.picture.split(',')
					that.spImg = spimgList[0]
					
					//将商品最大购买数量保存到daily_max_num属性中
					that.daily_max_num=that.goods.max_num;
					
					//遍历商品规格列表,找到与当前规格ID相同的规格,并将其保存到GoodsInfo属性中
					for(var i = 0; i <res.data.data.goods_spec.length; i++) {			
						if(res.data.data.goods_spec[i].id==that.specId){
							that.GoodsInfo=	res.data.data.goods_spec[i];
							that.price=res.data.data.goods_spec[i].vip_price;
							that.vip_price=res.data.data.goods_spec[i].vip_price;
							break;
						}
					}
			  		 
			  	}
			})
		},
		
		//获取可用优惠券列表函数
		async getUsableStoreDiscountList () {
			let that = this;
			
			//向服务器发送获取可用优惠券列表的请求
			uni.request({
				url: app.globalData.URL + "localLive/getUsableStoreDiscountList",
				method: 'POST',
				data: {
					version:'251',
					client:'wxmp',
					spec_id:this.specId,
					token:this.token.token,
					count:this.spnumber
				},
				success(res) {
					//将可用优惠券数量保存到discouponNum属性中
					that.discouponNum=res.data.data.usable_discount_count;
					//console.log(res.data.data,'getUsableStoreDiscountList');
				}
			})
		},
		
		//减少购买数量函数
		btnReduce(){
			if(this.spnumber!=1){
				this.spnumber= this.spnumber-1;
				this.sum_price();
				this.getUsableStoreDiscountList();
			}				 
		},
		
		//增加购买数量函数
		btnAdd(){
			//如果已达到商品最大购买数量,则弹出提示并返回false
			if( this.daily_max_num==this.spnumber){
				uni.showToast({title:"该宝物每日限购"+this.daily_max_num+"件",icon:"none"});
			return false;
			}

			//否则,增加购买数量并重新计算价格和可用优惠券数量
			this.spnumber= this.spnumber+1;
			this.sum_price();
			this.getUsableStoreDiscountList();
		},
		
		//计算价格函数
		sum_price(){
			this.price=this.vip_price*this.spnumber;
		},
		
		//选择优惠券函数
		selectCoupon(){
			//如果没有可用优惠券,则弹出提示并返回false
			if(this.discouponNum==0){
				uni.showToast({title:"暂无可用优惠券",icon:"none"});
				return false;
			}
			
			//否则,跳转到优惠券列表页
			uni.navigateTo({
				url:'./couponList?spec_id='+this.specId+'&count='+this.spnumber
			})
		},
		
		//同意协议函数
		checkChange(e){
			this.isChecked=e.detail.value.length>0;
		}
	}
}
</script>
样式部分
<style lang="scss" scoped>
	.container {
		width: 100%;
	}

	.spContainer {
		padding: 40rpx 36rpx;
        padding-bottom: 200rpx;
		.spInfo {
			background: #FFFFFF;
			box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.07);
			border-radius: 24rpx;
			padding: 40rpx 28rpx;
			padding-bottom: 10rpx;

			.spDetail {
				display: flex;

				.spImg {
					width: 160rpx;
					height: 160rpx;
					background-size: cover;
					background-repeat: no-repeat;
					background-position: center;
					border-radius: 8rpx;
					margin-right: 30rpx;
				}

				.spCon {
					flex: 1;
					overflow: hidden;

					.spName {
						overflow: hidden;
						text-overflow: ellipsis;
						display: -webkit-box;
						-webkit-line-clamp: 2;
						line-clamp: 2;
						-webkit-box-orient: vertical;
						text-overflow: -o-ellipsis-lastline;
						font-size: 28rpx;
						color: #333333;
						line-height: 36rpx;
						font-weight: 600;
						padding-top: 4rpx;
					}

					.spIntro {
						padding-top: 18rpx;
						overflow: hidden;
						text-overflow: ellipsis;
						display: -webkit-box;
						-webkit-line-clamp: 2;
						line-clamp: 2;
						-webkit-box-orient: vertical;
						text-overflow: -o-ellipsis-lastline;
						font-size: 24rpx;
						color: #999999;
						line-height: 34rpx;
					}
				}
			}

			.buyNum {
				height: 100rpx;
				line-height: 100rpx;
				border-bottom: 2rpx solid #F0F0F0;

				.titname {
					font-size: 32rpx;
					color: #999999;
				}

				.spbuyNum {
					height: 100rpx;

					.jian {
						width: 32rpx;
						height: 32rpx;
						background-color: #EFF2F4;
						display: inline-block;
						text-align: center;
						line-height: 32rpx;
						border-radius: 50%;
						position: relative;
						vertical-align: middle;
						font-size: 20rpx;
						font-weight: 600;
					}

					.jia {
						width: 32rpx;
						height: 32rpx;
						background-color: #EFF2F4;
						display: inline-block;
						text-align: center;
						line-height: 32rpx;
						border-radius: 50%;
						position: relative;
						vertical-align: middle;
						font-size: 20rpx;
						font-weight: 600;
					}

					.spnumber {
						font-size: 32rpx;
						color: #333333;
						padding: 0 20rpx;
						vertical-align: middle;
					}

					input {
						width: 80rpx;
						height: 60rpx;
						margin: 0;
						padding: 0;
						border: none;
						display: inline-block;
						text-align: center;
						vertical-align: middle;
					}
				}
			}

			.coupon {
				.titleInfo {
					.amountprice {
						display: inline-block;
						font-size: 28rpx;
						color: #F8C85D;
						line-height: 40rpx;
					}

					.isCanuse {
						display: inline-block;
						padding: 0 24rpx;
						height: 40rpx;
						line-height: 40rpx;
						background: #FF6403;
						border-radius: 8rpx;
						font-size: 24rpx;
						color: #FFFFFF;
					}

					.nocoupon {
						font-size: 28rpx;
						color: #999999;
						display: inline-block;
						height: 40rpx;
						line-height: 40rpx;
					}

					image {
						width: 11rpx;
						height: 20rpx;
						margin-left: 6rpx;
					}
				}
			}

			.allPrice {
				height: 100rpx;
				line-height: 100rpx;

				.titname {
					font-size: 32rpx;
					color: #999999;
				}

				.price {
					font-size: 24rpx;
					color: #F8C85D;

					text {
						font-size: 36rpx;
						color: #F8C85D;
					}
				}
			}
		}

		.userInfo {
			margin-top: 40rpx;
			background: #FFFFFF;
			box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.07);
			border-radius: 24rpx;
			padding: 0 30rpx;
			padding-top: 40rpx;

			.title {
				font-size: 32rpx;
				color: #333333;
				font-weight: 600;
			}

			.list {

				.listCon {
					height: 96rpx;
					line-height: 96rpx;
					border-bottom: 2rpx solid #F0F0F0;
					display: flex;

					.titleName {
						font-size: 32rpx;
						color: #333333;
						width: 188rpx;
					}

					.titleInput {
						flex: 1;

						input {
							height: 96rpx;
							line-height: 96rpx;
							color: #333333;
							margin: 0;
							padding: 0;
							border: none;
							font-size: 28rpx;
						}
					}
				}

				.listCon:last-of-type {
					border: none;
					height: 110rpx;
					line-height: 110rpx;
				}
			}
		}

		.submitTips {
			.ischecked {
				display: inline-block;
				width: 30rpx;
				height: 30rpx;
				border: 2rpx solid #D0D0D0;
				border-radius: 50%;
				vertical-align: middle;
			}

			.ischecked.active {
				border: none;
				background: linear-gradient(75deg, #6F9A45 0%, #B4DC8E 100%);
				position: relative;
			}

			.ischecked.active::after {
				content: '';
				position: absolute;
				left: 50%;
				top: 50%;
				transform: translate(-50%, -50%);
				width: 20rpx;
				height: 14rpx;
				background: url('https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/iconright.png') no-repeat center;
				background-size: 20rpx 14rpx;
			}

			.tips {
				display: inline-block;
				line-height: 88rpx;
				font-size: 22rpx;
				color: #333333;
				margin-left: 12rpx;

				.link {
					color: #007AFF;
					display: inline-block;
				}
			}
		}

		.mealTips {
			font-size: 22rpx;
			color: #999999;
			line-height: 32rpx;
		}
	}

	.bottom {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		background: #FFFFFF;
		box-shadow: 0rpx -4rpx 22rpx 0rpx rgba(0, 0, 0, 0.07);
		.content {
			padding: 16rpx 36rpx;
			display: flex;
			.finallyPrice {
				font-size: 24rpx;
				color: #333333;
				height: 88rpx;
				line-height: 88rpx;
				flex: 1;
				overflow: hidden;
				text-overflow: ellipsis;
				white-space: nowrap;
				padding-right: 20rpx;

				text {
					color: #F8C85D;
					font-size: 36rpx;
				}
			}

			.goPay {
				padding: 0 134rpx;
				height: 88rpx;
				line-height: 88rpx;
				text-align: center;
				background: #D8D8D8 linear-gradient(75deg, #6F9A45 0%, #B4DC8E 100%);
				border-radius: 20rpx;
				font-size: 28rpx;
				color: #FFFFFF;
			}
		}

	}
</style>

优惠券页面

<template>
	<view class="container">
		<view class="changeNum" >
			<input type="text" placeholder="请输入兑换码" v-model="localChangeNum" />
			<text @click="getLocalCouponNumList" :class="[localChangeNum ? 'active': '']">兑换</text>
		</view>
		<view class="canUse couponList">
			<view class="title">可使用红包</view>
			<view class="list">
				<view :class="{active:currentIndex == i}" v-for="(item, i) in usable_discount_arr" :key="i"
					class="listCon">
					<view class="link">
						<view class="couponWap">
							<view class="couponDetail">
								<view class="couponName">{{item.discount_title}}</view>
								<view class="couponTime">有效期至{{item.end_time}}</view>
							</view>
							<view class="couponNum">
								<view class="couponPrice"><text>{{item.amount/100}}</text></view>
								<view class="coupontip">{{item.suffice_amount/100}}可用</view>
							</view>
							<view class="noselect"     @click="selectCoupon(item.id, item.code, item.amount)">
								<text :class="{back:coupon_id==item.id}"></text>
								</view>
						</view>
						<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/line.png" mode="" class="line"></image>
						<view class="tips">
							<view class="tipsName">仅限<text class="tipstus">商品分类:</text><text>{{item.goods_or_category_name}}</text>使用
							</view>
<!-- 							<view class="tipsName">仅限<text class="tipstus"> 多品:</text><text>《满55元减5元》</text>使用
							</view>
							<view class="tipsName">仅限<text class="tipstus">商品分类:</text><text>《满55元减5元》</text>使用
							</view>
							<view class="tipsName" v-else></view> -->
						</view>
					</view>
				</view>
			</view>
			<!-- <view class="nodata">暂无可使用红包</view> -->
		</view>
		<view class="nocanUse couponList">
			<view class="title" >不可使用红包</view>
			<view class="list">
				<view v-for="(item, i) in not_usable_discount_arr" :key="i" class="listCon">
					<view class="link">
						<view class="couponWap">
							<view class="couponDetail">
								<view class="couponName nocanUse">{{item.discount_title}}</view>
								<view class="couponTime nocanUse">有效期至{{item.end_time}}</view>
							</view>
							<view class="couponNum">
								<view class="couponPrice"><text>{{item.amount/100}}</text></view>
								<view class="coupontip">{{item.suffice_amount/100}}可用</view>
							</view>
							<view class="noselect nocanUse"><text></text></view>
						</view>
						<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/line.png" mode="" class="line"></image>
						<view class="tips">
							<view class="tipsName nocanUse" v-if="item.send_type && item.type == 1">仅限<text class="tipstus">单品:</text><text>{{item.goods_or_category_name}}</text>使用
							</view>
							<view class="tipsName" v-else-if="item.send_type == 1 && item.type == 2">仅限<text
									class="tipstus"> 多品:</text><text
									v-if="item.goods_or_category_name">{{ item.goods_or_category_name }}</text>使用
							</view>
							<view class="tipsName" v-else-if="item.send_type == 2">仅限<text class="tipstus">
									商品分类:</text><text
									v-if="item.goods_or_category_name">{{ item.goods_or_category_name }}</text>使用
							</view>
							
							
<!-- 							<view class="tipsName">仅限<text class="tipstus"> 多品:</text><text>《满55元减5元》</text>使用
							</view>
							<view class="tipsName">仅限<text class="tipstus">商品分类:</text><text>《满55元减5元》</text>使用
							</view>
							<view class="tipsName" v-else></view> -->
						</view>
					</view>
				</view>
			</view>
			<view class="nodata" v-if="not_usable_discount_arr.length==0">暂无不可使用红包</view>
		</view>
		<view class="confirmuse" @click="confirmUse">确认使用</view>
	</view>
</template>
<script>
	let app = getApp();
	export default {
		data() {
			return {
				canUseCouponList: [1, 2, 3],
				specId:0,
				token:[],
				spnumber:0,
				not_usable_discount_arr:[],
				usable_discount_arr:[],
				coupon_id:0,
				code:'',
				amount:'',
				not_length:'',
				localChangeNum:null
			}
		},
		onLoad(e) {
			this.token=	uni.getStorageSync('token');
			this.specId=e.specId;
			this.spnumber=e.spnumber;
			this.getUsableStoreDiscountList ();
		},
		onShow() {},
		mounted() {},
		methods: {
			async selectCoupon(id,code,amount){
				this.coupon_id=id;
				this.code=code;			
				this.amount=amount;
			},
			async getUsableStoreDiscountList () {
							    let that = this;
								uni.request({
									url: app.globalData.URL + "localLive/getUsableStoreDiscountList",
										method: 'POST',
										data: {
											version:'251',
											client:'wxmp',
											spec_id:this.specId,
											token:this.token.token,
											count:this.spnumber
										},
										success(res) {
											that.discouponNum=res.data.data.usable_discount_count;
											that.not_usable_discount_arr=res.data.data.not_usable_discount_arr;
											that.usable_discount_arr=res.data.data.usable_discount_arr;
											//
											that.coupon_id=that.usable_discount_arr[0].id,
											that.code=that.usable_discount_arr[0].code,
											that.amount=that.usable_discount_arr[0].amount,
											that.not_length=that.not_usable_discount_arr.length;
											
									//	console.log(res.data.data,'getUsableStoreDiscountList');
									}
										})
			},
			async confirmUse(){ //当前选择的优惠券
				
				uni.$emit('up_coupon', {
					msg: '选择了优惠券',
					coupon_id:this.coupon_id,
					code:this.code,
					amount:this.amount,
					
				})
				
				uni.navigateBack();
			},
			// 兑换本地生活
			async getLocalCouponNumList () {
			  if (!this.localChangeNum) {
				setTimeout(()=> {
				   uni.showToast({title:'请输入优惠券兑换码',duration: 2000, icon:'none'});
				},0)
				return false
			  }
			  const res = await this.$request.post('localLive/redeemStoreGoodsCode',{token: this.token.token, code: this.localChangeNum}, {
					native: true
				})
				var data = res.data.data.data          
				if (res.data.status == 'ok') {
				  // 提示兑换成功,刷新优惠券列表 
				  setTimeout(()=> {
				     uni.showToast({title:'兑换成功',duration: 2000, icon:'none'});
				  },0)
				  this.localChangeNum = ''
				  this.page = 1
				  this.isEndflag = false
				  this.localCouponsList = []
				  this.getUsableStoreDiscountList()          
				}else {
				   setTimeout(()=> {
				      uni.showToast({title: res.data.msg, duration: 2000, icon:'none'});
				   },0)
				}
			},
			
		},
	}
</script>

<style lang="scss" scoped>
	.changeNum {
		height: 72rpx;
		/* position: fixed;
		top: 175rpx;
		left: 32rpx;
		right: 32rpx;
		z-index: 999; */
		margin-top: 20px;
		display: flex;
	    padding-bottom: 10rpx;
		background-color: #F7F7F7;
		input {
			flex: 1;
			height: 72rpx;
			background: #FFFFFF;
			border-radius: 2rpx;
			border: 2rpx solid #F0F0F0;
			padding: 0;
			margin: 0;
			padding: 0 22rpx;
			color: #333333;
			font-size: 28rpx;
		}
	
		text {
			padding: 0 46rpx;
			height: 72rpx;
			line-height: 72rpx;
			background: #D9D9D9;
			border-radius: 2rpx;
			margin-left: 22rpx;
			color: #333333;
			font-size: 28rpx;
			line-height: 72rpx;
		}
	
		text.active {
			background-color: #FF6403;
			color: #FFFFFF;
		}
	
	}
	
	
	
	.back{
		background: #7FA955;
	}
	
	.container {
		padding: 0 36rpx;
        padding-bottom: 180rpx;
		.couponList {
			.title {
				height: 116rpx;
				line-height: 116rpx;
				color: #333333;
				font-size: 32rpx;
				font-weight: 600;
			}

			.list {
				width: 100%;

				.listCon {
					width: 100%;
					margin-bottom: 16rpx;
					position: relative;
					border-radius: 10rpx;

					.link {
						.couponWap {
							background-color: #FFFFFF;
							padding: 0 40rpx;
							display: flex;
							border-radius: 10rpx 10rpx 0 0;
							.couponDetail {
								flex: 1;
								overflow: hidden;
								padding-top: 24rpx;

								.couponName {
									font-size: 32rpx;
									font-weight: 600;
									color: #333333;
									height: 44rpx;
									line-height: 44rpx;
									width: 100%;
									white-space: nowrap;
									overflow: hidden;
									text-overflow: ellipsis;
								}
                                
								.couponName.nocanUse {
									color: #999999;
								}
								.couponTime {
									padding-top: 16rpx;
									font-size: 24rpx;
									color: #666666;
									line-height: 34rpx;
								}
								.couponTime.nocanUse {
									color: #999999;
								}
							}

							.couponNum {
								.couponPrice {
									font-size: 32rpx;
									font-weight: 600;
									color: #FF6403;
									line-height: 84rpx;
									text-align: right;

									text {
										font-size: 60rpx;
									}
								}

								.coupontip {
									font-size: 24rpx;
									color: #FF6403;
									line-height: 34rpx;
								}
							}
							
							.noselect {
								color: #FF6403;
								font-size: 24rpx;
								padding-top: 40rpx;
								text-align: right;
                                 margin-left: 40rpx;
								text {
									width: 40rpx;
									height: 40rpx;
									border: 2rpx solid #E5E5E5;
									display: inline-block;
									border-radius: 50%;
									position: relative;
								}
								text:after {
								  content: '';
								  position: absolute;
								  left: 50%;
								  top: 50%;
								  transform: translate(-50%, -50%);
								  width: 24rpx;
								  height: 16rpx;
								  background: url("https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/iconright.png") no-repeat center;
								  background-size: 24rpx 16rpx;
								}
							}
							.noselect.nocanUse text {
								width: 40rpx;
								height: 40rpx;
								background: #E5E5E5;
								border: 2rpx solid #E5E5E5;
							}
							.noselect.nocanUse text:after {
								width: 0;
							}
						}

						.line {
							width: 100%;
							height: 42rpx;
							display: block;
						}
						.tips {
						    padding: 0 40rpx;
							background-color: #FFFFFF;
							border-radius: 0 0 10rpx 10rpx;
							padding-bottom: 24rpx;
							.tipsName {
								height: 40rpx;
								line-height: 40rpx;
								font-size: 20rpx;
								color: #999999;
								width: 100%;
								white-space: nowrap;
								overflow: hidden;
								text-overflow: ellipsis;
								text {
									
								}
								.tipstus {
									
								}
							}
						}
					}
				}
			}
		}
	
	}
	
	.nodata {
		  text-align: center;
		  color: #666666;
		  font-size: 24rpx;
	}
	
	.confirmuse {
		  height: 80rpx;
		  line-height: 80rpx;
		  background: linear-gradient(75deg, #6F9A45 0%, #B4DC8E 100%);
		  box-shadow: 0rpx 6rpx 22rpx 0rpx rgba(130, 172, 89, 0.39);
		  border-radius: 20rpx;
		  text-align: center;
		  font-size: 28rpx;
		  color: #ffffff;
		  position: fixed;
		  bottom: 66rpx;
		  left: 40rpx;
		  right: 40rpx;
	}
</style>

待支付页面

结构部分
<template>
	<view class="container">
		<view class="orderDetailWrapper">
			
			<view class="nopay" ><text class="" v-if="source_id==3&&orderInfo.order_status!=1">
			{{orderInfo.order_status | orderStatus}}
			</text><text class="" v-else="source_id!=3">
				{{orderInfo.order_status | orderStatus}}
			</text><text class="subtime" v-if="orderInfo.order_status==1">  {{ orderCs }}{{ rocallTime }}</text>
				<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/common/arr1.png" mode="" class="icon"></image>
			</view>
			<navigator   :url="'/pages/localLife/localLifespdetail?goodsId='+orderInfo.store_goods_id"   class="storeInfo list" >
				<view class="title">商家信息</view>
				<view class="content">
					<text  v-if="orderInfo.goods_name && orderInfo.goods_name!='null'">{{orderInfo.goods_name}}</text>
					<text v-if="orderInfo.goods_desc && orderInfo.goods_desc!='null'">{{orderInfo.goods_desc}}</text>
					
				</view>
			</navigator>

			<view class="batchDestory"
				v-if="orderInfo.order_status == 2 || orderInfo.order_status == 6 || orderInfo.order_status == 7 || orderInfo.order_status == 8">
				<view class="title">批量核销</view>
				<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/line.png" mode="" class="line"></image>
				
				  <!-- <div class="ercode">
				          <div class="ercodeImg" v-if="orderStatus == 2 || orderStatus == 6 || orderStatus == 7">
				            <img :src="qrcodeImg" alt="" >
				          </div>
				          <div class="ercodeImg active" v-else-if="orderStatus == 8">
				            <img :src="qrcodeuseImg" alt="" srcset="">
				            <img src="@/assets/images/localLife/used.png" alt="" srcset="" class="useImg">
				          </div>
				          <div class="tips">出示该二维码即可消费多个订单</div>
				        </div> -->
				<view class="ercode">
					<view class="" v-if="source_id==3">
						<view class="ercodeImg" v-if="orderInfo.order_status == 2 || orderInfo.order_status == 6 || orderInfo.order_status == 7">
							<image :src="orderInfo.batch_qrCode_img_url" mode=""></image>
						</view>
						<view class="" v-else-if="orderInfo.order_status == 9">
							<image :src="orderInfo.batch_qrCode_img_url" mode=""></image>
						</view>
					</view>
					<view class="" v-else-if="source_id!=3">
						<view class="ercodeImg" v-if="orderInfo.order_status == 2 || orderInfo.order_status == 6 || orderInfo.order_status == 7">
							<tki-qrcode cid="qrcode1" ref="qrcode" :val="code_arr" :size="160" :unit="px"  :loadMake="true"  :onval="true"   :usingComponents="true"/>					
						</view>
					</view>
					<view class="ercodeImg active" v-else-if="orderInfo.order_status == 8">
						<tki-qrcode cid="qrcode1" foreground="#999999"  pdground="#999999" ref="qrcode" :val="111" :size="160" :unit="px"  :loadMake="true"  :onval="true"   :usingComponents="true"/>					
					<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/used.png" mode="" class="useImg"></image>
					</view>
					<view class="tips">出示该二维码即可消费多个订单</view>
				</view>
			</view>

			<view class="onceDestory" v-if="orderInfo.goods_code_list.length > 0">
				<view class="title">单个核销</view>
				<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/line.png" mode="" class="line"></image>
				<view class="codeInfoList">
					<view class="ercodeList" v-for="(item, i) in orderInfo.goods_code_list" :key="i">
						<view class="eleCode">
							<view class="codeNum">电子码:{{item.goods_code}}</view>
							<view class="img">
								<image :src="spImg" mode="" @click="popup_qrcdoe(item.goods_code,item.status)"></image>
							</view>
						</view>
						<view class="confirmStatus clearfix">
							<view class="orderStatus fl" v-if="item.status == 1" style="color: #457014;">待核销</view>
							<view class="orderStatus fl" v-else-if="item.status== 2" style="color: #999999;">已核销</view>
							<view class="times fr" v-if="item.status == 2 && item.time_end">核销时间:{{item.time_end}}</view>
						</view>
					</view>
				</view>
			</view>

			<view class="storeDetail" v-if="orderStatus > 0">
				<view class="storeTitle">
					<navigator   :url="'/pages/localLife/localLifespdetail?goodsId='+orderInfo.store_goods_id" class="storeName">{{storeDetail.store_name}}</navigator>
					<view  class="linkStore" @click=go_tel(orderInfo.reserved_phone)>
						<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/localLife/phone.png" mode=""></image>联系商家
					</view>
				</view>
				<view class="storeAdress">{{storeDetail.address}}</view>
				<navigator :url="'./useStore?storeId='+storeDetail.p_store_id" class="storeUseNum">{{storeDetail_sum}}家店适用
					<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/common/arr1.png" mode=""></image>
				</navigator>
			</view>

			<view class="userInfo list">
				<view class="title">个人信息</view>
				<view class="list">
					<view class="listCon clearfix">
						<view class="titleName">用户姓名:</view>
						<view class="titleCon">{{orderInfo.reserved_name}}</view>
					</view>
					<view class="listCon clearfix">
						<view class="titleName">联系电话:</view>
						<view class="titleCon">{{orderInfo.reserved_phone}}</view>
					</view>
					<view class="listCon clearfix">
						<view class="titleName">下单备注:</view>
						 <view class="titleCon" v-if="OrderInfo.reserved_phone">{{userIdea}}</view>
						<view class="titleCon" v-else>暂无备注</view>
					</view>
				</view>
			</view>

			<view class="orderInfo list">
				<view class="title">订单信息</view>
				<view class="list">
					<view class="listCon">
						<view class="titleName">订单状态:</view>
						<view class="titleCon" v-if="source_id==3&&orderInfo.order_status!=1">{{orderInfo.order_status | orderStatus}}</view>
						<view class="titleCon" v-else>{{orderInfo.order_status | orderStatus}}</view>
					
					</view>
					<view class="listCon">
						<view class="titleName">订单号码:</view>
						<view class="titleCon orderNum">{{orderInfo.serial_num}}</view>
						<view class="copy" @click="copy(orderInfo.serial_num)">复制</view>
					</view>
					<view class="listCon" v-if="orderInfo.is_discount == 1">
						<view class="titleName">订单价格:</view>
						<view class="titleCon">¥{{orderInfo.discount_order_amount/100}}</view>
					</view>
					<view class="listCon" v-else>
						<view class="titleName">订单价格:</view>
						<view class="titleCon">¥{{orderInfo.order_amount/100}}</view>
					</view>
					
					
					<view v-if="orderInfo.is_discount == 1" class="listCon">
						<view class="titleName">优惠券抵扣:</view>
						<view class="titleCon">¥{{disPrice}}</view>
					</view>
					<navigator   :url="'/pages/localLife/localLifespdetail?goodsId='+orderInfo.store_goods_id" class="listCon">
						<view class="titleName">套餐类型:</view>
						<view class="titleCon">{{orderInfo.spec_name}}</view>
					</navigator>
					<view class="listCon">
						<view class="titleName">购买数量:</view>
						<view class="titleCon">{{orderInfo.goods_count}}</view>
					</view>
					<view class="listCon">
						<view class="titleName">下单时间:</view>
						<view class="titleCon">{{orderInfo.created_at}}</view>
					</view>
				</view>
			</view>			
		</view>
		<view class="bottom oncePay" v-if="pay_status==1 && orderInfo.order_status==1">
			<view class="content">
				<view class="finallyPrice" v-if='orderInfo.is_discount==1'>实付金额:<text>¥{{orderInfo.discount_order_amount/100}}</text></view>
				<view class="finallyPrice" v-else>实付金额:<text>¥{{orderInfo.order_amount/100}}</text></view>
				<view class="goPay" @click="goPay">去支付</view>
			</view>
		</view>
		
		<view class="qrimg popWrapper" @click="mask" v-if="is_make==1 " @touchmove.stop.prevent="moveHandle">
			<view class="popContent" v-if="code_status==1" v-for="(item, i) in orderInfo.goods_code_list" :key="i">	
				<view class="" v-if="source_id==3" >
					<image style="width: 520rpx !important;height: 520rpx !important;display: block;margin: 0 auto;" :src="item.qrCode_img_url"></image>
				</view>
			<tki-qrcode v-if="source_id!=3" class="qrcode_img" cid="qrcode2" ref="qrcode" :val=qr_code_txt  :unit="px"  :loadMake="true"  :onval="true" :usingComponents="true"/>
			</view>
			
			<view class="popContent" v-else>
			<tki-qrcode  foreground="#999999"  pdground="#999999"  class="qrcode_img" cid="qrcode2" ref="qrcode" :val=qr_code_txt  :unit="px"  :loadMake="true"  :onval="true" :usingComponents="true"/>
			</view>
		</view>
		
	</view>
</template>
逻辑部分(内含详细注释)
<script>
    let app = getApp(); // 获取小程序实例
    import tkiQrcode from '@/js_sdk/tki-qrcode/tki-qrcode.vue'; // 引入二维码组件

    export default {
        data() { // 数据
            return {
                rocallTime: "", // 回拨时间
                orderCs: "剩余", // 订单状态
                spImg: 'https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/ewm.png', // 商品图片
                discouponNum: 0, // 折扣券数量
                isChecked: true, // 是否选中
                orderStatus: 8, // 订单状态
                codeList: [1, 2, 1], // 券码列表
                goods_order_id:0, // 商品订单ID
                token:{}, // 用户token
                orderInfo:[], // 订单信息
                storeDetail:{}, // 商家详情
                storeDetail_sum:1, // 商家总数
                remainingd:300, // 剩余时间(秒)
                remaining:'剩余 5:00', // 剩余时间(格式化)
                qrcodeText:'test', // 二维码文本
                qr_code_txt:'测试', // 二维码文本
                is_make:0, // 是否生成二维码
                pay_status:1, // 支付状态
                code_arr:'', // 券码数组
                disPrice:0, // 折扣价格
                code_status:0, // 券码状态
                source_id:"", // 来源ID
                lianlian_img:"", // 联联图片
                batch_qrCode_img_url:"", // 批量二维码图片URL
                code_arr1:'', // 券码数组
                goods_code_list:{}, // 联联的券码
                goods_code:{} // 平台/享库存的券码
            }
        },
        components: { // 组件
            tkiQrcode
        },
        onLoad(e) { // 生命周期函数:页面加载时执行
            this.goods_order_id=e.store_order_id; // 获取商品订单ID
            this.token=uni.getStorageSync('token'); // 获取用户token
            this.getStoreGoodsOrderInfo(); // 获取商家商品订单信息
        },
        onShow() { // 生命周期函数:页面显示时执行
            console.log(this.code_arr,'waaw') // 打印券码数组
        },
        mounted() {}, // 生命周期函数:组件挂载后执行
        filters:{ // 过滤器
            orderStatus(e){ // 订单状态过滤器
                // 1 待支付 2已支付 3已取消 4 退款中 5已退款 6已支付生成券码 7已预约 8已完成
                switch(e){
                    case 1:
                        return '待支付'
                        break;
                    case 2:
                        return '支付成功'
                        break;
                    case 3:
                        return '已取消'
                        break;
                    case 4:
                        return '退款中'
                        break;
                    case 5:
                        return '已退款'
                        break;    
                    case 6:
                        return '已支付生成券码'
                        break;    
                    case 7:
                        return '已预约'
                        break;    
                    case 8:
                        return '已完成'
                        break;    
                    case 9:
                        return '出单中'
                        break;    
                }               
            }
        },
        methods: { // 方法
            go_tel(e){ // 拨打电话
                uni.makePhoneCall({ // 调用拨打电话API
                    phoneNumber: e, // 手机号码
                    success: (res) => { // 成功回调函数
                        console.log('调用成功!')    
                    },
                    fail: (res) => { // 失败回调函数
                        console.log('调用失败!')
                    }
                })
            },
            mask () { // 隐藏二维码弹窗
                this.is_make=0;
            },
            copy(e){ // 复制文本
                app.copy(e); // 调用小程序实例的复制文本方法
            },

            goPay() { // 去支付
                let _that = this; // 缓存this对象
                uni.request({ // 发起网络请求
                    url: app.globalData.URL + "localLive/againPay", // 请求地址
                    method: 'POST', // 请求方法
                    data: { // 请求参数
                        version:'251',
                        client:'wxmp',
                        count: 1,
                        goods_order_id: this.goods_order_id,
                        token:this.token.token,                        
                    },
                    success(res) { // 请求成功回调函数
                        var  paydata= res.data.data.pay_data; // 获取支付数据
                        console.log(res.data,'againPay');
                        console.log(paydata,'againPay');
                        uni.requestPayment({ // 调用微信支付API
                            provider: 'wxpay',
                            timeStamp: paydata.timeStamp,
                            nonceStr: paydata.nonceStr,
                            package: paydata.package,
                            signType: 'MD5',
                            paySign: paydata.paySign,
                            success: function (res) { // 支付成功回调函数
                                console.log('success:' + JSON.stringify(res));
                                _that.getStoreGoodsOrderInfo(); // 获取商家商品订单信息
                                uni.$emit('successPay', { // 发送支付成功事件
                                    msg: '支付成功',
                                    data: _that.order_id
                                })
                                console.log('success:' + JSON.stringify(res));
                            },
                            fail: function (err) { // 支付失败回调函数
                                console.log('fail:' + JSON.stringify(err));
                            }
                        });
                    }
                })
            },
            popup_qrcdoe(e,status){ // 显示二维码弹窗
                this.code_status=status; // 设置券码状态
                this.qr_code_txt=e; // 设置二维码文本
                this.is_make=1; // 显示二维码弹窗
            },
            getStoreGoodsOrderInfo(){ // 获取商家商品订单信息方法
    let _that = this; // 缓存this对象
    uni.request({ // 发起网络请求
        url: app.globalData.URL + "localLive/getStoreGoodsOrderInfo", // 请求地址
        method: 'POST', // 请求方法
        data: { // 请求参数
            version:'251',
            client:'wxmp',
            count: 1,
            goods_order_id: this.goods_order_id,
            token:this.token.token,
            //openid:''
        },
        success(res) { // 请求成功回调函数
            console.log(res.data.data,'getStoreGoodsOrderInfo');
            _that.orderInfo=res.data.data; // 缓存订单信息
            uni.setStorageSync('orderInfo',_that.orderInfo); // 将订单信息缓存到本地存储中
            _that.storeDetail=res.data.data.store_data[0]; // 缓存商家详情
            _that.storeDetail_sum=res.data.data.store_count; // 缓存商家总数
            console.log(res.data.data,'getStoreGoodsOrderInfo');
            _that.orderTime=res.data.data.created_at; // 缓存订单创建时间
            _that.source_id = res.data.data.store_source_id; // 缓存来源ID
            _that.ComputetTime(); // 计算剩余时间
            //平台/享库存的券码
            console.log(_that.goods_code,'平台/享库存的券码')
            const a = _that.orderInfo.goods_code_list;
            //数据需要处理才能赋值	
            const data = JSON.stringify(a); // 假设data是一个被Vue.js观察的对象
            _that.goods_code_list = JSON.parse(data); // 缓存联联的券码
            _that.goods_code = _that.orderInfo.goods_code_list; // 缓存平台/享库存的券码
            console.log(_that.goods_code_list.length,'平台/享库存的券码券码长度'); // 输出对象的长度
            if(_that.source_id==3){ // 如果是联联的商品
                _that.orderInfo = res.data.data;
                uni.setStorageSync('orderInfo',_that.orderInfo);
                _that.orderStatus = 9;
                const a = _that.orderInfo.goods_code_list;
                //数据需要处理才能赋值	
                const data = JSON.stringify(a); // 假设data是一个被Vue.js观察的对象
                _that.goods_code_list = JSON.parse(data); // 缓存联联的券码
                console.log(_that.goods_code_list,'联联的券码'); // 输出对象的长度														console.log(_that.orderInfo)
            }else{ // 如果不是联联的商品
                var code_arr='';
                for (var i = 0; i < _that.orderInfo.goods_code_list.length; i++) {
                    if (_that.orderInfo.goods_code_list[i].status == 1) {
                        code_arr += _that.orderInfo.goods_code_list[i].goods_code + ','
                    }
                }
                if (_that.orderInfo.is_discount == 1) {
                    _that.disPrice = Math.round((_that.orderInfo.order_amount / 100 - _that.orderInfo.discount_order_amount / 100) * 100) / 100
                } else {
                    _that.disPrice = 0
                }	  
                _that.code_arr=code_arr;
            }
        }
    })
},
ComputetTime() { // 计算剩余时间方法
    var st = new Date(); // 获取当前时间
    var ct = this.orderTime.replace(/-/g, "/"); // 创建订单时间
    var ts = new Date(st).getTime(); // 获取当前时间的毫秒数
    var tc = new Date(ct).getTime(); // 获取创建订单时间的毫秒数
    var cm = 5 * 60 * 1000 - (ts - tc); // 计算剩余时间(毫秒)
    //判断是否是联联的商品,如果是联联的商品则需要改为2分钟
    if(this.source_id ==3){
        var cm = 2 * 60 * 1000 - (ts - tc);
    }
    this.runBack(cm); // 执行倒计时方法
},
runBack(cm) { // 倒计时方法
    if (cm > 1000) {
            cm > 60000 // 如果剩余时间大于1分钟
            ? (this.rocallTime =
                (new Date(cm).getMinutes() < 10 // 获取剩余分钟数,如果小于10则在前面加0
                    ? "0" + new Date(cm).getMinutes()
                    : new Date(cm).getMinutes()) +
                ":" +
                (new Date(cm).getSeconds() < 10 // 获取剩余秒数,如果小于10则在前面加0
                    ? "0" + new Date(cm).getSeconds()
                    : new Date(cm).getSeconds()))
            : (this.rocallTime =
                "00:" +
                (new Date(cm).getSeconds() < 10 // 获取剩余秒数,如果小于10则在前面加0
                    ? "0" + new Date(cm).getSeconds()
                    : new Date(cm).getSeconds()));
    let _msThis = this;
    setTimeout(function () { // 延时1秒执行倒计时方法
        cm -= 1000; // 剩余时间减去1秒
        _msThis.runBack(cm); // 递归调用倒计时方法
    }, 1000);
} else { // 如果剩余时间小于等于1秒
    this.orderCs = "订单已超时"; // 设置订单状态为已超时
    this.pay_status =0; // 设置支付状态为未支付
    this.rocallTime = ""; // 清空剩余时间
    this.payFlag = true; // 设置支付标志为true
}
},
},
}
</script>
样式部分
<style lang="scss" scoped>
	.mask {
	text-align:center;
	position: fixed;
	top:0;
	left:0;
	z-index:999;
	width:100%;
	height:100vh;
	background:rgba(0,0,0,0.4);
	
	}
	.qrcode_img{
		
	}
	.container {
		width: 100%;
	}

	.orderDetailWrapper {
		padding: 0 36rpx;
		padding-top: 40rpx;
		padding-bottom: 40rpx;

		.nopay {
			height: 50rpx;
			line-height: 50rpx;
			font-size: 36rpx;
			color: #333333;
			vertical-align: middle;

			.subtime {
				color: #F8C85D;
				vertical-align: middle;
				display: inline-block;
			}

			.icon {
				width: 10rpx;
				height: 20rpx;
				margin-left: 20rpx;
				vertical-align: middle;
				display: inline-block;
			}
		}

		.storeInfo {
			background: #FFFFFF;
			border-radius: 24rpx;
			margin-top: 20rpx;
			padding: 20rpx 24rpx;
			padding-bottom: 60rpx;

			.title {
				height: 44rpx;
				font-size: 32rpx;
				font-weight: 600;
				color: #333333;
				line-height: 44rpx;
			}

			.content {
				padding-top: 20rpx;
				font-size: 24rpx;
				color: #333333;
				line-height: 36rpx;
			}
		}

		.batchDestory {
			margin-top: 28rpx;
			margin-bottom: 28rpx;

			.title {
				height: 56rpx;
				font-size: 32rpx;
				font-weight: 600;
				color: #333333;
				line-height: 44rpx;
				padding: 0 24rpx;
				background: #FFFFFF;
				padding-top: 40rpx;
				border-radius: 24rpx 24rpx 0 0;
			}

			.line {
				width: 100%;
				height: 42rpx;
				display: block;
			}

			.ercode {
				background: #FFFFFF;
				padding-bottom: 40rpx;
				border-radius: 0 0 24rpx 24rpx;
				width: 100%;

				.ercodeImg {
					width: 320rpx;
					height: 320rpx;
					margin: 0 auto;
					border: 2rpx solid #F5F5F5;
					padding: 20rpx;
					position: relative;

					image {
						width: 100%;
						height: 100%;
					}

					.useImg {
						position: absolute;
						bottom: -24rpx;
						right: -108rpx;
						width: 216rpx;
						height: 216rpx;
					}
				}

				.tips {
					padding-top: 28rpx;
					font-size: 24rpx;
					color: #666666;
					line-height: 34rpx;
					text-align: center;
				}
			}
		}

		.onceDestory {
			margin-bottom: 28rpx;

			.title {
				height: 56rpx;
				font-size: 32rpx;
				font-weight: 600;
				color: #333333;
				line-height: 44rpx;
				padding: 0 24rpx;
				background: #FFFFFF;
				padding-top: 40rpx;
				border-radius: 24rpx 24rpx 0 0;
			}

			.line {
				width: 100%;
				height: 42rpx;
				display: block;
			}

			.codeInfoList {
				background-color: #fff;
				border-radius: 0 0 24rpx 24rpx;

				>.ercodeList:last-child {
					padding-bottom: 30rpx;
				}
			}

			.eleCode {
				display: flex;
				padding: 0 24rpx;
				padding-top: 6rpx;

				.codeNum {
					height: 40rpx;
					font-size: 28rpx;
					color: #333333;
					line-height: 40rpx;
					flex: 1;
					overflow: hidden;
					text-overflow: ellipsis;
					white-space: nowrap;
				}

				.img {
					width: 36rpx;
					height: 36rpx;
					margin-left: 10rpx;

					image {
						width: 36rpx;
						height: 36rpx;
					}
				}
			}

			.confirmStatus {
				padding: 0 24rpx;
				padding-top: 28rpx;
				padding-bottom: 6rpx;

				.orderStatus {
					font-size: 24rpx;
					height: 56rpx;
					line-height: 56rpx;
				}

				.goOrder {
					padding: 0 36rpx;
					height: 56rpx;
					border-radius: 24rpx;
					border: 2rpx solid #457014;
					color: #457014;
					font-size: 24rpx;
					line-height: 56rpx;
				}

				.times {
					color: #333333;
					font-size: 24rpx;
					line-height: 56rpx;
				}
			}
		}

		.storeDetail {
			background: #FFFFFF;
			box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.07);
			border-radius: 24rpx;
			margin-top: 28rpx;
			padding: 40rpx 24rpx;

			.storeTitle {
				display: flex;

				.storeName {
					height: 44rpx;
					font-size: 32rpx;
					font-weight: 600;
					color: #333333;
					line-height: 44rpx;
					flex: 1;
					white-space: nowrap;
					overflow: hidden;
					text-overflow: ellipsis;
				}

				.linkStore {
					margin-left: 20rpx;
					height: 44rpx;
					font-size: 24rpx;
					color: #333333;
					line-height: 44rpx;

					image {
						width: 28rpx;
						height: 26rpx;
						display: inline-block;
						margin-right: 4rpx;
					}
				}
			}

			.storeAdress {
				padding-top: 26rpx;
				font-size: 24rpx;
				color: #999999;
				line-height: 32rpx;
			}

			.storeUseNum {
				padding-top: 26rpx;
				font-size: 24rpx;
				color: #333333;
				line-height: 34rpx;
				text-align: center;
				display: block;

				image {
					width: 11rpx;
					height: 20rpx;
					display: inline-block;
					margin-left: 8rpx;
				}
			}
		}

		.userInfo {
			background: #FFFFFF;
			box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.07);
			border-radius: 24rpx;
			margin-top: 28rpx;
			padding: 40rpx 24rpx;
			padding-bottom: 26rpx;

			.title {
				height: 44rpx;
				font-size: 32rpx;
				font-weight: 600;
				color: #333333;
				line-height: 44rpx;
			}

			.list {
				padding-top: 28rpx;

				.listCon {
					display: flex;
					height: 40rpx;
					line-height: 40rpx;
					margin-bottom: 14rpx;

					.titleName {
						font-size: 28rpx;
						color: #999999;
						line-height: 40rpx;
						white-space: nowrap;
					}

					.titleCon {
						font-size: 28rpx;
						color: #333333;
						line-height: 40rpx;
						flex: 1;
						word-break: break-word;
					}
				}
			}
		}

		.orderInfo {
			background: #FFFFFF;
			box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.07);
			border-radius: 24rpx;
			margin-top: 28rpx;
			padding: 40rpx 24rpx;
			padding-bottom: 26rpx;
			.title {
				height: 44rpx;
				font-size: 32rpx;
				font-weight: 600;
				color: #333333;
				line-height: 44rpx;
			}

			.list {
				padding-top: 28rpx;
				.listCon {
					display: flex;
					overflow: hidden;
					height: 40rpx;
					line-height: 40rpx;
					margin-bottom: 14rpx;
					.titleName {
						font-size: 28rpx;
						color: #999999;
						height: 40rpx;
						line-height: 40rpx;
						white-space: nowrap;
					}

					.titleCon {
						font-size: 28rpx;
						color: #333333;
						height: 40rpx;
						line-height: 40rpx;
						flex: 1;
						white-space: nowrap;
						overflow: hidden;
						text-overflow: ellipsis;
					}
					.copy {
						margin-left: 18rpx;
						padding: 0 10rpx;
						margin-top: 8rpx;
						background: #E4E4E4;
						border-radius: 8rpx;
						font-size: 16rpx;
						color: #333333;
						height: 28rpx;
						line-height: 28rpx;
					}
				}
			}
		}
		.Destruction{
			margin-top: 28rpx;
			padding: 40rpx 24rpx;
			padding-bottom: 92rpx;
			padding-top: 40rpx;
			background: #FFFFFF;
			border-radius: 24rpx 24rpx 24rpx 24rpx;
			display: flex;
			justify-content: space-between;
			.title{
				font-weight: 600;
				color: #333333;
				font-size: 32rpx;
			}
			.des_btn{
				width: 148rpx;
				border-radius: 200rpx 200rpx 200rpx 200rpx;
				border: 1rpx solid #999999;
				font-size: 24rpx;
				padding: 8rpx 4rpx;
				text-align: center;
				color: #666666;
				line-height: 28rpx;
			}
		}
		.Destruction1{
			margin-top: 28rpx;
			padding: 40rpx 24rpx;
			padding-bottom: 92rpx;
			padding-top: 40rpx;
			background: #FFFFFF;
			border-radius: 24rpx 24rpx 24rpx 24rpx;
			display: flex;
			justify-content: space-between;
			.title{
				font-weight: 600;
				color: #333333;
				font-size: 32rpx;
			}
			.des_btn{
				width: 148rpx;
				border-radius: 200rpx 200rpx 200rpx 200rpx;
				border: 1rpx solid #999999;
				font-size: 24rpx;
				padding: 8rpx 4rpx;
				text-align: center;
				color: #666666;
				line-height: 28rpx;
			}
		}
	}

	.bottom {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		background: #FFFFFF;
		box-shadow: 0rpx -4rpx 22rpx 0rpx rgba(0, 0, 0, 0.07);

		.content {
			padding: 16rpx 36rpx;
			display: flex;

			.finallyPrice {
				font-size: 24rpx;
				color: #333333;
				height: 88rpx;
				line-height: 88rpx;
				flex: 1;
				overflow: hidden;
				text-overflow: ellipsis;
				white-space: nowrap;
				padding-right: 20rpx;

				text {
					color: #F8C85D;
					font-size: 36rpx;
				}
			}

			.goPay {
				padding: 0 134rpx;
				height: 88rpx;
				line-height: 88rpx;
				text-align: center;
				background: #D8D8D8 linear-gradient(75deg, #6F9A45 0%, #B4DC8E 100%);
				border-radius: 20rpx;
				font-size: 28rpx;
				color: #FFFFFF;
			}
		}

	}
	
	.popWrapper {
		width: 100%;
		height: 100%;
		position: fixed;
		background-color: rgba(0, 0, 0, 0.7);
		top: 0;
		left: 0;
		z-index: 9999;
		.popContent {
			position: absolute;
			top: 50%;
			left: 32rpx;
			right: 32rpx;
			background: #FFFFFF;
			border-radius: 32rpx;
			transform: translateY(-50%);
			padding: 65rpx 0;
			/deep/ .tki-qrcode {
				border-radius: 32rpx;
				padding: 0 40rpx;
				margin-top: 30rpx;
				text-align: center;
				image {
					width: 400rpx;
					height: 400rpx;
				}
			}
			/deep/ .tki-barcode {
				border-radius: 32rpx;
				padding: 0 40rpx;
				image {
					width: 100% !important;
				}
			}
			.circle {
			  width: 100%;
			  height: 4rpx;
			  position: relative;
			}
			.circle::before {
			  content: '';
			  position: absolute;
			  left: -10rpx;
			  top: 0;
			  width: 20rpx;
			  height: 20rpx;
			  background:#4C4C4C;
			  border-radius: 50%;
			}
			.circle::after {
			  content: '';
			  position: absolute;
			  right: -10rpx;
			  top: 0;
			  width: 20rpx;
			  height: 20rpx;
			  background:#4C4C4C;
			  border-radius: 50%; 
			}
		}
	}
	
</style>

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>