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

news2024/12/29 10:43:09

文章目录

    • 功能描述:
    • 准备工作
      • 申请微信支付接口权限
    • 微信支付api需要的参数说明
        • 示例代码
    • 需要传入后端接口的参数说明:
    • 接口返回的参数说明:
    • 支付逻辑代码(只包含支付功能)
    • 以下是功能完整代码
      • 确认订单页面
        • 结构部分
        • 逻辑部分(内涵详细注释)
        • 样式部分
      • 优惠券页面
      • 待支付页面
        • 结构部分
        • 逻辑部分(内含详细注释)
        • 样式部分

功能描述:

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

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

准备工作

申请微信支付接口权限

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

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

微信支付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>

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

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

相关文章

【阿里云】文本转语音方言— 阿里云语音合成,文本转语音方言工具类

目录 一、导入SDK坐标 二、文本转语音方言 —步骤和工具类 1.登录阿里云账号&#xff0c;创建一个语音合成项目和创建用户并设置权限。 2.获取appKey、accessKeyId、accessKeySecret在相应位置进行填写。 3.相应位置填写自己需要保存的本地路径。意思就是说&#xff0c;自…

【HarmonyOS】低代码元服务开发中的地图实现

在元服务开发过程中&#xff0c;大家可能需要在应用中使用地图&#xff0c;如果使用SDK集成的方式&#xff0c;地图SDK包体积大小很大&#xff0c;集成后元服务大小可能会超过10M&#xff0c;这就超出了HAP包的大小限制。那么是否有其他途径可以在元服务中使用地图呢&#xff1…

视频理解学习笔记(一):双流卷积神经网络

视频理解学习笔记&#xff08;一&#xff09;&#xff1a;双流卷积神经网络 两句话总结双流卷积神经网络论文概览方法详解Spatial stream ConvNetTemporal stream ConvNet测试方法 光流什么是光流怎么预处理光流 数据集UCF101&#xff08;已被刷爆&#xff09;HMDB51 Experimen…

安装包UI美化之路-Electron打包出界面美观,功能完善的安装包,这三步就够了

这篇文章应该说是《安装包UI美化之路-nsNiuniuSkin安装包制作可视化配置向导》的延伸与进一步应用&#xff0c;在可视配置的基础之上&#xff0c;生成供electron-builder打包的脚本&#xff01; 一直有朋友反馈&#xff0c;不知道如何将nsNiuniuSkin与Electron打包结合起来&am…

Real-Time C++ 嵌入式C++ 程序设计(二)

翻译自 Real-Time C Efficient Object-Oriented and Template Microcontroller Programming 4th Edition - Kormanyos, Christopher&#xff0c;这书涉及了从C11 到C20 的内容&#xff0c;主要介绍使用C 的模板、面向对象等特性设计嵌入式程序。书里的示例代码都是公开的&#…

【OpenCV DNN】Flask 视频监控目标检测教程 03

欢迎关注『OpenCV DNN Youcans』系列&#xff0c;持续更新中 【OpenCV DNN】Flask 视频监控目标检测教程 03 3.3 上传本地图片进行人脸检测3.3.1 OpenCV 级联分类器类 cv::CascadeClassifier3.3.2 cvFlask03 项目的构建步骤 本系列从零开始&#xff0c;详细讲解使用 Flask 框架…

Unity3D :运行时 UI 的性能注意事项

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 运行时 UI 的性能注意事项 本页介绍如何提高运行时的性能用户界面 . 优化数据存储 您可以使用 usageHints 来设置元素在运行时的使用方式&#xff0c;以便相应地优化数据存储。例…

三、CNNs网络架构-跨层连接思想的网络架构

《A review of convolutional neural network architectures and their optimizations》论文指出随着网络架构的深入&#xff0c;梯度消失、爆炸或退化问题变得越来越严重。跨层连接的思想是解决现有问题的有效方案&#xff0c;允许网络在非相邻层之间传递信息。因此&#xff0…

如何利用Python中的pymysql库来操作Mysql数据库,看这篇就够啦~

为了使python连接上数据库&#xff0c;你需要一个驱动&#xff0c;这个驱动是用于与数据库交互的库&#xff0c;本文是向大家介绍了如何利用python中的pymysql库来操作mysql数据库。 1、什么是pymysql&#xff1f; pymysql是从python连接到mysql数据库服务器的接口&#xff0c…

上门服务小程序|东邻到家系统|上门服务系统包含哪些功能?

