diff --git a/public/pic/element/water.png b/public/pic/element/ice.png similarity index 100% rename from public/pic/element/water.png rename to public/pic/element/ice.png diff --git a/public/pic/element/earth.png b/public/pic/element/wind.png similarity index 100% rename from public/pic/element/earth.png rename to public/pic/element/wind.png diff --git a/public/pic/role/thief.png b/public/pic/role/assassin.png similarity index 100% rename from public/pic/role/thief.png rename to public/pic/role/assassin.png diff --git a/public/pic/role/soulweaver.png b/public/pic/role/manauser.png similarity index 100% rename from public/pic/role/soulweaver.png rename to public/pic/role/manauser.png diff --git a/src/pages/Characters.tsx b/src/pages/Characters.tsx index b7f1dba..7e8c896 100644 --- a/src/pages/Characters.tsx +++ b/src/pages/Characters.tsx @@ -2,616 +2,130 @@ 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("All Stars"); - const [selectedElement, setSelectedElement] = useState("All"); - const [selectedClass, setSelectedClass] = useState("All"); - const [selectedZodiac, setSelectedZodiac] = useState("All"); + const [selectedStars, setSelectedStars] = useState(0); + const [selectedElement, setSelectedElement] = useState("all"); + const [selectedRole, setSelectedRole] = useState("all"); const [searchTerm, setSearchTerm] = useState(""); - const [selectedBuffs, setSelectedBuffs] = useState([]); - const [selectedDebuffs, setSelectedDebuffs] = useState([]); - const [isBuffsOpen, setIsBuffsOpen] = useState(false); - const [isDebuffsOpen, setIsDebuffsOpen] = useState(false); - - // 添加ref用于下拉框 - const buffsDropdownRef = useRef(null); - const debuffsDropdownRef = useRef(null); - - // 添加全局点击事件监听器 - useEffect(() => { - const handleClickOutside = (event: MouseEvent) => { - // 检查点击是否在增益下拉框外部 - if (buffsDropdownRef.current && !buffsDropdownRef.current.contains(event.target as Node)) { - setIsBuffsOpen(false); - } - - // 检查点击是否在减益下拉框外部 - if (debuffsDropdownRef.current && !debuffsDropdownRef.current.contains(event.target as Node)) { - setIsDebuffsOpen(false); - } - }; - - // 添加事件监听器 - document.addEventListener('mousedown', handleClickOutside); - - // 清理函数 - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, []); + 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(); - const heroes = [ - { - id: 1, - name: "Abigail", - stars: 5, - element: "fire", - class: "Fire Warrior", - imageUrl: - "https://epic7db.com/images/heroes/abigail.webp", - }, - { - id: 2, - name: "Abyssal Yufine", - stars: 5, - element: "dark", - class: "Dark Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20knight%20with%20white%20hair%20and%20purple%20eyes%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=2&orientation=squarish", - }, - { - id: 3, - name: "Achates", - stars: 4, - element: "fire", - class: "Fire Soul Weaver", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20healer%20with%20blonde%20hair%20and%20red%20eyes%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=3&orientation=squarish", - }, - { - id: 4, - name: "Adin", - stars: 3, - element: "earth", - class: "Earth Thief", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20thief%20with%20purple%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=4&orientation=squarish", - }, - { - id: 5, - name: "Adlay", - stars: 3, - element: "earth", - class: "Earth Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20mage%20with%20brown%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=5&orientation=squarish", - }, - { - id: 6, - name: "Adventurer Ras", - stars: 3, - element: "fire", - class: "Fire Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20knight%20with%20white%20and%20blue%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=6&orientation=squarish", - }, - { - id: 7, - name: "ae-GISELLE", - stars: 5, - element: "earth", - class: "Earth Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20mage%20with%20light%20blonde%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=7&orientation=squarish", - }, - { - id: 8, - name: "ae-KARINA", - stars: 5, - element: "water", - class: "Ice Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20knight%20with%20purple%20hair%20and%20blue%20eyes%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=8&orientation=squarish", - }, - { - id: 9, - name: "ae-NINGNING", - stars: 5, - element: "fire", - class: "Fire Soul Weaver", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20soul%20weaver%20with%20light%20pink%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=9&orientation=squarish", - }, - { - id: 10, - name: "ae-WINTER", - stars: 5, - element: "fire", - class: "Fire Thief", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20thief%20with%20pink%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=10&orientation=squarish", - }, - { - id: 11, - name: "Afternoon Soak Flan", - stars: 5, - element: "fire", - class: "Fire Ranger", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20ranger%20with%20black%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=11&orientation=squarish", - }, - { - id: 12, - name: "Ainos", - stars: 3, - element: "dark", - class: "Dark Soul Weaver", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20soul%20weaver%20with%20dark%20purple%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=12&orientation=squarish", - }, - // 新增30个英雄数据 - { - id: 13, - name: "Alencia", - stars: 5, - element: "earth", - class: "Earth Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20knight%20with%20green%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=13&orientation=squarish", - }, - { - id: 14, - name: "Ambitious Tywin", - stars: 5, - element: "light", - class: "Light Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20knight%20with%20blonde%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=14&orientation=squarish", - }, - { - id: 15, - name: "Angelica", - stars: 4, - element: "water", - class: "Water Soul Weaver", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20healer%20with%20blue%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=15&orientation=squarish", - }, - { - id: 16, - name: "Angel of Light Angelica", - stars: 5, - element: "light", - class: "Light Soul Weaver", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20healer%20with%20white%20hair%20and%20wings%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=16&orientation=squarish", - }, - { - id: 17, - name: "Arbiter Vildred", - stars: 5, - element: "dark", - class: "Dark Thief", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20thief%20with%20black%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=17&orientation=squarish", - }, - { - id: 18, - name: "Architect Laika", - stars: 5, - element: "fire", - class: "Fire Warrior", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20warrior%20with%20red%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=18&orientation=squarish", - }, - { - id: 19, - name: "Armin", - stars: 4, - element: "earth", - class: "Earth Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20knight%20with%20brown%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=19&orientation=squarish", - }, - { - id: 20, - name: "Assassin Cartuja", - stars: 4, - element: "dark", - class: "Dark Thief", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20thief%20with%20dark%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=20&orientation=squarish", - }, - { - id: 21, - name: "Assassin Coli", - stars: 4, - element: "dark", - class: "Dark Thief", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20thief%20with%20dark%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=21&orientation=squarish", - }, - { - id: 22, - name: "Auxiliary Lots", - stars: 5, - element: "light", - class: "Light Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20mage%20with%20white%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=22&orientation=squarish", - }, - { - id: 23, - name: "Baal & Sezan", - stars: 5, - element: "fire", - class: "Fire Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20mage%20with%20red%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=23&orientation=squarish", - }, - { - id: 24, - name: "Basar", - stars: 5, - element: "earth", - class: "Earth Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20mage%20with%20green%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=24&orientation=squarish", - }, - { - id: 25, - name: "Batisse", - stars: 3, - element: "fire", - class: "Fire Warrior", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20warrior%20with%20red%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=25&orientation=squarish", - }, - { - id: 26, - name: "Bellona", - stars: 5, - element: "earth", - class: "Earth Warrior", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20warrior%20with%20green%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=26&orientation=squarish", - }, - { - id: 27, - name: "Benevolent Romann", - stars: 5, - element: "light", - class: "Light Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20mage%20with%20white%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=27&orientation=squarish", - }, - { - id: 28, - name: "Blaze Dingo", - stars: 4, - element: "fire", - class: "Fire Soul Weaver", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20healer%20with%20red%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=28&orientation=squarish", - }, - { - id: 29, - name: "Blood Blade Karin", - stars: 5, - element: "dark", - class: "Dark Thief", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20thief%20with%20dark%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=29&orientation=squarish", - }, - { - id: 30, - name: "Blue Krau", - stars: 5, - element: "water", - class: "Water Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20knight%20with%20blue%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=30&orientation=squarish", - }, - { - id: 31, - name: "Briar Witch Iseria", - stars: 5, - element: "dark", - class: "Dark Ranger", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20ranger%20with%20dark%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=31&orientation=squarish", - }, - { - id: 32, - name: "Butcher Corps Inquisitor", - stars: 4, - element: "dark", - class: "Dark Warrior", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20warrior%20with%20dark%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=32&orientation=squarish", - }, - { - id: 33, - name: "Cecilia", - stars: 5, - element: "earth", - class: "Earth Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20knight%20with%20green%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=33&orientation=squarish", - }, - { - id: 34, - name: "Celestial Mercedes", - stars: 5, - element: "light", - class: "Light Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20mage%20with%20white%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=34&orientation=squarish", - }, - { - id: 35, - name: "Cerise", - stars: 5, - element: "fire", - class: "Fire Ranger", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20ranger%20with%20red%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=35&orientation=squarish", - }, - { - id: 36, - name: "Challenger Dominiel", - stars: 5, - element: "light", - class: "Light Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20mage%20with%20white%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=36&orientation=squarish", - }, - { - id: 37, - name: "Champion Zerato", - stars: 5, - element: "dark", - class: "Dark Mage", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20mage%20with%20dark%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=37&orientation=squarish", - }, - { - id: 38, - name: "Charles", - stars: 5, - element: "earth", - class: "Earth Warrior", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20warrior%20with%20green%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=38&orientation=squarish", - }, - { - id: 39, - name: "Charlotte", - stars: 5, - element: "fire", - class: "Fire Warrior", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20warrior%20with%20red%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=39&orientation=squarish", - }, - { - id: 40, - name: "Chloe", - stars: 5, - element: "fire", - class: "Fire Knight", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20knight%20with%20red%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=40&orientation=squarish", - }, - { - id: 41, - name: "Cidd", - stars: 4, - element: "earth", - class: "Earth Thief", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20male%20thief%20with%20green%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=41&orientation=squarish", - }, - { - id: 42, - name: "Clarissa", - stars: 4, - element: "water", - class: "Water Warrior", - imageUrl: - "https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20warrior%20with%20blue%20hair%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=42&orientation=squarish", - }, - ]; + // 拉取英雄数据 + useEffect(() => { + EpicApi.getHeroList().then(setHeroes); + }, []); - // 测试数据 - const buffsData = [ - { id: "attack_up", name: "攻击力提升" }, - { id: "defense_up", name: "防御力提升" }, - { id: "speed_up", name: "速度提升" }, - { id: "critical_rate_up", name: "暴击率提升" }, - { id: "critical_damage_up", name: "暴击伤害提升" }, - { id: "effectiveness_up", name: "效果命中提升" }, - { id: "effect_resistance_up", name: "效果抗性提升" }, - { id: "barrier", name: "护盾" }, - { id: "invincible", name: "无敌" }, - { id: "immunity", name: "免疫" }, - { id: "continuous_heal", name: "持续回复" }, - { id: "counter_attack", name: "反击" }, - ]; - - const debuffsData = [ - { id: "attack_down", name: "攻击力降低" }, - { id: "defense_down", name: "防御力降低" }, - { id: "speed_down", name: "速度降低" }, - { id: "critical_rate_down", name: "暴击率降低" }, - { id: "critical_damage_down", name: "暴击伤害降低" }, - { id: "effectiveness_down", name: "效果命中降低" }, - { id: "effect_resistance_down", name: "效果抗性降低" }, - { id: "bleed", name: "出血" }, - { id: "burn", name: "燃烧" }, - { id: "poison", name: "中毒" }, - { id: "stun", name: "眩晕" }, - { id: "silence", name: "沉默" }, - { id: "sleep", name: "睡眠" }, - { id: "provoke", name: "挑衅" }, - { id: "unhealable", name: "无法回复" }, - { id: "unbuffable", name: "无法获得增益" }, - ]; - - // 处理增益选择 - const handleBuffToggle = (buffId: string) => { - setSelectedBuffs(prev => - prev.includes(buffId) - ? prev.filter(id => id !== buffId) - : [...prev, buffId] - ); - window.scrollTo({ top: 0, behavior: 'smooth' }); - }; - - // 处理减益选择 - const handleDebuffToggle = (debuffId: string) => { - setSelectedDebuffs(prev => - prev.includes(debuffId) - ? prev.filter(id => id !== debuffId) - : [...prev, debuffId] - ); - window.scrollTo({ top: 0, behavior: 'smooth' }); - }; - - // 获取选中的增益名称 - const getSelectedBuffsNames = () => { - return selectedBuffs - .map(id => buffsData.find(buff => buff.id === id)?.name) - .filter(Boolean) - .join(", "); - }; - - // 获取选中的减益名称 - const getSelectedDebuffsNames = () => { - return selectedDebuffs - .map(id => debuffsData.find(debuff => debuff.id === id)?.name) - .filter(Boolean) - .join(", "); - }; - - const renderStars = (count: number) => { - return Array(count) - .fill(0) - .map((_, index) => ( - - ★ - - )); - }; - - const getElementIcon = (element: string) => { - switch (element) { - case "fire": - return ( -
- -
- ); - case "water": - return ( -
- -
- ); - case "earth": - return ( -
- -
- ); - case "light": - return ( -
- -
- ); - case "dark": - return ( -
- -
- ); - default: - return null; - } - }; - - const getClassIcon = (className: string) => { - if (className.includes("Knight")) { - return ; - } else if (className.includes("Warrior")) { - return ; - } else if (className.includes("Thief")) { - return ; - } else if (className.includes("Ranger")) { - return ; - } else if (className.includes("Mage")) { - return ; - } else if (className.includes("Soul Weaver")) { - return ; - } - return null; - }; - - const getZodiacIcon = (index: number) => { - const zodiacs = [ - , - , - , - , - , - , - , - , - , - , - , - , - ]; - return zodiacs[index % zodiacs.length]; - }; + // // 拉取 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) => { - // Filter by search term - if ( - searchTerm && - !hero.name.toLowerCase().includes(searchTerm.toLowerCase()) - ) { - return false; - } - - // Filter by stars - if (selectedStars !== "All Stars") { - const starCount = parseInt(selectedStars.split(" ")[0]); - if (hero.stars !== starCount) { - return false; - } - } - - // Filter by element - if ( - selectedElement !== "All" && - hero.element !== selectedElement.toLowerCase() - ) { - return false; - } - - // 这里可以添加对增益和减益的筛选逻辑 - // 目前仅作为示例,实际应用中需要根据英雄数据添加相应的筛选逻辑 - + 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 handleCharacterClick = (heroId: number) => { - navigate(`/character/${heroId}`); + // 星级渲染 + 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 (
@@ -625,353 +139,125 @@ const Characters: React.FC = () => { - {/* 固定在顶部的搜索组件 */} -
+ {/* 搜索组件 */} +
- { - setSearchTerm(e.target.value); - window.scrollTo({ top: 0, behavior: 'smooth' }); - }} - /> -
- -
-
- {["All Stars", "3 Stars", "4 Stars", "5 Stars"].map((stars) => ( - - ))} -
-
- -
-
- - - - - - - - - - - -
-
- -
-
- - - {[ - "Knight", - "Warrior", - "Thief", - "Ranger", - "Mage", - "Soul Weaver", - ].map((classType) => ( - - ))} -
-
- -
-
- - - {[...Array(12)].map((_, index) => ( - - ))} -
-
- -
- {/* 增益多选下拉框 */} -
-
setIsBuffsOpen(!isBuffsOpen)} - > -
-

