diff --git a/apps/web/src/components/layout/MainLayout.css b/apps/web/src/components/layout/MainLayout.css index 5a6ffc690..d5c60167e 100644 --- a/apps/web/src/components/layout/MainLayout.css +++ b/apps/web/src/components/layout/MainLayout.css @@ -1,10 +1,12 @@ -/* V21 主容器 */ +/* V21 主布局样式 */ .xx-app-shell { display: flex; flex-direction: column; min-height: 100vh; background: var(--bg, #f8fafc); color: var(--slate, #0f172a); + position: relative; + z-index: 1; } .xx-app-content { @@ -15,7 +17,7 @@ padding: 38px 24px 76px; } -/* 根 CSS 变量 */ +/* V21 颜色变量 */ :root { --indigo: #4f46e5; --slate: #0f172a; @@ -28,5 +30,5 @@ body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif; } diff --git a/apps/web/src/index.css b/apps/web/src/index.css index f376d2ac7..07b9945c9 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1,12 +1,27 @@ +/** + * V21 全局基础样式 + */ :root { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; - line-height: 1.5; + line-height: 1.6; font-weight: 400; - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; + /* V21 颜色系统 */ + --indigo: #4f46e5; + --indigo-dark: #4338ca; + --indigo-soft: #eef2ff; + --slate: #0f172a; + --muted: #64748b; + --line: #e2e8f0; + --bg: #f8fafc; + --green: #10b981; + --amber: #f59e0b; + --red: #ef4444; + + color-scheme: light; + color: var(--slate); + background-color: var(--bg); font-synthesis: none; text-rendering: optimizeLegibility; @@ -21,16 +36,11 @@ } body { - margin: 0; - display: flex; - place-items: center; min-width: 320px; min-height: 100vh; } #root { width: 100%; - margin: 0 auto; - padding: 2rem; - text-align: center; + min-height: 100vh; } diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx index 6d7ac3d4b..daecd65fa 100644 --- a/apps/web/src/main.tsx +++ b/apps/web/src/main.tsx @@ -1,5 +1,5 @@ /** - * 更新主入口,引入全局样式 + * V21 设计系统入口 */ import React from 'react'; import ReactDOM from 'react-dom/client'; @@ -17,17 +17,21 @@ const queryClient = new QueryClient({ queries: { retry: 1, refetchOnWindowFocus: false, - staleTime: 5 * 60 * 1000, // 5 分钟 - gcTime: 10 * 60 * 1000, // 10 分钟 + staleTime: 5 * 60 * 1000, + gcTime: 10 * 60 * 1000, }, }, }); -// Ant Design 主题配置 +// V21 Ant Design 主题配置 const theme = { token: { - colorPrimary: '#1890ff', - borderRadius: 4, + // V21 Indigo 主色 + colorPrimary: '#4f46e5', + // V21 大圆角 + borderRadius: 14, + borderRadiusLG: 22, + borderRadiusSM: 12, }, }; diff --git a/apps/web/src/pages/subscription/Plans.css b/apps/web/src/pages/subscription/Plans.css index 729dfc609..8fd6a158b 100644 --- a/apps/web/src/pages/subscription/Plans.css +++ b/apps/web/src/pages/subscription/Plans.css @@ -1,11 +1,38 @@ -/* V21 订阅计划 */ +/* V21 定价页面 */ .xx-plans-page { + max-width: 1200px; + margin: 0 auto; + padding: 60px 24px; } +/* 页面头部 */ +.xx-page-head { + text-align: center; + margin-bottom: 60px; +} + +.xx-page-head h2 { + font-size: 42px; + font-weight: 900; + color: var(--slate, #0f172a); + margin: 0 0 16px; + letter-spacing: -0.02em; +} + +.xx-page-head p { + font-size: 18px; + color: var(--muted, #64748b); + margin: 0; + max-width: 560px; + margin-left: auto; + margin-right: auto; +} + +/* 定价卡片网格 - 4列 */ .xx-plans-grid { display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 20px; + grid-template-columns: repeat(4, 1fr); + gap: 24px; margin-top: 30px; } @@ -18,86 +45,172 @@ @media (max-width: 768px) { .xx-plans-grid { grid-template-columns: 1fr; + max-width: 400px; + margin-left: auto; + margin-right: auto; } } +/* V21 定价卡片 */ .xx-plan-card { - background: rgba(255, 255, 255, 0.94); - border: 1px solid #e2e8f0; + background: rgba(255,255,255,0.94); + border: 1px solid rgba(226,232,240,0.95); border-radius: 28px; - box-shadow: 0 24px 70px rgba(15, 23, 42, 0.09); - padding: 28px; + box-shadow: 0 24px 70px rgba(15,23,42,0.09); + padding: 32px 28px; position: relative; - transition: all 0.2s; + transition: all 0.3s; + display: flex; + flex-direction: column; } .xx-plan-card:hover { - border-color: #4f46e5; - box-shadow: 0 32px 90px rgba(79, 70, 229, 0.15); + border-color: var(--indigo, #4f46e5); + box-shadow: 0 32px 90px rgba(79,70,229,0.15); + transform: translateY(-4px); } .xx-plan-card.featured { - border-color: #4f46e5; - box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.12), 0 32px 90px rgba(79, 70, 229, 0.15); + border: 2px solid var(--indigo, #4f46e5); + box-shadow: 0 0 0 4px rgba(79,70,229,0.1), 0 32px 90px rgba(79,70,229,0.15); + transform: scale(1.02); } +.xx-plan-card.featured:hover { + transform: scale(1.02) translateY(-4px); +} + +/* 推荐标签 */ .xx-badge { position: absolute; - top: 0; - right: 24px; - transform: translateY(-50%); - background: #4f46e5; + top: -12px; + left: 50%; + transform: translateX(-50%); + background: linear-gradient(135deg, #6366f1, #4f46e5); color: white; - padding: 4px 12px; + padding: 6px 16px; border-radius: 999px; font-size: 12px; font-weight: 850; + white-space: nowrap; } +/* 企业版定制标签 */ +.xx-badge.enterprise { + background: linear-gradient(135deg, #f59e0b, #d97706); +} + +/* 套餐名称 */ .xx-plan-card h3 { - font-size: 24px; - margin: 0 0 16px; - color: #0f172a; + font-size: 22px; font-weight: 900; + color: var(--slate, #0f172a); + margin: 0 0 20px; + text-align: center; } +/* 价格 */ .xx-plan-price { - font-size: 42px; + text-align: center; + margin-bottom: 12px; +} + +.xx-plan-price .currency { + font-size: 18px; + font-weight: 700; + color: var(--muted, #64748b); + vertical-align: top; +} + +.xx-plan-price .amount { + font-size: 48px; font-weight: 900; - color: #4f46e5; - margin-bottom: 8px; + color: var(--indigo, #4f46e5); + line-height: 1; } -.xx-plan-price span { +.xx-plan-price .period { font-size: 16px; - color: #64748b; - font-weight: 750; + color: var(--muted, #64748b); + font-weight: 500; } +/* 企业版价格 */ +.xx-plan-price.custom .amount { + font-size: 32px; +} + +/* 描述 */ .xx-plan-description { - color: #64748b; + color: var(--muted, #64748b); font-size: 14px; + text-align: center; margin-bottom: 24px; + padding-bottom: 24px; + border-bottom: 1px solid var(--line, #e2e8f0); } +/* 功能列表 */ .xx-features { - margin-top: 24px; + margin-top: 8px; padding-top: 24px; - border-top: 1px solid #e2e8f0; + flex: 1; } .xx-feature { display: flex; - gap: 10px; + gap: 12px; align-items: flex-start; - color: #64748b; + color: var(--muted, #64748b); font-size: 14px; - margin-bottom: 12px; + margin-bottom: 16px; line-height: 1.5; } -.xx-feature span { - color: #10b981; +.xx-feature span:first-child { + color: var(--green, #10b981); font-weight: 900; flex-shrink: 0; } + +/* 订阅按钮 */ +.xx-subscribe-btn { + width: 100%; + margin-top: 24px; + padding: 14px 24px !important; + font-size: 15px !important; + font-weight: 850 !important; + border-radius: 14px !important; + transition: all 0.2s !important; +} + +.xx-subscribe-btn.primary { + background: linear-gradient(135deg, #6366f1, #4f46e5) !important; + color: white !important; + border: none !important; + box-shadow: 0 14px 26px rgba(79,70,229,0.22) !important; +} + +.xx-subscribe-btn.primary:hover { + box-shadow: 0 18px 34px rgba(79,70,229,0.28) !important; + transform: translateY(-1px); +} + +.xx-subscribe-btn.ghost { + background: white !important; + border: 1px solid var(--line, #e2e8f0) !important; + color: var(--slate, #0f172a) !important; +} + +.xx-subscribe-btn.ghost:hover { + border-color: var(--indigo, #4f46e5) !important; + color: var(--indigo, #4f46e5) !important; +} + +/* 企业版按钮 */ +.xx-subscribe-btn.enterprise { + background: linear-gradient(135deg, #f59e0b, #d97706) !important; + color: white !important; + border: none !important; + box-shadow: 0 14px 26px rgba(245,158,11,0.22) !important; +} diff --git a/apps/web/src/pages/subscription/Plans.tsx b/apps/web/src/pages/subscription/Plans.tsx index 99ff8d016..6d952ed2f 100644 --- a/apps/web/src/pages/subscription/Plans.tsx +++ b/apps/web/src/pages/subscription/Plans.tsx @@ -1,14 +1,68 @@ /** - * 订阅/计划页面 - V21 完全对标 + * 定价页面 - V21 UI 四级定价 */ import React, { useState } from 'react'; import { message } from 'antd'; import './Plans.css'; const PLANS = [ - { id: 'free', name: 'Free', price: 0, description: '免费试用', recommended: false, features: ['10个项目', '基础视频编辑', '社区支持'] }, - { id: 'pro', name: 'Pro', price: 99, description: '专业用户', recommended: true, features: ['无限项目', '高级编辑', '优先支持', 'API 访问'] }, - { id: 'enterprise', name: 'Enterprise', price: 999, description: '企业级', recommended: false, features: ['定制方案', '专属支持', '白标服务', 'SLA 保证'] }, + { + id: 'free', + name: '体验版', + price: 0, + description: '适合个人体验', + recommended: false, + features: [ + '3个视频成片', + '基础标题模板', + '基础配音音色', + '720p导出' + ] + }, + { + id: 'standard', + name: '标准版', + price: 99, + description: '适合内容创作者', + recommended: false, + features: [ + '无限视频成片', + '高级标题模板', + '全部配音音色', + '1080p导出', + 'API接口' + ] + }, + { + id: 'pro', + name: '专业版', + price: 299, + description: '适合专业团队', + recommended: true, + features: [ + '无限视频成片', + '自定义标题', + '全部配音音色', + '4K导出', + '优先渲染队列', + '专属客服' + ] + }, + { + id: 'enterprise', + name: '企业版', + price: null, + description: '适合企业用户', + recommended: false, + features: [ + '私有化部署', + '自定义品牌形象', + ' SLA服务保障', + '技术支持', + '团队协作', + '数据报表' + ] + }, ]; const Plans: React.FC = () => { @@ -28,41 +82,57 @@ const Plans: React.FC = () => { return (
-
-

选择订阅计划

-

升级您的账户享受更多功能

-
+

选择适合您的方案

+

灵活定价,满足不同规模的创作需求

{PLANS.map((plan) => ( -
+
{plan.recommended &&
推荐
} + {plan.id === 'enterprise' &&
定制
}

{plan.name}

-
- ¥{plan.price} - /月 + +
+ {plan.price !== null ? ( + <> + ¥ + {plan.price} + /月 + + ) : ( + 联系我们 + )}
+

{plan.description}

- -
- {plan.features.map((feature: string, idx: number) => ( + {plan.features.map((feature, idx) => (
- {feature} + {feature}
))}
+ +
))}
diff --git a/apps/web/src/pages/workspace/ProjectAssets.css b/apps/web/src/pages/workspace/ProjectAssets.css index 762900c58..d230650a9 100644 --- a/apps/web/src/pages/workspace/ProjectAssets.css +++ b/apps/web/src/pages/workspace/ProjectAssets.css @@ -1,200 +1,208 @@ -/* V21 素材库 */ +/* V21 素材库页面 */ .xx-project-assets { + max-width: 1200px; + margin: 0 auto; } +/* 页面头部 */ +.xx-page-head { + margin-bottom: 32px; +} + +.xx-page-head h2 { + font-size: 28px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 8px; +} + +.xx-page-head p { + font-size: 14px; + color: var(--muted, #64748b); + margin: 0; +} + +/* V21 大卡片 */ .xx-card { - background: rgba(255, 255, 255, 0.94); - border: 1px solid rgba(226, 232, 240, 0.95); + background: rgba(255,255,255,0.94); + border: 1px solid rgba(226,232,240,0.95); border-radius: 28px; - box-shadow: 0 24px 70px rgba(15, 23, 42, 0.09); + box-shadow: 0 24px 70px rgba(15,23,42,0.09); padding: 28px; - margin-bottom: 20px; + margin-bottom: 24px; + transition: all 0.25s; +} + +.xx-card:hover { + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + transform: translateY(-2px); } .xx-card h3 { - font-size: 21px; - margin: 0 0 16px; - color: #0f172a; + font-size: 18px; font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 16px; } -.xx-loading { - padding: 60px 24px; - text-align: center; - color: #64748b; -} - +/* 上传区域 */ .xx-upload-zone { - border: 2px dashed #e2e8f0; + border: 2px dashed var(--line, #e2e8f0); border-radius: 24px; - padding: 40px; + padding: 48px; text-align: center; - background: #f8fafc; + background: var(--bg, #f8fafc); cursor: pointer; transition: all 0.2s; } .xx-upload-zone:hover { - border-color: #4f46e5; - background: #eef2ff; + border-color: var(--indigo, #4f46e5); + background: var(--indigo-soft, #eef2ff); +} + +.xx-upload-zone .icon { + font-size: 48px; + margin-bottom: 16px; } .xx-upload-zone p { - color: #64748b; + color: var(--muted, #64748b); margin: 12px 0; font-size: 14px; } -.xx-video-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 16px; +/* V21 上传按钮 */ +.xx-upload-btn { + background: linear-gradient(135deg, #6366f1, #4f46e5) !important; + color: white !important; + border: none !important; + border-radius: 14px !important; + padding: 12px 24px !important; + font-weight: 850 !important; + box-shadow: 0 14px 26px rgba(79,70,229,0.22) !important; + transition: all 0.2s !important; + cursor: pointer; } -@media (max-width: 1200px) { - .xx-video-grid { +.xx-upload-btn:hover { + box-shadow: 0 18px 34px rgba(79,70,229,0.28) !important; + transform: translateY(-1px); +} + +/* 素材网格 - 9:16 竖屏卡片 */ +.xx-assets-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + gap: 20px; +} + +@media (max-width: 768px) { + .xx-assets-grid { grid-template-columns: repeat(2, 1fr); } } -@media (max-width: 768px) { - .xx-video-grid { +@media (max-width: 480px) { + .xx-assets-grid { grid-template-columns: 1fr; } } -.xx-video-card { - border: 1px solid #e2e8f0; +/* V21 素材卡片 - 大圆角 */ +.xx-asset-card { background: white; + border: 1px solid var(--line, #e2e8f0); border-radius: 22px; padding: 12px; - transition: all 0.2s; + transition: all 0.25s; + cursor: pointer; } -.xx-video-card:hover { - border-color: #4f46e5; - box-shadow: 0 12px 36px rgba(79, 70, 229, 0.12); +.xx-asset-card:hover { + border-color: var(--indigo, #4f46e5); + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + transform: translateY(-4px); } -.xx-video-thumb { - aspect-ratio: 16 / 9; +/* 缩略图 - 9:16 竖屏 */ +.xx-asset-thumb { + aspect-ratio: 9 / 16; border-radius: 16px; - background: linear-gradient(135deg, #0ea5e9, #312e81); + background: linear-gradient(135deg, #6366f1, #0ea5e9, #10b981); position: relative; overflow: hidden; display: grid; place-items: center; color: white; - margin-bottom: 10px; + font-size: 32px; + margin-bottom: 12px; } -.mini-play { - width: 46px; - height: 46px; - border-radius: 50%; - display: grid; - place-items: center; - background: rgba(255, 255, 255, 0.22); - border: 1px solid rgba(255, 255, 255, 0.3); - backdrop-filter: blur(8px); - font-size: 18px; -} - -.xx-video-card b { - display: block; - color: #0f172a; - font-weight: 850; -} - -.xx-video-card p { - margin: 5px 0 0; - color: #64748b; - font-size: 12px; -} - -.row { - display: flex; - justify-content: space-between; +/* 状态标签 - Pill 样式 */ +.xx-asset-status { + display: inline-flex; align-items: center; - gap: 8px; - margin-bottom: 4px; -} - -.pill { + gap: 4px; font-size: 11px; - padding: 3px 7px; - border-radius: 999px; font-weight: 850; + padding: 3px 10px; + border-radius: 999px; white-space: nowrap; } -.pill.ok { +.xx-asset-status.ready { background: #dcfce7; color: #15803d; } -.pill.warn { +.xx-asset-status.processing { background: #fef3c7; color: #b45309; } -.pill.bad { - background: #ffe4e6; - color: #be123c; +.xx-asset-status.failed { + background: #fee2e2; + color: #b91c1c; } -.assist-actions { - display: grid; - gap: 10px; - margin-top: 16px; - grid-template-columns: 1fr 1fr; -} - -.btn { - border: 0; - border-radius: 14px; - padding: 12px 17px; - font-weight: 850; - cursor: pointer; +.xx-asset-card b { + display: block; font-size: 14px; - transition: all 0.2s; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 8px 0 4px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } -.btn.primary { - background: #4f46e5; - color: white; - box-shadow: 0 16px 28px rgba(79, 70, 229, 0.24); -} - -.btn.primary:hover { - background: #4338ca; - box-shadow: 0 20px 36px rgba(79, 70, 229, 0.32); -} - -.btn.primary:disabled { - opacity: 0.6; - cursor: not-allowed; -} - -.btn.ghost { - background: white; - border: 1px solid #e2e8f0; - color: #475569; -} - -.btn.ghost:hover { - background: #f8fafc; - border-color: #4f46e5; - color: #4f46e5; +.xx-asset-card p { + font-size: 12px; + color: var(--muted, #64748b); + margin: 0; } +/* 空状态 */ .xx-empty-state { text-align: center; - padding: 40px 24px; - color: #64748b; + padding: 60px 24px; + color: var(--muted, #64748b); } .xx-empty-state p { font-size: 16px; - margin: 0; + margin: 12px 0; +} + +/* 加载状态 */ +.xx-loading { + padding: 60px 24px; + text-align: center; + color: var(--muted, #64748b); +} + +/* 隐藏文件输入 */ +input[type="file"] { + display: none; } diff --git a/apps/web/src/pages/workspace/ProjectAssets.tsx b/apps/web/src/pages/workspace/ProjectAssets.tsx index d748e0584..a6b5ecc29 100644 --- a/apps/web/src/pages/workspace/ProjectAssets.tsx +++ b/apps/web/src/pages/workspace/ProjectAssets.tsx @@ -1,5 +1,5 @@ /** - * 素材库页面 - V21 完全对标 + * 素材库页面 - V21 UI */ import React, { useState } from 'react'; import { useParams } from 'react-router-dom'; @@ -26,15 +26,13 @@ const ProjectAssets: React.FC = () => { return (
-
-

素材库

-

管理和组织您的视频素材

-
+

素材管理

+

上传和管理您的视频素材,支持多种格式

- {/* 上传区 */} + {/* 上传区域 - V21 设计 */}
-

上传新素材

+

📤 上传素材

e.preventDefault()} @@ -43,43 +41,46 @@ const ProjectAssets: React.FC = () => { if (e.dataTransfer.files) handleFileUpload(e.dataTransfer.files); }} > -
📁
-

拖拽文件到这里或点击选择

+
🎬
+

拖拽视频文件到此处,或点击下方按钮上传

+

支持 MP4、MOV、AVI 格式,单个文件最大 500MB

e.target.files && handleFileUpload(e.target.files)} />
- {/* 素材列表 */} + {/* 素材库 - V21 竖屏卡片网格 */}
-

已上传素材

+

📁 我的素材库

{assets.length === 0 ? (
-

还没有上传任何素材

+
📂
+

还没有上传素材

) : ( -
+
{assets.map((asset) => ( -
-
-
+
+
+
-
- {asset.name} -
-

视频素材

+ + {asset.status === 'processing' ? '⏳ 处理中' : '✓ 就绪'} + + {asset.name} +

{(asset.size / 1024 / 1024).toFixed(2)} MB

))}
diff --git a/apps/web/src/pages/workspace/ProjectGeneration.css b/apps/web/src/pages/workspace/ProjectGeneration.css index db7a1de78..3200f16ff 100644 --- a/apps/web/src/pages/workspace/ProjectGeneration.css +++ b/apps/web/src/pages/workspace/ProjectGeneration.css @@ -1,11 +1,77 @@ -/* V21 视频剪辑 */ +/* V21 剪辑计划页面 */ .xx-project-generation { + max-width: 1200px; + margin: 0 auto; } +/* 页面头部 */ +.xx-page-head { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 18px; + margin-bottom: 32px; +} + +.xx-page-head h2 { + font-size: 28px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 8px; +} + +.xx-page-head p { + font-size: 14px; + color: var(--muted, #64748b); + margin: 0; +} + +/* V21 按钮 */ +.xx-primary-btn { + background: linear-gradient(135deg, #6366f1, #4f46e5) !important; + color: white !important; + border: none !important; + border-radius: 14px !important; + padding: 12px 24px !important; + font-weight: 850 !important; + box-shadow: 0 14px 26px rgba(79,70,229,0.22) !important; + transition: all 0.2s !important; + cursor: pointer; +} + +.xx-primary-btn:hover { + box-shadow: 0 18px 34px rgba(79,70,229,0.28) !important; + transform: translateY(-1px); +} + +/* V21 卡片 */ +.xx-card { + background: rgba(255,255,255,0.94); + border: 1px solid rgba(226,232,240,0.95); + border-radius: 28px; + box-shadow: 0 24px 70px rgba(15,23,42,0.09); + padding: 28px; + margin-bottom: 24px; + transition: all 0.25s; +} + +.xx-card:hover { + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + transform: translateY(-2px); +} + +.xx-card h3 { + font-size: 18px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 20px; +} + +/* 模板网格 */ .xx-template-grid { display: grid; grid-template-columns: repeat(4, 1fr); - gap: 14px; + gap: 16px; } @media (max-width: 1200px) { @@ -20,59 +86,141 @@ } } -.xx-choice { +/* V21 模板卡片 */ +.xx-choice-card { position: relative; - border: 2px solid #e2e8f0; - border-radius: 18px; - padding: 14px; + border: 2px solid var(--line, #e2e8f0); + border-radius: 20px; + padding: 0; background: white; cursor: pointer; - transition: all 0.2s; + transition: all 0.25s; + overflow: hidden; } -.xx-choice:hover { - border-color: #4f46e5; +.xx-choice-card:hover { + border-color: var(--indigo, #4f46e5); + box-shadow: 0 12px 36px rgba(79,70,229,0.15); + transform: translateY(-2px); } -.xx-choice.selected { - border-color: #4f46e5; - box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.16); +.xx-choice-card.selected { + border-color: var(--indigo, #4f46e5); + box-shadow: 0 0 0 4px rgba(79,70,229,0.1), 0 12px 36px rgba(79,70,229,0.2); } -.check { +/* 模板封面 */ +.xx-template-cover { + height: 100px; + border-radius: 18px 18px 0 0; + display: grid; + place-items: center; + color: white; + font-size: 32px; + margin: 8px 8px 0; +} + +.xx-template-cover.gradient-1 { + background: linear-gradient(135deg, #6366f1, #4f46e5); +} + +.xx-template-cover.gradient-2 { + background: linear-gradient(135deg, #f97316, #ef4444); +} + +.xx-template-cover.gradient-3 { + background: linear-gradient(135deg, #10b981, #0284c7); +} + +.xx-template-cover.gradient-4 { + background: linear-gradient(135deg, #8b5cf6, #ec4899); +} + +/* 选中标记 */ +.xx-choice-card.selected .xx-template-cover::after { + content: '✓'; position: absolute; - right: -7px; - top: -7px; - width: 26px; - height: 26px; + top: 12px; + right: 12px; + width: 28px; + height: 28px; border-radius: 50%; - background: #4f46e5; + background: var(--indigo, #4f46e5); color: white; display: grid; place-items: center; font-weight: 900; + font-size: 14px; } -.cover { - height: 78px; - border-radius: 14px; - display: grid; - place-items: center; - color: white; - font-size: 28px; - margin-bottom: 10px; +.xx-choice-card .xx-template-info { + padding: 12px 16px 16px; } -.xx-choice b { +.xx-choice-card b { + display: block; font-size: 15px; font-weight: 850; - color: #0f172a; - display: block; + color: var(--slate, #0f172a); + margin-bottom: 4px; } -.xx-choice p { - margin: 5px 0 0; - color: #64748b; +.xx-choice-card p { font-size: 12px; + color: var(--muted, #64748b); + margin: 0; line-height: 1.4; } + +/* 分栏布局 */ +.xx-generation-layout { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 24px; +} + +@media (max-width: 768px) { + .xx-generation-layout { + grid-template-columns: 1fr; + } +} + +/* 计划预览 */ +.xx-preview-section { + display: flex; + flex-direction: column; + gap: 16px; +} + +.xx-preview-item { + display: flex; + align-items: center; + gap: 12px; + padding: 16px; + background: var(--bg, #f8fafc); + border-radius: 16px; +} + +.xx-preview-item .icon { + width: 48px; + height: 48px; + border-radius: 12px; + background: linear-gradient(135deg, #6366f1, #4f46e5); + display: grid; + place-items: center; + font-size: 20px; + color: white; +} + +.xx-preview-item h4 { + font-size: 14px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 4px; +} + +.xx-preview-item p { + font-size: 12px; + color: var(--muted, #64748b); + margin: 0; +} diff --git a/apps/web/src/pages/workspace/ProjectGeneration.tsx b/apps/web/src/pages/workspace/ProjectGeneration.tsx index 8710d8ec3..c64d15b66 100644 --- a/apps/web/src/pages/workspace/ProjectGeneration.tsx +++ b/apps/web/src/pages/workspace/ProjectGeneration.tsx @@ -1,15 +1,16 @@ /** - * 视频剪辑/生成页面 - V21 完全对标 + * 剪辑计划页面 - V21 UI */ import React, { useState } from 'react'; import { useParams } from 'react-router-dom'; import { Select, Modal, Form, message } from 'antd'; import './ProjectGeneration.css'; -const TITLE_OPTIONS = [ - { id: '1', name: '产品介绍', content: '完整介绍产品功能和优势' }, - { id: '2', name: '用户评价', content: '展示用户真实反馈和评分' }, - { id: '3', name: '功能演示', content: '详细演示产品各项功能' }, +const TEMPLATE_OPTIONS = [ + { id: '1', name: '知识科普', content: '适合科普、教育类内容' }, + { id: '2', name: '产品展示', content: '适合电商、产品介绍' }, + { id: '3', name: '生活分享', content: '适合日常Vlog、生活记录' }, + { id: '4', name: '新闻资讯', content: '适合新闻、热点解读' }, ]; const ProjectGeneration: React.FC = () => { @@ -21,12 +22,12 @@ const ProjectGeneration: React.FC = () => { const handleGenerate = async () => { const values = await form.validateFields(); try { - message.success('成片生成任务已创建'); + message.success('开始生成成片'); setGenerateOpen(false); form.resetFields(); setSelectedTitle(''); } catch (error: any) { - message.error('创建生成任务失败'); + message.error('生成失败'); } }; @@ -34,44 +35,71 @@ const ProjectGeneration: React.FC = () => {
-

视频剪辑

-

生成您的成片

+

剪辑计划

+

选择模板和标题,创建您的视频成片

-
-
-

生成计划

-
- {TITLE_OPTIONS.map((title, idx) => { - const colors = [ - 'linear-gradient(135deg,#4f46e5,#818cf8)', - 'linear-gradient(135deg,#f97316,#ef4444)', - 'linear-gradient(135deg,#10b981,#0284c7)', - 'linear-gradient(135deg,#64748b,#334155)', - ]; - return ( -
setSelectedTitle(title.id)} - > -
- 📹 +
+ {/* 模板选择 */} +
+

🎨 选择模板

+
+ {TEMPLATE_OPTIONS.map((title, idx) => { + const gradients = ['gradient-1', 'gradient-2', 'gradient-3', 'gradient-4']; + return ( +
setSelectedTitle(title.id)} + > +
+ {idx + 1} +
+
+ {title.name} +

{title.content}

+
- {selectedTitle === title.id &&
} - {title.name} -

{title.content.substring(0, 50)}...

+ ); + })} +
+
+ + {/* 计划预览 */} +
+
+

📋 计划概览

+
+
📹
+
+

视频素材

+

已上传 0 个素材

- ); - })} +
+
+
✍️
+
+

标题模板

+

{selectedTitle ? TEMPLATE_OPTIONS.find(t => t.id === selectedTitle)?.name : '未选择'}

+
+
+
+
🎙️
+
+

配音音色

+

请在配音库选择

+
+
+
{ label="选择模板" rules={[{ required: true, message: '请选择模板' }]} > - 基础模板 - 产品介绍 + 产品模板 生活方式 @@ -95,7 +123,7 @@ const ProjectGeneration: React.FC = () => { label="视频时长" rules={[{ required: true, message: '请选择时长' }]} > - 15秒 30秒 60秒 diff --git a/apps/web/src/pages/workspace/ProjectResults.css b/apps/web/src/pages/workspace/ProjectResults.css index f7c194df4..fcbe0d433 100644 --- a/apps/web/src/pages/workspace/ProjectResults.css +++ b/apps/web/src/pages/workspace/ProjectResults.css @@ -1,103 +1,175 @@ -/* V21 成片库 */ +/* V21 成片库页面 */ .xx-project-results { + max-width: 1200px; + margin: 0 auto; } +/* 页面头部 */ +.xx-page-head { + margin-bottom: 32px; +} + +.xx-page-head h2 { + font-size: 28px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 8px; +} + +.xx-page-head p { + font-size: 14px; + color: var(--muted, #64748b); + margin: 0; +} + +/* V21 竖屏成片网格 */ .xx-vertical-grid { display: grid; grid-template-columns: repeat(4, 1fr); - gap: 16px; -} - -.xx-vertical-grid.compact { - grid-template-columns: repeat(4, 1fr); + gap: 24px; } @media (max-width: 1200px) { .xx-vertical-grid { grid-template-columns: repeat(3, 1fr); } - - .xx-vertical-grid.compact { - grid-template-columns: repeat(2, 1fr); - } } @media (max-width: 768px) { .xx-vertical-grid { grid-template-columns: repeat(2, 1fr); } - - .xx-vertical-grid.compact { +} + +@media (max-width: 480px) { + .xx-vertical-grid { grid-template-columns: 1fr; + max-width: 300px; + margin: 0 auto; } } +/* V21 竖屏成片卡片 */ .xx-vertical-card { - border: 1px solid #e2e8f0; background: white; + border: 1px solid var(--line, #e2e8f0); border-radius: 24px; padding: 12px; - transition: all 0.2s; + transition: all 0.3s; + cursor: pointer; } .xx-vertical-card:hover { - border-color: #4f46e5; - box-shadow: 0 12px 36px rgba(79, 70, 229, 0.12); + border-color: var(--indigo, #4f46e5); + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + transform: translateY(-4px); } +/* 竖屏缩略图 */ .xx-vertical-thumb { aspect-ratio: 9 / 16; border-radius: 18px; - background: linear-gradient(135deg, #0ea5e9, #312e81); position: relative; overflow: hidden; display: grid; place-items: center; color: white; - margin-bottom: 10px; - cursor: pointer; + font-size: 32px; + margin-bottom: 12px; } .xx-vertical-thumb.orange { background: linear-gradient(135deg, #f97316, #ef4444); } -.xx-vertical-thumb.gray { - background: linear-gradient(135deg, #64748b, #334155); +.xx-vertical-thumb.indigo { + background: linear-gradient(135deg, #6366f1, #4f46e5); } .xx-vertical-thumb.green { background: linear-gradient(135deg, #10b981, #0284c7); } -.xx-vertical-thumb video { - width: 100%; - height: 100%; - object-fit: cover; +.xx-vertical-thumb.purple { + background: linear-gradient(135deg, #8b5cf6, #ec4899); } -.xx-vertical-thumb img { - width: 100%; - height: 100%; - object-fit: cover; +/* 播放按钮 */ +.xx-play-btn { + width: 52px; + height: 52px; + border-radius: 50%; + background: rgba(255,255,255,0.2); + backdrop-filter: blur(4px); + border: 2px solid rgba(255,255,255,0.3); + display: grid; + place-items: center; + font-size: 20px; + color: white; + transition: all 0.2s; } +.xx-vertical-card:hover .xx-play-btn { + background: rgba(255,255,255,0.3); + transform: scale(1.1); +} + +/* 视频信息 */ .xx-vertical-card b { display: block; - color: #0f172a; - font-weight: 850; font-size: 14px; + font-weight: 850; + color: var(--slate, #0f172a); + margin-bottom: 6px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } -.xx-vertical-card p { - margin: 5px 0 0; - color: #64748b; +.xx-vertical-card .meta { + display: flex; + justify-content: space-between; + align-items: center; font-size: 12px; + color: var(--muted, #64748b); } -.assist-actions { - display: grid; - gap: 8px; - margin-top: 12px; - grid-template-columns: 1fr 1fr; +.xx-vertical-card .duration { + font-weight: 600; +} + +.xx-vertical-card .size { + color: var(--green, #10b981); +} + +/* 状态标签 */ +.xx-status-pill { + display: inline-block; + font-size: 11px; + font-weight: 850; + padding: 4px 10px; + border-radius: 999px; + margin-bottom: 8px; +} + +.xx-status-pill.ready { + background: #dcfce7; + color: #15803d; +} + +.xx-status-pill.processing { + background: #fef3c7; + color: #b45309; +} + +/* 空状态 */ +.xx-empty-state { + text-align: center; + padding: 80px 24px; + color: var(--muted, #64748b); +} + +.xx-empty-state p { + font-size: 16px; + margin: 12px 0; } diff --git a/apps/web/src/pages/workspace/ProjectResults.tsx b/apps/web/src/pages/workspace/ProjectResults.tsx index 0d4fe6cf6..f92bb2bcb 100644 --- a/apps/web/src/pages/workspace/ProjectResults.tsx +++ b/apps/web/src/pages/workspace/ProjectResults.tsx @@ -1,5 +1,5 @@ /** - * 成片库页面 - V21 完全对标 + * 成片库页面 - V21 UI */ import React, { useState } from 'react'; import { useParams } from 'react-router-dom'; @@ -9,37 +9,40 @@ const ProjectResults: React.FC = () => { const { id: projectId } = useParams<{ id: string }>(); const [videos] = useState([]); + const colors = ['orange', 'indigo', 'green', 'purple']; + return (
-
-

成片库

-

查看和下载生成的成片

-
+

成片库

+

查看和管理已生成的视频成片

{videos.length === 0 ? (
-
🎬
-

还没有生成任何成片

+
🎬
+

还没有生成的成片

+

+ 前往剪辑计划开始生成您的第一个视频 +

) : ( -
-

生成的成片

-
- {videos.map((video: any) => ( -
-
- -
-
- {video.name} - 可发布 -
-

{video.duration || 0}s · 9:16 · {Math.round(video.file_size / 1024 / 1024)}MB

+
+ {videos.map((video, idx) => ( +
+
+
- ))} -
+ + {video.status === 'processing' ? '⏳ 生成中' : '✓ 就绪'} + + {video.name} +
+ {video.duration || 0}s + {(video.file_size / 1024 / 1024).toFixed(1)} MB +
+
+ ))}
)}
diff --git a/apps/web/src/pages/workspace/ProjectTitles.css b/apps/web/src/pages/workspace/ProjectTitles.css index 97ab3e47e..df28f2f55 100644 --- a/apps/web/src/pages/workspace/ProjectTitles.css +++ b/apps/web/src/pages/workspace/ProjectTitles.css @@ -1,49 +1,178 @@ -/* V21 标题库 */ +/* V21 标题库页面 */ .xx-project-titles { + max-width: 1200px; + margin: 0 auto; } +/* 页面头部 */ +.xx-page-head { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 18px; + margin-bottom: 32px; +} + +.xx-page-head h2 { + font-size: 28px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 8px; +} + +.xx-page-head p { + font-size: 14px; + color: var(--muted, #64748b); + margin: 0; +} + +/* V21 按钮 */ +.xx-primary-btn { + background: linear-gradient(135deg, #6366f1, #4f46e5) !important; + color: white !important; + border: none !important; + border-radius: 14px !important; + padding: 12px 24px !important; + font-weight: 850 !important; + box-shadow: 0 14px 26px rgba(79,70,229,0.22) !important; + transition: all 0.2s !important; + cursor: pointer; +} + +.xx-primary-btn:hover { + box-shadow: 0 18px 34px rgba(79,70,229,0.28) !important; + transform: translateY(-1px); +} + +/* V21 卡片 */ +.xx-card { + background: rgba(255,255,255,0.94); + border: 1px solid rgba(226,232,240,0.95); + border-radius: 28px; + box-shadow: 0 24px 70px rgba(15,23,42,0.09); + padding: 28px; + margin-bottom: 24px; + transition: all 0.25s; +} + +.xx-card:hover { + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + transform: translateY(-2px); +} + +/* 搜索栏 - V21 风格 */ .xx-search-bar { - margin-bottom: 16px; + margin-bottom: 24px; } -.xx-title-list { +.xx-search-input { + width: 100%; + padding: 14px 20px; + border: 2px solid var(--line, #e2e8f0); + border-radius: 16px; + font-size: 15px; + background: white; + transition: all 0.2s; + outline: none; +} + +.xx-search-input:focus { + border-color: var(--indigo, #4f46e5); + box-shadow: 0 0 0 4px rgba(79,70,229,0.1); +} + +.xx-search-input::placeholder { + color: var(--muted, #64748b); +} + +/* 标题列表网格 */ +.xx-title-grid { display: grid; - gap: 10px; + gap: 16px; } +/* V21 标题卡片 */ .xx-title-row { display: flex; justify-content: space-between; align-items: center; - gap: 12px; - border: 1px solid #e2e8f0; + gap: 16px; + padding: 20px; + border: 1px solid var(--line, #e2e8f0); background: white; - border-radius: 18px; - padding: 13px; - transition: all 0.2s; + border-radius: 20px; + transition: all 0.25s; + cursor: pointer; } .xx-title-row:hover { - border-color: #4f46e5; - box-shadow: 0 8px 24px rgba(79, 70, 229, 0.08); + border-color: var(--indigo, #4f46e5); + box-shadow: 0 12px 36px rgba(79,70,229,0.1); + transform: translateX(4px); +} + +.xx-title-content { + flex: 1; } .xx-title-row b { display: block; - color: #0f172a; - font-weight: 850; font-size: 16px; + font-weight: 850; + color: var(--slate, #0f172a); + margin-bottom: 6px; } .xx-title-row p { - margin: 5px 0 0; - color: #64748b; - font-size: 13px; + font-size: 14px; + color: var(--muted, #64748b); + margin: 0; line-height: 1.5; } +/* 操作按钮 */ .xx-actions { display: flex; gap: 8px; flex-shrink: 0; } + +.xx-action-btn { + width: 40px; + height: 40px; + border-radius: 12px; + background: var(--bg, #f8fafc); + border: 1px solid var(--line, #e2e8f0); + cursor: pointer; + display: grid; + place-items: center; + font-size: 16px; + transition: all 0.2s; +} + +.xx-action-btn:hover { + background: var(--indigo-soft, #eef2ff); + border-color: var(--indigo, #4f46e5); +} + +.xx-action-btn.copy:hover { + color: var(--indigo, #4f46e5); +} + +.xx-action-btn.delete:hover { + color: var(--red, #ef4444); + background: #fee2e2; + border-color: #fecaca; +} + +/* 空状态 */ +.xx-empty-state { + text-align: center; + padding: 60px 24px; + color: var(--muted, #64748b); +} + +.xx-empty-state p { + font-size: 16px; + margin: 12px 0; +} diff --git a/apps/web/src/pages/workspace/ProjectTitles.tsx b/apps/web/src/pages/workspace/ProjectTitles.tsx index c0b33f8db..98ca7ecdd 100644 --- a/apps/web/src/pages/workspace/ProjectTitles.tsx +++ b/apps/web/src/pages/workspace/ProjectTitles.tsx @@ -1,5 +1,5 @@ /** - * 标题库页面 - V21 完全对标 + * 标题库页面 - V21 UI */ import React, { useState } from 'react'; import { useParams } from 'react-router-dom'; @@ -16,7 +16,7 @@ const ProjectTitles: React.FC = () => { const handleCreate = async () => { const values = await form.validateFields(); try { - message.success('标题创建成功'); + message.success('创建标题成功'); setCreateOpen(false); form.resetFields(); } catch (error: any) { @@ -34,35 +34,42 @@ const ProjectTitles: React.FC = () => {

标题库

-

管理和搜索您的视频标题

+

管理和创作吸引眼球的视频标题

-
+ {/* 搜索栏 */}
- setSearchText(e.target.value)} - style={{ padding: '10px 14px', borderRadius: '12px' }} />
{filtered.length === 0 ? (
-

{searchText ? '没有找到匹配的标题' : '还没有创建任何标题'}

+
✍️
+

{searchText ? '没有找到匹配的标题' : '还没有创建标题'}

) : ( -
+
{filtered.map((title: any) => (
-
+
{title.name}

{title.content}

+
+ + +
))}
@@ -70,7 +77,7 @@ const ProjectTitles: React.FC = () => {
{
- + { rules={[{ required: true, message: '请输入标题内容' }]} > diff --git a/apps/web/src/pages/workspace/ProjectVoices.css b/apps/web/src/pages/workspace/ProjectVoices.css index 9c7519033..2e33e764f 100644 --- a/apps/web/src/pages/workspace/ProjectVoices.css +++ b/apps/web/src/pages/workspace/ProjectVoices.css @@ -1,105 +1,167 @@ -/* V21 配音库 */ +/* V21 配音库页面 */ .xx-project-voices { + max-width: 1200px; + margin: 0 auto; } +/* 页面头部 */ +.xx-page-head { + margin-bottom: 32px; +} + +.xx-page-head h2 { + font-size: 28px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 8px; +} + +.xx-page-head p { + font-size: 14px; + color: var(--muted, #64748b); + margin: 0; +} + +/* V21 卡片 */ +.xx-card { + background: rgba(255,255,255,0.94); + border: 1px solid rgba(226,232,240,0.95); + border-radius: 28px; + box-shadow: 0 24px 70px rgba(15,23,42,0.09); + padding: 28px; + margin-bottom: 24px; + transition: all 0.25s; +} + +.xx-card h3 { + font-size: 18px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 20px; +} + +/* 配音网格 - 双列 */ .xx-voice-grid { display: grid; - grid-template-columns: repeat(5, 1fr); - gap: 12px; -} - -@media (max-width: 1200px) { - .xx-voice-grid { - grid-template-columns: repeat(4, 1fr); - } + grid-template-columns: repeat(2, 1fr); + gap: 20px; } @media (max-width: 768px) { .xx-voice-grid { - grid-template-columns: repeat(3, 1fr); + grid-template-columns: 1fr; } } -.xx-voice { - text-align: center; - border: 2px solid #e2e8f0; - border-radius: 18px; +/* V21 配音卡片 */ +.xx-voice-card { + display: flex; + align-items: center; + gap: 16px; + padding: 20px; + border: 2px solid var(--line, #e2e8f0); + border-radius: 20px; background: white; - padding: 14px; cursor: pointer; - transition: all 0.2s; + transition: all 0.25s; position: relative; } -.xx-voice:hover { - border-color: #4f46e5; +.xx-voice-card:hover { + border-color: var(--indigo, #4f46e5); + box-shadow: 0 12px 36px rgba(79,70,229,0.12); + transform: translateY(-2px); } -.xx-voice.selected { - border-color: #4f46e5; - box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.14); +/* 选中态 */ +.xx-voice-card.selected { + border-color: var(--indigo, #4f46e5); + background: var(--indigo-soft, #eef2ff); + box-shadow: 0 0 0 4px rgba(79,70,229,0.1); } -.xx-voice.selected::after { +/* 选中标记 */ +.xx-voice-card.selected::after { content: '✓'; position: absolute; - right: -7px; - top: -7px; - width: 26px; - height: 26px; + right: -8px; + top: -8px; + width: 28px; + height: 28px; border-radius: 50%; - background: #4f46e5; + background: var(--indigo, #4f46e5); color: white; display: grid; place-items: center; font-weight: 900; + font-size: 14px; } -.voice-icon { - width: 54px; - height: 54px; - margin: 0 auto 9px; +/* 波形图占位 */ +.xx-voice-waveform { + width: 80px; + height: 48px; + border-radius: 12px; + background: linear-gradient(135deg, #6366f1, #4f46e5); + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.xx-voice-waveform span { + color: white; + font-size: 20px; +} + +/* 音色信息 */ +.xx-voice-info { + flex: 1; +} + +.xx-voice-info h4 { + font-size: 16px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 6px; +} + +.xx-voice-info p { + font-size: 13px; + color: var(--muted, #64748b); + margin: 0; +} + +/* 播放按钮 */ +.xx-voice-play { + width: 44px; + height: 44px; border-radius: 50%; + background: rgba(79,70,229,0.1); + border: none; + cursor: pointer; display: grid; place-items: center; + font-size: 18px; + color: var(--indigo, #4f46e5); + transition: all 0.2s; + flex-shrink: 0; +} + +.xx-voice-play:hover { + background: var(--indigo, #4f46e5); color: white; - font-size: 24px; - background: linear-gradient(135deg, #4f46e5, #6366f1); + transform: scale(1.1); } -.xx-voice div { - font-weight: 850; - font-size: 14px; - color: #0f172a; -} - -.xx-voice small { - display: block; - color: #64748b; - margin-top: 4px; +/* 标签 */ +.xx-voice-tag { + display: inline-block; font-size: 11px; -} - -.xx-voice-usage-list { - display: grid; - gap: 10px; -} - -.xx-voice-usage-row { - border: 1px solid #e2e8f0; - background: white; - border-radius: 18px; - padding: 13px; -} - -.xx-voice-usage-row b { - display: block; - color: #0f172a; font-weight: 850; -} - -.xx-voice-usage-row p { - margin: 5px 0 0; - color: #64748b; - font-size: 12px; + padding: 4px 10px; + border-radius: 999px; + background: var(--indigo-soft, #eef2ff); + color: var(--indigo-dark, #4338ca); + margin-top: 8px; } diff --git a/apps/web/src/pages/workspace/ProjectVoices.tsx b/apps/web/src/pages/workspace/ProjectVoices.tsx index fc8d9e986..60b539f80 100644 --- a/apps/web/src/pages/workspace/ProjectVoices.tsx +++ b/apps/web/src/pages/workspace/ProjectVoices.tsx @@ -1,17 +1,17 @@ /** - * 配音库页面 - V21 完全对标 + * 配音库页面 - V21 UI */ import React, { useState } from 'react'; import { useParams } from 'react-router-dom'; import './ProjectVoices.css'; const VOICE_OPTIONS = [ - { id: 'female-1', name: '女声1', icon: '👩' }, - { id: 'female-2', name: '女声2', icon: '👩' }, - { id: 'male-1', name: '男声1', icon: '👨' }, - { id: 'male-2', name: '男声2', icon: '👨' }, - { id: 'neutral-1', name: '中性声1', icon: '🎤' }, - { id: 'neutral-2', name: '中性声2', icon: '🎤' }, + { id: 'female-youth', name: '元气少女', desc: '年轻女性,活泼开朗', tag: '热门' }, + { id: 'female-mature', name: '知性姐姐', desc: '成熟女性,温柔亲切', tag: '推荐' }, + { id: 'male-young', name: '阳光男孩', desc: '年轻男性,清新自然', tag: '热门' }, + { id: 'male-mature', name: '磁性大叔', desc: '成熟男性,深沉有力', tag: '' }, + { id: 'neutral-youth', name: '活力童声', desc: '童声配音,活泼可爱', tag: '新品' }, + { id: 'neutral-mature', name: '专业播音', desc: '标准播音腔,端庄大气', tag: '' }, ]; const ProjectVoices: React.FC = () => { @@ -21,24 +21,28 @@ const ProjectVoices: React.FC = () => { return (
-
-

配音库

-

选择和管理配音

-
+

配音库

+

选择适合您内容的配音音色

-

可用配音

+

🎙️ 选择音色

{VOICE_OPTIONS.map((voice) => (
setSelectedVoice(voice.id)} > -
{voice.icon}
-
{voice.name}
- 点击预览 +
+ 🔊 +
+
+

{voice.name}

+

{voice.desc}

+ {voice.tag && {voice.tag}} +
+
))}
diff --git a/apps/web/src/pages/workspace/WorkspaceList.css b/apps/web/src/pages/workspace/WorkspaceList.css index dad94212a..92599a760 100644 --- a/apps/web/src/pages/workspace/WorkspaceList.css +++ b/apps/web/src/pages/workspace/WorkspaceList.css @@ -1,7 +1,110 @@ -/* V21 工作空间列表 */ +/* V21 工作空间列表页面 */ .xx-workspace-list { + max-width: 1200px; + margin: 0 auto; } +/* Hero 区域 - V21 设计 */ +.xx-hero { + text-align: center; + padding: 60px 24px 80px; + position: relative; +} + +.xx-hero::before { + content: ''; + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 300px; + height: 300px; + background: radial-gradient(circle, rgba(79,70,229,0.15), transparent 70%); + border-radius: 50%; + filter: blur(40px); +} + +.xx-hero h1 { + font-size: 42px; + font-weight: 900; + color: var(--slate, #0f172a); + margin: 0 0 16px; + letter-spacing: -0.02em; + position: relative; +} + +.xx-hero p { + font-size: 18px; + color: var(--muted, #64748b); + margin: 0 0 32px; + max-width: 560px; + margin-left: auto; + margin-right: auto; + line-height: 1.6; +} + +/* 功能卡片网格 - V21 */ +.xx-features-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; + margin-bottom: 60px; +} + +@media (max-width: 1200px) { + .xx-features-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + .xx-features-grid { + grid-template-columns: 1fr; + } +} + +.xx-feature-card { + background: rgba(255,255,255,0.94); + border: 1px solid rgba(226,232,240,0.95); + border-radius: 24px; + padding: 28px; + text-align: center; + transition: all 0.25s; + cursor: pointer; +} + +.xx-feature-card:hover { + transform: translateY(-4px); + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + border-color: var(--indigo, #4f46e5); +} + +.xx-feature-icon { + width: 56px; + height: 56px; + margin: 0 auto 16px; + background: linear-gradient(135deg, #6366f1, #4f46e5); + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; + font-size: 24px; +} + +.xx-feature-card h3 { + font-size: 16px; + font-weight: 850; + color: var(--slate, #0f172a); + margin: 0 0 8px; +} + +.xx-feature-card p { + font-size: 13px; + color: var(--muted, #64748b); + margin: 0; +} + +/* 页面头部 */ .xx-page-head { display: flex; justify-content: space-between; @@ -13,19 +116,19 @@ .xx-page-head h2 { font-size: 28px; margin: 0 0 6px; - color: #0f172a; + color: var(--slate, #0f172a); } .xx-page-head p { margin: 0; - color: #64748b; + color: var(--muted, #64748b); font-size: 14px; } .xx-grid4 { display: grid; grid-template-columns: repeat(4, 1fr); - gap: 12px; + gap: 16px; } @media (max-width: 1200px) { @@ -47,23 +150,24 @@ } .xx-workspace-card { - border: 1px solid #e2e8f0; + border: 1px solid var(--line, #e2e8f0); background: rgba(255, 255, 255, 0.94); border-radius: 24px; padding: 18px; cursor: pointer; - transition: all 0.2s; + transition: all 0.25s; } .xx-workspace-card:hover { - border-color: #4f46e5; - box-shadow: 0 12px 36px rgba(79, 70, 229, 0.12); + border-color: var(--indigo, #4f46e5); + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + transform: translateY(-2px); } .xx-workspace-name { font-size: 16px; font-weight: 850; - color: #0f172a; + color: var(--slate, #0f172a); margin-bottom: 12px; overflow: hidden; text-overflow: ellipsis; @@ -74,10 +178,10 @@ display: inline-block; font-size: 12px; font-weight: 850; - padding: 4px 8px; - border-radius: 8px; - background: #eef2ff; - color: #4338ca; + padding: 4px 10px; + border-radius: 10px; + background: var(--indigo-soft, #eef2ff); + color: var(--indigo-dark, #4338ca); margin-bottom: 12px; } @@ -89,7 +193,7 @@ .xx-empty-state { text-align: center; padding: 60px 24px; - color: #64748b; + color: var(--muted, #64748b); } .xx-empty-state p { diff --git a/apps/web/src/pages/workspace/WorkspaceList.tsx b/apps/web/src/pages/workspace/WorkspaceList.tsx index c9d438634..717b4fb25 100644 --- a/apps/web/src/pages/workspace/WorkspaceList.tsx +++ b/apps/web/src/pages/workspace/WorkspaceList.tsx @@ -1,5 +1,5 @@ /** - * 工作空间列表页面 - V21 严格对标 + * 工作空间列表页面 - V21 UI */ import React from 'react'; import { Button, Modal, Form, Input, message } from 'antd'; @@ -20,27 +20,53 @@ const WorkspaceList: React.FC = () => { const values = await form.validateFields(); try { const workspace = await createWorkspaceMutation.mutateAsync({ name: values.name }); - message.success('工作空间创建成功'); + message.success('创建工作空间成功'); setCreateOpen(false); form.resetFields(); navigate(`/workspaces/${workspace.id}`); } catch (createError: any) { - message.error(createError.response?.data?.detail || '工作空间创建失败'); + message.error(createError.response?.data?.detail || '创建失败'); } }; + // 功能卡片数据 + const features = [ + { id: 'assets', icon: '🎬', title: '素材管理', desc: '上传管理视频素材' }, + { id: 'titles', icon: '✍️', title: '标题库', desc: '创作吸引眼球的标题' }, + { id: 'voices', icon: '🎙️', title: '配音库', desc: '选择优质配音音色' }, + { id: 'generation', icon: '✨', title: '剪辑计划', desc: 'AI智能生成成片' }, + ]; + return (
-
-
-

我的工作空间

-

创建和管理您的视频剪辑项目

-
+ {/* Hero 区域 - V21 设计 */} +
+

小虾剪辑 SaaS

+

专业的AI视频剪辑平台,一站式管理素材、标题、配音,轻松创作优质内容

+ {/* 功能卡片 - V21 设计 */} +
+ {features.map((feature) => ( +
+
{feature.icon}
+

{feature.title}

+

{feature.desc}

+
+ ))} +
+ + {/* 工作空间列表 */} +
+
+

我的工作空间

+

选择或创建一个工作空间开始创作

+
+
+
{workspaces?.map((workspace) => (
{ {!isLoading && workspaces?.length === 0 && (
-
📦
+
🚀

还没有工作空间

)} @@ -84,10 +110,10 @@ const WorkspaceList: React.FC = () => { label="工作空间名称" rules={[ { required: true, message: '请输入工作空间名称' }, - { max: 50, message: '最多 50 个字符' }, + { max: 50, message: '名称不能超过50个字符' }, ]} > - + diff --git a/apps/web/src/styles/global.css b/apps/web/src/styles/global.css index 63fcad593..f9af86683 100644 --- a/apps/web/src/styles/global.css +++ b/apps/web/src/styles/global.css @@ -1,29 +1,43 @@ /** - * 全局样式变量 + * V21 设计系统 - 全局样式 */ :root { /* 主色调 */ - --primary-color: #1890ff; - --primary-hover: #40a9ff; - --primary-active: #096dd9; + --primary-color: #4f46e5; + --primary-hover: #6366f1; + --primary-active: #4338ca; + --primary-soft: #eef2ff; /* 状态色 */ - --success-color: #52c41a; - --warning-color: #faad14; - --error-color: #ff4d4f; - --info-color: #1890ff; + --success-color: #10b981; + --warning-color: #f59e0b; + --error-color: #ef4444; + --info-color: #4f46e5; - /* 文字颜色 */ - --text-primary: #262626; - --text-secondary: #595959; + /* 文字色 */ + --text-primary: #0f172a; + --text-secondary: #64748b; --text-disabled: #bfbfbf; /* 背景色 */ - --bg-primary: #ffffff; + --bg-primary: #f8fafc; --bg-secondary: #fafafa; --bg-tertiary: #f5f5f5; - /* 边框和分割线 */ + /* V21 设计令牌 */ + --indigo: #4f46e5; + --indigo-dark: #4338ca; + --indigo-soft: #eef2ff; + --gradient-primary: linear-gradient(135deg, #6366f1, #4f46e5); + --slate: #0f172a; + --muted: #64748b; + --line: #e2e8f0; + --bg: #f8fafc; + --green: #10b981; + --amber: #f59e0b; + --red: #ef4444; + + /* 边框色 */ --border-color: #d9d9d9; --divider-color: #f0f0f0; @@ -34,18 +48,102 @@ --space-lg: 24px; --space-xl: 32px; - /* 圆角 */ - --radius-sm: 2px; - --radius-md: 4px; - --radius-lg: 8px; + /* 圆角 - V21 大圆角 */ + --radius-sm: 12px; + --radius-md: 16px; + --radius-lg: 22px; + --radius-xl: 28px; - /* 阴影 */ - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08); - --shadow-md: 0 4px 8px rgba(0, 0, 0, 0.12); - --shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.16); + /* 阴影 - V21 柔和大阴影 */ + --shadow-sm: 0 10px 30px rgba(15,23,42,0.06); + --shadow-md: 0 20px 58px rgba(15,23,42,0.10); + --shadow-lg: 0 24px 70px rgba(15,23,42,0.09); + --shadow-hover: 0 26px 64px rgba(15,23,42,0.14); } -/* 全局样式重置 */ +/** + * V21 按钮样式 + */ +.btn.primary, +.ant-btn-primary { + background: linear-gradient(135deg, #6366f1, #4f46e5) !important; + color: white !important; + border-radius: 14px !important; + font-weight: 850 !important; + box-shadow: 0 14px 26px rgba(79,70,229,0.22) !important; + border: none !important; + padding: 12px 22px !important; + transition: all 0.2s !important; +} + +.btn.primary:hover, +.ant-btn-primary:hover { + box-shadow: 0 18px 34px rgba(79,70,229,0.28) !important; + transform: translateY(-1px); + background: linear-gradient(135deg, #6366f1, #4f46e5) !important; +} + +.btn.ghost, +.ant-btn-default { + background: white !important; + border: 1px solid #dbe3ef !important; + border-radius: 14px !important; + font-weight: 850 !important; + padding: 12px 22px !important; + transition: all 0.2s !important; +} + +.btn.ghost:hover, +.ant-btn-default:hover { + border-color: #4f46e5 !important; + color: #4f46e5 !important; +} + +/** + * V21 卡片样式 + */ +.xx-card { + background: rgba(255,255,255,0.94); + border: 1px solid rgba(226,232,240,0.95); + border-radius: 28px; + box-shadow: 0 24px 70px rgba(15,23,42,0.09); + padding: 28px; + transition: all 0.25s; +} + +.xx-card:hover { + box-shadow: 0 26px 64px rgba(15,23,42,0.14); + transform: translateY(-2px); +} + +/** + * V21 背景装饰 + */ +body::before { + content: ''; + position: fixed; + inset: 0; + z-index: 0; + pointer-events: none; + background: + radial-gradient(circle at 18% 20%, rgba(79,70,229,0.11), transparent 30%), + radial-gradient(circle at 86% 14%, rgba(16,185,129,0.08), transparent 28%), + radial-gradient(circle at 48% 80%, rgba(99,102,241,0.08), transparent 34%), + #f8fafc; +} + +body::after { + content: ''; + position: fixed; + inset: 0; + z-index: 0; + pointer-events: none; + background-image: radial-gradient(circle, rgba(79,70,229,0.1) 1px, transparent 1px); + background-size: 38px 38px; + opacity: 0.32; +} + +/* 全局重置 */ * { margin: 0; padding: 0; @@ -53,13 +151,12 @@ } body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', - 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } -/* 滚动条样式 */ +/* 滚动条 */ ::-webkit-scrollbar { width: 8px; height: 8px; @@ -74,7 +171,7 @@ body { background: rgba(0, 0, 0, 0.3); } -/* 通用工具类 */ +/* 工具类 */ .text-center { text-align: center; } @@ -107,7 +204,7 @@ body { margin-bottom: var(--space-lg); } -/* 卡片hover效果 */ +/* 卡片悬浮效果 */ .card-hover { transition: all 0.3s; cursor: pointer; @@ -118,7 +215,7 @@ body { box-shadow: var(--shadow-lg); } -/* 选中的套餐卡片 */ +/* 选中态 */ .selected-plan { border: 2px solid var(--primary-color) !important; box-shadow: var(--shadow-md);