fix(video-canvas): repair audited controls and document remaining validation gaps
This commit is contained in:
parent
f10e6b7c8d
commit
23f86dfce1
@ -15613,28 +15613,40 @@ function MultiAngleEditorDialog({
|
||||
<div className="absolute h-[308px] w-px bg-white/16" />
|
||||
<button
|
||||
className="absolute top-10 text-[32px] text-white/42"
|
||||
onClick={() => setVerticalAngle((value) => Math.min(90, value + 5))}
|
||||
onClick={() => {
|
||||
setActiveTab("自定义");
|
||||
setVerticalAngle((value) => Math.min(90, value + 5));
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
⌃
|
||||
</button>
|
||||
<button
|
||||
className="absolute bottom-9 text-[32px] text-white/42"
|
||||
onClick={() => setVerticalAngle((value) => Math.max(-30, value - 5))}
|
||||
onClick={() => {
|
||||
setActiveTab("自定义");
|
||||
setVerticalAngle((value) => Math.max(-30, value - 5));
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
⌄
|
||||
</button>
|
||||
<button
|
||||
className="absolute left-10 text-[42px] text-white/42"
|
||||
onClick={() => setHorizontalAngle((value) => Math.max(-180, value - 10))}
|
||||
onClick={() => {
|
||||
setActiveTab("自定义");
|
||||
setHorizontalAngle((value) => Math.max(-180, value - 10));
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
‹
|
||||
</button>
|
||||
<button
|
||||
className="absolute right-10 text-[42px] text-white/42"
|
||||
onClick={() => setHorizontalAngle((value) => Math.min(180, value + 10))}
|
||||
onClick={() => {
|
||||
setActiveTab("自定义");
|
||||
setHorizontalAngle((value) => Math.min(180, value + 10));
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
›
|
||||
@ -23774,6 +23786,7 @@ function CanvasAssetManagerPanel({
|
||||
const [activeTab, setActiveTab] = useState<"canvas" | "assets">("canvas");
|
||||
const [assetFilterOpen, setAssetFilterOpen] = useState(false);
|
||||
const [assetSearchQuery, setAssetSearchQuery] = useState("");
|
||||
const [assetTypeFilter, setAssetTypeFilter] = useState("全部");
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const [editingNodeId, setEditingNodeId] = useState<string | null>(null);
|
||||
const [menuNodeId, setMenuNodeId] = useState<string | null>(null);
|
||||
@ -23920,7 +23933,8 @@ function CanvasAssetManagerPanel({
|
||||
<div className="flex min-w-0 items-center gap-0.5">
|
||||
<span className="text-[13px] font-medium leading-normal text-[#919191]">画布元素</span>
|
||||
<button
|
||||
aria-label={collapsed ? "展开全部分组" : "收起全部分组"}
|
||||
aria-label={collapsed ? "展开节点列表" : "收起节点列表"}
|
||||
aria-expanded={!collapsed}
|
||||
className="flex h-7 w-7 items-center justify-center rounded-lg text-white/85 hover:bg-white/10"
|
||||
onClick={() => setCollapsed((value) => !value)}
|
||||
type="button"
|
||||
@ -23982,7 +23996,7 @@ function CanvasAssetManagerPanel({
|
||||
</div>
|
||||
|
||||
<div className="min-h-0 flex-1 overflow-y-auto px-2 py-2">
|
||||
{visibleNodes.length === 0 ? (
|
||||
{collapsed ? null : visibleNodes.length === 0 ? (
|
||||
<div className="mt-2 rounded-lg px-3 py-5 text-center text-[13px] text-white/36">暂无匹配节点</div>
|
||||
) : (
|
||||
<div className="grid gap-0.5">
|
||||
@ -24074,9 +24088,9 @@ function CanvasAssetManagerPanel({
|
||||
) : (
|
||||
<div className="flex min-h-0 flex-1 flex-col gap-3 px-3 py-3">
|
||||
<input aria-label="搜索当前素材" className="rounded-lg bg-white/10 p-2 text-sm" placeholder="搜索当前画布素材" value={assetSearchQuery} onChange={e=>setAssetSearchQuery(e.target.value)}/>
|
||||
<select aria-label="素材类型" className="rounded bg-[#222] p-2 text-sm" value={filter} onChange={e=>setFilter(e.target.value)}>{["全部","图片","视频","音频"].map(type=><option key={type}>{type}</option>)}</select>
|
||||
<select aria-label="素材类型" className="rounded bg-[#222] p-2 text-sm" value={assetTypeFilter} onChange={e=>setAssetTypeFilter(e.target.value)}>{["全部","图片","视频","音频"].map(type=><option key={type}>{type}</option>)}</select>
|
||||
<p className="text-xs text-white/40">当前画布中已有文件的素材,可定位或下载。</p>
|
||||
<div className="min-h-0 flex-1 space-y-3 overflow-auto">{nodes.filter(node=>Boolean(getNodeMediaUrl(node)) && (!assetSearchQuery.trim() || node.title.toLowerCase().includes(assetSearchQuery.trim().toLowerCase())) && (filter === "全部" || node.inputType === ({图片:"image",视频:"video",音频:"audio"} as Record<string,string>)[filter])).map(node=><article key={node.id} className="rounded-lg border border-white/10 p-2">
|
||||
<div className="min-h-0 flex-1 space-y-3 overflow-auto">{nodes.filter(node=>Boolean(getNodeMediaUrl(node)) && (!assetSearchQuery.trim() || node.title.toLowerCase().includes(assetSearchQuery.trim().toLowerCase())) && (assetTypeFilter === "全部" || node.inputType === ({图片:"image",视频:"video",音频:"audio"} as Record<string,string>)[assetTypeFilter])).map(node=><article key={node.id} className="rounded-lg border border-white/10 p-2">
|
||||
{node.inputType === "image" ? <img alt={node.title} src={getNodeMediaUrl(node)} className="h-24 w-full object-contain"/> : <p className="py-4 text-center text-xs text-white/50">{node.inputType === "video" ? "视频" : "音频"}</p>}
|
||||
<p className="truncate py-2 text-xs">{node.title}</p><div className="flex gap-2 text-xs"><button className="rounded bg-white/10 px-2 py-1" onClick={()=>onSelectNode(node.id)}>定位</button><button className="rounded bg-white/10 px-2 py-1" onClick={()=>void downloadCanvasMedia([{url:getNodeMediaUrl(node),name:node.title}]).catch(e=>toast.error(e.message))}>下载</button></div>
|
||||
</article>)}</div>
|
||||
|
||||
823
docs/video-canvas-control-scan-2026-09-17.json
Normal file
823
docs/video-canvas-control-scan-2026-09-17.json
Normal file
@ -0,0 +1,823 @@
|
||||
{
|
||||
"file": "components/canvas/LiblibVideoCanvasReplica.tsx",
|
||||
"root": "LiblibVideoCanvasReplica",
|
||||
"method": "Conservative identifier reachability; candidates need manual review, not runtime coverage.",
|
||||
"reachableDeclarations": [
|
||||
"LiblibVideoCanvasReplica",
|
||||
"createConfiguredToolCatalog",
|
||||
"functionRequiresMedia",
|
||||
"getConfiguredToolType",
|
||||
"getCanvasModelRef",
|
||||
"resolveSiteName",
|
||||
"DEFAULT_SITE_NAME",
|
||||
"DEFAULT_VIEWPORT",
|
||||
"ASSET_MANAGER_DEFAULT_WIDTH",
|
||||
"VIDEO_ROLE_AGREEMENT_STORAGE_KEY",
|
||||
"isVideoMediaNode",
|
||||
"getDraftString",
|
||||
"getNodeMediaUrl",
|
||||
"normalizeCanvasTitle",
|
||||
"restoreNodes",
|
||||
"normalizeRestoredNode",
|
||||
"isCharacterThreeViewNode",
|
||||
"getNodeFunctionKey",
|
||||
"getNodeParams",
|
||||
"CHARACTER_THREE_VIEW_FUNCTION_KEY",
|
||||
"isCharacterThreeViewOption",
|
||||
"getOfficialImagePresetFunctionKey",
|
||||
"STORY_BEAT_GRID_FUNCTION_KEY",
|
||||
"CONTINUOUS_STORYBOARD_GRID_FUNCTION_KEY",
|
||||
"CINEMATIC_LIGHTING_CORRECTION_FUNCTION_KEY",
|
||||
"FRAME_PREDICTION_PLUS_3S_FUNCTION_KEY",
|
||||
"FRAME_PREDICTION_MINUS_5S_FUNCTION_KEY",
|
||||
"MULTI_VIEW_NINE_GRID_FUNCTION_KEY",
|
||||
"getPresetMode",
|
||||
"normalizeTextResourceNode",
|
||||
"extractTrailingNumber",
|
||||
"OFFICIAL_TEXT_RESOURCE_WIDTH",
|
||||
"OFFICIAL_TEXT_RESOURCE_HEIGHT",
|
||||
"OFFICIAL_NINE_GRID_WIDTH",
|
||||
"OFFICIAL_NINE_GRID_HEIGHT",
|
||||
"getDefaultFunctionPrompt",
|
||||
"resolveOfficialImagePresetFunctionKey",
|
||||
"getPresetGridLayout",
|
||||
"getDraftNumber",
|
||||
"getTargetModuleKind",
|
||||
"inferLegacyTargetModuleKind",
|
||||
"normalizeTargetModuleNode",
|
||||
"createTargetModuleNode",
|
||||
"makeId",
|
||||
"shouldResetTargetModuleTitle",
|
||||
"restoreEdges",
|
||||
"clampCanvasZoom",
|
||||
"CANVAS_MAX_ZOOM",
|
||||
"CANVAS_MIN_ZOOM",
|
||||
"serializeNodes",
|
||||
"serializeEdges",
|
||||
"createMediaResourceNode",
|
||||
"DIRECTOR_CAMERA_SNAPSHOT_NODE_OFFSET_X",
|
||||
"createToolboxTemplateGroupNode",
|
||||
"TOOLBOX_TEMPLATE_GROUP_FRAME",
|
||||
"FIRST_FRAME_IMAGE_URL",
|
||||
"createTextResourceNode",
|
||||
"SCRIPT_VIDEO_REFERENCE_URL",
|
||||
"TOOLBOX_TEMPLATE_VIEWPORT",
|
||||
"createToolNode",
|
||||
"getToolType",
|
||||
"TOOL_TYPE_META",
|
||||
"getToolLabel",
|
||||
"getToolFunctionKey",
|
||||
"getConfiguredFunction",
|
||||
"getToolRoute",
|
||||
"resolveNodeReferenceImages",
|
||||
"getNodeReferenceMediaUrl",
|
||||
"getNodeGridSplitState",
|
||||
"normalizeGridSplitState",
|
||||
"createEqualGridRects",
|
||||
"normalizeGridRect",
|
||||
"getNodeGridSplitSourceUrl",
|
||||
"getNodeSourceMediaUrl",
|
||||
"createGridSplitReferenceAsset",
|
||||
"cropRectToBlobUrlSource",
|
||||
"loadCanvasImage",
|
||||
"requiresMedia",
|
||||
"getToolRules",
|
||||
"composeFunctionPrompt",
|
||||
"getFunctionModel",
|
||||
"normalizeModelRef",
|
||||
"normalizeVideoGenerationMode",
|
||||
"selectVideoReferenceImages",
|
||||
"isWideImageGenerationFunction",
|
||||
"composeMultiViewNineGridPrompt",
|
||||
"composeConfiguredImagePresetPrompt",
|
||||
"isOfficialImagePresetFunctionKey",
|
||||
"isPresetGridFunction",
|
||||
"getImageGenerationBillingFeature",
|
||||
"getFirstGeneratedImageUrl",
|
||||
"getGridCellVisual",
|
||||
"NINE_GRID_CELL_VISUALS",
|
||||
"getToolReferenceModuleTemplates",
|
||||
"getToolReferenceMediaSpec",
|
||||
"AUDIO_SOURCE_URL",
|
||||
"CHARACTER_IMAGE_URL",
|
||||
"VIDEO_FIRST_FRAME_SOURCE_URL",
|
||||
"VIDEO_FIRST_LAST_FIRST_URL",
|
||||
"VIDEO_FIRST_LAST_LAST_URL",
|
||||
"AUDIO_REFERENCE_IMAGE_URL",
|
||||
"HD_IMAGE_SOURCE_URL",
|
||||
"OFFICIAL_NODE_GAP",
|
||||
"createUploadedMediaNode",
|
||||
"MATERIAL_STYLE_SCREEN_ANCHOR",
|
||||
"createMaterialStyleNode",
|
||||
"MATERIAL_STYLE_NODE_SIZE",
|
||||
"STYLE_MARKET_THUMBNAIL_URL",
|
||||
"isVideoEffectMaterialNode",
|
||||
"createMaterialEffectNode",
|
||||
"isVideoRoleMaterialNode",
|
||||
"createMaterialRoleNode",
|
||||
"ROLE_LIBRARY_NODE_LAYOUT",
|
||||
"ROLE_LIBRARY_APPLY_VIEWPORT",
|
||||
"TEXT_TO_VIDEO_PROMPT",
|
||||
"TEXT_TO_VIDEO_GENERATE_PROMPT",
|
||||
"IMAGE_TO_PROMPT_PROMPT",
|
||||
"TEXT_TO_MUSIC_PROMPT",
|
||||
"AUDIO_TO_VIDEO_PROMPT",
|
||||
"VIDEO_FIRST_FRAME_PROMPT",
|
||||
"VIDEO_FIRST_LAST_PROMPT",
|
||||
"STORY_SCRIPT_TEXT",
|
||||
"SCRIPT_CHARACTER_PROMPT",
|
||||
"SCRIPT_CHARACTER_ONE_URL",
|
||||
"SCRIPT_CHARACTER_TWO_URL",
|
||||
"getNodeLocalEditRegions",
|
||||
"LOCAL_EDIT_MAX_REGIONS",
|
||||
"normalizeLocalEditRegion",
|
||||
"LOCAL_EDIT_COLORS",
|
||||
"normalizeGridOption",
|
||||
"clearGridSplitDraftValues",
|
||||
"createNineGridCompositeNode",
|
||||
"withReindexedLocalEditRegions",
|
||||
"LOCAL_EDIT_MAX_POLL_ATTEMPTS",
|
||||
"wait",
|
||||
"ensureRemoteCanvasImageUrl",
|
||||
"getGridSplitCellLabel",
|
||||
"normalizeVideoDurationValue",
|
||||
"getVideoCanvasMagicMarks",
|
||||
"normalizeVideoCanvasMagicMarks",
|
||||
"getVideoFunctionKeyForMode",
|
||||
"normalizeVideoRatioValue",
|
||||
"normalizeVideoResolutionValue",
|
||||
"formatVideoRatioLabel",
|
||||
"formatVideoResolutionLabel",
|
||||
"formatVideoDurationLabel",
|
||||
"STORY_SCRIPT_PROMPT",
|
||||
"getStoryScriptRows",
|
||||
"normalizeStoryScriptRow",
|
||||
"formatStoryShot",
|
||||
"buildStoryVideoPrompt",
|
||||
"normalizeVideoClipRange",
|
||||
"normalizeVideoHdResolutionOption",
|
||||
"createVideoHdUpscaleNode",
|
||||
"VIDEO_CROP_RECT",
|
||||
"createVideoCropResultNode",
|
||||
"getVideoNodePreviewUrl",
|
||||
"getVideoNodeDurationSeconds",
|
||||
"VIDEO_CROP_OUTPUT_LABEL",
|
||||
"createVideoStoryAnalysisNode",
|
||||
"buildVideoAnalysisRows",
|
||||
"formatVideoStoryNumber",
|
||||
"cleanVideoStoryText",
|
||||
"formatVideoStoryShot",
|
||||
"STARTER_CARDS",
|
||||
"createStarterWorkflow",
|
||||
"createPresetScriptNode",
|
||||
"makePresetEdges",
|
||||
"createPresetMediaNode",
|
||||
"CHARACTER_THREE_VIEW_URL",
|
||||
"PRESET_WORKFLOW_CENTER",
|
||||
"createInputNode",
|
||||
"createSimpleNode",
|
||||
"capturedTools",
|
||||
"arrangeNodesForPreview",
|
||||
"clampAssetManagerWidth",
|
||||
"ASSET_MANAGER_MAX_WIDTH",
|
||||
"ASSET_MANAGER_MIN_WIDTH",
|
||||
"isOfficialImageControlNode",
|
||||
"getPresetControlMode",
|
||||
"ReferenceSelectionToolbar",
|
||||
"VideoCanvasMarkSelectionToolbar",
|
||||
"CancelGenerationConfirmDialog",
|
||||
"CANVAS_EXTENT",
|
||||
"CloneEdges",
|
||||
"getCanvasEdgePath",
|
||||
"getCanvasEdgeMidpoint",
|
||||
"EdgeFlowSegments",
|
||||
"sampleEdgePath",
|
||||
"parseSimpleEdgePath",
|
||||
"getPointAtSampledLength",
|
||||
"CloneCanvasNode",
|
||||
"ToolboxTemplateGroupCanvasNode",
|
||||
"MaterialStyleCanvasNode",
|
||||
"preventNativeImageDrag",
|
||||
"CanvasNodeShell",
|
||||
"TargetModuleCanvasNode",
|
||||
"TargetModuleHeroGraphic",
|
||||
"ModuleActionIcon",
|
||||
"PureTextResourceCanvasNode",
|
||||
"VideoStoryCanvasNode",
|
||||
"getVideoStoryRows",
|
||||
"normalizeVideoStoryRow",
|
||||
"VideoAnalysisGlyph",
|
||||
"VideoSubtitleErasePendingCanvasNode",
|
||||
"VideoHdUpscaleCanvasNode",
|
||||
"PresetMediaCanvasNode",
|
||||
"normalizeGridCropTile",
|
||||
"normalizeGridCellVisual",
|
||||
"OfficialAudioCard",
|
||||
"formatAudioTimestamp",
|
||||
"GenerationPendingPreview",
|
||||
"OfficialVideoResultCard",
|
||||
"formatVideoTimestamp",
|
||||
"NineGridCompositePreview",
|
||||
"GridCellImage",
|
||||
"CroppedGridTileImage",
|
||||
"LocalEditOverlay",
|
||||
"getContainedImageRect",
|
||||
"GridSplitSelectionOverlay",
|
||||
"PresetScriptCanvasNode",
|
||||
"GridTilesGlyph",
|
||||
"VideoCanvasMarkSourceOverlay",
|
||||
"PointerBadge",
|
||||
"CanvasCommandPalette",
|
||||
"ADD_NODE_PRIMARY_MODULES",
|
||||
"ADD_NODE_MODULES",
|
||||
"CanvasAddMenuButton",
|
||||
"CanvasAddBadge",
|
||||
"CanvasAddSubmenu",
|
||||
"SCRIPT_SUBMENU_OPTIONS",
|
||||
"ASSET_LIBRARY_SUBMENU_OPTIONS",
|
||||
"NodeContextMenu",
|
||||
"ConnectionAddMenu",
|
||||
"CONNECTION_ADD_MODULES",
|
||||
"PresetWorkflowControls",
|
||||
"GridSplitActionToolbar",
|
||||
"OFFICIAL_IMAGE_TOOLBAR_SCALE",
|
||||
"WorkflowGlyph",
|
||||
"SceneToolIcon",
|
||||
"CharacterPresetToolbar",
|
||||
"SceneTool",
|
||||
"ImageToolbarActionGlyph",
|
||||
"SceneToolbarPopover",
|
||||
"OFFICIAL_DROPDOWN_SCALE",
|
||||
"NineGridPresetGlyph",
|
||||
"ImageToolMenuGlyph",
|
||||
"CustomGridPicker",
|
||||
"PromptComposer",
|
||||
"resolveVideoCanvasBillingDisplay",
|
||||
"getVideoCanvasFallbackBillingDisplay",
|
||||
"getCanvasModelOptionByRef",
|
||||
"PROMPT_COMPOSER_BASE_HEIGHT",
|
||||
"OFFICIAL_COMPOSER_SCALE",
|
||||
"PROMPT_COMPOSER_BASE_WIDTH",
|
||||
"PromptActionButton",
|
||||
"ComposerReferencePopover",
|
||||
"ComposerSlashPopover",
|
||||
"SLASH_IMAGE_ITEMS",
|
||||
"ComposerFocusPopover",
|
||||
"ComposerPopover",
|
||||
"filterCanvasModelsByKind",
|
||||
"ComposerControl",
|
||||
"getCanvasModelDisplayName",
|
||||
"getFunctionModelValue",
|
||||
"PresetFloatingToolbar",
|
||||
"PresetComposerPanel",
|
||||
"PRESET_COMPOSER_BASE_HEIGHT",
|
||||
"PRESET_MEDIA_TOOLBAR_ITEMS",
|
||||
"AudioToVideoComposerPanel",
|
||||
"VideoModelPopover",
|
||||
"getVideoComposerModelLabel",
|
||||
"VideoParameterEditor",
|
||||
"VideoParameterRow",
|
||||
"VideoRatioOptions",
|
||||
"VideoSegmentedOptions",
|
||||
"VIDEO_AUDIO_OPTIONS",
|
||||
"VIDEO_COUNT_OPTIONS",
|
||||
"VideoMotionPresetPopover",
|
||||
"VideoEffectPresetPopover",
|
||||
"VIDEO_EFFECT_PRESETS",
|
||||
"VideoRoleConsentPopover",
|
||||
"formatVideoParameterSummary",
|
||||
"OfficialVideoMediaToolbar",
|
||||
"OfficialVideoToolbarButton",
|
||||
"VideoHdSettingsPopover",
|
||||
"VideoToolbarMenuPopover",
|
||||
"VideoToolbarMenuItem",
|
||||
"VideoCropSelectionOverlay",
|
||||
"getVideoCardOverlayRect",
|
||||
"clampUnit",
|
||||
"VideoInlineActionBar",
|
||||
"LightningGlyph",
|
||||
"getVideoCropSelectionLabel",
|
||||
"VideoSubtitleEraseRegionOverlay",
|
||||
"normalizeSubtitleEraseRegion",
|
||||
"VideoSubtitleEraseRegionActionBar",
|
||||
"VideoRegionBarIconButton",
|
||||
"VideoClipEditorBar",
|
||||
"VIDEO_CLIP_FRAME_COUNT",
|
||||
"formatClipDurationLabel",
|
||||
"TextTargetModuleComposer",
|
||||
"VideoTargetModuleComposer",
|
||||
"inferVideoComposerDefaultTab",
|
||||
"normalizeComposerBoolean",
|
||||
"resolveVideoComposerMode",
|
||||
"getVideoModeIcon",
|
||||
"getVideoComposerModelShortLabel",
|
||||
"VideoModePopover",
|
||||
"VideoMotionLibraryPanel",
|
||||
"VIDEO_MOTION_FAVORITES_STORAGE_KEY",
|
||||
"VIDEO_MOTION_CUSTOM_STORAGE_KEY",
|
||||
"AudioTargetModuleComposer",
|
||||
"StoryScriptWorkflowDialog",
|
||||
"getStoryWorkflowAssetGroups",
|
||||
"downloadStoryScriptRows",
|
||||
"sanitizeDownloadFilename",
|
||||
"TopBar",
|
||||
"StylizedBrandLogo",
|
||||
"formatCreditValue",
|
||||
"LeftToolbar",
|
||||
"TOOLBAR_ITEMS",
|
||||
"getToolbarButtonLabel",
|
||||
"AssetGlyph",
|
||||
"ZoomDock",
|
||||
"MagnetGlyph",
|
||||
"ZoomDockButton",
|
||||
"ArrangeCanvasGlyph",
|
||||
"CanvasOverviewPopover",
|
||||
"EdgeVisibilityGlyph",
|
||||
"CANVAS_ZOOM_STEP",
|
||||
"ArrangeCanvasConfirm",
|
||||
"AddModulePanel",
|
||||
"WorkflowPanel",
|
||||
"TOOLBOX_TEMPLATE_PRESETS",
|
||||
"capturedWorkflows",
|
||||
"InspectorPanel",
|
||||
"getToolProperties",
|
||||
"getInspectorTitle",
|
||||
"getToolModes",
|
||||
"PropertyField",
|
||||
"getPropertyLabel",
|
||||
"getOptions",
|
||||
"getDefaultValue",
|
||||
"getOptionValue",
|
||||
"ToggleRow",
|
||||
"getOptionLabel",
|
||||
"AssetLibraryLauncherPanel",
|
||||
"AssetLibraryLauncherRow",
|
||||
"AssetMarketPanel",
|
||||
"EFFECT_MARKET_CARDS",
|
||||
"STYLE_MARKET_CARDS",
|
||||
"EFFECT_MARKET_SEARCH_CARDS",
|
||||
"STYLE_MARKET_SEARCH_CARDS",
|
||||
"STYLE_MARKET_CATEGORIES",
|
||||
"EFFECT_MARKET_THUMBNAIL_URL",
|
||||
"HistoryAssetsPanel",
|
||||
"HISTORY_ASSET_ZOOM_LEVELS",
|
||||
"HistoryBatchActionButton",
|
||||
"HistorySelectionCheckbox",
|
||||
"HistoryAssetPickerModal",
|
||||
"WatermarkRulesModal",
|
||||
"CanvasAssetManagerPanel",
|
||||
"ASSET_MANAGER_FILTERS",
|
||||
"ShortcutPanel",
|
||||
"TutorialHelpPanel",
|
||||
"VIDEO_CANVAS_TUTORIAL_URL",
|
||||
"RoleLibraryPanel",
|
||||
"ROLE_LIBRARY_FILTER_GROUPS",
|
||||
"VideoRoleLibraryPanel",
|
||||
"VideoRoleAgreementModal",
|
||||
"LibModal",
|
||||
"SupportPanel",
|
||||
"SkillsAccessModal",
|
||||
"SharePopover",
|
||||
"getSiteShowcaseName",
|
||||
"StoreGlyph",
|
||||
"PublishModal",
|
||||
"PUBLISH_MODAL_BG_URL",
|
||||
"UploadBox",
|
||||
"MemberStoreModal",
|
||||
"CreditPackGrid",
|
||||
"EmptyState",
|
||||
"formatCurrencyAmount",
|
||||
"VipPlanGrid",
|
||||
"BillingHistoryGrid",
|
||||
"formatBillingDate",
|
||||
"getBillingStatusClass",
|
||||
"getBillingStatusLabel",
|
||||
"NotificationsPopover",
|
||||
"AccountPopover",
|
||||
"TARGET_AVATAR",
|
||||
"AccountMetricCard",
|
||||
"AccountMenuButton",
|
||||
"LogoutGlyph",
|
||||
"ImageNodePreview",
|
||||
"DirectorStudioDialog",
|
||||
"DirectorTutorialFollowBar",
|
||||
"MultiAngleEditorDialog",
|
||||
"AngleSlider"
|
||||
],
|
||||
"unreachableFunctions": [
|
||||
"createWorkflowNode",
|
||||
"createHistoryDemoAssetNode",
|
||||
"createVideoSubtitleEraseNode",
|
||||
"buildStorySceneText",
|
||||
"getPersistedVideoAnalysisState",
|
||||
"isCanvasImageModel",
|
||||
"isCanvasVideoModel",
|
||||
"buildGridRectsFromLines",
|
||||
"getLineScore",
|
||||
"findGridDividerLines",
|
||||
"detectGridSplitFromImage",
|
||||
"ArrowGlyph",
|
||||
"MusicStarterIcon",
|
||||
"DiamondGlyph",
|
||||
"VideoMediaToolbar",
|
||||
"VideoToolbarActionButton",
|
||||
"VideoToolbarSubmenu",
|
||||
"VideoAnalysisFloatingPanel",
|
||||
"StoryScriptScene",
|
||||
"FirstFrameVideoScene",
|
||||
"AudioToVideoScene",
|
||||
"SceneConnector",
|
||||
"StoryTextPanel",
|
||||
"ScriptGeneratorPanel",
|
||||
"PresetMediaPanel",
|
||||
"VideoResultPanel",
|
||||
"AudioResourcePanel",
|
||||
"CharacterThreeViewScene",
|
||||
"CharacterImagePanel",
|
||||
"VideoAdvancedSwitchRow",
|
||||
"DirectorRatioPreview",
|
||||
"getNextDirectorCameraName",
|
||||
"formatDirectorCameraShotTitle",
|
||||
"getNextDirectorRoleName",
|
||||
"DirectorConsole3DDialog",
|
||||
"DirectorPanoramaHistoryDialog",
|
||||
"DirectorPanoramaAiDialog",
|
||||
"DirectorRoleInspectorPanel",
|
||||
"DirectorAiImportDialog",
|
||||
"DirectorAxisInputs",
|
||||
"AssetLibraryPanel"
|
||||
],
|
||||
"candidates": [
|
||||
{
|
||||
"owner": "LiblibVideoCanvasReplica",
|
||||
"line": 10996,
|
||||
"tag": "PresetWorkflowControls",
|
||||
"handler": "",
|
||||
"snippet": "(\n <PresetWorkflowControls\n anchor={selectedPresetAnchor}\n membershipSummary={membershipSummary}\n mode={selectedPresetMode ?? \"character-three-view\"}\n functionConfig={videoCanvasFunctionConfig}\n modelOptions={canvasModelOptions}\n nodes={nodes}\n onClearGridSplitSelection={() => clearNodeGridSplitSelection(selectedPresetControlNode.id)}\n onGridSplitCreateNodes={() => createGridSplitImageNodes(selectedPresetControlNode.id)}\n onGridSplitUpscale={(scaleFactor) => upscaleSelectedGridSplit(selectedPresetControlNode.id, scaleFactor)}\n onComposerSubmit={(p"
|
||||
},
|
||||
{
|
||||
"owner": "LiblibVideoCanvasReplica",
|
||||
"line": 11038,
|
||||
"tag": "VideoArchiveButton",
|
||||
"handler": "",
|
||||
"snippet": "return <VideoArchiveButton key={nodeId} automaticBusy={meta.storageStatus === \"archiving\"} url={sourceUrl} onSaved={url => setNodes(current => current.map(node =>\n node.id === nodeId && getNodeMediaUrl(node) === sourceUrl ? { ...node, draftValues: {\n ...node.draftValues, mediaUrl: url, url: [url], videoMeta: { ...meta, storageStatus: \"archived\", permanentVideoUrl: url },\n } } : node))} />;"
|
||||
},
|
||||
{
|
||||
"owner": "ZoomDock",
|
||||
"line": 12045,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button className=\"flex h-7 w-10 items-center justify-center rounded-lg bg-white/10 transition-colors hover:bg-white/14\" type=\"button\">\n <MagnetGlyph />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "VideoSubtitleEraseRegionActionBar",
|
||||
"line": 13371,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button\n aria-label=\"框选区域\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-[8px] bg-white/10 text-white transition\"\n type=\"button\"\n >\n <BoxSelect className=\"h-4 w-4\" />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "VideoClipEditorBar",
|
||||
"line": 13808,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"视频音轨编辑后端待接入。\")}",
|
||||
"snippet": "<button\n className=\"flex h-10 w-10 items-center justify-center rounded-[10px] text-white/44 transition hover:bg-white/8 hover:text-white/76\"\n onClick={() => toast.info(\"视频音轨编辑后端待接入。\")}\n type=\"button\"\n >\n <Music2 className=\"h-[18px] w-[18px]\" strokeWidth={2} />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "TextTargetModuleComposer",
|
||||
"line": 14184,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(\"翻译接口待接入。\")}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[84px] flex items-center gap-6 overflow-hidden text-[17px] text-white/78\">\n <ComposerControl\n active={menu === \"model\"}\n label={getCanvasModelDisplayName(selectedModel, modelOptions)}\n icon=\"⌘\"\n dropdown\n onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")}\n />\n <div className=\"min-w-0 flex-1\" />\n <ComposerControl label=\"文\" onClick={() => toast.info(\"翻译接口待接入。\")} />\n <ComposerControl\n label={billingDisplay.label}\n icon=\"⚡\"\n muted\n onC"
|
||||
},
|
||||
{
|
||||
"owner": "TextTargetModuleComposer",
|
||||
"line": 14185,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(billingDisplay.message)}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[84px] flex items-center gap-6 overflow-hidden text-[17px] text-white/78\">\n <ComposerControl\n active={menu === \"model\"}\n label={getCanvasModelDisplayName(selectedModel, modelOptions)}\n icon=\"⌘\"\n dropdown\n onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")}\n />\n <div className=\"min-w-0 flex-1\" />\n <ComposerControl label=\"文\" onClick={() => toast.info(\"翻译接口待接入。\")} />\n <ComposerControl\n label={billingDisplay.label}\n icon=\"⚡\"\n muted\n onC"
|
||||
},
|
||||
{
|
||||
"owner": "AudioToVideoComposerPanel",
|
||||
"line": 15442,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"展开音频生视频编辑器待接入。\")}",
|
||||
"snippet": "<button className=\"absolute right-6 top-5 text-[32px] text-white/38 hover:text-white/70\" onClick={() => toast.info(\"展开音频生视频编辑器待接入。\")} type=\"button\">↗</button>"
|
||||
},
|
||||
{
|
||||
"owner": "AudioToVideoComposerPanel",
|
||||
"line": 15445,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(`${tab}模式后端待接入。`)}",
|
||||
"snippet": "<button\n className={cn(\n \"h-[38px] rounded-[8px] border border-white/10 px-4 text-[18px] text-white/48\",\n index === 1 && \"bg-white/8 text-white\"\n )}\n key={tab}\n onClick={() => toast.info(`${tab}模式后端待接入。`)}\n type=\"button\"\n >\n {tab}\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "AudioToVideoComposerPanel",
|
||||
"line": 15466,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => {\n if (key === \"reference\") {\n toast.info(\"音频和图片参考已连接,可继续补充更多素材。\");\n return;\n }\n if (key === \"mark\") {\n appendPromptSnippet(\"添加人物与构图标记\");\n return;\n }\n setAssistMenu((current) => current === key ? null : (key as typeof assistMenu));\n setMenu(null);\n }}",
|
||||
"snippet": "<button\n className={cn(\n \"flex h-[72px] w-[92px] flex-col items-center justify-center gap-1 rounded-[8px] border border-white/10 text-[16px] text-white/50 transition hover:bg-white/[0.07] hover:text-white/80\",\n assistMenu === key && \"border-white/22 bg-white/10 text-white\"\n )}\n key={label}\n onClick={() => {\n if (key === \"reference\") {\n toast.info(\"音频和图片参考已连接,可继续补充更多素材。\");\n return;\n }\n if (key === \"mark\") {\n appendPromptSnippet(\"添加人物与构图标记\");\n return;\n "
|
||||
},
|
||||
{
|
||||
"owner": "AudioToVideoComposerPanel",
|
||||
"line": 15510,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(\"翻译接口待接入。\")}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[86px] flex items-center gap-7 overflow-hidden text-[22px] text-white/82\">\n <ComposerControl active={menu === \"model\"} label={getVideoComposerModelLabel(settings, modelOptions)} icon=\"▥\" dropdown onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")} />\n <span className=\"rounded-[5px] bg-[#f6c85f] px-1.5 py-0.5 text-[13px] font-bold text-[#2b2314]\">VIP</span>\n <ComposerControl active={menu === \"settings\"} label={formatVideoParameterSummary(settings)} icon=\"▭\" dropdown onClick={() => setMenu((current) => current === \"settings\" ? null : \"settings\")} />"
|
||||
},
|
||||
{
|
||||
"owner": "AudioToVideoComposerPanel",
|
||||
"line": 15511,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(\"高级设置后端待接入。\")}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[86px] flex items-center gap-7 overflow-hidden text-[22px] text-white/82\">\n <ComposerControl active={menu === \"model\"} label={getVideoComposerModelLabel(settings, modelOptions)} icon=\"▥\" dropdown onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")} />\n <span className=\"rounded-[5px] bg-[#f6c85f] px-1.5 py-0.5 text-[13px] font-bold text-[#2b2314]\">VIP</span>\n <ComposerControl active={menu === \"settings\"} label={formatVideoParameterSummary(settings)} icon=\"▭\" dropdown onClick={() => setMenu((current) => current === \"settings\" ? null : \"settings\")} />"
|
||||
},
|
||||
{
|
||||
"owner": "AudioToVideoComposerPanel",
|
||||
"line": 15512,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(billingDisplay.message)}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[86px] flex items-center gap-7 overflow-hidden text-[22px] text-white/82\">\n <ComposerControl active={menu === \"model\"} label={getVideoComposerModelLabel(settings, modelOptions)} icon=\"▥\" dropdown onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")} />\n <span className=\"rounded-[5px] bg-[#f6c85f] px-1.5 py-0.5 text-[13px] font-bold text-[#2b2314]\">VIP</span>\n <ComposerControl active={menu === \"settings\"} label={formatVideoParameterSummary(settings)} icon=\"▭\" dropdown onClick={() => setMenu((current) => current === \"settings\" ? null : \"settings\")} />"
|
||||
},
|
||||
{
|
||||
"owner": "AudioToVideoComposerPanel",
|
||||
"line": 15519,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => {\n if (onSubmit) {\n onSubmit(prompt, settings);\n return;\n }\n toast.info(\"音频生视频生成接口待接入。\");\n }}",
|
||||
"snippet": "<button\n className=\"absolute bottom-5 right-5 flex h-14 w-14 items-center justify-center rounded-[14px] bg-white text-[34px] leading-none text-black hover:bg-white/90\"\n onClick={() => {\n if (onSubmit) {\n onSubmit(prompt, settings);\n return;\n }\n toast.info(\"音频生视频生成接口待接入。\");\n }}\n type=\"button\"\n >\n ↑\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PresetFloatingToolbar",
|
||||
"line": 15941,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => {\n if (onClick) {\n onClick();\n return;\n }\n if (message) toast.info(message);\n }}",
|
||||
"snippet": "<button\n className={cn(\n \"flex items-center justify-center rounded-[8px] hover:bg-white/8 hover:text-white\",\n compact ? \"h-8 text-[14px] font-medium\" : \"h-10 gap-2 rounded-[10px] px-3 text-[15px]\"\n )}\n key={label}\n onClick={() => {\n if (onClick) {\n onClick();\n return;\n }\n if (message) toast.info(message);\n }}\n style={compact ? { width: compactWidth } : undefined}\n type=\"button\"\n >\n {!compact ? (\n <span className=\"flex h-5 w-5 items-center ju"
|
||||
},
|
||||
{
|
||||
"owner": "PresetComposerPanel",
|
||||
"line": 16227,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"展开提示词编辑器待接入。\")}",
|
||||
"snippet": "<button className=\"absolute right-5 top-5 text-[26px] text-white/45\" onClick={() => toast.info(\"展开提示词编辑器待接入。\")} type=\"button\">↗</button>"
|
||||
},
|
||||
{
|
||||
"owner": "PresetComposerPanel",
|
||||
"line": 16246,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(\"镜头配置接口待接入。\")}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[84px] flex items-center gap-6 overflow-hidden text-[17px] text-white/78\">\n\t <ComposerControl active={menu === \"model\"} label={getCanvasModelDisplayName(settings.model, modelOptions)} icon=\"◉\" dropdown onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")} />\n\t <ComposerControl active={menu === \"ratio\"} label={settings.ratio} icon=\"▭\" dropdown onClick={() => setMenu((current) => current === \"ratio\" ? null : \"ratio\")} />\n\t <ComposerControl active={menu === \"resolution\"} label={settings.resolution} dropdown onClick={() => setMenu((current) => current === \"re"
|
||||
},
|
||||
{
|
||||
"owner": "PresetComposerPanel",
|
||||
"line": 16247,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(\"当前仅支持单次生成 1 个结果。\")}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[84px] flex items-center gap-6 overflow-hidden text-[17px] text-white/78\">\n\t <ComposerControl active={menu === \"model\"} label={getCanvasModelDisplayName(settings.model, modelOptions)} icon=\"◉\" dropdown onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")} />\n\t <ComposerControl active={menu === \"ratio\"} label={settings.ratio} icon=\"▭\" dropdown onClick={() => setMenu((current) => current === \"ratio\" ? null : \"ratio\")} />\n\t <ComposerControl active={menu === \"resolution\"} label={settings.resolution} dropdown onClick={() => setMenu((current) => current === \"re"
|
||||
},
|
||||
{
|
||||
"owner": "PresetComposerPanel",
|
||||
"line": 16248,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(billingDisplay.message)}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[84px] flex items-center gap-6 overflow-hidden text-[17px] text-white/78\">\n\t <ComposerControl active={menu === \"model\"} label={getCanvasModelDisplayName(settings.model, modelOptions)} icon=\"◉\" dropdown onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")} />\n\t <ComposerControl active={menu === \"ratio\"} label={settings.ratio} icon=\"▭\" dropdown onClick={() => setMenu((current) => current === \"ratio\" ? null : \"ratio\")} />\n\t <ComposerControl active={menu === \"resolution\"} label={settings.resolution} dropdown onClick={() => setMenu((current) => current === \"re"
|
||||
},
|
||||
{
|
||||
"owner": "PresetComposerPanel",
|
||||
"line": 16255,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => {\n if (onSubmit) {\n onSubmit(draftPrompt, settings);\n return;\n }\n toast.info(submitMessage);\n }}",
|
||||
"snippet": "<button\n\t className=\"absolute bottom-5 right-5 flex h-11 w-11 items-center justify-center rounded-[12px] bg-white/76 text-[24px] text-black hover:bg-white\"\n\t onClick={() => {\n if (onSubmit) {\n onSubmit(draftPrompt, settings);\n return;\n }\n toast.info(submitMessage);\n }}\n\t type=\"button\"\n\t >\n\t ↑\n\t </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PromptComposer",
|
||||
"line": 16874,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"展开提示词编辑器待接入。\")}",
|
||||
"snippet": "<button className=\"absolute right-5 top-5 text-[26px] text-white/45\" onClick={() => toast.info(\"展开提示词编辑器待接入。\")} type=\"button\">↗</button>"
|
||||
},
|
||||
{
|
||||
"owner": "PromptComposer",
|
||||
"line": 16958,
|
||||
"tag": "ComposerControl",
|
||||
"handler": "onClick={() => toast.info(billingDisplay.message)}",
|
||||
"snippet": "<div className=\"absolute bottom-5 left-5 right-[84px] flex items-center gap-6 overflow-hidden text-[18px] text-white/78\">\n <ComposerControl active={menu === \"model\"} label={getCanvasModelDisplayName(settings.model, modelOptions)} icon=\"◉\" dropdown onClick={() => setMenu((current) => current === \"model\" ? null : \"model\")} />\n <ComposerControl active={menu === \"ratio\"} label={settings.ratio} icon=\"▭\" dropdown onClick={() => setMenu((current) => current === \"ratio\" ? null : \"ratio\")} />\n <ComposerControl active={menu === \"resolution\"} label={settings.resolution} dropdown onClick={() => setMenu((current) => current === "
|
||||
},
|
||||
{
|
||||
"owner": "PromptComposer",
|
||||
"line": 16965,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() =>\n onSubmit\n ? onSubmit({\n prompt,\n references,\n settings,\n slashScene,\n })\n : toast.info(\"角色三视图生成接口待接入。\")\n }",
|
||||
"snippet": "<button\n className=\"absolute bottom-5 right-5 flex h-11 w-11 items-center justify-center rounded-[12px] bg-white/76 text-[24px] text-black hover:bg-white\"\n onClick={() =>\n onSubmit\n ? onSubmit({\n prompt,\n references,\n settings,\n slashScene,\n })\n : toast.info(\"角色三视图生成接口待接入。\")\n }\n type=\"button\"\n >\n ↑\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "VideoMotionLibraryPanel",
|
||||
"line": 17618,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button\n aria-label=\"搜索\"\n className=\"flex size-6 shrink-0 items-center justify-center text-white/42 hover:text-white/75\"\n type=\"submit\"\n >\n <Search className=\"size-4\" />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "CloneCanvasNode",
|
||||
"line": 19132,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button className=\"relative mt-3 h-8 rounded-[8px] border border-[#dfe3ff] bg-white px-4 text-[11px] text-[#5161ff]\" type=\"button\">\n 选择文件\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PresetMediaCanvasNode",
|
||||
"line": 21735,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"视频全屏预览待接入。\")}",
|
||||
"snippet": "<button\n className=\"absolute right-3 top-3 rounded-[8px] bg-white/8 px-3 py-2 text-[12px] text-white/72 hover:bg-white/12\"\n onClick={() => toast.info(\"视频全屏预览待接入。\")}\n type=\"button\"\n >\n ↗\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PresetMediaCanvasNode",
|
||||
"line": 21810,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(`${node.title}素材替换接口待接入。`)}",
|
||||
"snippet": "<button\n className=\"absolute right-3 top-3 flex h-10 w-10 items-center justify-center rounded-[8px] bg-black/56 text-white/90\"\n onClick={() => toast.info(`${node.title}素材替换接口待接入。`)}\n type=\"button\"\n >\n ↥\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PresetScriptCanvasNode",
|
||||
"line": 22476,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"编辑剧本接口待接入。\")}",
|
||||
"snippet": "<button className=\"rounded-[8px] px-2 py-1 text-[#4f5cff] hover:bg-black/5\" onClick={() => toast.info(\"编辑剧本接口待接入。\")} type=\"button\">\n 编辑\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "AssetMarketPanel",
|
||||
"line": 22917,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button className=\"flex h-7 w-[54px] items-center justify-center rounded-[8px] bg-white/10 text-[13px] text-white\" type=\"button\">\n 全部\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "HistoryAssetPickerModal",
|
||||
"line": 23177,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button className=\"flex h-8 w-8 items-center justify-center rounded-lg text-white/36 transition hover:bg-white/8 hover:text-white\" type=\"button\">\n <ChevronRight className=\"h-4 w-4 rotate-180\" />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "HistoryAssetPickerModal",
|
||||
"line": 23181,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button className=\"flex h-8 w-8 items-center justify-center rounded-lg text-white/36 transition hover:bg-white/8 hover:text-white\" type=\"button\">\n <ChevronRight className=\"h-4 w-4\" />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "WorkflowPanel",
|
||||
"line": 24486,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button\n className=\"cursor-pointer rounded-md border-none bg-transparent py-1 pr-2 pl-0 text-sm font-medium text-white transition-colors\"\n type=\"button\"\n >\n 我的工具箱\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "WorkflowPanel",
|
||||
"line": 24492,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"工具箱模板会将参考图、提示词和成品节点应用到画布。\")}",
|
||||
"snippet": "<button\n aria-label=\"工具箱模板说明\"\n className=\"-ml-1.5 flex size-4 cursor-help items-center justify-center rounded-full border-none bg-transparent p-0 text-white/70 opacity-50 transition-opacity hover:opacity-80\"\n onClick={() => toast.info(\"工具箱模板会将参考图、提示词和成品节点应用到画布。\")}\n type=\"button\"\n >\n <HelpCircle className=\"h-3.5 w-3.5\" />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "WorkflowPanel",
|
||||
"line": 24501,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button\n className=\"cursor-pointer rounded-md border-none bg-transparent px-2 py-1 text-sm font-medium text-white/55 transition-colors hover:text-white/80\"\n type=\"button\"\n >\n 周星驰经典名场面\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "InspectorPanel",
|
||||
"line": 24620,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => (onAddReference ? onAddReference(node) : toast.info(\"上传/素材选择接口待接入。\"))}",
|
||||
"snippet": "<button\n className=\"flex h-[74px] w-full items-center justify-center rounded-[8px] border border-white/10 bg-white/5 text-[14px] text-white/52 hover:bg-white/8 hover:text-white\"\n onClick={() => (onAddReference ? onAddReference(node) : toast.info(\"上传/素材选择接口待接入。\"))}\n type=\"button\"\n >\n <Plus className=\"mr-2 h-4 w-4\" />\n {referenceCount > 0 ? `继续添加素材 · 已连入 ${referenceCount}` : \"添加素材\"}\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "InspectorPanel",
|
||||
"line": 24655,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => (onGenerate ? onGenerate(node) : toast.info(\"生成接口待接入。\"))}",
|
||||
"snippet": "<button\n className=\"h-[64px] w-full rounded-[8px] bg-white font-bold text-[16px] text-black hover:bg-white/90 disabled:cursor-not-allowed disabled:bg-white/35\"\n disabled={isGenerating || (selectableRoute && (!compatibleModels.length || unavailableSelection))}\n onClick={() => (onGenerate ? onGenerate(node) : toast.info(\"生成接口待接入。\"))}\n type=\"button\"\n >\n {isGenerating ? \"生成中...\" : \"生成\"}\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PropertyField",
|
||||
"line": 24751,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(`${label}选择器待接入。`)}",
|
||||
"snippet": "<button\n className=\"h-10 w-full rounded-[8px] border border-white/10 bg-black/18 px-3 text-left text-[13px] text-white/46 hover:border-white/20 hover:text-white\"\n onClick={() => toast.info(`${label}选择器待接入。`)}\n type=\"button\"\n >\n 选择{label}\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "SkillsAccessModal",
|
||||
"line": 24963,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() =>\n toast.info(\"安装包位于 integrations/openclaw,可通过 STDIO MCP 接入。\")\n }",
|
||||
"snippet": "<button\n className=\"ml-1 text-[#2f8bff] underline-offset-2 hover:underline\"\n onClick={() =>\n toast.info(\"安装包位于 integrations/openclaw,可通过 STDIO MCP 接入。\")\n }\n type=\"button\"\n >\n 接口文档\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "SkillsAccessModal",
|
||||
"line": 24998,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => {\n void navigator.clipboard?.writeText(createdToken);\n toast.success(\"Access Key 已复制\");\n }}",
|
||||
"snippet": "<button\n className=\"flex h-8 shrink-0 items-center gap-1 rounded-[6px] bg-white px-2 text-[11px] font-medium text-black\"\n onClick={() => {\n void navigator.clipboard?.writeText(createdToken);\n toast.success(\"Access Key 已复制\");\n }}\n type=\"button\"\n >\n <Copy className=\"h-3.5 w-3.5\" />\n 复制\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "VipPlanGrid",
|
||||
"line": 25468,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => {\n if (isCurrent) return;\n toast.info(\"会员订阅支付尚未接入,当前请优先使用积分充值。\");\n }}",
|
||||
"snippet": "<button\n className={cn(\n \"mt-4 h-9 w-full rounded-[8px] text-[13px] font-semibold transition-colors\",\n isCurrent\n ? \"cursor-default bg-white/12 text-white/38\"\n : \"bg-white text-black hover:bg-white/90\"\n )}\n disabled={isCurrent}\n onClick={() => {\n if (isCurrent) return;\n toast.info(\"会员订阅支付尚未接入,当前请优先使用积分充值。\");\n }}\n type=\"button\"\n >\n {isCurrent ? \"当前套餐\" : isFree ? \"默认套餐\" : \"即将接入\"}\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "NotificationsPopover",
|
||||
"line": 25654,
|
||||
"tag": "button",
|
||||
"handler": "",
|
||||
"snippet": "<button\n className={cn(\n \"h-7 rounded-[8px] px-3 text-[12px] transition-colors\",\n index === 0 ? \"bg-white text-black\" : \"bg-white/6 text-white/56 hover:bg-white/10 hover:text-white\"\n )}\n key={item}\n type=\"button\"\n >\n {item}\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "NotificationsPopover",
|
||||
"line": 25671,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(`${title}接口待接入。`)}",
|
||||
"snippet": "<button\n className=\"mb-2 w-full rounded-[10px] border border-white/8 bg-white/5 p-3 text-left hover:bg-white/8\"\n key={title}\n onClick={() => toast.info(`${title}接口待接入。`)}\n type=\"button\"\n >\n <span className=\"block text-[13px] font-semibold text-white/82\">{title}</span>\n <span className=\"mt-1 block text-[12px] leading-5 text-white/42\">{description}</span>\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "AccountPopover",
|
||||
"line": 25727,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => {\n void navigator.clipboard?.writeText(displayEmail);\n toast.success(\"邮箱复制成功\");\n }}",
|
||||
"snippet": "<button\n className=\"rounded-[6px] px-1 text-white/42 hover:bg-white/8 hover:text-white\"\n onClick={() => {\n void navigator.clipboard?.writeText(displayEmail);\n toast.success(\"邮箱复制成功\");\n }}\n type=\"button\"\n >\n <Copy className=\"h-3 w-3\" />\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "AccountPopover",
|
||||
"line": 25779,
|
||||
"tag": "AccountMenuButton",
|
||||
"handler": "onClick={() => toast.info(\"个人中心入口待接入。\")}",
|
||||
"snippet": "<div className=\"mt-4 space-y-1\">\n <AccountMenuButton\n icon={<StoreGlyph />}\n label=\"积分与会员中心\"\n onClick={() => {\n onClose();\n onOpenMember();\n }}\n />\n <AccountMenuButton icon={<UserRound className=\"h-[18px] w-[18px]\" />} label=\"个人中心\" onClick={() => toast.info(\"个人中心入口待接入。\")} />\n <AccountMenuButton icon={<Plus className=\"h-[18px] w-[18px]\" />} label=\"创建团队\" onClick={() => toast.info(\"创建团队接口待接入。\")} />\n <AccountMenuButton icon={<FileText className=\"h-[18px] w-[18px]\" />} label=\"订阅与开发票\" onClick={() => toast.info(\"订阅"
|
||||
},
|
||||
{
|
||||
"owner": "AccountPopover",
|
||||
"line": 25780,
|
||||
"tag": "AccountMenuButton",
|
||||
"handler": "onClick={() => toast.info(\"创建团队接口待接入。\")}",
|
||||
"snippet": "<div className=\"mt-4 space-y-1\">\n <AccountMenuButton\n icon={<StoreGlyph />}\n label=\"积分与会员中心\"\n onClick={() => {\n onClose();\n onOpenMember();\n }}\n />\n <AccountMenuButton icon={<UserRound className=\"h-[18px] w-[18px]\" />} label=\"个人中心\" onClick={() => toast.info(\"个人中心入口待接入。\")} />\n <AccountMenuButton icon={<Plus className=\"h-[18px] w-[18px]\" />} label=\"创建团队\" onClick={() => toast.info(\"创建团队接口待接入。\")} />\n <AccountMenuButton icon={<FileText className=\"h-[18px] w-[18px]\" />} label=\"订阅与开发票\" onClick={() => toast.info(\"订阅"
|
||||
},
|
||||
{
|
||||
"owner": "AccountPopover",
|
||||
"line": 25781,
|
||||
"tag": "AccountMenuButton",
|
||||
"handler": "onClick={() => toast.info(\"订阅与开发票入口待接入。\")}",
|
||||
"snippet": "<div className=\"mt-4 space-y-1\">\n <AccountMenuButton\n icon={<StoreGlyph />}\n label=\"积分与会员中心\"\n onClick={() => {\n onClose();\n onOpenMember();\n }}\n />\n <AccountMenuButton icon={<UserRound className=\"h-[18px] w-[18px]\" />} label=\"个人中心\" onClick={() => toast.info(\"个人中心入口待接入。\")} />\n <AccountMenuButton icon={<Plus className=\"h-[18px] w-[18px]\" />} label=\"创建团队\" onClick={() => toast.info(\"创建团队接口待接入。\")} />\n <AccountMenuButton icon={<FileText className=\"h-[18px] w-[18px]\" />} label=\"订阅与开发票\" onClick={() => toast.info(\"订阅"
|
||||
},
|
||||
{
|
||||
"owner": "AccountPopover",
|
||||
"line": 25782,
|
||||
"tag": "AccountMenuButton",
|
||||
"handler": "onClick={() => toast.info(\"账号设置入口待接入。\")}",
|
||||
"snippet": "<div className=\"mt-4 space-y-1\">\n <AccountMenuButton\n icon={<StoreGlyph />}\n label=\"积分与会员中心\"\n onClick={() => {\n onClose();\n onOpenMember();\n }}\n />\n <AccountMenuButton icon={<UserRound className=\"h-[18px] w-[18px]\" />} label=\"个人中心\" onClick={() => toast.info(\"个人中心入口待接入。\")} />\n <AccountMenuButton icon={<Plus className=\"h-[18px] w-[18px]\" />} label=\"创建团队\" onClick={() => toast.info(\"创建团队接口待接入。\")} />\n <AccountMenuButton icon={<FileText className=\"h-[18px] w-[18px]\" />} label=\"订阅与开发票\" onClick={() => toast.info(\"订阅"
|
||||
},
|
||||
{
|
||||
"owner": "AccountPopover",
|
||||
"line": 25783,
|
||||
"tag": "AccountMenuButton",
|
||||
"handler": "onClick={() => toast.info(\"退出登录接口待接入。\")}",
|
||||
"snippet": "<div className=\"mt-4 space-y-1\">\n <AccountMenuButton\n icon={<StoreGlyph />}\n label=\"积分与会员中心\"\n onClick={() => {\n onClose();\n onOpenMember();\n }}\n />\n <AccountMenuButton icon={<UserRound className=\"h-[18px] w-[18px]\" />} label=\"个人中心\" onClick={() => toast.info(\"个人中心入口待接入。\")} />\n <AccountMenuButton icon={<Plus className=\"h-[18px] w-[18px]\" />} label=\"创建团队\" onClick={() => toast.info(\"创建团队接口待接入。\")} />\n <AccountMenuButton icon={<FileText className=\"h-[18px] w-[18px]\" />} label=\"订阅与开发票\" onClick={() => toast.info(\"订阅"
|
||||
},
|
||||
{
|
||||
"owner": "AccountMetricCard",
|
||||
"line": 25805,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(`${label}接口待接入。`)}",
|
||||
"snippet": "<button\n className={cn(\n \"rounded-[12px] border border-white/8 bg-white/[0.04] px-4 py-3 text-left hover:bg-white/[0.07]\",\n className\n )}\n onClick={() => toast.info(`${label}接口待接入。`)}\n type=\"button\"\n >\n <span className={cn(\"block text-[12px]\", accent ? \"text-[#09caf5]\" : \"text-white/45\")}>{label}</span>\n <span className=\"mt-1 flex items-baseline gap-1\">\n <span className={cn(\"font-['PlusJakartaSans'] text-[18px] font-bold\", accent ? \"text-[#09caf5]\" : \"text-white/88\")}>{value}</span>\n <span className=\"text-[12px] text-white/44\">{suffix}</span>\n </span>\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "SupportPanel",
|
||||
"line": 25859,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(`${title}入口待接入。`)}",
|
||||
"snippet": "<button\n className=\"w-full rounded-[8px] border border-white/8 bg-white/5 p-3 text-left hover:bg-white/8\"\n key={title}\n onClick={() => toast.info(`${title}入口待接入。`)}\n type=\"button\"\n >\n <div className=\"text-[13px] font-semibold text-white/82\">{title}</div>\n <div className=\"mt-1 text-[12px] text-white/42\">{description}</div>\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PublishModal",
|
||||
"line": 26112,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"发布接口待接入。\")}",
|
||||
"snippet": "<button\n className=\"cursor-pointer rounded-lg bg-[#478EFF] px-3 py-2 text-[13px] text-white transition-colors hover:bg-[#2563EB]\"\n onClick={() => toast.info(\"发布接口待接入。\")}\n type=\"button\"\n >\n 发布并投稿\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "PublishModal",
|
||||
"line": 26125,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(\"服务协议入口待接入。\")}",
|
||||
"snippet": "<button\n className=\"text-[#478EFF] hover:underline\"\n onClick={() => toast.info(\"服务协议入口待接入。\")}\n type=\"button\"\n >\n 《{siteName}创作许可服务协议》\n </button>"
|
||||
},
|
||||
{
|
||||
"owner": "UploadBox",
|
||||
"line": 26142,
|
||||
"tag": "button",
|
||||
"handler": "onClick={() => toast.info(`${label}接口待接入。`)}",
|
||||
"snippet": "<button\n className=\"flex h-[120px] flex-1 flex-col items-center justify-center rounded-[8px] border border-white/8 bg-white/12 text-white/72 transition-colors hover:bg-white/16 hover:text-white\"\n onClick={() => toast.info(`${label}接口待接入。`)}\n type=\"button\"\n >\n <Plus className=\"h-5 w-5\" />\n <span className=\"mt-2 text-[13px]\">{label}</span>\n {hint ? <span className=\"mt-2 text-[12px] text-white/42\">{hint}</span> : null}\n </button>"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
# 视频画布修复记录 — 2026-09-17
|
||||
|
||||
后续全面验证扫描见 [2026-09-17 扫描报告](video-canvas-validation-scan-2026-09-17.md):仍存在任务恢复、取消等未完成项,不能以本文作为全功能验收通过证明。
|
||||
|
||||
基于 `e5b2de3c` 的 231 项对照检查继续修复。本文记录已修改的具体行为和验证边界;**不表示 231 项全部完成,也不表示与 LibTV 像素级一致**。代码在 `codex/video-canvas-parity-0916`;本轮没有部署、重启 48 服务器或修改生产数据库。
|
||||
|
||||
## 生成与参数
|
||||
|
||||
285
docs/video-canvas-validation-matrix-2026-09-17.md
Normal file
285
docs/video-canvas-validation-matrix-2026-09-17.md
Normal file
@ -0,0 +1,285 @@
|
||||
# 视频画布验证矩阵 · 2026-09-17
|
||||
|
||||
逐项核对原 231 项。分类表示**证据和剩余工作**,不是完成率;“有部分证据”包括历史实测、契约单测和代码检查,均不能单独代替本次端到端验收。详细说明见同名扫描报告与 JSON。
|
||||
|
||||
## 01 画布、节点和项目
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 01-01 | 项目/标题 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-02 | 项目/多画布切换 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-03 | 视图/工作流 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-04 | 视图/故事板 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-05 | 故事板/关键元素 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-06 | 故事板/音频 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-07 | 故事板/对话引用 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-08 | 故事板/剪辑 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-09 | 添加/基本节点 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-10 | 添加/智能剪辑 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-11 | 添加/逐帧拉片 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-12 | 添加/脚本版本 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-13 | 添加/搜索 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-14 | 画布/平移缩放 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-15 | 画布/小地图 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-16 | 画布/网格吸附 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-17 | 画布/连线显隐 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-18 | 画布/整理 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-19 | 画布/分组解组 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-20 | 画布/撤销重做 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-21 | 右键/评级 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-22 | 右键/复制粘贴 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-23 | 右键/资产沉淀 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-24 | 右键/全景预览 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-25 | 右键/素材校验 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-26 | 快捷键/一致性 | 有部分证据,未完整验收 | 本轮代码检查 | 全画布撤销、分组等原参考能力未实现。 |
|
||||
| 01-27 | 持久化/完成结果恢复 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 01-28 | 持久化/后台与刷新中任务 | 仍有问题(F01) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 02 文本和提示词
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 02-01 | 文本/手工编写 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-02 | 文本/文生视频 | 仍有问题(F03) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-03 | 文本/图片反推 | 仍有问题(F03) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-04 | 文本/文字生音乐 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-05 | 提示词/优化 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-06 | 提示词/翻译 | 仍有问题(F07) | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-07 | 提示词/@引用 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-08 | 提示词/AutoLink | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 02-09 | 提示词/联网搜索 | 缺失或停用 | 修复记录;本轮活动代码检查 | 联网搜索与供应商合规检查服务未实现。 |
|
||||
| 02-10 | 提示词/自动校验素材 | 缺失或停用 | 修复记录;本轮活动代码检查 | 联网搜索与供应商合规检查服务未实现。 |
|
||||
| 02-11 | 提示词/文本模型显示 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 03 图片生成与编辑
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 03-01 | 图片/模型选择 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-02 | 图片/1K 2K 4K | 有部分证据,未完整验收 | 本轮 generation-contract 回归通过 | 供应商逐模型规格、实际多张生成和页面端到端未逐一验收。 |
|
||||
| 03-03 | 图片/画质 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-04 | 图片/透明背景 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-05 | 图片/比例 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-06 | 图片/数量 | 有部分证据,未完整验收 | 本轮 generation-contract 回归通过 | 供应商逐模型规格、实际多张生成和页面端到端未逐一验收。 |
|
||||
| 03-07 | 图片/替换素材 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-08 | 图片/人像调节 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-09 | 图片/情绪调节 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-10 | 图片/全景生成 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-11 | 图片/全景沉浸预览 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-12 | 多角度/七种预设 | 有部分证据,未完整验收 | 本轮浏览器:鱼眼→右箭头→提交 preset=自定义、horizontalAngle=10;本轮角度映射回归通过 | 未验证全部预设的供应商实际画面效果。 |
|
||||
| 03-13 | 多角度/环绕俯仰缩放 | 有部分证据,未完整验收 | 本轮浏览器:鱼眼→右箭头→提交 preset=自定义、horizontalAngle=10;本轮角度映射回归通过 | 未验证全部预设的供应商实际画面效果。 |
|
||||
| 03-14 | 多角度/预览 | 有部分证据,未完整验收 | 此前组件浏览器验收 | 不是实时角度渲染;多分辨率布局仍待验。 |
|
||||
| 03-15 | 打光/智能模式 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-16 | 打光/亮度颜色 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-17 | 打光/六方向 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-18 | 打光/轮廓光 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-19 | 高清/专用模型 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-20 | 高清/倍率 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-21 | 宫格预设/11 类 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-22 | 宫格预设/禁用状态 | 有部分证据,未完整验收 | 本轮代码检查 | 后台开关与页面端到端尚未专项验收。 |
|
||||
| 03-23 | 宫格切分/固定规格 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-24 | 宫格切分/自定义 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-25 | 宫格切分/边界与选中 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-26 | 元素编辑/点选 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-27 | 元素编辑/框选 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-28 | 元素编辑/画笔 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-29 | 图层分离/物体拆分 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-30 | 图片/扩图重绘擦除抠图 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-31 | 图片/下载预览 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 03-32 | 图片/小屏弹窗 | 有部分证据,未完整验收 | 此前组件浏览器验收 | 不是实时角度渲染;多分辨率布局仍待验。 |
|
||||
| 03-33 | 图片/空参考输入 | 有部分证据,未完整验收 | 本轮 generation-contract 回归通过 | 供应商逐模型规格、实际多张生成和页面端到端未逐一验收。 |
|
||||
|
||||
## 04 视频生成和模型匹配
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 04-01 | 视频/文生视频 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-02 | 视频/首帧生成 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-03 | 视频/首尾帧 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-04 | 视频/多图参考 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-05 | 视频/全能参考 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-06 | 视频/5 分钟长视频 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-07 | 视频/模型目录 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-08 | 视频/按功能过滤模型 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-09 | 视频/无兼容模型 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-10 | 视频/比例规格 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-11 | 视频/清晰度 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-12 | 视频/时长 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-13 | 视频/生成音频 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-14 | 视频/生成数量 | 有部分证据,未完整验收 | 本轮代码检查 | 混合失败、排队中删除、重复提交、断线恢复未验收。 |
|
||||
| 04-15 | 视频/参考选择 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-16 | 视频/标记引用 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-17 | 视频/运镜库 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-18 | 视频/运镜引用 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-19 | 视频/角色素材 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-20 | 视频/特效库 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-21 | 视频/生成任务恢复 | 仍有问题(F01,F02) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 04-22 | 视频/结果归档 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 05 视频后期、智能剪辑和拉片
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 05-01 | 后期/工具栏结构 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-02 | 后期/时间裁剪 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-03 | 后期/空间裁剪 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-04 | 后期/视频高清 | 缺失或停用 | 本轮代码检查 | 专用超分、去字幕、人声/背景分离服务尚未接通。 |
|
||||
| 05-05 | 后期/补帧 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-06 | 后期/慢放 | 有部分证据,未完整验收 | 本轮真实 FFmpeg 回归:首/中/尾不同、2/3/5 倍慢放保留音轨 | 实际网页当前帧选取→处理接口→结果节点链路本轮未再执行。 |
|
||||
| 05-07 | 后期/片段重拍 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-08 | 后期/智能续写 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-09 | 后期/智能去字幕 | 缺失或停用 | 本轮代码检查 | 专用超分、去字幕、人声/背景分离服务尚未接通。 |
|
||||
| 05-10 | 后期/框选去字幕 | 缺失或停用 | 本轮代码检查 | 专用超分、去字幕、人声/背景分离服务尚未接通。 |
|
||||
| 05-11 | 后期/音视频分离 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-12 | 后期/人声提取 | 缺失或停用 | 本轮代码检查 | 专用超分、去字幕、人声/背景分离服务尚未接通。 |
|
||||
| 05-13 | 后期/背景音提取 | 缺失或停用 | 本轮代码检查 | 专用超分、去字幕、人声/背景分离服务尚未接通。 |
|
||||
| 05-14 | 后期/主体消除 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-15 | 后期/截取帧 | 有部分证据,未完整验收 | 本轮真实 FFmpeg 回归:首/中/尾不同、2/3/5 倍慢放保留音轨 | 实际网页当前帧选取→处理接口→结果节点链路本轮未再执行。 |
|
||||
| 05-16 | 后期/截图规格显示 | 有部分证据,未完整验收 | 本轮真实 FFmpeg 回归:首/中/尾不同、2/3/5 倍慢放保留音轨 | 实际网页当前帧选取→处理接口→结果节点链路本轮未再执行。 |
|
||||
| 05-17 | 智能剪辑/四种模板 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-18 | 智能剪辑/讲解模板 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-19 | 智能剪辑/多素材编排 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-20 | 逐帧拉片/输入信息 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-21 | 逐帧拉片/拆解维度 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 05-22 | 逐帧拉片/结果继续创作 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 06 脚本的三层流程
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 06-01 | 脚本/模型生成 | 仍有问题(F04) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 06-02 | 脚本/手工编写 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 06-03 | 确认镜头/字段 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 06-04 | 确认镜头/单元格编辑 | 有部分证据,未完整验收 | 此前组件浏览器编辑刷新恢复 | 数据库持久化、行删除后的资产/分镜同步仍需端到端。 |
|
||||
| 06-05 | 确认镜头/添加镜头 | 有部分证据,未完整验收 | 此前组件浏览器编辑刷新恢复 | 数据库持久化、行删除后的资产/分镜同步仍需端到端。 |
|
||||
| 06-06 | 确认镜头/拖动排序 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 06-07 | 确认镜头/行操作 | 有部分证据,未完整验收 | 此前组件浏览器编辑刷新恢复 | 数据库持久化、行删除后的资产/分镜同步仍需端到端。 |
|
||||
| 06-08 | 准备资产/角色场景道具 | 有部分证据,未完整验收 | 此前浏览器资产引用与计数;本轮代码检查 | 上传成功/失败、AI 生成及所有资产类型未完整验收。 |
|
||||
| 06-09 | 准备资产/真实来源 | 有部分证据,未完整验收 | 此前浏览器资产引用与计数;本轮代码检查 | 上传成功/失败、AI 生成及所有资产类型未完整验收。 |
|
||||
| 06-10 | 准备资产/新增 | 有部分证据,未完整验收 | 此前浏览器资产引用与计数;本轮代码检查 | 上传成功/失败、AI 生成及所有资产类型未完整验收。 |
|
||||
| 06-11 | 准备资产/替换清除删除 | 有部分证据,未完整验收 | 此前浏览器资产引用与计数;本轮代码检查 | 上传成功/失败、AI 生成及所有资产类型未完整验收。 |
|
||||
| 06-12 | 准备资产/资产生成参数 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 06-13 | 准备资产/完成状态 | 有部分证据,未完整验收 | 此前浏览器资产引用与计数;本轮代码检查 | 上传成功/失败、AI 生成及所有资产类型未完整验收。 |
|
||||
| 06-14 | 合成提示词/完成门槛 | 有部分证据,未完整验收 | 本轮浏览器:接口 501 后显示失败,原对白/两镜头保留,完成数 0/2;此前浏览器风格编辑与刷新 | 仅验证本地失败分支;真实合成成功与批量部分失败未验收。 |
|
||||
| 06-15 | 合成提示词/单镜合成 | 有部分证据,未完整验收 | 本轮浏览器:接口 501 后显示失败,原对白/两镜头保留,完成数 0/2;此前浏览器风格编辑与刷新 | 仅验证本地失败分支;真实合成成功与批量部分失败未验收。 |
|
||||
| 06-16 | 合成提示词/全部合成 | 有部分证据,未完整验收 | 本轮浏览器:接口 501 后显示失败,原对白/两镜头保留,完成数 0/2;此前浏览器风格编辑与刷新 | 仅验证本地失败分支;真实合成成功与批量部分失败未验收。 |
|
||||
| 06-17 | 合成提示词/风格来源 | 有部分证据,未完整验收 | 本轮浏览器:接口 501 后显示失败,原对白/两镜头保留,完成数 0/2;此前浏览器风格编辑与刷新 | 仅验证本地失败分支;真实合成成功与批量部分失败未验收。 |
|
||||
| 06-18 | 输出/批量分镜 | 仍有问题(F05) | 本轮执行链检查 | 不是完整自动批量生成;无首帧时仍选择首帧模型,时长未按离散规格约束。 |
|
||||
| 06-19 | 输出/批量视频 | 仍有问题(F05) | 本轮执行链检查 | 不是完整自动批量生成;无首帧时仍选择首帧模型,时长未按离散规格约束。 |
|
||||
| 06-20 | 输出/导出 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 06-21 | 脚本/旧版 | 仍有问题(F04,F07) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 07 音频、配音和音色
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 07-01 | 音频/模型选择 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-02 | 音频/生成提交 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-03 | 音频/草稿恢复 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-04 | 音频/停顿语气 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-05 | 音频/翻译 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-06 | 音频/语速声调音量 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-07 | 音频/音高强度音色 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-08 | 音频/音效 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-09 | 音频/重置 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-10 | 音频/语言 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-11 | 音频/采样率 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-12 | 音频/格式 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-13 | 音色/列表 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-14 | 音色/试听选择 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-15 | 音色/搜索筛选 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-16 | 音色/收藏分页 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-17 | 音色/克隆 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-18 | 音乐/生成 | 缺失或停用 | 本轮代码检查 | TTS、音乐、音色克隆及这些参数能力未实现;不能记为验收通过。 |
|
||||
| 07-19 | 音频生视频/模型匹配 | 仍有问题(F07) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 07-20 | 音频/播放已上传音轨 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 08 3D 导演台:场景与角色
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 08-01 | 场景/真实渲染 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-02 | 场景/视角 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-03 | 场景/对象搜索 | 有部分证据,未完整验收 | 本轮场景序列化回归通过;此前代码检查 | 需逐控件浏览器验收,锁定只限制变换轴,颜色只适用于基本对象。 |
|
||||
| 08-04 | 场景/显隐锁定 | 有部分证据,未完整验收 | 本轮场景序列化回归通过;此前代码检查 | 需逐控件浏览器验收,锁定只限制变换轴,颜色只适用于基本对象。 |
|
||||
| 08-05 | 场景/重命名 | 有部分证据,未完整验收 | 本轮场景序列化回归通过;此前代码检查 | 需逐控件浏览器验收,锁定只限制变换轴,颜色只适用于基本对象。 |
|
||||
| 08-06 | 场景/移动旋转缩放 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-07 | 场景/旋转单位 | 有部分证据,未完整验收 | 本轮场景序列化回归通过;此前代码检查 | 需逐控件浏览器验收,锁定只限制变换轴,颜色只适用于基本对象。 |
|
||||
| 08-08 | 场景/统一缩放 | 有部分证据,未完整验收 | 本轮场景序列化回归通过;此前代码检查 | 需逐控件浏览器验收,锁定只限制变换轴,颜色只适用于基本对象。 |
|
||||
| 08-09 | 场景/颜色 | 有部分证据,未完整验收 | 本轮场景序列化回归通过;此前代码检查 | 需逐控件浏览器验收,锁定只限制变换轴,颜色只适用于基本对象。 |
|
||||
| 08-10 | 角色/八种体型 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-11 | 角色/二十种姿势 | 有部分证据,未完整验收 | 本轮姿势数据/往返回归;此前浏览器 T 型、招手姿势 | 其余 10 种姿势逐一视觉检查未做;参考站 20 姿势及手工关节编辑未齐。 |
|
||||
| 08-12 | 角色/身体躯干头部 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-13 | 角色/肩肘髋膝 | 有部分证据,未完整验收 | 本轮姿势数据/往返回归;此前浏览器 T 型、招手姿势 | 其余 10 种姿势逐一视觉检查未做;参考站 20 姿势及手工关节编辑未齐。 |
|
||||
| 08-14 | 角色/群众阵列 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-15 | 角色/本地模型 | 有部分证据,未完整验收 | 此前真实 GLB 链路;本轮 GLB 完整性/代理契约回归 | 弱网、损坏文件、超大 GLB、WebGL 丢失与导入中关闭的实际浏览器行为待验。 |
|
||||
| 08-16 | 角色/几何模型 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-17 | 全景/上传背景 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-18 | 全景/历史记录 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-19 | 全景/AI 生成 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-20 | AI 导入/图源选择 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-21 | AI 导入/插入与覆盖 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 08-22 | AI 导入/关闭继续任务 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 09 3D 导演台:机位、轨迹、输出
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 09-01 | 机位/预设 | 有部分证据,未完整验收 | 此前浏览器正面预设与环绕导出;本轮相机数据回归;此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 12 机位逐项视觉和小屏布局未全验;不是自动跟随。 |
|
||||
| 09-02 | 机位/切换 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-03 | 机位/位置与注视坐标 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-04 | 机位/手动旋转 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-05 | 机位/跟随对象 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-06 | 机位/注视对象 | 有部分证据,未完整验收 | 此前浏览器正面预设与环绕导出;本轮相机数据回归;此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 12 机位逐项视觉和小屏布局未全验;不是自动跟随。 |
|
||||
| 09-07 | 机位/FOV | 有部分证据,未完整验收 | 此前浏览器正面预设与环绕导出;本轮相机数据回归;此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 12 机位逐项视觉和小屏布局未全验;不是自动跟随。 |
|
||||
| 09-08 | 机位/画幅比例 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-09 | 时间轴/布局 | 有部分证据,未完整验收 | 此前浏览器正面预设与环绕导出;本轮相机数据回归;此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 12 机位逐项视觉和小屏布局未全验;不是自动跟随。 |
|
||||
| 09-10 | 时间轴/播放暂停跳转 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-11 | 时间轴/总时长 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-12 | 时间轴/单位与缩放 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-13 | 时间轴/自动帧 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-14 | 时间轴/多轨 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-15 | 时间轴/属性轨 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-16 | 关键帧/编辑删除 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-17 | 轨迹/圆环直线矩形 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-18 | 轨迹/铅笔钢笔 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-19 | 轨迹/变换与朝向 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-20 | 轨迹/查看全路径 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-21 | 轨迹/平滑插值 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-22 | 轨迹/JSON 导入导出 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-23 | 输出/机位截图 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商) | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-24 | 输出/运镜视频 | 有部分证据,未完整验收 | 此前实测记录(见 director-chain/director-motion/real-test/aliyun-test 文档;本轮未重跑供应商);本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-25 | 输出/AI 生视频 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 09-26 | 输出/取消与切后台 | 有部分证据,未完整验收 | 本轮相关契约/算法回归通过;不覆盖全部 UI 与真实接口 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
## 10 素材、历史、模板与公共入口
|
||||
|
||||
| ID | 子功能 | 验证结论 | 证据 | 剩余工作 |
|
||||
|---|---|---|---|---|
|
||||
| 10-01 | 模板/工具箱 | 仍有问题(F03) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-02 | 模板/我的工具箱 | 仍有问题(F07) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-03 | 风格/广场分类 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-04 | 风格/收藏最近 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-05 | 特效/收藏最近 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-06 | 角色库/筛选 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-07 | 角色库/四类图片 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-08 | 运镜库/自定义收藏 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-09 | 历史/全部与本画布 | 有部分证据,未完整验收 | 此前空素材浏览器验收;本轮源码复核 | 素材选择弹窗仍有无处理函数的分页控件;大量素材滚动可达性未验。 |
|
||||
| 10-10 | 历史/示例混入 | 有部分证据,未完整验收 | 此前空素材浏览器验收;本轮源码复核 | 素材选择弹窗仍有无处理函数的分页控件;大量素材滚动可达性未验。 |
|
||||
| 10-11 | 历史/分页数量 | 仍有问题(F06) | 此前空素材浏览器验收;本轮源码复核 | 素材选择弹窗仍有无处理函数的分页控件;大量素材滚动可达性未验。 |
|
||||
| 10-12 | 历史/日期与排序 | 有部分证据,未完整验收 | 此前空素材浏览器验收;本轮源码复核 | 素材选择弹窗仍有无处理函数的分页控件;大量素材滚动可达性未验。 |
|
||||
| 10-13 | 历史/批量下载 | 有部分证据,未完整验收 | 本轮原始音频字节下载回归 | 认证下载/ZIP 部分失败、大文件、过期URL、Safari 下载本轮未端到端。 |
|
||||
| 10-14 | 历史/删除 | 有部分证据,未完整验收 | 本轮代码检查 | 非源文件删除;隐藏状态在数据库保存/刷新未本轮验收。 |
|
||||
| 10-15 | 历史/评级保存资产 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-16 | 资产管理/节点定位 | 有部分证据,未完整验收 | 本轮浏览器收起→节点消失→展开恢复;本轮浏览器:画布脚本筛选→素材默认全部→视频筛选→画布仍脚本 | 跨项目个人/Agent 资产库未实现;定位、重命名、下载仍需完整应用验收。 |
|
||||
| 10-17 | 资产管理/列表宫格 | 待专项验证 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-18 | 资产管理/个人与Agent | 有部分证据,未完整验收 | 本轮浏览器收起→节点消失→展开恢复;本轮浏览器:画布脚本筛选→素材默认全部→视频筛选→画布仍脚本 | 跨项目个人/Agent 资产库未实现;定位、重命名、下载仍需完整应用验收。 |
|
||||
| 10-19 | 资产管理/文件夹上传 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-20 | 分享/公开链接 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-21 | 发布/发布作品 | 仍有问题(F07) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-22 | Agent/对话及引用 | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-23 | Agent/Skills | 缺失或停用 | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-24 | Agent/生成权限与通知 | 仍有问题(F07) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
| 10-25 | 帮助/快捷键教程 | 有部分证据,未完整验收 | 本轮代码检查 | 全画布撤销、分组等原参考能力未实现。 |
|
||||
| 10-26 | 账户/积分 | 仍有问题(F07) | 基线代码对照;缺少可复验的专项结果 | 需要逐状态功能验收;不能以存在代码作为通过依据。 |
|
||||
|
||||
3151
docs/video-canvas-validation-scan-2026-09-17.json
Normal file
3151
docs/video-canvas-validation-scan-2026-09-17.json
Normal file
File diff suppressed because it is too large
Load Diff
64
docs/video-canvas-validation-scan-2026-09-17.md
Normal file
64
docs/video-canvas-validation-scan-2026-09-17.md
Normal file
@ -0,0 +1,64 @@
|
||||
# 视频画布全面验证扫描 · 2026-09-17
|
||||
|
||||
结论:**仍有未验证功能,也有已确认但尚未修复的功能缺口,不能判定全面验收通过。** 本轮以 `f10e6b7c` 为代码起点,核对原 10 组、231 项对照清单,追踪活动页面的调用、请求和保存流程,补跑相关回归与实际组件浏览器验证。没有重新提交付费模型任务,没有重新实测参考网站,也没有部署 48 服务器。
|
||||
|
||||
## 证据范围
|
||||
|
||||
| 分类 | 项数 | 含义 |
|
||||
|---|---:|---|
|
||||
| 待专项验证 | 56 | 主要有代码/对照记录,缺少对应的专项验收证据 |
|
||||
| 有部分证据,未完整验收 | 80 | 有代码检查、契约回归、本地组件或历史实测之一;不等于全链路通过 |
|
||||
| 仍有问题 | 16 | 关联下方 F01–F07 的具体问题;多个条目可属于同一问题 |
|
||||
| 缺失或停用 | 79 | 没有等价实现,或已明确禁用;不是单纯漏测 |
|
||||
| 合计 | 231 | 分类为保守的验证工作清单,**不是产品完成率** |
|
||||
|
||||
完整逐项清单:[验证矩阵](video-canvas-validation-matrix-2026-09-17.md),机器可读数据:[验证 JSON](video-canvas-validation-scan-2026-09-17.json)。原对照文件是旧基线,本次没有把旧状态全部改成“已完成”。
|
||||
|
||||
## 本轮确认的未完成项
|
||||
|
||||
| 编号 | 级别 | 触发与结果 | 证据位置 | 后续验收要求 |
|
||||
|---|---|---|---|---|
|
||||
| F01 | P1 | 生成中刷新/重开:保存的 pending 节点没有重新查询视频任务;本地定时器仍将进度推到 96%。局部编辑有 taskId,但轮询仅从提交入口启动,加载时未恢复 | `LiblibVideoCanvasReplica.tsx`:加载约 4922、定时器 5052、局部编辑 7214/7471;`services/canvas/index.ts` 的 generateVideo 为一次 HTTP 请求 | 服务端持久任务 ID、查询/续订、过期状态;真实刷新、断网、切后台、重开后恢复成功/失败,且不重复扣费。仅切后台是否必然失败本轮没有实测结论 |
|
||||
| F02 | P1 | “取消生成”→“确定”只关闭弹窗;请求仍继续。弹窗却写“停止将不退还算力” | 活动根组件约 10807:onCancel/onConfirm 都只 setCancelGenerationConfirmNodeId(null) | 明确上游能否取消;不能取消时真实告知。排队取消、执行中取消、取消后晚到结果分别验证 |
|
||||
| F03 | P1 | 快捷模板仍注入示例素材;角色三视图、首帧模板直接设 generated:true,未执行真实生成 | createStarterWorkflow 约 4588;getConfiguredReferenceAsset 约 3490 | 示例清楚标识;未运行节点不标生成完成,历史/导出不混淆样例与用户结果 |
|
||||
| F04 | P1 | 脚本弹窗“重新生成”调用 runNode;连入图片/视频后会选择 image-to-prompt/agent-plan。工具栏另一路却使用 story-script;此外 success:true 但空数据仍可能标完成 | 弹窗 onRun 约 11350;runNode 约 9740;runStoryScriptToolbarAction 约 8352 | 相同脚本在两入口生成应走同一功能契约;空响应、缺镜头字段保留旧稿并报告失败 |
|
||||
| F05 | P1 | “批量生视频”目前只创建生成器;没有首帧也取首帧模型;时长只限 2–15 秒,不遵守模型离散时长 | runStoryScriptToolbarAction 约 8623–8660 | 无图选兼容文生模式或拦截;批量真正执行、规格约束、部分失败续跑、刷新恢复 |
|
||||
| F06 | P1 | 素材选择弹窗仍保留无处理函数的上一页/下一页、“15条/页”和跳页外观;一次渲染所有素材,容器没有明确的纵向滚动,超一屏可达性待验。卡片垃圾桶/预览是 span | HistoryAssetPickerModal 约 23016–23190 | 去掉假分页或接真实分页;超过 15/100 条、最后一项可选、预览/删除行为和选择上限分别验收 |
|
||||
| F07 | P2 | 仍有仅提示“待接入”或无行为的次级控件:文本翻译、音频生视频高级设置/展开、旧脚本编辑、我的工具箱、通知分类、发布和账户退出等 | TextTargetModuleComposer、AudioToVideoComposerPanel、PresetScriptCanvasNode、WorkflowPanel、NotificationsPopover、PublishModal、AccountPopover | 与主入口逐一比对;接通或明确禁用,不能用主入口成功覆盖旧入口 |
|
||||
|
||||
上述判断来自代码调用链;没有把它们描述为全部浏览器复现。F01/F02 是优先项,关系到用户看到的长时间处理中和重复提交风险。
|
||||
|
||||
## 本轮修复并补验的三个小问题
|
||||
|
||||
1. **多角度方向箭头**:鱼眼/倾斜选中后,箭头修改数值仍保留特殊预设,提交会走特殊提示词路径。四个方向按钮现与滑块一致切到“自定义”。实际组件浏览器复现修复前 `preset=鱼眼视角,horizontalAngle=10`,修复后为 `preset=自定义,horizontalAngle=10`;本轮没有请求供应商生成图片。
|
||||
2. **资产管理收起列表**:原先只转动箭头,节点仍显示。现在收起真正隐藏节点行,展开恢复,文案改成“节点列表”,不冒充全画布分组。浏览器已验证消失和恢复。
|
||||
3. **画布/素材筛选串状态**:原先同一 filter 同时用于“脚本/导演台”和“图片/视频/音频”,切页可留下素材下拉框没有的选项。现在两套筛选各自保持;浏览器验证画布选“脚本”→素材默认为“全部”→素材选“视频”→返回画布仍为“脚本”。
|
||||
|
||||
另补验脚本合成的失败分支:本地静态服务器对真实分析请求返回 501,页面显示“工作流分析失败”,保留两行脚本和已修改对白,提示词完成数仍为 0/2。该结果只证明组件对这类失败的处理,不代表生产分析服务成功。
|
||||
|
||||
## 自动化检查
|
||||
|
||||
- 视频画布专项六组:**56 项通过,无跳过**;包括真实本地 FFmpeg 视频截帧、2/3/5 倍慢放及音轨验证。
|
||||
- 扩展 helpers 全量首轮:423 项中 421 通过,2 项模型目录用例失败。追溯到 2026-09-07 的 `e49b0707e`:目录已要求明确的多图输入契约,旧用例只有 image-to-image 标签。既有 `vip98k-reference-routing` 测试也要求不能从宽泛标签推断多图能力。
|
||||
- 补齐旧用例的数组输入 schema,并新增“只有标签/单图字符串 schema 必须拒绝”的反例,**未放宽生产筛选规则**。模型分类与参考路由专项 52 项通过。
|
||||
- 最终全量:**424 项通过,无失败、无跳过**。这 424 项是当前 `playwright.helpers.config.ts` 中的 helper/route 契约回归,**不是 424 个完整页面端到端测试,也不是全部供应商实测**。
|
||||
- TypeScript 检查通过(最终提交前重跑)。
|
||||
|
||||
复现:FFmpeg/ffprobe 加入 PATH 后执行 `pnpm exec playwright test --config=playwright.helpers.config.ts`。若未安装这两个程序,媒体测试会跳过,不能沿用“真实媒体通过”的结论。
|
||||
|
||||
## 活动入口扫描方式
|
||||
|
||||
`node scripts/audit/video-canvas-controls.cjs output.json` 用 TypeScript AST 从实际入口 `LiblibVideoCanvasReplica` 追踪本文件标识符引用,记录缺少直接事件/仅提示类控件的候选。本轮 400 个可达声明、41 个未引用函数、53 条控件候选。候选列表见 [控件扫描 JSON](video-canvas-control-scan-2026-09-17.json)。
|
||||
|
||||
这是保守静态扫描,不是运行时覆盖率:组合组件可用其他回调,submit 按钮可由 form 处理,恒为 false 的分支仍可能被扫描到。因此 **53 条候选不等于 53 个故障**。例如 VideoArchiveButton/工作流组合组件有真实回调;运镜搜索走 form submit;ZoomDock 的 compact 分支未在当前调用启用。旧 DirectorConsole3DDialog 等 41 个未引用函数未用于证明当前活动导演台故障;实际 3D 在 `components/canvas/director/` 中复核并由对应回归覆盖。
|
||||
|
||||
## 下一轮必须补齐的验证
|
||||
|
||||
- **任务生命周期**:刷新、断网重连、浏览器后台、退出重开、重复点击、批量中的取消/删除、多标签同时编辑;现有保存队列单测不能代替这些场景。
|
||||
- **生成与脚本**:逐模型/模式规格、真实多张返回、批量混合成败、脚本单镜/全部合成成功、资产生成上传、脚本到图片再到视频完整闭环。历史某条供应商线路成功不等于今天所有线路通过。
|
||||
- **素材与后期**:超过一屏的素材、跨域/过期 URL、ZIP 部分失败、音频上传格式与时长边界、网页播放器当前时间截帧、无音轨文件、长视频资源占用。
|
||||
- **3D 导演台**:全部 12 姿势/12 机位逐项视觉检查,4 类轨迹浏览器端运行;弱网/损坏/超大 GLB,WebGL 上下文丢失,切后台中断导出,多浏览器编码格式与生产上传。既有单测和历史一条 MP4 导出不足以覆盖这些情况。
|
||||
- **布局与一致性**:不同分辨率、缩放、空态/加载/失败/完成逐状态像素比对;本轮没有新增与参考站像素一致的结论。
|
||||
- **尚缺实现**:TTS/音乐/音色、智能剪辑、多画布/故事板/Agent、跨项目资产、专用后期、3D 多轨/自动帧/跟随/自由路径等,需先实现再验收。
|
||||
|
||||
本轮范围止于扫描、三处明确界面修复及回归记录。F01–F07 未因本次扫描自动视作修复;线上版本也不会因分支推送自动更新。
|
||||
10
scripts/audit/video-canvas-controls.cjs
Normal file
10
scripts/audit/video-canvas-controls.cjs
Normal file
@ -0,0 +1,10 @@
|
||||
// Run from repository root: node scripts/audit/video-canvas-controls.cjs [output.json]
|
||||
const fs=require('fs'),ts=require('typescript');
|
||||
const file='components/canvas/LiblibVideoCanvasReplica.tsx';
|
||||
const source=ts.createSourceFile(file,fs.readFileSync(file,'utf8'),ts.ScriptTarget.Latest,true,ts.ScriptKind.TSX);
|
||||
const decls=new Map();
|
||||
for(const s of source.statements){if(ts.isFunctionDeclaration(s)&&s.name)decls.set(s.name.text,s);if(ts.isVariableStatement(s))for(const d of s.declarationList.declarations)if(ts.isIdentifier(d.name))decls.set(d.name.text,d);}
|
||||
const live=new Set();function visitName(name){if(live.has(name)||!decls.has(name))return;live.add(name);function walk(n){if(ts.isIdentifier(n)&&n!==decls.get(name).name)visitName(n.text);ts.forEachChild(n,walk);}walk(decls.get(name));}visitName('LiblibVideoCanvasReplica');
|
||||
const findings=[];for(const[name,node]of decls){if(!live.has(name))continue;function walk(n){if(ts.isJsxOpeningElement(n)||ts.isJsxSelfClosingElement(n)){const tag=n.tagName.getText(source);if(tag==='button'||tag.includes('Button')||tag.includes('Control')){const attrs=n.attributes.properties.filter(ts.isJsxAttribute);const click=attrs.find(a=>a.name.text==='onClick');const txt=n.parent.getText(source); if(!click&&!attrs.some(a=>['disabled','onPointerDown','onMouseDown'].includes(a.name.text))||click&&/toast\.(info|success)/.test(click.getText(source)))findings.push({owner:name,line:source.getLineAndCharacterOfPosition(n.getStart(source)).line+1,tag,handler:click?.getText(source)||'',snippet:txt.slice(0,650)});}}ts.forEachChild(n,walk);}walk(node);}
|
||||
const out={file,root:'LiblibVideoCanvasReplica',method:'Conservative identifier reachability; candidates need manual review, not runtime coverage.',reachableDeclarations:[...live],unreachableFunctions:[...decls].filter(([n,d])=>ts.isFunctionDeclaration(d)&&!live.has(n)).map(([name])=>name),candidates:findings};if(process.argv[2]) fs.writeFileSync(process.argv[2],JSON.stringify(out,null,2));
|
||||
console.log(JSON.stringify({reachable:live.size,deadFunctions:out.unreachableFunctions.length,candidateCount:findings.length},null,2));
|
||||
@ -441,7 +441,7 @@ test.describe("AI model media classification", () => {
|
||||
expect(isVip98kImageModelVisible(models[3])).toBe(false);
|
||||
});
|
||||
|
||||
test("excludes pure text image/video models but keeps reference and 3D models", () => {
|
||||
test("excludes pure text models but keeps documented multi-image, reference video and 3D models", () => {
|
||||
expect(
|
||||
isVip98kCatalogModelEligible({
|
||||
modelId: "openai/gpt-image-2/text-to-image",
|
||||
@ -459,6 +459,7 @@ test.describe("AI model media classification", () => {
|
||||
expect(
|
||||
isVip98kCatalogModelEligible({
|
||||
modelId: "google/nano-banana-2/edit",
|
||||
invocation: { input_schema: { properties: { images: { type: "array", items: { type: "string" } } } } },
|
||||
type: "image",
|
||||
capabilities: ["text-to-image", "image-to-image"],
|
||||
}),
|
||||
@ -479,6 +480,14 @@ test.describe("AI model media classification", () => {
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("does not advertise multi-image editing from a single-image schema or capability tag", () => {
|
||||
const model = { modelId: "single-image-edit", type: "image" as const, capabilities: ["image_to_image"] };
|
||||
expect(isVip98kCatalogModelEligible(model)).toBe(false);
|
||||
expect(isVip98kCatalogModelEligible({ ...model, invocation: {
|
||||
input_schema: { properties: { image: { type: "string" } } },
|
||||
} })).toBe(false);
|
||||
});
|
||||
|
||||
test("excludes catalog models explicitly marked unavailable", () => {
|
||||
expect(
|
||||
isVip98kCatalogModelEligible({
|
||||
@ -490,7 +499,7 @@ test.describe("AI model media classification", () => {
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("excludes VIP98K text-to-image models without applying a price limit", () => {
|
||||
test("requires documented multi-image input without applying a price limit", () => {
|
||||
const presets = buildVip98kModelPresets([
|
||||
{
|
||||
modelId: "pure-text-to-image",
|
||||
@ -500,12 +509,14 @@ test.describe("AI model media classification", () => {
|
||||
},
|
||||
{
|
||||
modelId: "mixed-image-model",
|
||||
invocation: { input_schema: { properties: { images: { type: "array", items: { type: "string" } } } } },
|
||||
type: "image",
|
||||
capabilities: ["text_to_image", "image_to_image"],
|
||||
pricing: { effective_price: 0.2 },
|
||||
},
|
||||
{
|
||||
modelId: "expensive-image-edit",
|
||||
invocation: { input_schema: { properties: { images: { type: "array", items: { type: "string" } } } } },
|
||||
type: "image",
|
||||
capabilities: ["image_to_image"],
|
||||
pricing: { effective_price: 2.5 },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user