diff --git a/api/allMovieType.ts b/api/allMovieType.ts index ab50584..f22cad1 100644 --- a/api/allMovieType.ts +++ b/api/allMovieType.ts @@ -84,93 +84,21 @@ export enum Gender { } /** - * 角色信息接口 + * 草图提示JSON结构接口 */ - export interface Character { - /** 角色唯一标识符 */ - id: string; - /** 角色名称 */ - name: string; - /** 角色描述,包含外貌、性格等详细信息 */ - description: string; - /** 角色类型 */ - role: RoleType; - /** 角色年龄 */ - age: number; - /** 角色性别 */ - gender: Gender; - /** 角色种族 */ - race: Race; - /** 角色简介 */ - brief?: string; - /** 角色体型描述 */ - physique?: string; - /** 角色发型描述 */ - hairstyle?: string; - /** 角色默认举止描述 */ - default_demeanor?: string; - } - - /** - * 服装信息接口 - */ - export interface Wardrobe { - /** 服装所属角色ID */ - belongs_to: string; - /** 服装详细描述 */ - description: string; - } - - /** - * 场景信息接口 - */ - export interface Scene { - /** 场景名称 */ - name: string; - /** 场景详细描述 */ - description: string; - } - - /** - * 项目风格信息接口 - */ - export interface ProjectStyle { - /** 地理设置和种族信息 */ - geographic_setting_ethnicity: string; - /** 格式要求 */ - format: string; - /** 美学风格描述 */ - aesthetics: string; - /** 技术蓝图 */ - technical_blueprint: string; - } - - /** - * 提示JSON结构接口 - */ - export interface PromptJson { - /** 导演指令 */ - directors_directive: string; - /** 叙事提示 */ - narrative_prompt: string; - /** 对话语言 */ - dialogue_language: string; - /** 整体项目风格 */ - overall_project_style: string; - /** 主要角色列表 */ - master_character_list: MasterCharacter[]; - /** 主要服装列表 */ - master_wardrobe_list: MasterWardrobe[]; - /** 主要场景列表 */ - master_scene_list: MasterScene[]; + export interface SketchPromptJson { + /** 草图名称 */ + sketch_name: string; + /** 草图描述 */ + sketch_description: string; /** 核心氛围 */ core_atmosphere: string; } /** - * 场景草图项 + * 草图数据项 */ - export interface SketchItem { + export interface SketchData { /** 草图名称 */ sketch_name: string; /** 图片ID */ @@ -178,51 +106,97 @@ export enum Gender { /** 提示词 */ prompt: string; /** 提示词JSON */ - prompt_json: PromptJson; - /** 草图名称前缀 */ - sketch_name_prefix: string; - /** 图片URL列表 */ - urls: string[]; + prompt_json: SketchPromptJson; + /** 图片路径 */ + image_path: string; } /** - * 镜头草图项 + * 草图响应数据接口 */ - export interface ShotSketchItem { - /** 镜头草图名称 */ - shot_sketch_name: string; + export interface SketchResponse { + /** 总数 */ + total_count: number; + /** 草图数据列表 */ + data: SketchData[]; + } + + /** + * 角色响应数据接口 + */ + export interface CharacterResponse { + /** 角色图片路径 */ + image_path: string; + /** 角色名称 */ + character_name: string; + /** 角色描述 */ + character_description: string; + } + + /** + * 角色数据接口 + */ + export interface CharacterData { + /** 角色数据列表 */ + data: CharacterResponse[]; + /** 总数 */ + total_count: number; + } + + /** + * 镜头草图提示JSON结构接口 + */ + export interface ShotSketchPromptJson { + /** 镜头类型 */ + shot_type: string; + /** 帧描述 */ + frame_description: string; + /** 关键动作 */ + key_action: string; + /** 氛围 */ + atmosphere: string; + /** 摄影蓝图构图 */ + cinematography_blueprint_composition: string; + /** 摄影蓝图镜头运动 */ + cinematography_blueprint_camera_motion: string; + /** 对话表演台词 */ + dialogue_performance_line?: any; + /** 对话表演语言 */ + dialogue_performance_language?: any; + /** 对话表演表达 */ + dialogue_performance_delivery?: any; + /** 对话表演说话者 */ + dialogue_performance_speaker?: any; + } + + /** + * 镜头草图数据项 + */ + export interface ShotSketchData { /** 图片ID */ image_id: string; - /** 提示词 */ - prompt: string; - /** 提示词JSON */ - prompt_json: PromptJson; - /** 镜头草图名称前缀 */ - shot_sketch_name_prefix: string; - /** 图片URL列表 */ - urls: string[]; - } - - /** - * 视频项 - */ - export interface VideoItem { - /** 视频ID */ - video_id: string; /** 描述 */ description: string; /** 提示词JSON */ - prompt_json: PromptJson; - /** 视频名称前缀 */ - video_name_prefix: string; - /** 视频URL列表 */ - urls: string[]; + prompt_json: ShotSketchPromptJson; + /** 图片URL */ + url: string; } /** - * 主要角色 + * 镜头草图响应数据接口 */ - export interface MasterCharacter { + export interface ShotSketchResponse { + /** 镜头草图数据列表 */ + data: ShotSketchData[]; + /** 总数 */ + total_count: number; + } + + /** + * 主要角色列表项 + */ + export interface MasterCharacterListItem { /** 角色ID */ id: string; /** 角色名称 */ @@ -232,9 +206,9 @@ export enum Gender { } /** - * 主要服装 + * 主要服装列表项 */ - export interface MasterWardrobe { + export interface MasterWardrobeListItem { /** 所属角色 */ belongs_to: string; /** 服装描述 */ @@ -242,9 +216,9 @@ export enum Gender { } /** - * 主要场景 + * 主要场景列表项 */ - export interface MasterScene { + export interface MasterSceneListItem { /** 场景名称 */ name: string; /** 场景描述 */ @@ -252,11 +226,49 @@ export enum Gender { } /** - * 视频数据 + * 视频提示JSON结构接口 + */ + export interface VideoPromptJson { + /** 导演指令 */ + directors_directive: string; + /** 叙事提示 */ + narrative_prompt: string; + /** 对话语言 */ + dialogue_language: string; + /** 整体项目风格 */ + overall_project_style: string; + /** 主要角色列表 */ + master_character_list: MasterCharacterListItem[]; + /** 主要服装列表 */ + master_wardrobe_list: MasterWardrobeListItem[]; + /** 主要场景列表 */ + master_scene_list: MasterSceneListItem[]; + /** 核心氛围 */ + core_atmosphere: string; + } + + /** + * 视频数据项 */ export interface VideoData { - /** 视频列表 */ - data: VideoItem[]; + /** 视频ID */ + video_id: string; + /** 描述 */ + description: string; + /** 提示词JSON */ + prompt_json: VideoPromptJson; + /** 视频名称前缀 */ + video_name_prefix: string; + /** 视频URL列表 */ + urls: string[]; + } + + /** + * 视频响应数据接口 + */ + export interface VideoResponse { + /** 视频数据列表 */ + data: VideoData[]; /** 总数 */ total_count: number; /** 全局ID */ @@ -266,37 +278,14 @@ export enum Gender { } /** - * 音乐数据 + * 音乐数据接口 */ export interface MusicData { [key: string]: any; } - /** - * 视频信息接口 - */ - export interface Video { - /** 视频唯一标识符 */ - video_id: string; - /** 视频描述 */ - description: string; - /** 提示JSON数据 */ - prompt_json: PromptJson; - /** 视频名称前缀 */ - video_name_prefix: string; - /** 视频URL列表 */ - urls: string[]; - } /** - * 音乐信息接口 - */ - export interface Music { - /** 音乐相关数据,当前为空对象 */ - [key: string]: any; - } - - /** - * 最终视频信息接口 + * 最终视频接口 */ export interface FinalVideo { /** 最终视频URL */ @@ -304,126 +293,24 @@ export enum Gender { } /** - * 多语言视频信息接口 + * 多语言视频接口 */ export interface MultilingualVideo { - /** 多语言视频相关数据,当前为空对象 */ [key: string]: any; } /** - * 项目设置接口 + * 项目内容数据接口 */ - export interface ProjectSettings { - /** 视频质量设置 */ - quality: string; - /** 帧率设置 */ - frame_rate: string; - /** 分辨率设置 */ - resolution: string; - /** 音频设置 */ - audio: { - /** 音频质量 */ - quality: string; - /** 音频格式 */ - format: string; - }; - } - - /** - * 项目统计信息接口 - */ - export interface ProjectStatistics { - /** 总视频数 */ - total_videos: number; - /** 总角色数 */ - total_characters: number; - /** 总场景数 */ - total_scenes: number; - /** 总服装数 */ - total_wardrobes: number; - /** 总音乐数 */ - total_music: number; - /** 总时长 */ - total_duration: number; - /** 总大小 */ - total_size: number; - } - - /** - * 项目元数据接口 - */ - export interface ProjectMetadata { - /** 项目版本 */ - version: string; - /** 项目语言 */ - language: string; - /** 项目分类 */ - category: string; - /** 项目难度 */ - difficulty: string; - /** 项目时长 */ - duration: string; - /** 项目预算 */ - budget: string; - /** 项目团队 */ - team: string[]; - /** 项目设备 */ - equipment: string[]; - /** 项目软件 */ - software: string[]; - /** 项目许可证 */ - license: string; - /** 项目版权 */ - copyright: string; - /** 项目评分 */ - rating: number; - /** 项目评论数 */ - review_count: number; - /** 项目下载数 */ - download_count: number; - /** 项目分享数 */ - share_count: number; - /** 项目收藏数 */ - favorite_count: number; - /** 项目观看数 */ - view_count: number; - /** 项目完成度 */ - completion_rate: number; - /** 项目进度 */ - progress: number; - /** 项目阶段 */ - stage: string; - /** 项目里程碑 */ - milestones: string[]; - /** 项目任务 */ - tasks: string[]; - /** 项目文件 */ - files: string[]; - /** 项目链接 */ - links: string[]; - /** 项目备注 */ - notes: string; - /** 项目历史 */ - history: string[]; - /** 项目日志 */ - logs: string[]; - /** 项目统计 */ - statistics: ProjectStatistics; - } - - /** - * 项目内容接口 - */ - export interface ProjectContent { + export interface ProjectContentData { /** 草图数据 */ - sketch: SketchItem[]; + sketch: SketchResponse; /** 角色数据 */ - character: Character[]; + character: CharacterData; /** 镜头草图数据 */ - shot_sketch: ShotSketchItem[]; + shot_sketch: ShotSketchResponse; /** 视频数据 */ - video: VideoData; + video: VideoResponse; /** 音乐数据 */ music: MusicData; /** 最终视频 */ @@ -432,40 +319,6 @@ export enum Gender { multilingual_video: MultilingualVideo; } - /** - * 视频流程项目接口 - */ - export interface VideoFlowProject { - /** 项目名称 */ - name: string; - /** 项目描述 */ - description: string; - /** 项目类型 */ - type: string; - /** 项目状态 */ - status: string; - /** 项目创建时间 */ - created_at: string; - /** 项目更新时间 */ - updated_at: string; - /** 项目所有者ID */ - owner_id: string; - /** 项目标签列表 */ - tags: string[]; - /** 项目设置 */ - settings: ProjectSettings; - /** 项目元数据 */ - metadata: ProjectMetadata; - /** 项目内容 */ - content: ProjectContent; - /** 音乐信息 */ - music: Music; - /** 最终视频 */ - final_video: FinalVideo; - /** 多语言视频 */ - multilingual_video: MultilingualVideo; - } - /** * 视频流程项目 - 完整的接口返回值类型 */ @@ -475,17 +328,17 @@ export enum Gender { /** 项目ID */ project_id: string; /** 项目模式 */ - mode: ProjectMode; + mode: string; /** 分辨率 */ - resolution: Resolution; + resolution: string; /** 语言 */ - language: Language; + language: string; /** 原始文本 */ original_text: string; /** 生成的脚本 */ generated_script: string; /** 项目状态 */ - status: ProjectStatus; + status: string; /** 项目标题 */ title: string; /** 项目类型 */ @@ -493,11 +346,21 @@ export enum Gender { /** 项目标签 */ tags: string[]; /** 项目步骤 */ - step: ProjectStep; + step: string; /** 最后消息 */ last_message: string; /** 项目内容 */ - data: ProjectContent; + data: ProjectContentData; } + // 为了向后兼容,保留原有的接口名称 + export interface Character extends CharacterResponse {} + export interface Sketch extends SketchResponse {} + export interface Shot_sketch extends ShotSketchResponse {} + export interface Video extends VideoResponse {} + export interface Music extends MusicData {} + export interface Final_video extends FinalVideo {} + export interface Multilingual_video extends MultilingualVideo {} + export interface RootObject extends VideoFlowProjectResponse {} + diff --git a/app/service/Interaction/RoleService.ts b/app/service/Interaction/RoleService.ts index c7dc783..00347ce 100644 --- a/app/service/Interaction/RoleService.ts +++ b/app/service/Interaction/RoleService.ts @@ -1,7 +1,6 @@ import { useState, useCallback, useMemo } from 'react'; import { RoleEntity, AITextEntity } from '../domain/Entities'; import { RoleEditUseCase } from '../usecase/RoleEditUseCase'; -import { getRoleData, getRoleList, getUserRoleLibrary, replaceRole } from '@/api/video_flow'; import { getUploadToken, uploadToQiniu } from '@/api/common'; /** @@ -70,12 +69,12 @@ export const useRoleServiceHook = (): UseRoleService => { */ const fetchRoleList = useCallback(async (projectId: string) => { try { - const response = await getRoleList({ projectId }); - if (response.successful) { - setRoleList(response.data); - } else { - throw new Error(`获取角色列表失败: ${response.message}`); - } + // 初始化角色编辑UseCase实例 + const newRoleEditUseCase = new RoleEditUseCase(); + const roleList = await newRoleEditUseCase.getRoleList(projectId); + + setRoleList(roleList); + setRoleEditUseCase(newRoleEditUseCase); } catch (error) { console.error('获取角色列表失败:', error); throw error; @@ -90,18 +89,7 @@ export const useRoleServiceHook = (): UseRoleService => { * @returns {Promise} 初始化完成后的Promise */ const initializeRoleData = useCallback(async (roleId: string) => { - try { - const response = await getRoleData({ roleId }); - if (response.successful) { - const { text } = response.data; - setCurrentRoleText(text.content); - } else { - throw new Error(`获取角色数据失败: ${response.message}`); - } - } catch (error) { - console.error('初始化角色数据失败:', error); - throw error; - } + }, []); /** @@ -114,18 +102,22 @@ export const useRoleServiceHook = (): UseRoleService => { if (role) { setSelectedRole(role); - // 初始化角色编辑UseCase实例 - const newRoleEditUseCase = new RoleEditUseCase(); - newRoleEditUseCase.roleList = roleList; - await newRoleEditUseCase.selectRole(roleId); - setRoleEditUseCase(newRoleEditUseCase); + // 如果RoleEditUseCase已经初始化,直接使用;否则创建新的 + if (!roleEditUseCase) { + const newRoleEditUseCase = new RoleEditUseCase(); + newRoleEditUseCase.roleList = roleList; + setRoleEditUseCase(newRoleEditUseCase); + } + + // 调用selectRole方法 + await roleEditUseCase!.selectRole(roleId); // 初始化角色数据 await initializeRoleData(roleId); } else { throw new Error('未找到对应的角色'); } - }, [initializeRoleData, roleList]); + }, [roleList, roleEditUseCase, initializeRoleData]); /** * 优化AI文本 @@ -236,17 +228,19 @@ export const useRoleServiceHook = (): UseRoleService => { */ const fetchUserRoleLibrary = useCallback(async () => { try { - const response = await getUserRoleLibrary(); - if (response.successful) { - setUserRoleLibrary(response.data); - } else { - throw new Error(`获取用户角色库失败: ${response.message}`); + // 如果没有初始化RoleEditUseCase,创建一个新的实例 + if (!roleEditUseCase) { + const newRoleEditUseCase = new RoleEditUseCase(); + setRoleEditUseCase(newRoleEditUseCase); } + + const roleLibraryList = await roleEditUseCase!.getRoleLibraryList(); + setUserRoleLibrary(roleLibraryList); } catch (error) { console.error('获取用户角色库失败:', error); throw error; } - }, []); + }, [roleEditUseCase]); /** * 替换角色 diff --git a/app/service/usecase/RoleEditUseCase.ts b/app/service/usecase/RoleEditUseCase.ts index 4822393..e4db496 100644 --- a/app/service/usecase/RoleEditUseCase.ts +++ b/app/service/usecase/RoleEditUseCase.ts @@ -47,15 +47,15 @@ export class RoleEditUseCase { } parseRoleList(detail: VideoFlowProjectResponse): RoleEntity[] { - const characters = detail.data?.character || []; + const characters = detail.data?.character.data || []; return characters.map((char, index) => { const roleEntity: RoleEntity = { id: `role_${index + 1}`, - name: char.name || '', - generateText: char.description || '', + name: char.character_name || '', + generateText: char.character_description || '', tags: [], // 默认为空标签数组 - imageUrl: '', // 默认为空图片URL + imageUrl: char.image_path || '', // 使用API返回的图片路径 loadingProgress: 100, // 默认加载完成 disableEdit: false, // 默认允许编辑 updatedAt: Date.now() @@ -265,7 +265,7 @@ export class RoleEditUseCase { id: `role_${Date.now()}`, name: '从图片识别的角色', generateText: '通过图片识别生成的角色描述', - tagIds: [], // 空标签数组 + tags: [], // 空标签数组 imageUrl: imageUrl, // 使用传入的图片地址 loadingProgress: 100, // 加载完成 disableEdit: false, // 允许编辑 diff --git a/components/ui/character-library-selector.tsx b/components/ui/character-library-selector.tsx index e8e01f9..f25ebae 100644 --- a/components/ui/character-library-selector.tsx +++ b/components/ui/character-library-selector.tsx @@ -1,36 +1,40 @@ import FloatingGlassPanel from './FloatingGlassPanel'; import { ImageWave } from '@/components/ui/ImageWave'; +import { RoleEntity } from '@/app/service/domain/Entities'; -const imageUrls = [ - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', - 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', -]; +interface CharacterLibrarySelectorProps { + isReplaceLibraryOpen: boolean; + setIsReplaceLibraryOpen: (open: boolean) => void; + onSelect: (index: number) => void; + /** 用户角色库数据 */ + userRoleLibrary: RoleEntity[]; +} export function CharacterLibrarySelector({ isReplaceLibraryOpen, setIsReplaceLibraryOpen, onSelect, -}: { - isReplaceLibraryOpen: boolean; - setIsReplaceLibraryOpen: (open: boolean) => void; - onSelect: (index: number) => void; -}) { + userRoleLibrary = [] +}: CharacterLibrarySelectorProps) { + // 将 RoleEntity[] 转换为图片URL数组 + const imageUrls = userRoleLibrary.map(role => role.imageUrl); + + // 如果没有数据,显示空状态 + if (userRoleLibrary.length === 0) { + return ( + setIsReplaceLibraryOpen(false)} + > +
+

暂无角色库数据

+
+
+ ); + } + return ( ); -} \ No newline at end of file +} diff --git a/components/ui/character-tab-content.tsx b/components/ui/character-tab-content.tsx index 4f1cfdd..3c0e8bb 100644 --- a/components/ui/character-tab-content.tsx +++ b/components/ui/character-tab-content.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef } from 'react'; +import React, { useState, useRef, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { ImageUp, Library, Play, Pause, RefreshCw, Wand2, Users, Check, ReplaceAll, X, TriangleAlert } from 'lucide-react'; import { cn } from '@/public/lib/utils'; @@ -8,6 +8,7 @@ import FloatingGlassPanel from './FloatingGlassPanel'; import { ReplaceCharacterPanel, mockShots, mockCharacter } from './replace-character-panel'; import { CharacterLibrarySelector } from './character-library-selector'; import HorizontalScroller from './HorizontalScroller'; +import { useRoleServiceHook } from '@/app/service/Interaction/RoleService'; interface Appearance { hairStyle: string; @@ -56,7 +57,7 @@ interface CharacterTabContentProps { roles: Role[]; } -export function CharacterTabContent({ +export function CharacterTabContent({ taskSketch, currentRoleIndex, onSketchSelect, @@ -73,7 +74,14 @@ export function CharacterTabContent({ const fileInputRef = useRef(null); const [enableAnimation, setEnableAnimation] = useState(true); const [showAddToLibrary, setShowAddToLibrary] = useState(true); - + const {fetchRoleList,roleList,fetchUserRoleLibrary,userRoleLibrary} = useRoleServiceHook() + useEffect(() => { + // 从url 获取 episodeId 作为projctId + const projectId = new URLSearchParams(window.location.search).get('episodeId'); + if (projectId) { + fetchRoleList(projectId); + } + }, [fetchRoleList]); const handleConfirmGotoReplace = () => { setIsRemindReplacePanelOpen(false); setIsReplacePanelOpen(true); @@ -122,15 +130,23 @@ export function CharacterTabContent({ // 从角色库中选择角色 const handleSelectCharacter = (index: number) => { - console.log('index', index); + console.log('选择的角色索引:', index); + console.log('选择的角色数据:', userRoleLibrary[index]); + setIsReplaceLibraryOpen(false); setShowAddToLibrary(false); - handleReplaceCharacter('https://c.huiying.video/images/5740cb7c-6e08-478f-9e7c-bca7f78a2bf6.jpg'); + + // 使用真实的角色数据 + const selectedRole = userRoleLibrary[index]; + if (selectedRole) { + handleReplaceCharacter(selectedRole.imageUrl); + } }; const handleOpenReplaceLibrary = () => { setIsReplaceLibraryOpen(true); setShowAddToLibrary(true); + fetchUserRoleLibrary(); }; const handleRegenerate = () => { @@ -182,7 +198,7 @@ export function CharacterTabContent({ onChange={handleFileChange} /> {/* 上部分:角色缩略图 */} - handleChangeRole(i)} > - {roles.map((role, index) => ( + {roleList.map((role, index) => ( - {role.name} @@ -241,7 +257,7 @@ export function CharacterTabContent({ {/* 应用角色按钮 */}
handleReplaceCharacter('https://c.huiying.video/images/5740cb7c-6e08-478f-9e7c-bca7f78a2bf6.jpg')} - className="flex items-center justify-center gap-2 px-4 py-3 bg-pink-500/10 hover:bg-pink-500/20 + className="flex items-center justify-center gap-2 px-4 py-3 bg-pink-500/10 hover:bg-pink-500/20 text-pink-500 rounded-lg transition-colors" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} @@ -281,7 +297,7 @@ export function CharacterTabContent({ handleRegenerate()} - className="flex items-center justify-center gap-2 px-4 py-3 bg-blue-500/10 hover:bg-blue-500/20 + className="flex items-center justify-center gap-2 px-4 py-3 bg-blue-500/10 hover:bg-blue-500/20 text-blue-500 rounded-lg transition-colors" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} @@ -292,7 +308,7 @@ export function CharacterTabContent({
- +
@@ -317,6 +333,7 @@ export function CharacterTabContent({ isReplaceLibraryOpen={isReplaceLibraryOpen} setIsReplaceLibraryOpen={setIsReplaceLibraryOpen} onSelect={handleSelectCharacter} + userRoleLibrary={userRoleLibrary} /> {/* 提醒用户角色已修改 是否需要替换 */} @@ -330,9 +347,9 @@ export function CharacterTabContent({

角色已修改,是否需要替换?

- +
- - -
); -} \ No newline at end of file +}