You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.4 KiB
129 lines
4.4 KiB
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Activity;
|
|
use App\Models\ActivitySession;
|
|
use App\Support\ApiResponse;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class ActivitySessionController extends Controller
|
|
{
|
|
use ApiResponse;
|
|
|
|
public function index(int $activity): JsonResponse
|
|
{
|
|
Activity::query()->findOrFail($activity);
|
|
$items = ActivitySession::query()
|
|
->where('activity_id', $activity)
|
|
->orderBy('sort')
|
|
->orderBy('id')
|
|
->get()
|
|
->map(fn (ActivitySession $s) => $this->serialize($s));
|
|
|
|
return $this->ok(['items' => $items]);
|
|
}
|
|
|
|
public function store(Request $request, int $activity): JsonResponse
|
|
{
|
|
$activityModel = Activity::query()->findOrFail($activity);
|
|
$data = $request->validate([
|
|
'title' => ['nullable', 'string', 'max:255'],
|
|
'starts_at' => ['nullable', 'date'],
|
|
'ends_at' => ['nullable', 'date', 'after_or_equal:starts_at'],
|
|
'venue' => ['nullable', 'string', 'max:255'],
|
|
'capacity' => ['nullable', 'integer', 'min:0'],
|
|
'sort' => ['nullable', 'integer'],
|
|
]);
|
|
$this->assertSessionWithinActivity($activityModel, $data);
|
|
|
|
$session = ActivitySession::query()->create([
|
|
'activity_id' => $activity,
|
|
...$data,
|
|
]);
|
|
|
|
return $this->ok(['id' => $session->id], '已创建');
|
|
}
|
|
|
|
public function update(Request $request, int $activity, int $session): JsonResponse
|
|
{
|
|
$activityModel = Activity::query()->findOrFail($activity);
|
|
$model = ActivitySession::query()->where('activity_id', $activity)->findOrFail($session);
|
|
$data = $request->validate([
|
|
'title' => ['nullable', 'string', 'max:255'],
|
|
'starts_at' => ['nullable', 'date'],
|
|
'ends_at' => ['nullable', 'date'],
|
|
'venue' => ['nullable', 'string', 'max:255'],
|
|
'capacity' => ['nullable', 'integer', 'min:0'],
|
|
'sort' => ['nullable', 'integer'],
|
|
]);
|
|
$this->assertSessionWithinActivity($activityModel, $data, $model);
|
|
$model->fill($data);
|
|
$model->save();
|
|
|
|
return $this->ok(null, '已保存');
|
|
}
|
|
|
|
public function destroy(int $activity, int $session): JsonResponse
|
|
{
|
|
$model = ActivitySession::query()->where('activity_id', $activity)->findOrFail($session);
|
|
$model->delete();
|
|
|
|
return $this->ok(null, '已删除');
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
/**
|
|
* @param array<string, mixed> $data
|
|
*/
|
|
protected function assertSessionWithinActivity(Activity $activity, array $data, ?ActivitySession $existing = null): void
|
|
{
|
|
$startsAt = $data['starts_at'] ?? $existing?->starts_at?->toIso8601String();
|
|
$endsAt = $data['ends_at'] ?? $existing?->ends_at?->toIso8601String();
|
|
|
|
if ($startsAt && $activity->event_start_date) {
|
|
$start = Carbon::parse($startsAt);
|
|
if ($start->toDateString() < $activity->event_start_date->toDateString()) {
|
|
throw ValidationException::withMessages([
|
|
'starts_at' => ['场次开始时间不能早于活动开始日期'],
|
|
]);
|
|
}
|
|
}
|
|
|
|
if ($endsAt && $activity->event_end_date) {
|
|
$end = Carbon::parse($endsAt);
|
|
if ($end->toDateString() > $activity->event_end_date->toDateString()) {
|
|
throw ValidationException::withMessages([
|
|
'ends_at' => ['场次结束时间不能晚于活动结束日期'],
|
|
]);
|
|
}
|
|
}
|
|
|
|
if ($startsAt && $endsAt && Carbon::parse($endsAt)->lt(Carbon::parse($startsAt))) {
|
|
throw ValidationException::withMessages([
|
|
'ends_at' => ['场次结束时间不能早于开始时间'],
|
|
]);
|
|
}
|
|
}
|
|
|
|
protected function serialize(ActivitySession $s): array
|
|
{
|
|
return [
|
|
'id' => $s->id,
|
|
'activity_id' => $s->activity_id,
|
|
'title' => $s->title,
|
|
'starts_at' => $s->starts_at?->toIso8601String(),
|
|
'ends_at' => $s->ends_at?->toIso8601String(),
|
|
'venue' => $s->venue,
|
|
'capacity' => $s->capacity !== null ? (int) $s->capacity : null,
|
|
'sort' => (int) $s->sort,
|
|
];
|
|
}
|
|
}
|