order-list.vue 5.6 KB
<template>
  <view class="page-shell order-list-page">
    <view class="page-blur"></view>
    <view class="page-blur-secondary"></view>
    <view class="page-blur-tertiary"></view>

    <view class="page-content subpage-content">
      <view class="subpage-nav">
        <view class="subpage-back" @tap="goBack">‹</view>
        <view class="subpage-title-wrap">
          <text class="subpage-title">我的订单</text>
          <text class="subpage-subtitle">从下单到核销自提,把每一次购买都安静记录</text>
        </view>
      </view>

      <scroll-view class="status-scroll" scroll-x>
        <view class="status-row">
          <view v-for="item in statuses" :key="item.key" class="status-chip" :class="{ active: activeStatus === item.key }" @tap="activeStatus = item.key">
            {{ item.label }}
          </view>
        </view>
      </scroll-view>

      <view v-for="item in filteredOrders" :key="item.id" class="order-card glass-card" @tap="goDetail(item)">
        <view class="order-top">
          <text class="order-status">{{ item.status }}</text>
          <text class="order-time">{{ item.createdAt || item.time }}</text>
        </view>
        <view class="order-main">
          <view class="order-art">
            <view class="order-art-ring"></view>
            <text class="order-art-label">{{ shortLabel(item.title) }}</text>
          </view>
          <view class="order-copy">
            <text class="order-name">{{ item.title }}</text>
            <text class="order-sku">{{ item.collection }} · {{ item.sku }} × {{ item.quantity }}</text>
            <text class="order-store">{{ item.pickupStore }} · 门店自提</text>
            <text class="order-amount">¥{{ item.amount }}</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { getDisplayOrders } from '@/packageMall/data/orderFlow'

export default {
  data() {
    return {
      orders: getDisplayOrders(),
      activeStatus: 'all',
      statuses: [
        { key: 'all', label: '全部' },
        { key: 'pay', label: '待付款' },
        { key: 'verify', label: '待核销' },
        { key: 'pickup', label: '已自提' }
      ]
    }
  },
  computed: {
    filteredOrders() {
      if (this.activeStatus === 'all') {
        return this.orders
      }
      return this.orders.filter(item => item.statusKey === this.activeStatus)
    }
  },
  onLoad(options) {
    if (options.status) {
      this.activeStatus = options.status
    }
  },
  onShow() {
    this.orders = getDisplayOrders()
  },
  methods: {
    shortLabel(title) {
      return String(title || '绿纤').replace(/\s+/g, '').slice(0, 2)
    },
    goBack() {
      uni.navigateBack({ fail: () => uni.redirectTo({ url: '/pages/profile/profile' }) })
    },
    goDetail(item) {
      uni.navigateTo({ url: `/packageProfile/order-detail/order-detail?id=${item.id}` })
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/styles/mixins.scss';
@import '@/styles/subpage.scss';

.status-scroll {
  white-space: nowrap;
  margin-bottom: 24rpx;
}

.status-row {
  display: inline-flex;
  padding-bottom: 6rpx;
}

.status-chip {
  @include selection-chip;
  min-width: 138rpx;
  padding: 22rpx 28rpx;
  margin-right: 16rpx;
  text-align: center;
  font-size: 24rpx;
  color: $text-secondary;
  transition: transform 240ms ease, box-shadow 240ms ease, background 240ms ease, color 240ms ease;
}

.status-chip:active {
  transform: translateY(-2rpx) scale(0.98);
}

.status-chip.active {
  @include selection-chip-active;
}

.order-card {
  padding: 30rpx;
  margin-bottom: 22rpx;
  transition: transform 340ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 340ms ease;
  animation: lfRevealUp 760ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.order-card:nth-of-type(1) { animation-delay: 0.08s; }
.order-card:nth-of-type(2) { animation-delay: 0.16s; }
.order-card:nth-of-type(3) { animation-delay: 0.24s; }
.order-card:nth-of-type(4) { animation-delay: 0.32s; }

.order-card:active {
  transform: translateY(-4rpx);
}

.order-top,
.order-main {
  display: flex;
}

.order-top {
  justify-content: space-between;
  align-items: center;
}

.order-status {
  @include chip-soft;
}

.order-time {
  font-size: 22rpx;
  color: $text-tertiary;
}

.order-main {
  margin-top: 22rpx;
}

.order-art {
  width: 180rpx;
  height: 180rpx;
  border-radius: 28rpx;
  flex-shrink: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(241, 246, 241, 0.96);
  border: 1rpx solid rgba(120, 146, 121, 0.14);
  box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.65);
  overflow: hidden;
}

.order-art-ring {
  width: 96rpx;
  height: 96rpx;
  border-radius: 50%;
  border: 1rpx solid rgba(120, 146, 121, 0.18);
  background: rgba(255, 255, 255, 0.45);
  animation: lfPulseSoft 5.2s ease-in-out infinite;
}

.order-art-label {
  position: absolute;
  font-size: 24rpx;
  letter-spacing: 4rpx;
  color: $brand-primary-deep;
  font-weight: 600;
}

.order-art::before {
  content: '';
  position: absolute;
  right: -30rpx;
  top: -30rpx;
  width: 120rpx;
  height: 120rpx;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(210, 191, 156, 0.22), rgba(210, 191, 156, 0));
  animation: lfFloatSoft 9.8s ease-in-out infinite;
}

.order-copy {
  flex: 1;
  margin-left: 22rpx;
}

.order-name,
.order-sku,
.order-store,
.order-amount {
  display: block;
  margin-top: 14rpx;
}

.order-name {
  margin-top: 0;
  font-size: 30rpx;
  line-height: 1.5;
  font-weight: 700;
}

.order-sku,
.order-store {
  font-size: 24rpx;
  color: $text-secondary;
}

.order-amount {
  font-size: 34rpx;
  color: $brand-primary-deep;
  font-weight: 700;
}
</style>