import { useEffect, useState, useRef } from "react"; import { type Employee } from "../../services/api"; // 多选用户下拉框组件 - 带 tag 显示 export function UserMultiSelect({ users, selectedUserIds, onChange, }: { users: Employee[]; selectedUserIds: string[]; onChange: (ids: string[]) => void; }) { const [isOpen, setIsOpen] = useState(false); const containerRef = useRef(null); // 点击外部关闭下拉框 useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setIsOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, []); const selectedUsers = users.filter((user) => selectedUserIds.includes(user.user_id)); const toggleUser = (userId: string) => { if (selectedUserIds.includes(userId)) { onChange(selectedUserIds.filter((id) => id !== userId)); } else { onChange([...selectedUserIds, userId]); } }; const removeUser = (userId: string, event: React.MouseEvent) => { event.stopPropagation(); onChange(selectedUserIds.filter((id) => id !== userId)); }; return (
{/* 选择框 - 显示 tag */}
setIsOpen(!isOpen)} style={{ display: "flex", alignItems: "center", flexWrap: "wrap", gap: "4px", padding: "6px 32px 6px 8px", minHeight: "36px", border: "1px solid #ddd", borderRadius: "4px", cursor: "pointer", backgroundColor: "#fff", }} > {selectedUsers.length === 0 ? ( 请选择用户 ) : ( selectedUsers.map((user) => ( {user.display_name} removeUser(user.user_id, e)} style={{ marginLeft: "4px", cursor: "pointer", fontWeight: "bold", fontSize: "14px", }} > × )) )} {isOpen ? "▲" : "▼"}
{/* 下拉列表 */} {isOpen && (
{users.map((user) => { const isSelected = selectedUserIds.includes(user.user_id); return (
toggleUser(user.user_id)} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 12px", cursor: "pointer", backgroundColor: isSelected ? "#e6f7ff" : "transparent", borderBottom: "1px solid #f0f0f0", }} > {user.display_name} ({user.username}) {isSelected && }
); })}
)}
); }