AdminAreaController.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Http\Controllers\Controller;
  4. use App\Models\Dictionary\Area;
  5. use App\Models\Dictionary\District;
  6. use App\Services\Export\ExportAreasService;
  7. use App\Services\Import\ImportAreasService;
  8. use Illuminate\Http\RedirectResponse;
  9. use Illuminate\Http\Request;
  10. use Illuminate\Support\Facades\Storage;
  11. use Illuminate\View\View;
  12. class AdminAreaController extends Controller
  13. {
  14. protected string $id = 'admin_areas';
  15. protected array $header = [
  16. 'id' => 'ID',
  17. 'name' => 'Название',
  18. 'district_name' => 'Округ',
  19. 'actions' => '',
  20. ];
  21. protected array $searchFields = ['name'];
  22. public function index(Request $request): View
  23. {
  24. $nav = $this->resolveNavToken($request);
  25. $this->rememberNavigation($request, $nav);
  26. $allowedSortFields = ['id', 'name', 'district_name'];
  27. $sortBy = in_array($request->get('sortBy'), $allowedSortFields, true) ? $request->get('sortBy') : 'name';
  28. $orderBy = $request->get('order') === 'desc' ? 'desc' : 'asc';
  29. $query = Area::query()
  30. ->leftJoin('districts', 'areas.district_id', '=', 'districts.id')
  31. ->select('areas.*', 'districts.shortname as district_name');
  32. // Фильтр по округу
  33. if ($request->has('district_id') && $request->district_id) {
  34. $query->where('areas.district_id', $request->district_id);
  35. }
  36. if ($request->filled('s')) {
  37. $search = $request->get('s');
  38. $query->where(function ($q) use ($search) {
  39. $q->where('areas.name', 'like', '%' . $search . '%')
  40. ->orWhere('districts.shortname', 'like', '%' . $search . '%');
  41. });
  42. }
  43. if ($sortBy === 'district_name') {
  44. $query->orderBy('districts.shortname', $orderBy);
  45. } else {
  46. $query->orderBy('areas.' . $sortBy, $orderBy);
  47. }
  48. $areas = $query->get();
  49. $districts = District::orderBy('shortname')->pluck('shortname', 'id')->toArray();
  50. return view('admin.areas.index', [
  51. 'active' => 'admin_areas',
  52. 'id' => $this->id,
  53. 'header' => $this->header,
  54. 'sortBy' => $sortBy,
  55. 'orderBy' => $orderBy,
  56. 'searchFields' => ['name', 'district_name'],
  57. 'areas' => $areas,
  58. 'districts' => $districts,
  59. 'selectedDistrict' => $request->district_id,
  60. 'nav' => $nav,
  61. ]);
  62. }
  63. public function show(Request $request, int $areaId): View
  64. {
  65. $nav = $this->resolveNavToken($request);
  66. $this->rememberNavigation($request, $nav);
  67. $area = Area::withTrashed()->findOrFail($areaId);
  68. $districts = District::orderBy('shortname')->pluck('name', 'id')->toArray();
  69. return view('admin.areas.edit', [
  70. 'active' => 'admin_areas',
  71. 'area' => $area,
  72. 'districts' => $districts,
  73. 'nav' => $nav,
  74. 'back_url' => $this->navigationBackUrl($request, $nav, route('admin.area.index')),
  75. ]);
  76. }
  77. public function store(Request $request): RedirectResponse
  78. {
  79. $validated = $request->validate([
  80. 'id' => ['nullable', 'integer'],
  81. 'name' => ['required', 'string', 'max:255'],
  82. 'district_id' => ['required', 'integer', 'exists:districts,id'],
  83. ]);
  84. if (!empty($validated['id'])) {
  85. $area = Area::withTrashed()->findOrFail($validated['id']);
  86. $area->update([
  87. 'name' => $validated['name'],
  88. 'district_id' => $validated['district_id'],
  89. ]);
  90. } else {
  91. Area::create([
  92. 'name' => $validated['name'],
  93. 'district_id' => $validated['district_id'],
  94. ]);
  95. }
  96. return redirect()->route('admin.area.index')->with('success', 'Район сохранён');
  97. }
  98. public function destroy(Area $area): RedirectResponse
  99. {
  100. $area->delete();
  101. return redirect()->route('admin.area.index')->with('success', 'Район удалён');
  102. }
  103. public function undelete(int $areaId): RedirectResponse
  104. {
  105. $area = Area::withTrashed()->findOrFail($areaId);
  106. $area->restore();
  107. return redirect()->route('admin.area.index')->with('success', 'Район восстановлен');
  108. }
  109. public function export(Request $request): RedirectResponse
  110. {
  111. $service = new ExportAreasService();
  112. $link = $service->handle($request->user()->id);
  113. return redirect()->away($link);
  114. }
  115. public function import(Request $request): RedirectResponse
  116. {
  117. $request->validate([
  118. 'import_file' => ['required', 'file', 'mimes:xlsx,xls'],
  119. ]);
  120. $file = $request->file('import_file');
  121. $path = $file->store('import/areas', 'upload');
  122. $fullPath = Storage::disk('upload')->path($path);
  123. $service = new ImportAreasService($fullPath, $request->user()->id);
  124. $result = $service->handle();
  125. if ($result['success']) {
  126. return redirect()->route('admin.area.index')
  127. ->with('success', 'Импорт завершён успешно');
  128. }
  129. return redirect()->route('admin.area.index')
  130. ->with('error', 'Ошибка импорта: ' . ($result['error'] ?? 'неизвестная ошибка'));
  131. }
  132. }