get("month", ""); if (preg_match("/^(\d{4})-(0[1-9]|1[0-2])$/", $month_param, $matches)) { $month = Carbon::createFromDate((int)$matches[1], (int)$matches[2], 1)->startOfMonth(); } else { $month = Carbon::now()->startOfMonth(); } $videos = Videos::query()->orderBy("created_at")->get(["id", "bvid", "title", "total_duration"]); $by_date = VideoCalendarUtil::group_by_live_date($videos); $parsed_count = array_sum(array_map("sizeof", $by_date)); $weeks = []; $current_week = array_fill(0, 7, null); $cursor = $month->copy(); $month_end = $month->copy()->endOfMonth(); while ($cursor->lte($month_end)) { $day_index = $cursor->dayOfWeekIso - 1; // 周一为一周之始 $date_key = $cursor->format("Y-m-d"); $current_week[$day_index] = [ "day" => $cursor->day, "videos" => $by_date[$date_key] ?? [], "is_today" => $cursor->isToday(), ]; if ($day_index === 6) { $weeks[] = $current_week; $current_week = array_fill(0, 7, null); } $cursor->addDay(); } if (sizeof(array_filter($current_week)) > 0) { $weeks[] = $current_week; } $month_prefix = $month->format("Y-m"); $live_days = sizeof(array_filter(array_keys($by_date), function (string $date) use ($month_prefix) { return strpos($date, $month_prefix) === 0; })); $min_month = sizeof($by_date) > 0 ? Carbon::createFromFormat("Y-m-d", array_key_first($by_date))->startOfMonth() : $month->copy(); $max_month = sizeof($by_date) > 0 ? Carbon::createFromFormat("Y-m-d", array_key_last($by_date))->startOfMonth() : $month->copy(); $prev_month = $month->copy()->subMonth(); $next_month = $month->copy()->addMonth(); return view("calendar.index", [ "weeks" => $weeks, "month" => $month, "is_current_month" => $month->eq(Carbon::now()->startOfMonth()), "live_days" => $live_days, "unparsed_count" => sizeof($videos) - $parsed_count, "prev_month" => $prev_month, "next_month" => $next_month, "has_prev" => $prev_month->gte($min_month), "has_next" => $next_month->lte($max_month), ]); } }