更新角色和视频任务的保存逻辑,重构SaveEditUseCase以支持角色和视频任务的管理,优化相关服务的接口调用。

This commit is contained in:
海龙 2025-08-13 21:25:53 +08:00
parent 2ab25bc72c
commit 7abf41a83d
6 changed files with 424 additions and 208 deletions

View File

@ -1108,8 +1108,13 @@ export const checkShotVideoStatus = async (request: {
export const modifyCharacterOrScene = async (request: {
/** 项目ID */
project_id: string;
/** 角色ID可能为null */
character_id?: string | null;
/** 新的角色库角色 */
character_id: {
/** 角色ID */
character_id: string;
/** 角色名称 */
name: string;
}[];
/** 视频任务关联列表 */
video_tasks: Array<{
/** 生成视频的任务ID */
@ -1117,30 +1122,7 @@ export const modifyCharacterOrScene = async (request: {
/** 该任务对应的video_id列表 */
video_ids: string[];
}>;
}): Promise<ApiResponse<{
/** 项目ID */
project_id: string;
/** 自动检测到的修改类型("character" 或 "scene" */
modify_type: "character" | "scene";
/** 传入的视频任务列表 */
video_tasks: Array<{
task_id: string;
video_ids: string[];
}>;
/** 处理结果描述 */
message: string;
/** 详细处理信息 */
details: Record<string, any>;
/** 警告信息(如有) */
warning: string | null;
/** 启动的视频检测任务列表 */
video_check_tasks: Array<{
task_id: string;
video_ids: string[];
}>;
/** 启动的视频检测任务数量 */
video_check_started: number;
}>> => {
}) => {
return post<ApiResponse<{
project_id: string;
modify_type: "character" | "scene";

View File

@ -1,8 +1,12 @@
import { useState, useCallback, useMemo } from 'react';
import { RoleEntity, AITextEntity } from '../domain/Entities';
import { RoleEditUseCase } from '../usecase/RoleEditUseCase';
import { getUploadToken, uploadToQiniu } from '@/api/common';
import { analyzeImageDescription, checkShotVideoStatus } from '@/api/video_flow';
import { useState, useCallback, useMemo } from "react";
import { RoleEntity, AITextEntity } from "../domain/Entities";
import { RoleEditUseCase } from "../usecase/RoleEditUseCase";
import { getUploadToken, uploadToQiniu } from "@/api/common";
import {
analyzeImageDescription,
checkShotVideoStatus,
} from "@/api/video_flow";
import { SaveEditUseCase } from "../usecase/SaveEditUseCase";
/**
* Hook返回值接口
@ -52,11 +56,12 @@ export const useRoleServiceHook = (): UseRoleService => {
const [selectedRole, setSelectedRole] = useState<RoleEntity | null>(null);
const [currentRoleText, setCurrentRoleText] = useState<string | null>(null);
const [userRoleLibrary, setUserRoleLibrary] = useState<RoleEntity[]>([]);
const [projectId, setProjectId] = useState<string>(''); // 添加项目ID状态
const [projectId, setProjectId] = useState<string>(""); // 添加项目ID状态
const [cacheRole, setCacheRole] = useState<RoleEntity | null>(null);
// UseCase实例 - 在角色选择时初始化
const [roleEditUseCase, setRoleEditUseCase] = useState<RoleEditUseCase | null>(null);
const [roleEditUseCase, setRoleEditUseCase] =
useState<RoleEditUseCase | null>(null);
// 计算属性
/**
@ -64,7 +69,7 @@ export const useRoleServiceHook = (): UseRoleService => {
* @description URL
*/
const roleImageUrl = useMemo(() => {
return selectedRole?.imageUrl || '';
return selectedRole?.imageUrl || "";
}, [selectedRole]);
/**
@ -86,31 +91,32 @@ export const useRoleServiceHook = (): UseRoleService => {
setRoleList(roleList);
setRoleEditUseCase(newRoleEditUseCase);
} catch (error) {
console.error('获取角色列表失败:', error);
console.error("获取角色列表失败:", error);
throw error;
}
}, []);
/**
*
* @description ID选择角色UseCase实例
* @param roleId ID
*/
const selectRole = useCallback(async (role: RoleEntity) => {
console.log('selectRole', role);
// 根据 role.name 完全替换掉旧的数据
setRoleList(prev => prev.map(r => r.name === role.name ? role : r));
setSelectedRole(role);
// 如果缓存角色为空,则设置缓存角色,名字不同也切换
if(!cacheRole||cacheRole.name!==role.name){
setCacheRole(role);
}
const selectRole = useCallback(
async (role: RoleEntity) => {
console.log("selectRole", role);
// 根据 role.name 完全替换掉旧的数据
setRoleList((prev) => prev.map((r) => (r.name === role.name ? role : r)));
setSelectedRole(role);
// 如果缓存角色为空,则设置缓存角色,名字不同也切换
if (!cacheRole || cacheRole.name !== role.name) {
setCacheRole(role);
}
// 调用selectRole方法
roleEditUseCase!.selectRole(role);
}, [roleEditUseCase]);
roleEditUseCase!.selectRole(role);
},
[roleEditUseCase]
);
/**
* AI文本
@ -120,36 +126,39 @@ export const useRoleServiceHook = (): UseRoleService => {
*/
const optimizeRoleText = useCallback(async () => {
if (!roleEditUseCase) {
throw new Error('角色编辑UseCase未初始化');
throw new Error("角色编辑UseCase未初始化");
}
if (!currentRoleText) {
throw new Error('没有可优化的文本内容');
throw new Error("没有可优化的文本内容");
}
if (!selectedRole) {
throw new Error('没有选中的角色');
throw new Error("没有选中的角色");
}
try {
const { optimizedDescription, keywords } = await roleEditUseCase.optimizeRoleDescription(selectedRole);
const { optimizedDescription, keywords } =
await roleEditUseCase.optimizeRoleDescription(selectedRole);
setCurrentRoleText(optimizedDescription);
// 更新角色列表中的对应角色描述和标签
setRoleList(prev =>
prev.map(role =>
setRoleList((prev) =>
prev.map((role) =>
role.id === selectedRole?.id
? {
...role,
generateText: optimizedDescription,
tags: keywords.map(keyword => ({
id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
tags: keywords.map((keyword) => ({
id: `tag_${Date.now()}_${Math.random()
.toString(36)
.substr(2, 9)}`,
/** 名称 */
name: keyword,
/** 内容 */
content: keyword,
loadingProgress: 100,
disableEdit: false
}))
disableEdit: false,
})),
}
: role
)
@ -157,18 +166,22 @@ export const useRoleServiceHook = (): UseRoleService => {
// 更新当前选中角色
if (selectedRole) {
selectRole({ ...selectedRole, generateText: optimizedDescription, tags: keywords.map(keyword => ({
id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
/** 名称 */
name: keyword,
/** 内容 */
content: keyword,
loadingProgress: 100,
disableEdit: false
})) });
selectRole({
...selectedRole,
generateText: optimizedDescription,
tags: keywords.map((keyword) => ({
id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
/** 名称 */
name: keyword,
/** 内容 */
content: keyword,
loadingProgress: 100,
disableEdit: false,
})),
});
}
} catch (error) {
console.error('优化角色文本失败:', error);
console.error("优化角色文本失败:", error);
throw error;
}
}, [roleEditUseCase, currentRoleText, selectedRole, selectRole]);
@ -180,27 +193,30 @@ export const useRoleServiceHook = (): UseRoleService => {
* @throws {Error} UseCase未初始化时抛出错误
* @returns {Promise<void>} Promise
*/
const updateRoleText = useCallback(async (newContent: string) => {
if (!roleEditUseCase) {
throw new Error('角色编辑UseCase未初始化');
}
const updateRoleText = useCallback(
async (newContent: string) => {
if (!roleEditUseCase) {
throw new Error("角色编辑UseCase未初始化");
}
setCurrentRoleText(newContent);
setCurrentRoleText(newContent);
// 更新角色列表中的对应角色描述
setRoleList(prev =>
prev.map(role =>
role.id === selectedRole?.id
? { ...role, generateText: newContent }
: role
)
);
// 更新角色列表中的对应角色描述
setRoleList((prev) =>
prev.map((role) =>
role.id === selectedRole?.id
? { ...role, generateText: newContent }
: role
)
);
// 更新当前选中角色
if (selectedRole) {
selectRole({ ...selectedRole, generateText: newContent });
}
}, [roleEditUseCase, selectRole, selectedRole]);
// 更新当前选中角色
if (selectedRole) {
selectRole({ ...selectedRole, generateText: newContent });
}
},
[roleEditUseCase, selectRole, selectedRole]
);
/**
*
@ -210,15 +226,15 @@ export const useRoleServiceHook = (): UseRoleService => {
*/
const regenerateRole = useCallback(async () => {
if (!roleEditUseCase) {
throw new Error('角色编辑UseCase未初始化');
throw new Error("角色编辑UseCase未初始化");
}
if (!selectedRole || !currentRoleText) {
throw new Error('缺少重新生成角色所需的数据');
throw new Error("缺少重新生成角色所需的数据");
}
if (!projectId) {
throw new Error('缺少项目ID无法重新生成角色');
throw new Error("缺少项目ID无法重新生成角色");
}
try {
@ -230,15 +246,13 @@ export const useRoleServiceHook = (): UseRoleService => {
selectRole(newRoleEntity);
// 更新角色列表
setRoleList(prev =>
prev.map(role =>
role.id === newRoleEntity.id
? newRoleEntity
: role
setRoleList((prev) =>
prev.map((role) =>
role.id === newRoleEntity.id ? newRoleEntity : role
)
);
} catch (error) {
console.error('重新生成角色失败:', error);
console.error("重新生成角色失败:", error);
throw error;
}
}, [roleEditUseCase, selectedRole, currentRoleText, projectId, selectRole]);
@ -263,16 +277,19 @@ export const useRoleServiceHook = (): UseRoleService => {
const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
if (!User.id) {
throw new Error('无法获取用户ID请重新登录');
throw new Error("无法获取用户ID请重新登录");
}
// 获取当前选中角色的描述
const userDescription = selectedRole?.generateText || '';
const userDescription = selectedRole?.generateText || "";
const roleLibraryList = await useCase!.getRoleLibraryList(User.id, userDescription);
const roleLibraryList = await useCase!.getRoleLibraryList(
User.id,
userDescription
);
setUserRoleLibrary(roleLibraryList);
} catch (error) {
console.error('获取用户角色库失败:', error);
console.error("获取用户角色库失败:", error);
throw error;
}
}, [roleEditUseCase, selectedRole]);
@ -284,43 +301,46 @@ export const useRoleServiceHook = (): UseRoleService => {
* @throws {Error} API调用失败或UseCase未初始化时抛出错误
* @returns {Promise<void>} Promise
*/
const replaceRoleWithLibrary = useCallback(async (replaceRoleId: string) => {
if (!selectedRole) {
throw new Error('请先选择角色');
}
if (!roleEditUseCase) {
throw new Error('角色编辑UseCase未初始化');
}
try {
await roleEditUseCase.replaceRoleById(selectedRole.id, replaceRoleId);
// 更新角色列表
const libraryRole = userRoleLibrary.find(role => role.id === replaceRoleId);
if (libraryRole) {
const updatedRole = {
...selectedRole,
name: libraryRole.name,
generateText: libraryRole.generateText,
imageUrl: libraryRole.imageUrl,
fromDraft: false
};
selectRole(updatedRole);
setRoleList(prev =>
prev.map(role =>
role.id === selectedRole.id
? updatedRole
: role
)
);
const replaceRoleWithLibrary = useCallback(
async (replaceRoleId: string) => {
if (!selectedRole) {
throw new Error("请先选择角色");
}
} catch (error) {
console.error('替换角色失败:', error);
throw error;
}
}, [selectedRole, roleEditUseCase, userRoleLibrary, selectRole]);
if (!roleEditUseCase) {
throw new Error("角色编辑UseCase未初始化");
}
try {
await roleEditUseCase.replaceRoleById(selectedRole.id, replaceRoleId);
// 更新角色列表
const libraryRole = userRoleLibrary.find(
(role) => role.id === replaceRoleId
);
if (libraryRole) {
const updatedRole = {
...selectedRole,
name: libraryRole.name,
generateText: libraryRole.generateText,
imageUrl: libraryRole.imageUrl,
fromDraft: false,
};
selectRole(updatedRole);
setRoleList((prev) =>
prev.map((role) =>
role.id === selectedRole.id ? updatedRole : role
)
);
}
} catch (error) {
console.error("替换角色失败:", error);
throw error;
}
},
[selectedRole, roleEditUseCase, userRoleLibrary, selectRole]
);
/**
*
@ -328,62 +348,60 @@ export const useRoleServiceHook = (): UseRoleService => {
* @param file
* @returns {Promise<void>} Promise
*/
const uploadImageAndUpdateRole = useCallback(async (file: File) => {
if (!selectedRole) {
throw new Error('请先选择要更新的角色');
}
try {
// 1. 上传图片到七牛云
const { token } = await getUploadToken();
const imageUrl = await uploadToQiniu(file, token);
// 2. 调用图片分析接口获取描述
const result = await analyzeImageDescription({
image_url: imageUrl
});
if (!result.successful) {
throw new Error(`图片分析失败: ${result.message}`);
const uploadImageAndUpdateRole = useCallback(
async (file: File) => {
if (!selectedRole) {
throw new Error("请先选择要更新的角色");
}
const { description, highlights } = result.data;
try {
// 1. 上传图片到七牛云
const { token } = await getUploadToken();
const imageUrl = await uploadToQiniu(file, token);
// 3. 更新当前选中角色的图片、描述和标签
const updatedRole = {
...selectedRole,
imageUrl: imageUrl,
generateText: description,
tags: highlights.map((highlight: string, index: number) => ({
id: `tag_${Date.now()}_${index}`,
/** 名称 */
name: highlight,
/** 内容 */
content: highlight,
loadingProgress: 100,
disableEdit: false
}))
};
// 2. 调用图片分析接口获取描述
const result = await analyzeImageDescription({
image_url: imageUrl,
});
// 更新选中的角色
selectRole(updatedRole);
if (!result.successful) {
throw new Error(`图片分析失败: ${result.message}`);
}
// 更新角色列表中的对应角色
setRoleList(prev =>
prev.map(role =>
role.id === selectedRole.id
? updatedRole
: role
)
);
const { description, highlights } = result.data;
console.log('角色图片和描述更新成功:', updatedRole);
// 3. 更新当前选中角色的图片、描述和标签
const updatedRole = {
...selectedRole,
imageUrl: imageUrl,
generateText: description,
tags: highlights.map((highlight: string, index: number) => ({
id: `tag_${Date.now()}_${index}`,
/** 名称 */
name: highlight,
/** 内容 */
content: highlight,
loadingProgress: 100,
disableEdit: false,
})),
};
} catch (error) {
console.error('上传图片并分析失败:', error);
throw error;
}
}, [selectedRole, roleEditUseCase, selectRole]);
// 更新选中的角色
selectRole(updatedRole);
// 更新角色列表中的对应角色
setRoleList((prev) =>
prev.map((role) => (role.id === selectedRole.id ? updatedRole : role))
);
console.log("角色图片和描述更新成功:", updatedRole);
} catch (error) {
console.error("上传图片并分析失败:", error);
throw error;
}
},
[selectedRole, roleEditUseCase, selectRole]
);
/**
*
@ -393,15 +411,15 @@ export const useRoleServiceHook = (): UseRoleService => {
*/
const saveRoleToLibrary = useCallback(async () => {
if (!selectedRole) {
throw new Error('请先选择要保存的角色');
throw new Error("请先选择要保存的角色");
}
if (!roleEditUseCase) {
throw new Error('角色编辑UseCase未初始化');
throw new Error("角色编辑UseCase未初始化");
}
if (!projectId) {
throw new Error('缺少项目ID无法保存角色到角色库');
throw new Error("缺少项目ID无法保存角色到角色库");
}
try {
@ -409,7 +427,7 @@ export const useRoleServiceHook = (): UseRoleService => {
const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
if (!User.id) {
throw new Error('无法获取用户ID请重新登录');
throw new Error("无法获取用户ID请重新登录");
}
// 调用保存重新生成角色到角色库的方法
@ -418,11 +436,22 @@ export const useRoleServiceHook = (): UseRoleService => {
projectId,
String(User.id)
);
selectRole({
...selectedRole,
id: result.character_id,
fromDraft: true,
});
console.log('角色保存到角色库成功:', result);
SaveEditUseCase.setCharacterId([
...SaveEditUseCase.characterId,
{
character_id: result.character_id,
name: selectedRole.name,
},
]);
console.log("角色保存到角色库成功:", result);
} catch (error) {
console.error('保存角色到角色库失败:', error);
console.error("保存角色到角色库失败:", error);
throw error;
}
}, [selectedRole, roleEditUseCase, projectId]);
@ -435,21 +464,21 @@ export const useRoleServiceHook = (): UseRoleService => {
*/
const saveData = useCallback(async () => {
if (!projectId) {
throw new Error('缺少项目ID无法保存数据');
throw new Error("缺少项目ID无法保存数据");
}
try {
const result = await checkShotVideoStatus({
project_id: projectId
project_id: projectId,
});
if (!result.successful) {
throw new Error(`保存数据失败: ${result.message}`);
}
console.log('数据保存成功');
console.log("数据保存成功");
} catch (error) {
console.error('保存数据失败:', error);
console.error("保存数据失败:", error);
throw error;
}
}, [projectId]);
@ -472,6 +501,6 @@ export const useRoleServiceHook = (): UseRoleService => {
replaceRoleWithLibrary,
uploadImageAndUpdateRole,
saveRoleToLibrary,
saveData
saveData,
};
};

View File

@ -9,6 +9,7 @@ import {
import { VideoSegmentEntity } from "../domain/Entities";
import { LensType, SimpleCharacter } from "../domain/valueObject";
import { getUploadToken, uploadToQiniu } from "@/api/common";
import { SaveEditUseCase } from "../usecase/SaveEditUseCase";
/**
* Hook接口
@ -181,7 +182,13 @@ export const useShotService = (): UseShotService => {
// 保存任务ID用于后续状态查询
setGenerateTaskIds(prev => prev.add(taskResult.task_id));
SaveEditUseCase.setVideoTasks([
...SaveEditUseCase.videoTasks,
{
task_id: taskResult.task_id,
video_ids: [selectedSegment!.id],
},
]);
// 如果重新生成的是现有片段,更新其状态为处理中 (0: 视频加载中)
if (selectedSegment) {
setVideoSegments((prev) =>

View File

@ -0,0 +1,190 @@
import { modifyCharacterOrScene } from '@/api/video_flow';
/**
*
* @description
*/
export class SaveEditUseCase {
static projectId: string = '';
static characterId: {
/** 角色ID */
character_id: string;
/** 角色名称 */
name: string;
}[] = [];
static videoTasks: Array<{
task_id: string;
video_ids: string[];
}> = [];
/**
* ID
* @param projectId ID
*/
static setProjectId(projectId: string): void {
SaveEditUseCase.projectId = projectId;
}
/**
* ID
* @param characterId ID
*/
static setCharacterId(characterId: {
/** 角色ID */
character_id: string;
/** 角色名称 */
name: string;
}[]): void {
// 使用Set根据character_id去重
const seenIds = new Set<string>();
SaveEditUseCase.characterId = characterId.filter(character => {
if (seenIds.has(character.character_id)) {
return false;
}
seenIds.add(character.character_id);
return true;
});
}
/**
*
* @param videoTasks
*/
static setVideoTasks(videoTasks: Array<{
task_id: string;
video_ids: string[];
}>): void {
// 使用Set根据task_id去重
const seenIds = new Set<string>();
SaveEditUseCase.videoTasks = videoTasks.filter(task => {
if (seenIds.has(task.task_id)) {
return false;
}
seenIds.add(task.task_id);
return true;
});
}
/**
*
* @param taskId ID
* @param videoIds ID列表
*/
static addVideoTask(taskId: string, videoIds: string[]): void {
SaveEditUseCase.videoTasks.push({
task_id: taskId,
video_ids: videoIds,
});
}
/**
*
* @description
* @returns Promise<保存结果>
*/
static async saveData(): Promise<{
success: boolean;
message: string;
data?: any;
}> {
try {
if (!SaveEditUseCase.projectId) {
throw new Error('项目ID不能为空');
}
if (SaveEditUseCase.videoTasks.length === 0) {
throw new Error('视频任务列表不能为空');
}
const response = await modifyCharacterOrScene({
project_id: SaveEditUseCase.projectId,
character_id: SaveEditUseCase.characterId,
video_tasks: SaveEditUseCase.videoTasks,
});
if (!response.successful) {
throw new Error(response.message || '保存数据失败');
}
return {
success: true,
message: '数据保存成功',
data: response.data,
};
} catch (error) {
console.error('保存数据失败:', error);
return {
success: false,
message: error instanceof Error ? error.message : '保存数据失败',
};
}
}
/**
*
* @description character_id数据
* @returns Promise<保存结果>
*/
static async saveRoleData(): Promise<{
success: boolean;
message: string;
data?: any;
}> {
// 角色数据保存就是保存character_id
return SaveEditUseCase.saveData();
}
/**
*
* @description video_tasks数据
* @returns Promise<保存结果>
*/
static async saveShotData(): Promise<{
success: boolean;
message: string;
data?: any;
}> {
// 镜头数据保存就是保存video_tasks
return SaveEditUseCase.saveData();
}
/**
*
* @description
*/
static clearData(): void {
SaveEditUseCase.projectId = '';
SaveEditUseCase.characterId = [];
SaveEditUseCase.videoTasks = [];
}
/**
*
* @returns
*/
static getCurrentData(): {
projectId: string;
characterId: {
character_id: string;
name: string;
}[];
videoTasks: Array<{
task_id: string;
video_ids: string[];
}>;
} {
return {
projectId: SaveEditUseCase.projectId,
characterId: [...SaveEditUseCase.characterId],
videoTasks: [...SaveEditUseCase.videoTasks],
};
}
}
/**
*
* @returns {SaveEditUseCase}
*/
export const createSaveEditUseCase = (): SaveEditUseCase => {
return new SaveEditUseCase();
};

View File

@ -13,6 +13,8 @@ import { usePlaybackControls } from "./work-flow/use-playback-controls";
import { AlertCircle, RefreshCw, Pause, Play, ChevronLast } from "lucide-react";
import { motion } from "framer-motion";
import { GlassIconButton } from '@/components/ui/glass-icon-button';
import { SaveEditUseCase } from "@/app/service/usecase/SaveEditUseCase";
import { useSearchParams } from "next/navigation";
export default function WorkFlow() {
console.log('WorkFlow--0294877777777777')
@ -20,6 +22,10 @@ export default function WorkFlow() {
const [isEditModalOpen, setIsEditModalOpen] = React.useState(false);
const [activeEditTab, setActiveEditTab] = React.useState('1');
const searchParams = useSearchParams();
const episodeId = searchParams.get('episodeId') || '';
SaveEditUseCase.setProjectId(episodeId);
// 使用自定义 hooks 管理状态
const {
taskObject,
@ -64,7 +70,7 @@ export default function WorkFlow() {
// 跟踪是否已经自动开始播放过,避免重复触发
const hasAutoStartedRef = useRef(false);
// 跟踪循环播放的起始索引,用于判断是否完成一轮循环
const loopStartIndexRef = useRef<number | null>(null);
@ -136,13 +142,13 @@ export default function WorkFlow() {
</div>
</div>
<div className="media-Ocdu1O rounded-lg">
<div
className="videoContainer-qteKNi"
style={(currentStep !== '6' && currentStep !== '0') ? { flex: 3 } : {}}
<div
className="videoContainer-qteKNi"
style={(currentStep !== '6' && currentStep !== '0') ? { flex: 3 } : {}}
ref={containerRef}
>
{dataLoadError ? (
<motion.div
<motion.div
className="flex flex-col items-center justify-center w-full aspect-video rounded-lg bg-red-50 border-2 border-red-200"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
@ -157,11 +163,11 @@ export default function WorkFlow() {
<AlertCircle className="w-8 h-8 text-red-500" />
<h3 className="text-lg font-medium text-red-800"></h3>
</motion.div>
<p className="text-red-600 text-center mb-6 max-w-md px-4">
{dataLoadError}
</p>
<motion.button
className="flex items-center gap-2 px-6 py-3 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"
onClick={() => retryLoadData?.()}
@ -245,7 +251,7 @@ export default function WorkFlow() {
</div>
)
}
{/* AI 建议栏 */}
<ErrorBoundary>
@ -262,7 +268,10 @@ export default function WorkFlow() {
<EditModal
isOpen={isEditModalOpen}
activeEditTab={activeEditTab}
onClose={() => setIsEditModalOpen(false)}
onClose={() => {
SaveEditUseCase.clearData();
setIsEditModalOpen(false)
}}
taskStatus={taskObject?.taskStatus || '1'}
taskSketch={taskSketch}
sketchVideo={taskVideos}
@ -280,4 +289,4 @@ export default function WorkFlow() {
</div>
</ErrorBoundary>
)
}
}

View File

@ -109,7 +109,6 @@ const [pendingSwitchTabId, setPendingSwitchTabId] = useState<string | null>(null
if (disabled) return;
// 切换前 检查是否更新
const isUpdate = checkUpdate(activeTab);
console.log('contentEditableRef---isUpdate', isUpdate);
if (isUpdate) {
setPendingSwitchTabId(tabId); // 记录要切换到的目标tab
setRemindFallbackText('You must click Apply button to save the current changes.');