'orders_view', 'product_sku' => 'mafs_view', 'products' => 'products', 'reclamations' => 'reclamations_view', 'maf_order' => 'maf_orders_view', 'import' => 'imports', 'responsibles' => 'responsibles', 'users' => 'users', 'contracts' => 'contracts', 'spare_parts' => 'spare_parts_view', 'spare_part_orders' => 'spare_part_orders_view', 'notifications' => 'user_notifications', ]; const SKIP_YEAR_FILTER = [ 'reclamations', 'notifications', ]; /** * Маппинг виртуальных столбцов (аксессоров Eloquent) на реальные столбцы БД. * Ключ — имя таблицы из DB_TABLES, значение — массив 'виртуальный_столбец' => 'реальный_столбец'. */ const COLUMN_MAP = [ 'spare_part_orders' => [ 'status_name' => 'status', 'with_documents_text' => 'with_documents', ], 'spare_parts' => [ 'customer_price_txt' => 'customer_price', 'expertise_price_txt' => 'expertise_price', 'purchase_price_txt' => 'purchase_price', ], 'products' => [ 'product_price_txt' => 'product_price', 'installation_price_txt' => 'installation_price', 'total_price_txt' => 'total_price', ], ]; /** * Маппинг значений: реальное значение БД => отображаемое значение. * Ключ — имя таблицы, затем реальный столбец. */ const VALUE_MAP = [ 'notifications' => [ 'type' => [ 'platform' => 'Площадки', 'reclamation' => 'Рекламации', 'schedule' => 'График монтажей', ], 'event' => [ 'created' => 'Создание', 'status_changed' => 'Смена статуса', 'schedule_added' => 'Добавлено в график', ], ], 'spare_part_orders' => [ 'with_documents' => [ 0 => 'Нет', 1 => 'Да', ], 'status' => [ 'ordered' => 'Заказано', 'in_stock' => 'На складе', 'shipped' => 'Отгружено', ], ], ]; public function getFilters(FilterRequest $request) { $table = $request->validated('table'); $column = $request->validated('column'); if(!array_key_exists($table, self::DB_TABLES)) { abort(400, 'Table not found'); } $gp = session('gp_' . $table); $dbTable = self::DB_TABLES[$table]; // Определяем реальный столбец БД $dbColumn = self::resolveDbColumn($table, $dbTable, $column); if ($dbColumn && Schema::hasColumn($dbTable, $dbColumn)) { $q = DB::table($dbTable)->select($dbColumn)->distinct(); if (!in_array($table, self::SKIP_YEAR_FILTER) && Schema::hasColumn($dbTable, 'year')) { $q->where('year' , year()); } if (Schema::hasColumn($dbTable, 'deleted_at')) { $q->whereNull('deleted_at'); } if(isset($gp['filters']) && is_array($gp['filters']) && count($gp['filters'])) { foreach ($gp['filters'] as $colName => $vals) { if ($colName === $column) continue; $filterDbColumn = self::resolveDbColumn($table, $dbTable, $colName); if (!$filterDbColumn || !Schema::hasColumn($dbTable, $filterDbColumn)) continue; $q->where(function ($query) use ($filterDbColumn, $vals) { foreach (explode('||', $vals) as $val) { if($val == '-пусто-') { $query->orWhereNull($filterDbColumn); } else { $query->orWhere($filterDbColumn, '=', $val); } } }); } } $result = $q->orderBy($dbColumn)->get()->pluck($dbColumn)->toArray(); // Конвертация цен из копеек в рубли для отображения if (str_ends_with($dbColumn, '_price')) { $result = array_map(function ($val) { if ($val === null) { return $val; } return $val / 100; }, $result); } // Применяем маппинг значений, если есть if (isset(self::VALUE_MAP[$table][$dbColumn])) { $map = self::VALUE_MAP[$table][$dbColumn]; $result = array_map(fn($val) => $map[$val] ?? $val, $result); } } else { $result = []; } return response()->json($result, 200, [], JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT); } /** * Определяет реальный столбец БД по имени столбца из заголовка. * Приоритет: прямое совпадение в БД → COLUMN_MAP для конкретной таблицы. */ public static function resolveDbColumn(string $table, string $dbTable, string $column): ?string { // 1. Прямое совпадение — столбец существует в БД if (Schema::hasColumn($dbTable, $column)) { return $column; } // 2. Явный маппинг для конкретной таблицы if (isset(self::COLUMN_MAP[$table][$column])) { return self::COLUMN_MAP[$table][$column]; } return null; } }