Parcourir la source

fix(report): use raw SQL and DateTime for dot chart to avoid timezone issues

Replace Carbon-based date range with raw SQL query and plain DateTime
iteration. Previous versions had Carbon mutable object issues and
timezone mismatches between query params and DATE() keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
yemeishu il y a 4 jours
Parent
commit
d643e1fdf8
1 fichiers modifiés avec 15 ajouts et 18 suppressions
  1. 15 18
      scripts/report_teacher_weekly_stats.php

+ 15 - 18
scripts/report_teacher_weekly_stats.php

@@ -503,35 +503,32 @@ $chartSvg = $buildDualChartsHtml($curDaily, $prevDaily);
 // ============================================================
 // 1 月 6 日起每日学案量点状图
 // ============================================================
-$cumulativeStart = \Carbon\Carbon::create(2026, 1, 6, 0, 0, 0, $tz);
 $cumulativeEnd = $endCurrent->copy();
 
-// 查询原始行:不按时区分组,直接按 DB 中的 DATE 分
-$dailyRows = $db::table('papers')
-    ->whereNotNull('teacher_id')
-    ->where('teacher_id', '!=', '')
-    ->where('created_at', '>=', $cumulativeStart->setTimezone('UTC')->format('Y-m-d H:i:s'))
-    ->where('created_at', '<', $cumulativeEnd->copy()->setTimezone('UTC')->format('Y-m-d H:i:s'))
-    ->selectRaw('DATE(created_at) AS d, COUNT(*) AS c')
-    ->groupByRaw('DATE(created_at)')
-    ->orderBy('d')
-    ->get();
+$dailyRows = $db::select(
+    "SELECT DATE(created_at) AS d, COUNT(*) AS c FROM papers WHERE teacher_id IS NOT NULL AND teacher_id != '' AND created_at >= '2026-01-06 00:00:00' AND created_at < ? GROUP BY DATE(created_at) ORDER BY d",
+    [$cumulativeEnd->format('Y-m-d H:i:s')]
+);
 
 $dailyMap = [];
+$firstDate = '2026-01-06';
+$lastDate = $cumulativeEnd->format('Y-m-d');
 foreach ($dailyRows as $row) {
     $dailyMap[$row->d] = (int) $row->c;
+    if ($row->d < $firstDate) { $firstDate = $row->d; }
+    if ($row->d > $lastDate) { $lastDate = $row->d; }
 }
 
-// CarbonPeriod 也用 UTC 日期做 key,确保两边对齐
-$periodStart = \Carbon\Carbon::create(2026, 1, 6, 0, 0, 0, 'UTC');
-$periodEnd = $cumulativeEnd->copy()->setTimezone('UTC');
-$period = \Carbon\CarbonPeriod::create($periodStart->toDateString(), $periodEnd->subDay()->toDateString());
+// 直接按日期字符串迭代,避免 Carbon 时区问题
 $dotLabels = [];
 $dotValues = [];
-foreach ($period as $day) {
-    $key = $day->format('Y-m-d');
-    $dotLabels[] = $day->format('m/d');
+$iterDate = new \DateTime($firstDate);
+$endDate = new \DateTime($lastDate);
+while ($iterDate <= $endDate) {
+    $key = $iterDate->format('Y-m-d');
+    $dotLabels[] = $iterDate->format('m/d');
     $dotValues[] = $dailyMap[$key] ?? 0;
+    $iterDate->modify('+1 day');
 }
 $totalDays = count($dotValues);
 $cumulativeTotal = array_sum($dotValues);