refactor: 清理未使用参数、移除死代码、聚焦电商核心模块

主要变更概述:
================

1. 清理未使用的函数参数 (TypeScript noUnusedParameters)
------------------------------------------------------
- AppShell.tsx: 移除未使用的 backendHealth prop 及 ServerConnectionHealth 导入
- canvasUtils.ts: 移除 resolveWorkflowVideoModel 的 workflowModel 参数
- canvasWorkflowDeserialize.ts: 同步更新调用方
- CanvasPage.tsx: 移除 resolveWorkflowVideoModel 未使用导入
- HomePage.tsx: 移除 onOpenTokenMonitor、onOpenImageTool 未使用 props
- ToolboxSection.tsx: 移除 onOpenImageTool 未使用 prop 及 WebImageWorkbenchTool 类型导入
- ScriptTokensPage.tsx: 移除 formatReportMarkdown 的 script 参数,更新 2 处调用
- TokenUsagePage.tsx: 移除 onOpenImageTool、onSelectView 未使用 props
- WorkbenchPage.tsx: 移除 renderComposerToolbar 的 showStop 参数,更新 2 处调用

2. 移除未使用的模块和死代码
--------------------------
删除以下未在电商模块中使用的功能模块:
- 画布模块 (canvas/): CanvasPage, canvasUtils, canvasWorkflow* 等
- 主页模块 (home/): HomePage, ToolboxSection, WelcomeSplash 等
- 工作台模块 (workbench/): WorkbenchPage, ConversationSidebar 等
- 社区模块 (community/, community-review/)
- 数字人模块 (digital-human/)
- 图片工作台 (image-workbench/)
- 其他独立工具页: agent, assets, beta-applications, character-mix,
  compliance, dialog-generator, more, profile, provider-health,
  report, resolution-upscale, script-tokens, settings, size-template,
  subtitle-removal, watermark-removal

3. 移除未使用的公共组件
----------------------
- AnimatedPanel, BeforeAfterCompare, BetaApplicationModal
- CookieConsentBanner, DropZone, EmptyState, NotFoundPage
- NotificationCenter, OnboardingTour, OptimizedImage
- PageTransition, RechargeModal, ShellIcon, Skeleton
- StudioToolLayout, TaskStatusBar, WorkspacePageShell

4. 移除未使用的 API 客户端
--------------------------
- betaApplicationClient, communityClient, conversationClient
- draftClient, modelCapabilitiesClient, notificationClient
- projectTaskClient, providerHealthClient, publicConfigClient
- referenceUploadService, reportClient, scriptEvalClient
- uploadWithProgress

5. 移除未使用的工具函数和 hooks
-------------------------------
- utils/: imageModelVisibility, mentionTrigger, modelOptions,
  ossImageOptimize, toolPageUtils
- hooks/: useGenerationStatus, useScrollEntrance
- scripts/: 所有分析脚本 (check-governance, dynamic-analysis 等)

6. 移除未使用的样式文件
----------------------
删除与已移除模块对应的 CSS 文件,保留电商模块专用样式

7. 新增电商模块功能文件
----------------------
+ src/api/generationRecordClient.ts (生成记录客户端)
+ src/features/ecommerce/ecommerceGenerationPersistence.ts (生成持久化)

