import { useState } from 'react'; import { X, MapPin, AlertTriangle, CheckCircle, Send, ArrowRight, } from 'lucide-react'; import { motion } from 'motion/react'; import { sendNotify } from './api'; import type { SchedulingSuggestion, CandidateVehicle } from './types'; import Blur from '../../components/Blur'; interface Props { suggestion: SchedulingSuggestion; onClose: () => void; onNotifySuccess: () => void; } function fmtKm(value: number): string { if (value >= 10000) return (value / 10000).toFixed(1) + '万'; return value.toLocaleString(); } export default function SuggestionDetail({ suggestion: s, onClose, onNotifySuccess }: Props) { const [sending, setSending] = useState(false); const [sentPlates, setSentPlates] = useState>(new Set()); const v = s.currentVehicle; const isRescue = s.type === 'rescue_hopeless'; const handleNotify = async (candidate: CandidateVehicle) => { if (sending || sentPlates.has(candidate.plateNumber)) return; setSending(true); try { const result = await sendNotify({ suggestionId: s.id, currentPlate: v.plateNumber, candidatePlate: candidate.plateNumber, }); if (result.success) { setSentPlates(prev => new Set(prev).add(candidate.plateNumber)); onNotifySuccess(); } else { alert(result.message || '发送失败'); } } catch { alert('网络错误,请重试'); } finally { setSending(false); } }; return (
{/* Header */}
{isRescue ? '抢救低里程车辆' : '释放已达标车辆'}
{/* Body */}
{/* Current Vehicle — compact header */}
{v.plateNumber} {v.vehicleType}
= 1 ? 'text-emerald-600' : v.completionRate >= 0.5 ? 'text-amber-600' : 'text-rose-600'}`}> {(v.completionRate * 100).toFixed(1)}%
{/* Key metrics in a single compact row */}
{v.targetName} | 本年已跑 {fmtKm(v.currentYearMileage)} km 本年考核 {fmtKm(v.yearTarget)} km {v.region}
客户 {v.customer || '-'} 日均 {Math.round(v.customerAvgDaily)} km
{/* Reason — one line */}
{s.reason}
{/* Candidates */}
推荐替换车辆 {s.candidates.length} 辆可选
{s.candidates.map(c => { const sent = sentPlates.has(c.plateNumber); return (
{/* Candidate header row */}
{c.plateNumber} {c.vehicleType} {c.targetName || '库存'}
{c.canQualifyAfterSwap ? ( 换后可达标 ) : ( 需关注 )}
{/* Metrics row — compact inline */}
当前
{fmtKm(c.totalMileage)}
考核
{c.yearTarget ? fmtKm(c.yearTarget) : '-'}
缺口
{fmtKm(c.mileageGap)}
区域
{c.region}
换后
{fmtKm(c.predictedAfterSwap)}
{/* Action */}
); })}
{/* Footer */}
); }