import React, { useState, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Upload, Library, Play, Pause, RefreshCw, Wand2, Users, Check, Sparkles, Plus, X } from 'lucide-react'; import { cn } from '@/public/lib/utils'; import { GlassIconButton } from './glass-icon-button'; import { ReplaceCharacterModal } from './replace-character-modal'; import { Slider } from './slider'; import CharacterEditor from './character-editor'; interface Appearance { hairStyle: string; skinTone: string; facialFeatures: string; bodyType: string; } interface Role { name: string; url: string; sound: string; soundDescription: string; roleDescription: string; age: number; gender: 'male' | 'female' | 'other'; ethnicity: string; appearance: Appearance; // 新增标签数组 tags: string[]; } // Mock 数据 const mockRole: Role = { name: "青春女学生", url: "/assets/3dr_chihiro.png", sound: "", soundDescription: "", roleDescription: "一位充满活力和梦想的高中女生,蓝色长发随风飘扬,眼神中透露着对未来的憧憬。她身着整洁的校服,举止优雅而不失活力。", age: 16, gender: 'female', ethnicity: '亚洲人', appearance: { hairStyle: "鲜艳蓝色长发", skinTone: "白皙", facialFeatures: "大眼睛,清秀五官", bodyType: "苗条" }, tags: ['高中生', '校服', '蓝色长发', '大眼睛', '清秀五官', '苗条'] }; interface CharacterTabContentProps { taskSketch: any[]; currentRoleIndex: number; onSketchSelect: (index: number) => void; roles: Role[]; } export function CharacterTabContent({ taskSketch, currentRoleIndex, onSketchSelect, roles = [mockRole] }: CharacterTabContentProps) { const [isReplaceModalOpen, setIsReplaceModalOpen] = useState(false); const [activeReplaceMethod, setActiveReplaceMethod] = useState('upload'); const [newTag, setNewTag] = useState(''); const [localRole, setLocalRole] = useState(mockRole); const textareaRef = useRef(null); // 处理标签添加 const handleAddTag = () => { if (newTag.trim() && !localRole.tags.includes(newTag.trim())) { const newTagText = newTag.trim(); // 更新标签数组 const updatedTags = [...localRole.tags, newTagText]; // 更新角色描述文本 const updatedDescription = localRole.roleDescription + (localRole.roleDescription ? ',' : '') + newTagText; setLocalRole({ ...localRole, tags: updatedTags, roleDescription: updatedDescription }); setNewTag(''); // 自动调整文本框高度 if (textareaRef.current) { textareaRef.current.style.height = 'auto'; textareaRef.current.style.height = textareaRef.current.scrollHeight + 'px'; } } }; // 处理标签删除 const handleRemoveTag = (tagToRemove: string) => { setLocalRole({ ...localRole, tags: localRole.tags.filter(tag => tag !== tagToRemove) }); }; // 处理年龄滑块变化 const handleAgeChange = (value: number[]) => { setLocalRole({ ...localRole, age: value[0] }); }; // 处理描述更新 const handleDescriptionChange = (e: React.ChangeEvent) => { setLocalRole({ ...localRole, roleDescription: e.target.value }); // 自动调整文本框高度 if (textareaRef.current) { textareaRef.current.style.height = 'auto'; textareaRef.current.style.height = textareaRef.current.scrollHeight + 'px'; } }; // 新增智能优化处理函数 const handleSmartOptimize = () => { console.log('Optimizing character description...'); // TODO: 调用 AI 优化接口 }; // 如果没有角色数据,显示占位内容 if (!roles || roles.length === 0) { return (

No character data

); } // 获取当前选中的角色 const currentRole = roles[currentRoleIndex]; return (
{/* 上部分:角色缩略图 */}
{roles.map((role, index) => ( onSketchSelect(index)} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > {role.name}
{role.name}
))}
{/* 下部分:角色详情 */} {/* 左列:角色预览 */}
{/* 角色预览图 */}
{currentRole.name}
console.log('regenerate character')} />
{/* 操作按钮 */}
{/* 右列:角色信息 */}
{ setLocalRole({ ...localRole, roleDescription: description }); }} onAttributesChange={(attributes) => { const newRole = { ...localRole }; attributes.forEach(attr => { switch (attr.key) { case 'age': newRole.age = parseInt(attr.value); break; case 'gender': if (attr.value === '男性') { newRole.gender = 'male'; } else if (attr.value === '女性') { newRole.gender = 'female'; } else { newRole.gender = 'other'; } break; case 'hair': newRole.appearance.hairStyle = attr.value; break; case 'skin': newRole.appearance.skinTone = attr.value; break; case 'build': newRole.appearance.bodyType = attr.value; break; } }); setLocalRole(newRole); }} />
); }