feat(myAuthCar): 替换模拟数据为真实API接口并更新UI显示
- 移除模拟数据生成逻辑,改用真实API获取认证车列表 - 更新车辆信息显示字段以匹配API返回数据结构 - 使用Taro.showToast替换原有的nut-toast组件 - 添加默认封面图片处理逻辑
Showing
1 changed file
with
39 additions
and
108 deletions
| 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 | // ==================== 生命周期 ==================== | ... | ... |
-
Please register or login to post a comment