FilterController.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Http\Requests\FilterRequest;
  4. use Illuminate\Support\Facades\DB;
  5. use Illuminate\Support\Facades\Schema;
  6. class FilterController extends Controller
  7. {
  8. const DB_TABLES = [
  9. 'orders' => 'orders_view',
  10. 'product_sku' => 'mafs_view',
  11. 'products' => 'products',
  12. 'reclamations' => 'reclamations_view',
  13. 'maf_order' => 'maf_orders_view',
  14. 'import' => 'imports',
  15. 'responsibles' => 'responsibles',
  16. 'users' => 'users',
  17. 'contracts' => 'contracts',
  18. 'spare_parts' => 'spare_parts',
  19. 'spare_part_orders' => 'spare_part_orders_view',
  20. ];
  21. const SKIP_YEAR_FILTER = [
  22. 'reclamations',
  23. ];
  24. /**
  25. * Маппинг виртуальных столбцов (аксессоров Eloquent) на реальные столбцы БД.
  26. * Ключ — имя таблицы из DB_TABLES, значение — массив 'виртуальный_столбец' => 'реальный_столбец'.
  27. */
  28. const COLUMN_MAP = [
  29. 'spare_part_orders' => [
  30. 'status_name' => 'status',
  31. 'with_documents_text' => 'with_documents',
  32. ],
  33. ];
  34. /**
  35. * Маппинг значений: реальное значение БД => отображаемое значение.
  36. * Ключ — имя таблицы, затем реальный столбец.
  37. */
  38. const VALUE_MAP = [
  39. 'spare_part_orders' => [
  40. 'with_documents' => [
  41. 0 => 'Нет',
  42. 1 => 'Да',
  43. ],
  44. 'status' => [
  45. 'ordered' => 'Заказано',
  46. 'in_stock' => 'На складе',
  47. 'shipped' => 'Отгружено',
  48. ],
  49. ],
  50. ];
  51. public function getFilters(FilterRequest $request)
  52. {
  53. $table = $request->validated('table');
  54. $column = $request->validated('column');
  55. if(!array_key_exists($table, self::DB_TABLES)) {
  56. abort(400, 'Table not found');
  57. }
  58. $gp = session('gp_' . $table);
  59. $dbTable = self::DB_TABLES[$table];
  60. // Определяем реальный столбец БД
  61. $dbColumn = self::resolveDbColumn($table, $dbTable, $column);
  62. if ($dbColumn && Schema::hasColumn($dbTable, $dbColumn)) {
  63. $q = DB::table($dbTable)->select($dbColumn)->distinct();
  64. if (!in_array($table, self::SKIP_YEAR_FILTER) && Schema::hasColumn($dbTable, 'year')) {
  65. $q->where('year' , year());
  66. }
  67. if (Schema::hasColumn($dbTable, 'deleted_at')) {
  68. $q->whereNull('deleted_at');
  69. }
  70. if(isset($gp['filters']) && is_array($gp['filters']) && count($gp['filters'])) {
  71. foreach ($gp['filters'] as $colName => $vals) {
  72. if ($colName === $column) continue;
  73. $filterDbColumn = self::resolveDbColumn($table, $dbTable, $colName);
  74. if (!$filterDbColumn || !Schema::hasColumn($dbTable, $filterDbColumn)) continue;
  75. $q->where(function ($query) use ($filterDbColumn, $vals) {
  76. foreach (explode('||', $vals) as $val) {
  77. if($val == '-пусто-') {
  78. $query->orWhereNull($filterDbColumn);
  79. } else {
  80. $query->orWhere($filterDbColumn, '=', $val);
  81. }
  82. }
  83. });
  84. }
  85. }
  86. $result = $q->orderBy($dbColumn)->get()->pluck($dbColumn)->toArray();
  87. // Применяем маппинг значений, если есть
  88. if (isset(self::VALUE_MAP[$table][$dbColumn])) {
  89. $map = self::VALUE_MAP[$table][$dbColumn];
  90. $result = array_map(fn($val) => $map[$val] ?? $val, $result);
  91. }
  92. } else {
  93. $result = [];
  94. }
  95. return response()->json($result, 200, [], JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
  96. }
  97. /**
  98. * Определяет реальный столбец БД по имени столбца из заголовка.
  99. * Приоритет: прямое совпадение в БД → COLUMN_MAP для конкретной таблицы.
  100. */
  101. public static function resolveDbColumn(string $table, string $dbTable, string $column): ?string
  102. {
  103. // 1. Прямое совпадение — столбец существует в БД
  104. if (Schema::hasColumn($dbTable, $column)) {
  105. return $column;
  106. }
  107. // 2. Явный маппинг для конкретной таблицы
  108. if (isset(self::COLUMN_MAP[$table][$column])) {
  109. return self::COLUMN_MAP[$table][$column];
  110. }
  111. return null;
  112. }
  113. }