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>
406 lines
14 KiB
TypeScript
406 lines
14 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import { Card, CardContent, CardDescription, 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 {
|
|
Database,
|
|
GitBranch,
|
|
Zap,
|
|
Shield,
|
|
Activity,
|
|
CheckCircle,
|
|
AlertTriangle,
|
|
Clock,
|
|
TrendingUp,
|
|
Settings,
|
|
Plus,
|
|
} from "lucide-react"
|
|
import Link from "next/link"
|
|
|
|
export default function DataIntegrationPage() {
|
|
const [activeTab, setActiveTab] = useState("overview")
|
|
|
|
const integrationStats = {
|
|
totalSources: 12,
|
|
activeSources: 10,
|
|
dailyVolume: 2456789,
|
|
successRate: 98.5,
|
|
avgLatency: 156,
|
|
qualityScore: 94.2,
|
|
}
|
|
|
|
const dataSources = [
|
|
{
|
|
id: 1,
|
|
name: "MySQL主库",
|
|
type: "database",
|
|
status: "connected",
|
|
lastSync: "2分钟前",
|
|
records: 1245678,
|
|
quality: 98.5,
|
|
},
|
|
{
|
|
id: 2,
|
|
name: "触客宝API",
|
|
type: "api",
|
|
status: "connected",
|
|
lastSync: "5分钟前",
|
|
records: 456789,
|
|
quality: 96.2,
|
|
},
|
|
{
|
|
id: 3,
|
|
name: "抖音内容平台",
|
|
type: "api",
|
|
status: "warning",
|
|
lastSync: "1小时前",
|
|
records: 234567,
|
|
quality: 89.3,
|
|
},
|
|
{
|
|
id: 4,
|
|
name: "小红书API",
|
|
type: "api",
|
|
status: "connected",
|
|
lastSync: "10分钟前",
|
|
records: 123456,
|
|
quality: 95.8,
|
|
},
|
|
{
|
|
id: 5,
|
|
name: "微信视频号",
|
|
type: "api",
|
|
status: "connected",
|
|
lastSync: "15分钟前",
|
|
records: 98765,
|
|
quality: 92.4,
|
|
},
|
|
{
|
|
id: 6,
|
|
name: "飞书妙记API",
|
|
type: "api",
|
|
status: "error",
|
|
lastSync: "2小时前",
|
|
records: 45678,
|
|
quality: 78.9,
|
|
},
|
|
]
|
|
|
|
const recentActivities = [
|
|
{
|
|
id: 1,
|
|
type: "sync_complete",
|
|
message: "MySQL主库数据同步完成",
|
|
time: "2分钟前",
|
|
status: "success",
|
|
},
|
|
{
|
|
id: 2,
|
|
type: "quality_check",
|
|
message: "触客宝API数据质量检查通过",
|
|
time: "8分钟前",
|
|
status: "success",
|
|
},
|
|
{
|
|
id: 3,
|
|
type: "sync_warning",
|
|
message: "抖音内容平台同步延迟",
|
|
time: "1小时前",
|
|
status: "warning",
|
|
},
|
|
{
|
|
id: 4,
|
|
type: "sync_error",
|
|
message: "飞书妙记API连接失败",
|
|
time: "2小时前",
|
|
status: "error",
|
|
},
|
|
]
|
|
|
|
const getStatusIcon = (status: string) => {
|
|
switch (status) {
|
|
case "connected":
|
|
return <CheckCircle className="h-4 w-4 text-green-500" />
|
|
case "warning":
|
|
return <AlertTriangle className="h-4 w-4 text-yellow-500" />
|
|
case "error":
|
|
return <AlertTriangle className="h-4 w-4 text-red-500" />
|
|
default:
|
|
return <Clock className="h-4 w-4 text-gray-500" />
|
|
}
|
|
}
|
|
|
|
const getStatusColor = (status: string) => {
|
|
switch (status) {
|
|
case "connected":
|
|
return "bg-green-100 text-green-800"
|
|
case "warning":
|
|
return "bg-yellow-100 text-yellow-800"
|
|
case "error":
|
|
return "bg-red-100 text-red-800"
|
|
default:
|
|
return "bg-gray-100 text-gray-800"
|
|
}
|
|
}
|
|
|
|
const getActivityIcon = (type: string) => {
|
|
switch (type) {
|
|
case "sync_complete":
|
|
return <CheckCircle className="h-4 w-4 text-green-500" />
|
|
case "quality_check":
|
|
return <Shield className="h-4 w-4 text-blue-500" />
|
|
case "sync_warning":
|
|
return <AlertTriangle className="h-4 w-4 text-yellow-500" />
|
|
case "sync_error":
|
|
return <AlertTriangle className="h-4 w-4 text-red-500" />
|
|
default:
|
|
return <Activity className="h-4 w-4 text-gray-500" />
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="container mx-auto py-6 space-y-6">
|
|
{/* 页面标题 */}
|
|
<div className="flex flex-col md:flex-row md:justify-between md:items-center gap-4">
|
|
<div>
|
|
<h1 className="text-3xl font-bold tracking-tight">数据对接</h1>
|
|
<p className="text-muted-foreground">数据源管理与全流程监控</p>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
<Button>
|
|
<Plus className="mr-2 h-4 w-4" />
|
|
添加数据源
|
|
</Button>
|
|
<Button variant="outline">
|
|
<Settings className="mr-2 h-4 w-4" />
|
|
配置管理
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 核心指标 */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
<Card className="bg-gradient-to-r from-blue-50 to-cyan-50 border-none shadow-md">
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-sm font-medium">数据源总数</CardTitle>
|
|
<Database className="h-4 w-4 text-blue-600" />
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold text-blue-600">{integrationStats.totalSources}</div>
|
|
<div className="text-xs text-muted-foreground mt-1">活跃: {integrationStats.activeSources}个</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card className="bg-gradient-to-r from-green-50 to-emerald-50 border-none shadow-md">
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-sm font-medium">日处理量</CardTitle>
|
|
<Activity className="h-4 w-4 text-green-600" />
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold text-green-600">
|
|
{(integrationStats.dailyVolume / 1000000).toFixed(1)}M
|
|
</div>
|
|
<div className="text-xs text-muted-foreground mt-1">条记录</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card className="bg-gradient-to-r from-purple-50 to-pink-50 border-none shadow-md">
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-sm font-medium">成功率</CardTitle>
|
|
<TrendingUp className="h-4 w-4 text-purple-600" />
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold text-purple-600">{integrationStats.successRate}%</div>
|
|
<div className="text-xs text-muted-foreground mt-1">同步成功率</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card className="bg-gradient-to-r from-orange-50 to-red-50 border-none shadow-md">
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-sm font-medium">平均延迟</CardTitle>
|
|
<Zap className="h-4 w-4 text-orange-600" />
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold text-orange-600">{integrationStats.avgLatency}ms</div>
|
|
<div className="text-xs text-muted-foreground mt-1">响应时间</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* 数据源状态 */}
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<Card className="lg:col-span-2">
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<GitBranch className="h-5 w-5 text-blue-600" />
|
|
数据源状态
|
|
</CardTitle>
|
|
<CardDescription>各数据源连接状态与同步情况</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-4">
|
|
{dataSources.map((source) => (
|
|
<div key={source.id} className="flex items-center justify-between p-4 border rounded-lg">
|
|
<div className="flex items-center gap-3">
|
|
{getStatusIcon(source.status)}
|
|
<div>
|
|
<p className="font-medium text-sm">{source.name}</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
{source.type === "database" ? "数据库" : "API接口"} • 最后同步: {source.lastSync}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="text-right">
|
|
<Badge className={getStatusColor(source.status)}>
|
|
{source.status === "connected" ? "已连接" : source.status === "warning" ? "警告" : "错误"}
|
|
</Badge>
|
|
<div className="flex items-center gap-4 mt-1 text-xs text-muted-foreground">
|
|
<span>{source.records.toLocaleString()} 条</span>
|
|
<span>质量: {source.quality}%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className="flex justify-between mt-4">
|
|
<Link href="/data-integration/sources">
|
|
<Button variant="outline">管理数据源</Button>
|
|
</Link>
|
|
<Button>添加新数据源</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* 实时活动 */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<Activity className="h-5 w-5 text-green-600" />
|
|
实时活动
|
|
</CardTitle>
|
|
<CardDescription>数据同步活动日志</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-3">
|
|
{recentActivities.map((activity) => (
|
|
<div key={activity.id} className="flex items-start gap-3 p-2 hover:bg-gray-50 rounded-lg">
|
|
{getActivityIcon(activity.type)}
|
|
<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>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<Button variant="outline" className="w-full mt-4 bg-transparent">
|
|
查看全部日志
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* 数据流程概览 */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<Zap className="h-5 w-5 text-purple-600" />
|
|
数据流程概览
|
|
</CardTitle>
|
|
<CardDescription>数据从接入到处理的完整流程</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
|
|
<Link href="/data-integration/sources">
|
|
<div className="text-center p-4 border rounded-lg hover:bg-gray-50 transition-colors cursor-pointer">
|
|
<GitBranch className="h-8 w-8 mx-auto mb-2 text-blue-600" />
|
|
<h3 className="font-medium mb-1">数据源管理</h3>
|
|
<p className="text-xs text-muted-foreground">配置和管理各种数据源</p>
|
|
<Badge className="mt-2 bg-blue-100 text-blue-700">{integrationStats.totalSources}个源</Badge>
|
|
</div>
|
|
</Link>
|
|
|
|
<Link href="/data-integration/ingestion">
|
|
<div className="text-center p-4 border rounded-lg hover:bg-gray-50 transition-colors cursor-pointer">
|
|
<Database className="h-8 w-8 mx-auto mb-2 text-green-600" />
|
|
<h3 className="font-medium mb-1">数据接入</h3>
|
|
<p className="text-xs text-muted-foreground">实时数据采集和同步</p>
|
|
<Badge className="mt-2 bg-green-100 text-green-700">
|
|
{(integrationStats.dailyVolume / 1000000).toFixed(1)}M/日
|
|
</Badge>
|
|
</div>
|
|
</Link>
|
|
|
|
<Link href="/data-integration/processing">
|
|
<div className="text-center p-4 border rounded-lg hover:bg-gray-50 transition-colors cursor-pointer">
|
|
<Zap className="h-8 w-8 mx-auto mb-2 text-purple-600" />
|
|
<h3 className="font-medium mb-1">数据处理</h3>
|
|
<p className="text-xs text-muted-foreground">清洗、转换和标准化</p>
|
|
<Badge className="mt-2 bg-purple-100 text-purple-700">{integrationStats.successRate}%成功</Badge>
|
|
</div>
|
|
</Link>
|
|
|
|
<Link href="/data-integration/quality">
|
|
<div className="text-center p-4 border rounded-lg hover:bg-gray-50 transition-colors cursor-pointer">
|
|
<Shield className="h-8 w-8 mx-auto mb-2 text-orange-600" />
|
|
<h3 className="font-medium mb-1">质量监控</h3>
|
|
<p className="text-xs text-muted-foreground">数据质量评估和监控</p>
|
|
<Badge className="mt-2 bg-orange-100 text-orange-700">{integrationStats.qualityScore}%质量</Badge>
|
|
</div>
|
|
</Link>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* 性能监控 */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<TrendingUp className="h-5 w-5 text-green-600" />
|
|
性能监控
|
|
</CardTitle>
|
|
<CardDescription>数据处理性能指标</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div>
|
|
<div className="flex justify-between text-sm mb-2">
|
|
<span>数据处理速度</span>
|
|
<span className="font-medium">85%</span>
|
|
</div>
|
|
<Progress value={85} className="h-2 mb-1" />
|
|
<p className="text-xs text-muted-foreground">1.2M 记录/小时</p>
|
|
</div>
|
|
<div>
|
|
<div className="flex justify-between text-sm mb-2">
|
|
<span>系统资源使用</span>
|
|
<span className="font-medium">67%</span>
|
|
</div>
|
|
<Progress value={67} className="h-2 mb-1" />
|
|
<p className="text-xs text-muted-foreground">CPU + 内存</p>
|
|
</div>
|
|
<div>
|
|
<div className="flex justify-between text-sm mb-2">
|
|
<span>存储使用率</span>
|
|
<span className="font-medium">42%</span>
|
|
</div>
|
|
<Progress value={42} className="h-2 mb-1" />
|
|
<p className="text-xs text-muted-foreground">2.1TB / 5TB</p>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|