feat: 本次提交更新内容如下

场景获客列表搞定
This commit is contained in:
笔记本里的永平
2025-07-07 17:08:27 +08:00
parent 6543da9167
commit 5ff15472f5
352 changed files with 24040 additions and 18575 deletions

View File

@@ -1,47 +1,80 @@
"use client"
import { useState, useEffect } from "react"
import { useState, useEffect, useMemo } from "react"
import type { Device } from "@/components/device-grid"
import { deviceApi } from "@/lib/api/devices"
import type { DeviceStatus } from "@/types/device"
interface DeviceStatus {
status: "online" | "offline"
battery: number
}
async function fetchDeviceStatuses(deviceIds: string[]): Promise<Record<string, DeviceStatus>> {
// 模拟API调用
await new Promise((resolve) => setTimeout(resolve, 1000))
return deviceIds.reduce(
(acc, id) => {
acc[id] = {
status: Math.random() > 0.3 ? "online" : "offline",
battery: Math.floor(Math.random() * 100),
}
return acc
},
{} as Record<string, DeviceStatus>,
)
}
export function useDeviceStatusPolling(devices: Device[]) {
export function useDeviceStatusPolling(devices: Device[], interval = 30000) {
const [statuses, setStatuses] = useState<Record<string, DeviceStatus>>({})
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
// 使用 useMemo 序列化 device IDs确保依赖项的稳定性
const deviceIds = useMemo(
() =>
devices
.map((d) => d.id)
.sort()
.join(","),
[devices],
)
useEffect(() => {
if (!deviceIds) {
setStatuses({})
return
}
let isActive = true // 标记,防止在组件卸载后仍更新状态
const idArray = deviceIds.split(",")
const pollStatus = async () => {
setIsLoading(true)
setError(null)
try {
const newStatuses = await fetchDeviceStatuses(devices.map((d) => d.id))
setStatuses((prevStatuses) => ({ ...prevStatuses, ...newStatuses }))
} catch (error) {
console.error("Failed to fetch device statuses:", error)
const response = await deviceApi.checkStatus(idArray)
if (isActive && response.data) {
setStatuses((prev) => ({ ...prev, ...response.data }))
} else if (response.message) {
throw new Error(response.message)
}
} catch (e) {
if (isActive) {
setError(e instanceof Error ? e.message : "获取设备状态失败")
}
} finally {
if (isActive) {
setIsLoading(false)
}
}
}
pollStatus() // 立即执行一次
const intervalId = setInterval(pollStatus, 30000) // 每30秒更新一次
// 立即执行一次
pollStatus()
return () => clearInterval(intervalId)
}, [devices])
// 设置定时轮询
const intervalId = setInterval(pollStatus, interval)
return statuses
// 监听页面可见性,实现智能轮询
const handleVisibilityChange = () => {
if (document.hidden) {
clearInterval(intervalId) // 页面隐藏时暂停
} else {
pollStatus() // 页面可见时立即更新并重新开始轮询
setInterval(pollStatus, interval)
}
}
document.addEventListener("visibilitychange", handleVisibilityChange)
// 清理函数
return () => {
isActive = false
clearInterval(intervalId)
document.removeEventListener("visibilitychange", handleVisibilityChange)
}
}, [deviceIds, interval]) // 依赖项现在是稳定的字符串
return { statuses, isLoading, error }
}