88 lines
2.8 KiB
JavaScript
88 lines
2.8 KiB
JavaScript
function json(data, status = 200) {
|
|
return new Response(JSON.stringify(data), {
|
|
status,
|
|
headers: { "content-type": "application/json; charset=UTF-8" },
|
|
});
|
|
}
|
|
|
|
function ratio(correct, total) {
|
|
if (!total) return 0;
|
|
return Math.round((correct / total) * 10000) / 100;
|
|
}
|
|
|
|
export async function onRequestGet(context) {
|
|
const db = context.env.DB;
|
|
if (!db) {
|
|
return json({ success: false, error: "缺少 D1 绑定 DB" }, 500);
|
|
}
|
|
|
|
try {
|
|
const url = new URL(context.request.url);
|
|
const month = (url.searchParams.get("month") || new Date().toISOString().slice(0, 7)).trim();
|
|
|
|
const sql = `
|
|
SELECT
|
|
SUM(CASE WHEN actual_result IS NOT NULL AND ensemble_prediction IS NOT NULL THEN 1 ELSE 0 END) AS ens_total,
|
|
SUM(CASE WHEN ensemble_correct = 1 THEN 1 ELSE 0 END) AS ens_correct,
|
|
|
|
SUM(CASE WHEN actual_result IS NOT NULL AND dlinear_prediction IS NOT NULL THEN 1 ELSE 0 END) AS dl_total,
|
|
SUM(CASE WHEN dlinear_correct = 1 THEN 1 ELSE 0 END) AS dl_correct,
|
|
|
|
SUM(CASE WHEN actual_result IS NOT NULL AND nbeats_prediction IS NOT NULL THEN 1 ELSE 0 END) AS nb_total,
|
|
SUM(CASE WHEN nbeats_correct = 1 THEN 1 ELSE 0 END) AS nb_correct,
|
|
|
|
SUM(CASE WHEN actual_result IS NOT NULL AND ttm_prediction IS NOT NULL THEN 1 ELSE 0 END) AS ttm_total,
|
|
SUM(CASE WHEN ttm_correct = 1 THEN 1 ELSE 0 END) AS ttm_correct
|
|
FROM backup_hourly_model_predictions
|
|
WHERE date LIKE ?
|
|
`;
|
|
|
|
const row = await db.prepare(sql).bind(`${month}%`).first();
|
|
|
|
const ensTotal = Number(row?.ens_total || 0);
|
|
const ensCorrect = Number(row?.ens_correct || 0);
|
|
|
|
const dlTotal = Number(row?.dl_total || 0);
|
|
const dlCorrect = Number(row?.dl_correct || 0);
|
|
|
|
const nbTotal = Number(row?.nb_total || 0);
|
|
const nbCorrect = Number(row?.nb_correct || 0);
|
|
|
|
const ttmTotal = Number(row?.ttm_total || 0);
|
|
const ttmCorrect = Number(row?.ttm_correct || 0);
|
|
|
|
return json({
|
|
success: true,
|
|
month,
|
|
data: {
|
|
Ensemble: {
|
|
total: ensTotal,
|
|
correct: ensCorrect,
|
|
incorrect: Math.max(0, ensTotal - ensCorrect),
|
|
accuracy: ratio(ensCorrect, ensTotal),
|
|
},
|
|
DLinear: {
|
|
total: dlTotal,
|
|
correct: dlCorrect,
|
|
incorrect: Math.max(0, dlTotal - dlCorrect),
|
|
accuracy: ratio(dlCorrect, dlTotal),
|
|
},
|
|
"N-BEATS": {
|
|
total: nbTotal,
|
|
correct: nbCorrect,
|
|
incorrect: Math.max(0, nbTotal - nbCorrect),
|
|
accuracy: ratio(nbCorrect, nbTotal),
|
|
},
|
|
"TTM-R2": {
|
|
total: ttmTotal,
|
|
correct: ttmCorrect,
|
|
incorrect: Math.max(0, ttmTotal - ttmCorrect),
|
|
accuracy: ratio(ttmCorrect, ttmTotal),
|
|
},
|
|
},
|
|
});
|
|
} catch (error) {
|
|
return json({ success: false, error: String(error) }, 500);
|
|
}
|
|
}
|