You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

97 lines
3.9 KiB

<template>
<view class="page-orders">
<view class="top-bar">
<text class="top-back" @tap="goBack"></text>
<text class="top-title">我的订单</text>
<text></text>
</view>
<scroll-view class="orders-body" scroll-y v-if="orders.length > 0">
<OrderCard v-for="o in orders" :key="o.id" :order="o">
<template #actions>
<view class="card-actions">
<button v-if="o.status===0" class="action-btn action-remind" @tap="onRemind(o.id)">🔔 催单</button>
<button v-if="o.status!==3 && o.status!==2" class="action-btn action-chat" @tap="onChat">
💬 联系调酒师
<text v-if="card.unread > 0" class="unread-dot">{{ card.unread > 9 ? '9+' : card.unread }}</text>
</button>
</view>
</template>
</OrderCard>
</scroll-view>
<view v-else class="empty-state">
<text class="empty-icon">📋</text>
<text class="empty-text">暂无订单</text>
<button class="btn-back-menu" @tap="goMenu">去点酒 🍸</button>
</view>
</view>
</template>
<script>
import { ref, onMounted, onUnmounted } from 'vue'
import { useCardStore } from '@/stores/card'
import { get, post } from '@/utils/request'
import { API } from '@/utils/constants'
import { startPoll, stopPoll } from '@/utils/poller'
import OrderCard from '@/components/OrderCard.vue'
export default {
components: { OrderCard },
setup() {
const card = useCardStore()
const orders = ref([])
async function loadOrders() {
try {
const res = await get(API.ORDER_LIST, { card_no: card.cardNo })
if (Array.isArray(res)) orders.value = res
} catch (e) {}
}
async function checkUnread() {
try {
const res = await get(API.MESSAGE_UNREAD, { card_no: card.cardNo })
if (res && typeof res.count !== 'undefined') {
card.unread = res.count
}
} catch (e) {}
}
async function onRemind(id) {
try {
await post(API.ORDER_REMIND, { id, card_no: card.cardNo })
uni.showToast({ title: '已催单 🔔', icon: 'none' })
loadOrders()
} catch (e) {}
}
function onChat() { uni.navigateTo({ url: '/pages/chat/chat' }) }
function goBack() { uni.navigateBack() }
function goMenu() { uni.navigateBack() }
onMounted(() => {
loadOrders(); checkUnread(); startPoll('orders', loadOrders, 15000); startPoll('ordersUnread', checkUnread, 10000)
})
onUnmounted(() => { stopPoll('orders'); stopPoll('ordersUnread') })
return { card, orders, onRemind, onChat, goBack, goMenu }
}
}
</script>
<style scoped>
.page-orders{min-height:100vh;display:flex;flex-direction:column;background:var(--bg);width:100%}
.top-bar{height:100rpx;display:flex;align-items:center;justify-content:space-between;padding:0 28rpx;border-bottom:1px solid var(--border);flex-shrink:0}
.top-back{font-size:36rpx;color:var(--text-dim)}
.top-title{font-size:32rpx;font-weight:800;color:var(--gold)}
.orders-body{flex:1;padding:20rpx}
.card-actions{display:flex;gap:16rpx;padding-top:16rpx}
.action-btn{padding:12rpx 28rpx;border-radius:24rpx;font-size:24rpx;font-weight:600;border:none;position:relative}
.action-remind{background:rgba(255,59,59,.15);color:var(--red)}
.action-chat{background:rgba(74,144,217,.15);color:var(--blue)}
.unread-dot{margin-left:6rpx;background:var(--red);color:#fff;font-size:18rpx;min-width:32rpx;height:32rpx;border-radius:16rpx;display:inline-flex;align-items:center;justify-content:center;padding:0 8rpx;vertical-align:middle}
.empty-state{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}
.empty-icon{font-size:112rpx;opacity:.3}
.empty-text{font-size:28rpx;color:var(--text-muted);margin:16rpx 0}
.btn-back-menu{margin-top:40rpx;padding:16rpx 48rpx;border-radius:40rpx;background:var(--gold);color:#1A1A1A;font-size:28rpx;font-weight:700;border:none}
</style>