diff --git a/src/App.tsx b/src/App.tsx index 9bf127b..f333084 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -128,7 +128,7 @@ const App: React.FC = () => { } /> } /> } /> } /> diff --git a/src/api/index.ts b/src/api/index.ts index cc28330..fb86665 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,5 +1,4 @@ import {Api} from "../utils/axios/config"; -import axios, {AxiosRequestConfig} from "axios"; // 查询参数接口 export interface GvgTeamQueryParams { @@ -54,6 +53,37 @@ export interface Hero { headImgUrl: string; } +// 角色详情接口类型 +export interface HeroDetailResp { + heroRespSimpleVO: { + id: string; + heroCode: string; + heroName: string; + nickName: string | null; + headImgUrl: string; + stars: number; + role: string; + attribute: string; + }; + hero60AttributeVO: { + cp: number; + atk: number; + hp: number; + spd: number; + def: number; + chc: number; + chd: number; + dac: number; + eff: number; + efr: number; + }; +} + +// 查询角色详情 +export const getHeroDetail = async (heroCode: string): Promise> => { + return await Api.get>(`/epic/hero/hero-detail?heroCode=${heroCode}`) +}; + // 查询 GVG 阵容列表 export const getGvgTeamList = async (heroCodes?: string[]) => { const params = new URLSearchParams(); @@ -89,7 +119,7 @@ export const recognizeHeroesFromImage = async (file: File): Promise('/epic/hero/recognize', file); console.log(response) if (response && Array.isArray(response)) { - return { heroNames: response }; + return {heroNames: response}; } throw new Error("图片识别失败"); } catch (error) { diff --git a/src/pages/CharacterDetail.tsx b/src/pages/CharacterDetail.tsx index a6d2d19..71c002e 100644 --- a/src/pages/CharacterDetail.tsx +++ b/src/pages/CharacterDetail.tsx @@ -1,4 +1,7 @@ -import React, {useEffect} from 'react'; +import React, {useEffect, useState} from 'react'; +import {useParams} from 'react-router-dom'; +import * as EpicApi from '@/api/index'; +import {getHeroDetail} from "@/api/index"; export interface Skill { name: string; @@ -145,19 +148,82 @@ const artifactImgMap: Record = { '伊赛丽亚的誓约': 'https://epic7db.com/images/artifacts/elbris-ritual-sword.webp', }; -const CharacterDetail: React.FC = ({character}) => { - useEffect(() => { - window.scrollTo({top: 0, behavior: 'auto'}); - }, []); +// 角色职业中文映射 +const ROLE_LABELS: Record = { + knight: '骑士', + warrior: '战士', + assassin: '盗贼', + ranger: '射手', + mage: '魔导师', + manauser: '精灵师', + all: '全部', +}; +// 属性图标映射 +const ATTR_ICON_MAP: Record = { + attack: '/pic/item/attr/cm_icon_stat_attack.png', + defense: '/pic/item/attr/cm_icon_stat_defense.png', + health: '/pic/item/attr/cm_icon_stat_health.png', + speed: '/pic/item/attr/cm_icon_stat_speed.png', + critChance: '/pic/item/attr/cm_icon_stat_crit_chance.png', + critDamage: '/pic/item/attr/cm_icon_stat_crit_damage.png', + effectiveness: '/pic/item/attr/cm_icon_stat_effectiveness.png', + effectResistance: '/pic/item/attr/cm_icon_stat_effect_resistance.png', +}; + +// 属性中文映射 +const ATTR_LABEL_MAP: Record = { + attack: '攻击', + defense: '防御', + health: '生命', + speed: '速度', + critChance: '暴击率', + critDamage: '暴击伤害', + effectiveness: '效果命中', + effectResistance: '效果抗性', +}; + +const CharacterDetail: React.FC = () => { + const {heroCode} = useParams(); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [heroDetail, setHeroDetail] = useState(null); + + useEffect(() => { + if (!heroCode) return; + setLoading(true); + + EpicApi.getHeroDetail(heroCode) + .then(res => { + setHeroDetail(res); + setError(null); + }) + .catch(() => setError('获取角色详情失败')) + .finally(() => setLoading(false)); + }, [heroCode]); + + // 星级渲染(详情页专用星星) const renderStars = (count: number) => { - return Array(count) - .fill(0) - .map((_, index) => ( - - )); + return ( +
+ {Array(count).fill(0).map((_, i) => ( + star + ))} +
+ ); }; + // 属性图标 + const getElementIcon = (attribute: string) => { + if (!attribute) return null; + return {attribute}; + }; + + if (loading) return
加载中...
; + if (error || !heroDetail) return
{error || '无数据'}
; + + const {heroRespSimpleVO, hero60AttributeVO} = heroDetail; + const renderSkillType = (type: string) => { switch (type) { case 'None': @@ -180,18 +246,6 @@ const CharacterDetail: React.FC = ({character}) => { ); }; - // 属性图标占位 - const statIcons: Record = { - attack: '⚔️', - defense: '🛡️', - health: '❤️', - critChance: '🎯', - critDamage: '💥', - effectiveness: '🎲', - effectResistance: '🚫', - speed: '💨', - }; - return (
@@ -199,33 +253,50 @@ const CharacterDetail: React.FC = ({character}) => {
diff --git a/src/pages/Characters.tsx b/src/pages/Characters.tsx index 74e31ac..ddc6247 100644 --- a/src/pages/Characters.tsx +++ b/src/pages/Characters.tsx @@ -228,7 +228,7 @@ const Characters: React.FC = () => {
navigate(`/character/${hero.id}`)} + onClick={() => navigate(`/character/${hero.heroCode}`)} > {/* 头像+attr */}