index.vue 7.73 KB
<!--
 * @Date: 2022-09-19 14:11:06
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-07-06 18:13:43
 * @FilePath: /jgdl/src/pages/authCar/index.vue
 * @Description: 认证车源
-->
<template>
  <view class="auth-car-page">
    <!-- Banner轮播图 -->
    <view class="p-4">
      <nut-swiper :init-page="0" :pagination-visible="true" pagination-color="#ffffff" auto-play="3000"
        class="rounded-lg overflow-hidden" height="160">
        <nut-swiper-item v-for="(image, index) in bannerImages" :key="index">
          <image :src="image" mode="aspectFill" class="w-full h-40 object-cover" />
        </nut-swiper-item>
      </nut-swiper>
    </view>

    <!-- 我要认证按钮 -->
    <view class="px-16 mt-5">
      <nut-button
        color="#FFA135"
        size="large"
        block
        @click="handleAuth"
        class="auth-button"
      >
        <view class="flex items-center justify-center">
          <Check class="mr-2" size="20" color="#ffffff" />
          <text class="text-white font-medium">我要认证</text>
        </view>
      </nut-button>
    </view>

    <!-- 认证车源列表 -->
    <view class="px-4 mt-6">
      <view class="flex justify-between items-center mb-4">
        <text class="text-lg font-medium">认证车源</text>
      </view>

      <!-- 滚动列表 -->
      <scroll-view
        class="auth-car-list"
        :style="scrollStyle"
        :scroll-y="true"
        @scrolltolower="loadMore"
        @scroll="scroll"
        :lower-threshold="50"
        :enable-flex="false"
      >
        <view class="space-y-4">
          <view v-for="car in authCars" :key="car.id"
            class="bg-white rounded-lg shadow-sm overflow-hidden mb-3"
            @tap="() => onCarClick(car)"
          >
            <view class="flex">
              <view class="w-32 h-24 relative p-2">
                <image :src="car.imageUrl" :alt="car.name" mode="aspectFill"
                  class="w-full h-full object-cover rounded-lg" />
              </view>
              <view class="flex-1 p-3 relative">
                <view class="absolute top-2 right-4" @tap.stop="() => toggleFavorite(car.id)">
                  <Heart1 v-if="!favoriteIds.includes(car.id)" size="22" :color="'#9ca3af'" />
                  <HeartFill v-else size="22" :color="'#ef4444'" />
                </view>
                <text class="font-medium text-sm block">{{ car.name }}</text>
                <text class="text-xs text-gray-600 mt-1 block">
                  {{ car.year }} ·
                  <text v-if="car.batteryHealth">电池健康度{{ car.batteryHealth }}%</text>
                  <text v-if="car.mileage"> 行驶{{ car.mileage }}公里</text>
                </text>
                <view class="mt-2">
                  <text class="text-orange-500 font-bold" style="font-size: 1.2rem;">
                    ¥{{ car.price.toLocaleString() }}
                  </text>
                  <text class="text-xs text-gray-500 mt-1 block">{{ car.school }}</text>
                </view>
                <!-- 认证信息 -->
                <!-- <view class="mt-1">
                  <text class="text-xs text-green-600">认证时间 · {{ car.authDate }}</text>
                </view> -->
              </view>
            </view>
          </view>
        </view>

        <!-- Loading indicator -->
        <view v-if="loading" class="loading-container py-4 text-center">
          <text class="loading-text text-gray-500">加载中...</text>
        </view>

        <!-- 没有更多数据 -->
        <view v-if="!hasMore && authCars.length > 0" class="no-more-container py-4 text-center">
          <text class="text-gray-400 text-sm">没有更多数据了</text>
        </view>
      </scroll-view>
    </view>

    <!-- 成功提示 -->
    <nut-toast
      v-model:visible="toastVisible"
      :msg="toastMessage"
      :type="toastType"
    />
  </view>
</template>

