|
|
<template>
|
|
|
<view class="order-card" :class="{ pulse: order.status === 0 }">
|
|
|
<view class="card-header">
|
|
|
<view>
|
|
|
<text class="card-no">🎫 {{ order.cardNo }}</text>
|
|
|
<text v-if="order.remindCount > 0" class="remind-badge">🔔催单×{{ order.remindCount }}</text>
|
|
|
</view>
|
|
|
<text class="status-badge" :class="statusClass">{{ statusLabel }}</text>
|
|
|
</view>
|
|
|
<view class="card-body">
|
|
|
<view class="card-items">
|
|
|
<view v-for="(item, idx) in order.items" :key="idx" class="card-item-row">
|
|
|
<text class="card-item-name">{{ item.name }}</text>
|
|
|
<text class="card-item-qty">×{{ item.qty }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
<text v-if="order.note" class="card-note">💬 {{ order.note }}</text>
|
|
|
<text class="card-time">{{ order.submittedAt }}</text>
|
|
|
<slot name="actions"></slot>
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { computed } from 'vue'
|
|
|
import { ORDER_STATUS } from '@/utils/constants'
|
|
|
|
|
|
export default {
|
|
|
name: 'OrderCard',
|
|
|
props: { order: { type: Object, required: true } },
|
|
|
setup(props) {
|
|
|
const statusLabel = computed(() => ORDER_STATUS[props.order.status]?.label || '')
|
|
|
const statusClass = computed(() => ORDER_STATUS[props.order.status]?.class || '')
|
|
|
return { statusLabel, statusClass }
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
.order-card{background:var(--bg-card);border-radius:var(--radius);padding:24rpx;margin-bottom:20rpx;border:1px solid var(--border)}
|
|
|
.order-card.pulse{animation:pulse-glow 2s ease-in-out infinite}
|
|
|
.card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12rpx}
|
|
|
.card-no{font-weight:700;color:var(--gold);font-size:28rpx}
|
|
|
.remind-badge{font-size:20rpx;color:var(--red);font-weight:700;margin-left:8rpx}
|
|
|
.status-badge{font-size:22rpx;font-weight:700;padding:4rpx 16rpx;border-radius:20rpx}
|
|
|
.status-new{background:rgba(255,59,59,.15);color:#FF3B3B}
|
|
|
.status-confirmed{background:rgba(74,144,217,.15);color:#4A90D9}
|
|
|
.status-done{background:rgba(46,213,115,.15);color:#2ED573}
|
|
|
.status-cancelled{background:rgba(116,125,140,.15);color:#747D8C}
|
|
|
.card-body{padding-top:8rpx}
|
|
|
.card-items{padding:4rpx 0}
|
|
|
.card-item-row{display:flex;align-items:center;justify-content:space-between;padding:6rpx 0}
|
|
|
.card-item-name{font-size:52rpx;font-weight:700;color:var(--text)}
|
|
|
.card-item-qty{font-size:28rpx;font-weight:600;color:var(--gold);margin-left:16rpx}
|
|
|
.card-note{font-size:24rpx;color:var(--orange);display:block;padding:8rpx 0}
|
|
|
.card-time{font-size:22rpx;color:var(--text-muted);display:block;padding:4rpx 0}
|
|
|
@keyframes pulse-glow{0%,100%{box-shadow:0 0 20rpx rgba(245,166,35,.1)}50%{box-shadow:0 0 40rpx rgba(245,166,35,.2)}}
|
|
|
</style>
|