From 6b7f0eedd93b2e55564c31e875460a8cee3f9227 Mon Sep 17 00:00:00 2001 From: kkfluous Date: Wed, 3 Jun 2026 15:40:13 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"fix(mileage):=20=E5=B7=B2=E5=88=B0?= =?UTF-8?q?=E6=9C=9F=E5=B9=B4=E5=BA=A6=E6=8C=89=E6=9C=9F=E6=9C=AB=E9=87=8C?= =?UTF-8?q?=E7=A8=8B=E7=BB=9F=E8=AE=A1"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit feb950dd599010655bc5d086ed94682d59eb09bc. --- src/server/routes/mileage/targets.ts | 140 ++------------------------- 1 file changed, 9 insertions(+), 131 deletions(-) diff --git a/src/server/routes/mileage/targets.ts b/src/server/routes/mileage/targets.ts index edcc864..4f1dbb3 100644 --- a/src/server/routes/mileage/targets.ts +++ b/src/server/routes/mileage/targets.ts @@ -135,17 +135,8 @@ app.get('/', async (c) => { } const [targetVehicleRows] = await pool.execute( - `SELECT target_id, plate_number, current_mileage, current_year_number, - DATE_FORMAT(assessment_start_date, '%Y-%m-%d') as assessment_start_date - FROM tab_mileage_assessment_vehicle - WHERE is_deleted = 0` - ) as [{ - target_id: number; - plate_number: string; - current_mileage: string | number | null; - current_year_number: number; - assessment_start_date: string; - }[], unknown]; + 'SELECT target_id, plate_number FROM tab_mileage_assessment_vehicle WHERE is_deleted = 0' + ) as [{ target_id: number; plate_number: string }[], unknown]; const targetIdPlatesMap = new Map(); for (const r of targetVehicleRows) { @@ -154,118 +145,6 @@ app.get('/', async (c) => { targetIdPlatesMap.set(r.target_id, list); } - const targetRuleMap = new Map(); - for (const t of targets) targetRuleMap.set(t.id, t); - - function formatUtcDate(date: Date): string { - return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`; - } - - function addYearsMinusOneDay(dateStr: string, years: number): string { - const date = new Date(`${dateStr}T00:00:00Z`); - date.setUTCFullYear(date.getUTCFullYear() + years); - date.setUTCDate(date.getUTCDate() - 1); - return formatUtcDate(date); - } - - function round2(value: number): number { - return Math.round(value * 100) / 100; - } - - const todayStr = new Intl.DateTimeFormat('en-CA', { timeZone: 'Asia/Shanghai' }).format(new Date()); - const endedPeriodDates: string[] = []; - for (const row of targetVehicleRows) { - const target = targetRuleMap.get(row.target_id); - const maxYear = Math.min(Number(target?.assessment_years) || 0, Number(row.current_year_number) || 0); - for (let year = 1; year <= maxYear; year++) { - const endDate = addYearsMinusOneDay(row.assessment_start_date, year); - if (endDate < todayStr) endedPeriodDates.push(endDate); - } - } - - const postPeriodDailyMap = new Map(); - const allTargetPlates = Array.from(new Set(targetVehicleRows.map(row => row.plate_number))); - const minEndedDate = endedPeriodDates.sort()[0]; - if (minEndedDate && allTargetPlates.length > 0) { - const [postPeriodDailyRows] = await mileagePool.execute( - `SELECT plate, - DATE_FORMAT(stat_date, '%Y-%m-%d') as stat_date, - MAX(GREATEST(daily_km, 0)) as daily_km - FROM v_vehicle_daily_stats - WHERE stat_date > ? AND plate IN (${allTargetPlates.map(() => '?').join(',')}) - GROUP BY plate, stat_date`, - [minEndedDate, ...allTargetPlates] - ) as [{ plate: string; stat_date: string; daily_km: string | number | null }[], unknown]; - - for (const row of postPeriodDailyRows) { - const list = postPeriodDailyMap.get(row.plate) || []; - list.push({ date: row.stat_date, km: Number(row.daily_km) || 0 }); - postPeriodDailyMap.set(row.plate, list); - } - } - - const yearlyMetricMap = new Map(); - const yearlyMetricDraftMap = new Map(); - - for (const row of targetVehicleRows) { - const target = targetRuleMap.get(row.target_id); - const annualMileage = Number(target?.annual_mileage_per_vehicle) || 0; - const maxYear = Math.min(Number(target?.assessment_years) || 0, Number(row.current_year_number) || 0); - const postDailyRows = postPeriodDailyMap.get(row.plate_number) || []; - - for (let year = 1; year <= maxYear; year++) { - const key = `${row.target_id}-${year}`; - const goal = annualMileage * year; - const endDate = addYearsMinusOneDay(row.assessment_start_date, year); - const postPeriodMileage = endDate < todayStr - ? postDailyRows.reduce((sum, item) => item.date > endDate ? sum + item.km : sum, 0) - : 0; - const mileageAtCutoff = Math.max(0, (Number(row.current_mileage) || 0) - postPeriodMileage); - const completed = Math.min(mileageAtCutoff, goal); - const draft = yearlyMetricDraftMap.get(key) || { - target: 0, - completed: 0, - remaining: 0, - vehicleCount: 0, - qualifiedCount: 0, - halfQualifiedCount: 0, - }; - - draft.target += goal; - draft.completed += completed; - draft.remaining += Math.max(goal - mileageAtCutoff, 0); - draft.vehicleCount += 1; - if (mileageAtCutoff >= goal) draft.qualifiedCount += 1; - if (mileageAtCutoff >= goal * 0.5) draft.halfQualifiedCount += 1; - yearlyMetricDraftMap.set(key, draft); - } - } - - for (const [key, draft] of yearlyMetricDraftMap) { - yearlyMetricMap.set(key, { - completed: round2(draft.completed), - remaining: round2(draft.remaining), - completionRate: round2(draft.target > 0 ? (draft.completed / draft.target) * 100 : 0), - qualifiedCount: draft.qualifiedCount, - qualifiedRate: round2(draft.vehicleCount > 0 ? (draft.qualifiedCount / draft.vehicleCount) * 100 : 0), - halfQualifiedCount: draft.halfQualifiedCount, - }); - } - const now = new Date(); const result = targets.map((t: any) => { const s = statsMap.get(t.id) || {}; @@ -288,21 +167,20 @@ app.get('/', async (c) => { const endDate = row.end_date ? new Date(row.end_date) : now; const assessmentDaysLeft = Math.max(0, Math.ceil((endDate.getTime() - now.getTime()) / 86400000)); const yearNumber = Number(row.year_number) || 0; - const cutoffMetrics = yearlyMetricMap.get(`${row.target_id}-${row.year_number}`); return { yearNumber, label: `第${yearNumber}年`, vehicleCount, target: Number(row.target_mileage) || 0, - completed: cutoffMetrics?.completed ?? (Number(row.completed_mileage) || 0), - remaining: cutoffMetrics?.remaining ?? remainingMileage, - completionRate: cutoffMetrics?.completionRate ?? ((Number(row.completion_rate) || 0) * 100), - qualifiedCount: cutoffMetrics?.qualifiedCount ?? qualifiedCount, - qualifiedRate: cutoffMetrics?.qualifiedRate ?? (vehicleCount > 0 ? (qualifiedCount / vehicleCount) * 100 : 0), - halfQualifiedCount: cutoffMetrics?.halfQualifiedCount ?? (Number(row.half_qualified_count) || 0), + completed: Number(row.completed_mileage) || 0, + remaining: remainingMileage, + completionRate: (Number(row.completion_rate) || 0) * 100, + qualifiedCount, + qualifiedRate: vehicleCount > 0 ? (qualifiedCount / vehicleCount) * 100 : 0, + halfQualifiedCount: Number(row.half_qualified_count) || 0, daysLeft: assessmentDaysLeft, - dailyTarget: assessmentDaysLeft > 0 ? Math.round(((cutoffMetrics?.remaining ?? remainingMileage) / assessmentDaysLeft) * 10) / 10 : 0, + dailyTarget: assessmentDaysLeft > 0 ? Math.round((remainingMileage / assessmentDaysLeft) * 10) / 10 : 0, startDate: row.start_date || null, endDate: row.end_date || null, periods: yearlyPeriodsMap.get(`${row.target_id}-${row.year_number}`) || [],