fix(viral-video): 营销目的20项完整列表 + 修复图片大小显示0B #2142

Merged
xiaoxia merged 1 commits from fix/2041-marketing-purposes-filesize into develop 2026-10-02 13:11:15 +08:00
@@ -71,7 +71,7 @@ type UploadedImage = {
localId: string
url: string
name: string
size: number
size: number | undefined
uploading: boolean
pct: number
ossUrl?: string
@@ -184,7 +184,28 @@ const STRUCTURES = [
"连续否定+代入感受+打破认知+精准戳痛",
"揭秘行业+类比施压+放大焦虑+精准锁客",
]
const PURPOSES = ["品牌种草", "新品上市", "促销转化", "活动引流"]
const PURPOSES = [
"获客引流",
"账号涨粉",
"活动通知",
"口播带货",
"促销转化",
"场景种草",
"痛点解决",
"功能演示",
"门店发现",
"到店实录",
"招牌体验",
"同城团购",
"品牌主张",
"品牌故事",
"生活方式",
"创意概念",
"对话短剧",
"反转短剧",
"悬念短剧",
"情绪短片",
]
const DURATIONS = [15, 20, 30, 45, 60]
const RATIOS = [
{ v: "9:16", label: "9:16 竖屏(抖音/视频号)" },
@@ -345,7 +366,8 @@ const MOCK_STORYBOARD: Storyboard = {
"还在为餐桌选不到好桌子发愁?这张北美黑胡桃木餐桌,一家人坐下来吃饭刚刚好。全实木、无贴皮,纹理好看又耐刮。点小黄车,给家里添一张好桌子。",
}
const fmtSize = (bytes: number) => {
const fmtSize = (bytes: number | undefined) => {
if (!bytes || bytes <= 0) return "--"
if (bytes < 1024) return `${bytes}B`
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`
return `${(bytes / 1024 / 1024).toFixed(1)}MB`
@@ -366,7 +388,7 @@ const emptyTask = (id: string, title: string): TabTask => ({
targetCustomer: "",
language: "中文(普通话)",
viralStructure: STRUCTURES[0],
marketingPurpose: PURPOSES[0],
marketingPurpose: "",
duration: 15,
persona: "",
videoRatio: "9:16",
@@ -595,7 +617,15 @@ const ViralVideoPage: React.FC = () => {
setTask((t) => ({
...t,
images: t.images.map((im) =>
im.localId === item.localId ? { ...im, uploading: false, pct: 100, ossUrl: url } : im,
im.localId === item.localId
? {
...im,
uploading: false,
pct: 100,
ossUrl: url,
size: item.file!.size || im.size,
}
: im,
),
}))
} catch {
@@ -616,7 +646,7 @@ const ViralVideoPage: React.FC = () => {
localId: `lib_${a.id}_${Math.random().toString(36).slice(2, 6)}`,
url: a.thumbnail_url || a.file_url || "",
name: a.name || "未命名",
size: a.file_size || 0,
size: a.file_size || undefined,
uploading: false,
pct: 100,
ossUrl: a.file_url || undefined,
@@ -1822,7 +1852,7 @@ const ViralVideoPage: React.FC = () => {
<div className="vv-form-row">
<label className="vv-label">目标客户</label>
<Select
className="vv-select vv-select-purple"
className="vv-select"
style={{ width: "100%" }}
placeholder="请选择目标客户"
value={task.targetCustomer || undefined}
@@ -1834,7 +1864,7 @@ const ViralVideoPage: React.FC = () => {
<div className="vv-form-row">
<label className="vv-label">台词语言</label>
<Select
className="vv-select vv-select-purple"
className="vv-select"
style={{ width: "100%" }}
value={task.language}
onChange={(v) => setTask({ language: v })}
@@ -1844,7 +1874,7 @@ const ViralVideoPage: React.FC = () => {
<div className="vv-form-row">
<label className="vv-label">我的人设</label>
<Select
className="vv-select vv-select-purple"
className="vv-select"
style={{ width: "100%" }}
placeholder="请选择人设类型"
optionFilterProp="children"
@@ -1856,7 +1886,7 @@ const ViralVideoPage: React.FC = () => {
<div className="vv-form-row">
<label className="vv-label">爆款结构</label>
<Select
className="vv-select vv-select-purple"
className="vv-select"
style={{ width: "100%" }}
value={task.viralStructure}
onChange={(v) => setTask({ viralStructure: v })}
@@ -1866,9 +1896,10 @@ const ViralVideoPage: React.FC = () => {
<div className="vv-form-row">
<label className="vv-label">营销目的</label>
<Select
className="vv-select vv-select-purple"
className="vv-select"
style={{ width: "100%" }}
value={task.marketingPurpose}
placeholder="请选择营销目的"
value={task.marketingPurpose || undefined}
onChange={(v) => setTask({ marketingPurpose: v })}
options={PURPOSES.map((i) => ({ value: i, label: i }))}
/>
@@ -1876,7 +1907,7 @@ const ViralVideoPage: React.FC = () => {
<div className="vv-form-row" style={{ gridColumn: "1 / -1" }}>
<label className="vv-label">文案视频时长</label>
<Select
className="vv-select vv-select-purple"
className="vv-select"
style={{ width: "100%" }}
value={task.duration}
onChange={(v) => setTask({ duration: v })}