import React, { useState, useEffect } from "react"; import { Search, X } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; import { get } from "@/api/request"; // 群组接口类型 interface WechatGroup { id: string; chatroomId: string; name: string; avatar: string; ownerWechatId: string; ownerNickname: string; ownerAvatar: string; } interface GroupsResponse { code: number; msg: string; data: { list: Array<{ id: number; chatroomId: string; name: string; avatar?: string; ownerWechatId?: string; ownerNickname?: string; ownerAvatar?: string; }>; total: number; page: number; limit: number; }; } // 修改:支持keyword参数 const fetchGroupsList = async (params: { page: number; limit: number; keyword?: string; }): Promise => { const keywordParam = params.keyword ? `&keyword=${encodeURIComponent(params.keyword)}` : ""; return get( `/v1/chatroom?page=${params.page}&limit=${params.limit}${keywordParam}` ); }; interface GroupSelectionProps { selectedGroups: string[]; onSelect: (groups: string[]) => void; onSelectDetail?: (groups: WechatGroup[]) => void; // 新增 placeholder?: string; className?: string; } export default function GroupSelection({ selectedGroups, onSelect, onSelectDetail, placeholder = "选择群聊", className = "", }: GroupSelectionProps) { const [dialogOpen, setDialogOpen] = useState(false); const [groups, setGroups] = useState([]); const [searchQuery, setSearchQuery] = useState(""); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [totalGroups, setTotalGroups] = useState(0); const [loading, setLoading] = useState(false); // 打开弹窗并请求第一页群组 const openDialog = () => { setCurrentPage(1); setSearchQuery(""); // 重置搜索关键词 setDialogOpen(true); fetchGroups(1, ""); }; // 当页码变化时,拉取对应页数据(弹窗已打开时) useEffect(() => { if (dialogOpen && currentPage !== 1) { fetchGroups(currentPage, searchQuery); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [currentPage]); // 搜索防抖 useEffect(() => { if (!dialogOpen) return; const timer = setTimeout(() => { setCurrentPage(1); fetchGroups(1, searchQuery); }, 500); return () => clearTimeout(timer); }, [searchQuery, dialogOpen]); // 获取群组列表API - 支持keyword const fetchGroups = async (page: number, keyword: string = "") => { setLoading(true); try { const res = await fetchGroupsList({ page, limit: 20, keyword: keyword.trim() || undefined, }); if (res && res.code === 200 && res.data) { setGroups( res.data.list.map((group) => ({ id: group.id?.toString() || "", chatroomId: group.chatroomId || "", name: group.name || "", avatar: group.avatar || "", ownerWechatId: group.ownerWechatId || "", ownerNickname: group.ownerNickname || "", ownerAvatar: group.ownerAvatar || "", })) ); setTotalGroups(res.data.total || 0); setTotalPages(Math.ceil((res.data.total || 0) / 20)); } } catch (error) { console.error("获取群组列表失败:", error); } finally { setLoading(false); } }; // 处理群组选择 const handleGroupToggle = (groupId: string) => { let newIds: string[]; if (selectedGroups.includes(groupId)) { newIds = selectedGroups.filter((id) => id !== groupId); } else { newIds = [...selectedGroups, groupId]; } onSelect(newIds); if (onSelectDetail) { const selectedObjs = groups.filter((g) => newIds.includes(g.id)); onSelectDetail(selectedObjs); } }; // 获取显示文本 const getDisplayText = () => { if (selectedGroups.length === 0) return ""; return `已选择 ${selectedGroups.length} 个群聊`; }; const handleConfirm = () => { setDialogOpen(false); }; // 清空搜索 const handleClearSearch = () => { setSearchQuery(""); setCurrentPage(1); fetchGroups(1, ""); }; return ( <> {/* 输入框 */}
{/* 群组选择弹窗 */}
选择群聊
setSearchQuery(e.target.value)} className="pl-10 py-2 rounded-full border-gray-200" /> {searchQuery && ( )}
{loading ? (
加载中...
) : groups.length > 0 ? (
{groups.map((group) => ( ))}
) : (
{searchQuery ? `没有找到包含"${searchQuery}"的群聊` : "没有找到群聊"}
)}
总计 {totalGroups} 个群聊 {searchQuery && ` (搜索: "${searchQuery}")`}
{currentPage} / {totalPages}
); }