From ebb9a951bdab6d3fa369655e62ab1ad7d2343489 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:47:28 +0800
Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=A7=92=E8=89=B2?=
=?UTF-8?q?=E7=BC=96=E8=BE=91=E6=95=B0=E6=8D=AE=E9=80=BB=E8=BE=91=EF=BC=8C?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=8A=E4=BC=A0=E5=9B=BE=E7=89=87=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E5=B9=B6=E5=A4=84=E7=90=86=E5=8A=A0=E8=BD=BD=E7=8A=B6?=
=?UTF-8?q?=E6=80=81=EF=BC=8C=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2=E5=BA=93?=
=?UTF-8?q?=E9=80=89=E6=8B=A9=E7=BB=84=E4=BB=B6=E7=9A=84=E7=94=A8=E6=88=B7?=
=?UTF-8?q?=E4=BD=93=E9=AA=8C=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-tab-content.tsx | 19 ++++++++++++-------
2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/components/pages/work-flow/use-edit-data.tsx b/components/pages/work-flow/use-edit-data.tsx
index d199032..99c80fb 100644
--- a/components/pages/work-flow/use-edit-data.tsx
+++ b/components/pages/work-flow/use-edit-data.tsx
@@ -44,7 +44,8 @@ export const useEditData = (tabType: string) => {
fetchUserRoleLibrary,
optimizeRoleText,
updateRoleText,
- regenerateRole
+ regenerateRole,
+ uploadImageToQiniu
} = useRoleServiceHook();
const {
@@ -105,6 +106,7 @@ export const useEditData = (tabType: string) => {
updateRoleText,
regenerateRole,
fetchUserRoleLibrary,
+ uploadImageToQiniu,
// role shot
shotSelectionList,
selectedRoleId,
diff --git a/components/ui/character-tab-content.tsx b/components/ui/character-tab-content.tsx
index 73911f0..cc115c8 100644
--- a/components/ui/character-tab-content.tsx
+++ b/components/ui/character-tab-content.tsx
@@ -1,6 +1,6 @@
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 { ImageUp, Library, Play, Pause, RefreshCw, Wand2, Users, Check, ReplaceAll, X, TriangleAlert, Loader2 } from 'lucide-react';
import { cn } from '@/public/lib/utils';
import { CharacterEditor } from './character-editor';
import ImageBlurTransition from './ImageBlurTransition';
@@ -78,6 +78,7 @@ export function CharacterTabContent({
const [isRegenerate, setIsRegenerate] = useState(false);
const [isLoadingShots, setIsLoadingShots] = useState(false);
const [isLoadingLibrary, setIsLoadingLibrary] = useState(false);
+ const [isUploading, setIsUploading] = useState(false);
const {
loading,
@@ -89,6 +90,7 @@ export function CharacterTabContent({
updateRoleText,
regenerateRole,
fetchUserRoleLibrary,
+ uploadImageToQiniu,
// role shot
shotSelectionList,
fetchRoleShots,
@@ -212,6 +214,7 @@ export function CharacterTabContent({
};
const handleUploadClick = () => {
+ setIsUploading(true);
fileInputRef.current?.click();
};
@@ -227,11 +230,12 @@ export function CharacterTabContent({
// 创建本地预览URL
const imageUrl = URL.createObjectURL(file);
- setShowAddToLibrary(false);
- handleReplaceCharacter(imageUrl);
-
- // 清空input的值,这样同一个文件可以重复选择
- event.target.value = '';
+ uploadImageToQiniu(file).then((data) => {
+ console.log('上传图片成功', data);
+ // 清空input的值,这样同一个文件可以重复选择
+ event.target.value = '';
+ setIsUploading(false);
+ });
};
// 如果loading 显示loading状态
@@ -338,8 +342,9 @@ export function CharacterTabContent({
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={() => handleOpenReplaceLibrary()}
+ disabled={isUploading}
>
-
+ {isUploading ? : }
From 1f723d39f8b2546e6c8f1c46e88f14fdf69bf08e 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 18:44:51 +0800
Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2?=
=?UTF-8?q?=E8=AF=86=E5=88=AB=E9=80=BB=E8=BE=91=EF=BC=8C=E8=B0=83=E6=95=B4?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E5=B8=A7=E5=A4=84=E7=90=86=E5=92=8C=E8=A7=92?=
=?UTF-8?q?=E8=89=B2=E8=AF=86=E5=88=AB=E7=BB=93=E6=9E=9C=E7=9A=84=E8=BF=94?=
=?UTF-8?q?=E5=9B=9E=EF=BC=8C=E6=9B=B4=E6=96=B0=E8=A7=92=E8=89=B2=E8=AF=86?=
=?UTF-8?q?=E5=88=AB=E5=93=8D=E5=BA=94=E7=9A=84=E5=AF=BC=E5=87=BA=E6=96=B9?=
=?UTF-8?q?=E5=BC=8F=EF=BC=8C=E5=A2=9E=E5=BC=BA=E7=94=A8=E6=88=B7=E4=BD=93?=
=?UTF-8?q?=E9=AA=8C=E3=80=82=E5=90=8C=E6=97=B6=EF=BC=8C=E4=BF=AE=E5=A4=8D?=
=?UTF-8?q?=E6=89=AB=E6=8F=8F=E5=A4=B1=E8=B4=A5=E6=97=B6=E7=9A=84=E7=8A=B6?=
=?UTF-8?q?=E6=80=81=E7=AE=A1=E7=90=86=EF=BC=8C=E7=A1=AE=E4=BF=9D=E6=89=AB?=
=?UTF-8?q?=E6=8F=8F=E8=BF=87=E7=A8=8B=E7=9A=84=E6=B5=81=E7=95=85=E6=80=A7?=
=?UTF-8?q?=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/service/Interaction/ShotService.ts | 5 ++--
app/service/usecase/ShotEditUsecase.ts | 2 +-
components/ui/character-tab-content.tsx | 8 +++---
components/ui/edit-modal.tsx | 2 +-
components/ui/person-detection.tsx | 2 +-
components/ui/shot-tab-content.tsx | 35 +++++++++++++++----------
6 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/app/service/Interaction/ShotService.ts b/app/service/Interaction/ShotService.ts
index d537b1c..5b80d8e 100644
--- a/app/service/Interaction/ShotService.ts
+++ b/app/service/Interaction/ShotService.ts
@@ -309,7 +309,7 @@ export const useShotService = (): UseShotService => {
*/
const filterRole = useCallback(async (
video: HTMLVideoElement,
- ): Promise => {
+ ) => {
try {
// 创建canvas元素来截取视频帧
const canvas = document.createElement('canvas');
@@ -356,12 +356,11 @@ export const useShotService = (): UseShotService => {
imageUrl
);
console.log('角色识别结果:', recognitionResult);
+ return recognitionResult;
} catch (recognitionError) {
console.warn('角色识别失败,但图片上传成功:', recognitionError);
}
}
-
- return imageUrl;
} catch (error) {
console.error('获取视频帧失败:', error);
throw error;
diff --git a/app/service/usecase/ShotEditUsecase.ts b/app/service/usecase/ShotEditUsecase.ts
index a2c0b74..ba4a7eb 100644
--- a/app/service/usecase/ShotEditUsecase.ts
+++ b/app/service/usecase/ShotEditUsecase.ts
@@ -439,7 +439,7 @@ export interface RoleRecognitionResponse {
characters_used: CharacterUsed[];
}
-const roleRecognitionResponse:RoleRecognitionResponse = {
+export const roleRecognitionResponse:RoleRecognitionResponse = {
"project_id": "d0df7120-e27b-4f84-875c-e532f1bd318c",
"video_id": "984f3347-c81c-4af8-9145-49ead82becde",
"target_image_url": "https://cdn.qikongjian.com/videos/1754970412744_kqxplx.png",
diff --git a/components/ui/character-tab-content.tsx b/components/ui/character-tab-content.tsx
index cc115c8..4560aa8 100644
--- a/components/ui/character-tab-content.tsx
+++ b/components/ui/character-tab-content.tsx
@@ -228,8 +228,6 @@ export function CharacterTabContent({
return;
}
- // 创建本地预览URL
- const imageUrl = URL.createObjectURL(file);
uploadImageToQiniu(file).then((data) => {
console.log('上传图片成功', data);
// 清空input的值,这样同一个文件可以重复选择
@@ -333,8 +331,9 @@ export function CharacterTabContent({
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={handleUploadClick}
+ disabled={isUploading}
>
-
+ {isUploading ? : }
: }
+
diff --git a/components/ui/edit-modal.tsx b/components/ui/edit-modal.tsx
index 3c3024b..f2c268e 100644
--- a/components/ui/edit-modal.tsx
+++ b/components/ui/edit-modal.tsx
@@ -78,7 +78,7 @@ export function EditModal({
const isTabDisabled = (tabId: string) => {
if (tabId === 'settings') return false;
// 换成 如果对应标签下 数据存在 就不禁用
- if (tabId === '1') return roles.length === 0;
+ // if (tabId === '1') return roles.length === 0;
if (tabId === '2') return taskScenes.length === 0;
if (tabId === '3') return sketchVideo.length === 0;
if (tabId === '4') return false;
diff --git a/components/ui/person-detection.tsx b/components/ui/person-detection.tsx
index d9298af..81d61f2 100644
--- a/components/ui/person-detection.tsx
+++ b/components/ui/person-detection.tsx
@@ -62,7 +62,7 @@ export const PersonDetectionScene: React.FC = ({
onScanStart,
onScanTimeout,
onScanExit,
- scanTimeout = 10000,
+ scanTimeout = 100000,
isScanFailed = false,
onDetectionsChange,
onPersonClick
diff --git a/components/ui/shot-tab-content.tsx b/components/ui/shot-tab-content.tsx
index 97742f4..56f1358 100644
--- a/components/ui/shot-tab-content.tsx
+++ b/components/ui/shot-tab-content.tsx
@@ -11,6 +11,7 @@ import FloatingGlassPanel from './FloatingGlassPanel';
import { ReplaceCharacterPanel, mockShots, mockCharacter } from './replace-character-panel';
import HorizontalScroller from './HorizontalScroller';
import { useEditData } from '@/components/pages/work-flow/use-edit-data';
+import { roleRecognitionResponse } from '@/app/service/usecase/ShotEditUsecase';
interface ShotTabContentProps {
currentSketchIndex: number;
@@ -32,6 +33,7 @@ export function ShotTabContent({
const [detections, setDetections] = useState([]);
const [scanState, setScanState] = useState<'idle' | 'scanning' | 'detected'>('idle');
+ const [isScanFailed, setIsScanFailed] = useState(false);
const [isReplaceLibraryOpen, setIsReplaceLibraryOpen] = useState(false);
const [isReplacePanelOpen, setIsReplacePanelOpen] = useState(false);
@@ -48,26 +50,25 @@ export function ShotTabContent({
}, [selectedIndex, shotData]);
// 处理扫描开始
- const handleScan = () => {
+ const handleScan = async () => {
if (scanState === 'detected') {
// 如果已经有检测结果,点击按钮退出检测状态
setScanState('idle');
setDetections([]); // 清除检测结果
return;
}
- filterRole(document.getElementById('person-detection-video') as HTMLVideoElement);
setScanState('scanning');
- // 模拟检测过程
- setTimeout(() => {
- const mockDetections: PersonDetection[] = [
- {
- id: '1',
- name: '人物1',
- position: { top: 0, left: 100, width: 100, height: 200 }
- }
- ];
- setDetections(mockDetections);
- }, 5000);
+ await filterRole(document.getElementById('person-detection-video') as HTMLVideoElement);
+
+ if (roleRecognitionResponse.recognition_result.code === 200) {
+ setDetections(roleRecognitionResponse.recognition_result.data.matched_persons.map((person) => ({
+ id: person.person_id,
+ name: person.person_id,
+ position: { top: person.bbox.y, left: person.bbox.x, width: person.bbox.width, height: person.bbox.height }
+ })));
+ } else {
+ setIsScanFailed(true);
+ }
};
// 处理扫描超时/失败
@@ -76,6 +77,12 @@ export function ShotTabContent({
setDetections([]);
};
+ // 处理退出扫描
+ const handleScanExit = () => {
+ setScanState('idle');
+ setDetections([]);
+ };
+
// 处理检测到结果
const handleDetectionsChange = (newDetections: PersonDetection[]) => {
if (newDetections.length > 0 && scanState === 'scanning') {
@@ -287,7 +294,7 @@ export function ShotTabContent({
detections={detections}
triggerScan={scanState === 'scanning'}
onScanTimeout={handleScanTimeout}
- onScanExit={handleScanTimeout}
+ onScanExit={handleScanExit}
onDetectionsChange={handleDetectionsChange}
onPersonClick={handlePersonClick}
/>