优化 ScriptService 和 ShotService,移除调试信息,更新接口以支持新功能,重构代码以提高可读性。

This commit is contained in:
海龙 2025-08-08 14:08:33 +08:00
parent 817c5d5144
commit 1ef7d03830
6 changed files with 93 additions and 60 deletions

View File

@ -99,7 +99,6 @@ export interface UseScriptService {
*
*/
export const useScriptService = (): UseScriptService => {
console.log('useScriptService----9((@@@@@@@@@@@@@@@@@@');
// 响应式状态
const [loading, setLoading] = useState<boolean>(false);
const [synopsis, setSynopsis] = useState<string>("");
@ -215,7 +214,6 @@ export const useScriptService = (): UseScriptService => {
// 获取解析后的故事详情
const storyDetails = newScriptEditUseCase.getStoryDetails();
setSynopsis(storyDetails.synopsis || "");
setCategories(storyDetails.categories || []);
setProtagonist(storyDetails.protagonist || "");
@ -231,7 +229,7 @@ export const useScriptService = (): UseScriptService => {
setLoading(false);
}
},
[projectId, scriptEditUseCase]
[generateScriptFromIdea]
);
/**
@ -392,7 +390,6 @@ export const useScriptService = (): UseScriptService => {
const setAnyAttributeWrapper = useCallback(
(type: string, value: SetStateAction<string>, tags?: string[]) => {
console.log('setAnyAttributeWrapper', type);
if (type === 'synopsis') {
setFieldOld(synopsis)
scriptEditUseCase.replaceScript(fieldOld,synopsis)
@ -492,8 +489,7 @@ export const useScriptService = (): UseScriptService => {
];
// 筛选出有内容的block
const filteredArr = arr.filter(item => (item.content.length > 0 && item.content[0].text !== ''));
console.log('scriptBlocksMemo 所有关联数据', synopsis, categories, protagonist, incitingIncident, problem, conflict, stakes, characterArc);
console.log('scriptBlocksMemo', filteredArr);
console.log('scriptBlocksMemo', JSON.parse(JSON.stringify(filteredArr)));
return filteredArr;
}, [
synopsis,

View File

@ -1,7 +1,7 @@
import { useState, useCallback } from "react";
import { VideoSegmentEditUseCase } from "../usecase/ShotEditUsecase";
import { VideoSegmentEntity } from "../domain/Entities";
import { ContentItem, LensType } from "../domain/valueObject";
import { LensType } from "../domain/valueObject";
/**
* Hook接口
@ -15,8 +15,6 @@ export interface UseShotService {
videoSegments: VideoSegmentEntity[];
/** 当前选中的视频片段 */
selectedSegment: VideoSegmentEntity | null;
/** 错误信息 */
error: string | null;
// 操作方法
/** 获取视频片段列表 */
@ -38,8 +36,10 @@ export interface UseShotService {
abortOperation: () => void;
/** 设置选中的视频片段 */
setSelectedSegment: (segment: VideoSegmentEntity | null) => void;
/** 清除错误信息 */
clearError: () => void;
/** 添加新镜头到选中的视频片段 */
addNewLens: () => void;
/** 删除指定镜头 */
deleteLens: (lensName: string) => void;
}
/**
@ -52,10 +52,9 @@ export const useShotService = (): UseShotService => {
const [loading, setLoading] = useState<boolean>(false);
const [videoSegments, setVideoSegments] = useState<VideoSegmentEntity[]>([]);
const [selectedSegment, setSelectedSegment] = useState<VideoSegmentEntity | null>(null);
const [error, setError] = useState<string | null>(null);
// UseCase实例
const [shotEditUseCase] = useState<VideoSegmentEditUseCase>(
const [vidoEditUseCase] = useState<VideoSegmentEditUseCase>(
new VideoSegmentEditUseCase()
);
@ -67,19 +66,16 @@ export const useShotService = (): UseShotService => {
async (projectId: string): Promise<void> => {
try {
setLoading(true);
setError(null);
const segments = await shotEditUseCase.getVideoSegmentList(projectId);
const segments = await vidoEditUseCase.getVideoSegmentList(projectId);
setVideoSegments(segments);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "获取视频片段列表失败";
setError(errorMessage);
console.error("获取视频片段列表失败:", error);
} finally {
setLoading(false);
}
},
[shotEditUseCase]
[vidoEditUseCase]
);
/**
@ -99,9 +95,8 @@ export const useShotService = (): UseShotService => {
): Promise<VideoSegmentEntity> => {
try {
setLoading(true);
setError(null);
const regeneratedSegment = await shotEditUseCase.regenerateVideoSegment(
const regeneratedSegment = await vidoEditUseCase.regenerateVideoSegment(
shotPrompt,
shotId,
roleReplaceParams,
@ -122,15 +117,13 @@ export const useShotService = (): UseShotService => {
return regeneratedSegment;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "重新生成视频片段失败";
setError(errorMessage);
console.error("重新生成视频片段失败:", error);
throw error;
} finally {
setLoading(false);
}
},
[shotEditUseCase]
[vidoEditUseCase]
);
/**
@ -148,9 +141,8 @@ export const useShotService = (): UseShotService => {
): Promise<LensType[]> => {
try {
setLoading(true);
setError(null);
const optimizedLensData = await shotEditUseCase.optimizeVideoContent(
const optimizedLensData = await vidoEditUseCase.optimizeVideoContent(
shotId,
userRequirement,
lensData
@ -161,23 +153,21 @@ export const useShotService = (): UseShotService => {
return optimizedLensData;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "AI优化视频内容失败";
setError(errorMessage);
console.error("AI优化视频内容失败:", error);
throw error;
} finally {
setLoading(false);
}
},
[shotEditUseCase]
[vidoEditUseCase]
);
/**
*
*/
const abortOperation = useCallback((): void => {
shotEditUseCase.abortOperation();
vidoEditUseCase.abortOperation();
setLoading(false);
}, [shotEditUseCase]);
}, [vidoEditUseCase]);
/**
*
@ -187,24 +177,85 @@ export const useShotService = (): UseShotService => {
}, []);
/**
*
*
* @description selectedSegment的lens数组中添加一个新的空镜头
*/
const clearError = useCallback((): void => {
setError(null);
}, []);
const addNewLens = useCallback((): void => {
if (!selectedSegment) {
console.warn("没有选中的视频片段,无法添加镜头");
return;
}
// 计算下一个镜头编号
const currentLensCount = selectedSegment.lens.length;
const newLensName = `镜头${currentLensCount + 1}`;
// 创建新的空镜头
const newLens = new LensType(newLensName, "", []);
// 创建更新后的片段
const updatedSegment: VideoSegmentEntity = {
...selectedSegment,
lens: [...selectedSegment.lens, newLens]
};
// 批量更新状态,避免多次重渲染
setSelectedSegment(updatedSegment);
setVideoSegments(prev => {
const segmentIndex = prev.findIndex(segment => segment.id === selectedSegment.id);
if (segmentIndex === -1) return prev;
const newSegments = [...prev];
newSegments[segmentIndex] = updatedSegment;
return newSegments;
});
}, [selectedSegment]);
/**
*
* @param lensName
*/
const deleteLens = useCallback((lensName: string): void => {
if (!selectedSegment) {
console.warn("没有选中的视频片段,无法删除镜头");
return;
}
// 过滤掉指定名称的镜头并重新排序
const updatedLens = selectedSegment.lens
.filter(lens => lens.name !== lensName)
.map((lens, index) => new LensType(`镜头${index + 1}`, lens.script, lens.content));
// 创建更新后的片段
const updatedSegment: VideoSegmentEntity = {
...selectedSegment,
lens: updatedLens
};
// 批量更新状态,避免多次重渲染
setSelectedSegment(updatedSegment);
setVideoSegments(prev => {
const segmentIndex = prev.findIndex(segment => segment.id === selectedSegment.id);
if (segmentIndex === -1) return prev;
const newSegments = [...prev];
newSegments[segmentIndex] = updatedSegment;
return newSegments;
});
}, [selectedSegment]);
return {
// 响应式状态
loading,
videoSegments,
selectedSegment,
error,
// 操作方法
getVideoSegmentList,
regenerateVideoSegment,
optimizeVideoContent,
abortOperation,
setSelectedSegment: setSelectedSegmentHandler,
clearError,
addNewLens,
deleteLens,
};
};

