index.vue 5.28 KB
<!--
 * @Date: 2025-08-27 17:47:26
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-08-28 09:37:06
 * @FilePath: /lls_program/src/pages/Rewards/index.vue
 * @Description: 文件描述
-->
<template>
  <view class="min-h-screen flex flex-col bg-white">
    <!-- Blue header background -->
    <view class="bg-blue-500 h-48 absolute w-full top-0 left-0 z-0"></view>
    <!-- <AppHeader title="兑换中心" :showBack="false" /> -->
    <!-- Content -->
    <view class="relative z-10 flex-1 pb-20">
      <!-- Points display -->
      <view class="pt-8 pb-8 flex flex-col items-center">
        <h2 class="text-4xl font-bold text-white mb-1">2580分</h2>
        <p class="text-white text-opacity-80">我的积分</p>
      </view>
      <!-- Main content -->
      <view class="bg-white rounded-t-3xl px-4 pt-5">
        <!-- Quick exchange options -->
        <!-- Search bar -->
        <view class="mb-6">
          <view class="relative">
            <input type="text" v-model="searchQuery" placeholder="搜索商户名称"
              class=" bg-gray-100 rounded-lg py-3 pl-10 pr-4 border border-transparent focus:bg-white focus:border-blue-500 focus:outline-none" />
            <view class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
              <Search2 size="20" class="text-gray-400" />
            </view>
          </view>
        </view>

        <view class="flex gap-3 mb-6">
          <view v-for="option in quickExchangeOptions" :key="option.points" @click="selectedPoints = option.points"
            :class="[
              'flex-1 py-3 rounded-lg border text-center',
              selectedPoints === option.points
                ? 'border-blue-500 bg-blue-50 text-blue-500'
                : 'border-gray-200 text-gray-700'
            ]">
            {{ option.label }}
          </view>
        </view>
        <view class="flex justify-between items-center mb-4">
          <h3 class="text-lg font-medium">可兑换列表</h3>
          <view class="flex items-center text-gray-500 text-sm" @click="toggleSortOrder">
            <span class="mr-1">{{ sortOrder === 'desc' ? '从高到低排列' : '从低到高排列' }}</span>
            <ScreenLittle />
          </view>
        </view>
        <!-- Rewards list -->
        <view class="space-y-4">
          <view v-for="reward in sortedRewardItems" :key="reward.id"
            class="bg-white rounded-xl p-4 flex items-center shadow-[0_2px_8px_rgba(0,0,0,0.08)]">
            <image :src="reward.logo" class="w-16 h-16 rounded-lg mr-4 flex-shrink-0" mode="aspectFill" />
            <view class="flex-1 min-w-0">
              <view class="font-medium text-base">{{ reward.title }}</view>
              <view class="text-gray-500 text-sm mt-1">{{ reward.merchant }}</view>
            </view>
            <view class="ml-4 px-4 py-2 bg-blue-500 text-white rounded-lg text-sm flex-shrink-0"
              @click="goToRewardDetail(reward)">
              {{ reward.points }}分兑换
            </view>
          </view>
        </view>
      </view>
    </view>
    <!-- <BottomNav /> -->
  </view>
</template>

<script setup>
import { ref, computed } from 'vue';
import Taro from '@tarojs/taro';
import { ScreenLittle, Search2 } from '@nutui/icons-vue-taro';
import AppHeader from '../../components/AppHeader.vue';
import BottomNav from '../../components/BottomNav.vue';

const searchQuery = ref('');
const selectedPoints = ref(null);
const sortOrder = ref('desc'); // 'asc' or 'desc'

const sortedRewardItems = computed(() => {
  let items = [...rewardItems.value];

  // Filter by search query
  if (searchQuery.value) {
    items = items.filter(item =>
      item.merchant.toLowerCase().includes(searchQuery.value.toLowerCase())
    );
  }

  // Sort items
  return items.sort((a, b) => {
    if (sortOrder.value === 'asc') {
      return a.points - b.points;
    } else {
      return b.points - a.points;
    }
  });
});

const toggleSortOrder = () => {
  sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc';
};

const rewardItems = ref([
  {
    id: 1,
    logo: 'https://placehold.co/400x400/e2f3ff/0369a1?text=LFX&font=roboto',
    title: '杏花楼集团85折券',
    merchant: '杏花楼集团',
    points: 10
  },
  {
    id: 2,
    logo: 'https://placehold.co/400x400/e2f3ff/0369a1?text=LFX&font=roboto',
    title: '吴良材眼镜店85折券',
    merchant: '吴良材眼镜店',
    points: 10
  },
  {
    id: 3,
    logo: 'https://placehold.co/400x400/e2f3ff/0369a1?text=LFX&font=roboto',
    title: '老凤祥银楼20元抵用券',
    merchant: '老凤祥银楼',
    points: 1000
  },
  {
    id: 4,
    logo: 'https://placehold.co/400x400/e2f3ff/0369a1?text=LFX&font=roboto',
    title: '沈大成双酿团2元抵用券',
    merchant: '沈大成双酿团',
    points: 100
  },
  {
    id: 5,
    logo: 'https://placehold.co/400x400/e2f3ff/0369a1?text=LFX&font=roboto',
    title: '这是一个非常非常非常非常非常长的标题用于测试换行效果',
    merchant: '一个名字很长的商家',
    points: 500
  }
]);

const quickExchangeOptions = ref([
  { points: 3000, label: '3000分可兑' },
  { points: 1000, label: '1000分可兑' },
  { points: 100, label: '100分可兑' }
]);

const goToRewardDetail = (reward) => {
  Taro.navigateTo({
    url: `/pages/RewardDetail/index?id=${reward.id}`
  });
};
</script>