// The exported code uses Tailwind CSS. Install Tailwind CSS in your dev environment to ensure all styles work. import React, { useState, useEffect, useRef } from "react"; import { useNavigate } from 'react-router-dom'; import * as EpicApi from '@/api/index'; const ELEMENTS = [ { key: 'all', label: 'All', img: null }, { key: 'fire', label: 'Fire', img: '/pic/element/fire.png' }, { key: 'ice', label: 'Ice', img: '/pic/element/ice.png' }, { key: 'wind', label: 'Wind', img: '/pic/element/wind.png' }, { key: 'light', label: 'Light', img: '/pic/element/light.png' }, { key: 'dark', label: 'Dark', img: '/pic/element/dark.png' }, ]; const ROLES = [ { key: 'all', label: 'All', img: null }, { key: 'knight', label: 'Knight', img: '/pic/role/knight.png' }, { key: 'warrior', label: 'Warrior', img: '/pic/role/warrior.png' }, { key: 'assassin', label: 'Thief', img: '/pic/role/assassin.png' }, { key: 'ranger', label: 'Ranger', img: '/pic/role/ranger.png' }, { key: 'mage', label: 'Mage', img: '/pic/role/mage.png' }, { key: 'manauser', label: 'Soul Weaver', img: '/pic/role/manauser.png' }, ]; const STAR_OPTIONS = [ { label: "All Stars", value: 0 }, { label: "3 Stars", value: 3 }, { label: "4 Stars", value: 4 }, { label: "5 Stars", value: 5 }, ]; const ROLE_LABELS: Record = { knight: '骑士', warrior: '战士', assassin: '盗贼', ranger: '射手', mage: '魔导师', manauser: '精灵师', // 你可以自行修改为合适的中文 all: '全部', }; const Characters: React.FC = () => { const [selectedStars, setSelectedStars] = useState(0); const [selectedElement, setSelectedElement] = useState("all"); const [selectedRole, setSelectedRole] = useState("all"); const [searchTerm, setSearchTerm] = useState(""); const [heroes, setHeroes] = useState([]); const [dropdownOpen, setDropdownOpen] = useState(false); const [dropdownOptions, setDropdownOptions] = useState([]); const [dropdownLoading, setDropdownLoading] = useState(false); const dropdownRef = useRef(null); const navigate = useNavigate(); // 拉取英雄数据 useEffect(() => { EpicApi.getHeroList().then(setHeroes); }, []); // // 拉取 team-list 下拉数据(只请求一次) // useEffect(() => { // setDropdownLoading(true); // EpicApi.getGvgTeamList([]).then((data) => { // // 合并防守和进攻英雄,去重 // const allHeroes = [ // ...data.flatMap((item: any) => item.defenseHeroInfos || []), // ...data.flatMap((item: any) => item.attackHeroInfos || []), // ]; // const unique = Array.from(new Map(allHeroes.map(h => [h.heroCode, h])).values()); // setDropdownOptions(unique); // setDropdownLoading(false); // }); // }, []); // 过滤逻辑 const filteredHeroes = heroes.filter((hero) => { if (searchTerm && !hero.heroName.toLowerCase().includes(searchTerm.toLowerCase()) && !(hero.nickName && hero.nickName.toLowerCase().includes(searchTerm.toLowerCase())) ) return false; if (selectedStars && hero.stars !== selectedStars) return false; if (selectedElement !== 'all' && hero.attribute !== selectedElement) return false; if (selectedRole !== 'all' && hero.role !== selectedRole) return false; return true; }); // 星级渲染 const renderStars = (count: number) => (
{Array(count).fill(0).map((_, i) => ( star ))}
); // 属性图标 const getElementIcon = (attribute: string) => { if (!attribute) return null; return {attribute}; }; // 职业图标 const getRoleIcon = (role: string) => { if (!role) return null; return {role}; }; // 下拉选项过滤 const filteredDropdownOptions = dropdownOptions.filter((hero: any) => { if (!searchTerm) return true; return hero.heroName.toLowerCase().includes(searchTerm.toLowerCase()) || (hero.nickName && hero.nickName.toLowerCase().includes(searchTerm.toLowerCase())); }); // 点击下拉选项 const handleDropdownSelect = (hero: any) => { setSearchTerm(hero.heroName); setDropdownOpen(false); }; // 关闭下拉 useEffect(() => { const handleClick = (e: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) { setDropdownOpen(false); } }; document.addEventListener('mousedown', handleClick); return () => document.removeEventListener('mousedown', handleClick); }, []); return (
{/* 背景装饰 */}

All Epic Seven Heroes

{/* 搜索组件 */}
setDropdownOpen(!dropdownOpen)} > {searchTerm || '选择英雄名称/昵称'}
{dropdownOpen && (
setSearchTerm(e.target.value)} placeholder="输入英雄名称或昵称搜索..." className="w-full px-3 py-2 bg-[#1A1412] text-[#E6B17E] border-b border-[#C17F59]/30 rounded-t-md focus:outline-none focus:border-[#C17F59]" autoFocus /> {dropdownLoading ? (
加载中...
) : ( filteredDropdownOptions.length > 0 ? filteredDropdownOptions.map((hero: any) => (
handleDropdownSelect(hero)} > {hero.heroName} {hero.heroName} {hero.nickName && ({hero.nickName})}
)) :
无匹配结果
)}
)}
{STAR_OPTIONS.map((star) => ( ))}
{ELEMENTS.map((el) => ( ))}
{ROLES.map((role) => ( ))}
{filteredHeroes.map((hero) => (
navigate(`/character/${hero.id}`)} > {/* 头像+属性图标 */}
{hero.heroName}
{getElementIcon(hero.attribute)}
{/* 右侧信息 */}
{hero.heroName}
{renderStars(hero.stars)}
{hero.role && ( <> {hero.role} {ROLE_LABELS[hero.role] || hero.role} )}
))}
); }; export default Characters;