|
|
|
|
@ -90,84 +90,134 @@
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 支付二维码 -->
|
|
|
|
|
<!-- 支付区域 -->
|
|
|
|
|
<view class="payment-popup" v-if="orderInfo.pay_status === 0" id="pay-qrcode-section">
|
|
|
|
|
<view class="title">付款二维码</view>
|
|
|
|
|
<view class="amount">
|
|
|
|
|
<text class="symbol">¥</text>
|
|
|
|
|
<text class="number">{{orderInfo.price}}</text>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="qr-code">
|
|
|
|
|
<!-- 支付二维码 -->
|
|
|
|
|
<view v-if="myQrcode" style="border: 1px solid #ccc; padding: 10rpx;">
|
|
|
|
|
<uqrcode
|
|
|
|
|
v-if="myQrcode"
|
|
|
|
|
canvas-id="pay-qrcode"
|
|
|
|
|
:value="myQrcode"
|
|
|
|
|
:size="400"
|
|
|
|
|
:sizeUnit="'rpx'"
|
|
|
|
|
:options="{
|
|
|
|
|
margin: 10,
|
|
|
|
|
}"
|
|
|
|
|
></uqrcode>
|
|
|
|
|
<!-- Tab 切换 -->
|
|
|
|
|
<view class="payment-tabs">
|
|
|
|
|
<view
|
|
|
|
|
class="tab-item"
|
|
|
|
|
:class="{ 'tab-active': activeTab === 'qrcode' }"
|
|
|
|
|
@click="switchTab('qrcode')"
|
|
|
|
|
>
|
|
|
|
|
付款二维码
|
|
|
|
|
</view>
|
|
|
|
|
<view v-else style="text-align: center; color: #999; padding: 40rpx;">
|
|
|
|
|
正在生成二维码...
|
|
|
|
|
<view
|
|
|
|
|
class="tab-item"
|
|
|
|
|
:class="{ 'tab-active': activeTab === 'pay' }"
|
|
|
|
|
@click="switchTab('pay')"
|
|
|
|
|
>
|
|
|
|
|
立即支付
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="tips">
|
|
|
|
|
<text>请扫码支付订单金额</text>
|
|
|
|
|
<text class="sub-tips">支付完成后订单将自动完成</text>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- Tab 内容 -->
|
|
|
|
|
<view class="tab-content">
|
|
|
|
|
<!-- 付款二维码 Tab -->
|
|
|
|
|
<view v-if="activeTab === 'qrcode'" class="tab-panel">
|
|
|
|
|
<view class="amount">
|
|
|
|
|
<text class="symbol">¥</text>
|
|
|
|
|
<text class="number">{{orderInfo.price}}</text>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 分享按钮 -->
|
|
|
|
|
<view class="share-section">
|
|
|
|
|
<u-button
|
|
|
|
|
type="primary"
|
|
|
|
|
size="medium"
|
|
|
|
|
@click="showShareGuide"
|
|
|
|
|
:custom-style="{
|
|
|
|
|
background: 'linear-gradient(to right, #1479ff, #4a90e2)',
|
|
|
|
|
color: '#fff',
|
|
|
|
|
borderRadius: '40rpx',
|
|
|
|
|
fontSize: '28rpx'
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<u-icon name="share" color="#fff" size="16" style="margin-right: 8rpx;"></u-icon>
|
|
|
|
|
转发给微信好友
|
|
|
|
|
</u-button>
|
|
|
|
|
|
|
|
|
|
<!-- 返回首页按钮(仅分享进入时显示) -->
|
|
|
|
|
<u-button
|
|
|
|
|
v-if="isFromShare"
|
|
|
|
|
type="default"
|
|
|
|
|
size="medium"
|
|
|
|
|
@click="goToHome"
|
|
|
|
|
:custom-style="{
|
|
|
|
|
marginTop: '20rpx',
|
|
|
|
|
borderRadius: '40rpx',
|
|
|
|
|
fontSize: '28rpx'
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<u-icon name="home" color="#1479ff" size="16" style="margin-right: 8rpx;"></u-icon>
|
|
|
|
|
返回首页
|
|
|
|
|
</u-button>
|
|
|
|
|
<view class="qr-code">
|
|
|
|
|
<!-- 支付二维码 -->
|
|
|
|
|
<view v-if="myQrcode" style="border: 1px solid #ccc; padding: 10rpx;">
|
|
|
|
|
<!-- 显示图片(可长按识别) -->
|
|
|
|
|
<image
|
|
|
|
|
v-if="qrcodeImagePath"
|
|
|
|
|
:src="qrcodeImagePath"
|
|
|
|
|
mode="aspectFit"
|
|
|
|
|
show-menu-by-longpress
|
|
|
|
|
style="width: 400rpx; height: 400rpx; display: block; margin: 0 auto;"
|
|
|
|
|
></image>
|
|
|
|
|
<!-- Canvas 绘制(使用 hide 属性隐藏,但保持可渲染) -->
|
|
|
|
|
<uqrcode
|
|
|
|
|
v-else
|
|
|
|
|
ref="payQrcode"
|
|
|
|
|
id="pay-qrcode"
|
|
|
|
|
canvas-id="pay-qrcode"
|
|
|
|
|
:value="myQrcode"
|
|
|
|
|
:size="400"
|
|
|
|
|
:sizeUnit="'rpx'"
|
|
|
|
|
:hide="true"
|
|
|
|
|
:options="{
|
|
|
|
|
margin: 10,
|
|
|
|
|
}"
|
|
|
|
|
@complete="onQrcodeComplete"
|
|
|
|
|
></uqrcode>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-else style="text-align: center; color: #999; padding: 40rpx;">
|
|
|
|
|
正在生成二维码...
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="tips">
|
|
|
|
|
<text>请扫码支付订单金额</text>
|
|
|
|
|
<text class="sub-tips">支付完成后订单将自动完成</text>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 分享按钮 -->
|
|
|
|
|
<view class="share-section">
|
|
|
|
|
<u-button
|
|
|
|
|
type="primary"
|
|
|
|
|
size="medium"
|
|
|
|
|
@click="showShareGuide"
|
|
|
|
|
:custom-style="{
|
|
|
|
|
background: 'linear-gradient(to right, #1479ff, #4a90e2)',
|
|
|
|
|
color: '#fff',
|
|
|
|
|
borderRadius: '40rpx',
|
|
|
|
|
fontSize: '28rpx'
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<u-icon name="share" color="#fff" size="16" style="margin-right: 8rpx;"></u-icon>
|
|
|
|
|
转发给微信好友
|
|
|
|
|
</u-button>
|
|
|
|
|
|
|
|
|
|
<!-- 返回首页按钮(仅分享进入时显示) -->
|
|
|
|
|
<u-button
|
|
|
|
|
v-if="isFromShare"
|
|
|
|
|
type="default"
|
|
|
|
|
size="medium"
|
|
|
|
|
@click="goToHome"
|
|
|
|
|
:custom-style="{
|
|
|
|
|
marginTop: '20rpx',
|
|
|
|
|
borderRadius: '40rpx',
|
|
|
|
|
fontSize: '28rpx'
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<u-icon name="home" color="#1479ff" size="16" style="margin-right: 8rpx;"></u-icon>
|
|
|
|
|
返回首页
|
|
|
|
|
</u-button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 立即支付 Tab -->
|
|
|
|
|
<view v-if="activeTab === 'pay'" class="tab-panel">
|
|
|
|
|
<view class="amount">
|
|
|
|
|
<text class="symbol">¥</text>
|
|
|
|
|
<text class="number">{{orderInfo.price}}</text>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="pay-button-section">
|
|
|
|
|
<u-button
|
|
|
|
|
type="primary"
|
|
|
|
|
shape="circle"
|
|
|
|
|
@click="scrollToPayQr"
|
|
|
|
|
class="pay-btn-large"
|
|
|
|
|
:custom-style="{
|
|
|
|
|
width: '100%',
|
|
|
|
|
height: '88rpx',
|
|
|
|
|
fontSize: '32rpx',
|
|
|
|
|
fontWeight: '500'
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
立即支付
|
|
|
|
|
</u-button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 底部立即支付按钮 -->
|
|
|
|
|
<view v-if="orderInfo.pay_status === 0 && loginRole !== 'operator'" class="bottom-pay-btn">
|
|
|
|
|
<u-button
|
|
|
|
|
type="primary"
|
|
|
|
|
shape="circle"
|
|
|
|
|
@click="scrollToPayQr"
|
|
|
|
|
class="pay-btn"
|
|
|
|
|
>
|
|
|
|
|
立即支付
|
|
|
|
|
</u-button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
@ -180,6 +230,7 @@
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
myQrcode: '',
|
|
|
|
|
qrcodeImagePath: '', // 二维码图片路径
|
|
|
|
|
imgs: [],
|
|
|
|
|
orderId: '',
|
|
|
|
|
orderInfo: {},
|
|
|
|
|
@ -192,6 +243,7 @@
|
|
|
|
|
},
|
|
|
|
|
payTimer: null, // 支付状态检查定时器
|
|
|
|
|
isFromShare: false,
|
|
|
|
|
activeTab: 'qrcode', // 当前选中的 tab: 'qrcode' 或 'pay'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onLoad(options) {
|
|
|
|
|
@ -212,10 +264,7 @@
|
|
|
|
|
},
|
|
|
|
|
onUnload() {
|
|
|
|
|
// 清除支付状态检查定时器
|
|
|
|
|
if (this.payTimer) {
|
|
|
|
|
clearInterval(this.payTimer)
|
|
|
|
|
this.payTimer = null
|
|
|
|
|
}
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
|
|
|
|
// 清除分享相关存储
|
|
|
|
|
this.clearShareCache()
|
|
|
|
|
@ -303,12 +352,22 @@
|
|
|
|
|
})
|
|
|
|
|
this.imgs = _arr
|
|
|
|
|
}
|
|
|
|
|
// 只根据pay_status判断
|
|
|
|
|
if (res.pay_status === 0) {
|
|
|
|
|
// 如果订单已支付,停止支付状态检测
|
|
|
|
|
if (res.pay_status !== 0) {
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
this.myQrcode = ''
|
|
|
|
|
this.qrcodeImagePath = ''
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// 只在当前是二维码 tab 且订单未支付时,才获取二维码
|
|
|
|
|
if (res.pay_status === 0 && this.activeTab === 'qrcode') {
|
|
|
|
|
await this.getCode(res.no)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async getCode(no) {
|
|
|
|
|
// 如果已经有定时器在运行,先清除(避免重复创建)
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const res = await this.$u.api.accompanyPay({
|
|
|
|
|
no: no
|
|
|
|
|
@ -317,8 +376,12 @@
|
|
|
|
|
const result = res.result || res
|
|
|
|
|
if (result && result.code_url) {
|
|
|
|
|
this.myQrcode = result.code_url
|
|
|
|
|
// 开始检查支付状态
|
|
|
|
|
this.startPayCheck()
|
|
|
|
|
// 重置图片路径,等待二维码生成完成后转换为图片
|
|
|
|
|
this.qrcodeImagePath = ''
|
|
|
|
|
// 开始检查支付状态(只在二维码 tab 时启动)
|
|
|
|
|
if (this.activeTab === 'qrcode') {
|
|
|
|
|
this.startPayCheck()
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
@ -332,27 +395,77 @@
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 二维码生成完成回调
|
|
|
|
|
onQrcodeComplete(e) {
|
|
|
|
|
// 当二维码成功生成后,将其转换为图片
|
|
|
|
|
if (e && e.success && this.$refs.payQrcode) {
|
|
|
|
|
// 延迟一下,确保 canvas 完全渲染完成
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
if (this.$refs.payQrcode) {
|
|
|
|
|
this.$refs.payQrcode.toTempFilePath({
|
|
|
|
|
success: (res) => {
|
|
|
|
|
// 获取临时文件路径
|
|
|
|
|
this.qrcodeImagePath = res.tempFilePath
|
|
|
|
|
console.log('二维码图片生成成功:', this.qrcodeImagePath)
|
|
|
|
|
},
|
|
|
|
|
fail: (err) => {
|
|
|
|
|
console.error('二维码转图片失败:', err)
|
|
|
|
|
// 如果转换失败,仍然显示 canvas(虽然不能长按识别)
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: '二维码图片生成失败'
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}, 500) // 延迟 500ms 确保 canvas 渲染完成
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 停止支付状态检测
|
|
|
|
|
stopPayCheck() {
|
|
|
|
|
if (this.payTimer) {
|
|
|
|
|
clearInterval(this.payTimer)
|
|
|
|
|
this.payTimer = null
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 开始检查支付状态
|
|
|
|
|
startPayCheck() {
|
|
|
|
|
// 先清除旧的定时器,避免重复创建
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
|
|
|
|
// 如果订单已支付或不在二维码 tab,不启动检测
|
|
|
|
|
if (this.orderInfo.pay_status !== 0 || this.activeTab !== 'qrcode') {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.payTimer = setInterval(async () => {
|
|
|
|
|
// 如果不在二维码 tab 或订单已支付,停止检测
|
|
|
|
|
if (this.activeTab !== 'qrcode' || this.orderInfo.pay_status !== 0) {
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let res
|
|
|
|
|
res = await this.$u.api.accompanyOrderDetail({
|
|
|
|
|
const res = await this.$u.api.accompanyOrderDetail({
|
|
|
|
|
id: this.orderId
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 更新订单信息
|
|
|
|
|
if (res.pay_status !== this.orderInfo.pay_status) {
|
|
|
|
|
this.orderInfo = res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (res.pay_status === 1) {
|
|
|
|
|
clearInterval(this.payTimer)
|
|
|
|
|
this.payTimer = null
|
|
|
|
|
// 支付成功,停止检测
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
|
|
|
|
// 隐藏支付二维码
|
|
|
|
|
this.myQrcode = ''
|
|
|
|
|
this.qrcodeImagePath = ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新订单详情
|
|
|
|
|
await this.getOrderDetailStaff(this.orderId)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
title: '支付成功',
|
|
|
|
|
icon: 'success'
|
|
|
|
|
@ -360,20 +473,18 @@
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error('检查支付状态失败', err)
|
|
|
|
|
// 如果连续失败,可以考虑停止检测或增加重试逻辑
|
|
|
|
|
}
|
|
|
|
|
}, 3000) // 每3秒检查一次
|
|
|
|
|
},
|
|
|
|
|
isPayCode() {
|
|
|
|
|
// 清除定时器
|
|
|
|
|
if (this.payTimer) {
|
|
|
|
|
clearInterval(this.payTimer)
|
|
|
|
|
this.payTimer = null
|
|
|
|
|
}
|
|
|
|
|
// 停止支付状态检测
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
|
|
|
|
this.myQrcode = ''
|
|
|
|
|
this.qrcodeImagePath = ''
|
|
|
|
|
// 重新获取订单详情
|
|
|
|
|
this.getOrderDetailStaff(this.orderId)
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
showShareGuide() {
|
|
|
|
|
// 显示分享引导
|
|
|
|
|
@ -445,9 +556,28 @@
|
|
|
|
|
|
|
|
|
|
console.log('分享缓存数据已清除,下次进入将重新进行token校验')
|
|
|
|
|
},
|
|
|
|
|
// Tab 切换
|
|
|
|
|
async switchTab(tab) {
|
|
|
|
|
const previousTab = this.activeTab
|
|
|
|
|
this.activeTab = tab
|
|
|
|
|
|
|
|
|
|
// 如果切换到非二维码 tab,停止支付状态检测
|
|
|
|
|
if (tab !== 'qrcode') {
|
|
|
|
|
this.stopPayCheck()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 每次切换 tab 都重新请求接口,获取最新的订单信息(包含最新的 no)
|
|
|
|
|
await this.getOrderDetailStaff(this.orderId)
|
|
|
|
|
|
|
|
|
|
// getOrderDetailStaff 中会根据 activeTab 和 pay_status 决定是否调用 getCode
|
|
|
|
|
// 所以切换到 qrcode tab 时,如果订单未支付,会自动获取二维码并启动检测
|
|
|
|
|
},
|
|
|
|
|
scrollToPayQr: async function() {
|
|
|
|
|
// 每次点击都重新获取最新的订单信息(包含最新的 no)
|
|
|
|
|
await this.getOrderDetailStaff(this.orderId)
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 1. 获取微信支付参数(不需要传id参数)
|
|
|
|
|
// 1. 获取微信支付参数(使用最新的 no)
|
|
|
|
|
const res = await this.$u.api.accompanyOrderPayParams({ no: this.orderInfo.no });
|
|
|
|
|
console.log("获取支付参数:",res)
|
|
|
|
|
|
|
|
|
|
@ -565,6 +695,53 @@
|
|
|
|
|
box-shadow: 0 4rpx 16rpx #e6eaf1;
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
|
|
|
|
.payment-tabs {
|
|
|
|
|
display: flex;
|
|
|
|
|
border-bottom: 2rpx solid #e5e5e5;
|
|
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
|
|
|
|
|
.tab-item {
|
|
|
|
|
flex: 1;
|
|
|
|
|
text-align: center;
|
|
|
|
|
padding: 20rpx 0;
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
color: #666;
|
|
|
|
|
position: relative;
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
|
|
|
|
&.tab-active {
|
|
|
|
|
color: #1479ff;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
|
|
|
|
&::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: -2rpx;
|
|
|
|
|
left: 50%;
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
width: 60rpx;
|
|
|
|
|
height: 4rpx;
|
|
|
|
|
background: #1479ff;
|
|
|
|
|
border-radius: 2rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tab-content {
|
|
|
|
|
.tab-panel {
|
|
|
|
|
min-height: 400rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pay-button-section {
|
|
|
|
|
padding: 60rpx 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
color: #333;
|
|
|
|
|
|