Files
shensheshou/app/value-assessment/page.tsx
v0 b17b488f8e refactor: restructure navigation and module layout
Reorganize navigation and module structure based on new requirements.

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

318 lines
14 KiB
TypeScript

"use client"
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, Users, ArrowUpRight } 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: "bg-purple-100 text-purple-700 border-purple-200",
A: "bg-blue-100 text-blue-700 border-blue-200",
B: "bg-green-100 text-green-700 border-green-200",
C: "bg-yellow-100 text-yellow-700 border-yellow-200",
D: "bg-gray-100 text-gray-700 border-gray-200",
}
return colors[level as keyof typeof colors] || colors.D
}
return (
<div className="space-y-8">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-gray-900"></h1>
<p className="text-gray-500 mt-1"></p>
</div>
<div className="flex items-center gap-3">
<Button variant="outline" className="bg-white/60 backdrop-blur-md">
<Calculator className="w-4 h-4 mr-2" />
</Button>
<Button className="bg-gradient-to-r from-blue-500 to-purple-500 text-white">
<BarChart3 className="w-4 h-4 mr-2" />
</Button>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<Card className="bg-gradient-to-br from-purple-500 to-purple-600 text-white border-none shadow-md">
<CardHeader className="pb-3">
<CardTitle className="text-purple-100 flex items-center gap-2">
<DollarSign className="w-5 h-5" />
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-4xl font-bold mb-2">¥{formatCurrency(12580000000)}</div>
<div className="flex items-center gap-2 text-sm">
<ArrowUpRight className="w-4 h-4 text-green-300" />
<span className="text-green-300">+5.0%</span>
<span className="text-purple-200"></span>
</div>
</CardContent>
</Card>
<Card className="bg-white/60 backdrop-blur-md border-gray-200 shadow-sm">
<CardHeader className="pb-3">
<CardTitle className="text-gray-900 flex items-center gap-2">
<Users className="w-5 h-5 text-blue-600" />
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-4xl font-bold text-blue-600 mb-2">¥293.5</div>
<div className="flex items-center gap-2 text-sm">
<ArrowUpRight className="w-4 h-4 text-green-600" />
<span className="text-green-600">+2.8%</span>
<span className="text-gray-500"></span>
</div>
</CardContent>
</Card>
<Card className="bg-white/60 backdrop-blur-md border-gray-200 shadow-sm">
<CardHeader className="pb-3">
<CardTitle className="text-gray-900 flex items-center gap-2">
<TrendingUp className="w-5 h-5 text-green-600" />
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-4xl font-bold text-green-600 mb-2">85.5%</div>
<div className="text-sm text-gray-500"></div>
</CardContent>
</Card>
</div>
<Tabs defaultValue="models" className="space-y-6">
<TabsList className="bg-white/60 backdrop-blur-md border border-gray-200 p-1 rounded-xl">
<TabsTrigger value="models" className="rounded-lg data-[state=active]:bg-white data-[state=active]:shadow-sm">
</TabsTrigger>
<TabsTrigger
value="projects"
className="rounded-lg data-[state=active]:bg-white data-[state=active]:shadow-sm"
>
</TabsTrigger>
<TabsTrigger value="wechat" className="rounded-lg data-[state=active]:bg-white data-[state=active]:shadow-sm">
</TabsTrigger>
<TabsTrigger value="trend" className="rounded-lg data-[state=active]:bg-white data-[state=active]:shadow-sm">
</TabsTrigger>
</TabsList>
<TabsContent value="models" className="space-y-6">
{valueModels.map((model, index) => (
<Card key={index} className="bg-white/60 backdrop-blur-md border-gray-200 shadow-sm">
<CardHeader>
<div className="flex items-center justify-between">
<div>
<CardTitle className="text-gray-900 text-xl mb-1">{model.name}</CardTitle>
<p className="text-sm text-gray-500">{model.description}</p>
</div>
<Badge
variant="outline"
className={
model.status === "active"
? "bg-green-50 text-green-600 border-green-200"
: "bg-yellow-50 text-yellow-600 border-yellow-200"
}
>
{model.status === "active" ? "运行中" : "训练中"}
</Badge>
</div>
</CardHeader>
<CardContent>
<div className="grid grid-cols-3 gap-6 mb-4">
<div>
<div className="text-sm text-gray-500 mb-1"></div>
<div className="text-2xl font-bold text-gray-900">¥{formatCurrency(model.totalValue)}</div>
</div>
<div>
<div className="text-sm text-gray-500 mb-1"></div>
<div className="text-2xl font-bold text-blue-600">¥{model.avgValue}</div>
</div>
<div>
<div className="text-sm text-gray-500 mb-1"></div>
<div className="text-2xl font-bold text-green-600">{model.coverage}%</div>
</div>
</div>
<Progress value={model.coverage} className="h-2 bg-gray-100" />
</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/60 backdrop-blur-md border-gray-200 shadow-sm">
<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-bold text-gray-900">{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-600" />
<span className="text-green-600 font-semibold">+{project.growth}%</span>
</div>
</div>
<div className="grid grid-cols-4 gap-4 text-sm">
<div>
<div className="text-gray-500 mb-1"></div>
<div className="text-lg font-semibold text-gray-900">{formatNumber(project.users)}</div>
</div>
<div>
<div className="text-gray-500 mb-1"></div>
<div className="text-lg font-semibold text-green-600">¥{formatCurrency(project.value)}</div>
</div>
<div>
<div className="text-gray-500 mb-1"></div>
<div className="text-lg font-semibold text-blue-600">
¥{(project.value / project.users).toFixed(2)}
</div>
</div>
<div>
<div className="text-gray-500 mb-1"></div>
<div className="text-lg font-semibold text-gray-900">{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/60 backdrop-blur-md border-gray-200 shadow-sm">
<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 text-white ${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-gray-200 text-gray-600"}`}
>
{wechat.rank}
</div>
<div className="flex-1">
<h3 className="text-lg font-bold text-gray-900 mb-1">{wechat.name}</h3>
<div className="text-sm text-gray-500">{formatNumber(wechat.users)} </div>
</div>
<div className="text-right">
<div className="text-2xl font-bold text-green-600">¥{formatCurrency(wechat.value)}</div>
<div className="text-sm text-gray-500"> ¥{wechat.avgValue}</div>
</div>
</div>
</CardContent>
</Card>
))}
</div>
</TabsContent>
<TabsContent value="trend" className="space-y-6">
<Card className="bg-white/60 backdrop-blur-md border-gray-200 shadow-sm">
<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">
{growthTrend.map((item, index) => (
<div
key={index}
className="flex items-center justify-between p-4 bg-gray-50 rounded-lg border border-gray-100"
>
<div className="flex items-center gap-4">
<div className="text-lg font-semibold text-gray-900">{item.month}</div>
<div className="text-2xl font-bold text-green-600">¥{formatCurrency(item.value)}</div>
</div>
<div className="flex items-center gap-2">
<ArrowUpRight className="w-4 h-4 text-green-600" />
<span className="text-lg font-semibold text-green-600">+{item.growth}%</span>
</div>
</div>
))}
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
)
}