hookehuyr

feat(myAuthCar): 替换模拟数据为真实API接口并更新UI显示

- 移除模拟数据生成逻辑,改用真实API获取认证车列表
- 更新车辆信息显示字段以匹配API返回数据结构
- 使用Taro.showToast替换原有的nut-toast组件
- 添加默认封面图片处理逻辑
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-09 11:34:24 4 + * @LastEditTime: 2025-07-11 17:14:08
5 * @FilePath: /jgdl/src/pages/myAuthCar/index.vue 5 * @FilePath: /jgdl/src/pages/myAuthCar/index.vue
6 * @Description: 我的认证车页面 6 * @Description: 我的认证车页面
7 --> 7 -->
...@@ -29,22 +29,21 @@ ...@@ -29,22 +29,21 @@
29 <view class="flex p-4"> 29 <view class="flex p-4">
30 <view class="w-24 h-24 relative"> 30 <view class="w-24 h-24 relative">
31 <image 31 <image
32 - :src="item.imageUrl" 32 + :src="item.front_photo || DEFAULT_COVER_IMG"
33 - :alt="item.name"
34 mode="aspectFill" 33 mode="aspectFill"
35 class="w-full h-full object-cover rounded-lg" 34 class="w-full h-full object-cover rounded-lg"
36 /> 35 />
37 </view> 36 </view>
38 <view class="flex-1 ml-4"> 37 <view class="flex-1 ml-4">
39 - <text class="font-medium text-base block">{{ item.name }}</text> 38 + <text class="font-medium text-base block">{{ item.brand }} {{ item.model }}</text>
40 - <text class="text-sm text-gray-500 mt-1 block">{{ item.details }}</text> 39 + <text class="text-sm text-gray-500 mt-1 block">{{ item.manufacture_year }}年|续航{{ item.range_km }}km|最高时速{{ item.max_speed_kmh }}km/h</text>
41 <view class="mt-2 flex justify-between items-center"> 40 <view class="mt-2 flex justify-between items-center">
42 <view> 41 <view>
43 <text class="text-orange-500 font-bold" style="font-size: 1.2rem;"> 42 <text class="text-orange-500 font-bold" style="font-size: 1.2rem;">
44 - ¥{{ item.price.toLocaleString() }} 43 + ¥{{ item.price?.toLocaleString() }}
45 </text> 44 </text>
46 <text class="text-gray-400 text-xs line-through ml-2"> 45 <text class="text-gray-400 text-xs line-through ml-2">
47 - ¥{{ item.originalPrice.toLocaleString() }} 46 + ¥{{ item.market_price?.toLocaleString() }}
48 </text> 47 </text>
49 </view> 48 </view>
50 <nut-button 49 <nut-button
...@@ -81,13 +80,6 @@ ...@@ -81,13 +80,6 @@
81 </view> 80 </view>
82 </scroll-view> 81 </scroll-view>
83 </view> 82 </view>
84 -
85 - <!-- 成功提示 -->
86 - <nut-toast
87 - v-model:visible="toastVisible"
88 - :msg="toastMessage"
89 - :type="toastType"
90 - />
91 </view> 83 </view>
92 </template> 84 </template>
93 85
...@@ -95,37 +87,11 @@ ...@@ -95,37 +87,11 @@
95 import { ref, computed, onMounted } from 'vue' 87 import { ref, computed, onMounted } from 'vue'
96 import Taro from '@tarojs/taro' 88 import Taro from '@tarojs/taro'
97 import './index.less' 89 import './index.less'
90 +// 导入接口
91 +import { getVehicleListAPI } from '@/api/car'
92 +import { DEFAULT_COVER_IMG } from '@/utils/config'
98 93
99 // ==================== API相关 ==================== 94 // ==================== API相关 ====================
100 -/**
101 - * API服务 - 为真实API预留空间
102 - */
103 -const apiService = {
104 - /**
105 - * 获取我的认证车列表
106 - * @param {number} page - 页码
107 - * @param {number} pageSize - 每页数量
108 - * @returns {Promise} API响应
109 - */
110 - async getAuthCarsList(page = 1, pageSize = 10) {
111 - // TODO: 替换为真实API调用
112 - // return await request.get('/api/auth-cars', { page, pageSize })
113 -
114 - // 模拟API延迟
115 - await new Promise(resolve => setTimeout(resolve, 800 + Math.random() * 400))
116 -
117 - // 模拟API响应数据
118 - return {
119 - code: 200,
120 - data: {
121 - list: generateMockData(page, pageSize),
122 - total: 50, // 模拟总数
123 - hasMore: page < 5 // 模拟是否还有更多数据
124 - },
125 - message: 'success'
126 - }
127 - }
128 -}
129 95
130 // ==================== 响应式数据 ==================== 96 // ==================== 响应式数据 ====================
131 /** 97 /**
...@@ -138,15 +104,10 @@ const authCars = ref([]) ...@@ -138,15 +104,10 @@ const authCars = ref([])
138 */ 104 */
139 const loading = ref(false) 105 const loading = ref(false)
140 const hasMore = ref(true) 106 const hasMore = ref(true)
141 -const currentPage = ref(1) 107 +const currentPage = ref(0) // API页码从0开始
142 const pageSize = ref(10) 108 const pageSize = ref(10)
143 109
144 -/** 110 +
145 - * Toast提示
146 - */
147 -const toastVisible = ref(false)
148 -const toastMessage = ref('')
149 -const toastType = ref('success')
150 111
151 /** 112 /**
152 * 滚动样式 - 考虑header和TabBar的高度 113 * 滚动样式 - 考虑header和TabBar的高度
...@@ -158,48 +119,6 @@ const scrollStyle = computed(() => { ...@@ -158,48 +119,6 @@ const scrollStyle = computed(() => {
158 }) 119 })
159 120
160 // ==================== 数据处理方法 ==================== 121 // ==================== 数据处理方法 ====================
161 -/**
162 - * 生成模拟数据
163 - * @param {number} page - 页码
164 - * @param {number} size - 每页数量
165 - * @returns {Array} 模拟数据数组
166 - */
167 -const generateMockData = (page, size) => {
168 - const brands = ['小牛', '雅迪', '绿源', '爱玛', '台铃', '新日', '立马', '小鸟']
169 - const models = ['豪华版', '标准版', '运动版', '经典版', '智能版', '动力版']
170 - const images = [
171 - 'https://images.unsplash.com/photo-1558981285-6f0c94958bb6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
172 - 'https://images.unsplash.com/photo-1558981403-c5f9899a28bc?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
173 - 'https://images.unsplash.com/photo-1591637333184-19aa84b3e01f?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
174 - 'https://images.unsplash.com/photo-1558980664-3a031cf67ea8?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
175 - 'https://images.unsplash.com/photo-1567922045116-2a00fae2ed03?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
176 - 'https://images.unsplash.com/photo-1573981368236-719bbb6f70f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
177 - ]
178 -
179 - const data = []
180 - for (let i = 0; i < size; i++) {
181 - const index = (page - 1) * size + i
182 - const brand = brands[Math.floor(Math.random() * brands.length)]
183 - const model = models[Math.floor(Math.random() * models.length)]
184 - const image = images[Math.floor(Math.random() * images.length)]
185 - const originalPrice = Math.floor(Math.random() * 3000) + 3000
186 - const price = Math.floor(originalPrice * (0.7 + Math.random() * 0.2)) // 7-9折
187 - const usageTime = Math.floor(Math.random() * 24) + 1 // 1-24个月
188 - const range = Math.floor(Math.random() * 100) + 60 // 60-160km续航
189 -
190 - data.push({
191 - id: `auth_${index + 100}`,
192 - name: `${brand} ${model}`,
193 - details: `续航${range}km | 使用${usageTime}个月`,
194 - price: price,
195 - originalPrice: originalPrice,
196 - imageUrl: image,
197 - brand: brand,
198 - authTime: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toISOString() // 最近30天内认证
199 - })
200 - }
201 - return data
202 -}
203 122
204 /** 123 /**
205 * 初始化加载数据 124 * 初始化加载数据
...@@ -207,17 +126,23 @@ const generateMockData = (page, size) => { ...@@ -207,17 +126,23 @@ const generateMockData = (page, size) => {
207 const initData = async () => { 126 const initData = async () => {
208 loading.value = true 127 loading.value = true
209 try { 128 try {
210 - const response = await apiService.getAuthCarsList(1, pageSize.value) 129 + const response = await getVehicleListAPI({
211 - if (response.code) { 130 + verification_status: 5, // 已认证状态
212 - authCars.value = response.data.list 131 + page: 0,
213 - hasMore.value = response.data.hasMore 132 + limit: pageSize.value
214 - currentPage.value = 1 133 + })
134 +
135 + if (response.code === 1) {
136 + const { list, total } = response.data
137 + authCars.value = list || []
138 + hasMore.value = list && list.length === pageSize.value
139 + currentPage.value = 0
215 } else { 140 } else {
216 - showToast('加载失败,请重试', 'error') 141 + showToast(response.msg || '获取认证车列表失败', 'error')
217 } 142 }
218 } catch (error) { 143 } catch (error) {
219 console.error('加载我的认证车列表失败:', error) 144 console.error('加载我的认证车列表失败:', error)
220 - showToast('网络错误,请重试', 'error') 145 + showToast('加载失败,请重试', 'error')
221 } finally { 146 } finally {
222 loading.value = false 147 loading.value = false
223 } 148 }
...@@ -232,18 +157,23 @@ const loadMore = async () => { ...@@ -232,18 +157,23 @@ const loadMore = async () => {
232 loading.value = true 157 loading.value = true
233 try { 158 try {
234 const nextPage = currentPage.value + 1 159 const nextPage = currentPage.value + 1
235 - const response = await apiService.getAuthCarsList(nextPage, pageSize.value) 160 + const response = await getVehicleListAPI({
161 + verification_status: 5, // 已认证状态
162 + page: nextPage,
163 + limit: pageSize.value
164 + })
236 165
237 - if (response.code) { 166 + if (response.code === 1) {
238 - authCars.value.push(...response.data.list) 167 + const { list, total } = response.data
239 - hasMore.value = response.data.hasMore 168 + authCars.value.push(...(list || []))
169 + hasMore.value = list && list.length === pageSize.value
240 currentPage.value = nextPage 170 currentPage.value = nextPage
241 } else { 171 } else {
242 - showToast('加载失败,请重试', 'error') 172 + showToast(response.msg || '加载失败,请重试', 'error')
243 } 173 }
244 } catch (error) { 174 } catch (error) {
245 console.error('加载更多数据失败:', error) 175 console.error('加载更多数据失败:', error)
246 - showToast('网络错误,请重试', 'error') 176 + showToast('加载失败,请重试', 'error')
247 } finally { 177 } finally {
248 loading.value = false 178 loading.value = false
249 } 179 }
...@@ -282,9 +212,10 @@ const scroll = (e) => { ...@@ -282,9 +212,10 @@ const scroll = (e) => {
282 * 显示提示信息 212 * 显示提示信息
283 */ 213 */
284 const showToast = (message, type = 'success') => { 214 const showToast = (message, type = 'success') => {
285 - toastMessage.value = message 215 + Taro.showToast({
286 - toastType.value = type 216 + title: message,
287 - toastVisible.value = true 217 + icon: type === 'success' ? 'success' : 'none'
218 + })
288 } 219 }
289 220
290 // ==================== 生命周期 ==================== 221 // ==================== 生命周期 ====================
......