154 lines
5.5 KiB
PHP
154 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\ExportJob;
|
|
use App\Models\User;
|
|
use App\Services\ReportQueryService;
|
|
use App\Support\ApiResponse;
|
|
use hg\apidoc\annotation as Apidoc;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
#[Apidoc\Group('后台')]
|
|
#[Apidoc\Title('统计报表')]
|
|
#[Apidoc\RouteMiddleware(['jwt.auth'])]
|
|
final class ReportController extends Controller
|
|
{
|
|
#[Apidoc\Title('报表筛选选项')]
|
|
#[Apidoc\Url('/admin/reports/options')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function options(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->options($request->user(), $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('报表概览')]
|
|
#[Apidoc\Url('/admin/reports/overview')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function overview(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->overview($request->user(), $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('练习趋势')]
|
|
#[Apidoc\Url('/admin/reports/trends')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function trends(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->trends($request->user(), $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('题目错误率')]
|
|
#[Apidoc\Url('/admin/reports/question-errors')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function questionErrors(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::page($service->questionErrors($request->user(), $filters, (int) $request->query('per_page', 20)));
|
|
}
|
|
|
|
#[Apidoc\Title('班级排行')]
|
|
#[Apidoc\Url('/admin/reports/class-ranking')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function classRanking(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->classRanking($request->user(), $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('题库和分类掌握度')]
|
|
#[Apidoc\Url('/admin/reports/mastery')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function mastery(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->mastery($request->user(), $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('学生统计')]
|
|
#[Apidoc\Url('/admin/reports/students')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function students(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::page($service->students($request->user(), $filters, (int) $request->query('per_page', 20)));
|
|
}
|
|
|
|
#[Apidoc\Title('学生统计详情')]
|
|
#[Apidoc\Url('/admin/reports/students/{user}')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function studentDetail(Request $request, mixed $user, ReportQueryService $service): JsonResponse
|
|
{
|
|
$student = User::query()->findOrFail((int) $user);
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->studentDetail($request->user(), $student, $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('题库统计详情')]
|
|
#[Apidoc\Url('/admin/reports/banks/{bank}')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function bankDetail(Request $request, mixed $bank, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->bankDetail($request->user(), (int) $bank, $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('重点关注建议')]
|
|
#[Apidoc\Url('/admin/reports/insights')]
|
|
#[Apidoc\Method('GET')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function insights(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->query());
|
|
|
|
return ApiResponse::success($service->insights($request->user(), $filters));
|
|
}
|
|
|
|
#[Apidoc\Title('报表导出')]
|
|
#[Apidoc\Url('/admin/reports/export')]
|
|
#[Apidoc\Method('POST')]
|
|
#[Apidoc\RouteMiddleware(['permission:reports'])]
|
|
public function export(Request $request, ReportQueryService $service): JsonResponse
|
|
{
|
|
$filters = $service->filters($request->all());
|
|
$payload = $service->exportPayload($request->user(), $filters);
|
|
$path = 'exports/report-'.now()->format('YmdHis').'.json';
|
|
Storage::put($path, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
|
|
|
$job = ExportJob::create([
|
|
'user_id' => $request->user()->id,
|
|
'type' => 'report',
|
|
'file_path' => $path,
|
|
'payload' => $payload,
|
|
]);
|
|
|
|
return ApiResponse::success($job, '报表已导出');
|
|
}
|
|
}
|