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>
This commit is contained in:
175
app/platform/ai-assistant/data-analysis/page.tsx
Normal file
175
app/platform/ai-assistant/data-analysis/page.tsx
Normal file
@@ -0,0 +1,175 @@
|
||||
"use client"
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { BarChart3, TrendingUp, Users, Download, RefreshCw } from 'lucide-react'
|
||||
import { BarChart, Bar, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts'
|
||||
|
||||
export default function DataAnalysis() {
|
||||
const userBehaviorData = [
|
||||
{ hour: '00:00', active: 1250, purchases: 85, interactions: 4200 },
|
||||
{ hour: '04:00', active: 850, purchases: 35, interactions: 1800 },
|
||||
{ hour: '08:00', active: 5600, purchases: 420, interactions: 18500 },
|
||||
{ hour: '12:00', active: 8900, purchases: 680, interactions: 28600 },
|
||||
{ hour: '16:00', active: 7200, purchases: 520, interactions: 22400 },
|
||||
{ hour: '20:00', active: 9500, purchases: 750, interactions: 32800 },
|
||||
]
|
||||
|
||||
const channelData = [
|
||||
{ name: '微信朋友圈', value: 35, color: '#8b5cf6' },
|
||||
{ name: '微信群', value: 28, color: '#3b82f6' },
|
||||
{ name: '一对一私聊', value: 22, color: '#10b981' },
|
||||
{ name: '小程序', value: 15, color: '#f59e0b' },
|
||||
]
|
||||
|
||||
const conversionData = [
|
||||
{ stage: '浏览', users: 100000, rate: 100 },
|
||||
{ stage: '兴趣', users: 45000, rate: 45 },
|
||||
{ stage: '咨询', users: 18000, rate: 18 },
|
||||
{ stage: '下单', users: 5400, rate: 5.4 },
|
||||
{ stage: '复购', users: 1620, rate: 1.6 },
|
||||
]
|
||||
|
||||
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 text-gray-900 mb-2">数据分析</h1>
|
||||
<p className="text-gray-600">用户行为分析、渠道分析与转化漏斗</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="outline">
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
刷新数据
|
||||
</Button>
|
||||
<Button>
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
导出报告
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 关键指标 */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-6">
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">今日活跃用户</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">285.6K</div>
|
||||
<Badge variant="outline" className="border-green-500 text-green-600 bg-green-50">+12.5%</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">转化率</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">5.4%</div>
|
||||
<Badge variant="outline" className="border-blue-500 text-blue-600 bg-blue-50">+0.8%</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">人均互动次数</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">8.6</div>
|
||||
<Badge variant="outline" className="border-purple-500 text-purple-600 bg-purple-50">+1.2</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">客单价</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">¥328</div>
|
||||
<Badge variant="outline" className="border-orange-500 text-orange-600 bg-orange-50">+15.2%</Badge>
|
||||
</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">
|
||||
<Users className="w-5 h-5" />
|
||||
用户活跃时段分布
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ResponsiveContainer width="100%" height={300}>
|
||||
<BarChart data={userBehaviorData}>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
|
||||
<XAxis dataKey="hour" stroke="#6b7280" />
|
||||
<YAxis stroke="#6b7280" />
|
||||
<Tooltip />
|
||||
<Bar dataKey="active" fill="#8b5cf6" name="活跃用户" />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<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={channelData}
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
labelLine={false}
|
||||
label={({ name, value }) => `${name} ${value}%`}
|
||||
outerRadius={100}
|
||||
fill="#8884d8"
|
||||
dataKey="value"
|
||||
>
|
||||
{channelData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
<Tooltip />
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 转化漏斗 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5" />
|
||||
用户转化漏斗
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{conversionData.map((stage, index) => (
|
||||
<div key={index}>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-gray-700 font-medium">{stage.stage}</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-gray-900 font-semibold">{stage.users.toLocaleString()}人</span>
|
||||
<span className="text-blue-600 font-semibold w-16 text-right">{stage.rate}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-12 bg-gradient-to-r from-blue-500 to-purple-500 rounded-lg flex items-center px-4 text-white font-semibold" style={{ width: `${stage.rate}%`, minWidth: '10%' }}>
|
||||
{stage.rate}%
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
236
app/platform/ai-assistant/page.tsx
Normal file
236
app/platform/ai-assistant/page.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
"use client"
|
||||
|
||||
import Link from "next/link"
|
||||
import { useState } from "react"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { Cpu, BarChart3, TrendingUp, Users, Target, Brain, ArrowRight, Send, Sparkles } from 'lucide-react'
|
||||
|
||||
export default function AIAssistant() {
|
||||
const [message, setMessage] = useState("")
|
||||
const [chatHistory, setChatHistory] = useState([
|
||||
{
|
||||
role: "assistant",
|
||||
content: "你好!我是神射手AI助手,可以帮助你分析用户数据、生成报告、预测趋势。有什么我可以帮助你的吗?",
|
||||
timestamp: "10:30",
|
||||
},
|
||||
])
|
||||
|
||||
// AI功能卡片
|
||||
const aiFeatures = [
|
||||
{
|
||||
icon: <BarChart3 className="w-8 h-8" />,
|
||||
title: "数据分析",
|
||||
description: "自动分析用户行为,生成洞察报告",
|
||||
color: "from-blue-500 to-cyan-500",
|
||||
href: "/platform/ai-assistant/data-analysis",
|
||||
stats: { reports: 1258, insights: 856 }
|
||||
},
|
||||
{
|
||||
icon: <TrendingUp className="w-8 h-8" />,
|
||||
title: "趋势预测",
|
||||
description: "预测用户行为和价值变化趋势",
|
||||
color: "from-purple-500 to-pink-500",
|
||||
href: "/platform/ai-assistant/trend-prediction",
|
||||
stats: { accuracy: 94.2, predictions: 2450 }
|
||||
},
|
||||
{
|
||||
icon: <Users className="w-8 h-8" />,
|
||||
title: "用户画像",
|
||||
description: "智能生成用户群体画像",
|
||||
color: "from-green-500 to-emerald-500",
|
||||
href: "/platform/ai-assistant/user-profiling",
|
||||
stats: { profiles: 4285, segments: 128 }
|
||||
},
|
||||
{
|
||||
icon: <Target className="w-8 h-8" />,
|
||||
title: "精准推荐",
|
||||
description: "推荐最佳营销策略和用户群",
|
||||
color: "from-orange-500 to-red-500",
|
||||
href: "/platform/ai-assistant/recommendation",
|
||||
stats: { campaigns: 586, conversion: 18.5 }
|
||||
},
|
||||
]
|
||||
|
||||
// 快捷问题
|
||||
const quickQuestions = [
|
||||
"分析今日新增用户特征",
|
||||
"预测本月用户增长趋势",
|
||||
"高价值用户流失预警",
|
||||
"生成本周运营报告",
|
||||
]
|
||||
|
||||
const handleSend = () => {
|
||||
if (!message.trim()) return
|
||||
|
||||
setChatHistory([
|
||||
...chatHistory,
|
||||
{
|
||||
role: "user",
|
||||
content: message,
|
||||
timestamp: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }),
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content: "正在分析您的问题,请稍候...",
|
||||
timestamp: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }),
|
||||
},
|
||||
])
|
||||
setMessage("")
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 p-6">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-500 to-purple-500 flex items-center justify-center">
|
||||
<Brain className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold text-gray-900">AI智能助手</h1>
|
||||
<p className="text-gray-600">数据分析、报告生成与智能预测</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* AI状态 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<Cpu className="w-5 h-5 text-green-600" />
|
||||
AI运行状态
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">系统状态</span>
|
||||
<Badge variant="outline" className="border-green-500 text-green-600 bg-green-50">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500 animate-pulse mr-2"></div>
|
||||
运行中
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">模型版本</span>
|
||||
<span className="text-gray-900 font-semibold">v3.5</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">响应速度</span>
|
||||
<span className="text-gray-900 font-semibold">0.8s</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">准确率</span>
|
||||
<span className="text-green-600 font-semibold">94.2%</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* AI功能卡片 */}
|
||||
<div className="lg:col-span-2 grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{aiFeatures.map((feature, index) => (
|
||||
<Link key={index} href={feature.href}>
|
||||
<Card className="hover:shadow-lg transition-shadow cursor-pointer h-full">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-start gap-4 mb-4">
|
||||
<div className={`w-16 h-16 rounded-xl bg-gradient-to-br ${feature.color} flex items-center justify-center text-white`}>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h3 className="text-xl font-semibold text-gray-900">{feature.title}</h3>
|
||||
<ArrowRight className="w-5 h-5 text-gray-400" />
|
||||
</div>
|
||||
<p className="text-gray-600 text-sm">{feature.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4 pt-4 border-t border-gray-200">
|
||||
{Object.entries(feature.stats).map(([key, value], i) => (
|
||||
<div key={i}>
|
||||
<div className="text-xs text-gray-600 mb-1">{key === 'reports' ? '报告数' : key === 'insights' ? '洞察数' : key === 'accuracy' ? '准确率' : key === 'predictions' ? '预测数' : key === 'profiles' ? '画像数' : key === 'segments' ? '分组数' : key === 'campaigns' ? '活动数' : '转化率'}</div>
|
||||
<div className="text-lg font-semibold text-gray-900">
|
||||
{typeof value === 'number' && value % 1 !== 0 ? `${value}%` : value}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 对话区域 */}
|
||||
<div className="lg:col-span-2">
|
||||
<Card className="bg-white/5 border-white/10 h-[calc(100vh-200px)]">
|
||||
<CardHeader className="border-b border-white/10">
|
||||
<CardTitle className="text-white flex items-center gap-2">
|
||||
<BarChart3 className="w-5 h-5" />
|
||||
AI对话
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="p-6 flex flex-col h-[calc(100%-80px)]">
|
||||
{/* 聊天历史 */}
|
||||
<div className="flex-1 overflow-y-auto space-y-4 mb-6">
|
||||
{chatHistory.map((chat, index) => (
|
||||
<div key={index} className={`flex ${chat.role === "user" ? "justify-end" : "justify-start"}`}>
|
||||
<div
|
||||
className={`max-w-[80%] rounded-2xl p-4 ${
|
||||
chat.role === "user"
|
||||
? "bg-gradient-to-br from-blue-500 to-purple-500 text-white"
|
||||
: "bg-white/10 text-white"
|
||||
}`}
|
||||
>
|
||||
<div className="mb-1">{chat.content}</div>
|
||||
<div className="text-xs opacity-70">{chat.timestamp}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 快捷问题 */}
|
||||
<div className="mb-4 flex flex-wrap gap-2">
|
||||
{quickQuestions.map((question, index) => (
|
||||
<Button
|
||||
key={index}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setMessage(question)}
|
||||
className="bg-white/5 border-white/10 hover:bg-white/10 text-xs"
|
||||
>
|
||||
<Sparkles className="w-3 h-3 mr-1" />
|
||||
{question}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 输入框 */}
|
||||
<div className="flex items-end gap-3">
|
||||
<Textarea
|
||||
value={message}
|
||||
onChange={(e) => setMessage(e.target.value)}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === "Enter" && !e.shiftKey) {
|
||||
e.preventDefault()
|
||||
handleSend()
|
||||
}
|
||||
}}
|
||||
placeholder="输入您的问题,按Enter发送..."
|
||||
className="bg-white/5 border-white/10 text-white resize-none"
|
||||
rows={3}
|
||||
/>
|
||||
<Button onClick={handleSend} className="bg-gradient-to-r from-blue-500 to-purple-500 h-[88px]">
|
||||
<Send className="w-5 h-5" />
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
313
app/platform/ai-assistant/recommendation/page.tsx
Normal file
313
app/platform/ai-assistant/recommendation/page.tsx
Normal file
@@ -0,0 +1,313 @@
|
||||
"use client"
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Target, Users, TrendingUp, Zap, Download, RefreshCw, ArrowRight } from 'lucide-react'
|
||||
|
||||
export default function Recommendation() {
|
||||
const recommendedCampaigns = [
|
||||
{
|
||||
id: 1,
|
||||
title: '美妆新品推广',
|
||||
targetGroup: '高净值女性用户',
|
||||
userCount: 856780,
|
||||
expectedRevenue: 12850000,
|
||||
probability: 82,
|
||||
roi: 3.5,
|
||||
timeframe: '未来7天',
|
||||
actions: ['朋友圈广告', '私聊推送', '限时优惠'],
|
||||
priority: 'high'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '会员升级计划',
|
||||
targetGroup: '活跃普通会员',
|
||||
userCount: 1285670,
|
||||
expectedRevenue: 8560000,
|
||||
probability: 75,
|
||||
roi: 4.2,
|
||||
timeframe: '未来15天',
|
||||
actions: ['会员权益推广', '专属优惠', 'VIP体验券'],
|
||||
priority: 'high'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '沉默用户唤醒',
|
||||
targetGroup: '30天未活跃用户',
|
||||
userCount: 2856780,
|
||||
expectedRevenue: 5680000,
|
||||
probability: 58,
|
||||
roi: 2.8,
|
||||
timeframe: '未来30天',
|
||||
actions: ['优惠券发放', '新品预告', '个性化推荐'],
|
||||
priority: 'medium'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '交叉销售',
|
||||
targetGroup: '单品类购买用户',
|
||||
userCount: 1714283,
|
||||
expectedRevenue: 9280000,
|
||||
probability: 68,
|
||||
roi: 3.1,
|
||||
timeframe: '未来14天',
|
||||
actions: ['关联商品推荐', '搭配优惠', '场景营销'],
|
||||
priority: 'medium'
|
||||
},
|
||||
]
|
||||
|
||||
const recommendedSegments = [
|
||||
{
|
||||
name: '高转化潜力群体',
|
||||
count: 428567,
|
||||
conversion: 35.8,
|
||||
value: 580,
|
||||
characteristics: ['近期浏览频繁', '价格接受度高', '品牌认知强']
|
||||
},
|
||||
{
|
||||
name: '复购价值用户',
|
||||
count: 856780,
|
||||
conversion: 28.5,
|
||||
value: 420,
|
||||
characteristics: ['首购满意度高', '客单价适中', '活跃度稳定']
|
||||
},
|
||||
{
|
||||
name: '裂变传播节点',
|
||||
count: 285670,
|
||||
conversion: 22.3,
|
||||
value: 320,
|
||||
characteristics: ['社交影响力大', '分享意愿强', '粉丝基数高']
|
||||
},
|
||||
]
|
||||
|
||||
const contentRecommendations = [
|
||||
{
|
||||
type: '朋友圈内容',
|
||||
theme: '新品上市+限时优惠',
|
||||
targetUsers: 2856780,
|
||||
expectedEngagement: 18.5,
|
||||
bestTime: '20:00-22:00'
|
||||
},
|
||||
{
|
||||
type: '私聊话术',
|
||||
theme: '专属VIP权益介绍',
|
||||
targetUsers: 856780,
|
||||
expectedEngagement: 42.8,
|
||||
bestTime: '10:00-12:00'
|
||||
},
|
||||
{
|
||||
type: '社群活动',
|
||||
theme: '用户互动+抽奖',
|
||||
targetUsers: 1285670,
|
||||
expectedEngagement: 32.5,
|
||||
bestTime: '周末 15:00-17:00'
|
||||
},
|
||||
]
|
||||
|
||||
const getPriorityColor = (priority: string) => {
|
||||
return priority === 'high' ? 'border-red-500 text-red-600 bg-red-50' : 'border-yellow-500 text-yellow-600 bg-yellow-50'
|
||||
}
|
||||
|
||||
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 text-gray-900 mb-2">精准推荐</h1>
|
||||
<p className="text-gray-600">AI智能推荐营销策略、目标用户群与内容方案</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="outline">
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
刷新推荐
|
||||
</Button>
|
||||
<Button>
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
导出方案
|
||||
</Button>
|
||||
</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-sm text-gray-600">推荐方案数</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-purple-600">586</div>
|
||||
<div className="text-sm text-gray-600">本月生成</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-sm text-gray-600">平均转化率</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-blue-600">18.5%</div>
|
||||
<Badge variant="outline" className="border-green-500 text-green-600 bg-green-50">+3.2%</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-gradient-to-br from-green-50 to-green-100 border-green-200">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">预计收益</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-green-600">¥36.4M</div>
|
||||
<div className="text-sm text-gray-600">近期方案</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-sm text-gray-600">平均ROI</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-orange-600">3.4x</div>
|
||||
<div className="text-sm text-gray-600">投入产出比</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 推荐营销方案 */}
|
||||
<Card className="mb-6">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<Target className="w-5 h-5" />
|
||||
推荐营销方案
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{recommendedCampaigns.map((campaign) => (
|
||||
<div key={campaign.id} className="p-6 bg-white border border-gray-200 rounded-lg hover:shadow-md transition-shadow">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<h3 className="text-xl font-bold text-gray-900">{campaign.title}</h3>
|
||||
<Badge variant="outline" className={getPriorityColor(campaign.priority)}>
|
||||
{campaign.priority === 'high' ? '高优先级' : '中优先级'}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="border-gray-300 text-gray-600">
|
||||
{campaign.timeframe}
|
||||
</Badge>
|
||||
</div>
|
||||
<p className="text-gray-600">目标群体: {campaign.targetGroup}</p>
|
||||
</div>
|
||||
<Button>
|
||||
执行方案
|
||||
<ArrowRight className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-6 mb-4">
|
||||
<div>
|
||||
<div className="text-sm text-gray-600 mb-1">目标用户数</div>
|
||||
<div className="text-lg font-semibold text-gray-900">{campaign.userCount.toLocaleString()}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-600 mb-1">预期收益</div>
|
||||
<div className="text-lg font-semibold text-green-600">¥{(campaign.expectedRevenue / 10000).toFixed(1)}万</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-600 mb-1">成功概率</div>
|
||||
<div className="text-lg font-semibold text-blue-600">{campaign.probability}%</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-600 mb-1">预期ROI</div>
|
||||
<div className="text-lg font-semibold text-purple-600">{campaign.roi}x</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="text-sm text-gray-600 mb-2">推荐动作</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{campaign.actions.map((action, index) => (
|
||||
<Badge key={index} variant="outline" className="border-blue-300 text-blue-600 bg-blue-50">
|
||||
<Zap className="w-3 h-3 mr-1" />
|
||||
{action}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 推荐目标群体 */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
|
||||
{recommendedSegments.map((segment, index) => (
|
||||
<Card key={index}>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 text-lg">{segment.name}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-3 mb-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">用户数</span>
|
||||
<span className="text-lg font-semibold text-gray-900">{segment.count.toLocaleString()}</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">预期转化率</span>
|
||||
<span className="text-lg font-semibold text-green-600">{segment.conversion}%</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">人均价值</span>
|
||||
<span className="text-lg font-semibold text-blue-600">¥{segment.value}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-3 border-t border-gray-200">
|
||||
<div className="text-sm text-gray-600 mb-2">群体特征</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{segment.characteristics.map((char, i) => (
|
||||
<Badge key={i} variant="outline" className="border-gray-300 text-gray-700 text-xs">
|
||||
{char}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 内容推荐 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5" />
|
||||
内容推荐
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{contentRecommendations.map((content, index) => (
|
||||
<div key={index} className="p-4 bg-gradient-to-r from-blue-50 to-purple-50 rounded-lg border border-blue-200">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div>
|
||||
<h4 className="text-lg font-semibold text-gray-900 mb-1">{content.type}</h4>
|
||||
<p className="text-gray-600">{content.theme}</p>
|
||||
</div>
|
||||
<Badge variant="outline" className="border-purple-500 text-purple-600 bg-purple-50">
|
||||
最佳时间: {content.bestTime}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<span className="text-gray-600">目标触达: </span>
|
||||
<span className="font-semibold text-gray-900">{content.targetUsers.toLocaleString()} 人</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-gray-600">预期互动率: </span>
|
||||
<span className="font-semibold text-green-600">{content.expectedEngagement}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
222
app/platform/ai-assistant/trend-prediction/page.tsx
Normal file
222
app/platform/ai-assistant/trend-prediction/page.tsx
Normal file
@@ -0,0 +1,222 @@
|
||||
"use client"
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { TrendingUp, TrendingDown, AlertCircle, Download, RefreshCw } from 'lucide-react'
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, AreaChart, Area } from 'recharts'
|
||||
|
||||
export default function TrendPrediction() {
|
||||
const userGrowthPrediction = [
|
||||
{ date: '2024-06', actual: 428, predicted: null },
|
||||
{ date: '2024-07', actual: null, predicted: 445 },
|
||||
{ date: '2024-08', actual: null, predicted: 468 },
|
||||
{ date: '2024-09', actual: null, predicted: 495 },
|
||||
{ date: '2024-10', actual: null, predicted: 528 },
|
||||
{ date: '2024-11', actual: null, predicted: 565 },
|
||||
{ date: '2024-12', actual: null, predicted: 608 },
|
||||
]
|
||||
|
||||
const valuePrediction = [
|
||||
{ date: '2024-06', actual: 125.8, predicted: null },
|
||||
{ date: '2024-07', actual: null, predicted: 132.5 },
|
||||
{ date: '2024-08', actual: null, predicted: 141.2 },
|
||||
{ date: '2024-09', actual: null, predicted: 151.8 },
|
||||
{ date: '2024-10', actual: null, predicted: 164.5 },
|
||||
{ date: '2024-11', actual: null, predicted: 179.2 },
|
||||
{ date: '2024-12', actual: null, predicted: 196.5 },
|
||||
]
|
||||
|
||||
const churnRiskData = [
|
||||
{ segment: '高价值用户', risk: 8.5, count: 1285, trend: 'down' },
|
||||
{ segment: 'VIP用户', risk: 12.3, count: 856, trend: 'stable' },
|
||||
{ segment: '活跃用户', risk: 18.6, count: 12856, trend: 'up' },
|
||||
{ segment: '沉默用户', risk: 45.8, count: 28560, trend: 'up' },
|
||||
]
|
||||
|
||||
const opportunityData = [
|
||||
{ name: '新品推广机会', potential: '¥85.6M', probability: 78, timeframe: '未来30天' },
|
||||
{ name: '复购唤醒', potential: '¥56.2M', probability: 65, timeframe: '未来15天' },
|
||||
{ name: '会员升级', potential: '¥38.5M', probability: 82, timeframe: '未来7天' },
|
||||
{ name: '交叉销售', potential: '¥92.8M', probability: 58, timeframe: '未来45天' },
|
||||
]
|
||||
|
||||
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 text-gray-900 mb-2">趋势预测</h1>
|
||||
<p className="text-gray-600">用户增长预测、价值预测与流失预警</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="outline">
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
重新预测
|
||||
</Button>
|
||||
<Button>
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
导出报告
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 预测指标 */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-6">
|
||||
<Card className="bg-gradient-to-br from-blue-50 to-blue-100 border-blue-200">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">下月预测用户数</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-blue-600 mb-1">445M</div>
|
||||
<div className="text-sm text-gray-600">+3.9% 增长</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-sm text-gray-600">下月预测价值</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-green-600 mb-1">¥132.5亿</div>
|
||||
<div className="text-sm text-gray-600">+5.3% 增长</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-sm text-gray-600">流失风险用户</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-orange-600 mb-1">42.5K</div>
|
||||
<div className="text-sm text-gray-600">需重点关注</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-gradient-to-br from-purple-50 to-purple-100 border-purple-200">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">预测准确率</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-purple-600 mb-1">94.2%</div>
|
||||
<div className="text-sm text-gray-600">基于历史数据</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 text-blue-600" />
|
||||
用户增长预测
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ResponsiveContainer width="100%" height={300}>
|
||||
<LineChart data={userGrowthPrediction}>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
|
||||
<XAxis dataKey="date" stroke="#6b7280" />
|
||||
<YAxis stroke="#6b7280" />
|
||||
<Tooltip />
|
||||
<Line type="monotone" dataKey="actual" stroke="#3b82f6" strokeWidth={2} name="实际值" />
|
||||
<Line type="monotone" dataKey="predicted" stroke="#8b5cf6" strokeWidth={2} strokeDasharray="5 5" name="预测值" />
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5 text-green-600" />
|
||||
资产价值预测
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ResponsiveContainer width="100%" height={300}>
|
||||
<AreaChart data={valuePrediction}>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
|
||||
<XAxis dataKey="date" stroke="#6b7280" />
|
||||
<YAxis stroke="#6b7280" />
|
||||
<Tooltip />
|
||||
<Area type="monotone" dataKey="actual" stroke="#10b981" fill="#10b981" fillOpacity={0.3} name="实际值" />
|
||||
<Area type="monotone" dataKey="predicted" stroke="#8b5cf6" fill="#8b5cf6" fillOpacity={0.2} strokeDasharray="5 5" name="预测值" />
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 流失风险预警 */}
|
||||
<Card className="mb-6">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<AlertCircle className="w-5 h-5 text-orange-600" />
|
||||
流失风险预警
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{churnRiskData.map((item, index) => (
|
||||
<div key={index} className="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
||||
<div className="flex items-center gap-4">
|
||||
<div>
|
||||
<div className="text-lg font-semibold text-gray-900">{item.segment}</div>
|
||||
<div className="text-sm text-gray-600">{item.count.toLocaleString()} 用户</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="text-right">
|
||||
<div className="text-2xl font-bold text-orange-600">{item.risk}%</div>
|
||||
<div className="text-xs text-gray-600">流失风险</div>
|
||||
</div>
|
||||
{item.trend === 'down' ? (
|
||||
<TrendingDown className="w-6 h-6 text-green-600" />
|
||||
) : item.trend === 'up' ? (
|
||||
<TrendingUp className="w-6 h-6 text-red-600" />
|
||||
) : (
|
||||
<div className="w-6 h-6 flex items-center justify-center">
|
||||
<div className="w-4 h-0.5 bg-gray-400"></div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 商机预测 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5 text-purple-600" />
|
||||
商机预测
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
{opportunityData.map((item, index) => (
|
||||
<div key={index} className="p-4 bg-gradient-to-br from-purple-50 to-pink-50 rounded-lg border border-purple-200">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h3 className="text-lg font-semibold text-gray-900">{item.name}</h3>
|
||||
<Badge variant="outline" className="border-purple-500 text-purple-600 bg-purple-50">
|
||||
{item.timeframe}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex items-end justify-between">
|
||||
<div>
|
||||
<div className="text-sm text-gray-600 mb-1">预测收益</div>
|
||||
<div className="text-2xl font-bold text-purple-600">{item.potential}</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-sm text-gray-600 mb-1">成功概率</div>
|
||||
<div className="text-2xl font-bold text-green-600">{item.probability}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
239
app/platform/ai-assistant/user-profiling/page.tsx
Normal file
239
app/platform/ai-assistant/user-profiling/page.tsx
Normal file
@@ -0,0 +1,239 @@
|
||||
"use client"
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Users, Tag, Download, RefreshCw, TrendingUp } from 'lucide-react'
|
||||
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar } from 'recharts'
|
||||
|
||||
export default function UserProfiling() {
|
||||
const ageDistribution = [
|
||||
{ range: '18-25', count: 856780, percentage: 20 },
|
||||
{ range: '26-35', count: 1500000, percentage: 35 },
|
||||
{ range: '36-45', count: 1285670, percentage: 30 },
|
||||
{ range: '46-55', count: 428567, percentage: 10 },
|
||||
{ range: '55+', count: 214284, percentage: 5 },
|
||||
]
|
||||
|
||||
const behaviorProfile = [
|
||||
{ aspect: '消费能力', value: 85 },
|
||||
{ aspect: '活跃度', value: 72 },
|
||||
{ aspect: '互动频率', value: 68 },
|
||||
{ aspect: '忠诚度', value: 78 },
|
||||
{ aspect: '推荐意愿', value: 62 },
|
||||
{ aspect: '复购率', value: 75 },
|
||||
]
|
||||
|
||||
const segments = [
|
||||
{
|
||||
name: '高净值群体',
|
||||
count: 1284567,
|
||||
characteristics: ['消费能力强', '忠诚度高', '品牌认知强'],
|
||||
value: 580,
|
||||
color: 'purple'
|
||||
},
|
||||
{
|
||||
name: '年轻潮流族',
|
||||
count: 2856780,
|
||||
characteristics: ['追求时尚', '社交活跃', '冲动消费'],
|
||||
value: 280,
|
||||
color: 'blue'
|
||||
},
|
||||
{
|
||||
name: '理性消费者',
|
||||
count: 4285670,
|
||||
characteristics: ['价格敏感', '重视品质', '对比研究'],
|
||||
value: 180,
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
name: '价格敏感型',
|
||||
count: 1714283,
|
||||
characteristics: ['促销驱动', '低频复购', '优惠敏感'],
|
||||
value: 85,
|
||||
color: 'yellow'
|
||||
},
|
||||
]
|
||||
|
||||
const interestTags = [
|
||||
{ tag: '美妆护肤', count: 2856780, heat: 95 },
|
||||
{ tag: '时尚穿搭', count: 2145680, heat: 88 },
|
||||
{ tag: '健康养生', count: 1856780, heat: 76 },
|
||||
{ tag: '数码科技', count: 1428567, heat: 72 },
|
||||
{ tag: '母婴育儿', count: 1285670, heat: 68 },
|
||||
{ tag: '美食烹饪', count: 985670, heat: 58 },
|
||||
{ tag: '运动健身', count: 856780, heat: 52 },
|
||||
{ tag: '旅游出行', count: 714283, heat: 45 },
|
||||
]
|
||||
|
||||
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 text-gray-900 mb-2">用户画像</h1>
|
||||
<p className="text-gray-600">智能分析用户群体特征与行为偏好</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="outline">
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
重新分析
|
||||
</Button>
|
||||
<Button>
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
导出画像
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 核心指标 */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-6">
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">用户群体数</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">128</div>
|
||||
<div className="text-sm text-gray-600">覆盖42.8亿用户</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">标签覆盖率</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">87.5%</div>
|
||||
<Badge variant="outline" className="border-green-500 text-green-600 bg-green-50">优秀</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">画像完整度</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">92.3%</div>
|
||||
<Badge variant="outline" className="border-blue-500 text-blue-600 bg-blue-50">优秀</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm text-gray-600">更新频率</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">实时</div>
|
||||
<div className="text-sm text-gray-600">每小时更新</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">
|
||||
<Users className="w-5 h-5" />
|
||||
年龄分布
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ResponsiveContainer width="100%" height={300}>
|
||||
<BarChart data={ageDistribution}>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
|
||||
<XAxis dataKey="range" stroke="#6b7280" />
|
||||
<YAxis stroke="#6b7280" />
|
||||
<Tooltip />
|
||||
<Bar dataKey="count" fill="#8b5cf6" name="用户数" />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<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}>
|
||||
<RadarChart data={behaviorProfile}>
|
||||
<PolarGrid stroke="#e5e7eb" />
|
||||
<PolarAngleAxis dataKey="aspect" stroke="#6b7280" />
|
||||
<PolarRadiusAxis stroke="#6b7280" />
|
||||
<Radar name="行为指数" dataKey="value" stroke="#8b5cf6" fill="#8b5cf6" fillOpacity={0.5} />
|
||||
<Tooltip />
|
||||
</RadarChart>
|
||||
</ResponsiveContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 用户群体细分 */}
|
||||
<Card className="mb-6">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<Users className="w-5 h-5" />
|
||||
用户群体细分
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
{segments.map((segment, index) => (
|
||||
<div key={index} className={`p-6 bg-gradient-to-br from-${segment.color}-50 to-${segment.color}-100 rounded-lg border border-${segment.color}-200`}>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-xl font-bold text-gray-900">{segment.name}</h3>
|
||||
<Badge variant="outline" className={`border-${segment.color}-500 text-${segment.color}-600 bg-${segment.color}-50`}>
|
||||
{segment.count.toLocaleString()} 人
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="space-y-2 mb-4">
|
||||
{segment.characteristics.map((char, i) => (
|
||||
<Badge key={i} variant="outline" className="mr-2 border-gray-300 text-gray-700">
|
||||
{char}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">
|
||||
人均价值: <span className="text-lg font-semibold text-gray-900">¥{segment.value}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 兴趣标签热度 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-gray-900 flex items-center gap-2">
|
||||
<Tag className="w-5 h-5" />
|
||||
兴趣标签热度
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-3">
|
||||
{interestTags.map((item, index) => (
|
||||
<div key={index} className="flex items-center gap-4">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-gray-700 font-medium">{item.tag}</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-sm text-gray-600">{item.count.toLocaleString()} 人</span>
|
||||
<span className="text-sm font-semibold text-blue-600">热度 {item.heat}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-2 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-gradient-to-r from-blue-500 to-purple-500 rounded-full"
|
||||
style={{ width: `${item.heat}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
399
app/platform/dashboard/page.tsx
Normal file
399
app/platform/dashboard/page.tsx
Normal file
@@ -0,0 +1,399 @@
|
||||
"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>
|
||||
)
|
||||
}
|
||||
348
app/platform/data-management/page.tsx
Normal file
348
app/platform/data-management/page.tsx
Normal file
@@ -0,0 +1,348 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { Database, RefreshCw, CheckCircle2, AlertTriangle, Search, FileText, Upload, Download, Filter, TrendingUp, Zap, Tag } from 'lucide-react'
|
||||
import { Progress } from "@/components/ui/progress"
|
||||
|
||||
export default function DataManagement() {
|
||||
const [searchQuery, setSearchQuery] = useState("")
|
||||
|
||||
// 数据源管理
|
||||
const dataSources = [
|
||||
{
|
||||
id: 1,
|
||||
name: "私域系统数据源",
|
||||
type: "微信生态",
|
||||
status: "active",
|
||||
lastSync: "2分钟前",
|
||||
users: 2850000000,
|
||||
syncRate: 98.5,
|
||||
dataSize: "850TB",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "电商平台数据",
|
||||
type: "淘宝/京东",
|
||||
status: "active",
|
||||
lastSync: "5分钟前",
|
||||
users: 680000000,
|
||||
syncRate: 95.2,
|
||||
dataSize: "210TB",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "表单收集数据",
|
||||
type: "第三方表单",
|
||||
status: "active",
|
||||
lastSync: "10分钟前",
|
||||
users: 425000000,
|
||||
syncRate: 92.8,
|
||||
dataSize: "125TB",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "碰撞补全数据",
|
||||
type: "数据碰撞",
|
||||
status: "syncing",
|
||||
lastSync: "正在同步",
|
||||
users: 280000000,
|
||||
syncRate: 76.3,
|
||||
dataSize: "95TB",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "项目API数据源",
|
||||
type: "外部API",
|
||||
status: "active",
|
||||
lastSync: "1分钟前",
|
||||
users: 50670000,
|
||||
syncRate: 99.1,
|
||||
dataSize: "18TB",
|
||||
},
|
||||
]
|
||||
|
||||
// 数据清洗进度
|
||||
const cleaningTasks = [
|
||||
{ name: "手机号格式校验", total: 4285670000, processed: 4200000000, progress: 98.0, errors: 1250000 },
|
||||
{ name: "重复数据去除", total: 4285670000, processed: 3850000000, progress: 89.8, errors: 85000000 },
|
||||
{ name: "缺失字段补全", total: 4285670000, processed: 3250000000, progress: 75.8, errors: 125000000 },
|
||||
{ name: "异常值检测", total: 4285670000, processed: 4100000000, progress: 95.7, errors: 8500000 },
|
||||
]
|
||||
|
||||
// 标签系统统计
|
||||
const tagStats = {
|
||||
totalTags: 1258,
|
||||
systemTags: 485,
|
||||
customTags: 773,
|
||||
activeRules: 2850,
|
||||
todayTagged: 2845000,
|
||||
}
|
||||
|
||||
// 数据质量检测
|
||||
const qualityChecks = [
|
||||
{ type: "重复数据", count: 85420000, percentage: 2.0, severity: "warning" },
|
||||
{ type: "异常数据", count: 12850000, percentage: 0.3, severity: "error" },
|
||||
{ type: "缺失字段", count: 325680000, percentage: 7.6, severity: "warning" },
|
||||
{ type: "格式错误", count: 5280000, percentage: 0.12, severity: "error" },
|
||||
]
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black text-white p-6">
|
||||
{/* Header */}
|
||||
<div className="mb-8 flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-2">数据管理</h1>
|
||||
<p className="text-gray-400">全平台数据源管理、清洗与质量监控</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="outline" className="bg-white/5 border-white/10 hover:bg-white/10">
|
||||
<Upload className="w-4 h-4 mr-2" />
|
||||
上传数据
|
||||
</Button>
|
||||
<Button variant="outline" className="bg-white/5 border-white/10 hover:bg-white/10">
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
导出报告
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="sources" className="space-y-6">
|
||||
<TabsList className="bg-white/5 border border-white/10">
|
||||
<TabsTrigger value="sources">数据源管理</TabsTrigger>
|
||||
<TabsTrigger value="cleaning">数据清洗</TabsTrigger>
|
||||
<TabsTrigger value="tags">标签系统</TabsTrigger>
|
||||
<TabsTrigger value="quality">质量检测</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
{/* 数据源管理 */}
|
||||
<TabsContent value="sources" className="space-y-6">
|
||||
{/* 搜索栏 */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="relative flex-1">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" />
|
||||
<Input
|
||||
placeholder="搜索数据源..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-10 bg-white/5 border-white/10"
|
||||
/>
|
||||
</div>
|
||||
<Button variant="outline" className="bg-white/5 border-white/10 hover:bg-white/10">
|
||||
<Filter className="w-4 h-4 mr-2" />
|
||||
筛选
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 数据源列表 */}
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{dataSources.map((source) => (
|
||||
<Card key={source.id} className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 rounded-lg bg-gradient-to-br from-blue-500 to-purple-500 flex items-center justify-center">
|
||||
<Database className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white">{source.name}</h3>
|
||||
<p className="text-sm text-gray-400">{source.type}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={
|
||||
source.status === "active"
|
||||
? "border-green-500/50 text-green-400"
|
||||
: "border-yellow-500/50 text-yellow-400"
|
||||
}
|
||||
>
|
||||
{source.status === "active" ? (
|
||||
<>
|
||||
<CheckCircle2 className="w-3 h-3 mr-1" />
|
||||
运行中
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<RefreshCw className="w-3 h-3 mr-1 animate-spin" />
|
||||
同步中
|
||||
</>
|
||||
)}
|
||||
</Badge>
|
||||
<Button size="sm" variant="outline" className="bg-white/5 border-white/10 hover:bg-white/10">
|
||||
<RefreshCw className="w-3 h-3 mr-1" />
|
||||
同步
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-4 mb-3">
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">用户数量</div>
|
||||
<div className="text-xl font-bold text-white">{formatNumber(source.users)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">同步率</div>
|
||||
<div className="text-xl font-bold text-green-400">{source.syncRate}%</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">数据量</div>
|
||||
<div className="text-xl font-bold text-blue-400">{source.dataSize}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">最后同步</div>
|
||||
<div className="text-sm font-semibold text-white">{source.lastSync}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Progress value={source.syncRate} className="h-2" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
{/* 数据清洗 */}
|
||||
<TabsContent value="cleaning" className="space-y-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{cleaningTasks.map((task, index) => (
|
||||
<Card key={index} className="bg-white/5 border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white flex items-center gap-2">
|
||||
<Zap className="w-5 h-5 text-yellow-400" />
|
||||
{task.name}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-400">进度</span>
|
||||
<span className="text-2xl font-bold text-green-400">{task.progress}%</span>
|
||||
</div>
|
||||
<Progress value={task.progress} className="h-2" />
|
||||
<div className="grid grid-cols-2 gap-4 pt-4 border-t border-white/10">
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">已处理</div>
|
||||
<div className="text-lg font-semibold text-white">{formatNumber(task.processed)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">异常数据</div>
|
||||
<div className="text-lg font-semibold text-red-400">{formatNumber(task.errors)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
{/* 标签系统 */}
|
||||
<TabsContent value="tags" className="space-y-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-5 gap-6 mb-6">
|
||||
<Card className="bg-gradient-to-br from-purple-500/20 to-purple-900/20 border-purple-500/30">
|
||||
<CardContent className="p-6 text-center">
|
||||
<Tag className="w-8 h-8 text-purple-400 mx-auto mb-2" />
|
||||
<div className="text-3xl font-bold text-purple-400 mb-1">{tagStats.totalTags}</div>
|
||||
<div className="text-sm text-gray-400">标签总数</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6 text-center">
|
||||
<FileText className="w-8 h-8 text-blue-400 mx-auto mb-2" />
|
||||
<div className="text-3xl font-bold text-blue-400 mb-1">{tagStats.systemTags}</div>
|
||||
<div className="text-sm text-gray-400">系统标签</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6 text-center">
|
||||
<Tag className="w-8 h-8 text-green-400 mx-auto mb-2" />
|
||||
<div className="text-3xl font-bold text-green-400 mb-1">{tagStats.customTags}</div>
|
||||
<div className="text-sm text-gray-400">自定义标签</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6 text-center">
|
||||
<Zap className="w-8 h-8 text-yellow-400 mx-auto mb-2" />
|
||||
<div className="text-3xl font-bold text-yellow-400 mb-1">{tagStats.activeRules}</div>
|
||||
<div className="text-sm text-gray-400">活跃规则</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6 text-center">
|
||||
<TrendingUp className="w-8 h-8 text-orange-400 mx-auto mb-2" />
|
||||
<div className="text-3xl font-bold text-orange-400 mb-1">{formatNumber(tagStats.todayTagged)}</div>
|
||||
<div className="text-sm text-gray-400">今日打标</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Card className="bg-white/5 border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">标签管理</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-gray-400 text-center py-8">
|
||||
标签详细管理界面开发中...
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
{/* 质量检测 */}
|
||||
<TabsContent value="quality" className="space-y-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{qualityChecks.map((check, index) => (
|
||||
<Card key={index} className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-3">
|
||||
{check.severity === "error" ? (
|
||||
<AlertTriangle className="w-6 h-6 text-red-400" />
|
||||
) : (
|
||||
<AlertTriangle className="w-6 h-6 text-yellow-400" />
|
||||
)}
|
||||
<h3 className="text-lg font-semibold text-white">{check.type}</h3>
|
||||
</div>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={
|
||||
check.severity === "error"
|
||||
? "border-red-500/50 text-red-400"
|
||||
: "border-yellow-500/50 text-yellow-400"
|
||||
}
|
||||
>
|
||||
{check.severity === "error" ? "严重" : "警告"}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-400">问题数量</span>
|
||||
<span className="text-2xl font-bold text-white">{formatNumber(check.count)}</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-400">占比</span>
|
||||
<span className="text-lg font-semibold text-white">{check.percentage}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
277
app/platform/user-portrait/page.tsx
Normal file
277
app/platform/user-portrait/page.tsx
Normal file
@@ -0,0 +1,277 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { Users, Search, Tag, TrendingUp, Filter, UserCircle, Mail, Phone, MapPin, Calendar, Activity, Target } from 'lucide-react'
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
|
||||
|
||||
export default function UserPortrait() {
|
||||
const [searchQuery, setSearchQuery] = useState("")
|
||||
|
||||
// 用户群体分布
|
||||
const userSegments = [
|
||||
{ name: "高价值用户", count: 128456700, percentage: 3.0, avgValue: 580, color: "purple" },
|
||||
{ name: "活跃用户", count: 1285670000, percentage: 30.0, avgValue: 280, color: "blue" },
|
||||
{ name: "沉默用户", count: 1714283500, percentage: 40.0, avgValue: 85, color: "yellow" },
|
||||
{ name: "流失预警", count: 857134000, percentage: 20.0, avgValue: 45, color: "orange" },
|
||||
{ name: "新增用户", count: 300125800, percentage: 7.0, avgValue: 120, color: "green" },
|
||||
]
|
||||
|
||||
// 标签分类统计
|
||||
const tagCategories = [
|
||||
{ name: "基础属性", count: 485, usage: 4285670000, coverage: 100 },
|
||||
{ name: "行为标签", count: 328, usage: 3256780000, coverage: 76 },
|
||||
{ name: "兴趣偏好", count: 256, usage: 2570000000, coverage: 60 },
|
||||
{ name: "消费能力", count: 89, usage: 1714283500, coverage: 40 },
|
||||
{ name: "自定义标签", count: 100, usage: 857134000, coverage: 20 },
|
||||
]
|
||||
|
||||
// 最近用户示例
|
||||
const recentUsers = [
|
||||
{
|
||||
id: "U001285",
|
||||
name: "张**",
|
||||
phone: "138****5678",
|
||||
level: "S",
|
||||
tags: ["高净值", "美妆爱好者", "VIP客户"],
|
||||
value: 5800,
|
||||
lastActive: "2小时前",
|
||||
},
|
||||
{
|
||||
id: "U002456",
|
||||
name: "李**",
|
||||
phone: "186****1234",
|
||||
level: "A",
|
||||
tags: ["活跃用户", "教育培训", "复购客户"],
|
||||
value: 3200,
|
||||
lastActive: "5小时前",
|
||||
},
|
||||
{
|
||||
id: "U003789",
|
||||
name: "王**",
|
||||
phone: "159****9876",
|
||||
level: "B",
|
||||
tags: ["潜力用户", "电商购物", "新客户"],
|
||||
value: 1800,
|
||||
lastActive: "1天前",
|
||||
},
|
||||
{
|
||||
id: "U004123",
|
||||
name: "赵**",
|
||||
phone: "177****5432",
|
||||
level: "C",
|
||||
tags: ["普通用户", "低频互动"],
|
||||
value: 850,
|
||||
lastActive: "3天前",
|
||||
},
|
||||
]
|
||||
|
||||
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 getLevelColor = (level: string) => {
|
||||
const colors = {
|
||||
S: "border-purple-500/50 text-purple-400 bg-purple-500/10",
|
||||
A: "border-blue-500/50 text-blue-400 bg-blue-500/10",
|
||||
B: "border-green-500/50 text-green-400 bg-green-500/10",
|
||||
C: "border-yellow-500/50 text-yellow-400 bg-yellow-500/10",
|
||||
D: "border-gray-500/50 text-gray-400 bg-gray-500/10",
|
||||
}
|
||||
return colors[level as keyof typeof colors] || colors.D
|
||||
}
|
||||
|
||||
const getSegmentColor = (color: string) => {
|
||||
const colors = {
|
||||
purple: "from-purple-500/20 to-purple-900/20 border-purple-500/30",
|
||||
blue: "from-blue-500/20 to-blue-900/20 border-blue-500/30",
|
||||
green: "from-green-500/20 to-green-900/20 border-green-500/30",
|
||||
yellow: "from-yellow-500/20 to-yellow-900/20 border-yellow-500/30",
|
||||
orange: "from-orange-500/20 to-orange-900/20 border-orange-500/30",
|
||||
}
|
||||
return colors[color as keyof typeof colors]
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black text-white p-6">
|
||||
{/* Header */}
|
||||
<div className="mb-8 flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-2">用户画像</h1>
|
||||
<p className="text-gray-400">用户管理、标签体系与群体分析</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="outline" className="bg-white/5 border-white/10 hover:bg-white/10">
|
||||
<Filter className="w-4 h-4 mr-2" />
|
||||
高级筛选
|
||||
</Button>
|
||||
<Button className="bg-gradient-to-r from-blue-500 to-purple-500">
|
||||
<Target className="w-4 h-4 mr-2" />
|
||||
创建用户群
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="segments" className="space-y-6">
|
||||
<TabsList className="bg-white/5 border border-white/10">
|
||||
<TabsTrigger value="segments">用户群体</TabsTrigger>
|
||||
<TabsTrigger value="tags">标签体系</TabsTrigger>
|
||||
<TabsTrigger value="users">用户列表</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
{/* 用户群体分布 */}
|
||||
<TabsContent value="segments" className="space-y-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-5 gap-6">
|
||||
{userSegments.map((segment, index) => (
|
||||
<Card key={index} className={`bg-gradient-to-br ${getSegmentColor(segment.color)}`}>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-white text-lg">{segment.name}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2">
|
||||
<div className="text-3xl font-bold text-white">{formatNumber(segment.count)}</div>
|
||||
<div className="text-sm text-gray-300">占比 {segment.percentage}%</div>
|
||||
<div className="pt-2 border-t border-white/20">
|
||||
<div className="text-xs text-gray-300 mb-1">人均价值</div>
|
||||
<div className="text-lg font-semibold text-white">¥{segment.avgValue}</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 用户增长趋势 */}
|
||||
<Card className="bg-white/5 border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5" />
|
||||
用户增长趋势
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-64 flex items-center justify-center text-gray-400">
|
||||
用户增长趋势图表区域
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
{/* 标签体系 */}
|
||||
<TabsContent value="tags" className="space-y-6">
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{tagCategories.map((category, index) => (
|
||||
<Card key={index} className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 rounded-lg bg-gradient-to-br from-blue-500 to-purple-500 flex items-center justify-center">
|
||||
<Tag className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white">{category.name}</h3>
|
||||
<p className="text-sm text-gray-400">{category.count} 个标签</p>
|
||||
</div>
|
||||
</div>
|
||||
<Badge variant="outline" className="border-blue-500/50 text-blue-400">
|
||||
覆盖率 {category.coverage}%
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-4 text-sm">
|
||||
<div>
|
||||
<div className="text-gray-400 mb-1">标签数量</div>
|
||||
<div className="text-xl font-bold text-white">{category.count}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-gray-400 mb-1">使用用户</div>
|
||||
<div className="text-xl font-bold text-white">{formatNumber(category.usage)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-gray-400 mb-1">覆盖率</div>
|
||||
<div className="text-xl font-bold text-green-400">{category.coverage}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
{/* 用户列表 */}
|
||||
<TabsContent value="users" className="space-y-6">
|
||||
{/* 搜索栏 */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="relative flex-1">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" />
|
||||
<Input
|
||||
placeholder="搜索用户手机号、姓名、标签..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-10 bg-white/5 border-white/10"
|
||||
/>
|
||||
</div>
|
||||
<Button variant="outline" className="bg-white/5 border-white/10 hover:bg-white/10">
|
||||
<Filter className="w-4 h-4 mr-2" />
|
||||
筛选
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 用户卡片列表 */}
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{recentUsers.map((user) => (
|
||||
<Card key={user.id} className="bg-white/5 border-white/10 hover:bg-white/10 transition-colors cursor-pointer">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<Avatar className="w-12 h-12">
|
||||
<AvatarFallback className="bg-gradient-to-br from-blue-500 to-purple-500">
|
||||
{user.name[0]}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<div className="flex items-center gap-3 mb-1">
|
||||
<span className="text-lg font-semibold text-white">{user.name}</span>
|
||||
<Badge variant="outline" className={getLevelColor(user.level)}>
|
||||
{user.level}级
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex items-center gap-4 text-sm text-gray-400">
|
||||
<div className="flex items-center gap-1">
|
||||
<Phone className="w-3 h-3" />
|
||||
{user.phone}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Activity className="w-3 h-3" />
|
||||
{user.lastActive}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-sm text-gray-400 mb-1">用户价值</div>
|
||||
<div className="text-2xl font-bold text-green-400">¥{user.value}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex items-center gap-2">
|
||||
{user.tags.map((tag, index) => (
|
||||
<Badge key={index} variant="outline" className="border-blue-500/30 text-blue-400">
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
322
app/platform/value-assessment/page.tsx
Normal file
322
app/platform/value-assessment/page.tsx
Normal file
@@ -0,0 +1,322 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { DollarSign, TrendingUp, BarChart3, Calculator, Target, Users, ArrowUpRight, ArrowDownRight } from 'lucide-react'
|
||||
import { Progress } from "@/components/ui/progress"
|
||||
|
||||
export default function ValueAssessment() {
|
||||
// 价值评估模型数据
|
||||
const valueModels = [
|
||||
{
|
||||
name: "RFM价值模型",
|
||||
description: "基于最近购买、购买频率、购买金额",
|
||||
totalValue: 8560000000,
|
||||
avgValue: 199.8,
|
||||
coverage: 92.5,
|
||||
status: "active",
|
||||
},
|
||||
{
|
||||
name: "用户生命周期价值",
|
||||
description: "预测用户终身价值(LTV)",
|
||||
totalValue: 12580000000,
|
||||
avgValue: 293.5,
|
||||
coverage: 78.3,
|
||||
status: "active",
|
||||
},
|
||||
{
|
||||
name: "行为价值模型",
|
||||
description: "基于用户行为数据评估",
|
||||
totalValue: 6780000000,
|
||||
avgValue: 158.2,
|
||||
coverage: 85.7,
|
||||
status: "training",
|
||||
},
|
||||
]
|
||||
|
||||
// 项目价值分布
|
||||
const projectValues = [
|
||||
{ name: "美妆行业项目A", users: 45600000, value: 2856000000, growth: 15.8, level: "A" },
|
||||
{ name: "教育培训项目B", users: 32800000, value: 1968000000, growth: 12.3, level: "A" },
|
||||
{ name: "电商零售项目C", users: 58900000, value: 3534000000, growth: 18.5, level: "S" },
|
||||
{ name: "金融服务项目D", users: 28500000, value: 1995000000, growth: 8.7, level: "B" },
|
||||
{ name: "本地生活项目E", users: 19200000, value: 1152000000, growth: 6.5, level: "B" },
|
||||
]
|
||||
|
||||
// 微信号价值排名
|
||||
const wechatRanking = [
|
||||
{ name: "微信号001", users: 2856000, value: 168560000, avgValue: 59.0, rank: 1 },
|
||||
{ name: "微信号002", users: 2345000, value: 145780000, avgValue: 62.2, rank: 2 },
|
||||
{ name: "微信号003", users: 1980000, value: 128640000, avgValue: 65.0, rank: 3 },
|
||||
{ name: "微信号004", users: 1756000, value: 112340000, avgValue: 64.0, rank: 4 },
|
||||
{ name: "微信号005", users: 1520000, value: 95600000, avgValue: 62.9, rank: 5 },
|
||||
]
|
||||
|
||||
// 价值增长趋势
|
||||
const growthTrend = [
|
||||
{ month: "1月", value: 9850000000, growth: 8.5 },
|
||||
{ month: "2月", value: 10250000000, growth: 4.1 },
|
||||
{ month: "3月", value: 10850000000, growth: 5.9 },
|
||||
{ month: "4月", value: 11420000000, growth: 5.3 },
|
||||
{ month: "5月", value: 11980000000, growth: 4.9 },
|
||||
{ month: "6月", value: 12580000000, growth: 5.0 },
|
||||
]
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
const getLevelColor = (level: string) => {
|
||||
const colors = {
|
||||
S: "border-purple-500/50 text-purple-400 bg-purple-500/10",
|
||||
A: "border-blue-500/50 text-blue-400 bg-blue-500/10",
|
||||
B: "border-green-500/50 text-green-400 bg-green-500/10",
|
||||
C: "border-yellow-500/50 text-yellow-400 bg-yellow-500/10",
|
||||
D: "border-gray-500/50 text-gray-400 bg-gray-500/10",
|
||||
}
|
||||
return colors[level as keyof typeof colors] || colors.D
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black text-white p-6">
|
||||
{/* Header */}
|
||||
<div className="mb-8 flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-2">价值评估</h1>
|
||||
<p className="text-gray-400">用户价值分析、项目价值统计与预测</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="outline" className="bg-white/5 border-white/10 hover:bg-white/10">
|
||||
<Calculator className="w-4 h-4 mr-2" />
|
||||
价值计算器
|
||||
</Button>
|
||||
<Button className="bg-gradient-to-r from-blue-500 to-purple-500">
|
||||
<BarChart3 className="w-4 h-4 mr-2" />
|
||||
生成报告
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 核心价值指标 */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
|
||||
<Card className="bg-gradient-to-br from-purple-500/20 to-purple-900/20 border-purple-500/30">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-white flex items-center gap-2">
|
||||
<DollarSign className="w-5 h-5" />
|
||||
平台总价值
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-4xl font-bold text-purple-400 mb-2">¥{formatCurrency(12580000000)}</div>
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<ArrowUpRight className="w-4 h-4 text-green-400" />
|
||||
<span className="text-green-400">+5.0%</span>
|
||||
<span className="text-gray-400">本月增长</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-blue-500/20 to-blue-900/20 border-blue-500/30">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-white flex items-center gap-2">
|
||||
<Users className="w-5 h-5" />
|
||||
人均价值
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-4xl font-bold text-blue-400 mb-2">¥293.5</div>
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<ArrowUpRight className="w-4 h-4 text-green-400" />
|
||||
<span className="text-green-400">+2.8%</span>
|
||||
<span className="text-gray-400">环比提升</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-green-500/20 to-green-900/20 border-green-500/30">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-white flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5" />
|
||||
价值覆盖率
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-4xl font-bold text-green-400 mb-2">85.5%</div>
|
||||
<div className="text-sm text-gray-400">已评估用户占比</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="models" className="space-y-6">
|
||||
<TabsList className="bg-white/5 border border-white/10">
|
||||
<TabsTrigger value="models">价值模型</TabsTrigger>
|
||||
<TabsTrigger value="projects">项目价值</TabsTrigger>
|
||||
<TabsTrigger value="wechat">微信号排名</TabsTrigger>
|
||||
<TabsTrigger value="trend">增长趋势</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
{/* 价值模型 */}
|
||||
<TabsContent value="models" className="space-y-6">
|
||||
{valueModels.map((model, index) => (
|
||||
<Card key={index} className="bg-white/5 border-white/10">
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="text-white text-xl mb-1">{model.name}</CardTitle>
|
||||
<p className="text-sm text-gray-400">{model.description}</p>
|
||||
</div>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={
|
||||
model.status === "active"
|
||||
? "border-green-500/50 text-green-400"
|
||||
: "border-yellow-500/50 text-yellow-400"
|
||||
}
|
||||
>
|
||||
{model.status === "active" ? "运行中" : "训练中"}
|
||||
</Badge>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-3 gap-6 mb-4">
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">模型总价值</div>
|
||||
<div className="text-2xl font-bold text-white">¥{formatCurrency(model.totalValue)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">人均价值</div>
|
||||
<div className="text-2xl font-bold text-blue-400">¥{model.avgValue}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-gray-400 mb-1">覆盖率</div>
|
||||
<div className="text-2xl font-bold text-green-400">{model.coverage}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={model.coverage} className="h-2" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</TabsContent>
|
||||
|
||||
{/* 项目价值 */}
|
||||
<TabsContent value="projects" className="space-y-6">
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{projectValues.map((project, index) => (
|
||||
<Card key={index} className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="text-lg font-semibold text-white">{project.name}</div>
|
||||
<Badge variant="outline" className={getLevelColor(project.level)}>
|
||||
{project.level}级项目
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<ArrowUpRight className="w-4 h-4 text-green-400" />
|
||||
<span className="text-green-400 font-semibold">+{project.growth}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 gap-4 text-sm">
|
||||
<div>
|
||||
<div className="text-gray-400 mb-1">用户数</div>
|
||||
<div className="text-lg font-semibold text-white">{formatNumber(project.users)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-gray-400 mb-1">项目价值</div>
|
||||
<div className="text-lg font-semibold text-green-400">¥{formatCurrency(project.value)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-gray-400 mb-1">人均价值</div>
|
||||
<div className="text-lg font-semibold text-blue-400">
|
||||
¥{(project.value / project.users).toFixed(2)}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-gray-400 mb-1">增长率</div>
|
||||
<div className="text-lg font-semibold text-white">{project.growth}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
{/* 微信号排名 */}
|
||||
<TabsContent value="wechat" className="space-y-6">
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{wechatRanking.map((wechat, index) => (
|
||||
<Card key={index} className="bg-white/5 border-white/10">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div
|
||||
className={`w-12 h-12 rounded-full flex items-center justify-center text-2xl font-bold ${
|
||||
wechat.rank === 1
|
||||
? "bg-gradient-to-br from-yellow-400 to-orange-500"
|
||||
: wechat.rank === 2
|
||||
? "bg-gradient-to-br from-gray-300 to-gray-500"
|
||||
: wechat.rank === 3
|
||||
? "bg-gradient-to-br from-orange-400 to-orange-600"
|
||||
: "bg-white/10"
|
||||
}`}
|
||||
>
|
||||
{wechat.rank}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-lg font-semibold text-white mb-1">{wechat.name}</h3>
|
||||
<div className="text-sm text-gray-400">{formatNumber(wechat.users)} 用户</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-2xl font-bold text-green-400">¥{formatCurrency(wechat.value)}</div>
|
||||
<div className="text-sm text-gray-400">人均 ¥{wechat.avgValue}</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
{/* 增长趋势 */}
|
||||
<TabsContent value="trend" className="space-y-6">
|
||||
<Card className="bg-white/5 border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5" />
|
||||
价值增长趋势
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{growthTrend.map((item, index) => (
|
||||
<div key={index} className="flex items-center justify-between p-4 bg-white/5 rounded-lg">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="text-lg font-semibold text-white">{item.month}</div>
|
||||
<div className="text-2xl font-bold text-green-400">¥{formatCurrency(item.value)}</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<ArrowUpRight className="w-4 h-4 text-green-400" />
|
||||
<span className="text-lg font-semibold text-green-400">+{item.growth}%</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user