FeaturedRecommendations.vue
3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<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>