feat: refactor data asset center for enhanced search and analytics

Refactor homepage for focused search and data display; streamline data platform; enhance user and tag management; focus AI assistant on data analysis and report generation.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
v0
2025-07-25 06:42:34 +00:00
parent ecd8a48863
commit 4eed69520c
40 changed files with 6853 additions and 6111 deletions

View File

@@ -1,408 +1,335 @@
"use client"
import { useState } from "react"
import { useState, useEffect } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import { Progress } from "@/components/ui/progress"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { TooltipHelp, TooltipProvider } from "@/components/ui/tooltip-help"
import {
Database,
Users,
Target,
TrendingUp,
RefreshCw,
Download,
ChevronRight,
Activity,
TrendingUp,
Database,
Search,
RefreshCw,
Zap,
BarChart3,
Target,
Globe,
UserCheck,
Layers,
Tag,
Clock,
} from "lucide-react"
import Link from "next/link"
export default function HomePage() {
const [timeRange, setTimeRange] = useState("today")
export default function OverviewPage() {
const [searchQuery, setSearchQuery] = useState("")
const [isRefreshing, setIsRefreshing] = useState(false)
const [lastUpdate, setLastUpdate] = useState(new Date())
// 今日数据概览
const todayStats = {
dataSync: {
total: 1245678,
growth: "+12.5%",
sources: 8,
lastUpdate: "2分钟前",
},
userPool: {
totalUsers: 125678,
activeUsers: 45678,
newUsers: 1234,
growth: "+8.2%",
},
userPortrait: {
totalTags: 342,
activeTags: 287,
coverage: "95.8%",
growth: "+5.3%",
},
userValuation: {
avgValue: 3248,
highValue: 12456,
growth: "+15.8%",
upgradeRate: "12.5%",
},
// 核心数据状态
const [coreData, setCoreData] = useState({
totalUsers: 4000000000, // 40亿用户
activeUsers: 2800000000, // 28亿活跃用户
dataGrowthRate: 15.8, // 数据增长率
assetGrowthRate: 23.5, // 资产增长率
realTimeQueries: 156789, // 实时查询数
dataVolume: "12.8TB", // 数据量
systemHealth: 99.2, // 系统健康度
aiAnalysis: 8456, // AI分析次数
})
// 实时数据更新
useEffect(() => {
const interval = setInterval(() => {
setCoreData((prev) => ({
...prev,
realTimeQueries: prev.realTimeQueries + Math.floor(Math.random() * 50) + 10,
activeUsers: prev.activeUsers + Math.floor(Math.random() * 1000) + 100,
}))
setLastUpdate(new Date())
}, 5000) // 每5秒更新一次
return () => clearInterval(interval)
}, [])
// 手动刷新
const handleRefresh = async () => {
setIsRefreshing(true)
// 模拟数据刷新
setTimeout(() => {
setCoreData((prev) => ({
...prev,
totalUsers: prev.totalUsers + Math.floor(Math.random() * 10000) + 1000,
dataGrowthRate: +(Math.random() * 5 + 12).toFixed(1),
assetGrowthRate: +(Math.random() * 8 + 18).toFixed(1),
}))
setLastUpdate(new Date())
setIsRefreshing(false)
}, 2000)
}
// 实时活动数据
const realtimeActivities = [
{
id: 1,
type: "data_sync",
message: "IMEI数据同步完成",
time: "刚刚",
status: "success",
},
{
id: 2,
type: "user_pool",
message: "新增用户池分群",
time: "2分钟前",
status: "info",
},
{
id: 3,
type: "user_portrait",
message: "标签规则自动执行",
time: "5分钟前",
status: "warning",
},
{
id: 4,
type: "user_valuation",
message: "用户价值模型更新完成",
time: "8分钟前",
status: "success",
},
]
const getActivityIcon = (type: string) => {
switch (type) {
case "data_sync":
return <Database className="h-4 w-4" />
case "user_pool":
return <Users className="h-4 w-4" />
case "user_portrait":
return <Target className="h-4 w-4" />
case "user_valuation":
return <TrendingUp className="h-4 w-4" />
default:
return <Activity className="h-4 w-4" />
// 搜索处理
const handleSearch = () => {
if (searchQuery.trim()) {
// 跳转到智能搜索页面
window.location.href = `/intelligent-search?q=${encodeURIComponent(searchQuery)}`
}
}
const getStatusColor = (status: string) => {
switch (status) {
case "success":
return "text-green-600"
case "warning":
return "text-yellow-600"
case "info":
return "text-blue-600"
default:
return "text-gray-600"
const formatNumber = (num: number) => {
if (num >= 1000000000) {
return (num / 1000000000).toFixed(1) + "B"
}
if (num >= 1000000) {
return (num / 1000000).toFixed(1) + "M"
}
if (num >= 1000) {
return (num / 1000).toFixed(1) + "K"
}
return num.toString()
}
return (
<div className="container mx-auto py-4 md:py-6 space-y-4 md:space-y-6">
{/* 页面标题和工具栏 */}
<div className="flex flex-col md:flex-row md:justify-between md:items-center gap-4">
<div>
<h1 className="text-2xl md:text-3xl font-bold tracking-tight"></h1>
<p className="text-sm md:text-base text-muted-foreground"></p>
<TooltipProvider>
<div className="container mx-auto py-6 space-y-6">
{/* 页面标题和搜索 */}
<div className="flex justify-between items-center">
<div>
<h1 className="text-3xl font-bold tracking-tight"></h1>
<p className="text-muted-foreground mt-1 flex items-center gap-2">
<Badge variant="outline" className="text-xs">
<Clock className="h-3 w-3 mr-1" />
{lastUpdate.toLocaleTimeString()}
</Badge>
</p>
</div>
<div className="flex items-center space-x-3">
<div className="relative flex-1 max-w-md">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
<Input
type="text"
placeholder="搜索用户或流量关键词..."
className="pl-10 pr-20"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onKeyPress={(e) => e.key === "Enter" && handleSearch()}
/>
<Button size="sm" className="absolute right-1 top-1/2 transform -translate-y-1/2" onClick={handleSearch}>
</Button>
</div>
<Button variant="outline" size="sm" onClick={handleRefresh} disabled={isRefreshing}>
<RefreshCw className={`mr-2 h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`} />
{isRefreshing ? "刷新中" : "刷新"}
</Button>
</div>
</div>
<div className="flex gap-2">
<Select value={timeRange} onValueChange={setTimeRange}>
<SelectTrigger className="w-[120px] text-sm">
<SelectValue placeholder="时间范围" />
</SelectTrigger>
<SelectContent>
<SelectItem value="today"></SelectItem>
<SelectItem value="week"></SelectItem>
<SelectItem value="month"></SelectItem>
</SelectContent>
</Select>
<Button variant="outline" size="icon" className="h-9 w-9 bg-transparent">
<RefreshCw className="h-4 w-4" />
</Button>
<Button variant="outline" size="sm" className="hidden md:flex bg-transparent">
<Download className="mr-2 h-4 w-4" />
</Button>
{/* 核心用户数据展示 - 40亿用户为中心 */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* 中心用户总数卡片 */}
<div className="lg:col-span-1">
<Card className="h-full border-2 border-blue-200 bg-gradient-to-br from-blue-50 to-indigo-50">
<CardHeader className="text-center pb-2">
<CardTitle className="text-lg flex items-center justify-center gap-2">
<Globe className="h-6 w-6 text-blue-600" />
<TooltipHelp content="平台累计用户总数,包括所有注册和识别的用户" />
</CardTitle>
</CardHeader>
<CardContent className="text-center">
<div className="text-5xl font-bold text-blue-600 mb-2">{formatNumber(coreData.totalUsers)}</div>
<div className="text-sm text-muted-foreground"></div>
<div className="mt-4 grid grid-cols-2 gap-2 text-xs">
<div className="bg-white/50 rounded p-2">
<div className="font-medium"></div>
<div className="text-green-600 font-bold">{formatNumber(coreData.activeUsers)}</div>
</div>
<div className="bg-white/50 rounded p-2">
<div className="font-medium"></div>
<div className="text-blue-600 font-bold">
{((coreData.activeUsers / coreData.totalUsers) * 100).toFixed(1)}%
</div>
</div>
</div>
</CardContent>
</Card>
</div>
{/* 右侧数据指标 */}
<div className="lg:col-span-2 grid grid-cols-2 gap-4">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium flex items-center gap-1">
<TooltipHelp content="用户资产价值的增长率,反映用户价值提升情况" />
</CardTitle>
<TrendingUp className="h-4 w-4 text-green-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-green-600">+{coreData.assetGrowthRate}%</div>
<p className="text-xs text-muted-foreground"></p>
<div className="mt-2 h-2 bg-gray-200 rounded-full">
<div
className="h-2 bg-green-500 rounded-full transition-all duration-500"
style={{ width: `${Math.min(coreData.assetGrowthRate * 2, 100)}%` }}
></div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium flex items-center gap-1">
<TooltipHelp content="数据量的增长速度,包括用户行为数据、交易数据等" />
</CardTitle>
<Database className="h-4 w-4 text-blue-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-blue-600">+{coreData.dataGrowthRate}%</div>
<p className="text-xs text-muted-foreground">: {coreData.dataVolume}</p>
<div className="mt-2 h-2 bg-gray-200 rounded-full">
<div
className="h-2 bg-blue-500 rounded-full transition-all duration-500"
style={{ width: `${Math.min(coreData.dataGrowthRate * 3, 100)}%` }}
></div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium flex items-center gap-1">
<TooltipHelp content="当前实时查询次数,反映系统活跃度" />
</CardTitle>
<Zap className="h-4 w-4 text-yellow-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-yellow-600">{formatNumber(coreData.realTimeQueries)}</div>
<p className="text-xs text-muted-foreground"></p>
<div className="flex items-center mt-2">
<div className="w-2 h-2 bg-yellow-500 rounded-full animate-pulse mr-2"></div>
<span className="text-xs text-green-600"></span>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium flex items-center gap-1">
<TooltipHelp content="系统整体健康状态和AI分析能力" />
</CardTitle>
<Activity className="h-4 w-4 text-purple-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-purple-600">{coreData.systemHealth}%</div>
<p className="text-xs text-muted-foreground">AI分析: {formatNumber(coreData.aiAnalysis)} </p>
<div className="flex items-center mt-2">
<Badge className="bg-green-100 text-green-800 text-xs"></Badge>
</div>
</CardContent>
</Card>
</div>
</div>
</div>
{/* 核心功能模块 */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
{/* 数据中台 */}
<Link href="/data-platform">
<Card className="border-none shadow-md hover:shadow-lg transition-all duration-300 cursor-pointer group">
<CardHeader className="bg-gradient-to-r from-blue-50 to-indigo-50 pb-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Database className="h-5 w-5 text-blue-600" />
<CardTitle className="text-base"></CardTitle>
</div>
<Badge className="bg-blue-100 text-blue-700"></Badge>
</div>
<CardDescription className="text-xs"></CardDescription>
{/* 数据分布概览 */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Target className="h-4 w-4 text-red-500" />
</CardHeader>
<CardContent className="pt-3">
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.dataSync.total.toLocaleString()}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.dataSync.sources}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="text-green-600 font-bold">{todayStats.dataSync.growth}</span>
</div>
<div className="flex items-center justify-between mt-3">
<span className="text-xs text-gray-500">: {todayStats.dataSync.lastUpdate}</span>
<ChevronRight className="h-4 w-4 text-gray-400 group-hover:text-blue-600 transition-colors" />
</div>
</div>
<CardContent>
<div className="text-2xl font-bold">2.8M</div>
<p className="text-xs text-muted-foreground"> 7.2%</p>
</CardContent>
</Card>
</Link>
{/* 用户池 */}
<Link href="/user-pool">
<Card className="border-none shadow-md hover:shadow-lg transition-all duration-300 cursor-pointer group">
<CardHeader className="bg-gradient-to-r from-green-50 to-emerald-50 pb-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Users className="h-5 w-5 text-green-600" />
<CardTitle className="text-base"></CardTitle>
</div>
</div>
<CardDescription className="text-xs"></CardDescription>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<UserCheck className="h-4 w-4 text-green-500" />
</CardHeader>
<CardContent className="pt-3">
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.userPool.totalUsers.toLocaleString()}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.userPool.activeUsers.toLocaleString()}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.userPool.newUsers.toLocaleString()}</span>
</div>
<div className="flex items-center justify-between mt-3">
<span className="text-xs text-green-600"> {todayStats.userPool.growth}</span>
<ChevronRight className="h-4 w-4 text-gray-400 group-hover:text-green-600 transition-colors" />
</div>
</div>
<CardContent>
<div className="text-2xl font-bold">28.5M</div>
<p className="text-xs text-muted-foreground"></p>
</CardContent>
</Card>
</Link>
{/* 用户画像 */}
<Link href="/user-portrait">
<Card className="border-none shadow-md hover:shadow-lg transition-all duration-300 cursor-pointer group">
<CardHeader className="bg-gradient-to-r from-purple-50 to-pink-50 pb-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Target className="h-5 w-5 text-purple-600" />
<CardTitle className="text-base"></CardTitle>
</div>
</div>
<CardDescription className="text-xs"></CardDescription>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<BarChart3 className="h-4 w-4 text-blue-500" />
</CardHeader>
<CardContent className="pt-3">
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.userPortrait.totalTags}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.userPortrait.activeTags}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="text-purple-600 font-bold">{todayStats.userPortrait.coverage}</span>
</div>
<div className="flex items-center justify-between mt-3">
<span className="text-xs text-purple-600"> {todayStats.userPortrait.growth}</span>
<ChevronRight className="h-4 w-4 text-gray-400 group-hover:text-purple-600 transition-colors" />
</div>
</div>
<CardContent>
<div className="text-2xl font-bold">156K</div>
<p className="text-xs text-muted-foreground"></p>
</CardContent>
</Card>
</Link>
{/* 用户估值 */}
<Link href="/user-valuation">
<Card className="border-none shadow-md hover:shadow-lg transition-all duration-300 cursor-pointer group">
<CardHeader className="bg-gradient-to-r from-orange-50 to-red-50 pb-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<TrendingUp className="h-5 w-5 text-orange-600" />
<CardTitle className="text-base"></CardTitle>
</div>
</div>
<CardDescription className="text-xs"></CardDescription>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Database className="h-4 w-4 text-purple-500" />
</CardHeader>
<CardContent className="pt-3">
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">¥{todayStats.userValuation.avgValue.toLocaleString()}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="font-bold">{todayStats.userValuation.highValue.toLocaleString()}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="text-orange-600 font-bold">{todayStats.userValuation.upgradeRate}</span>
</div>
<div className="flex items-center justify-between mt-3">
<span className="text-xs text-orange-600"> {todayStats.userValuation.growth}</span>
<ChevronRight className="h-4 w-4 text-gray-400 group-hover:text-orange-600 transition-colors" />
</div>
</div>
<CardContent>
<div className="text-2xl font-bold">28</div>
<p className="text-xs text-muted-foreground"></p>
</CardContent>
</Card>
</Link>
</div>
</div>
{/* 实时数据流 */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 md:gap-6">
{/* 今日关键指标 */}
<Card className="lg:col-span-2 border-none shadow-md">
{/* 实时活动流 */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Activity className="h-5 w-5 text-blue-600" />
<Activity className="h-5 w-5" />
<TooltipHelp content="系统实时数据处理和分析活动" />
</CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div className="text-center p-3 bg-blue-50 rounded-lg">
<div className="text-2xl font-bold text-blue-600">98.5%</div>
<div className="text-xs text-gray-600"></div>
</div>
<div className="text-center p-3 bg-green-50 rounded-lg">
<div className="text-2xl font-bold text-green-600">2.3s</div>
<div className="text-xs text-gray-600"></div>
</div>
<div className="text-center p-3 bg-purple-50 rounded-lg">
<div className="text-2xl font-bold text-purple-600">342</div>
<div className="text-xs text-gray-600"></div>
</div>
<div className="text-center p-3 bg-orange-50 rounded-lg">
<div className="text-2xl font-bold text-orange-600">95.8%</div>
<div className="text-xs text-gray-600"></div>
</div>
</div>
<div className="mt-4 space-y-3">
<div>
<div className="flex justify-between text-sm mb-1">
<span></span>
<span>87%</span>
</div>
<Progress value={87} className="h-2" />
</div>
<div>
<div className="flex justify-between text-sm mb-1">
<span></span>
<span>92%</span>
</div>
<Progress value={92} className="h-2" />
</div>
</div>
</CardContent>
</Card>
{/* 实时活动 */}
<Card className="border-none shadow-md">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Activity className="h-5 w-5 text-green-600" />
</CardTitle>
<CardDescription></CardDescription>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
{realtimeActivities.map((activity) => (
<div key={activity.id} className="flex items-start gap-3 p-2 hover:bg-gray-50 rounded-lg">
<div className={`p-1 rounded-full ${getStatusColor(activity.status)}`}>
{getActivityIcon(activity.type)}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium truncate">{activity.message}</p>
<p className="text-xs text-gray-500">{activity.time}</p>
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
<div className="flex items-center gap-3">
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
<div>
<div className="font-medium"></div>
<div className="text-sm text-muted-foreground"> 1,247 </div>
</div>
</div>
))}
<Badge className="bg-green-100 text-green-800"></Badge>
</div>
<div className="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
<div className="flex items-center gap-3">
<div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse"></div>
<div>
<div className="font-medium">AI分析完成</div>
<div className="text-sm text-muted-foreground"></div>
</div>
</div>
<Badge className="bg-blue-100 text-blue-800">2</Badge>
</div>
<div className="flex items-center justify-between p-3 bg-purple-50 rounded-lg">
<div className="flex items-center gap-3">
<div className="w-2 h-2 bg-purple-500 rounded-full animate-pulse"></div>
<div>
<div className="font-medium"></div>
<div className="text-sm text-muted-foreground"> 89 </div>
</div>
</div>
<Badge className="bg-purple-100 text-purple-800">5</Badge>
</div>
</div>
<Button variant="outline" className="w-full mt-4 text-sm bg-transparent">
</Button>
</CardContent>
</Card>
</div>
{/* 快速操作 */}
<Card className="border-none shadow-md">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Zap className="h-5 w-5 text-yellow-600" />
</CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
<Link href="/data-platform">
<Button variant="outline" className="w-full h-16 flex flex-col gap-1 bg-transparent">
<Database className="h-5 w-5" />
<span className="text-xs"></span>
</Button>
</Link>
<Link href="/user-pool/management">
<Button variant="outline" className="w-full h-16 flex flex-col gap-1 bg-transparent">
<UserCheck className="h-5 w-5" />
<span className="text-xs"></span>
</Button>
</Link>
<Link href="/user-pool/segmentation">
<Button variant="outline" className="w-full h-16 flex flex-col gap-1 bg-transparent">
<Layers className="h-5 w-5" />
<span className="text-xs"></span>
</Button>
</Link>
<Link href="/user-portrait/tags">
<Button variant="outline" className="w-full h-16 flex flex-col gap-1 bg-transparent">
<Tag className="h-5 w-5" />
<span className="text-xs"></span>
</Button>
</Link>
</div>
</CardContent>
</Card>
</div>
</TooltipProvider>
)
}