资源存储
This commit is contained in:
@@ -27,6 +27,18 @@ const MOCK_USER: User = {
|
||||
username: 'videomaker',
|
||||
email: 'demo@videogen.ai',
|
||||
credits: 2680,
|
||||
resourceCapacity: {
|
||||
enabled: true,
|
||||
source: 'user',
|
||||
hasUserConfig: true,
|
||||
usedBytes: 298161654,
|
||||
availableBytes: 300349549066,
|
||||
totalBytes: 300647710720,
|
||||
usagePercent: 0.1,
|
||||
exceeded: false,
|
||||
limitValue: '280.000',
|
||||
limitUnit: 'GB',
|
||||
},
|
||||
};
|
||||
|
||||
const MOCK_CREDIT_RECORDS: CreditRecord[] = [
|
||||
|
||||
@@ -61,10 +61,146 @@ import {
|
||||
} from '@ant-design/icons';
|
||||
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAuthStore } from '../../store/useAuthStore';
|
||||
import { getMenuConfigs, getRechargePackages, getPaymentMethods, createRechargeOrder, getPaymentOrder, cancelPaymentOrder, getSiteInfo, getUnreadCount, createContactRequest } from '../../api';
|
||||
import { getMenuConfigs, getRechargePackages, getPaymentMethods, createRechargeOrder, getPaymentOrder, cancelPaymentOrder, getSiteInfo, getUnreadCount, createContactRequest, getUser } from '../../api';
|
||||
import NotificationPopup from '../NotificationPopup';
|
||||
import './AppLayout.css';
|
||||
|
||||
// ── ResourceCapacity 类型(与 src/types/index.ts 保持一致) ──
|
||||
type ResourceCapacityData = {
|
||||
enabled: boolean;
|
||||
usedBytes: number;
|
||||
totalBytes: number;
|
||||
availableBytes: number;
|
||||
usagePercent: number;
|
||||
exceeded: boolean;
|
||||
limitValue: string;
|
||||
limitUnit: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 资源存储展示卡片
|
||||
* - enabled === true:显示「已用 / 总额」+ 进度条(超额时变红并提示)
|
||||
* - enabled === false:按 usedBytes 大小自动选 KB / MB / GB / TB 单位显示「当前使用」
|
||||
*/
|
||||
const StorageCard: React.FC<{ data: ResourceCapacityData | null }> = ({ data }) => {
|
||||
if (!data) return null;
|
||||
|
||||
// 单位:后端返回的 limitUnit(KB / MB / GB)
|
||||
const unit = (data.limitUnit || 'GB').toUpperCase();
|
||||
const divisor = unit === 'GB' ? 1024 ** 3 : unit === 'MB' ? 1024 ** 2 : 1024;
|
||||
|
||||
// 百分比(可能 > 100)
|
||||
const rawPercent = Number(data.usagePercent) || 0;
|
||||
// 进度条宽度最多 100%
|
||||
const barPercent = Math.min(100, Math.max(0, rawPercent));
|
||||
|
||||
// 总额:优先用后端 limitValue,兜底 totalBytes / divisor
|
||||
const total = data.limitValue
|
||||
? parseFloat(data.limitValue)
|
||||
: data.totalBytes / divisor;
|
||||
|
||||
// 已用 = 总额 × 百分比 / 100(保证数字与 percent 自洽)
|
||||
const used = (total * rawPercent) / 100;
|
||||
// 剩余 = 总额 - 已用
|
||||
const available = total - used;
|
||||
|
||||
// 超额判断
|
||||
const isOver = data.exceeded || rawPercent >= 100;
|
||||
|
||||
// enabled === false 时按 usedBytes 自动选单位
|
||||
const KB = 1024;
|
||||
const MB = 1024 ** 2;
|
||||
const GB = 1024 ** 3;
|
||||
const TB = 1024 ** 4;
|
||||
const formatUsedAuto = (bytes: number) => {
|
||||
const b = Number(bytes) || 0;
|
||||
if (b >= TB) return { val: (b / TB).toFixed(2), unit: 'TB' };
|
||||
if (b >= GB) return { val: (b / GB).toFixed(2), unit: 'GB' };
|
||||
if (b >= MB) return { val: (b / MB).toFixed(2), unit: 'MB' };
|
||||
return { val: (b / KB).toFixed(2), unit: 'KB' };
|
||||
};
|
||||
const usedAuto = formatUsedAuto(data.usedBytes);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
marginTop: 12,
|
||||
padding: '10px 12px',
|
||||
borderRadius: 10,
|
||||
background: 'linear-gradient(135deg, rgba(248, 250, 252, 0.9) 0%, rgba(241, 245, 249, 0.9) 100%)',
|
||||
border: `1px solid ${isOver ? 'rgba(239, 68, 68, 0.25)' : 'rgba(99, 102, 241, 0.15)'}`,
|
||||
boxShadow: '0 2px 12px rgba(0, 0, 0, 0.04)',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 6,
|
||||
fontSize: 12,
|
||||
color: '#475569',
|
||||
}}
|
||||
>
|
||||
<span style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
||||
<DatabaseOutlined style={{ fontSize: 12, color: isOver ? '#ef4444' : '#6366f1' }} />
|
||||
资源存储
|
||||
</span>
|
||||
{data.enabled ? (
|
||||
<span style={{ fontWeight: 500, color: isOver ? '#ef4444' : '#1e293b' }}>
|
||||
{used.toFixed(2)} / {total.toFixed(2)} {unit}
|
||||
</span>
|
||||
) : (
|
||||
<span style={{ fontWeight: 500, color: '#1e293b' }}>
|
||||
当前使用 {usedAuto.val} {usedAuto.unit}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{data.enabled && (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 6,
|
||||
background: '#e2e8f0',
|
||||
borderRadius: 3,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: `${barPercent}%`,
|
||||
height: '100%',
|
||||
background: isOver
|
||||
? 'linear-gradient(90deg, #ef4444, #dc2626)'
|
||||
: 'linear-gradient(90deg, #6366f1, #8b5cf6)',
|
||||
borderRadius: 3,
|
||||
transition: 'width 0.4s ease',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 4,
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
fontSize: 11,
|
||||
color: isOver ? '#ef4444' : '#94a3b8',
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
{isOver
|
||||
? `存储超额 · 超用 ${Math.abs(available).toFixed(2)} ${unit}`
|
||||
: `剩余 ${available.toFixed(2)} ${unit}`}
|
||||
</span>
|
||||
<span>{rawPercent.toFixed(1)}%</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface MenuConfig {
|
||||
id: string;
|
||||
key?: string;
|
||||
@@ -179,6 +315,18 @@ const AppLayout: React.FC = () => {
|
||||
const [contactHovered, setContactHovered] = useState(false);
|
||||
const [submittingContact, setSubmittingContact] = useState(false);
|
||||
|
||||
// 资源存储容量(从 getUser().resource_capacity 获取)
|
||||
const [resourceCapacity, setResourceCapacity] = useState<{
|
||||
enabled: boolean;
|
||||
usedBytes: number;
|
||||
totalBytes: number;
|
||||
availableBytes: number;
|
||||
usagePercent: number;
|
||||
exceeded: boolean;
|
||||
limitValue: string;
|
||||
limitUnit: string;
|
||||
} | null>(null);
|
||||
|
||||
const PENDING_ORDER_KEY = 'pending_payment_order';
|
||||
|
||||
useEffect(() => {
|
||||
@@ -207,6 +355,31 @@ const AppLayout: React.FC = () => {
|
||||
}).catch(() => { });
|
||||
}, []);
|
||||
|
||||
// 拉取用户资源容量信息
|
||||
useEffect(() => {
|
||||
getUser().then((res: any) => {
|
||||
console.log('[Storage] getUser 返回:', res);
|
||||
|
||||
const rc = res?.resourceCapacity;
|
||||
if (rc) {
|
||||
setResourceCapacity({
|
||||
enabled: !!rc.enabled,
|
||||
usedBytes: Number(rc.usedBytes) || 0,
|
||||
totalBytes: Number(rc.totalBytes) || 0,
|
||||
availableBytes: Number(rc.availableBytes) || 0,
|
||||
usagePercent: Number(rc.usagePercent) || 0,
|
||||
exceeded: !!rc.exceeded,
|
||||
limitValue: rc.limitValue ?? '',
|
||||
limitUnit: rc.limitUnit || 'GB',
|
||||
});
|
||||
}
|
||||
// 没数据时不显示
|
||||
}).catch((err: any) => {
|
||||
console.error('[Storage] getUser 失败:', err);
|
||||
// 接口失败也不显示
|
||||
});
|
||||
}, []);
|
||||
|
||||
const loadUnreadCount = () => {
|
||||
getUnreadCount().then(count => {
|
||||
setUnreadCount(count);
|
||||
@@ -620,6 +793,9 @@ const AppLayout: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
{/* 资源存储容量展示(来自 getUser.resourceCapacity) */}
|
||||
<StorageCard data={resourceCapacity} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -714,6 +890,9 @@ const AppLayout: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 资源存储容量展示(与桌面端共用 StorageCard) */}
|
||||
<StorageCard data={resourceCapacity} />
|
||||
|
||||
{topLevelItems.map(item => {
|
||||
const menuType = item.menu_type ?? item.menuType;
|
||||
const hasChildren = childMap[item.id] && childMap[item.id].length > 0;
|
||||
|
||||
+564
-158
@@ -3,20 +3,26 @@
|
||||
:root {
|
||||
--font-sans: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
--nav-bg: #f8f9fb;
|
||||
--nav-surface: rgba(0,0,0,0.02);
|
||||
--nav-surface: rgba(0, 0, 0, 0.02);
|
||||
--nav-border: #e5e7eb;
|
||||
--nav-text: #1f2937;
|
||||
--nav-text-muted: #6b7280;
|
||||
--nav-hover: rgba(0,0,0,0.04);
|
||||
--nav-active: rgba(99,102,241,0.08);
|
||||
--nav-hover: rgba(0, 0, 0, 0.04);
|
||||
--nav-active: rgba(99, 102, 241, 0.08);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after { box-sizing: border-box; }
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: var(--font-sans);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
@@ -24,23 +30,68 @@ html, body {
|
||||
color: #1a1a2e;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
#root { min-height: 100vh; }
|
||||
|
||||
|
||||
#root {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Scrollbar ─────────────────────────── */
|
||||
::-webkit-scrollbar { width: 5px; height: 5px; }
|
||||
::-webkit-scrollbar-track { background: transparent; }
|
||||
::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 3px; }
|
||||
::-webkit-scrollbar-thumb:hover { background: #9ca3af; }
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #d1d5db;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #9ca3af;
|
||||
}
|
||||
|
||||
/* ── Electric Border Animation ─────────── */
|
||||
@keyframes electric-pulse {
|
||||
0%, 100% { opacity: 0.4; filter: blur(1px); }
|
||||
50% { opacity: 1; filter: blur(0); }
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.4;
|
||||
filter: blur(1px);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes electric-flow {
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.content_box {
|
||||
margin: -24px -32px -32px;
|
||||
border-radius: 0 0 16px 16px;
|
||||
height: calc(100vh - 34px);
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.electric-border-card {
|
||||
@@ -51,16 +102,14 @@ html, body {
|
||||
position: absolute;
|
||||
inset: -2px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
#6366f1,
|
||||
#8b5cf6,
|
||||
#a855f7,
|
||||
#6366f1,
|
||||
#8b5cf6,
|
||||
#a855f7,
|
||||
#6366f1
|
||||
);
|
||||
background: linear-gradient(90deg,
|
||||
#6366f1,
|
||||
#8b5cf6,
|
||||
#a855f7,
|
||||
#6366f1,
|
||||
#8b5cf6,
|
||||
#a855f7,
|
||||
#6366f1);
|
||||
background-size: 300% 100%;
|
||||
animation: electric-flow 3s linear infinite, electric-pulse 2s ease-in-out infinite;
|
||||
z-index: 0;
|
||||
@@ -85,6 +134,7 @@ html, body {
|
||||
0% {
|
||||
background-position: -200% center;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 200% center;
|
||||
}
|
||||
@@ -97,16 +147,14 @@ html, body {
|
||||
.shiny-text {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
#6366f1 0%,
|
||||
#8b5cf6 20%,
|
||||
#a855f7 40%,
|
||||
#c084fc 50%,
|
||||
#a855f7 60%,
|
||||
#8b5cf6 80%,
|
||||
#6366f1 100%
|
||||
);
|
||||
background: linear-gradient(90deg,
|
||||
#6366f1 0%,
|
||||
#8b5cf6 20%,
|
||||
#a855f7 40%,
|
||||
#c084fc 50%,
|
||||
#a855f7 60%,
|
||||
#8b5cf6 80%,
|
||||
#6366f1 100%);
|
||||
background-size: 200% auto;
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
@@ -118,92 +166,225 @@ html, body {
|
||||
|
||||
/* ── Keyframe Animations ───────────────── */
|
||||
@keyframes fadeInUp {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInLeft {
|
||||
from { opacity: 0; transform: translateX(-20px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInRight {
|
||||
from { opacity: 0; transform: translateX(20px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float1 {
|
||||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||
50% { transform: translate(20px, -30px) scale(1.05); }
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0) scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translate(20px, -30px) scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float2 {
|
||||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||
50% { transform: translate(-15px, 20px) scale(0.95); }
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0) scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translate(-15px, 20px) scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float3 {
|
||||
0%, 100% { transform: translate(0, 0) rotate(0deg); }
|
||||
50% { transform: translate(10px, -15px) rotate(3deg); }
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0) rotate(0deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translate(10px, -15px) rotate(3deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInCard {
|
||||
from { opacity: 0; transform: translateY(14px) scale(0.97); }
|
||||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(14px) scale(0.97);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinSlow {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fadeInUp { animation: fadeInUp 0.45s ease-out both; }
|
||||
.animate-fadeInLeft { animation: fadeInLeft 0.55s ease-out both; }
|
||||
.animate-fadeInRight { animation: fadeInRight 0.55s ease-out both; }
|
||||
.animate-slideInCard { animation: slideInCard 0.4s ease-out both; }
|
||||
.animate-float1 { animation: float1 8s ease-in-out infinite; }
|
||||
.animate-float2 { animation: float2 10s ease-in-out infinite; }
|
||||
.animate-float3 { animation: float3 12s ease-in-out infinite; }
|
||||
.animate-fadeInUp {
|
||||
animation: fadeInUp 0.45s ease-out both;
|
||||
}
|
||||
|
||||
.ref-thumb:hover .ref-delete { opacity: 1 !important; }
|
||||
.animate-fadeInLeft {
|
||||
animation: fadeInLeft 0.55s ease-out both;
|
||||
}
|
||||
|
||||
.stagger-children > *:nth-child(1) { animation-delay: 0.04s; }
|
||||
.stagger-children > *:nth-child(2) { animation-delay: 0.10s; }
|
||||
.stagger-children > *:nth-child(3) { animation-delay: 0.16s; }
|
||||
.stagger-children > *:nth-child(4) { animation-delay: 0.22s; }
|
||||
.stagger-children > *:nth-child(5) { animation-delay: 0.28s; }
|
||||
.stagger-children > *:nth-child(6) { animation-delay: 0.34s; }
|
||||
.animate-fadeInRight {
|
||||
animation: fadeInRight 0.55s ease-out both;
|
||||
}
|
||||
|
||||
.animate-slideInCard {
|
||||
animation: slideInCard 0.4s ease-out both;
|
||||
}
|
||||
|
||||
.animate-float1 {
|
||||
animation: float1 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float2 {
|
||||
animation: float2 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float3 {
|
||||
animation: float3 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.ref-thumb:hover .ref-delete {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.stagger-children>*:nth-child(1) {
|
||||
animation-delay: 0.04s;
|
||||
}
|
||||
|
||||
.stagger-children>*:nth-child(2) {
|
||||
animation-delay: 0.10s;
|
||||
}
|
||||
|
||||
.stagger-children>*:nth-child(3) {
|
||||
animation-delay: 0.16s;
|
||||
}
|
||||
|
||||
.stagger-children>*:nth-child(4) {
|
||||
animation-delay: 0.22s;
|
||||
}
|
||||
|
||||
.stagger-children>*:nth-child(5) {
|
||||
animation-delay: 0.28s;
|
||||
}
|
||||
|
||||
.stagger-children>*:nth-child(6) {
|
||||
animation-delay: 0.34s;
|
||||
}
|
||||
|
||||
/* ── Ant Design Overrides ──────────────── */
|
||||
.ant-input, .ant-input-affix-wrapper, .ant-select-selector, .ant-input-number {
|
||||
.ant-input,
|
||||
.ant-input-affix-wrapper,
|
||||
.ant-select-selector,
|
||||
.ant-input-number {
|
||||
border-radius: 10px !important;
|
||||
transition: all 0.25s ease !important;
|
||||
}
|
||||
.ant-input:focus, .ant-input-affix-wrapper:focus, .ant-input-affix-wrapper-focused,
|
||||
|
||||
.ant-input:focus,
|
||||
.ant-input-affix-wrapper:focus,
|
||||
.ant-input-affix-wrapper-focused,
|
||||
.ant-select-focused .ant-select-selector {
|
||||
box-shadow: 0 0 0 3px rgba(99,102,241,0.12) !important;
|
||||
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12) !important;
|
||||
border-color: #6366f1 !important;
|
||||
}
|
||||
|
||||
.ant-btn {
|
||||
border-radius: 10px !important;
|
||||
transition: all 0.25s ease !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
.ant-btn:hover { transform: none; }
|
||||
.ant-btn:active { transform: translateY(0); }
|
||||
.ant-card { border-radius: 16px !important; transition: all 0.3s ease !important; }
|
||||
.ant-modal-content { border-radius: 20px !important; overflow: hidden; }
|
||||
.ant-tag { font-size: 12px; border-radius: 8px !important; }
|
||||
|
||||
.ant-btn:hover {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.ant-btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
border-radius: 16px !important;
|
||||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
border-radius: 20px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-tag {
|
||||
font-size: 12px;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
/* ── Recharge card hover ───────────────── */
|
||||
.recharge-card {
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.recharge-card:hover {
|
||||
transform: translateY(-8px) scale(1.02) !important;
|
||||
box-shadow: 0 20px 40px rgba(99,102,241,0.15) !important;
|
||||
box-shadow: 0 20px 40px rgba(99, 102, 241, 0.15) !important;
|
||||
}
|
||||
|
||||
.recharge-card .recharge-price {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.recharge-card:hover .recharge-price {
|
||||
transform: scale(1.08);
|
||||
}
|
||||
.recharge-card .recharge-price { transition: all 0.3s ease; }
|
||||
.recharge-card:hover .recharge-price { transform: scale(1.08); }
|
||||
|
||||
/* ── Homepage tabs ────────────────────── */
|
||||
.homepage-tabs .ant-tabs-nav {
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.homepage-tabs .ant-tabs-tab {
|
||||
padding: 8px 16px !important;
|
||||
font-size: 13px !important;
|
||||
@@ -211,13 +392,16 @@ html, body {
|
||||
color: #6b7280 !important;
|
||||
transition: all 0.25s !important;
|
||||
}
|
||||
|
||||
.homepage-tabs .ant-tabs-tab:hover {
|
||||
color: #6366f1 !important;
|
||||
}
|
||||
|
||||
.homepage-tabs .ant-tabs-tab-active .ant-tabs-tab-btn {
|
||||
color: #6366f1 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.homepage-tabs .ant-tabs-ink-bar {
|
||||
background: linear-gradient(90deg, #6366f1, #a855f7) !important;
|
||||
height: 3px !important;
|
||||
@@ -230,108 +414,249 @@ html, body {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.project-card:hover {
|
||||
transform: translateY(-4px) !important;
|
||||
box-shadow: 0 16px 40px rgba(99,102,241,0.12) !important;
|
||||
box-shadow: 0 16px 40px rgba(99, 102, 241, 0.12) !important;
|
||||
border-color: #6366f1 !important;
|
||||
}
|
||||
|
||||
/* ── Mobile Bottom Nav ─────────────────── */
|
||||
.mobile-bottom-nav {
|
||||
display: none;
|
||||
position: fixed; bottom: 0; left: 0; right: 0; z-index: 200;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 200;
|
||||
height: 60px;
|
||||
background: rgba(255,255,255,0.95);
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(24px);
|
||||
border-top: 1px solid rgba(0,0,0,0.05);
|
||||
box-shadow: 0 -4px 20px rgba(0,0,0,0.06);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.mobile-bottom-nav .nav-item {
|
||||
flex: 1; display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center; gap: 2px;
|
||||
cursor: pointer; transition: all 0.2s;
|
||||
color: #8b8fa3; font-size: 9px; font-weight: 400;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
color: #8b8fa3;
|
||||
font-size: 9px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav .nav-item.active {
|
||||
color: #08080c;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav .nav-item .nav-icon {
|
||||
font-size: 18px; transition: transform 0.2s;
|
||||
font-size: 18px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav .nav-item.active .nav-icon {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* ── Responsive Breakpoints ────────────── */
|
||||
@media (max-width: 768px) {
|
||||
.desktop-sidebar { display: none !important; }
|
||||
.desktop-content { margin-left: 0 !important; padding: 16px !important; padding-bottom: 80px !important; overflow-x: hidden !important; }
|
||||
.desktop-sidebar-toggle-zone { display: none !important; }
|
||||
.mobile-bottom-nav { display: flex !important; }
|
||||
.desktop-sidebar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.desktop-content {
|
||||
margin-left: 0 !important;
|
||||
padding: 16px !important;
|
||||
padding-bottom: 80px !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
.desktop-sidebar-toggle-zone {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
/* Prevent horizontal overflow globally */
|
||||
html, body { overflow-x: hidden !important; }
|
||||
html,
|
||||
body {
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
.mobile-hide { display: none !important; }
|
||||
.mobile-full { width: 100% !important; max-width: 100% !important; }
|
||||
.mobile-stack { flex-direction: column !important; }
|
||||
.mobile-p-16 { padding: 16px !important; }
|
||||
.mobile-gap-12 { gap: 12px !important; }
|
||||
.mobile-hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-full {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.mobile-stack {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.mobile-p-16 {
|
||||
padding: 16px !important;
|
||||
}
|
||||
|
||||
.mobile-gap-12 {
|
||||
gap: 12px !important;
|
||||
}
|
||||
|
||||
/* Login page */
|
||||
.login-page { flex-direction: column !important; }
|
||||
.login-left { display: none !important; }
|
||||
.login-right { padding: 24px 16px !important; }
|
||||
.login-card { width: 100% !important; }
|
||||
.login-page {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.login-left {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.login-right {
|
||||
padding: 24px 16px !important;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* Project list */
|
||||
.project-item { flex-direction: column !important; align-items: flex-start !important; }
|
||||
.project-item .project-actions { margin-left: 0 !important; margin-top: 12px; width: 100%; justify-content: flex-end; }
|
||||
.project-item {
|
||||
flex-direction: column !important;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.project-item .project-actions {
|
||||
margin-left: 0 !important;
|
||||
margin-top: 12px;
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* Generate page header */
|
||||
.gen-header { flex-direction: column !important; gap: 12px !important; padding: 16px 18px !important; }
|
||||
.gen-header {
|
||||
flex-direction: column !important;
|
||||
gap: 12px !important;
|
||||
padding: 16px 18px !important;
|
||||
}
|
||||
|
||||
/* Operation flow bar */
|
||||
.gen-flow-bar { flex-direction: column !important; gap: 14px !important; padding: 16px !important; }
|
||||
.gen-flow-divider { display: none !important; }
|
||||
.gen-flow-bar {
|
||||
flex-direction: column !important;
|
||||
gap: 14px !important;
|
||||
padding: 16px !important;
|
||||
}
|
||||
|
||||
.gen-flow-divider {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Config form params row */
|
||||
.gen-form-row { flex-direction: column !important; gap: 0 !important; }
|
||||
.gen-form-row {
|
||||
flex-direction: column !important;
|
||||
gap: 0 !important;
|
||||
}
|
||||
|
||||
/* Credits estimate bar */
|
||||
.gen-credits-bar { flex-direction: column !important; gap: 8px !important; text-align: center; }
|
||||
.gen-credits-bar {
|
||||
flex-direction: column !important;
|
||||
gap: 8px !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Prompt rows */
|
||||
.gen-prompt-row { flex-direction: column !important; }
|
||||
.gen-prompt-row > * { width: 100% !important; }
|
||||
.gen-params { flex-wrap: wrap !important; gap: 8px !important; }
|
||||
.gen-params > div { flex: 1 1 45% !important; min-width: 0; }
|
||||
.gen-prompt-row {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.gen-prompt-row>* {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.gen-params {
|
||||
flex-wrap: wrap !important;
|
||||
gap: 8px !important;
|
||||
}
|
||||
|
||||
.gen-params>div {
|
||||
flex: 1 1 45% !important;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Expanded detail left+right stacks */
|
||||
.gen-detail-row { flex-direction: column !important; }
|
||||
.gen-detail-row > * { width: 100% !important; min-width: 0 !important; flex: 1 1 auto !important; }
|
||||
.gen-detail-row {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.gen-detail-row>* {
|
||||
width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
flex: 1 1 auto !important;
|
||||
}
|
||||
|
||||
/* Record filter bar stacks */
|
||||
.record-filter-bar { flex-direction: column !important; }
|
||||
.record-filter-bar .ant-space { flex-wrap: wrap !important; }
|
||||
.record-filter-bar .ant-select { width: 100% !important; }
|
||||
.record-filter-bar {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.record-filter-bar .ant-space {
|
||||
flex-wrap: wrap !important;
|
||||
}
|
||||
|
||||
.record-filter-bar .ant-select {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* Record summary row stacks */
|
||||
.record-item { flex-direction: column !important; align-items: flex-start !important; gap: 8px !important; overflow: hidden !important; }
|
||||
.record-item .record-actions { width: 100% !important; justify-content: flex-end; }
|
||||
.record-item > span[style*="textOverflow"] { white-space: normal !important; overflow: visible !important; text-overflow: unset !important; }
|
||||
.record-item {
|
||||
flex-direction: column !important;
|
||||
align-items: flex-start !important;
|
||||
gap: 8px !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.record-item .record-actions {
|
||||
width: 100% !important;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.record-item>span[style*="textOverflow"] {
|
||||
white-space: normal !important;
|
||||
overflow: visible !important;
|
||||
text-overflow: unset !important;
|
||||
}
|
||||
|
||||
/* Hide less important meta on mobile */
|
||||
.mobile-meta { display: none !important; }
|
||||
.mobile-meta {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Credits page */
|
||||
.credits-balance { flex-direction: column !important; }
|
||||
.recharge-grid { flex-direction: column !important; }
|
||||
.recharge-grid > * { width: 100% !important; }
|
||||
.credits-balance {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.recharge-grid {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.recharge-grid>* {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* Video player fits mobile */
|
||||
video { max-width: 100% !important; }
|
||||
video {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
/* InitialReplication page */
|
||||
.replication-container {
|
||||
@@ -340,17 +665,20 @@ html, body {
|
||||
padding: 16px !important;
|
||||
height: calc(100vh - 64px) !important;
|
||||
}
|
||||
|
||||
.replication-preview {
|
||||
width: 100% !important;
|
||||
height: 30vh !important;
|
||||
border-radius: 12px !important;
|
||||
}
|
||||
|
||||
.replication-form {
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
max-height: calc(70vh - 32px) !important;
|
||||
border-radius: 12px !important;
|
||||
}
|
||||
|
||||
.replication-form-content {
|
||||
padding: 16px !important;
|
||||
max-height: calc(70vh - 64px) !important;
|
||||
@@ -358,56 +686,92 @@ html, body {
|
||||
}
|
||||
|
||||
/* ── Date Display ──────────────────────── */
|
||||
.date-display { font-family: 'SF Mono', 'Menlo', 'Consolas', monospace; }
|
||||
.date-display {
|
||||
font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;
|
||||
}
|
||||
|
||||
/* ── Small Mobile Breakpoint (max-width: 480px) ────────────── */
|
||||
@media (max-width: 480px) {
|
||||
|
||||
/* Base styles */
|
||||
html, body { font-size: 14px !important; }
|
||||
html,
|
||||
body {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
/* Login page */
|
||||
.login-card { width: 100% !important; }
|
||||
.login-right { padding: 16px !important; }
|
||||
.login-card {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.login-right {
|
||||
padding: 16px !important;
|
||||
}
|
||||
|
||||
/* Header adjustments */
|
||||
.gen-header { padding: 12px 14px !important; }
|
||||
.gen-header {
|
||||
padding: 12px 14px !important;
|
||||
}
|
||||
|
||||
/* Form elements */
|
||||
.gen-form-row { gap: 8px !important; }
|
||||
|
||||
.gen-form-row {
|
||||
gap: 8px !important;
|
||||
}
|
||||
|
||||
/* Button adjustments */
|
||||
.ant-btn { height: 36px !important; font-size: 13px !important; padding: 0 12px !important; }
|
||||
|
||||
.ant-btn {
|
||||
height: 36px !important;
|
||||
font-size: 13px !important;
|
||||
padding: 0 12px !important;
|
||||
}
|
||||
|
||||
/* Input adjustments */
|
||||
.ant-input, .ant-input-affix-wrapper, .ant-select-selector {
|
||||
height: 36px !important;
|
||||
.ant-input,
|
||||
.ant-input-affix-wrapper,
|
||||
.ant-select-selector {
|
||||
height: 36px !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
/* Card padding */
|
||||
.ant-card { padding: 12px !important; }
|
||||
.ant-card {
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
/* Mobile bottom nav adjustments */
|
||||
.mobile-bottom-nav { height: 56px !important; }
|
||||
.mobile-bottom-nav .nav-item .nav-icon { font-size: 18px !important; }
|
||||
.mobile-bottom-nav .nav-item { font-size: 9px !important; gap: 2px !important; }
|
||||
.mobile-bottom-nav {
|
||||
height: 56px !important;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav .nav-item .nav-icon {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav .nav-item {
|
||||
font-size: 9px !important;
|
||||
gap: 2px !important;
|
||||
}
|
||||
|
||||
/* InitialReplication page - Small Mobile */
|
||||
.replication-container {
|
||||
padding: 12px !important;
|
||||
gap: 12px !important;
|
||||
}
|
||||
|
||||
.replication-preview {
|
||||
height: 25vh !important;
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
|
||||
.replication-form-content {
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
.replication-form-content .ant-btn {
|
||||
height: 36px !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.replication-form-content .ant-input,
|
||||
.replication-form-content .ant-input-affix-wrapper {
|
||||
height: 36px !important;
|
||||
@@ -415,30 +779,56 @@ html, body {
|
||||
}
|
||||
|
||||
/* Video and image containers */
|
||||
video, img {
|
||||
max-height: 160px !important;
|
||||
video,
|
||||
img {
|
||||
max-height: 160px !important;
|
||||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
/* Upload areas */
|
||||
.upload-area { padding: 12px !important; }
|
||||
.upload-area {
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
/* Spacing adjustments */
|
||||
.mobile-p-16 { padding: 12px !important; }
|
||||
.mobile-gap-12 { gap: 8px !important; }
|
||||
.mobile-p-16 {
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
.mobile-gap-12 {
|
||||
gap: 8px !important;
|
||||
}
|
||||
|
||||
/* Font size adjustments */
|
||||
h1 { font-size: 18px !important; }
|
||||
h2 { font-size: 16px !important; }
|
||||
h3 { font-size: 14px !important; }
|
||||
p { font-size: 12px !important; }
|
||||
h1 {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
/* Button text */
|
||||
.btn-text-sm { font-size: 12px !important; }
|
||||
.btn-text-sm {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
/* Margin adjustments */
|
||||
.mobile-mb-8 { margin-bottom: 8px !important; }
|
||||
.mobile-mb-12 { margin-bottom: 12px !important; }
|
||||
.mobile-mb-8 {
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.mobile-mb-12 {
|
||||
margin-bottom: 12px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Tablet Breakpoint (769px to 1024px) ────────────── */
|
||||
@@ -450,33 +840,49 @@ html, body {
|
||||
*/
|
||||
|
||||
/* Card max-width */
|
||||
.ant-card { max-width: calc(50% - 8px) !important; }
|
||||
.ant-card {
|
||||
max-width: calc(50% - 8px) !important;
|
||||
}
|
||||
|
||||
/* Font adjustments */
|
||||
html, body { font-size: 15px !important; }
|
||||
html,
|
||||
body {
|
||||
font-size: 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Large Desktop Breakpoint (min-width: 1200px) ────────────── */
|
||||
@media (min-width: 1200px) {
|
||||
|
||||
/* Max width container */
|
||||
.max-w-container { max-width: 1400px; margin: 0 auto; }
|
||||
.max-w-container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Card grid */
|
||||
.card-grid { grid-template-columns: repeat(3, 1fr) !important; }
|
||||
.card-grid {
|
||||
grid-template-columns: repeat(3, 1fr) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── HomePage Tabs ────────────── */
|
||||
.homepage-tabs .ant-tabs-nav { margin-bottom: 0; }
|
||||
.homepage-tabs .ant-tabs-nav {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.homepage-tabs .ant-tabs-tab {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding: 8px 20px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.homepage-tabs .ant-tabs-tab-active {
|
||||
color: #6366f1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.homepage-tabs .ant-tabs-ink-bar {
|
||||
background: linear-gradient(135deg, #6366f1, #8b5cf6);
|
||||
}
|
||||
}
|
||||
@@ -8,127 +8,326 @@ import {
|
||||
PlayCircleOutlined,
|
||||
CheckCircleOutlined,
|
||||
HeartOutlined,
|
||||
EyeOutlined,
|
||||
ArrowRightOutlined,
|
||||
CrownOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const CreativePlazaPage: React.FC = () => {
|
||||
const handleUnlock = () => {
|
||||
message.info('请联系客服开通');
|
||||
message.info('请联系客服开通会员');
|
||||
};
|
||||
|
||||
|
||||
// 顶部特性卡片
|
||||
const features = [
|
||||
{
|
||||
icon: <ThunderboltOutlined style={{ fontSize: 28, color: '#8b5cf6' }} />,
|
||||
title: 'AI智能生成',
|
||||
description: '先进的AI技术,一键生成高质量视频内容',
|
||||
icon: <ThunderboltOutlined style={{ fontSize: 26, color: '#8b5cf6' }} />,
|
||||
title: 'AI 智能生成',
|
||||
description: '先进 AI 技术一键产出高质量视频内容',
|
||||
},
|
||||
{
|
||||
icon: <PlayCircleOutlined style={{ fontSize: 28, color: '#ec4899' }} />,
|
||||
icon: <PlayCircleOutlined style={{ fontSize: 26, color: '#ec4899' }} />,
|
||||
title: '多格式输出',
|
||||
description: '支持多种视频格式,满足不同场景需求',
|
||||
description: '支持多种视频格式,满足不同场景需求',
|
||||
},
|
||||
{
|
||||
icon: <CheckCircleOutlined style={{ fontSize: 28, color: '#10b981' }} />,
|
||||
icon: <CheckCircleOutlined style={{ fontSize: 26, color: '#10b981' }} />,
|
||||
title: '品质保证',
|
||||
description: '专业级画质,细节清晰,色彩鲜艳',
|
||||
description: '专业级画质,细节清晰,色彩鲜艳',
|
||||
},
|
||||
{
|
||||
icon: <HeartOutlined style={{ fontSize: 28, color: '#f59e0b' }} />,
|
||||
icon: <HeartOutlined style={{ fontSize: 26, color: '#f59e0b' }} />,
|
||||
title: '创意无限',
|
||||
description: '丰富的模板和风格,激发创作灵感',
|
||||
description: '丰富模板与风格,激发创作灵感',
|
||||
},
|
||||
];
|
||||
|
||||
// 精选案例占位
|
||||
const caseList = [
|
||||
{ title: '美妆直播切片', tag: '热门', tagColor: '#ef4444' },
|
||||
{ title: '3C 数码测评', tag: '推荐', tagColor: '#6366f1' },
|
||||
{ title: '美食探店 vlog', tag: '推荐', tagColor: '#6366f1' },
|
||||
{ title: '服饰穿搭合集', tag: '热门', tagColor: '#ef4444' },
|
||||
{ title: '家居场景展示', tag: '推荐', tagColor: '#6366f1' },
|
||||
{ title: '母婴亲子内容', tag: '热门', tagColor: '#ef4444' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px 0' }}>
|
||||
<div style={{ marginBottom: 32 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
|
||||
<div style={{
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 14,
|
||||
background: 'linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxShadow: '0 4px 16px rgba(139,92,246,0.3)',
|
||||
}}>
|
||||
<GiftOutlined style={{ fontSize: 22, color: '#fff' }} />
|
||||
<div className="content_box">
|
||||
{/* 顶部 Hero 区域 */}
|
||||
<div
|
||||
className="animate-fadeInUp"
|
||||
style={{
|
||||
padding: '28px 32px',
|
||||
borderRadius: 16,
|
||||
background: 'linear-gradient(135deg, #f5f3ff 0%, #ede9fe 50%, #fce7f3 100%)',
|
||||
border: '1px solid rgba(139, 92, 246, 0.12)',
|
||||
marginBottom: 24,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 12 }}>
|
||||
<div
|
||||
style={{
|
||||
width: 52,
|
||||
height: 52,
|
||||
borderRadius: 14,
|
||||
background: 'linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxShadow: '0 6px 20px rgba(139, 92, 246, 0.3)',
|
||||
}}
|
||||
>
|
||||
<GiftOutlined style={{ fontSize: 24, 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 }}>
|
||||
探索AI创作无限可能
|
||||
<div className="shiny-text-container" style={{ marginBottom: 4 }}>
|
||||
<span className="shiny-text" style={{ fontSize: 26, fontWeight: 700 }}>
|
||||
创意素材案例
|
||||
</span>
|
||||
</Typography.Title>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#7c3aed' }}>
|
||||
<CrownOutlined style={{ fontSize: 12 }} />
|
||||
<span>探索 AI 创作无限可能</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Typography.Text style={{ color: '#64748b' }}>
|
||||
精选AI生成的优秀素材案例,展示AI创作的无限潜力与创意灵感
|
||||
<Typography.Text style={{ color: '#64748b', fontSize: 14, lineHeight: 1.7 }}>
|
||||
精选 AI 生成的优秀素材案例,展示 AI 创作的无限潜力与创意灵感
|
||||
</Typography.Text>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 20, marginBottom: 32 }}>
|
||||
{/* 特性卡片 */}
|
||||
{/* <div
|
||||
className="animate-fadeInUp stagger-children"
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(4, 1fr)',
|
||||
gap: 16,
|
||||
marginBottom: 24,
|
||||
}}
|
||||
>
|
||||
{features.map((feature, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
bordered={false}
|
||||
hoverable
|
||||
className="project-card"
|
||||
style={{
|
||||
borderRadius: 16,
|
||||
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,
|
||||
background: '#fff',
|
||||
border: '1px solid #e2e8f0',
|
||||
padding: '4px 0',
|
||||
}}
|
||||
styles={{ body: { padding: 20 } }}
|
||||
>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ marginBottom: 16 }}>{feature.icon}</div>
|
||||
<Typography.Title level={4} style={{ marginBottom: 8, color: '#1e293b' }}>
|
||||
<div style={{ textAlign: 'left' }}>
|
||||
<div
|
||||
style={{
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 12,
|
||||
background: 'linear-gradient(135deg, rgba(139, 92, 246, 0.08), rgba(99, 102, 241, 0.08))',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 14,
|
||||
}}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<div style={{ fontSize: 15, fontWeight: 600, color: '#1e293b', marginBottom: 6 }}>
|
||||
{feature.title}
|
||||
</Typography.Title>
|
||||
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
|
||||
</div>
|
||||
<div style={{ fontSize: 13, color: '#64748b', lineHeight: 1.6 }}>
|
||||
{feature.description}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<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: 10,
|
||||
background: 'linear-gradient(135deg, #8b5cf6 0%, #a78bfa 100%)',
|
||||
border: 'none',
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ marginRight: 6 }} />
|
||||
解锁全部案例
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Card
|
||||
bordered={false}
|
||||
{/* 精选案例展示区域 */}
|
||||
<div
|
||||
className="animate-fadeInUp"
|
||||
style={{
|
||||
padding: '24px 28px',
|
||||
borderRadius: 16,
|
||||
background: '#fafafa',
|
||||
padding: 40,
|
||||
textAlign: 'center',
|
||||
background: '#fff',
|
||||
// border: '1px solid #e2e8f0',
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<div style={{ color: '#94a3b8', fontSize: 14 }}>
|
||||
敬请期待更多创意案例
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<div
|
||||
style={{
|
||||
width: 4,
|
||||
height: 18,
|
||||
background: 'linear-gradient(180deg, #6366f1, #8b5cf6)',
|
||||
borderRadius: 2,
|
||||
marginRight: 10,
|
||||
}}
|
||||
/>
|
||||
<StarOutlined style={{ marginRight: 8, color: '#f59e0b', fontSize: 16 }} />
|
||||
<span style={{ fontSize: 17, fontWeight: 600, color: '#1f2937' }}>精选案例展示</span>
|
||||
|
||||
</div>
|
||||
{/* <Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={handleUnlock}
|
||||
style={{
|
||||
borderRadius: 10,
|
||||
fontWeight: 500,
|
||||
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
|
||||
border: 'none',
|
||||
boxShadow: '0 4px 14px rgba(99, 102, 241, 0.28)',
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ marginRight: 6 }} />
|
||||
解锁全部案例
|
||||
<ArrowRightOutlined style={{ marginLeft: 4, fontSize: 12 }} />
|
||||
</Button> */}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* 案例网格 */}
|
||||
<div
|
||||
className="stagger-children"
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(3, 1fr)',
|
||||
gap: 16,
|
||||
marginBottom: 16,
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
zIndex: 1,
|
||||
background: 'rgb(255,255,255)',
|
||||
// background:
|
||||
// 'linear-gradient(180deg, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.55) 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
borderRadius: 14,
|
||||
// boxShadow: '0px 4px 16px rgba(0, 0, 0, 0.08)',
|
||||
gap: 4,
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={handleUnlock}
|
||||
style={{
|
||||
borderRadius: 10,
|
||||
fontWeight: 500,
|
||||
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
|
||||
border: 'none',
|
||||
boxShadow: '0 4px 14px rgba(99, 102, 241, 0.28)',
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ marginRight: 6 }} />
|
||||
解锁全部案例
|
||||
<ArrowRightOutlined style={{ marginLeft: 4, fontSize: 12 }} />
|
||||
</Button>
|
||||
{/* <LockOutlined style={{ fontSize: 22, color: '#94a3b8', cursor: 'pointer' }}
|
||||
onClick={handleUnlock}
|
||||
/>
|
||||
<span style={{ fontSize: 16, color: '#1f2937', opacity: 0.9 }}>会员可查看</span> */}
|
||||
</div>
|
||||
|
||||
{caseList.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="project-card animate-fadeInUp"
|
||||
style={{
|
||||
position: 'relative',
|
||||
borderRadius: 14,
|
||||
overflow: 'hidden',
|
||||
cursor: 'pointer',
|
||||
border: '1px solid #e2e8f0',
|
||||
background: '#fff',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
aspectRatio: '16/9',
|
||||
background:
|
||||
'linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #4c1d95 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{/* 模糊视频缩略图占位 */}
|
||||
<PlayCircleOutlined style={{ fontSize: 36, color: 'rgba(255,255,255,0.6)' }} />
|
||||
{/* 标签 */}
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 10,
|
||||
left: 10,
|
||||
padding: '2px 8px',
|
||||
borderRadius: 6,
|
||||
background: item.tagColor,
|
||||
color: '#fff',
|
||||
fontSize: 11,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{item.tag}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
padding: '10px 14px',
|
||||
background: '#f8fafc',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontSize: 13,
|
||||
color: '#334155',
|
||||
fontWeight: 500,
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</span>
|
||||
<EyeOutlined style={{ fontSize: 13, color: '#94a3b8' }} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* 锁定遮罩 */}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreativePlazaPage;
|
||||
export default CreativePlazaPage;
|
||||
|
||||
@@ -72,7 +72,7 @@ const HomePage: React.FC = () => {
|
||||
setActiveTab(key);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const aiEntries = [
|
||||
{
|
||||
@@ -120,21 +120,43 @@ const HomePage: React.FC = () => {
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
margin: '-24px -32px -32px',
|
||||
borderRadius: 20,
|
||||
height: 'calc(100vh - 34px)',
|
||||
overflow: 'auto',
|
||||
scrollbarWidth: 'none',
|
||||
padding: '0 28px 32px',
|
||||
}}>
|
||||
<div className="content_box">
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
|
||||
<h3>首页工作台</h3>
|
||||
<p
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
fontSize: 12, letterSpacing: 0.3,
|
||||
padding: '10px 16px',
|
||||
backgroundColor: '#ffffffff',
|
||||
borderRadius: 30,
|
||||
boxShadow: '0px 4px 12px 0px rgba(0, 0, 0, 0.1)',
|
||||
|
||||
}}
|
||||
|
||||
>如需进行账户素材推送:
|
||||
<span
|
||||
style={{
|
||||
color: '#1a50bbff',
|
||||
|
||||
}}
|
||||
onClick={() => {
|
||||
navigate('/authorization')
|
||||
}}>
|
||||
一键推送
|
||||
<ArrowRightOutlined style={{ marginLeft: 8, transform: 'rotate(0deg)' }} />
|
||||
</span>
|
||||
|
||||
|
||||
</p>
|
||||
</div>
|
||||
{/* ========== 顶部工作台引导区域(三步流程) ========== */}
|
||||
<div className="animate-fadeInUp" style={{
|
||||
padding: '24px 28px',
|
||||
borderRadius: 16,
|
||||
background: 'linear-gradient(135deg, #f0f9ff 0%, #faf5ff 50%, #fef3c7 100%)',
|
||||
border: '1px solid rgba(99,102,241,0.10)',
|
||||
margin: '24px 0 20px',
|
||||
margin: '0 0 20px',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
@@ -151,7 +173,7 @@ const HomePage: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div >
|
||||
{/* <div >
|
||||
<span style={{
|
||||
cursor: 'pointer',
|
||||
fontSize: 12, color: '#1a50bbff', letterSpacing: 0.3,
|
||||
@@ -159,11 +181,11 @@ const HomePage: React.FC = () => {
|
||||
onClick={() => {
|
||||
navigate('/authorization')
|
||||
}}
|
||||
>一键授权
|
||||
>如需进行账户素材推送 一键推送
|
||||
<ArrowRightOutlined style={{ marginLeft: 8, transform: 'rotate(0deg)' }} />
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -553,7 +575,7 @@ const HomePage: React.FC = () => {
|
||||
近期作品
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
{/* Tab切换 */}
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
@@ -739,7 +761,7 @@ const HomePage: React.FC = () => {
|
||||
|
||||
|
||||
{/* ========== 素材案例区域 ========== */}
|
||||
<div className="animate-fadeInUp" style={{
|
||||
{/* <div className="animate-fadeInUp" style={{
|
||||
padding: '24px 28px',
|
||||
borderRadius: 16,
|
||||
background: '#fff',
|
||||
@@ -800,7 +822,7 @@ const HomePage: React.FC = () => {
|
||||
alt={`素材案例 ${index + 1}`}
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
{/* 案例悬停遮罩(由父级 hover 触发) */}
|
||||
案例悬停遮罩(由父级 hover 触发)
|
||||
<div
|
||||
className="case-overlay"
|
||||
style={{
|
||||
@@ -824,7 +846,7 @@ const HomePage: React.FC = () => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -31,6 +31,8 @@ function InitialInfo() {
|
||||
// 引擎和视频参数相关状态
|
||||
const [enginesele, setEnginesele] = useState<any>({});
|
||||
const [countType, setCountType] = useState('');
|
||||
// 图片引擎 id:取自 getEngine().engine.image[0].id
|
||||
const [imageEngineId, setImageEngineId] = useState<string>('');
|
||||
const [showEngineModal, setShowEngineModal] = useState(false);
|
||||
const [showVideoSettingsModal, setShowVideoSettingsModal] = useState(false);
|
||||
const [videoDuration, setVideoDuration] = useState(5);
|
||||
@@ -160,6 +162,10 @@ function InitialInfo() {
|
||||
durations: firstEngine.supportedDurations || [5, 8, 10, 12, 15],
|
||||
});
|
||||
}
|
||||
// 默认选中第一个图片引擎
|
||||
if (data.engine?.image && data.engine.image.length > 0) {
|
||||
setImageEngineId(data.engine.image[0].id);
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
});
|
||||
@@ -335,7 +341,7 @@ function InitialInfo() {
|
||||
|
||||
const createimage = (stepId: number) => {
|
||||
let params = {
|
||||
engine_id: "0019e3dac0b795b925b",
|
||||
engine_id: imageEngineId,
|
||||
image_proportion: "1:1",
|
||||
image_px: "2048x2048",
|
||||
image_size: "2K"
|
||||
@@ -349,7 +355,7 @@ function InitialInfo() {
|
||||
const newcreateimage = () => {
|
||||
// console.log('下一步:', stepId);
|
||||
let params = {
|
||||
engine_id: "0019e3dac0b795b925b",
|
||||
engine_id: imageEngineId,
|
||||
image_proportion: "1:1",
|
||||
image_px: "2048x2048",
|
||||
image_size: "2K"
|
||||
|
||||
@@ -850,6 +850,7 @@ const GenerateConver: React.FC = () => {
|
||||
</div>
|
||||
) : (
|
||||
<Upload
|
||||
style={{ width: '100%' }}
|
||||
beforeUpload={beforeVideoUpload}
|
||||
showUploadList={false}
|
||||
accept="video/mp4,video/quicktime,.mp4,.mov"
|
||||
@@ -965,6 +966,8 @@ const GenerateConver: React.FC = () => {
|
||||
</div>
|
||||
) : (
|
||||
<Upload
|
||||
style={{ width: '100%' }}
|
||||
|
||||
beforeUpload={beforeImageUpload}
|
||||
showUploadList={false}
|
||||
accept="image/jpeg,image/jpg,image/png,.jpg,.jpeg,.png"
|
||||
|
||||
@@ -1,115 +1,655 @@
|
||||
import React from 'react';
|
||||
import { Button, Card, message, Typography } from 'antd';
|
||||
import { Button, message, Typography } from 'antd';
|
||||
import {
|
||||
StarOutlined,
|
||||
CrownOutlined,
|
||||
LockOutlined,
|
||||
ThunderboltOutlined,
|
||||
GiftOutlined,
|
||||
BarChartOutlined,
|
||||
FireOutlined,
|
||||
TrophyOutlined,
|
||||
LockOutlined,
|
||||
ArrowRightOutlined,
|
||||
PlayCircleOutlined,
|
||||
EyeOutlined,
|
||||
LikeOutlined,
|
||||
CommentOutlined,
|
||||
ShareAltOutlined,
|
||||
RiseOutlined,
|
||||
ThunderboltOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const PopularPage: React.FC = () => {
|
||||
const handleUnlock = () => {
|
||||
message.info('请联系客服开通');
|
||||
message.info('请联系客服开通会员');
|
||||
};
|
||||
|
||||
// 顶部统计 KPI
|
||||
const stats = [
|
||||
{
|
||||
icon: <FireOutlined style={{ fontSize: 22, color: '#f59e0b' }} />,
|
||||
label: '今日爆款',
|
||||
value: '1,286',
|
||||
unit: '条',
|
||||
trend: '+12.5%',
|
||||
color: '#f59e0b',
|
||||
},
|
||||
{
|
||||
icon: <EyeOutlined style={{ fontSize: 22, color: '#6366f1' }} />,
|
||||
label: '总浏览量',
|
||||
value: '428',
|
||||
unit: '万',
|
||||
trend: '+8.2%',
|
||||
color: '#6366f1',
|
||||
},
|
||||
{
|
||||
icon: <LikeOutlined style={{ fontSize: 22, color: '#ec4899' }} />,
|
||||
label: '总互动数',
|
||||
value: '76.4',
|
||||
unit: '万',
|
||||
trend: '+15.7%',
|
||||
color: '#ec4899',
|
||||
},
|
||||
{
|
||||
icon: <ThunderboltOutlined style={{ fontSize: 22, color: '#10b981' }} />,
|
||||
label: '上升最快',
|
||||
value: '美妆',
|
||||
unit: '赛道',
|
||||
trend: '+28.3%',
|
||||
color: '#10b981',
|
||||
},
|
||||
];
|
||||
|
||||
// 行业热度排行(假数据)
|
||||
const industryRank = [
|
||||
{ rank: 1, name: '美妆个护', hot: 98.5, change: 'up' as const, value: 98234 },
|
||||
{ rank: 2, name: '服饰穿搭', hot: 95.2, change: 'up' as const, value: 87643 },
|
||||
{ rank: 3, name: '美食探店', hot: 91.7, change: 'up' as const, value: 78921 },
|
||||
{ rank: 4, name: '3C 数码', hot: 87.3, change: 'down' as const, value: 65432 },
|
||||
{ rank: 5, name: '家居生活', hot: 82.6, change: 'up' as const, value: 54321 },
|
||||
{ rank: 6, name: '母婴亲子', hot: 78.1, change: 'flat' as const, value: 43210 },
|
||||
{ rank: 7, name: '运动健身', hot: 72.4, change: 'up' as const, value: 38765 },
|
||||
];
|
||||
|
||||
// 爆款素材榜单
|
||||
const popularList = [
|
||||
{
|
||||
rank: 1,
|
||||
title: '夏日美妆教程:3 步打造奶油肌',
|
||||
author: '美妆博主·小雅',
|
||||
views: '128.4w',
|
||||
likes: '12.6w',
|
||||
comments: '8,234',
|
||||
tag: 'NO.1',
|
||||
tagColor: '#f59e0b',
|
||||
},
|
||||
{
|
||||
rank: 2,
|
||||
title: '平价穿搭 | 学生党一周不重样',
|
||||
author: '穿搭达人·Miki',
|
||||
views: '96.2w',
|
||||
likes: '9.8w',
|
||||
comments: '6,128',
|
||||
tag: 'NO.2',
|
||||
tagColor: '#a78bfa',
|
||||
},
|
||||
{
|
||||
rank: 3,
|
||||
title: '探店 vlog | 网红咖啡馆测评',
|
||||
author: '美食探店·阿伦',
|
||||
views: '78.5w',
|
||||
likes: '7.4w',
|
||||
comments: '4,892',
|
||||
tag: 'NO.3',
|
||||
tagColor: '#6366f1',
|
||||
},
|
||||
{
|
||||
rank: 4,
|
||||
title: 'iPhone 16 Pro 一周深度体验',
|
||||
author: '数码评测·老王',
|
||||
views: '65.7w',
|
||||
likes: '6.1w',
|
||||
comments: '3,847',
|
||||
tag: 'NO.4',
|
||||
tagColor: '#94a3b8',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px 0' }}>
|
||||
<div style={{ marginBottom: 32 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
|
||||
<div style={{
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 14,
|
||||
background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxShadow: '0 4px 16px rgba(245,158,11,0.3)',
|
||||
}}>
|
||||
<BarChartOutlined style={{ fontSize: 22, color: '#fff' }} />
|
||||
<div className="content_box">
|
||||
{/* Hero 区域 - 橙金主题(区别创意素材案例的紫粉) */}
|
||||
<div
|
||||
className="animate-fadeInUp"
|
||||
style={{
|
||||
padding: '28px 32px',
|
||||
borderRadius: 16,
|
||||
background: 'linear-gradient(135deg, #fffbeb 0%, #fef3c7 50%, #fed7aa 100%)',
|
||||
border: '1px solid rgba(245, 158, 11, 0.18)',
|
||||
marginBottom: 24,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 12 }}>
|
||||
<div
|
||||
style={{
|
||||
width: 52,
|
||||
height: 52,
|
||||
borderRadius: 14,
|
||||
background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxShadow: '0 6px 20px rgba(245, 158, 11, 0.3)',
|
||||
}}
|
||||
>
|
||||
<BarChartOutlined style={{ fontSize: 24, 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 }}>
|
||||
发现热门素材趋势
|
||||
<div className="shiny-text-container" style={{ marginBottom: 4 }}>
|
||||
<span
|
||||
className="shiny-text"
|
||||
style={{
|
||||
fontSize: 26,
|
||||
fontWeight: 700,
|
||||
backgroundImage:
|
||||
'linear-gradient(90deg, #f59e0b 0%, #d97706 30%, #ea580c 50%, #d97706 70%, #f59e0b 100%)',
|
||||
}}
|
||||
>
|
||||
行业爆款大盘
|
||||
</span>
|
||||
</Typography.Title>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#b45309' }}>
|
||||
<RiseOutlined style={{ fontSize: 12 }} />
|
||||
<span>实时追踪全网热门素材趋势</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Typography.Text style={{ color: '#64748b' }}>
|
||||
实时追踪各行业爆款素材,把握创作风向,打造热门内容
|
||||
<Typography.Text style={{ color: '#78716c', fontSize: 14, lineHeight: 1.7 }}>
|
||||
实时追踪各行业爆款素材,把握创作风向,打造热门内容
|
||||
</Typography.Text>
|
||||
</div>
|
||||
|
||||
<Card
|
||||
bordered={false}
|
||||
{/* 4 个 KPI 统计卡片 */}
|
||||
{/* <div
|
||||
className="animate-fadeInUp stagger-children"
|
||||
style={{
|
||||
borderRadius: 20,
|
||||
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: 10,
|
||||
marginBottom: 32,
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(4, 1fr)',
|
||||
gap: 16,
|
||||
marginBottom: 24,
|
||||
}}
|
||||
>
|
||||
<Typography.Title level={4} style={{ marginBottom: 20, color: '#1e293b' }}>
|
||||
<FireOutlined style={{ marginRight: 8, color: '#f59e0b' }} />
|
||||
行业热度排行
|
||||
</Typography.Title>
|
||||
<Card
|
||||
bordered={false}
|
||||
style={{
|
||||
borderRadius: 16,
|
||||
background: '#fafafa',
|
||||
padding: 40,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ color: '#94a3b8', fontSize: 14 }}>
|
||||
敬请期待行业热度排行
|
||||
{stats.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="project-card"
|
||||
style={{
|
||||
padding: 20,
|
||||
borderRadius: 16,
|
||||
background: '#fff',
|
||||
border: '1px solid #e2e8f0',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 14,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 44,
|
||||
height: 44,
|
||||
borderRadius: 12,
|
||||
background: `linear-gradient(135deg, ${item.color}15, ${item.color}08)`,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{item.icon}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 2,
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
color: '#10b981',
|
||||
background: 'rgba(16, 185, 129, 0.08)',
|
||||
padding: '2px 8px',
|
||||
borderRadius: 6,
|
||||
}}
|
||||
>
|
||||
<RiseOutlined style={{ fontSize: 10 }} />
|
||||
{item.trend}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'baseline', gap: 4, marginBottom: 4 }}>
|
||||
<span style={{ fontSize: 24, fontWeight: 700, color: '#1e293b' }}>{item.value}</span>
|
||||
<span style={{ fontSize: 13, color: '#94a3b8' }}>{item.unit}</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 13, color: '#64748b' }}>{item.label}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Card>
|
||||
))}
|
||||
</div> */}
|
||||
{/* 行业热度排行 */}
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, color: '#1e293b' }}>
|
||||
<TrophyOutlined style={{ marginRight: 8, color: '#6366f1' }} />
|
||||
爆款素材榜单
|
||||
</Typography.Title>
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={handleUnlock}
|
||||
<div style={{ position: 'relative' }}>
|
||||
{/* <div
|
||||
className="animate-fadeInUp"
|
||||
style={{
|
||||
borderRadius: 10,
|
||||
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
|
||||
border: 'none',
|
||||
padding: '24px 28px',
|
||||
borderRadius: 16,
|
||||
background: '#fff',
|
||||
border: '1px solid #e2e8f0',
|
||||
marginBottom: 24,
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ marginRight: 6 }} />
|
||||
立即解锁全部
|
||||
</Button>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<div
|
||||
style={{
|
||||
width: 4,
|
||||
height: 18,
|
||||
background: 'linear-gradient(180deg, #f59e0b, #d97706)',
|
||||
borderRadius: 2,
|
||||
marginRight: 10,
|
||||
}}
|
||||
/>
|
||||
<FireOutlined style={{ marginRight: 8, color: '#f59e0b', fontSize: 16 }} />
|
||||
<span style={{ fontSize: 17, fontWeight: 600, color: '#1f2937' }}>行业热度排行</span>
|
||||
<span
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
fontSize: 12,
|
||||
fontWeight: 400,
|
||||
color: '#94a3b8',
|
||||
}}
|
||||
>
|
||||
基于近 7 天数据 · 实时更新
|
||||
</span>
|
||||
</div>
|
||||
<span style={{ fontSize: 12, color: '#94a3b8' }}>更新时间: 10 分钟前</span>
|
||||
</div>
|
||||
<div style={{position: 'relative', height: 300}}>
|
||||
<Typography.Text style={{ width: '100%', textAlign: 'center', color: '#64748b', display: 'block', height: 100, background: '#f3f4f6', marginTop: 20, marginBottom: 20, padding: 20, }}>
|
||||
实时追踪各行业爆款素材,把握创作风向,打造热门内容
|
||||
</Typography.Text>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
// background:
|
||||
// ' linear-gradient(180deg, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.7) 100%)',
|
||||
background: 'rgb(255,255,255)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
gap: 2,
|
||||
color: '#fff',
|
||||
borderRadius: 6,
|
||||
// boxShadow: '0 0 10px rgba(0,0,0,0.5)',
|
||||
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ fontSize: 18, color: '#94a3b8', cursor: 'pointer' }}
|
||||
onClick={handleUnlock}
|
||||
/>
|
||||
<span style={{ fontSize: 16, color: '#1f2937', opacity: 0.9 }}>立即解锁全部</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div className="stagger-children">
|
||||
{industryRank.map((item) => {
|
||||
const rankColors: Record<number, string> = {
|
||||
1: 'linear-gradient(135deg, #f59e0b, #d97706)',
|
||||
2: 'linear-gradient(135deg, #94a3b8, #64748b)',
|
||||
3: 'linear-gradient(135deg, #ea580c, #c2410c)',
|
||||
};
|
||||
const rankColor = rankColors[item.rank] || '#cbd5e1';
|
||||
const trendIcon =
|
||||
item.change === 'up' ? (
|
||||
<RiseOutlined style={{ fontSize: 11, color: '#10b981' }} />
|
||||
) : item.change === 'down' ? (
|
||||
<RiseOutlined
|
||||
style={{ fontSize: 11, color: '#ef4444', transform: 'rotate(180deg)' }}
|
||||
/>
|
||||
) : (
|
||||
<span style={{ fontSize: 11, color: '#94a3b8' }}>—</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={item.rank}
|
||||
className="project-card animate-fadeInUp"
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '12px 16px',
|
||||
borderRadius: 12,
|
||||
marginBottom: 8,
|
||||
background: '#f8fafc',
|
||||
border: '1px solid transparent',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 8,
|
||||
background: rankColor,
|
||||
color: '#fff',
|
||||
fontSize: 14,
|
||||
fontWeight: 700,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 14,
|
||||
boxShadow: item.rank <= 3 ? '0 2px 8px rgba(0,0,0,0.15)' : 'none',
|
||||
}}
|
||||
>
|
||||
{item.rank}
|
||||
</div>
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 14,
|
||||
fontWeight: 600,
|
||||
color: '#1e293b',
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
height: 6,
|
||||
background: '#e2e8f0',
|
||||
borderRadius: 3,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: `${item.hot}%`,
|
||||
height: '100%',
|
||||
background:
|
||||
item.rank === 1
|
||||
? 'linear-gradient(90deg, #f59e0b, #d97706)'
|
||||
: item.rank === 2
|
||||
? 'linear-gradient(90deg, #94a3b8, #64748b)'
|
||||
: item.rank === 3
|
||||
? 'linear-gradient(90deg, #ea580c, #c2410c)'
|
||||
: 'linear-gradient(90deg, #6366f1, #8b5cf6)',
|
||||
borderRadius: 3,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
width: 80,
|
||||
textAlign: 'right',
|
||||
fontSize: 14,
|
||||
fontWeight: 600,
|
||||
color: '#1e293b',
|
||||
marginLeft: 16,
|
||||
}}
|
||||
>
|
||||
{item.hot}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
width: 80,
|
||||
textAlign: 'right',
|
||||
fontSize: 12,
|
||||
color: '#64748b',
|
||||
marginLeft: 12,
|
||||
}}
|
||||
>
|
||||
{item.value.toLocaleString()} 素材
|
||||
</div>
|
||||
<div style={{ width: 24, marginLeft: 12, textAlign: 'center' }}>{trendIcon}</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* 爆款素材榜单 */}
|
||||
<div
|
||||
className="animate-fadeInUp"
|
||||
style={{
|
||||
padding: '24px 28px',
|
||||
borderRadius: 16,
|
||||
background: '#fff',
|
||||
// border: '1px solid #e2e8f0',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<div
|
||||
style={{
|
||||
width: 4,
|
||||
height: 18,
|
||||
background: 'linear-gradient(180deg, #6366f1, #8b5cf6)',
|
||||
borderRadius: 2,
|
||||
marginRight: 10,
|
||||
}}
|
||||
/>
|
||||
<TrophyOutlined style={{ marginRight: 8, color: '#6366f1', fontSize: 16 }} />
|
||||
<span style={{ fontSize: 17, fontWeight: 600, color: '#1f2937' }}>爆款素材榜单</span>
|
||||
<span
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
fontSize: 12,
|
||||
fontWeight: 400,
|
||||
color: '#94a3b8',
|
||||
}}
|
||||
>
|
||||
{/* TOP 100 */}
|
||||
</span>
|
||||
</div>
|
||||
{/* <Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={handleUnlock}
|
||||
style={{
|
||||
borderRadius: 10,
|
||||
fontWeight: 500,
|
||||
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
|
||||
border: 'none',
|
||||
boxShadow: '0 4px 14px rgba(99, 102, 241, 0.28)',
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ marginRight: 6 }} />
|
||||
立即解锁全部
|
||||
<ArrowRightOutlined style={{ marginLeft: 4, fontSize: 12 }} />
|
||||
</Button> */}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="stagger-children"
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(2, 1fr)',
|
||||
gap: 16,
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
zIndex: 1,
|
||||
inset: 0,
|
||||
// background:
|
||||
// ' linear-gradient(180deg, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.7) 100%)',
|
||||
background: 'rgb(255,255,255)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
gap: 2,
|
||||
color: '#fff',
|
||||
borderRadius: 6,
|
||||
// boxShadow: '0 0 10px rgba(0,0,0,0.5)',
|
||||
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={handleUnlock}
|
||||
style={{
|
||||
borderRadius: 10,
|
||||
fontWeight: 500,
|
||||
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
|
||||
border: 'none',
|
||||
boxShadow: '0 4px 14px rgba(99, 102, 241, 0.28)',
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ marginRight: 6 }} />
|
||||
立即解锁全部
|
||||
<ArrowRightOutlined style={{ marginLeft: 4, fontSize: 12 }} />
|
||||
</Button>
|
||||
{/* <LockOutlined style={{ fontSize: 18, color: '#94a3b8', cursor: 'pointer' }}
|
||||
onClick={handleUnlock}
|
||||
/>
|
||||
<span style={{ fontSize: 16, color: '#1f2937', opacity: 0.9 }}>立即解锁全部</span> */}
|
||||
</div>
|
||||
|
||||
{popularList.map((item) => (
|
||||
<div
|
||||
key={item.rank}
|
||||
className="project-card animate-fadeInUp"
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: 14,
|
||||
padding: 14,
|
||||
borderRadius: 14,
|
||||
background: '#fff',
|
||||
border: '1px solid #e2e8f0',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: 140,
|
||||
height: 80,
|
||||
flexShrink: 0,
|
||||
borderRadius: 10,
|
||||
overflow: 'hidden',
|
||||
background: 'linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #4c1d95 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<PlayCircleOutlined style={{ fontSize: 28, color: 'rgba(255,255,255,0.6)' }} />
|
||||
{/* 排名徽章 */}
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 6,
|
||||
left: 6,
|
||||
padding: '2px 8px',
|
||||
borderRadius: 6,
|
||||
background: item.tagColor,
|
||||
color: '#fff',
|
||||
fontSize: 11,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{item.tag}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }}>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 14,
|
||||
fontWeight: 600,
|
||||
color: '#1e293b',
|
||||
marginBottom: 4,
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</div>
|
||||
<div style={{ fontSize: 12, color: '#94a3b8', marginBottom: 8 }}>
|
||||
{item.author}
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 12, fontSize: 12, color: '#64748b' }}>
|
||||
<span>
|
||||
<EyeOutlined style={{ marginRight: 3 }} />
|
||||
{item.views}
|
||||
</span>
|
||||
<span>
|
||||
<LikeOutlined style={{ marginRight: 3 }} />
|
||||
{item.likes}
|
||||
</span>
|
||||
<span>
|
||||
<CommentOutlined style={{ marginRight: 3 }} />
|
||||
{item.comments}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* 锁定遮罩 */}
|
||||
{/* <div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
background:
|
||||
' linear-gradient(to right, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.7) 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
gap: 2,
|
||||
color: '#fff',
|
||||
borderRadius: 6,
|
||||
|
||||
}}
|
||||
>
|
||||
<LockOutlined style={{ fontSize: 18 }} />
|
||||
<span style={{ fontSize: 10, opacity: 0.9 }}>会员可看</span>
|
||||
</div> */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<Card
|
||||
bordered={false}
|
||||
style={{
|
||||
borderRadius: 16,
|
||||
background: '#fafafa',
|
||||
padding: 40,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ color: '#94a3b8', fontSize: 14 }}>
|
||||
敬请期待更多爆款素材
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PopularPage;
|
||||
export default PopularPage;
|
||||
|
||||
@@ -31,6 +31,8 @@ function InitialInfo() {
|
||||
// 引擎和视频参数相关状态
|
||||
const [enginesele, setEnginesele] = useState<any>({});
|
||||
const [countType, setCountType] = useState('');
|
||||
// 图片引擎 id:取自 getEngine().engine.image[0].id
|
||||
const [imageEngineId, setImageEngineId] = useState<string>('');
|
||||
const [showEngineModal, setShowEngineModal] = useState(false);
|
||||
const [showVideoSettingsModal, setShowVideoSettingsModal] = useState(false);
|
||||
const [videoDuration, setVideoDuration] = useState(5);
|
||||
@@ -155,6 +157,10 @@ function InitialInfo() {
|
||||
durations: firstEngine.supportedDurations || [5, 8, 10, 12, 15],
|
||||
});
|
||||
}
|
||||
// 默认选中第一个图片引擎
|
||||
if (data.engine?.image && data.engine.image.length > 0) {
|
||||
setImageEngineId(data.engine.image[0].id);
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
});
|
||||
@@ -341,7 +347,7 @@ function InitialInfo() {
|
||||
|
||||
const createimage = (stepId: number) => {
|
||||
let params = {
|
||||
engine_id: "0019e3dac0b795b925b",
|
||||
engine_id: imageEngineId,
|
||||
image_proportion: "1:1",
|
||||
image_px: "2048x2048",
|
||||
image_size: "2K"
|
||||
@@ -355,7 +361,7 @@ function InitialInfo() {
|
||||
const newcreateimage = () => {
|
||||
// console.log('下一步:', stepId);
|
||||
let params = {
|
||||
engine_id: "0019e3dac0b795b925b",
|
||||
engine_id: imageEngineId,
|
||||
image_proportion: "1:1",
|
||||
image_px: "2048x2048",
|
||||
image_size: "2K"
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
export interface ResourceCapacity {
|
||||
enabled: boolean;
|
||||
source?: string;
|
||||
hasUserConfig?: boolean;
|
||||
usedBytes: number;
|
||||
availableBytes: number;
|
||||
totalBytes: number;
|
||||
usagePercent: number;
|
||||
exceeded: boolean;
|
||||
limitValue?: string;
|
||||
limitUnit: string; // 'KB' | 'MB' | 'GB' 等
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
avatar?: string;
|
||||
credits: number;
|
||||
isAdmin?: boolean;
|
||||
phone?: string;
|
||||
allowedMenus?: string[] | null;
|
||||
mustSetPassword?: boolean;
|
||||
resourceCapacity?: ResourceCapacity;
|
||||
}
|
||||
|
||||
export interface CreditRecord {
|
||||
|
||||
Reference in New Issue
Block a user