1
This commit is contained in:
406
src/pages/client/petOrder/index.vue
Normal file
406
src/pages/client/petOrder/index.vue
Normal file
@ -0,0 +1,406 @@
|
||||
<template>
|
||||
<view class="order-page-container">
|
||||
<scroll-view class="tab-view" scroll-x="true" :show-scrollbar="false">
|
||||
<view class="tab-view-content">
|
||||
<view class="tab-item" v-for="item in tabList" :key="item.value" @click.stop="selectOrderStatus(item)">
|
||||
<text class="fs-28 app-fc-normal" :class="{ 'tab-text ali-puhui-bold': item.value === currentStatus }">
|
||||
{{ item.label }}
|
||||
</text>
|
||||
<view class="tab-line" :class="{ 'tab-selected-line': item.value === currentStatus }" />
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="order-content">
|
||||
<view class="status-view-container" v-if="isLoading">
|
||||
<uni-load-more status="loading" />
|
||||
</view>
|
||||
<view class="status-view-container" v-if="!isLoading && orderList.length === 0">
|
||||
<uni-load-more status="noMore" />
|
||||
</view>
|
||||
<scroll-view
|
||||
class="scroll-view"
|
||||
scroll-y
|
||||
v-if="!isLoading && orderList.length"
|
||||
refresher-enabled
|
||||
:refresher-triggered="isRefresh"
|
||||
@refresherrefresh="refresherAction"
|
||||
@scrolltolower="loadMoreAction"
|
||||
refresher-background="transparent"
|
||||
>
|
||||
<!-- 根据 source 字段动态渲染不同的组件 -->
|
||||
<block v-for="(item, index) in orderList" :key="item.order_id || index">
|
||||
<!-- source 为 'pet_order' 时使用 reservation 组件 -->
|
||||
<reservation
|
||||
v-if="item.source === 'pet_order'"
|
||||
:order-info="item"
|
||||
@refresh-list="refresherAction"
|
||||
@cancel-order="handleCancelOrder"
|
||||
/>
|
||||
<!-- source 为 'home_service' 时使用 home-service-order-item 组件 -->
|
||||
<home-service-order-item
|
||||
v-else-if="item.source === 'home_service'"
|
||||
:order-info="item"
|
||||
@refresh-list="refresherAction"
|
||||
@cancel-order="handleCancelOrder"
|
||||
/>
|
||||
<!-- source 为 'home_training' 时使用 home-training-order-item 组件 -->
|
||||
<home-training-order-item
|
||||
v-else-if="item.source === 'home_training'"
|
||||
:order-info="item"
|
||||
@refresh-list="refresherAction"
|
||||
@pay-now="handlePayNow"
|
||||
@buy-course="handleBuyCourse"
|
||||
@cancel-order="handleCancelOrder"
|
||||
@view-contract="handleViewContract"
|
||||
@goto-evaluate="handleGotoEvaluate"
|
||||
/>
|
||||
</block>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 取消预约确认弹窗 - 放在父组件中避免被 overflow: hidden 裁剪 -->
|
||||
<pop-up-modal
|
||||
v-if="isShowCancelModal"
|
||||
content="确定要取消预约吗?"
|
||||
@confirm="confirmCancelOrder"
|
||||
@cancel="isShowCancelModal = false"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Reservation from './reservation.vue';
|
||||
import HomeServiceOrderItem from './home-service-order-item.vue';
|
||||
import HomeTrainingOrderItem from './home-training-order-item.vue';
|
||||
import { showOrderStatus } from "@/pageHome/constants/home";
|
||||
import { getOrderList, cancelHomeOrder, cancelTrainingOrder } from "@/api/order";
|
||||
import { cancelPetOrderRefund } from "@/api/login";
|
||||
import PopUpModal from "@/components/PopUpModal.vue";
|
||||
|
||||
export default {
|
||||
name: 'index',
|
||||
components: {
|
||||
Reservation,
|
||||
HomeServiceOrderItem,
|
||||
HomeTrainingOrderItem,
|
||||
PopUpModal
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabList: showOrderStatus,
|
||||
currentStatus: 0,
|
||||
isLoading: true,
|
||||
orderList: [],
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
isRefresh: false,
|
||||
isLoadMore: false,
|
||||
isNoMore: false,
|
||||
isShowCancelModal: false,
|
||||
cancelOrderInfo: null,
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
// 如果从外部传入状态,设置当前状态
|
||||
if (options.status !== undefined) {
|
||||
this.currentStatus = parseInt(options.status) || 0;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
uni.$on("createRemarkSuccess", this.refresherAction);
|
||||
uni.$on("refreshOrderList", this.refresherAction);
|
||||
this.initData();
|
||||
},
|
||||
destroyed() {
|
||||
uni.$off("createRemarkSuccess", this.refresherAction);
|
||||
uni.$off("refreshOrderList", this.refresherAction);
|
||||
},
|
||||
watch: {
|
||||
currentStatus: {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal !== oldVal && oldVal !== undefined) {
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
immediate: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectOrderStatus(status) {
|
||||
if (this.currentStatus === status.value) {
|
||||
return;
|
||||
}
|
||||
this.currentStatus = status.value;
|
||||
},
|
||||
initData() {
|
||||
this.isLoading = true;
|
||||
this.pageNumber = 1;
|
||||
this.isRefresh = false;
|
||||
this.isLoadMore = false;
|
||||
this.isNoMore = false;
|
||||
this.orderList = [];
|
||||
this.getData();
|
||||
},
|
||||
refresherAction() {
|
||||
if (this.isRefresh) {
|
||||
return;
|
||||
}
|
||||
this.pageNumber = 1;
|
||||
this.isRefresh = true;
|
||||
this.isLoadMore = false;
|
||||
this.isNoMore = false;
|
||||
this.getData();
|
||||
},
|
||||
loadMoreAction() {
|
||||
console.log(this.isNoMore)
|
||||
if (this.isNoMore) {
|
||||
return;
|
||||
}
|
||||
this.pageNumber++;
|
||||
this.getData();
|
||||
},
|
||||
getData() {
|
||||
const value = uni.getStorageSync("userInfo");
|
||||
const params = {
|
||||
user_id: value.user_id,
|
||||
status: this.currentStatus || 0,
|
||||
page: this.pageNumber,
|
||||
page_size: this.pageSize
|
||||
};
|
||||
getOrderList(params)
|
||||
.then((res) => {
|
||||
let list = res?.data || [];
|
||||
if (this.pageNumber === 1) {
|
||||
this.orderList = list;
|
||||
} else {
|
||||
this.orderList = [...this.orderList, ...list];
|
||||
}
|
||||
this.isRefresh = false;
|
||||
this.isLoading = false;
|
||||
this.isLoadMore = false;
|
||||
this.isNoMore = list.length < 9;
|
||||
})
|
||||
.catch(() => {
|
||||
if (this.pageNumber !== 1) {
|
||||
this.pageNumber--;
|
||||
}
|
||||
this.isLoading = false;
|
||||
this.isRefresh = false;
|
||||
this.isLoadMore = false;
|
||||
});
|
||||
},
|
||||
handleBookAgain(orderInfo) {
|
||||
// 处理再次预约的逻辑
|
||||
// 可以跳转到预约页面
|
||||
console.log('再次预约', orderInfo);
|
||||
// 例如:uni.navigateTo({ url: '/pageHome/service/feeding?orderId=' + orderInfo.order_id });
|
||||
},
|
||||
handleViewReport(orderInfo) {
|
||||
// 处理查看宠物报告的逻辑
|
||||
console.log('查看宠物报告', orderInfo);
|
||||
// 可以跳转到报告详情页面
|
||||
// uni.navigateTo({ url: '/pages/client/report/detail?orderId=' + orderInfo.order_id });
|
||||
},
|
||||
handleBuyGoods(orderInfo) {
|
||||
// 处理随车购商品的逻辑
|
||||
uni.navigateTo({
|
||||
url: `/pages/client/category/index?petOrderId=${orderInfo.order_id}&addressId=${orderInfo.address_id}`,
|
||||
});
|
||||
},
|
||||
handleAddService(orderInfo) {
|
||||
// 处理添加附加项的逻辑
|
||||
console.log('添加附加项', orderInfo);
|
||||
// 可以跳转到添加附加项页面或显示弹窗
|
||||
},
|
||||
handleCancelOrder(orderInfo) {
|
||||
// 显示取消预约确认弹窗
|
||||
this.cancelOrderInfo = orderInfo;
|
||||
this.isShowCancelModal = true;
|
||||
},
|
||||
confirmCancelOrder() {
|
||||
// 确认取消订单
|
||||
if (!this.cancelOrderInfo) {
|
||||
this.isShowCancelModal = false;
|
||||
return;
|
||||
}
|
||||
const orderInfo = this.cancelOrderInfo;
|
||||
this.isShowCancelModal = false;
|
||||
uni.showLoading({
|
||||
title: "正在取消订单",
|
||||
mask: true,
|
||||
});
|
||||
|
||||
// 根据订单类型调用不同的取消接口
|
||||
let cancelPromise;
|
||||
if (orderInfo.source === 'home_service') {
|
||||
// 上门服务订单使用 cancelHomeOrder 接口
|
||||
const orderId = orderInfo.home_service_order?.id;
|
||||
cancelPromise = cancelHomeOrder(orderId);
|
||||
} else if (orderInfo.source === 'pet_order') {
|
||||
// pet_order 类型订单使用 cancelPetOrderRefund 接口
|
||||
const orderId = orderInfo.pet_order?.order_id || orderInfo.order_id;
|
||||
cancelPromise = cancelPetOrderRefund({ order_id: Number(orderId) });
|
||||
} else {
|
||||
// 上门训练订单使用 cancelTrainingOrder 接口
|
||||
const orderId = orderInfo.home_training_order?.id;
|
||||
cancelPromise = cancelTrainingOrder({ order_id: Number(orderId) });
|
||||
}
|
||||
|
||||
cancelPromise
|
||||
.then((res) => {
|
||||
uni.hideLoading();
|
||||
// 判断是否成功:result === 'success'
|
||||
if (res.result === 'success') {
|
||||
this.cancelOrderInfo = null;
|
||||
uni.showToast({
|
||||
title:"取消成功",
|
||||
icon: "success",
|
||||
});
|
||||
// 刷新订单列表
|
||||
this.refresherAction();
|
||||
} else {
|
||||
// 失败:弹出错误信息
|
||||
this.cancelOrderInfo = null;
|
||||
uni.showToast({
|
||||
title: res.msg || res.message || "取消订单失败",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.hideLoading();
|
||||
this.cancelOrderInfo = null;
|
||||
// 捕获异常时显示错误信息
|
||||
const errorMsg = err?.msg || err?.message || err || "取消订单失败,请稍后重试";
|
||||
uni.showToast({
|
||||
title: errorMsg,
|
||||
icon: "none",
|
||||
});
|
||||
});
|
||||
},
|
||||
handlePayNow(orderInfo) {
|
||||
// 处理立即支付
|
||||
console.log('立即支付', orderInfo);
|
||||
// TODO: 实现支付逻辑
|
||||
uni.showToast({
|
||||
title: '支付功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
handleBuyCourse(orderInfo) {
|
||||
// 处理购买课程
|
||||
console.log('购买课程', orderInfo);
|
||||
// TODO: 实现购买课程逻辑
|
||||
uni.showToast({
|
||||
title: '购买课程功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
handleViewContract(orderInfo) {
|
||||
// 处理查看合同
|
||||
console.log('查看合同', orderInfo);
|
||||
// TODO: 实现查看合同逻辑,可能需要跳转到合同详情页
|
||||
uni.showToast({
|
||||
title: '查看合同功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
handleGotoEvaluate(orderInfo) {
|
||||
// 处理去评价
|
||||
const orderId = orderInfo.order_id || orderInfo.home_training_order?.order_id;
|
||||
const pinglunId = orderInfo.pinglun_id;
|
||||
|
||||
if (pinglunId) {
|
||||
// 如果已有评价,跳转到评价详情
|
||||
uni.navigateTo({
|
||||
url: `/pages/client/remark/details?remarkId=${pinglunId}`,
|
||||
});
|
||||
} else {
|
||||
// 跳转到评价页面
|
||||
// TODO: 确认订单类型常量
|
||||
uni.navigateTo({
|
||||
url: `/pages/client/order/remark?orderId=${orderId}&orderType=3`, // 3 可能是 home_training 的订单类型
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-page-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background-color: #f7f8fa;
|
||||
}
|
||||
|
||||
.tab-view {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
background-color: #ffffff;
|
||||
white-space: nowrap;
|
||||
border-top: 2rpx solid #f4f4f4;
|
||||
flex-shrink: 0;
|
||||
|
||||
.tab-view-content {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 20rpx;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
transition: 0.2ms all;
|
||||
|
||||
.tab-text {
|
||||
color: $app_fc_main;
|
||||
white-space: nowrap;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-line {
|
||||
width: 24rpx;
|
||||
height: 10rpx;
|
||||
background-color: transparent;
|
||||
margin-top: 18rpx;
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.tab-selected-line {
|
||||
background-color: $app_color_main;
|
||||
}
|
||||
}
|
||||
|
||||
.order-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.status-view-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding-bottom: 32rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user