|
|
<template>
|
|
|
<view>
|
|
|
<view class="detail-page">
|
|
|
<!-- 顶部导航 -->
|
|
|
<u-navbar
|
|
|
title="查看详情"
|
|
|
:is-back="true"
|
|
|
back-icon-color="#fff"
|
|
|
:background="{'background':'#1479ff'}"
|
|
|
title-color="#fff"
|
|
|
:border-bottom="false"
|
|
|
:custom-back="customBack"
|
|
|
></u-navbar>
|
|
|
<view class="b-border"></view>
|
|
|
<!-- 订单信息 -->
|
|
|
<view class="order-info">
|
|
|
<view class="info-item">
|
|
|
<text class="label">订单号</text>
|
|
|
<text class="value">{{orderInfo.no}}</text>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">服务项目</text>
|
|
|
<text class="value">{{orderInfo.accompany_product?orderInfo.accompany_product.name:''}}</text>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">服务时间</text>
|
|
|
<text class="value">{{orderInfo.time}}</text>
|
|
|
</view>
|
|
|
|
|
|
<view class="info-item" v-if="orderInfo.type === 2">
|
|
|
<text class="label">服务地址</text>
|
|
|
<text class="value">{{orderInfo.city?orderInfo.city:'' }}</text>
|
|
|
</view>
|
|
|
<view class="info-item" v-else>
|
|
|
<text class="label">就诊医院</text>
|
|
|
<text class="value">{{orderInfo.hospital?orderInfo.hospital.name:''}}</text>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">联系人</text>
|
|
|
<text class="value">{{orderInfo.appoint_name?orderInfo.appoint_name:''}}</text>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">联系方式</text>
|
|
|
<text class="value">{{orderInfo.appoint_mobile?orderInfo.appoint_mobile:''}}</text>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">被服务人</text>
|
|
|
<text class="value">{{orderInfo.user_archive?orderInfo.user_archive.name:''}}</text>
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="info-item">
|
|
|
<text class="label">是否可以自理</text>
|
|
|
<text class="value">{{orderInfo.my_provide===1?'可以自理':'不能自理'}}</text>
|
|
|
</view>
|
|
|
<view class="info-item info-item-reason">
|
|
|
<text class="label">就诊资料</text>
|
|
|
<view class="value">
|
|
|
<view class="order-item-img">
|
|
|
<image v-for="(item,index) in imgs" :src="item" @click="imgPreview(index)"></image>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">护工工资</text>
|
|
|
<text class="value">{{orderInfo.nurse_salary?orderInfo.nurse_salary:''}}</text>
|
|
|
</view>
|
|
|
<view class="info-item info-item-reason">
|
|
|
<text class="label">其他需求</text>
|
|
|
<text class="value">{{orderInfo.content?orderInfo.content:''}}</text>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">购买数量</text>
|
|
|
<text class="value">{{orderInfo.can_multi_num || 1}}</text>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<text class="label">订单金额</text>
|
|
|
<text class="value">¥{{orderInfo.price}}</text>
|
|
|
</view>
|
|
|
|
|
|
<view class="info-item">
|
|
|
<text class="label">原始金额</text>
|
|
|
<text class="value">¥{{orderInfo.from_price}}</text>
|
|
|
</view>
|
|
|
|
|
|
<view class="info-item" v-if="orderInfo.status===3||orderInfo.status===4">
|
|
|
<text class="label">待付金额</text>
|
|
|
<text class="value price">¥{{orderInfo.diff_price}}</text>
|
|
|
</view>
|
|
|
<view class="info-item info-item-reason">
|
|
|
<text class="label">修改原因</text>
|
|
|
<text class="value reason">{{orderInfo.update_price_reason?orderInfo.update_price_reason:''}}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 支付区域 -->
|
|
|
<view class="payment-popup" v-if="orderInfo.pay_status === 0" id="pay-qrcode-section">
|
|
|
<!-- Tab 切换 -->
|
|
|
<view class="payment-tabs">
|
|
|
<view
|
|
|
class="tab-item"
|
|
|
:class="{ 'tab-active': activeTab === 'qrcode' }"
|
|
|
@click="switchTab('qrcode')"
|
|
|
>
|
|
|
付款二维码
|
|
|
</view>
|
|
|
<view
|
|
|
class="tab-item"
|
|
|
:class="{ 'tab-active': activeTab === 'pay' }"
|
|
|
@click="switchTab('pay')"
|
|
|
>
|
|
|
立即支付
|
|
|
</view>
|
|
|
</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="qr-code">
|
|
|
<!-- 支付二维码 -->
|
|
|
<view v-if="myQrcode" style="border: 1px solid #ccc; padding: 10rpx; position: relative;">
|
|
|
<!-- 显示图片(可长按识别) -->
|
|
|
<image
|
|
|
v-if="qrcodeImagePath"
|
|
|
:src="qrcodeImagePath"
|
|
|
mode="aspectFit"
|
|
|
show-menu-by-longpress
|
|
|
:class="{ 'qrcode-disabled': qrcodeExpired }"
|
|
|
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 v-if="qrcodeExpired" class="qrcode-overlay" @click="regetQrcode">
|
|
|
<view class="reget-btn">
|
|
|
<text>重新获取</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</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"
|
|
|
:disabled="payCooldownSeconds > 0"
|
|
|
class="pay-btn-large"
|
|
|
:custom-style="{
|
|
|
width: '100%',
|
|
|
height: '88rpx',
|
|
|
fontSize: '32rpx',
|
|
|
fontWeight: '500',
|
|
|
opacity: payCooldownSeconds > 0 ? 0.6 : 1
|
|
|
}"
|
|
|
>
|
|
|
{{ payCooldownSeconds > 0 ? `支付成功,${payCooldownSeconds}秒后可再次支付` : '立即支付' }}
|
|
|
</u-button>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import uqrcode from "@/uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue";
|
|
|
export default {
|
|
|
components: {
|
|
|
uqrcode
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
myQrcode: '',
|
|
|
qrcodeImagePath: '', // 二维码图片路径
|
|
|
qrcodeExpired: false, // 二维码是否失效
|
|
|
imgs: [],
|
|
|
orderId: '',
|
|
|
orderInfo: {},
|
|
|
parStyle: {
|
|
|
'background': 'linear-gradient(to right, #476de4, #7bb9f7)',
|
|
|
'color': '#fff',
|
|
|
'font-size': '28rpx',
|
|
|
'padding': '0 30rpx',
|
|
|
'margin-left': '15rpx'
|
|
|
},
|
|
|
payTimer: null, // 支付状态检查定时器
|
|
|
isFromShare: false,
|
|
|
activeTab: 'qrcode', // 当前选中的 tab: 'qrcode' 或 'pay'
|
|
|
paySuccessTime: null, // 支付成功的时间戳
|
|
|
payCooldownSeconds: 0, // 支付冷却倒计时(秒)
|
|
|
payCooldownTimer: null, // 支付冷却定时器
|
|
|
}
|
|
|
},
|
|
|
onLoad(options) {
|
|
|
// 获取订单详情
|
|
|
this.orderId = options.id
|
|
|
|
|
|
// 检查是否从分享链接进入
|
|
|
this.isFromShare = uni.getStorageSync('isFromShare')
|
|
|
const isOrderDetailShare = uni.getStorageSync('isOrderDetailShare')
|
|
|
|
|
|
if (this.isFromShare && isOrderDetailShare) {
|
|
|
console.log('订单详情页检测到从分享链接进入')
|
|
|
console.log('分享查询参数:', uni.getStorageSync('shareQuery'))
|
|
|
console.log('分享推荐者信息:', uni.getStorageSync('shareReferrer'))
|
|
|
console.log('分享进入时间:', uni.getStorageSync('shareLaunchTime'))
|
|
|
}
|
|
|
this.getOrderDetailStaff(options.id)
|
|
|
},
|
|
|
onUnload() {
|
|
|
// 清除支付状态检查定时器
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
// 清除支付冷却定时器
|
|
|
this.stopPayCooldown()
|
|
|
|
|
|
// 清除分享相关存储
|
|
|
this.clearShareCache()
|
|
|
},
|
|
|
// 微信小程序分享给好友
|
|
|
onShareAppMessage() {
|
|
|
if (this.orderInfo.pay_status === 0) {
|
|
|
return {
|
|
|
title: `医康养${this.orderInfo.accompany_product ? this.orderInfo.accompany_product.name : '服务'}订单`,
|
|
|
desc: `订单号:${this.orderInfo.no},金额:¥${this.orderInfo.price}`,
|
|
|
path: `/package_sub/order/orderStaffDetail?id=${this.orderId}`,
|
|
|
imageUrl: this.orderInfo.accompany_product && this.orderInfo.accompany_product.cover ? this.orderInfo.accompany_product.cover.url : ''
|
|
|
}
|
|
|
}
|
|
|
return {
|
|
|
title: '医康养服务',
|
|
|
path: '/pages/index/index'
|
|
|
}
|
|
|
},
|
|
|
// 微信小程序分享到朋友圈
|
|
|
onShareTimeline() {
|
|
|
if (this.orderInfo.pay_status === 0) {
|
|
|
return {
|
|
|
title: `医康养${this.orderInfo.accompany_product ? this.orderInfo.accompany_product.name : '服务'}订单`,
|
|
|
query: `id=${this.orderId}`,
|
|
|
imageUrl: this.orderInfo.accompany_product && this.orderInfo.accompany_product.cover ? this.orderInfo.accompany_product.cover.url : ''
|
|
|
}
|
|
|
}
|
|
|
return {
|
|
|
title: '医康养服务',
|
|
|
query: '',
|
|
|
imageUrl: ''
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
// 自定义返回逻辑
|
|
|
customBack() {
|
|
|
// 检查页面栈
|
|
|
const pages = getCurrentPages()
|
|
|
console.log('当前页面栈:', pages.length)
|
|
|
|
|
|
// 检查是否从分享链接进入
|
|
|
const isFromShare = uni.getStorageSync('isFromShare')
|
|
|
const isOrderDetailShare = uni.getStorageSync('isOrderDetailShare')
|
|
|
|
|
|
if ((isFromShare && isOrderDetailShare) || pages.length <= 1) {
|
|
|
// 从订单详情分享进入或页面栈只有一页时,返回首页
|
|
|
console.log('从订单详情分享进入或页面栈只有一页,返回首页')
|
|
|
uni.showToast({
|
|
|
title: '返回首页',
|
|
|
icon: 'none'
|
|
|
})
|
|
|
|
|
|
// 清除分享相关的缓存数据
|
|
|
this.clearShareCache()
|
|
|
|
|
|
|
|
|
uni.reLaunch({
|
|
|
url: '/package_sub/login/login'
|
|
|
})
|
|
|
|
|
|
} else {
|
|
|
// 正常进入时,使用默认返回逻辑
|
|
|
uni.navigateBack({
|
|
|
delta: 1
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
imgPreview(index) {
|
|
|
uni.previewImage({
|
|
|
current: index, // 当前显示图片索引
|
|
|
urls: this.imgs // 需要预览的图片http链接列表
|
|
|
});
|
|
|
},
|
|
|
async getOrderDetailStaff(orderId) {
|
|
|
// 调用接口获取订单详情
|
|
|
const res = await this.$u.api.accompanyOrderDetail({
|
|
|
id: orderId
|
|
|
})
|
|
|
this.orderInfo = res
|
|
|
let _arr = []
|
|
|
if (res.files.length > 0) {
|
|
|
res.files.map(item => {
|
|
|
_arr.push(item.url)
|
|
|
})
|
|
|
this.imgs = _arr
|
|
|
}
|
|
|
// 如果订单已支付,停止支付状态检测
|
|
|
if (res.pay_status !== 0) {
|
|
|
this.stopPayCheck()
|
|
|
this.myQrcode = ''
|
|
|
this.qrcodeImagePath = ''
|
|
|
this.qrcodeExpired = false
|
|
|
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
|
|
|
})
|
|
|
if(res.errcode && res.errcode===10002){
|
|
|
// 设置二维码失效状态
|
|
|
this.qrcodeExpired = true
|
|
|
uni.showToast({
|
|
|
title: res.errmsg,
|
|
|
icon: 'none'
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
// 如果成功获取二维码,重置失效状态
|
|
|
this.qrcodeExpired = false
|
|
|
const result = res.result || res
|
|
|
if (result && result.code_url) {
|
|
|
this.myQrcode = result.code_url
|
|
|
// 重置图片路径,等待二维码生成完成后转换为图片
|
|
|
this.qrcodeImagePath = ''
|
|
|
// 开始检查支付状态(只在二维码 tab 时启动)
|
|
|
if (this.activeTab === 'qrcode') {
|
|
|
this.startPayCheck()
|
|
|
}
|
|
|
} else {
|
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: result.err_code_des || '获取二维码失败'
|
|
|
})
|
|
|
}
|
|
|
} catch (error) {
|
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: '获取二维码失败'
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
// 重新获取二维码
|
|
|
regetQrcode() {
|
|
|
if (this.orderInfo && this.orderInfo.no) {
|
|
|
this.getCode(this.orderInfo.no)
|
|
|
}
|
|
|
},
|
|
|
// 二维码生成完成回调
|
|
|
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
|
|
|
}
|
|
|
},
|
|
|
// 启动支付冷却期(30秒)
|
|
|
startPayCooldown() {
|
|
|
// 先清除旧的定时器
|
|
|
this.stopPayCooldown()
|
|
|
|
|
|
// 设置冷却时间为30秒
|
|
|
this.payCooldownSeconds = 30
|
|
|
this.paySuccessTime = Date.now()
|
|
|
|
|
|
// 启动倒计时定时器
|
|
|
this.payCooldownTimer = setInterval(() => {
|
|
|
this.payCooldownSeconds--
|
|
|
|
|
|
if (this.payCooldownSeconds <= 0) {
|
|
|
// 冷却期结束
|
|
|
this.stopPayCooldown()
|
|
|
}
|
|
|
}, 1000) // 每秒更新一次
|
|
|
},
|
|
|
// 停止支付冷却期
|
|
|
stopPayCooldown() {
|
|
|
if (this.payCooldownTimer) {
|
|
|
clearInterval(this.payCooldownTimer)
|
|
|
this.payCooldownTimer = null
|
|
|
}
|
|
|
this.payCooldownSeconds = 0
|
|
|
this.paySuccessTime = 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 {
|
|
|
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) {
|
|
|
// 支付成功,停止检测
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
// 隐藏支付二维码
|
|
|
this.myQrcode = ''
|
|
|
this.qrcodeImagePath = ''
|
|
|
|
|
|
// 刷新订单详情
|
|
|
await this.getOrderDetailStaff(this.orderId)
|
|
|
|
|
|
uni.showToast({
|
|
|
title: '支付成功',
|
|
|
icon: 'success'
|
|
|
})
|
|
|
}
|
|
|
} catch (err) {
|
|
|
console.error('检查支付状态失败', err)
|
|
|
// 如果连续失败,可以考虑停止检测或增加重试逻辑
|
|
|
}
|
|
|
}, 3000) // 每3秒检查一次
|
|
|
},
|
|
|
isPayCode() {
|
|
|
// 停止支付状态检测
|
|
|
this.stopPayCheck()
|
|
|
|
|
|
this.myQrcode = ''
|
|
|
this.qrcodeImagePath = ''
|
|
|
this.qrcodeExpired = false
|
|
|
// 重新获取订单详情
|
|
|
this.getOrderDetailStaff(this.orderId)
|
|
|
},
|
|
|
showShareGuide() {
|
|
|
// 显示分享引导
|
|
|
uni.showModal({
|
|
|
title: '转发给微信好友',
|
|
|
content: `订单号:${this.orderInfo.no}\n金额:¥${this.orderInfo.price}\n服务:${this.orderInfo.accompany_product ? this.orderInfo.accompany_product.name : '医康养服务'}\n\n请点击右上角"..."按钮,选择"转发"`,
|
|
|
confirmText: '知道了',
|
|
|
showCancel: false,
|
|
|
success: () => {
|
|
|
// 显示分享菜单
|
|
|
// #ifdef MP-WEIXIN
|
|
|
wx.showShareMenu({
|
|
|
withShareTicket: true,
|
|
|
menus: ['shareAppMessage'],
|
|
|
success: () => {
|
|
|
uni.showToast({
|
|
|
title: '请点击右上角转发',
|
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
|
})
|
|
|
}
|
|
|
})
|
|
|
// #endif
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
// 测试分享状态的方法
|
|
|
testShareStatus() {
|
|
|
const isFromShare = uni.getStorageSync('isFromShare')
|
|
|
const shareQuery = uni.getStorageSync('shareQuery')
|
|
|
const shareReferrer = uni.getStorageSync('shareReferrer')
|
|
|
const shareLaunchTime = uni.getStorageSync('shareLaunchTime')
|
|
|
|
|
|
console.log('=== 分享状态测试 ===')
|
|
|
console.log('是否从分享进入:', isFromShare)
|
|
|
console.log('分享查询参数:', shareQuery)
|
|
|
console.log('分享推荐者:', shareReferrer)
|
|
|
console.log('分享进入时间:', shareLaunchTime)
|
|
|
|
|
|
uni.showModal({
|
|
|
title: '分享状态测试',
|
|
|
content: `从分享进入: ${isFromShare}\n查询参数: ${JSON.stringify(shareQuery)}\n推荐者: ${JSON.stringify(shareReferrer)}`,
|
|
|
showCancel: false
|
|
|
})
|
|
|
},
|
|
|
goToHome() {
|
|
|
// 返回首页的逻辑
|
|
|
console.log('返回首页')
|
|
|
|
|
|
// 清除分享相关的缓存数据
|
|
|
this.clearShareCache()
|
|
|
|
|
|
|
|
|
uni.reLaunch({
|
|
|
url: '/package_sub/login/login'
|
|
|
})
|
|
|
|
|
|
},
|
|
|
clearShareCache() {
|
|
|
// 清除分享相关的缓存数据
|
|
|
console.log('清除分享相关的缓存数据')
|
|
|
|
|
|
// 清除所有分享相关的存储
|
|
|
uni.removeStorageSync('isFromShare')
|
|
|
uni.removeStorageSync('shareLaunchTime')
|
|
|
uni.removeStorageSync('shareQuery')
|
|
|
uni.removeStorageSync('shareReferrer')
|
|
|
uni.removeStorageSync('isOrderDetailShare')
|
|
|
|
|
|
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() {
|
|
|
// 检查是否在支付冷却期内
|
|
|
if (this.payCooldownSeconds > 0) {
|
|
|
uni.showToast({
|
|
|
title: `支付成功后${this.payCooldownSeconds}秒内不能重复支付`,
|
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 每次点击都重新获取最新的订单信息(包含最新的 no)
|
|
|
await this.getOrderDetailStaff(this.orderId)
|
|
|
|
|
|
try {
|
|
|
// 1. 获取微信支付参数(使用最新的 no)
|
|
|
const res = await this.$u.api.accompanyOrderPayParams({ no: this.orderInfo.no });
|
|
|
console.log("获取支付参数:", res,res.errcode && res.errcode===10002);
|
|
|
if(res.errcode && res.errcode===10002){
|
|
|
uni.showToast({
|
|
|
title: res.errmsg,
|
|
|
icon: 'none'
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
// 从嵌套的config对象中获取支付参数
|
|
|
const payConfig = res.config || res;
|
|
|
|
|
|
// 2. 发起微信支付
|
|
|
await uni.requestPayment({
|
|
|
provider: 'wxpay',
|
|
|
timeStamp: payConfig.timestamp || payConfig.timeStamp,
|
|
|
nonceStr: payConfig.nonceStr,
|
|
|
package: payConfig.package,
|
|
|
signType: payConfig.signType,
|
|
|
paySign: payConfig.paySign,
|
|
|
success: () => {
|
|
|
uni.showToast({ title: '支付成功', icon: 'success' });
|
|
|
// 支付成功后刷新订单详情
|
|
|
this.getOrderDetailStaff(this.orderId || this.orderInfo.id);
|
|
|
// 启动支付冷却期(30秒)
|
|
|
this.startPayCooldown();
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
if (err.errMsg && err.errMsg.indexOf('cancel') > -1) {
|
|
|
uni.showToast({ title: '已取消支付', icon: 'none' });
|
|
|
} else {
|
|
|
uni.showToast({ title: '支付失败', icon: 'none' });
|
|
|
console.log("支付失败",err)
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
} catch (e) {
|
|
|
uni.showToast({ title: e.errmsg || '拉起支付失败', icon: 'none' });
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
computed: {
|
|
|
// 获取登录角色
|
|
|
loginRole() {
|
|
|
return uni.getStorageSync('login_role') || '';
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.detail-page {
|
|
|
min-height: 100vh;
|
|
|
background: #f5f5f5;
|
|
|
padding-bottom: 120rpx;
|
|
|
|
|
|
.b-border {
|
|
|
width: 100%;
|
|
|
height: 30rpx;
|
|
|
border-radius: 0 0 120rpx 120rpx;
|
|
|
background-color: #1479ff;
|
|
|
}
|
|
|
|
|
|
.order-info {
|
|
|
background: #fff;
|
|
|
border-radius: 20rpx;
|
|
|
margin: 30rpx;
|
|
|
box-shadow: 0 4rpx 16rpx #e6eaf1;
|
|
|
padding: 0 30rpx;
|
|
|
|
|
|
.info-item {
|
|
|
padding: 30rpx;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
// margin-bottom: 30rpx;
|
|
|
border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
.label {
|
|
|
color: #666;
|
|
|
font-size: 28rpx;
|
|
|
width:180rpx;
|
|
|
}
|
|
|
|
|
|
.value {
|
|
|
color: #333;
|
|
|
font-size: 28rpx;
|
|
|
width:calc(100% - 190rpx);
|
|
|
text-align: right;
|
|
|
// &.price {
|
|
|
// color: #f56c6c;
|
|
|
// font-weight: bold;
|
|
|
// }
|
|
|
&.reason {
|
|
|
color: #999;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.info-item-reason {
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
&>text {
|
|
|
width: 100%
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.order-item-img {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
image {
|
|
|
width: 140rpx;
|
|
|
height: 140rpx;
|
|
|
margin: 10rpx;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.payment-popup {
|
|
|
background: #fff;
|
|
|
border-radius: 20rpx;
|
|
|
margin: 30rpx;
|
|
|
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;
|
|
|
text-align: center;
|
|
|
font-weight: 500;
|
|
|
margin-bottom: 20rpx;
|
|
|
}
|
|
|
|
|
|
.amount {
|
|
|
text-align: center;
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
.symbol {
|
|
|
font-size: 36rpx;
|
|
|
color: #000;
|
|
|
}
|
|
|
|
|
|
.number {
|
|
|
font-size: 48rpx;
|
|
|
color: #d80808;
|
|
|
font-weight: bold;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.qr-code {
|
|
|
width: 400rpx;
|
|
|
height: 400rpx;
|
|
|
margin: 0 auto 20rpx;
|
|
|
background: #fff;
|
|
|
padding: 20rpx;
|
|
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
|
|
|
image {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
|
|
|
&.qrcode-disabled {
|
|
|
filter: grayscale(100%);
|
|
|
opacity: 0.5;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.qrcode-overlay {
|
|
|
position: absolute;
|
|
|
top: 10rpx;
|
|
|
left: 10rpx;
|
|
|
right: 10rpx;
|
|
|
bottom: 10rpx;
|
|
|
background: rgba(0, 0, 0, 0.5);
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
border-radius: 8rpx;
|
|
|
|
|
|
.reget-btn {
|
|
|
background: #1479ff;
|
|
|
color: #fff;
|
|
|
padding: 20rpx 40rpx;
|
|
|
border-radius: 40rpx;
|
|
|
font-size: 28rpx;
|
|
|
font-weight: 500;
|
|
|
cursor: pointer;
|
|
|
|
|
|
&:active {
|
|
|
opacity: 0.8;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.tips {
|
|
|
text-align: center;
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
text {
|
|
|
display: block;
|
|
|
color: #333;
|
|
|
font-size: 28rpx;
|
|
|
line-height: 1.8;
|
|
|
}
|
|
|
|
|
|
.sub-tips {
|
|
|
color: #999;
|
|
|
font-size: 24rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.close-btn {
|
|
|
width: 80%;
|
|
|
margin: 0 auto;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
.share-section {
|
|
|
text-align: center;
|
|
|
margin-top: 20rpx;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.bottom-pay-btn {
|
|
|
position: fixed;
|
|
|
left: 0;
|
|
|
bottom: 0;
|
|
|
width: 100vw;
|
|
|
background: #fff;
|
|
|
z-index: 9999;
|
|
|
box-shadow: 0 -2rpx 8rpx #00000010;
|
|
|
padding: 20rpx 30rpx 40rpx 30rpx;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
.pay-btn {
|
|
|
width: 100%;
|
|
|
font-size: 32rpx;
|
|
|
border-radius: 40rpx;
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
}
|
|
|
</style> |