2025-11-28 06:31:36 +00:00
|
|
|
|
import { Tag } from '@/components/ui/tag'
|
|
|
|
|
|
import { cn, formatNumberToKMB } from '@/lib/utils'
|
|
|
|
|
|
import { AIPermission, AiUserBaseListOutput } from '@/services/create'
|
|
|
|
|
|
import Image from 'next/image'
|
|
|
|
|
|
import Link from 'next/link'
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
2025-11-28 06:31:36 +00:00
|
|
|
|
const CharacterCard = ({
|
|
|
|
|
|
character,
|
|
|
|
|
|
isHovered,
|
|
|
|
|
|
onHover,
|
|
|
|
|
|
}: {
|
|
|
|
|
|
character: AiUserBaseListOutput
|
|
|
|
|
|
isHovered: boolean
|
|
|
|
|
|
onHover: (hovered: boolean) => void
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}) => {
|
|
|
|
|
|
// 根据权限判断是否私密
|
2025-11-28 06:31:36 +00:00
|
|
|
|
const isPrivate = character.permission === AIPermission.Private
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Link href={`/@${character.aiId}`}>
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<div
|
|
|
|
|
|
className="group flex w-full min-w-[200px] grow basis-0 flex-col gap-3"
|
2025-11-13 08:38:25 +00:00
|
|
|
|
onMouseEnter={() => onHover(true)}
|
|
|
|
|
|
onMouseLeave={() => onHover(false)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{/* 角色图片 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<div
|
|
|
|
|
|
className="relative overflow-hidden rounded-lg bg-cover bg-center bg-no-repeat pb-[133%]"
|
|
|
|
|
|
style={
|
|
|
|
|
|
{
|
|
|
|
|
|
// backgroundImage: character.homeImageUrl ? `url('${character.homeImageUrl}')` : 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-13 08:38:25 +00:00
|
|
|
|
>
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<Image
|
2025-11-13 08:38:25 +00:00
|
|
|
|
src={character.homeImageUrl ?? ''}
|
|
|
|
|
|
alt={character.nickname ?? ''}
|
|
|
|
|
|
fill
|
|
|
|
|
|
className="object-cover object-top"
|
|
|
|
|
|
sizes="100%"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 私密标识 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<div className="bg-surface-element-dark-normal absolute top-2 right-2 z-[1] flex h-6 w-6 items-center justify-center rounded-xs backdrop-blur-xs">
|
|
|
|
|
|
<i
|
|
|
|
|
|
className={cn('iconfont !text-[12px]', {
|
|
|
|
|
|
'icon-eye-off': isPrivate,
|
|
|
|
|
|
'icon-eye-on': !isPrivate,
|
|
|
|
|
|
})}
|
|
|
|
|
|
/>
|
2025-11-13 08:38:25 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 底部遮罩层 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<div
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
'absolute right-0 bottom-0 left-0 flex flex-col justify-end bg-gradient-to-b from-transparent to-black px-3 pb-3',
|
|
|
|
|
|
{
|
|
|
|
|
|
'pt-6': !isHovered,
|
|
|
|
|
|
'h-full pt-12': isHovered,
|
|
|
|
|
|
}
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
2025-11-13 08:38:25 +00:00
|
|
|
|
{/* 描述文字 - hover时显示,带过渡动效 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<div
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
'txt-body-m mb-2 line-clamp-6 transform overflow-hidden text-white transition-all duration-300 ease-in-out',
|
|
|
|
|
|
{
|
|
|
|
|
|
'max-h-0 opacity-0': !isHovered,
|
|
|
|
|
|
'h-full max-h-max opacity-100': isHovered,
|
|
|
|
|
|
}
|
|
|
|
|
|
)}
|
2025-11-13 08:38:25 +00:00
|
|
|
|
>
|
|
|
|
|
|
{character.introduction || ''}
|
|
|
|
|
|
</div>
|
2025-11-28 06:31:36 +00:00
|
|
|
|
|
2025-11-13 08:38:25 +00:00
|
|
|
|
{/* 点赞数 - 暂时用固定值,实际应该从API获取 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<div className="flex h-6 items-center gap-1 px-1 py-0.5">
|
2025-11-13 08:38:25 +00:00
|
|
|
|
{/* <img src={likeIcon} alt="点赞" className="w-3 h-3" /> */}
|
|
|
|
|
|
<i className="iconfont icon-Like-fill" />
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<span className="text-xs font-medium text-white">
|
|
|
|
|
|
{formatNumberToKMB(character.likedNum ?? 0)}
|
|
|
|
|
|
</span>
|
2025-11-13 08:38:25 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 角色信息 */}
|
|
|
|
|
|
<div className="flex flex-col gap-2">
|
|
|
|
|
|
{/* 角色名称 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
<div className="txt-title-m truncate">{character.nickname}</div>
|
|
|
|
|
|
|
2025-11-13 08:38:25 +00:00
|
|
|
|
{/* 标签 */}
|
|
|
|
|
|
<div className="flex flex-wrap gap-1">
|
|
|
|
|
|
{/* 性格标签 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
{character.characterName && <Tag size="small">{character.characterName}</Tag>}
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
|
|
|
|
|
{/* 标签 */}
|
2025-11-28 06:31:36 +00:00
|
|
|
|
{character.tagName && <Tag size="small">{character.tagName}</Tag>}
|
2025-11-13 08:38:25 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Link>
|
2025-11-28 06:31:36 +00:00
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default CharacterCard
|