index.vue 10.6 KB
<!--
 * @Date: 2022-09-19 14:11:06
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-07-16 17:02:41
 * @FilePath: /jgdl/src/pages/myAuthCar/index.vue
 * @Description: 我的认证车页面
-->
<template>
    <view class="flex flex-col bg-white min-h-screen">
        <!-- Auth Car List -->
        <view class="flex-1">
            <!-- 滚动列表 -->
            <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="item in authCars"
                        :key="item.id"
                        @tap="() => onItemClick(item)"
                        style="border-bottom: 1px solid #e5e7eb"
                    >
                        <view class="flex p-4">
                            <view class="w-24 h-24 relative">
                                <image
                                    :src="item.front_photo || DEFAULT_COVER_IMG"
                                    mode="aspectFill"
                                    class="w-full h-full object-cover rounded-lg"
                                />
                            </view>
                            <view class="flex-1 ml-4">
                                <text class="font-medium text-base block">{{ item.brand }} {{ item.model }}</text>
                                <!-- 认证状态 -->
                                <view class="status-badges">
                                    <view class="status-badge" :class="getVerificationStatusClass(item.verification_status)">
                                        <text>{{ getVerificationStatusText(item.verification_status) }}</text>
                                    </view>
                                </view>
                                <text class="text-sm text-gray-500 mt-1 block">{{ item.manufacture_year }}年|续航{{ item.range_km }}km|最高时速{{ item.max_speed_kmh }}km/h</text>
                                <!-- 认证失败原因 -->
                                <view v-if="item.verification_status === 7 && item.verification_reason" class="verification-reason mt-1">
                                    <text class="text-xs text-red-500">审核结果:{{ item.verification_reason }}</text>
                                </view>
                                <!-- <view class="mt-2 flex justify-between items-center">
                                    <view>
                                        <text class="text-orange-500 font-bold" style="font-size: 1.2rem;">
                                            ¥ {{ item.price?.toLocaleString() }}
                                        </text>
                                        <text v-if="item.market_price" class="text-gray-400 text-xs line-through ml-2">
                                            ¥ {{ item.market_price?.toLocaleString() }}
                                        </text>
                                    </view>
                                </view> -->
                                <view class="action-buttons mt-4">
                                    <nut-button
                                        v-if="item.review_status === 7"
                                        @click.stop="handleSellClick(item)"
                                        size="small"
                                        type="primary"
                                        color="orange"
                                        class="px-3 py-1 rounded-full text-sm"
                                    >
                                        我要卖车
                                    </nut-button>
                                    <nut-button
                                        v-if="item.verification_status === 1 || item.verification_status === 7"
                                        size="small"
                                        type="primary"
                                        @click="authCar(item.id)"
                                        color="orange"
                                    >
                                        认证
                                    </nut-button>
                                </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>

                <!-- Empty State -->
                <view
                    v-if="authCars.length === 0 && !loading"
                    class="flex flex-col items-center justify-center h-64"
                >
                    <text class="text-gray-500">暂无认证车辆</text>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import './index.less'
// 导入接口
import { getMyListingVehicleAPI } from '@/api/car'
import { DEFAULT_COVER_IMG } from '@/utils/config'

// ==================== API相关 ====================

// ==================== 响应式数据 ====================
/**
 * 我的认证车列表数据
 */
const authCars = ref([])

/**
 * 加载状态
 */
const loading = ref(false)
const hasMore = ref(true)
const currentPage = ref(0) // API页码从0开始
const pageSize = ref(10)



/**
 * 滚动样式 - 考虑header和TabBar的高度
 */
const scrollStyle = computed(() => {
    return {
        height: 'calc(100vh)' // 减去header和TabBar的高度
    }
})

// ==================== 数据处理方法 ====================

/**
 * 获取认证状态文本
 * @param {number} status - 认证状态 (1=不认证, 3=认证待审核, 5=已认证, 7=认证失败)
 */
