Files
yuxingu-Miniprogram-dev/pages/order/order.vue
T
2026-03-23 11:52:05 +08:00

484 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>