FeaturedRecommendations.vue 3.7 KB
<template>
  <view class="px-4 mt-4">
    <view class="flex justify-between items-center mb-2">
      <text class="text-lg font-medium">精品推荐</text>
      <view class="text-sm text-gray-500 flex items-center" @tap="onMoreRecommendClick">
        <text>更多</text>
        <RectRight size="12" />
      </view>
    </view>
    <view class="grid grid-cols-2 gap-3">
      <view v-for="scooter in featuredScooters" :key="scooter.id"
        class="bg-white rounded-lg shadow-sm overflow-hidden" @tap="() => onProductClick(scooter)">
        <view class="relative p-2">
          <image :src="scooter.front_photo" mode="aspectFill" class="w-full h-36 object-cover rounded-lg" />
          <view
            class="absolute top-4 right-3 w-7 h-7 rounded-full bg-white bg-opacity-80 flex items-center justify-center"
            @tap.stop="() => toggleFavorite(scooter)">
            <Heart1 v-if="!scooter.is_favorite" size="22" :color="'#9ca3af'" />
            <HeartFill v-else size="22" :color="'#ef4444'" />
          </view>
          <view v-if="scooter.verification_status === 5"
            class="absolute bottom-4 right-4 text-white text-xs px-1.5 py-0.5 rounded flex items-center"
            style="background-color: #EB5305;">
            <Check size="12" color="#ffffff" class="mr-0.5" />
            <text class="text-white">认证</text>
          </view>
        </view>
        <view class="p-2 pl-3">
          <text class="font-medium text-sm block">{{ scooter.brand }} {{ scooter.model }}</text>
          <text class="text-xs text-gray-500 block mt-1 mb-1">
            {{ scooter.manufacture_year }}年 · {{ scooter.school_name }}
          </text>
          <view class="mt-1">
            <text class="text-orange-500 font-bold" style="font-size: 1.25rem;">
              ¥{{ scooter.price.toLocaleString() }}
            </text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import Taro from '@tarojs/taro'
import { ref, onMounted } from 'vue'
import { RectRight, Check, Heart1, HeartFill } from '@nutui/icons-vue-taro'
import { getRecommendVehicleAPI } from '@/api/car'
import { useFavorite } from '@/composables/useFavorite'
import { DEFAULT_COVER_IMG } from '@/utils/config'

// 定义组件名称
defineOptions({
  name: 'FeaturedRecommendations'
})

// 精品推荐数据
const featuredScooters = ref([])

// 使用收藏功能composables
const { toggleFavorite } = useFavorite()

/**
 * 查看更多点击事件
 */
const onMoreRecommendClick = () => {
  Taro.navigateTo({
    url: '/pages/recommendCarList/index'
  })
}

/**
 * 点击产品卡片
 * @param {Object} scooter - 电动车信息
 */
const onProductClick = (scooter) => {
  Taro.navigateTo({
    url: `/pages/productDetail/index?id=${scooter.id}`
  })
}

/**
 * 加载精品推荐数据
 */
const loadFeaturedData = async () => {
  try {
    const res = await getRecommendVehicleAPI({ section: 3, page: 0, limit: 4 })
    if (res.code) {
      // 处理图片数据
      const processedData = res.data.list.map(item => ({
        ...item,
        front_photo: item.front_photo || DEFAULT_COVER_IMG,
        // 确保价格为数字类型
        price: Number(item.price) || 0,
        market_price: Number(item.market_price) || 0
      }))
      featuredScooters.value = processedData
    }
  } catch (error) {
    console.error('加载精品推荐数据失败:', error)
  }
}

// 组件挂载时加载数据
onMounted(() => {
  loadFeaturedData()
})
</script>

<style lang="less" scoped>
// 使用Tailwind CSS类,只保留必要的自定义样式
.grid {
  display: grid;
}

.grid-cols-2 {
  grid-template-columns: repeat(2, 1fr);
}

.gap-3 {
  gap: 0.75rem;
}

// 确保图片正确显示
image {
  display: block;
}
</style>