fix(scheduling): use current year mileage for consistent data display

- Add currentYearMileage to SchedulingVehicleInfo (backend + frontend)
- Compute completionRate as currentYearMileage/yearTarget (year-based)
  instead of using overall completion_rate from DB
- Display "本年已跑" instead of "累计" in detail modal
- Fix reason text to show year completion rate

Before: 累计 4.6万, 考核 3.0万, 完成率 12.1% (mismatched periods)
After:  本年已跑 8.3万, 考核 3.0万, 完成率 275% (consistent year-based)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-16 21:08:29 +08:00
parent 6ee811c937
commit bcbeb64e28
4 changed files with 11 additions and 5 deletions

View File

@@ -85,8 +85,8 @@ export default function SuggestionDetail({ suggestion: s, onClose, onNotifySucce
<div className="flex items-center gap-3 text-[10px] text-slate-500 flex-wrap"> <div className="flex items-center gap-3 text-[10px] text-slate-500 flex-wrap">
<span>{v.targetName}</span> <span>{v.targetName}</span>
<span className="text-slate-300">|</span> <span className="text-slate-300">|</span>
<span> <span className="text-slate-700 font-bold">{fmtKm(v.totalMileage)}</span> km</span> <span> <span className="text-slate-700 font-bold">{fmtKm(v.currentYearMileage)}</span> km</span>
<span> <span className="text-slate-700 font-bold">{fmtKm(v.yearTarget)}</span> km</span> <span> <span className="text-slate-700 font-bold">{fmtKm(v.yearTarget)}</span> km</span>
<span><MapPin size={9} className="inline -mt-px" /> {v.region}</span> <span><MapPin size={9} className="inline -mt-px" /> {v.region}</span>
</div> </div>
<div className="flex items-center gap-3 text-[10px] text-slate-500 mt-1"> <div className="flex items-center gap-3 text-[10px] text-slate-500 mt-1">

View File

@@ -4,6 +4,7 @@ export interface SchedulingVehicleInfo {
targetName: string; targetName: string;
vehicleType: string; vehicleType: string;
totalMileage: number; totalMileage: number;
currentYearMileage: number;
completionRate: number; completionRate: number;
yearTarget: number; yearTarget: number;
region: string; region: string;

View File

@@ -35,13 +35,16 @@ export function classifyVehicle(
import type { SchedulingVehicleInfo } from './types.js'; import type { SchedulingVehicleInfo } from './types.js';
export function toVehicleInfo(v: EnrichedVehicle): SchedulingVehicleInfo { export function toVehicleInfo(v: EnrichedVehicle): SchedulingVehicleInfo {
// Use current year completion rate instead of overall
const yearCompletionRate = v.yearTarget > 0 ? v.currentYearMileage / v.yearTarget : 0;
return { return {
plateNumber: v.plateNumber, plateNumber: v.plateNumber,
targetId: v.targetId, targetId: v.targetId,
targetName: v.targetName, targetName: v.targetName,
vehicleType: v.vehicleType, vehicleType: v.vehicleType,
totalMileage: v.totalMileage, totalMileage: v.totalMileage,
completionRate: v.completionRate, currentYearMileage: v.currentYearMileage,
completionRate: yearCompletionRate,
yearTarget: v.yearTarget, yearTarget: v.yearTarget,
region: v.region, region: v.region,
province: v.province, province: v.province,
@@ -152,7 +155,8 @@ export function generateSuggestions(
}) })
.slice(0, 5); .slice(0, 5);
const reason = `${vehicle.customer}日均里程 ${Math.round(vehicle.customerAvgDaily)} KM高里程该车已达标完成率 ${Math.round(vehicle.completionRate * 100)}%),建议换上里程缺口大的车辆以加速达标。`; const yearRate = vehicle.yearTarget > 0 ? Math.round((vehicle.currentYearMileage / vehicle.yearTarget) * 100) : 0;
const reason = `${vehicle.customer}日均里程 ${Math.round(vehicle.customerAvgDaily)} KM高里程该车本年完成率 ${yearRate}%,建议换上里程缺口大的车辆以加速达标。`;
suggestions.push({ suggestions.push({
id: `qualified-${vehicle.plateNumber}`, id: `qualified-${vehicle.plateNumber}`,

View File

@@ -4,7 +4,8 @@ export interface SchedulingVehicleInfo {
targetName: string; targetName: string;
vehicleType: string; vehicleType: string;
totalMileage: number; totalMileage: number;
completionRate: number; currentYearMileage: number;
completionRate: number; // 本年完成率 currentYearMileage / yearTarget
yearTarget: number; yearTarget: number;
region: string; region: string;
province: string; province: string;