import { useId } from 'react' import { PolarAngleAxis, PolarGrid, PolarRadiusAxis, Radar, RadarChart, ResponsiveContainer, Tooltip, } from 'recharts' import { Sparkles, TrendingUp } from 'lucide-react' import type { Customer } from '@/types' import { cn } from '@/utils/cn' function qualitativeScore(value?: string, fallback = 50) { const text = String(value || '').toLowerCase() if (!text) return fallback if (/高|强|紧急|决策|老板|owner|director|high|urgent/.test(text)) return 86 if (/中|一般|参与|medium|normal/.test(text)) return 62 if (/低|弱|未知|助理|low|unknown/.test(text)) return 36 return fallback } export function profileRadarData(customer: Customer) { const profile = customer.aiProfile || {} const extracted = [ profile.companyName, profile.industry, profile.businessModel, profile.inquiryQuantity, profile.targetPrice, profile.budget, profile.purchaseTimeline, profile.payment, ].filter(Boolean).length const fitScore = Math.min(96, 42 + extracted * 6 + (profile.keyNeeds?.length || 0) * 4) return [ { dimension: '购买意向', score: Math.max(0, Math.min(100, Number(customer.intentScore || 0))), hint: '基于询盘强度与购买信号' }, { dimension: '成交可能', score: Number(profile.dealProbability || 0), hint: '根据当前客户资料和会话信号估算' }, { dimension: '决策能力', score: qualitativeScore(profile.decisionPower), hint: profile.decisionPower || '尚待确认采购决策权' }, { dimension: '需求紧迫', score: qualitativeScore(profile.urgency), hint: profile.urgency || '尚待确认采购时间表' }, { dimension: '客户匹配', score: fitScore, hint: '画像字段、需求与产品匹配度' }, { dimension: '关系健康', score: Math.max(0, 100 - Number(profile.churnProbability || 0)), hint: '流失风险的反向健康度' }, ] } export function CustomerProfileRadar({ customer, compact = false, className, }: { customer: Customer compact?: boolean className?: string }) { const data = profileRadarData(customer) const average = Math.round(data.reduce((sum, item) => sum + item.score, 0) / data.length) const chartId = useId().replace(/:/g, '') const gradientId = `radar-fill-${chartId}` const glowId = `radar-glow-${chartId}` const level = average >= 75 ? '高潜客户' : average >= 55 ? '重点培育' : '持续观察' const levelTone = average >= 75 ? 'text-blue-700 bg-blue-50 border-blue-100' : average >= 55 ? 'text-violet-700 bg-violet-50 border-violet-100' : 'text-amber-700 bg-amber-50 border-amber-100' return (

客户价值雷达

基于当前客户资料和会话信号

{level}

综合指数

{average}

[`${value} / 100`, '画像指数']} labelFormatter={(label) => `${label} · 参考值`} contentStyle={{ borderRadius: 14, border: '1px solid #dbeafe', boxShadow: '0 18px 40px rgba(37,99,235,.14)', fontSize: 12, }} />
{!compact && (
{data.map((item) => (
{item.dimension} {item.score}
))}
)}
) }