View File

@ -115,7 +115,9 @@ export class StoryDetails {
* @param text
*/
updateScript(text: string) {
console.log('text.length', text.length)
const scriptObject = this.createFromText(text);
console.log('scriptObject', scriptObject)
this.setProperties(scriptObject);
return scriptObject;
}

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
import { useVideoSegmentService } from '../Interaction/ShotService';
describe('VideoSegmentService 测试', () => {
it('初始化服务实例', () => {
const videoSegmentService = useVideoSegmentService();
expect(videoSegmentService).toBeDefined();
});
it('获取视频片段列表', () => {
const videoSegmentService = useVideoSegmentService();
expect(typeof videoSegmentService.fetchVideoSegmentList).toBe('function');
});
});

View File

@ -150,7 +150,7 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
onChange={handleBlockTextChange(block)}
onBlur={handleBlockTextBlur(block)}
autoFocus={true}
className="block w-full min-h-[120px] bg-white/5 backdrop-blur-md p-4 text-white/90
className="block w-full min-h-[120px] bg-white/5 backdrop-blur-md p-4 text-white/90
rounded-lg border-unset outline-none pb-12
whitespace-pre-wrap break-words"
placeholder=""
@ -166,7 +166,7 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
{addThemeTag.map((item, index) => (
<div key={index} className={`flex items-center gap-1 px-2 rounded-full ${Object.values(ThemeTagBgColor)[index]}`}>
<span className={`text-sm px-2 py-1 rounded-md`}>{item}</span>
<X className="w-4 h-4 cursor-pointer text-blue-500/80" onClick={() =>
<X className="w-4 h-4 cursor-pointer text-blue-500/80" onClick={() =>
handleThemeTagChange(addThemeTag.filter(v => v !== item))
} />
</div>
@ -234,11 +234,11 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
const isHovered = hoveredBlockId === block.id;
const isActive = activeBlockId === block.id;
const isEditing = editBlockId === block.id;
console.log('block', block)
return (
<motion.div
key={block.id}
className={`relative p-4 mb-1 rounded-lg shadow-md transition-colors duration-300
className={`relative p-4 mb-1 rounded-lg shadow-md transition-colors duration-300
${isActive ? 'bg-slate-700/50' : ''} hover:bg-slate-700/30`}
ref={(el) => (contentRefs.current[block.id] = el)}
onMouseEnter={() => setHoveredBlockId(block.id)}
@ -303,4 +303,4 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
</div>
</div>
);
};
};