选择增益效果

- {selectedBuffs.length > 0 && ( -
- {selectedBuffs.map(buffId => { - const buff = buffsData.find(b => b.id === buffId); - return buff ? ( - - {buff.name} - - - ) : null; - })} -
- )} -
- + {searchTerm || '选择英雄名称/昵称'} +
- - {isBuffsOpen && ( -
- {buffsData.map(buff => ( -
handleBuffToggle(buff.id)} - > -
- {selectedBuffs.includes(buff.id) && } + {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})}
- {buff.name} -
- ))} + )) :
无匹配结果
+ )}
)}
- - {/* 减益多选下拉框 */} -
-
setIsDebuffsOpen(!isDebuffsOpen)} - > -
-

选择减益效果

- {selectedDebuffs.length > 0 && ( -
- {selectedDebuffs.map(debuffId => { - const debuff = debuffsData.find(d => d.id === debuffId); - return debuff ? ( - - {debuff.name} - - - ) : null; - })} -
- )} -
- -
- - {isDebuffsOpen && ( -
- {debuffsData.map(debuff => ( -
handleDebuffToggle(debuff.id)} - > -
- {selectedDebuffs.includes(debuff.id) && } -
- {debuff.name} -
- ))} -
- )} +
+ +
+
+ {STAR_OPTIONS.map((star) => ( + + ))} +
+
+ +
+
+ {ELEMENTS.map((el) => ( + + ))} +
+
+ +
+
+ {ROLES.map((role) => ( + + ))}
-
+
{filteredHeroes.map((hero) => (
handleCharacterClick(hero.id)} + className="flex items-center bg-[#23201B] rounded-xl border border-[#C17F59]/30 hover:border-[#C17F59] transition-all duration-300 shadow-md px-4 py-3 min-h-[96px] max-h-[96px] cursor-pointer backdrop-blur-sm" + onClick={() => navigate(`/character/${hero.id}`)} > -
+ {/* 头像+属性图标 */} +
{hero.name} -
- {renderStars(hero.stars)} -
-
- {getElementIcon(hero.element)} +
+ {getElementIcon(hero.attribute)}
-
-

{hero.name}

-
- {getClassIcon(hero.class)} - {hero.class} + {/* 右侧信息 */} +
+
+ {hero.heroName} +
+
+ {renderStars(hero.stars)} +
+
+ {hero.role && ( + <> + + {hero.role} + + {ROLE_LABELS[hero.role] || hero.role} + + )}