diff --git a/src/modules/scheduling/SchedulingModule.tsx b/src/modules/scheduling/SchedulingModule.tsx index d99720a..0ac4516 100644 --- a/src/modules/scheduling/SchedulingModule.tsx +++ b/src/modules/scheduling/SchedulingModule.tsx @@ -81,51 +81,21 @@ export default function SchedulingModule() { <> {/* Summary Cards */}
- {/* Card 1: 已达标车辆 */} -
-
- - 已达标车辆 -
-
{data.summary.qualifiedCount}
-
达标概率 ≥ 120%
+
+
已达标
+
{data.summary.qualifiedCount}
- - {/* Card 2: 无望达标 */} -
-
- - 无望达标 -
-
{data.summary.hopelessCount}
-
达标概率 < 60%
+
+
无望达标
+
{data.summary.hopelessCount}
- - {/* Card 3: 可干预 */} -
-
- - 可干预 -
-
{data.summary.suggestionCount}
-
- 预计可新增达标 +{data.summary.estimatedGain} 台 -
+
+
可干预
+
{data.summary.suggestionCount}
+
+{data.summary.estimatedGain} 台可达标
- {/* Refresh Button */} -
- -
- {/* Suggestion List */} = 1 - ? 'text-emerald-600' - : v.completionRate >= 0.6 - ? 'text-amber-600' - : 'text-rose-600'; - const handleNotify = async (candidate: CandidateVehicle) => { if (sending || sentPlates.has(candidate.plateNumber)) return; setSending(true); @@ -59,7 +40,7 @@ export default function SuggestionDetail({ suggestion: s, onClose, onNotifySucce } else { alert(result.message || '发送失败'); } - } catch (e) { + } catch { alert('网络错误,请重试'); } finally { setSending(false); @@ -67,169 +48,126 @@ export default function SuggestionDetail({ suggestion: s, onClose, onNotifySucce }; return ( -
+
{/* Header */} -
- {title} -
- {/* Scrollable body */} -
- {/* Current Vehicle Card */} -
-
+ {/* Body */} +
+ + {/* Current Vehicle — compact header */} +
+
- - {v.plateNumber} - - - {v.vehicleType} - + {v.plateNumber} + {v.vehicleType}
- + = 1 ? 'text-emerald-600' : v.completionRate >= 0.5 ? 'text-amber-600' : 'text-rose-600'}`}> {(v.completionRate * 100).toFixed(1)}% -
完成率
-
{v.targetName}
- -
-
-
累计里程
-
{fmtKm(v.totalMileage)} km
-
-
-
本年考核
-
{fmtKm(v.yearTarget)} km
-
-
-
- 区域 -
-
{v.region}
-
-
-
客户日均
-
{fmtKm(v.customerAvgDaily)} km
-
+ {/* Key metrics in a single compact row */} +
+ {v.targetName} + | + 累计 {fmtKm(v.totalMileage)} km + 考核 {fmtKm(v.yearTarget)} km + {v.region} +
+
+ 客户 {v.customer || '-'} + 日均 {Math.round(v.customerAvgDaily)} km
- - {v.customer && ( -
- 客户:{v.customer} -
- )}
- {/* Reason Card */} -
- 建议原因 - {s.reason} + {/* Reason — one line */} +
+ {s.reason}
- {/* Candidates Section */} -
-
- - 推荐替换车辆 + {/* Candidates */} +
+
+ 推荐替换车辆 + {s.candidates.length} 辆可选
-
基于车型、区域及里程匹配
-
+
{s.candidates.map(c => { - const alreadySent = sentPlates.has(c.plateNumber); - const predColor = - c.canQualifyAfterSwap ? 'text-emerald-600' : 'text-amber-600'; - + const sent = sentPlates.has(c.plateNumber); return ( -
-
+
+ {/* Candidate header row */} +
- - {c.plateNumber} - - - {c.vehicleType} - - {c.targetName ? ( - {c.targetName} - ) : ( - 库存 - )} + {c.plateNumber} + {c.vehicleType} + {c.targetName || '库存'}
{c.canQualifyAfterSwap ? ( - - 换后可达标 + + 换后可达标 ) : ( - - 需关注 + + 需关注 )}
-
-
-
当前里程
-
{fmtKm(c.totalMileage)} km
+ {/* Metrics row — compact inline */} +
+
+
当前
+
{fmtKm(c.totalMileage)}
-
-
本年考核
-
{c.yearTarget ? fmtKm(c.yearTarget) + ' km' : '-'}
+
+
考核
+
{c.yearTarget ? fmtKm(c.yearTarget) : '-'}
-
-
里程缺口
-
{fmtKm(c.mileageGap)} km
+
+
缺口
+
{fmtKm(c.mileageGap)}
-
-
- 区域 -
-
{c.region}
+
+
区域
+
{c.region}
-
-
换后预测
-
{fmtKm(c.predictedAfterSwap)} km
+
+
换后
+
{fmtKm(c.predictedAfterSwap)}
- + {/* Action */} +
+ +
); })} @@ -238,10 +176,10 @@ export default function SuggestionDetail({ suggestion: s, onClose, onNotifySucce
{/* Footer */} -
+
diff --git a/src/modules/scheduling/SuggestionList.tsx b/src/modules/scheduling/SuggestionList.tsx index b9e1dfc..8fb72b7 100644 --- a/src/modules/scheduling/SuggestionList.tsx +++ b/src/modules/scheduling/SuggestionList.tsx @@ -1,4 +1,4 @@ -import { ArrowRightLeft, AlertTriangle, CheckCircle } from 'lucide-react'; +import { ArrowRightLeft, ChevronRight } from 'lucide-react'; import { motion } from 'motion/react'; import type { SchedulingSuggestion } from './types'; import Blur from '../../components/Blur'; @@ -13,112 +13,74 @@ function fmtKm(value: number): string { return value.toLocaleString(); } +function fmtRate(rate: number): string { + return (rate * 100).toFixed(1) + '%'; +} + export default function SuggestionList({ suggestions, onSelect }: Props) { if (suggestions.length === 0) { return ( -
-
- -

暂无调度建议

-

所有车辆当前无需干预

-
+
+ +

暂无调度建议

); } return (
- {/* Header */} -
-
- 智能调度干预清单 - +
+
+ 调度干预清单 + {suggestions.length}
- {/* Rows */}
{suggestions.map((s, idx) => { - const isHigh = s.priority === 'high' || s.type === 'rescue_hopeless'; + const isRescue = s.type === 'rescue_hopeless'; + const v = s.currentVehicle; return ( onSelect(s)} > -
- {/* Priority icon */} -
- {isHigh ? ( - - ) : ( - - )} + {/* Left: color bar */} +
+ + {/* Center: info */} +
+
+ + {v.plateNumber} + + + {isRescue ? '无望' : '达标'} + + {v.vehicleType} + · + {v.region}
- - {/* Content */} -
- {/* Top row: plate + badges */} -
- - - {s.currentVehicle.plateNumber} - - - - {/* Type badge */} - - {s.type === 'rescue_hopeless' ? '无望达标' : '已达标'} - - - {/* Vehicle type badge */} - - {s.currentVehicle.vehicleType} - - - {/* Region badge */} - - {s.currentVehicle.region} - -
- - {/* Info line */} -
- - 客户:{' '} - - {s.currentVehicle.customer ?? '—'} - - - - 日均: {fmtKm(s.currentVehicle.customerAvgDaily)} KM - - - 完成率: {s.currentVehicle.completionRate}% - -
+
+ {v.customer || '-'} + 日均 {Math.round(v.customerAvgDaily)} km + 完成 = 1 ? 'text-emerald-600' : v.completionRate >= 0.5 ? 'text-amber-600' : 'text-rose-500'}`}>{fmtRate(v.completionRate)}
+
- {/* Right: candidate count */} -
- {s.candidates.length} - -
+ {/* Right: candidate count + arrow */} +
+ {s.candidates.length} + +
);