AdminDistrictController.php 5.0 KB

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