Reorganize navigation and module structure based on new requirements. Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
400 lines
17 KiB
TypeScript
400 lines
17 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|
import { Badge } from "@/components/ui/badge"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Users, TrendingUp, Database, Activity, Zap, DollarSign, BarChart3, RefreshCw, AlertCircle, CheckCircle2, Clock, ArrowUpRight, ArrowDownRight, Cpu, HardDrive, Globe, Shield } from 'lucide-react'
|
|
import { Progress } from "@/components/ui/progress"
|
|
import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts'
|
|
|
|
export default function PlatformDashboard() {
|
|
const [refreshing, setRefreshing] = useState(false)
|
|
const [lastUpdate, setLastUpdate] = useState(new Date())
|
|
|
|
const monthlyData = [
|
|
{ month: '1月', users: 3.85, value: 98.5 },
|
|
{ month: '2月', users: 3.92, value: 102.5 },
|
|
{ month: '3月', users: 4.05, value: 108.5 },
|
|
{ month: '4月', users: 4.12, value: 114.2 },
|
|
{ month: '5月', users: 4.21, value: 119.8 },
|
|
{ month: '6月', users: 4.29, value: 125.8 },
|
|
]
|
|
|
|
const levelData = [
|
|
{ name: 'S级', value: 3.0, color: '#8b5cf6' },
|
|
{ name: 'A级', value: 11.0, color: '#3b82f6' },
|
|
{ name: 'B级', value: 25.0, color: '#10b981' },
|
|
{ name: 'C级', value: 40.0, color: '#f59e0b' },
|
|
{ name: 'D级', value: 21.0, color: '#9ca3af' },
|
|
]
|
|
|
|
// 模拟真实平台数据
|
|
const platformStats = {
|
|
totalUsers: 4285670000, // 42.8亿用户
|
|
totalProjects: 156, // 156个项目
|
|
totalEnterprises: 48, // 48家企业
|
|
totalWeChatAccounts: 892, // 892个微信号
|
|
dataCoverage: 87.3, // 数据覆盖率
|
|
assetValue: 12580000000, // 125.8亿资产价值
|
|
todayGrowth: 2845000, // 今日新增用户
|
|
activeRate: 68.5, // 活跃率
|
|
aiModelStatus: "running", // AI运行状态
|
|
dataSync: 94.2, // 数据同步进度
|
|
}
|
|
|
|
// 项目分布数据
|
|
const projectDistribution = [
|
|
{ name: "美妆行业", projects: 42, users: 1285000000, value: 3850000000, growth: 12.5 },
|
|
{ name: "教育培训", projects: 28, users: 856000000, value: 2280000000, growth: 8.3 },
|
|
{ name: "电商零售", projects: 35, users: 1124000000, value: 3560000000, growth: 15.2 },
|
|
{ name: "金融服务", projects: 18, users: 624000000, value: 1950000000, growth: 6.8 },
|
|
{ name: "其他行业", projects: 33, users: 396670000, value: 940000000, growth: 4.2 },
|
|
]
|
|
|
|
// 价值评分分布 (S/A/B/C/D级)
|
|
const valueDistribution = [
|
|
{ level: "S", count: 128456700, percentage: 3.0, avgValue: 580, color: "bg-purple-500" },
|
|
{ level: "A", count: 471424550, percentage: 11.0, avgValue: 320, color: "bg-blue-500" },
|
|
{ level: "B", count: 1071416750, percentage: 25.0, avgValue: 180, color: "bg-green-500" },
|
|
{ level: "C", count: 1714283500, percentage: 40.0, avgValue: 85, color: "bg-yellow-500" },
|
|
{ level: "D", count: 900088500, percentage: 21.0, avgValue: 25, color: "bg-gray-400" },
|
|
]
|
|
|
|
// AI模型运行数据
|
|
const aiModels = [
|
|
{ name: "数据清洗模型", status: "running", accuracy: 96.8, processedToday: 2845000, avgTime: 1.2 },
|
|
{ name: "用户标签模型", status: "running", accuracy: 94.5, processedToday: 2845000, avgTime: 0.8 },
|
|
{ name: "价值预测模型", status: "running", accuracy: 91.2, processedToday: 1580000, avgTime: 2.5 },
|
|
{ name: "流失预警模型", status: "training", accuracy: 88.9, processedToday: 0, avgTime: 0 },
|
|
]
|
|
|
|
// 数据流转实时状态
|
|
const dataFlow = {
|
|
incoming: 4250, // 每秒接入数据
|
|
processing: 3890, // 每秒处理数据
|
|
outgoing: 3650, // 每秒输出数据
|
|
queueSize: 12580, // 队列大小
|
|
}
|
|
|
|
const refreshData = async () => {
|
|
setRefreshing(true)
|
|
// 模拟刷新延迟
|
|
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
setLastUpdate(new Date())
|
|
setRefreshing(false)
|
|
}
|
|
|
|
const formatNumber = (num: number): string => {
|
|
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()
|
|
}
|
|
|
|
const formatCurrency = (num: number): string => {
|
|
if (num >= 100000000) return `${(num / 100000000).toFixed(1)}亿`
|
|
if (num >= 10000) return `${(num / 10000).toFixed(1)}万`
|
|
return num.toString()
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 p-6">
|
|
<div className="mb-8 flex items-center justify-between">
|
|
<div>
|
|
<h1 className="text-4xl font-bold mb-2 text-gray-900">平台总览</h1>
|
|
<p className="text-gray-600">神射手数据资产中台 - 实时监控</p>
|
|
</div>
|
|
<div className="flex items-center gap-4">
|
|
<Badge variant="outline" className="border-green-500 text-green-600 bg-green-50 px-4 py-2">
|
|
<CheckCircle2 className="w-4 h-4 mr-2" />
|
|
系统正常运行
|
|
</Badge>
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={refreshData}
|
|
disabled={refreshing}
|
|
>
|
|
<RefreshCw className={`w-4 h-4 mr-2 ${refreshing ? "animate-spin" : ""}`} />
|
|
刷新
|
|
</Button>
|
|
<div className="text-sm text-gray-600">
|
|
最后更新: {lastUpdate.toLocaleTimeString("zh-CN")}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 核心指标 */}
|
|
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-6">
|
|
<Card className="bg-gradient-to-br from-purple-50 to-purple-100 border-purple-200">
|
|
<CardHeader className="pb-3">
|
|
<CardTitle className="text-gray-900 flex items-center gap-2 text-lg">
|
|
<Users className="w-5 h-5 text-purple-600" />
|
|
用户资产总量
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-4xl font-bold text-purple-600 mb-2">
|
|
{formatNumber(platformStats.totalUsers)}
|
|
</div>
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<ArrowUpRight className="w-4 h-4 text-green-600" />
|
|
<span className="text-green-600">+{formatNumber(platformStats.todayGrowth)}</span>
|
|
<span className="text-gray-600">今日新增</span>
|
|
</div>
|
|
<div className="mt-3 text-xs text-gray-600">
|
|
活跃率: {platformStats.activeRate}%
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card className="bg-gradient-to-br from-blue-50 to-blue-100 border-blue-200">
|
|
<CardHeader className="pb-3">
|
|
<CardTitle className="text-gray-900 flex items-center gap-2 text-lg">
|
|
<DollarSign className="w-5 h-5 text-blue-600" />
|
|
数据资产价值
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-4xl font-bold text-blue-600 mb-2">
|
|
¥{formatCurrency(platformStats.assetValue)}
|
|
</div>
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<TrendingUp className="w-4 h-4 text-green-600" />
|
|
<span className="text-green-600">+15.8%</span>
|
|
<span className="text-gray-600">本月增长</span>
|
|
</div>
|
|
<div className="mt-3 text-xs text-gray-600">
|
|
人均价值: ¥{(platformStats.assetValue / platformStats.totalUsers).toFixed(2)}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card className="bg-gradient-to-br from-green-50 to-green-100 border-green-200">
|
|
<CardHeader className="pb-3">
|
|
<CardTitle className="text-gray-900 flex items-center gap-2 text-lg">
|
|
<Globe className="w-5 h-5 text-green-600" />
|
|
项目与企业
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-gray-600 text-sm">企业数</span>
|
|
<span className="text-2xl font-bold text-green-600">{platformStats.totalEnterprises}</span>
|
|
</div>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-gray-600 text-sm">项目数</span>
|
|
<span className="text-2xl font-bold text-green-600">{platformStats.totalProjects}</span>
|
|
</div>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-gray-600 text-sm">微信号</span>
|
|
<span className="text-xl font-bold text-green-600">{platformStats.totalWeChatAccounts}</span>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card className="bg-gradient-to-br from-orange-50 to-orange-100 border-orange-200">
|
|
<CardHeader className="pb-3">
|
|
<CardTitle className="text-gray-900 flex items-center gap-2 text-lg">
|
|
<Cpu className="w-5 h-5 text-orange-600" />
|
|
AI运行状态
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<div className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></div>
|
|
<span className="text-sm text-green-600">4个模型运行中</span>
|
|
</div>
|
|
<div className="flex items-center justify-between text-sm">
|
|
<span className="text-gray-600">平均准确率</span>
|
|
<span className="text-orange-600 font-semibold">92.9%</span>
|
|
</div>
|
|
<div className="flex items-center justify-between text-sm">
|
|
<span className="text-gray-600">今日处理</span>
|
|
<span className="text-orange-600 font-semibold">{formatNumber(7270000)}</span>
|
|
</div>
|
|
<div className="flex items-center justify-between text-sm">
|
|
<span className="text-gray-600">平均耗时</span>
|
|
<span className="text-orange-600 font-semibold">1.2s</span>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-gray-900 flex items-center gap-2">
|
|
<TrendingUp className="w-5 h-5" />
|
|
用户增长趋势
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ResponsiveContainer width="100%" height={300}>
|
|
<LineChart data={monthlyData}>
|
|
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
|
|
<XAxis dataKey="month" stroke="#6b7280" />
|
|
<YAxis stroke="#6b7280" />
|
|
<Tooltip />
|
|
<Line type="monotone" dataKey="users" stroke="#8b5cf6" strokeWidth={2} name="用户数(亿)" />
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-gray-900 flex items-center gap-2">
|
|
<DollarSign className="w-5 h-5" />
|
|
资产价值趋势
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ResponsiveContainer width="100%" height={300}>
|
|
<LineChart data={monthlyData}>
|
|
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
|
|
<XAxis dataKey="month" stroke="#6b7280" />
|
|
<YAxis stroke="#6b7280" />
|
|
<Tooltip />
|
|
<Line type="monotone" dataKey="value" stroke="#3b82f6" strokeWidth={2} name="价值(亿)" />
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-gray-900 flex items-center gap-2">
|
|
<BarChart3 className="w-5 h-5" />
|
|
价值评分分布
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ResponsiveContainer width="100%" height={300}>
|
|
<PieChart>
|
|
<Pie
|
|
data={levelData}
|
|
cx="50%"
|
|
cy="50%"
|
|
labelLine={false}
|
|
label={({ name, value }) => `${name} ${value}%`}
|
|
outerRadius={80}
|
|
fill="#8884d8"
|
|
dataKey="value"
|
|
>
|
|
{levelData.map((entry, index) => (
|
|
<Cell key={`cell-${index}`} fill={entry.color} />
|
|
))}
|
|
</Pie>
|
|
<Tooltip />
|
|
</PieChart>
|
|
</ResponsiveContainer>
|
|
<div className="grid grid-cols-5 gap-2 mt-4">
|
|
{valueDistribution.map((item, index) => (
|
|
<div key={index} className="text-center">
|
|
<div className={`w-8 h-8 rounded ${item.color} flex items-center justify-center font-bold text-white mx-auto mb-1`}>
|
|
{item.level}
|
|
</div>
|
|
<div className="text-xs text-gray-600">{formatNumber(item.count)}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-gray-900 flex items-center gap-2">
|
|
<Activity className="w-5 h-5" />
|
|
数据流转实时状态
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-4">
|
|
<div className="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
|
|
<div className="flex items-center gap-2">
|
|
<ArrowDownRight className="w-4 h-4 text-blue-600" />
|
|
<span className="text-gray-700">数据接入</span>
|
|
</div>
|
|
<div className="text-xl font-semibold text-blue-600">{dataFlow.incoming}/s</div>
|
|
</div>
|
|
<div className="flex items-center justify-between p-3 bg-yellow-50 rounded-lg">
|
|
<div className="flex items-center gap-2">
|
|
<Zap className="w-4 h-4 text-yellow-600" />
|
|
<span className="text-gray-700">数据处理</span>
|
|
</div>
|
|
<div className="text-xl font-semibold text-yellow-600">{dataFlow.processing}/s</div>
|
|
</div>
|
|
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
|
|
<div className="flex items-center gap-2">
|
|
<ArrowUpRight className="w-4 h-4 text-green-600" />
|
|
<span className="text-gray-700">数据输出</span>
|
|
</div>
|
|
<div className="text-xl font-semibold text-green-600">{dataFlow.outgoing}/s</div>
|
|
</div>
|
|
<div className="flex items-center justify-between p-3 bg-purple-50 rounded-lg">
|
|
<div className="flex items-center gap-2">
|
|
<HardDrive className="w-4 h-4 text-purple-600" />
|
|
<span className="text-gray-700">队列大小</span>
|
|
</div>
|
|
<div className="text-xl font-semibold text-purple-600">{dataFlow.queueSize}</div>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* 项目分布 */}
|
|
<Card className="mb-6">
|
|
<CardHeader>
|
|
<CardTitle className="text-gray-900 flex items-center gap-2">
|
|
<BarChart3 className="w-5 h-5" />
|
|
项目运营与企业分布
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-3">
|
|
{projectDistribution.map((item, index) => (
|
|
<div key={index} className="p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<div className="flex items-center gap-3">
|
|
<div className="text-lg font-semibold text-gray-900">{item.name}</div>
|
|
<Badge variant="outline" className="border-blue-300 text-blue-600 bg-blue-50">
|
|
{item.projects} 项目
|
|
</Badge>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<ArrowUpRight className="w-4 h-4 text-green-600" />
|
|
<span className="text-green-600 font-semibold">+{item.growth}%</span>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-3 gap-4 text-sm">
|
|
<div>
|
|
<div className="text-gray-600 mb-1">用户数</div>
|
|
<div className="text-gray-900 font-semibold">{formatNumber(item.users)}</div>
|
|
</div>
|
|
<div>
|
|
<div className="text-gray-600 mb-1">资产价值</div>
|
|
<div className="text-gray-900 font-semibold">¥{formatCurrency(item.value)}</div>
|
|
</div>
|
|
<div>
|
|
<div className="text-gray-600 mb-1">人均价值</div>
|
|
<div className="text-gray-900 font-semibold">¥{(item.value / item.users).toFixed(2)}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|