Files
users/app/ai-insight/page.tsx
v0 b17b488f8e refactor: restructure navigation and module layout
Reorganize navigation and module structure based on new requirements.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2026-01-31 04:32:36 +00:00

293 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState, useEffect } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Progress } from "@/components/ui/progress"
import {
Brain,
Sparkles,
TrendingUp,
MessageSquare,
FileText,
Tag,
Target,
Zap,
ArrowRight,
Activity,
Clock,
CheckCircle2,
AlertTriangle,
} from "lucide-react"
import Link from "next/link"
// 模拟数据
const aiModules = [
{
id: "smart-tag",
name: "智能打标",
description: "基于NLP和行为分析自动为用户生成标签",
icon: Tag,
color: "from-violet-500 to-purple-600",
status: "running",
stats: { today: 12580, accuracy: 94.2 },
href: "/ai-insight/smart-tag",
},
{
id: "prediction",
name: "智能预测",
description: "预测用户流失、转化、价值变化趋势",
icon: TrendingUp,
color: "from-blue-500 to-cyan-600",
status: "running",
stats: { today: 8420, accuracy: 91.8 },
href: "/ai-insight/prediction",
},
{
id: "nlq",
name: "自然语言查询",
description: "用自然语言查询数据AI自动生成SQL",
icon: MessageSquare,
color: "from-emerald-500 to-teal-600",
status: "running",
stats: { today: 256, accuracy: 88.5 },
href: "/ai-insight/nlq",
},
{
id: "report",
name: "智能报告生成",
description: "自动生成数据分析报告和洞察摘要",
icon: FileText,
color: "from-orange-500 to-amber-600",
status: "running",
stats: { today: 48, accuracy: 92.1 },
href: "/ai-insight/report",
},
]
const recentTasks = [
{ id: 1, type: "智能打标", target: "新增用户批次", status: "completed", count: 2580, time: "2分钟前" },
{ id: 2, type: "流失预测", target: "全量用户扫描", status: "running", progress: 67, time: "进行中" },
{ id: 3, type: "NLQ查询", target: "高价值用户分布", status: "completed", count: 1, time: "5分钟前" },
{ id: 4, type: "报告生成", target: "周度运营报告", status: "completed", count: 1, time: "1小时前" },
{ id: 5, type: "智能打标", target: "行为标签更新", status: "warning", count: 156, time: "2小时前" },
]
const aiInsights = [
{ id: 1, type: "预警", content: "检测到 2,340 位用户有流失风险,建议启动挽留计划", priority: "high" },
{ id: 2, type: "机会", content: "发现 890 位高潜力用户,转化概率 > 75%", priority: "medium" },
{ id: 3, type: "趋势", content: "近7天用户活跃度环比上升 12.5%", priority: "low" },
]
export default function AIInsightPage() {
const [gpuUsage, setGpuUsage] = useState(68)
const [apiCalls, setApiCalls] = useState(125800)
useEffect(() => {
const interval = setInterval(() => {
setGpuUsage((prev) => Math.min(95, Math.max(50, prev + (Math.random() - 0.5) * 10)))
setApiCalls((prev) => prev + Math.floor(Math.random() * 100))
}, 3000)
return () => clearInterval(interval)
}, [])
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-blue-50/30 p-6">
<div className="max-w-7xl mx-auto space-y-6">
{/* 页面标题 */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-slate-800">AI赋能与洞察中心</h1>
<p className="text-slate-500 mt-1"></p>
</div>
<div className="flex items-center gap-3">
<div className="flex items-center gap-2 px-3 py-1.5 bg-emerald-50 rounded-full">
<span className="w-2 h-2 bg-emerald-500 rounded-full animate-pulse" />
<span className="text-sm text-emerald-700">AI引擎运行中</span>
</div>
</div>
</div>
{/* AI 资源状态 */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-xs text-slate-500">GPU使用率</p>
<p className="text-2xl font-bold text-slate-800">{gpuUsage.toFixed(1)}%</p>
</div>
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-violet-500 to-purple-600 flex items-center justify-center">
<Brain className="w-6 h-6 text-white" />
</div>
</div>
<Progress value={gpuUsage} className="mt-3 h-1.5" />
</CardContent>
</Card>
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-xs text-slate-500">API调用</p>
<p className="text-2xl font-bold text-slate-800">{apiCalls.toLocaleString()}</p>
</div>
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-500 to-cyan-600 flex items-center justify-center">
<Zap className="w-6 h-6 text-white" />
</div>
</div>
<p className="text-xs text-emerald-600 mt-3"> +18.2%</p>
</CardContent>
</Card>
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-xs text-slate-500"></p>
<p className="text-2xl font-bold text-slate-800">91.6%</p>
</div>
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-emerald-500 to-teal-600 flex items-center justify-center">
<Target className="w-6 h-6 text-white" />
</div>
</div>
<p className="text-xs text-emerald-600 mt-3"> +3.2%</p>
</CardContent>
</Card>
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-xs text-slate-500"></p>
<p className="text-2xl font-bold text-slate-800">12</p>
</div>
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-orange-500 to-amber-600 flex items-center justify-center">
<Activity className="w-6 h-6 text-white" />
</div>
</div>
<p className="text-xs text-slate-500 mt-3"></p>
</CardContent>
</Card>
</div>
{/* AI 功能模块入口 */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
{aiModules.map((module) => (
<Link key={module.id} href={module.href}>
<Card className="bg-white/70 backdrop-blur border-slate-200/60 hover:shadow-lg hover:border-slate-300 transition-all cursor-pointer group h-full">
<CardContent className="p-5">
<div
className={`w-12 h-12 rounded-xl bg-gradient-to-br ${module.color} flex items-center justify-center mb-4`}
>
<module.icon className="w-6 h-6 text-white" />
</div>
<h3 className="font-semibold text-slate-800 mb-1">{module.name}</h3>
<p className="text-sm text-slate-500 mb-4">{module.description}</p>
<div className="flex items-center justify-between">
<div className="text-xs text-slate-500">
:{" "}
<span className="font-medium text-slate-700">{module.stats.today.toLocaleString()}</span>
</div>
<ArrowRight className="w-4 h-4 text-slate-400 group-hover:text-slate-600 group-hover:translate-x-1 transition-all" />
</div>
</CardContent>
</Card>
</Link>
))}
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* AI 洞察 */}
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardHeader className="pb-3">
<CardTitle className="text-base flex items-center gap-2">
<Sparkles className="w-4 h-4 text-amber-500" />
AI
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
{aiInsights.map((insight) => (
<div
key={insight.id}
className={`p-3 rounded-lg border ${
insight.priority === "high"
? "bg-red-50 border-red-200"
: insight.priority === "medium"
? "bg-amber-50 border-amber-200"
: "bg-blue-50 border-blue-200"
}`}
>
<div className="flex items-start gap-2">
<Badge
variant="outline"
className={
insight.priority === "high"
? "bg-red-100 text-red-700 border-red-300"
: insight.priority === "medium"
? "bg-amber-100 text-amber-700 border-amber-300"
: "bg-blue-100 text-blue-700 border-blue-300"
}
>
{insight.type}
</Badge>
</div>
<p className="text-sm text-slate-700 mt-2">{insight.content}</p>
</div>
))}
<Button variant="outline" className="w-full mt-2 bg-transparent" size="sm">
</Button>
</CardContent>
</Card>
{/* 最近任务 */}
<Card className="lg:col-span-2 bg-white/70 backdrop-blur border-slate-200/60">
<CardHeader className="pb-3">
<CardTitle className="text-base flex items-center gap-2">
<Clock className="w-4 h-4 text-slate-500" />
AI任务
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
{recentTasks.map((task) => (
<div key={task.id} className="flex items-center justify-between p-3 bg-slate-50/80 rounded-lg">
<div className="flex items-center gap-3">
{task.status === "completed" ? (
<CheckCircle2 className="w-5 h-5 text-emerald-500" />
) : task.status === "running" ? (
<div className="w-5 h-5 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
) : (
<AlertTriangle className="w-5 h-5 text-amber-500" />
)}
<div>
<p className="text-sm font-medium text-slate-800">{task.type}</p>
<p className="text-xs text-slate-500">{task.target}</p>
</div>
</div>
<div className="text-right">
{task.status === "running" ? (
<div className="flex items-center gap-2">
<Progress value={task.progress} className="w-20 h-1.5" />
<span className="text-xs text-slate-500">{task.progress}%</span>
</div>
) : (
<>
<p className="text-sm font-medium text-slate-700">{task.count?.toLocaleString()}</p>
<p className="text-xs text-slate-500">{task.time}</p>
</>
)}
</div>
</div>
))}
</div>
</CardContent>
</Card>
</div>
</div>
</div>
)
}