diff --git a/screenshots/ecommerce-1024.png b/screenshots/ecommerce-1024.png new file mode 100644 index 0000000..d12143e Binary files /dev/null and b/screenshots/ecommerce-1024.png differ diff --git a/screenshots/ecommerce-1366.png b/screenshots/ecommerce-1366.png new file mode 100644 index 0000000..7c757fe Binary files /dev/null and b/screenshots/ecommerce-1366.png differ diff --git a/screenshots/ecommerce-1440.png b/screenshots/ecommerce-1440.png new file mode 100644 index 0000000..3d9a662 Binary files /dev/null and b/screenshots/ecommerce-1440.png differ diff --git a/screenshots/ecommerce-1920.png b/screenshots/ecommerce-1920.png new file mode 100644 index 0000000..98302fa Binary files /dev/null and b/screenshots/ecommerce-1920.png differ diff --git a/screenshots/ecommerce-hero.png b/screenshots/ecommerce-hero.png new file mode 100644 index 0000000..938d54b Binary files /dev/null and b/screenshots/ecommerce-hero.png differ diff --git a/screenshots/home-features-1024.png b/screenshots/home-features-1024.png new file mode 100644 index 0000000..98c815b Binary files /dev/null and b/screenshots/home-features-1024.png differ diff --git a/screenshots/home-features-1366.png b/screenshots/home-features-1366.png new file mode 100644 index 0000000..e8ded83 Binary files /dev/null and b/screenshots/home-features-1366.png differ diff --git a/screenshots/home-features-1440.png b/screenshots/home-features-1440.png new file mode 100644 index 0000000..77915f3 Binary files /dev/null and b/screenshots/home-features-1440.png differ diff --git a/screenshots/home-features-1920.png b/screenshots/home-features-1920.png new file mode 100644 index 0000000..a87dc13 Binary files /dev/null and b/screenshots/home-features-1920.png differ diff --git a/src/App.tsx b/src/App.tsx index 77b1cce..9e13d34 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -199,7 +199,7 @@ function createWorkflowFromResult(payload: WorkbenchResultActionPayload): WebCan description: payload.prompt || "从生成结果进入画布继续创作。", source: "blank", settings: { - model: payload.resultType === "video" ? "Seedance 2.0" : "Nano Banana Pro", + model: payload.resultType === "video" ? "Seedance 2.0" : "omni-水果 Pro", ratio: payload.resultType === "video" ? "16:9" : "1:1", duration: payload.resultType === "video" ? "6s" : "0s", resolution: payload.resultType === "video" ? "720p" : "2K", @@ -1011,7 +1011,7 @@ function App() { previewUrl: payload.resultUrl, params: payload.resultType === "video" ? { model: "Kling V3 Omni", aspectRatio: "16:9", resolution: "720p", duration: "6s", videoMode: "text-to-video" } - : { model: "Nano Banana Pro", aspectRatio: "1:1", imageSize: "2K" }, + : { model: "omni-水果 Pro", aspectRatio: "1:1", imageSize: "2K" }, assetRef: payload.resultOssKey ? { url: payload.resultUrl, ossKey: payload.resultOssKey, mediaType: payload.resultType === "video" ? "video/mp4" : "image/png", sourceTaskId: payload.taskId } : undefined, }, ]; diff --git a/src/api/keyServerClient.ts b/src/api/keyServerClient.ts index 4653047..d86109a 100644 --- a/src/api/keyServerClient.ts +++ b/src/api/keyServerClient.ts @@ -481,7 +481,7 @@ function migrateLegacyWorkflowData(old: Record, wrapper: Record description: String(wrapper.description || ""), source: (wrapper.source as WebCanvasWorkflow["source"]) || "blank", settings: { - model: String(isRecord(old.settings) ? old.settings.model || "Nano Banana Pro" : "Nano Banana Pro"), + model: String(isRecord(old.settings) ? old.settings.model || "omni-水果 Pro" : "omni-水果 Pro"), ratio: String(isRecord(old.settings) ? old.settings.ratio || "1:1" : "1:1"), duration: String(isRecord(old.settings) ? old.settings.duration || "0s" : "0s"), resolution: String(isRecord(old.settings) ? old.settings.resolution || "2K" : "2K"), diff --git a/src/components/AppShell.tsx b/src/components/AppShell.tsx index 27f6d03..bc32b75 100644 --- a/src/components/AppShell.tsx +++ b/src/components/AppShell.tsx @@ -7,6 +7,7 @@ import { ossAssets } from "../data/ossAssets"; import { canManageCommunityCases, canReviewCommunity } from "../features/community-review/communityPermissions"; import type { WebNavItem, WebNotification, WebUsageSummary, WebUserSession, WebViewKey } from "../types"; import NotificationCenter from "./NotificationCenter"; +import BetaApplicationModal from "./BetaApplicationModal"; import { AnimatedPanel } from "./AnimatedPanel"; import AdminMonitor from "./AdminMonitor"; import CookieConsentBanner from "./CookieConsentBanner"; @@ -85,6 +86,7 @@ function AppShell({ const [rechargeOpen, setRechargeOpen] = useState(false); const [RechargeModal, setRechargeModal] = useState(null); const [infoOpen, setInfoOpen] = useState(false); + const [betaOpen, setBetaOpen] = useState(false); const infoRef = useRef(null); const [openSubmenuKey, setOpenSubmenuKey] = useState(null); const [publicConfig, setPublicConfig] = useState({}); @@ -343,6 +345,15 @@ function AppShell({ OmniAI
+ {session && ( setRechargeOpen(false)} currentBalance={displayedBalanceCents} /> ) : null} - + setBetaOpen(false)} />
); } diff --git a/src/components/BetaApplicationModal.tsx b/src/components/BetaApplicationModal.tsx new file mode 100644 index 0000000..5068eea --- /dev/null +++ b/src/components/BetaApplicationModal.tsx @@ -0,0 +1,283 @@ +import { CloseOutlined, ExperimentOutlined } from "@ant-design/icons"; +import { useState } from "react"; + +interface BetaApplicationModalProps { + open: boolean; + onClose: () => void; +} + +/* ── Form state ── */ +interface BetaFormData { + name: string; + phone: string; + wechat: string; + industry: string; + company: string; + city: string; + aiTools: string; + aiDuration: string; + aiTrack: string; + aiDirection: string[]; + weeklyUsage: string; + feedbackWilling: string; + wantFeature: string[]; + selfStatement: string; + signature: string; + agreeRules: boolean; +} + +const INITIAL_FORM: BetaFormData = { + name: "", + phone: "", + wechat: "", + industry: "", + company: "", + city: "", + aiTools: "", + aiDuration: "", + aiTrack: "", + aiDirection: [], + weeklyUsage: "", + feedbackWilling: "", + wantFeature: [], + selfStatement: "", + signature: "", + agreeRules: false, +}; + +/* ── Option groups (from the docx) ── */ +const AI_DURATION_OPTIONS = ["1年以内", "1-3年", "3-5年", "5年以上"]; +const AI_TRACK_OPTIONS = ["是,长期承接相关业务", "业余创作", "新手学习"]; +const AI_DIRECTION_OPTIONS = [ + "AI短剧批量制作", "漫剧剧情生成", "自媒体短视频", "电商图文及视频素材", + "MCN商业内容", "企业宣传视频", "个人兴趣创作", "其他", +]; +const WEEKLY_USAGE_OPTIONS = ["7次及以上", "1-3次", "空闲时间使用"]; +const FEEDBACK_OPTIONS = ["全力配合深度反馈", "简单体验留言", "仅使用不反馈"]; +const WANT_FEATURE_OPTIONS = [ + "一站式短剧漫剧完整AIGC工作流", "电商素材自动化创作流程", + "多模态智能中枢全能创作", "批量自动化创作流程", "全新未公开AI创作玩法", +]; + +/* ── Helper: single-select radio group ── */ +function RadioGroup({ + name, options, value, onChange, +}: { + name: string; + options: string[]; + value: string; + onChange: (v: string) => void; +}) { + return ( +
+ {options.map((opt) => ( + + ))} +
+ ); +} + +/* ── Helper: multi-select checkbox group ── */ +function CheckboxGroup({ + options, value, onChange, +}: { + options: string[]; + value: string[]; + onChange: (v: string[]) => void; +}) { + return ( +
+ {options.map((opt) => ( + + ))} +
+ ); +} + +/* ── Helper: text field ── */ +function TextField({ + label, value, onChange, placeholder, +}: { + label: string; + value: string; + onChange: (v: string) => void; + placeholder?: string; +}) { + return ( +
+ {label} + onChange(e.target.value)} + placeholder={placeholder ?? "请填写"} + /> +
+ ); +} + +const BetaApplicationModal = ({ open, onClose }: BetaApplicationModalProps) => { + const [form, setForm] = useState(INITIAL_FORM); + + const update = (key: K, value: BetaFormData[K]) => { + setForm((prev) => ({ ...prev, [key]: value })); + }; + + if (!open) return null; + + return ( +
+ + + + {/* ── Body (scrollable document) ── */} +
+ + {/* 一、个人基础信息 */} +
+

一、个人基础信息

+
+ update("name", v)} /> + update("phone", v)} /> + update("wechat", v)} /> + update("industry", v)} /> + update("company", v)} /> + update("city", v)} /> +
+
+ + {/* 二、AI从业与使用经历 */} +
+

二、AI 从业与使用经历

+
+ update("aiTools", v)} placeholder="例如:Midjourney / Stable Diffusion / ChatGPT 等" /> +
+ AI 内容创作从业时长 + update("aiDuration", v)} /> +
+
+ 是否深耕 AI 短剧、漫剧、数字视频、电商赛道 + update("aiTrack", v)} /> +
+
+ 日常主要创作方向(可多选) + update("aiDirection", v)} /> +
+
+
+ + {/* 三、内测使用意向调研 */} +
+

三、内测使用意向调研

+
+
+ 每周可稳定登录使用内测平台次数 + update("weeklyUsage", v)} /> +
+
+ 是否愿意积极反馈产品 BUG、优化建议、功能需求 + update("feedbackWilling", v)} /> +
+
+ 本次最想体验 OmniAI 核心功能(可多选) + update("wantFeature", v)} /> +
+
+
+ + {/* 四、申请自述 */} +
+

四、申请自述 (必填)

+

请简述自身 AI 创作优势、业务需求,以及加入本次封闭内测的理由:

+