功能介绍:

使用antd的progress进度条组件,将接口获取到的数据实时一条一条的生成若干个进度条。

每个进度条的上面展示进度条的名称,进度条的后面展示是否需要重新验证的按钮。

接口返回的是一个数组,里面有若干个对象,对象有name名称,id(唯一),status状态。

status一开始一般为null,说明这一条后台还在查询中未出结果,

如果status为0说明这一条正常,那么展示时,progress为100%;status若为1,说明这一条异常,对应的progress为50%,进度条的后面要展示“重新验证”按钮。

点击“重新验证”按钮时,此进度条的名字不隐藏,但进度条和按钮要隐藏。点击按钮调用传递对应的唯一值进行上面接口的轮询,直到这一条name的status不为null,此时隐藏的进度条可以再次展示。

循环直到所有的结果status都不为null。在这个过程中,如果某一条的结果不为null,页面就开始展示,等待下一个status不为null的返回,有则在后面展示,展示的顺序是status不为null的返回顺序。

如果接口结果一下子全返回了status不为null的,可以按照接口获取到的顺序,但要保持页面的进度条间隔一秒一条的展示,直到接口所有的数据不为null在页面展示完。

核心代码:

// 存储所有进度条数据
const allProgressData = ref([])
// 存储已展示的进度条数据
const displayedProgressData = ref([])
// 轮询定时器
const pollInterval = ref(null)
// 展示定时器
const displayInterval = ref(null)
// 是否正在加载
const isLoading = ref(true)

// 发送验证
const sendVerify= async (id) => {
    const mockData = await sendVerify(id)
    if (!id) {
        startPolling()
    }
};

// 查询结果
const getProRes = async () => {
    const mockData = await queryRes()
    return mockData;
};
        
// 开始轮询获取进度数据
const startPolling = () => {
    // 清除现有定时器
    if (pollInterval.value) {
        clearInterval(pollInterval.value)
    }
    if (displayInterval.value) {
        clearInterval(displayInterval.value)
    }

    try {
        // 设置新的轮询定时器(每3秒轮询一次)
        pollInterval.value = setInterval(async () => {
            try {
                const data = await getProRes();
                allProgressData.value = data;
                  
                // 检查是否所有项目都有结果
                const allHaveResults = data.every(item => item.status !== null)
                if (allHaveResults) {
                    clearInterval(pollInterval.value)
                    pollInterval.value = null
                    isLoading.value = false
                }
            } catch (error) {
            console.error('获取进度数据失败:', error)
            }
        }, 3000)
          
        // 初始调用一次
        getProRes().then(data => {
            allProgressData.value = data
        })

        // 设置定时器,每隔1秒检查并添加一个新的进度条
        displayInterval.value = setInterval(() => {
        // 查找第一个还没有显示且有结果的项目
            const itemToAdd = allProgressData.value.find(item => 
                item.status !== null && 
                !displayedProgressData.value.some(displayed => displayed.id === item.id)
            )

            const reItem = displayedProgressData.value.filter(t => t.loading === true)
                
            if (itemToAdd) {
                displayedProgressData.value.push({ 
                    ...itemToAdd, 
                    loading: false, 
                    percent: itemToAdd.status === 0 ? 100 : 50,
                    retryVerify: itemToAdd.status === 1
                })
            }

            if (reItem.length) {
                const updateMap = new Map(allProgressData.value.map((item) => [item.id, item]))
                displayedProgressData.value = displayedProgressData.value.map((item) => {
                    const updateItem = updateMap.get(item.id)
                    if (updateItem) {
                        return {
                            ...item,
                            status: updateItem.status,
                            loading: updateItem.status === null ? true : false,
                            percent: updateItem.status === 0 ? 100 : 50,
                            retryVerify: itemToAdd.status === 1
                        }
                    }
                })
            }
            
            // 检查是否所有项目都已显示
            const allDisplayedI = allProgressData.value.every(item => item.status === null)
            const allDispalyedD = displayedProgressData.value.every(item => item.status === null)
            
            if (allDisplayedI && allDispalyedD && allProgressData.value.length === displayedProgressData.value.length && displayInterval.value) {
                clearInterval(displayInterval.value)
                displayInterval.value = null
            }
        }, 1000)

    } catch(err) {
        console.log('err', err)
        stopVerify()
    }
}
        
// 处理重新验证
const handleRevalidate = (id) => {  
    try {
        await sendVerify(id)
        // 更新数据
        const displayedIndex = allProgressData.value.findIndex(item => item.id === id)
        if (displayedIndex !== -1) {
            allProgressData.value[displayedIndex] = {
                ...allProgressData.value[displayedIndex],
                status: null,
                loading: true
            }
        }
        startPolling()
    } catch (error) {
        console.error('重新验证失败:', error)
        stopVerify()
    }
}

const stopVerify = () => {
     if (pollInterval.value) {
         clearInterval(pollInterval.value)
     }
     if (displayInterval.value) {
         clearInterval(displayInterval.value)
     }
}
        
// 初始化
onMounted(() => {
    sendVerify('')
});
        
// 清理定时器
onUnmounted(() => {
    stopVerify()
})
        
// 计算已完成的项目数量
const completedCount = computed(() => {
    return allProgressData.value.filter(item => item.status !== null).length
})
        
// 计算总项目数量
const totalCount = computed(() => {
    return allProgressData.value.length
})

更多推荐