From 11db2fbd138545543ea637823c3d8630cf9cf00f Mon Sep 17 00:00:00 2001 From: lion <120344285@qq.com> Date: Fri, 1 May 2026 14:43:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Api/H5ContentController.php | 33 ++++-------- app/Models/Activity.php | 52 ++++++++++++------- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/app/Http/Controllers/Api/H5ContentController.php b/app/Http/Controllers/Api/H5ContentController.php index e03c392..f30071a 100644 --- a/app/Http/Controllers/Api/H5ContentController.php +++ b/app/Http/Controllers/Api/H5ContentController.php @@ -768,22 +768,13 @@ class H5ContentController extends Controller }))->values(); $items = $items->sort(function (array $x, array $y) { - $t = Carbon::now((string) config('app.timezone'))->toDateString(); $hx = (($x['list_kind'] ?? 'activity') === 'activity' && ! empty($x['is_hot'])) ? 0 : 1; $hy = (($y['list_kind'] ?? 'activity') === 'activity' && ! empty($y['is_hot'])) ? 0 : 1; if ($hx !== $hy) { return $hx <=> $hy; } - $sx = $this->scheduleRankForSort( - $x['start_at'] ? Carbon::parse($x['start_at'])->toDateString() : null, - $x['end_at'] ? Carbon::parse($x['end_at'])->toDateString() : null, - $t - ); - $sy = $this->scheduleRankForSort( - $y['start_at'] ? Carbon::parse($y['start_at'])->toDateString() : null, - $y['end_at'] ? Carbon::parse($y['end_at'])->toDateString() : null, - $t - ); + $sx = $this->scheduleRankFromComputedStatus($x['schedule_status'] ?? null); + $sy = $this->scheduleRankFromComputedStatus($y['schedule_status'] ?? null); if ($sx !== $sy) { return $sx <=> $sy; } @@ -844,21 +835,15 @@ class H5ContentController extends Controller } /** - * 0=进行中, 1=未开始, 2=已结束(与 orderByScheduleStatusPriority 同序). + * 0=进行中, 1=未开始, 2=已结束(与 Activity::scopeOrderByScheduleStatusPriority 展示口径一致). */ - private function scheduleRankForSort(?string $startD, ?string $endD, string $today): int + private function scheduleRankFromComputedStatus(?string $scheduleStatus): int { - if (! $endD && ! $startD) { - return 0; - } - if ($endD && $endD < $today) { - return 2; - } - if ($startD && $startD > $today) { - return 1; - } - - return 0; + return match ($scheduleStatus) { + 'not_started' => 1, + 'ended' => 2, + default => 0, + }; } private function heuristicTicketGrabBookable(TicketGrabEvent $e): bool diff --git a/app/Models/Activity.php b/app/Models/Activity.php index cf67ecd..f88128f 100644 --- a/app/Models/Activity.php +++ b/app/Models/Activity.php @@ -194,22 +194,45 @@ class Activity extends Model ->orderByDesc('id'); } + /** + * SQL:0=进行中 1=未开始 2=已结束,与 {@see computeScheduleStatusForDisplay} / {@see scopeWhereComputedScheduleStatus} 一致。 + * + * @return array{0: string, 1: array} + */ + public static function scheduleStatusPriorityRankSql(): array + { + $tz = (string) config('app.timezone'); + $today = Carbon::now($tz)->toDateString(); + $now = Carbon::now($tz); + $sessionDaySql = 'ad.activity_id = activities.id AND ad.session_start_at IS NOT NULL AND ad.session_end_at IS NOT NULL AND ad.booking_deadline_at IS NOT NULL'; + $online = '(activities.reservation_type IS NULL OR activities.reservation_type = \'\' OR activities.reservation_type = \''.self::RESERVATION_TYPE_ONLINE.'\')'; + + $sql = 'CASE + WHEN ('.$online.' + AND (SELECT COUNT(*) FROM activity_days ad WHERE '.$sessionDaySql.') > 0) + THEN + CASE + WHEN (SELECT MIN(ad.session_start_at) FROM activity_days ad WHERE '.$sessionDaySql.') > ? THEN 1 + WHEN (SELECT MAX(ad.session_end_at) FROM activity_days ad WHERE '.$sessionDaySql.') < ? THEN 2 + ELSE 0 + END + WHEN activities.end_at IS NOT NULL AND DATE(activities.end_at) < ? THEN 2 + WHEN activities.start_at IS NOT NULL AND DATE(activities.start_at) > ? THEN 1 + ELSE 0 + END'; + + return [$sql, [$now, $now, $today, $today]]; + } + /** * H5 活动列表:进行中 → 未开始 → 已结束;组内按开始时间、id。 */ public function scopeOrderByScheduleStatusPriority(Builder $query): Builder { - $today = Carbon::now((string) config('app.timezone'))->toDateString(); + [$rankSql, $rankBindings] = static::scheduleStatusPriorityRankSql(); return $query - ->orderByRaw( - 'CASE - WHEN end_at IS NOT NULL AND DATE(end_at) < ? THEN 2 - WHEN start_at IS NOT NULL AND DATE(start_at) > ? THEN 1 - ELSE 0 - END ASC', - [$today, $today] - ) + ->orderByRaw($rankSql.' ASC', $rankBindings) ->orderByRaw('start_at IS NULL ASC') ->orderBy('start_at', 'asc') ->orderByTicketNoteFreeBeforePaid() @@ -221,18 +244,11 @@ class Activity extends Model */ public function scopeOrderByHotThenScheduleStatusPriority(Builder $query): Builder { - $today = Carbon::now((string) config('app.timezone'))->toDateString(); + [$rankSql, $rankBindings] = static::scheduleStatusPriorityRankSql(); return $query ->orderByDesc('is_hot') - ->orderByRaw( - 'CASE - WHEN end_at IS NOT NULL AND DATE(end_at) < ? THEN 2 - WHEN start_at IS NOT NULL AND DATE(start_at) > ? THEN 1 - ELSE 0 - END ASC', - [$today, $today] - ) + ->orderByRaw($rankSql.' ASC', $rankBindings) ->orderByRaw('start_at IS NULL ASC') ->orderBy('start_at', 'asc') ->orderByTicketNoteFreeBeforePaid()