order-list.vue 4.46 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.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-amount">¥{{ item.amount }}</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { orders } from '@/data/mock'

export default {
  data() {
    return {
      orders,
      activeStatus: 'all',
      statuses: [
        { key: 'all', label: '全部' },
        { key: 'pay', label: '待付款' },
        { key: 'ship', label: '待发货' },
        { key: 'receive', label: '待收货' },
        { key: 'review', 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
    }
  },
  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;
}

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

.order-card {
  padding: 30rpx;
  margin-bottom: 22rpx;
}

.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);
}

.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);
}

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

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

.order-name {
  display: block;
  font-size: 30rpx;
  line-height: 1.5;
  font-weight: 700;
}

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

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

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