jiangchengfeiyi-xiaochengxu/pages/mine/mineorders/mineorders.vue
2025-03-02 11:27:11 +08:00

767 lines
20 KiB
Vue

<template>
<view class="flex-row relative page">
<view class="flex-row justify-center items-center section_2 pos">
<image class="image"
src="https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FVrgKnxCu-sousuo.png" />
<text class="font text ml-4">搜索订单</text>
</view>
<view class="flex-col section_44">
<view class="flex-row justify-between self-stretch groupp">
<view class="font_22" :class="{ active: orderStatus === '全部', selected: isSelected('全部') }"
@click="changeTab('全部')">
全部
</view>
<view class="font_22" :class="{ active: orderStatus === '待支付', selected: isSelected('待支付') }"
@click="changeTab('待支付')">
待支付
</view>
<view class="font_22" :class="{ active: orderStatus === '待发货', selected: isSelected('待发货') }"
@click="changeTab('待发货')">
待发货
</view>
<view class="font_22" :class="{ active: orderStatus === '待收货', selected: isSelected('待收货') }"
@click="changeTab('待收货')">
已发货
</view>
<view class="font_22" :class="{ active: orderStatus === '已退款', selected: isSelected('已退款') }"
@click="changeTab('已退款')">
售后/退款
</view>
</view>
<view class="flex-col pos_8">
<view class="flex-col section_4 list-item_1 mt-14" v-for="(order, index) in Status.displayedOrders"
:key="order.id" @click="goToText(order)">
<view class="flex-col">
<view class="flex-row items-center self-stretch mt-2" style="display: flex; justify-content: space-between;">
<view>
<text class="font_4">订单编号:</text>
<text class="font_5 ml-5">{{order.orderNumber}}</text>
</view>
<view style="width: 150rpx; display: flex; justify-content: space-between;">
<view><text v-if="order.orderStatus === '待支付'" class="font_status text_5">{{ order.countdown }}</text></view>
<view><text class="font_status text_5">{{ order.orderStatus }}</text></view>
</view>
</view>
</view>
<view class="flex-col group">
<view class="flex-row justify-between list-item group_3" v-for="(item,goodIndex) in order.orderItemList"
:key="goodIndex">
<view class="flex-row">
<image class="image_2" :src="item.goodSnapshot.goodImg.split(';')[0]" />
<view class="flex-col self-start group_1 ml-18">
<view class="flex-row self-stretch">
<text class="font">{{ item.goodSnapshot.name }}</text>
<text class="font text_10">{{ item.goodSnapshot.type }}</text>
</view>
<text class="self-start font_7 text_12 mt-36">x{{ item.quantity }}</text>
</view>
</view>
<view class="flex-row items-center self-start group_2">
{{ item.goodSnapshot.price }}
</view>
</view>
</view>
<view class="divider view_1"></view>
<!-- <view class="flex-row justify-end group_5">
<view v-if="order.orderStatus==='待支付'" class="font text_18">去支付</view>
<view v-if="order.orderStatus==='待发货'" class="font text_18">取消订单</view>
<view v-if="order.orderStatus==='已发货'" class="font text_18">确认收货</view>
<view v-if="order.orderStatus==='已退款'" class="font text_18">售后详情</view>
</view> -->
<view class="flex-row justify-end items-center view">
<text class="font_9 text_16">总金额:</text>
<image class="image_4 image_5"
src="https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FJmxvlQvD-rmbpink.png" />
<text class="font_8 text_17">{{order.totalAmount}}</text>
</view>
<!-- <view class="flex-row justify-end group_7"> -->
<!-- <view class="flex-col justify-start items-center text-wrapper"><text
class="font text_18">删除记录</text></view>
<view class="flex-col justify-start items-center text-wrapper_2 ml-14" v-if="order.orderStatus==='待支付'">
<text class="font_3">去支付</text>
</view>
<view class="flex-col justify-start items-center text-wrapper_2 ml-14" v-if="order.orderStatus==='待发货'">
<text class="font_3">取消订单</text>
</view>
<view class="flex-col justify-start items-center text-wrapper_2 ml-14" v-if="order.orderStatus==='已发货'">
<text class="font_3">确认收货</text>
</view>
<view class="flex-col justify-start items-center text-wrapper_2 ml-14" v-if="order.orderStatus==='已退款'">
<text class="font_3">已退款</text>
</view> -->
<!-- </view> -->
<view @click.stop>
<view class="flex-row justify-end group_7" v-if="order.orderStatus==='待支付'">
<view class="flex-col justify-start items-center text-wrapper" @click="cancelOrder(order)"><text
class="font text_18">取消订单</text></view>
<view class="flex-col justify-start items-center text-wrapper_2 ml-14" @click="wxPayFd(order)">
<text class="font_3">去支付</text>
</view>
</view>
<view class="flex-row justify-end group_7" v-if="order.orderStatus==='待发货'">
<view class="flex-col justify-start items-center text-wrapper_2 ml-14">
<text class="font_3">联系客服</text>
</view>
</view>
<view class="flex-row justify-end group_7" v-if="order.orderStatus==='待收货'">
<view class="flex-col justify-start items-center text-wrapper_2 ml-14" @click="viewLogistics(order.id)">
<text class="font_3">查看物流</text>
</view>
<view class="flex-col justify-start items-center text-wrapper ml-14" @click="confirm()">
<text class="font">确认收货</text>
</view>
</view>
<view class="flex-row justify-end group_7" v-if="order.orderStatus==='已退款' || order.orderStatus === '交易关闭'">
<view class="flex-col justify-start items-center text-wrapper" @click="deleteOrder()"><text
class="font text_18">删除订单</text></view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 遮罩层 -->
<view v-if="isShow" class="overlay"></view>
</template>
<script setup>
import { ref,onMounted,toRaw, onBeforeUnmount } from 'vue';
import { baseUrl } from '@/api/request';
import { onLoad } from "@dcloudio/uni-app";
const Status = ref({
orderStatus: '全部',
orders: [],
displayedOrders: [],
})
const orderStatus = '' //订单状态
const currentColor = ref(0);
var plugin = requirePlugin('logisticsPlugin') //微信插件
let waybillToken = '' //物流信息唯一标识符
const isSelected = (tab) => Status.value.orderStatus === tab
onMounted(async () => {
await Getorder()
if (Status.value.orderStatus === '全部') {
Status.value.displayedOrders = Status.value.orders;
console.log('Status.value.displayedOrders--->',Status.value.displayedOrders);
} else {
Status.value.displayedOrders = Status.value.orders.filter((order) => {
switch (Status.value.orderStatus) {
case '待支付':
return order.orderStatus === '待支付'
case '待发货':
return order.orderStatus === '待发货'
case '已发货':
return order.orderStatus === '待收货'
case '待收货':
return order.orderStatus === '已退款'
default:
return false;
}
})
}
getFonts()
})
const userInfo = wx.getStorageSync('userInfo')
const Getorder = async () => {
const res = await uni.request({
url: baseUrl + '/order/list',
method: 'POST',
header: {
cookie: wx.getStorageSync('cookie')
}
})
if (res.data.code === 1) {
Status.value.orders = res.data.data
Status.value.orders.forEach((order) => {
startCountdown(order)
})
// console.log('Status.value.orders--->',Status.value.orders);
} else {
console.log('没拿到用户数据')
}
}
const zt = ref({
tab:''
})
onLoad((options)=>{
zt.value.tab = JSON.parse(options.zt)
changeTab(zt.value.tab)
})
const changeTab = (tab) => {
if (tab === '全部') {
Status.value.displayedOrders = Status.value.orders;
Status.value.orderStatus = '全部';
} else {
Status.value.displayedOrders = Status.value.orders.filter((order) => {
switch (tab) {
case '待支付':
return order.orderStatus === '待支付';
case '待发货':
return order.orderStatus === '待发货';
case '待收货':
return order.orderStatus === '待收货';
case '已退款':
return order.orderStatus === '已退款';
default:
return false;
}
})
Status.value.orderStatus = tab
}
}
const goToText = (orderInfo) => {
console.log('订单信息--->',orderInfo);
if(orderInfo.orderType === 'product') {
uni.navigateTo({
url: '../../../pages/order/product-paysuccess/product-paysuccess?oid=' + JSON.stringify(orderInfo.id)
})
} else {
uni.navigateTo({
url: '../../../pages/order/service-paystatus/service-paystatus?oid=' + JSON.stringify(orderInfo.id)
})
}
}
const cancelOrder = async (order) => { //取消订单
console.log(order);
uni.showModal({
title: '提示',
content: '确定要取消订单吗?',
success:(e) => {
if(e.confirm) {
postCancelOrder(order)
} else if(e.cancel) {
return;
}
}
})
}
const wxPay = async( oid )=> { //传入订单id
try {
const res = await uni.request({
url: baseUrl + '/wechat/payment/create',
method: 'POST',
header: {
'cookie': wx.getStorageSync("cookie")
},
data: { id: oid }
})
const paymentData = res.data.data
wx.requestPayment({
appid: paymentData.appId,
nonceStr: paymentData.nonceStr,
package: paymentData.packageVal,
paySign: paymentData.paySign,
timeStamp: paymentData.timeStamp,
signType: paymentData.signType,
success(res) {
uni.showModal({
content: '支付成功',
showCancel: false
})
uni.redirectTo({
url: '/pages/order/product-paysuccess/product-paysuccess?oid=' + JSON.stringify(oid)
})
console.log('支付成功res--->',res);
},
fail(e) {
// uni.showModal({
// content: '支付失败,原因为:' + e.errMsg,
// showCancel: false
// })
// console.log('e.errMsg--->',e.errMsg);
}
})
}catch(error) {
console.error('支付请求失败',error);
uni.showModal({
content: '支付请求失败,请重试。',
showCancel: false
})
}
}
const postCancelOrder = async(order)=>{ //向后端发送取消订单请求
if(order.addressSnapshot != null) {
const res = await uni.request({
url: baseUrl + '/order/cancel/id',
method: 'POST',
header: {
cookie: wx.getStorageSync('cookie')
},
data: { id: order.id }
})
console.log('取消订单的信息--->',res.data);
if(res.data.code === 1) {
Getorder() //成功请求后获取订单信息
uni.redirectTo({
url: '/pages/mine/mineorders/mineorders?zt=' + JSON.stringify(Status.value.orderStatus)
})
}
} else {
const res = await uni.request({
url: baseUrl + '/order/cancel/service/id',
method: 'POST',
header: {
cookie: wx.getStorageSync('cookie')
},
data: { id: order.id }
})
console.log('取消订单的信息--->',res.data);
if(res.data.code === 1) {
Getorder() //成功请求后获取订单信息
uni.redirectTo({
url: '/pages/mine/mineorders/mineorders?zt=' + JSON.stringify(Status.value.orderStatus)
})
}
}
}
//查看物流方法
const viewLogistics = ( oid )=>{
// console.log('订单编号--->',oid);
uni.request({
url: baseUrl + '/logistics/get/info',
method: 'POST',
data: {
id: oid
},
header: {
'cookie': wx.getStorageSync("cookie")
},
success: (res) => {
console.log(res.data.data)
waybillToken = res.data.data.waybill_token
plugin.openWaybillTracking({
waybillToken: waybillToken
})
}
})
}
const deleteOrder = async () => { //删除订单方法
console.log('删除订单方法');
}
//获取字体
const getFonts =()=>{
uni.loadFontFace({
family: 'FangZhengFonts',
source: `url("https://carbon2.obs.cn-north-4.myhuaweicloud.com/fonts/FangZhengFonts.TTF")`,
success:(res) =>{
console.log('success',res);
},
fail:(err) => {
console.log('err',err);
}
})
}
const confirm =()=> { //确认收货方法
console.log('确认收货方法');
}
//防抖相关变量
let debounceTimer = null;
let wxPayTimer = null;
let loading = false;
let isLoading = ref(false)
let isShow = ref(false)
const wxPayFd = (order) => { //微信支付按钮防抖
clearTimeout(wxPayTimer)
showLoading()
isShow.value = true //打开遮罩
wxPayTimer = setTimeout(async () => {
await wxPay(order.id)
}, 1000)
setTimeout(()=>{
hideLoading()
isShow.value = false //关闭遮罩
},2000)
}
function showLoading() { //加载弹窗
if (!loading) {
wx.showLoading({
title: '加载中...',
});
loading = true;
isLoading.value = true
}
}
function hideLoading() { //关闭弹窗
if (loading) {
wx.hideLoading();
loading = false;
isLoading.value = false
}
}
// 时间格式化函数,处理后端返回的时间
const parseDate = (dateString) => {
const [date, time] = dateString.split(' ');
const [year, month, day] = date.split('-').map(Number);
const [hour, minute, second] = time.split(':').map(Number);
return new Date(year, month - 1, day, hour, minute, second); // JavaScript Date的月份是从0开始的
};
// 给订单创建时间加上30分钟
const add30Minutes = (createdTime) => {
const date = parseDate(createdTime);
date.setMinutes(date.getMinutes() + 31); // 加上30分钟
return Math.floor(date.getTime() / 1000); // 返回时间戳(秒)
};
// 启动每个订单的倒计时(仅对待支付订单有效)
const startCountdown = (order) => {
if (order.orderStatus === '待支付') {
order.endTime = add30Minutes(order.createTime); // 设置最终取消时间
order.countdownInterval = setInterval(() => {
const now = Math.floor(Date.now() / 1000); // 获取当前时间的时间戳(秒)
const remainingTime = order.endTime - now;
if (remainingTime <= 0) {
order.countdown = '00:00';
clearInterval(order.countdownInterval); // 清除定时器
Getorder()
// uni.showModal({
// title: '提示',
// content: '订单超时未支付,交易关闭',
// showCancel: false
// })
} else {
const minutes = Math.floor(remainingTime / 60); // 计算剩余分钟
const seconds = remainingTime % 60; // 计算剩余秒数
order.countdown = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}
}, 1000);
}
};
// 在组件挂载时启动待支付订单的倒计时
// 在组件卸载时清除所有定时器,避免内存泄漏
onBeforeUnmount(() => {
Status.value.orders.forEach(order => {
if (order.countdownInterval) {
clearInterval(order.countdownInterval);
}
});
});
</script>
<style lang="scss" scoped>
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4); /* 半透明黑色背景 */
z-index: 999;
}
.groupp {
padding: 22.5rpx 0 18.75rpx;
}
.section_44 {
padding-left: 33.75rpx;
padding-right: 30rpx;
width: 100%;
height: 120rpx;
margin-top: 80rpx;
}
.ml-5 {
margin-left: 9.38rpx;
}
.font_22.selected {
position: relative;
}
.font_22.selected::after {
content: '';
position: absolute;
bottom: -5px; // 调整线条距离底部的距离
left: 0;
right: 0;
height: 2px; // 调整线条的粗细
background-color: #f6aaa4; // 调整线条颜色
transition: all 0.3s ease; // 添加过渡效果
}
.page {
padding: 46.88rpx 22.5rpx 401.25rpx;
background-color: #ffffff;
background-image: url('https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FQfLHXSAU-feiyigongfangbeijin.png');
background-size: 100% 100%;
background-repeat: no-repeat;
height: 100vh;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
}
.section_2 {
padding: 9.38rpx 0;
background-color: #ffffff;
border-radius: 75rpx;
}
.pos {
position: absolute;
left: 35.63rpx;
right: 35.63rpx;
top: 46.88rpx;
}
.image {
width: 37.5rpx;
height: 37.5rpx;
}
.font {
font-size: 26.25rpx;
font-family: FangZhengFonts;
line-height: 25.54rpx;
color: #323232;
}
.text {
color: #c0c0c0;
line-height: 25.84rpx;
}
.font_2 {
font-size: 30rpx;
font-family: FangZhengFonts;
line-height: 28.84rpx;
color: #323232;
}
.font_22 {
font-size: 30rpx;
font-family: FangZhengFonts;
line-height: 27.81rpx;
color: #323232;
}
.text_2 {
line-height: 28.48rpx;
}
.pos_2 {
position: absolute;
left: 33.99rpx;
top: 146.36rpx;
}
.text_3 {
line-height: 28.24rpx;
}
.pos_3 {
position: absolute;
left: 147.66rpx;
top: 146.14rpx;
}
.pos_4 {
position: absolute;
left: 295.78rpx;
top: 145.78rpx;
}
.pos_5 {
position: absolute;
right: 214.22rpx;
top: 145.78rpx;
}
.text_4 {
line-height: 29.53rpx;
}
.pos_6 {
position: absolute;
right: 34.22rpx;
top: 147.07rpx;
}
.section_3 {
background-color: #ffaaa5;
width: 73.13rpx;
height: 5.63rpx;
}
.pos_7 {
position: absolute;
left: 30rpx;
top: 182.81rpx;
}
.pos_8 {
position: absolute;
left: 22.5rpx;
right: 30rpx;
top: 217.5rpx;
}
.section_4 {
padding: 34.61rpx 31rpx 31.88rpx;
background-color: #ffffff;
border-radius: 31.88rpx;
}
.list-item_1:first-child {
margin-top: 0;
}
.list-item_1:last-child {
margin-bottom: 30rpx;
}
.font_status {
// font-size: 26.25rpx;
font-family: FangZhengFonts;
line-height: 25.54rpx;
color: #ffaaa5;
}
.font_3 {
font-size: 26.25rpx;
font-family: FangZhengFonts;
line-height: 25.54rpx;
color: #ffaaa5;
}
.text_5 {
line-height: 24.62rpx;
}
.font_4 {
font-size: 22.5rpx;
font-family: FangZhengFonts;
line-height: 22.14rpx;
color: #818181;
}
.font_5 {
font-size: 22.5rpx;
font-family: FangZhengFonts;
line-height: 15.04rpx;
color: #818181;
}
.group {
margin-top: 29.21rpx;
}
.list-item:first-child {
margin-top: 0;
}
.image_2 {
border-radius: 9.38rpx;
width: 146.25rpx;
height: 144.38rpx;
}
.group_1 {
margin-top: 2.33rpx;
}
.text_10 {
line-height: 25.01rpx;
}
.font_7 {
font-size: 26.25rpx;
font-family: Open Sans;
line-height: 19.29rpx;
color: #323232;
}
.text_12 {
margin-left: 5.34rpx;
line-height: 18.73rpx;
}
.group_2 {
margin-right: 8.23rpx;
margin-top: 89.19rpx;
}
.font_6 {
font-size: 33.75rpx;
font-family: Open Sans;
line-height: 25.54rpx;
font-weight: 600;
color: #323232;
}
.text_11 {
margin-left: 25.03rpx;
line-height: 24.88rpx;
}
.image_3 {
margin-left: -90.66rpx;
width: 30rpx;
height: 26.25rpx;
}
.font_8 {
font-size: 26.25rpx;
font-family: Open Sans;
line-height: 19.29rpx;
font-weight: 600;
color: #323232;
}
.text_13 {
margin-left: 61.14rpx;
}
.divider {
background-color: #dad2d2;
height: 0.81rpx;
}
.view_1 {
margin: 30.43rpx 28.13rpx 0 39.38rpx;
}
.group_5 {
margin-top: 49.41rpx;
padding: 0 21.21rpx;
color: #ffaaa5;
}
.font_9 {
font-size: 26.25rpx;
font-family: FangZhengFonts;
line-height: 25.54rpx;
color: #000000;
}
.text_14 {
line-height: 24.62rpx;
}
.text_15 {
margin-top: 2.17rpx;
line-height: 24rpx;
}
.view {
margin-top: 19.93rpx;
padding: 0 19.54rpx;
}
.text_16 {
margin-right: 6.99rpx;
line-height: 24.3rpx;
}
.image_4 {
width: 31.88rpx;
height: 30rpx;
}
.image_5 {
margin-right: -8.29rpx;
}
.text_17 {
color: #ffaaa5;
line-height: 19.39rpx;
}
.group_7 {
margin-top: 52.5rpx;
padding: 0 9.38rpx;
}
.text-wrapper {
padding: 13.86rpx 0 13.52rpx;
background-color: #fffef8;
border-radius: 75rpx;
width: 155.63rpx;
height: 56.25rpx;
border: solid 1.88rpx #cbcbcb;
}
.text_18 {
line-height: 25.13rpx;
}
.text-wrapper_2 {
padding: 13.46rpx 0 13.5rpx;
background-color: #fffef8;
border-radius: 75rpx;
width: 155.63rpx;
height: 56.25rpx;
border: solid 1.88rpx #ffaaa5;
}
.group_3 {
margin-top: 15rpx;
}
@import url("../../../common/css/global.css");
</style>