feat(ark-assets): 方舟素材库 - 支持私域素材授权 (#294)

This commit is contained in:
kinoko
2026-08-23 08:27:55 +08:00
committed by GitHub
parent 1bb5d1423a
commit d77432693e
25 changed files with 1072 additions and 4 deletions

View File

@@ -296,6 +296,7 @@ function videoConfigPatch(key: keyof AiConfig, value: string) {
if (key === "videoSeconds") return { seconds: value };
if (key === "videoGenerateAudio") return { generateAudio: value };
if (key === "videoWatermark") return { watermark: value };
if (key === "videoArkPrivateAssetUpload") return { arkPrivateAssetUpload: value };
return { [key]: value };
}

View File

@@ -1,6 +1,6 @@
import { AnimatePresence, useReducedMotion } from "motion/react";
import { useEffect, useState, type CSSProperties, type ReactNode } from "react";
import { ArrowLeft, Check, ChevronRight, Clipboard, Copy, FolderOpen, FolderPlus, Image as ImageIcon, Layers3, Link2, Maximize2, PanelTop, Pencil, Plus, Redo2, Tags, Trash2, Undo2, Upload, UserRound } from "lucide-react";
import { ArrowLeft, Check, ChevronRight, Clipboard, CloudUpload, Copy, FolderOpen, FolderPlus, Image as ImageIcon, Layers3, Link2, Maximize2, PanelTop, Pencil, Plus, Redo2, Tags, Trash2, Undo2, Upload, UserRound } from "lucide-react";
import { CanvasCreateMenu, type CanvasCreateCommand } from "@/components/canvas/canvas-create-menu";
import { aceternityMotion } from "@/lib/aceternity-motion";
@@ -53,6 +53,7 @@ type CanvasNodeContextMenuProps = {
onGenerateImage: () => void;
onCopyContent: () => void;
onCopyMediaUrl: () => void;
onUploadToArkPrivateAsset: () => void;
onSetAssetCategory: (category: CanvasAssetCategory) => void;
onToggleFrame: () => void;
};
@@ -86,6 +87,7 @@ export function CanvasNodeContextMenu({
onGenerateImage,
onCopyContent,
onCopyMediaUrl,
onUploadToArkPrivateAsset,
onSetAssetCategory,
onToggleFrame,
}: CanvasNodeContextMenuProps) {
@@ -200,6 +202,7 @@ export function CanvasNodeContextMenu({
<MenuSection label="查看与归档" />
<MenuButton icon={<Maximize2 />} label="进入全景预览" disabled={!canOpenPreview} onClick={() => runAction(onViewMedia)} />
<MenuButton icon={<Tags />} label="设置资产分类" chevron onClick={() => setCategoryOpen(true)} />
{isImage ? <MenuButton icon={<CloudUpload />} label="上传到方舟素材库" onClick={() => runAction(onUploadToArkPrivateAsset)} /> : null}
<MenuDivider />
<MenuSection label="节点" />
<MenuButton icon={<Copy />} label="复制节点" shortcut="⌘C" onClick={() => runAction(onCopyNode)} />

View File

@@ -652,6 +652,7 @@ function videoConfigPatch(key: keyof AiConfig, value: string) {
if (key === "videoSeconds") return { seconds: value };
if (key === "videoGenerateAudio") return { generateAudio: value };
if (key === "videoWatermark") return { watermark: value };
if (key === "videoArkPrivateAssetUpload") return { arkPrivateAssetUpload: value };
return { [key]: value };
}

View File

@@ -19,7 +19,7 @@ const sizeOptions = [
type VideoSettingsPanelProps = {
config: AiConfig;
onConfigChange: (key: "vquality" | "size" | "videoSeconds" | "videoGenerateAudio" | "videoWatermark", value: string) => void;
onConfigChange: (key: "vquality" | "size" | "videoSeconds" | "videoGenerateAudio" | "videoWatermark" | "videoArkPrivateAssetUpload", value: string) => void;
theme: CanvasTheme;
showTitle?: boolean;
className?: string;
@@ -117,6 +117,8 @@ function SeedanceVideoSettingsPanel({ config, profile, priceTiers, onConfigChang
const duration = normalizeSeedanceDuration(config.videoSeconds);
const generateAudio = boolConfig(config.videoGenerateAudio, profile.generateAudio.default);
const watermark = boolConfig(config.videoWatermark, profile.watermark.default);
const useArkPrivateAssets = boolConfig(config.videoArkPrivateAssetUpload, true);
const isArkSeedance = resolveModelRequestConfig(config, config.model).interfaceType === "volcengine-ark-video";
return (
<ImageSettingsTheme theme={theme}>
@@ -167,6 +169,13 @@ function SeedanceVideoSettingsPanel({ config, profile, priceTiers, onConfigChang
{profile.watermark.supported ? <SwitchRow label="添加水印" checked={watermark} theme={theme} onChange={(checked) => onConfigChange("videoWatermark", String(checked))} /> : null}
</div>
</SettingGroup>
{isArkSeedance ? (
<SettingGroup title="参考图" color={theme.node.muted}>
<div className="rounded-md px-2" style={{ background: theme.toolbar.itemHover }}>
<SwitchRow label="自动同步可信素材(确认拥有使用权)" checked={useArkPrivateAssets} theme={theme} onChange={(checked) => onConfigChange("videoArkPrivateAssetUpload", String(checked))} />
</div>
</SettingGroup>
) : null}
</div>
</ImageSettingsTheme>
);