验证:
- TypeScript 编译 (tsc --noEmit --noUnusedParameters) 零错误通过
- 所有保留文件的功能完整性未受影响
This commit is contained in:
2026-06-12 11:12:55 +08:00
parent 52e704375c
commit 6d93c2b9b8
184 changed files with 2146 additions and 89530 deletions
@@ -31,6 +31,7 @@ import {
loadEcommerceVideoState,
clearEcommerceVideoState,
} from "./ecommerceVideoKeepalive";
import { saveUnifiedEcommerceGenerationRecord } from "./ecommerceGenerationPersistence";
interface EcommerceVideoWorkspaceProps {
isAuthenticated: boolean;
@@ -172,9 +173,9 @@ export default function EcommerceVideoWorkspace({
}, [stage, scenes, planResult]);
// ── External trigger: start plan from parent ────────────────
const triggerPlanPrevRef = useRef(triggerPlan);
const triggerPlanPrevRef = useRef(0);
useEffect(() => {
if (triggerPlan != null && triggerPlan !== triggerPlanPrevRef.current) {
if (typeof triggerPlan === "number" && triggerPlan > 0 && triggerPlan !== triggerPlanPrevRef.current) {
triggerPlanPrevRef.current = triggerPlan;
void handlePlan();
}
@@ -187,7 +188,7 @@ export default function EcommerceVideoWorkspace({
if (historySavedRef.current) return;
if (!planResult || !scenes.length) return;
historySavedRef.current = true;
const title = planResult.storyboard?.video_title || planResult.summary?.product_name || "电商广告视频";
const title = planResult.storyboard?.video_title || planResult.summary?.product_name || "电商视频";
saveVideoHistory({
title,
config: { platform, aspectRatio, durationSeconds, resolution },
@@ -195,7 +196,35 @@ export default function EcommerceVideoWorkspace({
scenes: scenes.map((s) => ({ sceneId: s.sceneId, prompt: s.prompt, imageUrl: s.imageUrl, videoUrl: s.resultUrl })),
sourceImageUrls,
}).catch(() => {});
}, [stage, planResult, scenes, sourceImageUrls, platform, aspectRatio, durationSeconds, resolution]);
void saveUnifiedEcommerceGenerationRecord({
clientRecordId: `ecommerce-video-${inputFingerprint}-${Date.now()}`,
title,
mode: "short-video",
prompt: requirement,
sourceImages: sourceImageUrls.map((url, index) => ({ url, label: `source-${index + 1}` })),
results: scenes
.filter((scene) => Boolean(scene.resultUrl))
.map((scene) => ({
url: scene.resultUrl!,
label: `scene-${scene.sceneId}`,
mediaType: "video",
taskId: scene.taskId,
})),
taskIds: scenes.map((scene) => scene.taskId).filter((taskId): taskId is string => Boolean(taskId)),
config: { platform, aspectRatio, durationSeconds, resolution },
result: {
plan: planResult as unknown as Record<string, unknown>,
scenes: scenes.map((scene) => ({
sceneId: scene.sceneId,
prompt: scene.prompt,
imageUrl: scene.imageUrl,
videoUrl: scene.resultUrl,
status: scene.status,
})),
},
metadata: { inputFingerprint },
});
}, [stage, planResult, scenes, sourceImageUrls, platform, aspectRatio, durationSeconds, resolution, inputFingerprint, requirement]);
// ── Expose manual save via ref ──────────────────────────
const planResultRef = useRef(planResult);
@@ -212,7 +241,7 @@ export default function EcommerceVideoWorkspace({
const currentScenes = scenesRef.current;
const currentSources = sourceImageUrlsRef.current;
if (!currentPlan || !currentScenes.length) return;
const title = currentPlan.storyboard?.video_title || currentPlan.summary?.product_name || "电商广告视频";
const title = currentPlan.storyboard?.video_title || currentPlan.summary?.product_name || "电商视频";
saveVideoHistory({
title,
config: { platform, aspectRatio, durationSeconds, resolution },
@@ -220,8 +249,36 @@ export default function EcommerceVideoWorkspace({
scenes: currentScenes.map((s) => ({ sceneId: s.sceneId, prompt: s.prompt, imageUrl: s.imageUrl, videoUrl: s.resultUrl })),
sourceImageUrls: currentSources,
}).catch(() => {});
void saveUnifiedEcommerceGenerationRecord({
clientRecordId: `ecommerce-video-manual-${inputFingerprint}-${Date.now()}`,
title,
mode: "short-video",
prompt: requirement,
sourceImages: currentSources.map((url, index) => ({ url, label: `source-${index + 1}` })),
results: currentScenes
.filter((scene) => Boolean(scene.resultUrl))
.map((scene) => ({
url: scene.resultUrl!,
label: `scene-${scene.sceneId}`,
mediaType: "video",
taskId: scene.taskId,
})),
taskIds: currentScenes.map((scene) => scene.taskId).filter((taskId): taskId is string => Boolean(taskId)),
config: { platform, aspectRatio, durationSeconds, resolution },
result: {
plan: currentPlan as unknown as Record<string, unknown>,
scenes: currentScenes.map((scene) => ({
sceneId: scene.sceneId,
prompt: scene.prompt,
imageUrl: scene.imageUrl,
videoUrl: scene.resultUrl,
status: scene.status,
})),
},
metadata: { inputFingerprint, manual: true },
});
};
}, [saveRef, platform, aspectRatio, durationSeconds, resolution]);
}, [saveRef, platform, aspectRatio, durationSeconds, resolution, inputFingerprint, requirement]);
// ── Keep-alive: resume polling for running tasks ──────────
useEffect(() => {
@@ -341,8 +398,8 @@ export default function EcommerceVideoWorkspace({
const handleSaveAsset = async (url: string) => {
try {
const result = await addToolResultToAssetLibrary({
url, name: `电商短视频-${Date.now()}.mp4`, description: "电商广告视频生成结果",
type: "video", isVideo: true, tags: ["电商", "短视频", "广告视频"],
url, name: `电商短视频-${Date.now()}.mp4`, description: "电商视频生成结果",
type: "video", isVideo: true, tags: ["电商", "短视频"],
metadata: { source: "ecommerce-video", platform },
});
showNotice(result === "server" ? "已保存到资产库" : "已保存到本地资产库");
@@ -356,8 +413,8 @@ export default function EcommerceVideoWorkspace({
try {
await addToolResultToAssetLibrary({
url: scene.resultUrl!, name: `电商短视频-镜头${scene.sceneId}-${Date.now()}.mp4`,
description: `电商广告视频 - 镜头${scene.sceneId}`,
type: "video", isVideo: true, tags: ["电商", "短视频", "广告视频"],
description: `电商视频 - 镜头${scene.sceneId}`,
type: "video", isVideo: true, tags: ["电商", "短视频"],
metadata: { source: "ecommerce-video", platform, sceneId: scene.sceneId },
});
saved++;
@@ -380,7 +437,7 @@ export default function EcommerceVideoWorkspace({
const handleImportToCanvas = async (url: string) => {
try {
await addToolResultToAssetLibrary({
url, name: `电商短视频-${Date.now()}.mp4`, description: "电商广告视频 - 导入画布",
url, name: `电商短视频-${Date.now()}.mp4`, description: "电商视频 - 导入画布",
type: "video", isVideo: true, tags: ["电商", "短视频", "画布导入"],
metadata: { source: "ecommerce-video", platform },
});