finstep-template-cli 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/cli.js +117 -0
- package/package.json +39 -0
- package/template/.env.development +3 -0
- package/template/.env.production +3 -0
- package/template/.env.staging +3 -0
- package/template/.env.test +3 -0
- package/template/.eslintrc.cjs +21 -0
- package/template/README.md +69 -0
- package/template/auto-imports.d.ts +47 -0
- package/template/eslint.config.js +26 -0
- package/template/index.html +16 -0
- package/template/package.json +46 -0
- package/template/postcss.config.js +5 -0
- package/template/public/logo.svg +85 -0
- package/template/public/vite.svg +1 -0
- package/template/src/App.css +42 -0
- package/template/src/App.tsx +25 -0
- package/template/src/api/home/index.ts +56 -0
- package/template/src/api/home/typings.d.ts +8 -0
- package/template/src/assets/logo.svg +85 -0
- package/template/src/assets/react.svg +1 -0
- package/template/src/components/admin-layout.tsx +211 -0
- package/template/src/components/f-b-footer.tsx +46 -0
- package/template/src/components/f-b-header.tsx +894 -0
- package/template/src/components/global-loading.tsx +143 -0
- package/template/src/components/hero-section.tsx +371 -0
- package/template/src/components/products-preview.tsx +175 -0
- package/template/src/components/stats-section.tsx +85 -0
- package/template/src/components/trusted-by.tsx +53 -0
- package/template/src/hooks/useGlobalLoading.ts +57 -0
- package/template/src/index.css +341 -0
- package/template/src/main.tsx +30 -0
- package/template/src/pages/admin/index.tsx +361 -0
- package/template/src/pages/admin/pages/applications/index.tsx +558 -0
- package/template/src/pages/home/index.tsx +129 -0
- package/template/src/router/index.tsx +9 -0
- package/template/src/router/routes.tsx +30 -0
- package/template/src/stores/loading.store.ts +46 -0
- package/template/src/stores/root.store.ts +22 -0
- package/template/src/stores/store-context.tsx +43 -0
- package/template/src/stores/user.store.ts +46 -0
- package/template/src/utils/index.ts +14 -0
- package/template/src/utils/request.ts +116 -0
- package/template/src/utils/tokenManager.ts +168 -0
- package/template/src/vite-env.d.ts +1 -0
- package/template/tailwind.config.js +19 -0
- package/template/tsconfig.app.json +29 -0
- package/template/tsconfig.json +7 -0
- package/template/tsconfig.node.json +26 -0
- package/template/vite.config.ts +36 -0
@@ -0,0 +1,143 @@
|
|
1
|
+
// AI生成的代码 - 全局Loading组件
|
2
|
+
import React from "react";
|
3
|
+
import { observer } from "mobx-react-lite";
|
4
|
+
import { useStore } from "@/stores/store-context";
|
5
|
+
import { motion, AnimatePresence } from "framer-motion";
|
6
|
+
import logoSvg from "../assets/logo.svg";
|
7
|
+
|
8
|
+
// AI生成的代码 - Logo动画变体
|
9
|
+
const logoVariants = {
|
10
|
+
initial: {
|
11
|
+
scale: 1,
|
12
|
+
rotate: 0,
|
13
|
+
},
|
14
|
+
animate: {
|
15
|
+
scale: [1, 1.1, 1],
|
16
|
+
rotate: [0, 5, -5, 0],
|
17
|
+
transition: {
|
18
|
+
duration: 2,
|
19
|
+
repeat: Infinity,
|
20
|
+
ease: [0.4, 0, 0.6, 1] as const,
|
21
|
+
},
|
22
|
+
},
|
23
|
+
};
|
24
|
+
|
25
|
+
// AI生成的代码 - 粒子动画变体
|
26
|
+
const particleVariants = {
|
27
|
+
initial: {
|
28
|
+
scale: 0,
|
29
|
+
opacity: 0,
|
30
|
+
},
|
31
|
+
animate: (i: number) => ({
|
32
|
+
scale: [0, 1, 0],
|
33
|
+
opacity: [0, 1, 0],
|
34
|
+
x: Math.cos((i * Math.PI * 2) / 6) * 40,
|
35
|
+
y: Math.sin((i * Math.PI * 2) / 6) * 40,
|
36
|
+
transition: {
|
37
|
+
duration: 2,
|
38
|
+
repeat: Infinity,
|
39
|
+
delay: i * 0.2,
|
40
|
+
ease: [0.4, 0, 0.6, 1] as const,
|
41
|
+
},
|
42
|
+
}),
|
43
|
+
};
|
44
|
+
|
45
|
+
const GlobalLoading: React.FC = observer(() => {
|
46
|
+
const { loadingStore } = useStore();
|
47
|
+
|
48
|
+
if (!loadingStore.isLoading) {
|
49
|
+
return null;
|
50
|
+
}
|
51
|
+
|
52
|
+
return (
|
53
|
+
<AnimatePresence>
|
54
|
+
{loadingStore.isLoading && (
|
55
|
+
<motion.div
|
56
|
+
className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/50 backdrop-blur-sm"
|
57
|
+
initial={{ opacity: 0 }}
|
58
|
+
animate={{ opacity: 1 }}
|
59
|
+
exit={{ opacity: 0 }}
|
60
|
+
transition={{ duration: 0.2 }}
|
61
|
+
>
|
62
|
+
<motion.div
|
63
|
+
className="p-8"
|
64
|
+
variants={logoVariants}
|
65
|
+
initial="hidden"
|
66
|
+
animate="visible"
|
67
|
+
exit="exit"
|
68
|
+
>
|
69
|
+
<div className="flex flex-col items-center space-y-6">
|
70
|
+
{/* AI生成的代码 - 主要loading图标 */}
|
71
|
+
<div className="relative flex items-center justify-center">
|
72
|
+
{/* AI生成的代码 - 主Logo动画 */}
|
73
|
+
<motion.div
|
74
|
+
className="relative z-10"
|
75
|
+
variants={logoVariants}
|
76
|
+
initial="initial"
|
77
|
+
animate="animate"
|
78
|
+
>
|
79
|
+
<img
|
80
|
+
src={logoSvg}
|
81
|
+
alt="Loading"
|
82
|
+
className="w-16 h-16 object-contain"
|
83
|
+
/>
|
84
|
+
</motion.div>
|
85
|
+
|
86
|
+
{/* AI生成的代码 - 围绕Logo的粒子效果 */}
|
87
|
+
{Array.from({ length: 6 }).map((_, i) => (
|
88
|
+
<motion.div
|
89
|
+
key={i}
|
90
|
+
className="absolute w-3 h-3 bg-gradient-to-r from-blue-500 to-purple-500 rounded-full"
|
91
|
+
variants={particleVariants}
|
92
|
+
initial="initial"
|
93
|
+
animate="animate"
|
94
|
+
custom={i}
|
95
|
+
/>
|
96
|
+
))}
|
97
|
+
|
98
|
+
{/* AI生成的代码 - 外圈光晕效果 */}
|
99
|
+
<motion.div
|
100
|
+
className="absolute w-24 h-24 border-2 border-blue-500/30 rounded-full"
|
101
|
+
animate={{
|
102
|
+
scale: [1, 1.2, 1],
|
103
|
+
opacity: [0.3, 0.6, 0.3],
|
104
|
+
rotate: 360,
|
105
|
+
}}
|
106
|
+
transition={{
|
107
|
+
duration: 3,
|
108
|
+
repeat: Infinity,
|
109
|
+
ease: "easeInOut",
|
110
|
+
}}
|
111
|
+
/>
|
112
|
+
|
113
|
+
{/* AI生成的代码 - 内圈光晕效果 */}
|
114
|
+
<motion.div
|
115
|
+
className="absolute w-20 h-20 border border-purple-500/40 rounded-full"
|
116
|
+
animate={{
|
117
|
+
scale: [1.2, 1, 1.2],
|
118
|
+
opacity: [0.2, 0.5, 0.2],
|
119
|
+
rotate: -360,
|
120
|
+
}}
|
121
|
+
transition={{
|
122
|
+
duration: 2.5,
|
123
|
+
repeat: Infinity,
|
124
|
+
ease: "easeInOut",
|
125
|
+
}}
|
126
|
+
/>
|
127
|
+
</div>
|
128
|
+
|
129
|
+
{/* AI生成的代码 - Loading文本 */}
|
130
|
+
<div className="text-center">
|
131
|
+
<h3 className="text-white text-lg font-semibold mb-2">
|
132
|
+
{loadingStore.loadingText}
|
133
|
+
</h3>
|
134
|
+
</div>
|
135
|
+
</div>
|
136
|
+
</motion.div>
|
137
|
+
</motion.div>
|
138
|
+
)}
|
139
|
+
</AnimatePresence>
|
140
|
+
);
|
141
|
+
});
|
142
|
+
|
143
|
+
export default GlobalLoading;
|
@@ -0,0 +1,371 @@
|
|
1
|
+
import { motion } from "framer-motion";
|
2
|
+
import { useMemo, useEffect, useRef, useState } from "react";
|
3
|
+
|
4
|
+
export default function HeroSection() {
|
5
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
6
|
+
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
|
7
|
+
|
8
|
+
// Generate static particle data to avoid hydration mismatch
|
9
|
+
const particleData = useMemo(() => {
|
10
|
+
const particles = [];
|
11
|
+
const seed = 42; // Fixed seed for consistent results
|
12
|
+
let random = seed;
|
13
|
+
|
14
|
+
const seededRandom = () => {
|
15
|
+
random = (random * 9301 + 49297) % 233280;
|
16
|
+
return random / 233280;
|
17
|
+
};
|
18
|
+
|
19
|
+
for (let i = 0; i < 30; i++) {
|
20
|
+
particles.push({
|
21
|
+
id: i,
|
22
|
+
x: seededRandom() * 100,
|
23
|
+
y: seededRandom() * 100,
|
24
|
+
size: 1 + seededRandom() * 3,
|
25
|
+
speed: 0.5 + seededRandom() * 1.5,
|
26
|
+
direction: seededRandom() * Math.PI * 2,
|
27
|
+
opacity: 0.3 + seededRandom() * 0.7,
|
28
|
+
pulseSpeed: 2 + seededRandom() * 3,
|
29
|
+
});
|
30
|
+
}
|
31
|
+
return particles;
|
32
|
+
}, []);
|
33
|
+
|
34
|
+
const neuronsData = useMemo(() => {
|
35
|
+
const neurons = [];
|
36
|
+
const seed = 123;
|
37
|
+
let random = seed;
|
38
|
+
|
39
|
+
const seededRandom = () => {
|
40
|
+
random = (random * 9301 + 49297) % 233280;
|
41
|
+
return random / 233280;
|
42
|
+
};
|
43
|
+
|
44
|
+
for (let i = 0; i < 12; i++) {
|
45
|
+
neurons.push({
|
46
|
+
id: i,
|
47
|
+
x: 15 + seededRandom() * 70,
|
48
|
+
y: 15 + seededRandom() * 70,
|
49
|
+
size: 3 + seededRandom() * 4,
|
50
|
+
connections: Math.floor(seededRandom() * 3) + 1,
|
51
|
+
});
|
52
|
+
}
|
53
|
+
return neurons;
|
54
|
+
}, []);
|
55
|
+
|
56
|
+
// Mouse tracking for interactive effects
|
57
|
+
useEffect(() => {
|
58
|
+
const handleMouseMove = (e: MouseEvent) => {
|
59
|
+
setMousePos({
|
60
|
+
x: (e.clientX / window.innerWidth) * 100,
|
61
|
+
y: (e.clientY / window.innerHeight) * 100,
|
62
|
+
});
|
63
|
+
};
|
64
|
+
|
65
|
+
window.addEventListener("mousemove", handleMouseMove);
|
66
|
+
return () => window.removeEventListener("mousemove", handleMouseMove);
|
67
|
+
}, []);
|
68
|
+
|
69
|
+
// Canvas animation for dynamic effects
|
70
|
+
useEffect(() => {
|
71
|
+
const canvas = canvasRef.current;
|
72
|
+
if (!canvas) return;
|
73
|
+
|
74
|
+
const ctx = canvas.getContext("2d");
|
75
|
+
if (!ctx) return;
|
76
|
+
|
77
|
+
const resizeCanvas = () => {
|
78
|
+
canvas.width = canvas.offsetWidth;
|
79
|
+
canvas.height = canvas.offsetHeight;
|
80
|
+
};
|
81
|
+
|
82
|
+
resizeCanvas();
|
83
|
+
window.addEventListener("resize", resizeCanvas);
|
84
|
+
|
85
|
+
let animationId: number;
|
86
|
+
let time = 0;
|
87
|
+
|
88
|
+
const animate = () => {
|
89
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
90
|
+
|
91
|
+
// Enhanced particle system
|
92
|
+
const drawParticles = () => {
|
93
|
+
particleData.forEach((particle, index) => {
|
94
|
+
const baseX = (particle.x / 100) * canvas.width;
|
95
|
+
const baseY = (particle.y / 100) * canvas.height;
|
96
|
+
|
97
|
+
// Complex movement pattern
|
98
|
+
const x =
|
99
|
+
baseX +
|
100
|
+
50 * Math.sin(time * 0.002 + particle.direction) * particle.speed +
|
101
|
+
20 * Math.cos(time * 0.001 + index) * particle.speed;
|
102
|
+
const y =
|
103
|
+
baseY +
|
104
|
+
40 * Math.cos(time * 0.0015 + particle.direction) * particle.speed +
|
105
|
+
15 * Math.sin(time * 0.003 + index) * particle.speed;
|
106
|
+
|
107
|
+
// Pulsing opacity
|
108
|
+
const opacity =
|
109
|
+
particle.opacity *
|
110
|
+
(0.5 + 0.5 * Math.sin(time * 0.004 * particle.pulseSpeed));
|
111
|
+
|
112
|
+
// Core particle
|
113
|
+
const gradient = ctx.createRadialGradient(
|
114
|
+
x,
|
115
|
+
y,
|
116
|
+
0,
|
117
|
+
x,
|
118
|
+
y,
|
119
|
+
particle.size * 3
|
120
|
+
);
|
121
|
+
gradient.addColorStop(0, `rgba(59, 130, 246, ${opacity})`);
|
122
|
+
gradient.addColorStop(0.5, `rgba(147, 51, 234, ${opacity * 0.6})`);
|
123
|
+
gradient.addColorStop(1, `rgba(6, 182, 212, 0)`);
|
124
|
+
|
125
|
+
ctx.fillStyle = gradient;
|
126
|
+
ctx.beginPath();
|
127
|
+
ctx.arc(x, y, particle.size * 2, 0, Math.PI * 2);
|
128
|
+
ctx.fill();
|
129
|
+
|
130
|
+
// Energy trails
|
131
|
+
if (index % 3 === 0) {
|
132
|
+
ctx.strokeStyle = `rgba(59, 130, 246, ${opacity * 0.3})`;
|
133
|
+
ctx.lineWidth = 1;
|
134
|
+
ctx.beginPath();
|
135
|
+
const trailLength = 30;
|
136
|
+
const prevX = x - Math.cos(particle.direction) * trailLength;
|
137
|
+
const prevY = y - Math.sin(particle.direction) * trailLength;
|
138
|
+
ctx.moveTo(prevX, prevY);
|
139
|
+
ctx.lineTo(x, y);
|
140
|
+
ctx.stroke();
|
141
|
+
}
|
142
|
+
});
|
143
|
+
};
|
144
|
+
|
145
|
+
// Neural network connections
|
146
|
+
const drawNeuralNetwork = () => {
|
147
|
+
neuronsData.forEach((neuron, i) => {
|
148
|
+
const neuronX = (neuron.x / 100) * canvas.width;
|
149
|
+
const neuronY = (neuron.y / 100) * canvas.height;
|
150
|
+
|
151
|
+
// Draw connections to nearby neurons
|
152
|
+
neuronsData.forEach((target, j) => {
|
153
|
+
if (i !== j) {
|
154
|
+
const targetX = (target.x / 100) * canvas.width;
|
155
|
+
const targetY = (target.y / 100) * canvas.height;
|
156
|
+
const distance = Math.sqrt(
|
157
|
+
Math.pow(targetX - neuronX, 2) + Math.pow(targetY - neuronY, 2)
|
158
|
+
);
|
159
|
+
|
160
|
+
if (distance < 200) {
|
161
|
+
const connectionOpacity = ((200 - distance) / 200) * 0.3;
|
162
|
+
const pulseEffect = 0.3 + 0.7 * Math.sin(time * 0.003 + i + j);
|
163
|
+
|
164
|
+
ctx.strokeStyle = `rgba(59, 130, 246, ${
|
165
|
+
connectionOpacity * pulseEffect
|
166
|
+
})`;
|
167
|
+
ctx.lineWidth = 1;
|
168
|
+
ctx.beginPath();
|
169
|
+
ctx.moveTo(neuronX, neuronY);
|
170
|
+
ctx.lineTo(targetX, targetY);
|
171
|
+
ctx.stroke();
|
172
|
+
}
|
173
|
+
}
|
174
|
+
});
|
175
|
+
|
176
|
+
// Draw neuron nodes
|
177
|
+
const nodeOpacity = 0.7 + 0.3 * Math.sin(time * 0.004 + i);
|
178
|
+
const gradient = ctx.createRadialGradient(
|
179
|
+
neuronX,
|
180
|
+
neuronY,
|
181
|
+
0,
|
182
|
+
neuronX,
|
183
|
+
neuronY,
|
184
|
+
neuron.size * 2
|
185
|
+
);
|
186
|
+
gradient.addColorStop(0, `rgba(59, 130, 246, ${nodeOpacity})`);
|
187
|
+
gradient.addColorStop(1, `rgba(147, 51, 234, 0)`);
|
188
|
+
|
189
|
+
ctx.fillStyle = gradient;
|
190
|
+
ctx.beginPath();
|
191
|
+
ctx.arc(neuronX, neuronY, neuron.size, 0, Math.PI * 2);
|
192
|
+
ctx.fill();
|
193
|
+
});
|
194
|
+
};
|
195
|
+
|
196
|
+
drawParticles();
|
197
|
+
drawNeuralNetwork();
|
198
|
+
|
199
|
+
time += 16;
|
200
|
+
animationId = requestAnimationFrame(animate);
|
201
|
+
};
|
202
|
+
|
203
|
+
animate();
|
204
|
+
|
205
|
+
return () => {
|
206
|
+
window.removeEventListener("resize", resizeCanvas);
|
207
|
+
cancelAnimationFrame(animationId);
|
208
|
+
};
|
209
|
+
}, [particleData, neuronsData]);
|
210
|
+
|
211
|
+
return (
|
212
|
+
<section className="relative min-h-screen flex items-center justify-center overflow-hidden bg-gradient-to-br from-slate-950 via-blue-950/20 to-slate-950">
|
213
|
+
{/* Enhanced Canvas Background */}
|
214
|
+
<canvas
|
215
|
+
ref={canvasRef}
|
216
|
+
className="absolute inset-0 w-full h-full"
|
217
|
+
style={{ background: "transparent" }}
|
218
|
+
/>
|
219
|
+
|
220
|
+
{/* Interactive Background Pattern */}
|
221
|
+
<div className="absolute inset-0">
|
222
|
+
<div
|
223
|
+
className="absolute inset-0 transition-all duration-1000 ease-out"
|
224
|
+
style={{
|
225
|
+
background: `
|
226
|
+
radial-gradient(circle at ${mousePos.x}% ${
|
227
|
+
mousePos.y
|
228
|
+
}%, rgba(59, 130, 246, 0.15) 0%, transparent 30%),
|
229
|
+
radial-gradient(circle at ${100 - mousePos.x}% ${
|
230
|
+
100 - mousePos.y
|
231
|
+
}%, rgba(147, 51, 234, 0.1) 0%, transparent 40%),
|
232
|
+
radial-gradient(circle at 50% 50%, rgba(6, 182, 212, 0.05) 0%, transparent 60%)
|
233
|
+
`,
|
234
|
+
}}
|
235
|
+
/>
|
236
|
+
</div>
|
237
|
+
|
238
|
+
{/* Enhanced Floating Elements */}
|
239
|
+
<div className="absolute inset-0 pointer-events-none">
|
240
|
+
{/* Large energy orbs */}
|
241
|
+
<div
|
242
|
+
className="absolute w-96 h-96 rounded-full blur-3xl opacity-30"
|
243
|
+
style={{
|
244
|
+
top: "20%",
|
245
|
+
left: "15%",
|
246
|
+
background:
|
247
|
+
"linear-gradient(45deg, rgba(59, 130, 246, 0.4), rgba(147, 51, 234, 0.3))",
|
248
|
+
animation: "energyOrb1 12s ease-in-out infinite",
|
249
|
+
}}
|
250
|
+
/>
|
251
|
+
<div
|
252
|
+
className="absolute w-80 h-80 rounded-full blur-3xl opacity-25"
|
253
|
+
style={{
|
254
|
+
bottom: "20%",
|
255
|
+
right: "15%",
|
256
|
+
background:
|
257
|
+
"linear-gradient(135deg, rgba(147, 51, 234, 0.4), rgba(236, 72, 153, 0.3))",
|
258
|
+
animation: "energyOrb2 15s ease-in-out infinite reverse",
|
259
|
+
}}
|
260
|
+
/>
|
261
|
+
<div
|
262
|
+
className="absolute w-64 h-64 rounded-full blur-2xl opacity-40"
|
263
|
+
style={{
|
264
|
+
top: "60%",
|
265
|
+
right: "25%",
|
266
|
+
background:
|
267
|
+
"linear-gradient(90deg, rgba(6, 182, 212, 0.4), rgba(59, 130, 246, 0.3))",
|
268
|
+
animation: "energyOrb3 10s ease-in-out infinite",
|
269
|
+
}}
|
270
|
+
/>
|
271
|
+
|
272
|
+
{/* Smaller floating elements */}
|
273
|
+
{Array.from({ length: 8 }).map((_, i) => (
|
274
|
+
<div
|
275
|
+
key={i}
|
276
|
+
className="absolute w-4 h-4 bg-blue-400/30 rounded-full blur-sm"
|
277
|
+
style={{
|
278
|
+
left: `${20 + i * 10}%`,
|
279
|
+
top: `${30 + i * 5}%`,
|
280
|
+
animation: `floatSmall ${5 + i}s linear infinite`,
|
281
|
+
animationDelay: `${i * 0.5}s`,
|
282
|
+
}}
|
283
|
+
/>
|
284
|
+
))}
|
285
|
+
</div>
|
286
|
+
|
287
|
+
{/* Holographic UI Elements */}
|
288
|
+
<div className="absolute inset-0 pointer-events-none">
|
289
|
+
{/* Corner brackets */}
|
290
|
+
<div className="absolute top-8 left-8 w-16 h-16 border-l-2 border-t-2 border-cyan-400/40 animate-pulse"></div>
|
291
|
+
<div
|
292
|
+
className="absolute top-8 right-8 w-16 h-16 border-r-2 border-t-2 border-cyan-400/40 animate-pulse"
|
293
|
+
style={{ animationDelay: "0.5s" }}
|
294
|
+
></div>
|
295
|
+
<div
|
296
|
+
className="absolute bottom-8 left-8 w-16 h-16 border-l-2 border-b-2 border-cyan-400/40 animate-pulse"
|
297
|
+
style={{ animationDelay: "1s" }}
|
298
|
+
></div>
|
299
|
+
<div
|
300
|
+
className="absolute bottom-8 right-8 w-16 h-16 border-r-2 border-b-2 border-cyan-400/40 animate-pulse"
|
301
|
+
style={{ animationDelay: "1.5s" }}
|
302
|
+
></div>
|
303
|
+
</div>
|
304
|
+
|
305
|
+
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 w-full">
|
306
|
+
<div className="text-center">
|
307
|
+
<motion.div
|
308
|
+
initial={{ opacity: 0, y: 30 }}
|
309
|
+
animate={{ opacity: 1, y: 0 }}
|
310
|
+
transition={{ duration: 0.8 }}
|
311
|
+
className="mb-8"
|
312
|
+
>
|
313
|
+
<span className="inline-flex items-center bg-gradient-to-r from-blue-500/10 to-purple-500/10 border border-blue-500/20 rounded-full px-6 py-3 text-blue-300 text-sm font-medium backdrop-blur-sm">
|
314
|
+
<div className="w-2 h-2 bg-blue-400 rounded-full mr-3 animate-pulse"></div>
|
315
|
+
智能金融科技解决方案
|
316
|
+
</span>
|
317
|
+
</motion.div>
|
318
|
+
|
319
|
+
<motion.h1
|
320
|
+
initial={{ opacity: 0, y: 30 }}
|
321
|
+
animate={{ opacity: 1, y: 0 }}
|
322
|
+
transition={{ duration: 0.8, delay: 0.2 }}
|
323
|
+
className="text-5xl md:text-7xl font-bold text-white mb-8 leading-tight"
|
324
|
+
>
|
325
|
+
构建智能金融
|
326
|
+
<br />
|
327
|
+
<span className="bg-gradient-to-r from-blue-400 via-purple-400 to-cyan-400 bg-clip-text text-transparent">
|
328
|
+
数字化未来
|
329
|
+
</span>
|
330
|
+
</motion.h1>
|
331
|
+
|
332
|
+
<motion.p
|
333
|
+
initial={{ opacity: 0, y: 30 }}
|
334
|
+
animate={{ opacity: 1, y: 0 }}
|
335
|
+
transition={{ duration: 0.8, delay: 0.4 }}
|
336
|
+
className="text-xl text-slate-300 mb-16 max-w-3xl mx-auto leading-relaxed"
|
337
|
+
>
|
338
|
+
上海财跃星辰智能科技有限公司,是一家专注于金融领域的大模型科技公司,核心优势在于全面且深度的专业金融知识体系,强大的多模态处理能力和不断进化的金融推理能力。
|
339
|
+
</motion.p>
|
340
|
+
|
341
|
+
{/* Trust Indicators */}
|
342
|
+
<motion.div
|
343
|
+
initial={{ opacity: 0, y: 30 }}
|
344
|
+
animate={{ opacity: 1, y: 0 }}
|
345
|
+
transition={{ duration: 0.8, delay: 0.6 }}
|
346
|
+
className="flex flex-col sm:flex-row items-center justify-center gap-8 text-slate-400"
|
347
|
+
>
|
348
|
+
<div className="flex items-center">
|
349
|
+
<div className="w-6 h-6 flex items-center justify-center mr-2">
|
350
|
+
<i className="ri-shield-check-line text-green-400"></i>
|
351
|
+
</div>
|
352
|
+
<span>银行级安全认证</span>
|
353
|
+
</div>
|
354
|
+
<div className="flex items-center">
|
355
|
+
<div className="w-6 h-6 flex items-center justify-center mr-2">
|
356
|
+
<i className="ri-award-line text-blue-400"></i>
|
357
|
+
</div>
|
358
|
+
<span>500+ 企业信赖</span>
|
359
|
+
</div>
|
360
|
+
<div className="flex items-center">
|
361
|
+
<div className="w-6 h-6 flex items-center justify-center mr-2">
|
362
|
+
<i className="ri-time-line text-purple-400"></i>
|
363
|
+
</div>
|
364
|
+
<span>7×24小时支持</span>
|
365
|
+
</div>
|
366
|
+
</motion.div>
|
367
|
+
</div>
|
368
|
+
</div>
|
369
|
+
</section>
|
370
|
+
);
|
371
|
+
}
|
@@ -0,0 +1,175 @@
|
|
1
|
+
import { motion } from "framer-motion";
|
2
|
+
|
3
|
+
export default function ProductsPreview() {
|
4
|
+
const productCategories = [
|
5
|
+
{
|
6
|
+
title: "智能风控",
|
7
|
+
description: "基于AI的全面风险管理解决方案",
|
8
|
+
icon: "ri-shield-check-line",
|
9
|
+
products: ["反欺诈检测", "信用评估", "风险预警", "合规监管"],
|
10
|
+
color: "from-blue-500 to-cyan-500",
|
11
|
+
bgColor: "bg-blue-500/10",
|
12
|
+
borderColor: "border-blue-500/20",
|
13
|
+
},
|
14
|
+
{
|
15
|
+
title: "量化交易",
|
16
|
+
description: "专业的量化投资与交易平台",
|
17
|
+
icon: "ri-line-chart-line",
|
18
|
+
products: ["策略开发", "回测分析", "自动交易", "风险控制"],
|
19
|
+
color: "from-purple-500 to-pink-500",
|
20
|
+
bgColor: "bg-purple-500/10",
|
21
|
+
borderColor: "border-purple-500/20",
|
22
|
+
},
|
23
|
+
{
|
24
|
+
title: "智能投顾",
|
25
|
+
description: "个性化投资建议与资产配置",
|
26
|
+
icon: "ri-lightbulb-line",
|
27
|
+
products: ["投资建议", "资产配置", "市场分析", "客户服务"],
|
28
|
+
color: "from-green-500 to-teal-500",
|
29
|
+
bgColor: "bg-green-500/10",
|
30
|
+
borderColor: "border-green-500/20",
|
31
|
+
},
|
32
|
+
{
|
33
|
+
title: "数据分析",
|
34
|
+
description: "深度挖掘金融数据价值",
|
35
|
+
icon: "ri-bar-chart-line",
|
36
|
+
products: ["数据建模", "预测分析", "可视化", "报告生成"],
|
37
|
+
color: "from-orange-500 to-red-500",
|
38
|
+
bgColor: "bg-orange-500/10",
|
39
|
+
borderColor: "border-orange-500/20",
|
40
|
+
},
|
41
|
+
];
|
42
|
+
|
43
|
+
return (
|
44
|
+
<section className="bg-slate-950 py-24">
|
45
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
46
|
+
{/* AI生成的代码 - 优化后的Header动画 */}
|
47
|
+
<motion.div
|
48
|
+
initial={{ opacity: 0, y: 20 }}
|
49
|
+
whileInView={{ opacity: 1, y: 0 }}
|
50
|
+
transition={{ duration: 0.5, ease: "easeOut" }}
|
51
|
+
viewport={{ once: true, margin: "-50px" }}
|
52
|
+
className="text-center mb-20"
|
53
|
+
>
|
54
|
+
<div className="inline-flex items-center bg-blue-500/10 border border-blue-500/20 rounded-full px-6 py-2 text-blue-300 text-sm font-medium mb-6">
|
55
|
+
产品矩阵
|
56
|
+
</div>
|
57
|
+
<h2 className="text-4xl md:text-5xl font-bold text-white mb-6">
|
58
|
+
全栈式AI金融产品
|
59
|
+
</h2>
|
60
|
+
<p className="text-xl text-slate-300 max-w-3xl mx-auto leading-relaxed">
|
61
|
+
覆盖金融业务全场景的AI产品体系,提供从数据采集到业务决策的完整解决方案
|
62
|
+
</p>
|
63
|
+
</motion.div>
|
64
|
+
|
65
|
+
{/* AI生成的代码 - 优化后的Product Categories Grid */}
|
66
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-16">
|
67
|
+
{productCategories.map((category, index) => (
|
68
|
+
<motion.div
|
69
|
+
key={category.title}
|
70
|
+
initial={{ opacity: 0, y: 15 }}
|
71
|
+
whileInView={{ opacity: 1, y: 0 }}
|
72
|
+
transition={{
|
73
|
+
duration: 0.4,
|
74
|
+
delay: index * 0.05,
|
75
|
+
ease: "easeOut",
|
76
|
+
}}
|
77
|
+
viewport={{ once: true, margin: "-30px" }}
|
78
|
+
className={`group relative ${category.bgColor} ${category.borderColor} border rounded-2xl p-8 hover:scale-[1.01] transition-transform duration-200 cursor-pointer`}
|
79
|
+
>
|
80
|
+
<div className="flex items-start justify-between mb-6">
|
81
|
+
<div
|
82
|
+
className={`w-16 h-16 rounded-xl bg-gradient-to-r ${category.color} flex items-center justify-center`}
|
83
|
+
>
|
84
|
+
<div className="w-8 h-8 flex items-center justify-center">
|
85
|
+
<i className={`${category.icon} text-white text-2xl`}></i>
|
86
|
+
</div>
|
87
|
+
</div>
|
88
|
+
<div className="w-6 h-6 flex items-center justify-center opacity-50 group-hover:opacity-100 group-hover:translate-x-1 transition-all">
|
89
|
+
<i className="ri-arrow-right-up-line text-slate-400"></i>
|
90
|
+
</div>
|
91
|
+
</div>
|
92
|
+
|
93
|
+
<h3 className="text-2xl font-bold text-white mb-3">
|
94
|
+
{category.title}
|
95
|
+
</h3>
|
96
|
+
<p className="text-slate-300 mb-6 leading-relaxed">
|
97
|
+
{category.description}
|
98
|
+
</p>
|
99
|
+
|
100
|
+
<div className="flex flex-wrap gap-2">
|
101
|
+
{category.products.map((product) => (
|
102
|
+
<span
|
103
|
+
key={product}
|
104
|
+
className="px-3 py-1 bg-slate-800/50 text-slate-300 text-sm rounded-full border border-slate-700"
|
105
|
+
>
|
106
|
+
{product}
|
107
|
+
</span>
|
108
|
+
))}
|
109
|
+
</div>
|
110
|
+
</motion.div>
|
111
|
+
))}
|
112
|
+
</div>
|
113
|
+
|
114
|
+
{/* Core Features */}
|
115
|
+
<motion.div
|
116
|
+
initial={{ opacity: 0, y: 30 }}
|
117
|
+
whileInView={{ opacity: 1, y: 0 }}
|
118
|
+
transition={{ duration: 0.8 }}
|
119
|
+
className="bg-gradient-to-r from-slate-900/50 to-slate-800/30 border border-slate-700 rounded-2xl p-8 md:p-12 mb-16"
|
120
|
+
>
|
121
|
+
<div className="text-center mb-12">
|
122
|
+
<h3 className="text-3xl font-bold text-white mb-4">核心技术优势</h3>
|
123
|
+
<p className="text-slate-300 max-w-2xl mx-auto">
|
124
|
+
基于深度学习与大数据技术,为金融机构提供稳定可靠的AI服务
|
125
|
+
</p>
|
126
|
+
</div>
|
127
|
+
|
128
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
129
|
+
<div className="text-center">
|
130
|
+
<div className="w-20 h-20 bg-gradient-to-r from-blue-500/20 to-purple-500/20 rounded-full flex items-center justify-center mx-auto mb-4">
|
131
|
+
<div className="w-10 h-10 flex items-center justify-center">
|
132
|
+
<i className="ri-brain-line text-blue-400 text-3xl"></i>
|
133
|
+
</div>
|
134
|
+
</div>
|
135
|
+
<h4 className="text-xl font-semibold text-white mb-2">
|
136
|
+
阶跃模型
|
137
|
+
</h4>
|
138
|
+
<p className="text-slate-400">
|
139
|
+
先进的神经网络模型,持续优化预测准确率
|
140
|
+
</p>
|
141
|
+
</div>
|
142
|
+
|
143
|
+
<div className="text-center">
|
144
|
+
<div className="w-20 h-20 bg-gradient-to-r from-purple-500/20 to-pink-500/20 rounded-full flex items-center justify-center mx-auto mb-4">
|
145
|
+
<div className="w-10 h-10 flex items-center justify-center">
|
146
|
+
<i className="ri-database-2-line text-purple-400 text-3xl"></i>
|
147
|
+
</div>
|
148
|
+
</div>
|
149
|
+
<h4 className="text-xl font-semibold text-white mb-2">
|
150
|
+
财联社数据
|
151
|
+
</h4>
|
152
|
+
<p className="text-slate-400">
|
153
|
+
高性能数据处理引擎,支持海量数据实时分析
|
154
|
+
</p>
|
155
|
+
</div>
|
156
|
+
|
157
|
+
<div className="text-center">
|
158
|
+
<div className="w-20 h-20 bg-gradient-to-r from-green-500/20 to-teal-500/20 rounded-full flex items-center justify-center mx-auto mb-4">
|
159
|
+
<div className="w-10 h-10 flex items-center justify-center">
|
160
|
+
<i className="ri-shield-check-line text-green-400 text-3xl"></i>
|
161
|
+
</div>
|
162
|
+
</div>
|
163
|
+
<h4 className="text-xl font-semibold text-white mb-2">
|
164
|
+
安全可靠
|
165
|
+
</h4>
|
166
|
+
<p className="text-slate-400">
|
167
|
+
银行级安全标准,全方位保障数据安全
|
168
|
+
</p>
|
169
|
+
</div>
|
170
|
+
</div>
|
171
|
+
</motion.div>
|
172
|
+
</div>
|
173
|
+
</section>
|
174
|
+
);
|
175
|
+
}
|