hookehuyr

feat: 新增特价好车和最新上架页面功能

添加特价好车和最新上架两个新页面,包含以下主要变更:
1. 新增页面路由配置
2. 实现车辆列表展示、筛选和收藏功能
3. 优化页面样式和交互体验
4. 添加页面间导航逻辑
1 /* 1 /*
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-02 18:16:09 4 + * @LastEditTime: 2025-07-02 22:18:10
5 * @FilePath: /jgdl/src/app.config.js 5 * @FilePath: /jgdl/src/app.config.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -16,6 +16,8 @@ export default { ...@@ -16,6 +16,8 @@ export default {
16 'pages/register/index', 16 'pages/register/index',
17 'pages/authCar/index', 17 'pages/authCar/index',
18 'pages/setAuthCar/index', 18 'pages/setAuthCar/index',
19 + 'pages/newCarList/index',
20 + 'pages/goodCarList/index',
19 'pages/auth/index', 21 'pages/auth/index',
20 ], 22 ],
21 subpackages: [ // 配置在tabBar中的页面不能分包写到subpackages中去 23 subpackages: [ // 配置在tabBar中的页面不能分包写到subpackages中去
......
1 +/*
2 + * @Date: 2025-07-02 22:18:16
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-07-02 23:00:27
5 + * @FilePath: /jgdl/src/pages/goodCarList/index.config.js
6 + * @Description: 文件描述
7 + */
8 +export default {
9 + navigationBarTitleText: '',
10 + usingComponents: {
11 + },
12 +}
1 +/* 特价好车页面样式 */
2 +.good-car-list {
3 + width: 100%;
4 + overflow-y: auto;
5 + -webkit-overflow-scrolling: touch;
6 +}
7 +
8 +/* 车辆卡片样式 */
9 +.good-car-list .bg-white {
10 + background-color: #ffffff;
11 + border: 1px solid #f0f0f0;
12 + transition: all 0.3s ease;
13 +}
14 +
15 +.good-car-list .bg-white:hover {
16 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
17 +}
18 +
19 +/* 图片容器 */
20 +.good-car-list .w-32 {
21 + width: 200rpx;
22 + height: 150rpx;
23 + flex-shrink: 0;
24 +}
25 +
26 +.good-car-list image {
27 + border-radius: 8rpx;
28 + object-fit: cover;
29 +}
30 +
31 +/* 信息区域 */
32 +.good-car-list .flex-1 {
33 + flex: 1;
34 + min-width: 0;
35 +}
36 +
37 +/* 价格样式 */
38 +.good-car-list .text-orange-500 {
39 + color: #f97316;
40 + font-weight: bold;
41 +}
42 +
43 +.good-car-list .line-through {
44 + text-decoration: line-through;
45 +}
46 +
47 +/* 特价标签 */
48 +.good-car-list .text-red-600 {
49 + color: #dc2626;
50 + font-weight: 500;
51 +}
52 +
53 +/* 折扣标签 */
54 +.good-car-list .bg-red-500 {
55 + background-color: #ef4444;
56 + padding: 2rpx 6rpx;
57 + border-radius: 4rpx;
58 + font-size: 20rpx;
59 + line-height: 1;
60 +}
61 +
62 +/* 加载状态 */
63 +.loading-container {
64 + display: flex;
65 + justify-content: center;
66 + align-items: center;
67 + padding: 32rpx 0 100rpx 0;
68 +}
69 +
70 +.loading-text {
71 + color: #9ca3af;
72 + font-size: 28rpx;
73 +}
74 +
75 +/* 无更多数据提示 */
76 +.no-more-container {
77 + display: flex;
78 + justify-content: center;
79 + align-items: center;
80 + padding: 32rpx 0 100rpx 0;
81 +}
82 +
83 +.no-more-container text {
84 + color: #9ca3af;
85 + font-size: 24rpx;
86 +}
87 +
88 +/* NutUI 组件样式覆盖 */
89 +:deep(.nut-menu) {
90 + background-color: #ffffff;
91 + border-bottom: 1px solid #f0f0f0;
92 +}
93 +
94 +:deep(.nut-menu-item) {
95 + color: #333333;
96 + font-size: 28rpx;
97 +}
98 +
99 +:deep(.nut-menu-item.active) {
100 + color: #f97316;
101 +}
102 +
103 +// .nut-searchbar{
104 +// background: transparent !important;
105 +// }
106 +
107 +// :deep(.nut-searchbar .nut-searchbar__input-inner) {
108 +// background-color: #ffffff;
109 +// border-radius: 20rpx;
110 +// font-size: 28rpx;
111 +// }
112 +
113 +:deep(.nut-sticky) {
114 + z-index: 999;
115 +}
116 +
117 +/* 响应式适配 */
118 +@media screen and (max-width: 750rpx) {
119 + .good-car-list .w-32 {
120 + width: 180rpx;
121 + height: 135rpx;
122 + }
123 +
124 + .good-car-list .text-xl {
125 + font-size: 32rpx;
126 + }
127 +
128 + .good-car-list .text-sm {
129 + font-size: 24rpx;
130 + }
131 +
132 + .good-car-list .text-xs {
133 + font-size: 20rpx;
134 + }
135 +}
136 +
137 +/* 深色模式适配 */
138 +@media (prefers-color-scheme: dark) {
139 + .good-car-list .bg-white {
140 + background-color: #1f2937;
141 + border-color: #374151;
142 + }
143 +
144 + .good-car-list .text-gray-600 {
145 + color: #9ca3af;
146 + }
147 +
148 + .good-car-list .text-gray-500 {
149 + color: #6b7280;
150 + }
151 +
152 + .good-car-list .text-gray-400 {
153 + color: #9ca3af;
154 + }
155 +}
156 +
157 +/* 动画效果 */
158 +.good-car-list .bg-white {
159 + animation: fadeInUp 0.3s ease-out;
160 +}
161 +
162 +@keyframes fadeInUp {
163 + from {
164 + opacity: 0;
165 + transform: translateY(20rpx);
166 + }
167 + to {
168 + opacity: 1;
169 + transform: translateY(0);
170 + }
171 +}
172 +
173 +/* 收藏按钮动画 */
174 +.good-car-list .absolute {
175 + transition: transform 0.2s ease;
176 +}
177 +
178 +.good-car-list .absolute:active {
179 + transform: scale(0.9);
180 +}
181 +
182 +/* 卡片点击效果 */
183 +.good-car-list .bg-white:active {
184 + transform: scale(0.98);
185 + transition: transform 0.1s ease;
186 +}
187 +
188 +/* 滚动条样式 */
189 +.good-car-list::-webkit-scrollbar {
190 + width: 0;
191 + background: transparent;
192 +}
193 +
194 +/* 特价标识样式优化 */
195 +.good-car-list .absolute.bottom-3.right-3 {
196 + background: linear-gradient(45deg, #ef4444, #dc2626);
197 + box-shadow: 0 2rpx 4rpx rgba(239, 68, 68, 0.3);
198 +}
199 +
200 +.good-car-list .absolute.top-3.left-3 {
201 + background: linear-gradient(45deg, #ef4444, #dc2626);
202 + box-shadow: 0 2rpx 4rpx rgba(239, 68, 68, 0.3);
203 +}
204 +
205 +/* 价格区域样式优化 */
206 +.good-car-list .flex.items-center {
207 + align-items: baseline;
208 + gap: 8rpx;
209 +}
210 +
211 +/* 文字省略 */
212 +.good-car-list .font-medium {
213 + overflow: hidden;
214 + text-overflow: ellipsis;
215 + white-space: nowrap;
216 + max-width: 100%;
217 +}
218 +
219 +/* 间距调整 */
220 +.good-car-list .space-y-4 > * + * {
221 + margin-top: 16rpx;
222 +}
223 +
224 +.good-car-list .mb-3 {
225 + margin-bottom: 12rpx;
226 +}
1 +<!--
2 + * @Date: 2022-09-19 14:11:06
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-07-02 22:49:42
5 + * @FilePath: /jgdl/src/pages/goodCarList/index.vue
6 + * @Description: 特价好车页面
7 +-->
8 +<template>
9 + <view>
10 + <view class="flex flex-col bg-white min-h-screen">
11 + <!-- Header -->
12 + <nut-sticky>
13 + <view class="bg-orange-400 p-4 pt-4 pb-4">
14 + <nut-row type="flex" justify="center" align="center">
15 + <nut-col span="6">
16 + <view class="text-xl font-bold text-white">特价好车</view>
17 + </nut-col>
18 + <nut-col span="18">
19 + <!-- Search Bar -->
20 + <nut-searchbar v-model="searchValue" placeholder="搜索品牌型号" shape="round"
21 + background="transparent" input-background="#ffffff">
22 + <template #leftin>
23 + <Search2 />
24 + </template>
25 + </nut-searchbar>
26 + </nut-col>
27 + </nut-row>
28 + </view>
29 +
30 + <!-- Filter options -->
31 + <nut-menu>
32 + <nut-menu-item v-model="selectedBrand" :options="brandOptions" @change="onBrandChange" />
33 + <nut-menu-item v-model="selectedYear" :options="yearOptions" @change="onYearChange" />
34 + <nut-menu-item v-model="selectedSchool" :options="schoolOptions" @change="onSchoolChange" />
35 + </nut-menu>
36 + </nut-sticky>
37 +
38 + <!-- 特价好车列表 -->
39 + <view class="flex-1 p-4">
40 + <!-- 滚动列表 -->
41 + <scroll-view
42 + class="good-car-list"
43 + :style="scrollStyle"
44 + :scroll-y="true"
45 + @scrolltolower="loadMore"
46 + @scroll="scroll"
47 + :lower-threshold="50"
48 + :enable-flex="false"
49 + >
50 + <view class="space-y-4">
51 + <view v-for="car in goodCars" :key="car.id"
52 + class="bg-white rounded-lg shadow-sm overflow-hidden mb-3"
53 + @tap="() => onCarClick(car)"
54 + >
55 + <view class="flex">
56 + <view class="w-32 h-24 relative p-2">
57 + <image :src="car.imageUrl" :alt="car.name" mode="aspectFill"
58 + class="w-full h-full object-cover rounded-lg" />
59 + <view v-if="car.isSpecial"
60 + class="absolute bottom-3 right-3 bg-red-500 text-white text-xs px-1 rounded flex items-center">
61 + <text class="text-white">特</text>
62 + </view>
63 + <!-- 折扣标签 -->
64 + <view v-if="car.discount"
65 + class="absolute top-3 left-3 bg-red-500 text-white text-xs px-1 rounded">
66 + <text class="text-white">{{ car.discount }}折</text>
67 + </view>
68 + </view>
69 + <view class="flex-1 p-3 relative">
70 + <view class="absolute top-3 right-4" @tap.stop="() => toggleFavorite(car.id)">
71 + <Addfollow v-if="!favoriteIds.includes(car.id)" size="16" color="#9ca3af" />
72 + <HeartFill v-else size="16" color="#ef4444" />
73 + </view>
74 + <text class="font-medium text-sm block">{{ car.name }}</text>
75 + <text class="text-xs text-gray-600 mt-1 block">
76 + {{ car.year }} ·
77 + <text v-if="car.batteryHealth">电池健康度{{ car.batteryHealth }}%</text>
78 + <text v-if="car.mileage"> 行驶{{ car.mileage }}公里</text>
79 + </text>
80 + <view class="mt-2">
81 + <!-- 原价和现价 -->
82 + <view class="flex items-center">
83 + <text v-if="car.originalPrice" class="text-xs text-gray-400 line-through mr-2">
84 + ¥{{ car.originalPrice.toLocaleString() }}
85 + </text>
86 + <text class="text-orange-500 font-bold">
87 + ¥{{ car.price.toLocaleString() }}
88 + </text>
89 + </view>
90 + <text class="text-xs text-gray-500 mt-1 block">{{ car.school }}</text>
91 + </view>
92 + <!-- 特价标签 -->
93 + <view class="mt-1">
94 + <text class="text-xs text-red-600">{{ car.specialTag }}</text>
95 + </view>
96 + </view>
97 + </view>
98 + </view>
99 + </view>
100 +
101 + <!-- Loading indicator -->
102 + <view v-if="loading" class="loading-container py-4 text-center">
103 + <text class="loading-text text-gray-500">加载中...</text>
104 + </view>
105 +
106 + <!-- 没有更多数据 -->
107 + <view v-if="!hasMore && goodCars.length > 0" class="no-more-container py-4 text-center">
108 + <text class="text-gray-400 text-sm">没有更多数据了</text>
109 + </view>
110 + </scroll-view>
111 + </view>
112 + </view>
113 +
114 + <!-- 自定义TabBar -->
115 + <TabBar />
116 +
117 + <!-- 成功提示 -->
118 + <nut-toast
119 + v-model:visible="toastVisible"
120 + :msg="toastMessage"
121 + :type="toastType"
122 + />
123 + </view>
124 +</template>
125 +
126 +<script setup>
127 +import { ref, computed, onMounted } from 'vue'
128 +import { Search2, Addfollow, HeartFill } from '@nutui/icons-vue-taro'
129 +import TabBar from '@/components/TabBar.vue'
130 +import './index.less'
131 +
132 +// 响应式数据
133 +const searchValue = ref('')
134 +const favoriteIds = ref(['2', '4', '6'])
135 +
136 +// Filter states - 使用NutUI Menu组件
137 +const selectedBrand = ref('全部品牌')
138 +const selectedYear = ref('出厂年份')
139 +const selectedSchool = ref('所在学校')
140 +
141 +// Menu选项数据
142 +const brandOptions = ref([
143 + { text: '全部品牌', value: '全部品牌' },
144 + { text: '雅迪', value: '雅迪' },
145 + { text: '台铃', value: '台铃' },
146 + { text: '小鸟', value: '小鸟' },
147 + { text: '新日', value: '新日' },
148 + { text: '爱玛', value: '爱玛' },
149 + { text: '小牛', value: '小牛' }
150 +])
151 +
152 +const yearOptions = ref([
153 + { text: '出厂年份', value: '出厂年份' },
154 + { text: '2024年', value: '2024年' },
155 + { text: '2023年', value: '2023年' },
156 + { text: '2022年', value: '2022年' },
157 + { text: '2021年', value: '2021年' },
158 + { text: '2020年', value: '2020年' }
159 +])
160 +
161 +const schoolOptions = ref([
162 + { text: '所在学校', value: '所在学校' },
163 + { text: '上海理工大学', value: '上海理工大学' },
164 + { text: '上海复旦大学', value: '上海复旦大学' },
165 + { text: '上海同济大学', value: '上海同济大学' },
166 + { text: '上海交通大学', value: '上海交通大学' }
167 +])
168 +
169 +// 特价好车数据
170 +const goodCars = ref([
171 + {
172 + id: 1,
173 + name: '雅迪 DE3 电动车',
174 + year: '2023年',
175 + batteryHealth: 85,
176 + mileage: 1200,
177 + originalPrice: 4800,
178 + price: 3600,
179 + discount: 7.5,
180 + school: '上海理工大学',
181 + imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
182 + specialTag: '限时特价',
183 + isSpecial: true,
184 + brand: '雅迪'
185 + },
186 + {
187 + id: 2,
188 + name: '爱玛 A600 电动车',
189 + year: '2022年',
190 + batteryHealth: 80,
191 + mileage: 2000,
192 + originalPrice: 3800,
193 + price: 2850,
194 + discount: 7.5,
195 + school: '上海大学',
196 + imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?w=400&h=300&fit=crop',
197 + specialTag: '急售特价',
198 + isSpecial: true,
199 + brand: '爱玛'
200 + },
201 + {
202 + id: 3,
203 + name: '台铃 TDR-2023 电动车',
204 + year: '2023年',
205 + batteryHealth: 88,
206 + mileage: 800,
207 + originalPrice: 4200,
208 + price: 3360,
209 + discount: 8.0,
210 + school: '华东理工大学',
211 + imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
212 + specialTag: '毕业甩卖',
213 + isSpecial: true,
214 + brand: '台铃'
215 + },
216 + {
217 + id: 4,
218 + name: '小牛 NGT 电动车',
219 + year: '2022年',
220 + batteryHealth: 75,
221 + mileage: 3000,
222 + originalPrice: 5200,
223 + price: 3640,
224 + discount: 7.0,
225 + school: '上海交通大学',
226 + imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
227 + specialTag: '超值特价',
228 + isSpecial: true,
229 + brand: '小牛'
230 + }
231 +])
232 +
233 +// 加载状态
234 +const loading = ref(false)
235 +const hasMore = ref(true)
236 +const currentPage = ref(1)
237 +const pageSize = ref(4)
238 +
239 +// Toast提示
240 +const toastVisible = ref(false)
241 +const toastMessage = ref('')
242 +const toastType = ref('success')
243 +
244 +// 滚动样式 - 考虑navbar、filter和TabBar的高度
245 +const scrollStyle = computed(() => {
246 + return {
247 + height: 'calc(100vh - 380rpx)' // 减去header、filter和TabBar的高度
248 + }
249 +})
250 +
251 +/**
252 + * 切换收藏状态
253 + * @param {string} carId - 车辆ID
254 + */
255 +const toggleFavorite = (carId) => {
256 + const index = favoriteIds.value.indexOf(carId.toString())
257 + if (index > -1) {
258 + favoriteIds.value.splice(index, 1)
259 + showToast('取消收藏', 'success')
260 + } else {
261 + favoriteIds.value.push(carId.toString())
262 + showToast('收藏成功', 'success')
263 + }
264 +}
265 +
266 +/**
267 + * 点击车辆卡片
268 + * @param {Object} car - 车辆信息
269 + */
270 +const onCarClick = (car) => {
271 + // TODO: 跳转到车辆详情页
272 + showToast(`查看${car.name}详情`, 'success')
273 +}
274 +
275 +// Menu组件事件处理方法
276 +/**
277 + * 品牌选择变化事件
278 + * @param {string} value - 选中的品牌值
279 + */
280 +const onBrandChange = (value) => {
281 + selectedBrand.value = value
282 + // 这里可以添加过滤逻辑
283 + filterCars()
284 +}
285 +
286 +/**
287 + * 年份选择变化事件
288 + * @param {string} value - 选中的年份值
289 + */
290 +const onYearChange = (value) => {
291 + selectedYear.value = value
292 + // 这里可以添加过滤逻辑
293 + filterCars()
294 +}
295 +
296 +/**
297 + * 学校选择变化事件
298 + * @param {string} value - 选中的学校值
299 + */
300 +const onSchoolChange = (value) => {
301 + selectedSchool.value = value
302 + // 这里可以添加过滤逻辑
303 + filterCars()
304 +}
305 +
306 +/**
307 + * 过滤车辆数据
308 + */
309 +const filterCars = () => {
310 + // TODO: 实现过滤逻辑
311 + showToast('筛选条件已更新', 'success')
312 +}
313 +
314 +/**
315 + * 生成模拟车辆数据
316 + * @param {number} page - 页码
317 + * @param {number} size - 每页数量
318 + * @returns {Array} 车辆数据数组
319 + */
320 +const generateMockData = (page, size) => {
321 + const brands = ['雅迪', '台铃', '小鸟', '新日', '爱玛', '小牛', '绿源', '立马']
322 + const schools = ['上海理工大学', '上海复旦大学', '上海同济大学', '上海交通大学', '华东师范大学', '上海大学']
323 + const years = ['2024年', '2023年', '2022年', '2021年', '2020年']
324 + const images = [
325 + 'https://images.unsplash.com/photo-1567922045116-2a00fae2ed03?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
326 + 'https://images.unsplash.com/photo-1573981368236-719bbb6f70f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
327 + 'https://images.unsplash.com/photo-1583568671741-c70dafa8e8e7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
328 + 'https://images.unsplash.com/photo-1595941069915-4ebc5197c14a?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
329 + 'https://images.unsplash.com/photo-1558981285-6f0c94958bb6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
330 + 'https://images.unsplash.com/photo-1558981403-c5f9899a28bc?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
331 + ]
332 + const specialTags = ['限时特价', '急售特价', '毕业甩卖', '超值特价', '清仓特价', '年底促销']
333 +
334 + const data = []
335 + for (let i = 0; i < size; i++) {
336 + const index = (page - 1) * size + i
337 + const brand = brands[Math.floor(Math.random() * brands.length)]
338 + const school = schools[Math.floor(Math.random() * schools.length)]
339 + const year = years[Math.floor(Math.random() * years.length)]
340 + const image = images[Math.floor(Math.random() * images.length)]
341 + const specialTag = specialTags[Math.floor(Math.random() * specialTags.length)]
342 + const originalPrice = Math.floor(Math.random() * 2000) + 3000
343 + const discount = (Math.floor(Math.random() * 30) + 60) / 10 // 6.0-8.9折
344 + const price = Math.floor(originalPrice * discount / 10)
345 +
346 + data.push({
347 + id: `good_${index + 100}`,
348 + name: `${brand} ${['豪华版', '标准版', '运动版', '经典版'][Math.floor(Math.random() * 4)]}`,
349 + year: year,
350 + school: school,
351 + originalPrice: originalPrice,
352 + price: price,
353 + discount: discount,
354 + imageUrl: image,
355 + batteryHealth: Math.floor(Math.random() * 30) + 70, // 特价车电池健康度相对较低
356 + mileage: Math.floor(Math.random() * 3000) + 1000, // 特价车里程相对较高
357 + brand: brand,
358 + specialTag: specialTag,
359 + isSpecial: true
360 + })
361 + }
362 + return data
363 +}
364 +
365 +/**
366 + * 加载更多数据
367 + */
368 +const loadMore = () => {
369 + if (loading.value || !hasMore.value) return
370 +
371 + loading.value = true
372 +
373 + // 模拟网络请求延迟
374 + setTimeout(() => {
375 + // 模拟最多加载5页数据
376 + if (currentPage.value >= 5) {
377 + hasMore.value = false
378 + loading.value = false
379 + return
380 + }
381 +
382 + currentPage.value++
383 + const newData = generateMockData(currentPage.value, pageSize.value)
384 + goodCars.value.push(...newData)
385 + loading.value = false
386 + }, 1000 + Math.random() * 1000)
387 +}
388 +
389 +/**
390 + * 滚动事件处理
391 + */
392 +const scroll = (e) => {
393 + // 可以在这里处理滚动事件
394 +}
395 +
396 +/**
397 + * 显示提示信息
398 + */
399 +const showToast = (message, type = 'success') => {
400 + toastMessage.value = message
401 + toastType.value = type
402 + toastVisible.value = true
403 +}
404 +
405 +// 初始化
406 +onMounted(() => {
407 + // 可以在这里加载初始数据
408 +})
409 +</script>
410 +
411 +<script>
412 +export default {
413 + name: 'GoodCarListPage'
414 +}
415 +</script>
1 <!-- 1 <!--
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-02 20:49:05 4 + * @LastEditTime: 2025-07-02 22:58:32
5 * @FilePath: /jgdl/src/pages/index/index.vue 5 * @FilePath: /jgdl/src/pages/index/index.vue
6 * @Description: 捡个电驴首页 6 * @Description: 捡个电驴首页
7 --> 7 -->
...@@ -40,13 +40,13 @@ ...@@ -40,13 +40,13 @@
40 <!-- Category Icons --> 40 <!-- Category Icons -->
41 <view class="px-4 mt-2"> 41 <view class="px-4 mt-2">
42 <view class="flex justify-around py-4"> 42 <view class="flex justify-around py-4">
43 - <view class="flex flex-col items-center"> 43 + <view class="flex flex-col items-center" @tap="onNewCarClick">
44 <view class="w-12 h-12 rounded-full bg-orange-100 flex items-center justify-center"> 44 <view class="w-12 h-12 rounded-full bg-orange-100 flex items-center justify-center">
45 <Clock size="20" color="#f97316" /> 45 <Clock size="20" color="#f97316" />
46 </view> 46 </view>
47 <text class="text-xs mt-1 text-gray-700">最新上架</text> 47 <text class="text-xs mt-1 text-gray-700">最新上架</text>
48 </view> 48 </view>
49 - <view class="flex flex-col items-center"> 49 + <view class="flex flex-col items-center" @tap="onGoodCarClick">
50 <view class="w-12 h-12 rounded-full bg-orange-100 flex items-center justify-center"> 50 <view class="w-12 h-12 rounded-full bg-orange-100 flex items-center justify-center">
51 <Star size="20" color="#f97316" /> 51 <Star size="20" color="#f97316" />
52 </view> 52 </view>
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
111 <view class="px-4 mt-6 mb-20"> 111 <view class="px-4 mt-6 mb-20">
112 <view class="flex justify-between items-center mb-2"> 112 <view class="flex justify-between items-center mb-2">
113 <text class="text-lg font-medium">最新上架</text> 113 <text class="text-lg font-medium">最新上架</text>
114 - <view class="text-sm text-gray-500 flex items-center"> 114 + <view class="text-sm text-gray-500 flex items-center" @tap="onNewCarClick">
115 <text>更多</text> 115 <text>更多</text>
116 <RectRight size="12" /> 116 <RectRight size="12" />
117 </view> 117 </view>
...@@ -295,6 +295,21 @@ const onCertifiedClick = () => { ...@@ -295,6 +295,21 @@ const onCertifiedClick = () => {
295 }) 295 })
296 } 296 }
297 297
298 +/**
299 + * 点击特价好车
300 + */
301 +const onGoodCarClick = () => {
302 + Taro.navigateTo({
303 + url: '/pages/goodCarList/index'
304 + })
305 +}
306 +
307 +const onNewCarClick = () => {
308 + Taro.navigateTo({
309 + url: '/pages/newCarList/index'
310 + })
311 +}
312 +
298 // 生命周期钩子 313 // 生命周期钩子
299 useDidShow(() => { 314 useDidShow(() => {
300 console.warn('index onShow') 315 console.warn('index onShow')
......
1 +/*
2 + * @Date: 2025-07-02 22:16:48
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-07-02 22:17:11
5 + * @FilePath: /jgdl/src/pages/newCarList/index.config.js
6 + * @Description: 文件描述
7 + */
8 +export default {
9 + navigationBarTitleText: '',
10 + usingComponents: {
11 + },
12 +}
1 +/* 最新上架页面样式 */
2 +.new-car-list {
3 + width: 100%;
4 + box-sizing: border-box;
5 +
6 + /* 滚动条样式 */
7 + &::-webkit-scrollbar {
8 + width: 6rpx;
9 + }
10 +
11 + &::-webkit-scrollbar-track {
12 + background: #f1f1f1;
13 + border-radius: 3rpx;
14 + }
15 +
16 + &::-webkit-scrollbar-thumb {
17 + background: #c1c1c1;
18 + border-radius: 3rpx;
19 +
20 + &:hover {
21 + background: #a8a8a8;
22 + }
23 + }
24 +}
25 +
26 +/* 车辆卡片样式 */
27 +.new-car-list .bg-white {
28 + background-color: #ffffff;
29 + border: 1px solid #f0f0f0;
30 + border-radius: 16rpx;
31 + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
32 + overflow: hidden;
33 + margin-bottom: 24rpx;
34 + transition: all 0.3s ease;
35 +}
36 +
37 +.new-car-list .bg-white:hover {
38 + transform: translateY(-2rpx);
39 + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.12);
40 + border-color: #e5e7eb;
41 +}
42 +
43 +.new-car-list .bg-white:active {
44 + transform: scale(0.98);
45 + transition: transform 0.1s ease;
46 +}
47 +
48 +/* 车辆图片容器 */
49 +.new-car-list .w-32 {
50 + width: 200rpx;
51 + height: 150rpx;
52 + flex-shrink: 0;
53 +}
54 +
55 +.new-car-list image {
56 + border-radius: 12rpx;
57 + object-fit: cover;
58 +}
59 +
60 +/* 新车标识样式优化 */
61 +.new-car-list .absolute.bottom-3.right-3 {
62 + background: linear-gradient(45deg, #ef4444, #dc2626);
63 + box-shadow: 0 2rpx 4rpx rgba(239, 68, 68, 0.3);
64 + border-radius: 8rpx;
65 + padding: 4rpx 8rpx;
66 + font-size: 20rpx;
67 + font-weight: 600;
68 +}
69 +
70 +/* 车辆信息区域 */
71 +.new-car-list .flex-1 {
72 + flex: 1;
73 + min-width: 0;
74 +}
75 +
76 +/* 收藏按钮样式 */
77 +.new-car-list .absolute {
78 + transition: transform 0.2s ease;
79 +}
80 +
81 +.new-car-list .absolute:active {
82 + transform: scale(0.9);
83 +}
84 +
85 +/* 价格样式 */
86 +.new-car-list .text-orange-500 {
87 + color: #f97316;
88 + font-weight: bold;
89 +}
90 +
91 +/* 上架时间样式 */
92 +.new-car-list .text-green-600 {
93 + color: #10b981;
94 + font-weight: 500;
95 +}
96 +
97 +/* 文字省略 */
98 +.new-car-list .font-medium {
99 + overflow: hidden;
100 + text-overflow: ellipsis;
101 + white-space: nowrap;
102 +}
103 +
104 +/* 加载状态样式 */
105 +.loading-container {
106 + padding: 32rpx 0 100rpx 0; /* 增加底部间距避免被TabBar遮挡 */
107 + text-align: center;
108 +
109 + .loading-text {
110 + color: #9ca3af;
111 + font-size: 28rpx;
112 + }
113 +}
114 +
115 +/* 无更多数据样式 */
116 +.no-more-container {
117 + padding: 32rpx 0 100rpx 0; /* 增加底部间距避免被TabBar遮挡 */
118 + text-align: center;
119 +
120 + text {
121 + color: #d1d5db;
122 + font-size: 24rpx;
123 + }
124 +}
125 +
126 +/* 动画效果 */
127 +.new-car-list .bg-white {
128 + animation: fadeInUp 0.3s ease-out;
129 +}
130 +
131 +@keyframes fadeInUp {
132 + from {
133 + opacity: 0;
134 + transform: translateY(20rpx);
135 + }
136 + to {
137 + opacity: 1;
138 + transform: translateY(0);
139 + }
140 +}
141 +
142 +/* 响应式适配 */
143 +@media screen and (max-width: 750rpx) {
144 + .new-car-list .w-32 {
145 + width: 180rpx;
146 + height: 135rpx;
147 + }
148 +
149 + .new-car-list .text-xl {
150 + font-size: 32rpx;
151 + }
152 +
153 + .new-car-list .text-sm {
154 + font-size: 24rpx;
155 + }
156 +
157 + .new-car-list .text-xs {
158 + font-size: 20rpx;
159 + }
160 +}
161 +
162 +/* 深色模式适配 */
163 +@media (prefers-color-scheme: dark) {
164 + .new-car-list .bg-white {
165 + background-color: #1f2937;
166 + border-color: #374151;
167 + }
168 +
169 + .new-car-list .text-gray-600 {
170 + color: #9ca3af;
171 + }
172 +
173 + .new-car-list .text-gray-500 {
174 + color: #6b7280;
175 + }
176 +
177 + .new-car-list .text-gray-400 {
178 + color: #9ca3af;
179 + }
180 +}
181 +
182 +/* NutUI组件样式覆盖 */
183 +:deep(.nut-sticky) {
184 + z-index: 999;
185 +}
186 +
187 +:deep(.nut-searchbar) {
188 + .nut-searchbar__content {
189 + border-radius: 50rpx;
190 + background: #fff;
191 +
192 + .nut-searchbar__input {
193 + font-size: 28rpx;
194 + color: #374151;
195 +
196 + &::placeholder {
197 + color: #9ca3af;
198 + }
199 + }
200 + }
201 +}
202 +
203 +:deep(.nut-menu) {
204 + background: #fff;
205 + border-bottom: 1rpx solid #e5e7eb;
206 +
207 + .nut-menu__item {
208 + font-size: 28rpx;
209 + color: #374151;
210 +
211 + &.active {
212 + color: #f97316;
213 + }
214 + }
215 +
216 + .nut-menu__title {
217 + font-size: 28rpx;
218 +
219 + &::after {
220 + border-color: #9ca3af;
221 + }
222 + }
223 +}
224 +
225 +:deep(.nut-toast) {
226 + .nut-toast__inner {
227 + background: rgba(0, 0, 0, 0.8);
228 + color: #fff;
229 + border-radius: 16rpx;
230 + font-size: 28rpx;
231 + }
232 +}
233 +
234 +/* 响应式适配 */
235 +@media (max-width: 750rpx) {
236 + .car-image-container {
237 + width: 200rpx;
238 + height: 150rpx;
239 + padding: 12rpx;
240 + }
241 +
242 + .car-info {
243 + padding: 20rpx;
244 +
245 + .car-name {
246 + font-size: 26rpx;
247 + }
248 +
249 + .car-details {
250 + font-size: 22rpx;
251 + }
252 +
253 + .car-price {
254 + font-size: 28rpx;
255 + }
256 +
257 + .car-school {
258 + font-size: 20rpx;
259 + }
260 +
261 + .listing-time {
262 + font-size: 20rpx;
263 + }
264 + }
265 +}
266 +
267 +/* 深色模式适配 */
268 +@media (prefers-color-scheme: dark) {
269 + .car-card {
270 + background: #1f2937;
271 + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
272 +
273 + &:hover {
274 + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.4);
275 + }
276 + }
277 +
278 + .car-info {
279 + .car-name {
280 + color: #f9fafb;
281 + }
282 +
283 + .car-details {
284 + color: #d1d5db;
285 + }
286 +
287 + .car-school {
288 + color: #9ca3af;
289 + }
290 + }
291 +
292 + .loading-container .loading-text {
293 + color: #6b7280;
294 + }
295 +
296 + .no-more-container text {
297 + color: #4b5563;
298 + }
299 +}
1 +<!--
2 + * @Date: 2022-09-19 14:11:06
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-07-02 22:59:12
5 + * @FilePath: /jgdl/src/pages/newCarList/index.vue
6 + * @Description: 最新上架页面
7 +-->
8 +<template>
9 + <view>
10 + <view class="flex flex-col bg-white min-h-screen">
11 + <!-- Header -->
12 + <nut-sticky>
13 + <view class="bg-orange-400 p-4 pt-4 pb-4">
14 + <nut-row type="flex" justify="center" align="center">
15 + <nut-col span="6">
16 + <view class="text-xl font-bold text-white">最新上架</view>
17 + </nut-col>
18 + <nut-col span="18">
19 + <!-- Search Bar -->
20 + <nut-searchbar v-model="searchValue" placeholder="搜索品牌型号" shape="round"
21 + background="transparent" input-background="#ffffff">
22 + <template #leftin>
23 + <Search2 />
24 + </template>
25 + </nut-searchbar>
26 + </nut-col>
27 + </nut-row>
28 + </view>
29 +
30 + <!-- Filter options -->
31 + <nut-menu>
32 + <nut-menu-item v-model="selectedBrand" :options="brandOptions" @change="onBrandChange" />
33 + <nut-menu-item v-model="selectedYear" :options="yearOptions" @change="onYearChange" />
34 + <nut-menu-item v-model="selectedSchool" :options="schoolOptions" @change="onSchoolChange" />
35 + </nut-menu>
36 + </nut-sticky>
37 +
38 + <!-- 最新上架车辆列表 -->
39 + <view class="flex-1 p-4">
40 + <!-- 滚动列表 -->
41 + <scroll-view
42 + class="new-car-list"
43 + :style="scrollStyle"
44 + :scroll-y="true"
45 + @scrolltolower="loadMore"
46 + @scroll="scroll"
47 + :lower-threshold="50"
48 + :enable-flex="false"
49 + >
50 + <view class="space-y-4">
51 + <view v-for="car in newCars" :key="car.id"
52 + class="bg-white rounded-lg shadow-sm overflow-hidden mb-3"
53 + @tap="() => onCarClick(car)"
54 + >
55 + <view class="flex">
56 + <view class="w-32 h-24 relative p-2">
57 + <image :src="car.imageUrl" :alt="car.name" mode="aspectFill"
58 + class="w-full h-full object-cover rounded-lg" />
59 + <view v-if="car.isNew"
60 + class="absolute bottom-3 right-3 bg-red-500 text-white text-xs px-1 rounded flex items-center">
61 + <text class="text-white">新</text>
62 + </view>
63 + </view>
64 + <view class="flex-1 p-3 relative">
65 + <view class="absolute top-3 right-4" @tap.stop="() => toggleFavorite(car.id)">
66 + <Addfollow v-if="!favoriteIds.includes(car.id)" size="16" color="#9ca3af" />
67 + <HeartFill v-else size="16" color="#ef4444" />
68 + </view>
69 + <text class="font-medium text-sm block">{{ car.name }}</text>
70 + <text class="text-xs text-gray-600 mt-1 block">
71 + {{ car.year }} ·
72 + <text v-if="car.batteryHealth">电池健康度{{ car.batteryHealth }}%</text>
73 + <text v-if="car.mileage"> 行驶{{ car.mileage }}公里</text>
74 + </text>
75 + <view class="mt-2">
76 + <text class="text-orange-500 font-bold">
77 + ¥{{ car.price.toLocaleString() }}
78 + </text>
79 + <text class="text-xs text-gray-500 mt-1 block">{{ car.school }}</text>
80 + </view>
81 + <!-- 上架时间 -->
82 + <view class="mt-1">
83 + <text class="text-xs text-green-600">{{ car.listingTime }}</text>
84 + </view>
85 + </view>
86 + </view>
87 + </view>
88 + </view>
89 +
90 + <!-- Loading indicator -->
91 + <view v-if="loading" class="loading-container py-4 text-center">
92 + <text class="loading-text text-gray-500">加载中...</text>
93 + </view>
94 +
95 + <!-- 没有更多数据 -->
96 + <view v-if="!hasMore && newCars.length > 0" class="no-more-container py-4 text-center">
97 + <text class="text-gray-400 text-sm">没有更多数据了</text>
98 + </view>
99 + </scroll-view>
100 + </view>
101 + </view>
102 +
103 + <!-- 自定义TabBar -->
104 + <TabBar />
105 +
106 + <!-- 成功提示 -->
107 + <nut-toast
108 + v-model:visible="toastVisible"
109 + :msg="toastMessage"
110 + :type="toastType"
111 + />
112 + </view>
113 +</template>
114 +
115 +<script setup>
116 +import { ref, computed, onMounted } from 'vue'
117 +import { Search2, Addfollow, HeartFill } from '@nutui/icons-vue-taro'
118 +import TabBar from '@/components/TabBar.vue'
119 +import './index.less'
120 +
121 +// 响应式数据
122 +const searchValue = ref('')
123 +const favoriteIds = ref(['2', '4', '6'])
124 +
125 +// Filter states - 使用NutUI Menu组件
126 +const selectedBrand = ref('全部品牌')
127 +const selectedYear = ref('出厂年份')
128 +const selectedSchool = ref('所在学校')
129 +
130 +// Menu选项数据
131 +const brandOptions = ref([
132 + { text: '全部品牌', value: '全部品牌' },
133 + { text: '雅迪', value: '雅迪' },
134 + { text: '台铃', value: '台铃' },
135 + { text: '小鸟', value: '小鸟' },
136 + { text: '新日', value: '新日' },
137 + { text: '爱玛', value: '爱玛' },
138 + { text: '小牛', value: '小牛' }
139 +])
140 +
141 +const yearOptions = ref([
142 + { text: '出厂年份', value: '出厂年份' },
143 + { text: '2024年', value: '2024年' },
144 + { text: '2023年', value: '2023年' },
145 + { text: '2022年', value: '2022年' },
146 + { text: '2021年', value: '2021年' },
147 + { text: '2020年', value: '2020年' }
148 +])
149 +
150 +const schoolOptions = ref([
151 + { text: '所在学校', value: '所在学校' },
152 + { text: '上海理工大学', value: '上海理工大学' },
153 + { text: '上海复旦大学', value: '上海复旦大学' },
154 + { text: '上海同济大学', value: '上海同济大学' },
155 + { text: '上海交通大学', value: '上海交通大学' }
156 +])
157 +
158 +// 最新上架车辆数据
159 +const newCars = ref([
160 + {
161 + id: 1,
162 + name: '小牛NGT 电动车',
163 + year: '2024年',
164 + batteryHealth: 100,
165 + mileage: 0,
166 + price: 5200,
167 + school: '上海理工大学',
168 + imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
169 + listingTime: '刚刚上架',
170 + isNew: true,
171 + brand: '小牛'
172 + },
173 + {
174 + id: 2,
175 + name: '雅迪 DE3 电动车',
176 + year: '2024年',
177 + batteryHealth: 98,
178 + mileage: 200,
179 + price: 4800,
180 + school: '上海大学',
181 + imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?w=400&h=300&fit=crop',
182 + listingTime: '5分钟前上架',
183 + isNew: true,
184 + brand: '雅迪'
185 + },
186 + {
187 + id: 3,
188 + name: '爱玛 A600 电动车',
189 + year: '2024年',
190 + batteryHealth: 95,
191 + mileage: 500,
192 + price: 3800,
193 + school: '华东理工大学',
194 + imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
195 + listingTime: '10分钟前上架',
196 + isNew: true,
197 + brand: '爱玛'
198 + },
199 + {
200 + id: 4,
201 + name: '台铃 TDR-2024 电动车',
202 + year: '2024年',
203 + batteryHealth: 92,
204 + mileage: 800,
205 + price: 4200,
206 + school: '上海交通大学',
207 + imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop',
208 + listingTime: '15分钟前上架',
209 + isNew: true,
210 + brand: '台铃'
211 + }
212 +])
213 +
214 +// 加载状态
215 +const loading = ref(false)
216 +const hasMore = ref(true)
217 +const currentPage = ref(1)
218 +const pageSize = ref(4)
219 +
220 +// Toast提示
221 +const toastVisible = ref(false)
222 +const toastMessage = ref('')
223 +const toastType = ref('success')
224 +
225 +// 滚动样式 - 考虑navbar、filter和TabBar的高度
226 +const scrollStyle = computed(() => {
227 + return {
228 + height: 'calc(100vh - 380rpx)' // 减去header、filter和TabBar的高度
229 + }
230 +})
231 +
232 +/**
233 + * 切换收藏状态
234 + * @param {string} carId - 车辆ID
235 + */
236 +const toggleFavorite = (carId) => {
237 + const index = favoriteIds.value.indexOf(carId.toString())
238 + if (index > -1) {
239 + favoriteIds.value.splice(index, 1)
240 + showToast('取消收藏', 'success')
241 + } else {
242 + favoriteIds.value.push(carId.toString())
243 + showToast('收藏成功', 'success')
244 + }
245 +}
246 +
247 +/**
248 + * 点击车辆卡片
249 + * @param {Object} car - 车辆信息
250 + */
251 +const onCarClick = (car) => {
252 + // TODO: 跳转到车辆详情页
253 + showToast(`查看${car.name}详情`, 'success')
254 +}
255 +
256 +// Menu组件事件处理方法
257 +/**
258 + * 品牌选择变化事件
259 + * @param {string} value - 选中的品牌值
260 + */
261 +const onBrandChange = (value) => {
262 + selectedBrand.value = value
263 + // 这里可以添加过滤逻辑
264 + filterCars()
265 +}
266 +
267 +/**
268 + * 年份选择变化事件
269 + * @param {string} value - 选中的年份值
270 + */
271 +const onYearChange = (value) => {
272 + selectedYear.value = value
273 + // 这里可以添加过滤逻辑
274 + filterCars()
275 +}
276 +
277 +/**
278 + * 学校选择变化事件
279 + * @param {string} value - 选中的学校值
280 + */
281 +const onSchoolChange = (value) => {
282 + selectedSchool.value = value
283 + // 这里可以添加过滤逻辑
284 + filterCars()
285 +}
286 +
287 +/**
288 + * 过滤车辆数据
289 + */
290 +const filterCars = () => {
291 + // TODO: 实现过滤逻辑
292 + showToast('筛选条件已更新', 'success')
293 +}
294 +
295 +/**
296 + * 生成模拟车辆数据
297 + * @param {number} page - 页码
298 + * @param {number} size - 每页数量
299 + * @returns {Array} 车辆数据数组
300 + */
301 +const generateMockData = (page, size) => {
302 + const brands = ['雅迪', '台铃', '小鸟', '新日', '爱玛', '小牛', '绿源', '立马']
303 + const schools = ['上海理工大学', '上海复旦大学', '上海同济大学', '上海交通大学', '华东师范大学', '上海大学']
304 + const years = ['2024年', '2023年', '2022年', '2021年', '2020年']
305 + const images = [
306 + 'https://images.unsplash.com/photo-1567922045116-2a00fae2ed03?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
307 + 'https://images.unsplash.com/photo-1573981368236-719bbb6f70f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
308 + 'https://images.unsplash.com/photo-1583568671741-c70dafa8e8e7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
309 + 'https://images.unsplash.com/photo-1595941069915-4ebc5197c14a?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
310 + 'https://images.unsplash.com/photo-1558981285-6f0c94958bb6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60',
311 + 'https://images.unsplash.com/photo-1558981403-c5f9899a28bc?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
312 + ]
313 + const listingTimes = ['刚刚上架', '5分钟前上架', '10分钟前上架', '15分钟前上架', '30分钟前上架', '1小时前上架']
314 +
315 + const data = []
316 + for (let i = 0; i < size; i++) {
317 + const index = (page - 1) * size + i
318 + const brand = brands[Math.floor(Math.random() * brands.length)]
319 + const school = schools[Math.floor(Math.random() * schools.length)]
320 + const year = years[Math.floor(Math.random() * years.length)]
321 + const image = images[Math.floor(Math.random() * images.length)]
322 + const listingTime = listingTimes[Math.floor(Math.random() * listingTimes.length)]
323 +
324 + data.push({
325 + id: `new_${index + 100}`,
326 + name: `${brand} ${['豪华版', '标准版', '运动版', '经典版'][Math.floor(Math.random() * 4)]}`,
327 + year: year,
328 + school: school,
329 + price: Math.floor(Math.random() * 3000) + 3000, // 新车价格相对较高
330 + imageUrl: image,
331 + batteryHealth: Math.floor(Math.random() * 10) + 90, // 新车电池健康度较高
332 + mileage: Math.floor(Math.random() * 1000), // 新车里程较少
333 + brand: brand,
334 + listingTime: listingTime,
335 + isNew: Math.random() > 0.3 // 70%概率显示新标签
336 + })
337 + }
338 + return data
339 +}
340 +
341 +/**
342 + * 加载更多数据
343 + */
344 +const loadMore = () => {
345 + if (loading.value || !hasMore.value) return
346 +
347 + loading.value = true
348 +
349 + // 模拟网络请求延迟
350 + setTimeout(() => {
351 + // 模拟最多加载5页数据
352 + if (currentPage.value >= 5) {
353 + hasMore.value = false
354 + loading.value = false
355 + return
356 + }
357 +
358 + currentPage.value++
359 + const newData = generateMockData(currentPage.value, pageSize.value)
360 + newCars.value.push(...newData)
361 + loading.value = false
362 + }, 1000 + Math.random() * 1000)
363 +}
364 +
365 +/**
366 + * 滚动事件处理
367 + */
368 +const scroll = (e) => {
369 + // 可以在这里处理滚动事件
370 +}
371 +
372 +/**
373 + * 显示提示信息
374 + */
375 +const showToast = (message, type = 'success') => {
376 + toastMessage.value = message
377 + toastType.value = type
378 + toastVisible.value = true
379 +}
380 +
381 +// 初始化
382 +onMounted(() => {
383 + // 可以在这里加载初始数据
384 +})
385 +</script>
386 +
387 +<script>
388 +export default {
389 + name: 'NewCarListPage'
390 +}
391 +</script>
1 +// Post页面样式
2 +.post-page {
3 + // 车辆卡片样式
4 + .vehicle-list {
5 + // 图片容器尺寸优化
6 + .w-32 {
7 + width: 200rpx !important;
8 + height: 150rpx !important;
9 + }
10 +
11 + // 卡片样式增强
12 + .bg-white {
13 + border: 1px solid #f0f0f0;
14 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
15 + transition: all 0.3s ease;
16 +
17 + &:hover {
18 + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
19 + transform: translateY(-2px);
20 + }
21 +
22 + &:active {
23 + transform: translateY(0);
24 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
25 + }
26 + }
27 +
28 + // 收藏按钮样式
29 + .absolute.top-2.right-2 {
30 + transition: transform 0.2s ease;
31 +
32 + &:hover {
33 + transform: scale(1.1);
34 + }
35 +
36 + &:active {
37 + transform: scale(0.95);
38 + }
39 + }
40 +
41 + // 价格样式优化
42 + .text-orange-500 {
43 + color: #f97316;
44 + font-weight: 700;
45 + }
46 +
47 + // 认证标识样式
48 + .bg-orange-500 {
49 + background: linear-gradient(135deg, #f97316, #ea580c);
50 + box-shadow: 0 2px 4px rgba(249, 115, 22, 0.3);
51 + }
52 +
53 + // 文字省略
54 + .font-medium {
55 + overflow: hidden;
56 + text-overflow: ellipsis;
57 + white-space: nowrap;
58 + }
59 + }
60 +
61 + // 精品推荐区域
62 + .grid {
63 + // 图片容器
64 + .w-full.h-36 {
65 + height: 280rpx;
66 + }
67 +
68 + // 卡片样式
69 + .bg-white {
70 + border: 1px solid #f0f0f0;
71 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
72 + transition: all 0.3s ease;
73 +
74 + &:hover {
75 + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
76 + transform: translateY(-2px);
77 + }
78 + }
79 + }
80 +
81 + // 加载状态样式
82 + .load-more-container {
83 + padding: 40rpx 0;
84 +
85 + .loading-container {
86 + display: flex;
87 + align-items: center;
88 + justify-content: center;
89 + color: #666;
90 +
91 + .loading-spinner {
92 + width: 40rpx;
93 + height: 40rpx;
94 + border: 4rpx solid #f3f3f3;
95 + border-top: 4rpx solid #f97316;
96 + border-radius: 50%;
97 + animation: spin 1s linear infinite;
98 + margin-right: 16rpx;
99 + }
100 +
101 + .loading-text {
102 + font-size: 28rpx;
103 + color: #666;
104 + }
105 + }
106 +
107 + .no-more-data {
108 + text-align: center;
109 + color: #999;
110 + font-size: 28rpx;
111 + }
112 + }
113 +}
114 +
115 +// NutUI组件样式覆盖
116 +.nut-menu {
117 + border-bottom: 1px solid #f0f0f0;
118 +
119 + .nut-menu-item {
120 + font-size: 28rpx;
121 +
122 + &.active {
123 + color: #f97316;
124 + }
125 + }
126 +}
127 +
128 +.nut-searchbar {
129 + .nut-searchbar__input {
130 + font-size: 28rpx;
131 + }
132 +}
133 +
134 +.nut-button {
135 + &[type="default"] {
136 + border-color: #f97316;
137 + color: #f97316;
138 +
139 + &:hover {
140 + background-color: #f97316;
141 + color: white;
142 + }
143 + }
144 +}
145 +
146 +// 响应式适配
147 +@media (max-width: 750rpx) {
148 + .post-page {
149 + .vehicle-list {
150 + .w-32 {
151 + width: 180rpx !important;
152 + height: 135rpx !important;
153 + }
154 + }
155 +
156 + .grid {
157 + .w-full.h-36 {
158 + height: 240rpx;
159 + }
160 + }
161 +
162 + .font-medium {
163 + font-size: 26rpx;
164 + }
165 +
166 + .text-xs {
167 + font-size: 22rpx;
168 + }
169 + }
170 +}
171 +
172 +// 深色模式适配
173 +@media (prefers-color-scheme: dark) {
174 + .post-page {
175 + .bg-white {
176 + background-color: #1f2937;
177 + border-color: #374151;
178 + color: #f9fafb;
179 + }
180 +
181 + .text-gray-600 {
182 + color: #9ca3af;
183 + }
184 +
185 + .text-gray-500 {
186 + color: #6b7280;
187 + }
188 + }
189 +}
190 +
191 +// 动画效果
192 +@keyframes spin {
193 + 0% {
194 + transform: rotate(0deg);
195 + }
196 + 100% {
197 + transform: rotate(360deg);
198 + }
199 +}
200 +
201 +@keyframes fadeInUp {
202 + from {
203 + opacity: 0;
204 + transform: translateY(30rpx);
205 + }
206 + to {
207 + opacity: 1;
208 + transform: translateY(0);
209 + }
210 +}
211 +
212 +// 卡片进入动画
213 +.post-page .vehicle-list > .space-y-4 > view {
214 + animation: fadeInUp 0.6s ease-out;
215 +}
216 +
217 +.post-page .grid > view {
218 + animation: fadeInUp 0.6s ease-out;
219 +}
220 +
221 +// 滚动条样式
222 +::-webkit-scrollbar {
223 + width: 8rpx;
224 +}
225 +
226 +::-webkit-scrollbar-track {
227 + background: #f1f1f1;
228 + border-radius: 4rpx;
229 +}
230 +
231 +::-webkit-scrollbar-thumb {
232 + background: #c1c1c1;
233 + border-radius: 4rpx;
234 +
235 + &:hover {
236 + background: #a8a8a8;
237 + }
238 +}
...\ No newline at end of file ...\ No newline at end of file
1 <template> 1 <template>
2 - <view> 2 + <view class="post-page">
3 <view class="flex flex-col bg-white min-h-screen"> 3 <view class="flex flex-col bg-white min-h-screen">
4 <!-- Header --> 4 <!-- Header -->
5 <nut-sticky> 5 <nut-sticky>
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
44 </view> 44 </view>
45 </view> 45 </view>
46 <view class="flex-1 p-3 relative"> 46 <view class="flex-1 p-3 relative">
47 - <view class="absolute top-2 right-2" @tap.stop="() => toggleFavorite(scooter.id)"> 47 + <view class="absolute top-3 right-4" @tap.stop="() => toggleFavorite(scooter.id)">
48 <Addfollow v-if="!favoriteIds.includes(scooter.id)" size="16" color="#9ca3af" /> 48 <Addfollow v-if="!favoriteIds.includes(scooter.id)" size="16" color="#9ca3af" />
49 <HeartFill v-else size="16" color="#ef4444" /> 49 <HeartFill v-else size="16" color="#ef4444" />
50 </view> 50 </view>
...@@ -132,7 +132,7 @@ ...@@ -132,7 +132,7 @@
132 <script setup> 132 <script setup>
133 import { ref } from 'vue' 133 import { ref } from 'vue'
134 import Taro from '@tarojs/taro' 134 import Taro from '@tarojs/taro'
135 -import { Search2, Right, RectRight, Check, Addfollow, HeartFill } from '@nutui/icons-vue-taro' 135 +import { Search2, RectRight, Check, Addfollow, HeartFill } from '@nutui/icons-vue-taro'
136 import TabBar from '@/components/TabBar.vue' 136 import TabBar from '@/components/TabBar.vue'
137 137
138 // 响应式数据 138 // 响应式数据
...@@ -393,6 +393,8 @@ const loadMoreData = async () => { ...@@ -393,6 +393,8 @@ const loadMoreData = async () => {
393 </script> 393 </script>
394 394
395 <style lang="less"> 395 <style lang="less">
396 +@import './index.less';
397 +
396 // 使用Tailwind CSS类,只保留必要的自定义样式 398 // 使用Tailwind CSS类,只保留必要的自定义样式
397 .space-y-4>view:not(:first-child) { 399 .space-y-4>view:not(:first-child) {
398 margin-top: 1rem; 400 margin-top: 1rem;
......