GameServicePlatform/pages/order/list.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>