feat: init ai-platform - 源码 + 配置

This commit is contained in:
2026-08-25 16:27:43 +08:00
commit 83210a606a
122 changed files with 27401 additions and 0 deletions
+299
View File
@@ -0,0 +1,299 @@
import { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { BrainCircuit, Calculator, Network, Boxes, ReceiptText, CalendarClock, Sparkles } from 'lucide-react';
import { useTheme } from '@/shared/context/ThemeContext';
import StarBackground from '@/shared/components/StarBackground';
import ThemeToggle from '@/shared/components/ThemeToggle';
import { modules } from '@/modules/registry';
const ICON_MAP: Record<string, React.ComponentType<{ size?: number; color?: string }>> = {
BrainCircuit,
Calculator,
Network,
Boxes,
ReceiptText,
CalendarClock,
Sparkles,
};
export default function HomePage() {
const navigate = useNavigate();
const { theme } = useTheme();
const isDark = theme === 'dark';
const [searchParams] = useSearchParams();
// 首页模块多时需纵向滚动;离开后恢复全局 overflow:hidden(其他模块自管布局)
useEffect(() => {
document.body.style.overflow = 'auto';
return () => { document.body.style.overflow = ''; };
}, []);
// 接收 URL 参数 userToken,写入 sessionStorage
useEffect(() => {
const userToken = searchParams.get('userToken');
if (userToken) {
sessionStorage.setItem('userToken', userToken);
}
}, [searchParams]);
return (
<div style={{
width: '100vw', minHeight: '100vh',
overflowX: 'hidden',
display: 'flex', flexDirection: 'column',
alignItems: 'stretch',
position: 'relative',
paddingTop: '64px',
boxSizing: 'border-box',
fontFamily: "-apple-system, 'SF Pro Display', 'SF Pro Text', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif",
color: isDark ? '#a8d8ff' : '#1e3a6e',
}}>
{/* 星空背景(dark)/ 浅色渐变(light) */}
{isDark ? (
<StarBackground theme="dark" />
) : (
<div style={{
position: 'fixed', top: 0, left: 0, width: '100%', height: '100%',
background: 'linear-gradient(160deg, #f8f8fb 0%, #f2f3f7 50%, #eef1f7 100%)',
zIndex: 0,
}} />
)}
{/* 顶部导航栏 */}
<div style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
height: '64px',
display: 'flex',
alignItems: 'center',
padding: '0 32px',
zIndex: 100,
background: isDark ? 'rgba(7,17,31,0.7)' : 'rgba(255,255,255,0.8)',
backdropFilter: 'blur(12px)',
borderBottom: `1px solid ${isDark ? 'rgba(0,212,255,0.15)' : 'rgba(0,0,0,0.06)'}`,
}}>
{/* 左上角 Logo + 标题 + 标语 */}
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
<img
src="/digiwin.svg"
alt="Digiwin"
style={{
height: '32px',
width: 'auto',
objectFit: 'contain',
filter: isDark ? 'drop-shadow(0 0 8px rgba(0,212,255,0.4))' : 'none'
}}
/>
<div style={{
width: '1px',
height: '24px',
background: isDark ? 'rgba(0,212,255,0.2)' : 'rgba(0,0,0,0.12)'
}} />
<div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
<h1 style={{
fontSize: 24, fontWeight: 700, letterSpacing: '0.04em', margin: 0,
...(isDark ? {
color: '#e8f4ff',
textShadow: '0 0 12px rgba(0,212,255,0.4)',
} : {
color: '#111827',
}),
}}>
EIOSpace
</h1>
<span style={{
fontSize: 13, fontWeight: 400, letterSpacing: '0.02em',
...(isDark ? { color: 'rgba(168,216,255,0.6)' } : { color: '#6b7280' }),
}}>
企业智能 · 数据驱动 · 产业赋能
</span>
</div>
</div>
{/* 右上角主题切换 */}
<div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center' }}>
<ThemeToggle />
</div>
</div>
{/* 内容层 */}
<div style={{ position: 'relative', zIndex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 32, padding: '32px 24px 60px', maxWidth: 1400, width: '100%', margin: '0 auto' }}>
{/* 模块卡片网格 */}
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(4, 1fr)',
gap: 20,
width: '100%',
maxWidth: 1400,
animation: 'card-in 0.5s 0.2s both',
}}>
{modules.map((mod, idx) => {
const IconComp = ICON_MAP[mod.icon];
const accentColor = isDark ? mod.accentColor : mod.accentColorLight;
const gradient = isDark ? mod.gradient : mod.gradientLight;
return (
<div
key={mod.id}
onClick={() => navigate(mod.path)}
style={{
borderRadius: 20,
overflow: 'hidden',
cursor: 'pointer',
transition: 'all 0.25s ease',
animation: `card-in 0.4s ${0.1 + idx * 0.08}s both`,
...(isDark ? {
background: 'rgba(0,20,60,0.55)',
border: '1px solid rgba(0,212,255,0.25)',
boxShadow: '0 0 20px rgba(0,212,255,0.06), inset 0 1px 0 rgba(255,255,255,0.05)',
backdropFilter: 'blur(12px)',
} : {
background: '#ffffff',
border: '1px solid rgba(10,122,255,0.12)',
boxShadow: '0 2px 12px rgba(0,0,0,0.06)',
}),
}}
onMouseEnter={(e) => {
if (isDark) {
e.currentTarget.style.borderColor = `${accentColor}60`;
e.currentTarget.style.boxShadow = `0 0 30px ${accentColor}20, inset 0 1px 0 rgba(255,255,255,0.08)`;
e.currentTarget.style.transform = 'translateY(-4px)';
} else {
e.currentTarget.style.borderColor = `${accentColor}40`;
e.currentTarget.style.boxShadow = `0 8px 24px rgba(0,0,0,0.10)`;
e.currentTarget.style.transform = 'translateY(-4px)';
}
}}
onMouseLeave={(e) => {
if (isDark) {
e.currentTarget.style.borderColor = 'rgba(0,212,255,0.25)';
e.currentTarget.style.boxShadow = '0 0 20px rgba(0,212,255,0.06), inset 0 1px 0 rgba(255,255,255,0.05)';
e.currentTarget.style.transform = 'translateY(0)';
} else {
e.currentTarget.style.borderColor = 'rgba(10,122,255,0.12)';
e.currentTarget.style.boxShadow = '0 2px 12px rgba(0,0,0,0.06)';
e.currentTarget.style.transform = 'translateY(0)';
}
}}
>
{/* 卡片顶部渐变条 */}
<div style={{
height: 108,
background: gradient,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
overflow: 'hidden',
}}>
{/* 扫光动画(dark模式) */}
{isDark && (
<div style={{
position: 'absolute', top: 0, left: '-100%', width: '60%', height: '100%',
background: `linear-gradient(to right, transparent, ${accentColor}15, transparent)`,
animation: 'space-border-scan 3s linear infinite',
}} />
)}
{IconComp && <IconComp size={48} color={isDark ? accentColor : '#ffffff'} />}
</div>
{/* 卡片内容 */}
<div style={{ padding: '20px 24px 24px' }}>
<h2 style={{
fontSize: 20, fontWeight: 800, letterSpacing: '0.04em', margin: '0 0 8px',
...(isDark ? {
color: '#e8f4ff',
textShadow: `0 0 12px ${accentColor}50`,
} : {
color: '#111827',
}),
}}>
{mod.name}
</h2>
<p style={{
fontSize: 14, lineHeight: 1.6, margin: '0 0 16px',
...(isDark ? { color: 'rgba(168,216,255,0.7)' } : { color: '#6b7280' }),
}}>
{mod.description}
</p>
{/* 标签 */}
<div style={{ display: 'flex', gap: 8, marginBottom: 16 }}>
{mod.tags.map(tag => (
<span key={tag} style={{
padding: '3px 10px', borderRadius: 20, fontSize: 12, fontWeight: 600,
...(isDark ? {
background: `${accentColor}10`,
border: `1px solid ${accentColor}30`,
color: accentColor,
} : {
background: `${accentColor}08`,
border: `1px solid ${accentColor}20`,
color: accentColor,
}),
}}>
{tag}
</span>
))}
</div>
{/* 进入按钮 */}
<button style={{
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
width: '100%', padding: '10px 0', borderRadius: 12,
fontSize: 14, fontWeight: 700, cursor: 'pointer',
transition: 'all 0.18s ease',
...(isDark ? {
background: `${accentColor}12`,
border: `1px solid ${accentColor}35`,
color: accentColor,
} : {
background: accentColor,
border: 'none',
color: '#ffffff',
}),
}}
onMouseEnter={(e) => {
if (isDark) {
e.currentTarget.style.background = `${accentColor}20`;
e.currentTarget.style.borderColor = accentColor;
e.currentTarget.style.boxShadow = `0 0 16px ${accentColor}30`;
} else {
e.currentTarget.style.background = `${accentColor}dd`;
e.currentTarget.style.boxShadow = `0 4px 12px ${accentColor}30`;
}
}}
onMouseLeave={(e) => {
if (isDark) {
e.currentTarget.style.background = `${accentColor}12`;
e.currentTarget.style.borderColor = `${accentColor}35`;
e.currentTarget.style.boxShadow = 'none';
} else {
e.currentTarget.style.background = accentColor;
e.currentTarget.style.boxShadow = 'none';
}
}}
>
进入模块 →
</button>
</div>
</div>
);
})}
</div>
{/* 底部品牌 */}
<div style={{
textAlign: 'center',
...(isDark ? { color: 'rgba(0,212,255,0.55)' } : { color: '#aeaeb2' }),
fontSize: 13, letterSpacing: '0.06em',
}}>
Powered by Digiwin EIOSpace
</div>
</div>
</div>
);
}