<script setup>
import Taro  from '@tarojs/taro'
import { ref, computed, onMounted } from 'vue'
import { Check, Addfollow, Follow, Heart1, HeartFill } from '@nutui/icons-vue-taro'
import './index.less'

// Banner图片数据
const bannerImages = ref([
  'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=800&h=400&fit=crop',
  'https://images.unsplash.com/photo-1571068316344-75bc76f77890?w=800&h=400&fit=crop',
  'https://images.unsplash.com/photo-1571068316344-75bc76f77890?w=800&h=400&fit=crop'
])

// 认证车源数据
const authCars = ref([
  {
    id: 1,
    name: '小牛NGT 电动车',
    year: '2023年',
    batteryHealth: 95,
    mileage: 1200,
    price: 4500,
    school: '上海理工大学',
    imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
    authDate: '2024-01-15'
  },
  {
    id: 2,
    name: '雅迪 DE2 电动车',
    year: '2023年',
    batteryHealth: 88,
    mileage: 2800,
    price: 3200,
    school: '上海大学',
    imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?w=400&h=300&fit=crop',
    authDate: '2024-01-10'
  },
  {
    id: 3,
    name: '爱玛 A500 电动车',
    year: '2022年',
    batteryHealth: 92,
    mileage: 1800,
    price: 2800,
    school: '华东理工大学',
    imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
    authDate: '2024-01-08'
  },
  {
    id: 4,
    name: '台铃 TDR-2023 电动车',
    year: '2023年',
    batteryHealth: 90,
    mileage: 2200,
    price: 3800,
    school: '上海交通大学',
    imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
    authDate: '2024-01-05'
  }
])

// 收藏状态
const favoriteIds = ref([2, 4])

// 加载状态
const loading = ref(false)
const hasMore = ref(true)

// Toast提示
const toastVisible = ref(false)
const toastMessage = ref('')
const toastType = ref('success')

// 滚动样式
const scrollStyle = computed(() => {
  return {
    height: 'calc(100vh - 400rpx)'
  }
})

/**
 * 处理认证按钮点击
 */
const handleAuth = () => {
  // TODO: 跳转到认证页面
  Taro.navigateTo({ url: '/pages/setAuthCar/index' })
}

/**
 * 处理车辆点击
 */
const onCarClick = (car) => {
  // 跳转到车辆详情页
  Taro.navigateTo({ url: `/pages/productDetail/index?id=${car.id}` })
}

/**
 * 切换收藏状态
 */
const toggleFavorite = (carId) => {
  const index = favoriteIds.value.indexOf(carId)
  if (index > -1) {
    favoriteIds.value.splice(index, 1)
    Taro.showToast({
      title: '取消收藏',
      icon: 'none',
      duration: 2000
    })
  } else {
    favoriteIds.value.push(carId)
    Taro.showToast({
      title: '收藏成功',
      icon: 'success',
      duration: 2000
    })
  }
}

/**
 * 加载更多数据
 */
const loadMore = () => {
  if (loading.value || !hasMore.value) return

  loading.value = true

  // 模拟加载更多数据
  setTimeout(() => {
    const newCars = [
      {
        id: authCars.value.length + 1,
        name: '新增认证车辆',
        year: '2023年',
        batteryHealth: 85,
        mileage: 3000,
        price: 2500,
        school: '复旦大学',
        imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?w=400&h=300&fit=crop',
        authDate: '2024-01-01'
      }
    ]

    authCars.value.push(...newCars)
    loading.value = false

    // 模拟没有更多数据
    if (authCars.value.length >= 10) {
      hasMore.value = false
    }
  }, 1000)
}

/**
 * 滚动事件处理
 */
const scroll = (e) => {
  // 可以在这里处理滚动事件
}

/**
 * 显示提示信息
 */
const showToast = (message, type = 'success') => {
  toastMessage.value = message
  toastType.value = type
  toastVisible.value = true
}

// 初始化
onMounted(() => {
  // 可以在这里加载初始数据
})
</script>

<script>
export default {
以在这里加载: 'AuthCarPage'
}
</script>