This commit is contained in:
2026-06-26 10:06:17 +08:00
parent cee7093db6
commit 509892ca7b
3 changed files with 386 additions and 529 deletions
+17 -2
View File
@@ -400,12 +400,27 @@ async def _seed_data():
("/generated", "素材云", "CloudOutlined", 1, "资产管理", True),
("/authorization", "授权管理", "UserOutlined", 0, "媒体关联", False),
("/consume", "消耗列表", "FileTextOutlined", 1, "媒体关联", False),
("/popular", "热门广场", "ThunderboltOutlined", 0, "AI项目行业生成", False),
("/creativeplaza", "创意广场", "GiftOutlined", 0, "AI对话生成", False),
]
for path, label, icon, order, group_label, is_default in frontend_pages:
existing = await db.execute(
select(MenuConfig).where(MenuConfig.path == path).limit(1)
select(MenuConfig).where(
MenuConfig.path == path,
MenuConfig.menu_target == "frontend",
).limit(1)
)
if not existing.scalar_one_or_none():
existing_page = existing.scalar_one_or_none()
if existing_page:
# Update existing menu item if needed
if existing_page.label != label or existing_page.icon != icon or \
existing_page.sort_order != order or existing_page.is_default != is_default:
existing_page.label = label
existing_page.icon = icon
existing_page.sort_order = order
existing_page.is_default = is_default
existing_page.parent_id = frontend_group_ids.get(group_label)
else:
db.add(
MenuConfig(
id=generate_id(),
+188 -301
View File
@@ -1,48 +1,103 @@
import React, { useState } from 'react';
import { Button, Card, Modal, message, Typography, Space } from 'antd';
import React from 'react';
import { Button, Card, message, Typography } from 'antd';
import {
StarOutlined,
LockOutlined,
PhoneOutlined,
MailOutlined,
MessageOutlined,
GiftOutlined,
BellOutlined,
WalletOutlined,
ThunderboltOutlined,
SparklesOutlined,
PlayCircleOutlined,
CheckCircleOutlined,
HeartOutlined,
} from '@ant-design/icons';
const CreativePlazaPage: React.FC = () => {
const [modalOpen, setModalOpen] = useState(false);
const handleUnlock = () => {
message.info('请联系客服开通VIP会员,客服热线:400-888-8888');
};
const creativeFeatures = [
const caseStudies = [
{
icon: <GiftOutlined style={{ fontSize: 24, color: '#ec4899' }} />,
title: '创意灵感',
description: '海量创意灵感库,激发无限创作潜能',
color: 'linear-gradient(135deg, rgba(236,72,153,0.1) 0%, rgba(236,72,153,0.05) 100%)',
borderColor: 'rgba(236,72,153,0.2)',
id: 1,
title: '品牌宣传视频',
category: '商业广告',
description: '为知名品牌打造的创意宣传视频,展现品牌理念与产品特色',
tags: ['AI生成', '品牌推广', '创意设计'],
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=professional%20brand%20promotional%20video%20advertisement%20modern&image_size=landscape_16_9',
duration: '0:45',
quality: '4K',
},
{
icon: <BellOutlined style={{ fontSize: 24, color: '#06b6d4' }} />,
title: '素材集市',
description: '丰富素材资源,打造独特作品风格',
color: 'linear-gradient(135deg, rgba(6,182,212,0.1) 0%, rgba(6,182,212,0.05) 100%)',
borderColor: 'rgba(6,182,212,0.2)',
id: 2,
title: '产品展示动画',
category: '电商展示',
description: '3D产品展示动画,让产品细节完美呈现',
tags: ['3D渲染', '产品展示', '电商'],
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=3D%20product%20showcase%20animation%20ecommerce&image_size=landscape_16_9',
duration: '0:30',
quality: '4K',
},
{
icon: <ThunderboltOutlined style={{ fontSize: 24, color: '#8b5cf6' }} />,
title: '特效工坊',
description: '专业特效工具,提升视频质感',
color: 'linear-gradient(135deg, rgba(139,92,246,0.1) 0%, rgba(139,92,246,0.05) 100%)',
borderColor: 'rgba(139,92,246,0.2)',
id: 3,
title: '教育培训课程',
category: '知识分享',
description: '生动有趣的教育内容,让学习更加轻松愉快',
tags: ['教育', '知识', '在线课程'],
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=educational%20video%20learning%20classroom%20modern&image_size=landscape_16_9',
duration: '15:20',
quality: '1080P',
},
{
icon: <StarOutlined style={{ fontSize: 24, color: '#f59e0b' }} />,
title: '精品模板',
description: '精选高品质模板,一键快速出片',
color: 'linear-gradient(135deg, rgba(245,158,11,0.1) 0%, rgba(245,158,11,0.05) 100%)',
borderColor: 'rgba(245,158,11,0.2)',
id: 4,
title: '短视频创意',
category: '社交媒体',
description: '适合各大社交平台的创意短视频内容',
tags: ['短视频', '社交', '创意'],
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=creative%20short%20video%20social%20media%20vibrant&image_size=landscape_16_9',
duration: '0:15',
quality: '1080P',
},
{
id: 5,
title: '企业宣传片',
category: '企业形象',
description: '全方位展示企业实力与文化的专业宣传片',
tags: ['企业', '宣传片', '品牌'],
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=corporate%20video%20company%20profile%20professional&image_size=landscape_16_9',
duration: '2:30',
quality: '4K',
},
{
id: 6,
title: '动画短片',
category: '创意动画',
description: '精美的AI生成动画短片,展现无限创意',
tags: ['动画', 'AI艺术', '创意'],
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=creative%20animated%20short%20film%20colorful%20artistic&image_size=landscape_16_9',
duration: '1:30',
quality: '4K',
},
];
const features = [
{
icon: <SparklesOutlined style={{ fontSize: 28, color: '#8b5cf6' }} />,
title: 'AI智能生成',
description: '先进的AI技术,一键生成高质量视频内容',
},
{
icon: <PlayCircleOutlined style={{ fontSize: 28, color: '#ec4899' }} />,
title: '多格式输出',
description: '支持多种视频格式,满足不同场景需求',
},
{
icon: <CheckCircleOutlined style={{ fontSize: 28, color: '#10b981' }} />,
title: '品质保证',
description: '专业级画质,细节清晰,色彩鲜艳',
},
{
icon: <HeartOutlined style={{ fontSize: 28, color: '#f59e0b' }} />,
title: '创意无限',
description: '丰富的模板和风格,激发创作灵感',
},
];
@@ -64,24 +119,27 @@ const CreativePlazaPage: React.FC = () => {
</div>
<div>
<Typography.Title level={2} style={{ margin: 0, color: '#1e293b', fontWeight: 700 }}>
广
<span style={{ color: '#6366f1', fontSize: 14, fontWeight: 400, marginLeft: 8 }}>
AI创作无限可能
</span>
</Typography.Title>
</div>
</div>
<Typography.Text style={{ color: '#64748b' }}>
AI生成的优秀素材案例AI创作的无限潜力与创意灵感
</Typography.Text>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 20, marginBottom: 32 }}>
{creativeFeatures.map((feature, index) => (
{features.map((feature, index) => (
<Card
key={index}
bordered={false}
style={{
borderRadius: 16,
background: feature.color,
border: `1px solid ${feature.borderColor}`,
background: 'linear-gradient(135deg, rgba(139,92,246,0.04) 0%, rgba(99,102,241,0.04) 100%)',
border: '1px solid rgba(139,92,246,0.1)',
padding: 20,
}}
>
@@ -98,280 +156,109 @@ const CreativePlazaPage: React.FC = () => {
))}
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20, marginBottom: 32 }}>
<Card
bordered={false}
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b' }}>
<StarOutlined style={{ marginRight: 8, color: '#f59e0b' }} />
</Typography.Title>
<Button
type="primary"
size="middle"
onClick={handleUnlock}
style={{
borderRadius: 16,
background: 'linear-gradient(135deg, rgba(99,102,241,0.03) 0%, rgba(139,92,246,0.03) 100%)',
border: '1px solid rgba(99,102,241,0.08)',
padding: 20,
borderRadius: 10,
background: 'linear-gradient(135deg, #8b5cf6 0%, #a78bfa 100%)',
border: 'none',
}}
>
<div style={{
height: 180,
borderRadius: 12,
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 16,
}}>
<BellOutlined style={{ fontSize: 48, color: 'rgba(255,255,255,0.8)' }} />
</div>
<Typography.Title level={5} style={{ marginBottom: 8, color: '#1e293b' }}>
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
</Typography.Text>
</Card>
<Card
bordered={false}
style={{
borderRadius: 16,
background: 'linear-gradient(135deg, rgba(245,158,11,0.03) 0%, rgba(217,119,6,0.03) 100%)',
border: '1px solid rgba(245,158,11,0.08)',
padding: 20,
}}
>
<div style={{
height: 180,
borderRadius: 12,
background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 16,
}}>
<GiftOutlined style={{ fontSize: 48, color: 'rgba(255,255,255,0.8)' }} />
</div>
<Typography.Title level={5} style={{ marginBottom: 8, color: '#1e293b' }}>
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
</Typography.Text>
</Card>
<Card
bordered={false}
style={{
borderRadius: 16,
background: 'linear-gradient(135deg, rgba(16,185,129,0.03) 0%, rgba(5,150,105,0.03) 100%)',
border: '1px solid rgba(16,185,129,0.08)',
padding: 20,
}}
>
<div style={{
height: 180,
borderRadius: 12,
background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 16,
}}>
<WalletOutlined style={{ fontSize: 48, color: 'rgba(255,255,255,0.8)' }} />
</div>
<Typography.Title level={5} style={{ marginBottom: 8, color: '#1e293b' }}>
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
</Typography.Text>
</Card>
<LockOutlined style={{ marginRight: 6 }} />
</Button>
</div>
<Card
bordered={false}
style={{
borderRadius: 20,
background: 'linear-gradient(135deg, rgba(139,92,246,0.04) 0%, rgba(167,139,250,0.04) 100%)',
border: '1px solid rgba(139,92,246,0.1)',
padding: 0,
overflow: 'hidden',
}}
>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div style={{
width: '50%',
padding: '48px 32px',
background: 'linear-gradient(135deg, #8b5cf6 0%, #a78bfa 50%, #c4b5fd 100%)',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}>
<div style={{
width: 120,
height: 120,
borderRadius: '50%',
background: 'rgba(255,255,255,0.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 24,
}}>
<LockOutlined style={{ fontSize: 48, color: '#fff' }} />
</div>
<Typography.Title level={3} style={{ margin: 0, color: '#fff', textAlign: 'center', marginBottom: 8 }}>
广
</Typography.Title>
<Typography.Text style={{ color: 'rgba(255,255,255,0.8)', textAlign: 'center', fontSize: 14 }}>
VIP会员广
</Typography.Text>
</div>
<div style={{
width: '50%',
padding: '48px 32px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 20,
}}>
<div style={{ textAlign: 'center' }}>
<div style={{
width: 56,
height: 56,
borderRadius: 14,
background: 'linear-gradient(135deg, rgba(139,92,246,0.1) 0%, rgba(167,139,250,0.1) 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 12px',
}}>
<GiftOutlined style={{ fontSize: 24, color: '#8b5cf6' }} />
</div>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b', marginBottom: 4 }}>
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
</Typography.Text>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{
width: 56,
height: 56,
borderRadius: 14,
background: 'linear-gradient(135deg, rgba(236,72,153,0.1) 0%, rgba(219,39,119,0.1) 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 12px',
}}>
<BellOutlined style={{ fontSize: 24, color: '#ec4899' }} />
</div>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b', marginBottom: 4 }}>
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
</Typography.Text>
</div>
<Button
type="primary"
size="large"
onClick={() => setModalOpen(true)}
style={{
borderRadius: 12,
padding: '12px 32px',
background: 'linear-gradient(135deg, #8b5cf6 0%, #a78bfa 100%)',
border: 'none',
boxShadow: '0 8px 24px rgba(139,92,246,0.35)',
fontWeight: 600,
}}
>
<LockOutlined style={{ marginRight: 8 }} />
</Button>
</div>
</div>
</Card>
<Modal
title={<Space><MessageOutlined /></Space>}
open={modalOpen}
onCancel={() => setModalOpen(false)}
footer={null}
width={480}
>
<div style={{ padding: 16 }}>
<div style={{
background: 'linear-gradient(135deg, rgba(139,92,246,0.04) 0%, rgba(167,139,250,0.04) 100%)',
borderRadius: 12,
padding: 20,
marginBottom: 20,
}}>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b', marginBottom: 12 }}>
VIP会员
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 14, lineHeight: 1.8 }}>
VIP会员即可解锁创意广场全部功能
</Typography.Text>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: 16, background: '#fafbfc', borderRadius: 12 }}>
<div style={{
width: 48,
height: 48,
borderRadius: 12,
background: 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
<PhoneOutlined style={{ fontSize: 20, color: '#fff' }} />
</div>
<div>
<Typography.Text strong style={{ color: '#1e293b' }}>线</Typography.Text>
<div style={{ color: '#8b5cf6', fontSize: 18, fontWeight: 600 }}>400-888-8888</div>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: 16, background: '#fafbfc', borderRadius: 12 }}>
<div style={{
width: 48,
height: 48,
borderRadius: 12,
background: 'linear-gradient(135deg, #ec4899 0%, #db2777 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
<MailOutlined style={{ fontSize: 20, color: '#fff' }} />
</div>
<div>
<Typography.Text strong style={{ color: '#1e293b' }}></Typography.Text>
<div style={{ color: '#8b5cf6', fontSize: 14 }}>vip@videogen.ai</div>
</div>
</div>
</div>
<Button
type="primary"
block
size="large"
onClick={() => {
message.success('已复制客服热线到剪贴板');
navigator.clipboard.writeText('400-888-8888');
setModalOpen(false);
}}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20 }}>
{caseStudies.map((caseItem) => (
<Card
key={caseItem.id}
bordered={false}
style={{
marginTop: 20,
borderRadius: 12,
background: 'linear-gradient(135deg, #8b5cf6 0%, #a78bfa 100%)',
border: 'none',
boxShadow: '0 4px 16px rgba(139,92,246,0.3)',
borderRadius: 16,
overflow: 'hidden',
boxShadow: '0 4px 16px rgba(0,0,0,0.06)',
}}
>
</Button>
</div>
</Modal>
<div style={{ position: 'relative' }}>
<img
src={caseItem.thumbnail}
alt={caseItem.title}
style={{ width: '100%', height: 180, objectFit: 'cover' }}
/>
<div style={{
position: 'absolute',
top: 12,
left: 12,
padding: '4px 12px',
background: 'rgba(139,92,246,0.9)',
borderRadius: 8,
color: '#fff',
fontSize: 12,
}}>
{caseItem.category}
</div>
<div style={{
position: 'absolute',
bottom: 12,
right: 12,
padding: '4px 10px',
background: 'rgba(0,0,0,0.7)',
borderRadius: 6,
color: '#fff',
fontSize: 11,
}}>
{caseItem.duration} | {caseItem.quality}
</div>
</div>
<div style={{ padding: 16 }}>
<Typography.Title level={5} style={{ marginBottom: 8, color: '#1e293b' }}>
{caseItem.title}
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13, marginBottom: 12, display: 'block' }}>
{caseItem.description}
</Typography.Text>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 12 }}>
{caseItem.tags.map((tag, index) => (
<span
key={index}
style={{
padding: '4px 12px',
background: 'rgba(99,102,241,0.08)',
borderRadius: 20,
color: '#6366f1',
fontSize: 12,
}}
>
{tag}
</span>
))}
</div>
<Button
type="primary"
block
size="small"
onClick={handleUnlock}
style={{
borderRadius: 8,
background: 'linear-gradient(135deg, #8b5cf6 0%, #a78bfa 100%)',
border: 'none',
}}
>
<SparklesOutlined style={{ marginRight: 4 }} />
</Button>
</div>
</Card>
))}
</div>
</div>
);
};
+181 -226
View File
@@ -1,47 +1,78 @@
import React, { useState } from 'react';
import { Button, Card, Modal, message, Typography, Space } from 'antd';
import React from 'react';
import { Button, Card, message, Typography } from 'antd';
import {
StarOutlined,
CrownOutlined,
LockOutlined,
PhoneOutlined,
MailOutlined,
MessageOutlined,
ThunderboltOutlined,
GiftOutlined,
TrendingUpOutlined,
FlameOutlined,
AwardOutlined,
} from '@ant-design/icons';
const PopularPage: React.FC = () => {
const [modalOpen, setModalOpen] = useState(false);
const handleUnlock = () => {
message.info('请联系客服开通VIP会员,客服热线:400-888-8888');
};
const features = [
const industries = [
{ name: '美妆护肤', hot: 'HOT', trend: '+125%', color: '#ec4899' },
{ name: '美食餐饮', hot: '', trend: '+89%', color: '#f59e0b' },
{ name: '服饰穿搭', hot: 'NEW', trend: '+76%', color: '#10b981' },
{ name: '数码科技', hot: '', trend: '+64%', color: '#06b6d4' },
{ name: '家居生活', hot: '', trend: '+52%', color: '#8b5cf6' },
{ name: '运动健身', hot: 'HOT', trend: '+48%', color: '#6366f1' },
];
const hotMaterials = [
{
icon: <ThunderboltOutlined style={{ fontSize: 24, color: '#f59e0b' }} />,
title: '热门趋势',
description: '实时追踪行业热点,把握创作风向',
color: 'linear-gradient(135deg, rgba(245,158,11,0.1) 0%, rgba(245,158,11,0.05) 100%)',
borderColor: 'rgba(245,158,11,0.2)',
id: 1,
title: '夏日清爽护肤教程',
industry: '美妆护肤',
views: '2.3M',
likes: '156K',
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=beautiful%20skincare%20product%20advertisement%20with%20fresh%20summer%20vibes&image_size=landscape_16_9',
},
{
icon: <StarOutlined style={{ fontSize: 24, color: '#ec4899' }} />,
title: '精选模板',
description: '精选热门视频模板,一键快速创作',
color: 'linear-gradient(135deg, rgba(236,72,153,0.1) 0%, rgba(236,72,153,0.05) 100%)',
borderColor: 'rgba(236,72,153,0.2)',
id: 2,
title: '网红美食探店vlog',
industry: '美食餐饮',
views: '1.8M',
likes: '128K',
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=delicious%20food%20foodie%20vlog%20style%20restaurant&image_size=landscape_16_9',
},
{
icon: <GiftOutlined style={{ fontSize: 24, color: '#10b981' }} />,
title: '达人榜单',
description: '查看热门创作者,学习优秀作品',
color: 'linear-gradient(135deg, rgba(16,185,129,0.1) 0%, rgba(16,185,129,0.05) 100%)',
borderColor: 'rgba(16,185,129,0.2)',
id: 3,
title: '秋季穿搭灵感分享',
industry: '服饰穿搭',
views: '1.5M',
likes: '98K',
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=fashion%20autumn%20outfit%20inspiration%20stylish&image_size=landscape_16_9',
},
{
icon: <CrownOutlined style={{ fontSize: 24, color: '#6366f1' }} />,
title: 'VIP专属',
description: '专属内容推荐,提升创作效率',
color: 'linear-gradient(135deg, rgba(99,102,241,0.1) 0%, rgba(99,102,241,0.05) 100%)',
borderColor: 'rgba(99,102,241,0.2)',
id: 4,
title: '新品手机开箱评测',
industry: '数码科技',
views: '1.2M',
likes: '87K',
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=smartphone%20unboxing%20review%20tech%20gadget&image_size=landscape_16_9',
},
{
id: 5,
title: '家居改造前后对比',
industry: '家居生活',
views: '980K',
likes: '76K',
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=home%20makeover%20before%20after%20interior%20design&image_size=landscape_16_9',
},
{
id: 6,
title: '健身房训练日常',
industry: '运动健身',
views: '850K',
likes: '65K',
thumbnail: 'https://neeko-copilot.bytedance.net/api/text_to_image?prompt=gym%20workout%20fitness%20training%20motivation&image_size=landscape_16_9',
},
];
@@ -59,232 +90,156 @@ const PopularPage: React.FC = () => {
justifyContent: 'center',
boxShadow: '0 4px 16px rgba(245,158,11,0.3)',
}}>
<ThunderboltOutlined style={{ fontSize: 22, color: '#fff' }} />
<TrendingUpOutlined style={{ fontSize: 22, color: '#fff' }} />
</div>
<div>
<Typography.Title level={2} style={{ margin: 0, color: '#1e293b', fontWeight: 700 }}>
广
<span style={{ color: '#6366f1', fontSize: 14, fontWeight: 400, marginLeft: 8 }}>
</span>
</Typography.Title>
</div>
</div>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 20, marginBottom: 32 }}>
{features.map((feature, index) => (
<Card
key={index}
bordered={false}
style={{
borderRadius: 16,
background: feature.color,
border: `1px solid ${feature.borderColor}`,
padding: 20,
}}
>
<div style={{ textAlign: 'center' }}>
<div style={{ marginBottom: 16 }}>{feature.icon}</div>
<Typography.Title level={4} style={{ marginBottom: 8, color: '#1e293b' }}>
{feature.title}
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
{feature.description}
</Typography.Text>
</div>
</Card>
))}
<Typography.Text style={{ color: '#64748b' }}>
</Typography.Text>
</div>
<Card
bordered={false}
style={{
borderRadius: 20,
background: 'linear-gradient(135deg, rgba(99,102,241,0.04) 0%, rgba(139,92,246,0.04) 100%)',
border: '1px solid rgba(99,102,241,0.1)',
padding: 0,
overflow: 'hidden',
background: 'linear-gradient(135deg, rgba(245,158,11,0.04) 0%, rgba(217,119,6,0.04) 100%)',
border: '1px solid rgba(245,158,11,0.1)',
padding: 24,
marginBottom: 32,
}}
>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div style={{
width: '50%',
padding: '48px 32px',
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%)',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}>
<div style={{
width: 120,
height: 120,
borderRadius: '50%',
background: 'rgba(255,255,255,0.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 24,
}}>
<LockOutlined style={{ fontSize: 48, color: '#fff' }} />
</div>
<Typography.Title level={3} style={{ margin: 0, color: '#fff', textAlign: 'center', marginBottom: 8 }}>
</Typography.Title>
<Typography.Text style={{ color: 'rgba(255,255,255,0.8)', textAlign: 'center', fontSize: 14 }}>
VIP会员广
</Typography.Text>
</div>
<div style={{
width: '50%',
padding: '48px 32px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 20,
}}>
<div style={{ textAlign: 'center' }}>
<div style={{
width: 56,
height: 56,
borderRadius: 14,
background: 'linear-gradient(135deg, rgba(99,102,241,0.1) 0%, rgba(139,92,246,0.1) 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 12px',
}}>
<StarOutlined style={{ fontSize: 24, color: '#6366f1' }} />
</div>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b', marginBottom: 4 }}>
VIP专属内容
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
</Typography.Text>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{
width: 56,
height: 56,
borderRadius: 14,
background: 'linear-gradient(135deg, rgba(245,158,11,0.1) 0%, rgba(217,119,6,0.1) 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 12px',
}}>
<ThunderboltOutlined style={{ fontSize: 24, color: '#f59e0b' }} />
</div>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b', marginBottom: 4 }}>
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
AI分析
</Typography.Text>
</div>
<Button
type="primary"
size="large"
onClick={() => setModalOpen(true)}
<Typography.Title level={4} style={{ marginBottom: 20, color: '#1e293b' }}>
<FlameOutlined style={{ marginRight: 8, color: '#f59e0b' }} />
</Typography.Title>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 16 }}>
{industries.map((industry, index) => (
<div
key={index}
style={{
background: '#fff',
borderRadius: 12,
padding: '12px 32px',
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
border: 'none',
boxShadow: '0 8px 24px rgba(99,102,241,0.35)',
fontWeight: 600,
padding: 16,
textAlign: 'center',
boxShadow: '0 2px 8px rgba(0,0,0,0.04)',
}}
>
<LockOutlined style={{ marginRight: 8 }} />
</Button>
</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4, marginBottom: 8 }}>
<span style={{ fontSize: 20, fontWeight: 700, color: industry.color }}>{index + 1}</span>
{industry.hot && (
<span style={{
fontSize: 10,
padding: '2px 8px',
borderRadius: 10,
background: industry.hot === 'HOT' ? 'rgba(239,68,68,0.1)' : 'rgba(16,185,129,0.1)',
color: industry.hot === 'HOT' ? '#ef4444' : '#10b981',
fontWeight: 600,
}}>
{industry.hot}
</span>
)}
</div>
<Typography.Text strong style={{ color: '#1e293b', fontSize: 14 }}>
{industry.name}
</Typography.Text>
<div style={{
marginTop: 8,
fontSize: 12,
color: '#10b981',
fontWeight: 600,
}}>
{industry.trend}
</div>
</div>
))}
</div>
</Card>
<Modal
title={<Space><MessageOutlined /></Space>}
open={modalOpen}
onCancel={() => setModalOpen(false)}
footer={null}
width={480}
>
<div style={{ padding: 16 }}>
<div style={{
background: 'linear-gradient(135deg, rgba(99,102,241,0.04) 0%, rgba(139,92,246,0.04) 100%)',
borderRadius: 12,
padding: 20,
marginBottom: 20,
}}>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b', marginBottom: 12 }}>
VIP会员
</Typography.Title>
<Typography.Text style={{ color: '#64748b', fontSize: 14, lineHeight: 1.8 }}>
VIP会员即可解锁热门广场全部功能
</Typography.Text>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: 16, background: '#fafbfc', borderRadius: 12 }}>
<div style={{
width: 48,
height: 48,
borderRadius: 12,
background: 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
<PhoneOutlined style={{ fontSize: 20, color: '#fff' }} />
</div>
<div>
<Typography.Text strong style={{ color: '#1e293b' }}>线</Typography.Text>
<div style={{ color: '#6366f1', fontSize: 18, fontWeight: 600 }}>400-888-8888</div>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: 16, background: '#fafbfc', borderRadius: 12 }}>
<div style={{
width: 48,
height: 48,
borderRadius: 12,
background: 'linear-gradient(135deg, #ec4899 0%, #db2777 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
<MailOutlined style={{ fontSize: 20, color: '#fff' }} />
</div>
<div>
<Typography.Text strong style={{ color: '#1e293b' }}></Typography.Text>
<div style={{ color: '#6366f1', fontSize: 14 }}>vip@videogen.ai</div>
</div>
</div>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b' }}>
<AwardOutlined style={{ marginRight: 8, color: '#6366f1' }} />
</Typography.Title>
<Button
type="primary"
size="middle"
onClick={handleUnlock}
style={{
borderRadius: 10,
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
border: 'none',
}}
>
<LockOutlined style={{ marginRight: 6 }} />
</Button>
</div>
<Button
type="primary"
block
size="large"
onClick={() => {
message.success('已复制客服热线到剪贴板');
navigator.clipboard.writeText('400-888-8888');
setModalOpen(false);
}}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20 }}>
{hotMaterials.map((material) => (
<Card
key={material.id}
bordered={false}
style={{
marginTop: 20,
borderRadius: 12,
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
border: 'none',
boxShadow: '0 4px 16px rgba(99,102,241,0.3)',
borderRadius: 16,
overflow: 'hidden',
boxShadow: '0 4px 16px rgba(0,0,0,0.06)',
}}
>
</Button>
</div>
</Modal>
<div style={{ position: 'relative' }}>
<img
src={material.thumbnail}
alt={material.title}
style={{ width: '100%', height: 180, objectFit: 'cover' }}
/>
<div style={{
position: 'absolute',
top: 12,
left: 12,
padding: '4px 12px',
background: 'rgba(0,0,0,0.6)',
borderRadius: 8,
color: '#fff',
fontSize: 12,
}}>
{material.industry}
</div>
</div>
<div style={{ padding: 16 }}>
<Typography.Title level={5} style={{ marginBottom: 8, color: '#1e293b' }}>
{material.title}
</Typography.Title>
<div style={{ display: 'flex', alignItems: 'center', gap: 16, color: '#64748b', fontSize: 13 }}>
<span><StarOutlined style={{ marginRight: 4 }} />{material.views} </span>
<span><CrownOutlined style={{ marginRight: 4 }} />{material.likes} </span>
</div>
<Button
type="primary"
block
size="small"
onClick={handleUnlock}
style={{
marginTop: 12,
borderRadius: 8,
background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
border: 'none',
}}
>
<ThunderboltOutlined style={{ marginRight: 4 }} />
</Button>
</div>
</Card>
))}
</div>
</div>
);
};