You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

656 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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">{{item.city?item.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 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">
<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>
</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>
</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>
<script>
import uqrcode from "@/uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue";
export default {
components: {
uqrcode
},
data() {
return {
myQrcode: '',
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,
}
},
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() {
// 清除支付状态检查定时器
if (this.payTimer) {
clearInterval(this.payTimer)
this.payTimer = null
}
// 清除分享相关存储
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
}
// 只根据pay_status判断
if (res.pay_status === 0) {
await this.getCode(res.no)
}
},
async getCode(no) {
try {
const res = await this.$u.api.accompanyPay({
no: no
})
const result = res.result || res
if (result && result.code_url) {
this.myQrcode = result.code_url
// 开始检查支付状态
this.startPayCheck()
} else {
uni.showToast({
icon: 'none',
title: result.err_code_des || '获取二维码失败'
})
}
} catch (error) {
uni.showToast({
icon: 'none',
title: '获取二维码失败'
})
}
},
// 开始检查支付状态
startPayCheck() {
this.payTimer = setInterval(async () => {
try {
let res
res = await this.$u.api.accompanyOrderDetail({
id: this.orderId
})
if (res.pay_status === 1) {
clearInterval(this.payTimer)
this.payTimer = null
// 隐藏支付二维码
this.myQrcode = ''
await this.getOrderDetailStaff(this.orderId)
uni.showToast({
title: '支付成功',
icon: 'success'
})
}
} catch (err) {
console.error('检查支付状态失败', err)
}
}, 3000) // 每3秒检查一次
},
isPayCode() {
// 清除定时器
if (this.payTimer) {
clearInterval(this.payTimer)
this.payTimer = null
}
this.myQrcode = ''
// 重新获取订单详情
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校验')
},
scrollToPayQr: async function() {
try {
// 1. 获取微信支付参数不需要传id参数
const res = await this.$u.api.accompanyOrderPayParams({ no: this.orderInfo.no });
console.log("获取支付参数:",res)
// 从嵌套的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);
},
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;
}
.value {
color: #333;
font-size: 28rpx;
// &.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;
.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%;
}
}
.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>