Files
componentsPC/app/Http/Controllers/PCBuildsController.php

246 lines
9.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers;
use App\Models\PCBuild;
use App\Models\Component;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Services\BuildValidator;
class PCBuildsController extends Controller
{
/**
* @OA\Get(
* path="/api/builds",
* summary="Получить список своих сборок",
* tags={"PC Builds"},
* @OA\Response(response=200, description="Список сборок"),
* @OA\Response(response=401, description="Неавторизован")
* )
*/
public function index()
{
$builds = PCBuild::where('user_id', auth()->id())
->with('components')
->get();
return response()->json($builds);
}
/**
* @OA\Post(
* path="/api/builds",
* summary="Создать новую сборку",
* tags={"PC Builds"},
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(
* required={"name", "component_ids"},
* @OA\Property(property="name", type="string", example="Игровой ПК 2025"),
* @OA\Property(property="description", type="string", nullable=true, example="Для игр в 1440p"),
* @OA\Property(property="component_ids", type="array", @OA\Items(type="integer", example=1)),
* @OA\Property(property="is_ai_generated", type="boolean", default=false),
* @OA\Property(property="ai_prompt", type="string", nullable=true, example="Сборка до 1000$ для игр")
* )
* ),
* @OA\Response(response=201, description="Сборка создана"),
* @OA\Response(response=400, description="Ошибка валидации"),
* @OA\Response(response=403, description="Запрещено: чужие компоненты")
* )
*/
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'description' => 'nullable|string',
'component_ids' => 'required|array|min:1',
'component_ids.*' => 'exists:components,id',
'is_ai_generated' => 'nullable|boolean',
'ai_prompt' => 'nullable|string',
]);
// Проверяем: все компоненты — либо официальные, либо ваши
$invalidComponents = Component::whereIn('id', $validated['component_ids'])
->where(function ($query) {
$query->where('is_official', false)
->where('created_by_user_id', '!=', auth()->id());
})
->pluck('name', 'id')
->toArray();
if (!empty($invalidComponents)) {
return response()->json([
'message' => 'Запрещено использовать неофициальные компоненты, созданные другими пользователями.',
'invalid_components' => $invalidComponents
], 403);
}
// 👇 ВСТАВЛЯЕМ ПРОВЕРКУ СОВМЕСТИМОСТИ ЗДЕСЬ — ПЕРЕД СОЗДАНИЕМ СБОРКИ
$validator = new BuildValidator();
$compatibility = $validator->validateCompatibility($validated['component_ids']);
if (!$compatibility['valid']) {
return response()->json([
'message' => 'Сборка содержит несовместимые компоненты.',
'errors' => $compatibility['errors'],
'warnings' => $compatibility['warnings']
], 422); // 422 Unprocessable Entity
}
// ✅ Только если совместимость OK — создаём сборку
$build = PCBuild::create([
'user_id' => auth()->id(),
'name' => $validated['name'],
'description' => $validated['description'] ?? null,
'is_ai_generated' => $validated['is_ai_generated'] ?? false,
'ai_prompt' => $validated['ai_prompt'] ?? null,
]);
$build->components()->attach($validated['component_ids']);
return response()->json([
'message' => 'Сборка успешно создана.',
'build' => $build->load('components'),
'compatibility' => $compatibility // опционально — для отладки
], 201);
}
/**
* @OA\Get(
* path="/api/builds/{id}",
* summary="Получить одну сборку по ID",
* tags={"PC Builds"},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
* @OA\Response(response=200, description="Сборка найдена"),
* @OA\Response(response=403, description="Запрещено: не ваша сборка"),
* @OA\Response(response=404, description="Не найдено")
* )
*/
public function show($id)
{
$build = PCBuild::with('components')->findOrFail($id);
if ($build->user_id !== auth()->id()) {
return response()->json([
'message' => 'Вы не можете просматривать эту сборку.'
], 403);
}
return response()->json($build);
}
/**
* @OA\Put(
* path="/api/builds/{id}",
* summary="Обновить сборку",
* tags={"PC Builds"},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(
* required={"name", "component_ids"},
* @OA\Property(property="name", type="string"),
* @OA\Property(property="description", type="string", nullable=true),
* @OA\Property(property="component_ids", type="array", @OA\Items(type="integer")),
* @OA\Property(property="is_ai_generated", type="boolean"),
* @OA\Property(property="ai_prompt", type="string", nullable=true)
* )
* ),
* @OA\Response(response=200, description="Сборка обновлена"),
* @OA\Response(response=403, description="Запрещено")
* )
*/
public function update(Request $request, $id)
{
$build = PCBuild::findOrFail($id);
if ($build->user_id !== auth()->id()) {
return response()->json([
'message' => 'Вы не можете редактировать эту сборку.'
], 403);
}
$validated = $request->validate([
'name' => 'required|string|max:255',
'description' => 'nullable|string',
'component_ids' => 'required|array|min:1',
'component_ids.*' => 'exists:components,id',
'is_ai_generated' => 'nullable|boolean',
'ai_prompt' => 'nullable|string',
]);
// Проверка: все компоненты — либо официальные, либо ваши
$invalidComponents = Component::whereIn('id', $validated['component_ids'])
->where(function ($query) {
$query->where('is_official', false)
->where('created_by_user_id', '!=', auth()->id());
})
->pluck('name', 'id')
->toArray();
if (!empty($invalidComponents)) {
return response()->json([
'message' => 'Запрещено использовать неофициальные компоненты, созданные другими пользователями.',
'invalid_components' => $invalidComponents
], 403);
}
// 👇 ВСТАВЛЯЕМ ПРОВЕРКУ СОВМЕСТИМОСТИ ЗДЕСЬ — ПЕРЕД ОБНОВЛЕНИЕМ
$validator = new BuildValidator();
$compatibility = $validator->validateCompatibility($validated['component_ids']);
if (!$compatibility['valid']) {
return response()->json([
'message' => 'Сборка содержит несовместимые компоненты.',
'errors' => $compatibility['errors'],
'warnings' => $compatibility['warnings']
], 422);
}
// ✅ Обновляем сборку
DB::transaction(function () use ($build, $validated) {
$build->update([
'name' => $validated['name'],
'description' => $validated['description'] ?? null,
'is_ai_generated' => $validated['is_ai_generated'] ?? $build->is_ai_generated,
'ai_prompt' => $validated['ai_prompt'] ?? $build->ai_prompt,
]);
$build->components()->sync($validated['component_ids']);
});
return response()->json([
'message' => 'Сборка обновлена.',
'build' => $build->load('components'),
'compatibility' => $compatibility // опционально
]);
}
/**
* @OA\Delete(
* path="/api/builds/{id}",
* summary="Удалить сборку",
* tags={"PC Builds"},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
* @OA\Response(response=200, description="Сборка удалена"),
* @OA\Response(response=403, description="Запрещено")
* )
*/
public function destroy($id)
{
$build = PCBuild::findOrFail($id);
if ($build->user_id !== auth()->id()) {
return response()->json([
'message' => 'Вы не можете удалить эту сборку.'
], 403);
}
$build->delete();
return response()->json([
'message' => 'Сборка удалена.'
]);
}
}