429 lines
11 KiB
Vue
429 lines
11 KiB
Vue
<template>
|
||
<view class="order-item">
|
||
<view class="flex-row-between order-title" @click="jumpToDetails">
|
||
<text class="fs-24 app-fc-normal">
|
||
订单编号:{{ data.order_no || "-" }}
|
||
</text>
|
||
<!-- 待支付状态:显示倒计时横幅 -->
|
||
<view v-if="data.status === SHOP_ORDER_UNPAY && !data.tui_status && countDownTime > 0"
|
||
class="order-status-banner">
|
||
<view class="status-banner-left">
|
||
<text class="status-text">等待付款</text>
|
||
</view>
|
||
<view class="status-banner-right">
|
||
<text class="countdown-text">{{ formatCountdown(countDownTime) }}</text>
|
||
</view>
|
||
</view>
|
||
<!-- 其他状态:显示原有样式 -->
|
||
<view v-else-if="
|
||
([
|
||
SHOP_ORDER_CANCEL,
|
||
SHOP_ORDER_UNPAY,
|
||
SHOP_ORDER_UNSLIVER,
|
||
SHOP_ORDER_UNRECEIVE,
|
||
SHOP_ORDER_DONE,
|
||
SHOP_ORDER_UNREMARK,
|
||
].includes(data.status) &&
|
||
!data.tui_status) ||
|
||
[SHOP_ORDER_AFTERSALE_REJECT].includes(data.tui_status)
|
||
" class="flex-center fs-24 order-btn" :class="[
|
||
![SHOP_ORDER_DONE, SHOP_ORDER_CANCEL, SHOP_ORDER_UNREMARK].includes(
|
||
data.status
|
||
)
|
||
? 'app-fc-mark confirm'
|
||
: 'cancel',
|
||
]">
|
||
{{ orderStatus }}
|
||
</view>
|
||
<view v-if="
|
||
[SHOP_ORDER_AFTERSALE, SHOP_ORDER_AFTERSALE_DONE].includes(
|
||
data.tui_status
|
||
)
|
||
" class="flex-center fs-24 order-btn cancel">
|
||
{{ refundOrderStatus }}
|
||
</view>
|
||
</view>
|
||
<view class="order-content" :class="{ 'split-border': showStatusBtn }" @click="jumpToDetails">
|
||
<good-info :data="data.items" :actual_price="data.actual_price" />
|
||
<view v-if="data.type && data.type !== 1" class="fs-24 app-fc-mark order-type">
|
||
随车订单
|
||
</view>
|
||
</view>
|
||
<view v-if="showStatusBtn" class="order-btns">
|
||
<!-- 待支付 -->
|
||
<template v-if="[SHOP_ORDER_UNPAY].includes(data.status)">
|
||
<view class="flex-center fs-24 app-fc-main cancel-order-btn" @click.stop="$emit('cancelOrder', data)">
|
||
取消订单
|
||
</view>
|
||
<view class="order-btns-right">
|
||
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('concactService', data)">
|
||
联系客服
|
||
</view> -->
|
||
<view class="flex-center fs-24 app-fc-white status-btn confirm" @click.stop="$emit('pay', data)">
|
||
立即支付
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 待发货 -->
|
||
<template v-if="[SHOP_ORDER_UNSLIVER].includes(data.status)">
|
||
<view class="order-btns-right">
|
||
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('concactService', data)">
|
||
联系客服
|
||
</view> -->
|
||
<!-- <view
|
||
class="flex-center fs-24 app-fc-main status-btn"
|
||
@click.stop="$emit('afterSale', data)"
|
||
>
|
||
申请售后
|
||
</view> -->
|
||
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('refund', data)">
|
||
退款
|
||
</view> -->
|
||
<refund-button
|
||
mode="2"
|
||
order-status="1"
|
||
:order-id="data.order_no"
|
||
:refund-total-amount="(data.actual_price || 0) * 100"
|
||
:compact="true"
|
||
@refund="handleRefund"
|
||
@error="handleError"
|
||
style="width:140rpx;height:68rpx;"
|
||
|
||
/>
|
||
<view class="flex-center fs-24 app-fc-white status-btn confirm"
|
||
@click.stop="jumpToReservation">
|
||
立即预约
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 待收货 -->
|
||
<template v-if="[SHOP_ORDER_UNRECEIVE].includes(data.status)">
|
||
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('concactService', data)">
|
||
联系客服
|
||
</view> -->
|
||
|
||
<view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('afterSale', data)">
|
||
申请售后
|
||
</view>
|
||
<!-- 随车订单不显示物流 -->
|
||
<!-- <view v-if="data.pay_type !== pay_type_BYCAR" class="flex-center fs-24 app-fc-main status-btn"
|
||
@click.stop="$emit('checkSliver', data)">
|
||
查看物流
|
||
</view> -->
|
||
<view class="flex-center fs-24 app-fc-white status-btn confirm"
|
||
@click.stop="$emit('confirmSliver', data)">
|
||
确认收货
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 已签收未评价 -->
|
||
<template v-if="[SHOP_ORDER_UNREMARK].includes(data.status)">
|
||
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('concactService', data)">
|
||
联系客服
|
||
</view> -->
|
||
<view class="flex-center fs-24 app-fc-white status-btn confirm" @click.stop="$emit('remark', data)">
|
||
立即评价
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 已完成 -->
|
||
<template v-if="[SHOP_ORDER_DONE].includes(data.status)">
|
||
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('concactService', data)">
|
||
联系客服
|
||
</view> -->
|
||
<view class="flex-center fs-24 app-fc-white status-btn confirm "
|
||
style="visibility: hidden;"
|
||
>
|
||
|
||
</view>
|
||
</template>
|
||
<template v-if="[SHOP_ORDER_DONE].includes(data.status)">
|
||
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('concactService', data)">
|
||
联系客服
|
||
</view> -->
|
||
<view class="flex-center fs-24 app-fc-white status-btn confirm"
|
||
@click.stop="$emit('remarkDetails', data)">
|
||
查看评价
|
||
</view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import PopUpModal from "@/components/PopUpModal.vue";
|
||
import GoodInfo from "./GoodInfo.vue";
|
||
import RefundButton from "@/components/RefundButton.vue";
|
||
import {
|
||
SHOP_ORDER_STATUS,
|
||
SHOP_ORDER_UNPAY,
|
||
SHOP_ORDER_UNSLIVER,
|
||
SHOP_ORDER_UNRECEIVE,
|
||
SHOP_ORDER_DONE,
|
||
SHOP_ORDER_CANCEL,
|
||
SHOP_ORDER_AFTERSALE,
|
||
SHOP_ORDER_AFTERSALE_DONE,
|
||
SHOP_ORDER_AFTERSALE_REJECT,
|
||
SHOP_ORDER_AFTERSALE_STATUS,
|
||
SHOP_ORDER_UNREMARK,
|
||
pay_type_ADDRESS,
|
||
pay_type_BYCAR,
|
||
pay_type_BYPET
|
||
} from "@/constants/app.business";
|
||
|
||
export default {
|
||
props: {
|
||
data: {
|
||
type: Object,
|
||
default: () => {},
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
pay_type_ADDRESS,
|
||
pay_type_BYCAR,
|
||
pay_type_BYPET,
|
||
SHOP_ORDER_STATUS,
|
||
SHOP_ORDER_UNPAY,
|
||
SHOP_ORDER_UNSLIVER,
|
||
SHOP_ORDER_UNRECEIVE,
|
||
SHOP_ORDER_DONE,
|
||
SHOP_ORDER_CANCEL,
|
||
SHOP_ORDER_AFTERSALE,
|
||
SHOP_ORDER_AFTERSALE_DONE,
|
||
SHOP_ORDER_AFTERSALE_REJECT,
|
||
SHOP_ORDER_UNREMARK,
|
||
showCancelModal: false,
|
||
countDownTime: 0,
|
||
countDownTimer: null,
|
||
};
|
||
},
|
||
components: {
|
||
GoodInfo,
|
||
PopUpModal,
|
||
RefundButton
|
||
},
|
||
options: {
|
||
styleIsolation: "shared",
|
||
},
|
||
computed: {
|
||
orderStatus() {
|
||
return SHOP_ORDER_STATUS[this.data.status] || "";
|
||
},
|
||
refundOrderStatus() {
|
||
return SHOP_ORDER_AFTERSALE_STATUS[this.data.tui_status] || "";
|
||
},
|
||
showStatusBtn() {
|
||
return (
|
||
([
|
||
SHOP_ORDER_UNPAY,
|
||
SHOP_ORDER_UNSLIVER,
|
||
SHOP_ORDER_UNRECEIVE,
|
||
SHOP_ORDER_DONE,
|
||
SHOP_ORDER_UNREMARK,
|
||
].includes(this.data.status) &&
|
||
!this.data.tui_status) || [SHOP_ORDER_AFTERSALE_REJECT].includes(this.data.tui_status)
|
||
);
|
||
},
|
||
},
|
||
watch: {
|
||
showCancelModal(val) {
|
||
this.$emit("disableScroll", val);
|
||
},
|
||
'data.daojishi'(newVal) {
|
||
if (this.data.status === this.SHOP_ORDER_UNPAY && newVal) {
|
||
this.countDownTime = newVal;
|
||
this.startCountDown();
|
||
}
|
||
},
|
||
'data.status'(newVal) {
|
||
if (newVal === this.SHOP_ORDER_UNPAY && this.data.daojishi) {
|
||
this.countDownTime = this.data.daojishi;
|
||
this.startCountDown();
|
||
} else {
|
||
this.stopCountDown();
|
||
}
|
||
},
|
||
},
|
||
mounted() {
|
||
// console.log(this.data,'--=')
|
||
if (this.data.status === SHOP_ORDER_UNPAY && this.data.daojishi) {
|
||
this.countDownTime = this.data.daojishi;
|
||
this.startCountDown();
|
||
}
|
||
},
|
||
beforeDestroy() {
|
||
this.stopCountDown();
|
||
},
|
||
methods: {
|
||
handleRefund(e) {
|
||
console.log('退款结果:', e.detail)
|
||
if (e.detail.status === 'success') {
|
||
uni.showToast({ title: '退款申请已提交', icon: 'success' })
|
||
this.$emit('refund', this.data)
|
||
} else {
|
||
uni.showToast({ title: '退款失败', icon: 'none' })
|
||
}
|
||
},
|
||
|
||
handleError(e) {
|
||
console.error('组件错误:', e.detail)
|
||
},
|
||
|
||
startCountDown() {
|
||
this.stopCountDown();
|
||
if (this.countDownTime > 0) {
|
||
this.countDownTimer = setInterval(() => {
|
||
if (this.countDownTime > 0) {
|
||
this.countDownTime--;
|
||
} else {
|
||
this.stopCountDown();
|
||
// 倒计时结束,可以触发刷新
|
||
this.$emit('countdownEnd', this.data);
|
||
}
|
||
}, 1000);
|
||
}
|
||
},
|
||
stopCountDown() {
|
||
if (this.countDownTimer) {
|
||
clearInterval(this.countDownTimer);
|
||
this.countDownTimer = null;
|
||
}
|
||
},
|
||
formatCountdown(seconds) {
|
||
const hour = Math.floor(seconds / 3600);
|
||
const minutes = Math.floor((seconds - hour * 3600) / 60);
|
||
return `${hour}小时${minutes}分钟`;
|
||
},
|
||
orderCancel() {
|
||
this.showCancelModal = false;
|
||
},
|
||
cancel() {
|
||
this.showCancelModal = false;
|
||
},
|
||
jumpToDetails() {
|
||
this.$emit('jumpToDetails', this.data)
|
||
},
|
||
jumpToReservation() {
|
||
uni.reLaunch({
|
||
url: '/pages/client/index/index?activePageId=reservationPage'
|
||
});
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.order-item {
|
||
width: calc(100vw - 40rpx);
|
||
background: #fff;
|
||
margin: 20rpx;
|
||
border-radius: 30rpx;
|
||
box-sizing: border-box;
|
||
padding: 20rpx;
|
||
margin-bottom: 0;
|
||
|
||
.order-title {
|
||
padding-bottom: 20rpx;
|
||
border-bottom: 1rpx solid #ececec;
|
||
|
||
.order-btn {
|
||
width: 104rpx;
|
||
height: 48rpx;
|
||
border-radius: 48rpx;
|
||
|
||
&.confirm {
|
||
background: #fef6ff;
|
||
}
|
||
|
||
&.cancel {
|
||
background: #f7f7f7;
|
||
color: #afa5ae;
|
||
}
|
||
}
|
||
|
||
.order-status-banner {
|
||
display: flex;
|
||
align-items: center;
|
||
border-radius: 48rpx;
|
||
overflow: hidden;
|
||
|
||
.status-banner-left {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100%;
|
||
background: #FF19A0;
|
||
padding: 8rpx;
|
||
flex-shrink: 0;
|
||
border-radius: 10px 0px 10px 10px;
|
||
|
||
.status-text {
|
||
font-size: 20rpx;
|
||
color: #FFFFFF;
|
||
}
|
||
}
|
||
|
||
.status-banner-right {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100%;
|
||
background: #FFF0F8;
|
||
padding: 8rpx;
|
||
flex-shrink: 0;
|
||
|
||
|
||
|
||
.countdown-text {
|
||
font-size: 20rpx;
|
||
color: #FF19A0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
.order-btns {
|
||
padding-top: 20rpx;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
|
||
.cancel-order-btn {
|
||
font-size: 24rpx;
|
||
color: #9B939A;
|
||
padding: 16rpx 0;
|
||
}
|
||
|
||
.order-btns-right {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.status-btn {
|
||
width: 70px;
|
||
height: 34px;
|
||
// padding: 16rpx 20rpx;
|
||
border-radius: 64rpx;
|
||
border: 1px solid #FF19A0;;
|
||
margin-left: 20rpx;
|
||
|
||
&.confirm {
|
||
color: $app_color_main;
|
||
border: 1px solid $app_color_main;
|
||
}
|
||
}
|
||
}
|
||
|
||
::v-deep {
|
||
.good-info-multi {
|
||
padding-top: 20rpx;
|
||
}
|
||
|
||
}
|
||
}
|
||
</style>
|