QuickQuiz/app/Http/Controllers/Api/App/ClassroomController.php

73 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api\App;
use App\Http\Controllers\Controller;
use App\Models\SchoolClass;
use App\Models\WrongQuestion;
use App\Services\LearningAccessService;
use App\Support\ApiResponse;
use hg\apidoc\annotation as Apidoc;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
#[Apidoc\Group('用户端')]
#[Apidoc\Title('班级学习入口')]
#[Apidoc\RouteMiddleware(['jwt.auth'])]
final class ClassroomController extends Controller
{
#[Apidoc\Title('我的班级')]
#[Apidoc\Url('/app/classes')]
#[Apidoc\Method('GET')]
public function myClasses(Request $request): JsonResponse
{
return ApiResponse::success(
SchoolClass::query()
->whereHas('members', fn ($query) => $query->where('users.id', $request->user()->id))
->withCount('members')
->get(),
);
}
#[Apidoc\Title('通过班级码加入')]
#[Apidoc\Url('/app/classes/join')]
#[Apidoc\Method('POST')]
public function join(Request $request): JsonResponse
{
$data = $request->validate(['join_code' => ['required', 'string']]);
$class = SchoolClass::query()->where('join_code', strtoupper($data['join_code']))->where('is_active', true)->firstOrFail();
$class->members()->syncWithoutDetaching([$request->user()->id => ['role' => 'student']]);
return ApiResponse::success($class, '已加入班级');
}
#[Apidoc\Title('可学习资源')]
#[Apidoc\Url('/app/resources')]
#[Apidoc\Method('GET')]
public function resources(Request $request, LearningAccessService $access): JsonResponse
{
$banks = $access->visibleBanksQuery($request->user())
->withCount('questions')
->get();
$wrongCounts = WrongQuestion::query()
->where('user_id', $request->user()->id)
->whereNull('mastered_at')
->join('questions', 'questions.id', '=', 'wrong_questions.question_id')
->selectRaw('questions.question_bank_id, count(*) as total')
->groupBy('questions.question_bank_id')
->pluck('total', 'question_bank_id');
$banks->each(fn ($bank) => $bank->setAttribute('wrong_questions_count', (int) ($wrongCounts[$bank->id] ?? 0)));
$papers = $access->visiblePapersQuery($request->user())
->withCount('questions')
->latest()
->get();
return ApiResponse::success(['banks' => $banks, 'papers' => $papers]);
}
}