import React, { useState, useEffect, useCallback } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Search, RefreshCw, Loader2 } from "lucide-react"; import { fetchDeviceList } from "@/api/devices"; import { ServerDevice } from "@/types/device"; import { useToast } from "@/components/ui/toast"; interface Device { id: string; name: string; imei: string; wxid: string; status: "online" | "offline"; usedInPlans: number; nickname: string; } interface DeviceSelectionDialogProps { open: boolean; onOpenChange: (open: boolean) => void; selectedDevices: string[]; onSelect: (devices: string[]) => void; } export function DeviceSelectionDialog({ open, onOpenChange, selectedDevices, onSelect, }: DeviceSelectionDialogProps) { const { toast } = useToast(); const [searchQuery, setSearchQuery] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); const [loading, setLoading] = useState(false); const [devices, setDevices] = useState([]); // 获取设备列表,支持keyword const fetchDevices = useCallback( async (keyword: string = "") => { setLoading(true); try { const response = await fetchDeviceList( 1, 100, keyword.trim() || undefined ); if (response.code === 200 && response.data) { // 转换服务端数据格式为组件需要的格式 const convertedDevices: Device[] = response.data.list.map( (serverDevice: ServerDevice) => ({ id: serverDevice.id.toString(), name: serverDevice.memo || `设备 ${serverDevice.id}`, imei: serverDevice.imei, wxid: serverDevice.wechatId || "", status: serverDevice.alive === 1 ? "online" : "offline", usedInPlans: 0, // 这个字段需要从其他API获取 nickname: serverDevice.nickname || "", }) ); setDevices(convertedDevices); } else { toast({ title: "获取设备列表失败", description: response.msg, variant: "destructive", }); } } catch (error) { console.error("获取设备列表失败:", error); toast({ title: "获取设备列表失败", description: "请检查网络连接", variant: "destructive", }); } finally { setLoading(false); } }, [toast] ); // 打开弹窗时获取设备列表 useEffect(() => { if (open) { fetchDevices(""); } }, [open, fetchDevices]); // 搜索防抖 useEffect(() => { if (!open) return; const timer = setTimeout(() => { fetchDevices(searchQuery); }, 500); return () => clearTimeout(timer); }, [searchQuery, open, fetchDevices]); // 过滤设备(只保留状态过滤) const filteredDevices = devices.filter((device) => { const matchesStatus = statusFilter === "all" || (statusFilter === "online" && device.status === "online") || (statusFilter === "offline" && device.status === "offline"); return matchesStatus; }); const handleDeviceSelect = (deviceId: string) => { if (selectedDevices.includes(deviceId)) { onSelect(selectedDevices.filter((id) => id !== deviceId)); } else { onSelect([...selectedDevices, deviceId]); } }; return (
请选择一个或多个设备,支持搜索和筛选。
选择设备
setSearchQuery(e.target.value)} className="pl-9" />
{loading ? (
加载中...
) : filteredDevices.length === 0 ? (
暂无数据
) : ( filteredDevices.map((device) => ( )) )}
已选择 {selectedDevices.length} 个设备
); }