使用东郊到家小程序&#xff0c;只需要一键预约即可在工作之余、休息娱乐的时候&#xff0c;点一个理按疗摩技师&#xff0c;做一个SPA&#xff0c;缓解工作压力&#xff0c;不失为一种享受&#xff0c;并且上门服务小程序可以为技师或从业岗位人员提供就业服务&#xff0c;线上…

抖音seo优化源代码搭建+抖音小程序私有化开源部署

抖音seo优化源码&#xff0c;抖音seo矩阵系统搭建&#xff0c;抖音账号矩阵系统开发&#xff0c;企业在做账号矩阵过程中&#xff0c;最头疼的莫过于私域线索转化&#xff0c;作为开发者都知道&#xff0c;目前市面上我们了解的矩阵系统除了挂载POI信息外&#xff0c;无法挂载留…

一篇关于 ApiKit 的简单介绍

简介 本文介绍 ApiKit 工具&#xff0c;它是 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台。 一、常用解决方案 使用 Swagger 管理 API 文档 使用 Postman 调试 API 使用 mockjs 等工具 Mock API 数据 使用 JMeter 做 API 自动化测试 二、存在的问题 维护…

ffmpeg学习日记122-视频-获取视频的解码器,yuv格式名称,理解编码格式,封装格式,yuv格式的关系

Author: wencoo Blog&#xff1a;https://wencoo.blog.csdn.net/ Date: 25/05/2023 Email: jianwen056aliyun.com Wechat&#xff1a;wencoo824 QQ&#xff1a;1419440391 Details:文章目录 正文 或 背景获取像素格式&#xff0c;也就是yuv排列格式获取解码器id获取输出文件的封…

景区上线智慧客流人数采集分析系统的根本原因

智慧客流量采集系统是一种高效、智能的客流量采集解决方案&#xff0c;可以实现客流量的实时监控、数据分析和预测&#xff0c;提高服务质量、降低管理成本、提高安全性等优势。该系统适用于各种场所&#xff0c;如景区、商场、服务区、机场等。 AI客流视觉监控 一、智慧客流量…

安科瑞电力监控系统和五防系统在锡林郭勒项目的应用

摘要&#xff1a;随着电力、计算机、信息和网络等技术的不断发展&#xff0c;推动了电力监控的快速发展&#xff0c;人们对电力系统运行的安全性以及稳定性的要求越来越高。本文针对锡林郭勒供配电系统特点及供配电系统高可靠性的要求&#xff0c;提出了保护类、监测类和防误闭…

ASEMI代理长电MCR100-6可控硅的性能与应用分析

编辑-Z 本文主要介绍了新型MCR100-6晶闸管的性能与应用。首先&#xff0c;从晶闸管的基本原理和结构出发&#xff0c;分析了MCR100-6晶闸管的性能特点&#xff1b;其次&#xff0c;探讨了MCR100-6晶闸管在各种电子电路中的应用&#xff1b;最后&#xff0c;对MCR100-6晶闸管的…

档案馆建设标准条文说明

第一章 总则 第一条 本条阐明了本标准的编制目的。 中国是一个历史悠久的文明古国&#xff0c;档案事业的发展源远流长。档案是人类活动的真实记录&#xff0c;是人们认识和把握客观规律的重要依据。借助档案&#xff0c;我们能够更好地了解过去、把握现在、预见未来。档案工…

工业机器视觉缺陷检测工作小结

工业机器视觉检测工作小结 &#xff08;因为网上没有很系统的讲义和文档&#xff0c;都是零零散散的&#xff0c;因此&#xff0c;我自己尝试着总结一下、仅供参考&#xff09; 你想知道的大概率在这都可以找到、相机的了解镜头的了解光源的了解传统算法DL深度学习方法 &#…

基于微信小程序渗透-反编译小程序

文章目录 一、概述二、使用电脑版微信获取小程序源码三、使用工具解密源码四、配置nodejs环境五、使用工具解包 一、概述 微信小程序渗透时&#xff0c;因为小程序没有网页端页面&#xff0c;所以不能直接访问抓包分析&#xff0c;如果需要抓包分析&#xff0c;那么一般就是用…

Spring:用 Spring 整合 MyBatis(Spring-MyBatis)代码整理

文章目录 Spring&#xff1a;Day 05Spring - MyBatis1. 依赖&#xff1a;pom.xml2. 外部配置文件&#xff1a;db.properties3. MyBatis 核心配置文件&#xff1a;mybatis-config.xml4. 实体类5. 接口&#xff1a;xxxMapper.java6. 实现类&#xff1a;xxxMapper.xml7. Spring 通…