484 lines
15 KiB
Vue
484 lines
15 KiB
Vue
<template>
|
||
<view class="content">
|
||
<myNav title="咨询订单" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="backHomeFlag" :flex="false"></myNav>
|
||
|
||
|
||
<scroll-view :scroll-y="enableScroll" @scrolltolower="scrolltolower" class="scroll-style"
|
||
:style="{ height: `${showHight}rpx` }">
|
||
|
||
<view ref="contentRef" id="contentContainer" style="display:flex;align-items:center;flex-direction:column;"
|
||
v-if="orderList.length>0">
|
||
|
||
<view v-for="(item,index) in orderList" :key="index" @click="toDetail(item)"
|
||
style="width: 670rpx;background-color: #fff;padding: 40rpx;display: flex;flex-direction: column;margin-top: 40rpx; box-sizing: border-box;border-radius: 10rpx;">
|
||
<view style="display: flex;">
|
||
<image :src="item.avatar" style="width: 120rpx;height: 120rpx;border-radius: 10rpx;">
|
||
</image>
|
||
<view style="display: flex;flex-direction: column;margin-left: 20rpx;">
|
||
<text class="show-name">{{ item.name }}</text>
|
||
<view style="display: flex; align-items: last baseline;" v-if="item.consultationMethod == 'face_to_face'">
|
||
<image src="/static/n-zx/face-to-face.png" style="width: 26rpx;height: 28.66rpx;"></image>
|
||
<text class="consult-method-text" style="margin-left: 10rpx;">面对面咨询·1次</text>
|
||
</view>
|
||
<view style="display: flex; align-items: last baseline;" v-if="item.consultationMethod == 'video'">
|
||
<image src="/static/n-zx/video-camera.png" style="width: 26rpx;height: 28.66rpx;"></image>
|
||
<text class="consult-method-text" style="margin-left: 10rpx;">视频咨询·1次</text>
|
||
</view>
|
||
</view>
|
||
<view style="flex: 1;text-align: right;display: flex;flex-direction: column;">
|
||
<text class="order-status-text1" v-if="item.status== 0 ">待支付</text>
|
||
<text class="order-status-text1" v-if="item.status== 1 ">待咨询</text>
|
||
<text class="order-status-text1" v-if="item.status== 4 ">待确认</text>
|
||
<text class="order-status-text1" v-if="item.status== 5 ">已完成</text>
|
||
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 6 ">申请退款中</text>
|
||
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 7 ">退款中</text>
|
||
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 8 ">已退款</text>
|
||
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 9 ">交易关闭</text>
|
||
<view style="">
|
||
<text class="rmb-text">¥{{ advancedFormat(item.totalAmount) }}</text>
|
||
<!-- <text class="effect-time-text">/{{ calculateTimeDifference(item.startTime, item.endTime) }}分钟</text> -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view
|
||
style="border-radius: 10rpx;background-color: #F7F4F3;padding: 20rpx;display: flex;margin-top: 20rpx;align-items: first baseline;">
|
||
<image src="/static/n-zx/notice-icon.png" style="width:21rpx ;height:18.48rpx;"></image>
|
||
<view style="line-height: 24rpx;" v-if="item.status==0">
|
||
<text class="order-text"
|
||
style="margin-left: 10rpx;color: #186BF9;flex-wrap: nowrap;">
|
||
{{ item.validTime.split('T').join(' ') }}
|
||
</text>
|
||
<text class="order-text">前未支付,订单将自动取消,请及时完成支付</text>
|
||
</view>
|
||
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==1">
|
||
<text class="order-text" @click="toConsultAppointment">支付成功,等待执行,相关详情请查看
|
||
<text style="color: #186BF9;">《预约须知》</text>
|
||
</text>
|
||
</view>
|
||
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==4">
|
||
<text class="order-text">等待客服确认本次咨询</text>
|
||
</view>
|
||
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==5">
|
||
<text class="order-text">订单已完成</text>
|
||
</view>
|
||
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==6">
|
||
<text class="order-text">申请退款中,请耐心等待</text>
|
||
</view>
|
||
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==7">
|
||
<text class="order-text">退款已受理,将会在1个工作日内返回到支付账户</text>
|
||
</view>
|
||
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==8">
|
||
<text class="order-text">退款金额已成功返回到支付账户</text>
|
||
</view>
|
||
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==9">
|
||
<text class="order-text" v-if="item.cancelFlag == 1">支付超时,已关闭交易</text>
|
||
<text class="order-text" v-if="item.cancelFlag == 2">订单已取消</text>
|
||
</view>
|
||
</view>
|
||
<view style="margin-top: 20rpx;display: flex;justify-content: space-between;align-items: center;">
|
||
<view style="display: flex;flex-direction: column;">
|
||
<!-- <view style="display: flex;align-items: baseline">
|
||
<text class="rmb-text">¥{{ advancedFormat(item.totalAmount) }}</text>
|
||
<text class="effect-time-text">/{{ calculateTimeDifference(item.startTime, item.endTime) }}分钟</text>
|
||
</view> -->
|
||
<text class="time-text">{{ item.createTime.split('T').join(' ') }}</text>
|
||
</view>
|
||
<view class="btn1" v-if="item.status==0" @click.stop="cancelOrder(item)">
|
||
<text class="btn-text1">取消订单</text>
|
||
</view>
|
||
<view class="btn" v-if="item.status==0" @click.stop="toPay(item)">
|
||
<text class="btn-text">立即支付</text>
|
||
</view>
|
||
|
||
<view class="btn" v-if="item.status==1">
|
||
<button plain class="contact-btn" open-type="contact">
|
||
<text class="btn-text">联系助理</text>
|
||
</button>
|
||
</view>
|
||
|
||
|
||
<view class="btn1" v-if="item.status==8||item.status==9" @click.stop="deleteOrder(item)">
|
||
<text class="btn-text1">删除订单</text>
|
||
</view>
|
||
<!-- <view class="btn" v-if="item.status==8" style="width: 40%;margin-left: 5%" @click.stop="findOtherDoctor">
|
||
<text class="btn-text">预约其他咨询师</text>
|
||
</view> -->
|
||
<view class="btn" v-if="item.status==4||item.status==5||item.status==9||item.status==8" @click.stop="consultAgain(item)">
|
||
<text class="btn-text">再次咨询</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
<view ref="contentRef" id="contentContainer" style="display:flex;align-items:center;flex-direction:column;width: 100%;height: 100%;
|
||
display: flex;align-items: center;justify-content: center"
|
||
v-if="orderList.length==0">
|
||
<text style="font-size: 30rpx;font-family: SourceHanSansBold;color: #EA4E2D">暂无订单数据</text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import myNav from '@/components/my-nav.vue'
|
||
import {
|
||
urls
|
||
} from '@/util/apiUrl.js'
|
||
import dohttp from '@/util/requestConfig.js'
|
||
|
||
const backHomeFlag = ref(false)
|
||
onLoad((option) => {
|
||
if(option.backHome && option.backHome == 1){
|
||
backHomeFlag.value=true
|
||
}
|
||
if (option.num && option.num > 0) {
|
||
toOrderRead()
|
||
}
|
||
|
||
requestParam.value.pageNo = 1
|
||
orderList.value = []
|
||
const systemInfo = uni.getSystemInfoSync()
|
||
// 更精准的高度计算
|
||
showHight.value = (systemInfo.windowHeight * (750 / systemInfo.screenWidth)) - 200
|
||
getOrderList()
|
||
|
||
|
||
})
|
||
const timeToMinutes = (timeStr) => {
|
||
const [hours, minutes] = timeStr.split(':').map(Number);
|
||
return hours * 60 + minutes;
|
||
}
|
||
|
||
// 计算时间差(处理跨天情况)
|
||
const calculateTimeDifference = (startTime, endTime) => {
|
||
const startMinutes = timeToMinutes(startTime);
|
||
const endMinutes = timeToMinutes(endTime);
|
||
let diff = endMinutes - startMinutes;
|
||
// 如果跨天(结束时间早于开始时间),补上24小时
|
||
if (diff < 0) diff += 24 * 60;
|
||
return diff;
|
||
}
|
||
|
||
const advancedFormat = (num) => {
|
||
const divided = Number(num) / 100;
|
||
// 转换为字符串处理科学计数法(如1e-7)
|
||
const str = divided.toLocaleString('en-US', {
|
||
maximumFractionDigits: 2,
|
||
useGrouping: false
|
||
});
|
||
return str.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, '');
|
||
}
|
||
|
||
|
||
import {
|
||
ref,
|
||
onMounted,
|
||
nextTick,
|
||
getCurrentInstance
|
||
} from 'vue'
|
||
|
||
const showHight = ref(0)
|
||
const instance = getCurrentInstance()
|
||
const enableScroll = ref(false) // 新增动态滚动控制
|
||
|
||
|
||
// 新增高度检查方法
|
||
const checkContentHeight = () => {
|
||
const query = uni.createSelectorQuery().in(instance.proxy)
|
||
query.select('#contentContainer').boundingClientRect(rect => {
|
||
if (rect) {
|
||
const systemInfo = uni.getSystemInfoSync()
|
||
|
||
// 转换为rpx比较
|
||
// 计算容器实际像素高度
|
||
const containerHeightPx = (showHight.value * systemInfo.screenWidth) / 750
|
||
const threshold = 5 // 容错阈值
|
||
|
||
enableScroll.value = rect.height > (containerHeightPx + threshold)
|
||
// console.log('[Layout Debug]', {
|
||
// contentHeight: rect.height,
|
||
// containerPx: containerHeightPx,
|
||
// containerRpx: showHight.value,
|
||
// shouldScroll: enableScroll.value
|
||
// })
|
||
}
|
||
}).exec()
|
||
}
|
||
|
||
// 初始加载检查
|
||
onMounted(() => {
|
||
nextTick(checkContentHeight)
|
||
})
|
||
|
||
const orderList = ref([])
|
||
const toOrderRead = () => {
|
||
dohttp.post(urls.orderToRead).then((result) => {
|
||
|
||
})
|
||
}
|
||
|
||
const onShareAppMessage = () => {
|
||
return {
|
||
title: '快来体验一下吧~',
|
||
path: '/pages/index/index', // 分享的路径
|
||
};
|
||
};
|
||
|
||
const onShareTimeline = () => {
|
||
return {
|
||
title: '快来体验一下吧~',
|
||
query: 'id=5', // 分享路径的参数
|
||
};
|
||
};
|
||
|
||
const requestParam = ref({
|
||
pageNo: 1,
|
||
pageSize: 10
|
||
})
|
||
const totalNum = ref(0)
|
||
const getOrderList = () => {
|
||
dohttp.post(urls.orderList, requestParam.value).then((result) => {
|
||
orderList.value = [...orderList.value, ...result.list]
|
||
totalNum.value = result.totalNum
|
||
// 确保图片加载完成
|
||
nextTick(() => {
|
||
setTimeout(() => {
|
||
checkContentHeight()
|
||
// 添加重试机制
|
||
if (!enableScroll.value) setTimeout(checkContentHeight, 500)
|
||
}, 300)
|
||
})
|
||
})
|
||
}
|
||
|
||
|
||
const findOtherDoctor = () => {
|
||
uni.switchTab({
|
||
"url": "/pages/consult/consult",
|
||
"animationType": "pop-in"
|
||
})
|
||
}
|
||
|
||
|
||
const deleteOrder = (item) => {
|
||
|
||
uni.showModal({
|
||
content: '是否删除该订单信息,删除后将不能恢复',
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
dohttp.post(urls.deleteOrder + "?orderId=" + item.id).then((result) => {
|
||
if (result) {
|
||
orderList.value = orderList.value.filter(order => order.id !== item.id);
|
||
// getOrderList()
|
||
uni.showToast({
|
||
title: '删除成功',
|
||
duration: 1500
|
||
});
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
const consultAgain = (item) => {
|
||
dohttp.navigateTo("/pages/consult-detail/consult-detail?id=" + item.doctorId)
|
||
}
|
||
|
||
const toPay = (item) => {
|
||
let params = {
|
||
orderSn: item.orderSn
|
||
}
|
||
dohttp.get(urls.getPayParam, params).then((result) => {
|
||
console.log("urls.getPayParam", result)
|
||
uni.requestPayment({
|
||
provider: 'wxpay',
|
||
timeStamp: result.timeStamp,
|
||
nonceStr: result.nonceStr,
|
||
package: result.packageStr,
|
||
signType: result.signType,
|
||
paySign: result.paySign,
|
||
success: function (res) {
|
||
console.log('success:' + JSON.stringify(res));
|
||
},
|
||
fail: function (err) {
|
||
console.log('fail:' + JSON.stringify(err));
|
||
}
|
||
})
|
||
})
|
||
|
||
}
|
||
|
||
|
||
const toDetail = (item) => {
|
||
dohttp.navigateTo("/pages/order-detail/order-detail?id=" + item.id)
|
||
}
|
||
const cancelOrder = (item) => {
|
||
|
||
uni.showModal({
|
||
content: '确定取消该订单吗?',
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
dohttp.post(urls.cancelOrder + "?orderId=" + item.id).then((result) => {
|
||
if (result) {
|
||
item.status = 9
|
||
item.cancelFlag = 2
|
||
uni.showToast({
|
||
title: '取消成功',
|
||
duration: 1500
|
||
});
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
const toConsultAppointment = () => {
|
||
dohttp.navigateTo("/pages/consult-appointment/consult-appointment")
|
||
}
|
||
|
||
const scrolltolower = () => {
|
||
if (totalNum.value > requestParam.value.pageNo * requestParam.value.pageSize) {
|
||
requestParam.value.pageNo += 1
|
||
getOrderList()
|
||
} else {
|
||
uni.showToast({
|
||
title: '没有更多数据了',
|
||
duration: 1500
|
||
});
|
||
}
|
||
|
||
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.content {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
background-color: #F9F6F5;
|
||
display: flex;
|
||
flex-direction: column;
|
||
font-family: SourceHanSans;
|
||
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
}
|
||
|
||
|
||
.scroll-style {
|
||
box-sizing: border-box;
|
||
padding: 0 !important;
|
||
/* 清除可能的内边距 */
|
||
}
|
||
|
||
.show-name {
|
||
font-family: SourceHanSansBold;
|
||
font-size: 40rpx;
|
||
font-variation-settings: "opsz" auto;
|
||
color: #614D49;
|
||
}
|
||
|
||
.consult-method-text {
|
||
font-size: 24rpx;
|
||
font-variation-settings: "opsz" auto;
|
||
/* 正文色/正文辅助4 */
|
||
color: #9B918C;
|
||
}
|
||
|
||
.order-text {
|
||
font-size: 20rpx;
|
||
font-variation-settings: "opsz" auto;
|
||
color: #9B918C
|
||
}
|
||
|
||
.rmb-text {
|
||
color: #F37155;
|
||
font-family: SourceHanSansBold;
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
.effect-time-text {
|
||
color: #EA4E2D;
|
||
font-weight: 700;
|
||
font-size: 20rpx;
|
||
|
||
}
|
||
|
||
.time-text {
|
||
font-size: 24rpx;
|
||
font-variation-settings: "opsz" auto;
|
||
/* 正文色/正文色辅助3 */
|
||
color: #909099;
|
||
}
|
||
|
||
.order-status-text1 {
|
||
font-size: 28rpx;
|
||
font-family: SourceHanSansBold;
|
||
font-variation-settings: "opsz" auto;
|
||
color: #DB0000;
|
||
}
|
||
|
||
.order-status-text2 {
|
||
font-size: 28rpx;
|
||
font-family: SourceHanSansBold;
|
||
font-variation-settings: "opsz" auto;
|
||
color: #00B637;
|
||
}
|
||
|
||
.btn {
|
||
width: 152rpx;
|
||
height: 56rpx;
|
||
border-radius: 2002rpx;
|
||
|
||
|
||
/* 自动布局 */
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);
|
||
}
|
||
|
||
.btn-text {
|
||
|
||
font-size: 28rpx;
|
||
font-family: SourceHanSansBold;
|
||
color: #FFFFFF;
|
||
}
|
||
|
||
.btn1 {
|
||
width: 152rpx;
|
||
height: 56rpx;
|
||
border-radius: 2002rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
|
||
box-sizing: border-box;
|
||
border: 2rpx solid #F36749;
|
||
}
|
||
|
||
.btn-text1 {
|
||
|
||
font-size: 28rpx;
|
||
font-family: SourceHanSansBold;
|
||
color: #F36749;
|
||
}
|
||
|
||
.contact-btn {
|
||
border: none;
|
||
outline: none;
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 0rpx;
|
||
margin: 0rpx;
|
||
background-color: transparent;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
</style> |