From 5842f177de4749e2f591c49c045bea1255340000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=97=E6=9E=B3?= <7854742+wang_rumeng@user.noreply.gitee.com> Date: Tue, 12 Aug 2025 17:37:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=A7=92=E8=89=B2=E5=BA=93?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E7=BB=84=E4=BB=B6=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E7=8A=B6=E6=80=81=E5=A4=84=E7=90=86=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2=E6=95=B0=E6=8D=AE=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E9=80=BB=E8=BE=91=E3=80=82=E5=90=8C=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=A7=92=E8=89=B2=E6=9B=BF=E6=8D=A2=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E4=BB=A5=E6=94=AF=E6=8C=81=E5=8A=A0=E8=BD=BD=E7=8A=B6?= =?UTF-8?q?=E6=80=81=EF=BC=8C=E7=A1=AE=E4=BF=9D=E7=94=A8=E6=88=B7=E4=BD=93?= =?UTF-8?q?=E9=AA=8C=E6=B5=81=E7=95=85=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/pages/work-flow/use-edit-data.tsx | 4 +-- components/ui/character-library-selector.tsx | 22 ++++++++++-- components/ui/character-tab-content.tsx | 37 +++++++++++++------- components/ui/replace-character-panel.tsx | 13 ++++--- components/ui/replace-panel.tsx | 27 +++++++++----- 5 files changed, 73 insertions(+), 30 deletions(-) diff --git a/components/pages/work-flow/use-edit-data.tsx b/components/pages/work-flow/use-edit-data.tsx index eddb315..d199032 100644 --- a/components/pages/work-flow/use-edit-data.tsx +++ b/components/pages/work-flow/use-edit-data.tsx @@ -57,7 +57,7 @@ export const useEditData = (tabType: string) => { toggleShotSelection, applyRoleToSelectedShots, clearShotSelection - } = useRoleShotServiceHook(projectId); + } = useRoleShotServiceHook(projectId, selectedRole); useEffect(() => { if (tabType === 'shot') { @@ -69,7 +69,6 @@ export const useEditData = (tabType: string) => { setLoading(false); }); } else if (tabType === 'role') { - // fetchUserRoleLibrary(); fetchRoleList(projectId).then(() => { setLoading(false); }).catch((err) => { @@ -105,6 +104,7 @@ export const useEditData = (tabType: string) => { optimizeRoleText, updateRoleText, regenerateRole, + fetchUserRoleLibrary, // role shot shotSelectionList, selectedRoleId, diff --git a/components/ui/character-library-selector.tsx b/components/ui/character-library-selector.tsx index f25ebae..4521316 100644 --- a/components/ui/character-library-selector.tsx +++ b/components/ui/character-library-selector.tsx @@ -3,6 +3,7 @@ import { ImageWave } from '@/components/ui/ImageWave'; import { RoleEntity } from '@/app/service/domain/Entities'; interface CharacterLibrarySelectorProps { + isLoading: boolean; isReplaceLibraryOpen: boolean; setIsReplaceLibraryOpen: (open: boolean) => void; onSelect: (index: number) => void; @@ -11,13 +12,28 @@ interface CharacterLibrarySelectorProps { } export function CharacterLibrarySelector({ + isLoading, isReplaceLibraryOpen, setIsReplaceLibraryOpen, onSelect, userRoleLibrary = [] }: CharacterLibrarySelectorProps) { - // 将 RoleEntity[] 转换为图片URL数组 - const imageUrls = userRoleLibrary.map(role => role.imageUrl); + + if (isLoading) { + return ( + setIsReplaceLibraryOpen(false)} + > +
+
+

Loading...

+
+ + ); + } // 如果没有数据,显示空状态 if (userRoleLibrary.length === 0) { @@ -44,7 +60,7 @@ export function CharacterLibrarySelector({ > {/* 内容 */} role.imageUrl)} containerWidth="90vw" containerHeight="calc(var(--index) * 15)" itemWidth="calc(var(--index) * 2)" diff --git a/components/ui/character-tab-content.tsx b/components/ui/character-tab-content.tsx index 865980d..76ecbe6 100644 --- a/components/ui/character-tab-content.tsx +++ b/components/ui/character-tab-content.tsx @@ -10,6 +10,7 @@ import { CharacterLibrarySelector } from './character-library-selector'; import HorizontalScroller from './HorizontalScroller'; import { useEditData } from '@/components/pages/work-flow/use-edit-data'; import { useSearchParams } from 'next/navigation'; +import { RoleEntity } from '@/app/service/domain/Entities'; interface Appearance { hairStyle: string; @@ -75,6 +76,8 @@ export function CharacterTabContent({ const characterEditorRef = useRef(null); const [isInitialized, setIsInitialized] = useState(false); const [isRegenerate, setIsRegenerate] = useState(false); + const [isLoadingShots, setIsLoadingShots] = useState(false); + const [isLoadingLibrary, setIsLoadingLibrary] = useState(false); const { loading, @@ -85,16 +88,11 @@ export function CharacterTabContent({ optimizeRoleText, updateRoleText, regenerateRole, + fetchUserRoleLibrary, // role shot shotSelectionList, - selectedRoleId, - isAllVideoSegmentSelected, - selectedVideoSegmentCount, fetchRoleShots, - toggleSelectAllShots, - toggleShotSelection, - applyRoleToSelectedShots, - clearShotSelection + applyRoleToSelectedShots } = useEditData('role'); const searchParams = useSearchParams(); const episodeId = searchParams.get('episodeId'); @@ -113,16 +111,22 @@ export function CharacterTabContent({ console.log('获取选中项数据', selectedRole); }, [selectedRole]); + useEffect(() => { + console.log('获取角色库数据', userRoleLibrary); + }, [userRoleLibrary]); + const handleSmartPolish = (text: string) => { // 然后调用优化角色文本 optimizeRoleText(text); }; - const handleStartReplaceCharacter = () => { - // 获取当前角色对应的视频片段 - fetchRoleShots(selectedRole?.id || ''); - // 打开替换角色面板 + const handleStartReplaceCharacter = async () => { + setIsLoadingShots(true); setIsReplacePanelOpen(true); + // 获取当前角色对应的视频片段 + await fetchRoleShots(selectedRole?.name || ''); + // 打开替换角色面板 + setIsLoadingShots(false); }; const handleConfirmGotoReplace = () => { @@ -146,6 +150,7 @@ export function CharacterTabContent({ // 处理替换确认逻辑 console.log('Selected shots:', selectedShots); console.log('Add to library:', addToLibrary); + applyRoleToSelectedShots(selectedRole || {} as RoleEntity); setIsReplacePanelOpen(false); }; @@ -185,9 +190,12 @@ export function CharacterTabContent({ } }; - const handleOpenReplaceLibrary = () => { + const handleOpenReplaceLibrary = async () => { + setIsLoadingLibrary(true); setIsReplaceLibraryOpen(true); setShowAddToLibrary(true); + await fetchUserRoleLibrary(); + setIsLoadingLibrary(false); }; const handleRegenerate = async () => { @@ -200,6 +208,7 @@ export function CharacterTabContent({ // 然后调用重新生成角色 await regenerateRole(); setIsRegenerate(false); + handleStartReplaceCharacter(); }; const handleUploadClick = () => { @@ -384,8 +393,9 @@ export function CharacterTabContent({ onClose={() => handleCloseReplacePanel()} > handleCloseReplacePanel()} onConfirm={handleConfirmReplace} @@ -394,6 +404,7 @@ export function CharacterTabContent({ {/* 从角色库中选择角色 */} void; onConfirm: (selectedShots: string[], addToLibrary: boolean) => void; @@ -40,21 +42,24 @@ export const mockShots: Shot[] = [ ]; export function ReplaceCharacterPanel({ - shots = [], - character, + isLoading, + shots, + role, showAddToLibrary = true, onClose, onConfirm, }: ReplaceCharacterPanelProps) { + return ( ); } \ No newline at end of file diff --git a/components/ui/replace-panel.tsx b/components/ui/replace-panel.tsx index ca69d2e..51033f2 100644 --- a/components/ui/replace-panel.tsx +++ b/components/ui/replace-panel.tsx @@ -4,6 +4,7 @@ import { Check, X, CircleAlert, ArrowLeft, ArrowRight } from 'lucide-react'; import { cn } from '@/public/lib/utils'; interface ReplacePanelProps { + isLoading: boolean; title: string; shots: any[]; item: any; @@ -14,6 +15,7 @@ interface ReplacePanelProps { } export function ReplacePanel({ + isLoading, title, shots, item, @@ -56,11 +58,11 @@ export function ReplacePanel({ }, []); const handleShotToggle = (shotId: string) => { - setSelectedShots(prev => - prev.includes(shotId) - ? prev.filter(id => id !== shotId) - : [...prev, shotId] - ); + // setSelectedShots(prev => + // prev.includes(shotId) + // ? prev.filter(id => id !== shotId) + // : [...prev, shotId] + // ); }; const handleSelectAllShots = (checked: boolean) => { @@ -104,6 +106,15 @@ export function ReplacePanel({ }); }; + if (isLoading) { + return ( +
+
+

Loading...

+
+ ) + } + return (
{/* 标题 */} @@ -115,7 +126,7 @@ export function ReplacePanel({ 该内容出现在 {shots.length} 个分镜中,替换后将影响如下分镜
-
+ {/*
-
+
*/}
{/* 分镜展示区 */}
-
选择需要替换的分镜:
+ {/*
选择需要替换的分镜:
*/}
{shots.map((shot) => (