Initial ecommerce standalone package

This commit is contained in:
2026-06-10 14:06:16 +08:00
commit 3d98933e24
241 changed files with 135283 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
const OSS_PUBLIC_BASE_URL = "https://stringtest.oss-cn-hangzhou.aliyuncs.com";
function oss(path: string): string {
return `${OSS_PUBLIC_BASE_URL}/${path.replace(/^\/+/, "")}`;
}
function muban(path: string): string {
return oss(`muban/${path.replace(/^\/+/, "")}`);
}
function toolbox(path: string): string {
return oss(`static/toolbox/${path.replace(/^\/+/, "")}`);
}
export const ossAssets = {
brand: {
logo: oss("logo.png"),
},
auth: {
showcaseVideo: oss("test5.mp4"),
},
home: {
backgroundVideo: muban("hero-bg.mp4"),
heroSlides: [oss("static/banners/light2_轮播1.jpg"), oss("static/banners/light2_轮播2.jpg"), oss("static/banners/light2_轮播3.jpg")],
features: {
ecommerce: muban("feature-ecommerce.jpg"),
script: muban("feature-script.jpg"),
token: muban("feature-token.jpg"),
},
},
toolbox: {
imageBefore: toolbox("%E7%89%9B%E4%BB%94.webp"),
imageAfter: toolbox("%E8%A5%BF%E8%A3%85.webp"),
watermarkBefore: toolbox("%E5%8E%BB%E6%B0%B4%E5%8D%B0%E5%89%8D.webp"),
watermarkAfter: toolbox("%E5%8E%BB%E6%B0%B4%E5%8D%B0%E5%90%8E.webp"),
},
community: {
cardImages: [
muban("dianshang1.png"),
muban("dianshang2.png"),
muban("dianshang3.png"),
muban("wechat-7.png"),
muban("wechat-8.png"),
muban("wechat-9.png"),
],
carouselVideos: [oss("test3.mp4"), oss("test4.mp4"), oss("test6.mp4")],
},
workflows: {
caseImages: [
muban("community/workflow-rain-night.jpg"),
muban("community/workflow-character-look.jpg"),
muban("community/workflow-skyline.jpg"),
muban("community/workflow-lab.jpg"),
],
},
ecommerce: {
generated: muban("ecommerce-carousel-generated.png"),
slides: {
slide4: muban("slide-4.png"),
slide5: muban("slide-5.png"),
},
heroSlides: [
muban("ecommerce-hero-carousel/slide-1.webp"),
muban("ecommerce-hero-carousel/slide-2.webp"),
muban("ecommerce-hero-carousel/slide-3.webp"),
muban("ecommerce-hero-carousel/slide-4.webp"),
muban("ecommerce-hero-carousel/slide-5.webp"),
],
templateSlides: [
muban("more-template-carousel/slide-1.jpg"),
muban("more-template-carousel/slide-2.jpg"),
muban("more-template-carousel/slide-3.jpg"),
muban("more-template-carousel/slide-4.png"),
muban("more-template-carousel/slide-5.gif"),
],
templateCases: [
muban("ecommerce/templates/case-1.png"),
muban("ecommerce/templates/case-2.png"),
muban("ecommerce/templates/case-3.png"),
muban("ecommerce/templates/case-4.png"),
muban("ecommerce/templates/case-5.png"),
muban("ecommerce/templates/case-6.png"),
],
productSet: {
main: muban("ecommerce/product-set/main.webp"),
scene: muban("ecommerce/product-set/scene.webp"),
model: muban("ecommerce/product-set/model.webp"),
detail: muban("ecommerce/product-set/detail.webp"),
selling: muban("ecommerce/product-set/selling.webp"),
hosting: muban("ecommerce/product-set/hosting.webp"),
},
tryOn: {
dressA: muban("ecommerce/try-on/dress-a.webp"),
dressB: muban("ecommerce/try-on/dress-b.webp"),
modelWoman: muban("ecommerce/try-on/model-woman.webp"),
modelMan: muban("ecommerce/try-on/model-man.webp"),
modelAsian: muban("ecommerce/try-on/model-asian.webp"),
tryA: muban("ecommerce/try-on/result-a.webp"),
tryB: muban("ecommerce/try-on/result-b.webp"),
jacket: muban("ecommerce/try-on/jacket.webp"),
jacketResultA: muban("ecommerce/try-on/jacket-result-a.webp"),
jacketResultB: muban("ecommerce/try-on/jacket-result-b.webp"),
hat: muban("ecommerce/try-on/hat.webp"),
hatResultA: muban("ecommerce/try-on/hat-result-a.webp"),
hatResultB: muban("ecommerce/try-on/hat-result-b.webp"),
},
detail: {
productA: muban("ecommerce/detail/product-a.webp"),
productB: muban("ecommerce/detail/product-b.webp"),
productC: muban("ecommerce/detail/product-c.webp"),
longPage: muban("ecommerce/detail/long-page.webp"),
gridA: muban("ecommerce/detail/grid-a.webp"),
gridB: muban("ecommerce/detail/grid-b.webp"),
gridC: muban("ecommerce/detail/grid-c.webp"),
gridD: muban("ecommerce/detail/grid-d.webp"),
gridE: muban("ecommerce/detail/grid-e.webp"),
gridF: muban("ecommerce/detail/grid-f.webp"),
},
},
} as const;
export type ProductSetOssAssets = typeof ossAssets.ecommerce.productSet;
export type TryOnOssAssets = typeof ossAssets.ecommerce.tryOn;
export type DetailOssAssets = typeof ossAssets.ecommerce.detail;
+182
View File
@@ -0,0 +1,182 @@
import type { WebCanvasWorkflow, WebCommunityCase } from "../types";
import { ossAssets } from "./ossAssets";
const [rainNightImage, characterLookImage, skylineImage, labImage] = ossAssets.workflows.caseImages;
function createNodes(
title: string,
previewUrl: string,
model = "Seedance 2.0",
): WebCanvasWorkflow["nodes"] {
return [
{
id: "prompt",
kind: "prompt",
label: "提示词",
detail: title,
position: { x: 90, y: 120 },
},
{
id: "reference",
kind: "image",
label: "参考图",
detail: "社区分享的视觉锚点",
position: { x: 380, y: 70 },
previewUrl,
},
{
id: "motion",
kind: "model",
label: "镜头与运动",
detail: "推镜、摇移、节奏",
position: { x: 720, y: 170 },
},
{
id: "output",
kind: "output",
label: "视频输出",
detail: `${model} 预览渲染`,
position: { x: 1020, y: 100 },
},
];
}
function createEdges(): WebCanvasWorkflow["edges"] {
return [
{ id: "prompt-reference", source: "prompt", target: "reference", label: "参考", animated: true },
{ id: "reference-motion", source: "reference", target: "motion", label: "运动", animated: true },
{ id: "motion-output", source: "motion", target: "output", label: "生成", animated: true },
];
}
export const blankCanvasWorkflow: WebCanvasWorkflow = {
id: "workflow-blank",
version: 1,
title: "新建创作",
description: "从空白画布开始,直接进入节点式创作。",
source: "blank",
settings: {
model: "Seedance 2.0",
ratio: "16:9",
duration: "6s",
resolution: "720p",
},
nodes: [],
edges: [],
};
export const communityCases: WebCommunityCase[] = [
{
id: "case-01",
title: "雨夜推镜",
author: "Dave",
tag: "视频案例",
summary: "从街口推到人物面部,强调雨夜反光与情绪收束。",
imageUrl: rainNightImage,
workflow: {
id: "workflow-rain-night",
version: 1,
title: "雨夜推镜",
description: "城市雨夜案例,突出推镜和情绪转场。",
author: "Dave",
source: "community",
settings: {
model: "Seedance 2.0",
ratio: "16:9",
duration: "6s",
resolution: "720p",
},
nodes: createNodes("雨夜街巷,镜头从水面倒影推进到人物特写", rainNightImage),
edges: createEdges(),
},
},
{
id: "case-02",
title: "角色定妆",
author: "SuperXe",
tag: "角色案例",
summary: "把单张角色图扩展成可连续出片的角色工作流。",
imageUrl: characterLookImage,
workflow: {
id: "workflow-character-look",
version: 1,
title: "角色定妆",
description: "角色定妆与动作参考结合的社区模板。",
author: "SuperXe",
source: "community",
settings: {
model: "Seedance 2.0",
ratio: "9:16",
duration: "5s",
resolution: "720p",
},
nodes: createNodes("角色定妆,强调服装、姿态与近景表情", characterLookImage),
edges: createEdges(),
},
},
{
id: "case-03",
title: "天际奇境",
author: "OmniAI",
tag: "风景案例",
summary: "用广角风景做镜头进入,适合转场和开场片头。",
imageUrl: skylineImage,
workflow: {
id: "workflow-skyline",
version: 1,
title: "天际奇境",
description: "适合开场镜头的广角风景工作流。",
author: "OmniAI",
source: "community",
settings: {
model: "Seedance 2.0",
ratio: "16:9",
duration: "8s",
resolution: "1080p",
},
nodes: createNodes("风景开场,镜头缓慢推进到天际线", skylineImage),
edges: createEdges(),
},
},
{
id: "case-04",
title: "镜头实验室",
author: "Studio",
tag: "实验案例",
summary: "更适合拆解推拉摇移和节奏控制的实验模板。",
imageUrl: labImage,
workflow: {
id: "workflow-lab",
version: 1,
title: "镜头实验室",
description: "用于测试节奏、焦段和多段镜头拆解的模板。",
author: "Studio",
source: "community",
settings: {
model: "Seedance 2.0",
ratio: "16:9",
duration: "6s",
resolution: "720p",
},
nodes: createNodes("镜头实验,分镜更清晰,便于二次调整", labImage),
edges: createEdges(),
},
},
];
export function cloneWorkflow(input: WebCanvasWorkflow): WebCanvasWorkflow {
return {
...input,
nodes: input.nodes.map((node) => ({ ...node, position: { ...node.position } })),
edges: input.edges.map((edge) => ({ ...edge })),
settings: { ...input.settings },
};
}
export function createBlankWorkflow(title = "新建创作"): WebCanvasWorkflow {
return {
...cloneWorkflow(blankCanvasWorkflow),
id: `workflow-${Date.now()}`,
title,
};
}