const getVerificationStatusText = (status) => {
    const statusMap = {
        1: '未认证',
        3: '认证待审核',
        5: '已认证',
        7: '认证失败'
    }
    return statusMap[status] || '未知状态'
}

/**
 * 获取认证状态样式类
 * @param {number} status - 认证状态
 */
const getVerificationStatusClass = (status) => {
    const classMap = {
        1: 'unverified',
        3: 'review',
        5: 'verified',
        7: 'failed'
    }
    return classMap[status] || 'unverified'
}

/**
 * 初始化加载数据
 */
const initData = async () => {
    loading.value = true
    try {
        const response = await getMyListingVehicleAPI({
            verification_status: [3, 5, 7],
            page: 0,
            limit: pageSize.value
        })

        if (response.code === 1) {
            const { list, total } = response.data
            authCars.value = list || []
            hasMore.value = list && list.length === pageSize.value
            currentPage.value = 0
        } else {
            showToast(response.msg || '获取认证车列表失败', 'error')
        }
    } catch (error) {
        console.error('加载我的认证车列表失败:', error)
        showToast('加载失败,请重试', 'error')
    } finally {
        loading.value = false
    }
}

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

    loading.value = true
    try {
        const nextPage = currentPage.value + 1
        const response = await getMyListingVehicleAPI({
            verification_status: [3, 5, 7],
            page: nextPage,
            limit: pageSize.value
        })

        if (response.code === 1) {
            const { list, total } = response.data
            authCars.value.push(...(list || []))
            hasMore.value = list && list.length === pageSize.value
            currentPage.value = nextPage
        } else {
            showToast(response.msg || '加载失败,请重试', 'error')
        }
    } catch (error) {
        console.error('加载更多数据失败:', error)
        showToast('加载失败,请重试', 'error')
    } finally {
        loading.value = false
    }
}

// ==================== 事件处理方法 ====================
/**
 * 点击车辆项目
 * @param {Object} item - 车辆信息
 */
const onItemClick = (item) => {
    // 跳转到车辆详情页
    Taro.navigateTo({
        url: `/pages/productDetail/index?id=${item.id}`
    })
}

/**
 * 处理我要卖车点击事件
 * @param {Object} item - 车辆信息
 */
const handleSellClick = (item) => {
    // 翻车的状态为待审核
    item.review_status = 1;
    Taro.navigateTo({
        url: `/pages/sell/index?id=${item.id}&mode=edit&type=auth`
    })
}

/**
 * 滚动事件处理
 */
const scroll = (e) => {
    // 可以在这里处理滚动事件,比如记录滚动位置
}

/**
 * 显示提示信息
 */
const showToast = (message, type = 'success') => {
    Taro.showToast({
        title: message,
        icon: type === 'success' ? 'success' : 'none'
    })
}

/**
 * 认证车源
 */
const authCar = (carId) => {
    Taro.navigateTo({
        url: `/pages/setAuthCar/index?id=${carId}&mode=edit`
    })
}

// ==================== 生命周期 ====================
onMounted(() => {
    initData()
})
</script>

<script>
export default {
    name: "MyAuthCarPage",
};
</script>

<style lang="less" scoped>
// 自定义样式
.object-cover {
    object-fit: cover;
}

.line-through {
    text-decoration: line-through;
}

.auth-car-list {
    .loading-container {
        display: flex;
        justify-content: center;
        align-items: center;

        .loading-text {
            font-size: 28rpx;
            color: #999;
        }
    }

    .no-more-container {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 32rpx 0;

        text {
            font-size: 24rpx;
            color: #ccc;
        }
    }
}

// 认证标签样式
.absolute {
    position: absolute;
}

.top-1 {
    top: 4rpx;
}

.right-1 {
    right: 4rpx;
}

.bg-green-500 {
    background-color: #10b981;
}

.text-white {
    color: white;
}

.text-xs {
    font-size: 20rpx;
}

.px-1 {
    padding-left: 4rpx;
    padding-right: 4rpx;
}

.rounded {
    border-radius: 8rpx;
}

.flex {
    display: flex;
}

.items-center {
    align-items: center;
}
</style>