221 lines
4.9 KiB
Vue
221 lines
4.9 KiB
Vue
<template>
|
|
<view class="order-list-page page-container">
|
|
<!-- Tab标签栏 -->
|
|
<view class="tabs-bar">
|
|
<scroll-view class="tabs-scroll" scroll-x show-scrollbar="false">
|
|
<view class="tabs-container">
|
|
<view
|
|
v-for="(tab, index) in tabs"
|
|
:key="index"
|
|
class="tab-item"
|
|
:class="{ active: currentTab === index }"
|
|
@click="changeTab(index)"
|
|
>
|
|
<text class="tab-text">{{ tab.name }}</text>
|
|
<text v-if="tab.count > 0" class="tab-badge">{{ tab.count }}</text>
|
|
<view v-if="currentTab === index" class="tab-indicator"></view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<!-- 订单列表 -->
|
|
<scroll-view class="orders-scroll" scroll-y refresher-enabled :refresher-triggered="refreshing" @refresherrefresh="onRefresh">
|
|
<view class="orders-list">
|
|
<order-card
|
|
v-for="order in displayOrders"
|
|
:key="order.id"
|
|
:order="order"
|
|
@click="goOrderDetail"
|
|
@action="handleOrderAction"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 空状态 -->
|
|
<view v-if="displayOrders.length === 0" class="empty-state">
|
|
<text class="empty-icon">📦</text>
|
|
<text class="empty-text">暂无订单</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from 'vue'
|
|
import { orders, getOrdersByStatus, getOrderCountByStatus } from '../../mock'
|
|
|
|
const currentTab = ref(0)
|
|
const refreshing = ref(false)
|
|
|
|
const tabs = computed(() => [
|
|
{ name: '全部', status: 'all', count: getOrderCountByStatus('all') },
|
|
{ name: '待支付', status: 0, count: getOrderCountByStatus(0) },
|
|
{ name: '待接单', status: 1, count: getOrderCountByStatus(1) },
|
|
{ name: '进行中', status: 3, count: getOrderCountByStatus(3) },
|
|
{ name: '待确认', status: 4, count: getOrderCountByStatus(4) },
|
|
{ name: '已完成', status: 5, count: getOrderCountByStatus(5) }
|
|
])
|
|
|
|
const displayOrders = computed(() => {
|
|
const status = tabs.value[currentTab.value].status
|
|
return getOrdersByStatus(status)
|
|
})
|
|
|
|
const changeTab = (index) => {
|
|
currentTab.value = index
|
|
}
|
|
|
|
const onRefresh = () => {
|
|
refreshing.value = true
|
|
setTimeout(() => {
|
|
refreshing.value = false
|
|
uni.showToast({ title: '刷新成功', icon: 'none' })
|
|
}, 1000)
|
|
}
|
|
|
|
const goOrderDetail = (order) => {
|
|
uni.navigateTo({
|
|
url: `/pages/order/detail?id=${order.id}`
|
|
})
|
|
}
|
|
|
|
const handleOrderAction = ({ action, order }) => {
|
|
console.log('Action:', action, 'Order:', order)
|
|
|
|
switch (action) {
|
|
case 'pay':
|
|
uni.showToast({ title: '跳转支付...', icon: 'none' })
|
|
break
|
|
case 'cancel':
|
|
uni.showModal({
|
|
title: '提示',
|
|
content: '确定要取消订单吗?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
uni.showToast({ title: '订单已取消', icon: 'none' })
|
|
}
|
|
}
|
|
})
|
|
break
|
|
case 'confirm':
|
|
uni.showModal({
|
|
title: '确认完成',
|
|
content: '确认服务已完成?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
uni.showToast({ title: '已确认完成', icon: 'success' })
|
|
}
|
|
}
|
|
})
|
|
break
|
|
case 'evaluate':
|
|
uni.showToast({ title: '去评价', icon: 'none' })
|
|
break
|
|
case 'detail':
|
|
goOrderDetail(order)
|
|
break
|
|
default:
|
|
uni.showToast({ title: action, icon: 'none' })
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.order-list-page {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100vh;
|
|
}
|
|
|
|
.tabs-bar {
|
|
padding: 0 24rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.tabs-scroll {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.tabs-container {
|
|
display: inline-flex;
|
|
gap: 12rpx;
|
|
}
|
|
|
|
.tab-item {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8rpx;
|
|
padding: 16rpx 32rpx;
|
|
background: rgba(20, 25, 50, 0.6);
|
|
border: 1px solid rgba(0, 255, 255, 0.2);
|
|
border-radius: 50rpx;
|
|
transition: all 0.3s ease;
|
|
|
|
&.active {
|
|
background: rgba(0, 255, 255, 0.15);
|
|
border-color: rgba(0, 255, 255, 0.5);
|
|
|
|
.tab-text {
|
|
color: #00ffff;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
}
|
|
|
|
.tab-text {
|
|
font-size: 26rpx;
|
|
color: #a0a4c4;
|
|
}
|
|
|
|
.tab-badge {
|
|
min-width: 36rpx;
|
|
height: 36rpx;
|
|
line-height: 36rpx;
|
|
padding: 0 8rpx;
|
|
background: #ff3366;
|
|
border-radius: 18rpx;
|
|
font-size: 20rpx;
|
|
color: #ffffff;
|
|
text-align: center;
|
|
}
|
|
|
|
.tab-indicator {
|
|
position: absolute;
|
|
bottom: 8rpx;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 40%;
|
|
height: 4rpx;
|
|
background: linear-gradient(90deg, #00ffff 0%, #0099ff 100%);
|
|
border-radius: 2rpx;
|
|
}
|
|
|
|
.orders-scroll {
|
|
flex: 1;
|
|
}
|
|
|
|
.orders-list {
|
|
padding: 0 24rpx 24rpx;
|
|
}
|
|
|
|
.empty-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 120rpx 0;
|
|
}
|
|
|
|
.empty-icon {
|
|
font-size: 120rpx;
|
|
margin-bottom: 24rpx;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 28rpx;
|
|
color: #7a7e9d;
|
|
}
|
|
</style>
|