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.

167 lines
5.4 KiB

<?php
namespace App\Http\Controllers\Miniapp;
use App\Models\Activity;
use App\Models\ActivitySignup;
use App\Models\ActivitySignupCheckin;
use App\Models\CourseCheckinDay;
use App\Models\CourseSignup;
use App\Models\CourseSignupCheckin;
use App\Models\MiniappUser;
use App\Support\ApiResponse;
use App\Support\ActivitySigninCodeSync;
use App\Support\Miniapp\MiniappPresenter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CheckinController extends BaseController
{
use ApiResponse;
public function course(Request $request): JsonResponse
{
/** @var MiniappUser $user */
$user = $request->user();
$data = $request->validate([
'signin_code' => ['required', 'string', 'max:64'],
]);
$day = CourseCheckinDay::query()
->with([
'course' => fn ($q) => $q
->with(['courseSystemItem', 'coverMedia', 'promoMedia'])
->withCount('signups'),
])
->where('signin_code', $data['signin_code'])
->first();
if (! $day || ! $day->course) {
return $this->fail('签到码无效', 422);
}
$signup = CourseSignup::query()
->where('course_id', $day->course_id)
->where('miniapp_user_id', $user->id)
->first();
if (! $signup) {
return $this->fail('您尚未报名该课程,无法签到', 422);
}
$checkinDate = $day->teach_date->toDateString();
$existing = CourseSignupCheckin::query()
->where('course_signup_id', $signup->id)
->whereDate('checkin_date', $checkinDate)
->whereNotNull('checked_in_at')
->first();
if ($existing) {
return $this->ok([
'type' => 'course',
'already_checked_in' => true,
'checked_in_at' => $existing->checked_in_at?->toDateTimeString(),
'checkin_date' => $checkinDate,
'target' => MiniappPresenter::serializeCourseList($day->course, $user),
], '今日已签到');
}
$checkin = CourseSignupCheckin::query()->updateOrCreate(
[
'course_signup_id' => $signup->id,
'checkin_date' => $checkinDate,
],
['checked_in_at' => now()]
);
return $this->ok([
'type' => 'course',
'already_checked_in' => false,
'checked_in_at' => $checkin->checked_in_at?->toDateTimeString(),
'checkin_date' => $checkinDate,
'target' => MiniappPresenter::serializeCourseList($day->course, $user),
], '签到成功');
}
public function activity(Request $request): JsonResponse
{
/** @var MiniappUser $user */
$user = $request->user();
$data = $request->validate([
'signin_code' => ['required', 'string', 'max:64'],
]);
$code = strtoupper(trim($data['signin_code']));
$activity = Activity::query()
->whereRaw('UPPER(code) = ?', [$code])
->first();
if (! $activity) {
$activity = Activity::query()
->get()
->first(fn (Activity $item) => strtoupper(ActivitySigninCodeSync::activitySigninCode($item)) === $code);
}
if (! $activity) {
return $this->fail('签到码无效', 422);
}
$activity->load(['activityTypeItem', 'sessions'])->loadCount('signups');
$signup = ActivitySignup::query()
->with('session')
->where('activity_id', $activity->id)
->where('miniapp_user_id', $user->id)
->first();
if (! $signup) {
return $this->fail('您尚未报名该活动,无法签到', 422);
}
if (! $signup->activity_session_id) {
return $this->fail('报名记录缺少场次信息', 422);
}
$existing = ActivitySignupCheckin::query()
->where('activity_signup_id', $signup->id)
->where('activity_session_id', $signup->activity_session_id)
->whereNotNull('checked_in_at')
->first();
$target = MiniappPresenter::serializeActivityList($activity, $user);
$target['summary'] = strip_tags((string) $activity->intro_html);
if ($existing) {
return $this->ok([
'type' => 'activity',
'already_checked_in' => true,
'checked_in_at' => $existing->checked_in_at?->toDateTimeString(),
'target' => $target,
'session' => $signup->session
? MiniappPresenter::serializeActivitySession($signup->session)
: null,
], '已签到');
}
$checkin = ActivitySignupCheckin::query()->updateOrCreate(
[
'activity_signup_id' => $signup->id,
'activity_session_id' => $signup->activity_session_id,
],
['checked_in_at' => now()]
);
return $this->ok([
'type' => 'activity',
'already_checked_in' => false,
'checked_in_at' => $checkin->checked_in_at?->toDateTimeString(),
'target' => $target,
'session' => $signup->session
? MiniappPresenter::serializeActivitySession($signup->session)
: null,
], '签到成功');
}
}