master
lion 6 days ago
parent 596f100821
commit 11db2fbd13

@ -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

@ -194,22 +194,45 @@ class Activity extends Model
->orderByDesc('id');
}
/**
* SQL0=进行中 1=未开始 2=已结束,与 {@see computeScheduleStatusForDisplay} / {@see scopeWhereComputedScheduleStatus} 一致。
*
* @return array{0: string, 1: array<int, Carbon|string>}
*/
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()

Loading…
Cancel
Save