From 10fcaae3ac1ebae30dd002bd4758d9a05231f085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=20=D0=98?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Fri, 30 May 2025 00:03:33 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D1=81?= =?UTF-8?q?=D0=BE=20=D1=81=D1=82=D1=83=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/Http/Controllers/AuthController.php | 19 +- .../Http/Controllers/DashboardController.php | 31 +- .../Http/Controllers/StatisticController.php | 10 + .../Http/Controllers/StudentController.php | 86 +++++- .../app/Http/Middleware/CheckJWTToken.php | 31 ++ University.Web/app/Services/ApiService.php | 66 ++++ University.Web/bootstrap/app.php | 5 +- .../resources/views/dashboard.blade.php | 287 ++++++++++++++---- .../resources/views/layouts/app.blade.php | 39 +++ .../resources/views/students/form.blade.php | 187 ++++++++++++ .../resources/views/students/index.blade.php | 87 ++++++ University.Web/routes/web.php | 8 +- 12 files changed, 786 insertions(+), 70 deletions(-) create mode 100644 University.Web/app/Http/Controllers/StatisticController.php create mode 100644 University.Web/app/Http/Middleware/CheckJWTToken.php create mode 100644 University.Web/app/Services/ApiService.php create mode 100644 University.Web/resources/views/layouts/app.blade.php create mode 100644 University.Web/resources/views/students/form.blade.php create mode 100644 University.Web/resources/views/students/index.blade.php diff --git a/University.Web/app/Http/Controllers/AuthController.php b/University.Web/app/Http/Controllers/AuthController.php index c968b0f..b8803be 100644 --- a/University.Web/app/Http/Controllers/AuthController.php +++ b/University.Web/app/Http/Controllers/AuthController.php @@ -2,8 +2,10 @@ namespace App\Http\Controllers; +use Illuminate\Http\Client\ConnectionException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Facades\Session; class AuthController extends Controller { @@ -63,9 +65,13 @@ class AuthController extends Controller ]); if ($response->successful()) { - $token = $response->json()['token']; - session(['api_token' => $token]); - session()->forget('user_id'); + $data = $response->json(); + Session::put([ + 'api_token' => $data['token'], + 'user_id' => $data['user']['id'] ?? null, + 'user_name' => $data['user']['name'] ?? null, + 'user_role' => $data['user']['roles_id'] ?? null, + ]); return redirect()->intended('/dashboard'); } @@ -74,12 +80,15 @@ class AuthController extends Controller ]); } + /** + * @throws ConnectionException + */ public function logout(Request $request) { - Http::withToken(session('api_token')) + $response = Http::withToken(Session::get('api_token')) ->post("{$this->apiBaseUrl}/employee/logout"); $request->session()->invalidate(); - return redirect('/'); + return redirect('/login'); } } diff --git a/University.Web/app/Http/Controllers/DashboardController.php b/University.Web/app/Http/Controllers/DashboardController.php index 1c85bfa..303bbe5 100644 --- a/University.Web/app/Http/Controllers/DashboardController.php +++ b/University.Web/app/Http/Controllers/DashboardController.php @@ -2,12 +2,37 @@ namespace App\Http\Controllers; -use Illuminate\Http\Request; +use App\Services\ApiService; +use Illuminate\Contracts\View\Factory; +use Illuminate\Contracts\View\View; +use Illuminate\Foundation\Application; +use Illuminate\Http\Client\ConnectionException; class DashboardController extends Controller { - public function index() + protected ApiService $api; + + public function __construct(ApiService $api) { - return view('dashboard'); + $this->api = $api; + } + + /** + * @param ApiService $api + * @return Factory|View|Application|\Illuminate\View\View|object + * @throws ConnectionException + */ + public function index(ApiService $api) + { + $response = $api->withAuth()->get('/employee/me'); + $user = $response->json(); + + $statsResponse = $api->withAuth()->get('/employee/statistics'); + $stats = $statsResponse->json(); + + return view('dashboard', [ + 'user' => $user, + 'stats' => $stats + ]); } } diff --git a/University.Web/app/Http/Controllers/StatisticController.php b/University.Web/app/Http/Controllers/StatisticController.php new file mode 100644 index 0000000..b5805cb --- /dev/null +++ b/University.Web/app/Http/Controllers/StatisticController.php @@ -0,0 +1,10 @@ +api = $api; + } + + public function index() + { + $responseStudents = $this->api->get('/employee/students'); + $responseGroups = $this->api->get('/employee/groups'); + + if ($responseStudents->successful() && $responseGroups->successful()) { + $students = $responseStudents->json(); + $groups = $responseGroups->json(); + $groupsList = collect($groups)->pluck('name', 'id')->toArray(); + return view('students.index', compact('students', 'groupsList')); + } + + abort($responseStudents->status()); + } + + public function create() + { + $groups = $this->api->get('/employee/groups')->json(); + return view('students.form', ['groups' => $groups]); + } + + public function store(Request $request) + { + $response = $this->api->post('/employee/students', $request->all()); + + if ($response->successful()) { + return redirect()->route('students.index') + ->with('success', 'Студент успешно создан'); + } + + return back()->withErrors($response->json()['errors'] ?? []); + } + + public function edit($id) + { + $response = $this->api->get("/employee/students/{$id}"); + + if ($response->successful()) { + $student = $response->json(); + $groups = $this->api->get('/employee/groups')->json(); + return view('students.form', [ + 'student' => $student, + 'groups' => $groups, + 'isEdit' => true + ]); + } + + abort($response->status()); + } + + /** + * @throws ConnectionException + */ + public function update(Request $request, $id) + { + $response = $this->api->patch("/employee/students/{$id}", $request->all()); + + if ($response->successful()) { + return redirect()->route('students.index') + ->with('success', 'Данные студента обновлены'); + } + + return back()->withErrors($response->json()['errors'] ?? []); + } + + public function destroy($id) + { + $response = $this->api->delete("/employee/students/{$id}"); + + if ($response->successful()) { + return redirect()->route('students.index') + ->with('success', 'Студент удален'); + } + + return back()->withErrors($response->json()['error'] ?? 'Ошибка при удалении'); + } } diff --git a/University.Web/app/Http/Middleware/CheckJWTToken.php b/University.Web/app/Http/Middleware/CheckJWTToken.php new file mode 100644 index 0000000..1e43af4 --- /dev/null +++ b/University.Web/app/Http/Middleware/CheckJWTToken.php @@ -0,0 +1,31 @@ +route('login'); + } + + $response = Http::withToken(Session::get('api_token')) + ->get(env('API_BASE_URL') . '/employee/me'); + + if ($response->failed()) { + Session::forget('api_token'); + return redirect()->route('login'); + } + + return $next($request); + } +} diff --git a/University.Web/app/Services/ApiService.php b/University.Web/app/Services/ApiService.php new file mode 100644 index 0000000..fa5444e --- /dev/null +++ b/University.Web/app/Services/ApiService.php @@ -0,0 +1,66 @@ +baseUrl = env('API_BASE_URL', 'http://127.0.0.1:8000/api'); + } + + public function withAuth(): PendingRequest + { + return Http::withToken(Session::get('api_token')) + ->baseUrl($this->baseUrl); + } + + /** + * @throws ConnectionException + */ + public function get(string $url, array $params = []): PromiseInterface|Response + { + return $this->withAuth()->get($url, $params); + } + + /** + * @throws ConnectionException + */ + public function post(string $url, array $data = []): PromiseInterface|Response + { + return $this->withAuth()->post($url, $data); + } + + /** + * @throws ConnectionException + */ + public function patch(string $url, array $data = []): PromiseInterface|Response + { + return $this->withAuth()->patch($url, $data); + } + + /** + * @throws ConnectionException + */ + public function put(string $url, array $data = []): PromiseInterface|Response + { + return $this->withAuth()->put($url, $data); + } + + /** + * @throws ConnectionException + */ + public function delete(string $url, array $params = []): PromiseInterface|Response + { + return $this->withAuth()->delete($url, $params); + } +} diff --git a/University.Web/bootstrap/app.php b/University.Web/bootstrap/app.php index 7b162da..289e175 100644 --- a/University.Web/bootstrap/app.php +++ b/University.Web/bootstrap/app.php @@ -1,5 +1,6 @@ withMiddleware(function (Middleware $middleware) { - // + $middleware->alias([ + 'jwt.auth' => CheckJWTToken::class, + ]); }) ->withExceptions(function (Exceptions $exceptions) { // diff --git a/University.Web/resources/views/dashboard.blade.php b/University.Web/resources/views/dashboard.blade.php index b5410b0..43c9a6a 100644 --- a/University.Web/resources/views/dashboard.blade.php +++ b/University.Web/resources/views/dashboard.blade.php @@ -6,112 +6,283 @@ Панель управления @vite(['resources/css/app.css', 'resources/js/app.js'])
-

Панель управления сотрудника

-

Выберите раздел для работы

+

Панель управления

+

Добро пожаловать, {{ $user['name'] }}!

-
- - -
- - - +
+

Статистика

+
+
+
{{ number_format($stats['students_count'] ?? 0, 0, ',', ' ') }}
+
Студентов
-

Студенты

-

Управление списком студентов

-
- - -
- - - +
+
{{ number_format($stats['groups_count'] ?? 0, 0, ',', ' ') }}
+
Учебных группы
-

Группы

-

Управление учебными группами

-
- - - diff --git a/University.Web/resources/views/layouts/app.blade.php b/University.Web/resources/views/layouts/app.blade.php new file mode 100644 index 0000000..e659990 --- /dev/null +++ b/University.Web/resources/views/layouts/app.blade.php @@ -0,0 +1,39 @@ + + + + + + + + + + @yield('title') + + + + + + @yield('links') + + @vite([ 'resources/js/app.js']) + + + +
+ + +
+ @yield('content') +
+
+ + diff --git a/University.Web/resources/views/students/form.blade.php b/University.Web/resources/views/students/form.blade.php new file mode 100644 index 0000000..d045441 --- /dev/null +++ b/University.Web/resources/views/students/form.blade.php @@ -0,0 +1,187 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
+ {{ isset($student) ? 'Редактирование студента' : 'Добавление нового студента' }} +
+ +
+
+ @csrf + @if(isset($student)) + @method('PATCH') + @endif + +
+ +
+ + @error('surname') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('name') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('patronymic') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('email') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('telephone') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('password') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('gender') + + {{ $message }} + + @enderror +
+
+ + +
+ +
+ + @error('birth_date') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('citizenship') + + {{ $message }} + + @enderror +
+
+ +
+ +
+ + @error('group_id') + + {{ $message }} + + @enderror +
+
+ + +
+ +
+ + @error('matriculation_number') + + {{ $message }} + + @enderror +
+
+ +
+
+ + Отмена +
+
+
+
+
+
+
+
+@endsection diff --git a/University.Web/resources/views/students/index.blade.php b/University.Web/resources/views/students/index.blade.php new file mode 100644 index 0000000..ba41e7b --- /dev/null +++ b/University.Web/resources/views/students/index.blade.php @@ -0,0 +1,87 @@ +@extends('layouts.app') +@section('links') + + +@endsection +@section('content') +
+ +
+
+ + + + + + + + + + + + + + + + @foreach($students as $student) + + + + + + + + + + + + @endforeach + +
ФИОГруппаEmailТелефонПолДата рожденияГражданствоЗачетная книжка
+
+ {{ $student['surname'] }} {{ $student['name'] }} {{ $student['patronymic'] ?? '' }} +
+
+
+ {{ $groupsList[$student['student_profile']['group_id']] ?? 'Не указана' }} +
+
+
{{ $student['email'] }}
+
+
{{ $student['telephone'] }}
+
+
{{ $student['gender'] }}
+
+
{{ \Carbon\Carbon::parse($student['birth_date'])->format('d.m.Y') }}
+
+
{{ $student['citizenship'] }}
+
+
+ {{ $student['student_profile']['matriculation_number'] ?? 'Не указан' }} +
+
+ +
+ @csrf + @method('DELETE') + +
+
+
+
+
+@endsection diff --git a/University.Web/routes/web.php b/University.Web/routes/web.php index 8eaf08f..976e4cc 100644 --- a/University.Web/routes/web.php +++ b/University.Web/routes/web.php @@ -6,6 +6,7 @@ use App\Http\Controllers\DirectionController; use App\Http\Controllers\DisciplineController; use App\Http\Controllers\GroupController; use App\Http\Controllers\StatementController; +use App\Http\Controllers\StatisticController; use App\Http\Controllers\StudentController; use Illuminate\Support\Facades\Route; @@ -21,12 +22,12 @@ Route::controller(AuthController::class)->group(function () { Route::post('/logout', 'logout')->name('logout'); }); -Route::middleware(['auth'])->group(function () { +Route::middleware(['jwt.auth'])->group(function () { // Dashboard Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard'); // Students - Route::get('/students', [StudentController::class, 'index'])->name('students.index'); + Route::resource('students', StudentController::class)->except(['show']); // Groups Route::get('/groups', [GroupController::class, 'index'])->name('groups.index'); @@ -39,4 +40,7 @@ Route::middleware(['auth'])->group(function () { // Statements Route::get('/statements', [StatementController::class, 'index'])->name('statements.index'); + + // Statistics + Route::get('/statistics', [StatisticController::class, 'index'])->name('statistics.index'); });