import { useState } from 'react'; import { ArrowDownUp, CheckCircle, Send, X, Ban } from 'lucide-react'; import { sendNotify, updateNotification } from './api'; import type { SchedulingSuggestion, CandidateVehicle } from './types'; import Blur from '../../components/Blur'; interface Props { suggestion: SchedulingSuggestion; candidate: CandidateVehicle; onClose: () => void; onSuccess: () => void; } function fmtKm(value: number): string { if (value >= 10000) return (value / 10000).toFixed(1) + '万'; return Math.round(value).toLocaleString(); } function fmtRate(rate: number): string { return (rate * 100).toFixed(1) + '%'; } export default function SwapPreview({ suggestion: s, candidate: c, onClose, onSuccess }: Props) { const [sending, setSending] = useState(false); const [sent, setSent] = useState(false); const [cancelling, setCancelling] = useState(false); const v = s.currentVehicle; const alreadyIntervened = !sent && (c.notificationStatus === 'sent' || c.notificationStatus === 'executed'); const isExecuted = c.notificationStatus === 'executed'; const handleSend = async () => { if (sending || sent || alreadyIntervened) return; setSending(true); try { const result = await sendNotify({ suggestionId: s.id, currentPlate: v.plateNumber, candidatePlate: c.plateNumber }); if (result.success) { setSent(true); onSuccess(); } else { alert(result.message || '发送失败'); } } catch { alert('网络错误'); } finally { setSending(false); } }; const handleCancel = async () => { if (!c.notificationId || cancelling) return; if (isExecuted) { if (!confirm('此干预已标记为执行。确定要取消吗?')) return; } else { if (!confirm(`确定取消 ${v.plateNumber} → ${c.plateNumber} 的干预?`)) return; } setCancelling(true); try { const result = await updateNotification(c.notificationId, { status: 'cancelled' }); if (result.success) { onSuccess(); onClose(); } else { alert(result.message || '取消失败'); } } catch { alert('网络错误'); } finally { setCancelling(false); } }; return (
{/* Header */}
车辆替换方案
{/* Content */}
{/* === Swap Cards === */}
{/* Current vehicle */}
{v.plateNumber}
{v.vehicleType} · {v.targetName}
{fmtKm(v.currentYearMileage)}km
考核 {fmtKm(v.yearTarget)} km
年度考核剩余 {v.daysLeft}
{v.customer || '-'} 日均 {Math.round(v.customerAvgDaily)} 完成 = 1 ? 'text-emerald-600' : 'text-rose-500'}>{fmtRate(v.completionRate)}
{/* Arrow bridge */}
{/* Replacement vehicle */}
{c.plateNumber}
{c.vehicleType} · {c.targetName || '库存'} · {c.region}
{fmtKm(c.totalMileage)}km
考核 {c.yearTarget ? fmtKm(c.yearTarget) : '-'} km
缺口 {fmtKm(c.mileageGap)}
{/* === Result === */}
替换后预测
预测年终里程
{fmtKm(c.predictedAfterSwap)} km
考核目标
{c.yearTarget ? fmtKm(c.yearTarget) : '-'} km
{c.canQualifyAfterSwap ? '可达标' : '需关注'}
{/* Bottom */}
{alreadyIntervened && (
此车已{isExecuted ? '执行干预' : '登记干预'},如需重新干预请先取消。
)} {alreadyIntervened ? ( ) : ( )}
); }